C++23 · header-only · MIT · sha 5e209d4
[ sys ]my-stlconfirmed in repo
A standard librarythat self-hosts.
I rebuilt 28 STL containers from scratch in header-only C++23, each layered on the ones beneath it the way a real standard library is. map rides a red-black tree. lru_cache is a list plus a hash map. Every speed claim on this page is a derived artifact, read straight from the committed benchmark CSV.
- 0.230×
- 28containers
- 55tests
Most STL clones are a pile of parts.
Reimplementing the STL is a rite of passage, so the internet is full of them. Almost all share two flaws. The containers stand alone, twenty copies of the same growth and node-allocation logic, none of them composing. And the speed is asserted, never shown: a README says fast and you take it on faith.
The harder version is harder on both axes. Build a library where the higher-level containers are actually implemented on top of lower-level ones, the way a real standard library stacks map on a tree and priority_queue on a heap. Then make every speed claim reproducible: a number on the page should trace to a committed run, not get typed in by hand. Get both right and you have a library worth examining: one whose behavior you can trace from the allocator up, and whose speed claims you can check.
Layer the containers. Generate the numbers.
Two decisions carry the project: containers self-host on each other, and every benchmark number is generated from the committed data.
Everything is header-only. Each container is a .hpp declaration paired with a .tpp of template definitions, wired through CMake paths. That makes the self-hosting visible: when map wants a balanced tree it includes the rb-tree header instead of copying 670 lines of rotation logic. The dependency graph in §3 is read straight out of those include directives, not drawn by hand.
Built on each other
Numbers, not adjectives
The self-hosting graph.
Every edge below is a real #include read out of the headers. Storage primitives sit at the base. Everything above them is composed, not re-implemented. Four foundation containers (vector, rb-tree, list, forward_list) carry the whole structure.
verified include graph · every arrow is a real #include @ sha 5e209d4
What I gave up, on purpose.
The wins are where the data structure earns them. The losses are in the same chart, because pretending a from-scratch node-based tree beats libc++ would be the tell of someone who does not measure.
my-stl vs the system STL.
Median ns/op ratio, my-stl over std::. Lower is better. The amber line is the 1.0× parity baseline. Bars left of it are wins, bars right are losses. All ten numbers are read from the committed benchmark CSV.
- flat_set build + find
- flat_map build + find
- deque push_back + pop_front
- vector push_back (no reserve)
- vector push_back (reserve)
- small_vector push_back
- stable_vector push_back
- map build + find
- set build + find
- unordered_map emplace (reserve)
[ demo · in the repo ]