diff options
| -rw-r--r-- | README.md | 126 | ||||
| -rw-r--r-- | examples/README.md | 14 | ||||
| -rw-r--r-- | examples/advanced.c | 16 | ||||
| -rw-r--r-- | examples/benchmark.c | 4 | ||||
| -rw-r--r-- | examples/bits.c | 4 | ||||
| -rw-r--r-- | examples/complex.c | 18 | ||||
| -rw-r--r-- | examples/demos.c | 38 | ||||
| -rw-r--r-- | examples/geek1.c | 6 | ||||
| -rw-r--r-- | examples/geek2.c | 12 | ||||
| -rw-r--r-- | examples/geek3.c | 8 | ||||
| -rw-r--r-- | examples/geek4.c | 20 | ||||
| -rw-r--r-- | examples/geek5.c | 14 | ||||
| -rw-r--r-- | examples/geek6.c | 4 | ||||
| -rw-r--r-- | examples/geek7.c | 12 | ||||
| -rw-r--r-- | examples/heap.c | 6 | ||||
| -rw-r--r-- | examples/inits.c | 16 | ||||
| -rw-r--r-- | examples/list.c | 4 | ||||
| -rw-r--r-- | examples/mapmap.c | 8 | ||||
| -rw-r--r-- | examples/prime.c | 2 | ||||
| -rw-r--r-- | examples/priority.c | 6 | ||||
| -rw-r--r-- | examples/rngbirthday.c | 10 | ||||
| -rw-r--r-- | stc/carray.h | 78 | ||||
| -rw-r--r-- | stc/cbitset.h | 64 | ||||
| -rw-r--r-- | stc/clist.h | 146 | ||||
| -rw-r--r-- | stc/cmap.h | 206 | ||||
| -rw-r--r-- | stc/coption.h | 173 | ||||
| -rw-r--r-- | stc/cstr.h | 132 | ||||
| -rw-r--r-- | stc/cvec.h | 96 | ||||
| -rw-r--r-- | stc/cvecpq.h | 46 |
29 files changed, 731 insertions, 558 deletions
@@ -19,13 +19,13 @@ in *O*(1). Also contains various *splice* functions and (merge) *sort*. The usage of the containers is similar to the C++ standard containers, so it should be easier for those who are familiar with them.
-All containers mentioned above, except for cstr_t are generic (similar to templates in C++). A simple example:
+All containers mentioned above, except for CStr are generic (similar to templates in C++). A simple example:
```
#include <stc/cvec.h>
-declare_cvec(i, int);
+declare_CVec(i, int);
int main(void) {
- cvec_i vec = cvec_init;
+ CVec_i vec = cvec_init;
cvec_i_pushBack(&vec, 42);
cvec_i_destroy(&vec);
}
@@ -52,17 +52,17 @@ Because it is headers only, files can simply be included in your program. The fu #include <stc/cmap.h>
#include <stc/cvec.h>
-declare_cmap(ii, int, int); // map
-declare_cmap(ix, int64_t); // set
-declare_cvec(i, int);
+declare_CMap(ii, int, int); // map
+declare_CMap(ix, int64_t); // set
+declare_CVec(i, int);
...
```
Performance
-----------
-This library is very efficent. Containers have templated intrusive elements. One of the most performance critical containers is the **cmap / cset**. Luckily, cmap is among the fastest C/C++ map implementations available: **examples/benchmark.c** compiled with g++ v9.2.0 -O3 on windows (the results are similar with VC++ and g++ on linux):
+This library is very efficent. Containers have templated intrusive elements. One of the most performance critical containers is the **CMap / CSet**. Luckily, CMap is among the fastest C/C++ map implementations available: **examples/benchmark.c** compiled with g++ v9.2.0 -O3 on windows (the results are similar with VC++ and g++ on linux):
-**CMAP**=*cmap*, KMAP=*khash*, UMAP=*std::unordered_map*, BMAP=*ska::bytell_hash_map*, FMAP=*ska::flat_hash_map*, RMAP=*robin_hood::unordered_map*
+**CMAP**=*CMap*, KMAP=*khash*, UMAP=*std::unordered_map*, BMAP=*ska::bytell_hash_map*, FMAP=*ska::flat_hash_map*, RMAP=*robin_hood::unordered_map*
```
Random keys are in range [0, 2^20):
map<uint64_t, uint64_t>: 7000000 repeats of Insert random key + (try to) remove a different random key:
@@ -93,49 +93,49 @@ Memory efficiency -----------------
The containers are memory efficent, i.e. they occupy as little memory as practical possible.
-- **cstr**, **cvec**: Representaion: one pointer size. The size and capacity is stored as part of the heap allocation that also holds the vector elements.
-- **clist**: Representation: one pointer size. Each node allocates block storing value and next pointer.
-- **cset**: Representation: 4 pointers size. cset uses one table of keys, and one table of "used/hash-value", which occupies only one byte per bucket.
-- **cmap**: Same as cset, but this uses a table of (key, value) pairs, not only keys.
-- **carray**: carray1, carray2 and carray3. Representation: One pointers, plus 1, 2, or 3 size_t variables to store dimensions. Elements are stored as one block of heap memory.
+- **CStr**, **CVec**: Representaion: one pointer size. The size and capacity is stored as part of the heap allocation that also holds the vector elements.
+- **CList**: Representation: one pointer size. Each node allocates block storing value and next pointer.
+- **CSet**: Representation: 4 pointers size. CSet uses one table of keys, and one table of "used/hash-value", which occupies only one byte per bucket.
+- **CMap**: Same as CSet, but this uses a table of (key, value) pairs, not only keys.
+- **CArray**: CArray1, CArray2 and CArray3. Representation: One pointers, plus 1, 2, or 3 size_t variables to store dimensions. Elements are stored as one block of heap memory.
-cmap, cset and cvec discussion
+CMap, CSet and CVec discussion
----------------------------
-**cmap/cset** are the most complex of the containers (although, currently only ~370 lines of code). It uses open hashing, but does not rely on power-of-two size table, nor prime number lengths, and it does not have tombstone buckets. It is still among the fastest hash-tables, as shown above. The default max load-factor is 0.85, and it shrinks (and rehashes) when load-factor goes below 0.15, by default (can be set per hash container).
+**CMap/CSet** are the most complex of the containers (although, currently only ~370 lines of code). It uses open hashing, but does not rely on power-of-two size table, nor prime number lengths, and it does not have tombstone buckets. It is still among the fastest hash-tables, as shown above. The default max load-factor is 0.85, and it shrinks (and rehashes) when load-factor goes below 0.15, by default (can be set per hash container).
-You may customize the destroy-, hash- and equals- function. It also supports a few other arguments in the declare-statement that allows to define a convertion from a raw/literal type to the key-type specified. This is handy when e.g. having cstr_t as key, as it enables the usage of string literals as key in *put() and *get() functions, instead of requering a constructed cstr_t. Without it, you would have to write:
+You may customize the destroy-, hash- and equals- function. It also supports a few other arguments in the declare-statement that allows to define a convertion from a raw/literal type to the key-type specified. This is handy when e.g. having CStr as key, as it enables the usage of string literals as key in *put() and *get() functions, instead of requering a constructed CStr. Without it, you would have to write:
```
-declare_cmap(si, cstr_t, int);
+declare_CMap(si, CStr, int);
...
cmap_si_put(&map, cstr_make("mykey"), 12);
```
but the main incovenience is with lookup:
```
-cstr_t lookup = cstr_make("mykey");
+CStr lookup = cstr_make("mykey");
int x = cmap_si_get(&map, lookup)->value;
cstr_destroy(&lookup);
```
-To avoid this, use *declare_cmap_str()*:
+To avoid this, use *declare_CMap_str()*:
```
-declare_cmap_str(si, int);
+declare_CMap_str(si, int);
...
-cmap_si map = cmap_init;
-cmap_si_put(&map, "mykey", 12); // constructs a cstr_t key from the const char* internally.
+CMap_si map = cmap_init;
+cmap_si_put(&map, "mykey", 12); // constructs a CStr key from the const char* internally.
int x = cmap_si_get(&map, "mykey")->value; // no allocation of string key happens here.
cmap_si_destroy(&map);
```
An alternative would be to use *char* * as key type, but you would have to manage the memory of the hash char* keys yourself.
-Note that this customization is also available for **cvec**, but only affects the *find()* function currently. See *declare_cvec_str()*.
+Note that this customization is also available for **CVec**, but only affects the *find()* function currently. See *declare_CVec_str()*.
Also look at **examples/advanced.c**, it demonstrates how to use a custom struct as a hash map key, using the feature mentioned.
Example usages
--------------
The first example has a very complex nested container type, which demonstrates the power of this library. Look at the simpler examples below to understand it better. The example adds an element into the data structure, and then accesses it. The type used, with c++ template syntax is:
-**cmapMap**< **cstr_t**, **cmapMap**< *int*, **clist**< **carray2**< *float* >>>>
+**CMapMap**< **CStr**, **CMapMap**< *int*, **CList**< **CArray2**< *float* >>>>
-Note: The *cmap_sm_destroy(&theMap)* call below, will destroy all the nested containers including the memory allocated for cstr_t keys in theMap object.
+Note: The *cmap_sm_destroy(&theMap)* call below, will destroy all the nested containers including the memory allocated for CStr keys in theMap object.
```
#include <stc/cstr.h>
#include <stc/cmap.h>
@@ -144,20 +144,20 @@ Note: The *cmap_sm_destroy(&theMap)* call below, will destroy all the nested con void verify_destroy(float* v) {printf("destroy %g\n", *v);}
-declare_carray(f, float, verify_destroy); // you should omit the last argument - float type need no destroy.
-declare_clist(t2, carray2_f, carray2_f_destroy, c_noCompare);
-declare_cmap(il, int, clist_t2, clist_t2_destroy);
-declare_cmap_str(sm, cmap_il, cmap_il_destroy);
+declare_CArray(f, float, verify_destroy); // you should omit the last argument - float type need no destroy.
+declare_CList(t2, CArray2_f, carray2_f_destroy, c_noCompare);
+declare_CMap(il, int, CList_t2, clist_t2_destroy);
+declare_CMap_str(sm, CMap_il, cmap_il_destroy);
int main() {
int xdim = 4, ydim = 6;
int x = 2, y = 5, entry = 42;
- cmap_sm theMap = cmap_init;
+ CMap_sm theMap = cmap_init;
{
// Construct.
- carray2_f table = carray2_f_make(xdim, ydim, 0.f);
- clist_t2 tableList = clist_init;
- cmap_il listMap = cmap_init;
+ CArray2_f table = carray2_f_make(xdim, ydim, 0.f);
+ CList_t2 tableList = clist_init;
+ CMap_il listMap = cmap_init;
// Put in some data.
carray2_f_data(table, x)[y] = 3.1415927; // table[x][y]
@@ -167,18 +167,18 @@ int main() { }
// Access the data entry
- carray2_f table = clist_back(cmap_il_get(&cmap_sm_get(&theMap, "First")->value, entry)->value);
+ CArray2_f table = clist_back(cmap_il_get(&cmap_sm_get(&theMap, "First")->value, entry)->value);
printf("value is: %f\n", carray2_f_value(table, x, y));
cmap_sm_destroy(&theMap); // free up the whole shebang!
}
```
-**cstr_t**
+**CStr**
```
#include <stc/cstr.h>
int main() {
- cstr_t s1 = cstr_make("one-nine-three-seven-five");
+ CStr s1 = cstr_make("one-nine-three-seven-five");
printf("%s.\n", s1.str);
cstr_insert(&s1, 3, "-two");
@@ -197,17 +197,17 @@ int main() { printf("append: %s\n", s1.str);
cstr_destroy(&s1);
- cstr_t s2 = cstr_from("Index %d: %f", 123, 4.56);
+ CStr s2 = cstr_from("Index %d: %f", 123, 4.56);
cstr_destroy(&s2);
}
```
-**cvec** of *int64_t*
+**CVec** of *int64_t*
```
#include <stc/cvec.h>
-declare_cvec(ix, int64_t); // ix is just an example tag name, use anything without underscore.
+declare_CVec(ix, int64_t); // ix is just an example tag name, use anything without underscore.
int main() {
- cvec_ix bignums = cvec_init; // = (cvec_ix) cvec_init; if initializing after declaration.
+ CVec_ix bignums = cvec_init; // = (CVec_ix) cvec_init; if initializing after declaration.
cvec_ix_reserve(&bignums, 100);
for (size_t i = 0; i<100; ++i)
cvec_ix_pushBack(&bignums, i * i * i);
@@ -219,14 +219,14 @@ int main() { cvec_ix_destroy(&bignums);
}
```
-**cvec** of *cstr_t*
+**CVec** of *CStr*
```
#include <stc/cstr.h>
#include <stc/cvec.h>
-declare_cvec_str();
+declare_CVec_str();
int main() {
- cvec_str names = cvec_init;
+ CVec_str names = cvec_init;
cvec_str_pushBack(&names, cstr_make("Mary"));
cvec_str_pushBack(&names, cstr_make("Joe"));
cstr_assign(&names.data[1], cstr_make("Jake")); // replace Joe
@@ -235,14 +235,14 @@ int main() { cvec_str_destroy(&names);
}
```
-**cmap** of *int -> int*
+**CMap** of *int -> int*
```
#include <stdio.h>
#include <stc/cmap.h>
-declare_cmap(ii, int, int);
+declare_CMap(ii, int, int);
int main() {
- cmap_ii nums = cmap_init;
+ CMap_ii nums = cmap_init;
cmap_ii_put(&nums, 8, 64);
cmap_ii_put(&nums, 11, 121);
@@ -250,14 +250,14 @@ int main() { cmap_ii_destroy(&nums);
}
```
-**cset** of *cstr_t*
+**CSet** of *CStr*
```
#include <stc/cstr.h>
#include <stc/cmap.h>
-declare_cset_str(); // cstr_t set. See the discussion above.
+declare_CSet_str(); // CStr set. See the discussion above.
int main() {
- cset_str words = cset_init;
+ CSet_str words = cset_init;
cset_str_put(&words, "Hello");
cset_str_put(&words, "Groovy");
cset_str_erase(&words, "Hello");
@@ -268,37 +268,37 @@ int main() { cset_str_destroy(&words);
}
```
-**cmap** of *cstr_t -> cstr_t*. Temporary cstr_t values are created by *cstr_make()*, and moved into the container
+**CMap** of *CStr -> CStr*. Temporary CStr values are created by *cstr_make()*, and moved into the container
```
#include <stc/cstr.h>
#include <stc/cmap.h>
-declare_cmap_str(ss, cstr_t, cstr_destroy);
+declare_CMap_str(ss, CStr, cstr_destroy);
int main() {
- cmap_ss table = cmap_init;
+ CMap_ss table = cmap_init;
cmap_ss_put(&table, "Make", cstr_make("my"));
cmap_ss_put(&table, "Sunny", cstr_make("day"));
printf("Sunny: %s\n", cmap_ss_get(table, "Sunny")->value.str);
cmap_ss_erase(&table, "Make");
printf("size %d\n", cmap_size(table));
- cmap_ss_destroy(&table); // frees key and value cstrs, and hash table (cvec).
+ cmap_ss_destroy(&table); // frees key and value CStrs, and hash table (CVec).
}
```
-**clist** of *int64_t*. Similar to c++ *std::forward_list*, but can do both *pushFront()* and *pushBack()*.
+**CList** of *int64_t*. Similar to c++ *std::forward_list*, but can do both *pushFront()* and *pushBack()*.
```
#include <stdio.h>
#include <time.h>
#include <stc/clist.h>
#include <stc/crandom.h>
-declare_clist(i, uint64_t);
+declare_CList(i, uint64_t);
int main() {
- clist_i list = clist_init;
+ CList_i list = clist_init;
int N = 2000000, n;
- crandom64_t rng = crandom64_seed(time(NULL));
- for (int i=0; i<N; ++i) // two million random numbers
- clist_i_pushBack(&list, crandom64(&rng));
+ sfc64_t rng = sfc64_seed(time(NULL));
+ for (int i=0; i<N; ++i) // one million random numbers
+ clist_i_pushBack(&list, sfc64_rand(&rng));
n = 0;
c_foreach (i, clist_i, list)
if (++n % (N/50) == 0) printf("%10d: %zu\n", n, i.item->value);
@@ -312,17 +312,17 @@ int main() { clist_i_destroy(&list);
}
```
-**carray**. 1D, 2D and 3D arrays, heap allocated in one memory block. *carray3* can have sub-array "views" of *carray2* and *carray1* etc., as shown in the following example.
+**CArray**. 1D, 2D and 3D arrays, heap allocated in one memory block. *CArray3* can have sub-array "views" of *CArray2* and *CArray1* etc., as shown in the following example.
```
#include <stdio.h>
#include <stc/carray.h>
-declare_carray(f, float);
+declare_CArray(f, float);
int main()
{
- carray3_f a3 = carray3_f_make(30, 20, 10, 0.f);
+ CArray3_f a3 = carray3_f_make(30, 20, 10, 0.f);
carray3_f_data(a3, 5, 4)[3] = 10.2f; // a3[5][4][3]
- carray2_f a2 = carray3_f_at(a3, 5); // sub-array reference (no data copy).
+ CArray2_f a2 = carray3_f_at(a3, 5); // sub-array reference (no data copy).
printf("%f\n", carray2_f_value(a2, 4, 3)); // readonly lookup a2[4][3] (=10.2f)
printf("%f\n", carray2_f_data(a2, 4)[3]); // same, but this is writable.
diff --git a/examples/README.md b/examples/README.md index e222f8bc..4d43a7d2 100644 --- a/examples/README.md +++ b/examples/README.md @@ -6,7 +6,7 @@ Contains various examples and benchmarks. advanced.c Example
------------------
-This demonstrates how to customize hash **cmap** with a user-defined key-type. You need to define two things:
+This demonstrates how to customize hash **CMap** with a user-defined key-type. You need to define two things:
1. A hash function; calculates the hash value given an object of the key-type.
@@ -40,8 +40,8 @@ int vikingvw_equals(const VikingVw* x, const VikingVw* y) { And the Viking data struct:
```
typedef struct Viking {
- cstr_t name;
- cstr_t country;
+ CStr name;
+ CStr country;
} Viking;
@@ -58,9 +58,9 @@ Viking viking_fromVw(VikingVw vw) { }
```
-With this in place, we use the full declare_cmap() macro to define {Viking -> int} hash map type:
+With this in place, we use the full declare_CMap() macro to define {Viking -> int} hash map type:
```
-declare_cmap(vk, Viking, int, c_defaultDestroy, vikingvw_equals, vikingvw_hash,
+declare_CMap(vk, Viking, int, c_defaultDestroy, vikingvw_equals, vikingvw_hash,
viking_destroy, VikingVw, viking_getVw, viking_fromVw);
```
CMap_vk uses vikingvw_hash() for hash value calculations, and vikingvw_equals() for equality test. cmap_vk_destroy() will free all memory allocated for Viking keys and the hash table values.
@@ -68,13 +68,13 @@ Finally, the demo: ```
int main()
{
- cmap_vk vikings = cmap_init;
+ CMap_vk vikings = cmap_init;
// emplace constructs the keys
cmap_vk_put(&vikings, (VikingVw) {"Einar", "Norway"}, 20);
cmap_vk_put(&vikings, (VikingVw) {"Olaf", "Denmark"}, 24);
cmap_vk_put(&vikings, (VikingVw) {"Harald", "Iceland"}, 12);
- cmapentry_vk* e = cmap_vk_get(&vikings, (VikingVw) {"Einar", "Norway"});
+ CMapEntry_vk* e = cmap_vk_get(&vikings, (VikingVw) {"Einar", "Norway"});
e->value += 5; // update
c_foreach (k, cmap_vk, vikings) {
diff --git a/examples/advanced.c b/examples/advanced.c index b5481f94..68ddc9ef 100644 --- a/examples/advanced.c +++ b/examples/advanced.c @@ -1,5 +1,5 @@ /* - * To be able to use cmap with a user-defined key-type, you need to define two things: + * To be able to use CMap with a user-defined key-type, you need to define two things: * 1. A hash function; this must be a function that calculates the hash value given * an object of the key-type. * 2. A comparison function for equality. @@ -34,8 +34,8 @@ int vikingvw_equals(const VikingVw* x, const VikingVw* y) { // Viking data struct ----------------------- typedef struct Viking { - cstr_t name; - cstr_t country; + CStr name; + CStr country; } Viking; @@ -52,25 +52,25 @@ Viking viking_fromVw(VikingVw vw) { } -// Using the full declare_cmap() macro to define [Viking -> int] hash map type: -declare_cmap(vk, Viking, int, c_defaultDestroy, vikingvw_equals, vikingvw_hash, +// Using the full declare_CMap() macro to define [Viking -> int] hash map type: +declare_CMap(vk, Viking, int, c_defaultDestroy, vikingvw_equals, vikingvw_hash, viking_destroy, VikingVw, viking_getVw, viking_fromVw); -// cmap_vk uses vikingvw_hash() for hash value calculations, and vikingvw_equals() for equality test. +// CMap_vk uses vikingvw_hash() for hash value calculations, and vikingvw_equals() for equality test. // cmap_vk_destroy() will free all memory allocated for Viking keys and the hash table values. // Main ---------------------------- int main() { - cmap_vk vikings = cmap_init; + CMap_vk vikings = cmap_init; c_push(&vikings, cmap_vk, c_items( {{"Einar", "Norway"}, 20}, {{"Olaf", "Denmark"}, 24}, {{"Harald", "Iceland"}, 12}, )); - cmapentry_vk* e = cmap_vk_find(&vikings, (VikingVw) {"Einar", "Norway"}); + CMapEntry_vk* e = cmap_vk_find(&vikings, (VikingVw) {"Einar", "Norway"}); e->value += 5; // update c_foreach (k, cmap_vk, vikings) { diff --git a/examples/benchmark.c b/examples/benchmark.c index 8b9f33c2..c9a82d6d 100644 --- a/examples/benchmark.c +++ b/examples/benchmark.c @@ -14,7 +14,7 @@ // Visual Studio: compile with -TP to force C++: cl -TP -EHsc -O2 benchmark.c
-declare_cmap(ii, int64_t, int64_t, c_defaultDestroy, c_defaultEquals, c_fibonacciHash64);
+declare_CMap(ii, int64_t, int64_t, c_defaultDestroy, c_defaultEquals, c_fibonacciHash64);
KHASH_MAP_INIT_INT64(ii, uint64_t)
@@ -26,7 +26,7 @@ crandom64_t rng; #define RAND(N) (crandom64(&rng) & ((1 << N) - 1))
-#define CMAP_SETUP(tag, Key, Value) cmap_##tag map = cmap_init \
+#define CMAP_SETUP(tag, Key, Value) CMap_##tag map = cmap_init \
; cmap_##tag##_setLoadFactors(&map, maxLoadFactor, 0.0)
#define CMAP_PUT(tag, key, val) cmap_##tag##_put(&map, key, val)->value
#define CMAP_ERASE(tag, key) cmap_##tag##_erase(&map, key)
diff --git a/examples/bits.c b/examples/bits.c index 7c048c80..16adaf96 100644 --- a/examples/bits.c +++ b/examples/bits.c @@ -2,7 +2,7 @@ #include <stc/cbitset.h>
int main() {
- cbitset_t set = cbitset_make(23, true);
+ CBitset set = cbitset_make(23, true);
printf("count %zu, %zu\n", cbitset_count(set), set.size);
cbitset_reset(&set, 9);
cbitset_resize(&set, 43, false);
@@ -21,7 +21,7 @@ int main() { printf("%d", cbitset_test(set, i));
puts("");
- cbitset_t s2 = cbitset_from(set);
+ CBitset s2 = cbitset_from(set);
cbitset_flipAll(&s2);
cbitset_set(&s2, 16);
cbitset_set(&s2, 17);
diff --git a/examples/complex.c b/examples/complex.c index 87caaa4e..40dc9722 100644 --- a/examples/complex.c +++ b/examples/complex.c @@ -5,22 +5,22 @@ void check_destroy(float* v) {printf("destroy %g\n", *v);}
-declare_carray(f, float, check_destroy); // normally omit the last argument - float type need no destroy.
-declare_clist(t2, carray2f, carray2f_destroy, c_noCompare);
-declare_cmap(il, int, clist_t2, clist_t2_destroy);
-declare_cmap_str(sm, cmap_il, cmap_il_destroy);
+declare_CArray(f, float, check_destroy); // normally omit the last argument - float type need no destroy.
+declare_CList(t2, CArray2f, carray2f_destroy, c_noCompare);
+declare_CMap(il, int, CList_t2, clist_t2_destroy);
+declare_CMap_str(sm, CMap_il, cmap_il_destroy);
int main() {
int xdim = 4, ydim = 6;
int x = 1, y = 5, tableKey = 42;
const char* strKey = "first";
- cmap_sm theMap = cmap_init;
+ CMap_sm theMap = cmap_init;
{ // Construct.
- carray2f table = carray2f_make(ydim, xdim, 0.f);
+ CArray2f table = carray2f_make(ydim, xdim, 0.f);
printf("table: (%zu, %zu)\n", carray2_ydim(table), carray2_xdim(table));
- clist_t2 tableList = clist_init;
- cmap_il listMap = cmap_init;
+ CList_t2 tableList = clist_init;
+ CMap_il listMap = cmap_init;
// Put in some data.
carray2f_data(table, y)[x] = 3.1415927; // table[y][x]
@@ -29,7 +29,7 @@ int main() { cmap_sm_put(&theMap, strKey, listMap);
}
{ // Access the data entry
- carray2f table = clist_back(cmap_il_find(&cmap_sm_find(&theMap, strKey)->value, tableKey)->value);
+ CArray2f table = clist_back(cmap_il_find(&cmap_sm_find(&theMap, strKey)->value, tableKey)->value);
printf("value (%d, %d) is: %f\n", y, x, carray2f_value(table, y, x));
}
diff --git a/examples/demos.c b/examples/demos.c index 3a29f7d6..03d8a21d 100644 --- a/examples/demos.c +++ b/examples/demos.c @@ -8,7 +8,7 @@ void stringdemo1()
{
printf("\nSTRINGDEMO1\n");
- cstr_t cs = cstr_make("one-nine-three-seven-five");
+ CStr cs = cstr_make("one-nine-three-seven-five");
printf("%s.\n", cs.str);
cstr_insert(&cs, 3, "-two");
@@ -33,12 +33,12 @@ void stringdemo1() }
-declare_cvec(ix, int64_t); // ix is just an example tag name.
+declare_CVec(ix, int64_t); // ix is just an example tag name.
void vectordemo1()
{
printf("\nVECTORDEMO1\n");
- cvec_ix bignums = cvec_init; // = (cvec_ix) cvec_init; if initializing after declaration.
+ CVec_ix bignums = cvec_init; // = (CVec_ix) cvec_init; if initializing after declaration.
cvec_ix_reserve(&bignums, 100);
for (size_t i = 0; i<=100; ++i)
cvec_ix_pushBack(&bignums, i * i * i);
@@ -54,12 +54,12 @@ void vectordemo1() -declare_cvec(cs, cstr_t, cstr_destroy, cstr_compare); // supply inline destructor of values
+declare_CVec(cs, CStr, cstr_destroy, cstr_compare); // supply inline destructor of values
void vectordemo2()
{
printf("\nVECTORDEMO2\n");
- cvec_cs names = cvec_init;
+ CVec_cs names = cvec_init;
cvec_cs_pushBack(&names, cstr_make("Mary"));
cvec_cs_pushBack(&names, cstr_make("Joe"));
cvec_cs_pushBack(&names, cstr_make("Chris"));
@@ -72,12 +72,12 @@ void vectordemo2() cvec_cs_destroy(&names);
}
-declare_clist(ix, int);
+declare_CList(ix, int);
void listdemo1()
{
printf("\nLISTDEMO1\n");
- clist_ix nums = clist_init, nums2 = clist_init;
+ CList_ix nums = clist_init, nums2 = clist_init;
for (int i = 0; i < 10; ++i)
clist_ix_pushBack(&nums, i);
for (int i = 100; i < 110; ++i)
@@ -99,12 +99,12 @@ void listdemo1() clist_ix_destroy(&nums);
}
-declare_cset(i, int);
+declare_CSet(i, int);
void setdemo1()
{
printf("\nSETDEMO1\n");
- cset_i nums = cset_init;
+ CSet_i nums = cset_init;
cset_i_put(&nums, 8);
cset_i_put(&nums, 11);
@@ -114,12 +114,12 @@ void setdemo1() }
-declare_cmap(ii, int, int);
+declare_CMap(ii, int, int);
void mapdemo1()
{
printf("\nMAPDEMO1\n");
- cmap_ii nums = cmap_init;
+ CMap_ii nums = cmap_init;
cmap_ii_put(&nums, 8, 64);
cmap_ii_put(&nums, 11, 121);
@@ -128,12 +128,12 @@ void mapdemo1() }
-declare_cmap_str(si, int); // Shorthand macro for the general declare_cmap expansion.
+declare_CMap_str(si, int); // Shorthand macro for the general declare_CMap expansion.
void mapdemo2()
{
printf("\nMAPDEMO2\n");
- cmap_si nums = cmap_init;
+ CMap_si nums = cmap_init;
cmap_si_put(&nums, "Hello", 64);
cmap_si_put(&nums, "Groovy", 121);
cmap_si_put(&nums, "Groovy", 200); // overwrite previous
@@ -150,16 +150,16 @@ void mapdemo2() }
-declare_cmap_str(ss, cstr_t, cstr_destroy);
+declare_CMap_str(ss, CStr, cstr_destroy);
void mapdemo3()
{
printf("\nMAPDEMO3\n");
- cmap_ss table = cmap_init;
+ CMap_ss table = cmap_init;
cmap_ss_put(&table, "Map", cstr_make("test"));
cmap_ss_put(&table, "Make", cstr_make("my"));
cmap_ss_put(&table, "Sunny", cstr_make("day"));
- cmapentry_ss *e = cmap_ss_find(&table, "Make");
+ CMapEntry_ss *e = cmap_ss_find(&table, "Make");
c_foreach (i, cmap_ss, table)
printf("entry: %s: %s\n", i.item->key.str, i.item->value.str);
printf("size %zu: remove: Make: %s\n", cmap_size(table), e->value.str);
@@ -173,14 +173,14 @@ void mapdemo3() }
-declare_carray(f, float);
+declare_CArray(f, float);
void arraydemo1()
{
printf("\nARRAYDEMO1\n");
- carray3f a3 = carray3f_make(30, 20, 10, 0.f);
+ CArray3f a3 = carray3f_make(30, 20, 10, 0.f);
carray3f_data(a3, 5, 4)[3] = 10.2f; // a3[5][4][3]
- carray2f a2 = carray3f_at(a3, 5); // sub-array reference (no data copy).
+ CArray2f a2 = carray3f_at(a3, 5); // sub-array reference (no data copy).
printf("a3: %zu: (%zu, %zu, %zu) = %zu\n", sizeof(a3), carray3_xdim(a3), carray3_ydim(a3), carray3_zdim(a3), carray3_size(a3));
printf("a2: %zu: (%zu, %zu) = %zu\n", sizeof(a2), carray2_xdim(a2), carray2_ydim(a2), carray2_size(a2));
diff --git a/examples/geek1.c b/examples/geek1.c index 1df74024..f8471122 100644 --- a/examples/geek1.c +++ b/examples/geek1.c @@ -12,14 +12,14 @@ int a[] = { 1, 2, 2, 3, 2, 4, 10 }; #include <stdio.h>
#include <stc/cmap.h>
-declare_cmap(ii, int, int);
+declare_CMap(ii, int, int);
// Function to maximize the number of pairs
int findMaximumPairs(int a[], int n, int k)
{
// Hash-table
- cmap_ii hash = cmap_init;
+ CMap_ii hash = cmap_init;
for (int i = 0; i < n; i++) {
cmap_ii_insert(&hash, a[i] % k, 0)->value++;
}
@@ -38,7 +38,7 @@ int findMaximumPairs(int a[], int n, int k) int first = it.item->key;
int second = k - it.item->key;
- cmapentry_ii *hf = cmap_ii_find(&hash, first),
+ CMapEntry_ii *hf = cmap_ii_find(&hash, first),
*hs = cmap_ii_insert(&hash, second, 0);
// Check for minimal occurrence
if (hf->value < hs->value) {
diff --git a/examples/geek2.c b/examples/geek2.c index 988f1f98..1c2f0c05 100644 --- a/examples/geek2.c +++ b/examples/geek2.c @@ -3,15 +3,15 @@ #include <stc/cmap.h>
#include <stc/cstr.h>
-declare_cmap_str(ss, cstr_t, cstr_destroy);
-declare_cset_str();
+declare_CMap_str(ss, CStr, cstr_destroy);
+declare_CSet_str();
int main()
{
// Lets use an explicit type signature (which would
- // be `cmap<String, String>` in this example).
- cmap_ss book_reviews = cmap_init;
- cset_str set = cset_init;
+ // be `CMap<String, String>` in this example).
+ CMap_ss book_reviews = cmap_init;
+ CSet_str set = cset_init;
cset_str_put(&set, "Hello");
cset_str_put(&set, "You");
cset_str_put(&set, "Tube");
@@ -50,7 +50,7 @@ int main() // Look up the values associated with some keys.
const char* to_find[] = {"Pride and Prejudice", "Alice's Adventure in Wonderland", NULL};
for (const char** book = to_find; *book; ++book) {
- cmapentry_ss* review = cmap_ss_find(&book_reviews, *book);
+ CMapEntry_ss* review = cmap_ss_find(&book_reviews, *book);
if (review) printf("%s: %s\n", *book, review->value.str);
else printf("%s is unreviewed.\n", *book);
}
diff --git a/examples/geek3.c b/examples/geek3.c index b8de97c8..f6f8942a 100644 --- a/examples/geek3.c +++ b/examples/geek3.c @@ -3,12 +3,12 @@ #include <stc/cmap.h>
#include <stc/cstr.h>
-declare_cmap_str(si, int);
-declare_cmap_str(ss, cstr_t, cstr_destroy);
+declare_CMap_str(si, int);
+declare_CMap_str(ss, CStr, cstr_destroy);
int main ()
{
- cmap_si mymap = cmap_init;
+ CMap_si mymap = cmap_init;
cmap_si_put(&mymap, "Mars", 3000);
cmap_si_put(&mymap, "Saturn", 60000);
cmap_si_put(&mymap, "Jupiter", 70000);
@@ -28,7 +28,7 @@ int main () puts("------------------------");
// Create an unordered_map of three strings (that map to strings)
- cmap_ss u = cmap_init;
+ CMap_ss u = cmap_init;
cmap_ss_put(&u, "RED", cstr_make("#FF0000"));
cmap_ss_put(&u, "GREEN", cstr_make("#00FF00"));
cmap_ss_put(&u, "BLUE", cstr_make("#0000FF"));
diff --git a/examples/geek4.c b/examples/geek4.c index 87f9b919..e7522bb3 100644 --- a/examples/geek4.c +++ b/examples/geek4.c @@ -37,19 +37,19 @@ Efficient Approach: For all the words of the first sentence, we can check if it #include <stc/cvec.h>
#include <stc/cstr.h>
-declare_cvec_str();
-declare_cmap_str(sb, bool);
-declare_cvec(sb, cmapentry_sb, cmapentry_sb_destroy, c_noCompare);
+declare_CVec_str();
+declare_CMap_str(sb, bool);
+declare_CVec(sb, CMapEntry_sb, cmapentry_sb_destroy, c_noCompare);
// Function to return the count of common words
// in all the sentences
-int commonWords(cvec_str S)
+int commonWords(CVec_str S)
{
int m, n, i, j;
// To store all the words of first string
- cvec_sb ans = cvec_init;
+ CVec_sb ans = cvec_init;
// m will store number of strings in given vector
m = cvec_size(S);
@@ -59,8 +59,8 @@ int commonWords(cvec_str S) // Extract all words of first string and store it in ans
while (i < cstr_size(S.data[0])) {
// To store separate words
- cstr_t word = cstr_init;
- cmapentry_sb tmp = {cstr_init, false};
+ CStr word = cstr_init;
+ CMapEntry_sb tmp = {cstr_init, false};
while (i < cstr_size(S.data[0]) && S.data[0].str[i] != ' ') {
cstr_pushBack(&word, S.data[0].str[i]);
@@ -85,11 +85,11 @@ int commonWords(cvec_str S) for (j = 1; j < m; j++) {
// It will be used to check if a word is present
// in a particuler string
- cmap_sb has = cmap_init;
+ CMap_sb has = cmap_init;
i = 0;
while (i < cstr_size(S.data[j])) {
- cstr_t word = cstr_init;
+ CStr word = cstr_init;
while (i < cstr_size(S.data[j]) && S.data[j].str[i] != ' ') {
cstr_pushBack(&word, S.data[j].str[i]);
i++;
@@ -136,7 +136,7 @@ int commonWords(cvec_str S) // Driver code
int main()
{
- cvec_str S = cvec_init;
+ CVec_str S = cvec_init;
cvec_str_pushBack(&S, cstr_make("there is a cow"));
cvec_str_pushBack(&S, cstr_make("cow is our mother"));
cvec_str_pushBack(&S, cstr_make("cow gives us milk and milk is sweet"));
diff --git a/examples/geek5.c b/examples/geek5.c index b1e2f2b9..546cb278 100644 --- a/examples/geek5.c +++ b/examples/geek5.c @@ -21,24 +21,24 @@ Output: 0 #include <stc/cvec.h>
#include <stc/cstr.h>
-declare_cvec(i, int);
-declare_cmap_str(sv, cvec_i, cvec_i_destroy);
+declare_CVec(i, int);
+declare_CMap_str(sv, CVec_i, cvec_i_destroy);
// Function to return the number of occurrences of
int NumOccurrences(const char* arr[], int n, const char* str, int L, int R)
{
// To store the indices of strings in the array
- cmap_sv M = cmap_init;
+ CMap_sv M = cmap_init;
for (int i = 0; i < n; i++) {
const char* temp = arr[i];
- cmapentry_sv* it = cmap_sv_find(&M, temp);
+ CMapEntry_sv* it = cmap_sv_find(&M, temp);
// If current string doesn't
// have an entry in the map
// then create the entry
if (it == NULL) {
- cvec_i A = cvec_init;
+ CVec_i A = cvec_init;
cvec_i_pushBack(&A, i + 1);
cmap_sv_put(&M, temp, A);
}
@@ -47,7 +47,7 @@ int NumOccurrences(const char* arr[], int n, const char* str, int L, int R) }
}
- cmapentry_sv* it = cmap_sv_find(&M, str);
+ CMapEntry_sv* it = cmap_sv_find(&M, str);
// If the given string is not
// present in the array
@@ -56,7 +56,7 @@ int NumOccurrences(const char* arr[], int n, const char* str, int L, int R) // If the given string is present
// in the array
- cvec_i A = it->value;
+ CVec_i A = it->value;
int y = 0, x = 0;
for (; y < cvec_size(A); ++y) if (A.data[y] > R) break;
for (; x < cvec_size(A); ++x) if (A.data[x] > L - 1) break;
diff --git a/examples/geek6.c b/examples/geek6.c index 4689d934..6b70dd5e 100644 --- a/examples/geek6.c +++ b/examples/geek6.c @@ -30,14 +30,14 @@ operation in almost O(1) time complexity. #include <stdio.h>
#include <stc/cmap.h>
-declare_cset(i, int);
+declare_CSet(i, int);
// Function to find the smallest positive
// missing number
int missingNumber(int a[], int n)
{
// Declaring an unordered_map
- cset_i mp = cset_init;
+ CSet_i mp = cset_init;
// if array value is positive
// store it in map
diff --git a/examples/geek7.c b/examples/geek7.c index 88cfa33c..e304718d 100644 --- a/examples/geek7.c +++ b/examples/geek7.c @@ -26,9 +26,9 @@ After inserting all the elements excluding the ones which are to be deleted, Pop #include <stc/cmap.h>
#include <stc/cvecpq.h>
-declare_cmap(ii, int, int);
-declare_cvec(i, int);
-declare_cvec_priority_queue(i, >);
+declare_CMap(ii, int, int);
+declare_CVec(i, int);
+declare_CVec_priority_queue(i, >);
// Find k minimum element from arr[0..m-1] after deleting
// elements from del[0..n-1]
@@ -36,19 +36,19 @@ void findElementsAfterDel(int arr[], int m, int del[], int n, int k)
{
// Hash Map of the numbers to be deleted
- cmap_ii mp = cmap_init;
+ CMap_ii mp = cmap_init;
for (int i = 0; i < n; ++i) {
// Increment the count of del[i]
cmap_ii_insert(&mp, del[i], 0)->value++;
}
- cvec_i heap = cvec_init;
+ CVec_i heap = cvec_init;
for (int i = 0; i < m; ++i) {
// Search if the element is present
- cmapentry_ii *e = cmap_ii_find(&mp, arr[i]);
+ CMapEntry_ii *e = cmap_ii_find(&mp, arr[i]);
if (e != NULL) {
// Decrement its frequency
diff --git a/examples/heap.c b/examples/heap.c index 94409371..e4e91544 100644 --- a/examples/heap.c +++ b/examples/heap.c @@ -3,15 +3,15 @@ #include "stc/cvecpq.h"
#include "stc/crandom.h"
-declare_cvec(f, float);
-declare_cvec_priority_queue(f, >);
+declare_CVec(f, float);
+declare_CVec_priority_queue(f, >);
int main()
{
uint32_t seed = time(NULL);
crandom32_t pcg = crandom32_init(seed);
int N = 30000000, M = 100;
- cvec_f vec = cvec_init;
+ CVec_f vec = cvec_init;
clock_t start = clock();
for (int i=0; i<N; ++i)
cvec_f_pushBack(&vec, crandom32(&pcg));
diff --git a/examples/inits.c b/examples/inits.c index 5f8563c7..240ce5c9 100644 --- a/examples/inits.c +++ b/examples/inits.c @@ -4,17 +4,17 @@ #include <stc/cvec.h>
#include <stc/clist.h>
-declare_cmap(id, int, cstr_t, cstr_destroy); // Map of int -> cstr_t
-declare_cmap_str(cnt, int);
+declare_CMap(id, int, CStr, cstr_destroy); // Map of int -> CStr
+declare_CMap_str(cnt, int);
typedef struct {int x, y;} ipair_t;
-declare_cvec(ip, ipair_t, c_defaultDestroy, c_memCompare);
-declare_clist(ip, ipair_t, c_defaultDestroy, c_memCompare);
+declare_CVec(ip, ipair_t, c_defaultDestroy, c_memCompare);
+declare_CList(ip, ipair_t, c_defaultDestroy, c_memCompare);
int main(void) {
int year = 2020;
- cmap_id idnames = cmap_init;
+ CMap_id idnames = cmap_init;
c_push(&idnames, cmap_id, c_items(
{100, cstr_make("Hello")},
{110, cstr_make("World")},
@@ -27,7 +27,7 @@ int main(void) { // ------------------
- cmap_cnt countries = cmap_init;
+ CMap_cnt countries = cmap_init;
cmap_cnt_insert(&countries, "Greenland", 0)->value += 20;
c_push(&countries, cmap_cnt, c_items(
@@ -46,7 +46,7 @@ int main(void) { // ------------------
- cvec_ip pairs1 = cvec_init;
+ CVec_ip pairs1 = cvec_init;
c_push(&pairs1, cvec_ip, c_items(
{1, 2},
{3, 4},
@@ -61,7 +61,7 @@ int main(void) { // ------------------
- clist_ip pairs2 = clist_init;
+ CList_ip pairs2 = clist_init;
c_push(&pairs2, clist_ip, c_items(
{1, 2},
{3, 4},
diff --git a/examples/list.c b/examples/list.c index 2eb1f4c0..53b8711f 100644 --- a/examples/list.c +++ b/examples/list.c @@ -2,10 +2,10 @@ #include <time.h>
#include <stc/clist.h>
#include <stc/crandom.h>
-declare_clist(ix, uint64_t);
+declare_CList(ix, uint64_t);
int main() {
- clist_ix list = clist_init;
+ CList_ix list = clist_init;
crandom32_t pcg = crandom32_init(time(NULL));
int n;
for (int i=0; i<10000000; ++i) // ten million
diff --git a/examples/mapmap.c b/examples/mapmap.c index b349e8d3..67672dee 100644 --- a/examples/mapmap.c +++ b/examples/mapmap.c @@ -6,12 +6,12 @@ static void test_destr(int* x) { printf("destroy int: %d\n", *x);
}
-declare_cmap(ii, int, int, test_destr);
-declare_cmap(im, int, cmap_ii, cmap_ii_destroy);
+declare_CMap(ii, int, int, test_destr);
+declare_CMap(im, int, CMap_ii, cmap_ii_destroy);
int main(void) {
- cmap_im m = cmap_init;
- cmap_ii ini = cmap_init;
+ CMap_im m = cmap_init;
+ CMap_ii ini = cmap_init;
cmap_ii_put(&cmap_im_insert(&m, 100, ini)->value, 2000, 200);
cmap_ii_put(&cmap_im_insert(&m, 100, ini)->value, 2001, 201);
cmap_ii_put(&cmap_im_insert(&m, 100, ini)->value, 2000, 400); // update
diff --git a/examples/prime.c b/examples/prime.c index 611690ac..05ef4d57 100644 --- a/examples/prime.c +++ b/examples/prime.c @@ -10,7 +10,7 @@ static inline void sieveOfEratosthenes(size_t n)
{
- cbitset_t prime = cbitset_make(n + 1, true);
+ CBitset prime = cbitset_make(n + 1, true);
printf("computing prime numbers up to %zu\n", n);
cbitset_reset(&prime, 0);
cbitset_reset(&prime, 1);
diff --git a/examples/priority.c b/examples/priority.c index 37e7be60..c1890f8c 100644 --- a/examples/priority.c +++ b/examples/priority.c @@ -5,12 +5,12 @@ #include <stc/cmap.h>
#include <stc/crandom.h>
-declare_cvec(i, uint32_t);
-declare_cvec_priority_queue(i, >); // min-heap (increasing values)
+declare_CVec(i, uint32_t);
+declare_CVec_priority_queue(i, >); // min-heap (increasing values)
int main() {
crandom32_t pcg = crandom32_init(time(NULL));
- cvec_i heap = cvec_init;
+ CVec_i heap = cvec_init;
// Push ten million random numbers to queue
for (int i=0; i<10000000; ++i)
diff --git a/examples/rngbirthday.c b/examples/rngbirthday.c index 5e77fe43..1e6178aa 100644 --- a/examples/rngbirthday.c +++ b/examples/rngbirthday.c @@ -7,7 +7,7 @@ #include <stc/cvec.h>
#include <stc/cstr.h>
-declare_cmap(ic, uint64_t, uint8_t);
+declare_CMap(ic, uint64_t, uint8_t);
const static uint64_t seed = 1234;
const static uint64_t N = 1ull << 27;
@@ -16,7 +16,7 @@ const static uint64_t mask = (1ull << 52) - 1; void repeats(void)
{
crandom64_t rng = crandom64_init(seed);
- cmap_ic m = cmap_init;
+ CMap_ic m = cmap_init;
cmap_ic_reserve(&m, N);
clock_t now = clock();
for (size_t i = 0; i < N; ++i) {
@@ -29,14 +29,14 @@ void repeats(void) }
-declare_cmap(x, uint32_t, uint64_t);
-declare_cvec(x, uint64_t);
+declare_CMap(x, uint32_t, uint64_t);
+declare_CVec(x, uint64_t);
void distribution(void)
{
crandom32_t rng = crandom32_init(seed); // time(NULL), time(NULL));
const size_t N = 1ull << 28, M = 1ull << 9; // 1ull << 10;
- cmap_x map = cmap_x_make(M);
+ CMap_x map = cmap_x_make(M);
clock_t now = clock();
for (size_t i = 0; i < N; ++i) {
++cmap_x_insert(&map, crandom32b(&rng, M), 0)->value;
diff --git a/stc/carray.h b/stc/carray.h index caab846f..6157b7f3 100644 --- a/stc/carray.h +++ b/stc/carray.h @@ -30,13 +30,13 @@ Multi-dimensional generic array allocated as one block of heap-memory.
// demo:
#include <stc/carray.h>
-declare_carray(f, float);
+declare_CArray(f, float);
int main()
{
- carray3f a3 = carray3f_make(30, 20, 10, 0.f);
+ CArray3_f a3 = carray3f_make(30, 20, 10, 0.f);
carray3f_data(a3, 5, 4)[3] = 10.2f; // a3[5][4][3]
- carray2f a2 = carray3f_at(a3, 5); // sub-array reference (no data copy).
+ CArray2_f a2 = carray3f_at(a3, 5); // sub-array reference (no data copy).
printf("%f\n", carray2f_value(a2, 4, 3)); // readonly lookup a2[4][3] (=10.2f)
printf("%f\n", carray2f_data(a2, 4)[3]); // same, but this is writable.
@@ -74,122 +74,122 @@ static inline size_t _carray3_size(const size_t* zdim) { }
-#define declare_carray(...) c_MACRO_OVERLOAD(declare_carray, __VA_ARGS__)
+#define declare_CArray(...) c_MACRO_OVERLOAD(declare_CArray, __VA_ARGS__)
-#define declare_carray_2(tag, Value) \
- declare_carray_3(tag, Value, c_defaultDestroy)
+#define declare_CArray_2(tag, Value) \
+ declare_CArray_3(tag, Value, c_defaultDestroy)
-#define declare_carray_3(tag, Value, valueDestroy) \
+#define declare_CArray_3(tag, Value, valueDestroy) \
typedef struct { \
Value *data; \
size_t _xdim; \
- } carray1##tag; \
+ } CArray1##tag; \
\
typedef struct { \
Value *data; \
size_t _xdim, _yxdim; \
- } carray2##tag; \
+ } CArray2##tag; \
\
typedef struct { \
Value *data; \
size_t _xdim, _yxdim, _zdim; \
- } carray3##tag; \
+ } CArray3##tag; \
\
- static inline carray1##tag \
+ static inline CArray1##tag \
carray1##tag##_make(size_t xdim, Value val) { \
Value* m = c_new_N(Value, xdim); \
for (size_t i=0; i<xdim; ++i) m[i] = val; \
- carray1##tag a = {m, xdim | _carray_OWN}; \
+ CArray1##tag a = {m, xdim | _carray_OWN}; \
return a; \
} \
- static inline carray2##tag \
+ static inline CArray2##tag \
carray2##tag##_make(size_t ydim, size_t xdim, Value val) { \
const size_t n = ydim * xdim; \
Value* m = c_new_N(Value, n); \
for (size_t i=0; i<n; ++i) m[i] = val; \
- carray2##tag a = {m, xdim | _carray_OWN, ydim * xdim}; \
+ CArray2##tag a = {m, xdim | _carray_OWN, ydim * xdim}; \
return a; \
} \
- static inline carray3##tag \
+ static inline CArray3##tag \
carray3##tag##_make(size_t zdim, size_t ydim, size_t xdim, Value val) { \
const size_t n = zdim * ydim * xdim; \
Value* m = c_new_N(Value, n); \
for (size_t i=0; i<n; ++i) m[i] = val; \
- carray3##tag a = {m, xdim | _carray_OWN, ydim * xdim, zdim}; \
+ CArray3##tag a = {m, xdim | _carray_OWN, ydim * xdim, zdim}; \
return a; \
} \
\
- static inline carray1##tag \
+ static inline CArray1##tag \
carray1##tag##_from(size_t xdim, Value* array, bool own) { \
- carray1##tag a = {array, xdim | (own ? _carray_OWN : 0)}; \
+ CArray1##tag a = {array, xdim | (own ? _carray_OWN : 0)}; \
return a; \
} \
- static inline carray2##tag \
+ static inline CArray2##tag \
carray2##tag##_from(size_t ydim, size_t xdim, Value* array, bool own) { \
- carray2##tag a = {array, xdim | (own ? _carray_OWN : 0), ydim * xdim}; \
+ CArray2##tag a = {array, xdim | (own ? _carray_OWN : 0), ydim * xdim}; \
return a; \
} \
- static inline carray3##tag \
+ static inline CArray3##tag \
carray3##tag##_from(size_t zdim, size_t ydim, size_t xdim, Value* array, bool own) { \
- carray3##tag a = {array, xdim | (own ? _carray_OWN : 0), ydim * xdim, zdim}; \
+ CArray3##tag a = {array, xdim | (own ? _carray_OWN : 0), ydim * xdim, zdim}; \
return a; \
} \
\
static inline void \
- carray1##tag##_destroy(carray1##tag* self) { \
+ carray1##tag##_destroy(CArray1##tag* self) { \
if (self->_xdim & _carray_OWN) { \
size_t n = carray1_size(*self); Value* a = self->data; \
while (n--) valueDestroy(&a[n]); free(a); \
} \
} \
static inline void \
- carray2##tag##_destroy(carray2##tag* self) { \
+ carray2##tag##_destroy(CArray2##tag* self) { \
if (self->_xdim & _carray_OWN) { \
size_t n = carray2_size(*self); Value* a = self->data; \
while (n--) valueDestroy(&a[n]); free(a); \
} \
} \
static inline void \
- carray3##tag##_destroy(carray3##tag* self) { \
+ carray3##tag##_destroy(CArray3##tag* self) { \
if (self->_xdim & _carray_OWN) { \
size_t n = carray3_size(*self); Value* a = self->data; \
while (n--) valueDestroy(&a[n]); free(a); \
} \
} \
\
- static inline carray1##tag \
- carray2##tag##_at(carray2##tag a, size_t y) { \
- carray1##tag sub = {a.data + y*carray2_xdim(a), carray2_xdim(a)}; \
+ static inline CArray1##tag \
+ carray2##tag##_at(CArray2##tag a, size_t y) { \
+ CArray1##tag sub = {a.data + y*carray2_xdim(a), carray2_xdim(a)}; \
return sub; \
} \
static inline Value* \
- carray2##tag##_data(carray2##tag a, size_t y) { \
+ carray2##tag##_data(CArray2##tag a, size_t y) { \
return a.data + y*carray2_xdim(a); \
} \
static inline Value \
- carray2##tag##_value(carray2##tag a, size_t y, size_t x) { \
+ carray2##tag##_value(CArray2##tag a, size_t y, size_t x) { \
return a.data[ y*carray2_xdim(a) + x ]; \
} \
\
- static inline carray2##tag \
- carray3##tag##_at(carray3##tag a, size_t z) { \
- carray2##tag sub = {a.data + z*a._yxdim, carray3_xdim(a), a._yxdim}; \
+ static inline CArray2##tag \
+ carray3##tag##_at(CArray3##tag a, size_t z) { \
+ CArray2##tag sub = {a.data + z*a._yxdim, carray3_xdim(a), a._yxdim}; \
return sub; \
} \
- static inline carray1##tag \
- carray3##tag##_at2(carray3##tag a, size_t z, size_t y) { \
- carray1##tag sub = {a.data + z*a._yxdim + y*carray3_xdim(a), carray3_xdim(a)}; \
+ static inline CArray1##tag \
+ carray3##tag##_at2(CArray3##tag a, size_t z, size_t y) { \
+ CArray1##tag sub = {a.data + z*a._yxdim + y*carray3_xdim(a), carray3_xdim(a)}; \
return sub; \
} \
static inline Value* \
- carray3##tag##_data(carray3##tag a, size_t z, size_t y) { \
+ carray3##tag##_data(CArray3##tag a, size_t z, size_t y) { \
return a.data + z*a._yxdim + y*carray3_xdim(a); \
} \
static inline Value \
- carray3##tag##_value(carray3##tag a, size_t z, size_t y, size_t x) { \
+ carray3##tag##_value(CArray3##tag a, size_t z, size_t y, size_t x) { \
return a.data[ z*a._yxdim + y*carray3_xdim(a) + x ]; \
} \
- typedef Value carrayValue_##tag
+ typedef Value CArrayValue_##tag
#endif
diff --git a/stc/cbitset.h b/stc/cbitset.h index 94488f24..4f30c091 100644 --- a/stc/cbitset.h +++ b/stc/cbitset.h @@ -27,7 +27,7 @@ Similar to boost::dynamic_bitset / std::bitset #include "cbitset.h"
int main() {
- cbitset_t set = cbitset_make(23, true);
+ CBitset set = cbitset_make(23, true);
cbitset_reset(&set, 9);
cbitset_resize(&set, 43, false);
printf("%4zu: ", set.size);for (int i=0; i<set.size; ++i) printf("%d", cbitset_value(&set, i));puts("");
@@ -55,97 +55,97 @@ int main() { #define cbitset_popcnt64(i) _mm_popcnt_u64(i)
#endif
-typedef struct { uint64_t* _arr; size_t size; } cbitset_t;
+typedef struct { uint64_t* _arr; size_t size; } CBitset;
#define cbitset_init {NULL, 0}
-STC_API void cbitset_resize(cbitset_t* self, size_t size, bool value);
-STC_API size_t cbitset_count(cbitset_t set);
+STC_API void cbitset_resize(CBitset* self, size_t size, bool value);
+STC_API size_t cbitset_count(CBitset set);
-STC_INLINE void cbitset_setAll(cbitset_t *self, bool value);
+STC_INLINE void cbitset_setAll(CBitset *self, bool value);
-STC_INLINE cbitset_t cbitset_make(size_t size, bool value) {
- cbitset_t set = {(uint64_t *) malloc(((size + 63) >> 6) * 8), size};
+STC_INLINE CBitset cbitset_make(size_t size, bool value) {
+ CBitset set = {(uint64_t *) malloc(((size + 63) >> 6) * 8), size};
cbitset_setAll(&set, value);
return set;
}
-STC_INLINE cbitset_t cbitset_from(cbitset_t other) {
+STC_INLINE CBitset cbitset_from(CBitset other) {
size_t n = (other.size + 63) >> 6;
- cbitset_t set = {(uint64_t *) memcpy(malloc(n * 8), other._arr, n * 8), other.size};
+ CBitset set = {(uint64_t *) memcpy(malloc(n * 8), other._arr, n * 8), other.size};
return set;
}
-STC_INLINE void cbitset_destroy(cbitset_t* self) {
+STC_INLINE void cbitset_destroy(CBitset* self) {
free(self->_arr);
}
-STC_INLINE size_t cbitset_size(cbitset_t set) {return set.size;}
+STC_INLINE size_t cbitset_size(CBitset set) {return set.size;}
-STC_INLINE void cbitset_set(cbitset_t *self, size_t i) {
+STC_INLINE void cbitset_set(CBitset *self, size_t i) {
self->_arr[i >> 6] |= 1ull << (i & 63);
}
-STC_INLINE void cbitset_reset(cbitset_t *self, size_t i) {
+STC_INLINE void cbitset_reset(CBitset *self, size_t i) {
self->_arr[i >> 6] &= ~(1ull << (i & 63));
}
-STC_INLINE void cbitset_setTo(cbitset_t *self, size_t i, bool value) {
+STC_INLINE void cbitset_setTo(CBitset *self, size_t i, bool value) {
value ? cbitset_set(self, i) : cbitset_reset(self, i);
}
-STC_INLINE void cbitset_flip(cbitset_t *self, size_t i) {
+STC_INLINE void cbitset_flip(CBitset *self, size_t i) {
self->_arr[i >> 6] ^= 1ull << (i & 63);
}
-STC_INLINE bool cbitset_test(cbitset_t set, size_t i) {
+STC_INLINE bool cbitset_test(CBitset set, size_t i) {
return (set._arr[i >> 6] & (1ull << (i & 63))) != 0;
}
-STC_INLINE void cbitset_setAll(cbitset_t *self, bool value) {
+STC_INLINE void cbitset_setAll(CBitset *self, bool value) {
memset(self->_arr, value ? 0xff : 0x0, ((self->size + 63) >> 6) * 8);
}
-STC_INLINE void cbitset_setAll64(cbitset_t *self, uint64_t pattern) {
+STC_INLINE void cbitset_setAll64(CBitset *self, uint64_t pattern) {
size_t n = (self->size + 63) >> 6;
for (size_t i=0; i<n; ++i) self->_arr[i] = pattern;
}
-STC_INLINE void cbitset_flipAll(cbitset_t *self) {
+STC_INLINE void cbitset_flipAll(CBitset *self) {
size_t n = (self->size + 63) >> 6;
for (size_t i=0; i<n; ++i) self->_arr[i] ^= ~0ull;
}
/* Intersection */
-STC_INLINE void cbitset_setAnd(cbitset_t *self, cbitset_t other) {
+STC_INLINE void cbitset_setAnd(CBitset *self, CBitset other) {
assert(self->size == other.size);
size_t n = (self->size + 63) >> 6;
for (size_t i=0; i<n; ++i) self->_arr[i] &= other._arr[i];
}
/* Union */
-STC_INLINE void cbitset_setOr(cbitset_t *self, cbitset_t other) {
+STC_INLINE void cbitset_setOr(CBitset *self, CBitset other) {
assert(self->size == other.size);
size_t n = (self->size + 63) >> 6;
for (size_t i=0; i<n; ++i) self->_arr[i] |= other._arr[i];
}
/* Exclusive disjunction */
-STC_INLINE void cbitset_setXor(cbitset_t *self, cbitset_t other) {
+STC_INLINE void cbitset_setXor(CBitset *self, CBitset other) {
assert(self->size == other.size);
size_t n = (self->size + 63) >> 6;
for (size_t i=0; i<n; ++i) self->_arr[i] ^= other._arr[i];
}
-STC_INLINE cbitset_t cbitset_and(cbitset_t s1, cbitset_t s2) {
- cbitset_t set = cbitset_from(s1);
+STC_INLINE CBitset cbitset_and(CBitset s1, CBitset s2) {
+ CBitset set = cbitset_from(s1);
cbitset_setAnd(&set, s2); return set;
}
-STC_INLINE cbitset_t cbitset_or(cbitset_t s1, cbitset_t s2) {
- cbitset_t set = cbitset_from(s1);
+STC_INLINE CBitset cbitset_or(CBitset s1, CBitset s2) {
+ CBitset set = cbitset_from(s1);
cbitset_setOr(&set, s2); return set;
}
-STC_INLINE cbitset_t cbitset_xor(cbitset_t s1, cbitset_t s2) {
- cbitset_t set = cbitset_from(s1);
+STC_INLINE CBitset cbitset_xor(CBitset s1, CBitset s2) {
+ CBitset set = cbitset_from(s1);
cbitset_setXor(&set, s2); return set;
}
-STC_INLINE cbitset_t cbitset_not(cbitset_t s1) {
- cbitset_t set = cbitset_from(s1);
+STC_INLINE CBitset cbitset_not(CBitset s1) {
+ CBitset set = cbitset_from(s1);
cbitset_flipAll(&set); return set;
}
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-STC_API void cbitset_resize(cbitset_t* self, size_t size, bool value) {
+STC_API void cbitset_resize(CBitset* self, size_t size, bool value) {
size_t new_n = (size + 63) >> 6, osize = self->size, old_n = (osize + 63) >> 6;
self->_arr = (uint64_t *) realloc(self->_arr, new_n * 8);
self->size = size;
@@ -158,7 +158,7 @@ STC_API void cbitset_resize(cbitset_t* self, size_t size, bool value) { }
}
-STC_API size_t cbitset_count(cbitset_t set) {
+STC_API size_t cbitset_count(CBitset set) {
size_t count = 0, n = (set.size + 63) >> 6;
if (set.size > 0) {
--n; for (size_t i=0; i<n; ++i) count += cbitset_popcnt64(set._arr[i]);
diff --git a/stc/clist.h b/stc/clist.h index 8da0e79d..026becff 100644 --- a/stc/clist.h +++ b/stc/clist.h @@ -35,10 +35,10 @@ #include <stdio.h>
#include <stc/clist.h>
#include <stc/crandom.h>
- declare_clist(ix, int64_t);
+ declare_CList(ix, int64_t);
int main() {
- clist_ix list = clist_init;
+ CList_ix list = clist_init;
pcg32_random_t pcg = pcg32_seed(123, 0);
int n;
for (int i=0; i<1000000; ++i) // one million
@@ -56,30 +56,30 @@ }
*/
-#define declare_clist(...) c_MACRO_OVERLOAD(declare_clist, __VA_ARGS__)
+#define declare_CList(...) c_MACRO_OVERLOAD(declare_CList, __VA_ARGS__)
-#define declare_clist_2(tag, Value) \
- declare_clist_3(tag, Value, c_defaultDestroy)
-#define declare_clist_3(tag, Value, valueDestroy) \
- declare_clist_4(tag, Value, valueDestroy, c_defaultCompare)
-#define declare_clist_4(tag, Value, valueDestroy, valueCompare) \
- declare_clist_6(tag, Value, valueDestroy, Value, valueCompare, c_defaultGetRaw)
-#define declare_clist_str() \
- declare_clist_6(str, cstr_t, cstr_destroy, const char*, cstr_compareRaw, cstr_getRaw)
+#define declare_CList_2(tag, Value) \
+ declare_CList_3(tag, Value, c_defaultDestroy)
+#define declare_CList_3(tag, Value, valueDestroy) \
+ declare_CList_4(tag, Value, valueDestroy, c_defaultCompare)
+#define declare_CList_4(tag, Value, valueDestroy, valueCompare) \
+ declare_CList_6(tag, Value, valueDestroy, Value, valueCompare, c_defaultGetRaw)
+#define declare_CList_str() \
+ declare_CList_6(str, CStr, cstr_destroy, const char*, cstr_compareRaw, cstr_getRaw)
-#define declare_clistTypes(tag, Value) \
- typedef struct clistnode_##tag { \
- struct clistnode_##tag *next; \
+#define declare_CListTypes(tag, Value) \
+ typedef struct CListNode_##tag { \
+ struct CListNode_##tag *next; \
Value value; \
- } clistnode_##tag; \
+ } CListNode_##tag; \
\
- typedef struct clist_##tag { \
- clistnode_##tag *last; \
- } clist_##tag; \
+ typedef struct CList_##tag { \
+ CListNode_##tag *last; \
+ } CList_##tag; \
\
typedef struct { \
- clistnode_##tag *item, **_last; \
- } clist_##tag##_iter_t
+ CListNode_##tag *item, **_last; \
+ } CListIter_##tag, clist_##tag##_iter_t
#define clist_init {NULL}
#define clist_front(list) (list).last->next->value
@@ -87,49 +87,49 @@ #define clist_empty(list) ((list).last == NULL)
-#define declare_clist_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \
+#define declare_CList_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \
\
- declare_clistTypes(tag, Value); \
+ declare_CListTypes(tag, Value); \
\
- STC_INLINE clist_##tag \
- clist_##tag##_init(void) {clist_##tag x = clist_init; return x;} \
+ STC_INLINE CList_##tag \
+ clist_##tag##_init(void) {CList_##tag x = clist_init; return x;} \
STC_API void \
- clist_##tag##_destroy(clist_##tag* self); \
+ clist_##tag##_destroy(CList_##tag* self); \
STC_INLINE void \
- clist_##tag##_clear(clist_##tag* self) {clist_##tag##_destroy(self);} \
+ clist_##tag##_clear(CList_##tag* self) {clist_##tag##_destroy(self);} \
STC_API void \
- clist_##tag##_pushBack(clist_##tag* self, Value value); \
+ clist_##tag##_pushBack(CList_##tag* self, Value value); \
STC_API void \
- clist_##tag##_pushFront(clist_##tag* self, Value value); \
+ clist_##tag##_pushFront(CList_##tag* self, Value value); \
STC_API void \
- clist_##tag##_pushN(clist_##tag *self, const Value in[], size_t size); \
+ clist_##tag##_pushN(CList_##tag *self, const Value in[], size_t size); \
STC_API void \
- clist_##tag##_popFront(clist_##tag* self); \
+ clist_##tag##_popFront(CList_##tag* self); \
STC_API void \
- clist_##tag##_insertAfter(clist_##tag* self, clist_##tag##_iter_t pos, Value value); \
+ clist_##tag##_insertAfter(CList_##tag* self, clist_##tag##_iter_t pos, Value value); \
STC_API void \
- clist_##tag##_eraseAfter(clist_##tag* self, clist_##tag##_iter_t pos); \
+ clist_##tag##_eraseAfter(CList_##tag* self, clist_##tag##_iter_t pos); \
STC_API void \
- clist_##tag##_spliceFront(clist_##tag* self, clist_##tag* other); \
+ clist_##tag##_spliceFront(CList_##tag* self, CList_##tag* other); \
STC_API void \
- clist_##tag##_spliceAfter(clist_##tag* self, clist_##tag##_iter_t pos, clist_##tag* other); \
+ clist_##tag##_spliceAfter(CList_##tag* self, clist_##tag##_iter_t pos, CList_##tag* other); \
STC_API clist_##tag##_iter_t \
- clist_##tag##_findBefore(clist_##tag* self, RawValue val); \
+ clist_##tag##_findBefore(CList_##tag* self, RawValue val); \
STC_API Value* \
- clist_##tag##_find(clist_##tag* self, RawValue val); \
+ clist_##tag##_find(CList_##tag* self, RawValue val); \
STC_API clist_##tag##_iter_t \
- clist_##tag##_remove(clist_##tag* self, RawValue val); \
+ clist_##tag##_remove(CList_##tag* self, RawValue val); \
STC_API void \
- clist_##tag##_sort(clist_##tag* self); \
+ clist_##tag##_sort(CList_##tag* self); \
\
STC_INLINE Value* \
- clist_##tag##_front(clist_##tag* self) {return &self->last->next->value;} \
+ clist_##tag##_front(CList_##tag* self) {return &self->last->next->value;} \
STC_INLINE Value* \
- clist_##tag##_back(clist_##tag* self) {return &self->last->value;} \
+ clist_##tag##_back(CList_##tag* self) {return &self->last->value;} \
\
STC_INLINE clist_##tag##_iter_t \
- clist_##tag##_begin(clist_##tag* self) { \
- clistnode_##tag *head = self->last ? self->last->next : NULL; \
+ clist_##tag##_begin(CList_##tag* self) { \
+ CListNode_##tag *head = self->last ? self->last->next : NULL; \
clist_##tag##_iter_t it = {head, &self->last}; return it; \
} \
STC_INLINE clist_##tag##_iter_t \
@@ -137,61 +137,61 @@ it.item = it.item == *it._last ? NULL : it.item->next; return it; \
} \
STC_INLINE clist_##tag##_iter_t \
- clist_##tag##_last(clist_##tag* self) { \
+ clist_##tag##_last(CList_##tag* self) { \
clist_##tag##_iter_t it = {self->last, &self->last}; return it; \
} \
\
- implement_clist_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \
- typedef RawValue clist_##tag##_rawvalue_t; \
- typedef Value clist_##tag##_value_t, clist_##tag##_input_t
+ implement_CList_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \
+ typedef RawValue CListRawValue_##tag; \
+ typedef Value CListValue_##tag, clist_##tag##_input_t
/* -------------------------- IMPLEMENTATION ------------------------- */
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-#define implement_clist_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \
+#define implement_CList_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \
\
STC_API void \
- clist_##tag##_destroy(clist_##tag* self) { \
+ clist_##tag##_destroy(CList_##tag* self) { \
while (self->last) \
clist_##tag##_popFront(self); \
} \
\
STC_API void \
- clist_##tag##_pushBack(clist_##tag* self, Value value) { \
+ clist_##tag##_pushBack(CList_##tag* self, Value value) { \
_clist_insertAfter(self, tag, self->last, value); \
self->last = entry; \
} \
STC_API void \
- clist_##tag##_pushFront(clist_##tag* self, Value value) { \
+ clist_##tag##_pushFront(CList_##tag* self, Value value) { \
_clist_insertAfter(self, tag, self->last, value); \
if (!self->last) self->last = entry; \
} \
STC_API void \
- clist_##tag##_pushN(clist_##tag *self, const Value in[], size_t size) { \
+ clist_##tag##_pushN(CList_##tag *self, const Value in[], size_t size) { \
for (size_t i=0; i<size; ++i) clist_##tag##_pushBack(self, in[i]); \
} \
STC_API void \
- clist_##tag##_popFront(clist_##tag* self) { \
+ clist_##tag##_popFront(CList_##tag* self) { \
_clist_eraseAfter(self, tag, self->last, valueDestroy); \
} \
\
STC_API void \
- clist_##tag##_insertAfter(clist_##tag* self, clist_##tag##_iter_t pos, Value value) { \
+ clist_##tag##_insertAfter(CList_##tag* self, clist_##tag##_iter_t pos, Value value) { \
_clist_insertAfter(self, tag, pos.item, value); \
if (!self->last || pos.item == self->last) self->last = entry; \
} \
STC_API void \
- clist_##tag##_eraseAfter(clist_##tag* self, clist_##tag##_iter_t pos) { \
+ clist_##tag##_eraseAfter(CList_##tag* self, clist_##tag##_iter_t pos) { \
_clist_eraseAfter(self, tag, pos.item, valueDestroy); \
} \
\
static inline void \
- _clist_##tag##_splice(clist_##tag* self, clist_##tag##_iter_t pos, clist_##tag* other, bool bottom) { \
+ _clist_##tag##_splice(CList_##tag* self, clist_##tag##_iter_t pos, CList_##tag* other, bool bottom) { \
if (!pos.item) \
self->last = pos.item = other->last; \
else if (other->last) { \
- clistnode_##tag *next = pos.item->next; \
+ CListNode_##tag *next = pos.item->next; \
pos.item->next = other->last->next; \
other->last->next = next; \
if (bottom && pos.item == self->last) self->last = other->last; \
@@ -199,16 +199,16 @@ other->last = NULL; \
} \
STC_API void \
- clist_##tag##_spliceFront(clist_##tag* self, clist_##tag* other) { \
+ clist_##tag##_spliceFront(CList_##tag* self, CList_##tag* other) { \
_clist_##tag##_splice(self, clist_##tag##_last(self), other, false); \
} \
STC_API void \
- clist_##tag##_spliceAfter(clist_##tag* self, clist_##tag##_iter_t pos, clist_##tag* other) { \
+ clist_##tag##_spliceAfter(CList_##tag* self, clist_##tag##_iter_t pos, CList_##tag* other) { \
_clist_##tag##_splice(self, pos, other, true); \
} \
\
STC_API clist_##tag##_iter_t \
- clist_##tag##_findBefore(clist_##tag* self, RawValue val) { \
+ clist_##tag##_findBefore(CList_##tag* self, RawValue val) { \
clist_##tag##_iter_t prev = {self->last, &self->last}; \
c_foreach (i, clist_##tag, *self) { \
RawValue r = valueGetRaw(&i.item->value); \
@@ -221,13 +221,13 @@ } \
\
STC_API Value* \
- clist_##tag##_find(clist_##tag* self, RawValue val) { \
+ clist_##tag##_find(CList_##tag* self, RawValue val) { \
clist_##tag##_iter_t it = clist_##tag##_findBefore(self, val); \
return it.item ? &it.item->next->value : NULL; \
} \
\
STC_API clist_##tag##_iter_t \
- clist_##tag##_remove(clist_##tag* self, RawValue val) { \
+ clist_##tag##_remove(CList_##tag* self, RawValue val) { \
clist_##tag##_iter_t it = clist_##tag##_findBefore(self, val); \
if (it.item) clist_##tag##_eraseAfter(self, it); \
return it; \
@@ -235,18 +235,18 @@ \
static inline int \
clist_##tag##_sortCompare(const void* x, const void* y) { \
- RawValue a = valueGetRaw(&((clistnode_##tag *) x)->value); \
- RawValue b = valueGetRaw(&((clistnode_##tag *) y)->value); \
+ RawValue a = valueGetRaw(&((CListNode_##tag *) x)->value); \
+ RawValue b = valueGetRaw(&((CListNode_##tag *) y)->value); \
return valueCompareRaw(&a, &b); \
} \
STC_API void \
- clist_##tag##_sort(clist_##tag* self) { \
- clistnode__base* last = _clist_mergesort((clistnode__base *) self->last->next, clist_##tag##_sortCompare); \
- self->last = (clistnode_##tag *) last; \
+ clist_##tag##_sort(CList_##tag* self) { \
+ CListNode__base* last = _clist_mergesort((CListNode__base *) self->last->next, clist_##tag##_sortCompare); \
+ self->last = (CListNode_##tag *) last; \
}
#define _clist_insertAfter(self, tag, node, val) \
- clistnode_##tag *entry = c_new (clistnode_##tag), \
+ CListNode_##tag *entry = c_new (CListNode_##tag), \
*next = self->last ? node->next : entry; \
entry->value = val; \
entry->next = next; \
@@ -254,21 +254,21 @@ /* +: set self->last based on node */
#define _clist_eraseAfter(self, tag, node, valueDestroy) \
- clistnode_##tag* del = node->next, *next = del->next; \
+ CListNode_##tag* del = node->next, *next = del->next; \
node->next = next; \
if (del == next) self->last = NULL; \
else if (self->last == del) self->last = node; \
valueDestroy(&del->value); \
free(del)
-declare_clistTypes(_base, int);
+declare_CListTypes(_base, int);
/* Singly linked list Mergesort implementation by Simon Tatham. O(n*log n).
* https://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
*/
-static inline clistnode__base *
-_clist_mergesort(clistnode__base *list, int (*cmp)(const void*, const void*)) {
- clistnode__base *p, *q, *e, *tail, *oldhead;
+static inline CListNode__base *
+_clist_mergesort(CListNode__base *list, int (*cmp)(const void*, const void*)) {
+ CListNode__base *p, *q, *e, *tail, *oldhead;
int insize = 1, nmerges, psize, qsize, i;
if (!list) return NULL;
@@ -321,7 +321,7 @@ _clist_mergesort(clistnode__base *list, int (*cmp)(const void*, const void*)) { }
#else
-#define implement_clist_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw)
+#define implement_CList_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw)
#endif
#endif
@@ -24,21 +24,21 @@ /* // Example:
#include <stdio.h>
#include <stc/cmap.h>
-declare_cset(sx, int); // Set of int
-declare_cmap(mx, int, char); // Map of int -> char
+declare_CSet(sx, int); // Set of int
+declare_CMap(mx, int, char); // Map of int -> char
int main(void) {
- cset_sx s = cset_init;
+ CSet_sx s = cset_init;
cset_sx_put(&s, 5);
cset_sx_put(&s, 8);
c_foreach (i, cset_sx, s) printf("set %d\n", i.item->key);
cset_sx_destroy(&s);
- cmap_mx m = cmap_init;
+ CMap_mx m = cmap_init;
cmap_mx_put(&m, 5, 'a');
cmap_mx_put(&m, 8, 'b');
cmap_mx_put(&m, 12, 'c');
- cmapentry_mx *e = cmap_mx_find(&m, 10); // = NULL
+ CMapEntry_mx *e = cmap_mx_find(&m, 10); // = NULL
char val = cmap_mx_find(&m, 5)->value;
cmap_mx_put(&m, 5, 'd'); // update
cmap_mx_erase(&m, 8);
@@ -66,58 +66,58 @@ int main(void) { enum {chash_HASH = 0x7f, chash_USED = 0x80};
-#define declare_cmap(...) \
- c_MACRO_OVERLOAD(declare_cmap, __VA_ARGS__)
+#define declare_CMap(...) \
+ c_MACRO_OVERLOAD(declare_CMap, __VA_ARGS__)
-#define declare_cmap_3(tag, Key, Value) \
- declare_cmap_4(tag, Key, Value, c_defaultDestroy)
+#define declare_CMap_3(tag, Key, Value) \
+ declare_CMap_4(tag, Key, Value, c_defaultDestroy)
-#define declare_cmap_4(tag, Key, Value, valueDestroy) \
- declare_cmap_6(tag, Key, Value, valueDestroy, c_defaultEquals, c_defaultHash)
+#define declare_CMap_4(tag, Key, Value, valueDestroy) \
+ declare_CMap_6(tag, Key, Value, valueDestroy, c_defaultEquals, c_defaultHash)
-#define declare_cmap_6(tag, Key, Value, valueDestroy, keyEquals, keyHash) \
- declare_cmap_10(tag, Key, Value, valueDestroy, keyEquals, keyHash, \
+#define declare_CMap_6(tag, Key, Value, valueDestroy, keyEquals, keyHash) \
+ declare_CMap_10(tag, Key, Value, valueDestroy, keyEquals, keyHash, \
c_defaultDestroy, Key, c_defaultGetRaw, c_defaultInitRaw)
-#define declare_cmap_10(tag, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \
+#define declare_CMap_10(tag, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \
keyDestroy, RawKey, keyGetRaw, keyInitRaw) \
- declare_CHASH(tag, cmap, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \
+ declare_CHASH(tag, CMap, cmap, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \
keyDestroy, RawKey, keyGetRaw, keyInitRaw)
-/* cset: */
-#define declare_cset(...) \
- c_MACRO_OVERLOAD(declare_cset, __VA_ARGS__)
+/* CSet: */
+#define declare_CSet(...) \
+ c_MACRO_OVERLOAD(declare_CSet, __VA_ARGS__)
-#define declare_cset_2(tag, Key) \
- declare_cset_4(tag, Key, c_defaultEquals, c_defaultHash)
+#define declare_CSet_2(tag, Key) \
+ declare_CSet_4(tag, Key, c_defaultEquals, c_defaultHash)
-#define declare_cset_4(tag, Key, keyEquals, keyHash) \
- declare_cset_5(tag, Key, keyEquals, keyHash, c_defaultDestroy)
+#define declare_CSet_4(tag, Key, keyEquals, keyHash) \
+ declare_CSet_5(tag, Key, keyEquals, keyHash, c_defaultDestroy)
-#define declare_cset_5(tag, Key, keyEquals, keyHash, keyDestroy) \
- declare_cset_8(tag, Key, keyEquals, keyHash, keyDestroy, \
+#define declare_CSet_5(tag, Key, keyEquals, keyHash, keyDestroy) \
+ declare_CSet_8(tag, Key, keyEquals, keyHash, keyDestroy, \
Key, c_defaultGetRaw, c_defaultInitRaw)
-#define declare_cset_8(tag, Key, keyEqualsRaw, keyHashRaw, keyDestroy, \
+#define declare_CSet_8(tag, Key, keyEqualsRaw, keyHashRaw, keyDestroy, \
RawKey, keyGetRaw, keyInitRaw) \
- declare_CHASH(tag, cset, Key, void, void, keyEqualsRaw, keyHashRaw, \
+ declare_CHASH(tag, CSet, cset, Key, void, void, keyEqualsRaw, keyHashRaw, \
keyDestroy, RawKey, keyGetRaw, keyInitRaw)
-/* cset_str, cmap_str: */
-#define declare_cset_str() \
- declare_CHASH_STR(str, cset, void, void)
+/* CSet_str, CMap_str: */
+#define declare_CSet_str() \
+ declare_CHASH_STR(str, CSet, cset, void, void)
-#define declare_cmap_str(...) \
- c_MACRO_OVERLOAD(declare_cmap_str, __VA_ARGS__)
+#define declare_CMap_str(...) \
+ c_MACRO_OVERLOAD(declare_CMap_str, __VA_ARGS__)
-#define declare_cmap_str_2(tag, Value) \
- declare_CHASH_STR(tag, cmap, Value, c_defaultDestroy)
+#define declare_CMap_str_2(tag, Value) \
+ declare_CHASH_STR(tag, CMap, cmap, Value, c_defaultDestroy)
-#define declare_cmap_str_3(tag, Value, ValueDestroy) \
- declare_CHASH_STR(tag, cmap, Value, ValueDestroy)
+#define declare_CMap_str_3(tag, Value, ValueDestroy) \
+ declare_CHASH_STR(tag, CMap, cmap, Value, ValueDestroy)
-#define declare_CHASH_STR(tag, ctype, Value, valueDestroy) \
- declare_CHASH(tag, ctype, cstr_t, Value, valueDestroy, cstr_equalsRaw, cstr_hashRaw, \
+#define declare_CHASH_STR(tag, CType, ctype, Value, valueDestroy) \
+ declare_CHASH(tag, CType, ctype, CStr, Value, valueDestroy, cstr_equalsRaw, cstr_hashRaw, \
cstr_destroy, const char*, cstr_getRaw, cstr_make)
#define OPT_1_cset(x)
@@ -126,124 +126,124 @@ enum {chash_HASH = 0x7f, chash_USED = 0x80}; #define OPT_2_cmap(x, y) x, y
/* CHASH full: use 'void' for Value if ctype is cset */
-#define declare_CHASH(tag, ctype, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \
+#define declare_CHASH(tag, CType, ctype, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \
keyDestroy, RawKey, keyGetRaw, keyInitRaw) \
typedef struct { \
Key key; \
OPT_1_##ctype(Value value;) \
-} ctype##entry_##tag, ctype##_##tag##_entry_t; \
+} CType##Entry_##tag, ctype##_##tag##_entry_t; \
\
STC_INLINE void \
-ctype##entry_##tag##_destroy(ctype##entry_##tag* e) { \
+ctype##entry_##tag##_destroy(CType##Entry_##tag* e) { \
keyDestroy(&e->key); \
OPT_1_##ctype(valueDestroy(&e->value);) \
} \
typedef struct { \
RawKey key; \
OPT_1_##ctype(Value value;) \
-} ctype##_##tag##_input_t; \
+} CType##Input_##tag, ctype##_##tag##_input_t; \
\
-typedef RawKey ctype##_##tag##_rawkey_t; \
+typedef RawKey CType##RawKey_##tag, ctype##_##tag##_rawkey_t; \
\
typedef struct { \
- ctype##entry_##tag* table; \
+ CType##Entry_##tag* table; \
uint8_t* _hashx; \
uint32_t size, bucketCount; \
float maxLoadFactor; \
float shrinkLimitFactor; \
-} ctype##_##tag; \
+} CType##_##tag; \
\
typedef struct { \
- ctype##entry_##tag *item, *_end; \
+ CType##Entry_##tag *item, *_end; \
uint8_t* _hx; \
-} ctype##_##tag##_iter_t; \
+} CType##Iter_##tag, ctype##_##tag##_iter_t; \
\
-STC_INLINE ctype##_##tag \
-ctype##_##tag##_init(void) {ctype##_##tag x = cmap_init; return x;} \
-STC_API ctype##_##tag \
+STC_INLINE CType##_##tag \
+ctype##_##tag##_init(void) {CType##_##tag x = cmap_init; return x;} \
+STC_API CType##_##tag \
ctype##_##tag##_make(size_t initialSize); \
STC_API void \
-ctype##_##tag##_pushN(ctype##_##tag* self, const ctype##_##tag##_input_t in[], size_t size); \
+ctype##_##tag##_pushN(CType##_##tag* self, const CType##Input_##tag in[], size_t size); \
STC_API void \
-ctype##_##tag##_destroy(ctype##_##tag* self); \
+ctype##_##tag##_destroy(CType##_##tag* self); \
STC_API void \
-ctype##_##tag##_clear(ctype##_##tag* self); \
+ctype##_##tag##_clear(CType##_##tag* self); \
STC_INLINE void \
-ctype##_##tag##_setLoadFactors(ctype##_##tag* self, float max, float shrink) { \
+ctype##_##tag##_setLoadFactors(CType##_##tag* self, float max, float shrink) { \
self->maxLoadFactor = max; self->shrinkLimitFactor = shrink; \
} \
-STC_API ctype##entry_##tag* \
-ctype##_##tag##_find(const ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey); \
-STC_FORCE_INLINE ctype##entry_##tag* /* alias */ \
-ctype##_##tag##_get(const ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey) \
+STC_API CType##Entry_##tag* \
+ctype##_##tag##_find(const CType##_##tag* self, CType##RawKey_##tag rawKey); \
+STC_FORCE_INLINE CType##Entry_##tag* /* alias */ \
+ctype##_##tag##_get(const CType##_##tag* self, CType##RawKey_##tag rawKey) \
{return ctype##_##tag##_find(self, rawKey);} \
-STC_API ctype##entry_##tag* /* similar to c++ std::map.insert_or_assign(): */ \
-ctype##_##tag##_put(ctype##_##tag* self, OPT_2_##ctype(ctype##_##tag##_rawkey_t rawKey, Value value)); \
-OPT_1_##ctype(STC_API ctype##entry_##tag* /* similar to c++ std::map.operator[](): */ \
-ctype##_##tag##_insert(ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey, Value initValue);) \
+STC_API CType##Entry_##tag* /* similar to c++ std::map.insert_or_assign(): */ \
+ctype##_##tag##_put(CType##_##tag* self, OPT_2_##ctype(CType##RawKey_##tag rawKey, Value value)); \
+OPT_1_##ctype(STC_API CType##Entry_##tag* /* similar to c++ std::map.operator[](): */ \
+ctype##_##tag##_insert(CType##_##tag* self, CType##RawKey_##tag rawKey, Value initValue);) \
STC_INLINE void \
-ctype##_##tag##_swap(ctype##_##tag* a, ctype##_##tag* b) { c_swap(ctype##_##tag, *a, *b); } \
+ctype##_##tag##_swap(CType##_##tag* a, CType##_##tag* b) { c_swap(CType##_##tag, *a, *b); } \
STC_API size_t \
-ctype##_##tag##_reserve(ctype##_##tag* self, size_t size); \
+ctype##_##tag##_reserve(CType##_##tag* self, size_t size); \
STC_API bool \
-ctype##_##tag##_eraseEntry(ctype##_##tag* self, ctype##entry_##tag* entry); \
+ctype##_##tag##_eraseEntry(CType##_##tag* self, CType##Entry_##tag* entry); \
STC_API bool \
-ctype##_##tag##_erase(ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey); \
+ctype##_##tag##_erase(CType##_##tag* self, CType##RawKey_##tag rawKey); \
STC_API ctype##_##tag##_iter_t \
-ctype##_##tag##_begin(ctype##_##tag* map); \
+ctype##_##tag##_begin(CType##_##tag* map); \
STC_API ctype##_##tag##_iter_t \
ctype##_##tag##_next(ctype##_##tag##_iter_t it); \
\
-implement_CHASH(tag, ctype, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \
+implement_CHASH(tag, CType, ctype, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \
keyDestroy, RawKey, keyGetRaw, keyInitRaw) \
-typedef Key ctype##_##tag##_key_t; \
-typedef Value ctype##_##tag##_value_t
+typedef Key CType##Key_##tag, ctype##_##tag##_key_t; \
+typedef Value CType##Value_##tag, ctype##_##tag##_value_t
/* -------------------------- IMPLEMENTATION ------------------------- */
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-#define implement_CHASH(tag, ctype, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \
+#define implement_CHASH(tag, CType, ctype, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \
keyDestroy, RawKey, keyGetRaw, keyInitRaw) \
- STC_API ctype##_##tag \
+ STC_API CType##_##tag \
ctype##_##tag##_make(size_t initialSize) { \
- ctype##_##tag h = ctype##_init; \
+ CType##_##tag h = ctype##_init; \
ctype##_##tag##_reserve(&h, initialSize); \
return h; \
} \
STC_API void \
-ctype##_##tag##_pushN(ctype##_##tag* self, const ctype##_##tag##_input_t in[], size_t size) { \
+ctype##_##tag##_pushN(CType##_##tag* self, const CType##Input_##tag in[], size_t size) { \
for (size_t i=0; i<size; ++i) ctype##_##tag##_put(self, OPT_2_##ctype(in[i].key, in[i].value)); \
} \
\
-STC_INLINE void ctype##_##tag##_wipe_(ctype##_##tag* self) { \
+STC_INLINE void ctype##_##tag##_wipe_(CType##_##tag* self) { \
if (self->size == 0) return; \
- ctype##entry_##tag* e = self->table, *end = e + self->bucketCount; \
+ CType##Entry_##tag* e = self->table, *end = e + self->bucketCount; \
uint8_t *hx = self->_hashx; \
for (; e != end; ++e) if (*hx++) ctype##entry_##tag##_destroy(e); \
} \
\
-STC_API void ctype##_##tag##_destroy(ctype##_##tag* self) { \
+STC_API void ctype##_##tag##_destroy(CType##_##tag* self) { \
ctype##_##tag##_wipe_(self); \
free(self->_hashx); \
free(self->table); \
} \
\
-STC_API void ctype##_##tag##_clear(ctype##_##tag* self) { \
+STC_API void ctype##_##tag##_clear(CType##_##tag* self) { \
ctype##_##tag##_wipe_(self); \
self->size = 0; \
memset(self->_hashx, 0, self->bucketCount); \
} \
\
STC_API size_t \
-ctype##_##tag##_bucket(const ctype##_##tag* self, const ctype##_##tag##_rawkey_t* rawKeyPtr, uint32_t* hxPtr) { \
- uint32_t hash = keyHashRaw(rawKeyPtr, sizeof(ctype##_##tag##_rawkey_t)); \
+ctype##_##tag##_bucket(const CType##_##tag* self, const CType##RawKey_##tag* rawKeyPtr, uint32_t* hxPtr) { \
+ uint32_t hash = keyHashRaw(rawKeyPtr, sizeof(CType##RawKey_##tag)); \
uint32_t sx, hx = (hash & chash_HASH) | chash_USED; \
size_t cap = self->bucketCount; \
size_t idx = chash_reduce(hash, cap); \
uint8_t* hashx = self->_hashx; \
while ((sx = hashx[idx])) { \
if (sx == hx) { \
- ctype##_##tag##_rawkey_t r = keyGetRaw(&self->table[idx].key); \
+ CType##RawKey_##tag r = keyGetRaw(&self->table[idx].key); \
if (keyEqualsRaw(&r, rawKeyPtr)) break; \
} \
if (++idx == cap) idx = 0; \
@@ -252,25 +252,25 @@ ctype##_##tag##_bucket(const ctype##_##tag* self, const ctype##_##tag##_rawkey_t return idx; \
} \
\
-STC_API ctype##entry_##tag* \
-ctype##_##tag##_find(const ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey) { \
+STC_API CType##Entry_##tag* \
+ctype##_##tag##_find(const CType##_##tag* self, CType##RawKey_##tag rawKey) { \
if (self->size == 0) return NULL; \
uint32_t hx; \
size_t idx = ctype##_##tag##_bucket(self, &rawKey, &hx); \
return self->_hashx[idx] ? &self->table[idx] : NULL; \
} \
\
-static inline void ctype##_##tag##_reserveExpand_(ctype##_##tag* self) { \
+static inline void ctype##_##tag##_reserveExpand_(CType##_##tag* self) { \
if (self->size + 1 >= self->bucketCount * self->maxLoadFactor) \
ctype##_##tag##_reserve(self, 7 + self->size * 3 / 2); \
} \
\
-STC_API ctype##entry_##tag* \
-ctype##_##tag##_put(ctype##_##tag* self, OPT_2_##ctype(ctype##_##tag##_rawkey_t rawKey, Value value)) { \
+STC_API CType##Entry_##tag* \
+ctype##_##tag##_put(CType##_##tag* self, OPT_2_##ctype(CType##RawKey_##tag rawKey, Value value)) { \
ctype##_##tag##_reserveExpand_(self); \
uint32_t hx; \
size_t idx = ctype##_##tag##_bucket(self, &rawKey, &hx); \
- ctype##entry_##tag* e = &self->table[idx]; \
+ CType##Entry_##tag* e = &self->table[idx]; \
if (self->_hashx[idx]) \
OPT_1_##ctype(valueDestroy(&e->value)) ; \
else { \
@@ -283,12 +283,12 @@ ctype##_##tag##_put(ctype##_##tag* self, OPT_2_##ctype(ctype##_##tag##_rawkey_t } \
\
OPT_1_##ctype( \
-STC_API ctype##entry_##tag* \
-ctype##_##tag##_insert(ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey, Value initValue) { \
+STC_API CType##Entry_##tag* \
+ctype##_##tag##_insert(CType##_##tag* self, CType##RawKey_##tag rawKey, Value initValue) { \
ctype##_##tag##_reserveExpand_(self); \
uint32_t hx; \
size_t idx = ctype##_##tag##_bucket(self, &rawKey, &hx); \
- ctype##entry_##tag* e = &self->table[idx]; \
+ CType##Entry_##tag* e = &self->table[idx]; \
if (! self->_hashx[idx]) { \
e->key = keyInitRaw(rawKey); \
self->_hashx[idx] = (uint8_t) hx; \
@@ -299,24 +299,24 @@ ctype##_##tag##_insert(ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey, Val }) \
\
STC_API size_t \
-ctype##_##tag##_reserve(ctype##_##tag* self, size_t newcap) { \
+ctype##_##tag##_reserve(CType##_##tag* self, size_t newcap) { \
size_t oldcap = self->bucketCount; \
if (self->size > newcap) return oldcap; \
newcap /= self->maxLoadFactor; newcap |= 1; \
- ctype##_##tag tmp = { \
- c_new_N(ctype##entry_##tag, newcap), \
+ CType##_##tag tmp = { \
+ c_new_N(CType##Entry_##tag, newcap), \
(uint8_t *) calloc(newcap, sizeof(uint8_t)), \
self->size, (uint32_t) newcap, \
self->maxLoadFactor, self->shrinkLimitFactor \
}; \
ctype##_##tag##_swap(self, &tmp); \
\
- ctype##entry_##tag* e = tmp.table, *slot = self->table; \
+ CType##Entry_##tag* e = tmp.table, *slot = self->table; \
uint8_t* hashx = self->_hashx; \
uint32_t hx; \
for (size_t i = 0; i < oldcap; ++i, ++e) \
if (tmp._hashx[i]) { \
- ctype##_##tag##_rawkey_t r = keyGetRaw(&e->key); \
+ CType##RawKey_##tag r = keyGetRaw(&e->key); \
size_t idx = ctype##_##tag##_bucket(self, &r, &hx); \
slot[idx] = *e, \
hashx[idx] = (uint8_t) hx; \
@@ -327,11 +327,11 @@ ctype##_##tag##_reserve(ctype##_##tag* self, size_t newcap) { \ } \
\
STC_API bool \
-ctype##_##tag##_eraseEntry(ctype##_##tag* self, ctype##entry_##tag* entry) { \
+ctype##_##tag##_eraseEntry(CType##_##tag* self, CType##Entry_##tag* entry) { \
size_t i = chash_entryIndex(*self, entry), j = i, k, cap = self->bucketCount; \
- ctype##entry_##tag* slot = self->table; \
+ CType##Entry_##tag* slot = self->table; \
uint8_t* hashx = self->_hashx; \
- ctype##_##tag##_rawkey_t r; \
+ CType##RawKey_##tag r; \
if (! hashx[i]) \
return false; \
do { /* deletion from hash table without tombstone */ \
@@ -339,7 +339,7 @@ ctype##_##tag##_eraseEntry(ctype##_##tag* self, ctype##entry_##tag* entry) { \ if (! hashx[j]) \
break; \
r = keyGetRaw(&slot[j].key); \
- k = chash_reduce(keyHashRaw(&r, sizeof(ctype##_##tag##_rawkey_t)), cap); \
+ k = chash_reduce(keyHashRaw(&r, sizeof(CType##RawKey_##tag)), cap); \
if ((j < i) ^ (k <= i) ^ (k > j)) /* is k outside (i, j]? */ \
slot[i] = slot[j], hashx[i] = hashx[j], i = j; \
} while (true); \
@@ -350,11 +350,11 @@ ctype##_##tag##_eraseEntry(ctype##_##tag* self, ctype##entry_##tag* entry) { \ } \
\
STC_API bool \
-ctype##_##tag##_erase(ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey) { \
+ctype##_##tag##_erase(CType##_##tag* self, CType##RawKey_##tag rawKey) { \
if (self->size == 0) \
return false; \
size_t cap = self->bucketCount; \
- if (self->size < cap * self->shrinkLimitFactor && cap * sizeof(ctype##entry_##tag) > 1024) \
+ if (self->size < cap * self->shrinkLimitFactor && cap * sizeof(CType##Entry_##tag) > 1024) \
ctype##_##tag##_reserve(self, self->size * 6 / 5); \
uint32_t hx; \
size_t i = ctype##_##tag##_bucket(self, &rawKey, &hx); \
@@ -362,9 +362,9 @@ ctype##_##tag##_erase(ctype##_##tag* self, ctype##_##tag##_rawkey_t rawKey) { \ } \
\
STC_API ctype##_##tag##_iter_t \
-ctype##_##tag##_begin(ctype##_##tag* map) { \
+ctype##_##tag##_begin(CType##_##tag* map) { \
uint8_t* hx = map->_hashx; \
- ctype##entry_##tag* e = map->table, *end = e + map->bucketCount; \
+ CType##Entry_##tag* e = map->table, *end = e + map->bucketCount; \
while (e != end && !*hx) ++e, ++hx; \
ctype##_##tag##_iter_t it = {e == end ? NULL : e, end, hx}; return it; \
} \
@@ -377,7 +377,7 @@ ctype##_##tag##_next(ctype##_##tag##_iter_t it) { \ }
#else
-#define implement_CHASH(tag, ctype, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \
+#define implement_CHASH(tag, CType, ctype, Key, Value, valueDestroy, keyEqualsRaw, keyHashRaw, \
keyDestroy, RawKey, keyGetRaw, keyInitRaw)
#endif
diff --git a/stc/coption.h b/stc/coption.h new file mode 100644 index 00000000..78500210 --- /dev/null +++ b/stc/coption.h @@ -0,0 +1,173 @@ +/* MIT License
+ *
+ * Copyright (c) 2020 Tyge Løvset, NORCE, www.norceresearch.no
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef COPTION__H__
+#define COPTION__H__
+
+/* Inspired by https://attractivechaos.wordpress.com/2018/08/31/a-survey-of-argument-parsing-libraries-in-c-c
+ Fixed major bugs with option arguments (both long and short).
+ Added arg->faulty output field, and has a more consistent API.
+
+ coption_get() has a very similar interface to GNU's getopt_long(). Each call
+ parses one option and returns the option name. opt->arg points to the option
+ argument if present. The function returns -1 when all command-line arguments
+ are parsed. In this case, opt->ind is the index of the first non-option argument.
+Example:
+ int main(int argc, char *argv[])
+ {
+ COptLong longopts[] = {
+ {"foo", copt_no_argument, 'f'},
+ {"bar", copt_required_argument, 'b'},
+ {"opt", copt_optional_argument, 'o'},
+ {NULL}
+ };
+ const char* optstr = "xy:z::123";
+ printf("program -x -y ARG -z [ARG] -1 -2 -3 --foo --bar ARG --opt [ARG] [ARGUMENTS]\n");
+ int c;
+ COption opt = coption_init;
+ while ((c = coption_get(&opt, argc, argv, optstr, longopts)) != -1) {
+ switch (c) {
+ case '?': printf("error: unknown option: %s\n", opt.faulty); break;
+ case ':': printf("error: missing argument for %s\n", opt.faulty); break;
+ default: printf("option: %c [%s]\n", c, opt.arg ? opt.arg : ""); break;
+ }
+ }
+ printf("\nNon-option arguments:");
+ for (int i = opt.ind; i < argc; ++i)
+ printf(" %s", argv[i]);
+ putchar('\n');
+ return 0;
+ }
+*/
+
+#include <string.h>
+#include <stdbool.h>
+
+enum {
+ copt_no_argument = 0,
+ copt_required_argument = 1,
+ copt_optional_argument = 2
+};
+typedef struct {
+ int ind; /* equivalent to optind */
+ int opt; /* equivalent to optopt */
+ char *arg; /* equivalent to optarg */
+ char *faulty; /* points to the faulty option */
+ int longindex; /* idx of long option; or -1 if short */
+ int _i, _pos, _nargs;
+ char _faulty[4];
+} COption;
+
+typedef struct {
+ char *name;
+ int has_arg;
+ int val;
+} COptLong;
+
+static const COption coption_init = {1, 0, NULL, NULL, -1, 1, 0, 0, {'-', '?', '\0'}};
+
+static void _coption_permute(char *argv[], int j, int n) { /* move argv[j] over n elements to the left */
+ int k;
+ char *p = argv[j];
+ for (k = 0; k < n; ++k)
+ argv[j - k] = argv[j - k - 1];
+ argv[j - k] = p;
+}
+
+/* @param opt output; must be initialized to coption_init on first call
+ * @return ASCII val for a short option; longopt.val for a long option;
+ * -1 if argv[] is fully processed; '?' for an unknown option or
+ * an ambiguous long option; ':' if an option argument is missing
+ */
+static int coption_get(COption *opt, int argc, char *argv[],
+ const char *shortopts, const COptLong *longopts) {
+ int optc = -1, i0, j, posixly_correct = (shortopts[0] == '+');
+ if (!posixly_correct) {
+ while (opt->_i < argc && (argv[opt->_i][0] != '-' || argv[opt->_i][1] == '\0'))
+ ++opt->_i, ++opt->_nargs;
+ }
+ opt->arg = 0, opt->longindex = -1, i0 = opt->_i;
+ if (opt->_i >= argc || argv[opt->_i][0] != '-' || argv[opt->_i][1] == '\0') {
+ opt->ind = opt->_i - opt->_nargs;
+ return -1;
+ }
+ if (argv[opt->_i][0] == '-' && argv[opt->_i][1] == '-') { /* "--" or a long option */
+ if (argv[opt->_i][2] == '\0') { /* a bare "--" */
+ _coption_permute(argv, opt->_i, opt->_nargs);
+ ++opt->_i, opt->ind = opt->_i - opt->_nargs;
+ return -1;
+ }
+ opt->opt = 0, optc = '?', opt->_pos = -1;
+ if (longopts) { /* parse long options */
+ int k, n_exact = 0, n_partial = 0;
+ const COptLong *o = 0, *o_exact = 0, *o_partial = 0;
+ for (j = 2; argv[opt->_i][j] != '\0' && argv[opt->_i][j] != '='; ++j) {} /* find the end of the option name */
+ for (k = 0; longopts[k].name != 0; ++k)
+ if (strncmp(&argv[opt->_i][2], longopts[k].name, j - 2) == 0) {
+ if (longopts[k].name[j - 2] == 0) ++n_exact, o_exact = &longopts[k];
+ else ++n_partial, o_partial = &longopts[k];
+ }
+ opt->faulty = argv[opt->_i];
+ if (n_exact > 1 || (n_exact == 0 && n_partial > 1)) return '?';
+ o = n_exact == 1? o_exact : n_partial == 1? o_partial : 0;
+ if (o) {
+ opt->opt = optc = o->val, opt->longindex = o - longopts;
+ if (o->has_arg != copt_no_argument) {
+ if (argv[opt->_i][j] == '=')
+ opt->arg = &argv[opt->_i][j + 1];
+ else if (argv[opt->_i][j] == '\0' && opt->_i < argc - 1 && (o->has_arg == copt_required_argument ||
+ argv[opt->_i + 1][0] != '-'))
+ opt->arg = argv[++opt->_i];
+ else if (o->has_arg == copt_required_argument)
+ optc = ':'; /* missing option argument */
+ }
+ }
+ }
+ } else { /* a short option */
+ const char *p;
+ if (opt->_pos == 0) opt->_pos = 1;
+ optc = opt->opt = argv[opt->_i][opt->_pos++];
+ opt->_faulty[1] = optc, opt->faulty = opt->_faulty;
+ p = strchr((char *) shortopts, optc);
+ if (p == 0) {
+ optc = '?'; /* unknown option */
+ } else if (p[1] == ':') {
+ if (argv[opt->_i][opt->_pos] != '\0')
+ opt->arg = &argv[opt->_i][opt->_pos];
+ else if (opt->_i < argc - 1 && (p[2] != ':' || argv[opt->_i + 1][0] != '-'))
+ opt->arg = argv[++opt->_i];
+ else if (p[2] != ':')
+ optc = ':';
+ opt->_pos = -1;
+ }
+ }
+ if (opt->_pos < 0 || argv[opt->_i][opt->_pos] == 0) {
+ ++opt->_i, opt->_pos = 0;
+ if (opt->_nargs > 0) /* permute */
+ for (j = i0; j < opt->_i; ++j)
+ _coption_permute(argv, j, opt->_nargs);
+ }
+ opt->ind = opt->_i - opt->_nargs;
+ return optc;
+}
+
+#endif
@@ -31,159 +31,159 @@ #include "cdefs.h"
-typedef struct cstr_t {
+typedef struct CStr {
char* str;
-} cstr_t;
+} CStr;
#define _cstr_rep(self) (((size_t *) (self)->str) - 2)
#define _cstr_size(s) ((size_t *) (s).str)[-2]
#define _cstr_mem(cap) (sizeof(size_t) * (3 + (cap)/sizeof(size_t)))
static size_t _cstr_nullrep[] = {0, 0, 0};
-static cstr_t cstr_init = {(char* ) &_cstr_nullrep[2]};
+static CStr cstr_init = {(char* ) &_cstr_nullrep[2]};
#define cstr_size(s) ((const size_t *) (s).str)[-2]
#define cstr_capacity(s) ((const size_t *) (s).str)[-1]
#define cstr_npos ((size_t) (-1))
-STC_API cstr_t
+STC_API CStr
cstr_makeN(const char* str, size_t len);
-STC_API cstr_t
+STC_API CStr
cstr_from(const char* fmt, ...);
STC_API void
-cstr_reserve(cstr_t* self, size_t cap);
+cstr_reserve(CStr* self, size_t cap);
STC_API void
-cstr_resize(cstr_t* self, size_t len, char fill);
-STC_API cstr_t
+cstr_resize(CStr* self, size_t len, char fill);
+STC_API CStr
cstr_makeReserved(size_t cap);
-STC_API cstr_t*
-cstr_assignN(cstr_t* self, const char* str, size_t len);
-STC_API cstr_t*
-cstr_appendN(cstr_t* self, const char* str, size_t len);
+STC_API CStr*
+cstr_assignN(CStr* self, const char* str, size_t len);
+STC_API CStr*
+cstr_appendN(CStr* self, const char* str, size_t len);
STC_API void
-cstr_insertN(cstr_t* self, size_t pos, const char* str, size_t n);
+cstr_insertN(CStr* self, size_t pos, const char* str, size_t n);
STC_API size_t
-cstr_replaceN(cstr_t* self, size_t pos, const char* str1, size_t n1, const char* str2, size_t n2);
+cstr_replaceN(CStr* self, size_t pos, const char* str1, size_t n1, const char* str2, size_t n2);
STC_API void
-cstr_erase(cstr_t* self, size_t pos, size_t n);
+cstr_erase(CStr* self, size_t pos, size_t n);
STC_API char*
-cstr_strnstr(cstr_t s, size_t pos, const char* needle, size_t n);
+cstr_strnstr(CStr s, size_t pos, const char* needle, size_t n);
STC_INLINE void
-cstr_destroy(cstr_t* self) {
+cstr_destroy(CStr* self) {
if (cstr_capacity(*self)) {
free(_cstr_rep(self));
}
}
-STC_INLINE cstr_t
+STC_INLINE CStr
cstr_makeFilled(size_t len, char fill) {
- cstr_t s = cstr_init;
+ CStr s = cstr_init;
if (len) cstr_resize(&s, len, fill);
return s;
}
-STC_INLINE cstr_t
+STC_INLINE CStr
cstr_make(const char* str) {
return cstr_makeN(str, strlen(str));
}
-STC_INLINE cstr_t
-cstr_makeCopy(cstr_t s) {
+STC_INLINE CStr
+cstr_makeCopy(CStr s) {
return cstr_makeN(s.str, cstr_size(s));
}
STC_INLINE void
-cstr_clear(cstr_t* self) {
+cstr_clear(CStr* self) {
cstr_destroy(self);
*self = cstr_init;
}
-STC_INLINE cstr_t*
-cstr_assign(cstr_t* self, const char* str) {
+STC_INLINE CStr*
+cstr_assign(CStr* self, const char* str) {
return cstr_assignN(self, str, strlen(str));
}
-STC_INLINE cstr_t*
-cstr_copy(cstr_t* self, cstr_t s) {
+STC_INLINE CStr*
+cstr_copy(CStr* self, CStr s) {
return cstr_assignN(self, s.str, cstr_size(s));
}
-STC_INLINE cstr_t*
-cstr_take(cstr_t* self, cstr_t s) {
+STC_INLINE CStr*
+cstr_take(CStr* self, CStr s) {
if (self->str != s.str && cstr_capacity(*self))
free(_cstr_rep(self));
self->str = s.str;
return self;
}
-STC_INLINE cstr_t
-cstr_move(cstr_t* self) {
- cstr_t tmp = *self;
+STC_INLINE CStr
+cstr_move(CStr* self) {
+ CStr tmp = *self;
*self = cstr_init;
return tmp;
}
-STC_INLINE cstr_t*
-cstr_append(cstr_t* self, const char* str) {
+STC_INLINE CStr*
+cstr_append(CStr* self, const char* str) {
return cstr_appendN(self, str, strlen(str));
}
-STC_INLINE cstr_t*
-cstr_appendS(cstr_t* self, cstr_t s) {
+STC_INLINE CStr*
+cstr_appendS(CStr* self, CStr s) {
return cstr_appendN(self, s.str, cstr_size(s));
}
-STC_INLINE cstr_t*
-cstr_pushBack(cstr_t* self, char value) {
+STC_INLINE CStr*
+cstr_pushBack(CStr* self, char value) {
return cstr_appendN(self, &value, 1);
}
STC_INLINE void
-cstr_popBack(cstr_t* self) {
+cstr_popBack(CStr* self) {
--_cstr_size(*self);
}
STC_INLINE char
-cstr_back(cstr_t s) {
+cstr_back(CStr s) {
return s.str[cstr_size(s) - 1];
}
STC_INLINE void
-cstr_insert(cstr_t* self, size_t pos, const char* str) {
+cstr_insert(CStr* self, size_t pos, const char* str) {
cstr_insertN(self, pos, str, strlen(str));
}
STC_INLINE size_t
-cstr_replace(cstr_t* self, size_t pos, const char* str1, const char* str2) {
+cstr_replace(CStr* self, size_t pos, const char* str1, const char* str2) {
return cstr_replaceN(self, pos, str1, strlen(str1), str2, strlen(str2));
}
/* readonly */
STC_INLINE bool
-cstr_empty(cstr_t s) {
+cstr_empty(CStr s) {
return cstr_size(s) == 0;
}
STC_INLINE bool
-cstr_equals(cstr_t s1, const char* str) {
+cstr_equals(CStr s1, const char* str) {
return strcmp(s1.str, str) == 0;
}
STC_INLINE bool
-cstr_equalsS(cstr_t s1, cstr_t s2) {
+cstr_equalsS(CStr s1, CStr s2) {
return strcmp(s1.str, s2.str) == 0;
}
STC_INLINE int
cstr_compare(const void* s1, const void* s2) {
- return strcmp(((const cstr_t*)s1)->str, ((const cstr_t*)s2)->str);
+ return strcmp(((const CStr*)s1)->str, ((const CStr*)s2)->str);
}
STC_INLINE size_t
-cstr_findN(cstr_t s, size_t pos, const char* needle, size_t n) {
+cstr_findN(CStr s, size_t pos, const char* needle, size_t n) {
char* res = cstr_strnstr(s, pos, needle, n);
return res ? res - s.str : cstr_npos;
}
STC_INLINE size_t
-cstr_find(cstr_t s, size_t pos, const char* needle) {
+cstr_find(CStr s, size_t pos, const char* needle) {
char* res = strstr(s.str + pos, needle);
return res ? res - s.str : cstr_npos;
}
-/* CVec / cmap API functions: */
+/* CVec / CMap API functions: */
#define cstr_getRaw(x) ((x)->str)
#define cstr_compareRaw(x, y) strcmp(*(x), *(y))
@@ -200,7 +200,7 @@ STC_INLINE uint32_t cstr_hashRaw(const char* const* sPtr, size_t ignored) { #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
STC_API void
-cstr_reserve(cstr_t* self, size_t cap) {
+cstr_reserve(CStr* self, size_t cap) {
size_t len = cstr_size(*self), oldcap = cstr_capacity(*self);
if (cap > oldcap) {
size_t* rep = (size_t *) realloc(oldcap ? _cstr_rep(self) : NULL, _cstr_mem(cap));
@@ -211,35 +211,35 @@ cstr_reserve(cstr_t* self, size_t cap) { }
STC_API void
-cstr_resize(cstr_t* self, size_t len, char fill) {
+cstr_resize(CStr* self, size_t len, char fill) {
size_t n = cstr_size(*self);
cstr_reserve(self, len);
if (len > n) memset(self->str + n, fill, len - n);
self->str[_cstr_size(*self) = len] = '\0';
}
-STC_API cstr_t
+STC_API CStr
cstr_makeReserved(size_t cap) {
if (cap == 0) return cstr_init;
size_t *rep = (size_t *) malloc(_cstr_mem(cap));
- cstr_t s = {(char *) (rep + 2)};
+ CStr s = {(char *) (rep + 2)};
rep[0] = 0, rep[1] = cap, s.str[0] = '\0';
return s;
}
-STC_API cstr_t
+STC_API CStr
cstr_makeN(const char* str, size_t len) {
if (len == 0) return cstr_init;
size_t *rep = (size_t *) malloc(_cstr_mem(len));
- cstr_t s = {(char *) (rep + 2)};
+ CStr s = {(char *) (rep + 2)};
memcpy(s.str, str, len);
s.str[rep[0] = rep[1] = len] = '\0';
return s;
}
-STC_API cstr_t
+STC_API CStr
cstr_from(const char* fmt, ...) {
- cstr_t tmp = cstr_init;
+ CStr tmp = cstr_init;
va_list args;
va_start(args, fmt);
int len = vsnprintf(NULL, (size_t)0, fmt, args);
@@ -252,8 +252,8 @@ cstr_from(const char* fmt, ...) { return tmp;
}
-STC_API cstr_t*
-cstr_assignN(cstr_t* self, const char* str, size_t len) {
+STC_API CStr*
+cstr_assignN(CStr* self, const char* str, size_t len) {
if (len || cstr_capacity(*self)) {
cstr_reserve(self, len);
memmove(self->str, str, len);
@@ -262,8 +262,8 @@ cstr_assignN(cstr_t* self, const char* str, size_t len) { return self;
}
-STC_API cstr_t*
-cstr_appendN(cstr_t* self, const char* str, size_t len) {
+STC_API CStr*
+cstr_appendN(CStr* self, const char* str, size_t len) {
if (len) {
size_t oldlen = cstr_size(*self), newlen = oldlen + len;
if (newlen > cstr_capacity(*self))
@@ -274,7 +274,7 @@ cstr_appendN(cstr_t* self, const char* str, size_t len) { return self;
}
-STC_INLINE void _cstr_internalMove(cstr_t* self, size_t pos1, size_t pos2) {
+STC_INLINE void _cstr_internalMove(CStr* self, size_t pos1, size_t pos2) {
if (pos1 == pos2)
return;
size_t len = cstr_size(*self), newlen = len + pos2 - pos1;
@@ -285,7 +285,7 @@ STC_INLINE void _cstr_internalMove(cstr_t* self, size_t pos1, size_t pos2) { }
STC_API void
-cstr_insertN(cstr_t* self, size_t pos, const char* str, size_t n) {
+cstr_insertN(CStr* self, size_t pos, const char* str, size_t n) {
char* xstr = (char *) memcpy(n > c_max_alloca ? malloc(n) : alloca(n), str, n);
_cstr_internalMove(self, pos, pos + n);
memcpy(&self->str[pos], xstr, n);
@@ -293,7 +293,7 @@ cstr_insertN(cstr_t* self, size_t pos, const char* str, size_t n) { }
STC_API size_t
-cstr_replaceN(cstr_t* self, size_t pos, const char* str1, size_t n1, const char* str2, size_t n2) {
+cstr_replaceN(CStr* self, size_t pos, const char* str1, size_t n1, const char* str2, size_t n2) {
size_t pos2 = cstr_findN(*self, pos, str1, n1);
if (pos2 == cstr_npos) return cstr_npos;
char* xstr2 = (char *) memcpy(n2 > c_max_alloca ? malloc(n2) : alloca(n2), str2, n2);
@@ -304,7 +304,7 @@ cstr_replaceN(cstr_t* self, size_t pos, const char* str1, size_t n1, const char* }
STC_API void
-cstr_erase(cstr_t* self, size_t pos, size_t n) {
+cstr_erase(CStr* self, size_t pos, size_t n) {
size_t len = cstr_size(*self);
if (len) {
memmove(&self->str[pos], &self->str[pos + n], len - (pos + n));
@@ -313,7 +313,7 @@ cstr_erase(cstr_t* self, size_t pos, size_t n) { }
STC_API char*
-cstr_strnstr(cstr_t s, size_t pos, const char* needle, size_t n) {
+cstr_strnstr(CStr s, size_t pos, const char* needle, size_t n) {
char *x = s.str + pos, /* haystack */
*z = s.str + cstr_size(s) - n + 1;
if (x >= z)
@@ -34,67 +34,67 @@ #define cvec_front(cv) (cv).data[0]
#define cvec_back(cv) (cv).data[_cvec_size(cv) - 1] /* may have side effect */
-#define declare_cvec(...) c_MACRO_OVERLOAD(declare_cvec, __VA_ARGS__)
-#define declare_cvec_2(tag, Value) \
- declare_cvec_3(tag, Value, c_defaultDestroy)
-#define declare_cvec_3(tag, Value, valueDestroy) \
- declare_cvec_4(tag, Value, valueDestroy, c_defaultCompare)
-#define declare_cvec_4(tag, Value, valueDestroy, valueCompare) \
- declare_cvec_6(tag, Value, valueDestroy, valueCompare, Value, c_defaultGetRaw)
-#define declare_cvec_str() \
- declare_cvec_6(str, cstr_t, cstr_destroy, cstr_compareRaw, const char*, cstr_getRaw)
+#define declare_CVec(...) c_MACRO_OVERLOAD(declare_CVec, __VA_ARGS__)
+#define declare_CVec_2(tag, Value) \
+ declare_CVec_3(tag, Value, c_defaultDestroy)
+#define declare_CVec_3(tag, Value, valueDestroy) \
+ declare_CVec_4(tag, Value, valueDestroy, c_defaultCompare)
+#define declare_CVec_4(tag, Value, valueDestroy, valueCompare) \
+ declare_CVec_6(tag, Value, valueDestroy, valueCompare, Value, c_defaultGetRaw)
+#define declare_CVec_str() \
+ declare_CVec_6(str, CStr, cstr_destroy, cstr_compareRaw, const char*, cstr_getRaw)
-#define declare_cvec_6(tag, Value, valueDestroy, valueCompareRaw, RawValue, valueGetRaw) \
+#define declare_CVec_6(tag, Value, valueDestroy, valueCompareRaw, RawValue, valueGetRaw) \
\
-typedef struct cvec_##tag { \
+typedef struct CVec_##tag { \
Value* data; \
-} cvec_##tag; \
+} CVec_##tag; \
\
-STC_INLINE cvec_##tag \
-cvec_##tag##_init(void) {cvec_##tag x = cvec_init; return x;} \
-STC_API cvec_##tag \
+STC_INLINE CVec_##tag \
+cvec_##tag##_init(void) {CVec_##tag x = cvec_init; return x;} \
+STC_API CVec_##tag \
cvec_##tag##_make(size_t size, Value null); \
STC_API void \
-cvec_##tag##_pushN(cvec_##tag *self, const Value in[], size_t size); \
+cvec_##tag##_pushN(CVec_##tag *self, const Value in[], size_t size); \
STC_API void \
-cvec_##tag##_destroy(cvec_##tag* self); \
+cvec_##tag##_destroy(CVec_##tag* self); \
STC_API void \
-cvec_##tag##_reserve(cvec_##tag* self, size_t cap); \
+cvec_##tag##_reserve(CVec_##tag* self, size_t cap); \
STC_API void \
-cvec_##tag##_clear(cvec_##tag* self); \
+cvec_##tag##_clear(CVec_##tag* self); \
STC_API void \
-cvec_##tag##_pushBack(cvec_##tag* self, Value value); \
+cvec_##tag##_pushBack(CVec_##tag* self, Value value); \
STC_INLINE void \
-cvec_##tag##_popBack(cvec_##tag* self) { \
+cvec_##tag##_popBack(CVec_##tag* self) { \
valueDestroy(&self->data[_cvec_size(*self) - 1]); \
--_cvec_size(*self); \
} \
STC_INLINE Value* \
-cvec_##tag##_front(cvec_##tag* self) {return self->data;} \
+cvec_##tag##_front(CVec_##tag* self) {return self->data;} \
STC_INLINE Value* \
-cvec_##tag##_back(cvec_##tag* self) {return self->data + _cvec_size(*self) - 1;} \
+cvec_##tag##_back(CVec_##tag* self) {return self->data + _cvec_size(*self) - 1;} \
STC_INLINE Value* \
-cvec_##tag##_at(cvec_##tag* self, size_t i) {return self->data + i;} \
+cvec_##tag##_at(CVec_##tag* self, size_t i) {return self->data + i;} \
STC_API void \
-cvec_##tag##_insert(cvec_##tag* self, size_t pos, Value value); \
+cvec_##tag##_insert(CVec_##tag* self, size_t pos, Value value); \
STC_API void \
-cvec_##tag##_erase(cvec_##tag* self, size_t pos, size_t size); \
+cvec_##tag##_erase(CVec_##tag* self, size_t pos, size_t size); \
STC_API void \
-cvec_##tag##_sort(cvec_##tag* self); \
+cvec_##tag##_sort(CVec_##tag* self); \
STC_API size_t \
-cvec_##tag##_find(const cvec_##tag* self, RawValue rawValue); \
+cvec_##tag##_find(const CVec_##tag* self, RawValue rawValue); \
STC_INLINE void \
-cvec_##tag##_swap(cvec_##tag* a, cvec_##tag* b) { \
+cvec_##tag##_swap(CVec_##tag* a, CVec_##tag* b) { \
c_swap(Value*, a->data, b->data); \
} \
\
typedef struct { \
Value *item, *end; \
-} cvec_##tag##_iter_t; \
+} CVecIter_##tag, cvec_##tag##_iter_t; \
\
STC_INLINE cvec_##tag##_iter_t \
-cvec_##tag##_begin(cvec_##tag* vec) { \
+cvec_##tag##_begin(CVec_##tag* vec) { \
const size_t n = cvec_size(*vec); \
cvec_##tag##_iter_t it = {n ? vec->data : NULL, vec->data + n}; \
return it; \
@@ -105,32 +105,32 @@ cvec_##tag##_next(cvec_##tag##_iter_t it) { \ return it; \
} \
\
-implement_cvec_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \
-typedef Value cvec_##tag##_value_t, cvec_##tag##_input_t; \
-typedef RawValue cvec_##tag##_rawvalue_t
+implement_CVec_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \
+typedef Value CVecValue_##tag, cvec_##tag##_input_t; \
+typedef RawValue CVecRawValue_##tag
/* -------------------------- IMPLEMENTATION ------------------------- */
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-#define implement_cvec_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \
+#define implement_CVec_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \
\
-STC_API cvec_##tag \
+STC_API CVec_##tag \
cvec_##tag##_make(size_t size, Value null) { \
- cvec_##tag vec = cvec_init; \
+ CVec_##tag vec = cvec_init; \
cvec_##tag##_reserve(&vec, size); \
_cvec_size(vec) = size; \
for (size_t i=0; i<size; ++i) vec.data[i] = null; \
return vec; \
} \
STC_API void \
-cvec_##tag##_pushN(cvec_##tag *self, const Value in[], size_t size) { \
+cvec_##tag##_pushN(CVec_##tag *self, const Value in[], size_t size) { \
cvec_##tag##_reserve(self, cvec_size(*self) + size); \
_cvec_size(*self) += size; \
for (size_t i=0; i<size; ++i) self->data[i] = in[i]; \
} \
\
STC_API void \
-cvec_##tag##_destroy(cvec_##tag* self) { \
+cvec_##tag##_destroy(CVec_##tag* self) { \
Value* p = self->data; \
size_t i = 0, n = cvec_size(*self); \
for (; i < n; ++p, ++i) valueDestroy(p); \
@@ -138,7 +138,7 @@ cvec_##tag##_destroy(cvec_##tag* self) { \ } \
\
STC_API void \
-cvec_##tag##_reserve(cvec_##tag* self, size_t cap) { \
+cvec_##tag##_reserve(CVec_##tag* self, size_t cap) { \
size_t len = cvec_size(*self); \
if (cap >= len) { \
size_t* rep = (size_t *) realloc(_cvec_alloced(self->data), 2 * sizeof(size_t) + cap * sizeof(Value)); \
@@ -149,14 +149,14 @@ cvec_##tag##_reserve(cvec_##tag* self, size_t cap) { \ } \
\
STC_API void \
-cvec_##tag##_clear(cvec_##tag* self) { \
- cvec_##tag cv = cvec_init; \
+cvec_##tag##_clear(CVec_##tag* self) { \
+ CVec_##tag cv = cvec_init; \
cvec_##tag##_destroy(self); \
*self = cv; \
} \
\
STC_API void \
-cvec_##tag##_pushBack(cvec_##tag* self, Value value) { \
+cvec_##tag##_pushBack(CVec_##tag* self, Value value) { \
size_t len = cvec_size(*self); \
if (len == cvec_capacity(*self)) \
cvec_##tag##_reserve(self, 7 + len * 5 / 3); \
@@ -165,7 +165,7 @@ cvec_##tag##_pushBack(cvec_##tag* self, Value value) { \ } \
\
STC_API void \
-cvec_##tag##_insert(cvec_##tag* self, size_t pos, Value value) { \
+cvec_##tag##_insert(CVec_##tag* self, size_t pos, Value value) { \
size_t len = cvec_size(*self); \
if (len == cvec_capacity(*self)) \
cvec_##tag##_reserve(self, 7 + len * 5 / 3); \
@@ -175,7 +175,7 @@ cvec_##tag##_insert(cvec_##tag* self, size_t pos, Value value) { \ } \
\
STC_API void \
-cvec_##tag##_erase(cvec_##tag* self, size_t pos, size_t size) { \
+cvec_##tag##_erase(CVec_##tag* self, size_t pos, size_t size) { \
size_t len = cvec_size(*self); \
if (len) { \
Value* p = &self->data[pos], *start = p, *end = p + size; \
@@ -186,7 +186,7 @@ cvec_##tag##_erase(cvec_##tag* self, size_t pos, size_t size) { \ } \
\
STC_API size_t \
-cvec_##tag##_find(const cvec_##tag* self, RawValue rawValue) { \
+cvec_##tag##_find(const CVec_##tag* self, RawValue rawValue) { \
const Value *p = self->data, *end = p + cvec_size(*self); \
for (; p != end; ++p) { \
RawValue r = valueGetRaw(p); \
@@ -203,13 +203,13 @@ cvec_##tag##_sortCompare(const void* x, const void* y) { \ } \
STC_EXTERN_IMPORT void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*)); \
STC_API void \
-cvec_##tag##_sort(cvec_##tag* self) { \
+cvec_##tag##_sort(CVec_##tag* self) { \
size_t len = cvec_size(*self); \
if (len) qsort(self->data, len, sizeof(Value), cvec_##tag##_sortCompare); \
}
#else
-#define implement_cvec_6(tag, Value, valueDestroy, valueCompareRaw, RawValue, valueGetRaw)
+#define implement_CVec_6(tag, Value, valueDestroy, valueCompareRaw, RawValue, valueGetRaw)
#endif
#if defined(_WIN32) && defined(_DLL)
diff --git a/stc/cvecpq.h b/stc/cvecpq.h index 3256f98a..1d0f390b 100644 --- a/stc/cvecpq.h +++ b/stc/cvecpq.h @@ -25,11 +25,11 @@ #include <stc/cvecpq.h>
#include <stc/crandom.h>
- declare_cvec(i, int);
- declare_cvec_priority_queue(i, >); // min-heap (increasing values)
+ declare_CVec(i, int);
+ declare_CVec_priority_queue(i, >); // min-heap (increasing values)
int main() {
pcg32_random_t pcg = pcg32_seed(1234, 0);
- cvec_i heap = cvec_init;
+ CVec_i heap = cvec_init;
// Push one million random numbers onto the queue.
for (int i=0; i<1000000; ++i)
cvecpq_i_push(&heap, pcg32_random(&pcg));
@@ -47,37 +47,37 @@ #include "cvec.h"
-#define declare_cvec_priority_queue(tag, cmpOpr) /* < or > */ \
+#define declare_CVec_priority_queue(tag, cmpOpr) /* < or > */ \
\
STC_API void \
-cvecpq_##tag##_build(cvec_##tag* self); \
+cvecpq_##tag##_build(CVec_##tag* self); \
STC_API void \
-cvecpq_##tag##_erase(cvec_##tag* self, size_t i); \
-STC_INLINE cvec_##tag##_value_t \
-cvecpq_##tag##_top(cvec_##tag* self) {return self->data[0];} \
+cvecpq_##tag##_erase(CVec_##tag* self, size_t i); \
+STC_INLINE CVecValue_##tag \
+cvecpq_##tag##_top(CVec_##tag* self) {return self->data[0];} \
STC_INLINE void \
-cvecpq_##tag##_pop(cvec_##tag* self) {cvecpq_##tag##_erase(self, 0);} \
+cvecpq_##tag##_pop(CVec_##tag* self) {cvecpq_##tag##_erase(self, 0);} \
STC_API void \
-cvecpq_##tag##_push(cvec_##tag* self, cvec_##tag##_value_t value); \
+cvecpq_##tag##_push(CVec_##tag* self, CVecValue_##tag value); \
STC_API void \
-cvecpq_##tag##_pushN(cvec_##tag *self, const cvec_##tag##_value_t in[], size_t size); \
+cvecpq_##tag##_pushN(CVec_##tag *self, const CVecValue_##tag in[], size_t size); \
\
-implement_cvec_priority_queue(tag, cmpOpr) \
-typedef cvec_##tag##_value_t cvecpq_##tag##_input_t
+implement_CVec_priority_queue(tag, cmpOpr) \
+typedef CVecValue_##tag cvecpq_##tag##_input_t
/* -------------------------- IMPLEMENTATION ------------------------- */
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-#define implement_cvec_priority_queue(tag, cmpOpr) \
+#define implement_CVec_priority_queue(tag, cmpOpr) \
\
STC_INLINE void \
-_cvecpq_##tag##_siftDown(cvec_##tag##_value_t* arr, size_t i, size_t n) { \
+_cvecpq_##tag##_siftDown(CVecValue_##tag* arr, size_t i, size_t n) { \
size_t r = i, c = i << 1; \
while (c <= n) { \
if (c < n && cvec_##tag##_sortCompare(&arr[c], &arr[c + 1]) cmpOpr 0) \
++c; \
if (cvec_##tag##_sortCompare(&arr[r], &arr[c]) cmpOpr 0) { \
- cvec_##tag##_value_t t = arr[r]; arr[r] = arr[c]; arr[r = c] = t; \
+ CVecValue_##tag t = arr[r]; arr[r] = arr[c]; arr[r = c] = t; \
} else \
return; \
c <<= 1; \
@@ -85,7 +85,7 @@ _cvecpq_##tag##_siftDown(cvec_##tag##_value_t* arr, size_t i, size_t n) { \ } \
\
STC_API void \
-cvecpq_##tag##_erase(cvec_##tag* self, size_t i) { \
+cvecpq_##tag##_erase(CVec_##tag* self, size_t i) { \
size_t n = cvec_size(*self) - 1; \
self->data[i] = self->data[n]; \
cvec_##tag##_popBack(self); \
@@ -93,30 +93,30 @@ cvecpq_##tag##_erase(cvec_##tag* self, size_t i) { \ } \
\
STC_API void \
-cvecpq_##tag##_push(cvec_##tag* self, cvec_##tag##_value_t value) { \
+cvecpq_##tag##_push(CVec_##tag* self, CVecValue_##tag value) { \
cvec_##tag##_pushBack(self, value); /* sift-up the value */ \
size_t n = cvec_size(*self), c = n; \
- cvec_##tag##_value_t *arr = self->data - 1; \
+ CVecValue_##tag *arr = self->data - 1; \
for (; c > 1 && cvec_##tag##_sortCompare(&arr[c >> 1], &value) cmpOpr 0; c >>= 1) \
arr[c] = arr[c >> 1]; \
if (c != n) arr[c] = value; \
} \
STC_API void \
-cvecpq_##tag##_pushN(cvec_##tag *self, const cvec_##tag##_value_t in[], size_t size) { \
+cvecpq_##tag##_pushN(CVec_##tag *self, const CVecValue_##tag in[], size_t size) { \
cvec_##tag##_reserve(self, cvec_size(*self) + size); \
for (size_t i=0; i<size; ++i) cvecpq_##tag##_push(self, in[i]); \
} \
\
STC_API void \
-cvecpq_##tag##_build(cvec_##tag* self) { \
+cvecpq_##tag##_build(CVec_##tag* self) { \
size_t n = cvec_size(*self); \
- cvec_##tag##_value_t *arr = self->data - 1; \
+ CVecValue_##tag *arr = self->data - 1; \
for (size_t k = n >> 1; k != 0; --k) \
_cvecpq_##tag##_siftDown(arr, k, n); \
}
#else
-#define implement_cvec_priority_queue(tag, cmpOpr)
+#define implement_CVec_priority_queue(tag, cmpOpr)
#endif
#endif
|
