{"id":13812206,"url":"https://github.com/rurban/ctl","last_synced_at":"2025-05-14T21:32:29.974Z","repository":{"id":43035711,"uuid":"325870217","full_name":"rurban/ctl","owner":"rurban","description":"My variant of the C Template Library","archived":false,"fork":true,"pushed_at":"2025-04-17T08:42:33.000Z","size":27554,"stargazers_count":188,"open_issues_count":14,"forks_count":8,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-05-07T17:59:39.881Z","etag":null,"topics":["algorithms","algorithms-and-data-structures","c","deque","hashmap","hashtable","header-only","iterator","list","priority-queue","queue","rbtree","set","stack","stl-containers","tree","verified"],"latest_commit_sha":null,"homepage":"https://rurban.github.io/ctl/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"glouw/ctl","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rurban.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null}},"created_at":"2020-12-31T20:39:27.000Z","updated_at":"2025-04-29T08:18:50.000Z","dependencies_parsed_at":"2023-01-23T10:46:26.051Z","dependency_job_id":null,"html_url":"https://github.com/rurban/ctl","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rurban%2Fctl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rurban%2Fctl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rurban%2Fctl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rurban%2Fctl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rurban","download_url":"https://codeload.github.com/rurban/ctl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254231206,"owners_count":22036322,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorithms","algorithms-and-data-structures","c","deque","hashmap","hashtable","header-only","iterator","list","priority-queue","queue","rbtree","set","stack","stl-containers","tree","verified"],"created_at":"2024-08-04T04:00:49.164Z","updated_at":"2025-05-14T21:32:24.876Z","avatar_url":"https://github.com/rurban.png","language":"C","readme":"# C CONTAINER TEMPLATE LIBRARY (CTL)\n\nCTL is a fast compiling, type safe, header only, template-like\ncontainer library for ISO C99/C11.\n\n[![GH Actions](https://github.com/rurban/ctl/workflows/Full%20C/C++%20CI/badge.svg)](https://github.com/rurban/ctl/actions/)\n[![Cirrus CI](https://api.cirrus-ci.com/github/rurban/ctl.svg)](https://cirrus-ci.com/github/rurban/ctl/)\n[![Codecov](https://codecov.io/gh/rurban/ctl/branch/master/graph/badge.svg?token=l04y4zWBIb)](https://codecov.io/gh/rurban/ctl)\n\n## Use\n\nConfigure a CTL container with a built-in or typedef type `T`.\n\n```C\n    #include \u003cstdio.h\u003e\n    \n    #define POD\n    #define T int\n    #include \u003cctl/vector.h\u003e\n    \n    int compare(int* a, int* b) { return *b \u003c *a; }\n    \n    int main(void)\n    {\n        vec_int a = vec_int_init();\n        vec_int_push_back(\u0026a, 9);\n        vec_int_push_back(\u0026a, 1);\n        vec_int_push_back(\u0026a, 8);\n        vec_int_push_back(\u0026a, 3);\n        vec_int_push_back(\u0026a, 4);\n        vec_int_sort(\u0026a, compare);\n        foreach(vec_int, \u0026a, it)\n            printf(\"%d\\n\", *it.ref);\n        vec_int_free(\u0026a);\n    }\n```\n\nDefinition `POD` states type `T` is Plain Old Data (POD).\n\nFor a much more thorough getting started guide,\nsee the wiki: https://github.com/rurban/ctl/wiki and\nhttps://github.com/glouw/ctl/wiki for the original sample with three-letter names.\n\n## Motivation\n\nCTL aims to improve ISO C99/C11 developer productivity by implementing\nall containers in ISO C99/C11:\n\n| CTL                                            | = C++ STL            | C prefix |\n|:-----------------------------------------------|:---------------------|----------|\n| [ctl/deque.h](docs/deque.md)                   | std::deque           | deq      |\n| [ctl/list.h](docs/list.md)                     | std::list            | list     |\n| [ctl/forward_list.h](docs/slist.md)            | std::forward_list    | slist    |\n| [ctl/priority_queue.h](docs/priority_queue.md) | std::priority_queue  | pqu      |\n| [ctl/queue.h](docs/queue.md)                   | std::queue           | queue    |\n| [ctl/set.h](docs/set.md)                       | std::set             | set      |\n| [ctl/stack.h](docs/stack.md)                   | std::stack           | stack    |\n| [ctl/string.h](docs/string.md)                 | std::string          | str      |\n| [ctl/vector.h](docs/vector.md)                 | std::vector          | vec      |\n| [ctl/array.h](docs/array.md)                   | std::array           | arrNNNN  |\n| [ctl/map.h](docs/map.md)                       | std::map             | map      |\n| [ctl/unordered_map.h](docs/unordered_map.md)   | std::unordered_map   | umap     |\n| [ctl/unordered_set.h](docs/unordered_set.md)   | std::unordered_set   | uset     |\n|------------------------------------------------|----------------------|\n| [ctl/algorithm.h](docs/algorithm.md)           | `\u003calgorithm\u003e`        |\n| [ctl/numeric.h](docs/numeric.md)               | `\u003cnumeric\u003e`          |\n\nIn work:\n\n[ctl/pair.h](docs/pair.md),\n[ctl/hashmap.h](docs/hashmap.md),\n[ctl/swisstable.h](docs/swisstable.md),\n[ctl/btree.h](docs/btree.md),\n[ctl/u8string.h](docs/u8string.md),\n[ctl/u8ident.h](docs/u8ident.md).\n\nmap (with pairs), and some C++ methods, algorithms are in work still.\n\nIt is based on glouw's ctl, but with proper names, and using the incpath `ctl/` prefix.\n\nmultiset and multimap can be composed by set and list. Better open\nflat hashmap's are in work as stanford hash variant for integer keys, and\nswisstable for string keys, both with the `unordered_map` API.\n\n## Memory Ownership\n\nTypes with memory ownership require definition `POD` be omitted, and require\nfunction declarations for the C++ equivalent of the destructor and copy constructor,\nprior to the inclusion of the container:\n\n```C\n    typedef struct { ... } type;\n    void type_free(type*);\n    type type_copy(type*);\n    #define T type\n    #include \u003cctl/vector.h\u003e\n```\n\nForgetting a declaration will print a human-readable error message:\n\n```shell\ntests/test_c11.c:11:11: error: ‘type_free’ undeclared (first use in this function)\n   11 | #define T type\n```\n\n## Compare\n\nIn contrast to the original CTL, this applies default `compare` and `equal` methods\nto all integral types T as `int`, `long`, `bool`, `char`, `short`, `float`, `double`, `char8_t`,\n`uint8_t` - `uin64_t`, `int8_t` - `in64_t`.\nSince T may not contain a space, we also accept `long double` as `ldbl`,\n`long long` as `llong`, `unsigned int` as `uint` and `uint8_t` - `uin64_t`,\n`unsigned long` as `ulong`, `unsigned char` as `uchar`.\n\nOnly with structs a `compare` and optionally an `equal` method must be set.\nRemoved the compare and equal args from `equal`, `sort`, `sort_range`, `find`,\n`merge`, `unique`.\n\nWithout an `equal` method two `compare` calls are used, so having a special equal\nmethod is preferred if one of those methods from above are used.\n\n**2way vs 3way compare**: Officially only the lower-than `operator\u003c` 2-way comparator\nis supported, as in the STL. However, with the `set` core methods the 3way\ncomparator `\u003c=\u003e` (such as e.g. `memcmp`, `strcmp`) may also be used. Not with algorithms!\nIt is not faster with 3way, rather slower.\n\nIf you have a POD type, i.e. a struct with only integral types, i.e. no pointers, you\nhave to define `NOT_INTEGRAL`.\n\n```C\n\n    #define POD\n    #define NOT_INTEGRAL\n    #define T point\n    #include \u003cctl/priority_queue.h\u003e\n    \n    // or\n    \n    #define T digi\n    #include \u003cctl/deque.h\u003e\n\n    deq_digi a = deq_digi_init();\n    a.compare = digi_compare;\n    a.equal = digi_equal;\n```\n\nForgetting a compare method will assert with \"compare undefined\", if enabled.\n\n## Iterators and Ranges\n\nThe special iterator objects created by `begin`, `end` and returned by `next`,\n`advance` contain the current and the end position for ranges, 3 vtable methods,\nand have more iterator specific fields contained within. Thus they are fat and\nsafe iterators.\n\nPrevious versions of the ctl (_with version numbers \u003c 202000_) had different heavier\nand incompatible iterators, initialized by `each`. Our iterators are as in the\nSTL initialized with `begin` or `end`, and for ranges with `range`.  Now they are\ncompatible with the STL and are safer.\n\nWe also support for certain algorithm methods **generic iterators** as 2nd range,\nabstracting different containers. So we can insert a vector into a deque, or use\na mixed set algorithm with different container types. They are denoted as `GI*`,\ngeneric iters, and can be simply casted from container-specific iterators.\n\nSee [iterators](docs/iterators.md).\n\nRange methods are suffixed with `_range`, taking a single iterator as range,\nsimilar to C++20 ranges, but the STL uses a pair of two iterators. We are using one.\n\n## Performance\n\nCTL performance is presented in solid colors, and STL in dotted colors,\nfor template type `T` as type `int` for all measurements.\n\n![](docs/images/vec.log.png)\n![](docs/images/list.log.png)\n![](docs/images/slist.log.png)\n![](docs/images/deq.log.png)\n![](docs/images/set.log.png)\n![](docs/images/uset.log.png)\n![](docs/images/pqu.log.png)\n![](docs/images/arr.log.png)\n![](docs/images/str.log.png)\n![](docs/images/compile.log.png)\n\nOmitted from these performance measurements are `queue.h` and `stack.h`,\nas their performance characteristics can be inferred from `deque.h`.\nLikewise `map.h` from `set.h` and `unordered_map.h` from `unordered_set.h`.\n\n`unordered_set.h` is defined with the default `CTL_USET_GROWTH_PRIMED`.\nlibstdc++ uses POWER2 by default, libc++ supports both, depending on the initial size.\n`CTL_USET_GROWTH_POWER2` is here:\n\n![](docs/images/uset_pow2.log.png)\n\n`CTL_USET_CACHED_HASH` is here:\n\n![](docs/images/uset_cached.log.png)\n\nThis trades memory for faster unsuccessful searches, such as with insert with\nhigh load factor.\n\nC is rougly comparable to C++ included, but note that most of the\nC++ functions are dynaloaded from `libstdc++.so.6`, whilst the C versions are\ndirectly in the binary.\n\n## Security\n\nThe CTL is more opinionated on security than the STL.\n\nThe default **`max_size`** of containers is restricted to max 2^32 byte, i.e. 2GB,\nto avoid DDOS attacks. Allocating an overlarge container may need several\nminutes until it crashes. If you really need more than 2GB containers adjust\nyour `max_size` for your container.\n\nThe `unordered_set` hashtable has by default **security policies** enabled to avoid\n**DDOS attacks** by exploiting weak hash functions or exposure of ordering on the\nunfortunate linked-list chaining, demanded by the unfortunate C++ specs. The\nusual random seed strategy is considered security theatre, but can be enabled by\n`#define CTL_USET_SECURITY_COLLCOUNTING 0` and define a custom hash function\nwith a random seed.\nSee [unordered_set hash-policy](docs/unordered_set.md#hash-policy) and\n[github.com/rurban/smhasher/#security](https://github.com/rurban/smhasher/#security).\n\nUsing a mix of 3way and 2way comparators may lead to **endless loops** with certain\nsequences only. The STL does nothing against it, we try to detect this at least in the\nset core methods.\n\nThe CTL is **formally verified** via cbmc and satabs models for most core functions, the\nSTL not. Several STL bugs and limitations have been found by our extensive test suite. See\nalso [cprover.org/stl/](http://www.cprover.org/stl/) for \u003cvector\u003e and \u003clist\u003e verifications.\n\nProper unicode security practices are in work. The STL and most other libraries ignore\nit. Esp. for identifiers, which need to be identifiable, but are not. But the\nSTL cannot even compare, i.e. find strings, only byte buffers.\n\n## Running Tests\n\nTo run all functional tests, run:\n\n```shell\nmake\n```\n\nTo compile examples, run:\n\n```shell\nmake examples\n```\n\nTo generate performance graphs, run:\n\n```shell\nmake images\n\n# Graphing requires python3 and the Plotly family of libraries via pip3.\npip install plotly\npip install psutil\npip install kaleido\n```\n\nTo do all of the above in one step, run:\n\n```shell\n./all.sh\n```\n\nThe full CI suite is run via: (1-2 hrs)\n```shell\n./ci-all.sh\n```\n\nTo generate the manpages or run `make install` install the `ronn` gem.\n\nFor maintaining CTL, a container templated to type `int` can be\noutput to `stdout` by running make on the container name with .i, eg:\n\n```shell\nmake ctl/deque.i\nmake ctl/list.i\nmake ctl/priority_queue.i\nmake ctl/queue.i\nmake ctl/set.i\nmake ctl/stack.i\nmake ctl/string.i\nmake ctl/vector.i\nmake ctl/array.i\nmake ctl/map.i\nmake ctl/unordered_set.i\nmake ctl/unordered_map.i\nmake ctl/hashmap.i\nmake ctl/swisstable.i\nmake tests/func/test_c11.i\nmake tests/func/test_list.i\n```\n\n## Other\n\nSTL variants of multi-sets and multi-maps will not be implemented because\nsimilar behaviour can be implemented as an amalgamation of a `set` and `list`.\nSee `tests/func/test_container_composing.cc`\n\nUTF-8 strings and identifiers will be added eventually, Wide, UTF-16 or UTF-32\nnot. Parallel variants of all containers and algos in `pctl` with openmp are in\nplanning.\n\nMany methods from algorithm, with iterators and range are now implemented, with\niterators changed from upstream.\nAlso implemented are type utilities to omit default compare, equal and hash methods\nfor POD integral types.\n\nIn planning are also `small_vector` (stack-allocated for performance),\n`sorted_vector` and parallel, thread-safe variants in `pctl`.\n\nSee also [Differences](#differences) below.\n\nMany other header-only STL variants in C exist:\n* [pottery](https://github.com/ludocode/pottery) which also sucks less and also\n  fairly complete and decent,\n* [matrixjoeq/c_container](https://github.com/matrixjoeq/c_container) which is even better,\n* [mlib](https://github.com/P-p-H-d/mlib) good stuff, but maybe a bit over-engineered,\n* [Gena](https://github.com/cher-nov/Gena)\n* [OpenCSTL](https://github.com/springkim/OpenCSTL)\n* https://github.com/LeoVen/C-Macro-Collections\n* [STC](https://github.com/stclib/STC) _(Windows preferred)_\n\nIn its infancies:\n* [CSTL](https://github.com/brliron/CSTL)\n* https://github.com/yaowen369/STL_Container_with_C/\n* [libmowgli](https://github.com/atheme/libmowgli-2)\n* [libulz](https://github.com/rofl0r/libulz)\n* https://github.com/hstefan/htlib\n* https://github.com/SLukasDE/scf\n\nAnd in its grandiosity (esp. not header-only):\n* [glib](http://suckless.org/sucks/),\n* https://github.com/attractivechaos/klib,\n* http://libcello.org/\n* https://github.com/bkthomps/Containers\n* https://github.com/MichaelJWelsh/cdsa\n* https://github.com/concurrencykit/ck\n* https://github.com/mgrosvenor/libchaste\n* https://bitbucket.org/manvscode/libcollections/\n* https://github.com/fmela/libdict\n* https://github.com/fredrikwidlund/libdynamic\n* https://www.liblfds.org/\n* https://github.com/faragon/libsrt\n* https://github.com/ned14/nedtries\n* http://wolkykim.github.io/qlibc/\n* http://sglib.sourceforge.net/\n* [Smart pointer for GNUC](https://github.com/Snaipe/libcsptr)\n* [STB stretchy buffer](https://github.com/nothings/stb)\n* https://github.com/amadvance/tommyds\n* https://github.com/2cats/cstl-lite\n* https://github.com/ljianhui/libcontainer\n* http://troydhanson.github.io/uthash/\n* https://github.com/rurban/safeclib by yours truly\n\n## Base Implementation Details\n\n\n    array.h:            stack/heap allocated\n    vector.h:           realloc\n    string.h:           vector.h\n    deque.h:            realloc (paged)\n    queue.h:            deque.h\n    stack.h:            deque.h\n    priority_queue.h:   vector.h\n    list.h:             doubly linked list\n    forward_list.h:     single linked list\n    set.h:              red black tree\n    map.h:              set.h\n    unordered_set.h:    hashed forward linked lists\n    unordered_map.h:    unordered_set.h (pair in work)\n    hashmap.h:          stanford hash for integer keys, intel only.\n    swisstable.h:       abseil flat_hash_map for string keys, with non-intel fallbacks.\n\n    ✓  stable and tested\n    x  implemented, but broken or untested\n       not yet implemented\n    -  unspecified, unsupported\n\n\n|                                 |vec |str |arr |deq |list|slst|set |map |uset|umap|pqu |que |stk |\n|---------------------------------|----|----|----|----|----|----|----|----|----|----|----|----|----|\n|`init`                           | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |\n|`init_from`                      | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |\n|`free`                           | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |\n|`copy`                           | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  |    |    |    |\n|`size`                           | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |\n|`max_size`                       | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |\n|`empty`                          | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |\n|`equal`                          | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |\n|`insert`                         | ✓  | ✓  | -  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`insert_index`                   | ✓  | ✓  | -  | ✓  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`insert_count`                   | ✓  | ✓  | -  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  |\n|`insert_range`                   | ✓  | ✓  | -  | ✓  | ✓  | x  | ✓  |    | -  | -  | -  | -  | -  |\n|`insert_generic`                 | x  |    |    | x  | ✓  | ✓  | ✓  |    | x  |    | -  | -  | -  |\n|`insert_found`                   | -  | -  | -  | -  | -  | -  | ✓  |    | ✓  | ✓  | -  | -  | -  |\n|`insert_or_assign`               | -  | -  | -  | -  | -  | -  | -  | ✓  | -  | ✓  | -  | -  | -  |\n|`insert_or_assign_found`         | -  | -  | -  | -  | -  | -  | -  |    | -  | ✓  | -  | -  | -  |\n|`load_factor`                    | -  | -  | -  | -  | -  | -  | -  | -  | ✓  | ✓  | -  | -  | -  |\n|`max_load_factor`                | -  | -  | -  | -  | -  | -  | -  | -  | ✓  | ✓  | -  | -  | -  |\n|`max_bucket_count`               | -  | -  | -  | -  | -  | -  | -  | -  | ✓  | ✓  | -  | -  | -  |\n|`bucket_count`                   | -  | -  | -  | -  | -  | -  | -  | -  | ✓  | ✓  | -  | -  | -  |\n|`bucket_size`                    | -  | -  | -  | -  | -  | -  | -  | -  | ✓  | ✓  | -  | -  | -  |\n|`rehash`                         | -  | -  | -  | -  | -  | -  | -  | -  | ✓  | ✓  | -  | -  | -  |\n|`emplace`                        | x  |    | -  | ✓  | ✓  | ✓  | x  | -  | ✓  | x  | ✓  | -  | -  |\n|`emplace_front`                  | -  | -  | -  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  |\n|`emplace_back`                   | ✓  | -  | -  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  |\n|`emplace_hint`                   | -  | -  | -  | -  | -  | -  |    |    | ✓  | x  | -  | -  | -  |\n|`reserve`                        | ✓  | ✓  | -  | -  | -  | -  | -  | -  | ✓  | ✓  | -  | -  | -  |\n|`find`                           | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`erase`                          | ✓  | ✓  | -  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`erase_if`                       | ✓  |    | -  | ✓  | ✓  | ✓  | ✓  | x  | ✓  | ✓  | -  | -  | -  |\n|`erase_index`                    | ✓  | ✓  | -  | ✓  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`erase_node`                     | -  | -  | -  | -  | ✓  | ✓  | ✓  |    |    |    | -  | -  | -  |\n|`erase_range`                    | ✓  |    | -  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`erase_generic`                  | -  | -  | -  | -  | x  | x  | -  | -  | -  | -  | -  | -  | -  |\n|`top`                            | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | ✓  |    | ✓  |\n|`push`                           | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | ✓  | ✓  | ✓  |\n|`pop`                            | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | ✓  | ✓  | ✓  |\n|`at`                             | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`front`                          | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`back`                           | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`set`                            |    |    |    |    |    |    |    |    |    |    | -  | -  | -  |\n|`pop_back`                       | ✓  | ✓  | -  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  |\n|`pop_front`                      | -  | -  | -  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  |\n|`push_back`                      | ✓  | ✓  | -  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  |\n|`push_front`                     | -  | -  | -  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  |\n|`clear`                          | ✓  | ✓  |    | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`assign`                         | ✓  | ✓  | ✓  | ✓  | ✓  | x  | -  | -  | -  | -  | -  | -  | -  |\n|`assign_range`                   | ✓  | -  | ✓  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`assign_generic`                 | ✓  | -  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`resize`                         | ✓  | ✓  | -  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  |\n|`shrink_to_fit`                  | ✓  | ✓  | -  | ✓  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`data`                           |    |    |    | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`splice`                         | -  | -  | -  | -  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  |\n|`splice_it`                      | -  | -  | -  | -  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  |\n|`splice_range`                   | -  | -  | -  | -  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  |\n|`contains`                       | -  | -  | -  | -  | -  | -  | ✓  | x  | ✓  | ✓  | -  | -  | -  |\n|`append`                         | -  | ✓  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`insert_str`                     | -  |    | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`c_str`                          | -  | ✓  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`find`                           | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`rfind`                          | -  | ✓  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`find_last_of`                   | -  | ✓  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`find_first_not_of`              | -  | ✓  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`find_last_not_of`               | -  | ✓  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`substr`                         | -  | ✓  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`compare`                        | -  | ✓  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`key_compare`                    | -  | ✓  | -  | -  | -  | -  | -  |    | -  |    | -  | -  | -  |\n|---------------------------------|----|----|----|----|----|----|----|----|----|----|----|----|----|\n|                                 |vec |str |arr |deq |list|slst|set |map |uset|umap|pqu |que |stk |\n|---------------------------------|----|----|----|----|----|----|----|----|----|----|----|----|----|\n|`begin`                          | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`end`                            | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`next`                           | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`done`                           | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`set_pos`                        | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`set_done`                       | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`set_end`                        | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`iter`                           | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`ref`                            | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`prev`                           | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  |\n|`distance`                       | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  |\n|`index`                          | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  |\n|`advance`                        | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  |\n|`advance_end`                    | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  |\n|`distance_range`                 | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`range`                          | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  |\n|---------------------------------|----|----|----|----|----|----|----|----|----|----|----|----|----|\n|                                 |vec |str |arr |deq |list|slst|set |map |uset|umap|pqu |que |stk |\n|---------------------------------|----|----|----|----|----|----|----|----|----|----|----|----|----|\n|`all_of`                         | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | ✓  | x  | -  | -  | -  |\n|`any_of`                         | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | ✓  | x  | -  | -  | -  |\n|`none_of`                        | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | ✓  | x  | -  | -  | -  |\n|`all_of_range`                   | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | -  | -  | -  | -  | -  |\n|`any_of_range`                   | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | -  | -  | -  | -  | -  |\n|`none_of_range`                  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | -  | -  | -  | -  | -  |\n|`foreach`                        | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`foreach_range`                  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  |\n|`foreach_n`                      | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  |\n|`foreach_n_range`                | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  |\n|`count`                          | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`count_range`                    | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | -  | -  | -  | -  | -  |\n|`count_if`                       | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | ✓  | x  | -  | -  | -  |\n|`count_if_range`                 | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | -  | -  | -  | -  | -  |\n|`mismatch`                       | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`find_if`                        | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | ✓  | x  | -  | -  | -  |\n|`find_if_not`                    | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | ✓  | x  | -  | -  | -  |\n|`find_range`                     | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | -  | -  | -  | -  | -  |\n|`find_if_range`                  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | -  | -  | -  | -  | -  |\n|`find_if_not_range`              | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | -  | -  | -  | -  | -  |\n|`find_end`                       | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`find_end_range`                 | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`find_first_of`                  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    |    |    | -  | -  | -  |\n|`find_first_of_range`            | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`adjacent_find`                  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`adjacent_find_range`            | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`search`                         | ✓  | ✓  | ✓  | ✓  | ✓  | x  | ✓  |    | -  | -  | -  | -  | -  |\n|`search_range`                   | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`search_n`                       | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`search_n_range`                 | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`copy_range`                     | ✓  | ✓  | -  | ✓  | ✓  | x  |    |    | -  | -  | -  | -  | -  |\n|`inserter`                       | ✓  | ✓  | x  | ✓  | ✓  | ✓  | ✓  |    | ✓  |    | -  | -  | -  |\n|`copy_if`                        | ✓  | ✓  | x  | ✓  | ✓  | ✓  | ✓  |    | ✓  |    | -  | -  | -  |\n|`copy_if_range`                  | ✓  | ✓  | x  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`copy_n`                         |    |    |    |    |    |    |    |    |    |    | -  | -  | -  |\n|`copy_n_range`                   |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`copy_backward`                  |    |    |    |    |    |    |    |    |    |    | -  | -  | -  |\n|`copy_backward_range`            |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`move`                           |    |    |    |    |    |    |    |    |    |    | -  | -  | -  |\n|`move_range`                     |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`move_backward`                  |    |    |    |    |    |    |    |    |    |    | -  | -  | -  |\n|`move_backward_range`            |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`fill`                           |    |    | ✓  |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`fill_range`                     |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`fill_n`                         |    |    | ✓  |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`fill_n_range`                   |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`transform`                      | ✓  | ✓  | ✓  | ✓  | ✓  | x  | ✓  |    | ✓  | x  | -  | -  | -  |\n|`transform_it`                   | ✓  | ✓  | ✓  | ✓  | x  | x  | ✓  |    |    |    | -  | -  | -  |\n|`transform_range`                | ✓  | x  | x  | ✓  | x  | x  | ✓  |    | -  | -  | -  | -  | -  |\n|`transform_it_range`             | x  |    |    | ✓  |    |    | ✓  |    | -  | -  | -  | -  | -  |\n|`generate`                       | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | ✓  | x  | -  | -  | -  |\n|`generate_range`                 | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  |    | -  | -  | -  | -  | -  |\n|`generate_n`                     | ✓  | ✓  | ✓  | ✓  | ✓  | x  | ✓  |    | ✓  |    | -  | -  | -  |\n|`generate_n_range`               | x  | x  | x  | ✓  | x  | x  | ✓  |    | -  | -  | -  | -  | -  |\n|`remove`                         |    |    |    |    | ✓  | ✓  |    |    |    |    | -  | -  | -  |\n|`remove_if`                      | ✓  |    |    | ✓  | ✓  | ✓  | ✓  |    | x  | x  | -  | -  | -  |\n|`remove_copy`                    |    |    |    |    |    |    |    |    |    |    | -  | -  | -  |\n|`remove_copy_if`                 |    |    |    |    |    |    |    |    |    |    | -  | -  | -  |\n|`remove_copy_range`              |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`remove_copy_if_range`           |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`replace`                        |    | ✓  |    |    |    |    |    |    |    |    | -  | -  | -  |\n|`replace_if`                     |    |    |    |    |    |    |    |    |    |    | -  | -  | -  |\n|`replace_range`                  |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`replace_if_range`               |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`replace_copy`                   |    |    |    |    |    |    |    |    |    |    | -  | -  | -  |\n|`replace_copy_if`                |    |    |    |    |    |    |    |    |    |    | -  | -  | -  |\n|`replace_copy_range`             |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`replace_copy_if_range`          |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`swap`                           | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | ✓  | ✓  | ✓  |\n|`swap_ranges`                    |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`iter_swap`                      | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  |    |    | -  | -  | -  |\n|`reverse`                        | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  |\n|`reverse_range`                  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | -  | -  | -  | -  | -  | -  | -  |\n|`reverse_copy`                   |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`reverse_copy_range`             |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`rotate`                         |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`rotate_range`                   |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`rotate_copy`                    |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`rotate_copy_range`              |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`shift_left`                     |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`shift_right`                    |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`shuffle`                        | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  |\n|`shuffle_range`                  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  | -  | -  |\n|`sample`                         |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`sample_range`                   |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`unique`                         | ✓  | x  | -  | x  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  |\n|`unique_range`                   | ✓  | x  | -  | x  | ✓  | x  | -  | -  | -  | -  | -  | -  | -  |\n|`unique_copy`                    |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`unique_copy_range`              |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`is_partitioned`                 |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`is_partitioned_range`           |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`partition`                      |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`partition_range`                |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`partition_copy`                 |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`partition_copy_range`           |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`stable_partition`               |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`stable_partition_range`         |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`partition_point`                |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`partition_point_range`          |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`is_sorted`                      | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`is_sorted_until`                | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`sort`                           | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  |\n|`sort_range`                     |    |    |    | ✓  |    | x  | -  | -  | -  | -  | -  | -  | -  |\n|`partial_sort`                   |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`partial_sort_range`             |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`partial_sort_copy`              |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`partial_sort_copy_range`        |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`stable_sort`                    |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`stable_sort_range`              |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`nth_element`                    |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`nth_element_range`              |    |    |    |    |    |    |    |    | -  | -  | -  | -  | -  |\n|`lower_bound`                    | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`lower_bound_range`              | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`upper_bound`                    | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`upper_bound_range`              | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`binary_search`                  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`binary_search_range`            | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`equal_value`                    | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | -  | -  | -  | -  | -  |\n|`equal_range`                    | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  | x  | -  | -  | -  | -  | -  |\n|`merge`                          | ✓  | ✓  |    | ✓  | ✓  | ✓  | ✓  |    | ✓  | x  | -  | -  | -  |\n|`merge_range`                    | ✓  | ✓  |    | ✓  | ✓  | ✓  | ✓  |    | ✓  |    | -  | -  | -  |\n|`inplace_merge`                  |    |    |    |    |    |    |    |    |    |    | -  | -  | -  |\n|`inplace_merge_range`            |    |    |    |    |    |    |    |    |    |    | -  | -  | -  |\n|`includes`                       | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`includes_range`                 | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|`difference`                     | ✓  | ✓  | -  | ✓  | ✓  | x  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`intersection`                   | ✓  | ✓  | -  | ✓  | ✓  | x  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`symmetric_difference`           | ✓  | ✓  | -  | ✓  | ✓  | x  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`union`                          | ✓  | ✓  | -  | ✓  | ✓  | x  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  |\n|`difference_range`               | ✓  | ✓  | ✓  | ✓  | ✓  | x  | ✓  |    |    |    | -  | -  | -  |\n|`intersection_range`             | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | x  |    |    |    | -  | -  | -  |\n|`symmetric_difference_range`     | ✓  | ✓  | ✓  | ✓  | ✓  | x  | ✓  |    |    |    | -  | -  | -  |\n|`union_range`                    | ✓  | ✓  | -  | ✓  | ✓  | x  | ✓  |    |    |    | -  | -  | -  |\n|`lexicographical_compare`        | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  |    | -  | -  | -  | -  | -  |\n|---------------------------------|----|----|----|----|----|----|----|----|----|----|----|----|----|\n|                                 |vec |str |arr |deq |list|slst|set |map |uset|umap|pqu |que |stk |\n|---------------------------------|----|----|----|----|----|----|----|----|----|----|----|----|----|\n|`gcd`                            |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`lcm`                            |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`midpoint`                       |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`lerp`                           |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`iota`                           | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  |\n|`iota_range`                     | ✓  | ✓  | ✓  | ✓  | ✓  | ✓  | -  | -  | -  | -  | -  | -  | -  |\n|`accumulate`                     |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`accumulate_range`               |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`reduce`                         |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`reduce_range`                   |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`transform_reduce`               |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`transform_reduce_range`         |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`inner_product`                  |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`inner_product_range`            |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`adjacent_difference`            |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`adjacent_difference_range`      |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`partial_sum`                    |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`partial_sum_range`              |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`inclusive_scan`                 |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`inclusive_scan_range`           |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`exclusive_scan`                 |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`exclusive_scan_range`           |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`transform_inclusive_scan`       |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|`transform_exclusive_scan`       |    |    |    |    |    |    | -  | -  | -  | -  | -  | -  | -  |\n|---------------------------------|----|----|----|----|----|----|----|----|----|----|----|----|----|\n|                                 |vec |str |arr |deq |list|slst|set |map |uset|umap|pqu |que |stk |\n\n## Differences\n\n### Differences to the original https://github.com/glouw/ctl\n\n`#include` with the `ctl/` prefix.\n\nUse the original long names, not three-letter abbrevations.\n\n`#define POD` not `P`\n\n`#define NOT_INTEGRAL` not `COMPARE`\n\nOur version number `CTL_VERSION` is greater than 202000 (starting with `202102`),\nthe old ctl is lower than 202000, starting with `1.0`.\n\nAdded lots of missing methods. We have 158 methods in 942 stable variants.\nglouw has 63 methods in 196 stable variants.\n\ninclusion of numeric via `#define INCLUDE_NUMERIC`. For now algorithm is always loaded.\n\nProbe for -std=c++20 c++ support and use this for testing against the STL.\nFallback to c++2a, c++17 or c++11.\n\nAdded **array**, **map** and **unordered_map** containers; generic iterators\nwith a vtable.\n\nAdded docs and manpages.\n\nAdded builtin default `compare` and `equal` methods for the simple integral types T:\n`int`, `long`, `bool`, `char`, `short`, `float`, `double`, `char8_t`,\n`long double`, `long long`, `unsigned int`, `unsigned long`, `unsigned char`.\nOnly with structs a compare and optionally and equal method must be set.\nRemoved the compare and equal args from `equal`, `sort`, `sort_range`, `find`,\n`merge`, `unique`\nAdded compare and equal fields to all.\n\nAdded many `_it` and `_range` method variants to accept iterator pairs or single\nranges, `_found` to return found or not.\nMethods working on iterators don't need the container arg `(A* self)`.\n\n    deque:  insert_range, insert_count, erase_range,\n            emplace, emplace_back, emplace_front, sort_range\n    vector: assign_range, erase_index, erase_range, insert_range, insert_count,\n            emplace, emplace_back\n    list:   remove, emplace, emplace_front, insert_range, insert_count\n    set:    erase_node, erase_range\n    map:    insert_or_assign\n    umap:   insert_or_assign, insert_or_assign_found\n    uset:   clear, equal, insert_found, union, difference, intersection,\n            symmetric_difference, emplace, emplace_found, emplace_hint\n\nvector `swap` does `shrink_to_fit` as in the STL.\n\nThe compare method is two-way `operator\u003c` as in the STL, not `operator\u003e` as in\nglouw/ctl. We support two-way and three-way compare for set, which needs more\ncomparisons, but is safer.\n\nRedesigned iterators and better range support. Much closer to the STL, and\nmuch faster. Full generic iterator support is in `bits/iterator.h`,\n`bits/iterator_vtable.h`, `algorithm.h`, the extended `range` methods,\nand `foreach_range`, `foreach_n`, `foreach_n_range` macros.\n\nReproducible tests with `SEED=n`, many more test improvements.\nOptimized test dependencies, time went from 25s to 3s even with ccache.\n\nOptimized hashmaps with two growth policies and many security policies.  Faster\nand more insecure with the policy `CTL_USET_GROWTH_POWER2` instead of the\ndefault `CTL_USET_GROWTH_PRIMED`.  Added the `CTL_USET_CACHED_HASH` policy for\nfaster unsuccessful finds with high load factors, but more memory.  The default\n`CTL_USET_SECURITY_COLLCOUNTING` policy is `2`, using a customizable `sleep()`\ncall on DDOS attack.\n\nA flat `hashmap` and `swisstable` will be added with open addressing, thus no\ninternal bucket methods, and faster, but pointers into it are disallowed. Flat\nsets and maps as open hashmaps and btree will support no pointer stability, and\nno iterator stability.\n\nOptimized `list`, seperate connect before and after methods.\n\nImplemented correct string and vector capacity policies, as in gcc libstdc++ and\nllvm libc++.  Tested also against the libc++ from llvm and the Windows MSVC STL,\nnot just the GNU libstdc++ v3.\n\nWork is ongoing to finish the rest of `algorithm.h`, `numeric.h` and `memory.h`,\nadd `pair` for map and `btree_set`, add proper string and identifier support.\n`string_view` and `span` (i.e. vector\\_view) not yet planned.\n\nOn errors, like `size \u003e max_size` return silently. This avoids DDOS attacks.\nWhen assert is used, throw them. (when assert.h included, no NDEBUG. This is\nsimlar to the no-exception abseil)\nglouw/ctl does not treat errors at all. There cannot be any.\n\nAdded formal verification tests for many functions, via `cbmc` for bounded loops\nand `satabs` for unbounded lists, which even caught a set.find error not caught\nby review, nor random testing nor sanitizers.\n\nSupport not only GNU make, but also BSD make and MSVC nmake.\n`gen_images.sh` is not bash-only anymore, and supports updating single graphs.\n\nTested also on macOS (default apple clang++ with libc++), FreeBSD (default\nclang with libc++), and Windows MSVC (default CL 19).\n\n### Differences to the STL\n\nOur iterators are safe and fat with an `end` range. We supprt the equivalent of\nC++20 ranges (single arg iterator), not begin/end pairs.  Not as safe as\nglouw/ctl iterators, but also not as slow. We need 2 assignments\n(currently. will be fixed), the STL needs one assignment, glouw/ctl needs three\nassignments. glouw/ctl is safe for destructive operations (i.e. insert, erase)\nin a foreach loop, we and the STL are not.\n\nOur iterators are generic only for certain algorithm methods, where we use\na 2nd range of any container type on a typed container. C++ classes use two\nindirections on all vtable calls. We inline all our iterator vtables, which are very\nshort, 3 pointers, so we a tiny initialization overhead of 3 copies vs 1, but\nhave no call overhead, unlike with C++. Specific iterator calls are completely\ninlined, only generic iterator calls in rare cases go through the vtable.\n\nOur vector and string growth policies for multiple insertions are much better.\nE.g. in the set algos or `insert_count`.\nWe reserve space at front, the STL piecewise in `push_back`/`insert` and this often\nleads to massive overallocation, hitting `* 2`. We try to mimic the upstream\ngrowth policies, but not its mistakes.\n\nSTL multiset and multimap variants will not be implemented because\nsimilar behaviour can be implemented as an amalgamation of a `set` and `list`.\n\nSTL string_view, span and short string optimizations are still missing.\n\nSTL methods returning a pair of iterator and bool have a `_found` suffix,\nreturn the iterator and set a `int *foundp` value. Eg.\n\n    int found;\n    map_T_insert_assign_found (self, key, \u0026found);\n\nSome algorithms and C++20 methods are still missing or are in work.\n\nSTL **set** algorithms such as `set_union`, `set_difference`, `set_intersection`,\n`set_symmetric_difference` do not work with `unordered_set`, because the specs\nrequire them to be ordered.  The CTL set algorithms do work properly on\n`unordered_set`. Likewise we don't define any range iterators on unordered_set,\nas this is unordered by default.\n\nhashmaps will not rely on chained lists with buckets, and can be either changed\nto open addressing or a better modern layout, such as Swiss tables (flat or\nnode variants), the stanford hash for integers or even the currently fastest\n[greg7mdp/parallel-hashmap](https://github.com/greg7mdp/parallel-hashmap).\nThus the bucket interface methods will not be defined for all hashmap variants,\nexcept maybe `max_bucket_count`. hashmap policies are compile-time defined via\n`#define CTL_USET_...` and `#define CTL_HMAP_...`\n\n**u8string** will get proper utf-8/unicode support, exceeding C++ STL.\ncompare will check u8strings normalized to NFD.\nNo wstring, u16string and u32string (most likely).\n\n**u8ident**: POSIX std extension for people using utf-8 identifiers, but\nneed security. See http://unicode.org/reports/tr39/\nLike a kernel filesystem or user database or programming language\nin a UTF-8 terminal, UI widget or editor wishes to present identifiers, like\nnames, paths or files identifiable.\nI.e. normalized and with identifiable characters only. Most don't display\nnames as puny-code as webbrowers or email clients.\nImplement the **Moderately Restrictive** restriction level for identifiers as default.\n\n* All characters in the string are in the ASCII range, or\n* The string is single-script, according to the definition in TR39 Section 5.1, or\n* The string is covered by any of the following sets of scripts, according to\n  the definition in TR39 Section 5.1:\n     Latin + Han + Hiragana + Katakana; or equivalently: Latn + Jpan\n     Latin + Han + Bopomofo; or equivalently: Latn + Hanb\n     Latin + Han + Hangul; or equivalently: Latn + Kore, or\n* The string is covered by Latin and any one other Recommended script, except Cyrillic, Greek.\n* The string must be validated UTF-8 and normalized, and only consist of valid identifier\n  characters.\nReject violations, optionally warn about confusables.\n\nNo exceptions or errors. Just ignore or return NULL. If assert is included, use\nit, with a proper error message.\nNo bloat and not many indirect calls (only compare and equal).\n\n## History\n\nList of added, changed. removed features:\n\n* 202104 Apr ?? 2021\n\n  * Added forward_list/slist.\n  * Added generic iterators (GI) for insert_generic, assign_generic, merge_range,\n    includes_range, equal_range, mismatch, lexicographical_compare, union_range,\n    intersection_range, difference_range, symmetric_difference_range,\n    search_range, find_first_of_range, find_end_range.\n  * Added numeric: iota, iota_range.\n  * algorithm: Added shuffle, iter_swap, reverse, reverse_range,\n    lexicographical_compare, is_sorted, is_sorted_until.\n    Requires now INCLUDE_ALGORITHM\n  * array: Added difference, intersection, symmetric_difference, assign_range.\n  * set: Added includes, includes_range.\n  * string: Added find_if, find_if_not, find_if_range, find_if_not_range, includes,\n    includes_range.\n\n* 202102 Feb 22 2021\n\n  * Moved to ctl/ subdir. Use long names.\n  * Added unordered_set, map, unordered_map, array.\n\n## Acknowledgements\n\nThank you https://github.com/glouw/ctl for the initial three-letter variant.\n\nThank you https://github.com/kully for the Plotly code, and thank you for the general review.\n\nThank you `smlckz` for the `foreach` cleanup.\n","funding_links":[],"categories":["Data Structures","标准库","Common"],"sub_categories":["模板库"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frurban%2Fctl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frurban%2Fctl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frurban%2Fctl/lists"}