From a2b750608e2ee64052c3eda3ba054390ce4950ac Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Mon, 12 Apr 2021 22:09:16 +0200 Subject: Improved docs. --- README.md | 6 +++++- docs/clist_api.md | 15 +++++++-------- docs/csset_api.md | 7 ++++--- examples/csset_erase.c | 29 +++++++++++++++++++++++++++++ stc/csmap.h | 2 +- 5 files changed, 46 insertions(+), 13 deletions(-) create mode 100644 examples/csset_erase.c 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 +#include + +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); \ -- cgit v1.2.3