From 890e210893d96a6658a838331fa233b4a58723c7 Mon Sep 17 00:00:00 2001 From: tylov Date: Sun, 23 Jul 2023 23:43:55 +0200 Subject: Internal: Reorganized cqueue and cdeq: spliced out header and impl in cqueue.h to priv/cqueue_hdr.h and priv/cqueue_imp.h. --- include/stc/priv/cqueue_hdr.h | 117 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 include/stc/priv/cqueue_hdr.h (limited to 'include/stc/priv/cqueue_hdr.h') diff --git a/include/stc/priv/cqueue_hdr.h b/include/stc/priv/cqueue_hdr.h new file mode 100644 index 00000000..90539f36 --- /dev/null +++ b/include/stc/priv/cqueue_hdr.h @@ -0,0 +1,117 @@ +/* MIT License + * + * Copyright (c) 2023 Tyge Løvset + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "template.h" +#ifndef i_is_forward +_cx_DEFTYPES(_c_cdeq_types, _cx_Self, i_key); +#endif +typedef i_keyraw _cx_raw; + +STC_API _cx_Self _cx_MEMB(_with_capacity)(const intptr_t n); +STC_API bool _cx_MEMB(_reserve)(_cx_Self* self, const intptr_t n); +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); // push_back +STC_API void _cx_MEMB(_shrink_to_fit)(_cx_Self *self); +STC_API _cx_iter _cx_MEMB(_advance)(_cx_iter it, intptr_t n); + +#define _cdeq_toidx(self, pos) (((pos) - (self)->start) & (self)->capmask) +#define _cdeq_topos(self, idx) (((self)->start + (idx)) & (self)->capmask) + +STC_INLINE _cx_Self _cx_MEMB(_init)(void) + { _cx_Self cx = {0}; return cx; } +STC_INLINE void _cx_MEMB(_put_n)(_cx_Self* self, const _cx_raw* raw, intptr_t n) + { while (n--) _cx_MEMB(_push)(self, i_keyfrom(*raw++)); } +STC_INLINE _cx_Self _cx_MEMB(_from_n)(const _cx_raw* raw, intptr_t n) + { _cx_Self cx = {0}; _cx_MEMB(_put_n)(&cx, raw, n); return cx; } +STC_INLINE void _cx_MEMB(_value_drop)(_cx_value* val) { i_keydrop(val); } + +#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 + +#if defined _i_has_eq || defined _i_has_cmp +STC_API bool _cx_MEMB(_eq)(const _cx_Self* self, const _cx_Self* other); +#endif + +#if !defined i_no_clone +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 intptr_t _cx_MEMB(_size)(const _cx_Self* self) + { return _cdeq_toidx(self, self->end); } +STC_INLINE intptr_t _cx_MEMB(_capacity)(const _cx_Self* self) + { return self->capmask; } +STC_INLINE bool _cx_MEMB(_empty)(const _cx_Self* self) + { return self->start == self->end; } +STC_INLINE _cx_raw _cx_MEMB(_value_toraw)(const _cx_value* pval) + { return i_keyto(pval); } + +STC_INLINE _cx_value* _cx_MEMB(_front)(const _cx_Self* self) + { return self->data + self->start; } + +STC_INLINE _cx_value* _cx_MEMB(_back)(const _cx_Self* self) + { return self->data + ((self->end - 1) & self->capmask); } + +STC_INLINE void _cx_MEMB(_pop)(_cx_Self* self) { // pop_front + c_assert(!_cx_MEMB(_empty)(self)); + i_keydrop((self->data + self->start)); + self->start = (self->start + 1) & self->capmask; +} + +STC_INLINE _cx_value _cx_MEMB(_pull)(_cx_Self* self) { // move front out of queue + c_assert(!_cx_MEMB(_empty)(self)); + intptr_t s = self->start; + self->start = (s + 1) & self->capmask; + return self->data[s]; +} + +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); +} + +STC_INLINE _cx_iter _cx_MEMB(_begin)(const _cx_Self* self) { + return c_LITERAL(_cx_iter){ + _cx_MEMB(_empty)(self) ? NULL : self->data + self->start, + self->start, self + }; +} + +STC_INLINE _cx_iter _cx_MEMB(_end)(const _cx_Self* self) + { return c_LITERAL(_cx_iter){.pos=self->end, ._s=self}; } + +STC_INLINE void _cx_MEMB(_next)(_cx_iter* it) { + if (it->pos != it->_s->capmask) { ++it->ref; ++it->pos; } + else { it->ref -= it->pos; it->pos = 0; } + if (it->pos == it->_s->end) it->ref = NULL; +} + +STC_INLINE intptr_t _cx_MEMB(_index)(const _cx_Self* self, _cx_iter it) + { return _cdeq_toidx(self, it.pos); } + +STC_INLINE void _cx_MEMB(_adjust_end_)(_cx_Self* self, intptr_t n) + { self->end = (self->end + n) & self->capmask; } -- cgit v1.2.3 From c27c266b6c4ae0e5e535b18c3790ee97416412b9 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Tue, 8 Aug 2023 12:28:15 +0200 Subject: Reverted cco_cleanup => cco_final. (cco_cleanup deprecated). Updated generator.c example. Misc internal refactoring. --- docs/coroutine_api.md | 12 +++++------ include/stc/cmap.h | 16 +++++++-------- include/stc/coroutine.h | 5 +++-- include/stc/forward.h | 6 ++---- include/stc/priv/cqueue_hdr.h | 4 ++-- misc/examples/coroutines/coread.c | 2 +- misc/examples/coroutines/coroutines.c | 6 +++--- misc/examples/coroutines/cotasks1.c | 4 ++-- misc/examples/coroutines/cotasks2.c | 4 ++-- misc/examples/coroutines/dining_philosophers.c | 4 ++-- misc/examples/coroutines/filetask.c | 4 ++-- misc/examples/coroutines/generator.c | 28 ++++++++++++++++++-------- misc/examples/coroutines/triples.c | 2 +- 13 files changed, 54 insertions(+), 43 deletions(-) (limited to 'include/stc/priv/cqueue_hdr.h') diff --git a/docs/coroutine_api.md b/docs/coroutine_api.md index b356dcf0..6bd558f2 100644 --- a/docs/coroutine_api.md +++ b/docs/coroutine_api.md @@ -16,7 +16,7 @@ NB! ***cco_yield\*()*** / ***cco_await\*()*** may not be called from within a `s | | Function / operator | Description | |:----------|:-------------------------------------|:----------------------------------------| |`cco_result` | `CCO_DONE`, `CCO_AWAIT`, `CCO_YIELD` | Default set of return values from coroutines | -| | `cco_cleanup:` | Label for cleanup position in coroutine | +| | `cco_final:` | Label for cleanup position in coroutine | | `bool` | `cco_done(co)` | Is coroutine done? | | | `cco_routine(co) {}` | The coroutine scope | | | `cco_yield();` | Yield/suspend execution (return CCO_YIELD)| @@ -101,13 +101,13 @@ int triples(struct triples* i) { (int64_t)i->c * i->c) { if (i->c > i->max_c) - cco_return; // "jump" to cco_cleanup if defined, else exit scope. + cco_return; // "jump" to cco_final if defined, else exit scope. cco_yield(); } } } } - cco_cleanup: + cco_final: puts("done"); } return 0; // CCO_DONE @@ -160,7 +160,7 @@ int gcd1_triples(struct gcd1_triples* i) else cco_yield(); } - cco_cleanup: + cco_final: cco_stop(&i->tri); // to cleanup state if still active triples(&i->tri); // do cleanup (or no-op if done) } @@ -248,7 +248,7 @@ int produce_items(struct produce_items* p, cco_runtime* rt) printf("produced %s\n", cstr_str(&p->str)); cco_yield(); } - cco_cleanup: + cco_final: cstr_drop(&p->str); puts("done produce"); } @@ -273,7 +273,7 @@ int consume_items(struct consume_items* c, cco_runtime* rt) print_time(); printf("consumed %s\n", cstr_str(&c->produce.str)); } - cco_cleanup: + cco_final: cco_stop(&c->produce); cco_resume_task(&c->produce, rt); puts("done consume"); diff --git a/include/stc/cmap.h b/include/stc/cmap.h index cd7430ba..e0134964 100644 --- a/include/stc/cmap.h +++ b/include/stc/cmap.h @@ -306,7 +306,7 @@ STC_INLINE void _cx_MEMB(_wipe_)(_cx_Self* self) { if (self->size == 0) return; _cx_value* d = self->data, *_end = d + self->bucket_count; - chash_slot* s = self->slot; + struct chash_slot* s = self->slot; for (; d != _end; ++d) if ((s++)->hashx) _cx_MEMB(_value_drop)(d); @@ -321,7 +321,7 @@ STC_DEF void _cx_MEMB(_drop)(_cx_Self* self) { STC_DEF void _cx_MEMB(_clear)(_cx_Self* self) { _cx_MEMB(_wipe_)(self); self->size = 0; - c_memset(self->slot, 0, c_sizeof(chash_slot)*self->bucket_count); + c_memset(self->slot, 0, c_sizeof(struct chash_slot)*self->bucket_count); } #ifdef _i_ismap @@ -359,7 +359,7 @@ _cx_MEMB(_bucket_)(const _cx_Self* self, const _cx_keyraw* rkeyptr) { intptr_t _cap = self->bucket_count; intptr_t _idx = fastrange_2(_hash, _cap); _cx_result b = {NULL, true, (uint8_t)(_hash | 0x80)}; - const chash_slot* s = self->slot; + const struct chash_slot* s = self->slot; while (s[_idx].hashx) { if (s[_idx].hashx == b.hashx) { const _cx_keyraw _raw = i_keyto(_i_keyref(self->data + _idx)); @@ -394,8 +394,8 @@ _cx_MEMB(_clone)(_cx_Self m) { if (m.data) { _cx_value *d = (_cx_value *)i_malloc(c_sizeof(_cx_value)*m.bucket_count), *_dst = d, *_end = m.data + m.bucket_count; - const intptr_t _mem = c_sizeof(chash_slot)*(m.bucket_count + 1); - chash_slot *s = (chash_slot *)c_memcpy(i_malloc(_mem), m.slot, _mem); + const intptr_t _mem = c_sizeof(struct chash_slot)*(m.bucket_count + 1); + struct chash_slot *s = (struct chash_slot *)c_memcpy(i_malloc(_mem), m.slot, _mem); if (!(d && s)) { i_free(d), i_free(s), d = 0, s = 0, m.bucket_count = 0; } else @@ -417,14 +417,14 @@ _cx_MEMB(_reserve)(_cx_Self* self, const intptr_t _newcap) { _newbucks = cnextpow2(_newbucks); _cx_Self m = { (_cx_value *)i_malloc(_newbucks*c_sizeof(_cx_value)), - (chash_slot *)i_calloc(_newbucks + 1, sizeof(chash_slot)), + (struct chash_slot *)i_calloc(_newbucks + 1, sizeof(struct chash_slot)), self->size, _newbucks }; bool ok = m.data && m.slot; if (ok) { // Rehash: m.slot[_newbucks].hashx = 0xff; const _cx_value* d = self->data; - const chash_slot* s = self->slot; + const struct chash_slot* s = self->slot; for (intptr_t i = 0; i < _oldbucks; ++i, ++d) if ((s++)->hashx) { _cx_keyraw r = i_keyto(_i_keyref(d)); _cx_result b = _cx_MEMB(_bucket_)(&m, &r); @@ -441,7 +441,7 @@ _cx_MEMB(_reserve)(_cx_Self* self, const intptr_t _newcap) { STC_DEF void _cx_MEMB(_erase_entry)(_cx_Self* self, _cx_value* _val) { _cx_value* d = self->data; - chash_slot* s = self->slot; + struct chash_slot* s = self->slot; intptr_t i = _val - d, j = i, k; const intptr_t _cap = self->bucket_count; _cx_MEMB(_value_drop)(_val); diff --git a/include/stc/coroutine.h b/include/stc/coroutine.h index 0e592bae..cecd4002 100644 --- a/include/stc/coroutine.h +++ b/include/stc/coroutine.h @@ -38,7 +38,7 @@ int iterpair(struct iterpair* I) { for (I->y = 0; I->y < I->max_y; I->y++) cco_yield(); - cco_cleanup: // required if there is cleanup code + cco_final: // required if there is cleanup code puts("final"); } return 0; // CCO_DONE @@ -103,7 +103,8 @@ typedef enum { /* cco_blocking_call(): assumes coroutine returns a cco_result value (int) */ #define cco_blocking_call(corocall) while ((corocall) != CCO_DONE) -#define cco_cleanup \ +#define cco_cleanup cco_final // [deprecated] +#define cco_final \ *_state = CCO_STATE_CLEANUP; case CCO_STATE_CLEANUP #define cco_return \ diff --git a/include/stc/forward.h b/include/stc/forward.h index 085205cf..572a319f 100644 --- a/include/stc/forward.h +++ b/include/stc/forward.h @@ -107,8 +107,6 @@ typedef union { SELF##_node *last; \ } SELF -typedef struct chash_slot chash_slot; - #define _c_chash_types(SELF, KEY, VAL, MAP_ONLY, SET_ONLY) \ typedef KEY SELF##_key; \ typedef VAL SELF##_mapped; \ @@ -125,12 +123,12 @@ typedef struct chash_slot chash_slot; \ typedef struct { \ SELF##_value *ref, *_end; \ - chash_slot* sref; \ + struct chash_slot* sref; \ } SELF##_iter; \ \ typedef struct SELF { \ SELF##_value* data; \ - chash_slot* slot; \ + struct chash_slot* slot; \ intptr_t size, bucket_count; \ } SELF diff --git a/include/stc/priv/cqueue_hdr.h b/include/stc/priv/cqueue_hdr.h index 90539f36..1cad8684 100644 --- a/include/stc/priv/cqueue_hdr.h +++ b/include/stc/priv/cqueue_hdr.h @@ -96,8 +96,8 @@ STC_INLINE void _cx_MEMB(_copy)(_cx_Self* self, const _cx_Self* other) { STC_INLINE _cx_iter _cx_MEMB(_begin)(const _cx_Self* self) { return c_LITERAL(_cx_iter){ - _cx_MEMB(_empty)(self) ? NULL : self->data + self->start, - self->start, self + .ref=_cx_MEMB(_empty)(self) ? NULL : self->data + self->start, + .pos=self->start, ._s=self }; } diff --git a/misc/examples/coroutines/coread.c b/misc/examples/coroutines/coread.c index 359ca85d..6d3acdd7 100644 --- a/misc/examples/coroutines/coread.c +++ b/misc/examples/coroutines/coread.c @@ -21,7 +21,7 @@ int file_read(struct file_read* g) cco_await(!cstr_getline(&g->line, g->fp)); - cco_cleanup: + cco_final: printf("finish\n"); cstr_drop(&g->line); if (g->fp) fclose(g->fp); diff --git a/misc/examples/coroutines/coroutines.c b/misc/examples/coroutines/coroutines.c index faeb71f6..802a976a 100644 --- a/misc/examples/coroutines/coroutines.c +++ b/misc/examples/coroutines/coroutines.c @@ -34,7 +34,7 @@ int prime(struct prime* g) { cco_yield(); } } - cco_cleanup: + cco_final: printf("final prm\n"); } return 0; @@ -68,7 +68,7 @@ int fibonacci(struct fibonacci* g) { } cco_yield(); } - cco_cleanup: + cco_final: printf("final fib\n"); } return 0; @@ -92,7 +92,7 @@ int combined(struct combined* g) { cco_reset(&g->prm); cco_await_call(prime(&g->prm)); - cco_cleanup: + cco_final: puts("final combined"); } return 0; diff --git a/misc/examples/coroutines/cotasks1.c b/misc/examples/coroutines/cotasks1.c index 230bd62b..7df4eb34 100644 --- a/misc/examples/coroutines/cotasks1.c +++ b/misc/examples/coroutines/cotasks1.c @@ -52,7 +52,7 @@ int produce_items(struct produce_items* p) printf("produced %s\n", cstr_str(&p->str)); cco_yield(); } - cco_cleanup: + cco_final: cstr_drop(&p->str); puts("done produce"); } @@ -76,7 +76,7 @@ int consume_items(struct consume_items* c, struct produce_items* p) print_time(); printf("consumed %s\n", cstr_str(&p->str)); } - cco_cleanup: + cco_final: puts("done consume"); } return 0; diff --git a/misc/examples/coroutines/cotasks2.c b/misc/examples/coroutines/cotasks2.c index d77a28bc..f6257a7e 100644 --- a/misc/examples/coroutines/cotasks2.c +++ b/misc/examples/coroutines/cotasks2.c @@ -53,7 +53,7 @@ int produce_items(struct produce_items* p, cco_runtime* rt) cco_yield(); } - cco_cleanup: + cco_final: cstr_drop(&p->str); puts("done produce"); } @@ -80,7 +80,7 @@ int consume_items(struct consume_items* c, cco_runtime* rt) printf("consumed %s\n", cstr_str(&c->produce.str)); } - cco_cleanup: + cco_final: cco_stop(&c->produce); cco_resume_task(&c->produce, rt); puts("done consume"); diff --git a/misc/examples/coroutines/dining_philosophers.c b/misc/examples/coroutines/dining_philosophers.c index e917c303..d353b3b9 100644 --- a/misc/examples/coroutines/dining_philosophers.c +++ b/misc/examples/coroutines/dining_philosophers.c @@ -48,7 +48,7 @@ int philosopher(struct Philosopher* p) cco_sem_release(p->right_fork); } - cco_cleanup: + cco_final: printf("Philosopher %d finished\n", p->id); } return 0; @@ -76,7 +76,7 @@ int dining(struct Dining* d) cco_yield(); // suspend, return control back to main } - cco_cleanup: + cco_final: for (int i = 0; i < num_philosophers; ++i) { cco_stop(&d->ph[i]); philosopher(&d->ph[i]); diff --git a/misc/examples/coroutines/filetask.c b/misc/examples/coroutines/filetask.c index 0607442d..74388359 100644 --- a/misc/examples/coroutines/filetask.c +++ b/misc/examples/coroutines/filetask.c @@ -28,7 +28,7 @@ int file_read(struct file_read* co, cco_runtime* rt) cco_yield(); } - cco_cleanup: + cco_final: fclose(co->fp); cstr_drop(&co->line); puts("done file_read"); @@ -56,7 +56,7 @@ int count_line(struct count_line* co, cco_runtime* rt) cco_yield(); } - cco_cleanup: + cco_final: cstr_drop(&co->path); puts("done count_line"); } diff --git a/misc/examples/coroutines/generator.c b/misc/examples/coroutines/generator.c index 3f51ce9c..96498498 100644 --- a/misc/examples/coroutines/generator.c +++ b/misc/examples/coroutines/generator.c @@ -2,12 +2,15 @@ #include #include +#include typedef struct { - int size; + int max_triples; int a, b, c; } Triple; +// Create an iterable generator over Triple with count items. +// Requires coroutine Triple_next() and function Triple_begin() to be defined. cco_iter_struct(Triple, int count; ); @@ -20,16 +23,15 @@ int Triple_next(Triple_iter* it) { for (g->a = 1; g->a < g->c; ++g->a) { for (g->b = g->a; g->b < g->c; ++g->b) { if (g->a*g->a + g->b*g->b == g->c*g->c) { - if (it->count++ == g->size) + if (it->count++ == g->max_triples) cco_return; cco_yield(); } } } } - cco_cleanup: - it->ref = NULL; - puts("done"); + cco_final: + it->ref = NULL; // stop the iterator } return 0; } @@ -43,12 +45,22 @@ Triple_iter Triple_begin(Triple* g) { int main(void) { - puts("Pythagorean triples; stops at 100 triples or c >= 100:"); - Triple triple = {.size=100}; + puts("Pythagorean triples.\nGet max 200 triples with c < 50:"); + Triple triple = {.max_triples=200}; + c_foreach (i, Triple, triple) { - if (i.ref->c < 100) + if (i.ref->c < 50) printf("%u: (%d, %d, %d)\n", i.count, i.ref->a, i.ref->b, i.ref->c); else cco_stop(&i); } + + puts("\nGet the 10 first triples with odd a's and a <= 20:"); + c_forfilter (i, Triple, triple, + i.ref->a <= 20 && + (i.ref->a & 1) && + c_flt_take(i, 10) + ){ + printf("%d: (%d, %d, %d)\n", c_flt_getcount(i), i.ref->a, i.ref->b, i.ref->c); + } } diff --git a/misc/examples/coroutines/triples.c b/misc/examples/coroutines/triples.c index 22914c2b..d6ce2791 100644 --- a/misc/examples/coroutines/triples.c +++ b/misc/examples/coroutines/triples.c @@ -40,7 +40,7 @@ int triples_coro(struct triples* t) { } } } - cco_cleanup: + cco_final: puts("done"); } return 0; -- cgit v1.2.3 From 1802558d41112e99d965000c97c45ebf7984d70c Mon Sep 17 00:00:00 2001 From: tylov Date: Sun, 13 Aug 2023 14:14:25 +0200 Subject: Fixed cqueue.h: cqueue_X_copy() was not defined inside a `c_no_clone` check. Reverted to 2X expansion for cvec to compete with gcc speed. --- include/stc/cvec.h | 14 +++++++------- include/stc/priv/cqueue_hdr.h | 11 +++++------ 2 files changed, 12 insertions(+), 13 deletions(-) (limited to 'include/stc/priv/cqueue_hdr.h') diff --git a/include/stc/cvec.h b/include/stc/cvec.h index dc16e94a..12cd6875 100644 --- a/include/stc/cvec.h +++ b/include/stc/cvec.h @@ -94,13 +94,13 @@ STC_API _cx_iter _cx_MEMB(_binary_search_in)(_cx_iter it1, _cx_iter it2, STC_INLINE void _cx_MEMB(_value_drop)(_cx_value* val) { i_keydrop(val); } STC_INLINE _cx_value* _cx_MEMB(_push)(_cx_Self* self, i_key value) { - if (self->_len == self->_cap) - if (!_cx_MEMB(_reserve)(self, self->_len*3/2 + 4)) - return NULL; - _cx_value *v = self->data + self->_len++; - *v = value; - return v; -} + if (self->_len == self->_cap) + if (!_cx_MEMB(_reserve)(self, self->_len*2 + 4)) + return NULL; + _cx_value *v = self->data + self->_len++; + *v = value; + return v; + } #if !defined i_no_emplace STC_API _cx_iter diff --git a/include/stc/priv/cqueue_hdr.h b/include/stc/priv/cqueue_hdr.h index 1cad8684..06f3bd74 100644 --- a/include/stc/priv/cqueue_hdr.h +++ b/include/stc/priv/cqueue_hdr.h @@ -59,6 +59,11 @@ STC_API bool _cx_MEMB(_eq)(const _cx_Self* self, const _cx_Self* othe 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); } +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); + } #endif // !i_no_clone STC_INLINE intptr_t _cx_MEMB(_size)(const _cx_Self* self) { return _cdeq_toidx(self, self->end); } @@ -88,12 +93,6 @@ STC_INLINE _cx_value _cx_MEMB(_pull)(_cx_Self* self) { // move front out of queu return self->data[s]; } -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); -} - STC_INLINE _cx_iter _cx_MEMB(_begin)(const _cx_Self* self) { return c_LITERAL(_cx_iter){ .ref=_cx_MEMB(_empty)(self) ? NULL : self->data + self->start, -- cgit v1.2.3