summaryrefslogtreecommitdiffhomepage
path: root/stc
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2020-07-22 13:01:47 +0200
committerTyge Løvset <[email protected]>2020-07-22 13:01:47 +0200
commitc47f6949cbd6d851eddb83cc1b9aa4e2cf3dbe61 (patch)
treeb9738ca838fb0ad40bda6a117263f3e78fd024fc /stc
parente0ebdfb05aa543eac980920949bc993e1bec931b (diff)
downloadSTC-modified-c47f6949cbd6d851eddb83cc1b9aa4e2cf3dbe61.tar.gz
STC-modified-c47f6949cbd6d851eddb83cc1b9aa4e2cf3dbe61.zip
Renamed CArray to CArr. Renamed cmap_xx_get() to cmap_xx_find(). Changed _front() and _back() signatures.
Diffstat (limited to 'stc')
-rw-r--r--stc/carr.h195
-rw-r--r--stc/carray.h193
-rw-r--r--stc/cdefs.h6
-rw-r--r--stc/clist.h11
-rw-r--r--stc/cmap.h12
-rw-r--r--stc/cvec.h24
-rw-r--r--stc/cvecpq.h5
7 files changed, 229 insertions, 217 deletions
diff --git a/stc/carr.h b/stc/carr.h
new file mode 100644
index 00000000..e80d0ad9
--- /dev/null
+++ b/stc/carr.h
@@ -0,0 +1,195 @@
+/* MIT License
+ *
+ * Copyright (c) 2020 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 CARR__H__
+#define CARR__H__
+
+#include <stdlib.h>
+#include "cdefs.h"
+
+/*
+ Multi-dimensional generic array allocated as one block of heap-memory.
+ // demo:
+#include <stc/carr.h>
+declare_CArr(f, float);
+
+int main()
+{
+ CArr3_f a3 = carr3_f_make(30, 20, 10, 0.f);
+ carr3_f_data(a3, 5, 4)[3] = 10.2f; // a3[5][4][3]
+ CArr2_f a2 = carr3_f_at(a3, 5); // sub-array reference (no data copy).
+
+ printf("%f\n", carr2_f_value(a2, 4, 3)); // readonly lookup a2[4][3] (=10.2f)
+ printf("%f\n", carr2_f_data(a2, 4)[3]); // same, but this is writable.
+ printf("%f\n", carr2_f_at(a2, 4).data[3]); // same, via sub-array access.
+
+ printf("%f\n", carr3_f_value(a3, 5, 4, 3)); // same data location, via a3 array.
+ printf("%f\n", carr3_f_data(a3, 5, 4)[3]);
+ printf("%f\n", carr3_f_at2(a3, 5, 4).data[3]);
+
+ carr2_f_destroy(&a2); // does nothing, since it is a sub-array.
+ carr3_f_destroy(&a3); // also invalidates a2.
+}
+*/
+
+#define carr1_xdim(a) ((a)._xdim & _carr_SUB)
+#define carr1_size(a) carr1_xdim(a)
+
+#define carr2_xdim(a) carr1_xdim(a)
+#define carr2_ydim(a) _carr2_ydim(&(a)._yxdim)
+#define carr2_size(a) ((a)._yxdim)
+
+#define carr3_xdim(a) carr1_xdim(a)
+#define carr3_ydim(a) carr2_ydim(a)
+#define carr3_zdim(a) ((a)._zdim)
+#define carr3_size(a) _carr3_size(&(a)._zdim)
+
+#define _carr_SUB (SIZE_MAX >> 1)
+#define _carr_OWN (_carr_SUB + 1)
+
+static inline size_t _carr2_ydim(const size_t* yxdim) {
+ return yxdim[0] / (yxdim[-1] & _carr_SUB);
+}
+static inline size_t _carr3_size(const size_t* zdim) {
+ return zdim[0] * zdim[-1];
+}
+
+
+#define declare_CArr(...) c_MACRO_OVERLOAD(declare_CArr, __VA_ARGS__)
+
+#define declare_CArr_2(tag, Value) \
+ declare_CArr_3(tag, Value, c_defaultDestroy)
+
+
+#define declare_CArr_3(tag, Value, valueDestroy) \
+ typedef struct { \
+ Value *data; \
+ size_t _xdim; \
+ } CArr1_##tag; \
+ \
+ typedef struct { \
+ Value *data; \
+ size_t _xdim, _yxdim; \
+ } CArr2_##tag; \
+ \
+ typedef struct { \
+ Value *data; \
+ size_t _xdim, _yxdim, _zdim; \
+ } CArr3_##tag; \
+ \
+ static inline CArr1_##tag \
+ carr1_##tag##_make(size_t xdim, Value val) { \
+ Value* m = c_new_N(Value, xdim); \
+ for (size_t i=0; i<xdim; ++i) m[i] = val; \
+ CArr1_##tag a = {m, xdim | _carr_OWN}; \
+ return a; \
+ } \
+ static inline CArr2_##tag \
+ carr2_##tag##_make(size_t ydim, size_t xdim, Value val) { \
+ const size_t n = ydim * xdim; \
+ Value* m = c_new_N(Value, n); \
+ for (size_t i=0; i<n; ++i) m[i] = val; \
+ CArr2_##tag a = {m, xdim | _carr_OWN, ydim * xdim}; \
+ return a; \
+ } \
+ static inline CArr3_##tag \
+ carr3_##tag##_make(size_t zdim, size_t ydim, size_t xdim, Value val) { \
+ const size_t n = zdim * ydim * xdim; \
+ Value* m = c_new_N(Value, n); \
+ for (size_t i=0; i<n; ++i) m[i] = val; \
+ CArr3_##tag a = {m, xdim | _carr_OWN, ydim * xdim, zdim}; \
+ return a; \
+ } \
+ \
+ static inline CArr1_##tag \
+ carr1_##tag##_makeFrom(size_t xdim, Value* array, bool own) { \
+ CArr1_##tag a = {array, xdim | (own ? _carr_OWN : 0)}; \
+ return a; \
+ } \
+ static inline CArr2_##tag \
+ carr2_##tag##_makeFrom(size_t ydim, size_t xdim, Value* array, bool own) { \
+ CArr2_##tag a = {array, xdim | (own ? _carr_OWN : 0), ydim * xdim}; \
+ return a; \
+ } \
+ static inline CArr3_##tag \
+ carr3_##tag##_makeFrom(size_t zdim, size_t ydim, size_t xdim, Value* array, bool own) { \
+ CArr3_##tag a = {array, xdim | (own ? _carr_OWN : 0), ydim * xdim, zdim}; \
+ return a; \
+ } \
+ \
+ static inline void \
+ carr1_##tag##_destroy(CArr1_##tag* self) { \
+ if (self->_xdim & _carr_OWN) { \
+ size_t n = carr1_size(*self); Value* a = self->data; \
+ while (n--) valueDestroy(&a[n]); free(a); \
+ } \
+ } \
+ static inline void \
+ carr2_##tag##_destroy(CArr2_##tag* self) { \
+ if (self->_xdim & _carr_OWN) { \
+ size_t n = carr2_size(*self); Value* a = self->data; \
+ while (n--) valueDestroy(&a[n]); free(a); \
+ } \
+ } \
+ static inline void \
+ carr3_##tag##_destroy(CArr3_##tag* self) { \
+ if (self->_xdim & _carr_OWN) { \
+ size_t n = carr3_size(*self); Value* a = self->data; \
+ while (n--) valueDestroy(&a[n]); free(a); \
+ } \
+ } \
+ \
+ static inline CArr1_##tag \
+ carr2_##tag##_at(CArr2_##tag a, size_t y) { \
+ CArr1_##tag sub = {a.data + y*carr2_xdim(a), carr2_xdim(a)}; \
+ return sub; \
+ } \
+ static inline Value* \
+ carr2_##tag##_data(CArr2_##tag a, size_t y) { \
+ return a.data + y*carr2_xdim(a); \
+ } \
+ static inline Value \
+ carr2_##tag##_value(CArr2_##tag a, size_t y, size_t x) { \
+ return a.data[ y*carr2_xdim(a) + x ]; \
+ } \
+ \
+ static inline CArr2_##tag \
+ carr3_##tag##_at(CArr3_##tag a, size_t z) { \
+ CArr2_##tag sub = {a.data + z*a._yxdim, carr3_xdim(a), a._yxdim}; \
+ return sub; \
+ } \
+ static inline CArr1_##tag \
+ carr3_##tag##_at2(CArr3_##tag a, size_t z, size_t y) { \
+ CArr1_##tag sub = {a.data + z*a._yxdim + y*carr3_xdim(a), carr3_xdim(a)}; \
+ return sub; \
+ } \
+ static inline Value* \
+ carr3_##tag##_data(CArr3_##tag a, size_t z, size_t y) { \
+ return a.data + z*a._yxdim + y*carr3_xdim(a); \
+ } \
+ static inline Value \
+ carr3_##tag##_value(CArr3_##tag a, size_t z, size_t y, size_t x) { \
+ return a.data[ z*a._yxdim + y*carr3_xdim(a) + x ]; \
+ } \
+ typedef Value CArrValue_##tag
+
+#endif
diff --git a/stc/carray.h b/stc/carray.h
deleted file mode 100644
index 4b5ab171..00000000
--- a/stc/carray.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/* MIT License
- *
- * Copyright (c) 2020 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 CARRAY__H__
-#define CARRAY__H__
-
-#include <stdlib.h>
-#include "cdefs.h"
-
-/* // demo:
-#include <stc/carray.h>
-declare_CArray(f, float);
-
-int main()
-{
- CArray3_f a3 = carray3_f_make(30, 20, 10, 0.f);
- carray3_f_data(a3, 5, 4)[3] = 10.2f; // a3[5][4][3]
- CArray2_f a2 = carray3_f_at(a3, 5); // sub-array reference (no data copy).
-
- printf("%f\n", carray2_f_value(a2, 4, 3)); // readonly lookup a2[4][3] (=10.2f)
- printf("%f\n", carray2_f_data(a2, 4)[3]); // same, but this is writable.
- printf("%f\n", carray2_f_at(a2, 4).data[3]); // same, via sub-array access.
-
- printf("%f\n", carray3_f_value(a3, 5, 4, 3)); // same data location, via a3 array.
- printf("%f\n", carray3_f_data(a3, 5, 4)[3]);
- printf("%f\n", carray3_f_at2(a3, 5, 4).data[3]);
-
- carray2_f_destroy(&a2); // does nothing, since it is a sub-array.
- carray3_f_destroy(&a3); // also invalidates a2.
-}
-*/
-
-#define carray1_xdim(a) ((a)._xdim & _carray_SUB)
-#define carray1_size(a) carray1_xdim(a)
-
-#define carray2_xdim(a) carray1_xdim(a)
-#define carray2_ydim(a) _carray2_ydim(&(a)._yxdim)
-#define carray2_size(a) ((a)._yxdim)
-
-#define carray3_xdim(a) carray1_xdim(a)
-#define carray3_ydim(a) carray2_ydim(a)
-#define carray3_zdim(a) ((a)._zdim)
-#define carray3_size(a) _carray3_size(&(a)._zdim)
-
-#define _carray_SUB (SIZE_MAX >> 1)
-#define _carray_OWN (_carray_SUB + 1)
-
-static inline size_t _carray2_ydim(const size_t* yxdim) {
- return yxdim[0] / (yxdim[-1] & _carray_SUB);
-}
-static inline size_t _carray3_size(const size_t* zdim) {
- return zdim[0] * zdim[-1];
-}
-
-
-#define declare_CArray(...) c_MACRO_OVERLOAD(declare_CArray, __VA_ARGS__)
-
-#define declare_CArray_2(tag, Value) \
- declare_CArray_3(tag, Value, c_defaultDestroy)
-
-
-#define declare_CArray_3(tag, Value, valueDestroy) \
- typedef struct { \
- Value *data; \
- size_t _xdim; \
- } CArray1_##tag; \
- \
- typedef struct { \
- Value *data; \
- size_t _xdim, _yxdim; \
- } CArray2_##tag; \
- \
- typedef struct { \
- Value *data; \
- size_t _xdim, _yxdim, _zdim; \
- } CArray3_##tag; \
- \
- static inline CArray1_##tag \
- carray1_##tag##_make(size_t xdim, Value val) { \
- Value* m = c_new_N(Value, xdim); \
- for (size_t i=0; i<xdim; ++i) m[i] = val; \
- CArray1_##tag a = {m, xdim | _carray_OWN}; \
- return a; \
- } \
- static inline CArray2_##tag \
- carray2_##tag##_make(size_t ydim, size_t xdim, Value val) { \
- const size_t n = ydim * xdim; \
- Value* m = c_new_N(Value, n); \
- for (size_t i=0; i<n; ++i) m[i] = val; \
- CArray2_##tag a = {m, xdim | _carray_OWN, ydim * xdim}; \
- return a; \
- } \
- static inline CArray3_##tag \
- carray3_##tag##_make(size_t zdim, size_t ydim, size_t xdim, Value val) { \
- const size_t n = zdim * ydim * xdim; \
- Value* m = c_new_N(Value, n); \
- for (size_t i=0; i<n; ++i) m[i] = val; \
- CArray3_##tag a = {m, xdim | _carray_OWN, ydim * xdim, zdim}; \
- return a; \
- } \
- \
- static inline CArray1_##tag \
- carray1_##tag##_makeFrom(size_t xdim, Value* array, bool own) { \
- CArray1_##tag a = {array, xdim | (own ? _carray_OWN : 0)}; \
- return a; \
- } \
- static inline CArray2_##tag \
- carray2_##tag##_makeFrom(size_t ydim, size_t xdim, Value* array, bool own) { \
- CArray2_##tag a = {array, xdim | (own ? _carray_OWN : 0), ydim * xdim}; \
- return a; \
- } \
- static inline CArray3_##tag \
- carray3_##tag##_makeFrom(size_t zdim, size_t ydim, size_t xdim, Value* array, bool own) { \
- CArray3_##tag a = {array, xdim | (own ? _carray_OWN : 0), ydim * xdim, zdim}; \
- return a; \
- } \
- \
- static inline void \
- carray1_##tag##_destroy(CArray1_##tag* self) { \
- if (self->_xdim & _carray_OWN) { \
- size_t n = carray1_size(*self); Value* a = self->data; \
- while (n--) valueDestroy(&a[n]); free(a); \
- } \
- } \
- static inline void \
- carray2_##tag##_destroy(CArray2_##tag* self) { \
- if (self->_xdim & _carray_OWN) { \
- size_t n = carray2_size(*self); Value* a = self->data; \
- while (n--) valueDestroy(&a[n]); free(a); \
- } \
- } \
- static inline void \
- carray3_##tag##_destroy(CArray3_##tag* self) { \
- if (self->_xdim & _carray_OWN) { \
- size_t n = carray3_size(*self); Value* a = self->data; \
- while (n--) valueDestroy(&a[n]); free(a); \
- } \
- } \
- \
- static inline CArray1_##tag \
- carray2_##tag##_at(CArray2_##tag a, size_t y) { \
- CArray1_##tag sub = {a.data + y*carray2_xdim(a), carray2_xdim(a)}; \
- return sub; \
- } \
- static inline Value* \
- carray2_##tag##_data(CArray2_##tag a, size_t y) { \
- return a.data + y*carray2_xdim(a); \
- } \
- static inline Value \
- carray2_##tag##_value(CArray2_##tag a, size_t y, size_t x) { \
- return a.data[ y*carray2_xdim(a) + x ]; \
- } \
- \
- static inline CArray2_##tag \
- carray3_##tag##_at(CArray3_##tag a, size_t z) { \
- CArray2_##tag sub = {a.data + z*a._yxdim, carray3_xdim(a), a._yxdim}; \
- return sub; \
- } \
- static inline CArray1_##tag \
- carray3_##tag##_at2(CArray3_##tag a, size_t z, size_t y) { \
- CArray1_##tag sub = {a.data + z*a._yxdim + y*carray3_xdim(a), carray3_xdim(a)}; \
- return sub; \
- } \
- static inline Value* \
- carray3_##tag##_data(CArray3_##tag a, size_t z, size_t y) { \
- return a.data + z*a._yxdim + y*carray3_xdim(a); \
- } \
- static inline Value \
- carray3_##tag##_value(CArray3_##tag a, size_t z, size_t y, size_t x) { \
- return a.data[ z*a._yxdim + y*carray3_xdim(a) + x ]; \
- } \
- typedef Value CArrayValue_##tag
-
-#endif
diff --git a/stc/cdefs.h b/stc/cdefs.h
index 88c160a4..9ab3ed79 100644
--- a/stc/cdefs.h
+++ b/stc/cdefs.h
@@ -64,10 +64,12 @@
#define c_defaultInitRaw(x) (x)
#define c_defaultGetRaw(ptr) (*(ptr))
-#define c_defaultCompare(x, y) (*(x) < *(y) ? -1 : *(y) < *(x))
#define c_noCompare(x, y) (0)
-#define c_defaultEquals(x, y) (*(x) == *(y))
#define c_memEquals(x, y) (memcmp(x, y, sizeof(*(y))) == 0)
+#define c_defaultEquals(x, y) (*(x) == *(y))
+#define c_defaultLess(x, y) (*(x) < *(y))
+#define c_compare(less, x, y) (less(x, y) ? -1 : less(y, x))
+#define c_defaultCompare(x, y) c_compare(c_defaultLess, x, y)
#define c_defaultDestroy(p) ((void)0)
#define c_foreach(it, prefix, container) \
diff --git a/stc/clist.h b/stc/clist.h
index 9d26f7f3..7f9be5e6 100644
--- a/stc/clist.h
+++ b/stc/clist.h
@@ -118,16 +118,21 @@
STC_API void \
clist_##tag##_sort(CList_##tag* self); \
\
- static inline clist_##tag##_iter_t \
+ STC_INLINE Value* \
+ clist_##tag##_front(CList_##tag* self) {return &self->last->next->value;} \
+ STC_INLINE Value* \
+ clist_##tag##_back(CList_##tag* self) {return &self->last->value;} \
+ \
+ STC_INLINE clist_##tag##_iter_t \
clist_##tag##_begin(CList_##tag* self) { \
CListNode_##tag *head = self->last ? self->last->next : NULL; \
clist_##tag##_iter_t it = {head, &self->last}; return it; \
} \
- static inline clist_##tag##_iter_t \
+ STC_INLINE clist_##tag##_iter_t \
clist_##tag##_next(clist_##tag##_iter_t it) { \
it.item = it.item == *it._last ? NULL : it.item->next; return it; \
} \
- static inline clist_##tag##_iter_t \
+ STC_INLINE clist_##tag##_iter_t \
clist_##tag##_last(CList_##tag* self) { \
clist_##tag##_iter_t it = {self->last, &self->last}; return it; \
} \
diff --git a/stc/cmap.h b/stc/cmap.h
index c0a887b4..d9a3ed36 100644
--- a/stc/cmap.h
+++ b/stc/cmap.h
@@ -38,8 +38,8 @@ int main(void) {
cmap_mx_put(&m, 5, 'a');
cmap_mx_put(&m, 8, 'b');
cmap_mx_put(&m, 12, 'c');
- CMapEntry_mx *e = cmap_mx_get(&m, 10); // = NULL
- char val = cmap_mx_get(&m, 5)->value;
+ CMapEntry_mx *e = cmap_mx_find(&m, 10); // = NULL
+ char val = cmap_mx_find(&m, 5)->value;
cmap_mx_put(&m, 5, 'd'); // update
cmap_mx_erase(&m, 8);
c_foreach (i, cmap_mx, m) printf("map %d: %c\n", i.item->key, i.item->value);
@@ -168,10 +168,10 @@ ctype##_##tag##_clear(CType##_##tag* self); \
STC_API void \
ctype##_##tag##_setLoadFactors(CType##_##tag* self, float maxLoadFactor, float shrinkLimitFactor); \
STC_API CType##Entry_##tag* \
-ctype##_##tag##_get(const CType##_##tag* self, CType##RawKey_##tag rawKey); \
-STC_API CType##Entry_##tag* \
+ctype##_##tag##_find(const CType##_##tag* self, CType##RawKey_##tag rawKey); \
+STC_API CType##Entry_##tag* /* similar to c++ std::map.insert_or_assign(): */ \
ctype##_##tag##_put(CType##_##tag* self, OPT_2_##ctype(CType##RawKey_##tag rawKey, Value value)); \
-OPT_1_##ctype(STC_API CType##Entry_##tag* \
+OPT_1_##ctype(STC_API CType##Entry_##tag* /* similar to c++ std::map.operator[](): */ \
ctype##_##tag##_at(CType##_##tag* self, CType##RawKey_##tag rawKey, Value initValue);) \
STC_INLINE void \
ctype##_##tag##_swap(CType##_##tag* a, CType##_##tag* b) { c_swap(CType##_##tag, *a, *b); } \
@@ -252,7 +252,7 @@ ctype##_##tag##_bucket(const CType##_##tag* self, const CType##RawKey_##tag* raw
} \
\
STC_API CType##Entry_##tag* \
-ctype##_##tag##_get(const CType##_##tag* self, CType##RawKey_##tag rawKey) { \
+ctype##_##tag##_find(const CType##_##tag* self, CType##RawKey_##tag rawKey) { \
if (self->size == 0) return NULL; \
uint32_t hx; \
size_t idx = ctype##_##tag##_bucket(self, &rawKey, &hx); \
diff --git a/stc/cvec.h b/stc/cvec.h
index c2dfd525..35110294 100644
--- a/stc/cvec.h
+++ b/stc/cvec.h
@@ -66,10 +66,12 @@ cvec_##tag##_popBack(CVec_##tag* self) { \
valueDestroy(&self->data[_cvec_size(*self) - 1]); \
--_cvec_size(*self); \
} \
-STC_INLINE Value \
-cvec_##tag##_back(CVec_##tag cv) { \
- return cv.data[_cvec_size(cv) - 1]; \
-} \
+STC_INLINE Value* \
+cvec_##tag##_front(CVec_##tag* self) {return self->data;} \
+STC_INLINE Value* \
+cvec_##tag##_back(CVec_##tag* self) {return self->data + _cvec_size(*self) - 1;} \
+STC_INLINE Value* \
+cvec_##tag##_at(CVec_##tag* self, size_t i) {return self->data + i;} \
STC_API void \
cvec_##tag##_insert(CVec_##tag* self, size_t pos, Value value); \
STC_API void \
@@ -77,7 +79,7 @@ cvec_##tag##_erase(CVec_##tag* self, size_t pos, size_t size); \
STC_API void \
cvec_##tag##_sort(CVec_##tag* self); \
STC_API size_t \
-cvec_##tag##_find(CVec_##tag cv, RawValue rawValue); \
+cvec_##tag##_find(const CVec_##tag* self, RawValue rawValue); \
STC_INLINE void \
cvec_##tag##_swap(CVec_##tag* a, CVec_##tag* b) { \
c_swap(Value*, a->data, b->data); \
@@ -182,13 +184,13 @@ cvec_##tag##_erase(CVec_##tag* self, size_t pos, size_t size) { \
} \
\
STC_API size_t \
-cvec_##tag##_find(CVec_##tag cv, RawValue rawValue) { \
- size_t n = cvec_size(cv); \
- for (size_t i = 0; i < n; ++i) { \
- RawValue r = valueGetRaw(&cv.data[i]); \
- if (valueCompareRaw(&r, &rawValue) == 0) return i; \
+cvec_##tag##_find(const CVec_##tag* self, RawValue rawValue) { \
+ const Value *p = self->data, *end = p + cvec_size(*self); \
+ for (; p != end; ++p) { \
+ RawValue r = valueGetRaw(p); \
+ if (valueCompareRaw(&r, &rawValue) == 0) return p - self->data; \
} \
- return (size_t) (-1); /*SIZE_MAX;*/ \
+ return SIZE_MAX; /*(size_t) (-1)*/ \
} \
\
STC_API int \
diff --git a/stc/cvecpq.h b/stc/cvecpq.h
index 441859a5..993ca841 100644
--- a/stc/cvecpq.h
+++ b/stc/cvecpq.h
@@ -84,9 +84,10 @@ _cvec_##tag##_siftDown(CVecValue_##tag* arr, size_t i, size_t n) { \
\
STC_API void \
cvec_##tag##_eraseFromPriorityQ(CVec_##tag* self, size_t i) { \
- self->data[i] = cvec_##tag##_back(*self); \
+ size_t n = cvec_size(*self) - 1; \
+ self->data[i] = self->data[n]; \
cvec_##tag##_popBack(self); \
- _cvec_##tag##_siftDown(self->data - 1, i + 1, cvec_size(*self)); \
+ _cvec_##tag##_siftDown(self->data - 1, i + 1, n); \
} \
\
STC_API void \