diff options
| author | Tyge Løvset <[email protected]> | 2020-07-16 17:17:24 +0200 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2020-07-16 17:17:24 +0200 |
| commit | 5f004f4f91b4a383005c763ea925cf655ba2d7c2 (patch) | |
| tree | 9a4d9162edc37f897f07a82ee15f9adf90a39827 | |
| parent | 1d8b2adc084d684b90ec525e342b7a3a159a0474 (diff) | |
| download | STC-modified-5f004f4f91b4a383005c763ea925cf655ba2d7c2.tar.gz STC-modified-5f004f4f91b4a383005c763ea925cf655ba2d7c2.zip | |
CHanged API: Renamed CString to CStr and CVector to CVec. All function names are changed likewise.
| -rw-r--r-- | README.md | 106 | ||||
| -rw-r--r-- | examples/README.md | 12 | ||||
| -rw-r--r-- | examples/advanced.c | 10 | ||||
| -rw-r--r-- | examples/complex.c | 2 | ||||
| -rw-r--r-- | examples/demos.c | 62 | ||||
| -rw-r--r-- | stc/chash.h | 6 | ||||
| -rw-r--r-- | stc/clist.h | 616 | ||||
| -rw-r--r-- | stc/cstring.h | 252 | ||||
| -rw-r--r-- | stc/cvector.h | 166 |
9 files changed, 616 insertions, 616 deletions
@@ -16,15 +16,15 @@ An elegant, typesafe, generic, customizable, user-friendly, consistent, and very 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 CString 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/vector.h>
-declare_CVector(i, int);
+declare_CVec(i, int);
int main(void) {
- CVector_i vec = cvector_init;
- cvector_i_pushBack(&vec, 42);
- cvector_i_destroy(&vec);
+ CVec_i vec = cvec_init;
+ cvec_i_pushBack(&vec, 42);
+ cvec_i_destroy(&vec);
}
```
Motivation
@@ -51,7 +51,7 @@ Because it is headers only, files can simply be included in your program. The fu declare_CHash(ii, int, int); // map
declare_CHash(ix, int64_t); // set
-declare_CVector(i, int);
+declare_CVec(i, int);
...
```
Performance
@@ -90,49 +90,49 @@ Memory efficiency -----------------
The containers are memory efficent, i.e. they occupy as little memory as practical possible.
-- **CString**, **CVector**: Representaion: one pointer size. The size and capacity is stored as part of the heap allocation that also holds the vector elements.
+- **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.
- **CHash set**: Representation: 4 pointers size. The CHash set uses one table of keys, and one table of "used/hash-value", which occupies one byte per bucket.
- **CHash map**: Same as CHash set, 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 memory block.
-CHash and CVector discussion
+CHash and CVec discussion
----------------------------
**CHash** is 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. Still, it is 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 CString as key, as it enables the usage of string literals as key in *put() and *get() functions, instead of requering a constructed CString. 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_CHash(si, CString, int);
+declare_CHash(si, CStr, int);
...
-chash_si_put(&map, cstring_make("mykey"), 12);
+chash_si_put(&map, cstr_make("mykey"), 12);
```
but the main incovenience is with lookup:
```
-CString lookup = cstring_make("mykey");
+CStr lookup = cstr_make("mykey");
int x = chash_si_get(&map, lookup)->value;
-cstring_destroy(&lookup);
+cstr_destroy(&lookup);
```
-To avoid this, use *declare_CHash_string()*:
+To avoid this, use *declare_CHash_str()*:
```
-declare_CHash_string(si, int);
+declare_CHash_str(si, int);
...
CHash_si map = chash_init;
-chash_si_put(&map, "mykey", 12); // constructs a CString key from the const char* internally.
+chash_si_put(&map, "mykey", 12); // constructs a CStr key from the const char* internally.
int x = chash_si_get(&map, "mykey")->value; // no allocation of string key happens here.
chash_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 **CVector**, but only affects the *find()* function currently. See *declare_CVector_string()*.
+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:
-**CHashMap**< **CString**, **CHashMap**< *int*, **CList**< **CArray2**< *float* >>>>
+**CHashMap**< **CStr**, **CHashMap**< *int*, **CList**< **CArray2**< *float* >>>>
-Note: The *chash_sm_destroy(&theMap)* call below, will destroy all the nested containers including the memory allocated for CString keys in theMap object.
+Note: The *chash_sm_destroy(&theMap)* call below, will destroy all the nested containers including the memory allocated for CStr keys in theMap object.
```
#include "stc/cstring.h"
#include "stc/chash.h"
@@ -144,7 +144,7 @@ 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, CArray2_f, carray2_f_destroy, c_noCompare);
declare_CHash(il, int, CList_t2, clist_t2_destroy);
-declare_CHash_string(sm, CHash_il, chash_il_destroy);
+declare_CHash_str(sm, CHash_il, chash_il_destroy);
int main() {
int xdim = 4, ydim = 6;
@@ -170,66 +170,66 @@ int main() { chash_sm_destroy(&theMap); // free up the whole shebang!
}
```
-**CString**
+**CStr**
```
#include "stc/cstring.h"
int main() {
- CString s1 = cstring_make("one-nine-three-seven-five");
+ CStr s1 = cstr_make("one-nine-three-seven-five");
printf("%s.\n", s1.str);
- cstring_insert(&s1, 3, "-two");
+ cstr_insert(&s1, 3, "-two");
printf("%s.\n", s1.str);
- cstring_erase(&s1, 7, 5); // -nine
+ cstr_erase(&s1, 7, 5); // -nine
printf("%s.\n", s1.str);
- cstring_replace(&s1, 0, "seven", "four");
+ cstr_replace(&s1, 0, "seven", "four");
printf("%s.\n", s1.str);
- printf("find: %s\n", s1.str + cstring_find(s1, 0, "four"));
+ printf("find: %s\n", s1.str + cstr_find(s1, 0, "four"));
// reassign:
- cstring_assign(&s1, "one two three four five six seven");
- cstring_append(&s1, " eight");
+ cstr_assign(&s1, "one two three four five six seven");
+ cstr_append(&s1, " eight");
printf("append: %s\n", s1.str);
- cstring_destroy(&s1);
+ cstr_destroy(&s1);
- CString s2 = cstring_makeFmt("Index %d: %f", 123, 4.56);
- cstring_destroy(&s2);
+ CStr s2 = cstr_makeFmt("Index %d: %f", 123, 4.56);
+ cstr_destroy(&s2);
}
```
-**CVector** of *int64_t*
+**CVec** of *int64_t*
```
#include "stc/cvector.h"
-declare_CVector(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() {
- CVector_ix bignums = cvector_init; // = (CVector_ix) cvector_init; if initializing after declaration.
- cvector_ix_reserve(&bignums, 100);
+ 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)
- cvector_ix_pushBack(&bignums, i * i * i);
- cvector_ix_popBack(&bignums); // erase the last
+ cvec_ix_pushBack(&bignums, i * i * i);
+ cvec_ix_popBack(&bignums); // erase the last
uint64_t value;
- for (size_t i = 0; i < cvector_size(bignums); ++i)
+ for (size_t i = 0; i < cvec_size(bignums); ++i)
value = bignums.data[i];
- cvector_ix_destroy(&bignums);
+ cvec_ix_destroy(&bignums);
}
```
-**CVector** of *CString*
+**CVec** of *CStr*
```
#include "stc/cstring.h"
#include "stc/cvector.h"
-declare_CVector_string(cs);
+declare_CVec_str(cs);
int main() {
- CVector_cs names = cvector_init;
- cvector_cs_pushBack(&names, cstring_make("Mary"));
- cvector_cs_pushBack(&names, cstring_make("Joe"));
- cstring_assign(&names.data[1], cstring_make("Jake")); // replace Joe
+ CVec_cs names = cvec_init;
+ cvec_cs_pushBack(&names, cstr_make("Mary"));
+ cvec_cs_pushBack(&names, cstr_make("Joe"));
+ cstr_assign(&names.data[1], cstr_make("Jake")); // replace Joe
printf("%s\n", names.data[1].str); // Access the string char*
- cvector_cs_destroy(&names);
+ cvec_cs_destroy(&names);
}
```
**CHash map** of *int -> int*
@@ -247,11 +247,11 @@ int main() { chash_ii_destroy(&nums);
}
```
-**CHash set** of *CString*
+**CHash set** of *CStr*
```
#include "stc/cstring.h"
#include "stc/chash.h"
-declare_CHash_string(s); // CString set. See the discussion above.
+declare_CHash_str(s); // CStr set. See the discussion above.
int main() {
CHash_s words = chash_init;
@@ -265,21 +265,21 @@ int main() { chash_s_destroy(&words);
}
```
-**CHash map** of *CString -> CString*. Temporary CString values are created by *cstring_make()*, and moved into the container
+**CHash map** of *CStr -> CStr*. Temporary CStr values are created by *cstr_make()*, and moved into the container
```
#include "stc/cstring.h"
#include "stc/chash.h"
-declare_CHash_string(ss, CString, cstring_destroy);
+declare_CHash_str(ss, CStr, cstr_destroy);
int main() {
CHash_ss table = chash_init;
- chash_ss_put(&table, "Make", cstring_make("my"));
- chash_ss_put(&table, "Sunny", cstring_make("day"));
+ chash_ss_put(&table, "Make", cstr_make("my"));
+ chash_ss_put(&table, "Sunny", cstr_make("day"));
printf("Sunny: %s\n", chash_ss_get(table, "Sunny")->value.str);
chash_ss_erase(&table, "Make");
printf("size %d\n", chash_size(table));
- chash_ss_destroy(&table); // frees key and value CStrings, and hash table (CVector).
+ chash_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()*.
diff --git a/examples/README.md b/examples/README.md index 3658076c..b77fb94e 100644 --- a/examples/README.md +++ b/examples/README.md @@ -13,7 +13,7 @@ This demonstrates how to customize **CHash map** with a user-defined key-type. Y 2. A comparison function for equality;
When your key type consists of several members, you will usually have the hash function calculate hash values for the individual members, and then somehow combine them into one hash value for the entire object.
-If your key-type stores dynamic memory (e.g. CString as we will use), it is smart to define a plain-old-data "view" of the your key struct first:
+If your key-type stores dynamic memory (e.g. CStr as we will use), it is smart to define a plain-old-data "view" of the your key struct first:
```
#include <stdio.h>
#include <stc/chash.h>
@@ -40,21 +40,21 @@ int vikingvw_equals(const VikingVw* x, const VikingVw* y) { And then the Viking data struct:
```
typedef struct Viking {
- CString name;
- CString country;
+ CStr name;
+ CStr country;
} Viking;
void viking_destroy(Viking* vk) {
- cstring_destroy(&vk->name);
- cstring_destroy(&vk->country);
+ cstr_destroy(&vk->name);
+ cstr_destroy(&vk->country);
}
VikingVw viking_getVw(Viking* vk) {
VikingVw vw = {vk->name.str, vk->country.str}; return vw;
}
Viking viking_fromVw(VikingVw vw) {
- Viking vk = {cstring_make(vw.name), cstring_make(vw.country)}; return vk;
+ Viking vk = {cstr_make(vw.name), cstr_make(vw.country)}; return vk;
}
```
diff --git a/examples/advanced.c b/examples/advanced.c index cd86b21d..e8b62fe2 100644 --- a/examples/advanced.c +++ b/examples/advanced.c @@ -34,21 +34,21 @@ int vikingvw_equals(const VikingVw* x, const VikingVw* y) { // Viking data struct ----------------------- typedef struct Viking { - CString name; - CString country; + CStr name; + CStr country; } Viking; void viking_destroy(Viking* vk) { - cstring_destroy(&vk->name); - cstring_destroy(&vk->country); + cstr_destroy(&vk->name); + cstr_destroy(&vk->country); } VikingVw viking_getVw(Viking* vk) { VikingVw vw = {vk->name.str, vk->country.str}; return vw; } Viking viking_fromVw(VikingVw vw) { - Viking vk = {cstring_make(vw.name), cstring_make(vw.country)}; return vk; + Viking vk = {cstr_make(vw.name), cstr_make(vw.country)}; return vk; } diff --git a/examples/complex.c b/examples/complex.c index 8c44f6cc..3ecf6a1f 100644 --- a/examples/complex.c +++ b/examples/complex.c @@ -8,7 +8,7 @@ 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, CArray2_f, carray2_f_destroy, c_noCompare);
declare_CHash(il, int, CList_t2, clist_t2_destroy);
-declare_CHash_string(sm, CHash_il, chash_il_destroy);
+declare_CHash_str(sm, CHash_il, chash_il_destroy);
int main() {
int xdim = 4, ydim = 6;
diff --git a/examples/demos.c b/examples/demos.c index 2705257b..20ecd3a0 100644 --- a/examples/demos.c +++ b/examples/demos.c @@ -8,68 +8,68 @@ void stringdemo1()
{
printf("\nSTRINGDEMO1\n");
- CString cs = cstring_make("one-nine-three-seven-five");
+ CStr cs = cstr_make("one-nine-three-seven-five");
printf("%s.\n", cs.str);
- cstring_insert(&cs, 3, "-two");
+ cstr_insert(&cs, 3, "-two");
printf("%s.\n", cs.str);
- cstring_erase(&cs, 7, 5); // -nine
+ cstr_erase(&cs, 7, 5); // -nine
printf("%s.\n", cs.str);
- cstring_replace(&cs, 0, "seven", "four");
+ cstr_replace(&cs, 0, "seven", "four");
printf("%s.\n", cs.str);
- cstring_take(&cs, cstring_makeFmt("%s *** %s", cs.str, cs.str));
+ cstr_take(&cs, cstr_makeFmt("%s *** %s", cs.str, cs.str));
printf("%s.\n", cs.str);
- printf("find: %s\n", cs.str + cstring_find(cs, 0, "four"));
+ printf("find: %s\n", cs.str + cstr_find(cs, 0, "four"));
// reassign:
- cstring_assign(&cs, "one two three four five six seven");
- cstring_append(&cs, " eight");
+ cstr_assign(&cs, "one two three four five six seven");
+ cstr_append(&cs, " eight");
printf("append: %s\n", cs.str);
- cstring_destroy(&cs);
+ cstr_destroy(&cs);
}
-declare_CVector(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");
- CVector_ix bignums = cvector_init; // = (CVector_ix) cvector_init; if initializing after declaration.
- cvector_ix_reserve(&bignums, 100);
+ 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)
- cvector_ix_pushBack(&bignums, i * i * i);
+ cvec_ix_pushBack(&bignums, i * i * i);
printf("erase - %d: %zu\n", 100, bignums.data[100]);
- cvector_ix_popBack(&bignums); // erase the last
+ cvec_ix_popBack(&bignums); // erase the last
- for (size_t i = 0; i < cvector_size(bignums); ++i) {
+ for (size_t i = 0; i < cvec_size(bignums); ++i) {
if (i >= 90) printf("%zu: %zu\n", i, bignums.data[i]);
}
- cvector_ix_destroy(&bignums);
+ cvec_ix_destroy(&bignums);
}
-declare_CVector(cs, CString, cstring_destroy, cstring_compare); // supply inline destructor of values
+declare_CVec(cs, CStr, cstr_destroy, cstr_compare); // supply inline destructor of values
void vectordemo2()
{
printf("\nVECTORDEMO2\n");
- CVector_cs names = cvector_init;
- cvector_cs_pushBack(&names, cstring_make("Mary"));
- cvector_cs_pushBack(&names, cstring_make("Joe"));
- cvector_cs_pushBack(&names, cstring_make("Chris"));
- cstring_assign(&names.data[1], "Jane"); // replace Joe
+ 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"));
+ cstr_assign(&names.data[1], "Jane"); // replace Joe
printf("names[1]: %s\n", names.data[1].str);
- cvector_cs_sort(&names); // Sort the array
- c_foreach (i, cvector_cs, names)
+ cvec_cs_sort(&names); // Sort the array
+ c_foreach (i, cvec_cs, names)
printf("sorted: %s\n", i.item->str);
- cvector_cs_destroy(&names);
+ cvec_cs_destroy(&names);
}
declare_CList(ix, int);
@@ -128,7 +128,7 @@ void mapdemo1() }
-declare_CHash_string(si, int); // Shorthand macro for the general declare_CHash expansion.
+declare_CHash_str(si, int); // Shorthand macro for the general declare_CHash expansion.
void mapdemo2()
{
@@ -150,15 +150,15 @@ void mapdemo2() }
-declare_CHash_string(ss, CString, cstring_destroy);
+declare_CHash_str(ss, CStr, cstr_destroy);
void mapdemo3()
{
printf("\nMAPDEMO3\n");
CHash_ss table = chash_init;
- chash_ss_put(&table, "Map", cstring_make("test"));
- chash_ss_put(&table, "Make", cstring_make("my"));
- chash_ss_put(&table, "Sunny", cstring_make("day"));
+ chash_ss_put(&table, "Map", cstr_make("test"));
+ chash_ss_put(&table, "Make", cstr_make("my"));
+ chash_ss_put(&table, "Sunny", cstr_make("day"));
CHashEntry_ss *e = chash_ss_get(&table, "Make");
printf("size %zu: remove: Make: %s\n", chash_size(table), e->value.str);
chash_ss_erase(&table, "Make");
@@ -167,7 +167,7 @@ void mapdemo3() printf("size %zu\n", chash_size(table));
c_foreach (i, chash_ss, table)
printf("entry: %s: %s\n", i.item->key.str, i.item->value.str);
- chash_ss_destroy(&table); // frees key and value CStrings, and hash table (CVector).
+ chash_ss_destroy(&table); // frees key and value CStrs, and hash table (CVec).
}
diff --git a/stc/chash.h b/stc/chash.h index aa6ceadc..e6143b5e 100644 --- a/stc/chash.h +++ b/stc/chash.h @@ -99,7 +99,7 @@ enum {chash_HASH = 0x7f, chash_USED = 0x80}; keyDestroy, Key, c_defaultGetRaw, c_defaultInitRaw)
/* CHash_string: */
-#define declare_CHash_string(...) \
+#define declare_CHash_str(...) \
c_MACRO_OVERLOAD(declare_CHash_string, __VA_ARGS__)
#define declare_CHash_string_1(tag) \
@@ -112,8 +112,8 @@ enum {chash_HASH = 0x7f, chash_USED = 0x80}; declare_CHash_string_4(tag, MAP, Value, ValueDestroy)
#define declare_CHash_string_4(tag, type, Value, valueDestroy) \
- declare_CHash_11(tag, type, CString, Value, valueDestroy, cstring_hashRaw, cstring_equalsRaw, \
- cstring_destroy, const char*, cstring_getRaw, cstring_make)
+ declare_CHash_11(tag, type, CStr, Value, valueDestroy, cstr_hashRaw, cstr_equalsRaw, \
+ cstr_destroy, const char*, cstr_getRaw, cstr_make)
#define _chash1_SET(x)
#define _chash2_SET(x, y) x
diff --git a/stc/clist.h b/stc/clist.h index 4dcd6e26..24353af1 100644 --- a/stc/clist.h +++ b/stc/clist.h @@ -1,308 +1,308 @@ -/* 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 CLIST__H__ -#define CLIST__H__ - -#include <stdlib.h> -#include "cdefs.h" - -/* Circular Singly-linked Lists. - - This implements a std::forward_list-like class in C, but because it is circular, - it also support push* and splice* at both ends of the list. This makes it ideal - for being used as a queue, unlike std::forward_list. Basic usage is similar to CVector: - - #include "stc/clist.h" - declare_CList(i, int64_t); - - int main() { - CList_i list = clist_init; - int n; - for (int i=0; i<1000000; ++i) // one million - clist_i_pushBack(&list, rand() * rand()); - n = 0; - c_foreach (i, clist_i, list) - if (++n % 10000 == 0) printf("%d: %zd\n", n, i.item->value); - // Sort them... - clist_i_sort(&list); // mergesort O(n*log n) - n = 0; - c_foreach (i, clist_i, list) - if (++n % 10000 == 0) printf("%d: %zd\n", n, i.item->value); - clist_i_destroy(&list); - } -*/ - -#define declare_CList(...) c_MACRO_OVERLOAD(declare_CList, __VA_ARGS__) - -#define declare_CList_2(tag, Value) \ - declare_CList_3(tag, Value, c_emptyDestroy) -#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_string(tag) \ - declare_CList_6(tag, CString, cstring_destroy, const char*, cstring_compareRaw, cstring_getRaw) - -#define declare_CListTypes(tag, Value) \ - typedef struct CListNode_##tag { \ - struct CListNode_##tag *next; \ - Value value; \ - } CListNode_##tag; \ - \ - typedef struct CList_##tag { \ - CListNode_##tag *last; \ - } CList_##tag; \ - \ - typedef struct { \ - CListNode_##tag *item, **_last; \ - } CListIter_##tag, clist_##tag##_iter_t - -#define clist_init {NULL} -#define clist_front(list) (list).last->next->value -#define clist_back(list) (list).last->value -#define clist_empty(list) ((list).last == NULL) - - -#define declare_CList_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \ - \ - declare_CListTypes(tag, Value); \ - \ - STC_API void \ - clist_##tag##_destroy(CList_##tag* self); \ - STC_API void \ - clist_##tag##_pushBack(CList_##tag* self, Value value); \ - STC_API void \ - clist_##tag##_pushFront(CList_##tag* self, Value value); \ - STC_API void \ - clist_##tag##_popFront(CList_##tag* self); \ - STC_API void \ - 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); \ - STC_API void \ - 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); \ - STC_API clist_##tag##_iter_t \ - clist_##tag##_findBefore(CList_##tag* self, RawValue val); \ - STC_API Value* \ - clist_##tag##_find(CList_##tag* self, RawValue val); \ - STC_API clist_##tag##_iter_t \ - clist_##tag##_remove(CList_##tag* self, RawValue val); \ - STC_API void \ - clist_##tag##_sort(CList_##tag* self); \ - \ - static inline clist_##tag##_iter_t \ - 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; \ - } \ - static inline clist_##tag##_iter_t \ - clist_##tag##_next(clist_##tag##_iter_t it) { \ - it.item = it.item == *it._last ? NULL : it.item->next; return it; \ - } \ - static inline clist_##tag##_iter_t \ - 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 CListRawValue_##tag; \ - typedef Value CListValue_##tag - - -/* -------------------------- IMPLEMENTATION ------------------------- */ - -#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) -#define implement_CList_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \ - \ - STC_API void \ - 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_insertAfter(self, tag, self->last, value); \ - self->last = entry; \ - } \ - STC_API void \ - 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##_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_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_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) { \ - if (!pos.item) \ - self->last = pos.item = other->last; \ - else if (other->last) { \ - 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; \ - } \ - other->last = NULL; \ - } \ - STC_API void \ - 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##_splice(self, pos, other, true); \ - } \ - \ - STC_API clist_##tag##_iter_t \ - 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); \ - if (valueCompareRaw(&r, &val) == 0) { \ - return prev; \ - } \ - prev = i; \ - } \ - prev.item = NULL; return prev; \ - } \ - \ - STC_API Value* \ - 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##_iter_t it = clist_##tag##_findBefore(self, val); \ - if (it.item) clist_##tag##_eraseAfter(self, it); \ - return it; \ - } \ - \ - static inline int \ - clist_##tag##_sortCmp(const void* x, const void* y) { \ - 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##_sortCmp); \ - self->last = (CListNode_##tag *) last; \ - } - -#define _clist_insertAfter(self, tag, node, val) \ - CListNode_##tag *entry = c_new (CListNode_##tag), \ - *next = self->last ? node->next : entry; \ - entry->value = val; \ - entry->next = next; \ - if (node) node->next = entry - /* +: set self->last based on node */ - -#define _clist_eraseAfter(self, tag, node, valueDestroy) \ - 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); - -/* 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; - int insize = 1, nmerges, psize, qsize, i; - if (!list) return NULL; - - while (1) { - p = list; - oldhead = list; - list = tail = NULL; - nmerges = 0; - - while (p) { - ++nmerges; - q = p; - psize = 0; - for (i = 0; i < insize; ++i) { - ++psize; - q = (q->next == oldhead ? NULL : q->next); - if (!q) break; - } - qsize = insize; - - while (psize > 0 || (qsize > 0 && q)) { - if (psize == 0) { - e = q; q = q->next; --qsize; - if (q == oldhead) q = NULL; - } else if (qsize == 0 || !q) { - e = p; p = p->next; --psize; - if (p == oldhead) p = NULL; - } else if (cmp(p, q) <= 0) { - e = p; p = p->next; --psize; - if (p == oldhead) p = NULL; - } else { - e = q; q = q->next; --qsize; - if (q == oldhead) q = NULL; - } - if (tail) - tail->next = e; - else - list = e; - tail = e; - } - p = q; - } - tail->next = list; - - if (nmerges <= 1) - return tail; - - insize *= 2; - } -} - -#else -#define implement_CList_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) -#endif - -#endif +/* 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 CLIST__H__
+#define CLIST__H__
+
+#include <stdlib.h>
+#include "cdefs.h"
+
+/* Circular Singly-linked Lists.
+
+ This implements a std::forward_list-like class in C, but because it is circular,
+ it also support push* and splice* at both ends of the list. This makes it ideal
+ for being used as a queue, unlike std::forward_list. Basic usage is similar to CVec:
+
+ #include "stc/clist.h"
+ declare_CList(i, int64_t);
+
+ int main() {
+ CList_i list = clist_init;
+ int n;
+ for (int i=0; i<1000000; ++i) // one million
+ clist_i_pushBack(&list, rand() * rand());
+ n = 0;
+ c_foreach (i, clist_i, list)
+ if (++n % 10000 == 0) printf("%d: %zd\n", n, i.item->value);
+ // Sort them...
+ clist_i_sort(&list); // mergesort O(n*log n)
+ n = 0;
+ c_foreach (i, clist_i, list)
+ if (++n % 10000 == 0) printf("%d: %zd\n", n, i.item->value);
+ clist_i_destroy(&list);
+ }
+*/
+
+#define declare_CList(...) c_MACRO_OVERLOAD(declare_CList, __VA_ARGS__)
+
+#define declare_CList_2(tag, Value) \
+ declare_CList_3(tag, Value, c_emptyDestroy)
+#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(tag) \
+ declare_CList_6(tag, CStr, cstr_destroy, const char*, cstr_compareRaw, cstr_getRaw)
+
+#define declare_CListTypes(tag, Value) \
+ typedef struct CListNode_##tag { \
+ struct CListNode_##tag *next; \
+ Value value; \
+ } CListNode_##tag; \
+ \
+ typedef struct CList_##tag { \
+ CListNode_##tag *last; \
+ } CList_##tag; \
+ \
+ typedef struct { \
+ CListNode_##tag *item, **_last; \
+ } CListIter_##tag, clist_##tag##_iter_t
+
+#define clist_init {NULL}
+#define clist_front(list) (list).last->next->value
+#define clist_back(list) (list).last->value
+#define clist_empty(list) ((list).last == NULL)
+
+
+#define declare_CList_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \
+ \
+ declare_CListTypes(tag, Value); \
+ \
+ STC_API void \
+ clist_##tag##_destroy(CList_##tag* self); \
+ STC_API void \
+ clist_##tag##_pushBack(CList_##tag* self, Value value); \
+ STC_API void \
+ clist_##tag##_pushFront(CList_##tag* self, Value value); \
+ STC_API void \
+ clist_##tag##_popFront(CList_##tag* self); \
+ STC_API void \
+ 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); \
+ STC_API void \
+ 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); \
+ STC_API clist_##tag##_iter_t \
+ clist_##tag##_findBefore(CList_##tag* self, RawValue val); \
+ STC_API Value* \
+ clist_##tag##_find(CList_##tag* self, RawValue val); \
+ STC_API clist_##tag##_iter_t \
+ clist_##tag##_remove(CList_##tag* self, RawValue val); \
+ STC_API void \
+ clist_##tag##_sort(CList_##tag* self); \
+ \
+ static inline clist_##tag##_iter_t \
+ 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; \
+ } \
+ static inline clist_##tag##_iter_t \
+ clist_##tag##_next(clist_##tag##_iter_t it) { \
+ it.item = it.item == *it._last ? NULL : it.item->next; return it; \
+ } \
+ static inline clist_##tag##_iter_t \
+ 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 CListRawValue_##tag; \
+ typedef Value CListValue_##tag
+
+
+/* -------------------------- IMPLEMENTATION ------------------------- */
+
+#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
+#define implement_CList_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \
+ \
+ STC_API void \
+ 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_insertAfter(self, tag, self->last, value); \
+ self->last = entry; \
+ } \
+ STC_API void \
+ 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##_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_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_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) { \
+ if (!pos.item) \
+ self->last = pos.item = other->last; \
+ else if (other->last) { \
+ 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; \
+ } \
+ other->last = NULL; \
+ } \
+ STC_API void \
+ 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##_splice(self, pos, other, true); \
+ } \
+ \
+ STC_API clist_##tag##_iter_t \
+ 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); \
+ if (valueCompareRaw(&r, &val) == 0) { \
+ return prev; \
+ } \
+ prev = i; \
+ } \
+ prev.item = NULL; return prev; \
+ } \
+ \
+ STC_API Value* \
+ 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##_iter_t it = clist_##tag##_findBefore(self, val); \
+ if (it.item) clist_##tag##_eraseAfter(self, it); \
+ return it; \
+ } \
+ \
+ static inline int \
+ clist_##tag##_sortCmp(const void* x, const void* y) { \
+ 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##_sortCmp); \
+ self->last = (CListNode_##tag *) last; \
+ }
+
+#define _clist_insertAfter(self, tag, node, val) \
+ CListNode_##tag *entry = c_new (CListNode_##tag), \
+ *next = self->last ? node->next : entry; \
+ entry->value = val; \
+ entry->next = next; \
+ if (node) node->next = entry
+ /* +: set self->last based on node */
+
+#define _clist_eraseAfter(self, tag, node, valueDestroy) \
+ 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);
+
+/* 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;
+ int insize = 1, nmerges, psize, qsize, i;
+ if (!list) return NULL;
+
+ while (1) {
+ p = list;
+ oldhead = list;
+ list = tail = NULL;
+ nmerges = 0;
+
+ while (p) {
+ ++nmerges;
+ q = p;
+ psize = 0;
+ for (i = 0; i < insize; ++i) {
+ ++psize;
+ q = (q->next == oldhead ? NULL : q->next);
+ if (!q) break;
+ }
+ qsize = insize;
+
+ while (psize > 0 || (qsize > 0 && q)) {
+ if (psize == 0) {
+ e = q; q = q->next; --qsize;
+ if (q == oldhead) q = NULL;
+ } else if (qsize == 0 || !q) {
+ e = p; p = p->next; --psize;
+ if (p == oldhead) p = NULL;
+ } else if (cmp(p, q) <= 0) {
+ e = p; p = p->next; --psize;
+ if (p == oldhead) p = NULL;
+ } else {
+ e = q; q = q->next; --qsize;
+ if (q == oldhead) q = NULL;
+ }
+ if (tail)
+ tail->next = e;
+ else
+ list = e;
+ tail = e;
+ }
+ p = q;
+ }
+ tail->next = list;
+
+ if (nmerges <= 1)
+ return tail;
+
+ insize *= 2;
+ }
+}
+
+#else
+#define implement_CList_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw)
+#endif
+
+#endif
diff --git a/stc/cstring.h b/stc/cstring.h index 5ce9b868..8380e8dd 100644 --- a/stc/cstring.h +++ b/stc/cstring.h @@ -31,28 +31,28 @@ #include "cdefs.h"
-typedef struct CString {
+typedef struct CStr {
char* str;
-} CString;
+} CStr;
-static size_t _cstring_nullrep[] = {0, 0, 0};
-#define _cstring_rep(self) (((size_t *) (self)->str) - 2)
-#define _cstring_size(s) ((size_t *) (s).str)[-2]
-#define _cstring_mem(cap) (sizeof(size_t) * (3 + (cap)/sizeof(size_t)))
+static size_t _cstr_nullrep[] = {0, 0, 0};
+#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)))
-#define cstring_size(s) ((const size_t *) (s).str)[-2]
-#define cstring_capacity(s) ((const size_t *) (s).str)[-1]
-#define cstring_npos ((size_t) (-1))
+#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))
-static const CString cstring_init = {(char* ) &_cstring_nullrep[2]};
+static const CStr cstr_init = {(char* ) &_cstr_nullrep[2]};
static inline void
-cstring_reserve(CString* self, size_t cap) {
- size_t len = cstring_size(*self), oldcap = cstring_capacity(*self);
+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 ? _cstring_rep(self) : NULL, _cstring_mem(cap));
+ size_t* rep = (size_t *) realloc(oldcap ? _cstr_rep(self) : NULL, _cstr_mem(cap));
self->str = (char *) (rep + 2);
self->str[rep[0] = len] = '\0';
rep[1] = cap;
@@ -60,67 +60,67 @@ cstring_reserve(CString* self, size_t cap) { }
static inline void
-cstring_resize(CString* self, size_t len, char fill) {
- size_t n = cstring_size(*self);
- cstring_reserve(self, len);
+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[_cstring_size(*self) = len] = '\0';
+ self->str[_cstr_size(*self) = len] = '\0';
}
static inline void
-cstring_destroy(CString* self) {
- if (cstring_capacity(*self)) {
- free(_cstring_rep(self));
+cstr_destroy(CStr* self) {
+ if (cstr_capacity(*self)) {
+ free(_cstr_rep(self));
}
}
-static inline CString
-cstring_makeFilled(size_t len, char fill) {
- CString s = cstring_init;
- if (len) cstring_resize(&s, len, fill);
+static inline CStr
+cstr_makeFilled(size_t len, char fill) {
+ CStr s = cstr_init;
+ if (len) cstr_resize(&s, len, fill);
return s;
}
-static inline CString
-cstring_makeReserved(size_t cap) {
- if (cap == 0) return cstring_init;
- size_t *rep = (size_t *) malloc(_cstring_mem(cap));
- CString s = {(char *) (rep + 2)};
+static inline CStr
+cstr_makeReserved(size_t cap) {
+ if (cap == 0) return cstr_init;
+ size_t *rep = (size_t *) malloc(_cstr_mem(cap));
+ CStr s = {(char *) (rep + 2)};
rep[0] = 0, rep[1] = cap, s.str[0] = '\0';
return s;
}
-static inline CString
-cstring_makeN(const char* str, size_t len) {
- if (len == 0) return cstring_init;
- size_t *rep = (size_t *) malloc(_cstring_mem(len));
- CString s = {(char *) (rep + 2)};
+static inline 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 s = {(char *) (rep + 2)};
memcpy(s.str, str, len);
s.str[rep[0] = rep[1] = len] = '\0';
return s;
}
-static inline CString
-cstring_make(const char* str) {
- return cstring_makeN(str, strlen(str));
+static inline CStr
+cstr_make(const char* str) {
+ return cstr_makeN(str, strlen(str));
}
-static inline CString
-cstring_makeCopy(CString s) {
- return cstring_makeN(s.str, cstring_size(s));
+static inline CStr
+cstr_makeCopy(CStr s) {
+ return cstr_makeN(s.str, cstr_size(s));
}
-static inline CString
-cstring_makeFmt(const char* fmt, ...) {
- CString tmp = cstring_init;
+static inline CStr
+cstr_makeFmt(const char* fmt, ...) {
+ CStr tmp = cstr_init;
int len;
va_list args;
va_start(args, fmt);
len = vsnprintf(NULL, (size_t)0, fmt, args);
if (len > 0) {
- tmp = cstring_makeReserved(len);
+ tmp = cstr_makeReserved(len);
vsprintf(tmp.str, fmt, args);
- _cstring_size(tmp) = len;
+ _cstr_size(tmp) = len;
}
va_end(args);
return tmp;
@@ -128,162 +128,162 @@ cstring_makeFmt(const char* fmt, ...) { static inline void
-cstring_clear(CString* self) {
- cstring_destroy(self);
- *self = cstring_init;
+cstr_clear(CStr* self) {
+ cstr_destroy(self);
+ *self = cstr_init;
}
-static inline CString*
-cstring_assignN(CString* self, const char* str, size_t len) {
- if (len || cstring_capacity(*self)) {
- cstring_reserve(self, len);
+static inline 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);
- self->str[_cstring_size(*self) = len] = '\0';
+ self->str[_cstr_size(*self) = len] = '\0';
}
return self;
}
-static inline CString*
-cstring_assign(CString* self, const char* str) {
- return cstring_assignN(self, str, strlen(str));
+static inline CStr*
+cstr_assign(CStr* self, const char* str) {
+ return cstr_assignN(self, str, strlen(str));
}
-static inline CString*
-cstring_copy(CString* self, CString s) {
- return cstring_assignN(self, s.str, cstring_size(s));
+static inline CStr*
+cstr_copy(CStr* self, CStr s) {
+ return cstr_assignN(self, s.str, cstr_size(s));
}
-static inline CString*
-cstring_take(CString* self, CString s) {
- if (self->str != s.str && cstring_capacity(*self))
- free(_cstring_rep(self));
+static 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;
}
-static inline CString
-cstring_move(CString* self) {
- CString tmp = *self;
- *self = cstring_init;
+static inline CStr
+cstr_move(CStr* self) {
+ CStr tmp = *self;
+ *self = cstr_init;
return tmp;
}
-static inline CString*
-cstring_appendN(CString* self, const char* str, size_t len) {
+static inline CStr*
+cstr_appendN(CStr* self, const char* str, size_t len) {
if (len) {
- size_t oldlen = cstring_size(*self), newlen = oldlen + len;
- if (newlen > cstring_capacity(*self))
- cstring_reserve(self, newlen * 5 / 3);
+ size_t oldlen = cstr_size(*self), newlen = oldlen + len;
+ if (newlen > cstr_capacity(*self))
+ cstr_reserve(self, newlen * 5 / 3);
memmove(&self->str[oldlen], str, len);
- self->str[_cstring_size(*self) = newlen] = '\0';
+ self->str[_cstr_size(*self) = newlen] = '\0';
}
return self;
}
-static inline CString*
-cstring_append(CString* self, const char* str) {
- return cstring_appendN(self, str, strlen(str));
+static inline CStr*
+cstr_append(CStr* self, const char* str) {
+ return cstr_appendN(self, str, strlen(str));
}
-static inline CString*
-cstring_appendC(CString* self, char ch) {
- return cstring_appendN(self, &ch, 1);
+static inline CStr*
+cstr_appendC(CStr* self, char ch) {
+ return cstr_appendN(self, &ch, 1);
}
-static inline CString*
-cstring_appendS(CString* self, CString s) {
- return cstring_appendN(self, s.str, cstring_size(s));
+static inline CStr*
+cstr_appendS(CStr* self, CStr s) {
+ return cstr_appendN(self, s.str, cstr_size(s));
}
-static inline void _cstring_internalMove(CString* self, size_t pos1, size_t pos2) {
+static inline void _cstr_internalMove(CStr* self, size_t pos1, size_t pos2) {
if (pos1 == pos2)
return;
- size_t len = cstring_size(*self), newlen = len + pos2 - pos1;
- if (newlen > cstring_capacity(*self))
- cstring_reserve(self, newlen * 5 / 3);
+ size_t len = cstr_size(*self), newlen = len + pos2 - pos1;
+ if (newlen > cstr_capacity(*self))
+ cstr_reserve(self, newlen * 5 / 3);
memmove(&self->str[pos2], &self->str[pos1], len - pos1);
- self->str[_cstring_size(*self) = newlen] = '\0';
+ self->str[_cstr_size(*self) = newlen] = '\0';
}
static inline void
-cstring_insertN(CString* 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);
- _cstring_internalMove(self, pos, pos + n);
+ _cstr_internalMove(self, pos, pos + n);
memcpy(&self->str[pos], xstr, n);
if (n > c_max_alloca) free(xstr);
}
static inline void
-cstring_insert(CString* self, size_t pos, const char* str) {
- cstring_insertN(self, pos, str, strlen(str));
+cstr_insert(CStr* self, size_t pos, const char* str) {
+ cstr_insertN(self, pos, str, strlen(str));
}
static inline void
-cstring_erase(CString* self, size_t pos, size_t n) {
- size_t len = cstring_size(*self);
+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));
- self->str[_cstring_size(*self) -= n] = '\0';
+ self->str[_cstr_size(*self) -= n] = '\0';
}
}
-static inline size_t cstring_findN(CString s, size_t pos, const char* needle, size_t n);
+static inline size_t cstr_findN(CStr s, size_t pos, const char* needle, size_t n);
static inline size_t
-cstring_replaceN(CString* self, size_t pos, const char* str1, size_t n1, const char* str2, size_t n2) {
- size_t pos2 = cstring_findN(*self, pos, str1, n1);
- if (pos2 == cstring_npos) return cstring_npos;
+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);
- _cstring_internalMove(self, pos2 + n1, pos2 + n2);
+ _cstr_internalMove(self, pos2 + n1, pos2 + n2);
memcpy(&self->str[pos2], xstr2, n2);
if (n2 > c_max_alloca) free(xstr2);
return pos2;
}
static inline size_t
-cstring_replace(CString* self, size_t pos, const char* str1, const char* str2) {
- return cstring_replaceN(self, pos, str1, strlen(str1), str2, strlen(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));
}
static inline char
-cstring_back(CString s) {
- return s.str[cstring_size(s) - 1];
+cstr_back(CStr s) {
+ return s.str[cstr_size(s) - 1];
}
-static inline CString*
-cstring_push(CString* self, char value) {
- return cstring_appendN(self, &value, 1);
+static inline CStr*
+cstr_push(CStr* self, char value) {
+ return cstr_appendN(self, &value, 1);
}
static inline void
-cstring_pop(CString* self) {
- --_cstring_size(*self);
+cstr_pop(CStr* self) {
+ --_cstr_size(*self);
}
/* readonly */
static inline bool
-cstring_empty(CString s) {
- return cstring_size(s) == 0;
+cstr_empty(CStr s) {
+ return cstr_size(s) == 0;
}
static inline bool
-cstring_equals(CString s1, const char* str) {
+cstr_equals(CStr s1, const char* str) {
return strcmp(s1.str, str) == 0;
}
static inline bool
-cstring_equalsS(CString s1, CString s2) {
+cstr_equalsS(CStr s1, CStr s2) {
return strcmp(s1.str, s2.str) == 0;
}
static inline int
-cstring_compare(const void* s1, const void* s2) {
- return strcmp(((const CString*)s1)->str, ((const CString*)s2)->str);
+cstr_compare(const void* s1, const void* s2) {
+ return strcmp(((const CStr*)s1)->str, ((const CStr*)s2)->str);
}
static inline char*
-cstring_strnstr(CString 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 + cstring_size(s) - n + 1;
+ *z = s.str + cstr_size(s) - n + 1;
if (x >= z)
return NULL;
ptrdiff_t sum = 0;
@@ -299,24 +299,24 @@ cstring_strnstr(CString s, size_t pos, const char* needle, size_t n) { }
static inline size_t
-cstring_findN(CString s, size_t pos, const char* needle, size_t n) {
- char* res = cstring_strnstr(s, pos, needle, n);
- return res ? res - s.str : cstring_npos;
+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;
}
static inline size_t
-cstring_find(CString 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 : cstring_npos;
+ return res ? res - s.str : cstr_npos;
}
-/* CVector / CMap API functions: */
+/* CVec / CMap API functions: */
-#define cstring_getRaw(x) ((x)->str)
-#define cstring_compareRaw(x, y) strcmp(*(x), *(y))
-#define cstring_equalsRaw(x, y) (strcmp(*(x), *(y)) == 0)
-static inline uint32_t cstring_hashRaw(const char* const* sPtr, size_t ignored) {
+#define cstr_getRaw(x) ((x)->str)
+#define cstr_compareRaw(x, y) strcmp(*(x), *(y))
+#define cstr_equalsRaw(x, y) (strcmp(*(x), *(y)) == 0)
+static inline uint32_t cstr_hashRaw(const char* const* sPtr, size_t ignored) {
return c_defaultHash(*sPtr, strlen(*sPtr));
}
diff --git a/stc/cvector.h b/stc/cvector.h index f85a5c1b..e864bb34 100644 --- a/stc/cvector.h +++ b/stc/cvector.h @@ -27,107 +27,107 @@ #include <string.h>
#include "cdefs.h"
-#define cvector_init {NULL}
-#define cvector_size(cv) _cvector_safe_size((cv).data)
-#define cvector_capacity(cv) _cvector_safe_capacity((cv).data)
-#define cvector_empty(cv) (_cvector_safe_size((cv).data) == 0)
+#define cvec_init {NULL}
+#define cvec_size(cv) _cvec_safe_size((cv).data)
+#define cvec_capacity(cv) _cvec_safe_capacity((cv).data)
+#define cvec_empty(cv) (_cvec_safe_size((cv).data) == 0)
-#define declare_CVector(...) c_MACRO_OVERLOAD(declare_CVector, __VA_ARGS__)
-#define declare_CVector_2(tag, Value) \
- declare_CVector_3(tag, Value, c_emptyDestroy)
-#define declare_CVector_3(tag, Value, valueDestroy) \
- declare_CVector_4(tag, Value, valueDestroy, c_defaultCompare)
-#define declare_CVector_4(tag, Value, valueDestroy, valueCompare) \
- declare_CVector_6(tag, Value, valueDestroy, valueCompare, Value, c_defaultGetRaw)
-#define declare_CVector_string(tag) \
- declare_CVector_6(tag, CString, cstring_destroy, cstring_compareRaw, const char*, cstring_getRaw)
+#define declare_CVec(...) c_MACRO_OVERLOAD(declare_CVec, __VA_ARGS__)
+#define declare_CVec_2(tag, Value) \
+ declare_CVec_3(tag, Value, c_emptyDestroy)
+#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(tag) \
+ declare_CVec_6(tag, CStr, cstr_destroy, cstr_compareRaw, const char*, cstr_getRaw)
-#define declare_CVector_6(tag, Value, valueDestroy, valueCompareRaw, RawValue, valueGetRaw) \
+#define declare_CVec_6(tag, Value, valueDestroy, valueCompareRaw, RawValue, valueGetRaw) \
\
-typedef struct CVector_##tag { \
+typedef struct CVec_##tag { \
Value* data; \
-} CVector_##tag; \
+} CVec_##tag; \
\
-STC_API CVector_##tag \
-cvector_##tag##_make(size_t size, Value null); \
+STC_API CVec_##tag \
+cvec_##tag##_make(size_t size, Value null); \
STC_API void \
-cvector_##tag##_destroy(CVector_##tag* self); \
+cvec_##tag##_destroy(CVec_##tag* self); \
STC_API void \
-cvector_##tag##_reserve(CVector_##tag* self, size_t cap); \
+cvec_##tag##_reserve(CVec_##tag* self, size_t cap); \
STC_API void \
-cvector_##tag##_clear(CVector_##tag* self); \
+cvec_##tag##_clear(CVec_##tag* self); \
STC_API void \
-cvector_##tag##_pushBack(CVector_##tag* self, Value value); \
+cvec_##tag##_pushBack(CVec_##tag* self, Value value); \
static inline void \
-cvector_##tag##_popBack(CVector_##tag* self) { \
- valueDestroy(&self->data[_cvector_size(*self) - 1]); \
- --_cvector_size(*self); \
+cvec_##tag##_popBack(CVec_##tag* self) { \
+ valueDestroy(&self->data[_cvec_size(*self) - 1]); \
+ --_cvec_size(*self); \
} \
static inline Value \
-cvector_##tag##_back(CVector_##tag cv) { \
- return cv.data[_cvector_size(cv) - 1]; \
+cvec_##tag##_back(CVec_##tag cv) { \
+ return cv.data[_cvec_size(cv) - 1]; \
} \
STC_API void \
-cvector_##tag##_insert(CVector_##tag* self, size_t pos, Value value); \
+cvec_##tag##_insert(CVec_##tag* self, size_t pos, Value value); \
STC_API void \
-cvector_##tag##_erase(CVector_##tag* self, size_t pos, size_t size); \
+cvec_##tag##_erase(CVec_##tag* self, size_t pos, size_t size); \
STC_API void \
-cvector_##tag##_sort(CVector_##tag* self); \
+cvec_##tag##_sort(CVec_##tag* self); \
STC_API size_t \
-cvector_##tag##_find(CVector_##tag cv, RawValue rawValue); \
+cvec_##tag##_find(CVec_##tag cv, RawValue rawValue); \
static inline void \
-cvector_##tag##_swap(CVector_##tag* a, CVector_##tag* b) { \
+cvec_##tag##_swap(CVec_##tag* a, CVec_##tag* b) { \
c_swap(Value*, a->data, b->data); \
} \
\
typedef struct { \
Value *item, *end; \
-} CVectorIter_##tag, cvector_##tag##_iter_t; \
+} CVecIter_##tag, cvec_##tag##_iter_t; \
\
-static inline cvector_##tag##_iter_t \
-cvector_##tag##_begin(CVector_##tag* vec) { \
- const size_t n = cvector_size(*vec); \
- cvector_##tag##_iter_t it = {n ? vec->data : NULL, vec->data + n}; \
+static inline cvec_##tag##_iter_t \
+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; \
} \
-static inline cvector_##tag##_iter_t \
-cvector_##tag##_next(cvector_##tag##_iter_t it) { \
+static inline cvec_##tag##_iter_t \
+cvec_##tag##_next(cvec_##tag##_iter_t it) { \
if (++it.item == it.end) it.item = NULL; \
return it; \
} \
\
-implement_CVector_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \
-typedef Value CVectorValue_##tag; \
-typedef RawValue CVectorRawValue_##tag
+implement_CVec_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \
+typedef Value CVecValue_##tag; \
+typedef RawValue CVecRawValue_##tag
/* -------------------------- IMPLEMENTATION ------------------------- */
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-#define implement_CVector_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \
+#define implement_CVec_6(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueGetRaw) \
\
-STC_API CVector_##tag \
-cvector_##tag##_make(size_t size, Value null) { \
- CVector_##tag vec = cvector_init; \
- cvector_##tag##_reserve(&vec, size); \
- _cvector_size(vec) = size; \
+STC_API CVec_##tag \
+cvec_##tag##_make(size_t size, Value null) { \
+ 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 \
-cvector_##tag##_destroy(CVector_##tag* self) { \
+cvec_##tag##_destroy(CVec_##tag* self) { \
Value* p = self->data; \
- size_t i = 0, n = cvector_size(*self); \
+ size_t i = 0, n = cvec_size(*self); \
for (; i < n; ++p, ++i) valueDestroy(p); \
- free(_cvector_alloced(self->data)); \
+ free(_cvec_alloced(self->data)); \
} \
\
STC_API void \
-cvector_##tag##_reserve(CVector_##tag* self, size_t cap) { \
- size_t len = cvector_size(*self); \
+cvec_##tag##_reserve(CVec_##tag* self, size_t cap) { \
+ size_t len = cvec_size(*self); \
if (cap >= len) { \
- size_t* rep = (size_t *) realloc(_cvector_alloced(self->data), 2 * sizeof(size_t) + cap * sizeof(Value)); \
+ size_t* rep = (size_t *) realloc(_cvec_alloced(self->data), 2 * sizeof(size_t) + cap * sizeof(Value)); \
self->data = (Value *) (rep + 2); \
rep[0] = len; \
rep[1] = cap; \
@@ -135,45 +135,45 @@ cvector_##tag##_reserve(CVector_##tag* self, size_t cap) { \ } \
\
STC_API void \
-cvector_##tag##_clear(CVector_##tag* self) { \
- CVector_##tag cv = cvector_init; \
- cvector_##tag##_destroy(self); \
+cvec_##tag##_clear(CVec_##tag* self) { \
+ CVec_##tag cv = cvec_init; \
+ cvec_##tag##_destroy(self); \
*self = cv; \
} \
\
STC_API void \
-cvector_##tag##_pushBack(CVector_##tag* self, Value value) { \
- size_t len = cvector_size(*self); \
- if (len == cvector_capacity(*self)) \
- cvector_##tag##_reserve(self, 7 + len * 5 / 3); \
- self->data[cvector_size(*self)] = value; \
- ++_cvector_size(*self); \
+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); \
+ self->data[cvec_size(*self)] = value; \
+ ++_cvec_size(*self); \
} \
\
STC_API void \
-cvector_##tag##_insert(CVector_##tag* self, size_t pos, Value value) { \
- size_t len = cvector_size(*self); \
- if (len == cvector_capacity(*self)) \
- cvector_##tag##_reserve(self, 7 + len * 5 / 3); \
+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); \
memmove(&self->data[pos + 1], &self->data[pos], (len - pos) * sizeof(Value)); \
self->data[pos] = value; \
- ++_cvector_size(*self); \
+ ++_cvec_size(*self); \
} \
\
STC_API void \
-cvector_##tag##_erase(CVector_##tag* self, size_t pos, size_t size) { \
- size_t len = cvector_size(*self); \
+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; \
while (p != end) valueDestroy(p++); \
memmove(start, end, (len - pos - size) * sizeof(Value)); \
- _cvector_size(*self) -= size; \
+ _cvec_size(*self) -= size; \
} \
} \
\
STC_API size_t \
-cvector_##tag##_find(CVector_##tag cv, RawValue rawValue) { \
- size_t n = cvector_size(cv); \
+cvec_##tag##_find(CVec_##tag cv, RawValue rawValue) { \
+ size_t n = cvec_size(cv); \
for (size_t i = 0; i < n; ++i) { \
RawValue r = valueGetRaw(&cv.data[i]); \
if (valueCompareRaw(&r, &rawValue) == 0) return i; \
@@ -182,20 +182,20 @@ cvector_##tag##_find(CVector_##tag cv, RawValue rawValue) { \ } \
\
STC_API int \
-cvector_##tag##_sortCompare(const void* x, const void* y) { \
+cvec_##tag##_sortCompare(const void* x, const void* y) { \
RawValue rx = valueGetRaw((const Value *) x); \
RawValue ry = valueGetRaw((const Value *) y); \
return valueCompareRaw(&rx, &ry); \
} \
STC_EXTERN_IMPORT void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*)); \
STC_API void \
-cvector_##tag##_sort(CVector_##tag* self) { \
- size_t len = cvector_size(*self); \
- if (len) qsort(self->data, len, sizeof(Value), cvector_##tag##_sortCompare); \
+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_CVector_6(tag, Value, valueDestroy, valueCompareRaw, RawValue, valueGetRaw)
+#define implement_CVec_6(tag, Value, valueDestroy, valueCompareRaw, RawValue, valueGetRaw)
#endif
#if defined(_WIN32) && defined(_DLL)
@@ -204,16 +204,16 @@ cvector_##tag##_sort(CVector_##tag* self) { \ #define STC_EXTERN_IMPORT extern
#endif
-#define _cvector_size(cv) ((size_t *)(cv).data)[-2]
-#define _cvector_capacity(cv) ((size_t *)(cv).data)[-1]
+#define _cvec_size(cv) ((size_t *)(cv).data)[-2]
+#define _cvec_capacity(cv) ((size_t *)(cv).data)[-1]
-static inline size_t* _cvector_alloced(void* data) {
+static inline size_t* _cvec_alloced(void* data) {
return data ? ((size_t *) data) - 2 : NULL;
}
-static inline size_t _cvector_safe_size(const void* data) {
+static inline size_t _cvec_safe_size(const void* data) {
return data ? ((const size_t *) data)[-2] : 0;
}
-static inline size_t _cvector_safe_capacity(const void* data) {
+static inline size_t _cvec_safe_capacity(const void* data) {
return data ? ((const size_t *) data)[-1] : 0;
}
|
