diff options
| author | Tyge Løvset <[email protected]> | 2021-12-02 14:39:42 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2021-12-02 14:39:42 +0100 |
| commit | 323f21d57aaf30ffd43d6b67146bc887ad206298 (patch) | |
| tree | 3e4045251b0a0d0fb55e152ce728da6b5a3e875b | |
| parent | f857d8215a266673e25356779f740100fe362025 (diff) | |
| download | STC-modified-323f21d57aaf30ffd43d6b67146bc887ad206298.tar.gz STC-modified-323f21d57aaf30ffd43d6b67146bc887ad206298.zip | |
Breaking changes for i_fwd and i_cmp_none:
- Removed: i_cmp_none and i_fwd (replaced by c_no_compare and c_is_fwd args to i_opt).
- Added compile-time disabling of clonable and comparable container elements, controlled by i_opt (c_no_clone | c_no_compare)
- Added i_opt: can define multiple compile-time options: c_no_compare, c_no_clone, c_no_atomic, c_is_fwd: may be combined with | separator.
- Except for csptr, when i_del / i_valdel / i_keydel is defined, also i_from / i_keyfrom / i_valfrom must be defined or i_opt c_no_clone.
- For struct elements, either i_cmp must be defined (as before), or define i_opt c_no_compare for non-associative containers.
36 files changed, 636 insertions, 429 deletions
@@ -5,6 +5,13 @@ STC - Smart Template Containers for C News ---- +Breaking changes for i_cmp_none and i_fwd: +- Removed: i_cmp_none and i_fwd (replaced by c_no_compare and c_is_fwd args to i_opt). +- Added compile-time disabling of clonable and comparable container elements, controlled by i_opt (c_no_clone | c_no_compare) +- Added i_opt: can define multiple compile-time options: c_no_compare, c_no_clone, c_no_atomic, c_is_fwd: may be combined with | separator. +- Except for csptr, when i_del / i_valdel / i_keydel is defined, also i_from / i_keyfrom / i_valfrom must be defined or i_opt c_no_clone. +- For struct elements, either i_cmp must be defined (as before), or define i_opt c_no_compare (for non-associative containers only). + **VERSION 2.X RELEASED**: There are two main breaking changes from V1.X. - Uses a different way to instantiate templated containers, which is incompatible with v1.X. - c_forauto, c_forvar, c_forscope macros are now renamed to **c_auto**, **c_autovar**, and **c_autoscope**. These are for automatic scope resource management, aka RAII. @@ -91,17 +98,21 @@ int main(void) { cvec_float_del(&vec); } ``` -In order to include two **cvec**s with different element types, include cvec.h twice. For structs, -specify a compare function (as `<` and `==` operators does not work on them), or `i_cmp_none`. -This enables sorting and searching. +In order to include two **cvec**s with different element types, include cvec.h twice. For struct, a `i_cmp` +compare function is required to enable sorting and searching (`<` and `==` operators is default and works +for integral types only). Alternatively, `#define i_opt c_no_compare` to disable methods using comparison. + +Similarly, if a destructor `i_del` is defined, either define a `i_valfrom` construct/clone function +or `#define i_opt c_no_clone` to disable cloning and emplace methods. Unless these requirements are met, +compile errors are generated. ```c #define i_val struct One -#define i_cmp_none +#define i_opt c_no_compare #define i_tag one #include <stc/cvec.h> #define i_val struct Two -#define i_cmp_none +#define i_opt c_no_compare #define i_tag two #include <stc/cvec.h> ... @@ -242,6 +253,37 @@ of containers used in a single C-source file, e.g.: #include <stc/clist.h> // clist_pnt ``` +Specifying template parameters +------------------------------ +Each templated type requires one `#include`, even if it's the same container base type, as described earlier. +The template parameters are given by a `#define i_xxxx` statement, where *xxxx* is the parameter name. +The list of template parameters: + +- `i_tag` - Container type tag. Defaults to same as `i_key` +- `i_cnt` - Container type name. +- `i_opt` - Boolean properties: may combine `c_no_compare`, `c_no_clone`, `c_is_fwd` with `|` character. + +- `i_key` - Maps key type. **[required]** for cmap/csmap. +- `i_val` - The container **[required]** element type. For cmap/csmap, it is the mapped value. +- `i_cmp` - Three-way comparison of two `i_keyraw`, **[required]** for non-integral `i_keyraw`. +- `i_equ` - Equality comparison of two `i_keyraw`, `i_cmp` alternative. + +- `i_keydel` - Destroy map key func - defaults to empty destructor. +- `i_keyraw` - Convertion "raw" type - defaults to `i_key` type. +- `i_keyfrom` - Convertion func `i_keyraw` => `i_key` - defaults to simple copy. **[required]** if `i_keydel` is defined. +- `i_keyto` - Convertion func `i_key` => `i_keyraw` - defaults to simple copy. + +- `i_valdel` - Destroy mapped or value func - defaults to empty destruct. +- `i_valraw` - Convertion "raw" type - defaults to `i_val` type. +- `i_valfrom` - Convertion func `i_valraw` => `i_val` - defaults to simple copy. +- `i_valto` - Convertion func `i_val` => `i_valraw` - defaults to simple copy. + +An alternative to defining `i_cmp`, you may `#define i_opt c_no_compare` to disable methods using comparison. + +Similarly, if a destructor `i_del` is defined, either define `i_valfrom` constructor/clone function +or `#define i_opt c_no_clone` to disable cloning and the emplace methods. Unless these requirements are met, +compile errors are generated. + The *emplace* versus non-emplace container methods -------------------------------------------------- STC, like c++ STL, has two sets of methods for adding elements to containers. One set begins @@ -337,7 +379,7 @@ typedef struct Dataset { ... // Implementation -#define i_fwd // flag that the container was forward declared. +#define c_opt c_is_fwd // flag that the container was forward declared. #define i_val struct Point #define i_tag pnt #include <stc/cstack.h> diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md index db89120e..3d353e6c 100644 --- a/docs/ccommon_api.md +++ b/docs/ccommon_api.md @@ -155,6 +155,17 @@ cstr a = cstr_from("Hello"), b = cstr_from("World"); c_del(cstr, &a, &b); ``` +### General predefined template parameter functions +``` +int c_default_compare(const Type*, const Type*); +Type c_default_fromraw(Type val); // simple copy +Type c_default_toraw(const Type* val); // dereference val +void c_default_del(Type* val); // does nothing + +int c_rawstr_compare(const char* const* a, const char* const* b); +bool c_rawstr_equalto(const char* const* a, const char* const* b); +``` + ### c_malloc, c_calloc, c_realloc, c_free Memory allocator for the entire library. Macros can be overloaded by the user. diff --git a/docs/cmap_api.md b/docs/cmap_api.md index a33dc5c0..e4bc266a 100644 --- a/docs/cmap_api.md +++ b/docs/cmap_api.md @@ -80,22 +80,18 @@ cmap_X_rawvalue cmap_X_value_toraw(cmap_X_value* pval); ``` Helpers: ```c -uint64_t c_strhash(const char *str); // utility function - -int c_rawstr_compare(const char* const* a, const char* const* b); -bool c_rawstr_equalto(const char* const* a, const char* const* b); -uint64_t c_rawstr_hash(const char* const* strp, ...); - -uint64_t c_default_hash(const void *data, size_t len); // key is any integral type -uint64_t c_hash32(const void* data, size_t is4); // key is one 32-bit int -uint64_t c_hash64(const void* data, size_t is8); // key is one 64-bit int -bool c_default_equalto(const i_keyraw* a, const i_keyraw* b); // the == operator -bool c_memcmp_equalto(const i_keyraw* a, const i_keyraw* b); // uses memcmp - -Type c_no_clone(Type val); -Type c_default_fromraw(Type val); // plain copy -Type c_default_toraw(Type* val); -void c_default_del(Type* val); // does nothing +uint64_t c_strhash(const char *str); // utility function + +// hash template parameter functions: +uint64_t c_default_hash(const void *data, size_t len); // key is any integral type +uint64_t c_hash32(const void* data, size_t is4); // key is one 32-bit int +uint64_t c_hash64(const void* data, size_t is8); // key is one 64-bit int +uint64_t c_rawstr_hash(const char* const* strp, size_t unused); + +// equalto template parameter functions: +bool c_default_equalto(const i_keyraw* a, const i_keyraw* b); // *a == *b +bool c_memcmp_equalto(const i_keyraw* a, const i_keyraw* b); // !memcmp(a, b, sizeof *a) +bool c_rawstr_equalto(const char* const* a, const char* const* b); // !strcmp(*a, *b) ``` ## Types diff --git a/examples/astar.c b/examples/astar.c index 7410de96..2bf136e3 100644 --- a/examples/astar.c +++ b/examples/astar.c @@ -61,7 +61,7 @@ point_key_compare(const point* a, const point* b) #include <stc/cpque.h>
#define i_val point
-#define i_cmp c_no_compare
+#define i_opt c_no_compare
#include <stc/cdeq.h>
#define i_key point
diff --git a/examples/complex.c b/examples/complex.c index 64c1903e..b6aef5a8 100644 --- a/examples/complex.c +++ b/examples/complex.c @@ -4,11 +4,12 @@ void check_del(float* v) {printf("destroy %g\n", *v);} #define i_val float
#define i_valdel check_del
+#define i_opt c_no_clone
#define i_tag f
#include <stc/cstack.h>
#define i_val cstack_f
-#define i_cmp_none
+#define i_opt c_no_clone|c_no_compare
#define i_valdel cstack_f_del
#define i_tag arr
#include <stc/clist.h>
@@ -16,12 +17,14 @@ void check_del(float* v) {printf("destroy %g\n", *v);} #define i_key int
#define i_val clist_arr
#define i_valdel clist_arr_del
+#define i_opt c_no_clone
#define i_tag lst
#include <stc/cmap.h>
#define i_key_str
#define i_val cmap_lst
#define i_valdel cmap_lst_del
+#define i_opt c_no_clone
#define i_tag map
#include <stc/cmap.h>
diff --git a/examples/csmap_find.c b/examples/csmap_find.c index 977ae6ca..78b6bbf5 100644 --- a/examples/csmap_find.c +++ b/examples/csmap_find.c @@ -8,7 +8,7 @@ #include <stc/csmap.h> #define i_val csmap_istr_rawvalue -#define i_cmp c_no_compare +#define i_opt c_no_compare #define i_tag istr #include <stc/cvec.h> diff --git a/examples/csmap_insert.c b/examples/csmap_insert.c index 3e908164..32f53377 100644 --- a/examples/csmap_insert.c +++ b/examples/csmap_insert.c @@ -15,7 +15,7 @@ #include <stc/csmap.h>
#define i_val csmap_ii_rawvalue
-#define i_cmp c_no_compare
+#define i_opt c_no_compare
#define i_tag ii
#include <stc/cvec.h>
diff --git a/examples/demos.c b/examples/demos.c index 49ac8486..30250c5f 100644 --- a/examples/demos.c +++ b/examples/demos.c @@ -184,7 +184,6 @@ void mapdemo3() cmap_str_del(&table); // frees key and value cstrs, and hash table.
}
-//#define i_prefix carray3 // backward compatible.
#define i_val float
#define i_tag f
#include <stc/carr3.h>
diff --git a/examples/mapmap.c b/examples/mapmap.c index 73a00861..e22a4f7b 100644 --- a/examples/mapmap.c +++ b/examples/mapmap.c @@ -3,13 +3,14 @@ #define i_key_str
#define i_val_str
#define i_tag sect
-#include <stc/csmap.h>
+#include <stc/csmap.h> // csmap_sect
#define i_key_str
#define i_val csmap_sect
#define i_valdel csmap_sect_del
+#define i_valfrom csmap_sect_clone
#define i_tag conf
-#include <stc/csmap.h>
+#include <stc/csmap.h> // csmap_conf
void add(csmap_conf* map, const char* section, const char* entry, const char* value)
{
diff --git a/examples/mmap.c b/examples/mmap.c index e3c876ce..26b271d1 100644 --- a/examples/mmap.c +++ b/examples/mmap.c @@ -9,6 +9,7 @@ #define i_val clist_str
#define i_cmp -c_default_compare
#define i_valdel clist_str_del
+#define i_valfrom clist_str_clone
#define i_tag mult
#include <stc/csmap.h>
diff --git a/examples/multimap.c b/examples/multimap.c index 3dbe952d..543b8b22 100644 --- a/examples/multimap.c +++ b/examples/multimap.c @@ -38,14 +38,21 @@ typedef struct { int year; cstr city, date; } OlympicLocation; int OlympicLocation_compare(OlympicLocation* a, OlympicLocation* b) {
return a->year - b->year;
}
+
+OlympicLocation OlympicLocation_clone(OlympicLocation loc) {
+ loc.city = cstr_clone(loc.city);
+ loc.date = cstr_clone(loc.date);
+ return loc;
+}
void OlympicLocation_del(OlympicLocation* self) {
- c_del (cstr, &self->city, &self->date);
+ c_del(cstr, &self->city, &self->date);
}
// Create a clist<OlympicLocation>, can be sorted by year.
#define i_val OlympicLocation
#define i_cmp OlympicLocation_compare
#define i_del OlympicLocation_del
+#define i_from OlympicLocation_clone
#define i_tag OL
#include <stc/clist.h>
@@ -53,6 +60,7 @@ void OlympicLocation_del(OlympicLocation* self) { #define i_key_str
#define i_val clist_OL
#define i_valdel clist_OL_del
+#define i_valfrom clist_OL_clone
#define i_tag OL
#include <stc/csmap.h>
diff --git a/examples/new_deq.c b/examples/new_deq.c index 0b41b167..cc3ff76b 100644 --- a/examples/new_deq.c +++ b/examples/new_deq.c @@ -11,7 +11,7 @@ struct MyStruct { #define i_val int
-#define i_fwd
+#define i_opt c_is_fwd
#define i_tag i32
#include <stc/cdeq.h>
@@ -23,7 +23,7 @@ int point_compare(const Point* a, const Point* b) { #define i_val Point
#define i_cmp point_compare
-#define i_fwd
+#define i_opt c_is_fwd
#define i_tag pnt
#include <stc/cdeq.h>
diff --git a/examples/new_list.c b/examples/new_list.c index 4d2328be..e07030b5 100644 --- a/examples/new_list.c +++ b/examples/new_list.c @@ -10,7 +10,7 @@ struct MyStruct { } typedef MyStruct; #define i_val int -#define i_fwd +#define i_opt c_is_fwd #define i_tag i32 #include <stc/clist.h> @@ -22,7 +22,7 @@ int point_compare(const Point* a, const Point* b) { #define i_val Point #define i_cmp point_compare -#define i_fwd +#define i_opt c_is_fwd #define i_tag pnt #include <stc/clist.h> diff --git a/examples/new_map.c b/examples/new_map.c index 1094fd91..7f4d19ee 100644 --- a/examples/new_map.c +++ b/examples/new_map.c @@ -24,7 +24,7 @@ int point_compare(const Point* a, const Point* b) { #define i_key Point
#define i_val int
#define i_cmp point_compare
-#define i_fwd // forward declared
+#define i_opt c_is_fwd
#define i_tag pnt
#include <stc/cmap.h>
diff --git a/examples/new_pque.c b/examples/new_pque.c index 94a12fbd..5048ea77 100644 --- a/examples/new_pque.c +++ b/examples/new_pque.c @@ -22,7 +22,7 @@ int Point_cmp(const Point* a, const Point* b) { #define i_val Point
#define i_cmp Point_cmp
-#define i_fwd // forward declared.
+#define i_opt c_is_fwd
#define i_tag pnt
#include <stc/cpque.h>
diff --git a/examples/new_queue.c b/examples/new_queue.c index 53a5b341..3ad571bb 100644 --- a/examples/new_queue.c +++ b/examples/new_queue.c @@ -12,7 +12,7 @@ int point_compare(const Point* a, const Point* b) { }
#define i_val Point
#define i_cmp point_compare
-#define i_fwd
+#define i_opt c_is_fwd
#define i_tag pnt
#include <stc/cqueue.h>
diff --git a/examples/new_smap.c b/examples/new_smap.c index 1c84a961..7f0730db 100644 --- a/examples/new_smap.c +++ b/examples/new_smap.c @@ -23,7 +23,7 @@ int point_compare(const Point* a, const Point* b) { #define i_key Point
#define i_val int
#define i_cmp point_compare
-#define i_fwd
+#define i_opt c_is_fwd
#define i_tag pnt
#include <stc/csmap.h>
diff --git a/examples/new_vec.c b/examples/new_vec.c index 5460789a..62804125 100644 --- a/examples/new_vec.c +++ b/examples/new_vec.c @@ -9,9 +9,9 @@ struct MyStruct { cvec_pnt pntvec;
} typedef MyStruct;
-#define i_fwd pnt
-#define i_tag i32
#define i_val int
+#define i_opt c_is_fwd
+#define i_tag i32
#include <stc/cvec.h>
struct Point { int x, y; } typedef Point;
@@ -22,7 +22,7 @@ int point_compare(const Point* a, const Point* b) { #define i_val Point
#define i_cmp point_compare
-#define i_fwd pnt
+#define i_opt c_is_fwd
#define i_tag pnt
#include <stc/cvec.h>
diff --git a/examples/ptr_elems.c b/examples/ptr_elems.c new file mode 100644 index 00000000..1b4f881a --- /dev/null +++ b/examples/ptr_elems.c @@ -0,0 +1,54 @@ +#include <stc/ccommon.h>
+#include <stdio.h>
+
+struct { double x, y; } typedef Point;
+
+#define i_val Point*
+#define i_from(val) c_new(Point, *(val))
+#define i_del(pval) c_free(*(pval))
+#define i_tag pnt
+#include <stc/cvec.h>
+
+#define i_key_str
+#define i_val int*
+#define i_valraw int
+#define i_valfrom(raw) c_new(int, raw)
+#define i_valto(pval) **(pval)
+#define i_valdel(pval) c_free(*(pval))
+#include <stc/cmap.h>
+
+int main()
+{
+ c_auto (cvec_pnt, vec, cpy)
+ {
+ printf("Vector with pointer elements:\n");
+ // c++: vec.push_back(new Point{1.2, 3.4});
+ cvec_pnt_push_back(&vec, c_new(Point, {1.2, 3.4}));
+ cvec_pnt_push_back(&vec, c_new(Point, {6.1, 4.7}));
+
+ cpy = cvec_pnt_clone(vec);
+ cpy.data[1]->x = 100;
+
+ printf("vec:");
+ c_foreach (i, cvec_pnt, vec)
+ printf(" (%g %g)", (*i.ref)->x, (*i.ref)->y);
+ printf("\ncpy:");
+ c_foreach (i, cvec_pnt, cpy)
+ printf(" (%g %g)", (*i.ref)->x, (*i.ref)->y);
+ puts("");
+ }
+
+ c_auto (cmap_str, map)
+ {
+ printf("\nMap with pointer elements:\n");
+ cmap_str_insert(&map, cstr_lit("testing"), c_new(int, 999));
+ cmap_str_insert(&map, cstr_lit("done"), c_new(int, 111));
+
+ // Emplace: implicit key, val construction using i_keyfrom/i_valfrom:
+ cmap_str_emplace(&map, "hello", 200);
+ cmap_str_emplace(&map, "goodbye", 400);
+
+ c_foreach (i, cmap_str, map)
+ printf("%s: %d\n", i.ref->first.str, *i.ref->second);
+ }
+}
diff --git a/include/stc/alt/csmap.h b/include/stc/alt/csmap.h index 0e1650ee..5b331efb 100644 --- a/include/stc/alt/csmap.h +++ b/include/stc/alt/csmap.h @@ -53,7 +53,7 @@ int main(void) { #define KEY_REF_csmap_(vp) (&(vp)->first)
#define _c_aatree_complete_types(_cx_self, C) \
- cx_MAP_ONLY( struct _cx_value { \
+ _i_MAP_ONLY( struct _cx_value { \
_cx_key first; \
_cx_mapped second; \
}; ) \
@@ -71,8 +71,8 @@ int main(void) { \
typedef i_keyraw _cx_rawkey; \
typedef i_valraw _cx_memb(_rawmapped); \
- typedef cx_SET_ONLY( _cx_rawkey ) \
- cx_MAP_ONLY( struct { _cx_rawkey first; \
+ typedef _i_SET_ONLY( _cx_rawkey ) \
+ _i_MAP_ONLY( struct { _cx_rawkey first; \
_cx_memb(_rawmapped) second; } ) \
_cx_rawvalue; \
\
@@ -104,41 +104,41 @@ int main(void) { \
STC_INLINE void \
_cx_memb(_value_del)(_cx_value* val) { \
- i_keydel(cx_keyref(val)); \
- cx_MAP_ONLY( i_valdel(&val->second); ) \
+ i_keydel(_i_keyref(val)); \
+ _i_MAP_ONLY( i_valdel(&val->second); ) \
} \
\
STC_INLINE void \
_cx_memb(_value_clone)(_cx_value* dst, _cx_value* val) { \
- *cx_keyref(dst) = i_keyfrom(i_keyto(cx_keyref(val))); \
- cx_MAP_ONLY( dst->second = i_valfrom(i_valto(&val->second)); ) \
+ *_i_keyref(dst) = i_keyfrom(i_keyto(_i_keyref(val))); \
+ _i_MAP_ONLY( dst->second = i_valfrom(i_valto(&val->second)); ) \
} \
\
STC_INLINE _cx_result \
- _cx_memb(_emplace)(_cx_self* self, i_keyraw rkey cx_MAP_ONLY(, i_valraw rmapped)) { \
+ _cx_memb(_emplace)(_cx_self* self, i_keyraw rkey _i_MAP_ONLY(, i_valraw rmapped)) { \
_cx_result res = _cx_memb(_insert_entry_)(self, rkey); \
if (res.inserted) { \
- *cx_keyref(res.ref) = i_keyfrom(rkey); \
- cx_MAP_ONLY(res.ref->second = i_valfrom(rmapped);) \
+ *_i_keyref(res.ref) = i_keyfrom(rkey); \
+ _i_MAP_ONLY(res.ref->second = i_valfrom(rmapped);) \
} \
return res; \
} \
\
STC_INLINE void \
_cx_memb(_emplace_items)(_cx_self* self, const _cx_rawvalue arr[], size_t n) { \
- for (size_t i=0; i<n; ++i) cx_SET_ONLY( _cx_memb(_emplace)(self, arr[i]); ) \
- cx_MAP_ONLY( _cx_memb(_emplace)(self, arr[i].first, arr[i].second); ) \
+ for (size_t i=0; i<n; ++i) _i_SET_ONLY( _cx_memb(_emplace)(self, arr[i]); ) \
+ _i_MAP_ONLY( _cx_memb(_emplace)(self, arr[i].first, arr[i].second); ) \
} \
\
STC_INLINE _cx_result \
- _cx_memb(_insert)(_cx_self* self, i_key key cx_MAP_ONLY(, i_val mapped)) { \
+ _cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped)) { \
_cx_result res = _cx_memb(_insert_entry_)(self, i_keyto(&key)); \
- if (res.inserted) {*cx_keyref(res.ref) = key; cx_MAP_ONLY( res.ref->second = mapped; )} \
- else {i_keydel(&key); cx_MAP_ONLY( i_valdel(&mapped); )} \
+ if (res.inserted) {*_i_keyref(res.ref) = key; _i_MAP_ONLY( res.ref->second = mapped; )} \
+ else {i_keydel(&key); _i_MAP_ONLY( i_valdel(&mapped); )} \
return res; \
} \
\
- cx_MAP_ONLY( \
+ _i_MAP_ONLY( \
STC_INLINE _cx_result \
_cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped) { \
_cx_result res = _cx_memb(_insert_entry_)(self, i_keyto(&key)); \
@@ -231,7 +231,7 @@ static csmap_SENTINEL_node _aatree_sentinel = {&_aatree_sentinel, &_aatree_senti _cx_node *tn = self->root; \
out->_top = 0; \
while (tn->level) { \
- int c; _cx_rawkey rx = i_keyto(cx_keyref(&tn->value)); \
+ int c; _cx_rawkey rx = i_keyto(_i_keyref(&tn->value)); \
if ((c = i_cmp(&rx, &rkey)) < 0) tn = tn->link[1]; \
else if (c > 0) {out->_st[out->_top++] = tn; tn = tn->link[0]; } \
else {out->_tn = tn->link[1]; return (out->ref = &tn->value); } \
@@ -295,7 +295,7 @@ static csmap_SENTINEL_node _aatree_sentinel = {&_aatree_sentinel, &_aatree_senti int c, top = 0, dir = 0; \
while (tx->level) { \
up[top++] = tx; \
- _cx_rawkey r = i_keyto(cx_keyref(&tx->value)); \
+ _cx_rawkey r = i_keyto(_i_keyref(&tx->value)); \
if (!(c = i_cmp(&r, rkey))) {res->ref = &tx->value; return tn; } \
tx = tx->link[(dir = (c < 0))]; \
} \
@@ -325,7 +325,7 @@ static csmap_SENTINEL_node _aatree_sentinel = {&_aatree_sentinel, &_aatree_senti _cx_memb(_erase_r_)(_cx_node *tn, const _cx_rawkey* rkey, int *erased) { \
if (tn->level == 0) \
return tn; \
- _cx_rawkey raw = i_keyto(cx_keyref(&tn->value)); \
+ _cx_rawkey raw = i_keyto(_i_keyref(&tn->value)); \
_cx_node *tx; int c = i_cmp(&raw, rkey); \
if (c != 0) \
tn->link[c < 0] = _cx_memb(_erase_r_)(tn->link[c < 0], rkey, erased); \
@@ -336,7 +336,7 @@ static csmap_SENTINEL_node _aatree_sentinel = {&_aatree_sentinel, &_aatree_senti while (tx->link[1]->level) \
tx = tx->link[1]; \
tn->value = tx->value; \
- raw = i_keyto(cx_keyref(&tn->value)); \
+ raw = i_keyto(_i_keyref(&tn->value)); \
tn->link[0] = _cx_memb(_erase_r_)(tn->link[0], &raw, erased); \
} else { \
tx = tn; \
@@ -357,9 +357,9 @@ static csmap_SENTINEL_node _aatree_sentinel = {&_aatree_sentinel, &_aatree_senti } \
STC_DEF _cx_iter \
_cx_memb(_erase_at)(_cx_self* self, _cx_iter it) { \
- _cx_rawkey raw = i_keyto(cx_keyref(it.ref)), nxt; \
+ _cx_rawkey raw = i_keyto(_i_keyref(it.ref)), nxt; \
_cx_memb(_next)(&it); \
- if (it.ref) nxt = i_keyto(cx_keyref(it.ref)); \
+ if (it.ref) nxt = i_keyto(_i_keyref(it.ref)); \
_cx_memb(_erase)(self, raw); \
if (it.ref) _cx_memb(_find_it)(self, nxt, &it); \
return it; \
@@ -369,11 +369,11 @@ static csmap_SENTINEL_node _aatree_sentinel = {&_aatree_sentinel, &_aatree_senti _cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2) { \
if (!it2.ref) { while (it1.ref) it1 = _cx_memb(_erase_at)(self, it1); \
return it1; } \
- _cx_key k1 = *cx_keyref(it1.ref), k2 = *cx_keyref(it2.ref); \
+ _cx_key k1 = *_i_keyref(it1.ref), k2 = *_i_keyref(it2.ref); \
_cx_rawkey r1 = i_keyto(&k1); \
for (;;) { \
if (memcmp(&k1, &k2, sizeof k1) == 0) return it1; \
- _cx_memb(_next)(&it1); k1 = *cx_keyref(it1.ref); \
+ _cx_memb(_next)(&it1); k1 = *_i_keyref(it1.ref); \
_cx_memb(_erase)(self, r1); \
_cx_memb(_find_it)(self, (r1 = i_keyto(&k1)), &it1); \
} \
diff --git a/include/stc/carr2.h b/include/stc/carr2.h index 439a5c2d..d1feb90b 100644 --- a/include/stc/carr2.h +++ b/include/stc/carr2.h @@ -52,20 +52,22 @@ int main() { } */ -#ifndef i_prefix -#define i_prefix carr2_ +#ifndef _i_prefix +#define _i_prefix carr2_ #endif #include "template.h" - -#ifndef i_fwd +#if !c_option(c_is_fwd) _cx_deftypes(_c_carr2_types, _cx_self, i_val); #endif -STC_API _cx_self _cx_memb(_with_values)(size_t xdim, size_t ydim, i_val value); -STC_API _cx_self _cx_memb(_with_storage)(size_t xdim, size_t ydim, _cx_value* storage); -STC_API _cx_self _cx_memb(_clone)(_cx_self src); +STC_API _cx_self _cx_memb(_with_values)(size_t xdim, size_t ydim, i_val value); +STC_API _cx_self _cx_memb(_with_storage)(size_t xdim, size_t ydim, _cx_value* storage); STC_API _cx_value* _cx_memb(_release)(_cx_self* self); -STC_API void _cx_memb(_del)(_cx_self* self); +STC_API void _cx_memb(_del)(_cx_self* self); +#if !c_option(c_no_clone) +STC_API _cx_self _cx_memb(_clone)(_cx_self src); +STC_API void _cx_memb(_copy)(_cx_self *self, _cx_self other); +#endif STC_INLINE _cx_self _cx_memb(_init)(size_t xdim, size_t ydim) { return _cx_memb(_with_storage)(xdim, ydim, c_alloc_n(_cx_value, xdim*ydim)); @@ -85,11 +87,6 @@ STC_INLINE size_t _cx_memb(_idx)(const _cx_self* self, size_t x, size_t y) { return self->ydim*x + y; } -STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) { - if (self->data == other.data) return; - _cx_memb(_del)(self); *self = _cx_memb(_clone)(other); -} - STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { return c_make(_cx_iter){*self->data}; } @@ -116,6 +113,8 @@ STC_DEF _cx_self _cx_memb(_with_values)(size_t xdim, size_t ydim, i_val value) { return _arr; } +#if !c_option(c_no_clone) + STC_DEF _cx_self _cx_memb(_clone)(_cx_self src) { _cx_self _arr = _cx_memb(_init)(src.xdim, src.ydim); for (_cx_value* p = _arr.data[0], *q = src.data[0], *e = p + _cx_memb(_size)(src); p != e; ++p, ++q) @@ -123,6 +122,12 @@ STC_DEF _cx_self _cx_memb(_clone)(_cx_self src) { return _arr; } +STC_DEF void _cx_memb(_copy)(_cx_self *self, _cx_self other) { + if (self->data == other.data) return; + _cx_memb(_del)(self); *self = _cx_memb(_clone)(other); +} +#endif + STC_DEF _cx_value *_cx_memb(_release)(_cx_self* self) { _cx_value *values = self->data[0]; c_free(self->data); diff --git a/include/stc/carr3.h b/include/stc/carr3.h index 80e1ef0f..4a4a6484 100644 --- a/include/stc/carr3.h +++ b/include/stc/carr3.h @@ -53,20 +53,24 @@ int main() { } */ -#ifndef i_prefix -#define i_prefix carr3_ +#ifndef _i_prefix +#define _i_prefix carr3_ #endif #include "template.h" -#ifndef i_fwd +#if !c_option(c_is_fwd) _cx_deftypes(_c_carr3_types, _cx_self, i_val); #endif -STC_API _cx_self _cx_memb(_with_values)(size_t xdim, size_t ydim, size_t zdim, i_val value); -STC_API _cx_self _cx_memb(_with_storage)(size_t xdim, size_t ydim, size_t zdim, _cx_value* storage); -STC_API _cx_self _cx_memb(_clone)(_cx_self src); +STC_API _cx_self _cx_memb(_with_values)(size_t xdim, size_t ydim, size_t zdim, i_val value); +STC_API _cx_self _cx_memb(_with_storage)(size_t xdim, size_t ydim, size_t zdim, _cx_value* storage); STC_API _cx_value* _cx_memb(_release)(_cx_self* self); -STC_API void _cx_memb(_del)(_cx_self* self); +STC_API void _cx_memb(_del)(_cx_self* self); +#if !c_option(c_no_clone) +STC_API _cx_self _cx_memb(_clone)(_cx_self src); +STC_API void _cx_memb(_copy)(_cx_self *self, _cx_self other); +#endif + STC_INLINE _cx_self _cx_memb(_init)(size_t xdim, size_t ydim, size_t zdim) { return _cx_memb(_with_storage)(xdim, ydim, zdim, c_alloc_n(_cx_value, xdim*ydim*zdim)); @@ -87,11 +91,6 @@ STC_INLINE size_t _cx_memb(_idx)(const _cx_self* self, size_t x, size_t y, size_ return self->zdim*(self->ydim*x + y) + z; } -STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) { - if (self->data == other.data) return; - _cx_memb(_del)(self); *self = _cx_memb(_clone)(other); -} - STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { return c_make(_cx_iter){**self->data}; } @@ -120,6 +119,8 @@ STC_DEF _cx_self _cx_memb(_with_values)(size_t xdim, size_t ydim, size_t zdim, i return _arr; } +#if !c_option(c_no_clone) + STC_DEF _cx_self _cx_memb(_clone)(_cx_self src) { _cx_self _arr = _cx_memb(_init)(src.xdim, src.ydim, src.zdim); for (_cx_value* p = **_arr.data, *q = **src.data, *e = p + _cx_memb(_size)(src); p != e; ++p, ++q) @@ -127,6 +128,12 @@ STC_DEF _cx_self _cx_memb(_clone)(_cx_self src) { return _arr; } +STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) { + if (self->data == other.data) return; + _cx_memb(_del)(self); *self = _cx_memb(_clone)(other); +} +#endif + STC_DEF _cx_value* _cx_memb(_release)(_cx_self* self) { _cx_value *values = self->data[0][0]; c_free(self->data); diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h index 7d0eceeb..794948e6 100644 --- a/include/stc/ccommon.h +++ b/include/stc/ccommon.h @@ -98,20 +98,22 @@ #define c_default_compare(x, y) c_less_compare(c_default_less, x, y)
#define c_default_less(x, y) (*(x) < *(y))
-#define c_no_compare(x, y) (assert(!"c_no_compare() called"), (x)==(y)) // [deprecated]
+#define c_default_equalto(x, y) (*(x) == *(y))
+#define c_memcmp_equalto(x, y) (memcmp(x, y, sizeof *(x)) == 0)
#define c_less_compare(less, x, y) (less(y, x) - less(x, y))
-#define c_default_equalto(x, y) (*(x) == *(y))
-#define c_memcmp_equalto(x, y) (memcmp(x, y, sizeof *(x)) == 0)
-
#define c_rawstr_compare(x, y) strcmp(*(x), *(y))
#define c_rawstr_equalto(x, y) (strcmp(*(x), *(y)) == 0)
#define c_rawstr_hash(p, dummy) c_strhash(*(p))
-#define c_no_clone(x) (assert(!"c_no_clone() called"), x)
+#define c_option(flag) ((i_opt) & (flag))
+#define c_is_fwd 1
+#define c_no_compare 2
+#define c_no_clone 4
+#define c_no_atomic 8
+
#define c_default_fromraw(x) (x)
#define c_default_toraw(ptr) (*(ptr))
-
#define c_default_del(ptr) ((void) (ptr))
/* Generic algorithms */
diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h index 3e32beb6..f8cc1d52 100644 --- a/include/stc/cdeq.h +++ b/include/stc/cdeq.h @@ -20,7 +20,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-
#ifndef CDEQ_H_INCLUDED
#include "ccommon.h"
#include "forward.h"
@@ -31,48 +30,58 @@ struct cdeq_rep { size_t size, cap; void* base[]; }; #define cdeq_rep_(self) c_container_of((self)->_base, struct cdeq_rep, base)
#endif // CDEQ_H_INCLUDED
-#ifndef i_prefix
-#define i_prefix cdeq_
+#ifndef _i_prefix
+#define _i_prefix cdeq_
#endif
#include "template.h"
-#if !defined i_fwd
+#if !c_option(c_is_fwd)
_cx_deftypes(_c_cdeq_types, _cx_self, i_val);
#endif
typedef i_valraw _cx_rawvalue;
STC_API _cx_self _cx_memb(_init)(void);
-STC_API _cx_self _cx_memb(_clone)(_cx_self cx);
STC_API void _cx_memb(_clear)(_cx_self* self);
STC_API void _cx_memb(_del)(_cx_self* self);
STC_API _cx_value* _cx_memb(_push_back)(_cx_self* self, i_val value);
STC_API bool _cx_memb(_expand_right_half_)(_cx_self* self, size_t idx, size_t n);
+#ifndef _i_queue
+#if !c_option(c_no_clone)
+STC_API void _cx_memb(_shrink_to_fit)(_cx_self *self);
+STC_API _cx_iter _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos,
+ const _cx_value* p1, const _cx_value* p2);
+STC_API _cx_iter _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos,
+ const _cx_rawvalue* p1, const _cx_rawvalue* p2);
+#endif // !c_no_clone
-#ifndef i_queue
+#if !c_option(c_no_compare)
STC_API _cx_iter _cx_memb(_find_in)(_cx_iter p1, _cx_iter p2, i_valraw raw);
STC_API int _cx_memb(_value_compare)(const _cx_value* x, const _cx_value* y);
+#endif
STC_API _cx_value* _cx_memb(_push_front)(_cx_self* self, i_val value);
STC_API _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2);
STC_API _cx_iter _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_value* p1, const _cx_value* p2, bool clone);
-STC_API _cx_iter _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_rawvalue* p1, const _cx_rawvalue* p2);
-#endif // i_queue
+ const _cx_value* p1, const _cx_value* p2);
+#endif // !_i_queue
-STC_INLINE bool _cx_memb(_empty)(_cx_self cx) { return !cdeq_rep_(&cx)->size; }
-STC_INLINE size_t _cx_memb(_size)(_cx_self cx) { return cdeq_rep_(&cx)->size; }
-STC_INLINE size_t _cx_memb(_capacity)(_cx_self cx) { return cdeq_rep_(&cx)->cap; }
-STC_INLINE void _cx_memb(_swap)(_cx_self* a, _cx_self* b) {c_swap(_cx_self, *a, *b); }
-STC_INLINE i_val _cx_memb(_value_fromraw)(i_valraw raw) { return i_valfrom(raw); }
-STC_INLINE i_valraw _cx_memb(_value_toraw)(_cx_value* pval) { return i_valto(pval); }
+#if !c_option(c_no_clone)
+STC_API _cx_self _cx_memb(_clone)(_cx_self cx);
+STC_INLINE _cx_value* _cx_memb(_emplace_back)(_cx_self* self, i_valraw raw)
+ { return _cx_memb(_push_back)(self, i_valfrom(raw)); }
STC_INLINE i_val _cx_memb(_value_clone)(i_val val)
{ return i_valfrom(i_valto(&val)); }
STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) {
if (self->data == other.data) return;
_cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
}
-STC_INLINE _cx_value* _cx_memb(_emplace_back)(_cx_self* self, i_valraw raw)
- { return _cx_memb(_push_back)(self, i_valfrom(raw)); }
+#endif
+STC_INLINE bool _cx_memb(_empty)(_cx_self cx) { return !cdeq_rep_(&cx)->size; }
+STC_INLINE size_t _cx_memb(_size)(_cx_self cx) { return cdeq_rep_(&cx)->size; }
+STC_INLINE size_t _cx_memb(_capacity)(_cx_self cx) { return cdeq_rep_(&cx)->cap; }
+STC_INLINE void _cx_memb(_swap)(_cx_self* a, _cx_self* b) {c_swap(_cx_self, *a, *b); }
+STC_INLINE i_val _cx_memb(_value_fromraw)(i_valraw raw) { return i_valfrom(raw); }
+STC_INLINE i_valraw _cx_memb(_value_toraw)(_cx_value* pval) { return i_valto(pval); }
+
STC_INLINE void _cx_memb(_pop_front)(_cx_self* self)
{ i_valdel(self->data); ++self->data; --cdeq_rep_(self)->size; }
STC_INLINE _cx_value* _cx_memb(_back)(const _cx_self* self)
@@ -93,19 +102,7 @@ _cx_memb(_with_capacity)(const size_t n) { return cx;
}
-STC_INLINE void
-_cx_memb(_shrink_to_fit)(_cx_self *self) {
- if (_cx_memb(_size)(*self) != _cx_memb(_capacity)(*self)) {
- _cx_self cx = _cx_memb(_clone)(*self);
- _cx_memb(_del)(self); *self = cx;
- }
-}
-
-#ifndef i_queue
-
-STC_INLINE _cx_value* _cx_memb(_emplace_front)(_cx_self* self, i_valraw raw) {
- return _cx_memb(_push_front)(self, i_valfrom(raw));
-}
+#ifndef _i_queue
STC_INLINE void _cx_memb(_pop_back)(_cx_self* self) {
_cx_value* p = &self->data[--cdeq_rep_(self)->size];
@@ -129,48 +126,56 @@ _cx_memb(_reserve)(_cx_self* self, const size_t n) { STC_INLINE _cx_iter
_cx_memb(_insert)(_cx_self* self, const size_t idx, i_val value) {
- return _cx_memb(_insert_range_p)(self, self->data + idx, &value, &value + 1, false);
+ return _cx_memb(_insert_range_p)(self, self->data + idx, &value, &value + 1);
}
STC_INLINE _cx_iter
_cx_memb(_insert_n)(_cx_self* self, const size_t idx, const _cx_value arr[], const size_t n) {
- return _cx_memb(_insert_range_p)(self, self->data + idx, arr, arr + n, false);
+ return _cx_memb(_insert_range_p)(self, self->data + idx, arr, arr + n);
}
STC_INLINE _cx_iter
_cx_memb(_insert_at)(_cx_self* self, _cx_iter it, i_val value) {
- return _cx_memb(_insert_range_p)(self, it.ref, &value, &value + 1, false);
+ return _cx_memb(_insert_range_p)(self, it.ref, &value, &value + 1);
}
STC_INLINE _cx_iter
-_cx_memb(_emplace)(_cx_self* self, const size_t idx, i_valraw raw) {
- return _cx_memb(_emplace_range_p)(self, self->data + idx, &raw, &raw + 1);
+_cx_memb(_erase_n)(_cx_self* self, const size_t idx, const size_t n) {
+ return _cx_memb(_erase_range_p)(self, self->data + idx, self->data + idx + n);
}
STC_INLINE _cx_iter
-_cx_memb(_emplace_n)(_cx_self* self, const size_t idx, const _cx_rawvalue arr[], const size_t n) {
- return _cx_memb(_emplace_range_p)(self, self->data + idx, arr, arr + n);
+_cx_memb(_erase_at)(_cx_self* self, _cx_iter it) {
+ return _cx_memb(_erase_range_p)(self, it.ref, it.ref + 1);
}
STC_INLINE _cx_iter
-_cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, i_valraw raw) {
- return _cx_memb(_emplace_range_p)(self, it.ref, &raw, &raw + 1);
+_cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2) {
+ return _cx_memb(_erase_range_p)(self, it1.ref, it2.ref);
}
+
+#if !c_option(c_no_clone)
+
STC_INLINE _cx_iter
_cx_memb(_emplace_range)(_cx_self* self, _cx_iter it, _cx_iter it1, _cx_iter it2) {
- return _cx_memb(_insert_range_p)(self, it.ref, it1.ref, it2.ref, true);
+ return _cx_memb(_clone_range_p)(self, it.ref, it1.ref, it2.ref);
+}
+
+STC_INLINE _cx_value* _cx_memb(_emplace_front)(_cx_self* self, i_valraw raw) {
+ return _cx_memb(_push_front)(self, i_valfrom(raw));
}
STC_INLINE _cx_iter
-_cx_memb(_erase_n)(_cx_self* self, const size_t idx, const size_t n) {
- return _cx_memb(_erase_range_p)(self, self->data + idx, self->data + idx + n);
+_cx_memb(_emplace)(_cx_self* self, const size_t idx, i_valraw raw) {
+ return _cx_memb(_emplace_range_p)(self, self->data + idx, &raw, &raw + 1);
}
STC_INLINE _cx_iter
-_cx_memb(_erase_at)(_cx_self* self, _cx_iter it) {
- return _cx_memb(_erase_range_p)(self, it.ref, it.ref + 1);
+_cx_memb(_emplace_n)(_cx_self* self, const size_t idx, const _cx_rawvalue arr[], const size_t n) {
+ return _cx_memb(_emplace_range_p)(self, self->data + idx, arr, arr + n);
}
STC_INLINE _cx_iter
-_cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2) {
- return _cx_memb(_erase_range_p)(self, it1.ref, it2.ref);
+_cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, i_valraw raw) {
+ return _cx_memb(_emplace_range_p)(self, it.ref, &raw, &raw + 1);
}
+#endif // !c_no_clone
-#ifndef i_cmp_none
+#if !c_option(c_no_compare)
STC_INLINE _cx_iter
_cx_memb(_find)(const _cx_self* self, i_valraw raw) {
@@ -198,8 +203,8 @@ STC_INLINE void _cx_memb(_sort)(_cx_self* self) {
_cx_memb(_sort_range)(_cx_memb(_begin)(self), _cx_memb(_end)(self), _cx_memb(_value_compare));
}
-#endif // !i_cmp_none
-#endif // i_queue
+#endif // !c_no_compare
+#endif // _i_queue
/* -------------------------- IMPLEMENTATION ------------------------- */
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) || defined(i_imp)
@@ -226,6 +231,17 @@ _cx_memb(_clear)(_cx_self* self) { }
STC_DEF void
+_cx_memb(_shrink_to_fit)(_cx_self *self) {
+ if (_cx_memb(_size)(*self) != _cx_memb(_capacity)(*self)) {
+ struct cdeq_rep* rep = cdeq_rep_(self);
+ const size_t sz = rep->size;
+ memmove(self->_base, self->data, sz*sizeof(i_val));
+ rep = (struct cdeq_rep*) c_realloc(rep, offsetof(struct cdeq_rep, base) + sz*sizeof(i_val));
+ if (rep) { self->_base = self->data = (_cx_value*) rep->base; rep->cap = sz; }
+ }
+}
+
+STC_DEF void
_cx_memb(_del)(_cx_self* self) {
_cx_memb(_clear)(self);
if (cdeq_rep_(self)->cap)
@@ -255,7 +271,7 @@ _cx_memb(_expand_right_half_)(_cx_self* self, const size_t idx, const size_t n) if (!_cx_memb(_realloc_)(self, n)) return false;
memmove(self->data + idx + n, self->data + idx, (sz - idx)*sizeof(i_val));
} else {
-#ifdef i_queue
+#ifdef _i_queue
const size_t pos = 0;
#else
const size_t unused = cap - (sz + n);
@@ -277,6 +293,7 @@ _cx_memb(_push_back)(_cx_self* self, i_val value) { *v = value; return v;
}
+#if !c_option(c_no_clone)
STC_DEF _cx_self
_cx_memb(_clone)(_cx_self cx) {
const size_t sz = cdeq_rep_(&cx)->size;
@@ -285,8 +302,9 @@ _cx_memb(_clone)(_cx_self cx) { for (size_t i = 0; i < sz; ++i) out.data[i] = i_valfrom(i_valto(&cx.data[i]));
return out;
}
+#endif
-#ifndef i_queue
+#ifndef _i_queue
STC_DEF void
_cx_memb(_expand_left_half_)(_cx_self* self, const size_t idx, const size_t n) {
@@ -327,19 +345,10 @@ _cx_memb(_push_front)(_cx_self* self, i_val value) { STC_DEF _cx_iter
_cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_value* p1, const _cx_value* p2, bool clone) {
+ const _cx_value* p1, const _cx_value* p2) {
pos = _cx_memb(_insert_space_)(self, pos, p2 - p1);
_cx_iter it = {pos};
- if (clone) for (; p1 != p2; ++p1) *pos++ = i_valfrom(i_valto(p1));
- else memcpy(pos, p1, (p2 - p1)*sizeof *p1);
- return it;
-}
-
-STC_DEF _cx_iter
-_cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, const _cx_rawvalue* p1, const _cx_rawvalue* p2) {
- pos = _cx_memb(_insert_space_)(self, pos, p2 - p1);
- _cx_iter it = {pos};
- for (; p1 != p2; ++p1) *pos++ = i_valfrom(*p1);
+ memcpy(pos, p1, (p2 - p1)*sizeof *p1);
return it;
}
@@ -356,7 +365,28 @@ _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) { return c_make(_cx_iter){p1};
}
-#ifndef i_cmp_none
+#if !c_option(c_no_clone)
+
+STC_DEF _cx_iter
+_cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, const _cx_rawvalue* p1, const _cx_rawvalue* p2) {
+ pos = _cx_memb(_insert_space_)(self, pos, p2 - p1);
+ _cx_iter it = {pos};
+ for (; p1 != p2; ++p1) *pos++ = i_valfrom(*p1);
+ return it;
+}
+
+STC_DEF _cx_iter
+_cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos,
+ const _cx_value* p1, const _cx_value* p2) {
+ pos = _cx_memb(_insert_space_)(self, pos, p2 - p1);
+ _cx_iter it = {pos};
+ for (; p1 != p2; ++p1) *pos++ = i_valfrom(i_valto(p1));
+ return it;
+}
+#endif // !c_option(c_no_clone)
+
+#if !c_option(c_no_compare)
+
STC_DEF _cx_iter
_cx_memb(_find_in)(_cx_iter i1, _cx_iter i2, i_valraw raw) {
for (; i1.ref != i2.ref; ++i1.ref) {
@@ -372,8 +402,8 @@ _cx_memb(_value_compare)(const _cx_value* x, const _cx_value* y) { i_valraw ry = i_valto(y);
return i_cmp(&rx, &ry);
}
-#endif // !i_cmp_none
-#endif // i_queue
+#endif // !c_no_compare
+#endif // !_i_queue
#endif // IMPLEMENTATION
#include "template.h"
#define CDEQ_H_INCLUDED
diff --git a/include/stc/clist.h b/include/stc/clist.h index 8a019b65..bb090a62 100644 --- a/include/stc/clist.h +++ b/include/stc/clist.h @@ -78,12 +78,12 @@ _c_clist_complete_types(clist_VOID, dummy); #endif // CLIST_H_INCLUDED
-#ifndef i_prefix
-#define i_prefix clist_
+#ifndef _i_prefix
+#define _i_prefix clist_
#endif
#include "template.h"
-#if !defined i_fwd
+#if !c_option(c_is_fwd)
_cx_deftypes(_c_clist_types, _cx_self, i_val);
#endif
_cx_deftypes(_c_clist_complete_types, _cx_self, dummy);
@@ -91,14 +91,13 @@ typedef i_valraw _cx_rawvalue; STC_API size_t _clist_count(const clist_VOID* self);
-STC_API _cx_self _cx_memb(_clone)(_cx_self cx);
STC_API void _cx_memb(_del)(_cx_self* self);
STC_API _cx_value* _cx_memb(_push_back)(_cx_self* self, i_val value);
STC_API _cx_value* _cx_memb(_push_front)(_cx_self* self, i_val value);
STC_API _cx_iter _cx_memb(_insert)(_cx_self* self, _cx_iter it, i_val value);
STC_API _cx_iter _cx_memb(_erase_at)(_cx_self* self, _cx_iter it);
STC_API _cx_iter _cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2);
-#ifndef i_cmp_none
+#if !c_option(c_no_compare)
STC_API size_t _cx_memb(_remove)(_cx_self* self, i_valraw val);
STC_API _cx_iter _cx_memb(_find_in)(_cx_iter it1, _cx_iter it2, i_valraw val);
#endif
@@ -107,31 +106,34 @@ STC_API _cx_self _cx_memb(_split_off)(_cx_self* self, _cx_iter it1, _cx_i STC_API void _cx_memb(_sort)(_cx_self* self);
STC_API _cx_node* _cx_memb(_erase_after_)(_cx_self* self, _cx_node* node);
-STC_INLINE _cx_self _cx_memb(_init)(void) { return c_make(_cx_self){NULL}; }
-STC_INLINE bool _cx_memb(_empty)(_cx_self cx) { return cx.last == NULL; }
-STC_INLINE size_t _cx_memb(_count)(_cx_self cx)
- { return _clist_count((const clist_VOID*) &cx); }
-STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_del)(self); }
-STC_INLINE i_val _cx_memb(_value_fromraw)(i_valraw raw) { return i_valfrom(raw); }
-STC_INLINE i_valraw _cx_memb(_value_toraw)(_cx_value* pval) { return i_valto(pval); }
-STC_INLINE i_val _cx_memb(_value_clone)(i_val val)
- { return i_valfrom(i_valto(&val)); }
-STC_INLINE void _cx_memb(_pop_front)(_cx_self* self)
- { _cx_memb(_erase_after_)(self, self->last); }
+#if !c_option(c_no_clone)
+STC_API _cx_self _cx_memb(_clone)(_cx_self cx);
STC_INLINE _cx_value* _cx_memb(_emplace_back)(_cx_self* self, i_valraw raw)
{ return _cx_memb(_push_back)(self, i_valfrom(raw)); }
STC_INLINE _cx_value* _cx_memb(_emplace_front)(_cx_self* self, i_valraw raw)
{ return _cx_memb(_push_front)(self, i_valfrom(raw)); }
STC_INLINE _cx_iter _cx_memb(_emplace)(_cx_self* self, _cx_iter it, i_valraw raw)
{ return _cx_memb(_insert)(self, it, i_valfrom(raw)); }
-STC_INLINE _cx_value* _cx_memb(_front)(const _cx_self* self) { return &self->last->next->value; }
-STC_INLINE _cx_value* _cx_memb(_back)(const _cx_self* self) { return &self->last->value; }
-
+STC_INLINE i_val _cx_memb(_value_fromraw)(i_valraw raw)
+ { return i_valfrom(raw); }
+STC_INLINE i_val _cx_memb(_value_clone)(i_val val)
+ { return i_valfrom(i_valto(&val)); }
STC_INLINE void
_cx_memb(_copy)(_cx_self *self, _cx_self other) {
if (self->last == other.last) return;
_cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
}
+#endif
+STC_INLINE _cx_self _cx_memb(_init)(void) { return c_make(_cx_self){NULL}; }
+STC_INLINE bool _cx_memb(_empty)(_cx_self cx) { return cx.last == NULL; }
+STC_INLINE size_t _cx_memb(_count)(_cx_self cx)
+ { return _clist_count((const clist_VOID*) &cx); }
+STC_INLINE void _cx_memb(_clear)(_cx_self* self) { _cx_memb(_del)(self); }
+STC_INLINE i_valraw _cx_memb(_value_toraw)(_cx_value* pval) { return i_valto(pval); }
+STC_INLINE void _cx_memb(_pop_front)(_cx_self* self)
+ { _cx_memb(_erase_after_)(self, self->last); }
+STC_INLINE _cx_value* _cx_memb(_front)(const _cx_self* self) { return &self->last->next->value; }
+STC_INLINE _cx_value* _cx_memb(_back)(const _cx_self* self) { return &self->last->value; }
STC_INLINE _cx_iter
_cx_memb(_begin)(const _cx_self* self) {
@@ -163,7 +165,7 @@ _cx_memb(_splice_range)(_cx_self* self, _cx_iter it, return _cx_memb(_splice)(self, it, &tmp);
}
-#ifndef i_cmp_none
+#if !c_option(c_no_compare)
STC_INLINE _cx_iter
_cx_memb(_find)(const _cx_self* self, i_valraw val) {
return _cx_memb(_find_in)(_cx_memb(_begin)(self), _cx_memb(_end)(self), val);
@@ -184,12 +186,14 @@ _cx_memb(_get_mut)(_cx_self* self, i_valraw val) { #if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) || defined(i_imp)
+#if !c_option(c_no_clone)
STC_DEF _cx_self
_cx_memb(_clone)(_cx_self cx) {
_cx_self out = _cx_memb(_init)();
c_foreach (it, _cx_self, cx) _cx_memb(_emplace_back)(&out, i_valto(it.ref));
return out;
}
+#endif
STC_DEF void
_cx_memb(_del)(_cx_self* self) {
@@ -275,7 +279,7 @@ _cx_memb(_split_off)(_cx_self* self, _cx_iter it1, _cx_iter it2) { return cx;
}
-#ifndef i_cmp_none
+#if !c_option(c_no_compare)
STC_DEF _cx_iter
_cx_memb(_find_in)(_cx_iter it1, _cx_iter it2, i_valraw val) {
@@ -316,7 +320,7 @@ _cx_memb(_sort)(_cx_self* self) { if (self->last)
self->last = (_cx_node *) _clist_mergesort((clist_VOID_node *) self->last->next, _cx_memb(_sort_cmp_));
}
-#endif // !i_cmp_none
+#endif // !c_no_compare
#endif // TEMPLATE IMPLEMENTATION
@@ -331,7 +335,8 @@ _clist_count(const clist_VOID* self) { return n;
}
-#ifndef i_cmp_none
+#if !c_option(c_no_compare)
+
// Singly linked list Mergesort implementation by Simon Tatham. O(n*log n).
// https://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
STC_DEF clist_VOID_node *
@@ -381,7 +386,7 @@ _clist_mergesort(clist_VOID_node *list, int (*cmp)(const clist_VOID_node*, const insize *= 2;
}
}
-#endif // !i_cmp_none
+#endif // !c_no_compare
#endif // NON-TEMPLATE IMPLEMENTATION
#include "template.h"
#define CLIST_H_INCLUDED
diff --git a/include/stc/cmap.h b/include/stc/cmap.h index 979f1b44..3d1915d3 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -58,37 +58,39 @@ int main(void) { typedef struct { MAP_SIZE_T idx; uint_fast8_t hx; } chash_bucket_t;
#endif // CMAP_H_INCLUDED
-#ifndef i_prefix
-#define i_prefix cmap_
+#ifndef _i_prefix
+#define _i_prefix cmap_
#endif
-#ifdef i_isset
- #define cx_MAP_ONLY c_false
- #define cx_SET_ONLY c_true
- #define cx_keyref(vp) (vp)
+#ifdef _i_isset
+ #define _i_MAP_ONLY c_false
+ #define _i_SET_ONLY c_true
+ #define _i_keyref(vp) (vp)
#else
- #define cx_MAP_ONLY c_true
- #define cx_SET_ONLY c_false
- #define cx_keyref(vp) (&(vp)->first)
+ #define _i_MAP_ONLY c_true
+ #define _i_SET_ONLY c_false
+ #define _i_keyref(vp) (&(vp)->first)
#endif
#include "template.h"
-#ifndef i_fwd
-_cx_deftypes(_c_chash_types, _cx_self, i_key, i_val, cx_MAP_ONLY, cx_SET_ONLY);
+#if !c_option(c_is_fwd)
+_cx_deftypes(_c_chash_types, _cx_self, i_key, i_val, _i_MAP_ONLY, _i_SET_ONLY);
#endif
-cx_MAP_ONLY( struct _cx_value {
+_i_MAP_ONLY( struct _cx_value {
_cx_key first;
_cx_mapped second;
}; )
typedef i_keyraw _cx_rawkey;
typedef i_valraw _cx_memb(_rawmapped);
-typedef cx_SET_ONLY( i_keyraw )
- cx_MAP_ONLY( struct { i_keyraw first;
+typedef _i_SET_ONLY( i_keyraw )
+ _i_MAP_ONLY( struct { i_keyraw first;
i_valraw second; } )
_cx_rawvalue;
STC_API _cx_self _cx_memb(_with_capacity)(size_t cap);
+#if !c_option(c_no_clone)
STC_API _cx_self _cx_memb(_clone)(_cx_self map);
+#endif
STC_API void _cx_memb(_del)(_cx_self* self);
STC_API void _cx_memb(_clear)(_cx_self* self);
STC_API bool _cx_memb(_reserve)(_cx_self* self, size_t capacity);
@@ -108,9 +110,11 @@ STC_INLINE void _cx_memb(_swap)(_cx_self *map1, _cx_self *map2) {c_swap( STC_INLINE bool _cx_memb(_contains)(const _cx_self* self, i_keyraw rkey)
{ return self->size && self->_hashx[_cx_memb(_bucket_)(self, &rkey).idx]; }
-cx_MAP_ONLY(
- STC_API _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key _key, i_val _mapped);
+#ifndef _i_isset
+ #if !c_option(c_no_clone)
STC_API _cx_result _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped);
+ #endif
+ STC_API _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key _key, i_val _mapped);
STC_INLINE _cx_result /* short-form, like operator[]: */
_cx_memb(_put)(_cx_self* self, i_key key, i_val mapped) {
@@ -123,41 +127,48 @@ cx_MAP_ONLY( assert(self->_hashx[b.idx]);
return &self->table[b.idx].second;
}
-)
-
-STC_INLINE void
-_cx_memb(_value_clone)(_cx_value* _dst, _cx_value* _val) {
- *cx_keyref(_dst) = i_keyfrom(i_keyto(cx_keyref(_val)));
- cx_MAP_ONLY( _dst->second = i_valfrom(i_valto(&_val->second)); )
-}
+#endif
-STC_INLINE _cx_rawvalue
-_cx_memb(_value_toraw)(_cx_value* val) {
- return cx_SET_ONLY( i_keyto(val) )
- cx_MAP_ONLY( c_make(_cx_rawvalue){i_keyto(&val->first), i_valto(&val->second)} );
+#if !c_option(c_no_clone)
+STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) {
+ if (self->table == other.table) return;
+ _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
}
STC_INLINE void
-_cx_memb(_value_del)(_cx_value* _val) {
- i_keydel(cx_keyref(_val));
- cx_MAP_ONLY( i_valdel(&_val->second); )
+_cx_memb(_value_clone)(_cx_value* _dst, _cx_value* _val) {
+ *_i_keyref(_dst) = i_keyfrom(i_keyto(_i_keyref(_val)));
+ _i_MAP_ONLY( _dst->second = i_valfrom(i_valto(&_val->second)); )
}
STC_INLINE _cx_result
-_cx_memb(_emplace)(_cx_self* self, i_keyraw rkey cx_MAP_ONLY(, i_valraw rmapped)) {
+_cx_memb(_emplace)(_cx_self* self, i_keyraw rkey _i_MAP_ONLY(, i_valraw rmapped)) {
_cx_result _res = _cx_memb(_insert_entry_)(self, rkey);
if (_res.inserted) {
- *cx_keyref(_res.ref) = i_keyfrom(rkey);
- cx_MAP_ONLY( _res.ref->second = i_valfrom(rmapped); )
+ *_i_keyref(_res.ref) = i_keyfrom(rkey);
+ _i_MAP_ONLY( _res.ref->second = i_valfrom(rmapped); )
}
return _res;
}
+#endif // !c_no_clone
+
+STC_INLINE _cx_rawvalue
+_cx_memb(_value_toraw)(_cx_value* val) {
+ return _i_SET_ONLY( i_keyto(val) )
+ _i_MAP_ONLY( c_make(_cx_rawvalue){i_keyto(&val->first), i_valto(&val->second)} );
+}
+
+STC_INLINE void
+_cx_memb(_value_del)(_cx_value* _val) {
+ i_keydel(_i_keyref(_val));
+ _i_MAP_ONLY( i_valdel(&_val->second); )
+}
STC_INLINE _cx_result
-_cx_memb(_insert)(_cx_self* self, i_key _key cx_MAP_ONLY(, i_val _mapped)) {
+_cx_memb(_insert)(_cx_self* self, i_key _key _i_MAP_ONLY(, i_val _mapped)) {
_cx_result _res = _cx_memb(_insert_entry_)(self, i_keyto(&_key));
- if (_res.inserted) { *cx_keyref(_res.ref) = _key; cx_MAP_ONLY( _res.ref->second = _mapped; )}
- else { i_keydel(&_key); cx_MAP_ONLY( i_valdel(&_mapped); )}
+ if (_res.inserted) { *_i_keyref(_res.ref) = _key; _i_MAP_ONLY( _res.ref->second = _mapped; )}
+ else { i_keydel(&_key); _i_MAP_ONLY( i_valdel(&_mapped); )}
return _res;
}
@@ -253,12 +264,7 @@ STC_DEF void _cx_memb(_clear)(_cx_self* self) { memset(self->_hashx, 0, self->bucket_count);
}
-STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) {
- if (self->table == other.table) return;
- _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
-}
-
-cx_MAP_ONLY(
+#if !defined _i_isset
STC_DEF _cx_result
_cx_memb(_insert_or_assign)(_cx_self* self, i_key _key, i_val _mapped) {
_cx_result _res = _cx_memb(_insert_entry_)(self, i_keyto(&_key));
@@ -266,7 +272,7 @@ cx_MAP_ONLY( else { i_keydel(&_key); i_valdel(&_res.ref->second); }
_res.ref->second = _mapped; return _res;
}
-
+ #if !c_option(c_no_clone)
STC_DEF _cx_result
_cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped) {
_cx_result _res = _cx_memb(_insert_entry_)(self, rkey);
@@ -274,7 +280,8 @@ cx_MAP_ONLY( else i_valdel(&_res.ref->second);
_res.ref->second = i_valfrom(rmapped); return _res;
}
-)
+ #endif
+#endif
STC_DEF chash_bucket_t
_cx_memb(_bucket_)(const _cx_self* self, const _cx_rawkey* rkeyptr) {
@@ -284,7 +291,7 @@ _cx_memb(_bucket_)(const _cx_self* self, const _cx_rawkey* rkeyptr) { const uint8_t* _hashx = self->_hashx;
while ((_hx = _hashx[b.idx])) {
if (_hx == b.hx) {
- _cx_rawkey _raw = i_keyto(cx_keyref(self->table + b.idx));
+ _cx_rawkey _raw = i_keyto(_i_keyref(self->table + b.idx));
if (i_equ(&_raw, rkeyptr)) break;
}
if (++b.idx == _cap) b.idx = 0;
@@ -305,6 +312,7 @@ _cx_memb(_insert_entry_)(_cx_self* self, i_keyraw rkey) { return res;
}
+#if !c_option(c_no_clone)
STC_DEF _cx_self
_cx_memb(_clone)(_cx_self m) {
_cx_self clone = {
@@ -318,6 +326,7 @@ _cx_memb(_clone)(_cx_self m) { if (*hx) _cx_memb(_value_clone)(dst, e);
return clone;
}
+#endif
STC_DEF bool
_cx_memb(_reserve)(_cx_self* self, const size_t _newcap) {
@@ -337,7 +346,7 @@ _cx_memb(_reserve)(_cx_self* self, const size_t _newcap) { _cx_value* e = _tmp.table, *_slot = self->table;
uint8_t* _hashx = self->_hashx;
for (size_t i = 0; i < _oldbuckets; ++i, ++e) if (_tmp._hashx[i]) {
- _cx_rawkey _raw = i_keyto(cx_keyref(e));
+ _cx_rawkey _raw = i_keyto(_i_keyref(e));
chash_bucket_t b = _cx_memb(_bucket_)(self, &_raw);
_slot[b.idx] = *e;
_hashx[b.idx] = (uint8_t) b.hx;
@@ -359,7 +368,7 @@ _cx_memb(_erase_entry)(_cx_self* self, _cx_value* _val) { if (++j == _cap) j = 0;
if (! _hashx[j])
break;
- _cx_rawkey _raw = i_keyto(cx_keyref(_slot + j));
+ _cx_rawkey _raw = i_keyto(_i_keyref(_slot + j));
k = c_PASTE(fastrange_,MAP_SIZE_T)(i_hash(&_raw, sizeof _raw), _cap);
if ((j < i) ^ (k <= i) ^ (k > j)) /* is k outside (i, j]? */
_slot[i] = _slot[j], _hashx[i] = _hashx[j], i = j;
@@ -369,9 +378,9 @@ _cx_memb(_erase_entry)(_cx_self* self, _cx_value* _val) { }
#endif // TEMPLATED IMPLEMENTATION
-#undef i_isset
-#undef cx_keyref
-#undef cx_MAP_ONLY
-#undef cx_SET_ONLY
+#undef _i_isset
+#undef _i_keyref
+#undef _i_MAP_ONLY
+#undef _i_SET_ONLY
#include "template.h"
#define CMAP_H_INCLUDED
diff --git a/include/stc/cpque.h b/include/stc/cpque.h index c43072c9..86bab2ec 100644 --- a/include/stc/cpque.h +++ b/include/stc/cpque.h @@ -27,13 +27,13 @@ #include "forward.h"
#endif
-#ifndef i_prefix
-#define i_prefix cpque_
+#ifndef _i_prefix
+#define _i_prefix cpque_
#endif
#include "template.h"
-#if !defined i_fwd
+#if !c_option(c_is_fwd)
_cx_deftypes(_c_cpque_types, _cx_self, i_val);
#endif
typedef i_valraw _cx_rawvalue;
@@ -41,7 +41,6 @@ typedef i_valraw _cx_rawvalue; STC_API void _cx_memb(_make_heap)(_cx_self* self);
STC_API void _cx_memb(_erase_at)(_cx_self* self, size_t idx);
STC_API void _cx_memb(_push)(_cx_self* self, _cx_value value);
-STC_API _cx_self _cx_memb(_clone)(_cx_self q);
STC_INLINE _cx_self _cx_memb(_init)(void)
{ return c_make(_cx_self){0}; }
@@ -65,11 +64,6 @@ STC_INLINE void _cx_memb(_clear)(_cx_self* self) { STC_INLINE void _cx_memb(_del)(_cx_self* self)
{ _cx_memb(_clear)(self); c_free(self->data); }
-STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) {
- if (self->data == other.data) return;
- _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
-}
-
STC_INLINE size_t _cx_memb(_size)(_cx_self q)
{ return q.size; }
@@ -85,11 +79,20 @@ STC_INLINE _cx_value* _cx_memb(_top)(const _cx_self* self) STC_INLINE void _cx_memb(_pop)(_cx_self* self)
{ _cx_memb(_erase_at)(self, 0); }
+#if !c_option(c_no_clone)
+STC_API _cx_self _cx_memb(_clone)(_cx_self q);
+
+STC_INLINE void _cx_memb(_copy)(_cx_self *self, _cx_self other) {
+ if (self->data == other.data) return;
+ _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
+}
+
STC_INLINE void _cx_memb(_emplace)(_cx_self* self, _cx_rawvalue raw)
{ _cx_memb(_push)(self, i_valfrom(raw)); }
STC_INLINE i_val _cx_memb(_value_clone)(_cx_value val)
{ return i_valfrom(i_valto(&val)); }
+#endif
STC_INLINE void
_cx_memb(_push_back)(_cx_self* self, _cx_value value) {
@@ -121,12 +124,15 @@ _cx_memb(_make_heap)(_cx_self* self) { _cx_memb(_sift_down_)(arr, k, n);
}
+#if !c_option(c_no_clone)
+
STC_DEF _cx_self _cx_memb(_clone)(_cx_self q) {
_cx_self out = _cx_memb(_with_capacity)(q.size);
for (; out.size < out.capacity; ++out.size, ++q.data)
out.data[out.size] = i_valfrom(i_valto(q.data));
return out;
}
+#endif
STC_DEF void
_cx_memb(_erase_at)(_cx_self* self, size_t idx) {
diff --git a/include/stc/cqueue.h b/include/stc/cqueue.h index 45e3c2a6..aba07726 100644 --- a/include/stc/cqueue.h +++ b/include/stc/cqueue.h @@ -53,10 +53,10 @@ int main() { }
*/
-#ifndef i_prefix
-#define i_prefix cqueue_
+#ifndef _i_prefix
+#define _i_prefix cqueue_
#endif
-#define i_queue
+#define _i_queue
#define _push_back _push
#define _pop_front _pop
@@ -64,4 +64,4 @@ int main() { #undef _push_back
#undef _pop_front
-#undef i_queue
+#undef _i_queue
diff --git a/include/stc/cset.h b/include/stc/cset.h index aa2ba022..d74a8ccc 100644 --- a/include/stc/cset.h +++ b/include/stc/cset.h @@ -39,8 +39,8 @@ int main(void) { }
*/
-#ifndef i_prefix
-#define i_prefix cset_
+#ifndef _i_prefix
+#define _i_prefix cset_
#endif
-#define i_isset
+#define _i_isset
#include "cmap.h"
diff --git a/include/stc/csmap.h b/include/stc/csmap.h index 279bdf6d..101e7399 100644 --- a/include/stc/csmap.h +++ b/include/stc/csmap.h @@ -59,25 +59,25 @@ struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; }; #define _csmap_rep(self) c_container_of((self)->nodes, struct csmap_rep, nodes)
#endif // CSMAP_H_INCLUDED
-#ifndef i_prefix
-#define i_prefix csmap_
+#ifndef _i_prefix
+#define _i_prefix csmap_
#endif
-#ifdef i_isset
- #define cx_MAP_ONLY c_false
- #define cx_SET_ONLY c_true
- #define cx_keyref(vp) (vp)
+#ifdef _i_isset
+ #define _i_MAP_ONLY c_false
+ #define _i_SET_ONLY c_true
+ #define _i_keyref(vp) (vp)
#else
- #define cx_MAP_ONLY c_true
- #define cx_SET_ONLY c_false
- #define cx_keyref(vp) (&(vp)->first)
+ #define _i_MAP_ONLY c_true
+ #define _i_SET_ONLY c_false
+ #define _i_keyref(vp) (&(vp)->first)
#endif
#include "template.h"
-#ifndef i_fwd
-_cx_deftypes(_c_aatree_types, _cx_self, i_key, i_val, cx_MAP_ONLY, cx_SET_ONLY);
+#if !c_option(c_is_fwd)
+_cx_deftypes(_c_aatree_types, _cx_self, i_key, i_val, _i_MAP_ONLY, _i_SET_ONLY);
#endif
-cx_MAP_ONLY( struct _cx_value {
+_i_MAP_ONLY( struct _cx_value {
_cx_key first;
_cx_mapped second;
}; )
@@ -89,12 +89,14 @@ struct _cx_node { typedef i_keyraw _cx_rawkey;
typedef i_valraw _cx_memb(_rawmapped);
-typedef cx_SET_ONLY( i_keyraw )
- cx_MAP_ONLY( struct { i_keyraw first; i_valraw second; } )
+typedef _i_SET_ONLY( i_keyraw )
+ _i_MAP_ONLY( struct { i_keyraw first; i_valraw second; } )
_cx_rawvalue;
STC_API _cx_self _cx_memb(_init)(void);
+#if !c_option(c_no_clone)
STC_API _cx_self _cx_memb(_clone)(_cx_self tree);
+#endif
STC_API void _cx_memb(_del)(_cx_self* self);
STC_API bool _cx_memb(_reserve)(_cx_self* self, size_t cap);
STC_API _cx_value* _cx_memb(_find_it)(const _cx_self* self, i_keyraw rkey, _cx_iter* out);
@@ -126,33 +128,23 @@ _cx_memb(_with_capacity)(const size_t cap) { return tree;
}
-STC_INLINE void
-_cx_memb(_copy)(_cx_self *self, _cx_self other) {
- if (self->nodes == other.nodes) return;
- _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
-}
-
STC_INLINE _cx_rawvalue
_cx_memb(_value_toraw)(_cx_value* val) {
- return cx_SET_ONLY( i_keyto(val) )
- cx_MAP_ONLY( c_make(_cx_rawvalue){i_keyto(&val->first), i_valto(&val->second)} );
+ return _i_SET_ONLY( i_keyto(val) )
+ _i_MAP_ONLY( c_make(_cx_rawvalue){i_keyto(&val->first), i_valto(&val->second)} );
}
STC_INLINE void
_cx_memb(_value_del)(_cx_value* val) {
- i_keydel(cx_keyref(val));
- cx_MAP_ONLY( i_valdel(&val->second); )
+ i_keydel(_i_keyref(val));
+ _i_MAP_ONLY( i_valdel(&val->second); )
}
-STC_INLINE void
-_cx_memb(_value_clone)(_cx_value* dst, _cx_value* val) {
- *cx_keyref(dst) = i_keyfrom(i_keyto(cx_keyref(val)));
- cx_MAP_ONLY( dst->second = i_valfrom(i_valto(&val->second)); )
-}
-
-cx_MAP_ONLY(
- STC_API _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped);
+#ifndef _i_isset
+ #if !c_option(c_no_clone)
STC_API _cx_result _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped);
+ #endif
+ STC_API _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped);
STC_INLINE _cx_result
_cx_memb(_put)(_cx_self* self, i_key key, i_val mapped)
@@ -161,7 +153,7 @@ cx_MAP_ONLY( STC_INLINE const _cx_mapped*
_cx_memb(_at)(const _cx_self* self, i_keyraw rkey)
{ _cx_iter it; return &_cx_memb(_find_it)(self, rkey, &it)->second; }
-)
+#endif
STC_INLINE _cx_iter
_cx_memb(_find)(const _cx_self* self, i_keyraw rkey) {
@@ -170,21 +162,35 @@ _cx_memb(_find)(const _cx_self* self, i_keyraw rkey) { return it;
}
+#if !c_option(c_no_clone)
+STC_INLINE void
+_cx_memb(_copy)(_cx_self *self, _cx_self other) {
+ if (self->nodes == other.nodes) return;
+ _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
+}
+
+STC_INLINE void
+_cx_memb(_value_clone)(_cx_value* dst, _cx_value* val) {
+ *_i_keyref(dst) = i_keyfrom(i_keyto(_i_keyref(val)));
+ _i_MAP_ONLY( dst->second = i_valfrom(i_valto(&val->second)); )
+}
+
STC_INLINE _cx_result
-_cx_memb(_emplace)(_cx_self* self, i_keyraw rkey cx_MAP_ONLY(, i_valraw rmapped)) {
+_cx_memb(_emplace)(_cx_self* self, i_keyraw rkey _i_MAP_ONLY(, i_valraw rmapped)) {
_cx_result res = _cx_memb(_insert_entry_)(self, rkey);
if (res.inserted) {
- *cx_keyref(res.ref) = i_keyfrom(rkey);
- cx_MAP_ONLY(res.ref->second = i_valfrom(rmapped);)
+ *_i_keyref(res.ref) = i_keyfrom(rkey);
+ _i_MAP_ONLY(res.ref->second = i_valfrom(rmapped);)
}
return res;
}
+#endif // !c_no_clone
STC_INLINE _cx_result
-_cx_memb(_insert)(_cx_self* self, i_key key cx_MAP_ONLY(, i_val mapped)) {
+_cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped)) {
_cx_result res = _cx_memb(_insert_entry_)(self, i_keyto(&key));
- if (res.inserted) { *cx_keyref(res.ref) = key; cx_MAP_ONLY( res.ref->second = mapped; )}
- else { i_keydel(&key); cx_MAP_ONLY( i_valdel(&mapped); )}
+ if (res.inserted) { *_i_keyref(res.ref) = key; _i_MAP_ONLY( res.ref->second = mapped; )}
+ else { i_keydel(&key); _i_MAP_ONLY( i_valdel(&mapped); )}
return res;
}
@@ -268,7 +274,7 @@ _cx_memb(_node_new_)(_cx_self* self, int level) { return (_cx_size) tn;
}
-cx_MAP_ONLY(
+#if !defined _i_isset
STC_DEF _cx_result
_cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped) {
_cx_result res = _cx_memb(_insert_entry_)(self, i_keyto(&key));
@@ -276,7 +282,7 @@ cx_MAP_ONLY( else { i_keydel(&key); i_valdel(&res.ref->second); }
res.ref->second = mapped; return res;
}
-
+ #if !c_option(c_no_clone)
STC_DEF _cx_result
_cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped) {
_cx_result res = _cx_memb(_insert_entry_)(self, rkey);
@@ -284,7 +290,8 @@ cx_MAP_ONLY( else i_valdel(&res.ref->second);
res.ref->second = i_valfrom(rmapped); return res;
}
-)
+ #endif
+#endif
STC_DEF _cx_value*
_cx_memb(_find_it)(const _cx_self* self, i_keyraw rkey, _cx_iter* out) {
@@ -292,7 +299,7 @@ _cx_memb(_find_it)(const _cx_self* self, i_keyraw rkey, _cx_iter* out) { _cx_node *d = out->_d = self->nodes;
out->_top = 0;
while (tn) {
- int c; _cx_rawkey raw = i_keyto(cx_keyref(&d[tn].value));
+ int c; _cx_rawkey raw = i_keyto(_i_keyref(&d[tn].value));
if ((c = i_cmp(&raw, &rkey)) < 0)
tn = d[tn].link[1];
else if (c > 0)
@@ -360,7 +367,7 @@ _cx_memb(_insert_entry_i_)(_cx_self* self, _cx_size tn, const _cx_rawkey* rkey, int c, top = 0, dir = 0;
while (tx) {
up[top++] = tx;
- i_keyraw raw = i_keyto(cx_keyref(&d[tx].value));
+ i_keyraw raw = i_keyto(_i_keyref(&d[tx].value));
if ((c = i_cmp(&raw, rkey)) == 0) {res->ref = &d[tx].value; return tn; }
dir = (c < 0);
tx = d[tx].link[dir];
@@ -391,7 +398,7 @@ STC_DEF _cx_size _cx_memb(_erase_r_)(_cx_node *d, _cx_size tn, const _cx_rawkey* rkey, int *erased) {
if (tn == 0)
return 0;
- i_keyraw raw = i_keyto(cx_keyref(&d[tn].value));
+ i_keyraw raw = i_keyto(_i_keyref(&d[tn].value));
_cx_size tx; int c = i_cmp(&raw, rkey);
if (c != 0)
d[tn].link[c < 0] = _cx_memb(_erase_r_)(d, d[tn].link[c < 0], rkey, erased);
@@ -403,7 +410,7 @@ _cx_memb(_erase_r_)(_cx_node *d, _cx_size tn, const _cx_rawkey* rkey, int *erase while (d[tx].link[1])
tx = d[tx].link[1];
d[tn].value = d[tx].value; /* move */
- raw = i_keyto(cx_keyref(&d[tn].value));
+ raw = i_keyto(_i_keyref(&d[tn].value));
d[tn].link[0] = _cx_memb(_erase_r_)(d, d[tn].link[0], &raw, erased);
} else { /* unlink node */
tx = tn;
@@ -436,9 +443,9 @@ _cx_memb(_erase)(_cx_self* self, i_keyraw rkey) { STC_DEF _cx_iter
_cx_memb(_erase_at)(_cx_self* self, _cx_iter it) {
- _cx_rawkey raw = i_keyto(cx_keyref(it.ref)), nxt;
+ _cx_rawkey raw = i_keyto(_i_keyref(it.ref)), nxt;
_cx_memb(_next)(&it);
- if (it.ref) nxt = i_keyto(cx_keyref(it.ref));
+ if (it.ref) nxt = i_keyto(_i_keyref(it.ref));
_cx_memb(_erase)(self, raw);
if (it.ref) _cx_memb(_find_it)(self, nxt, &it);
return it;
@@ -448,16 +455,17 @@ STC_DEF _cx_iter _cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2) {
if (!it2.ref) { while (it1.ref) it1 = _cx_memb(_erase_at)(self, it1);
return it1; }
- _cx_key k1 = *cx_keyref(it1.ref), k2 = *cx_keyref(it2.ref);
+ _cx_key k1 = *_i_keyref(it1.ref), k2 = *_i_keyref(it2.ref);
_cx_rawkey r1 = i_keyto(&k1);
for (;;) {
if (memcmp(&k1, &k2, sizeof k1) == 0) return it1;
- _cx_memb(_next)(&it1); k1 = *cx_keyref(it1.ref);
+ _cx_memb(_next)(&it1); k1 = *_i_keyref(it1.ref);
_cx_memb(_erase)(self, r1);
_cx_memb(_find_it)(self, (r1 = i_keyto(&k1)), &it1);
}
}
+#if !c_option(c_no_clone)
STC_DEF _cx_size
_cx_memb(_clone_r_)(_cx_self* self, _cx_node* src, _cx_size sn) {
if (sn == 0) return 0;
@@ -476,6 +484,7 @@ _cx_memb(_clone)(_cx_self tree) { _csmap_rep(&clone)->size = _csmap_rep(&tree)->size;
return clone;
}
+#endif // !c_no_clone
STC_DEF void
_cx_memb(_del_r_)(_cx_node* d, _cx_size tn) {
@@ -495,9 +504,9 @@ _cx_memb(_del)(_cx_self* self) { }
#endif // IMPLEMENTATION
-#undef i_isset
-#undef cx_keyref
-#undef cx_MAP_ONLY
-#undef cx_SET_ONLY
+#undef _i_isset
+#undef _i_keyref
+#undef _i_MAP_ONLY
+#undef _i_SET_ONLY
#include "template.h"
#define CSMAP_H_INCLUDED
diff --git a/include/stc/csptr.h b/include/stc/csptr.h index 7415c20a..82d882d9 100644 --- a/include/stc/csptr.h +++ b/include/stc/csptr.h @@ -73,25 +73,26 @@ typedef long atomic_count_t; #endif
#define csptr_null {NULL, NULL}
+#define _cx_csptr_rep struct _cx_memb(_rep_)
#endif // CSPTR_H_INCLUDED
-#ifndef i_prefix
-#define i_prefix csptr_
+#ifndef _i_prefix
+#define _i_prefix csptr_
#endif
+#define i_valfrom _not_to_be_used_
#include "template.h"
-#ifdef i_nonatomic
- #define cx_increment(v) (++*(v))
- #define cx_decrement(v) (--*(v))
+#if !c_option(c_no_atomic)
+ #define _i_increment(v) c_atomic_increment(v)
+ #define _i_decrement(v) c_atomic_decrement(v)
#else
- #define cx_increment(v) c_atomic_increment(v)
- #define cx_decrement(v) c_atomic_decrement(v)
+ #define _i_increment(v) (++*(v))
+ #define _i_decrement(v) (--*(v))
#endif
-#ifndef i_fwd
+#if !c_option(c_is_fwd)
_cx_deftypes(_c_csptr_types, _cx_self, i_val);
#endif
-#define cx_csptr_rep struct _cx_memb(_rep_)
-cx_csptr_rep { atomic_count_t counter; _cx_value value; };
+_cx_csptr_rep { atomic_count_t counter; _cx_value value; };
STC_INLINE _cx_self
_cx_memb(_init)(void) { return c_make(_cx_self){NULL, NULL}; }
@@ -108,7 +109,7 @@ _cx_memb(_from)(_cx_value* p) { STC_INLINE _cx_self
_cx_memb(_make)(_cx_value val) {
- _cx_self ptr; cx_csptr_rep *rep = c_alloc(cx_csptr_rep);
+ _cx_self ptr; _cx_csptr_rep *rep = c_alloc(_cx_csptr_rep);
*(ptr.use_count = &rep->counter) = 1;
*(ptr.get = &rep->value) = val;
return ptr;
@@ -116,7 +117,7 @@ _cx_memb(_make)(_cx_value val) { STC_INLINE _cx_self
_cx_memb(_clone)(_cx_self ptr) {
- if (ptr.use_count) cx_increment(ptr.use_count);
+ if (ptr.use_count) _i_increment(ptr.use_count);
return ptr;
}
@@ -129,9 +130,9 @@ _cx_memb(_move)(_cx_self* self) { STC_INLINE void
_cx_memb(_del)(_cx_self* self) {
- if (self->use_count && cx_decrement(self->use_count) == 0) {
+ if (self->use_count && _i_decrement(self->use_count) == 0) {
i_valdel(self->get);
- if (self->get != &((cx_csptr_rep *)self->use_count)->value)
+ if (self->get != &((_cx_csptr_rep *)self->use_count)->value)
c_free(self->get);
c_free(self->use_count);
}
@@ -157,7 +158,7 @@ _cx_memb(_reset_with)(_cx_self* self, _cx_value val) { STC_INLINE void
_cx_memb(_copy)(_cx_self* self, _cx_self ptr) {
- if (ptr.use_count) cx_increment(ptr.use_count);
+ if (ptr.use_count) _i_increment(ptr.use_count);
_cx_memb(_del)(self); *self = ptr;
}
@@ -167,18 +168,16 @@ _cx_memb(_take)(_cx_self* self, _cx_self ptr) { *self = ptr;
}
-#ifndef i_cmp_none
+#if !c_option(c_no_compare)
STC_INLINE int
_cx_memb(_compare)(const _cx_self* x, const _cx_self* y) {
-#ifdef i_cmp_default
+#ifdef _i_cmp_default
return c_default_compare(&x->get, &y->get);
#else
return i_cmp(x->get, y->get);
#endif
}
#endif
-#undef cx_csptr_rep
-#undef cx_increment
-#undef cx_decrement
-#undef i_nonatomic
+#undef _i_increment
+#undef _i_decrement
#include "template.h"
\ No newline at end of file diff --git a/include/stc/csset.h b/include/stc/csset.h index ee06ec7f..e4558192 100644 --- a/include/stc/csset.h +++ b/include/stc/csset.h @@ -42,8 +42,8 @@ int main(void) { }
*/
-#ifndef i_prefix
-#define i_prefix csset_
+#ifndef _i_prefix
+#define _i_prefix csset_
#endif
-#define i_isset
+#define _i_isset
#include "csmap.h"
diff --git a/include/stc/cstack.h b/include/stc/cstack.h index 099c2869..c1170f79 100644 --- a/include/stc/cstack.h +++ b/include/stc/cstack.h @@ -28,12 +28,12 @@ #include "forward.h"
#endif // CSTACK_H_INCLUDED
-#ifndef i_prefix
-#define i_prefix cstack_
+#ifndef _i_prefix
+#define _i_prefix cstack_
#endif
#include "template.h"
-#if !defined i_fwd
+#if !c_option(c_is_fwd)
_cx_deftypes(_c_cstack_types, _cx_self, i_val);
#endif
typedef i_valraw _cx_rawvalue;
@@ -91,12 +91,14 @@ STC_INLINE _cx_value* _cx_memb(_push)(_cx_self* self, _cx_value val) { *vp = val; return vp;
}
-STC_INLINE _cx_value* _cx_memb(_emplace)(_cx_self* self, _cx_rawvalue raw)
- { return _cx_memb(_push)(self, i_valfrom(raw)); }
-
STC_INLINE _cx_value* _cx_memb(_at)(const _cx_self* self, size_t idx)
{ assert(idx < self->size); return self->data + idx; }
+#if !c_option(c_no_clone)
+
+STC_INLINE _cx_value* _cx_memb(_emplace)(_cx_self* self, _cx_rawvalue raw)
+ { return _cx_memb(_push)(self, i_valfrom(raw)); }
+
STC_INLINE _cx_self _cx_memb(_clone)(_cx_self v) {
_cx_self out = {(_cx_value *) c_malloc(v.size*sizeof(_cx_value)), v.size, v.size};
for (size_t i = 0; i < v.size; ++i, ++v.data) out.data[i] = i_valfrom(i_valto(v.data));
@@ -113,6 +115,8 @@ STC_INLINE i_val _cx_memb(_value_clone)(_cx_value val) STC_INLINE i_valraw _cx_memb(_value_toraw)(_cx_value* val)
{ return i_valto(val); }
+#endif // !c_no_clone
+
STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self)
{ return c_make(_cx_iter){self->data}; }
STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self)
diff --git a/include/stc/cstr.h b/include/stc/cstr.h index 7cb92685..f47d8a02 100644 --- a/include/stc/cstr.h +++ b/include/stc/cstr.h @@ -383,4 +383,4 @@ c_strnstrn(const char *s, const char *needle, size_t slen, const size_t nlen) { }
#endif
-#endif
\ No newline at end of file +#endif
diff --git a/include/stc/cvec.h b/include/stc/cvec.h index 25c82765..626ddad5 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -38,9 +38,9 @@ struct MyStruct { #define i_val_str // special for cstr
#include <stc/cvec.h>
-#define i_fwd // forward declared
-#define i_tag i32
#define i_val int
+#define i_opt c_is_fwd // forward declared
+#define i_tag i32
#include <stc/cvec.h>
int main() {
@@ -68,47 +68,73 @@ struct cvec_rep { size_t size, cap; void* data[]; }; #define cvec_rep_(self) c_container_of((self)->data, struct cvec_rep, data)
#endif // CVEC_H_INCLUDED
-#ifndef i_prefix
-#define i_prefix cvec_
+#ifndef _i_prefix
+#define _i_prefix cvec_
#endif
#include "template.h"
-#if !defined i_fwd
+#if !c_option(c_is_fwd)
_cx_deftypes(_c_cvec_types, _cx_self, i_val);
#endif
typedef i_valraw _cx_rawvalue;
STC_API _cx_self _cx_memb(_init)(void);
-STC_API _cx_self _cx_memb(_clone)(_cx_self cx);
STC_API void _cx_memb(_del)(_cx_self* self);
STC_API void _cx_memb(_clear)(_cx_self* self);
STC_API bool _cx_memb(_reserve)(_cx_self* self, size_t cap);
STC_API bool _cx_memb(_resize)(_cx_self* self, size_t size, i_val fill_val);
-#ifndef i_cmp_none
+STC_API _cx_value* _cx_memb(_push_back)(_cx_self* self, i_val value);
+STC_API _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2);
+STC_API _cx_iter _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos,
+ const _cx_value* p1, const _cx_value* p2);
+#if !c_option(c_no_compare)
STC_API int _cx_memb(_value_compare)(const _cx_value* x, const _cx_value* y);
STC_API _cx_iter _cx_memb(_find_in)(_cx_iter it1, _cx_iter it2, i_valraw raw);
STC_API _cx_iter _cx_memb(_bsearch_in)(_cx_iter it1, _cx_iter it2, i_valraw raw);
#endif
-STC_API _cx_value* _cx_memb(_push_back)(_cx_self* self, i_val value);
-STC_API _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2);
-STC_API _cx_iter _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_value* p1, const _cx_value* p2, bool clone);
+
+#if !c_option(c_no_clone)
+STC_API _cx_self _cx_memb(_clone)(_cx_self cx);
+STC_API _cx_iter _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos,
+ const _cx_value* p1, const _cx_value* p2);
STC_API _cx_iter _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_rawvalue* p1, const _cx_rawvalue* p2);
+ const _cx_rawvalue* p1, const _cx_rawvalue* p2);
+STC_INLINE i_val _cx_memb(_value_clone)(_cx_value val)
+ { return i_valfrom(i_valto(&val)); }
+STC_INLINE i_val _cx_memb(_value_fromraw)(i_valraw raw) { return i_valfrom(raw); }
+STC_INLINE _cx_value* _cx_memb(_emplace_back)(_cx_self* self, i_valraw raw)
+ { return _cx_memb(_push_back)(self, i_valfrom(raw)); }
+STC_INLINE void
+_cx_memb(_copy)(_cx_self *self, _cx_self other) {
+ if (self->data == other.data) return;
+ _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
+}
+STC_INLINE _cx_iter
+_cx_memb(_emplace)(_cx_self* self, const size_t idx, i_valraw raw) {
+ return _cx_memb(_emplace_range_p)(self, self->data + idx, &raw, &raw + 1);
+}
+STC_INLINE _cx_iter
+_cx_memb(_emplace_n)(_cx_self* self, const size_t idx, const _cx_rawvalue arr[], const size_t n) {
+ return _cx_memb(_emplace_range_p)(self, self->data + idx, arr, arr + n);
+}
+STC_INLINE _cx_iter
+_cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, i_valraw raw) {
+ return _cx_memb(_emplace_range_p)(self, it.ref, &raw, &raw + 1);
+}
+STC_INLINE _cx_iter
+_cx_memb(_emplace_range)(_cx_self* self, _cx_iter it, _cx_iter it1, _cx_iter it2) {
+ return _cx_memb(_clone_range_p)(self, it.ref, it1.ref, it2.ref);
+}
+#endif
STC_INLINE size_t _cx_memb(_size)(_cx_self cx) { return cvec_rep_(&cx)->size; }
STC_INLINE size_t _cx_memb(_capacity)(_cx_self cx) { return cvec_rep_(&cx)->cap; }
STC_INLINE bool _cx_memb(_empty)(_cx_self cx) { return !cvec_rep_(&cx)->size; }
-STC_INLINE i_val _cx_memb(_value_fromraw)(i_valraw raw) { return i_valfrom(raw); }
STC_INLINE i_valraw _cx_memb(_value_toraw)(_cx_value* val) { return i_valto(val); }
-STC_INLINE i_val _cx_memb(_value_clone)(_cx_value val)
- { return i_valfrom(i_valto(&val)); }
STC_INLINE void _cx_memb(_swap)(_cx_self* a, _cx_self* b) { c_swap(_cx_self, *a, *b); }
STC_INLINE _cx_value* _cx_memb(_front)(const _cx_self* self) { return self->data; }
STC_INLINE _cx_value* _cx_memb(_back)(const _cx_self* self)
{ return self->data + cvec_rep_(self)->size - 1; }
-STC_INLINE _cx_value* _cx_memb(_emplace_back)(_cx_self* self, i_valraw raw)
- { return _cx_memb(_push_back)(self, i_valfrom(raw)); }
STC_INLINE void _cx_memb(_pop_back)(_cx_self* self)
{ _cx_value* p = &self->data[--cvec_rep_(self)->size]; i_valdel(p); }
STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self)
@@ -139,40 +165,17 @@ _cx_memb(_shrink_to_fit)(_cx_self *self) { _cx_memb(_reserve)(self, _cx_memb(_size)(*self));
}
-STC_INLINE void
-_cx_memb(_copy)(_cx_self *self, _cx_self other) {
- if (self->data == other.data) return;
- _cx_memb(_del)(self); *self = _cx_memb(_clone)(other);
-}
-
STC_INLINE _cx_iter
_cx_memb(_insert)(_cx_self* self, const size_t idx, i_val value) {
- return _cx_memb(_insert_range_p)(self, self->data + idx, &value, &value + 1, false);
+ return _cx_memb(_insert_range_p)(self, self->data + idx, &value, &value + 1);
}
STC_INLINE _cx_iter
_cx_memb(_insert_n)(_cx_self* self, const size_t idx, const _cx_value arr[], const size_t n) {
- return _cx_memb(_insert_range_p)(self, self->data + idx, arr, arr + n, false);
+ return _cx_memb(_insert_range_p)(self, self->data + idx, arr, arr + n);
}
STC_INLINE _cx_iter
_cx_memb(_insert_at)(_cx_self* self, _cx_iter it, i_val value) {
- return _cx_memb(_insert_range_p)(self, it.ref, &value, &value + 1, false);
-}
-
-STC_INLINE _cx_iter
-_cx_memb(_emplace)(_cx_self* self, const size_t idx, i_valraw raw) {
- return _cx_memb(_emplace_range_p)(self, self->data + idx, &raw, &raw + 1);
-}
-STC_INLINE _cx_iter
-_cx_memb(_emplace_n)(_cx_self* self, const size_t idx, const _cx_rawvalue arr[], const size_t n) {
- return _cx_memb(_emplace_range_p)(self, self->data + idx, arr, arr + n);
-}
-STC_INLINE _cx_iter
-_cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, i_valraw raw) {
- return _cx_memb(_emplace_range_p)(self, it.ref, &raw, &raw + 1);
-}
-STC_INLINE _cx_iter
-_cx_memb(_emplace_range)(_cx_self* self, _cx_iter it, _cx_iter it1, _cx_iter it2) {
- return _cx_memb(_insert_range_p)(self, it.ref, it1.ref, it2.ref, true);
+ return _cx_memb(_insert_range_p)(self, it.ref, &value, &value + 1);
}
STC_INLINE _cx_iter
@@ -194,7 +197,7 @@ _cx_memb(_at)(const _cx_self* self, const size_t idx) { return self->data + idx;
}
-#ifndef i_cmp_none
+#if !c_option(c_no_compare)
STC_INLINE _cx_iter
_cx_memb(_find)(const _cx_self* self, i_valraw raw) {
@@ -225,7 +228,7 @@ STC_INLINE void _cx_memb(_sort)(_cx_self* self) {
_cx_memb(_sort_range)(_cx_memb(_begin)(self), _cx_memb(_end)(self), _cx_memb(_value_compare));
}
-#endif // !i_cmp_none
+#endif // !c_no_compare
/* -------------------------- IMPLEMENTATION ------------------------- */
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) || defined(i_imp)
@@ -292,14 +295,6 @@ _cx_memb(_push_back)(_cx_self* self, i_val value) { *v = value; return v;
}
-STC_DEF _cx_self
-_cx_memb(_clone)(_cx_self cx) {
- const size_t len = cvec_rep_(&cx)->size;
- _cx_self out = _cx_memb(_with_capacity)(len);
- _cx_memb(_insert_range_p)(&out, out.data, cx.data, cx.data + len, true);
- return out;
-}
-
STC_DEF _cx_value*
_cx_memb(_insert_space_)(_cx_self* self, _cx_value* pos, const size_t len) {
const size_t idx = pos - self->data, size = cvec_rep_(self)->size;
@@ -314,20 +309,10 @@ _cx_memb(_insert_space_)(_cx_self* self, _cx_value* pos, const size_t len) { STC_DEF _cx_iter
_cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_value* p1, const _cx_value* p2, bool clone) {
- pos = _cx_memb(_insert_space_)(self, pos, p2 - p1);
- _cx_iter it = {pos};
- if (clone) for (; p1 != p2; ++p1) *pos++ = i_valfrom(i_valto(p1));
- else memcpy(pos, p1, (p2 - p1)*sizeof *p1);
- return it;
-}
-
-STC_DEF _cx_iter
-_cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_rawvalue* p1, const _cx_rawvalue* p2) {
+ const _cx_value* p1, const _cx_value* p2) {
pos = _cx_memb(_insert_space_)(self, pos, p2 - p1);
_cx_iter it = {pos};
- for (; p1 != p2; ++p1) *pos++ = i_valfrom(*p1);
+ memcpy(pos, p1, (p2 - p1)*sizeof *p1);
return it;
}
@@ -343,7 +328,37 @@ _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) { return c_make(_cx_iter){.ref = p1};
}
-#ifndef i_cmp_none
+#if !c_option(c_no_clone)
+
+STC_DEF _cx_self
+_cx_memb(_clone)(_cx_self cx) {
+ const size_t len = cvec_rep_(&cx)->size;
+ _cx_self out = _cx_memb(_with_capacity)(len);
+ _cx_memb(_clone_range_p)(&out, out.data, cx.data, cx.data + len);
+ return out;
+}
+
+STC_DEF _cx_iter
+_cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos,
+ const _cx_value* p1, const _cx_value* p2) {
+ pos = _cx_memb(_insert_space_)(self, pos, p2 - p1);
+ _cx_iter it = {pos};
+ for (; p1 != p2; ++p1) *pos++ = i_valfrom(i_valto(p1));
+ return it;
+}
+
+STC_DEF _cx_iter
+_cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos,
+ const _cx_rawvalue* p1, const _cx_rawvalue* p2) {
+ pos = _cx_memb(_insert_space_)(self, pos, p2 - p1);
+ _cx_iter it = {pos};
+ for (; p1 != p2; ++p1) *pos++ = i_valfrom(*p1);
+ return it;
+}
+#endif
+
+#if !c_option(c_no_compare)
+
STC_DEF _cx_iter
_cx_memb(_find_in)(_cx_iter i1, _cx_iter i2, i_valraw raw) {
for (; i1.ref != i2.ref; ++i1.ref) {
@@ -372,7 +387,7 @@ _cx_memb(_value_compare)(const _cx_value* x, const _cx_value* y) { i_valraw ry = i_valto(y);
return i_cmp(&rx, &ry);
}
-#endif // !i_cmp_none
+#endif // !c_no_compare
#endif
#include "template.h"
#define CVEC_H_INCLUDED
diff --git a/include/stc/template.h b/include/stc/template.h index ff1ea3fc..b8f6dfc4 100644 --- a/include/stc/template.h +++ b/include/stc/template.h @@ -20,12 +20,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#ifndef i_template
-#define i_template
+#ifndef _i_template
+#define _i_template
#ifndef STC_TEMPLATE_H_INCLUDED
#define STC_TEMPLATE_H_INCLUDED
- #define _cx_self c_PASTE(i_prefix, i_tag)
+ #define _cx_self c_PASTE(_i_prefix, i_tag)
#define _cx_memb(name) c_PASTE(_cx_self, name)
#define _cx_deftypes(macro, SELF, ...) c_EXPAND(macro(SELF, __VA_ARGS__))
#define _cx_value _cx_memb(_value)
@@ -53,8 +53,8 @@ #ifdef i_cnt
#define i_tag i_cnt
- #undef i_prefix
- #define i_prefix
+ #undef _i_prefix
+ #define _i_prefix
#endif
#ifdef i_key_csptr
@@ -107,19 +107,23 @@ #elif defined i_del
#error i_del not supported for maps, define i_keydel / i_valdel instead.
#endif
+#if defined i_from && defined i_isset
+ #define i_keyfrom i_from
+#elif defined i_from && !defined i_key
+ #define i_valfrom i_from
+#elif defined i_from
+ #error i_from not supported for maps, define i_keyfrom / i_valfrom instead.
+#endif
#ifdef i_key
- #ifdef i_isset
+ #ifdef _i_isset
#define i_val i_key
#endif
#ifndef i_tag
#define i_tag i_key
#endif
- #if !defined i_keyfrom && defined i_keydel
- #ifdef STC_DEBUG
- #error i_keydel defined, but not i_keyfrom.
- #endif
- #define i_keyfrom c_no_clone
+ #if defined i_keydel && !defined i_keyfrom && !c_option(c_no_clone)
+ #error i_keydel defined requires defining i_keyfrom or '#define i_opt c_no_clone'
#elif !defined i_keyfrom
#define i_keyfrom c_default_fromraw
#endif
@@ -138,18 +142,15 @@ #ifndef i_keydel
#define i_keydel c_default_del
#endif
-#elif defined i_isset || defined i_hash || defined i_equ
+#elif defined _i_isset || defined i_hash || defined i_equ
#error i_key define is missing.
#endif
#ifndef i_tag
#define i_tag i_val
#endif
-#if !defined i_valfrom && defined i_valdel
- #ifdef STC_DEBUG
- #error i_del/i_valdel defined, but not i_valfrom.
- #endif
- #define i_valfrom c_no_clone
+#if defined i_valdel && !defined i_valfrom && !c_option(c_no_clone)
+ #error i_del/i_valdel defined: requires also defining i_valfrom or '#define i_opt c_no_clone'
#elif !defined i_valfrom
#define i_valfrom c_default_fromraw
#endif
@@ -162,18 +163,16 @@ #endif
#ifndef i_cmp
#define i_cmp c_default_compare
- #define i_cmp_default
+ #define _i_cmp_default
#endif
#else // -------------------------------------------------------
-#undef i_prefix
+#undef i_cnt
#undef i_tag
#undef i_imp
-#undef i_fwd
+#undef i_opt
#undef i_cmp
-#undef i_cmp_none
-#undef i_cmp_default
#undef i_del
#undef i_equ
#undef i_hash
@@ -181,6 +180,7 @@ #undef i_val_str
#undef i_valdel
#undef i_valfrom
+#undef i_from
#undef i_valto
#undef i_valraw
#undef i_key
@@ -191,7 +191,8 @@ #undef i_keyraw
#undef i_key_csptr
#undef i_val_csptr
-#undef i_cnt
-#undef i_template
+#undef _i_prefix
+#undef _i_cmp_default
+#undef _i_template
#endif
|
