summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.md69
-rw-r--r--docs/cspan_api.md47
2 files changed, 61 insertions, 55 deletions
diff --git a/README.md b/README.md
index 311763e1..e9ddf7de 100644
--- a/README.md
+++ b/README.md
@@ -3,14 +3,14 @@
STC - Smart Template Containers for C
=====================================
-News: Version 4.1 RC3 (Feb 2023)
+News: Version 4.1 Released (Feb 2023)
------------------------------------------------
Major changes:
- A new exciting [**cspan**](docs/cspan_api.md) single/multi-dimensional array view (with numpy-like slicing).
- Signed sizes and indices for all containers. See C++ Core Guidelines by Stroustrup/Sutter: [ES.100](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es100-dont-mix-signed-and-unsigned-arithmetic), [ES.102](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es102-use-signed-types-for-arithmetic), [ES.106](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es106-dont-try-to-avoid-negative-values-by-using-unsigned), and [ES.107](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#es107-dont-use-unsigned-for-subscripts-prefer-gslindex).
- 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).
-- Uppercase flow-control macro names in ccommon.h [supported as alternative](include/stc/priv/altnames.h).
+- Uppercase flow-control macro names in ccommon.h [supported as alternatives](include/stc/priv/altnames.h).
- Some API changes in cregex and cstr.
- [Previous changes for version 4](#version-4).
@@ -46,7 +46,7 @@ Containers
- [***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::mdspan** alike type](docs/cspan_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)
@@ -86,49 +86,53 @@ Benchmark notes:
- **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.
-Three standout features of STC
-------------------------------
-1. ***Centralized analysis of template arguments***. Assigns good defaults to non-specified templates.
-You may specify a number of "standard" template arguments for each container, but as minimum only one is
-required (two for maps). In the latter case, STC assumes the elements are basic types. For more complex types,
-additional template arguments should be defined.
-2. ***General "heterogeneous lookup"-like feature***. Allows specification of an alternative type to use
-for lookup in containers. E.g. for containers with string type (**cstr**) elements, `const char*` is used
-as lookup type. It will then use the input `const char*` directly when comparing with the string data in the
-container. This avoids the construction of a new `cstr` (which possible allocates memory) for the lookup.
-Finally, destruction of the lookup key (i.e. string literal) after usage is not needed (or allowed), which
-is convenient in C. A great ergonomic feature is that the alternative lookup type can also be used for adding
-entries into containers through using the *emplace*-functions. E.g. `MyCStrVec_emplace_back(&vec, "Hello")`.
-3. ***Standardized container iterators***. All container can be iterated the same way, and uses the
-same element access syntax. E.g. `c_foreach (it, IntContainer, container) printf(" %d", *it.ref);` will work for
-every type of container defined as `IntContainer` with `int` elements. Also the form `c_foreach (it, IntContainer, it1, it2)`
-may be used to iterate from `it1` up to `it2`.
-
-Naming conventions
-------------------
+STC 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`.
+- All containers can be initialized with `{0}`, i.e. no heap allocation used for empty init.
- Common types for container type Con:
- Con
- - Con_value -- element type
- - Con_raw -- same as Con_value by default
+ - Con_value
+ - Con_raw
- Con_iter
+ - Con_ssize
- Common function names for container type Con:
- Con_init()
- Con_reserve(&con, capacity)
- Con_drop(&con)
- Con_empty(&con)
- Con_size(&con)
- - Con_push(&con, value)
- - Con_put_n(&con, values, n)
- Con_clone(con)
+ - Con_push(&con, value)
+ - Con_emplace(&con, rawval)
+ - Con_put_n(&con, rawval[], n)
- Con_erase_at(&con, iter)
- Con_front(&con)
- Con_back(&con)
- Con_begin(&con)
- Con_end(&con)
- Con_next(&iter)
+ - Con_advance(iter, n)
+
+Standout features of STC
+------------------------
+1. ***Centralized analysis of template arguments***. Assigns good defaults to non-specified templates.
+You may specify a number of "standard" template arguments for each container, but as minimum only one is
+required (two for maps). In the latter case, STC assumes the elements are basic types. For more complex types,
+additional template arguments should be defined.
+2. ***General "heterogeneous lookup"-like feature***. Allows specification of an alternative type to use
+for lookup in containers. E.g. for containers with string type (**cstr**) elements, `const char*` is used
+as lookup type. It will then use the input `const char*` directly when comparing with the string data in the
+container. This avoids the construction of a new `cstr` (which possible allocates memory) for the lookup.
+Finally, destruction of the lookup key (i.e. string literal) after usage is not needed (or allowed), which
+is convenient in C. A great ergonomic feature is that the alternative lookup type can also be used for adding
+entries into containers through using the *emplace*-functions. E.g. `MyCStrVec_emplace_back(&vec, "Hello")`.
+3. ***Standardized container iterators***. All container can be iterated the same way, and uses the
+same element access syntax. E.g. `c_foreach (it, IntContainer, container) printf(" %d", *it.ref);` will work for
+every type of container defined as `IntContainer` with `int` elements. Also the form `c_foreach (it, IntContainer, it1, it2)`
+may be used to iterate from `it1` up to `it2`.
Usage
-----
@@ -153,17 +157,16 @@ int main(void)
FVec_drop(&vec); // cleanup memory
}
```
-Below is an alternative way to write this code with STC. It uses the generic flow control macros c_auto and c_foreach,
-and the function macro *c_make()*. This simplifies the code and makes it less prone to errors, while maintaining readability:
+Below is an alternative way to write this with STC. It uses the generic flow control macros `c_auto` and `c_foreach`, and the function macro *c_make()*. This simplifies the code and makes it less prone to errors:
```c
int main()
{
- c_auto (FVec, vec) // RAII: define vec, init() and drop() all-in-one syntax.
+ c_auto (FVec, vec) // RAII: define, init() and drop() combined.
{
- vec = c_make(FVec, {10.f, 20.f, 30.f}); // Initialize with a list of floats.
+ vec = c_make(FVec, {10.f, 20.f, 30.f}); // Initialize with a list of floats.
- c_foreach (i, FVec, vec) // Iterate elements of the container.
- printf(" %g", *i.ref); // i.ref is a pointer to the current element.
+ c_foreach (i, FVec, vec) // Iterate elements of the container.
+ printf(" %g", *i.ref); // i.ref is a pointer to the current element.
}
// vec is "dropped" at end of c_auto scope
}
diff --git a/docs/cspan_api.md b/docs/cspan_api.md
index db706a51..1bd36446 100644
--- a/docs/cspan_api.md
+++ b/docs/cspan_api.md
@@ -1,16 +1,19 @@
# STC [cspan](../include/stc/cspan.h): Multi-dimensional Array View
![Array](pics/array.jpg)
-The **cspan** is templated non-owning multi-dimensional view of an array. It is similar to Python's
-numpy array slicing and C++ [std::span](https://en.cppreference.com/w/cpp/container/span) / [std::mdspan](https://en.cppreference.com/w/cpp/container/mdspan).
+The **cspan** is templated non-owning *single* and *multi-dimensional* view of an array. It is similar
+to Python's numpy array slicing and C++ [std::span](https://en.cppreference.com/w/cpp/container/span) /
+[std::mdspan](https://en.cppreference.com/w/cpp/container/mdspan).
## Header file and declaration
-
+**cspan** types are defined by the *using_cspan()* macro after the header is included.
+This is different from other containers where template parameters are defined prior to
+including each container. This works well mainly because cspan is non-owning.
```c
#include <stc/cspan.h>
using_cspan(SpanType, ValueType); // define a 1-d SpanType with ValueType elements.
-using_cspan(SpanTypeN, ValueType, Rank); // define multi-dimensional span with Rank.
- // Rank is number of dimensions (max 5)
+using_cspan(SpanTypeN, ValueType, RANK); // define multi-dimensional span with RANK.
+ // RANK is the literal number of dimensions
// Shorthands:
using_cspan2(S, ValueType); // define span types S, S2 with ranks 1, 2.
using_cspan3(S, ValueType); // define span types S, S2, S3 with ranks 1, 2, 3.
@@ -20,25 +23,25 @@ using_cspan4(S, ValueType); // define span types S, S2, S3, S4 with
All functions are type-safe. Note that the span argument itself is generally not side-effect safe,
i.e., it may be expanded multiple times. However, all integer arguments are safe, e.g.
-`cspan_at(&ms3, i++, j++, k++)` is fine. If the number of arguments does not match the span rank,
-a compile error is issued. Runtime bounds checks are enabled by default (define STC_NDEBUG or NDEBUG to disable).
+`cspan_at(&ms3, i++, j++, k++)` is allowed. If the number of arguments does not match the span rank,
+a compile error is issued. Runtime bounds checks are enabled by default (define `STC_NDEBUG` or `NDEBUG` to disable).
```c
-SpanTypeN cspan_md(ValueType* data, intptr_t xdim, ...); // create a multi-dimensional cspan
-SpanType cspan_make(T SpanType, {v1, v2, ...}); // make a 1d-dimensional cspan from values
-SpanType cspan_from(STCContainer* cnt); // create a 1d cspan from a compatible STC container
-SpanType cspan_from_array(ValueType array[]); // create a 1d cspan from a C array
+SpanType cspan_make(T SpanType, {v1, v2, ...}); // make a 1-d cspan from values
+SpanType cspan_from(STCContainer* cnt); // make a 1-d cspan from compatible STC container
+SpanType cspan_from_array(ValueType array[]); // make a 1-d cspan from C array
+SpanTypeN cspan_md(ValueType* data, intptr_t xdim, ...); // make a multi-dimensional cspan
intptr_t cspan_size(const SpanTypeN* self); // return number of elements
-unsigned cspan_rank(const SpanTypeN* self); // return number of dimensions
+intptr_t cspan_rank(const SpanTypeN* self); // dimensions; compile time constant
intptr_t cspan_index(const SpanTypeN* self, intptr_t x, ..); // index of element
-ValueType* cspan_at(const SpanTypeN* self, intptr_t x, ...); // at(): num of args specifies rank of input span.
+ValueType* cspan_at(const SpanTypeN* self, intptr_t x, ...); // #args must match input span rank
ValueType* cspan_front(const SpanTypeN* self);
ValueType* cspan_back(const SpanTypeN* self);
// general index slicing to create a subspan.
- // {x} reduces rank. {x,c_END} slice to end. {c_ALL} take the full extent.
-SpanTypeN cspan_slice(T SpanTypeN, const SpanTypeM* parent, {x0,x1}, {y0,y1}, ...);
+ // {i} reduces rank. {i,c_END} slice to end. {c_ALL} use the full extent.
+SpanTypeR cspan_slice(T SpanTypeR, const SpanTypeN* self, {x0,x1}, {y0,y1}.., {N0,N1});
// create a subspan of lower rank. Like e.g. cspan_slice(Span2, &ms4, {x}, {y}, {c_ALL}, {c_ALL});
SpanType cspan_submd2(const SpanType2* self, intptr_t x); // return a 1d subspan from a 2d span.
@@ -56,13 +59,13 @@ void SpanType_next(SpanTypeN_iter* it);
```
## Types
-| Type name | Type definition | Used to represent... |
-|:------------------|:-----------------------------------------------|:---------------------|
-| SpanTypeN | `struct { ValueType *data; uint32_t shape[N]; }` | SpanType with rank N |
-| SpanTypeN`_value` | `ValueType` | The ValueType |
-| `c_ALL` | `0,-1` | Full extent |
-| `c_END` | `-1` | End of extent |
-
+| Type name | Type definition | Used to represent... |
+|:------------------|:----------------------------------------------------|:---------------------|
+| SpanTypeN | `struct { ValueType *data; uint32_t shape[N]; .. }` | SpanType with rank N |
+| SpanTypeN`_value` | `ValueType` | The ValueType |
+| `c_ALL` | | Full extent |
+| `c_END` | | End of extent |
+
## Example 1
The *cspan_slice()* function is similar to pythons numpy multi-dimensional arrays slicing, e.g.: