From 89de800ff2e0a8389359a8a7a2684edaae8ce742 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Sat, 31 Dec 2022 00:23:59 +0100 Subject: More file restructure. --- misc/archived/carr2.h | 152 ++++++++++++++ misc/archived/carr3.h | 157 ++++++++++++++ misc/archived/csmap.h | 512 +++++++++++++++++++++++++++++++++++++++++++++ misc/archived/cstr.h | 384 ++++++++++++++++++++++++++++++++++ misc/archived/new_arr.c | 57 +++++ misc/include/old/carr2.h | 152 -------------- misc/include/old/carr3.h | 157 -------------- misc/include/old/csmap.h | 512 --------------------------------------------- misc/include/old/cstr.h | 384 ---------------------------------- misc/include/old/new_arr.c | 57 ----- 10 files changed, 1262 insertions(+), 1262 deletions(-) create mode 100644 misc/archived/carr2.h create mode 100644 misc/archived/carr3.h create mode 100644 misc/archived/csmap.h create mode 100644 misc/archived/cstr.h create mode 100644 misc/archived/new_arr.c delete mode 100644 misc/include/old/carr2.h delete mode 100644 misc/include/old/carr3.h delete mode 100644 misc/include/old/csmap.h delete mode 100644 misc/include/old/cstr.h delete mode 100644 misc/include/old/new_arr.c diff --git a/misc/archived/carr2.h b/misc/archived/carr2.h new file mode 100644 index 00000000..aebaec81 --- /dev/null +++ b/misc/archived/carr2.h @@ -0,0 +1,152 @@ +/* MIT License + * + * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include + +#ifndef CARR2_H_INCLUDED +#define CARR2_H_INCLUDED +#include +#include +#endif +/* +// carr2- 2D dynamic array in one memory block with easy indexing. +#define i_key int +#include +#include + +int main() { + int w = 7, h = 5; + 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) + dat[i] = i; + + for (int x = 0; x < image.xdim; ++x) + for (int y = 0; y < image.ydim; ++y) + printf(" %d", image.data[x][y]); + puts("\n"); + + c_foreach (i, carr2_int, image) + printf(" %d", *i.ref); + puts(""); + } +} +*/ + +#ifndef _i_prefix +#define _i_prefix carr2_ +#endif +#include +#if !c_option(c_is_forward) +_cx_deftypes(_c_carr2_types, _cx_self, i_key); +#endif + +STC_API _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, i_key null); +STC_API _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, _cx_value* storage); +STC_API _cx_value* _cx_memb(_release)(_cx_self* self); +STC_API void _cx_memb(_drop)(_cx_self* self); +#if !defined i_no_clone +STC_API _cx_self _cx_memb(_clone)(_cx_self src); +STC_API void _cx_memb(_copy)(_cx_self *self, const _cx_self* other); +#endif + +STC_INLINE _cx_self _cx_memb(_new_uninit)(size_t xdim, size_t ydim) { + return _cx_memb(_with_data)(xdim, ydim, c_alloc_n(_cx_value, xdim*ydim)); +} +STC_INLINE size_t _cx_memb(_size)(const _cx_self* self) + { return self->xdim*self->ydim; } + +STC_INLINE _cx_value *_cx_memb(_data)(_cx_self* self) + { return *self->data; } + +STC_INLINE const _cx_value *_cx_memb(_at)(const _cx_self* self, size_t x, size_t y) { + assert(x < self->xdim && y < self->ydim); + return *self->data + self->ydim*x + y; +} + +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) { + size_t n = self->xdim*self->ydim; + return c_INIT(_cx_iter){n ? *self->data : NULL, *self->data + n}; +} + +STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) + { return c_INIT(_cx_iter){NULL, *self->data + self->xdim*self->ydim}; } + +STC_INLINE void _cx_memb(_next)(_cx_iter* it) + { if (++it->ref == it->end) it->ref = NULL; } + +/* -------------------------- IMPLEMENTATION ------------------------- */ +#if defined(i_implement) + +STC_DEF _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, _cx_value* block) { + _cx_self _arr = {c_alloc_n(_cx_value*, xdim), xdim, ydim}; + for (size_t x = 0; x < xdim; ++x, block += ydim) + _arr.data[x] = block; + return _arr; +} + +STC_DEF _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, i_key null) { + _cx_self _arr = _cx_memb(_new_uninit)(xdim, ydim); + for (_cx_value* p = _arr.data[0], *e = p + xdim*ydim; p != e; ++p) + *p = null; + return _arr; +} + +#if !defined i_no_clone + +STC_DEF _cx_self _cx_memb(_clone)(_cx_self src) { + _cx_self _arr = _cx_memb(_new_uninit)(src.xdim, src.ydim); + for (_cx_value* p = _arr.data[0], *q = src.data[0], *e = p + _cx_memb(_size)(&src); p != e; ++p, ++q) + *p = i_keyclone((*q)); + return _arr; +} + +STC_DEF 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 + +STC_DEF _cx_value *_cx_memb(_release)(_cx_self* self) { + _cx_value *values = self->data[0]; + c_free(self->data); + self->data = NULL; + return values; +} + +STC_DEF void _cx_memb(_drop)(_cx_self* self) { + if (!self->data) return; + for (_cx_value* p = self->data[0], *q = p + _cx_memb(_size)(self); p != q; ) { + --q; i_keydrop(q); + } + c_free(self->data[0]); /* values */ + c_free(self->data); /* pointers */ +} + +#endif +#include diff --git a/misc/archived/carr3.h b/misc/archived/carr3.h new file mode 100644 index 00000000..a0148992 --- /dev/null +++ b/misc/archived/carr3.h @@ -0,0 +1,157 @@ +/* MIT License + * + * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include + +#ifndef CARR3_H_INCLUDED +#define CARR3_H_INCLUDED +#include +#include +#endif +/* +// carr3 - 3D dynamic array in one memory block with easy indexing. +#define i_key int +#include +#include + +int main() { + int w = 7, h = 5, d = 3; + 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) + dat[i] = i; + + for (int x = 0; x < image.xdim; ++x) + for (int y = 0; y < image.ydim; ++y) + for (int z = 0; z < image.zdim; ++z) + printf(" %d", image.data[x][y][z]); + puts("\n"); + + c_foreach (i, carr3_int, image) + printf(" %d", *i.ref); + puts(""); + } +} +*/ + +#ifndef _i_prefix +#define _i_prefix carr3_ +#endif +#include + +#if !c_option(c_is_forward) +_cx_deftypes(_c_carr3_types, _cx_self, i_key); +#endif + +STC_API _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, size_t zdim, i_key null); +STC_API _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, size_t zdim, _cx_value* storage); +STC_API _cx_value* _cx_memb(_release)(_cx_self* self); +STC_API void _cx_memb(_drop)(_cx_self* self); +#if !defined i_no_clone +STC_API _cx_self _cx_memb(_clone)(_cx_self src); +STC_API void _cx_memb(_copy)(_cx_self *self, const _cx_self* other); +#endif + +STC_INLINE _cx_self _cx_memb(_new_uninit)(size_t xdim, size_t ydim, size_t zdim) { + return _cx_memb(_with_data)(xdim, ydim, zdim, c_alloc_n(_cx_value, xdim*ydim*zdim)); +} + +STC_INLINE size_t _cx_memb(_size)(const _cx_self* self) + { return self->xdim*self->ydim*self->zdim; } + +STC_INLINE _cx_value* _cx_memb(_data)(_cx_self* self) + { return **self->data; } + +STC_INLINE const _cx_value* _cx_memb(_at)(const _cx_self* self, size_t x, size_t y, size_t z) { + assert(x < self->xdim && y < self->ydim && z < self->zdim); + return **self->data + self->zdim*(self->ydim*x + y) + z; +} + +STC_INLINE size_t _cx_memb(_idx)(const _cx_self* self, size_t x, size_t y, size_t z) { + return self->zdim*(self->ydim*x + y) + z; +} + + +STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { + size_t n = _cx_memb(_size)(self); + return c_INIT(_cx_iter){n ? **self->data : NULL, **self->data + n}; +} + +STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) + { return c_INIT(_cx_iter){NULL, **self->data + _cx_memb(_size)(self)}; } + +STC_INLINE void _cx_memb(_next)(_cx_iter* it) + { if (++it->ref == it->end) it->ref = NULL; } + +/* -------------------------- IMPLEMENTATION ------------------------- */ +#if defined(i_implement) + +STC_DEF _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, size_t zdim, _cx_value* block) { + _cx_self _arr = {c_alloc_n(_cx_value**, xdim*(ydim + 1)), xdim, ydim, zdim}; + _cx_value** p = (_cx_value**) &_arr.data[xdim]; + for (size_t x = 0, y; x < xdim; ++x, p += ydim) + for (y = 0, _arr.data[x] = p; y < ydim; ++y, block += zdim) + p[y] = block; + return _arr; +} + +STC_DEF _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, size_t zdim, i_key null) { + _cx_self _arr = _cx_memb(_new_uninit)(xdim, ydim, zdim); + for (_cx_value* p = **_arr.data, *e = p + xdim*ydim*zdim; p != e; ++p) + *p = null; + return _arr; +} + +#if !defined i_no_clone + +STC_DEF _cx_self _cx_memb(_clone)(_cx_self src) { + _cx_self _arr = _cx_memb(_new_uninit)(src.xdim, src.ydim, src.zdim); + for (_cx_value* p = **_arr.data, *q = **src.data, *e = p + _cx_memb(_size)(&src); p != e; ++p, ++q) + *p = i_keyclone((*q)); + return _arr; +} + +STC_DEF 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 + +STC_DEF _cx_value* _cx_memb(_release)(_cx_self* self) { + _cx_value *values = self->data[0][0]; + c_free(self->data); + self->data = NULL; + return values; +} + +STC_DEF void _cx_memb(_drop)(_cx_self* self) { + if (!self->data) return; + for (_cx_value* p = **self->data, *q = p + _cx_memb(_size)(self); p != q; ) { + --q; i_keydrop(q); + } + c_free(self->data[0][0]); /* data */ + c_free(self->data); /* pointers */ +} + +#endif +#include diff --git a/misc/archived/csmap.h b/misc/archived/csmap.h new file mode 100644 index 00000000..4b4e764c --- /dev/null +++ b/misc/archived/csmap.h @@ -0,0 +1,512 @@ +/* MIT License + * + * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// Sorted/Ordered set and map - implemented as an AA-tree. +/* +#include +#include + +#define i_tag sx // Sorted map +#define i_key_str +#define i_val double +#include + +int main(void) { + 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); + csmap_sx_emplace(&m, "Testing three", 123.4); + + csmap_sx_value *v = csmap_sx_get(&m, "Testing five"); // NULL + double num = *csmap_sx_at(&m, "Testing one"); + csmap_sx_emplace_or_assign(&m, "Testing three", 1000.0); // update + csmap_sx_erase(&m, "Testing two"); + + c_foreach (i, csmap_sx, m) + printf("map %s: %g\n", cstr_str(&i.ref->first), i.ref->second); + } +} +*/ +#include + +#ifndef CSMAP_H_INCLUDED +#define STC_CSMAP_V1 1 +#include +#include +#include +#endif // CSMAP_H_INCLUDED + +#ifndef _i_prefix +#define _i_prefix csmap_ +#endif +#ifdef _i_isset + #define _i_MAP_ONLY c_false + #define _i_SET_ONLY c_true + #define _i_keyref(vp) (vp) +#else + #define _i_ismap + #define _i_MAP_ONLY c_true + #define _i_SET_ONLY c_false + #define _i_keyref(vp) (&(vp)->first) +#endif +#include + +#if !c_option(c_is_forward) +_cx_deftypes(_c_aatree_types, _cx_self, i_key, i_val, i_size, _i_MAP_ONLY, _i_SET_ONLY); +#endif + +_i_MAP_ONLY( struct _cx_value { + _cx_key first; + _cx_mapped second; +}; ) +struct _cx_node { + struct _cx_node *link[2]; + uint8_t level; + _cx_value value; +}; + +typedef i_keyraw _cx_rawkey; +typedef i_valraw _cx_memb(_rawmapped); +typedef _i_SET_ONLY( i_keyraw ) + _i_MAP_ONLY( struct { i_keyraw first; i_valraw second; } ) + _cx_raw; + +#if !defined i_no_clone +STC_API _cx_self _cx_memb(_clone)(_cx_self cx); +#if !defined i_no_emplace +STC_API _cx_result _cx_memb(_emplace)(_cx_self* self, i_keyraw rkey _i_MAP_ONLY(, i_valraw rmapped)); +#endif // !i_no_emplace +#endif // !i_no_clone +STC_API _cx_self _cx_memb(_init)(void); +STC_API _cx_result _cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped)); +STC_API _cx_result _cx_memb(_push)(_cx_self* self, _cx_value _val); +STC_API void _cx_memb(_drop)(_cx_self* self); +STC_API _cx_value* _cx_memb(_find_it)(const _cx_self* self, i_keyraw rkey, _cx_iter* out); +STC_API _cx_iter _cx_memb(_lower_bound)(const _cx_self* self, i_keyraw rkey); +STC_API _cx_value* _cx_memb(_front)(const _cx_self* self); +STC_API _cx_value* _cx_memb(_back)(const _cx_self* self); +STC_API int _cx_memb(_erase)(_cx_self* self, i_keyraw rkey); +STC_API _cx_iter _cx_memb(_erase_at)(_cx_self* self, _cx_iter it); +STC_API _cx_iter _cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2); +STC_API void _cx_memb(_next)(_cx_iter* it); + +STC_INLINE bool _cx_memb(_empty)(_cx_self cx) { return cx.size == 0; } +STC_INLINE size_t _cx_memb(_size)(_cx_self cx) { return cx.size; } +STC_INLINE void _cx_memb(_swap)(_cx_self* a, _cx_self* b) { c_swap(_cx_self, *a, *b); } +STC_INLINE _cx_iter _cx_memb(_find)(const _cx_self* self, i_keyraw rkey) + { _cx_iter it; _cx_memb(_find_it)(self, rkey, &it); return it; } +STC_INLINE bool _cx_memb(_contains)(const _cx_self* self, i_keyraw rkey) + { _cx_iter it; return _cx_memb(_find_it)(self, rkey, &it) != NULL; } +STC_INLINE const _cx_value* _cx_memb(_get)(const _cx_self* self, i_keyraw rkey) + { _cx_iter it; return _cx_memb(_find_it)(self, rkey, &it); } +STC_INLINE _cx_value* _cx_memb(_get_mut)(_cx_self* self, i_keyraw rkey) + { _cx_iter it; return _cx_memb(_find_it)(self, rkey, &it); } + +STC_INLINE void +_cx_memb(_clear)(_cx_self* self) + { _cx_memb(_drop)(self); *self = _cx_memb(_init)(); } + +STC_INLINE _cx_raw +_cx_memb(_value_toraw)(_cx_value* val) { + return _i_SET_ONLY( i_keyto(val) ) + _i_MAP_ONLY( c_INIT(_cx_raw){i_keyto((&val->first)), + i_valto((&val->second))} ); +} + +STC_INLINE int +_cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y) { + _cx_rawkey rx = i_keyto(_i_keyref(x)), ry = i_keyto(_i_keyref(y)); + return i_cmp((&rx), (&ry)); +} + +STC_INLINE void +_cx_memb(_value_drop)(_cx_value* val) { + i_keydrop(_i_keyref(val)); + _i_MAP_ONLY( i_valdrop((&val->second)); ) +} + +#if !defined i_no_clone +STC_INLINE _cx_value +_cx_memb(_value_clone)(_cx_value _val) { + *_i_keyref(&_val) = i_keyclone((*_i_keyref(&_val))); + _i_MAP_ONLY( _val.second = i_valclone(_val.second); ) + return _val; +} + +STC_INLINE void +_cx_memb(_copy)(_cx_self *self, const _cx_self* other) { + if (self->root == other->root) + return; + _cx_memb(_drop)(self); + *self = _cx_memb(_clone)(*other); +} +#endif // !i_no_clone + +#ifndef _i_isset + #if !defined i_no_clone && !defined i_no_emplace + STC_API _cx_result _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped); + #endif + STC_API _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped); + + STC_INLINE const _cx_mapped* + _cx_memb(_at)(const _cx_self* self, i_keyraw rkey) + { _cx_iter it; return &_cx_memb(_find_it)(self, rkey, &it)->second; } + STC_INLINE _cx_mapped* + _cx_memb(_at_mut)(_cx_self* self, i_keyraw rkey) + { _cx_iter it; return &_cx_memb(_find_it)(self, rkey, &it)->second; } +#endif // !_i_isset + +STC_INLINE _cx_iter +_cx_memb(_begin)(const _cx_self* self) { + _cx_iter it; + it.ref = NULL, it._top = 0, it._tn = self->root; + _cx_memb(_next)(&it); + return it; +} + +STC_INLINE _cx_iter +_cx_memb(_end)(const _cx_self* self) { + (void)self; + _cx_iter it; it.ref = NULL, it._top = 0, it._tn = NULL; + return it; +} + +STC_INLINE _cx_iter +_cx_memb(_advance)(_cx_iter it, size_t n) { + while (n-- && it.ref) + _cx_memb(_next)(&it); + return it; +} + +/* -------------------------- IMPLEMENTATION ------------------------- */ +#if defined(i_implement) + +#ifndef CSMAP_H_INCLUDED +static struct { void *link[2]; uint8_t level; } +_csmap_sentinel = {{&_csmap_sentinel, &_csmap_sentinel}, 0}; +#endif + +static _cx_result _cx_memb(_insert_entry_)(_cx_self* self, i_keyraw rkey); + +STC_DEF _cx_self +_cx_memb(_init)(void) { + _cx_self cx = {(_cx_node *)&_csmap_sentinel, 0}; + return cx; +} + +STC_DEF _cx_value* +_cx_memb(_front)(const _cx_self* self) { + _cx_node *tn = self->root; + while (tn->link[0]->level) + tn = tn->link[0]; + return &tn->value; +} + +STC_DEF _cx_value* +_cx_memb(_back)(const _cx_self* self) { + _cx_node *tn = self->root; + while (tn->link[1]->level) + tn = tn->link[1]; + return &tn->value; +} + +STC_DEF _cx_result +_cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped)) { + _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto((&key))); + if (res.inserted) + { *_i_keyref(res.ref) = key; _i_MAP_ONLY( res.ref->second = mapped; )} + else + { i_keydrop((&key)); _i_MAP_ONLY( i_valdrop((&mapped)); )} + return res; +} + +STC_DEF _cx_result +_cx_memb(_push)(_cx_self* self, _cx_value _val) { + _cx_result _res = _cx_memb(_insert_entry_)(self, i_keyto(_i_keyref(&_val))); + if (_res.inserted) + *_res.ref = _val; + else + _cx_memb(_value_drop)(&_val); + return _res; +} + +#ifndef _i_isset + STC_DEF _cx_result + _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped) { + _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto((&key))); + if (res.inserted) + res.ref->first = key; + else + { i_keydrop((&key)); i_valdrop((&res.ref->second)); } + res.ref->second = mapped; + return res; + } + #if !defined i_no_clone && !defined i_no_emplace + STC_DEF _cx_result + _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped) { + _cx_result res = _cx_memb(_insert_entry_)(self, rkey); + if (res.inserted) + res.ref->first = i_keyfrom(rkey); + else + { i_valdrop((&res.ref->second)); } + res.ref->second = i_valfrom(rmapped); + return res; + } + #endif // !i_no_clone && !i_no_emplace +#endif // !_i_isset + +STC_DEF _cx_value* +_cx_memb(_find_it)(const _cx_self* self, _cx_rawkey rkey, _cx_iter* out) { + _cx_node *tn = self->root; + out->_top = 0; + while (tn->level) { + int c; _cx_rawkey raw = i_keyto(_i_keyref(&tn->value)); + if ((c = i_cmp((&raw), (&rkey))) < 0) + tn = tn->link[1]; + else if (c > 0) + { out->_st[out->_top++] = tn; tn = tn->link[0]; } + else + { out->_tn = tn->link[1]; return (out->ref = &tn->value); } + } + return (out->ref = NULL); +} + +STC_DEF _cx_iter +_cx_memb(_lower_bound)(const _cx_self* self, i_keyraw rkey) { + _cx_iter it; + _cx_memb(_find_it)(self, rkey, &it); + if (!it.ref && it._top) { + _cx_node *tn = it._st[--it._top]; + it._tn = tn->link[1]; + it.ref = &tn->value; + } + return it; +} + +STC_DEF void +_cx_memb(_next)(_cx_iter *it) { + _cx_node *tn = it->_tn; + if (it->_top || tn->level) { + while (tn->level) { + it->_st[it->_top++] = tn; + tn = tn->link[0]; + } + tn = it->_st[--it->_top]; + it->_tn = tn->link[1]; + it->ref = &tn->value; + } else + it->ref = NULL; +} + +static _cx_node * +_cx_memb(_skew_)(_cx_node *tn) { + if (tn && tn->link[0]->level == tn->level && tn->level) { + _cx_node *tmp = tn->link[0]; + tn->link[0] = tmp->link[1]; + tmp->link[1] = tn; + tn = tmp; + } + return tn; +} + +static _cx_node * +_cx_memb(_split_)(_cx_node *tn) { + if (tn->link[1]->link[1]->level == tn->level && tn->level) { + _cx_node *tmp = tn->link[1]; + tn->link[1] = tmp->link[0]; + tmp->link[0] = tn; + tn = tmp; + ++tn->level; + } + return tn; +} + +static _cx_node* +_cx_memb(_insert_entry_i_)(_cx_node* tn, const _cx_rawkey* rkey, _cx_result* res) { + _cx_node *up[64], *tx = tn; + int c, top = 0, dir = 0; + while (tx->level) { + up[top++] = tx; + _cx_rawkey r = i_keyto(_i_keyref(&tx->value)); + if (!(c = (i_cmp((&r), rkey)))) + { res->ref = &tx->value; return tn; } + dir = (c < 0); + tx = tx->link[dir]; + } + tn = c_alloc(_cx_node); + tn->link[0] = tn->link[1] = (_cx_node*)&_csmap_sentinel; + tn->level = 1; + res->ref = &tn->value, res->inserted = true; + if (top == 0) + return tn; + up[top - 1]->link[dir] = tn; + while (top--) { + if (top) + dir = (up[top - 1]->link[1] == up[top]); + up[top] = _cx_memb(_skew_)(up[top]); + up[top] = _cx_memb(_split_)(up[top]); + if (top) + up[top - 1]->link[dir] = up[top]; + } + return up[0]; +} + +STC_DEF _cx_result +_cx_memb(_insert_entry_)(_cx_self* self, i_keyraw rkey) { + _cx_result res = {NULL}; + self->root = _cx_memb(_insert_entry_i_)(self->root, &rkey, &res); + self->size += res.inserted; + return res; +} + +static _cx_node* +_cx_memb(_erase_r_)(_cx_node *tn, const _cx_rawkey* rkey, int *erased) { + if (tn->level == 0) + return tn; + _cx_rawkey raw = i_keyto(_i_keyref(&tn->value)); + _cx_node *tx; int c = (i_cmp((&raw), rkey)); + if (c != 0) + tn->link[c < 0] = _cx_memb(_erase_r_)(tn->link[c < 0], rkey, erased); + else { + if (!*erased) + { _cx_memb(_value_drop)(&tn->value); *erased = 1; } + if (tn->link[0]->level && tn->link[1]->level) { + tx = tn->link[0]; + while (tx->link[1]->level) + tx = tx->link[1]; + tn->value = tx->value; + raw = i_keyto(_i_keyref(&tn->value)); + tn->link[0] = _cx_memb(_erase_r_)(tn->link[0], &raw, erased); + } else { /* unlink node */ + tx = tn; + tn = tn->link[tn->link[0]->level == 0]; + c_free(tx); + } + } + if (tn->link[0]->level < tn->level - 1 || tn->link[1]->level < tn->level - 1) { + if (tn->link[1]->level > --tn->level) + tn->link[1]->level = tn->level; + tn = _cx_memb(_skew_)(tn); + tx = tn->link[0] = _cx_memb(_skew_)(tn->link[0]); + tx->link[0] = _cx_memb(_skew_)(tx->link[0]); + tn = _cx_memb(_split_)(tn); + tn->link[0] = _cx_memb(_split_)(tn->link[0]); + } + return tn; +} + +STC_DEF int +_cx_memb(_erase)(_cx_self* self, i_keyraw rkey) { + int erased = 0; + self->root = _cx_memb(_erase_r_)(self->root, &rkey, &erased); + self->size -= erased; + return erased; +} + +STC_DEF _cx_iter +_cx_memb(_erase_at)(_cx_self* self, _cx_iter it) { + _cx_rawkey raw = i_keyto(_i_keyref(it.ref)), nxt; + _cx_memb(_next)(&it); + if (it.ref) + nxt = i_keyto(_i_keyref(it.ref)); + _cx_memb(_erase)(self, raw); + if (it.ref) + _cx_memb(_find_it)(self, nxt, &it); + return it; +} + +STC_DEF _cx_iter +_cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2) { + if (!it2.ref) { + while (it1.ref) + it1 = _cx_memb(_erase_at)(self, it1); + return it1; + } + _cx_key k1 = *_i_keyref(it1.ref), k2 = *_i_keyref(it2.ref); + _cx_rawkey r1 = i_keyto((&k1)); + for (;;) { + if (memcmp(&k1, &k2, sizeof k1) == 0) + return it1; + _cx_memb(_next)(&it1); + k1 = *_i_keyref(it1.ref); + _cx_memb(_erase)(self, r1); + r1 = i_keyto((&k1)); + _cx_memb(_find_it)(self, r1, &it1); + } +} + +#if !defined i_no_clone +static _cx_node* +_cx_memb(_clone_r_)(_cx_node *tn) { + if (! tn->level) + return tn; + _cx_node *cn = c_alloc(_cx_node); + cn->level = tn->level; + cn->value = _cx_memb(_value_clone)(tn->value); + cn->link[0] = _cx_memb(_clone_r_)(tn->link[0]); + cn->link[1] = _cx_memb(_clone_r_)(tn->link[1]); + return cn; +} + +STC_DEF _cx_self +_cx_memb(_clone)(_cx_self cx) { + return c_INIT(_cx_self){_cx_memb(_clone_r_)(cx.root), cx.size}; +} +#endif // !i_no_clone + +#if !defined i_no_emplace +STC_DEF _cx_result +_cx_memb(_emplace)(_cx_self* self, i_keyraw rkey _i_MAP_ONLY(, i_valraw rmapped)) { + _cx_result res = _cx_memb(_insert_entry_)(self, rkey); + if (res.inserted) { + *_i_keyref(res.ref) = i_keyfrom(rkey); + _i_MAP_ONLY(res.ref->second = i_valfrom(rmapped);) + } + return res; +} +#endif // i_no_emplace + +static void +_cx_memb(_drop_r_)(_cx_node* tn) { + if (tn->level != 0) { + _cx_memb(_drop_r_)(tn->link[0]); + _cx_memb(_drop_r_)(tn->link[1]); + _cx_memb(_value_drop)(&tn->value); + c_free(tn); + } +} + +STC_DEF void +_cx_memb(_drop)(_cx_self* self) { + _cx_memb(_drop_r_)(self->root); +} + +#endif // i_implement +#undef _i_isset +#undef _i_ismap +#undef _i_keyref +#undef _i_MAP_ONLY +#undef _i_SET_ONLY +#define CSMAP_H_INCLUDED +#include diff --git a/misc/archived/cstr.h b/misc/archived/cstr.h new file mode 100644 index 00000000..8de6c4b0 --- /dev/null +++ b/misc/archived/cstr.h @@ -0,0 +1,384 @@ +/* MIT License + * + * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef CSTR_H_INCLUDED +#define CSTR_H_INCLUDED + +#include +#include +#include /* malloc */ +#include +#include +#include /* vsnprintf */ +#include + +#define c_unchecked_container_of(ptr, type, member) \ + ((type*)((char*)(ptr) - offsetof(type, member))) + +typedef char cstr_value; +typedef struct { cstr_value* str; } cstr; +typedef struct { size_t size, cap; char chr[1]; } cstr_priv; +#define _cstr_p(self) c_unchecked_container_of((self)->str, cstr_priv, chr) +#ifdef i_static + static cstr_priv _cstr_nullrep = {0, 0, {0}}; + static const cstr cstr_NULL = {_cstr_nullrep.chr}; +#else + extern const cstr cstr_NULL; +#endif +/* optimal memory: based on malloc_usable_size() sequence: 24, 40, 56, ... */ +#define _cstr_opt_mem(cap) ((((offsetof(cstr_priv, chr) + (cap) + 8)>>4)<<4) + 8) +/* optimal string capacity: 7, 23, 39, ... */ +#define _cstr_opt_cap(cap) (_cstr_opt_mem(cap) - offsetof(cstr_priv, chr) - 1) + +STC_API cstr cstr_from_n(const char* str, size_t n); +STC_API cstr cstr_from_fmt(const char* fmt, ...); +STC_API char* cstr_reserve(cstr* self, size_t cap); +STC_API void cstr_resize(cstr* self, size_t len, char fill); +STC_API cstr* cstr_assign_n(cstr* self, const char* str, size_t n); +STC_API int cstr_printf(cstr* self, const char* fmt, ...); +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(cstr* self, size_t pos, size_t n); +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; } +STC_INLINE const char* cstr_str(const cstr* self) { return self->str; } +#define cstr_toraw(self) (self)->str +STC_INLINE csview cstr_sv(const cstr* self) + { return c_INIT(csview){self->str, _cstr_p(self)->size}; } +#define cstr_lit(literal) \ + cstr_from_n(literal, c_strlen_lit(literal)) +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(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) + { if (_cstr_p(self)->cap) c_free(_cstr_p(self)); } +STC_INLINE cstr cstr_clone(cstr s) + { return cstr_from_n(s.str, _cstr_p(&s)->size); } +STC_INLINE void cstr_clear(cstr* self) + { self->str[_cstr_p(self)->size = 0] = '\0'; } +STC_INLINE cstr* cstr_assign(cstr* self, const char* str) + { return cstr_assign_n(self, str, strlen(str)); } +STC_INLINE cstr* cstr_copy(cstr* self, cstr s) + { return cstr_assign_n(self, s.str, _cstr_p(&s)->size); } +STC_INLINE cstr* cstr_append(cstr* self, const char* str) + { return cstr_append_n(self, str, strlen(str)); } +STC_INLINE cstr* cstr_append_s(cstr* self, cstr s) + { return cstr_append_n(self, s.str, _cstr_p(&s)->size); } +STC_INLINE void cstr_push_back(cstr* self, char value) + { cstr_append_n(self, &value, 1); } +STC_INLINE void cstr_pop_back(cstr* self) + { self->str[ --_cstr_p(self)->size ] = '\0'; } +STC_INLINE void cstr_insert_n(cstr* self, const size_t pos, const char* str, const size_t n) + { cstr_replace_at_sv(self, pos, 0, c_SV(str, n)); } +STC_INLINE void cstr_insert(cstr* self, const size_t pos, const char* str) + { cstr_replace_at_sv(self, pos, 0, c_SV(str, strlen(str))); } +STC_INLINE void cstr_insert_s(cstr* self, const size_t pos, cstr s) + { cstr_replace_at_sv(self, pos, 0, c_SV(s.str, _cstr_p(&s)->size)); } +STC_INLINE void cstr_replace_at(cstr* self, const size_t pos, const size_t len, const char* str) + { cstr_replace_at_sv(self, pos, len, c_SV(str, strlen(str))); } +STC_INLINE void cstr_replace_s(cstr* self, const size_t pos, const size_t len, cstr s) + { cstr_replace_at_sv(self, pos, len, c_SV(s.str, _cstr_p(&s)->size)); } +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(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); } + +STC_INLINE cstr_buf cstr_buffer(cstr* s) { + cstr_priv* p = _cstr_p(s); + return c_INIT(cstr_buf){s->str, p->size, p->cap}; +} + +STC_INLINE cstr cstr_with_capacity(const size_t cap) { + cstr s = cstr_NULL; + cstr_reserve(&s, cap); + return s; +} + +STC_INLINE cstr cstr_with_size(const size_t len, const char fill) { + cstr s = cstr_NULL; + cstr_resize(&s, len, fill); + return s; +} + +STC_INLINE char* cstr_append_uninit(cstr *self, size_t n) { + 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; +} + +STC_INLINE cstr* cstr_take(cstr* self, cstr s) { + if (self->str != s.str && _cstr_p(self)->cap) + c_free(_cstr_p(self)); + self->str = s.str; + return self; +} + +STC_INLINE cstr cstr_move(cstr* self) { + cstr tmp = *self; + *self = cstr_NULL; + return tmp; +} + +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(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) { + int ret = 0; + while (nmax-- && (ret = tolower(*s1++) - tolower(*s2)) == 0 && *s2++) + ; + return ret; +} + +/* container adaptor functions: */ +#define cstr_cmp(xp, yp) strcmp((xp)->str, (yp)->str) + +STC_INLINE bool cstr_eq(const cstr* x, const cstr* y) { + size_t xs = _cstr_p(x)->size, ys = _cstr_p(y)->size; + return xs == ys && !memcmp(x->str, y->str, xs); +} +STC_INLINE uint64_t cstr_hash(const cstr *self) { + return cfasthash(self->str, _cstr_p(self)->size); +} + +STC_INLINE void cstr_replace_ex(cstr* self, const char* find, const char* repl, unsigned count) { + cstr_take(self, cstr_replace_sv(cstr_sv(self), c_SV(find, strlen(find)), + c_SV(repl, strlen(repl)), count)); +} +STC_INLINE void cstr_replace(cstr* self, const char* search, const char* repl) + { cstr_replace_ex(self, search, repl, ~0U); } + +/* -------------------------- IMPLEMENTATION ------------------------- */ +#if defined(i_implement) + +#ifndef i_static +static cstr_priv _cstr_nullrep = {0, 0, {0}}; +const cstr cstr_NULL = {_cstr_nullrep.chr}; +#endif + +STC_DEF char* +cstr_reserve(cstr* self, const size_t cap) { + cstr_priv *p = _cstr_p(self); + const size_t oldcap = p->cap; + if (cap > oldcap) { + p = (cstr_priv*) c_realloc(((oldcap != 0) & (p != &_cstr_nullrep)) ? p : NULL, _cstr_opt_mem(cap)); + if (!p) return NULL; + self->str = p->chr; + if (oldcap == 0) self->str[p->size = 0] = '\0'; + p->cap = _cstr_opt_cap(cap); + } + return self->str; +} + +STC_DEF void +cstr_resize(cstr* self, const size_t len, const char fill) { + const size_t n = _cstr_p(self)->size; + cstr_reserve(self, len); + if (len > n) memset(self->str + n, fill, len - n); + if (len | n) self->str[_cstr_p(self)->size = len] = '\0'; +} + +STC_DEF cstr +cstr_from_n(const char* str, const size_t n) { + if (n == 0) return cstr_NULL; + cstr_priv* prv = (cstr_priv*) c_malloc(_cstr_opt_mem(n)); + cstr s = {(char *) memcpy(prv->chr, str, n)}; + s.str[prv->size = n] = '\0'; + prv->cap = _cstr_opt_cap(n); + return s; +} + +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wdeprecated-declarations" +#elif defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable: 4996) +#endif + +STC_DEF int +cstr_vfmt(cstr* self, const char* fmt, va_list args) { + va_list args2; + va_copy(args2, args); + int len = vsnprintf(NULL, (size_t)0, fmt, args); + cstr_reserve(self, len); + vsprintf(self->str, fmt, args2); + va_end(args2); + return _cstr_p(self)->size = len; +} + +#if defined(__clang__) +# pragma clang diagnostic pop +#elif defined(_MSC_VER) +# pragma warning(pop) +#endif + +STC_DEF cstr +cstr_from_fmt(const char* fmt, ...) { + cstr ret = cstr_NULL; + va_list args; va_start(args, fmt); + cstr_vfmt(&ret, fmt, args); + va_end(args); + return ret; +} + +STC_DEF int +cstr_printf(cstr* self, const char* fmt, ...) { + cstr ret = cstr_NULL; + va_list args; + va_start(args, fmt); + int n = cstr_vfmt(&ret, fmt, args); + va_end(args); + cstr_drop(self); + *self = ret; + return n; +} + +STC_DEF cstr* +cstr_assign_n(cstr* self, const char* str, const size_t n) { + if (n || _cstr_p(self)->cap) { + cstr_reserve(self, n); + memmove(self->str, str, n); + self->str[_cstr_p(self)->size = n] = '\0'; + } + return self; +} + +STC_DEF cstr* +cstr_append_n(cstr* self, const char* str, const size_t n) { + if (n == 0) return self; + const size_t oldlen = _cstr_p(self)->size, newlen = oldlen + n; + if (newlen > _cstr_p(self)->cap) { + const size_t off = (size_t) (str - self->str); /* handle self append */ + cstr_reserve(self, (oldlen*3 >> 1) + n); + if (off <= oldlen) str = self->str + off; + } + memcpy(&self->str[oldlen], str, n); + self->str[_cstr_p(self)->size = newlen] = '\0'; + return self; +} + +STC_INLINE void _cstr_internal_move(cstr* self, const size_t pos1, const size_t pos2) { + if (pos1 == pos2) + return; + const size_t len = _cstr_p(self)->size, newlen = len + pos2 - pos1; + if (newlen > _cstr_p(self)->cap) + cstr_reserve(self, (len*3 >> 1) + pos2 - pos1); + memmove(&self->str[pos2], &self->str[pos1], len - pos1); + self->str[_cstr_p(self)->size = newlen] = '\0'; +} + +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); + if (len > sz - pos) len = sz - pos; + char buf[256], *xstr = repl.size > 256 ? c_malloc(repl.size) : buf; + memcpy(xstr, repl.str, repl.size); + _cstr_internal_move(self, pos + len, pos + repl.size); + memcpy(&self->str[pos], xstr, repl.size); + if (repl.size > 256) c_free(xstr); +} + +STC_DEF cstr +cstr_replace_sv(csview str, csview find, csview repl, unsigned count) { + cstr out = cstr_NULL; + size_t from = 0; char* res; + if (find.size) + while (count-- && (res = cstrnstrn(str.str + from, find.str, str.size - from, find.size))) { + const size_t pos = res - str.str; + cstr_append_n(&out, str.str + from, pos - from); + cstr_append_n(&out, repl.str, repl.size); + from = pos + find.size; + } + cstr_append_n(&out, str.str + from, str.size - from); + return out; +} + +STC_DEF void +cstr_erase(cstr* self, const size_t pos, size_t n) { + const size_t len = _cstr_p(self)->size; + if (n > len - pos) n = len - pos; + if (len) { + memmove(&self->str[pos], &self->str[pos + n], len - (pos + n)); + self->str[_cstr_p(self)->size -= n] = '\0'; + } +} + +STC_DEF bool +cstr_getdelim(cstr *self, const int delim, FILE *fp) { + size_t pos = 0, cap = _cstr_p(self)->cap; + char* d = self->str; + int c = fgetc(fp); + if (c == EOF) + return false; + for (;;) { + if (c == delim || c == EOF) { + if (cap) d[_cstr_p(self)->size = pos] = '\0'; + return true; + } + if (pos == cap) { + d = cstr_reserve(self, (cap*3 >> 1) + 16); + cap = cstr_capacity(*self); + } + d[pos++] = (char) c; + c = fgetc(fp); + } +} + +STC_DEF size_t +cstr_find(const cstr* self, const char* needle) { + char* res = strstr(self->str, needle); + return res ? res - self->str : c_NPOS; +} + +STC_DEF size_t +cstr_find_at(const cstr* self, const size_t pos, const char* needle) { + if (pos > _cstr_p(self)->size) return c_NPOS; + char* res = strstr(self->str + pos, needle); + return res ? res - self->str : c_NPOS; +} + +#endif +#endif // CSTR_H_INCLUDED +#undef i_opt diff --git a/misc/archived/new_arr.c b/misc/archived/new_arr.c new file mode 100644 index 00000000..1006439d --- /dev/null +++ b/misc/archived/new_arr.c @@ -0,0 +1,57 @@ +#include + +#define i_val int +#include "carr2.h" + +#define i_val int +#include "carr3.h" + +#define i_val_str +#include "carr2.h" + +int main() +{ + int w = 7, h = 5, d = 3; + + c_WITH (carr2_int volume = carr2_int_new_uninit(w, h), carr2_int_drop(&volume)) + { + int *dat = carr2_int_data(&volume); + for (size_t i = 0; i < carr2_int_size(&volume); ++i) + dat[i] = i; + + for (size_t x = 0; x < volume.xdim; ++x) + for (size_t y = 0; y < volume.ydim; ++y) + printf(" %d", volume.data[x][y]); + puts(""); + + c_FOREACH (i, carr2_int, volume) + printf(" %d", *i.ref); + puts("\n"); + } + + c_WITH (carr3_int volume = carr3_int_new_uninit(w, h, d), carr3_int_drop(&volume)) + { + int *dat = carr3_int_data(&volume); + for (size_t i = 0; i < carr3_int_size(&volume); ++i) + dat[i] = i; + + for (size_t x = 0; x < volume.xdim; ++x) + for (size_t y = 0; y < volume.ydim; ++y) + for (size_t z = 0; z < volume.zdim; ++z) + printf(" %d", volume.data[x][y][z]); + puts(""); + + c_FOREACH (i, carr3_int, volume) + printf(" %d", *i.ref); + puts(""); + } + + c_WITH (carr2_str text2d = carr2_str_with_size(h, d, cstr_NULL), carr2_str_drop(&text2d)) + { + cstr_assign(&text2d.data[2][1], "hello"); + cstr_assign(&text2d.data[4][0], "world"); + + c_FOREACH (i, carr2_str, text2d) + printf("line: %s\n", cstr_str(i.ref)); + } +} diff --git a/misc/include/old/carr2.h b/misc/include/old/carr2.h deleted file mode 100644 index aebaec81..00000000 --- a/misc/include/old/carr2.h +++ /dev/null @@ -1,152 +0,0 @@ -/* MIT License - * - * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include - -#ifndef CARR2_H_INCLUDED -#define CARR2_H_INCLUDED -#include -#include -#endif -/* -// carr2- 2D dynamic array in one memory block with easy indexing. -#define i_key int -#include -#include - -int main() { - int w = 7, h = 5; - 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) - dat[i] = i; - - for (int x = 0; x < image.xdim; ++x) - for (int y = 0; y < image.ydim; ++y) - printf(" %d", image.data[x][y]); - puts("\n"); - - c_foreach (i, carr2_int, image) - printf(" %d", *i.ref); - puts(""); - } -} -*/ - -#ifndef _i_prefix -#define _i_prefix carr2_ -#endif -#include -#if !c_option(c_is_forward) -_cx_deftypes(_c_carr2_types, _cx_self, i_key); -#endif - -STC_API _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, i_key null); -STC_API _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, _cx_value* storage); -STC_API _cx_value* _cx_memb(_release)(_cx_self* self); -STC_API void _cx_memb(_drop)(_cx_self* self); -#if !defined i_no_clone -STC_API _cx_self _cx_memb(_clone)(_cx_self src); -STC_API void _cx_memb(_copy)(_cx_self *self, const _cx_self* other); -#endif - -STC_INLINE _cx_self _cx_memb(_new_uninit)(size_t xdim, size_t ydim) { - return _cx_memb(_with_data)(xdim, ydim, c_alloc_n(_cx_value, xdim*ydim)); -} -STC_INLINE size_t _cx_memb(_size)(const _cx_self* self) - { return self->xdim*self->ydim; } - -STC_INLINE _cx_value *_cx_memb(_data)(_cx_self* self) - { return *self->data; } - -STC_INLINE const _cx_value *_cx_memb(_at)(const _cx_self* self, size_t x, size_t y) { - assert(x < self->xdim && y < self->ydim); - return *self->data + self->ydim*x + y; -} - -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) { - size_t n = self->xdim*self->ydim; - return c_INIT(_cx_iter){n ? *self->data : NULL, *self->data + n}; -} - -STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) - { return c_INIT(_cx_iter){NULL, *self->data + self->xdim*self->ydim}; } - -STC_INLINE void _cx_memb(_next)(_cx_iter* it) - { if (++it->ref == it->end) it->ref = NULL; } - -/* -------------------------- IMPLEMENTATION ------------------------- */ -#if defined(i_implement) - -STC_DEF _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, _cx_value* block) { - _cx_self _arr = {c_alloc_n(_cx_value*, xdim), xdim, ydim}; - for (size_t x = 0; x < xdim; ++x, block += ydim) - _arr.data[x] = block; - return _arr; -} - -STC_DEF _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, i_key null) { - _cx_self _arr = _cx_memb(_new_uninit)(xdim, ydim); - for (_cx_value* p = _arr.data[0], *e = p + xdim*ydim; p != e; ++p) - *p = null; - return _arr; -} - -#if !defined i_no_clone - -STC_DEF _cx_self _cx_memb(_clone)(_cx_self src) { - _cx_self _arr = _cx_memb(_new_uninit)(src.xdim, src.ydim); - for (_cx_value* p = _arr.data[0], *q = src.data[0], *e = p + _cx_memb(_size)(&src); p != e; ++p, ++q) - *p = i_keyclone((*q)); - return _arr; -} - -STC_DEF 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 - -STC_DEF _cx_value *_cx_memb(_release)(_cx_self* self) { - _cx_value *values = self->data[0]; - c_free(self->data); - self->data = NULL; - return values; -} - -STC_DEF void _cx_memb(_drop)(_cx_self* self) { - if (!self->data) return; - for (_cx_value* p = self->data[0], *q = p + _cx_memb(_size)(self); p != q; ) { - --q; i_keydrop(q); - } - c_free(self->data[0]); /* values */ - c_free(self->data); /* pointers */ -} - -#endif -#include diff --git a/misc/include/old/carr3.h b/misc/include/old/carr3.h deleted file mode 100644 index a0148992..00000000 --- a/misc/include/old/carr3.h +++ /dev/null @@ -1,157 +0,0 @@ -/* MIT License - * - * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include - -#ifndef CARR3_H_INCLUDED -#define CARR3_H_INCLUDED -#include -#include -#endif -/* -// carr3 - 3D dynamic array in one memory block with easy indexing. -#define i_key int -#include -#include - -int main() { - int w = 7, h = 5, d = 3; - 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) - dat[i] = i; - - for (int x = 0; x < image.xdim; ++x) - for (int y = 0; y < image.ydim; ++y) - for (int z = 0; z < image.zdim; ++z) - printf(" %d", image.data[x][y][z]); - puts("\n"); - - c_foreach (i, carr3_int, image) - printf(" %d", *i.ref); - puts(""); - } -} -*/ - -#ifndef _i_prefix -#define _i_prefix carr3_ -#endif -#include - -#if !c_option(c_is_forward) -_cx_deftypes(_c_carr3_types, _cx_self, i_key); -#endif - -STC_API _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, size_t zdim, i_key null); -STC_API _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, size_t zdim, _cx_value* storage); -STC_API _cx_value* _cx_memb(_release)(_cx_self* self); -STC_API void _cx_memb(_drop)(_cx_self* self); -#if !defined i_no_clone -STC_API _cx_self _cx_memb(_clone)(_cx_self src); -STC_API void _cx_memb(_copy)(_cx_self *self, const _cx_self* other); -#endif - -STC_INLINE _cx_self _cx_memb(_new_uninit)(size_t xdim, size_t ydim, size_t zdim) { - return _cx_memb(_with_data)(xdim, ydim, zdim, c_alloc_n(_cx_value, xdim*ydim*zdim)); -} - -STC_INLINE size_t _cx_memb(_size)(const _cx_self* self) - { return self->xdim*self->ydim*self->zdim; } - -STC_INLINE _cx_value* _cx_memb(_data)(_cx_self* self) - { return **self->data; } - -STC_INLINE const _cx_value* _cx_memb(_at)(const _cx_self* self, size_t x, size_t y, size_t z) { - assert(x < self->xdim && y < self->ydim && z < self->zdim); - return **self->data + self->zdim*(self->ydim*x + y) + z; -} - -STC_INLINE size_t _cx_memb(_idx)(const _cx_self* self, size_t x, size_t y, size_t z) { - return self->zdim*(self->ydim*x + y) + z; -} - - -STC_INLINE _cx_iter _cx_memb(_begin)(const _cx_self* self) { - size_t n = _cx_memb(_size)(self); - return c_INIT(_cx_iter){n ? **self->data : NULL, **self->data + n}; -} - -STC_INLINE _cx_iter _cx_memb(_end)(const _cx_self* self) - { return c_INIT(_cx_iter){NULL, **self->data + _cx_memb(_size)(self)}; } - -STC_INLINE void _cx_memb(_next)(_cx_iter* it) - { if (++it->ref == it->end) it->ref = NULL; } - -/* -------------------------- IMPLEMENTATION ------------------------- */ -#if defined(i_implement) - -STC_DEF _cx_self _cx_memb(_with_data)(size_t xdim, size_t ydim, size_t zdim, _cx_value* block) { - _cx_self _arr = {c_alloc_n(_cx_value**, xdim*(ydim + 1)), xdim, ydim, zdim}; - _cx_value** p = (_cx_value**) &_arr.data[xdim]; - for (size_t x = 0, y; x < xdim; ++x, p += ydim) - for (y = 0, _arr.data[x] = p; y < ydim; ++y, block += zdim) - p[y] = block; - return _arr; -} - -STC_DEF _cx_self _cx_memb(_with_size)(size_t xdim, size_t ydim, size_t zdim, i_key null) { - _cx_self _arr = _cx_memb(_new_uninit)(xdim, ydim, zdim); - for (_cx_value* p = **_arr.data, *e = p + xdim*ydim*zdim; p != e; ++p) - *p = null; - return _arr; -} - -#if !defined i_no_clone - -STC_DEF _cx_self _cx_memb(_clone)(_cx_self src) { - _cx_self _arr = _cx_memb(_new_uninit)(src.xdim, src.ydim, src.zdim); - for (_cx_value* p = **_arr.data, *q = **src.data, *e = p + _cx_memb(_size)(&src); p != e; ++p, ++q) - *p = i_keyclone((*q)); - return _arr; -} - -STC_DEF 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 - -STC_DEF _cx_value* _cx_memb(_release)(_cx_self* self) { - _cx_value *values = self->data[0][0]; - c_free(self->data); - self->data = NULL; - return values; -} - -STC_DEF void _cx_memb(_drop)(_cx_self* self) { - if (!self->data) return; - for (_cx_value* p = **self->data, *q = p + _cx_memb(_size)(self); p != q; ) { - --q; i_keydrop(q); - } - c_free(self->data[0][0]); /* data */ - c_free(self->data); /* pointers */ -} - -#endif -#include diff --git a/misc/include/old/csmap.h b/misc/include/old/csmap.h deleted file mode 100644 index 4b4e764c..00000000 --- a/misc/include/old/csmap.h +++ /dev/null @@ -1,512 +0,0 @@ -/* MIT License - * - * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -// Sorted/Ordered set and map - implemented as an AA-tree. -/* -#include -#include - -#define i_tag sx // Sorted map -#define i_key_str -#define i_val double -#include - -int main(void) { - 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); - csmap_sx_emplace(&m, "Testing three", 123.4); - - csmap_sx_value *v = csmap_sx_get(&m, "Testing five"); // NULL - double num = *csmap_sx_at(&m, "Testing one"); - csmap_sx_emplace_or_assign(&m, "Testing three", 1000.0); // update - csmap_sx_erase(&m, "Testing two"); - - c_foreach (i, csmap_sx, m) - printf("map %s: %g\n", cstr_str(&i.ref->first), i.ref->second); - } -} -*/ -#include - -#ifndef CSMAP_H_INCLUDED -#define STC_CSMAP_V1 1 -#include -#include -#include -#endif // CSMAP_H_INCLUDED - -#ifndef _i_prefix -#define _i_prefix csmap_ -#endif -#ifdef _i_isset - #define _i_MAP_ONLY c_false - #define _i_SET_ONLY c_true - #define _i_keyref(vp) (vp) -#else - #define _i_ismap - #define _i_MAP_ONLY c_true - #define _i_SET_ONLY c_false - #define _i_keyref(vp) (&(vp)->first) -#endif -#include - -#if !c_option(c_is_forward) -_cx_deftypes(_c_aatree_types, _cx_self, i_key, i_val, i_size, _i_MAP_ONLY, _i_SET_ONLY); -#endif - -_i_MAP_ONLY( struct _cx_value { - _cx_key first; - _cx_mapped second; -}; ) -struct _cx_node { - struct _cx_node *link[2]; - uint8_t level; - _cx_value value; -}; - -typedef i_keyraw _cx_rawkey; -typedef i_valraw _cx_memb(_rawmapped); -typedef _i_SET_ONLY( i_keyraw ) - _i_MAP_ONLY( struct { i_keyraw first; i_valraw second; } ) - _cx_raw; - -#if !defined i_no_clone -STC_API _cx_self _cx_memb(_clone)(_cx_self cx); -#if !defined i_no_emplace -STC_API _cx_result _cx_memb(_emplace)(_cx_self* self, i_keyraw rkey _i_MAP_ONLY(, i_valraw rmapped)); -#endif // !i_no_emplace -#endif // !i_no_clone -STC_API _cx_self _cx_memb(_init)(void); -STC_API _cx_result _cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped)); -STC_API _cx_result _cx_memb(_push)(_cx_self* self, _cx_value _val); -STC_API void _cx_memb(_drop)(_cx_self* self); -STC_API _cx_value* _cx_memb(_find_it)(const _cx_self* self, i_keyraw rkey, _cx_iter* out); -STC_API _cx_iter _cx_memb(_lower_bound)(const _cx_self* self, i_keyraw rkey); -STC_API _cx_value* _cx_memb(_front)(const _cx_self* self); -STC_API _cx_value* _cx_memb(_back)(const _cx_self* self); -STC_API int _cx_memb(_erase)(_cx_self* self, i_keyraw rkey); -STC_API _cx_iter _cx_memb(_erase_at)(_cx_self* self, _cx_iter it); -STC_API _cx_iter _cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2); -STC_API void _cx_memb(_next)(_cx_iter* it); - -STC_INLINE bool _cx_memb(_empty)(_cx_self cx) { return cx.size == 0; } -STC_INLINE size_t _cx_memb(_size)(_cx_self cx) { return cx.size; } -STC_INLINE void _cx_memb(_swap)(_cx_self* a, _cx_self* b) { c_swap(_cx_self, *a, *b); } -STC_INLINE _cx_iter _cx_memb(_find)(const _cx_self* self, i_keyraw rkey) - { _cx_iter it; _cx_memb(_find_it)(self, rkey, &it); return it; } -STC_INLINE bool _cx_memb(_contains)(const _cx_self* self, i_keyraw rkey) - { _cx_iter it; return _cx_memb(_find_it)(self, rkey, &it) != NULL; } -STC_INLINE const _cx_value* _cx_memb(_get)(const _cx_self* self, i_keyraw rkey) - { _cx_iter it; return _cx_memb(_find_it)(self, rkey, &it); } -STC_INLINE _cx_value* _cx_memb(_get_mut)(_cx_self* self, i_keyraw rkey) - { _cx_iter it; return _cx_memb(_find_it)(self, rkey, &it); } - -STC_INLINE void -_cx_memb(_clear)(_cx_self* self) - { _cx_memb(_drop)(self); *self = _cx_memb(_init)(); } - -STC_INLINE _cx_raw -_cx_memb(_value_toraw)(_cx_value* val) { - return _i_SET_ONLY( i_keyto(val) ) - _i_MAP_ONLY( c_INIT(_cx_raw){i_keyto((&val->first)), - i_valto((&val->second))} ); -} - -STC_INLINE int -_cx_memb(_value_cmp)(const _cx_value* x, const _cx_value* y) { - _cx_rawkey rx = i_keyto(_i_keyref(x)), ry = i_keyto(_i_keyref(y)); - return i_cmp((&rx), (&ry)); -} - -STC_INLINE void -_cx_memb(_value_drop)(_cx_value* val) { - i_keydrop(_i_keyref(val)); - _i_MAP_ONLY( i_valdrop((&val->second)); ) -} - -#if !defined i_no_clone -STC_INLINE _cx_value -_cx_memb(_value_clone)(_cx_value _val) { - *_i_keyref(&_val) = i_keyclone((*_i_keyref(&_val))); - _i_MAP_ONLY( _val.second = i_valclone(_val.second); ) - return _val; -} - -STC_INLINE void -_cx_memb(_copy)(_cx_self *self, const _cx_self* other) { - if (self->root == other->root) - return; - _cx_memb(_drop)(self); - *self = _cx_memb(_clone)(*other); -} -#endif // !i_no_clone - -#ifndef _i_isset - #if !defined i_no_clone && !defined i_no_emplace - STC_API _cx_result _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped); - #endif - STC_API _cx_result _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped); - - STC_INLINE const _cx_mapped* - _cx_memb(_at)(const _cx_self* self, i_keyraw rkey) - { _cx_iter it; return &_cx_memb(_find_it)(self, rkey, &it)->second; } - STC_INLINE _cx_mapped* - _cx_memb(_at_mut)(_cx_self* self, i_keyraw rkey) - { _cx_iter it; return &_cx_memb(_find_it)(self, rkey, &it)->second; } -#endif // !_i_isset - -STC_INLINE _cx_iter -_cx_memb(_begin)(const _cx_self* self) { - _cx_iter it; - it.ref = NULL, it._top = 0, it._tn = self->root; - _cx_memb(_next)(&it); - return it; -} - -STC_INLINE _cx_iter -_cx_memb(_end)(const _cx_self* self) { - (void)self; - _cx_iter it; it.ref = NULL, it._top = 0, it._tn = NULL; - return it; -} - -STC_INLINE _cx_iter -_cx_memb(_advance)(_cx_iter it, size_t n) { - while (n-- && it.ref) - _cx_memb(_next)(&it); - return it; -} - -/* -------------------------- IMPLEMENTATION ------------------------- */ -#if defined(i_implement) - -#ifndef CSMAP_H_INCLUDED -static struct { void *link[2]; uint8_t level; } -_csmap_sentinel = {{&_csmap_sentinel, &_csmap_sentinel}, 0}; -#endif - -static _cx_result _cx_memb(_insert_entry_)(_cx_self* self, i_keyraw rkey); - -STC_DEF _cx_self -_cx_memb(_init)(void) { - _cx_self cx = {(_cx_node *)&_csmap_sentinel, 0}; - return cx; -} - -STC_DEF _cx_value* -_cx_memb(_front)(const _cx_self* self) { - _cx_node *tn = self->root; - while (tn->link[0]->level) - tn = tn->link[0]; - return &tn->value; -} - -STC_DEF _cx_value* -_cx_memb(_back)(const _cx_self* self) { - _cx_node *tn = self->root; - while (tn->link[1]->level) - tn = tn->link[1]; - return &tn->value; -} - -STC_DEF _cx_result -_cx_memb(_insert)(_cx_self* self, i_key key _i_MAP_ONLY(, i_val mapped)) { - _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto((&key))); - if (res.inserted) - { *_i_keyref(res.ref) = key; _i_MAP_ONLY( res.ref->second = mapped; )} - else - { i_keydrop((&key)); _i_MAP_ONLY( i_valdrop((&mapped)); )} - return res; -} - -STC_DEF _cx_result -_cx_memb(_push)(_cx_self* self, _cx_value _val) { - _cx_result _res = _cx_memb(_insert_entry_)(self, i_keyto(_i_keyref(&_val))); - if (_res.inserted) - *_res.ref = _val; - else - _cx_memb(_value_drop)(&_val); - return _res; -} - -#ifndef _i_isset - STC_DEF _cx_result - _cx_memb(_insert_or_assign)(_cx_self* self, i_key key, i_val mapped) { - _cx_result res = _cx_memb(_insert_entry_)(self, i_keyto((&key))); - if (res.inserted) - res.ref->first = key; - else - { i_keydrop((&key)); i_valdrop((&res.ref->second)); } - res.ref->second = mapped; - return res; - } - #if !defined i_no_clone && !defined i_no_emplace - STC_DEF _cx_result - _cx_memb(_emplace_or_assign)(_cx_self* self, i_keyraw rkey, i_valraw rmapped) { - _cx_result res = _cx_memb(_insert_entry_)(self, rkey); - if (res.inserted) - res.ref->first = i_keyfrom(rkey); - else - { i_valdrop((&res.ref->second)); } - res.ref->second = i_valfrom(rmapped); - return res; - } - #endif // !i_no_clone && !i_no_emplace -#endif // !_i_isset - -STC_DEF _cx_value* -_cx_memb(_find_it)(const _cx_self* self, _cx_rawkey rkey, _cx_iter* out) { - _cx_node *tn = self->root; - out->_top = 0; - while (tn->level) { - int c; _cx_rawkey raw = i_keyto(_i_keyref(&tn->value)); - if ((c = i_cmp((&raw), (&rkey))) < 0) - tn = tn->link[1]; - else if (c > 0) - { out->_st[out->_top++] = tn; tn = tn->link[0]; } - else - { out->_tn = tn->link[1]; return (out->ref = &tn->value); } - } - return (out->ref = NULL); -} - -STC_DEF _cx_iter -_cx_memb(_lower_bound)(const _cx_self* self, i_keyraw rkey) { - _cx_iter it; - _cx_memb(_find_it)(self, rkey, &it); - if (!it.ref && it._top) { - _cx_node *tn = it._st[--it._top]; - it._tn = tn->link[1]; - it.ref = &tn->value; - } - return it; -} - -STC_DEF void -_cx_memb(_next)(_cx_iter *it) { - _cx_node *tn = it->_tn; - if (it->_top || tn->level) { - while (tn->level) { - it->_st[it->_top++] = tn; - tn = tn->link[0]; - } - tn = it->_st[--it->_top]; - it->_tn = tn->link[1]; - it->ref = &tn->value; - } else - it->ref = NULL; -} - -static _cx_node * -_cx_memb(_skew_)(_cx_node *tn) { - if (tn && tn->link[0]->level == tn->level && tn->level) { - _cx_node *tmp = tn->link[0]; - tn->link[0] = tmp->link[1]; - tmp->link[1] = tn; - tn = tmp; - } - return tn; -} - -static _cx_node * -_cx_memb(_split_)(_cx_node *tn) { - if (tn->link[1]->link[1]->level == tn->level && tn->level) { - _cx_node *tmp = tn->link[1]; - tn->link[1] = tmp->link[0]; - tmp->link[0] = tn; - tn = tmp; - ++tn->level; - } - return tn; -} - -static _cx_node* -_cx_memb(_insert_entry_i_)(_cx_node* tn, const _cx_rawkey* rkey, _cx_result* res) { - _cx_node *up[64], *tx = tn; - int c, top = 0, dir = 0; - while (tx->level) { - up[top++] = tx; - _cx_rawkey r = i_keyto(_i_keyref(&tx->value)); - if (!(c = (i_cmp((&r), rkey)))) - { res->ref = &tx->value; return tn; } - dir = (c < 0); - tx = tx->link[dir]; - } - tn = c_alloc(_cx_node); - tn->link[0] = tn->link[1] = (_cx_node*)&_csmap_sentinel; - tn->level = 1; - res->ref = &tn->value, res->inserted = true; - if (top == 0) - return tn; - up[top - 1]->link[dir] = tn; - while (top--) { - if (top) - dir = (up[top - 1]->link[1] == up[top]); - up[top] = _cx_memb(_skew_)(up[top]); - up[top] = _cx_memb(_split_)(up[top]); - if (top) - up[top - 1]->link[dir] = up[top]; - } - return up[0]; -} - -STC_DEF _cx_result -_cx_memb(_insert_entry_)(_cx_self* self, i_keyraw rkey) { - _cx_result res = {NULL}; - self->root = _cx_memb(_insert_entry_i_)(self->root, &rkey, &res); - self->size += res.inserted; - return res; -} - -static _cx_node* -_cx_memb(_erase_r_)(_cx_node *tn, const _cx_rawkey* rkey, int *erased) { - if (tn->level == 0) - return tn; - _cx_rawkey raw = i_keyto(_i_keyref(&tn->value)); - _cx_node *tx; int c = (i_cmp((&raw), rkey)); - if (c != 0) - tn->link[c < 0] = _cx_memb(_erase_r_)(tn->link[c < 0], rkey, erased); - else { - if (!*erased) - { _cx_memb(_value_drop)(&tn->value); *erased = 1; } - if (tn->link[0]->level && tn->link[1]->level) { - tx = tn->link[0]; - while (tx->link[1]->level) - tx = tx->link[1]; - tn->value = tx->value; - raw = i_keyto(_i_keyref(&tn->value)); - tn->link[0] = _cx_memb(_erase_r_)(tn->link[0], &raw, erased); - } else { /* unlink node */ - tx = tn; - tn = tn->link[tn->link[0]->level == 0]; - c_free(tx); - } - } - if (tn->link[0]->level < tn->level - 1 || tn->link[1]->level < tn->level - 1) { - if (tn->link[1]->level > --tn->level) - tn->link[1]->level = tn->level; - tn = _cx_memb(_skew_)(tn); - tx = tn->link[0] = _cx_memb(_skew_)(tn->link[0]); - tx->link[0] = _cx_memb(_skew_)(tx->link[0]); - tn = _cx_memb(_split_)(tn); - tn->link[0] = _cx_memb(_split_)(tn->link[0]); - } - return tn; -} - -STC_DEF int -_cx_memb(_erase)(_cx_self* self, i_keyraw rkey) { - int erased = 0; - self->root = _cx_memb(_erase_r_)(self->root, &rkey, &erased); - self->size -= erased; - return erased; -} - -STC_DEF _cx_iter -_cx_memb(_erase_at)(_cx_self* self, _cx_iter it) { - _cx_rawkey raw = i_keyto(_i_keyref(it.ref)), nxt; - _cx_memb(_next)(&it); - if (it.ref) - nxt = i_keyto(_i_keyref(it.ref)); - _cx_memb(_erase)(self, raw); - if (it.ref) - _cx_memb(_find_it)(self, nxt, &it); - return it; -} - -STC_DEF _cx_iter -_cx_memb(_erase_range)(_cx_self* self, _cx_iter it1, _cx_iter it2) { - if (!it2.ref) { - while (it1.ref) - it1 = _cx_memb(_erase_at)(self, it1); - return it1; - } - _cx_key k1 = *_i_keyref(it1.ref), k2 = *_i_keyref(it2.ref); - _cx_rawkey r1 = i_keyto((&k1)); - for (;;) { - if (memcmp(&k1, &k2, sizeof k1) == 0) - return it1; - _cx_memb(_next)(&it1); - k1 = *_i_keyref(it1.ref); - _cx_memb(_erase)(self, r1); - r1 = i_keyto((&k1)); - _cx_memb(_find_it)(self, r1, &it1); - } -} - -#if !defined i_no_clone -static _cx_node* -_cx_memb(_clone_r_)(_cx_node *tn) { - if (! tn->level) - return tn; - _cx_node *cn = c_alloc(_cx_node); - cn->level = tn->level; - cn->value = _cx_memb(_value_clone)(tn->value); - cn->link[0] = _cx_memb(_clone_r_)(tn->link[0]); - cn->link[1] = _cx_memb(_clone_r_)(tn->link[1]); - return cn; -} - -STC_DEF _cx_self -_cx_memb(_clone)(_cx_self cx) { - return c_INIT(_cx_self){_cx_memb(_clone_r_)(cx.root), cx.size}; -} -#endif // !i_no_clone - -#if !defined i_no_emplace -STC_DEF _cx_result -_cx_memb(_emplace)(_cx_self* self, i_keyraw rkey _i_MAP_ONLY(, i_valraw rmapped)) { - _cx_result res = _cx_memb(_insert_entry_)(self, rkey); - if (res.inserted) { - *_i_keyref(res.ref) = i_keyfrom(rkey); - _i_MAP_ONLY(res.ref->second = i_valfrom(rmapped);) - } - return res; -} -#endif // i_no_emplace - -static void -_cx_memb(_drop_r_)(_cx_node* tn) { - if (tn->level != 0) { - _cx_memb(_drop_r_)(tn->link[0]); - _cx_memb(_drop_r_)(tn->link[1]); - _cx_memb(_value_drop)(&tn->value); - c_free(tn); - } -} - -STC_DEF void -_cx_memb(_drop)(_cx_self* self) { - _cx_memb(_drop_r_)(self->root); -} - -#endif // i_implement -#undef _i_isset -#undef _i_ismap -#undef _i_keyref -#undef _i_MAP_ONLY -#undef _i_SET_ONLY -#define CSMAP_H_INCLUDED -#include diff --git a/misc/include/old/cstr.h b/misc/include/old/cstr.h deleted file mode 100644 index 8de6c4b0..00000000 --- a/misc/include/old/cstr.h +++ /dev/null @@ -1,384 +0,0 @@ -/* MIT License - * - * Copyright (c) 2022 Tyge Løvset, NORCE, www.norceresearch.no - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef CSTR_H_INCLUDED -#define CSTR_H_INCLUDED - -#include -#include -#include /* malloc */ -#include -#include -#include /* vsnprintf */ -#include - -#define c_unchecked_container_of(ptr, type, member) \ - ((type*)((char*)(ptr) - offsetof(type, member))) - -typedef char cstr_value; -typedef struct { cstr_value* str; } cstr; -typedef struct { size_t size, cap; char chr[1]; } cstr_priv; -#define _cstr_p(self) c_unchecked_container_of((self)->str, cstr_priv, chr) -#ifdef i_static - static cstr_priv _cstr_nullrep = {0, 0, {0}}; - static const cstr cstr_NULL = {_cstr_nullrep.chr}; -#else - extern const cstr cstr_NULL; -#endif -/* optimal memory: based on malloc_usable_size() sequence: 24, 40, 56, ... */ -#define _cstr_opt_mem(cap) ((((offsetof(cstr_priv, chr) + (cap) + 8)>>4)<<4) + 8) -/* optimal string capacity: 7, 23, 39, ... */ -#define _cstr_opt_cap(cap) (_cstr_opt_mem(cap) - offsetof(cstr_priv, chr) - 1) - -STC_API cstr cstr_from_n(const char* str, size_t n); -STC_API cstr cstr_from_fmt(const char* fmt, ...); -STC_API char* cstr_reserve(cstr* self, size_t cap); -STC_API void cstr_resize(cstr* self, size_t len, char fill); -STC_API cstr* cstr_assign_n(cstr* self, const char* str, size_t n); -STC_API int cstr_printf(cstr* self, const char* fmt, ...); -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(cstr* self, size_t pos, size_t n); -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; } -STC_INLINE const char* cstr_str(const cstr* self) { return self->str; } -#define cstr_toraw(self) (self)->str -STC_INLINE csview cstr_sv(const cstr* self) - { return c_INIT(csview){self->str, _cstr_p(self)->size}; } -#define cstr_lit(literal) \ - cstr_from_n(literal, c_strlen_lit(literal)) -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(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) - { if (_cstr_p(self)->cap) c_free(_cstr_p(self)); } -STC_INLINE cstr cstr_clone(cstr s) - { return cstr_from_n(s.str, _cstr_p(&s)->size); } -STC_INLINE void cstr_clear(cstr* self) - { self->str[_cstr_p(self)->size = 0] = '\0'; } -STC_INLINE cstr* cstr_assign(cstr* self, const char* str) - { return cstr_assign_n(self, str, strlen(str)); } -STC_INLINE cstr* cstr_copy(cstr* self, cstr s) - { return cstr_assign_n(self, s.str, _cstr_p(&s)->size); } -STC_INLINE cstr* cstr_append(cstr* self, const char* str) - { return cstr_append_n(self, str, strlen(str)); } -STC_INLINE cstr* cstr_append_s(cstr* self, cstr s) - { return cstr_append_n(self, s.str, _cstr_p(&s)->size); } -STC_INLINE void cstr_push_back(cstr* self, char value) - { cstr_append_n(self, &value, 1); } -STC_INLINE void cstr_pop_back(cstr* self) - { self->str[ --_cstr_p(self)->size ] = '\0'; } -STC_INLINE void cstr_insert_n(cstr* self, const size_t pos, const char* str, const size_t n) - { cstr_replace_at_sv(self, pos, 0, c_SV(str, n)); } -STC_INLINE void cstr_insert(cstr* self, const size_t pos, const char* str) - { cstr_replace_at_sv(self, pos, 0, c_SV(str, strlen(str))); } -STC_INLINE void cstr_insert_s(cstr* self, const size_t pos, cstr s) - { cstr_replace_at_sv(self, pos, 0, c_SV(s.str, _cstr_p(&s)->size)); } -STC_INLINE void cstr_replace_at(cstr* self, const size_t pos, const size_t len, const char* str) - { cstr_replace_at_sv(self, pos, len, c_SV(str, strlen(str))); } -STC_INLINE void cstr_replace_s(cstr* self, const size_t pos, const size_t len, cstr s) - { cstr_replace_at_sv(self, pos, len, c_SV(s.str, _cstr_p(&s)->size)); } -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(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); } - -STC_INLINE cstr_buf cstr_buffer(cstr* s) { - cstr_priv* p = _cstr_p(s); - return c_INIT(cstr_buf){s->str, p->size, p->cap}; -} - -STC_INLINE cstr cstr_with_capacity(const size_t cap) { - cstr s = cstr_NULL; - cstr_reserve(&s, cap); - return s; -} - -STC_INLINE cstr cstr_with_size(const size_t len, const char fill) { - cstr s = cstr_NULL; - cstr_resize(&s, len, fill); - return s; -} - -STC_INLINE char* cstr_append_uninit(cstr *self, size_t n) { - 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; -} - -STC_INLINE cstr* cstr_take(cstr* self, cstr s) { - if (self->str != s.str && _cstr_p(self)->cap) - c_free(_cstr_p(self)); - self->str = s.str; - return self; -} - -STC_INLINE cstr cstr_move(cstr* self) { - cstr tmp = *self; - *self = cstr_NULL; - return tmp; -} - -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(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) { - int ret = 0; - while (nmax-- && (ret = tolower(*s1++) - tolower(*s2)) == 0 && *s2++) - ; - return ret; -} - -/* container adaptor functions: */ -#define cstr_cmp(xp, yp) strcmp((xp)->str, (yp)->str) - -STC_INLINE bool cstr_eq(const cstr* x, const cstr* y) { - size_t xs = _cstr_p(x)->size, ys = _cstr_p(y)->size; - return xs == ys && !memcmp(x->str, y->str, xs); -} -STC_INLINE uint64_t cstr_hash(const cstr *self) { - return cfasthash(self->str, _cstr_p(self)->size); -} - -STC_INLINE void cstr_replace_ex(cstr* self, const char* find, const char* repl, unsigned count) { - cstr_take(self, cstr_replace_sv(cstr_sv(self), c_SV(find, strlen(find)), - c_SV(repl, strlen(repl)), count)); -} -STC_INLINE void cstr_replace(cstr* self, const char* search, const char* repl) - { cstr_replace_ex(self, search, repl, ~0U); } - -/* -------------------------- IMPLEMENTATION ------------------------- */ -#if defined(i_implement) - -#ifndef i_static -static cstr_priv _cstr_nullrep = {0, 0, {0}}; -const cstr cstr_NULL = {_cstr_nullrep.chr}; -#endif - -STC_DEF char* -cstr_reserve(cstr* self, const size_t cap) { - cstr_priv *p = _cstr_p(self); - const size_t oldcap = p->cap; - if (cap > oldcap) { - p = (cstr_priv*) c_realloc(((oldcap != 0) & (p != &_cstr_nullrep)) ? p : NULL, _cstr_opt_mem(cap)); - if (!p) return NULL; - self->str = p->chr; - if (oldcap == 0) self->str[p->size = 0] = '\0'; - p->cap = _cstr_opt_cap(cap); - } - return self->str; -} - -STC_DEF void -cstr_resize(cstr* self, const size_t len, const char fill) { - const size_t n = _cstr_p(self)->size; - cstr_reserve(self, len); - if (len > n) memset(self->str + n, fill, len - n); - if (len | n) self->str[_cstr_p(self)->size = len] = '\0'; -} - -STC_DEF cstr -cstr_from_n(const char* str, const size_t n) { - if (n == 0) return cstr_NULL; - cstr_priv* prv = (cstr_priv*) c_malloc(_cstr_opt_mem(n)); - cstr s = {(char *) memcpy(prv->chr, str, n)}; - s.str[prv->size = n] = '\0'; - prv->cap = _cstr_opt_cap(n); - return s; -} - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wdeprecated-declarations" -#elif defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable: 4996) -#endif - -STC_DEF int -cstr_vfmt(cstr* self, const char* fmt, va_list args) { - va_list args2; - va_copy(args2, args); - int len = vsnprintf(NULL, (size_t)0, fmt, args); - cstr_reserve(self, len); - vsprintf(self->str, fmt, args2); - va_end(args2); - return _cstr_p(self)->size = len; -} - -#if defined(__clang__) -# pragma clang diagnostic pop -#elif defined(_MSC_VER) -# pragma warning(pop) -#endif - -STC_DEF cstr -cstr_from_fmt(const char* fmt, ...) { - cstr ret = cstr_NULL; - va_list args; va_start(args, fmt); - cstr_vfmt(&ret, fmt, args); - va_end(args); - return ret; -} - -STC_DEF int -cstr_printf(cstr* self, const char* fmt, ...) { - cstr ret = cstr_NULL; - va_list args; - va_start(args, fmt); - int n = cstr_vfmt(&ret, fmt, args); - va_end(args); - cstr_drop(self); - *self = ret; - return n; -} - -STC_DEF cstr* -cstr_assign_n(cstr* self, const char* str, const size_t n) { - if (n || _cstr_p(self)->cap) { - cstr_reserve(self, n); - memmove(self->str, str, n); - self->str[_cstr_p(self)->size = n] = '\0'; - } - return self; -} - -STC_DEF cstr* -cstr_append_n(cstr* self, const char* str, const size_t n) { - if (n == 0) return self; - const size_t oldlen = _cstr_p(self)->size, newlen = oldlen + n; - if (newlen > _cstr_p(self)->cap) { - const size_t off = (size_t) (str - self->str); /* handle self append */ - cstr_reserve(self, (oldlen*3 >> 1) + n); - if (off <= oldlen) str = self->str + off; - } - memcpy(&self->str[oldlen], str, n); - self->str[_cstr_p(self)->size = newlen] = '\0'; - return self; -} - -STC_INLINE void _cstr_internal_move(cstr* self, const size_t pos1, const size_t pos2) { - if (pos1 == pos2) - return; - const size_t len = _cstr_p(self)->size, newlen = len + pos2 - pos1; - if (newlen > _cstr_p(self)->cap) - cstr_reserve(self, (len*3 >> 1) + pos2 - pos1); - memmove(&self->str[pos2], &self->str[pos1], len - pos1); - self->str[_cstr_p(self)->size = newlen] = '\0'; -} - -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); - if (len > sz - pos) len = sz - pos; - char buf[256], *xstr = repl.size > 256 ? c_malloc(repl.size) : buf; - memcpy(xstr, repl.str, repl.size); - _cstr_internal_move(self, pos + len, pos + repl.size); - memcpy(&self->str[pos], xstr, repl.size); - if (repl.size > 256) c_free(xstr); -} - -STC_DEF cstr -cstr_replace_sv(csview str, csview find, csview repl, unsigned count) { - cstr out = cstr_NULL; - size_t from = 0; char* res; - if (find.size) - while (count-- && (res = cstrnstrn(str.str + from, find.str, str.size - from, find.size))) { - const size_t pos = res - str.str; - cstr_append_n(&out, str.str + from, pos - from); - cstr_append_n(&out, repl.str, repl.size); - from = pos + find.size; - } - cstr_append_n(&out, str.str + from, str.size - from); - return out; -} - -STC_DEF void -cstr_erase(cstr* self, const size_t pos, size_t n) { - const size_t len = _cstr_p(self)->size; - if (n > len - pos) n = len - pos; - if (len) { - memmove(&self->str[pos], &self->str[pos + n], len - (pos + n)); - self->str[_cstr_p(self)->size -= n] = '\0'; - } -} - -STC_DEF bool -cstr_getdelim(cstr *self, const int delim, FILE *fp) { - size_t pos = 0, cap = _cstr_p(self)->cap; - char* d = self->str; - int c = fgetc(fp); - if (c == EOF) - return false; - for (;;) { - if (c == delim || c == EOF) { - if (cap) d[_cstr_p(self)->size = pos] = '\0'; - return true; - } - if (pos == cap) { - d = cstr_reserve(self, (cap*3 >> 1) + 16); - cap = cstr_capacity(*self); - } - d[pos++] = (char) c; - c = fgetc(fp); - } -} - -STC_DEF size_t -cstr_find(const cstr* self, const char* needle) { - char* res = strstr(self->str, needle); - return res ? res - self->str : c_NPOS; -} - -STC_DEF size_t -cstr_find_at(const cstr* self, const size_t pos, const char* needle) { - if (pos > _cstr_p(self)->size) return c_NPOS; - char* res = strstr(self->str + pos, needle); - return res ? res - self->str : c_NPOS; -} - -#endif -#endif // CSTR_H_INCLUDED -#undef i_opt diff --git a/misc/include/old/new_arr.c b/misc/include/old/new_arr.c deleted file mode 100644 index 1006439d..00000000 --- a/misc/include/old/new_arr.c +++ /dev/null @@ -1,57 +0,0 @@ -#include - -#define i_val int -#include "carr2.h" - -#define i_val int -#include "carr3.h" - -#define i_val_str -#include "carr2.h" - -int main() -{ - int w = 7, h = 5, d = 3; - - c_WITH (carr2_int volume = carr2_int_new_uninit(w, h), carr2_int_drop(&volume)) - { - int *dat = carr2_int_data(&volume); - for (size_t i = 0; i < carr2_int_size(&volume); ++i) - dat[i] = i; - - for (size_t x = 0; x < volume.xdim; ++x) - for (size_t y = 0; y < volume.ydim; ++y) - printf(" %d", volume.data[x][y]); - puts(""); - - c_FOREACH (i, carr2_int, volume) - printf(" %d", *i.ref); - puts("\n"); - } - - c_WITH (carr3_int volume = carr3_int_new_uninit(w, h, d), carr3_int_drop(&volume)) - { - int *dat = carr3_int_data(&volume); - for (size_t i = 0; i < carr3_int_size(&volume); ++i) - dat[i] = i; - - for (size_t x = 0; x < volume.xdim; ++x) - for (size_t y = 0; y < volume.ydim; ++y) - for (size_t z = 0; z < volume.zdim; ++z) - printf(" %d", volume.data[x][y][z]); - puts(""); - - c_FOREACH (i, carr3_int, volume) - printf(" %d", *i.ref); - puts(""); - } - - c_WITH (carr2_str text2d = carr2_str_with_size(h, d, cstr_NULL), carr2_str_drop(&text2d)) - { - cstr_assign(&text2d.data[2][1], "hello"); - cstr_assign(&text2d.data[4][0], "world"); - - c_FOREACH (i, carr2_str, text2d) - printf("line: %s\n", cstr_str(i.ref)); - } -} -- cgit v1.2.3