summaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/stc/alt/csmap.h2
-rw-r--r--include/stc/alt/cstr.h47
-rw-r--r--include/stc/carc.h45
-rw-r--r--include/stc/carr2.h13
-rw-r--r--include/stc/carr3.h13
-rw-r--r--include/stc/cbits.h2
-rw-r--r--include/stc/cbox.h37
-rw-r--r--include/stc/ccommon.h51
-rw-r--r--include/stc/cdeq.h204
-rw-r--r--include/stc/clist.h5
-rw-r--r--include/stc/cmap.h41
-rw-r--r--include/stc/cpque.h12
-rw-r--r--include/stc/cregex.h5
-rw-r--r--include/stc/csmap.h2
-rw-r--r--include/stc/cstack.h15
-rw-r--r--include/stc/cstr.h125
-rw-r--r--include/stc/csview.h21
-rw-r--r--include/stc/cvec.h206
-rw-r--r--include/stc/forward.h18
-rw-r--r--include/stc/template.h14
20 files changed, 474 insertions, 404 deletions
diff --git a/include/stc/alt/csmap.h b/include/stc/alt/csmap.h
index 60a1b72a..4b90fb78 100644
--- a/include/stc/alt/csmap.h
+++ b/include/stc/alt/csmap.h
@@ -32,7 +32,7 @@
#include <stc/csmap.h>
int main(void) {
- c_autovar (csmap_sx m = csmap_sx_init(), csmap_sx_drop(&m))
+ c_with (csmap_sx m = csmap_sx_init(), csmap_sx_drop(&m))
{
csmap_sx_emplace(&m, "Testing one", 1.234);
csmap_sx_emplace(&m, "Testing two", 12.34);
diff --git a/include/stc/alt/cstr.h b/include/stc/alt/cstr.h
index c669c620..a2233432 100644
--- a/include/stc/alt/cstr.h
+++ b/include/stc/alt/cstr.h
@@ -56,8 +56,8 @@ STC_API cstr* cstr_append_n(cstr* self, const char* str, size_t n);
STC_API cstr cstr_replace_sv(csview str, csview find, csview repl, unsigned count);
STC_DEF void cstr_replace_at_sv(cstr* self, const size_t pos, size_t len, csview repl);
STC_API void cstr_erase_n(cstr* self, size_t pos, size_t n);
-STC_API size_t cstr_find(cstr s, const char* needle);
-STC_API size_t cstr_find_at(cstr s, size_t pos, const char* needle);
+STC_API size_t cstr_find(const cstr* self, const char* needle);
+STC_API size_t cstr_find_at(const cstr* self, size_t pos, const char* needle);
STC_API bool cstr_getdelim(cstr *self, int delim, FILE *stream);
STC_INLINE cstr cstr_init() { return cstr_null; }
@@ -70,7 +70,7 @@ STC_INLINE csview cstr_sv(const cstr* self)
STC_INLINE cstr cstr_from(const char* str)
{ return cstr_from_n(str, strlen(str)); }
STC_INLINE char* cstr_data(cstr* self) { return self->str; }
-STC_INLINE size_t cstr_size(cstr s) { return _cstr_p(&s)->size; }
+STC_INLINE size_t cstr_size(const cstr* self) { return _cstr_p(self)->size; }
STC_INLINE size_t cstr_capacity(cstr s) { return _cstr_p(&s)->cap; }
STC_INLINE bool cstr_empty(cstr s) { return _cstr_p(&s)->size == 0; }
STC_INLINE void cstr_drop(cstr* self)
@@ -106,12 +106,12 @@ STC_INLINE void cstr_erase(cstr* self, const size_t pos)
STC_INLINE char* cstr_front(cstr* self) { return self->str; }
STC_INLINE char* cstr_back(cstr* self)
{ return self->str + _cstr_p(self)->size - 1; }
-STC_INLINE bool cstr_equals(cstr s, const char* str)
- { return strcmp(s.str, str) == 0; }
-STC_INLINE bool cstr_equals_s(cstr s1, cstr s2)
- { return strcmp(s1.str, s2.str) == 0; }
-STC_INLINE bool cstr_contains(cstr s, const char* needle)
- { return strstr(s.str, needle) != NULL; }
+STC_INLINE bool cstr_equals(const cstr* self, const char* str)
+ { return strcmp(self->str, str) == 0; }
+STC_INLINE bool cstr_equals_s(const cstr* self, cstr s)
+ { return strcmp(self->str, s.str) == 0; }
+STC_INLINE bool cstr_contains(const cstr* self, const char* needle)
+ { return strstr(self->str, needle) != NULL; }
STC_INLINE bool cstr_getline(cstr *self, FILE *stream)
{ return cstr_getdelim(self, '\n', stream); }
@@ -133,7 +133,7 @@ STC_INLINE cstr cstr_with_size(const size_t len, const char fill) {
}
STC_INLINE char* cstr_append_uninit(cstr *self, size_t n) {
- size_t len = cstr_size(*self); char* d;
+ size_t len = cstr_size(self); char* d;
if (!(d = cstr_reserve(self, len + n))) return NULL;
_cstr_p(self)->size += n;
return d + len;
@@ -152,14 +152,15 @@ STC_INLINE cstr cstr_move(cstr* self) {
return tmp;
}
-STC_INLINE bool cstr_starts_with(cstr s, const char* sub) {
- while (*sub && *s.str == *sub) ++s.str, ++sub;
+STC_INLINE bool cstr_starts_with(const cstr* self, const char* sub) {
+ const char* p = self->str;
+ while (*sub && *p == *sub) ++p, ++sub;
return *sub == 0;
}
-STC_INLINE bool cstr_ends_with(cstr s, const char* sub) {
- const size_t n = strlen(sub), sz = _cstr_p(&s)->size;
- return n <= sz && !memcmp(s.str + sz - n, sub, n);
+STC_INLINE bool cstr_ends_with(const cstr* self, const char* sub) {
+ const size_t n = strlen(sub), sz = _cstr_p(self)->size;
+ return n <= sz && !memcmp(self->str + sz - n, sub, n);
}
STC_INLINE int c_strncasecmp(const char* s1, const char* s2, size_t nmax) {
@@ -309,7 +310,7 @@ STC_INLINE void _cstr_internal_move(cstr* self, const size_t pos1, const size_t
STC_DEF void
cstr_replace_at_sv(cstr* self, const size_t pos, size_t len, csview repl) {
- const size_t sz = cstr_size(*self);
+ const size_t sz = cstr_size(self);
if (len > sz - pos) len = sz - pos;
c_autobuf (xstr, char, repl.size) {
memcpy(xstr, repl.str, repl.size);
@@ -366,16 +367,16 @@ cstr_getdelim(cstr *self, const int delim, FILE *fp) {
}
STC_DEF size_t
-cstr_find(cstr s, const char* needle) {
- char* res = strstr(s.str, needle);
- return res ? res - s.str : cstr_npos;
+cstr_find(const cstr* self, const char* needle) {
+ char* res = strstr(self->str, needle);
+ return res ? res - self->str : cstr_npos;
}
STC_DEF size_t
-cstr_find_at(cstr s, const size_t pos, const char* needle) {
- if (pos > _cstr_p(&s)->size) return cstr_npos;
- char* res = strstr(s.str + pos, needle);
- return res ? res - s.str : cstr_npos;
+cstr_find_at(const cstr* self, const size_t pos, const char* needle) {
+ if (pos > _cstr_p(self)->size) return cstr_npos;
+ char* res = strstr(self->str + pos, needle);
+ return res ? res - self->str : cstr_npos;
}
#endif
diff --git a/include/stc/carc.h b/include/stc/carc.h
index 57f00899..6e8f7d38 100644
--- a/include/stc/carc.h
+++ b/include/stc/carc.h
@@ -34,18 +34,18 @@ void Person_drop(Person* p) {
c_drop(cstr, &p->name, &p->last);
}
-#define i_tag person
+#define i_type ArcPers
#define i_key Person
#define i_keydrop Person_drop
#define i_opt c_no_cmp
#include <stc/carc.h>
int main() {
- carc_person p = carc_person_make(Person_new("John", "Smiths"));
- carc_person q = carc_person_clone(p); // share the pointer
+ ArcPers p = ArcPers_from(Person_new("John", "Smiths"));
+ ArcPers q = ArcPers_clone(p); // share the pointer
printf("%s %s. uses: %" PRIuMAX "\n", cstr_str(&q.get->name), cstr_str(&q.get->last), *q.use_count);
- c_drop(carc_person, &p, &q);
+ c_drop(ArcPers, &p, &q);
}
*/
#include "ccommon.h"
@@ -56,14 +56,17 @@ int main() {
#include <stdlib.h>
#if defined(__GNUC__) || defined(__clang__)
+ typedef long catomic_long;
#define c_atomic_inc(v) (void)__atomic_add_fetch(v, 1, __ATOMIC_SEQ_CST)
#define c_atomic_dec_and_test(v) !__atomic_sub_fetch(v, 1, __ATOMIC_SEQ_CST)
#elif defined(_MSC_VER)
#include <intrin.h>
+ typedef long catomic_long;
#define c_atomic_inc(v) (void)_InterlockedIncrement(v)
#define c_atomic_dec_and_test(v) !_InterlockedDecrement(v)
#else
#include <stdatomic.h>
+ typedef _Atomic long catomic_long;
#define c_atomic_inc(v) (void)atomic_fetch_add(v, 1)
#define c_atomic_dec_and_test(v) (atomic_fetch_sub(v, 1) == 1)
#endif
@@ -88,23 +91,23 @@ typedef i_keyraw _cx_raw;
#if !c_option(c_is_fwd)
_cx_deftypes(_c_carc_types, _cx_self, i_key);
#endif
-_cx_carc_rep { long counter; i_key value; };
+_cx_carc_rep { catomic_long counter; i_key value; };
STC_INLINE _cx_self _cx_memb(_init)(void)
{ return c_make(_cx_self){NULL, NULL}; }
-STC_INLINE long _cx_memb(_use_count)(_cx_self ptr)
- { return ptr.use_count ? *ptr.use_count : 0; }
+STC_INLINE long _cx_memb(_use_count)(const _cx_self* self)
+ { return self->use_count ? *self->use_count : 0; }
STC_INLINE _cx_self _cx_memb(_from_ptr)(_cx_value* p) {
_cx_self ptr = {p};
if (p)
- *(ptr.use_count = c_alloc(long)) = 1;
+ *(ptr.use_count = c_alloc(catomic_long)) = 1;
return ptr;
}
// c++: std::make_shared<_cx_value>(val)
-STC_INLINE _cx_self _cx_memb(_make)(_cx_value val) {
+STC_INLINE _cx_self _cx_memb(_from)(_cx_value val) {
_cx_self ptr;
_cx_carc_rep *rep = c_alloc(_cx_carc_rep);
*(ptr.use_count = &rep->counter) = 1;
@@ -112,12 +115,12 @@ STC_INLINE _cx_self _cx_memb(_make)(_cx_value val) {
return ptr;
}
+STC_INLINE _cx_self _cx_memb(_make)(_cx_value val) // [deprecated]
+ { return _cx_memb(_from)(val); }
+
STC_INLINE _cx_raw _cx_memb(_toraw)(const _cx_self* self)
{ return i_keyto(self->get); }
-STC_INLINE _cx_value _cx_memb(_toval)(const _cx_self* self)
- { return *self->get; }
-
STC_INLINE _cx_self _cx_memb(_move)(_cx_self* self) {
_cx_self ptr = *self;
self->get = NULL, self->use_count = NULL;
@@ -129,7 +132,7 @@ STC_INLINE void _cx_memb(_drop)(_cx_self* self) {
i_keydrop(self->get);
if ((char *)self->get != (char *)self->use_count + offsetof(_cx_carc_rep, value))
c_free(self->get);
- c_free(self->use_count);
+ c_free((long*)self->use_count);
}
}
@@ -144,8 +147,8 @@ STC_INLINE void _cx_memb(_reset_to)(_cx_self* self, _cx_value* p) {
}
#if !defined _i_no_clone && !defined _i_no_emplace
- STC_INLINE _cx_self _cx_memb(_from)(_cx_raw raw)
- { return _cx_memb(_make)(i_keyfrom(raw)); }
+ STC_INLINE _cx_self _cx_memb(_new)(_cx_raw raw)
+ { return _cx_memb(_from)(i_keyfrom(raw)); }
#endif // !_i_no_clone
// does not use i_keyclone, so OK to always define.
@@ -155,7 +158,7 @@ STC_INLINE _cx_self _cx_memb(_clone)(_cx_self ptr) {
return ptr;
}
-STC_INLINE void _cx_memb(_assign)(_cx_self* self, _cx_self ptr) {
+STC_INLINE void _cx_memb(_copy)(_cx_self* self, _cx_self ptr) {
if (ptr.use_count)
_i_atomic_inc(ptr.use_count);
_cx_memb(_drop)(self);
@@ -194,6 +197,16 @@ STC_INLINE bool _cx_memb(_value_eq)(const _cx_value* x, const _cx_value* y) {
return i_eq((&rx), (&ry));
#endif
}
+
+STC_INLINE uint64_t _cx_memb(_hash)(const _cx_self* x)
+ { return _cx_memb(_value_hash)(x->get); }
+
+STC_INLINE int _cx_memb(_cmp)(const _cx_self* x, const _cx_self* y)
+ { return _cx_memb(_value_cmp)(x->get, y->get); }
+
+STC_INLINE bool _cx_memb(_eq)(const _cx_self* x, const _cx_self* y)
+ { return _cx_memb(_value_eq)(x->get, y->get); }
+
#undef _i_atomic_inc
#undef _i_atomic_dec_and_test
#include "template.h"
diff --git a/include/stc/carr2.h b/include/stc/carr2.h
index 66a98f58..ffedb07d 100644
--- a/include/stc/carr2.h
+++ b/include/stc/carr2.h
@@ -35,7 +35,7 @@
int main() {
int w = 7, h = 5;
- c_autovar (carr2_int image = carr2_int_new_uninit(w, h), carr2_int_drop(&image))
+ c_with (carr2_int image = carr2_int_new_uninit(w, h), carr2_int_drop(&image))
{
int *dat = carr2_int_data(&image);
for (int i = 0; i < carr2_int_size(&image); ++i)
@@ -88,14 +88,17 @@ STC_INLINE size_t _cx_memb(_idx)(const _cx_self* self, size_t x, size_t y) {
return self->ydim*x + y;
}
-STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self)
- { return c_make(_cx_iter){*self->data}; }
+
+STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) {
+ size_t n = self->xdim*self->ydim;
+ return c_make(_cx_iter){n ? *self->data : NULL, *self->data + n};
+}
STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self)
- { return c_make(_cx_iter){*self->data + self->xdim*self->ydim}; }
+ { return c_make(_cx_iter){NULL, *self->data + self->xdim*self->ydim}; }
STC_INLINE void _cx_memb(_next)(_cx_iter* it)
- { ++it->ref; }
+ { if (++it->ref == it->end) it->ref = NULL; }
/* -------------------------- IMPLEMENTATION ------------------------- */
#if defined(i_implement)
diff --git a/include/stc/carr3.h b/include/stc/carr3.h
index 8ff1670e..07eac2a1 100644
--- a/include/stc/carr3.h
+++ b/include/stc/carr3.h
@@ -35,7 +35,7 @@
int main() {
int w = 7, h = 5, d = 3;
- c_autovar (carr3_int image = carr3_int_new_uninit(w, h, d), carr3_int_drop(&image))
+ c_with (carr3_int image = carr3_int_new_uninit(w, h, d), carr3_int_drop(&image))
{
int *dat = carr3_int_data(&image);
for (int i = 0; i < carr3_int_size(&image); ++i)
@@ -91,14 +91,17 @@ 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 _cx_iter _cx_memb(_begin)(const _cx_self* self)
- { return c_make(_cx_iter){**self->data}; }
+
+STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) {
+ size_t n = _cx_memb(_size)(self);
+ return c_make(_cx_iter){n ? **self->data : NULL, **self->data + n};
+}
STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self)
- { return c_make(_cx_iter){**self->data + _cx_memb(_size)(self)}; }
+ { return c_make(_cx_iter){NULL, **self->data + _cx_memb(_size)(self)}; }
STC_INLINE void _cx_memb(_next)(_cx_iter* it)
- { ++it->ref; }
+ { if (++it->ref == it->end) it->ref = NULL; }
/* -------------------------- IMPLEMENTATION ------------------------- */
#if defined(i_implement)
diff --git a/include/stc/cbits.h b/include/stc/cbits.h
index 3f75226d..a1b84acd 100644
--- a/include/stc/cbits.h
+++ b/include/stc/cbits.h
@@ -27,7 +27,7 @@ Similar to boost::dynamic_bitset / std::bitset
#include "cbits.h"
int main() {
- c_autovar (cbits bset = cbits_with_size(23, true), cbits_drop(&bset))
+ c_with (cbits bset = cbits_with_size(23, true), cbits_drop(&bset))
{
cbits_reset(&bset, 9);
cbits_resize(&bset, 43, false);
diff --git a/include/stc/cbox.h b/include/stc/cbox.h
index c3a9dd02..02a73fdc 100644
--- a/include/stc/cbox.h
+++ b/include/stc/cbox.h
@@ -48,7 +48,7 @@ void Person_drop(Person* p) {
int main() {
c_auto (PBox, p, q)
{
- p = PBox_make(Person_from("John Smiths", "[email protected]"));
+ p = PBox_from(Person_from("John Smiths", "[email protected]"));
q = PBox_clone(p);
cstr_assign(&q.get->name, "Joe Smiths");
@@ -82,24 +82,24 @@ _cx_deftypes(_c_cbox_types, _cx_self, i_key);
STC_INLINE _cx_self _cx_memb(_init)(void)
{ return c_make(_cx_self){NULL}; }
-STC_INLINE long _cx_memb(_use_count)(_cx_self box)
- { return (long)(box.get != NULL); }
+STC_INLINE long _cx_memb(_use_count)(const _cx_self* self)
+ { return (long)(self->get != NULL); }
STC_INLINE _cx_self _cx_memb(_from_ptr)(_cx_value* p)
{ return c_make(_cx_self){p}; }
// c++: std::make_unique<i_key>(val)
-STC_INLINE _cx_self _cx_memb(_make)(_cx_value val) {
+STC_INLINE _cx_self _cx_memb(_from)(_cx_value val) {
_cx_self ptr = {c_alloc(_cx_value)};
*ptr.get = val; return ptr;
}
+// [deprecated]
+STC_INLINE _cx_self _cx_memb(_make)(_cx_value val)
+ { return _cx_memb(_from)(val); }
STC_INLINE _cx_raw _cx_memb(_toraw)(const _cx_self* self)
{ return i_keyto(self->get); }
-STC_INLINE _cx_value _cx_memb(_toval)(const _cx_self* self)
- { return *self->get; }
-
// destructor
STC_INLINE void _cx_memb(_drop)(_cx_self* self) {
if (self->get) {
@@ -126,11 +126,11 @@ STC_INLINE void _cx_memb(_reset_to)(_cx_self* self, _cx_value* p) {
self->get = p;
}
-#if !defined _i_no_clone
#if !defined _i_no_emplace
- STC_INLINE _cx_self _cx_memb(_from)(_cx_raw raw)
- { return _cx_memb(_make)(i_keyfrom(raw)); }
+ STC_INLINE _cx_self _cx_memb(_new)(_cx_raw raw)
+ { return _cx_memb(_from)(i_keyfrom(raw)); }
#endif
+#if !defined _i_no_clone
STC_INLINE _cx_self _cx_memb(_clone)(_cx_self other) {
if (!other.get)
return other;
@@ -138,13 +138,6 @@ STC_INLINE void _cx_memb(_reset_to)(_cx_self* self, _cx_value* p) {
*out.get = i_keyclone(*other.get);
return out;
}
-
- STC_INLINE void _cx_memb(_assign)(_cx_self* self, const _cx_self ptr) {
- if (self->get == ptr.get)
- return;
- _cx_memb(_drop)(self);
- *self = _cx_memb(_clone)(ptr);
- }
#endif // !_i_no_clone
STC_INLINE void _cx_memb(_take)(_cx_self* self, _cx_self other) {
@@ -179,4 +172,14 @@ STC_INLINE bool _cx_memb(_value_eq)(const _cx_value* x, const _cx_value* y) {
return i_eq((&rx), (&ry));
#endif
}
+
+STC_INLINE uint64_t _cx_memb(_hash)(const _cx_self* x)
+ { return _cx_memb(_value_hash)(x->get); }
+
+STC_INLINE int _cx_memb(_cmp)(const _cx_self* x, const _cx_self* y)
+ { return _cx_memb(_value_cmp)(x->get, y->get); }
+
+STC_INLINE bool _cx_memb(_eq)(const _cx_self* x, const _cx_self* y)
+ { return _cx_memb(_value_eq)(x->get, y->get); }
+
#include "template.h"
diff --git a/include/stc/ccommon.h b/include/stc/ccommon.h
index e2c63b8c..58d74ddf 100644
--- a/include/stc/ccommon.h
+++ b/include/stc/ccommon.h
@@ -157,16 +157,14 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle,
#define c_foreach(...) c_MACRO_OVERLOAD(c_foreach, __VA_ARGS__)
#define c_foreach3(it, C, cnt) \
- for (C##_iter it = C##_begin(&cnt), it##_end_ = C##_end(&cnt) \
- ; it.ref != it##_end_.ref; C##_next(&it))
+ for (C##_iter it = C##_begin(&cnt); it.ref; C##_next(&it))
#define c_foreach4(it, C, start, finish) \
- for (C##_iter it = start, it##_end_ = finish \
- ; it.ref != it##_end_.ref; C##_next(&it))
+ for (C##_iter it = start, *_endref = (C##_iter*)(finish).ref \
+ ; it.ref != (C##_value*)_endref; C##_next(&it))
#define c_forpair(key, val, C, cnt) /* structured binding */ \
- for (struct {C##_iter _it; C##_value* _endref; const C##_key* key; C##_mapped* val;} \
- _ = {C##_begin(&cnt), C##_end(&cnt).ref} \
- ; _._it.ref != _._endref && (_.key = &_._it.ref->first, _.val = &_._it.ref->second) \
+ for (struct {C##_iter _it; const C##_key* key; C##_mapped* val;} _ = {C##_begin(&cnt)} \
+ ; _._it.ref && (_.key = &_._it.ref->first, _.val = &_._it.ref->second) \
; C##_next(&_._it))
#define c_forrange(...) c_MACRO_OVERLOAD(c_forrange, __VA_ARGS__)
@@ -178,24 +176,28 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle,
for (itype i=start, _inc=step, _end=(stop) - (0 < _inc) \
; (i <= _end) == (0 < _inc); i += _inc)
-#define c_autovar(...) c_MACRO_OVERLOAD(c_autovar, __VA_ARGS__)
-#define c_autovar2(declvar, drop) for (declvar, **_c_i = NULL; !_c_i; ++_c_i, drop)
-#define c_autovar3(declvar, pred, drop) for (declvar, **_c_i = NULL; !_c_i && (pred); ++_c_i, drop)
-#define c_autoscope(init, drop) for (int _c_i = (init, 0); !_c_i; ++_c_i, drop)
-#define c_autodefer(...) for (int _c_i = 0; !_c_i; ++_c_i, __VA_ARGS__)
+#define c_autovar c_with // [deprecated]
+#define c_autoscope c_scope // [deprecated]
+#define c_autodefer c_defer // [deprecated]
+
+#define c_with(...) c_MACRO_OVERLOAD(c_with, __VA_ARGS__)
+#define c_with2(declvar, drop) for (declvar, **_c_i = NULL; !_c_i; ++_c_i, drop)
+#define c_with3(declvar, pred, drop) for (declvar, **_c_i = NULL; !_c_i && (pred); ++_c_i, drop)
+#define c_scope(init, drop) for (int _c_i = (init, 0); !_c_i; ++_c_i, drop)
+#define c_defer(...) for (int _c_i = 0; !_c_i; ++_c_i, __VA_ARGS__)
#define c_breakauto continue
#define c_auto(...) c_MACRO_OVERLOAD(c_auto, __VA_ARGS__)
#define c_auto2(C, a) \
- c_autovar2(C a = C##_init(), C##_drop(&a))
+ c_with2(C a = C##_init(), C##_drop(&a))
#define c_auto3(C, a, b) \
- c_autovar2(c_expand(C a = C##_init(), b = C##_init()), \
+ c_with2(c_expand(C a = C##_init(), b = C##_init()), \
(C##_drop(&b), C##_drop(&a)))
#define c_auto4(C, a, b, c) \
- c_autovar2(c_expand(C a = C##_init(), b = C##_init(), c = C##_init()), \
+ c_with2(c_expand(C a = C##_init(), b = C##_init(), c = C##_init()), \
(C##_drop(&c), C##_drop(&b), C##_drop(&a)))
#define c_auto5(C, a, b, c, d) \
- c_autovar2(c_expand(C a = C##_init(), b = C##_init(), c = C##_init(), d = C##_init()), \
+ c_with2(c_expand(C a = C##_init(), b = C##_init(), c = C##_init(), d = C##_init()), \
(C##_drop(&d), C##_drop(&c), C##_drop(&b), C##_drop(&a)))
#define c_autobuf(b, type, n) c_autobuf_N(b, type, n, 256)
@@ -221,16 +223,19 @@ STC_INLINE char* c_strnstrn(const char *s, const char *needle,
#define c_pair(v) (v)->first, (v)->second
#define c_drop(C, ...) do { c_forarray_p(C*, _p, {__VA_ARGS__}) C##_drop(*_p); } while(0)
-#define c_find_if(C, cnt, it, pred) \
- c_find_in(C, C##_begin(&cnt), C##_end(&cnt), it, pred)
+// it.ref == NULL when not found:
+#define c_find_if(it, C, cnt, pred) do { \
+ size_t index = 0; \
+ for (it = C##_begin(&cnt); it.ref && !(pred); C##_next(&it)) \
+ ++index; \
+} while (0)
-// NB: it.ref == NULL when not found, not end.ref:
-#define c_find_in(C, start, end, it, pred) do { \
+#define c_find_in(it, C, start, end, pred) do { \
size_t index = 0; \
- C##_iter _end = end; \
- for (it = start; it.ref != _end.ref && !(pred); C##_next(&it)) \
+ const C##_value* _endref = (end).ref; \
+ for (it = start; it.ref != _endref && !(pred); C##_next(&it)) \
++index; \
- if (it.ref == _end.ref) it.ref = NULL; \
+ if (it.ref == _endref) it.ref = NULL; \
} while (0)
#endif // CCOMMON_H_INCLUDED
diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h
index c5e08393..a8c880f2 100644
--- a/include/stc/cdeq.h
+++ b/include/stc/cdeq.h
@@ -29,6 +29,8 @@
struct cdeq_rep { size_t size, cap; unsigned base[1]; };
#define cdeq_rep_(self) c_unchecked_container_of((self)->_base, struct cdeq_rep, base)
+#define _it2_ptr(it1, it2) (it1.ref && !it2.ref ? it2.end : it2.ref)
+#define _it_ptr(it) (it.ref ? it.ref : it.end)
#endif // CDEQ_H_INCLUDED
#ifndef _i_prefix
@@ -48,15 +50,12 @@ STC_API void _cx_memb(_clear)(_cx_self* self);
STC_API void _cx_memb(_drop)(_cx_self* self);
STC_API _cx_value* _cx_memb(_push)(_cx_self* self, i_key value);
STC_API void _cx_memb(_shrink_to_fit)(_cx_self *self);
+
#if !defined _i_queue
#if !defined _i_no_emplace
-STC_API _cx_value* _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_raw* p1, const _cx_raw* p2);
+STC_API _cx_iter _cx_memb(_emplace_range)(_cx_self* self, _cx_value* pos,
+ const _cx_raw* p1, const _cx_raw* p2);
#endif // _i_no_emplace
-#if !defined _i_no_clone
-STC_API _cx_value* _cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_value* p1, const _cx_value* p2);
-#endif // !_i_no_clone
#if !c_option(c_no_cmp)
STC_API _cx_iter _cx_memb(_find_in)(_cx_iter p1, _cx_iter p2, _cx_raw raw);
@@ -64,23 +63,30 @@ STC_API int _cx_memb(_value_cmp)(const _cx_value* x, const _cx_value
#endif
STC_API _cx_value* _cx_memb(_push_front)(_cx_self* self, i_key value);
STC_API _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2);
-STC_API _cx_value* _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_value* p1, const _cx_value* p2);
+STC_API _cx_iter _cx_memb(_insert_range)(_cx_self* self, _cx_value* pos,
+ const _cx_value* p1, const _cx_value* p2);
#endif // !_i_queue
-#if !defined _i_no_clone
-STC_API _cx_self _cx_memb(_clone)(_cx_self cx);
#if !defined _i_no_emplace
STC_INLINE _cx_value* _cx_memb(_emplace)(_cx_self* self, _cx_raw raw)
{ return _cx_memb(_push)(self, i_keyfrom(raw)); }
#endif
-STC_INLINE i_key _cx_memb(_value_clone)(i_key val)
- { return i_keyclone(val); }
+
+#if !defined _i_no_clone
+#if !defined _i_queue
+STC_API _cx_iter _cx_memb(_copy_range)(_cx_self* self, _cx_value* pos,
+ const _cx_value* p1, const _cx_value* p2);
+
STC_INLINE void _cx_memb(_copy)(_cx_self *self, const _cx_self* other) {
if (self->data == other->data) return;
- _cx_memb(_drop)(self);
- *self = _cx_memb(_clone)(*other);
+ _cx_memb(_clear)(self);
+ _cx_memb(_copy_range)(self, self->data, other->data,
+ other->data + cdeq_rep_(other)->size);
}
+#endif // !_i_queue
+STC_API _cx_self _cx_memb(_clone)(_cx_self cx);
+STC_INLINE i_key _cx_memb(_value_clone)(i_key val)
+ { return i_keyclone(val); }
#endif // !_i_no_clone
STC_INLINE size_t _cx_memb(_size)(const _cx_self* cx) { return cdeq_rep_(cx)->size; }
STC_INLINE size_t _cx_memb(_capacity)(const _cx_self* cx) { return cdeq_rep_(cx)->cap; }
@@ -92,13 +98,6 @@ STC_INLINE _cx_value* _cx_memb(_back)(const _cx_self* self)
{ return self->data + cdeq_rep_(self)->size - 1; }
STC_INLINE void _cx_memb(_pop_front)(_cx_self* self) // == _pop() when _i_queue
{ i_keydrop(self->data); ++self->data; --cdeq_rep_(self)->size; }
-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)
- { return c_make(_cx_iter){self->data + cdeq_rep_(self)->size}; }
-STC_INLINE void _cx_memb(_next)(_cx_iter* it) { ++it->ref; }
-STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, intptr_t offs)
- { it.ref += offs; return it; }
#if !defined _i_queue
@@ -117,17 +116,17 @@ STC_INLINE _cx_value* _cx_memb(_at_mut)(_cx_self* self, const size_t idx) {
STC_INLINE _cx_value* _cx_memb(_push_back)(_cx_self* self, i_key value) {
return _cx_memb(_push)(self, value);
}
-STC_INLINE _cx_value*
+STC_INLINE _cx_iter
_cx_memb(_insert)(_cx_self* self, const size_t idx, i_key value) {
- return _cx_memb(_insert_range_p)(self, self->data + idx, &value, &value + 1);
+ return _cx_memb(_insert_range)(self, self->data + idx, &value, &value + 1);
}
-STC_INLINE _cx_value*
+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);
+ return _cx_memb(_insert_range)(self, self->data + idx, arr, arr + n);
}
-STC_INLINE _cx_value*
+STC_INLINE _cx_iter
_cx_memb(_insert_at)(_cx_self* self, _cx_iter it, i_key value) {
- return _cx_memb(_insert_range_p)(self, it.ref, &value, &value + 1);
+ return _cx_memb(_insert_range)(self, _it_ptr(it), &value, &value + 1);
}
STC_INLINE _cx_iter
@@ -139,16 +138,25 @@ _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(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2) {
- return _cx_memb(_erase_range_p)(self, it1.ref, it2.ref);
+_cx_memb(_erase_range)(_cx_self* self, _cx_iter i1, _cx_iter i2) {
+ return _cx_memb(_erase_range_p)(self, i1.ref, _it2_ptr(i1, i2));
}
-#if !defined _i_no_clone
-STC_INLINE _cx_value*
-_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);
+
+STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) {
+ size_t n = cdeq_rep_(self)->size;
+ return c_make(_cx_iter){n ? self->data : NULL, self->data + n};
}
-#endif // !_i_no_clone
+
+STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self)
+ { return c_make(_cx_iter){NULL, self->data + cdeq_rep_(self)->size}; }
+
+STC_INLINE void _cx_memb(_next)(_cx_iter* it)
+ { if (++it->ref == it->end) it->ref = NULL; }
+
+STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, size_t n)
+ { if ((it.ref += n) >= it.end) it.ref = NULL; return it; }
+
#if !defined _i_no_emplace
STC_INLINE _cx_value*
_cx_memb(_emplace_front)(_cx_self* self, _cx_raw raw) {
@@ -159,13 +167,13 @@ STC_INLINE _cx_value* _cx_memb(_emplace_back)(_cx_self* self, _cx_raw raw) {
return _cx_memb(_push)(self, i_keyfrom(raw));
}
-STC_INLINE _cx_value*
+STC_INLINE _cx_iter
_cx_memb(_emplace_n)(_cx_self* self, const size_t idx, const _cx_raw arr[], const size_t n) {
- return _cx_memb(_emplace_range_p)(self, self->data + idx, arr, arr + n);
+ return _cx_memb(_emplace_range)(self, self->data + idx, arr, arr + n);
}
-STC_INLINE _cx_value*
+STC_INLINE _cx_iter
_cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, _cx_raw raw) {
- return _cx_memb(_emplace_range_p)(self, it.ref, &raw, &raw + 1);
+ return _cx_memb(_emplace_range)(self, _it_ptr(it), &raw, &raw + 1);
}
#endif // !_i_no_emplace
@@ -178,9 +186,7 @@ _cx_memb(_find)(const _cx_self* self, _cx_raw raw) {
STC_INLINE const _cx_value*
_cx_memb(_get)(const _cx_self* self, _cx_raw raw) {
- _cx_iter end = _cx_memb(_end)(self);
- _cx_value* val = _cx_memb(_find_in)(_cx_memb(_begin)(self), end, raw).ref;
- return val == end.ref ? NULL : val;
+ return _cx_memb(_find_in)(_cx_memb(_begin)(self), _cx_memb(_end)(self), raw).ref;
}
STC_INLINE _cx_value*
@@ -188,9 +194,9 @@ _cx_memb(_get_mut)(_cx_self* self, _cx_raw raw)
{ return (_cx_value *) _cx_memb(_get)(self, raw); }
STC_INLINE void
-_cx_memb(_sort_range)(_cx_iter i1, _cx_iter i2,
- int(*_cmp_)(const _cx_value*, const _cx_value*)) {
- qsort(i1.ref, i2.ref - i1.ref, sizeof *i1.ref, (int(*)(const void*, const void*)) _cmp_);
+_cx_memb(_sort_range)(_cx_iter i1, _cx_iter i2, int(*cmp)(const _cx_value*, const _cx_value*)) {
+ qsort(i1.ref, _it2_ptr(i1, i2) - i1.ref, sizeof *i1.ref,
+ (int(*)(const void*, const void*)) cmp);
}
STC_INLINE void
@@ -222,6 +228,7 @@ _cx_memb(_clear)(_cx_self* self) {
--q; i_keydrop(q);
}
rep->size = 0;
+ self->data = self->_base;
}
}
@@ -231,7 +238,8 @@ _cx_memb(_shrink_to_fit)(_cx_self *self) {
struct cdeq_rep* rep = cdeq_rep_(self);
const size_t sz = rep->size;
memmove(self->_base, self->data, sz*sizeof(i_key));
- rep = (struct cdeq_rep*) c_realloc(rep, offsetof(struct cdeq_rep, base) + sz*sizeof(i_key));
+ rep = (struct cdeq_rep*) c_realloc(rep, offsetof(struct cdeq_rep, base) +
+ sz*sizeof(i_key));
if (rep) {
self->_base = self->data = (_cx_value*)rep->base;
rep->cap = sz;
@@ -316,10 +324,10 @@ STC_DEF _cx_self
_cx_memb(_clone)(_cx_self cx) {
const size_t sz = cdeq_rep_(&cx)->size;
_cx_self out = _cx_memb(_with_capacity)(sz);
- if (cdeq_rep_(&out)->cap) {
- cdeq_rep_(&out)->size = sz;
- for (size_t i = 0; i < sz; ++i)
- out.data[i] = i_keyclone(cx.data[i]);
+ struct cdeq_rep* r = cdeq_rep_(&out);
+ if (r->cap) {
+ for (size_t i = 0; i < sz; ++i) out.data[i] = i_keyclone(cx.data[i]);
+ r->size = sz;
}
return out;
}
@@ -345,16 +353,21 @@ _cx_memb(_expand_left_half_)(_cx_self* self, const size_t idx, const size_t n) {
}
}
-static _cx_value*
-_cx_memb(_insert_uninit_p)(_cx_self* self, const _cx_value* pos, const size_t n) {
- const size_t idx = pos - self->data;
- if (idx*2 < cdeq_rep_(self)->size)
- _cx_memb(_expand_left_half_)(self, idx, n);
- else
- _cx_memb(_expand_right_half_)(self, idx, n);
- if (n)
- cdeq_rep_(self)->size += n; /* do only if size > 0 */
- return self->data + idx;
+static _cx_iter
+_cx_memb(_insert_uninit)(_cx_self* self, _cx_value* pos, const size_t n) {
+ struct cdeq_rep* r = cdeq_rep_(self);
+ if (n) {
+ if (!pos) pos = self->data + r->size;
+ const size_t idx = pos - self->data;
+ if (idx*2 < r->size)
+ _cx_memb(_expand_left_half_)(self, idx, n);
+ else
+ _cx_memb(_expand_right_half_)(self, idx, n);
+ r = cdeq_rep_(self);
+ r->size += n;
+ pos = self->data + idx;
+ }
+ return c_make(_cx_iter){pos, self->data + r->size};
}
STC_DEF _cx_value*
@@ -368,62 +381,63 @@ _cx_memb(_push_front)(_cx_self* self, i_key value) {
return self->data;
}
-STC_DEF _cx_value*
-_cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos,
+STC_DEF _cx_iter
+_cx_memb(_insert_range)(_cx_self* self, _cx_value* pos,
const _cx_value* p1, const _cx_value* p2) {
- pos = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1);
- if (pos)
- memcpy(pos, p1, (p2 - p1)*sizeof *p1);
- return pos;
+ _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1);
+ if (it.ref)
+ memcpy(it.ref, p1, (p2 - p1)*sizeof *p1);
+ return it;
}
STC_DEF _cx_iter
_cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) {
- const size_t n = p2 - p1;
- if (n > 0) {
- _cx_value* p = p1, *end = self->data + cdeq_rep_(self)->size;
- for (; p != p2; ++p) { i_keydrop(p); }
- if (p1 == self->data)
- self->data += n;
- else memmove(p1, p2, (end - p2) * sizeof(i_key));
- cdeq_rep_(self)->size -= n;
- }
- return c_make(_cx_iter){p1};
+ assert(p1 && p2);
+ intptr_t len = p2 - p1;
+ struct cdeq_rep* r = cdeq_rep_(self);
+ _cx_value* p = p1, *end = self->data + r->size;
+ for (; p != p2; ++p)
+ { i_keydrop(p); }
+ memmove(p1, p2, (end - p2) * sizeof *p1);
+ r->size -= len;
+ return c_make(_cx_iter){p2 == end ? NULL : p1, end - len};
}
-#if !defined _i_no_emplace
-STC_DEF _cx_value*
-_cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos, const _cx_raw* p1, const _cx_raw* p2) {
- pos = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1);
- _cx_value* it = pos;
- if (pos) for (; p1 != p2; ++p1)
- *pos++ = i_keyfrom((*p1));
+#if !defined _i_no_clone
+STC_DEF _cx_iter
+_cx_memb(_copy_range)(_cx_self* self, _cx_value* pos,
+ const _cx_value* p1, const _cx_value* p2) {
+ _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1);
+ if (it.ref)
+ for (_cx_value* p = it.ref; p1 != p2; ++p1)
+ *p++ = i_keyclone((*p1));
return it;
}
-#endif // !_i_no_emplace
+#endif // !_i_no_clone
-#if !defined _i_no_clone
-STC_DEF _cx_value*
-_cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_value* p1, const _cx_value* p2) {
- pos = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1);
- _cx_value* it = pos;
- if (pos) for (; p1 != p2; ++p1)
- *pos++ = i_keyclone((*p1));
+#if !defined _i_no_emplace
+STC_DEF _cx_iter
+_cx_memb(_emplace_range)(_cx_self* self, _cx_value* pos,
+ const _cx_raw* p1, const _cx_raw* p2) {
+ _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1);
+ if (it.ref)
+ for (_cx_value* p = it.ref; p1 != p2; ++p1)
+ *p++ = i_keyfrom((*p1));
return it;
}
-#endif // !_i_no_clone
+#endif // !_i_no_emplace
#if !c_option(c_no_cmp)
STC_DEF _cx_iter
_cx_memb(_find_in)(_cx_iter i1, _cx_iter i2, _cx_raw raw) {
- for (; i1.ref != i2.ref; ++i1.ref) {
- _cx_raw r = i_keyto(i1.ref);
+ const _cx_value* p2 = _it2_ptr(i1, i2);
+ for (; i1.ref != p2; ++i1.ref) {
+ const _cx_raw r = i_keyto(i1.ref);
if (i_eq((&raw), (&r)))
return i1;
}
- return i2;
+ i2.ref = NULL; return i2; // NB!
}
STC_DEF int
diff --git a/include/stc/clist.h b/include/stc/clist.h
index 229db32c..5b9cf0d3 100644
--- a/include/stc/clist.h
+++ b/include/stc/clist.h
@@ -159,9 +159,8 @@ _cx_memb(_begin)(const _cx_self* self) {
}
STC_INLINE _cx_iter
-_cx_memb(_end)(const _cx_self* self) {
- return c_make(_cx_iter){NULL};
-}
+_cx_memb(_end)(const _cx_self* self)
+ { return c_make(_cx_iter){NULL}; }
STC_INLINE void
_cx_memb(_next)(_cx_iter* it) {
diff --git a/include/stc/cmap.h b/include/stc/cmap.h
index 84957e69..58774fb2 100644
--- a/include/stc/cmap.h
+++ b/include/stc/cmap.h
@@ -31,7 +31,7 @@
#include <stc/cmap.h>
int main(void) {
- c_autovar (cmap_ichar m = cmap_ichar_init(), cmap_ichar_drop(&m))
+ c_with (cmap_ichar m = cmap_ichar_init(), cmap_ichar_drop(&m))
{
cmap_ichar_emplace(&m, 5, 'a');
cmap_ichar_emplace(&m, 8, 'b');
@@ -188,12 +188,29 @@ _cx_memb(_push)(_cx_self* self, _cx_value _val) {
return _res;
}
+
+STC_INLINE _cx_iter
+_cx_memb(_end)(const _cx_self* self)
+ { return c_make(_cx_iter){NULL}; }
+
+STC_INLINE void
+_cx_memb(_next)(_cx_iter* it) {
+ while ((++it->ref, *++it->_hx == 0)) ;
+ if (it->ref == it->end) it->ref = NULL;
+}
+
+STC_INLINE _cx_iter
+_cx_memb(_advance)(_cx_iter it, size_t n) {
+ while (n-- && it.ref) _cx_memb(_next)(&it);
+ return it;
+}
+
STC_INLINE _cx_iter
_cx_memb(_find)(const _cx_self* self, _cx_rawkey rkey) {
i_size idx;
if (!(self->size && self->_hashx[idx = _cx_memb(_bucket_)(self, &rkey).idx]))
- idx = self->bucket_count;
- return c_make(_cx_iter){self->table+idx, self->_hashx+idx};
+ return _cx_memb(_end)(self);
+ return c_make(_cx_iter){self->table+idx, self->table+self->bucket_count, self->_hashx+idx};
}
STC_INLINE const _cx_value*
@@ -210,25 +227,11 @@ _cx_memb(_get_mut)(_cx_self* self, _cx_rawkey rkey)
STC_INLINE _cx_iter
_cx_memb(_begin)(const _cx_self* self) {
- _cx_iter it = {self->table, self->_hashx};
+ _cx_iter it = {self->table, self->table+self->bucket_count, self->_hashx};
if (it._hx)
while (*it._hx == 0)
++it.ref, ++it._hx;
- return it;
-}
-
-STC_INLINE _cx_iter
-_cx_memb(_end)(const _cx_self* self)
- { return c_make(_cx_iter){self->table + self->bucket_count}; }
-
-STC_INLINE void
-_cx_memb(_next)(_cx_iter* it)
- { while ((++it->ref, *++it->_hx == 0)) ; }
-
-STC_INLINE _cx_iter
-_cx_memb(_advance)(_cx_iter it, size_t n) {
- // UB if n > elements left
- while (n--) _cx_memb(_next)(&it);
+ if (it.ref == it.end) it.ref = NULL;
return it;
}
diff --git a/include/stc/cpque.h b/include/stc/cpque.h
index bb7c207e..79d12b95 100644
--- a/include/stc/cpque.h
+++ b/include/stc/cpque.h
@@ -110,9 +110,9 @@ STC_INLINE void _cx_memb(_emplace)(_cx_self* self, _cx_raw raw)
STC_DEF void
_cx_memb(_sift_down_)(_cx_value* arr, const size_t idx, const size_t n) {
- for (size_t r = idx, c = idx << 1; c <= n; c <<= 1) {
- c += (c < n && (i_cmp((&arr[c]), (&arr[c + 1]))) < 0);
- if ((i_cmp((&arr[r]), (&arr[c]))) >= 0) return;
+ for (size_t r = idx, c = idx*2; c <= n; c *= 2) {
+ c += (c < n && (i_less((&arr[c]), (&arr[c + 1]))));
+ if (!(i_less((&arr[r]), (&arr[c])))) return;
_cx_value t = arr[r]; arr[r] = arr[c]; arr[r = c] = t;
}
}
@@ -121,7 +121,7 @@ STC_DEF void
_cx_memb(_make_heap)(_cx_self* self) {
size_t n = self->size;
_cx_value *arr = self->data - 1;
- for (size_t k = n >> 1; k != 0; --k)
+ for (size_t k = n/2; k != 0; --k)
_cx_memb(_sift_down_)(arr, k, n);
}
@@ -148,8 +148,8 @@ _cx_memb(_push)(_cx_self* self, _cx_value value) {
_cx_memb(_reserve)(self, self->size*3/2 + 4);
_cx_value *arr = self->data - 1; /* base 1 */
size_t c = ++self->size;
- for (; c > 1 && (i_cmp((&arr[c >> 1]), (&value))) < 0; c >>= 1)
- arr[c] = arr[c >> 1];
+ for (; c > 1 && (i_less((&arr[c/2]), (&value))); c /= 2)
+ arr[c] = arr[c/2];
arr[c] = value;
}
diff --git a/include/stc/cregex.h b/include/stc/cregex.h
index d19d518f..4812bff2 100644
--- a/include/stc/cregex.h
+++ b/include/stc/cregex.h
@@ -76,8 +76,9 @@ typedef struct {
csview ref[cre_MAXCAPTURES];
} cregex_iter;
-#define c_foreach_match(i, _re, _input) \
- for (cregex_iter i = {_re, _input}; cregex_find(i.input, i.re, i.ref, cre_m_next) == cre_success;)
+#define c_foreach_match(it, Re, Input) \
+ for (cregex_iter it = {Re, Input}; \
+ cregex_find(it.input, it.re, it.ref, cre_m_next) == cre_success;)
static inline
cregex cregex_init(void) {
diff --git a/include/stc/csmap.h b/include/stc/csmap.h
index 97f1fce1..c773e70f 100644
--- a/include/stc/csmap.h
+++ b/include/stc/csmap.h
@@ -32,7 +32,7 @@
#include <stc/csmap.h>
int main(void) {
- c_autovar (csmap_sx m = csmap_sx_init(), csmap_sx_drop(&m))
+ c_with (csmap_sx m = csmap_sx_init(), csmap_sx_drop(&m))
{
csmap_sx_emplace(&m, "Testing one", 1.234);
csmap_sx_emplace(&m, "Testing two", 12.34);
diff --git a/include/stc/cstack.h b/include/stc/cstack.h
index 46d209ca..e1839d37 100644
--- a/include/stc/cstack.h
+++ b/include/stc/cstack.h
@@ -169,15 +169,18 @@ STC_INLINE i_keyraw _cx_memb(_value_toraw)(const _cx_value* val)
{ return i_keyto(val); }
#endif // !_i_no_clone
-STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self)
- { return c_make(_cx_iter){(_cx_value*)self->data}; }
+STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) {
+ return c_make(_cx_iter){self->size ? (_cx_value*)self->data : NULL,
+ (_cx_value*)self->data + self->size};
+}
STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self)
- { return c_make(_cx_iter){(_cx_value*)self->data + self->size}; }
+ { return c_make(_cx_iter){NULL, (_cx_value*)self->data + self->size}; }
-STC_INLINE void _cx_memb(_next)(_cx_iter* it) { ++it->ref; }
+STC_INLINE void _cx_memb(_next)(_cx_iter* it)
+ { if (++it->ref == it->end) it->ref = NULL; }
-STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, intptr_t offs)
- { it.ref += offs; return it; }
+STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, size_t n)
+ { if ((it.ref += n) >= it.end) it.ref = NULL ; return it; }
#include "template.h"
diff --git a/include/stc/cstr.h b/include/stc/cstr.h
index aae52ea0..99b60e49 100644
--- a/include/stc/cstr.h
+++ b/include/stc/cstr.h
@@ -80,7 +80,7 @@ STC_API char* _cstr_internal_move(cstr* self, size_t pos1, size_t pos2);
STC_API char* cstr_reserve(cstr* self, size_t cap);
STC_API void cstr_shrink_to_fit(cstr* self);
STC_API void cstr_resize(cstr* self, size_t size, char value);
-STC_API size_t cstr_find_at(cstr s, size_t pos, const char* search);
+STC_API size_t cstr_find_at(const cstr* self, size_t pos, const char* search);
STC_API char* cstr_assign_n(cstr* self, const char* str, size_t len);
STC_API char* cstr_append_n(cstr* self, const char* str, size_t len);
STC_API bool cstr_getdelim(cstr *self, int delim, FILE *fp);
@@ -161,14 +161,14 @@ STC_INLINE char* cstr_data(cstr* self)
STC_INLINE const char* cstr_str(const cstr* self)
{ return SSO_CALL(self, data(self)); }
-STC_INLINE bool cstr_empty(cstr s)
- { return s.sml.last == cstr_s_cap; }
+STC_INLINE bool cstr_empty(const cstr* self)
+ { return self->sml.last == cstr_s_cap; }
-STC_INLINE size_t cstr_size(cstr s)
- { return SSO_CALL(&s, size(&s)); }
+STC_INLINE size_t cstr_size(const cstr* self)
+ { return SSO_CALL(self, size(self)); }
-STC_INLINE size_t cstr_capacity(cstr s)
- { return cstr_is_long(&s) ? cstr_l_cap(&s) : cstr_s_cap; }
+STC_INLINE size_t cstr_capacity(const cstr* self)
+ { return cstr_is_long(self) ? cstr_l_cap(self) : cstr_s_cap; }
// utf8 methods defined in/depending on src/utf8code.c:
@@ -200,11 +200,11 @@ STC_INLINE bool cstr_valid_utf8(const cstr* self)
// other utf8
-STC_INLINE size_t cstr_u8_size(cstr s)
- { return utf8_size(cstr_str(&s)); }
+STC_INLINE size_t cstr_u8_size(const cstr* self)
+ { return utf8_size(cstr_str(self)); }
-STC_INLINE size_t cstr_u8_size_n(cstr s, size_t nbytes)
- { return utf8_size_n(cstr_str(&s), nbytes); }
+STC_INLINE size_t cstr_u8_size_n(const cstr* self, size_t nbytes)
+ { return utf8_size_n(cstr_str(self), nbytes); }
STC_INLINE size_t cstr_u8_to_pos(const cstr* self, size_t u8idx)
{ return utf8_pos(cstr_str(self), u8idx); }
@@ -223,16 +223,18 @@ STC_INLINE csview cstr_u8_chr(const cstr* self, size_t u8idx) {
// utf8 iterator
STC_INLINE cstr_iter cstr_begin(const cstr* self) {
- const char* str = cstr_str(self);
- return c_make(cstr_iter){.chr = {str, utf8_chr_size(str)}};
+ csview sv = cstr_sv(self);
+ if (!sv.size) return c_make(cstr_iter){NULL};
+ return c_make(cstr_iter){.u8 = {{sv.str, utf8_chr_size(sv.str)}, sv.str + sv.size}};
}
STC_INLINE cstr_iter cstr_end(const cstr* self) {
csview sv = cstr_sv(self);
- return c_make(cstr_iter){sv.str + sv.size};
+ return c_make(cstr_iter){.u8 = {{NULL}, sv.str + sv.size}};
}
STC_INLINE void cstr_next(cstr_iter* it) {
- it->ref += it->chr.size;
- it->chr.size = utf8_chr_size(it->ref);
+ it->ref += it->u8.chr.size;
+ it->u8.chr.size = utf8_chr_size(it->ref);
+ if (it->ref == it->u8.end) it->ref = NULL;
}
@@ -240,7 +242,7 @@ STC_INLINE void cstr_clear(cstr* self)
{ _cstr_set_size(self, 0); }
STC_INLINE char* cstr_append_uninit(cstr *self, size_t len) {
- size_t sz = cstr_size(*self);
+ size_t sz = cstr_size(self);
char* d = cstr_reserve(self, sz + len);
if (!d) return NULL;
_cstr_set_size(self, sz + len);
@@ -259,75 +261,75 @@ STC_INLINE bool cstr_eq(const cstr* s1, const cstr* s2) {
}
-STC_INLINE bool cstr_equals(cstr s1, const char* str)
- { return !strcmp(cstr_str(&s1), str); }
+STC_INLINE bool cstr_equals(const cstr* self, const char* str)
+ { return !strcmp(cstr_str(self), str); }
-STC_INLINE bool cstr_equals_sv(cstr s, csview sv)
- { return sv.size == cstr_size(s) && !memcmp(cstr_str(&s), sv.str, sv.size); }
+STC_INLINE bool cstr_equals_sv(const cstr* self, csview sv)
+ { return sv.size == cstr_size(self) && !memcmp(cstr_str(self), sv.str, sv.size); }
-STC_INLINE bool cstr_equals_s(cstr s1, cstr s2)
- { return !cstr_cmp(&s1, &s2); }
+STC_INLINE bool cstr_equals_s(const cstr* self, cstr s)
+ { return !cstr_cmp(self, &s); }
-STC_INLINE bool cstr_iequals(cstr s1, const char* str)
- { return !utf8_icmp(cstr_str(&s1), str); }
+STC_INLINE bool cstr_iequals(const cstr* self, const char* str)
+ { return !utf8_icmp(cstr_str(self), str); }
-STC_INLINE size_t cstr_find(cstr s, const char* search) {
- const char *str = cstr_str(&s), *res = strstr((char*)str, search);
+STC_INLINE size_t cstr_find(const cstr* self, const char* search) {
+ const char *str = cstr_str(self), *res = strstr((char*)str, search);
return res ? res - str : cstr_npos;
}
-STC_API size_t cstr_find_sv(cstr s, csview search);
+STC_API size_t cstr_find_sv(const cstr* self, csview search);
-STC_INLINE size_t cstr_find_s(cstr s, cstr search)
- { return cstr_find(s, cstr_str(&search)); }
+STC_INLINE size_t cstr_find_s(const cstr* self, cstr search)
+ { return cstr_find(self, cstr_str(&search)); }
-STC_INLINE bool cstr_contains(cstr s, const char* search)
- { return strstr(cstr_data(&s), search) != NULL; }
+STC_INLINE bool cstr_contains(const cstr* self, const char* search)
+ { return strstr((char*)cstr_str(self), search) != NULL; }
-STC_INLINE bool cstr_contains_sv(cstr s, csview search)
- { return cstr_find_sv(s, search) != cstr_npos; }
+STC_INLINE bool cstr_contains_sv(const cstr* self, csview search)
+ { return cstr_find_sv(self, search) != cstr_npos; }
-STC_INLINE bool cstr_contains_s(cstr s, cstr search)
- { return strstr(cstr_data(&s), cstr_str(&search)) != NULL; }
+STC_INLINE bool cstr_contains_s(const cstr* self, cstr search)
+ { return strstr((char*)cstr_str(self), cstr_str(&search)) != NULL; }
-STC_INLINE bool cstr_starts_with_sv(cstr s, csview sub) {
- if (sub.size > cstr_size(s)) return false;
- return !memcmp(cstr_str(&s), sub.str, sub.size);
+STC_INLINE bool cstr_starts_with_sv(const cstr* self, csview sub) {
+ if (sub.size > cstr_size(self)) return false;
+ return !memcmp(cstr_str(self), sub.str, sub.size);
}
-STC_INLINE bool cstr_starts_with(cstr s, const char* sub) {
- const char* str = cstr_str(&s);
+STC_INLINE bool cstr_starts_with(const cstr* self, const char* sub) {
+ const char* str = cstr_str(self);
while (*sub && *str == *sub) ++str, ++sub;
return !*sub;
}
-STC_INLINE bool cstr_starts_with_s(cstr s, cstr sub)
- { return cstr_starts_with_sv(s, cstr_sv(&sub)); }
+STC_INLINE bool cstr_starts_with_s(const cstr* self, cstr sub)
+ { return cstr_starts_with_sv(self, cstr_sv(&sub)); }
-STC_INLINE bool cstr_istarts_with(cstr s, const char* sub) {
- csview sv = cstr_sv(&s);
+STC_INLINE bool cstr_istarts_with(const cstr* self, const char* sub) {
+ csview sv = cstr_sv(self);
size_t len = strlen(sub);
return len <= sv.size && !utf8_icmp_sv(sv, c_sv(sub, len));
}
-STC_INLINE bool cstr_ends_with_sv(cstr s, csview sub) {
- csview sv = cstr_sv(&s);
+STC_INLINE bool cstr_ends_with_sv(const cstr* self, csview sub) {
+ csview sv = cstr_sv(self);
if (sub.size > sv.size) return false;
return !memcmp(sv.str + sv.size - sub.size, sub.str, sub.size);
}
-STC_INLINE bool cstr_ends_with_s(cstr s, cstr sub)
- { return cstr_ends_with_sv(s, cstr_sv(&sub)); }
+STC_INLINE bool cstr_ends_with_s(const cstr* self, cstr sub)
+ { return cstr_ends_with_sv(self, cstr_sv(&sub)); }
-STC_INLINE bool cstr_ends_with(cstr s, const char* sub)
- { return cstr_ends_with_sv(s, c_sv(sub, strlen(sub))); }
+STC_INLINE bool cstr_ends_with(const cstr* self, const char* sub)
+ { return cstr_ends_with_sv(self, c_sv(sub, strlen(sub))); }
-STC_INLINE bool cstr_iends_with(cstr s, const char* sub) {
- csview sv = cstr_sv(&s);
+STC_INLINE bool cstr_iends_with(const cstr* self, const char* sub) {
+ csview sv = cstr_sv(self);
size_t n = strlen(sub);
return n <= sv.size && !utf8_icmp(sv.str + sv.size - n, sub);
}
@@ -368,11 +370,8 @@ STC_INLINE void cstr_replace_at(cstr* self, size_t pos, size_t len, const char*
STC_INLINE void cstr_replace_at_s(cstr* self, size_t pos, size_t len, cstr repl)
{ cstr_replace_at_sv(self, pos, len, cstr_sv(&repl)); }
-STC_INLINE void cstr_u8_replace_at(cstr* self, size_t u8pos, size_t u8len, csview repl) {
- csview sv = cstr_sv(self);
- const char* p = utf8_at(sv.str, u8pos);
- cstr_replace_at_sv(self, p - sv.str, utf8_pos(p, u8len), repl);
-}
+STC_INLINE void cstr_u8_replace(cstr* self, size_t pos, size_t u8len, csview repl)
+ { cstr_replace_at_sv(self, pos, utf8_pos(cstr_str(self) + pos, u8len), repl); }
STC_INLINE void cstr_insert(cstr* self, size_t pos, const char* str)
@@ -400,9 +399,9 @@ STC_DEF uint64_t cstr_hash(const cstr *self) {
return c_fasthash(sv.str, sv.size);
}
-STC_DEF size_t cstr_find_sv(cstr s, csview search) {
- char* res = c_strnstrn(cstr_str(&s), search.str, cstr_size(s), search.size);
- return res ? res - cstr_str(&s) : cstr_npos;
+STC_DEF size_t cstr_find_sv(const cstr* self, csview search) {
+ char* res = c_strnstrn(cstr_str(self), search.str, cstr_size(self), search.size);
+ return res ? res - cstr_str(self) : cstr_npos;
}
STC_DEF char* _cstr_internal_move(cstr* self, const size_t pos1, const size_t pos2) {
@@ -472,8 +471,8 @@ STC_DEF void cstr_resize(cstr* self, const size_t size, const char value) {
_cstr_set_size(self, size);
}
-STC_DEF size_t cstr_find_at(cstr s, const size_t pos, const char* search) {
- csview sv = cstr_sv(&s);
+STC_DEF size_t cstr_find_at(const cstr* self, const size_t pos, const char* search) {
+ csview sv = cstr_sv(self);
if (pos > sv.size) return cstr_npos;
const char* res = strstr((char*)sv.str + pos, search);
return res ? res - sv.str : cstr_npos;
diff --git a/include/stc/csview.h b/include/stc/csview.h
index 2efeff5b..dbff8620 100644
--- a/include/stc/csview.h
+++ b/include/stc/csview.h
@@ -69,15 +69,22 @@ STC_INLINE csview csview_slice(csview sv, size_t p1, size_t p2) {
return sv;
}
-/* iterator */
-STC_INLINE csview_iter csview_begin(const csview* self)
- { return c_make(csview_iter){.chr = {self->str, utf8_chr_size(self->str)}}; }
+/* utf8 iterator */
+STC_INLINE csview_iter csview_begin(const csview* self) {
+ if (!self->size) return c_make(csview_iter){NULL};
+ return c_make(csview_iter){.u8 = {{self->str, utf8_chr_size(self->str)},
+ self->str + self->size}};
+}
+
+STC_INLINE csview_iter csview_end(const csview* self)
+ { return c_make(csview_iter){.u8 = {{NULL}, self->str + self->size}}; }
-STC_INLINE csview_iter csview_end(const csview* self)
- { return c_make(csview_iter){self->str + self->size}; }
+STC_INLINE void csview_next(csview_iter* it) {
+ it->ref += it->u8.chr.size;
+ it->u8.chr.size = utf8_chr_size(it->ref);
+ if (it->ref == it->u8.end) it->ref = NULL;
+}
-STC_INLINE void csview_next(csview_iter* it)
- { it->ref += it->chr.size; it->chr.size = utf8_chr_size(it->ref); }
/* utf8 */
STC_INLINE size_t csview_u8_size(csview sv)
diff --git a/include/stc/cvec.h b/include/stc/cvec.h
index 81678293..6b120ff0 100644
--- a/include/stc/cvec.h
+++ b/include/stc/cvec.h
@@ -66,6 +66,8 @@ int main() {
struct cvec_rep { size_t size, cap; unsigned data[1]; };
#define cvec_rep_(self) c_unchecked_container_of((self)->data, struct cvec_rep, data)
+#define _it2_ptr(it1, it2) (it1.ref && !it2.ref ? it2.end : it2.ref)
+#define _it_ptr(it) (it.ref ? it.ref : it.end)
#endif // CVEC_H_INCLUDED
#ifndef _i_prefix
@@ -84,9 +86,9 @@ 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_key null);
STC_API _cx_value* _cx_memb(_push)(_cx_self* self, i_key value);
STC_API _cx_iter _cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2);
-STC_API _cx_value* _cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_value* p1, const _cx_value* p2);
-STC_API _cx_value* _cx_memb(_insert_uninit_p)(_cx_self* self, _cx_value* pos, const size_t n);
+STC_API _cx_iter _cx_memb(_insert_range)(_cx_self* self, _cx_value* pos,
+ const _cx_value* p1, const _cx_value* p2);
+STC_API _cx_iter _cx_memb(_insert_uninit)(_cx_self* self, _cx_value* pos, const size_t n);
#if !c_option(c_no_cmp)
STC_API int _cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y);
STC_API _cx_iter _cx_memb(_find_in)(_cx_iter it1, _cx_iter it2, _cx_raw raw);
@@ -94,37 +96,34 @@ STC_API _cx_iter _cx_memb(_binary_search_in)(_cx_iter it1, _cx_iter it2,
#endif
#if !defined _i_no_emplace
-STC_API _cx_value* _cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_raw* p1, const _cx_raw* p2);
+STC_API _cx_iter _cx_memb(_emplace_range)(_cx_self* self, _cx_value* pos,
+ const _cx_raw* p1, const _cx_raw* p2);
STC_INLINE _cx_value* _cx_memb(_emplace)(_cx_self* self, _cx_raw raw)
{ return _cx_memb(_push)(self, i_keyfrom(raw)); }
STC_INLINE _cx_value* _cx_memb(_emplace_back)(_cx_self* self, _cx_raw raw)
{ return _cx_memb(_push)(self, i_keyfrom(raw)); }
-STC_INLINE _cx_value*
+STC_INLINE _cx_iter
_cx_memb(_emplace_n)(_cx_self* self, const size_t idx, const _cx_raw arr[], const size_t n) {
- return _cx_memb(_emplace_range_p)(self, self->data + idx, arr, arr + n);
+ return _cx_memb(_emplace_range)(self, self->data + idx, arr, arr + n);
}
-STC_INLINE _cx_value*
+STC_INLINE _cx_iter
_cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, _cx_raw raw) {
- return _cx_memb(_emplace_range_p)(self, it.ref, &raw, &raw + 1);
+ return _cx_memb(_emplace_range)(self, _it_ptr(it), &raw, &raw + 1);
}
#endif // !_i_no_emplace
#if !defined _i_no_clone
STC_API _cx_self _cx_memb(_clone)(_cx_self cx);
-STC_API _cx_value* _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(_copy_range)(_cx_self* self, _cx_value* pos,
+ const _cx_value* p1, const _cx_value* p2);
STC_INLINE i_key _cx_memb(_value_clone)(_cx_value val)
{ return i_keyclone(val); }
STC_INLINE void _cx_memb(_copy)(_cx_self* self, const _cx_self* other) {
if (self->data == other->data) return;
- _cx_memb(_drop)(self);
- *self = _cx_memb(_clone)(*other);
+ _cx_memb(_clear)(self);
+ _cx_memb(_copy_range)(self, self->data, other->data,
+ other->data + cvec_rep_(other)->size);
}
-STC_INLINE _cx_value*
-_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 // !_i_no_clone
STC_INLINE size_t _cx_memb(_size)(const _cx_self* cx) { return cvec_rep_(cx)->size; }
@@ -140,14 +139,6 @@ STC_INLINE void _cx_memb(_pop)(_cx_self* self)
STC_INLINE _cx_value* _cx_memb(_push_back)(_cx_self* self, i_key value)
{ return _cx_memb(_push)(self, value); }
STC_INLINE void _cx_memb(_pop_back)(_cx_self* self) { _cx_memb(_pop)(self); }
-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)
- { return c_make(_cx_iter){self->data + cvec_rep_(self)->size}; }
-STC_INLINE void _cx_memb(_next)(_cx_iter* it) { ++it->ref; }
-STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, intptr_t offs)
- { it.ref += offs; return it; }
-STC_INLINE size_t _cx_memb(_index)(const _cx_self* cx, _cx_iter it) { return it.ref - cx->data; }
STC_INLINE _cx_self
_cx_memb(_with_size)(const size_t size, i_key null) {
@@ -168,22 +159,18 @@ _cx_memb(_shrink_to_fit)(_cx_self* self) {
_cx_memb(_reserve)(self, _cx_memb(_size)(self));
}
-STC_INLINE _cx_value*
-_cx_memb(_append_uninit)(_cx_self* self, const size_t n) {
- return _cx_memb(_insert_uninit_p)(self, self->data + _cx_memb(_size)(self), n);
-}
-STC_INLINE _cx_value*
+STC_INLINE _cx_iter
_cx_memb(_insert)(_cx_self* self, const size_t idx, i_key value) {
- return _cx_memb(_insert_range_p)(self, self->data + idx, &value, &value + 1);
+ return _cx_memb(_insert_range)(self, self->data + idx, &value, &value + 1);
}
-STC_INLINE _cx_value*
+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);
+ return _cx_memb(_insert_range)(self, self->data + idx, arr, arr + n);
}
-STC_INLINE _cx_value*
+STC_INLINE _cx_iter
_cx_memb(_insert_at)(_cx_self* self, _cx_iter it, i_key value) {
- return _cx_memb(_insert_range_p)(self, it.ref, &value, &value + 1);
+ return _cx_memb(_insert_range)(self, _it_ptr(it), &value, &value + 1);
}
STC_INLINE _cx_iter
@@ -195,8 +182,8 @@ _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(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2) {
- return _cx_memb(_erase_range_p)(self, it1.ref, it2.ref);
+_cx_memb(_erase_range)(_cx_self* self, _cx_iter i1, _cx_iter i2) {
+ return _cx_memb(_erase_range_p)(self, i1.ref, _it2_ptr(i1, i2));
}
STC_INLINE const _cx_value*
@@ -208,6 +195,24 @@ _cx_memb(_at_mut)(_cx_self* self, const size_t idx) {
assert(idx < cvec_rep_(self)->size); return self->data + idx;
}
+
+STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) {
+ size_t n = cvec_rep_(self)->size;
+ return c_make(_cx_iter){n ? self->data : NULL, self->data + n};
+}
+
+STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self)
+ { return c_make(_cx_iter){NULL, self->data + cvec_rep_(self)->size}; }
+
+STC_INLINE void _cx_memb(_next)(_cx_iter* it)
+ { if (++it->ref == it->end) it->ref = NULL; }
+
+STC_INLINE _cx_iter _cx_memb(_advance)(_cx_iter it, size_t n)
+ { if ((it.ref += n) >= it.end) it.ref = NULL; return it; }
+
+STC_INLINE size_t _cx_memb(_index)(const _cx_self* cx, _cx_iter it)
+ { return it.ref - cx->data; }
+
#if !c_option(c_no_cmp)
STC_INLINE _cx_iter
@@ -217,9 +222,7 @@ _cx_memb(_find)(const _cx_self* self, _cx_raw raw) {
STC_INLINE const _cx_value*
_cx_memb(_get)(const _cx_self* self, _cx_raw raw) {
- _cx_iter end = _cx_memb(_end)(self);
- _cx_value* val = _cx_memb(_find)(self, raw).ref;
- return val == end.ref ? NULL : val;
+ return _cx_memb(_find)(self, raw).ref;
}
STC_INLINE _cx_value*
@@ -240,10 +243,11 @@ _cx_memb(_lower_bound)(const _cx_self* self, _cx_raw raw) {
}
STC_INLINE void
-_cx_memb(_sort_range)(_cx_iter i1, _cx_iter i2,
- int(*_cmp_)(const _cx_value*, const _cx_value*)) {
- qsort(i1.ref, i2.ref - i1.ref, sizeof(_cx_value), (int(*)(const void*, const void*)) _cmp_);
+_cx_memb(_sort_range)(_cx_iter i1, _cx_iter i2, int(*cmp)(const _cx_value*, const _cx_value*)) {
+ qsort(i1.ref, _it2_ptr(i1, i2) - i1.ref, sizeof(_cx_value),
+ (int(*)(const void*, const void*)) cmp);
}
+
STC_INLINE void
_cx_memb(_sort)(_cx_self* self) {
_cx_memb(_sort_range)(_cx_memb(_begin)(self), _cx_memb(_end)(self), _cx_memb(_value_cmp));
@@ -289,7 +293,8 @@ _cx_memb(_reserve)(_cx_self* self, const size_t cap) {
const size_t len = rep->size;
if (cap > rep->cap || (cap && cap == len)) {
rep = (struct cvec_rep*) c_realloc(rep->cap ? rep : NULL,
- offsetof(struct cvec_rep, data) + cap*sizeof(i_key));
+ offsetof(struct cvec_rep, data)
+ + cap*sizeof(i_key));
if (!rep)
return false;
self->data = (_cx_value*) rep->data;
@@ -325,103 +330,106 @@ _cx_memb(_push)(_cx_self* self, i_key value) {
*v = value; return v;
}
-STC_DEF _cx_value*
-_cx_memb(_insert_uninit_p)(_cx_self* self, _cx_value* pos, const size_t n) {
- const size_t idx = pos - self->data;
+STC_DEF _cx_iter
+_cx_memb(_insert_uninit)(_cx_self* self, _cx_value* pos, const size_t n) {
struct cvec_rep* r = cvec_rep_(self);
- if (!n)
- return pos;
- if (r->size + n > r->cap) {
- if (!_cx_memb(_reserve)(self, r->size*3/2 + n))
- return NULL;
- r = cvec_rep_(self);
- pos = self->data + idx;
+ if (n) {
+ if (!pos) pos = self->data + r->size;
+ const size_t idx = pos - self->data;
+ if (r->size + n > r->cap) {
+ if (!_cx_memb(_reserve)(self, r->size*3/2 + n))
+ return _cx_memb(_end)(self);
+ r = cvec_rep_(self);
+ pos = self->data + idx;
+ }
+ memmove(pos + n, pos, (r->size - idx)*sizeof *pos);
+ r->size += n;
}
- memmove(pos + n, pos, (r->size - idx)*sizeof *pos);
- r->size += n;
- return pos;
+ return c_make(_cx_iter){pos, self->data + r->size};
}
-STC_DEF _cx_value*
-_cx_memb(_insert_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_value* p1, const _cx_value* p2) {
- pos = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1);
- if (pos)
- memcpy(pos, p1, (p2 - p1)*sizeof *p1);
- return pos;
+STC_DEF _cx_iter
+_cx_memb(_insert_range)(_cx_self* self, _cx_value* pos,
+ const _cx_value* p1, const _cx_value* p2) {
+ _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1);
+ if (it.ref)
+ memcpy(it.ref, p1, (p2 - p1)*sizeof *p1);
+ return it;
}
STC_DEF _cx_iter
_cx_memb(_erase_range_p)(_cx_self* self, _cx_value* p1, _cx_value* p2) {
+ assert(p1 && p2);
intptr_t len = p2 - p1;
- if (len > 0) {
- _cx_value* p = p1, *end = self->data + cvec_rep_(self)->size;
- for (; p != p2; ++p)
- { i_keydrop(p); }
- memmove(p1, p2, (end - p2) * sizeof(i_key));
- cvec_rep_(self)->size -= len;
- }
- return c_make(_cx_iter){.ref = p1};
+ struct cvec_rep* r = cvec_rep_(self);
+ _cx_value* p = p1, *end = self->data + r->size;
+ for (; p != p2; ++p)
+ { i_keydrop(p); }
+ memmove(p1, p2, (end - p2) * sizeof *p1);
+ r->size -= len;
+ return c_make(_cx_iter){p2 == end ? NULL : p1, end - len};
}
#if !defined _i_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);
- if (cvec_rep_(&out)->cap)
- _cx_memb(_clone_range_p)(&out, out.data, cx.data, cx.data + len);
+ _cx_self out = _cx_memb(_init)();
+ _cx_memb(_copy_range)(&out, out.data, cx.data, cx.data + len);
return out;
}
-STC_DEF _cx_value*
-_cx_memb(_clone_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_value* p1, const _cx_value* p2) {
- pos = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1);
- _cx_value* it = pos;
- if (pos) for (; p1 != p2; ++p1)
- *pos++ = i_keyclone((*p1));
+STC_DEF _cx_iter
+_cx_memb(_copy_range)(_cx_self* self, _cx_value* pos,
+ const _cx_value* p1, const _cx_value* p2) {
+ _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1);
+ if (it.ref)
+ for (_cx_value* p = it.ref; p1 != p2; ++p1)
+ *p++ = i_keyclone((*p1));
return it;
}
+#endif // !_i_no_clone
#if !defined _i_no_emplace
-STC_DEF _cx_value*
-_cx_memb(_emplace_range_p)(_cx_self* self, _cx_value* pos,
- const _cx_raw* p1, const _cx_raw* p2) {
- pos = _cx_memb(_insert_uninit_p)(self, pos, p2 - p1);
- _cx_value* it = pos;
- if (pos) for (; p1 != p2; ++p1)
- *pos++ = i_keyfrom((*p1));
+STC_DEF _cx_iter
+_cx_memb(_emplace_range)(_cx_self* self, _cx_value* pos,
+ const _cx_raw* p1, const _cx_raw* p2) {
+ _cx_iter it = _cx_memb(_insert_uninit)(self, pos, p2 - p1);
+ if (it.ref)
+ for (_cx_value* p = it.ref; p1 != p2; ++p1)
+ *p++ = i_keyfrom((*p1));
return it;
}
#endif // !_i_no_emplace
-#endif // !_i_no_clone
#if !c_option(c_no_cmp)
STC_DEF _cx_iter
_cx_memb(_find_in)(_cx_iter i1, _cx_iter i2, _cx_raw raw) {
- for (; i1.ref != i2.ref; ++i1.ref) {
+ const _cx_value* p2 = _it2_ptr(i1, i2);
+ for (; i1.ref != p2; ++i1.ref) {
const _cx_raw r = i_keyto(i1.ref);
if (i_eq((&raw), (&r)))
return i1;
}
- return i2;
+ i2.ref = NULL; return i2; // NB!
}
STC_DEF _cx_iter
-_cx_memb(_binary_search_in)(_cx_iter i1, _cx_iter i2, const _cx_raw raw, _cx_iter* lower_bound) {
- _cx_iter mid, last = i2;
- while (i1.ref != i2.ref) {
- mid.ref = i1.ref + (i2.ref - i1.ref)/2;
+_cx_memb(_binary_search_in)(_cx_iter i1, _cx_iter i2, const _cx_raw raw,
+ _cx_iter* lower_bound) {
+ const _cx_value* p2 = _it2_ptr(i1, i2);
+ _cx_iter mid = i1;
+ while (i1.ref != p2) {
+ mid.ref = i1.ref + (p2 - i1.ref)/2;
const _cx_raw m = i_keyto(mid.ref);
const int c = i_cmp((&raw), (&m));
if (!c) return *lower_bound = mid;
- else if (c < 0) i2.ref = mid.ref;
+ else if (c < 0) p2 = mid.ref;
else i1.ref = mid.ref + 1;
}
- *lower_bound = i1;
- return last;
+ *lower_bound = i1.ref == i2.end ? i2 : i1;
+ i2.ref = NULL; return i2; // NB!
}
STC_DEF int
diff --git a/include/stc/forward.h b/include/stc/forward.h
index 04566b98..264d6939 100644
--- a/include/stc/forward.h
+++ b/include/stc/forward.h
@@ -57,7 +57,7 @@ typedef struct { const char* str; size_t size; } csview;
typedef char csview_value;
typedef union {
const char *ref;
- csview chr;
+ struct { csview chr; const char *end; } u8;
} csview_iter, cstr_iter;
#define c_true(...) __VA_ARGS__
@@ -68,17 +68,17 @@ typedef union {
\
typedef struct { \
SELF##_value* get; \
- long* use_count; \
+ catomic_long* use_count; \
} SELF
#define _c_carr2_types(SELF, VAL) \
typedef VAL SELF##_value; \
- typedef struct { SELF##_value *ref; } SELF##_iter; \
+ typedef struct { SELF##_value *ref, *end; } SELF##_iter; \
typedef struct { SELF##_value **data; size_t xdim, ydim; } SELF
#define _c_carr3_types(SELF, VAL) \
typedef VAL SELF##_value; \
- typedef struct { SELF##_value *ref; } SELF##_iter; \
+ typedef struct { SELF##_value *ref, *end; } SELF##_iter; \
typedef struct { SELF##_value ***data; size_t xdim, ydim, zdim; } SELF
#define _c_cbox_types(SELF, VAL) \
@@ -89,7 +89,7 @@ typedef union {
#define _c_cdeq_types(SELF, VAL) \
typedef VAL SELF##_value; \
- typedef struct {SELF##_value *ref; } SELF##_iter; \
+ typedef struct {SELF##_value *ref, *end; } SELF##_iter; \
typedef struct {SELF##_value *_base, *data;} SELF
#define _c_clist_types(SELF, VAL) \
@@ -120,7 +120,7 @@ typedef union {
} SELF##_result; \
\
typedef struct { \
- SELF##_value *ref; \
+ SELF##_value *ref, *end; \
uint8_t* _hx; \
} SELF##_iter; \
\
@@ -186,7 +186,7 @@ typedef union {
#endif
#define _c_cstack_types(SELF, VAL) \
typedef VAL SELF##_value; \
- typedef struct { SELF##_value *ref; } SELF##_iter; \
+ typedef struct { SELF##_value *ref, *end; } SELF##_iter; \
typedef struct SELF { \
SELF##_value* data; \
size_t size, capacity; \
@@ -194,7 +194,7 @@ typedef union {
#define _c_cstack_fixed(SELF, VAL, CAP) \
typedef VAL SELF##_value; \
- typedef struct { SELF##_value *ref; } SELF##_iter; \
+ typedef struct { SELF##_value *ref, *end; } SELF##_iter; \
typedef struct SELF { \
SELF##_value data[CAP]; \
size_t size; \
@@ -209,7 +209,7 @@ typedef union {
#define _c_cvec_types(SELF, VAL) \
typedef VAL SELF##_value; \
- typedef struct { SELF##_value *ref; } SELF##_iter; \
+ typedef struct { SELF##_value *ref, *end; } SELF##_iter; \
typedef struct { SELF##_value *data; } SELF
#endif // STC_FORWARD_H_INCLUDED
diff --git a/include/stc/template.h b/include/stc/template.h
index cb0c7ef2..4597e02c 100644
--- a/include/stc/template.h
+++ b/include/stc/template.h
@@ -110,7 +110,8 @@
#elif defined i_key_arcbox
#define i_key_bind i_key_arcbox
#define i_keyraw c_paste(i_key_arcbox, _value)
- #define i_keyto c_paste(i_key_arcbox, _toval)
+ #define i_keyfrom c_paste(i_key_arcbox, _from)
+ #define i_keyto(x) *(x)->get
#define i_eq c_paste(i_key_arcbox, _value_eq)
#endif
@@ -167,7 +168,7 @@
#define i_keydrop c_default_drop
#endif
-// i_eq, i_less, i_cmp, i_hash
+// i_eq, i_less, i_cmp
#if !defined i_eq && (defined i_cmp || defined i_less)
#define i_eq(x, y) !(i_cmp(x, y))
#elif !defined i_eq
@@ -175,10 +176,13 @@
#endif
#if !defined i_less && !defined i_cmp
#define i_less c_default_less
+#elif !defined i_less
+ #define i_less(x, y) (i_cmp(x, y)) < 0
#endif
#ifndef i_cmp
#define i_cmp(x, y) (i_less(y, x)) - (i_less(x, y))
#endif
+
#ifndef i_hash
#define i_hash c_default_hash
#endif
@@ -197,7 +201,8 @@
#elif defined i_val_arcbox
#define i_val_bind i_val_arcbox
#define i_valraw c_paste(i_val_arcbox, _value)
- #define i_valto c_paste(i_val_arcbox, _toval)
+ #define i_valfrom c_paste(i_val_arcbox, _from)
+ #define i_valto(x) *(x)->get
#endif
#ifdef i_val_bind
@@ -213,6 +218,9 @@
#endif
#endif
+#ifndef i_val
+ #error "i_val* must be defined for maps"
+#endif
#if defined i_valraw ^ defined i_valto
#error "both i_valto and i_valraw must be defined, if any"
#elif defined i_valfrom && !defined i_valraw