From 7fd50323b46599090d5cd9ade43a7cdb69c1e145 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Wed, 2 Sep 2020 20:56:22 +0200 Subject: Added cqueue.h, cstack.h and renamed cpqueue.h to cprique.h --- README.md | 2 +- examples/geek7.c | 14 +++--- examples/heap.c | 18 +++---- examples/inits.c | 14 +++--- examples/priority.c | 18 +++---- examples/queue.c | 31 ++++++++++++ stc/clist.h | 22 ++++++-- stc/cpqueue.h | 141 ---------------------------------------------------- stc/cprique.h | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++ stc/cqueue.h | 95 +++++++++++++++++++++++++++++++++++ stc/cstack.h | 82 ++++++++++++++++++++++++++++++ 11 files changed, 400 insertions(+), 178 deletions(-) create mode 100644 examples/queue.c delete mode 100644 stc/cpqueue.h create mode 100644 stc/cprique.h create mode 100644 stc/cqueue.h create mode 100644 stc/cstack.h diff --git a/README.md b/README.md index 03ecaf99..1b957255 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ An elegant, fully typesafe, generic, customizable, user-friendly, consistent, an - **stc/cset.h** - A generic **unordered set** implemented in tandem with *unordered map* - **stc/cstr.h** - Compact and powerful **string** class. - **stc/cvec.h** - Dynamic generic **vector** class, works well as a **stack**. -- **stc/cpqueue.h** - Priority queue adapter for **cvec.h**, as a **heap**. +- **stc/cprique.h** - Priority queue adapter for **cvec.h**, as a **heap**. - **stc/copt.h** - Implementation of a **getopt_long()**-like function, *copt_get()*, to parse command line arguments. - **stc/crandom.h** - A few very efficent modern random number generators *pcg32* and my own *64-bit PRNG* inspired by *sfc64*. Both uniform and normal distributions. - **stc/cdefs.h** - A common include file with a few general definitions. diff --git a/examples/geek7.c b/examples/geek7.c index 9004a1a8..c686b014 100644 --- a/examples/geek7.c +++ b/examples/geek7.c @@ -25,11 +25,11 @@ After inserting all the elements excluding the ones which are to be deleted, Pop #include #include #include -#include +#include declare_cmap(ii, int, int); declare_cvec(i, int); -declare_cpqueue(i, cvec_i, >); +declare_cprique(i, cvec_i, >); // Find k minimum element from arr[0..m-1] after deleting // elements from del[0..n-1] @@ -44,7 +44,7 @@ void findElementsAfterDel(int arr[], int m, int del[], cmap_ii_insert(&mp, del[i], 0)->value++; } - cpqueue_i heap = cpqueue_i_init(); + cprique_i heap = cprique_i_init(); for (int i = 0; i < m; ++i) { @@ -63,17 +63,17 @@ void findElementsAfterDel(int arr[], int m, int del[], // Else push it in the min heap else - cpqueue_i_push(&heap, arr[i]); + cprique_i_push(&heap, arr[i]); } // Print top k elements in the min heap for (int i = 0; i < k; ++i) { - printf("%d ", *cpqueue_i_top(&heap)); + printf("%d ", *cprique_i_top(&heap)); // Pop the top element - cpqueue_i_pop(&heap); + cprique_i_pop(&heap); } - cpqueue_i_destroy(&heap); + cprique_i_destroy(&heap); } int main() diff --git a/examples/heap.c b/examples/heap.c index 5917dd30..fbcef0cd 100644 --- a/examples/heap.c +++ b/examples/heap.c @@ -2,10 +2,10 @@ #include #include #include -#include +#include declare_cvec(f, float); -declare_cpqueue(f, cvec_f, >); +declare_cprique(f, cvec_f, >); int main() { @@ -13,33 +13,33 @@ int main() crand_rng32_t pcg; int N = 3000000, M = 100; - cpqueue_f pq = cpqueue_f_init(); + cprique_f pq = cprique_f_init(); pcg = crand_rng32_init(seed); clock_t start = clock(); for (int i=0; i #include #include -#include +#include #include declare_cmap(id, int, cstr_t, cstr_destroy); // Map of int -> cstr_t @@ -17,7 +17,7 @@ declare_cvec(ip, ipair_t, c_default_destroy, ipair_compare); declare_clist(ip, ipair_t, c_default_destroy, ipair_compare); declare_cvec(f, float); -declare_cpqueue(f, cvec_f, >); +declare_cprique(f, cvec_f, >); int main(void) { @@ -31,16 +31,16 @@ int main(void) { // CVEC PRIORITY QUEUE - cpqueue_f_build(&floats); // reorganise vec - c_push(&floats, cpqueue_f, c_items(40.0f, 20.0f, 50.0f, 30.0f, 10.0f)); + cprique_f_build(&floats); // reorganise vec + c_push(&floats, cprique_f, c_items(40.0f, 20.0f, 50.0f, 30.0f, 10.0f)); // sorted: while (cvec_size(floats) > 0) { - printf("%.1f ", *cpqueue_f_top(&floats)); - cpqueue_f_pop(&floats); + printf("%.1f ", *cprique_f_top(&floats)); + cprique_f_pop(&floats); } puts("\n"); - cpqueue_f_destroy(&floats); + cprique_f_destroy(&floats); // CMAP ID diff --git a/examples/priority.c b/examples/priority.c index 82e78621..fc0526bf 100644 --- a/examples/priority.c +++ b/examples/priority.c @@ -2,34 +2,34 @@ #include #include #include -#include +#include #include #include declare_cvec(i, int64_t); -declare_cpqueue(i, cvec_i, >); // min-heap (increasing values) +declare_cprique(i, cvec_i, >); // min-heap (increasing values) int main() { size_t N = 10000000; crand_rng64_t pcg = crand_rng64_init(time(NULL)); crand_uniform_i64_t dist = crand_uniform_i64_init(pcg, 0, N * 10); - cpqueue_i heap = cpqueue_i_init(); + cprique_i heap = cprique_i_init(); // Push ten million random numbers to priority queue for (int i=0; i +#include +#include + +declare_clist(i, int); +declare_cqueue(i, clist_i); // min-heap (increasing values) + +int main() { + int n = 10000000; + crand_rng32_t gen = crand_rng32_init(1234); + crand_uniform_i32_t dist = crand_uniform_i32_init(gen, 0, n); + + cqueue_i queue = cqueue_i_init(); + + // Push ten million random numbers onto the queue. + for (int i=0; i0; --i) { + int r = crand_uniform_i32(&dist); + if (r & 1) + ++n, cqueue_i_push(&queue, r); + else + --n, cqueue_i_pop(&queue); + } + printf("%d\n", n); + printf("%zu\n", n, cqueue_i_size(queue)); + cqueue_i_destroy(&queue); +} diff --git a/stc/clist.h b/stc/clist.h index 4cba9d1f..1415bcd5 100644 --- a/stc/clist.h +++ b/stc/clist.h @@ -85,6 +85,10 @@ #define clist_init {NULL} #define clist_empty(list) ((list).last == NULL) + +declare_clist_types(void, int); +STC_API size_t _clist_size(const clist_void* self); + #define declare_clist_7(tag, Value, valueDestroy, RawValue, valueCompareRaw, valueToRaw, valueFromRaw) \ \ declare_clist_types(tag, Value); \ @@ -94,7 +98,9 @@ STC_INLINE clist_##tag \ clist_##tag##_init(void) {clist_##tag x = clist_init; return x;} \ STC_INLINE bool \ - clist_##tag##_empty(clist_##tag l) {return clist_empty(l);} \ + clist_##tag##_empty(clist_##tag ls) {return clist_empty(ls);} \ + STC_INLINE size_t \ + clist_##tag##_size(clist_##tag ls) {return _clist_size((const clist_void*) &ls);} \ STC_INLINE Value \ clist_##tag##_value_from_raw(RawValue rawValue) {return valueFromRaw(rawValue);} \ \ @@ -278,9 +284,7 @@ free(del) -declare_clist_types(void, int); - -STC_API void \ +STC_API void _clist_splice_after(clist_void* self, clist_void_iter_t pos, clist_void* other) { if (!pos.item) self->last = other->last; @@ -293,6 +297,16 @@ _clist_splice_after(clist_void* self, clist_void_iter_t pos, clist_void* other) other->last = NULL; } +STC_API size_t +_clist_size(const clist_void* self) { + const clist_void_node_t *i = self->last; + if (!i) return 0; + size_t n = 1; + while ((i = i->next) != self->last) ++n; + return n; +} + + /* Singly linked list Mergesort implementation by Simon Tatham. O(n*log n). * https://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html */ diff --git a/stc/cpqueue.h b/stc/cpqueue.h deleted file mode 100644 index b2c81478..00000000 --- a/stc/cpqueue.h +++ /dev/null @@ -1,141 +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. - */ - -/* Priority Queue using heap, with adapter class (normally cvec). - - #include - #include - declare_cvec(f, float); - declare_cpqueue(f, cvec_f, >); // min-heap (increasing values) - - int main() { - crand_rng32_t gen = crand_rng32_init(1234); - crand_uniform_f32_t dist = crand_uniform_f32_init(10.0f, 100.0f); - - cpqueue_f queue = cpqueue_f_init(); - // Push ten million random numbers onto the queue. - for (int i=0; i<10000000; ++i) - cpqueue_f_push(&queue, crand_uniform_f32(&gen, dist)); - // Extract the 100 smallest. - for (int i=0; i<100; ++i) { - printf("%f ", *cpqueue_f_top(queue)); - cpqueue_f_pop(&queue); - } - cpqueue_f_destroy(&queue); - } -*/ - -#ifndef CPQUEUE__H__ -#define CPQUEUE__H__ - -#include "cvec.h" - -#define declare_cpqueue(tag, ctype, cmpOpr) /* cmpOpr: < or > */ \ - \ -typedef ctype cpqueue_##tag; \ -typedef ctype##_value_t cpqueue_##tag##_value_t; \ -typedef ctype##_rawvalue_t cpqueue_##tag##_rawvalue_t; \ -typedef ctype##_input_t cpqueue_##tag##_input_t; \ -STC_INLINE cpqueue_##tag \ -cpqueue_##tag##_init() {return ctype##_init();} \ -STC_INLINE size_t \ -cpqueue_##tag##_size(cpqueue_##tag pq) {return ctype##_size(pq);} \ -STC_INLINE bool \ -cpqueue_##tag##_empty(cpqueue_##tag pq) {return ctype##_empty(pq);} \ -STC_INLINE void \ -cpqueue_##tag##_destroy(cpqueue_##tag* self) {ctype##_destroy(self);} \ -STC_API void \ -cpqueue_##tag##_build(cpqueue_##tag* self); \ -STC_API void \ -cpqueue_##tag##_erase(cpqueue_##tag* self, size_t i); \ -STC_INLINE const cpqueue_##tag##_value_t* \ -cpqueue_##tag##_top(const cpqueue_##tag* self) {return &self->data[0];} \ -STC_INLINE void \ -cpqueue_##tag##_pop(cpqueue_##tag* self) {cpqueue_##tag##_erase(self, 0);} \ -STC_API void \ -cpqueue_##tag##_push_v(cpqueue_##tag* self, cpqueue_##tag##_value_t value); \ -STC_INLINE void \ -cpqueue_##tag##_push(cpqueue_##tag* self, cpqueue_##tag##_rawvalue_t rawValue) { \ - cpqueue_##tag##_push_v(self, ctype##_value_from_raw(rawValue)); \ -} \ -STC_API void \ -cpqueue_##tag##_push_n(cpqueue_##tag *self, const cpqueue_##tag##_input_t in[], size_t size); \ - \ -implement_cpqueue(tag, ctype, cmpOpr) - -/* -------------------------- IMPLEMENTATION ------------------------- */ - -#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) -#define implement_cpqueue(tag, ctype, cmpOpr) \ - \ -STC_INLINE void \ -_cpqueue_##tag##_sift_down(cpqueue_##tag##_value_t* arr, size_t i, size_t n) { \ - size_t r = i, c = i << 1; \ - while (c <= n) { \ - if (c < n && ctype##_value_compare(&arr[c], &arr[c + 1]) cmpOpr 0) \ - ++c; \ - if (ctype##_value_compare(&arr[r], &arr[c]) cmpOpr 0) { \ - cpqueue_##tag##_value_t t = arr[r]; arr[r] = arr[c]; arr[r = c] = t; \ - } else \ - return; \ - c <<= 1; \ - } \ -} \ - \ -STC_API void \ -cpqueue_##tag##_build(cpqueue_##tag* self) { \ - size_t n = cpqueue_##tag##_size(*self); \ - cpqueue_##tag##_value_t *arr = self->data - 1; \ - for (size_t k = n >> 1; k != 0; --k) \ - _cpqueue_##tag##_sift_down(arr, k, n); \ -} \ - \ -STC_API void \ -cpqueue_##tag##_erase(cpqueue_##tag* self, size_t i) { \ - size_t n = cpqueue_##tag##_size(*self) - 1; \ - self->data[i] = self->data[n]; \ - ctype##_pop_back(self); \ - _cpqueue_##tag##_sift_down(self->data - 1, i + 1, n); \ -} \ - \ -STC_API void \ -cpqueue_##tag##_push_v(cpqueue_##tag* self, cpqueue_##tag##_value_t value) { \ - ctype##_push_back(self, value); /* sift-up the value */ \ - size_t n = cpqueue_##tag##_size(*self), c = n; \ - cpqueue_##tag##_value_t *arr = self->data - 1; \ - for (; c > 1 && ctype##_value_compare(&arr[c >> 1], &value) cmpOpr 0; c >>= 1) \ - arr[c] = arr[c >> 1]; \ - if (c != n) arr[c] = value; \ -} \ -STC_API void \ -cpqueue_##tag##_push_n(cpqueue_##tag *self, const cpqueue_##tag##_input_t in[], size_t size) { \ - ctype##_reserve(self, cpqueue_##tag##_size(*self) + size); \ - for (size_t i=0; i + #include + declare_cvec(f, float); + declare_cprique(f, cvec_f, >); // min-heap (increasing values) + + int main() { + crand_rng32_t gen = crand_rng32_init(1234); + crand_uniform_f32_t dist = crand_uniform_f32_init(10.0f, 100.0f); + + cprique_f queue = cprique_f_init(); + // Push ten million random numbers onto the queue. + for (int i=0; i<10000000; ++i) + cprique_f_push(&queue, crand_uniform_f32(&gen, dist)); + // Extract the 100 smallest. + for (int i=0; i<100; ++i) { + printf("%f ", *cprique_f_top(queue)); + cprique_f_pop(&queue); + } + cprique_f_destroy(&queue); + } +*/ + +#ifndef CPQUEUE__H__ +#define CPQUEUE__H__ + +#include "cvec.h" + +#define declare_cprique(tag, ctype, cmpOpr) /* cmpOpr: < or > */ \ + \ +typedef ctype cprique_##tag; \ +typedef ctype##_value_t cprique_##tag##_value_t; \ +typedef ctype##_rawvalue_t cprique_##tag##_rawvalue_t; \ +typedef ctype##_input_t cprique_##tag##_input_t; \ +STC_INLINE cprique_##tag \ +cprique_##tag##_init() {return ctype##_init();} \ +STC_INLINE size_t \ +cprique_##tag##_size(cprique_##tag pq) {return ctype##_size(pq);} \ +STC_INLINE bool \ +cprique_##tag##_empty(cprique_##tag pq) {return ctype##_empty(pq);} \ +STC_INLINE void \ +cprique_##tag##_destroy(cprique_##tag* self) {ctype##_destroy(self);} \ +STC_API void \ +cprique_##tag##_build(cprique_##tag* self); \ +STC_API void \ +cprique_##tag##_erase(cprique_##tag* self, size_t i); \ +STC_INLINE const cprique_##tag##_value_t* \ +cprique_##tag##_top(const cprique_##tag* self) {return &self->data[0];} \ +STC_INLINE void \ +cprique_##tag##_pop(cprique_##tag* self) {cprique_##tag##_erase(self, 0);} \ +STC_API void \ +cprique_##tag##_push_v(cprique_##tag* self, cprique_##tag##_value_t value); \ +STC_INLINE void \ +cprique_##tag##_push(cprique_##tag* self, cprique_##tag##_rawvalue_t rawValue) { \ + cprique_##tag##_push_v(self, ctype##_value_from_raw(rawValue)); \ +} \ +STC_API void \ +cprique_##tag##_push_n(cprique_##tag *self, const cprique_##tag##_input_t in[], size_t size); \ + \ +implement_cprique(tag, ctype, cmpOpr) + +/* -------------------------- IMPLEMENTATION ------------------------- */ + +#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION) +#define implement_cprique(tag, ctype, cmpOpr) \ + \ +STC_INLINE void \ +_cprique_##tag##_sift_down(cprique_##tag##_value_t* arr, size_t i, size_t n) { \ + size_t r = i, c = i << 1; \ + while (c <= n) { \ + if (c < n && ctype##_value_compare(&arr[c], &arr[c + 1]) cmpOpr 0) \ + ++c; \ + if (ctype##_value_compare(&arr[r], &arr[c]) cmpOpr 0) { \ + cprique_##tag##_value_t t = arr[r]; arr[r] = arr[c]; arr[r = c] = t; \ + } else \ + return; \ + c <<= 1; \ + } \ +} \ + \ +STC_API void \ +cprique_##tag##_build(cprique_##tag* self) { \ + size_t n = cprique_##tag##_size(*self); \ + cprique_##tag##_value_t *arr = self->data - 1; \ + for (size_t k = n >> 1; k != 0; --k) \ + _cprique_##tag##_sift_down(arr, k, n); \ +} \ + \ +STC_API void \ +cprique_##tag##_erase(cprique_##tag* self, size_t i) { \ + size_t n = cprique_##tag##_size(*self) - 1; \ + self->data[i] = self->data[n]; \ + ctype##_pop_back(self); \ + _cprique_##tag##_sift_down(self->data - 1, i + 1, n); \ +} \ + \ +STC_API void \ +cprique_##tag##_push_v(cprique_##tag* self, cprique_##tag##_value_t value) { \ + ctype##_push_back(self, value); /* sift-up the value */ \ + size_t n = cprique_##tag##_size(*self), c = n; \ + cprique_##tag##_value_t *arr = self->data - 1; \ + for (; c > 1 && ctype##_value_compare(&arr[c >> 1], &value) cmpOpr 0; c >>= 1) \ + arr[c] = arr[c >> 1]; \ + if (c != n) arr[c] = value; \ +} \ +STC_API void \ +cprique_##tag##_push_n(cprique_##tag *self, const cprique_##tag##_input_t in[], size_t size) { \ + ctype##_reserve(self, cprique_##tag##_size(*self) + size); \ + for (size_t i=0; i + #include + declare_clist(i, int); + declare_cqueue(i, clist_i); // min-heap (increasing values) + + int main() { + int n = 10000000; + crand_rng32_t gen = crand_rng32_init(1234); + crand_uniform_i32_t dist = crand_uniform_i32_init(gen, 0, n); + + cqueue_i queue = cqueue_i_init(); + + // Push ten million random numbers onto the queue. + for (int i=0; i0; --i) { + int r = crand_uniform_i32(&dist); + if (r & 1) + ++n, cqueue_i_push(&queue, r); + else + --n, cqueue_i_pop(&queue); + } + printf("%d\n", n); + cqueue_i_destroy(&queue); + } +*/ + +#ifndef CQUEUE__H__ +#define CQUEUE__H__ + +#include "clist.h" + +#define declare_cqueue(tag, ctype) \ + \ +typedef ctype cqueue_##tag; \ +typedef ctype##_value_t cqueue_##tag##_value_t; \ +typedef ctype##_rawvalue_t cqueue_##tag##_rawvalue_t; \ +typedef ctype##_input_t cqueue_##tag##_input_t; \ +STC_INLINE cqueue_##tag \ +cqueue_##tag##_init() {return ctype##_init();} \ +STC_INLINE void \ +cqueue_##tag##_destroy(cqueue_##tag* self) {ctype##_destroy(self);} \ +STC_INLINE size_t \ +cqueue_##tag##_size(cqueue_##tag pq) {return ctype##_size(pq);} \ +STC_INLINE bool \ +cqueue_##tag##_empty(cqueue_##tag pq) {return ctype##_empty(pq);} \ +STC_INLINE cqueue_##tag##_value_t* \ +cqueue_##tag##_front(cqueue_##tag* self) {return ctype##_front(self);} \ +STC_INLINE cqueue_##tag##_value_t* \ +cqueue_##tag##_back(cqueue_##tag* self) {return ctype##_back(self);} \ +STC_INLINE void \ +cqueue_##tag##_pop(cqueue_##tag* self) {ctype##_pop_front(self);} \ +STC_API void \ +cqueue_##tag##_push_v(cqueue_##tag* self, ctype##_value_t value) { \ + ctype##_push_back_v(self, value); \ +} \ +STC_INLINE void \ +cqueue_##tag##_push(cqueue_##tag* self, cqueue_##tag##_rawvalue_t rawValue) { \ + ctype##_push_back(self, rawValue); \ +} \ +STC_API void \ +cqueue_##tag##_push_n(cqueue_##tag *self, const cqueue_##tag##_input_t in[], size_t size) { \ + ctype##_push_n(self, in, size); \ +} \ +typedef int cqueue_##tag##_dud + +#endif diff --git a/stc/cstack.h b/stc/cstack.h new file mode 100644 index 00000000..8c806523 --- /dev/null +++ b/stc/cstack.h @@ -0,0 +1,82 @@ +/* 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. + */ + +/* Stack adapter (normally uses cvec). + + #include + #include + + declare_cvec(i, int); + declare_cstack(i, cvec_i); + + int main() { + cstack_i stack = cstack_i_init(); + + for (int i=0; i<100; ++i) + cstack_i_push(&stack, i*i); + + for (int i=0; i<90; ++i) + cstack_i_pop(&stack); + + printf("top: %d\n", *cstack_i_top(&stack)); + } +*/ + +#ifndef CSTACK__H__ +#define CSTACK__H__ + +#include "cvec.h" + +#define declare_cstack(tag, ctype) \ + \ +typedef ctype cstack_##tag; \ +typedef ctype##_value_t cstack_##tag##_value_t; \ +typedef ctype##_rawvalue_t cstack_##tag##_rawvalue_t; \ +typedef ctype##_input_t cstack_##tag##_input_t; \ +STC_INLINE cstack_##tag \ +cstack_##tag##_init() {return ctype##_init();} \ +STC_INLINE void \ +cstack_##tag##_destroy(cstack_##tag* self) {ctype##_destroy(self);} \ +STC_INLINE size_t \ +cstack_##tag##_size(cstack_##tag pq) {return ctype##_size(pq);} \ +STC_INLINE bool \ +cstack_##tag##_empty(cstack_##tag pq) {return ctype##_empty(pq);} \ +STC_INLINE cstack_##tag##_value_t* \ +cstack_##tag##_top(cstack_##tag* self) {return ctype##_back(self);} \ +STC_INLINE void \ +cstack_##tag##_pop(cstack_##tag* self) {ctype##_pop_back(self);} \ +STC_API void \ +cstack_##tag##_push_v(cstack_##tag* self, ctype##_value_t value) { \ + ctype##_push_back_v(self, value); \ +} \ +STC_INLINE void \ +cstack_##tag##_push(cstack_##tag* self, cstack_##tag##_rawvalue_t rawValue) { \ + ctype##_push_back(self, rawValue); \ +} \ +STC_API void \ +cstack_##tag##_push_n(cstack_##tag *self, const cstack_##tag##_input_t in[], size_t size) { \ + ctype##_push_n(self, in, size); \ +} \ +typedef int cstack_##tag##_dud + +#endif -- cgit v1.2.3