summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2021-01-24 00:01:27 +0100
committerTyge Løvset <[email protected]>2021-01-24 00:01:27 +0100
commitdcf8d43f14d7116561957089192451b9ac832872 (patch)
tree04182abf9f7988d965998db062a35bbde3d22899
parent5fbc99f7004f3b8a1634cc9dc35199542126da63 (diff)
downloadSTC-modified-dcf8d43f14d7116561957089192451b9ac832872.tar.gz
STC-modified-dcf8d43f14d7116561957089192451b9ac832872.zip
Improved cvec cdeq. Must be initied with cvec_X_init() and cdeq_X_init(). Not cvec_inits.
Improved docs.
-rw-r--r--benchmarks/cdeq_benchmark.cpp6
-rw-r--r--benchmarks/crand_benchmark.cpp38
-rw-r--r--benchmarks/vector_vs_deque.cpp4
-rw-r--r--docs/ccommon_api.md26
-rw-r--r--docs/cpque_api.md2
-rw-r--r--docs/cptr_api.md6
-rw-r--r--docs/cqueue_api.md2
-rw-r--r--docs/cstack_api.md2
-rw-r--r--docs/cstr_api.md2
-rw-r--r--docs/cvec_api.md2
-rw-r--r--examples/complex.c2
-rw-r--r--examples/demos.c6
-rw-r--r--examples/inits.c6
-rw-r--r--examples/list.c2
-rw-r--r--examples/ptr.c6
-rw-r--r--stc/cdeq.h50
-rw-r--r--stc/clist.h8
-rw-r--r--stc/cvec.h55
18 files changed, 132 insertions, 93 deletions
diff --git a/benchmarks/cdeq_benchmark.cpp b/benchmarks/cdeq_benchmark.cpp
index ea1c69b3..b56c5c38 100644
--- a/benchmarks/cdeq_benchmark.cpp
+++ b/benchmarks/cdeq_benchmark.cpp
@@ -51,7 +51,7 @@ void test2() {
clock_t t1 = clock(), t2, t3;
stc64_t rng = stc64_init(0);
{
- cdeq_i deq = cdeq_inits;
+ cdeq_i deq = cdeq_i_init();
for (size_t i = 1; i < N; i++) {
cdeq_i_push_front(&deq, stc64_rand(&rng));
if (i % M == 0)
@@ -68,7 +68,7 @@ void test2() {
printf("stc access : %5.2f sec, sum=%zu\n", (float)(t3 - t2) / CLOCKS_PER_SEC, sum);
cdeq_i_del(&deq);
}{
- cdeq_i deq = cdeq_inits;
+ cdeq_i deq = cdeq_i_init();
for (size_t i = 1; i < N/10; i++) {
if (i & 1) cdeq_i_push_front(&deq, stc64_rand(&rng));
else cdeq_i_push_back(&deq, stc64_rand(&rng));
@@ -77,7 +77,7 @@ void test2() {
printf("stc pushf/pushb : %5.2f sec\n", (float)(t2 - t3) / CLOCKS_PER_SEC);
cdeq_i_del(&deq);
}{
- cdeq_i deq = cdeq_inits;
+ cdeq_i deq = cdeq_i_init();
for (size_t i = 1; i < N/2; i++) {
cdeq_i_push_back(&deq, stc64_rand(&rng));
}
diff --git a/benchmarks/crand_benchmark.cpp b/benchmarks/crand_benchmark.cpp
index 136dcf30..df13befd 100644
--- a/benchmarks/crand_benchmark.cpp
+++ b/benchmarks/crand_benchmark.cpp
@@ -66,14 +66,28 @@ static inline uint64_t xoshiro256starstar(uint64_t* s) {
return result;
}
-
-inline unsigned long long wyhash64(uint64_t* s) {
- *s += 0x60bee2bee120fc15ull;
- __uint128_t tmp = (__uint128_t) *s * 0xa3b195354a39b70dull;
- unsigned long long m1 = (tmp >> 64) ^ tmp;
- tmp = (__uint128_t)m1 * 0x1b03738712fad5c9ull;
- return (tmp >> 64) ^ tmp;
+// wyrand - 2020-12-07
+static inline void _wymum(uint64_t *A, uint64_t *B){
+#if defined(__SIZEOF_INT128__)
+ __uint128_t r = *A; r *= *B;
+ *A = (uint64_t) r; *B = (uint64_t ) (r >> 64);
+#elif defined(_MSC_VER) && defined(_M_X64)
+ *A = _umul128(*A, *B, B);
+#else
+ uint64_t ha=*A>>32, hb=*B>>32, la=(uint32_t)*A, lb=(uint32_t)*B, hi, lo;
+ uint64_t rh=ha*hb, rm0=ha*lb, rm1=hb*la, rl=la*lb, t=rl+(rm0<<32), c=t<rl;
+ lo=t+(rm1<<32); c+=lo<t; hi=rh+(rm0>>32)+(rm1>>32)+c;
+ *A=lo; *B=hi;
+#endif
+}
+static inline uint64_t _wymix(uint64_t A, uint64_t B){
+ _wymum(&A,&B); return A^B;
}
+static inline uint64_t wyrand64(uint64_t *seed){
+ static const uint64_t _wyp[] = {0xa0761d6478bd642full, 0xe7037ed1a0b428dbull};
+ *seed+=_wyp[0]; return _wymix(*seed,*seed^_wyp[1]);
+}
+
inline unsigned long long lehmer64(uint64_t* s) {
*(__uint128_t *)s *= 0xda942042e4dd58b5ull;
@@ -91,16 +105,16 @@ int main(void)
cout << "WARMUP" << endl;
for (size_t i = 0; i < N; i++)
- recipient[i] = wyhash64(rng.state);
+ recipient[i] = wyrand64(rng.state);
clock_t beg, end;
for (size_t ti = 0; ti < 4; ti++) {
cout << endl << "ROUND " << ti+1 << endl;
beg = clock();
for (size_t i = 0; i < N; i++)
- recipient[i] = wyhash64(rng.state);
+ recipient[i] = wyrand64(rng.state);
end = clock();
- cout << "wyhash64:\t"
+ cout << "wyrand64:\t"
<< (float(end - beg) / CLOCKS_PER_SEC)
<< " s: " << recipient[312] << endl;
beg = clock();
@@ -140,9 +154,9 @@ int main(void)
uint64_t s = 0;
beg = clock();
for (size_t i = 0; i < N; i++)
- s += wyhash64(rng.state);
+ s += wyrand64(rng.state);
end = clock();
- cout << "wyhash64:\t"
+ cout << "wyrand64:\t"
<< ((float) end - beg) / CLOCKS_PER_SEC
<< " s: " << s << endl;
diff --git a/benchmarks/vector_vs_deque.cpp b/benchmarks/vector_vs_deque.cpp
index a488b7ab..46da98b7 100644
--- a/benchmarks/vector_vs_deque.cpp
+++ b/benchmarks/vector_vs_deque.cpp
@@ -12,7 +12,7 @@
typedef struct {const char* first; int second;} Si;
using_cvec(si, Si, c_no_compare);
-cvec_si tm = cvec_inits;
+cvec_si tm = cvec_si_init();
void add(cvec_si* tm, const char* s, int n) { Si si = {s, n}; cvec_si_push_back(tm, si); }
@@ -176,7 +176,7 @@ using_cvec(i, int);
void test_cvec(const int num_iterations)
{
- cvec_i v = cvec_inits;
+ cvec_i v = cvec_i_init();
stc64_t rng = stc64_init(0);
//v.reserve(num_iterations + 2); //Ensure there is enough space reserved.
diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md
index b6f0b83c..9e1d1767 100644
--- a/docs/ccommon_api.md
+++ b/docs/ccommon_api.md
@@ -1,16 +1,35 @@
-# STC Module [ccommon](../stc/ccommon.h): Common methods and definitions
+# STC [ccommon](../stc/ccommon.h): Common definitions and safe macros
This describes the features the ccommon.h header file.
## Macros
+The following macros a completely safe to use, with no side-effects.
#### c_new, c_del
+- Type* c_new (VType)
+- Type* c_new (VType, size_t N)
+- c_del (CType, CType* x1, ..., CType* xN)
#### c_malloc, c_calloc, c_realloc, c_free
+Macros that can be overloaded by user to use a different allocator for the entire library
#### c_foreach
+- c_foreach (it, CType, container)
+```c
+using_cvec(x, double);
+...
+cvec_x vec = cvec_x_init();
+double sum = 0;
+c_foreach (i, cvec_x, vec) sum += *i.ref;
+```
#### c_forrange
+Declare an iterator and specify a range to iterate with a for loop.
+- c_forrange (end)
+- c_forrange (it, end)
+- c_forrange (it, IterType, end)
+- c_forrange (it, IterType, begin, end)
+- c_forrange (it, IterType, begin, end, step)
#### c_withbuffer
@@ -19,8 +38,3 @@ This describes the features the ccommon.h header file.
#### c_push_items
#### c_swap
-
-## Example
-
-```c
-```
diff --git a/docs/cpque_api.md b/docs/cpque_api.md
index e85b8bb9..a1762fbe 100644
--- a/docs/cpque_api.md
+++ b/docs/cpque_api.md
@@ -1,4 +1,4 @@
-# STC Container [cpque](../stc/cpque.h): Priority Queue
+# STC [cpque](../stc/cpque.h): Priority Queue
A priority queue is a container adaptor that provides constant time lookup of the largest (by default) element, at the expense of logarithmic insertion and extraction.
A user-provided argument `<`or `>` must be supplied to set the ordering, e.g. using `>` would cause the smallest element to appear as the top().
diff --git a/docs/cptr_api.md b/docs/cptr_api.md
index f95b0062..f1fd0cf1 100644
--- a/docs/cptr_api.md
+++ b/docs/cptr_api.md
@@ -110,9 +110,9 @@ const char* names[] = {
};
int main() {
- cvec_pe vec1 = cvec_inits;
- cvec_pp vec2 = cvec_inits;
- cvec_ps vec3 = cvec_inits;
+ cvec_pe vec1 = cvec_pe_init();
+ cvec_pp vec2 = cvec_pp_init();
+ cvec_ps vec3 = cvec_ps_init();
for (int i = 0; i < 6; i += 2) {
Person tmp;
diff --git a/docs/cqueue_api.md b/docs/cqueue_api.md
index 7a225e92..fee5bee4 100644
--- a/docs/cqueue_api.md
+++ b/docs/cqueue_api.md
@@ -1,4 +1,4 @@
-# STC Container [cqueue](../stc/cqueue.h): Queue
+# STC [cqueue](../stc/cqueue.h): Queue
![Queue](pics/queue.jpg)
The **cqueue** is container adapter that gives the programmer the functionality of a queue - specifically, a FIFO (first-in, first-out) data structure. The class template acts as a wrapper to the underlying container - only a specific set of functions is provided. The queue pushes the elements on the back of the underlying container and pops them from the front.
diff --git a/docs/cstack_api.md b/docs/cstack_api.md
index 764b258b..3028f6cb 100644
--- a/docs/cstack_api.md
+++ b/docs/cstack_api.md
@@ -3,7 +3,7 @@
The **cstack** is a container adapter that gives the programmer the functionality of a stack - specifically, a LIFO (last-in, first-out) data structure. The class template acts as a wrapper to the underlying container - only a specific set of functions is provided. The stack pushes and pops the element from the back of the underlying container, known as the top of the stack.
-See [std::stack](https://en.cppreference.com/w/cpp/container/stack) for a similar c++ class.
+See the c++ class [std::stack](https://en.cppreference.com/w/cpp/container/stack) for a functional description.
## Declaration
diff --git a/docs/cstr_api.md b/docs/cstr_api.md
index c6292906..d5e2f4b0 100644
--- a/docs/cstr_api.md
+++ b/docs/cstr_api.md
@@ -3,7 +3,7 @@
A **cstr* is an object that represent sequences of characters. It supports an interface similar to that of a standard container of bytes, but adding features specifically designed to operate with strings of single-byte characters.
-See [std::basic_string](https://en.cppreference.com/w/cpp/string/basic_string) for a similar c++ class.
+See the c++ class [std::basic_string](https://en.cppreference.com/w/cpp/string/basic_string) for a functional description.
## Header file
diff --git a/docs/cvec_api.md b/docs/cvec_api.md
index 8cc7af15..aeaf8ca7 100644
--- a/docs/cvec_api.md
+++ b/docs/cvec_api.md
@@ -114,7 +114,7 @@ using_cvec(i, int);
int main()
{
// Create a vector containing integers
- cvec_i vec = cvec_inits;
+ cvec_i vec = cvec_i_init();
c_push_items(&vec, cvec_i, {7, 5, 16, 8});
// Add two more integers to vector
diff --git a/examples/complex.c b/examples/complex.c
index 1346007a..67397669 100644
--- a/examples/complex.c
+++ b/examples/complex.c
@@ -22,7 +22,7 @@ int main() {
carray2f arr_a = carray2f_init(ydim, xdim, 0.f);
printf("arr_a: (%zu, %zu)\n", carray2f_ydim(arr_a), carray2f_xdim(arr_a));
- clist_a tableList = clist_inits;
+ clist_a tableList = clist_a_init();
// Put in some data.
*carray2f_at(&arr_a, y, x) = 3.1415927f; // aa[y][x]
clist_a_push_back(&tableList, arr_a);
diff --git a/examples/demos.c b/examples/demos.c
index e460591b..2ee267e6 100644
--- a/examples/demos.c
+++ b/examples/demos.c
@@ -39,7 +39,7 @@ using_cvec(ix, int64_t); // ix is just an example tag name.
void vectordemo1()
{
printf("\nVECTORDEMO1\n");
- cvec_ix bignums = cvec_inits; // = (cvec_ix) cvec_inits; if initializing after declaration.
+ cvec_ix bignums = cvec_ix_init();
cvec_ix_reserve(&bignums, 100);
for (size_t i = 10; i <= 100; i += 10)
cvec_ix_push_back(&bignums, i * i);
@@ -63,7 +63,7 @@ using_cvec_str();
void vectordemo2()
{
printf("\nVECTORDEMO2\n");
- cvec_str names = cvec_inits;
+ cvec_str names = cvec_str_init();
cvec_str_emplace_back(&names, "Mary");
cvec_str_emplace_back(&names, "Joe");
cvec_str_emplace_back(&names, "Chris");
@@ -81,7 +81,7 @@ using_clist(ix, int);
void listdemo1()
{
printf("\nLISTDEMO1\n");
- clist_ix nums = clist_inits, nums2 = clist_inits;
+ clist_ix nums = clist_ix_init(), nums2 = clist_ix_init();
for (int i = 0; i < 10; ++i)
clist_ix_push_back(&nums, i);
for (int i = 100; i < 110; ++i)
diff --git a/examples/inits.c b/examples/inits.c
index 1ef722ea..759fc7a7 100644
--- a/examples/inits.c
+++ b/examples/inits.c
@@ -23,7 +23,7 @@ int main(void)
{
// CVEC FLOAT / PRIORITY QUEUE
- cvec_f floats = cvec_inits;
+ cvec_f floats = cvec_f_init();
c_push_items(&floats, cvec_f, {4.0f, 2.0f, 5.0f, 3.0f, 1.0f});
c_foreach (i, cvec_f, floats) printf("%.1f ", *i.ref);
@@ -82,7 +82,7 @@ int main(void)
// CVEC PAIR
- cvec_ip pairs1 = cvec_inits;
+ cvec_ip pairs1 = cvec_ip_init();
c_push_items(&pairs1, cvec_ip, {
{5, 6},
{3, 4},
@@ -98,7 +98,7 @@ int main(void)
// CLIST PAIR
- clist_ip pairs2 = clist_inits;
+ clist_ip pairs2 = clist_ip_init();
c_push_items(&pairs2, clist_ip, {
{5, 6},
{3, 4},
diff --git a/examples/list.c b/examples/list.c
index 394d0b38..84ef90f7 100644
--- a/examples/list.c
+++ b/examples/list.c
@@ -8,7 +8,7 @@ int main() {
int k;
const int n = 2000000;
- clist_fx list = clist_inits;
+ clist_fx list = clist_fx_init();
stc64_t rng = stc64_init(1234);
stc64_uniformf_t dist = stc64_uniformf_init(100.0f, n);
int m = 0;
diff --git a/examples/ptr.c b/examples/ptr.c
index a7b18ad5..98fe0811 100644
--- a/examples/ptr.c
+++ b/examples/ptr.c
@@ -40,9 +40,9 @@ const char* names[] = {
};
int main() {
- cvec_pe vec1 = cvec_inits;
- cvec_pp vec2 = cvec_inits;
- cvec_ps vec3 = cvec_inits;
+ cvec_pe vec1 = cvec_pe_init();
+ cvec_pp vec2 = cvec_pp_init();
+ cvec_ps vec3 = cvec_ps_init();
for (int i = 0; i < 6; i += 2) {
Person tmp;
diff --git a/stc/cdeq.h b/stc/cdeq.h
index f714b0cb..4b89b15c 100644
--- a/stc/cdeq.h
+++ b/stc/cdeq.h
@@ -27,8 +27,6 @@
#include <stdlib.h>
#include <string.h>
-#define cdeq_inits {NULL, NULL}
-
#define using_cdeq(...) c_MACRO_OVERLOAD(using_cdeq, __VA_ARGS__)
#define using_cdeq_2(X, Value) \
using_cdeq_3(X, Value, c_default_compare)
@@ -50,14 +48,14 @@
#define using_cdeq_7(X, Value, valueCompareRaw, valueDestroy, valueFromRaw, valueToRaw, RawValue) \
typedefs_cdeq(X, Value, RawValue); \
\
- STC_INLINE cdeq_##X \
- cdeq_##X##_init(void) {cdeq_##X deq = cdeq_inits; return deq;} \
+ STC_API cdeq_##X \
+ cdeq_##X##_init(void); \
STC_INLINE bool \
- cdeq_##X##_empty(cdeq_##X deq) {return !deq.base || _cdeq_size(&deq) == 0;} \
+ cdeq_##X##_empty(cdeq_##X deq) {return !_cdeq_size(&deq);} \
STC_INLINE size_t \
- cdeq_##X##_size(cdeq_##X deq) {return deq.base ? _cdeq_size(&deq) : 0;} \
+ cdeq_##X##_size(cdeq_##X deq) {return _cdeq_size(&deq);} \
STC_INLINE size_t \
- cdeq_##X##_capacity(cdeq_##X deq) {return deq.base ? _cdeq_capacity(&deq) : 0;} \
+ cdeq_##X##_capacity(cdeq_##X deq) {return _cdeq_cap(&deq);} \
STC_INLINE Value \
cdeq_##X##_value_from_raw(RawValue raw) {return valueFromRaw(raw);} \
STC_INLINE cdeq_##X##_value_t \
@@ -75,13 +73,13 @@
\
STC_INLINE cdeq_##X \
cdeq_##X##_with_size(size_t size, Value null_val) { \
- cdeq_##X x = cdeq_inits; \
+ cdeq_##X x = cdeq_##X##_init(); \
cdeq_##X##_resize(&x, size, null_val); \
return x; \
} \
STC_INLINE cdeq_##X \
cdeq_##X##_with_capacity(size_t size) { \
- cdeq_##X x = cdeq_inits; \
+ cdeq_##X x = cdeq_##X##_init(); \
_cdeq_##X##_expand(&x, size, false); \
return x; \
} \
@@ -182,7 +180,7 @@
} \
STC_INLINE void \
cdeq_##X##_sort(cdeq_##X* self) { \
- cdeq_##X##_sort_with(self, 0, cdeq_##X##_size(*self), cdeq_##X##_value_compare); \
+ cdeq_##X##_sort_with(self, 0, _cdeq_size(self), cdeq_##X##_value_compare); \
} \
\
STC_INLINE cdeq_##X##_iter_t \
@@ -191,7 +189,7 @@
} \
STC_INLINE cdeq_##X##_iter_t \
cdeq_##X##_end(const cdeq_##X* self) { \
- cdeq_##X##_iter_t it = {self->data ? self->data + _cdeq_size(self) : NULL}; return it; \
+ cdeq_##X##_iter_t it = {self->data + _cdeq_size(self)}; return it; \
} \
STC_INLINE void \
cdeq_##X##_next(cdeq_##X##_iter_t* it) {++it->ref;} \
@@ -208,10 +206,16 @@
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
#define _c_implement_cdeq_7(X, Value, valueCompareRaw, valueDestroy, valueFromRaw, valueToRaw, RawValue) \
\
+ STC_DEF cdeq_##X \
+ cdeq_##X##_init(void) { \
+ cdeq_##X##_value_t *t = (cdeq_##X##_value_t *) (_cdeq_inits + 2); \
+ cdeq_##X deq = {t, t}; return deq; \
+ } \
+\
STC_DEF void \
cdeq_##X##_push_n(cdeq_##X *self, const cdeq_##X##_rawvalue_t arr[], size_t n) { \
_cdeq_##X##_expand(self, n, false); \
- cdeq_##X##_value_t* p = self->data + cdeq_##X##_size(*self); \
+ cdeq_##X##_value_t* p = self->data + _cdeq_size(self); \
for (size_t i=0; i < n; ++i) *p++ = valueFromRaw(arr[i]); \
_cdeq_size(self) += n; \
} \
@@ -227,18 +231,20 @@
STC_DEF void \
cdeq_##X##_del(cdeq_##X* self) { \
cdeq_##X##_clear(self); \
- if (self->base) c_free(_cdeq_alloced(self)); \
+ if (_cdeq_alloced(self) != _cdeq_inits) \
+ c_free(_cdeq_alloced(self)); \
} \
\
STC_DEF void \
_cdeq_##X##_expand(cdeq_##X* self, size_t n, bool at_front) { \
- size_t len = cdeq_##X##_size(*self), cap = cdeq_##X##_capacity(*self); \
+ size_t len = _cdeq_size(self), cap = _cdeq_cap(self); \
size_t nfront = self->data - self->base, nback = cap - (nfront + len); \
if (at_front && nfront >= n || !at_front && nback >= n) \
return; \
if ((len + n)*1.3 > cap) { \
cap = (len + n + 6)*1.8; \
- size_t* rep = (size_t *) c_realloc(_cdeq_alloced(self), 2*sizeof(size_t) + cap*sizeof(Value)); \
+ size_t* rep = (size_t *) c_realloc(_cdeq_alloced(self) != _cdeq_inits ? _cdeq_alloced(self) : NULL, \
+ 2*sizeof(size_t) + cap*sizeof(Value)); \
rep[0] = len, rep[1] = cap; \
self->base = (cdeq_##X##_value_t *) (rep + 2); \
self->data = self->base + nfront; \
@@ -254,7 +260,7 @@
STC_DEF void \
cdeq_##X##_resize(cdeq_##X* self, size_t size, Value null_val) { \
_cdeq_##X##_expand(self, size, false); \
- size_t i, n = cdeq_##X##_size(*self); \
+ size_t i, n = _cdeq_size(self); \
for (i=size; i<n; ++i) valueDestroy(self->data + i); \
for (i=n; i<size; ++i) self->data[i] = null_val; \
if (self->data) _cdeq_size(self) = size; \
@@ -269,14 +275,14 @@
} \
STC_DEF void \
cdeq_##X##_push_back(cdeq_##X* self, Value value) { \
- if (!self->data || _cdeq_nfront(self) + _cdeq_size(self) == _cdeq_capacity(self)) \
+ if (_cdeq_nfront(self) + _cdeq_size(self) == _cdeq_cap(self)) \
_cdeq_##X##_expand(self, 1, false); \
self->data[_cdeq_size(self)++] = value; \
} \
\
STC_DEF cdeq_##X \
cdeq_##X##_clone(cdeq_##X vec) { \
- size_t len = cdeq_##X##_size(vec); \
+ size_t len = _cdeq_size(&vec); \
cdeq_##X out = cdeq_##X##_with_capacity(len); \
cdeq_##X##_insert_range_p(&out, out.data, vec.data, vec.data + len); \
return out; \
@@ -285,7 +291,7 @@
STC_DEF cdeq_##X##_iter_t \
cdeq_##X##_insert_range_p(cdeq_##X* self, cdeq_##X##_value_t* pos, \
const cdeq_##X##_value_t* first, const cdeq_##X##_value_t* finish) { \
- size_t n = finish - first, idx = pos - self->data, size = cdeq_##X##_size(*self); \
+ size_t n = finish - first, idx = pos - self->data, size = _cdeq_size(self); \
bool at_front = (idx < size/2); \
_cdeq_##X##_expand(self, n, at_front); \
if (at_front) { \
@@ -335,6 +341,9 @@
return valueCompareRaw(&rx, &ry); \
}
+static size_t _cdeq_inits[2] = {0, 0};
+#define _cdeq_alloced(self) (((size_t *) (self)->base) - 2)
+
#else
#define _c_implement_cdeq_7(X, Value, valueCompareRaw, valueDestroy, valueFromRaw, valueToRaw, RawValue)
#endif
@@ -349,9 +358,8 @@ typedef int(*_cdeq_cmp)(const void*, const void*);
STC_EXTERN_IMPORT void qsort(void *start, size_t nitems, size_t size, _cdeq_cmp cmp);
#define _cdeq_size(self) ((size_t *) (self)->base)[-2]
-#define _cdeq_capacity(self) ((size_t *) (self)->base)[-1]
+#define _cdeq_cap(self) ((size_t *) (self)->base)[-1]
#define _cdeq_nfront(self) ((self)->data - (self)->base)
-#define _cdeq_alloced(self) ((self)->base ? ((size_t *) (self)->base) - 2 : NULL)
static inline double c_minf(double x, double y) { return x < y ? x : y; }
static inline double c_maxf(double x, double y) { return x > y ? x : y; }
diff --git a/stc/clist.h b/stc/clist.h
index 1673d71e..c9189ffa 100644
--- a/stc/clist.h
+++ b/stc/clist.h
@@ -35,7 +35,7 @@
using_clist(ix, int64_t);
int main() {
- clist_ix list = clist_inits;
+ clist_ix list = clist_ix_init();
stc64_t rng = stc64_init(12345);
int n;
for (int i=0; i<1000000; ++i) // one million
@@ -83,8 +83,6 @@
int _state; \
} clist_##X##_iter_t
-#define clist_inits {NULL}
-
#define c_emplace_after(self, ctype, pos, ...) do { \
ctype* __self = self; \
ctype##_iter_t __pos = pos; \
@@ -104,7 +102,7 @@ STC_API size_t _clist_size(const clist_void* self);
typedef RawValue clist_##X##_rawvalue_t; \
\
STC_INLINE clist_##X \
- clist_##X##_init(void) {clist_##X x = clist_inits; return x;} \
+ clist_##X##_init(void) {clist_##X x = {NULL}; return x;} \
STC_INLINE bool \
clist_##X##_empty(clist_##X ls) {return ls.last == NULL;} \
STC_INLINE size_t \
@@ -219,7 +217,7 @@ STC_API size_t _clist_size(const clist_void* self);
\
STC_DEF clist_##X \
clist_##X##_clone(clist_##X list) { \
- clist_##X out = clist_inits; \
+ clist_##X out = clist_##X##_init(); \
c_foreach_3 (i, clist_##X, list) \
clist_##X##_emplace_back(&out, valueToRaw(i.ref)); \
return out; \
diff --git a/stc/cvec.h b/stc/cvec.h
index 64b5dcd9..e8f24ac7 100644
--- a/stc/cvec.h
+++ b/stc/cvec.h
@@ -27,8 +27,6 @@
#include <stdlib.h>
#include <string.h>
-#define cvec_inits {NULL}
-
#define using_cvec(...) c_MACRO_OVERLOAD(using_cvec, __VA_ARGS__)
#define using_cvec_2(X, Value) \
using_cvec_3(X, Value, c_default_compare)
@@ -50,16 +48,14 @@
#define using_cvec_7(X, Value, valueCompareRaw, valueDestroy, valueFromRaw, valueToRaw, RawValue) \
typedefs_cvec(X, Value, RawValue); \
\
- STC_INLINE cvec_##X \
- cvec_##X##_init(void) {cvec_##X vec = cvec_inits; return vec;} \
+ STC_API cvec_##X \
+ cvec_##X##_init(void); \
STC_INLINE size_t \
- cvec_##X##_size(cvec_##X vec) \
- {return vec.data ? ((const size_t *) vec.data)[-2] : 0;} \
+ cvec_##X##_size(cvec_##X vec) { return _cvec_size(&vec); } \
STC_INLINE size_t \
- cvec_##X##_capacity(cvec_##X vec) \
- {return vec.data ? ((const size_t *) vec.data)[-1] : 0;} \
+ cvec_##X##_capacity(cvec_##X vec) { return _cvec_cap(&vec); } \
STC_INLINE bool \
- cvec_##X##_empty(cvec_##X vec) {return !cvec_##X##_size(vec);} \
+ cvec_##X##_empty(cvec_##X vec) {return !_cvec_size(&vec);} \
STC_INLINE Value \
cvec_##X##_value_from_raw(RawValue raw) {return valueFromRaw(raw);} \
STC_INLINE cvec_##X##_value_t \
@@ -77,13 +73,13 @@
\
STC_INLINE cvec_##X \
cvec_##X##_with_size(size_t size, Value null_val) { \
- cvec_##X x = cvec_inits; \
+ cvec_##X x = cvec_##X##_init(); \
cvec_##X##_resize(&x, size, null_val); \
return x; \
} \
STC_INLINE cvec_##X \
cvec_##X##_with_capacity(size_t size) { \
- cvec_##X x = cvec_inits; \
+ cvec_##X x = cvec_##X##_init(); \
cvec_##X##_reserve(&x, size); \
return x; \
} \
@@ -158,8 +154,8 @@
STC_INLINE cvec_##X##_value_t* \
cvec_##X##_back(cvec_##X* self) {return self->data + _cvec_size(self) - 1;} \
STC_INLINE cvec_##X##_value_t* \
- cvec_##X##_at(cvec_##X* self, size_t i) { \
- assert(i < cvec_##X##_size(*self)); \
+ cvec_##X##_at(cvec_##X* self, size_t i) { \
+ assert(i < _cvec_size(self)); \
return self->data + i; \
} \
\
@@ -171,7 +167,7 @@
} \
STC_INLINE void \
cvec_##X##_sort(cvec_##X* self) { \
- cvec_##X##_sort_with(self, 0, cvec_##X##_size(*self), cvec_##X##_value_compare); \
+ cvec_##X##_sort_with(self, 0, _cvec_size(self), cvec_##X##_value_compare); \
} \
\
STC_INLINE cvec_##X##_iter_t \
@@ -180,7 +176,7 @@
} \
STC_INLINE cvec_##X##_iter_t \
cvec_##X##_end(const cvec_##X* self) { \
- cvec_##X##_iter_t it = {self->data + cvec_##X##_size(*self)}; return it; \
+ cvec_##X##_iter_t it = {self->data + _cvec_size(self)}; return it; \
} \
STC_INLINE void \
cvec_##X##_next(cvec_##X##_iter_t* it) {++it->ref;} \
@@ -197,9 +193,14 @@
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
#define _c_implement_cvec_7(X, Value, valueCompareRaw, valueDestroy, valueFromRaw, valueToRaw, RawValue) \
\
+ STC_DEF cvec_##X \
+ cvec_##X##_init(void) { \
+ cvec_##X vec = {(cvec_##X##_value_t *) (_cvec_inits + 2)}; return vec; \
+ } \
+\
STC_DEF void \
cvec_##X##_push_n(cvec_##X *self, const cvec_##X##_rawvalue_t arr[], size_t n) { \
- cvec_##X##_reserve(self, cvec_##X##_size(*self) + n); \
+ cvec_##X##_reserve(self, _cvec_size(self) + n); \
cvec_##X##_value_t* p = self->data + _cvec_size(self); \
for (size_t i=0; i < n; ++i) *p++ = valueFromRaw(arr[i]); \
_cvec_size(self) += n; \
@@ -215,15 +216,17 @@
STC_DEF void \
cvec_##X##_del(cvec_##X* self) { \
cvec_##X##_clear(self); \
- if (self->data) c_free(_cvec_alloced(self->data)); \
+ if (_cvec_alloced(self) != _cvec_inits) \
+ c_free(_cvec_alloced(self)); \
} \
\
STC_DEF void \
cvec_##X##_reserve(cvec_##X* self, size_t cap) { \
size_t* rep; \
if (cap > cvec_##X##_capacity(*self)) { \
- size_t len = cvec_##X##_size(*self); \
- rep = (size_t *) c_realloc(_cvec_alloced(self->data), 2 * sizeof(size_t) + cap * sizeof(Value)); \
+ size_t len = _cvec_size(self); \
+ rep = (size_t *) c_realloc(_cvec_alloced(self) != _cvec_inits ? _cvec_alloced(self) : NULL, \
+ 2*sizeof(size_t) + cap*sizeof(Value)); \
self->data = (Value *) (rep + 2); \
rep[0] = len; \
rep[1] = cap; \
@@ -232,7 +235,7 @@
STC_DEF void \
cvec_##X##_resize(cvec_##X* self, size_t size, Value null_val) { \
cvec_##X##_reserve(self, size); \
- size_t i, n = cvec_##X##_size(*self); \
+ size_t i, n = _cvec_size(self); \
for (i=size; i<n; ++i) valueDestroy(self->data + i); \
for (i=n; i<size; ++i) self->data[i] = null_val; \
if (self->data) _cvec_size(self) = size; \
@@ -240,7 +243,7 @@
\
STC_DEF void \
cvec_##X##_push_back(cvec_##X* self, Value value) { \
- size_t len = cvec_##X##_size(*self); \
+ size_t len = _cvec_size(self); \
if (len == cvec_##X##_capacity(*self)) \
cvec_##X##_reserve(self, 4 + len*3/2); \
self->data[_cvec_size(self)++] = value; \
@@ -248,7 +251,7 @@
\
STC_DEF cvec_##X \
cvec_##X##_clone(cvec_##X vec) { \
- size_t len = cvec_##X##_size(vec); \
+ size_t len = _cvec_size(&vec); \
cvec_##X out = cvec_##X##_with_capacity(len); \
cvec_##X##_insert_range_p(&out, out.data, vec.data, vec.data + len); \
return out; \
@@ -256,7 +259,7 @@
\
STC_DEF cvec_##X##_iter_t \
cvec_##X##_insert_range_p(cvec_##X* self, cvec_##X##_value_t* pos, const cvec_##X##_value_t* first, const cvec_##X##_value_t* finish) { \
- size_t len = finish - first, idx = pos - self->data, size = cvec_##X##_size(*self); \
+ size_t len = finish - first, idx = pos - self->data, size = _cvec_size(self); \
cvec_##X##_iter_t it = {pos}; \
if (len == 0) return it; \
if (size + len > cvec_##X##_capacity(*self)) \
@@ -301,6 +304,9 @@
return valueCompareRaw(&rx, &ry); \
}
+static size_t _cvec_inits[2] = {0, 0};
+#define _cvec_alloced(self) (((size_t *) (self)->data) - 2)
+
#else
#define _c_implement_cvec_7(X, Value, valueCompareRaw, valueDestroy, valueFromRaw, valueToRaw, RawValue)
#endif
@@ -313,8 +319,7 @@
typedef int(*_cvec_cmp)(const void*, const void*);
STC_EXTERN_IMPORT void qsort(void *base, size_t nitems, size_t size, _cvec_cmp cmp);
-
#define _cvec_size(self) ((size_t *) (self)->data)[-2]
-#define _cvec_alloced(data) ((data) ? ((size_t *) (data)) - 2 : NULL)
+#define _cvec_cap(self) ((size_t *) (self)->data)[-1]
#endif