summaryrefslogtreecommitdiffhomepage
path: root/include/stc/priv
diff options
context:
space:
mode:
author_Tradam <[email protected]>2023-09-08 01:29:47 +0000
committerGitHub <[email protected]>2023-09-08 01:29:47 +0000
commit3c76c7f3d5db3f9586a90d03f8fbb02d79de9acd (patch)
treeafbe4b540967223911f7c5de36559b82154f02f3 /include/stc/priv
parent0841165881871ee01b782129be681209aeed2423 (diff)
parent1a72205fe05c2375cfd380dd8381a8460d9ed8d1 (diff)
downloadSTC-modified-modified.tar.gz
STC-modified-modified.zip
Merge branch 'stclib:master' into modifiedHEADmodified
Diffstat (limited to 'include/stc/priv')
-rw-r--r--include/stc/priv/cqueue_hdr.h116
-rw-r--r--include/stc/priv/cqueue_imp.h129
-rw-r--r--include/stc/priv/linkage.h (renamed from include/stc/priv/altnames.h)30
-rw-r--r--include/stc/priv/raii.h27
-rw-r--r--include/stc/priv/template.h132
-rw-r--r--include/stc/priv/template2.h14
6 files changed, 339 insertions, 109 deletions
diff --git a/include/stc/priv/cqueue_hdr.h b/include/stc/priv/cqueue_hdr.h
new file mode 100644
index 00000000..06f3bd74
--- /dev/null
+++ b/include/stc/priv/cqueue_hdr.h
@@ -0,0 +1,116 @@
+/* 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); }
+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); }
+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 _cx_iter _cx_MEMB(_begin)(const _cx_Self* self) {
+ return c_LITERAL(_cx_iter){
+ .ref=_cx_MEMB(_empty)(self) ? NULL : self->data + self->start,
+ .pos=self->start, ._s=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; }
diff --git a/include/stc/priv/cqueue_imp.h b/include/stc/priv/cqueue_imp.h
new file mode 100644
index 00000000..65711fc0
--- /dev/null
+++ b/include/stc/priv/cqueue_imp.h
@@ -0,0 +1,129 @@
+/* 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.
+ */
+
+STC_DEF _cx_iter _cx_MEMB(_advance)(_cx_iter it, intptr_t n) {
+ intptr_t len = _cx_MEMB(_size)(it._s);
+ intptr_t pos = it.pos, idx = _cdeq_toidx(it._s, pos);
+ it.pos = (pos + n) & it._s->capmask;
+ it.ref += it.pos - pos;
+ if (!c_less_unsigned(idx + n, len)) it.ref = NULL;
+ return it;
+}
+
+STC_DEF void
+_cx_MEMB(_clear)(_cx_Self* self) {
+ c_foreach (i, _cx_Self, *self)
+ { i_keydrop(i.ref); }
+ self->start = 0, self->end = 0;
+}
+
+STC_DEF void
+_cx_MEMB(_drop)(_cx_Self* self) {
+ _cx_MEMB(_clear)(self);
+ i_free(self->data);
+}
+
+STC_DEF _cx_Self
+_cx_MEMB(_with_capacity)(const intptr_t n) {
+ _cx_Self cx = {0};
+ _cx_MEMB(_reserve)(&cx, n);
+ return cx;
+}
+
+STC_DEF bool
+_cx_MEMB(_reserve)(_cx_Self* self, const intptr_t n) {
+ if (n <= self->capmask)
+ return true;
+ intptr_t oldcap = self->capmask + 1, newcap = stc_nextpow2(n + 1);
+ _cx_value* d = (_cx_value *)i_realloc(self->data, newcap*c_sizeof *self->data);
+ if (!d)
+ return false;
+ intptr_t head = oldcap - self->start;
+ if (self->start <= self->end)
+ ;
+ else if (head < self->end) {
+ self->start = newcap - head;
+ c_memmove(d + self->start, d + oldcap - head, head*c_sizeof *d);
+ } else {
+ c_memmove(d + oldcap, d, self->end*c_sizeof *d);
+ self->end += oldcap;
+ }
+ self->capmask = newcap - 1;
+ self->data = d;
+ return true;
+}
+
+STC_DEF _cx_value*
+_cx_MEMB(_push)(_cx_Self* self, i_key value) { // push_back
+ intptr_t end = (self->end + 1) & self->capmask;
+ if (end == self->start) { // full
+ _cx_MEMB(_reserve)(self, self->capmask + 3); // => 2x expand
+ end = (self->end + 1) & self->capmask;
+ }
+ _cx_value *v = self->data + self->end;
+ self->end = end;
+ *v = value;
+ return v;
+}
+
+STC_DEF void
+_cx_MEMB(_shrink_to_fit)(_cx_Self *self) {
+ intptr_t sz = _cx_MEMB(_size)(self), j = 0;
+ if (sz > self->capmask/2)
+ return;
+ _cx_Self out = _cx_MEMB(_with_capacity)(sz);
+ if (!out.data)
+ return;
+ c_foreach (i, _cx_Self, *self)
+ out.data[j++] = *i.ref;
+ out.end = sz;
+ i_free(self->data);
+ *self = out;
+}
+
+#if !defined i_no_clone
+STC_DEF _cx_Self
+_cx_MEMB(_clone)(_cx_Self cx) {
+ intptr_t sz = _cx_MEMB(_size)(&cx), j = 0;
+ _cx_Self out = _cx_MEMB(_with_capacity)(sz);
+ if (out.data)
+ c_foreach (i, _cx_Self, cx)
+ out.data[j++] = i_keyclone((*i.ref));
+ out.end = sz;
+ return out;
+}
+#endif // i_no_clone
+
+#if defined _i_has_eq || defined _i_has_cmp
+STC_DEF bool
+_cx_MEMB(_eq)(const _cx_Self* self, const _cx_Self* other) {
+ if (_cx_MEMB(_size)(self) != _cx_MEMB(_size)(other)) return false;
+ for (_cx_iter i = _cx_MEMB(_begin)(self), j = _cx_MEMB(_begin)(other);
+ i.ref; _cx_MEMB(_next)(&i), _cx_MEMB(_next)(&j))
+ {
+ const _cx_raw _rx = i_keyto(i.ref), _ry = i_keyto(j.ref);
+ if (!(i_eq((&_rx), (&_ry)))) return false;
+ }
+ return true;
+}
+#endif
diff --git a/include/stc/priv/altnames.h b/include/stc/priv/linkage.h
index 723b6a66..7f63f5f1 100644
--- a/include/stc/priv/altnames.h
+++ b/include/stc/priv/linkage.h
@@ -20,15 +20,21 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#define c_FORLIST c_forlist
-#define c_FORRANGE c_forrange
-#define c_FOREACH c_foreach
-#define c_FORPAIR c_forpair
-#define c_FORFILTER c_forfilter
-#define c_FORMATCH c_formatch
-#define c_FORTOKEN c_fortoken
-#define c_FORTOKEN_SV c_fortoken_sv
-#define c_AUTO c_auto
-#define c_WITH c_with
-#define c_SCOPE c_scope
-#define c_DEFER c_defer
+#undef STC_API
+#undef STC_DEF
+
+#ifdef i_extern // [deprecated]
+# define i_import
+#endif
+#if !defined(i_static) && !defined(STC_STATIC) && (defined(i_header) || defined(STC_HEADER) || \
+ defined(i_implement) || defined(STC_IMPLEMENT))
+ #define STC_API extern
+ #define STC_DEF
+#else
+ #define i_static
+ #define STC_API static inline
+ #define STC_DEF static inline
+#endif
+#if defined(STC_IMPLEMENT) || defined(i_import)
+ #define i_implement
+#endif
diff --git a/include/stc/priv/raii.h b/include/stc/priv/raii.h
deleted file mode 100644
index bb41e0d1..00000000
--- a/include/stc/priv/raii.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#define c_defer(...) \
- for (int _i = 1; _i; _i = 0, __VA_ARGS__)
-
-#define c_with(...) c_MACRO_OVERLOAD(c_with, __VA_ARGS__)
-#define c_with_2(declvar, drop) \
- for (declvar, *_i, **_ip = &_i; _ip; _ip = 0, drop)
-#define c_with_3(declvar, pred, drop) \
- for (declvar, *_i, **_ip = &_i; _ip && (pred); _ip = 0, drop)
-
-#define c_scope(...) c_MACRO_OVERLOAD(c_scope, __VA_ARGS__)
-#define c_scope_2(init, drop) \
- for (int _i = (init, 1); _i; _i = 0, drop)
-#define c_scope_3(init, pred, drop) \
- for (int _i = (init, 1); _i && (pred); _i = 0, drop)
-
-#define c_auto(...) c_MACRO_OVERLOAD(c_auto, __VA_ARGS__)
-#define c_auto_2(C, a) \
- c_with_2(C a = C##_init(), C##_drop(&a))
-#define c_auto_3(C, a, b) \
- c_with_2(c_EXPAND(C a = C##_init(), b = C##_init()), \
- (C##_drop(&b), C##_drop(&a)))
-#define c_auto_4(C, a, b, c) \
- c_with_2(c_EXPAND(C a = C##_init(), b = C##_init(), c = C##_init()), \
- (C##_drop(&c), C##_drop(&b), C##_drop(&a)))
-#define c_auto_5(C, a, b, c, d) \
- c_with_2(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)))
diff --git a/include/stc/priv/template.h b/include/stc/priv/template.h
index 16ef51af..38097a35 100644
--- a/include/stc/priv/template.h
+++ b/include/stc/priv/template.h
@@ -20,34 +20,28 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-#ifdef _i_template
- #error template.h already included
-#endif
+#ifndef _i_template
#define _i_template
#ifndef STC_TEMPLATE_H_INCLUDED
#define STC_TEMPLATE_H_INCLUDED
- #define _cx_self i_type
- #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)
- #define _cx_key _cx_memb(_key)
- #define _cx_mapped _cx_memb(_mapped)
- #define _cx_raw _cx_memb(_raw)
- #define _cx_keyraw _cx_memb(_keyraw)
- #define _cx_iter _cx_memb(_iter)
- #define _cx_result _cx_memb(_result)
- #define _cx_node _cx_memb(_node)
+ #define _cx_Self i_type
+ #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)
+ #define _cx_key _cx_MEMB(_key)
+ #define _cx_mapped _cx_MEMB(_mapped)
+ #define _cx_raw _cx_MEMB(_raw)
+ #define _cx_keyraw _cx_MEMB(_keyraw)
+ #define _cx_iter _cx_MEMB(_iter)
+ #define _cx_result _cx_MEMB(_result)
+ #define _cx_node _cx_MEMB(_node)
#endif
#ifndef i_type
#define i_type c_PASTE(_i_prefix, i_tag)
#endif
-#ifndef i_ssize
- #define i_ssize intptr_t
-#endif
-
#ifndef i_allocator
#define i_allocator c
#endif
@@ -99,23 +93,22 @@
#if c_option(c_is_forward)
#define i_is_forward
#endif
-#if c_option(c_no_cmp)
- #define i_no_cmp
-#endif
#if c_option(c_no_hash)
#define i_no_hash
#endif
#if c_option(c_no_emplace)
#define i_no_emplace
#endif
-#ifdef i_eq
- #define _i_has_eq
+#if c_option(c_use_cmp) || defined _i_ismap || defined _i_isset || defined _i_ispque
+ #define i_use_cmp
+#endif
+#if c_option(c_no_clone) || defined _i_carc
+ #define i_no_clone
#endif
#if defined i_key_str
#define i_keyclass cstr
- #define i_rawclass crawstr
- #define i_keyfrom cstr_from
+ #define i_rawclass ccharptr
#ifndef i_tag
#define i_tag str
#endif
@@ -131,7 +124,7 @@
#elif defined i_keyboxed
#define i_keyclass i_keyboxed
#define i_rawclass c_PASTE(i_keyboxed, _raw)
- #ifndef i_no_cmp
+ #if defined i_use_cmp
#define i_eq c_PASTE(i_keyboxed, _raw_eq)
#endif
#endif
@@ -142,56 +135,68 @@
#define i_rawclass i_key
#endif
-#ifdef i_keyclass
+#if defined i_keyclass
#define i_key i_keyclass
#ifndef i_keyclone
#define i_keyclone c_PASTE(i_key, _clone)
#endif
- #if !defined i_keyto && defined i_keyraw
- #define i_keyto c_PASTE(i_key, _toraw)
+ #ifndef i_keydrop
+ #define i_keydrop c_PASTE(i_key, _drop)
#endif
#if !defined i_keyfrom && defined i_keyraw
#define i_keyfrom c_PASTE(i_key, _from)
#endif
- #ifndef i_keydrop
- #define i_keydrop c_PASTE(i_key, _drop)
+ #if !defined i_keyto && defined i_keyraw
+ #define i_keyto c_PASTE(i_key, _toraw)
+ #endif
+ #if !defined i_keyraw && (defined i_cmp || defined i_less || defined i_eq || defined i_hash)
+ #define i_use_cmp
#endif
#endif
-#ifdef i_rawclass
- #if !defined i_cmp && !defined i_no_cmp
+#if defined i_rawclass && defined i_use_cmp
+ #if !(defined i_cmp || defined i_less)
#define i_cmp c_PASTE(i_keyraw, _cmp)
#endif
- #if !defined i_hash && !defined i_no_hash
+ #if !(defined i_hash || defined i_no_hash)
#define i_hash c_PASTE(i_keyraw, _hash)
#endif
#endif
+#if defined i_cmp || defined i_less || defined i_use_cmp
+ #define _i_has_cmp
+#endif
+#if defined i_eq || defined i_use_cmp
+ #define _i_has_eq
+#endif
+#if !(defined i_hash || defined i_no_hash)
+ #define i_hash c_default_hash
+#endif
+
#if !defined i_key
#error "No i_key or i_val defined"
#elif defined i_keyraw ^ defined i_keyto
- #error "Both i_keyraw/valraw and i_keyto/valto must be defined, if any"
-#elif defined i_keyfrom && !defined i_keyraw
- #error "i_keyfrom/valfrom defined without i_keyraw/valraw"
+ #error "Both i_keyraw/i_valraw and i_keyto/i_valto must be defined, if any"
+#elif !defined i_no_clone && (defined i_keyclone ^ defined i_keydrop)
+ #error "Both i_keyclone/i_valclone and i_keydrop/i_valdrop must be defined, if any (unless i_no_clone defined)."
#elif defined i_from || defined i_drop
#error "i_from / i_drop not supported. Define i_keyfrom/i_valfrom and/or i_keydrop/i_valdrop instead"
+#elif defined i_keyraw && defined _i_ishash && !(defined i_hash && (defined _i_has_cmp || defined i_eq))
+ #error "For cmap/cset, both i_hash and i_eq (or i_less or i_cmp) must be defined when i_keyraw is defined."
+#elif defined i_keyraw && defined i_use_cmp && !defined _i_has_cmp
+ #error "For csmap/csset/cpque, i_cmp or i_less must be defined when i_keyraw is defined."
#endif
#ifndef i_tag
#define i_tag i_key
#endif
-#if c_option(c_no_clone)
- #define i_no_clone
-#elif !(defined i_keyclone || defined i_no_clone) && (defined i_keydrop || defined i_keyraw)
- #error i_keyclone/valclone should be defined when i_keydrop/valdrop or i_keyraw/valraw is defined
-#endif
#ifndef i_keyraw
#define i_keyraw i_key
#endif
#ifndef i_keyfrom
#define i_keyfrom c_default_clone
#else
- #define _i_has_from
+ #define i_has_emplace
#endif
#ifndef i_keyto
#define i_keyto c_default_toraw
@@ -204,32 +209,27 @@
#endif
// i_eq, i_less, i_cmp
-#if !defined i_eq && (defined i_cmp || defined i_less)
+#if !defined i_eq && defined i_cmp
#define i_eq(x, y) !(i_cmp(x, y))
#elif !defined i_eq
- #define i_eq c_default_eq
+ #define i_eq(x, y) *x == *y
#endif
-#if defined i_less && defined i_cmp
- #error "Only one of i_less and i_cmp may be defined"
-#elif !defined i_less && !defined i_cmp
- #define i_less c_default_less
-#elif !defined i_less
+#if defined i_cmp && defined i_less
+ #error "Only one of i_cmp and i_less may be defined"
+#elif defined i_cmp
#define i_less(x, y) (i_cmp(x, y)) < 0
+#elif !defined i_less
+ #define i_less(x, y) *x < *y
#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
-
#if defined _i_ismap // ---- process cmap/csmap value i_val, ... ----
#ifdef i_val_str
#define i_valclass cstr
- #define i_valraw crawstr
- #define i_valfrom cstr_from
+ #define i_valraw const char*
#elif defined i_val_ssv
#define i_valclass cstr
#define i_valraw csview
@@ -245,31 +245,32 @@
#ifndef i_valclone
#define i_valclone c_PASTE(i_val, _clone)
#endif
- #if !defined i_valto && defined i_valraw
- #define i_valto c_PASTE(i_val, _toraw)
+ #ifndef i_valdrop
+ #define i_valdrop c_PASTE(i_val, _drop)
#endif
#if !defined i_valfrom && defined i_valraw
#define i_valfrom c_PASTE(i_val, _from)
#endif
- #ifndef i_valdrop
- #define i_valdrop c_PASTE(i_val, _drop)
+ #if !defined i_valto && defined i_valraw
+ #define i_valto c_PASTE(i_val, _toraw)
#endif
#endif
#ifndef i_val
#error "i_val* must be defined for maps"
+#elif defined i_valraw ^ defined i_valto
+ #error "Both i_valraw and i_valto must be defined, if any"
+#elif !defined i_no_clone && (defined i_valclone ^ defined i_valdrop)
+ #error "Both i_valclone and i_valdrop must be defined, if any"
#endif
-#if !(defined i_valclone || defined i_no_clone) && (defined i_valdrop || defined i_valraw)
- #error i_valclone should be defined when i_valdrop or i_valraw is defined
-#endif
#ifndef i_valraw
#define i_valraw i_val
#endif
#ifndef i_valfrom
#define i_valfrom c_default_clone
#else
- #define _i_has_from
+ #define i_has_emplace
#endif
#ifndef i_valto
#define i_valto c_default_toraw
@@ -289,6 +290,7 @@
#ifndef i_valraw
#define i_valraw i_keyraw
#endif
-#ifndef _i_has_from
+#ifndef i_has_emplace
#define i_no_emplace
#endif
+#endif
diff --git a/include/stc/priv/template2.h b/include/stc/priv/template2.h
index 27c6a890..44254601 100644
--- a/include/stc/priv/template2.h
+++ b/include/stc/priv/template2.h
@@ -20,6 +20,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
+#ifdef i_more
+#undef i_more
+#else
#undef i_type
#undef i_tag
#undef i_imp
@@ -30,7 +33,6 @@
#undef i_hash
#undef i_rawclass
#undef i_capacity
-#undef i_ssize
#undef i_val
#undef i_val_str
@@ -57,7 +59,7 @@
#undef i_header
#undef i_implement
#undef i_static
-#undef i_extern
+#undef i_import
#undef i_allocator
#undef i_malloc
@@ -65,14 +67,16 @@
#undef i_realloc
#undef i_free
-#undef i_no_cmp
+#undef i_use_cmp
#undef i_no_hash
#undef i_no_clone
#undef i_no_emplace
#undef i_is_forward
+#undef i_has_emplace
+#undef _i_has_cmp
+#undef _i_has_eq
#undef _i_prefix
#undef _i_expandby
-#undef _i_has_from
-#undef _i_has_eq
#undef _i_template
+#endif