summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTyge Lovset <[email protected]>2023-05-19 19:06:37 +0200
committerTyge Lovset <[email protected]>2023-05-19 19:06:37 +0200
commitd629139d053fdc1ff24bc0dc1985e1a2d1a0ac47 (patch)
tree86af3209ee9f11d38cbb053ee658b0f2dae6565d
parent424e522d6f081bb8649777a3376e1dd5913daac8 (diff)
downloadSTC-modified-d629139d053fdc1ff24bc0dc1985e1a2d1a0ac47.tar.gz
STC-modified-d629139d053fdc1ff24bc0dc1985e1a2d1a0ac47.zip
Added container equality function to docs _eq(c1, c2).
-rw-r--r--docs/ccommon_api.md28
-rw-r--r--docs/cdeq_api.md1
-rw-r--r--docs/clist_api.md1
-rw-r--r--docs/cqueue_api.md1
-rw-r--r--docs/cstack_api.md1
-rw-r--r--docs/cvec_api.md1
-rw-r--r--include/stc/cdeq.h13
-rw-r--r--include/stc/cqueue.h18
-rw-r--r--include/stc/cstack.h11
-rw-r--r--misc/benchmarks/various/csort_bench.c2
10 files changed, 59 insertions, 18 deletions
diff --git a/docs/ccommon_api.md b/docs/ccommon_api.md
index e37a1463..eaf01996 100644
--- a/docs/ccommon_api.md
+++ b/docs/ccommon_api.md
@@ -204,22 +204,40 @@ if (it.ref) cmap_str_erase_at(&map, it);
c_erase_if(i, csmap_str, map, cstr_contains(i.ref, "hello"));
```
-### csort - two times faster qsort
+### sort_n_ - two times faster qsort
-When very fast array sorting is required, **csort** is about twice as fast as *qsort()*, and often simpler to use.
+The **sort_n**, **sort_ij** algorithm is about twice as fast as *qsort()*, and often simpler to use.
You may customize `i_tag` and the comparison function `i_cmp` or `i_less`.
There is a [benchmark/test file here](../misc/benchmarks/various/csort_bench.c).
```c
#define i_val int
#include <stc/algo/sort.h>
+#include <stdio.h>
int main() {
- int array[] = {5, 3, 5, 9, 7, 4, 7, 2, 4, 9, 3, 1, 2, 6, 4};
- csort_int(array, c_arraylen(array));
+ int nums[] = {5, 3, 5, 9, 7, 4, 7, 2, 4, 9, 3, 1, 2, 6, 4};
+ intarray_sort_n(nums, c_arraylen(nums));
+ c_forrange (i, c_arraylen(arr)) printf(" %d", arr[i]);
}
```
+Containers with random access may also be sorted. Even sorting cdeq/cqueue (with ring buffer) is
+possible and very fast. Note that `i_more` must be defined to pick up template parameters from the container:
+```c
+#define i_type MyDeq
+#define i_val int
+#define i_more
+#include <stc/cdeq.h> // deque
+#include <stc/algo/sort.h>
+#include <stdio.h>
+int main() {
+ MyDeq deq = c_make(MyDeq, {5, 3, 5, 9, 7, 4, 7, 2, 4, 9, 3, 1, 2, 6, 4});
+ MyDeq_sort_n(&deq, MyDeq_size(&deq));
+ c_foreach (i, MyDeq, deq) printf(" %d", *i.ref);
+ MyDeq_drop(&deq);
+}
+```
### c_new, c_delete
@@ -403,6 +421,8 @@ The **checkauto** utility described below, ensures that the `c_auto*` macros are
| `continue` | Exit a defer-block without resource leak |
```c
+#include <stc/algo/raii.h> // or <stc/calgo.h>
+...
// `c_defer` executes the expression(s) when leaving scope.
cstr s1 = cstr_lit("Hello"), s2 = cstr_lit("world");
c_defer (cstr_drop(&s1), cstr_drop(&s2))
diff --git a/docs/cdeq_api.md b/docs/cdeq_api.md
index 91022a5c..99980c24 100644
--- a/docs/cdeq_api.md
+++ b/docs/cdeq_api.md
@@ -79,6 +79,7 @@ cdeq_X_iter cdeq_X_end(const cdeq_X* self);
void cdeq_X_next(cdeq_X_iter* it);
cdeq_X_iter cdeq_X_advance(cdeq_X_iter it, intptr_t n);
+bool cdeq_X_eq(const cdeq_X* c1, const cdeq_X* c2); // require i_eq/i_cmp/i_less.
cdeq_X_value cdeq_X_value_clone(cdeq_X_value val);
cdeq_X_raw cdeq_X_value_toraw(const cdeq_X_value* pval);
void cdeq_X_value_drop(cdeq_X_value* pval);
diff --git a/docs/clist_api.md b/docs/clist_api.md
index 44c3bb7c..eb84fbd4 100644
--- a/docs/clist_api.md
+++ b/docs/clist_api.md
@@ -96,6 +96,7 @@ clist_X_iter clist_X_end(const clist_X* self);
void clist_X_next(clist_X_iter* it);
clist_X_iter clist_X_advance(clist_X_iter it, size_t n); // return n elements ahead.
+bool clist_X_eq(const clist_X* c1, const clist_X* c2); // equality test
clist_X_value clist_X_value_clone(clist_X_value val);
clist_X_raw clist_X_value_toraw(const clist_X_value* pval);
void clist_X_value_drop(clist_X_value* pval);
diff --git a/docs/cqueue_api.md b/docs/cqueue_api.md
index 7d8d4e5c..f5df86d6 100644
--- a/docs/cqueue_api.md
+++ b/docs/cqueue_api.md
@@ -51,6 +51,7 @@ cqueue_X_iter cqueue_X_end(const cqueue_X* self);
void cqueue_X_next(cqueue_X_iter* it);
cqueue_X_iter cqueue_X_advance(cqueue_X_iter it, intptr_t n);
+bool cqueue_X_eq(const cqueue_X* c1, const cqueue_X* c2); // require i_eq/i_cmp/i_less.
i_val cqueue_X_value_clone(i_val value);
cqueue_X_raw cqueue_X_value_toraw(const cqueue_X_value* pval);
void cqueue_X_value_drop(cqueue_X_value* pval);
diff --git a/docs/cstack_api.md b/docs/cstack_api.md
index c20de7d1..9cb7b42b 100644
--- a/docs/cstack_api.md
+++ b/docs/cstack_api.md
@@ -54,6 +54,7 @@ cstack_X_iter cstack_X_begin(const cstack_X* self);
cstack_X_iter cstack_X_end(const cstack_X* self);
void cstack_X_next(cstack_X_iter* it);
+bool cstack_X_eq(const cstack_X* c1, const cstack_X* c2); // require i_eq/i_cmp/i_less.
i_val cstack_X_value_clone(i_val value);
i_valraw cstack_X_value_toraw(const cvec_X_value* pval);
void cstack_X_value_drop(cvec_X_value* pval);
diff --git a/docs/cvec_api.md b/docs/cvec_api.md
index 194d48e1..841321b2 100644
--- a/docs/cvec_api.md
+++ b/docs/cvec_api.md
@@ -91,6 +91,7 @@ cvec_X_iter cvec_X_end(const cvec_X* self);
void cvec_X_next(cvec_X_iter* iter);
cvec_X_iter cvec_X_advance(cvec_X_iter it, size_t n);
+bool cvec_X_eq(const cvec_X* c1, const cvec_X* c2); // equality comp.
cvec_X_value cvec_X_value_clone(cvec_X_value val);
cvec_X_raw cvec_X_value_toraw(const cvec_X_value* pval);
cvec_X_raw cvec_X_value_drop(cvec_X_value* pval);
diff --git a/include/stc/cdeq.h b/include/stc/cdeq.h
index 0dbe7f5d..77fb015f 100644
--- a/include/stc/cdeq.h
+++ b/include/stc/cdeq.h
@@ -96,7 +96,6 @@ _cx_memb(_emplace_at)(_cx_self* self, _cx_iter it, const _cx_raw raw)
#if defined _i_has_eq || defined _i_has_cmp
STC_API _cx_iter _cx_memb(_find_in)(_cx_iter p1, _cx_iter p2, _cx_raw raw);
-STC_API bool _cx_memb(_eq)(const _cx_self* self, const _cx_self* other);
STC_INLINE _cx_iter
_cx_memb(_find)(const _cx_self* self, _cx_raw raw) {
@@ -183,18 +182,6 @@ _cx_memb(_find_in)(_cx_iter i1, _cx_iter i2, _cx_raw raw) {
}
return i1;
}
-
-STC_DEF bool
-_cx_memb(_eq)(const _cx_self* self, const _cx_self* other) {
- if (_cx_memb(_size)(self) != _cx_memb(_size)(other)) return false;
- for (_cx_iter i = _cx_memb(_begin)(self), j = _cx_memb(_begin)(other);
- i.ref; _cx_memb(_next)(&i), _cx_memb(_next)(&j))
- {
- const _cx_raw _rx = i_keyto(i.ref), _ry = i_keyto(j.ref);
- if (!(i_eq((&_rx), (&_ry)))) return false;
- }
- return true;
-}
#endif
#endif // IMPLEMENTATION
#define CDEQ_H_INCLUDED
diff --git a/include/stc/cqueue.h b/include/stc/cqueue.h
index 840c4fa6..1f2c7d0f 100644
--- a/include/stc/cqueue.h
+++ b/include/stc/cqueue.h
@@ -62,6 +62,10 @@ STC_INLINE _cx_value* _cx_memb(_emplace)(_cx_self* self, _cx_raw raw)
{ return _cx_memb(_push)(self, i_keyfrom(raw)); }
#endif
+#if defined _i_has_eq || defined _i_has_cmp
+STC_API bool _cx_memb(_eq)(const _cx_self* self, const _cx_self* other);
+#endif
+
#if !defined i_no_clone
STC_API _cx_self _cx_memb(_clone)(_cx_self cx);
STC_INLINE i_key _cx_memb(_value_clone)(i_key val)
@@ -211,6 +215,20 @@ _cx_memb(_clone)(_cx_self cx) {
return out;
}
#endif // i_no_clone
+
+#if defined _i_has_eq || defined _i_has_cmp
+STC_DEF bool
+_cx_memb(_eq)(const _cx_self* self, const _cx_self* other) {
+ if (_cx_memb(_size)(self) != _cx_memb(_size)(other)) return false;
+ for (_cx_iter i = _cx_memb(_begin)(self), j = _cx_memb(_begin)(other);
+ i.ref; _cx_memb(_next)(&i), _cx_memb(_next)(&j))
+ {
+ const _cx_raw _rx = i_keyto(i.ref), _ry = i_keyto(j.ref);
+ if (!(i_eq((&_rx), (&_ry)))) return false;
+ }
+ return true;
+}
+#endif
#endif // IMPLEMENTATION
#include "priv/template2.h"
#define CQUEUE_H_INCLUDED
diff --git a/include/stc/cstack.h b/include/stc/cstack.h
index 84bdb41b..bee7d17b 100644
--- a/include/stc/cstack.h
+++ b/include/stc/cstack.h
@@ -194,4 +194,15 @@ STC_INLINE intptr_t _cx_memb(_index)(const _cx_self* self, _cx_iter it)
STC_INLINE void _cx_memb(_adjust_end_)(_cx_self* self, intptr_t n)
{ self->_len += n; }
+#if defined _i_has_eq || defined _i_has_cmp
+STC_INLINE bool
+_cx_memb(_eq)(const _cx_self* self, const _cx_self* other) {
+ if (self->_len != other->_len) return false;
+ for (intptr_t i = 0; i < self->_len; ++i) {
+ const _cx_raw _rx = i_keyto(self->data+i), _ry = i_keyto(other->data+i);
+ if (!(i_eq((&_rx), (&_ry)))) return false;
+ }
+ return true;
+}
+#endif
#include "priv/template2.h"
diff --git a/misc/benchmarks/various/csort_bench.c b/misc/benchmarks/various/csort_bench.c
index 4d1149fc..d434693f 100644
--- a/misc/benchmarks/various/csort_bench.c
+++ b/misc/benchmarks/various/csort_bench.c
@@ -32,7 +32,7 @@ void testsort(Ints *a, int size, const char *desc) {
#elif defined QSORT
printf("qsort: "); qsort(a->data, size, sizeof *a->data, cmp_int);
#else
- printf("stc_qsort: "); Ints_sort_n(a, size);
+ printf("STC sort_n: "); Ints_sort_n(a, size);
#endif
t = clock() - t;