diff options
| author | _Tradam <[email protected]> | 2023-09-08 01:29:47 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-09-08 01:29:47 +0000 |
| commit | 3c76c7f3d5db3f9586a90d03f8fbb02d79de9acd (patch) | |
| tree | afbe4b540967223911f7c5de36559b82154f02f3 /README.md | |
| parent | 0841165881871ee01b782129be681209aeed2423 (diff) | |
| parent | 1a72205fe05c2375cfd380dd8381a8460d9ed8d1 (diff) | |
| download | STC-modified-modified.tar.gz STC-modified-modified.zip | |
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 293 |
1 files changed, 178 insertions, 115 deletions
@@ -3,8 +3,8 @@ STC - Smart Template Containers =============================== -### [Version 4.2](#version-history) - +### [Version 4.3 Pre-release](#version-history) +- See details for breaking changes. --- Description ----------- @@ -18,25 +18,26 @@ Containers - [***cbox*** - **std::unique_ptr** alike type](docs/cbox_api.md) - [***cbits*** - **std::bitset** alike type](docs/cbits_api.md) - [***clist*** - **std::forward_list** alike type](docs/clist_api.md) +- [***cstack*** - **std::stack** alike type](docs/cstack_api.md) +- [***cvec*** - **std::vector** alike type](docs/cvec_api.md) - [***cqueue*** - **std::queue** alike type](docs/cqueue_api.md) +- [***cdeq*** - **std::deque** alike type](docs/cdeq_api.md) - [***cpque*** - **std::priority_queue** alike type](docs/cpque_api.md) - [***cmap*** - **std::unordered_map** alike type](docs/cmap_api.md) - [***cset*** - **std::unordered_set** alike type](docs/cset_api.md) - [***csmap*** - **std::map** sorted map alike type](docs/csmap_api.md) - [***csset*** - **std::set** sorted set alike type](docs/csset_api.md) -- [***cstack*** - **std::stack** alike type](docs/cstack_api.md) - [***cstr*** - **std::string** alike type](docs/cstr_api.md) - [***csview*** - **std::string_view** alike type](docs/csview_api.md) -- [***cspan*** - **std::span/std::mdspan** alike type](docs/cspan_api.md) -- [***cdeq*** - **std::deque** alike type](docs/cdeq_api.md) -- [***cvec*** - **std::vector** alike type](docs/cvec_api.md) +- [***crawstr*** - null-terminated string view type](docs/crawstr_api.md) +- [***cspan*** - **std::span** + **std::mdspan** alike type](docs/cspan_api.md) Algorithms ---------- -- [***Ranged for-loops*** - c_foreach, c_forpair, c_forlist](docs/ccommon_api.md#ranged-for-loops) -- [***Range algorithms*** - c_forrange, crange, c_forfilter](docs/ccommon_api.md#range-algorithms) -- [***Generic algorithms*** - c_make, c_find_if, c_erase_if, csort, etc.](docs/ccommon_api.md#generic-algorithms) -- [***Coroutines*** - Simon Tatham's coroutines done right.](docs/ccommon_api.md#coroutines) +- [***Ranged for-loops*** - c_foreach, c_forpair, c_forlist](docs/algorithm_api.md#ranged-for-loops) +- [***Range algorithms*** - c_forrange, crange, c_forfilter](docs/algorithm_api.md#range-algorithms) +- [***Generic algorithms*** - c_init, c_find_if, c_erase_if, csort, etc.](docs/algorithm_api.md#generic-algorithms) +- [***Coroutines*** - ergonomic portable coroutines](docs/coroutine_api.md) - [***Regular expressions*** - Rob Pike's Plan 9 regexp modernized!](docs/cregex_api.md) - [***Random numbers*** - a very fast *PRNG* based on *SFC64*](docs/crandom_api.md) - [***Command line argument parser*** - similar to *getopt()*](docs/coption_api.md) @@ -61,15 +62,14 @@ List of contents --- ## Highlights -- **No boilerplate code** - Specify only the required template parameters, e.g. ***cmp***- and/or ***clone***-, ***drop***- functions, and leave the rest as defaults. +- **Minimal boilerplate code** - Specify only the required template parameters, and leave the rest as defaults. - **Fully type safe** - Because of templating, it avoids error-prone casting of container types and elements back and forth from the containers. -- **User friendly** - Just include the headers and you are good. The API and functionality is very close to c++ STL and is fully listed in the docs. -- **Unparalleled performance** - Maps and sets are much faster than the C++ STL containers, the remaining are similar in speed. +- **High performance** - Unordered maps and sets, queues and deques are significantly faster than the C++ STL containers, the remaining are similar or close to STL in speed (See graph below). - **Fully memory managed** - Containers destructs keys/values via default or user supplied drop function. They may be cloned if element types are clonable. Also, smart pointers are supported and can be stored in containers. See [***carc***](docs/carc_api.md) and [***cbox***](docs/cbox_api.md). -- **Uniform, easy-to-learn API** - Intuitive method/type names and uniform usage across the various containers. +- **Uniform, easy-to-learn API** - Just include the headers and you are good. The API and functionality resembles c++ STL and is fully listed in the docs. Intuitive method/type names and uniform usage across the various containers. - **No signed/unsigned mixing** - Unsigned sizes and indices mixed with signed for comparison and calculation is asking for trouble. STC only uses signed numbers in the API for this reason. - **Small footprint** - Small source code and generated executables. The executable from the example below using *four different* container types is only ***19 Kb in size*** compiled with gcc -O3 -s on Linux. -- **Dual mode compilation** - By default it is a simple header-only library with inline and static methods only, but you can easily switch to create a traditional library with shared symbols, without changing existing source files. See the Installation section. +- **Dual mode compilation** - By default it is a simple header-only library with inline and static methods only, but you can easily switch to create a traditional library with shared symbols, without changing existing source files. See the [installation section](#installation). - **No callback functions** - All passed template argument functions/macros are directly called from the implementation, no slow callbacks which requires storage. - **Compiles with C++ and C99** - C code can be compiled with C++ (container element types must be POD). - **Forward declaration** - Templated containers may be [forward declared](#forward-declarations) without including the full API/implementation. @@ -81,9 +81,9 @@ List of contents 1. ***Centralized analysis of template parameters***. The analyser assigns values to all non-specified template parameters (based on the specified ones) using meta-programming, so that you don't have to! You may specify a set of "standard" template parameters for each -container, but as a minimum *only one is required*: `i_val` (+ `i_key` for maps). In this +container, but as a minimum *only one is required*: `i_key` (+ `i_val` for maps). In this case, STC assumes that the elements are of basic types. For non-trivial types, additional -template parameters must be given. +template parameters must be given. 2. ***Alternative insert/lookup type***. You may specify an alternative type to use for lookup in containers. E.g., containers with STC string elements (**cstr**) uses `const char*` as lookup type, so constructing a `cstr` (which may allocate memory) for the lookup @@ -95,21 +95,21 @@ So instead of calling e.g. `cvec_str_push(&vec, cstr_from("Hello"))`, you may ca same element access syntax. E.g.: - `c_foreach (it, MyInts, myints) *it.ref += 42;` works for any container defined as `MyInts` with `int` elements. - - `c_foreach (it, MyInts, it1, it2) *it.ref += 42;` iterates from `it1` up to `it2`. + - `c_foreach (it, MyInts, it1, it2) *it.ref += 42;` iterates from `it1` up to not including `it2`. --- ## Performance STC is a fast and memory efficient library, and code compiles fast: - + Benchmark notes: -- The barchart shows average test times over three platforms: Mingw64 10.30, Win-Clang 12, VC19. CPU: Ryzen 7 2700X CPU @4Ghz. +- The barchart shows average test times over three compilers: **Mingw64 13.1.0, Win-Clang 16.0.5, VC-19-36**. CPU: **Ryzen 7 5700X**. - Containers uses value types `uint64_t` and pairs of `uint64_t` for the maps. - Black bars indicates performance variation between various platforms/compilers. -- Iterations are repeated 4 times over n elements. -- **find()**: not executed for *forward_list*, *deque*, and *vector* because these c++ containers does not have native *find()*. +- Iterations and access are repeated 4 times over n elements. +- access: no entryfor *forward_list*, *deque*, and *vector* because these c++ containers does not have native *find()*. - **deque**: *insert*: n/3 push_front(), n/3 push_back()+pop_front(), n/3 push_back(). - **map and unordered map**: *insert*: n/2 random numbers, n/2 sequential numbers. *erase*: n/2 keys in the map, n/2 random keys. @@ -117,8 +117,8 @@ Benchmark notes: ## Naming conventions - Container names are prefixed by `c`, e.g. `cvec`, `cstr`. -- Public STC macros are prefixed by `c_`, e.g. `c_foreach`, `c_make`. -- Template parameter macros are prefixed by `i_`, e.g. `i_val`, `i_type`. +- Public STC macros are prefixed by `c_`, e.g. `c_foreach`, `c_init`. +- Template parameter macros are prefixed by `i_`, e.g. `i_key`, `i_type`. - All containers can be initialized with `{0}`, i.e. no heap allocation used by default init. - Common types for a container type Con: - Con @@ -147,10 +147,10 @@ Benchmark notes: STC containers have similar functionality to C++ STL standard containers. All containers except for a few, like **cstr** and **cbits** are generic/templated. No type casting is used, so containers are type-safe like templated types in C++. However, to specify template parameters with STC, you define them as macros prior to -including the container: +including the container. ```c -#define i_type Floats // Container type name; unless defined name would be cvec_float -#define i_val float // Container element type +#define i_type Floats // Container type name (optional); if not defined name would be cvec_float +#define i_key float // Container element type #include <stc/cvec.h> // "instantiate" the desired container type #include <stdio.h> @@ -164,39 +164,44 @@ int main(void) for (int i = 0; i < Floats_size(&nums); ++i) printf(" %g", nums.data[i]); - Floats_sort(&nums); - c_foreach (i, Floats, nums) // Alternative and recommended way to iterate. printf(" %g", *i.ref); // i.ref is a pointer to the current element. Floats_drop(&nums); // cleanup memory } ``` -You may switch to a different container type, e.g. a sorted set (csset): +Note that `i_val*` template parameters can be used instead of `i_key*` for *non-map* containers. + +Switching to a different container type, e.g. a sorted set (csset): [ [Run this code](https://godbolt.org/z/qznfa65e1) ] ```c #define i_type Floats -#define i_val float +#define i_key float #include <stc/csset.h> // Use a sorted set instead #include <stdio.h> -int main() +int main(void) { Floats nums = {0}; Floats_push(&nums, 30.f); Floats_push(&nums, 10.f); Floats_push(&nums, 20.f); - // already sorted, print the numbers + // print the numbers (sorted) c_foreach (i, Floats, nums) printf(" %g", *i.ref); Floats_drop(&nums); } ``` -For user-defined struct elements, `i_cmp` compare function should be defined as the default `<` and `==` -only works for integral types. *Alternatively, `#define i_opt c_no_cmp` to disable sorting and searching*. Similarily, if an element destructor `i_valdrop` is defined, `i_valclone` function is required. +Comparison/lookup functions are enabled by default for associative containers and priority queue (cmap, cset, csmap, csset, cpque). To enable it for the remaining containers, define `i_cmp` or `i_less` (and optionally `i_eq`) on the element type. If the element is an integral type, simply define `i_use_cmp` to use `<` and `==` operators for comparisons. + +Note that for `#define i_keyclass Type`, defining `i_use_cmp` means that *Type_cmp()* function is expected to exist (along with *Type_clone()* and *Type_drop()*). + +To summarize, `i_use_cmp` is only needed to enable comparison (sort/search) functions when defining cstack, cvec, cqueue, cdeq, carc, cbox. With built-in types, it enables the comparison operators, whereas for keyclass types, it binds comparison to its Type_cmp() function. + +If an element destructor `i_keydrop` is defined, `i_keyclone` function is required. *Alternatively `#define i_opt c_no_clone` to disable container cloning.* Let's make a vector of vectors, which can be cloned. All of its element vectors will be destroyed when destroying the Vec2D. @@ -206,12 +211,11 @@ Let's make a vector of vectors, which can be cloned. All of its element vectors #include <stdio.h> #define i_type Vec -#define i_val float +#define i_key float #include <stc/cvec.h> #define i_type Vec2D -#define i_valclass Vec // Use i_valclass when element type has "members" _clone(), _drop() and _cmp(). -#define i_opt c_no_cmp // Disable cmp (search/sort) for Vec2D because Vec_cmp() is not defined. +#define i_keyclass Vec // Use i_keyclass instead i_key when element type has "members" _clone(), _drop() and _cmp(). #include <stc/cvec.h> int main(void) @@ -237,21 +241,22 @@ int main(void) ``` This example uses four different container types: -[ [Run this code](https://godbolt.org/z/x5YKeMrEh) ] +[ [Run this code](https://godbolt.org/z/j68od14hv) ] ```c #include <stdio.h> #define i_key int -#include <stc/cset.h> // cset_int: unordered set +#include <stc/cset.h> // cset_int: unordered set (assume i_key is basic type, uses `==` operator) struct Point { float x, y; }; // Define cvec_pnt with a less-comparison function for Point. -#define i_val struct Point -#define i_less(a, b) a->x < b->x || (a->x == b->x && a->y < b->y) +#define i_key struct Point +#define i_less(a, b) a->x < b->x || (a->x == b->x && a->y < b->y) // enable sort/search #define i_tag pnt #include <stc/cvec.h> // cvec_pnt: vector of struct Point -#define i_val int +#define i_key int +#define i_use_cmp // enable sort/search. Use native `<` and `==` operators #include <stc/clist.h> // clist_int: singly linked list #define i_key int @@ -333,49 +338,29 @@ After erasing the elements found: --- ## Installation -Because it is headers-only, headers can simply be included in your program. By default, functions are static -(some inlined). You may add the *include* folder to the **CPATH** environment variable to -let GCC, Clang, and TinyC locate the headers. +STC is primarily a "headers-only" library, so most headers can simply be included in your program. By default, +all "templated" functions are static (many inlined). If you add the STC *include* folder to the **CPATH** +environment variable, GCC, Clang, and TinyC will locate the headers automatically. -If containers are used across several translation units with common instantiated container types, it is -recommended to build as a "library" with external linking to minimize executable size. To enable this, -specify `-DSTC_HEADER` as compiler option in your build environment. Next, place all the instantiations -of the containers used inside a single C-source file as in the example below, and `#define STC_IMPLEMENT` at top. -You may also cherry-pick shared linking mode on individual containers by `#define i_header` and -`#define i_implement`, or force static symbols by `#define i_static` before container includes. - -As a special case, there may be non-templated functions in templated containers that should be implemented only -once and if needed. Currently, define `i_extern` before including **clist** for its sorting function, and before -**cregex** or **utf8** to implement them (global `STC_EXTERN` can alternatively be defined). - -It is possible to generate single headers by executing the python script `src/singleheader.py header-file > single`. - -Conveniently, `src\libstc.c` implements non-templated functions as shared symbols for **cstr**, **csview**, -**cbits** and **crand**. When building in shared mode (-DSTC_HEADER), you may include this file in your project, -or define your own as descibed above. +The templated container functions are defined with static linking by default, which is normally optimal +for both performance and compiled binary size. However, some common container type instances, e.g. `cvec_int` +may be used in several translation units. When they are used in more than 3-4, consider creating a separate +header file for them [as described here](#1-include-as-a-header-file). Now it will use shared +linking, so *one* c-file must implement the templated container, e.g.: ```c -// stc_libs.c -#define STC_IMPLEMENT - -#include <stc/cstr.h> -#include "Point.h" - -#define i_key int -#define i_val int -#define i_tag ii -#include <stc/cmap.h> // cmap_ii: int => int +#define i_implement +#include "cvec_int.h" +``` +The non-templated string type **cstr** uses shared linking by default, but can have static linking instead by +`#define i_static`. Same for the string-view type **csview**, but most of its functions are static inlined, so +linking specifications and implementation are only needed for a few lesser used functions. -#define i_key int64_t -#define i_tag ix -#include <stc/cset.h> // cset_ix +Conveniently, `src\libstc.c` implements all the non-templated functions with shared linking for **cstr**, +**csview**, **cregex**, **utf8**, and **crand**. -#define i_val int -#include <stc/cvec.h> // cvec_int +As a special case, you can `#define i_import` before including **cregex** or **cstr** to implement the dependent +**utf8** functions (proper utf8 case conversions, etc.). Or link with src\libstc. -#define i_val Point -#define i_tag pnt -#include <stc/clist.h> // clist_pnt -``` --- ## Specifying template parameters @@ -383,16 +368,16 @@ Each templated type requires one `#include`, even if it's the same container bas The template parameters are given by a `#define i_xxxx` statement, where *xxxx* is the parameter name. The list of template parameters: -- `i_key` *Type* - Element key type for map/set only. **[required]**. -- `i_val` *Type* - Element value type. **[required for]** cmap/csmap, it is the mapped value type. -- `i_cmp` *Func* - Three-way comparison of two *i_keyraw*\* or *i_valraw*\* - **[required for]** non-integral *i_keyraw* elements unless *i_opt* is defined with *c_no_cmp*. +- `i_key` *Type* - Element key type. **[required]**. Note: `i_val` *may* be used instead for non-maps (not recommended). +- `i_val` *Type* - Element value type. **[required for]** cmap/csmap as the mapped value type. +- `i_cmp` *Func* - Three-way comparison of two *i_keyraw*\* or *i_valraw*\* - **[required for]** non-integral *i_keyraw* elements. - `i_hash` *Func* - Hash function taking *i_keyraw*\* - defaults to *c_default_hash*. **[required for]** ***cmap/cset*** with non-POD *i_keyraw* elements. - `i_eq` *Func* - Equality comparison of two *i_keyraw*\* - defaults to *!i_cmp*. Companion with *i_hash*. Properties: - `i_tag` *Name* - Container type name tag. Defaults to *i_key* name. - `i_type` *Name* - Full container type name. Alternative to *i_tag*. -- `i_opt` *Flags* - Boolean properties: may combine *c_no_cmp*, *c_no_clone*, *c_no_atomic*, *c_is_forward*, *c_static*, *c_header* with the *|* separator. +- `i_opt` *Flags* - Boolean properties: may combine *c_no_clone*, *c_no_atomic*, *c_is_forward*, *c_static*, *c_header* with the *|* separator. Key: - `i_keydrop` *Func* - Destroy map/set key func - defaults to empty destructor. @@ -413,7 +398,7 @@ Specials: Meta-template parameters. Use instead of `i_key` / `i_val`. If `i_keyraw` is defined, it sets `i_keyto` = *Type_toraw()* and `i_keyfrom` = *Type_from()*. Only functions required by the container type is required to be defined. E.g.: - *Type_hash()* and *Type_eq()* are only required by **cmap**, **cset** and smart pointers. - - *Type_cmp()* is not used by **cstack** and **cmap/cset**, or if *#define i_opt c_no_cmp* is specified. + - *Type_cmp()* is not used by **cstack** and **cmap/cset**. - *Type_clone()* is not used if *#define i_opt c_no_clone* is specified. - `i_key_str` - Sets `i_keyclass` = *cstr*, `i_tag` = *str*, and `i_keyraw` = *const char*\*. Defines both type convertion `i_keyfrom`, `i_keyto`, and sets `i_cmp`, `i_eq`, `i_hash` functions with *const char\*\** as argument. @@ -424,7 +409,6 @@ NB: Do not use when defining carc/cbox types themselves. - `i_valclass` *Type*, `i_val_str`, `i_val_ssv`, `i_valboxed` - Similar rules as for ***key***. **Notes**: -- Instead of defining `i_cmp`, you may define *i_opt c_no_cmp* to disable *searching and sorting* functions. - Instead of defining `i_*clone`, you may define *i_opt c_no_clone* to disable *clone* functionality. - For `i_keyclass`, if *i_keyraw* is defined along with it, *i_keyfrom* may also be defined to enable the *emplace*-functions. NB: the signature for ***cmp***, ***eq***, and ***hash*** uses *i_keyraw* as input. @@ -458,7 +442,7 @@ and non-emplace methods: #define i_implement // define in ONE file to implement longer functions in cstr #include <stc/cstr.h> -#define i_val_str // special macro to enable container of cstr +#define i_key_str // special macro to enable container of cstr #include <stc/cvec.h> // vector of string (cstr) ... cvec_str vec = {0}; @@ -518,36 +502,93 @@ last example on the **cmap** page demonstrates how to specify a map with non-tri Define `i_type` instead of `i_tag`: ```c #define i_type MyVec -#define i_val int +#define i_key int #include <stc/cvec.h> -myvec vec = MyVec_init(); -MyVec_push_back(&vec, 1); +MyVec vec = {0}; +MyVec_push(&vec, 42); ... ``` --- ## Forward declarations -It is possible to forward declare containers. This is useful when a container is part of a struct, -but still not expose or include the full implementation / API of the container. +There are two ways to pre-declare templated containers in header files: + +1. Include the templated container type instance as a header file. This also exposes all container +functions, which can be used by client code. It requires that the element type is complete. +2. Or, pre-declare the container type only. In this case, the container can be a "private" member of a +user struct (the container functions will not be available to the user). + +### 1. Include as a header file + +Create a dedicated header for the container type instance: +```c +#ifndef PointVec_H_ +#define PointVec_H_ +// Do not to include user defined headers here if they use templated containers themselves + +#define i_type PointVec +#define i_val struct Point // NB! Element type must be complete at this point! +#define i_header // Do not implement, only expose API +#include <stc/cvec.h> + +#endif +``` +Usage from e.g. other headers is trivial: ```c -// Header file -#include <stc/forward.h> // only include data structures -forward_cstack(cstack_pnt, struct Point); // declare cstack_pnt (and cstack_pnt_value, cstack_pnt_iter); - // struct Point may be an incomplete type. +#ifndef Dataset_H_ +#define Dataset_H_ +#include "Point.h" // include element type separately +#include "PointVec.h" + typedef struct Dataset { - cstack_pnt vertices; - cstack_pnt colors; + PointVec vertices; + PointVec colors; } Dataset; +... +#endif +``` -// Implementation -#define i_is_forward // flag that the container was forward declared. -#define i_val struct Point -#define i_tag pnt -#include <stc/cstack.h> +Implement PointVec in a c-file: +```c +#include "Point.h" +#define i_implement // define immediately before PointVec.h +#include "PointVec.h" +... ``` +### 2. Forward declare only +```c +// Dataset.h +#ifndef Dataset_H_ +#define Dataset_H_ +#include <stc/forward.h> // include various container data structure templates + +// declare PointVec. Note: struct Point may be an incomplete/undeclared type. +forward_cvec(PointVec, struct Point); + +typedef struct Dataset { + PointVec vertices; + PointVec colors; +} Dataset; + +void Dataset_drop(Dataset* self); +... +#endif +``` +Define and use the "private" container in the c-file: +```c +// Dataset.c +#include "Dataset.h" +#include "Point.h" // Point must be defined here. + +#define i_is_forward // flag that the container was forward declared. +#define i_type PointVec +#define i_val struct Point +#include <stc/cvec.h> // Implements PointVec with static linking by default +... +``` --- ## Per container-instance customization Sometimes it is useful to extend a container type to store extra data, e.g. a comparison @@ -564,8 +605,8 @@ It adds a MemoryContext to each container by defining the `i_extend` template pa the by inclusion of `<stc/extend.h>`. ```c // stcpgs.h -#define pgs_malloc(sz) MemoryContextAlloc(c_getcon(self)->memctx, sz) -#define pgs_calloc(n, sz) MemoryContextAllocZero(c_getcon(self)->memctx, (n)*(sz)) +#define pgs_malloc(sz) MemoryContextAlloc(c_extend(self)->memctx, sz) +#define pgs_calloc(n, sz) MemoryContextAllocZero(c_extend(self)->memctx, (n)*(sz)) #define pgs_realloc(p, sz) (p ? repalloc(p, sz) : pgs_malloc(sz)) #define pgs_free(p) (p ? pfree(p) : (void)0) // pfree/repalloc does not accept NULL. @@ -574,12 +615,12 @@ the by inclusion of `<stc/extend.h>`. #define i_extend MemoryContext memctx; #include <stc/extend.h> ``` -To use it, define both `i_type` and `i_con` (the container type) before including the custom header: +To use it, define both `i_type` and `i_base` (the container type) before including the custom header: ```c #define i_type IMap +#define i_base csmap #define i_key int #define i_val int -#define i_con csmap #include "stcpgs.h" // Note the wrapper struct type is IMap_ext. IMap is accessed by .get @@ -611,6 +652,29 @@ STC is generally very memory efficient. Memory usage for the different container --- # Version History + +## Version 4.3 +- Breaking changes: + - **cstr** and **csview** now uses *shared linking* by default. Implement by either defining `i_implement` or `i_static` before including. + - Renamed <stc/calgo.h> => `<stc/algorithm.h>` + - Moved <stc/algo/coroutine.h> => `<stc/coroutine.h>` + - Much improved with some new API and added features. + - Removed deprecated <stc/crandom.h>. Use `<stc/crand.h>` with the new API. + - Reverted names _unif and _norm back to `_uniform` and `_normal`. + - Removed default comparison for **clist**, **cvec** and **cdeq**: + - Define `i_use_cmp` to enable comparison for built-in i_key types (<, ==). + - Use of `i_keyclass` still expects comparison functions to be defined. + - Use of `i_keyboxed` compares stored pointers instead of pointed to values if comparison not defined. + - Renamed input enum flags for ***cregex***-functions. +- **cspan**: Added **column-major** order (fortran) multidimensional spans and transposed views (changed representation of strides). +- All new faster and smaller **cqueue** and **cdeq** implementations, using a circular buffer. +- Renamed i_extern => `i_import` (i_extern deprecated). + - Define `i_import` before `#include <stc/cstr.h>` will also define full utf8 case conversions. + - Define `i_import` before `#include <stc/cregex.h>` will also define cstr + utf8 tables. +- Renamed c_make() => ***c_init()*** macro for initializing containers with element lists. c_make deprecated. +- Removed deprecated uppercase flow-control macro names. +- Other smaller additions, bug fixes and improved documentation. + ## Version 4.2 - New home! And online single headers for https://godbolt.org - Library: https://github.com/stclib/STC @@ -620,7 +684,6 @@ STC is generally very memory efficient. Memory usage for the different container - Added new crand.h API & header. Old crandom.h is deprecated. - Added `c_const_cast()` typesafe macro. - Removed RAII macros usage from examples -- Renamed c_foreach_r => `c_foreach_rv` - Renamed c_flt_count(i) => `c_flt_counter(i)` - Renamed c_flt_last(i) => `c_flt_getcount(i)` - Renamed c_ARRAYLEN() => c_arraylen() @@ -634,9 +697,9 @@ Major changes: - Customizable allocator [per templated container type](https://github.com/tylov/STC/discussions/44#discussioncomment-4891925). - Updates on **cregex** with several [new unicode character classes](docs/cregex_api.md#regex-cheatsheet). - Algorithms: - - [crange](docs/ccommon_api.md#crange) - similar to [boost::irange](https://www.boost.org/doc/libs/release/libs/range/doc/html/range/reference/ranges/irange.html) integer range generator. - - [c_forfilter](docs/ccommon_api.md#c_forfilter) - ranges-like view filtering. - - [csort](include/stc/algo/csort.h) - [fast quicksort](misc/benchmarks/various/csort_bench.c) with custom inline comparison. + - [crange](docs/algorithm_api.md#crange) - similar to [boost::irange](https://www.boost.org/doc/libs/release/libs/range/doc/html/range/reference/ranges/irange.html) integer range generator. + - [c_forfilter](docs/algorithm_api.md#c_forfilter) - ranges-like view filtering. + - [csort](include/stc/algo/sort.h) - [fast quicksort](misc/benchmarks/various/csort_bench.c) with custom inline comparison. - Renamed `c_ARGSV()` => `c_SV()`: **csview** print arg. Note `c_sv()` is shorthand for *csview_from()*. - Support for [uppercase flow-control](include/stc/priv/altnames.h) macro names in ccommon.h. - Some API changes in **cregex** and **cstr**. @@ -696,10 +759,10 @@ Major changes: - Renamed: *csptr_X_make()* to `carc_X_from()`. - Renamed: *cstr_new()* to `cstr_lit(literal)`, and *cstr_assign_fmt()* to `cstr_printf()`. - Renamed: *c_default_fromraw()* to `c_default_from()`. -- Changed: the [**c_apply**](docs/ccommon_api.md) macros API. +- Changed: the [**c_apply**](docs/algorithm_api.md) macros API. - Replaced: *csview_first_token()* and *csview_next_token()* with one function: `csview_token()`. - Added: **checkauto** tool for checking that c-source files uses `c_auto*` macros correctly. - Added: general `i_keyclass` / `i_valclass` template parameters which auto-binds template functions. -- Added: `i_opt` template parameter: compile-time options: `c_no_cmp`, `c_no_clone`, `c_no_atomic`, `c_is_forward`; may be combined with `|` +- Added: `i_opt` template parameter: compile-time options: `c_no_clone`, `c_no_atomic`, `c_is_forward`; may be combined with `|` - Added: [**cbox**](docs/cbox_api.md) type: smart pointer, similar to [Rust Box](https://doc.rust-lang.org/rust-by-example/std/box.html) and [std::unique_ptr](https://en.cppreference.com/w/cpp/memory/unique_ptr). -- Added: [**c_forpair**](docs/ccommon_api.md) macro: for-loop with "structured binding" +- Added: [**c_forpair**](docs/algorithm_api.md) macro: for-loop with "structured binding" |
