STC - Smart Template Containers for C
STC - Smart Template Containers for C
News: Version 3.6 released (April 2022)
Introduction
STC is a modern, templated, user-friendly, type-safe, very fast and compact container library for C99. The API is fairly similar to c++ STL, but a bit more uniform across the containers and takes inspiration from Rust and Python too. It is an advantage to know how these containers work in other languages, like Java, C# or C++, but it's not required.
This library allows you to manage both trivial to very complex data in a wide variety of containers without the need for boilerplate code. You may specify element-cloning, -comparison, -destruction and more on complex container hierarchies without resorting to cumbersome function pointers with type casting. Usage with trivial data types is simple to use compared to most generic container libraries for C because of its type safety with an intuitive and consistent API.
Three standout features of STC are
- the centralized analysis of template arguments: It 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 must be defined.
- the 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*
may be used as lookup type. It will then use the inputconst char*
directly when comparing with the string data in the container. This avoids the construction of a newcstr
(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. The alternative lookup type may also be used for adding entries into containers by using the emplace-functions. E.g.MyCStrVec_emplace_back(&vec, "Hello")
, which further simplifies usage of STC. - the design of 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 asIntContainer
withint
elements. Also the formc_foreach (it, IntContainer, it1, it2)
may be used to iterate fromit1
up toit2
.
The library is mature and well tested, so you may use it in projects. However, minor breaking API changes may still happen. The main development of this project is finished, but I will handle PRs with bugs and improvements in the future, and do minor modifications.
Contents
- ccommon - RAII and iterator macros
- carc - std::shared_ptr alike support
- carr2/3 - 2d and 3d dynamic array type
- cbits - std::bitset alike type
- cbox - std::unique_ptr alike type
- cdeq - std::deque alike type
- clist - std::forward_list alike type
- cmap - std::unordered_map alike type
- cpque - std::priority_queue alike type
- cqueue - std::queue alike type
- cset - std::unordered_set alike type
- csmap - std::map sorted map alike type
- csset - std::set sorted set alike type
- cstack - std::stack alike type
- cstr - std::string alike type
- csview - std::string_view alike type
- cvec - std::vector alike type
Others:
- crandom - A novel very fast PRNG named stc64
- coption - Command line options scanner
- threads - Mimic C11-threads (by Marcus Geelnard)
Highlights
- 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.
- Templates - Use
#define i_{arg}
to specify container template arguments. There are templates for element-type, -comparison, -destruction, -cloning, -conversion types, and more. - Unparalleled performance - Some containers are much faster than the c++ STL containers, the rest are about equal in speed.
- Fully memory managed - All containers will destruct keys/values via destructor defined as macro parameters before including the container header. Also, shared pointers are supported and can be stored in containers, see carc.
- Fully type safe - Because of templating, it avoids error-prone casting of container types and elements back and forth from the containers.
- Uniform, easy-to-learn API - Methods to construct, initialize, iterate and destruct have uniform and intuitive usage across the various containers.
- Small footprint - Small source code and generated executables. The executable from the example below with six different containers is 22 kb in size compiled with gcc -Os 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.
- 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).
- Container prefix and forward declaration - Templated containers may have user defined prefix, e.g. myvec_push_back(). They may also be forward declared without including the full API/implementation. See documentation below.