summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.md6
-rw-r--r--docs/clist_api.md15
-rw-r--r--docs/csset_api.md7
-rw-r--r--examples/csset_erase.c29
-rw-r--r--stc/csmap.h2
5 files changed, 46 insertions, 13 deletions
diff --git a/README.md b/README.md
index 82ed4e49..47796372 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,11 @@ Introduction
A modern, templated, user-friendly, fast, fully type-safe, and customizable container library for C99,
with a uniform API across the containers, and is similar to the c++ standard library containers API.
-It is a compact, header-only library with the all the major "standard" data containers, except for the multi-map/set variants:
+Please read [this blog](https://iafisher.com/blog/2020/06/type-safe-generics-in-c) by Ian Fisher for
+an introduction to type-safe generic data structures in C.
+
+STC is a compact, header-only library with the all the major "standard" data containers, except for
+the multi-map/set variants:
- [***carray*** - **multi-dim array** type](docs/carray_api.md)
- [***cbits*** - **std::bitset** alike type](docs/cbits_api.md)
- [***cdeq*** - **std::deque** alike type](docs/cdeq_api.md)
diff --git a/docs/clist_api.md b/docs/clist_api.md
index 9d0945d6..d1219046 100644
--- a/docs/clist_api.md
+++ b/docs/clist_api.md
@@ -7,7 +7,7 @@ Fast random access is not supported.
Unlike the c++ class *std::forward_list*, **clist** has an API similar to ***std::list***, and also supports
*push_back()* (**O**(1) time). It is still implemented as a singly-linked list. A **clist** object
occupies only one pointer in memory, and like *std::forward_list* the length of the list is not stored.
-The method *clist_X_count()* returns size of list, computed in **O**(*n*) time.
+All functions have **O**(1) complexity, apart from *clist_X_count()*, which returns size of list in **O**(*n*) time.
***Iterator invalidation***: Adding, removing and moving the elements within the list, or across several lists
will invalidate other iterators currently refering to these elements and their immediate succesive elements.
@@ -51,7 +51,7 @@ void clist_X_clear(clist_X* self);
void clist_X_del(clist_X* self); // destructor
bool clist_X_empty(clist_X list);
-size_t clist_X_count(clist_X list); // size() in O(n)
+size_t clist_X_count(clist_X list); // size() in O(n) time
clist_X_value_t* clist_X_front(const clist_X* self);
clist_X_value_t* clist_X_back(const clist_X* self);
@@ -60,11 +60,11 @@ void clist_X_push_front(clist_X* self, Value value);
void clist_X_emplace_front(clist_X* self, RawValue raw);
void clist_X_pop_front(clist_X* self);
-void clist_X_push_back(clist_X* self, Value value);
+void clist_X_push_back(clist_X* self, Value value); // note: no pop_back().
void clist_X_emplace_back(clist_X* self, RawValue raw);
void clist_X_emplace_n(clist_X *self, const clist_X_rawvalue_t arr[], size_t size);
-clist_X_iter_t clist_X_insert(clist_X* self, clist_X_iter_t it, Value value); // return iter to new elem; 'it' may be end
+clist_X_iter_t clist_X_insert(clist_X* self, clist_X_iter_t it, Value value); // return iter to new elem; End allowed
clist_X_iter_t clist_X_emplace(clist_X* self, clist_X_iter_t it, RawValue raw);
clist_X_iter_t clist_X_erase_at(clist_X* self, clist_X_iter_t it); // return iter after it
@@ -72,9 +72,9 @@ clist_X_iter_t clist_X_erase_range(clist_X* self, clist_X_iter_t it1, clist
size_t clist_X_remove(clist_X* self, RawValue raw); // removes all elements equal to raw
void clist_X_splice(clist_X* self, clist_X_iter_t it, clist_X* other);
-void clist_X_splice_range(clist_X* self, clist_X_iter_t it,
+void clist_X_splice_range(clist_X* self, clist_X_iter_t it, // see std::list::splice() docs
clist_X* other, clist_X_iter_t it1, clist_X_iter_t it2);
- // non-std: split out [it1, it2) from self, returned as a clist
+ // split out [it1, it2) from self, and return as a clist
clist_X clist_X_split(clist_X* self, clist_X_iter_t it1, clist_X_iter_t it2);
clist_X_iter_t clist_X_find(const clist_X* self, RawValue raw);
@@ -87,8 +87,7 @@ clist_X_iter_t clist_X_begin(const clist_X* self);
clist_X_iter_t clist_X_end(const clist_X* self);
void clist_X_next(clist_X_iter_t* it);
- // advance iter n elements forward. accepts and can return end.
-clist_X_iter_t clist_X_fwd(clist_X_iter it, size_t n);
+clist_X_iter_t clist_X_fwd(clist_X_iter it, size_t n); // return it n elements ahead. End allowed.
clist_X_value_t clist_X_value_clone(clist_X_value_t val);
```
diff --git a/docs/csset_api.md b/docs/csset_api.md
index 002752f7..67e3c6a7 100644
--- a/docs/csset_api.md
+++ b/docs/csset_api.md
@@ -29,13 +29,13 @@ csset_X csset_X_clone(csset_x set);
void csset_X_clear(csset_X* self);
void csset_X_swap(csset_X* a, csset_X* b);
-void csset_X_del(csset_X* self); // destructor
+void csset_X_del(csset_X* self); // destructor
bool csset_X_empty(csset_X set);
size_t csset_X_size(csset_X set);
csset_X_iter_t csset_X_find(const csset_X* self, RawKey rkey);
-csset_X_iter_t csset_X_lower_bound(const csset_X* self, RawKey rkey); // find closest entry >= rkey
+csset_X_iter_t csset_X_lower_bound(const csset_X* self, RawKey rkey); // find closest entry >= rkey
csset_X_value_t* csset_X_find_it(const csset_X* self, RawKey rkey, csset_X_iter_t* out);
bool csset_X_contains(const csset_X* self, RawKey rkey);
@@ -44,7 +44,8 @@ csset_X_result_t csset_X_emplace(csset_X* self, RawKey rkey);
void csset_X_emplace_n(csset_X* self, const RawKey arr[], size_t size);
size_t csset_X_erase(csset_X* self, RawKey rkey);
-csset_X_iter_t csset_X_erase_at(csset_X* self, csset_X_iter_t pos);
+csset_X_iter_t csset_X_erase_at(csset_X* self, csset_X_iter_t it); // return iter after it
+csset_X_iter_t csset_X_erase_range(csset_X* self, csset_X_iter_t it1, csset_X_iter_t it2); // return updated it2
csset_X_iter_t csset_X_begin(const csset_X* self);
csset_X_iter_t csset_X_end(const csset_X* self);
diff --git a/examples/csset_erase.c b/examples/csset_erase.c
new file mode 100644
index 00000000..9a05290d
--- /dev/null
+++ b/examples/csset_erase.c
@@ -0,0 +1,29 @@
+#include <stc/csset.h>
+#include <stdio.h>
+
+using_csset(i, int);
+
+int main()
+{
+ c_init(csset_i, set, {30, 20, 80, 40, 60, 90, 10, 70, 50});
+ c_foreach (k, csset_i, set) printf(" %d", *k.ref); puts("");
+
+ int val = 64;
+ csset_i_iter_t it;
+ printf("Show values >= %d:\n", val);
+ it = csset_i_lower_bound(&set, val);
+ c_foreach (k, csset_i, it, csset_i_end(&set)) printf(" %d", *k.ref); puts("");
+
+ printf("Erase values >= %d:\n", val);
+ while (it.ref) it = csset_i_erase_at(&set, it);
+ c_foreach (k, csset_i, set) printf(" %d", *k.ref); puts("");
+
+ val = 35;
+ printf("Erase values < %d:\n", val);
+ it = csset_i_lower_bound(&set, val);
+ csset_i_erase_range(&set, csset_i_begin(&set), it);
+ c_foreach (k, csset_i, set) printf(" %d", *k.ref); puts("");
+
+ csset_i_del(&set);
+}
+
diff --git a/stc/csmap.h b/stc/csmap.h
index 7e433c1d..dcf6d04d 100644
--- a/stc/csmap.h
+++ b/stc/csmap.h
@@ -171,7 +171,7 @@ struct csmap_rep { size_t root, disp, head, size, cap; void* nodes[]; };
CX##_value_t *ref; \
CX##_node_t *_d; \
int _top; \
- CX##_size_t _tn, _st[40]; \
+ CX##_size_t _tn, _st[36]; \
} CX##_iter_t; \
\
STC_API CX CX##_init(void); \