STC
A modern, user friendly, generic, type-safe and fast C99 container library: String, Vector, Sorted and Unordered Map and Set, Deque, Forward List, Smart Pointers, Bitset and Random numbers.
Install / Use
/learn @stclib/STCREADME
STC - Smart Template Containers
Version 6.0 RC4
STC is a mature, comprehensive, general purpose container and algorithm library for C99/C11. It has excellent ergonomics and requires virtually no boilerplate code. The library adds many missing features to C, like common data containers, algorithms, and abstractions found in contemporary system languages like Zig, Rust, and C++. Containers and algorithms are templated or generic, which allows for a fully typesafe, compact, and high performance implementation.
<details> <summary><b>Version 6 NEWS</b></summary> Apologies for the multiple API changes particularly on the coroutine, cspan and cregex modules after V5.1. From upcoming V6.0 release, API is planned to be stable and changes will be made backward compatible.V6.0:
- New powerful V2 coroutines with waitgroups, cancellation and async finalization.
- Fixed #149: improved cregex API and fixed bug on word-boundary match.
- Fixed #143: major container initialization flaw.
- Fixed #146: regression on cstr initialization.
- Fixed #142: regression regarding i_no_clone.
- Fixed #138: general hash function bug.
- Fixed queue/deque shrink_to_fit() and reserve() bugs.
- Fixed i_aux and custom allocations bugs.
- Fixed #136: missing exports in hmap, #137: declare_hash_set()
- Fixed #133: bug in vec/stack _begin() and _rbegin().
- Fixed #129 & #150: Makefile bugs and improvements.
- Fixed #128: bug in cstr_istarts_with().
- Issue #123: Added GNU print format attribute to cstr_from_fmt(), cstr_printf().
- Improved documentation.
V5.1:
- Specifying containers with non-trivial element types can now be done with a single
#defineprior to including the container (usingc_class_key,c_pro_key, andc_comp_keyoption traits). - Users may now define
Tas a shorthand fori_type. - Replaced arc with a new implementation which take up only one pointer. Previous arc is now available as a traits option (c_use_arc2). The new arc may not be constructed from an object pointer, for that use arc2.
- Updated and fixed bugs in cregex to handle invalid utf8 strings.
- Some breaking changes in cspan API.
- Several other smaller improvements and bug fixes.
V5.0.2:
- Changed
c_foreach (...)=>for (c_each(...)), andc_forrange(...)=>for (c_range(...)), etc.
V5.0:
- Added build system/CI with Meson. Makefile provided as well.
- Added support for extending templated containers by
#define i_aux <TYPE>. - Changed ranged for-loop macros to use more natural C-syntax (v5.0.2)
- Added sum type (tagged union), included via
algorithm.h - Added single/multi-dimensional generic span type, with numpy-like slicing.
- Updated coroutines support with structured concurrency and symmetric coroutines.
- Updated coroutines support with proper error handling and error recovery.
- Template parameter
Tlets you define container type plusi_keyandi_val(ori_opt) all in one line. - Template parameters
i_class_keyandi_class_valto specify types with_drop()and_clone()functions defined. - Template parameters
i_pro_keyandi_pro_valto specifycstr,boxandarctypes (users may also define pro-types). - hmap now uses Robin Hood hashing (very fast on clang compiler).
- Several new algorithms added, e.g.
c_filter(ranges-like),c_shuffle,c_reverse. See also version history for breaking changes in V5.0.
A. Supplementing features missing in the C standard library
- A wide set of high performance, generic/templated typesafe container types, including smart pointers and bitsets.
- String type with utf8 support and short string optimization (sso), plus two string-view types.
- Typesafe and ergonomic sum type implementation, aka. tagged union or variant.
- A coroutine implementation with good ergonomics, error handling/recovery and cleanup support.
- Fast, modern regular expressions with full utf8 and a subset of unicode character classes support.
- Ranges algorithms like iota and filter views like take, skip, take-while, skip-while, map.
- Generic algorithms, iterators and loop abstactions. Blazing fast sort, binary search and lower bound.
- Single/multi-dimensional generic span view with arbitrary array dimensions and numpy array-like slicing.
B. Improved safety and increased productivity
- Abstractions for raw loops, ranged iteration over containers, and generic ranges algorithms. All this reduces the chance of creating bugs, as user code with raw loops and ad-hoc implementation of common algorithms and containers is minimized/eliminated.
- STC is inherently type safe. Essentially, there are no opaque pointers or casting away of type information.
Only where neccesary, generic code will use some macros to do compile-time type-checking before types are casted.
Examples are
c_static_assert,c_const_cast,c_safe_castand macros for safe integer type casting. - Containers and algorithms all use signed integers for indices and sizes, and it encourange to use signed integers for quantities in general (unsigned integers have valid usages as bitsets and in bit operations). This could remove a wide range of bugs related to mixed unsigned-signed calculations and comparisons, which intuitively gives the wrong answer in many cases.
- Tagged unions in C are common, but normally unsafely implemented. Traditionally, it leaves the inactive payload data readily accesible to user code, and there is no general way to ensure that the payload is assigned along with the tag, or that they match. STC sum type is a typesafe version of tagged unions which eliminates all those safety concerns.
Containers
- arc - (atomic) reference counted; shared pointer
- box - heap allocated unique pointer`
- cbits - dynamic bitset
- cstr - string type (short string optimized)
- list - forward linked list
- stack - stack type
- vec - vector type
- deque - double-ended queue
- queue - queue type
- pqueue - priority queue
- hashmap - unordered map
- hashset - unordered set
- sortedmap - binary tree map
- sortedset - binary tree set
Views
- cspan - dynamic multi-dimensional (sub)span array view
- csview - string view (non-zero terminated)
- zsview - zero-terminated string view
Algorithms
- Coroutines - ergonomic, portable coroutines
- Regular expressions - Rob Pike's Plan 9 regexp modernized!
- Tagged unions - a.k.a. sum types, variants, discriminating unions
- for-loop abstractions - ranged and on containers
- Misc generic algorithms - incl. fast qsort/binsort/lowerbound
- Random numbers - a very fast PRNG based on SFC64
- Command line argument parser - similar to getopt()
Contents
<details> <summary>Highlights</summary>Highlights
- 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.
- 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. Smart pointers (shared and unique) works seamlessly when stored in containers. See arc and box.
- Uniform, easy-to-learn API - For the generic containers and algorithms, simply include the headers. The API and functionality resembles c++ STL or Rust and is fully listed in the docs. 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.
- Dual mode compilation - By default it is a header-only library with inline and static methods, but you can easily switch to create a shared library without changing existing source files. Non-generic types, like (utf8) strings are compiled with external linking. one See the installation section.
- 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).
- Pre-declaration - Templated containers may be pre-declared without including the full API/implementation.
- Extendable containers - STC provides a mechanism to wrap containers inside a struct with custom data per instance.
Installation
STC uses meson build system. Make sure to have meson and ninja installed, e.g. as a python pip package from a bash shell:
pip install meson ninja
export LIBRARY_PATH=$LIBRARY_P

