LMMC
Lamina Mathematic core
载入中...
搜索中...
未找到
stdlib_text_sets.c
浏览该文件的文档.
1#include "lmmc/stdlib.h"
2
3#include <string.h>
4
5#include "memory_bridge.h"
6
7#include "stdlib_internal.h"
8
9lmmc_status_t lmmc_std_text_equal(const char* lhs, const char* rhs, int* out)
10{
11 if (!lhs || !rhs || !out) { return LMMC_STATUS_INVALID_ARGUMENT; }
12 *out = strcmp(lhs, rhs) == 0 ? 1 : 0;
13 return LMMC_STATUS_OK;
14}
15
16lmmc_status_t lmmc_std_text_hash(const char* value, uint64_t* out)
17{
18 if (!value || !out) { return LMMC_STATUS_INVALID_ARGUMENT; }
19 *out = lmmc_std_text_hash_bytes(value);
20 return LMMC_STATUS_OK;
21}
22
23static char* lmmc_std_text_copy(const char* value)
24{
25 size_t length = strlen(value);
26 char* copy = NULL;
27 if (length == (size_t)-1) { return NULL; }
28 copy = (char*)lmmc_memory_alloc_array_plus(length, 1, sizeof(char));
29 if (!copy) { return NULL; }
30 memcpy(copy, value, length + 1);
31 return copy;
32}
33
34static int lmmc_std_text_set_valid(const lmmc_std_text_set_t* set)
35{
36 if (!set) { return 0; }
37 if (set->size == 0) { return 1; }
38 if (!set->data) { return 0; }
39 for (size_t i = 0; i < set->size; ++i) {
40 if (!set->data[i]) { return 0; }
41 }
42 return 1;
43}
44
45static int lmmc_std_text_set_contains_value(const lmmc_std_text_set_t* set,
46 const char* value)
47{
48 for (size_t i = 0; i < set->size; ++i) {
49 if (strcmp(set->data[i], value) == 0) { return 1; }
50 }
51 return 0;
52}
53
54static lmmc_status_t lmmc_std_text_set_alloc(size_t capacity,
56{
57 size_t bytes = 0;
58 if (!out) { return LMMC_STATUS_INVALID_ARGUMENT; }
59 out->size = 0;
60 out->data = NULL;
61 out->owns_data = 0;
62 if (capacity == 0) { return LMMC_STATUS_OK; }
63 if (!lmmc_safe_mul_size(capacity, sizeof(char*), &bytes)) {
65 }
66 out->data = (char**)lmmc_memory_alloc(bytes);
67 if (!out->data) { return LMMC_STATUS_ALLOCATION_FAILED; }
68 memset(out->data, 0, bytes);
69 out->owns_data = 1;
70 return LMMC_STATUS_OK;
71}
72
73static lmmc_status_t lmmc_std_text_set_append_unique(
75 const char* value)
76{
77 char* copy = NULL;
78 if (!set || !value) { return LMMC_STATUS_INVALID_ARGUMENT; }
79 if (lmmc_std_text_set_contains_value(set, value)) { return LMMC_STATUS_OK; }
80 if (!set->data) { return LMMC_STATUS_INVALID_ARGUMENT; }
81 copy = lmmc_std_text_copy(value);
82 if (!copy) { return LMMC_STATUS_ALLOCATION_FAILED; }
83 set->data[set->size++] = copy;
84 return LMMC_STATUS_OK;
85}
86
87lmmc_status_t lmmc_std_text_set_make(const char* const* values,
88 size_t count,
90{
91 lmmc_status_t status;
92 if (!out || (count > 0 && !values)) { return LMMC_STATUS_INVALID_ARGUMENT; }
93 status = lmmc_std_text_set_alloc(count, out);
94 if (status != LMMC_STATUS_OK) { return status; }
95 for (size_t i = 0; i < count; ++i) {
96 status = lmmc_std_text_set_append_unique(out, values[i]);
97 if (status != LMMC_STATUS_OK) {
99 return status;
100 }
101 }
102 return LMMC_STATUS_OK;
103}
104
106{
107 if (!set) return;
108 if (set->owns_data && set->data) {
109 for (size_t i = 0; i < set->size; ++i) {
110 if (set->data[i]) {
111 lmmc_memory_free(set->data[i]);
112 }
113 }
115 }
116 set->size = 0;
117 set->data = NULL;
118 set->owns_data = 0;
119}
120
122 const char* value,
123 int* out)
124{
125 if (!value || !out) { return LMMC_STATUS_INVALID_ARGUMENT; }
126 if (!lmmc_std_text_set_valid(set)) { return LMMC_STATUS_INVALID_ARGUMENT; }
127 *out = lmmc_std_text_set_contains_value(set, value);
128 return LMMC_STATUS_OK;
129}
130
132 const lmmc_std_text_set_t* rhs,
133 int* out)
134{
135 if (!out || !lmmc_std_text_set_valid(lhs) ||
136 !lmmc_std_text_set_valid(rhs)) {
138 }
139 for (size_t i = 0; i < lhs->size; ++i) {
140 if (!lmmc_std_text_set_contains_value(rhs, lhs->data[i])) {
141 *out = 0;
142 return LMMC_STATUS_OK;
143 }
144 }
145 *out = 1;
146 return LMMC_STATUS_OK;
147}
148
149static lmmc_status_t lmmc_std_text_set_binary_alloc(
150 const lmmc_std_text_set_t* lhs,
151 const lmmc_std_text_set_t* rhs,
153{
154 if (!out || (const void*)out == (const void*)lhs ||
155 (const void*)out == (const void*)rhs ||
156 !lmmc_std_text_set_valid(lhs) || !lmmc_std_text_set_valid(rhs)) {
158 }
159 if (lhs->size > ((size_t)-1) - rhs->size) {
161 }
162 return lmmc_std_text_set_alloc(lhs->size + rhs->size, out);
163}
164
166 const lmmc_std_text_set_t* rhs,
168{
169 lmmc_status_t status = lmmc_std_text_set_binary_alloc(lhs, rhs, out);
170 if (status != LMMC_STATUS_OK) { return status; }
171 for (size_t i = 0; i < lhs->size; ++i) {
172 status = lmmc_std_text_set_append_unique(out, lhs->data[i]);
173 if (status != LMMC_STATUS_OK) {
174 goto fail;
175 }
176 }
177 for (size_t i = 0; i < rhs->size; ++i) {
178 status = lmmc_std_text_set_append_unique(out, rhs->data[i]);
179 if (status != LMMC_STATUS_OK) {
180 goto fail;
181 }
182 }
183 return LMMC_STATUS_OK;
184fail:
186 return status;
187}
188
190 const lmmc_std_text_set_t* rhs,
192{
193 lmmc_status_t status = lmmc_std_text_set_binary_alloc(lhs, rhs, out);
194 if (status != LMMC_STATUS_OK) { return status; }
195 for (size_t i = 0; i < lhs->size; ++i) {
196 if (lmmc_std_text_set_contains_value(rhs, lhs->data[i])) {
197 status = lmmc_std_text_set_append_unique(out, lhs->data[i]);
198 if (status != LMMC_STATUS_OK) {
199 goto fail;
200 }
201 }
202 }
203 return LMMC_STATUS_OK;
204fail:
206 return status;
207}
208
210 const lmmc_std_text_set_t* rhs,
212{
213 lmmc_status_t status = lmmc_std_text_set_binary_alloc(lhs, rhs, out);
214 if (status != LMMC_STATUS_OK) { return status; }
215 for (size_t i = 0; i < lhs->size; ++i) {
216 if (!lmmc_std_text_set_contains_value(rhs, lhs->data[i])) {
217 status = lmmc_std_text_set_append_unique(out, lhs->data[i]);
218 if (status != LMMC_STATUS_OK) {
219 goto fail;
220 }
221 }
222 }
223 return LMMC_STATUS_OK;
224fail:
226 return status;
227}
228
230 const lmmc_std_text_set_t* lhs,
231 const lmmc_std_text_set_t* rhs,
233{
234 lmmc_status_t status = lmmc_std_text_set_binary_alloc(lhs, rhs, out);
235 if (status != LMMC_STATUS_OK) { return status; }
236 for (size_t i = 0; i < lhs->size; ++i) {
237 if (!lmmc_std_text_set_contains_value(rhs, lhs->data[i])) {
238 status = lmmc_std_text_set_append_unique(out, lhs->data[i]);
239 if (status != LMMC_STATUS_OK) {
240 goto fail;
241 }
242 }
243 }
244 for (size_t i = 0; i < rhs->size; ++i) {
245 if (!lmmc_std_text_set_contains_value(lhs, rhs->data[i])) {
246 status = lmmc_std_text_set_append_unique(out, rhs->data[i]);
247 if (status != LMMC_STATUS_OK) {
248 goto fail;
249 }
250 }
251 }
252 return LMMC_STATUS_OK;
253fail:
255 return status;
256}
void * lmmc_memory_alloc(size_t size)
void * lmmc_memory_alloc_array_plus(size_t count, size_t extra, size_t element_size)
void lmmc_memory_free(void *pointer)
Private recoverable allocator for persistent LMMC ownership.
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_OK
@ LMMC_STATUS_ALLOCATION_FAILED
@ LMMC_STATUS_INVALID_ARGUMENT
lmmc_status_t lmmc_std_text_hash(const char *value, uint64_t *out)
为 LSR 规范的表键计算 UTF-8 文本哈希。
lmmc_status_t lmmc_std_text_set_symmetric_difference(const lmmc_std_text_set_t *lhs, const lmmc_std_text_set_t *rhs, lmmc_std_text_set_t *out)
lmmc_status_t lmmc_std_text_equal(const char *lhs, const char *rhs, int *out)
按 LSR 规范的表键语义比较 UTF-8 文本值。
lmmc_status_t lmmc_std_text_set_union(const lmmc_std_text_set_t *lhs, const lmmc_std_text_set_t *rhs, lmmc_std_text_set_t *out)
lmmc_status_t lmmc_std_text_set_difference(const lmmc_std_text_set_t *lhs, const lmmc_std_text_set_t *rhs, lmmc_std_text_set_t *out)
lmmc_status_t lmmc_std_text_set_make(const char *const *values, size_t count, lmmc_std_text_set_t *out)
构造去重的文本集合。
void lmmc_std_text_set_destroy(lmmc_std_text_set_t *set)
lmmc_status_t lmmc_std_text_set_intersection(const lmmc_std_text_set_t *lhs, const lmmc_std_text_set_t *rhs, lmmc_std_text_set_t *out)
lmmc_status_t lmmc_std_text_set_contains(const lmmc_std_text_set_t *set, const char *value, int *out)
lmmc_status_t lmmc_std_text_set_subset(const lmmc_std_text_set_t *lhs, const lmmc_std_text_set_t *rhs, int *out)