{"id":13470648,"url":"https://github.com/teslamotors/fixed-containers","last_synced_at":"2025-10-04T18:35:15.657Z","repository":{"id":44638900,"uuid":"375132799","full_name":"teslamotors/fixed-containers","owner":"teslamotors","description":"C++ Fixed Containers","archived":false,"fork":false,"pushed_at":"2024-10-22T00:02:08.000Z","size":1117,"stargazers_count":383,"open_issues_count":15,"forks_count":34,"subscribers_count":11,"default_branch":"main","last_synced_at":"2024-10-22T21:21:05.238Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/teslamotors.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":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-06-08T20:12:20.000Z","updated_at":"2024-10-22T00:02:12.000Z","dependencies_parsed_at":"2024-05-17T02:45:46.322Z","dependency_job_id":"9b6b3a8d-a335-4db3-9d1e-9f3b95ba7257","html_url":"https://github.com/teslamotors/fixed-containers","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teslamotors%2Ffixed-containers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teslamotors%2Ffixed-containers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teslamotors%2Ffixed-containers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teslamotors%2Ffixed-containers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/teslamotors","download_url":"https://codeload.github.com/teslamotors/fixed-containers/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222138883,"owners_count":16937422,"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":[],"created_at":"2024-07-31T16:00:33.114Z","updated_at":"2025-10-04T18:35:15.639Z","avatar_url":"https://github.com/teslamotors.png","language":"C++","readme":"# C++ Fixed Containers\n\n![License](https://img.shields.io/github/license/teslamotors/fixed-containers)\n![Standard](https://img.shields.io/badge/c%2B%2B-20-blue)\n[![Ubuntu](https://github.com/teslamotors/fixed-containers/actions/workflows/ubuntu.yml/badge.svg)](https://github.com/teslamotors/fixed-containers/actions/workflows/ubuntu.yml)\n[![Ubuntu (clang)](https://github.com/teslamotors/fixed-containers/actions/workflows/ubuntu-clang.yml/badge.svg)](https://github.com/teslamotors/fixed-containers/actions/workflows/ubuntu-clang.yml)\n[![Windows](https://github.com/teslamotors/fixed-containers/actions/workflows/windows.yml/badge.svg)](https://github.com/teslamotors/fixed-containers/actions/workflows/windows.yml)\n[![CodeQL](https://github.com/teslamotors/fixed-containers/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/teslamotors/fixed-containers/actions/workflows/codeql-analysis.yml)\n\nHeader-only C++20 library that provides containers with the following properties:\n\n* Fixed-capacity, declared at compile-time, no dynamic allocations\n* constexpr - can be used at both compile-time and runtime (including mutation)\n* containers retain the properties of T (e.g. if T is trivially copyable, then so is FixedVector\u003cT\u003e)\n* no pointers stored (data layout is purely self-referential and can be serialized directly)\n* instances can be used as non-type template parameters\n\n# Features\n\n* The following table shows the available fixed containers and their equivalent std-containers.\nThe fixed-container types have identical APIs to their std:: equivalents, so you can refer to the traditional C++ docs for how to use them.\n\n   | fixed-container      | std-container equivalent                        |\n   |:---------------------|:------------------------------------------------|\n   | `FixedVector`        | `std::vector`                                   |\n   | `FixedDeque`         | `std::deque`                                    |\n   | `FixedList `         | `std::list`                                     |\n   | `FixedQueue`         | `std::queue`                                    |\n   | `FixedStack`         | `std::stack`                                    |\n   | `FixedCircularDeque` | `std::deque` API with Circular Buffer semantics |\n   | `FixedCircularQueue` | `std::queue` API with Circular Buffer semantics |\n   | `FixedBitset`        | `std::bitset`                                   |\n   | `FixedString`        | `std::string`                                   |\n   | `FixedMap`           | `std::map`                                      |\n   | `FixedSet`           | `std::set`                                      |\n   | `FixedUnorderedMap`  | `std::unordered_map`                            |\n   | `FixedUnorderedSet`  | `std::unordered_set`                            |\n   | `EnumMap`            | `std::map` for enum keys only                   |\n   | `EnumSet`            | `std::set` for enum keys only                   |\n   | `EnumArray`          | `std::array` but with typed accessors           |\n\n* `StringLiteral` - Compile-time null-terminated literal string.\n* Rich enums - `enum` \u0026 `class` hybrid.\n\n## Rich enum features\n* Rich enums behave like an enum (compile-time known values, can be used in switch-statements, template parameters as well as `EnumMap`/`EnumSet` etc).\n* Can have member functions and fields.\n* Readily available `count()`, `to_string()`.\n* Conversion from string, ordinal.\n* Implicit `std::optional`-like semantics.\n* Avoid the need for error-prone sentinel values like `UNKNOWN`, `UNINITIALIZED`, `COUNT` etc.\n* Avoid Undefined Behavior from uninitialized state. Default constructor can be disabled altogether.\n* `EnumAdapter\u003cT\u003e` can adapt any enum-like class to the rich enum API.\n\n```C++\nstatic_assert(fixed_containers::rich_enums::is_rich_enum\u003cColor\u003e);  // Type-trait `concept`\ninline constexpr Color COLOR = Color::RED();                // Note the parens\nstatic_assert(\"RED\" == COLOR.to_string());                         // auto-provided member\nstatic_assert(COLOR.is_primary());                                 // Custom member\nstatic_assert(COLOR == Color::value_of(\"RED\").value());            // auto-provided\nstatic_assert(4 == Color::count());                                // auto-provided\n```\nMore examples can be found [here](test/enums_test_common.hpp).\n\n# Examples\n- FixedVector\n    ```C++\n    constexpr auto v1 = []()\n    {\n        FixedVector\u003cint, 11\u003e v{};\n        v.push_back(0);\n        v.emplace_back(1);\n        v.push_back(2);\n        return v;\n    }();\n    static_assert(v1[0] == 0);\n    static_assert(v1[1] == 1);\n    static_assert(v1[2] == 2);\n    static_assert(v1.size() == 3);\n    static_assert(v1.capacity() == 11);\n    ```\n\n- FixedList\n    ```C++\n    constexpr auto v1 = []()\n    {\n        FixedList\u003cint, 11\u003e v{};\n        v.push_back(0);\n        v.emplace_back(1);\n        v.push_front(2);\n        return v;\n    }();\n    static_assert(*v1.begin() == 2);\n    static_assert(v1.size() == 3);\n    static_assert(v1.max_size() == 11);\n    ```\n\n- FixedDeque\n    ```C++\n    constexpr auto v1 = []()\n    {\n        FixedDeque\u003cint, 11\u003e v{};\n        v.push_back(0);\n        v.emplace_back(1);\n        v.push_front(2);\n        return v;\n    }();\n    static_assert(v1[0] == 2);\n    static_assert(v1[1] == 0);\n    static_assert(v1[2] == 1);\n    static_assert(v1.size() == 3);\n    static_assert(v1.max_size() == 11);\n    ```\n\n- FixedQueue\n    ```C++\n    constexpr auto s1 = []()\n    {\n        FixedQueue\u003cint, 3\u003e v1{};\n        v1.push(77);\n        v1.push(88);\n        v1.push(99);\n        return v1;\n    }();\n\n    static_assert(s1.front() == 77);\n    static_assert(s1.back() == 99);\n    static_assert(s1.size() == 3);\n    ```\n\n- FixedStack\n    ```C++\n    constexpr auto s1 = []()\n    {\n        FixedStack\u003cint, 3\u003e v1{};\n        int my_int = 77;\n        v1.push(my_int);\n        v1.push(99);\n        return v1;\n    }();\n\n    static_assert(s1.top() == 99);\n    static_assert(s1.size() == 2);\n    ```\n\n- FixedCircularDeque\n    ```C++\n    constexpr auto v1 = []()\n    {\n        FixedCircularDeque\u003cint, 3\u003e v{};\n        v.push_back(2);\n        v.emplace_back(3);\n        v.push_front(1);\n        v.emplace_front(0);\n        v.push_back(4);\n        return v;\n    }();\n\n    static_assert(v1[0] == 1);\n    static_assert(v1[1] == 2);\n    static_assert(v1[2] == 4);\n    static_assert(v1.size() == 3);\n    ```\n\n- FixedCircularQueue\n    ```C++\n    constexpr auto s1 = []()\n    {\n        FixedCircularQueue\u003cint, 3\u003e v1{};\n        v1.push(55);\n        v1.push(66);\n        v1.push(77);\n        v1.push(88);\n        v1.push(99);\n        return v1;\n    }();\n\n    static_assert(s1.front() == 77);\n    static_assert(s1.back() == 99);\n    static_assert(s1.size() == 3);\n    ```\n\n- FixedBitset\n    ```C++\n    constexpr auto s1 = []()\n    {\n        FixedBitset\u003c4\u003e v1{\"0101\"};\n        v1.flip(0);\n        return v1;\n    }();\n\n    static_assert(s1.test(0) == 0);\n    static_assert(s1.test(1) == 0);\n    static_assert(s1.test(2) == 1);\n    static_assert(s1.test(3) == 0);\n    ```\n\n- FixedString\n    ```C++\n    constexpr auto v1 = []()\n    {\n        FixedString\u003c11\u003e v{\"012\"};\n        v.at(1) = 'b';\n\n        return v;\n    }();\n\n    static_assert(v1.at(0) == '0');\n    static_assert(v1.at(1) == 'b');\n    static_assert(v1.at(2) == '2');\n    static_assert(v1.size() == 3);\n    ```\n\n- FixedMap\n    ```C++\n    constexpr auto m1 = []()\n    {\n        FixedMap\u003cint, int, 11\u003e m{};\n        m.insert({2, 20});\n        m[4] = 40;\n        return m;\n    }();\n    static_assert(!m1.contains(1));\n    static_assert(m1.contains(2));\n    static_assert(m1.at(4) == 40);\n    static_assert(m1.size() == 2);\n    static_assert(m1.max_size() == 11);\n    ```\n\n- FixedSet\n    ```C++\n    constexpr auto s1 = []()\n    {\n        FixedSet\u003cint, 11\u003e s{};\n        s.insert(2);\n        s.insert(4);\n        return s;\n    }();\n    static_assert(!s1.contains(1));\n    static_assert(s1.contains(2));\n    static_assert(s1.size() == 2);\n    static_assert(s1.max_size() == 11);\n    ```\n\n- FixedUnorderedMap\n    ```C++\n    constexpr auto m1 = []()\n    {\n        FixedUnorderedMap\u003cint, int, 11\u003e m{};\n        m.insert({2, 20});\n        m[4] = 40;\n        return m;\n    }();\n    static_assert(!m1.contains(1));\n    static_assert(m1.contains(2));\n    static_assert(m1.at(4) == 40);\n    static_assert(m1.size() == 2);\n    static_assert(m1.max_size() == 11);\n    ```\n\n- FixedUnorderedSet\n    ```C++\n    constexpr auto s1 = []()\n    {\n        FixedUnorderedSet\u003cint, 11\u003e s{};\n        s.insert(2);\n        s.insert(4);\n        return s;\n    }();\n    static_assert(!s1.contains(1));\n    static_assert(s1.contains(2));\n    static_assert(s1.size() == 2);\n    static_assert(s1.max_size() == 11);\n    ```\n\n- EnumMap\n    ```C++\n    enum class Color { RED, YELLOW, BLUE};\n\n    constexpr auto m1 = []()\n    {\n        EnumMap\u003cColor, int\u003e m{};\n        m.insert({Color::RED, 20});\n        m[Color::YELLOW] = 40;\n        return m;\n    }();\n    static_assert(!m1.contains(Color::BLUE));\n    static_assert(m1.contains(Color::RED));\n    static_assert(m1.at(Color::YELLOW) == 40);\n    static_assert(m1.size() == 2);\n\n    // Ensures all keys are specified, at compile-time\n    constexpr auto m2 = EnumMap\u003cColor, int\u003e::create_with_all_entries({\n        {Color::RED, 42},\n        {Color::YELLOW, 7},\n        {Color::BLUE, 6},\n    });\n    ```\n\n- EnumSet\n    ```C++\n    enum class Color { RED, YELLOW, BLUE};\n\n    constexpr auto s1 = []()\n    {\n        EnumSet\u003cColor\u003e s{};\n        s.insert(Color::RED);\n        s.insert(Color::YELLOW);\n        return s;\n    }();\n    static_assert(!s1.contains(Color::BLUE));\n    static_assert(s1.contains(Color::RED));\n    static_assert(s1.size() == 2);\n\n    constexpr auto s2 = EnumSet\u003cColor\u003e::all(); // full set\n    constexpr auto s3 = EnumSet\u003cColor\u003e::none(); // empty set\n    constexpr auto s4 = EnumSet\u003cColor\u003e::complement_of(s2); // empty set\n    ```\n\n- EnumArray\n    ```C++\n    constexpr EnumArray\u003cTestEnum1, int\u003e s1{{TestEnum1::ONE, 10}, {TestEnum1::FOUR, 40}};\n    static_assert(4 == s1.max_size());\n    static_assert(s1.at(TestEnum1::ONE) == 10);\n    static_assert(s1.at(TestEnum1::TWO) == 0);\n    static_assert(s1.at(TestEnum1::THREE) == 0);\n    static_assert(s1.at(TestEnum1::FOUR) == 40);\n    ```\n\n- StringLiteral\n    ```C++\n    static constexpr const char* s = \"blah\"; // strlen==4, sizeof==8\n    static constexpr const char s[5] = \"blah\";  // strlen==4, sizeof==5 (null terminator)\n    static constexpr StringLiteral s = \"blah\";  // constexpr .size()==4\n    ```\n\n- Using instances as non-type template parameters\n    ```C++\n    // Similarly to simple types like ints/enums and std::array,\n    // fixed_container instances can be used as template parameters\n    template \u003cFixedVector\u003cint, 5\u003e /*MY_VEC*/\u003e\n    constexpr void fixed_vector_instance_can_be_used_as_a_template_parameter()\n    {\n    }\n\n    void test()\n    {\n        static constexpr FixedVector\u003cint, 5\u003e VEC1{};\n        fixed_vector_instance_can_be_used_as_a_template_parameter\u003cVEC1\u003e();\n    }\n    ```\n\n# Integration\n\n### cmake\n```\nfind_package(fixed_containers CONFIG REQUIRED)\ntarget_link_libraries(\u003cyour_binary\u003e fixed_containers::fixed_containers)\n```\n\n### bazel\nIf you are managing dependencies with the newer bzlmod system, use the following in your `MODULE.bazel` file:\n```\nbazel_dep(name = \"fixed_containers\")\narchive_override(\n    module_name = \"fixed_containers\",\n    strip_prefix = \"fixed-containers-\u003ccommit\u003e\",\n    urls = [\"https://github.com/teslamotors/fixed-containers/archive/\u003ccommit\u003e.tar.gz\"],\n)\n```\n\nIf you are managing dependencies with the older `WORKSPACE` system, use the following in your `WORKSPACE` file:\n```\nhttp_archive(\n    name = \"fixed_containers\",\n    urls = [\"https://github.com/teslamotors/fixed-containers/archive/\u003ccommit\u003e.tar.gz\"],\n    strip_prefix = \"fixed-containers-\u003ccommit\u003e\",\n)\n\nload(\"@fixed_containers//:fixed_containers_deps.bzl\", \"fixed_containers_deps\")\nfixed_containers_deps()\n```\n\nThen use in your targets like this:\n```\ncc_test(\n    name = \"test\",\n    srcs = [\"test.cpp\"],\n    deps = [\n        \"@fixed_containers//:fixed_vector\",\n        \"@fixed_containers//:enum_map\",\n        \"@fixed_containers//:enum_set\",\n    ],\n    copts = [\"-std=c++20\"],\n)\n```\n### Alternative\nSince this is a header-only library, you can also:\n- Add the `include/` folder to your includes\n- Get the dependencies. For example, with [vcpkg](https://github.com/Microsoft/vcpkg):\n```\nvcpkg install magic-enum\n```\n\n# Running the tests\n\n### cmake\n\n1) Build with the [vcpkg toolchain file](https://vcpkg.io/en/docs/users/buildsystems/cmake-integration.html)\n```\nmkdir build \u0026\u0026 cd build\ncmake .. -DCMAKE_C_COMPILER=/bin/clang-13 -DCMAKE_CXX_COMPILER=/bin/clang++-13 -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake\ncmake --build .\n```\n\n2) Run tests\n```\nctest -C Debug\n```\n\n### bazel\n#### clang\n1) Build separately (optional)\n```\nCC=clang++-13 bazel build --config=clang ...\n```\n2) Run tests\n```\nCC=clang++-13 bazel test --config=clang :all_tests\n```\n\n#### clang with libc++\n```\nCC=clang++-13 bazel build --config=clang_with_libcxx ...\n```\n2) Run tests\n```\nCC=clang++-13 bazel test --config=clang_with_libcxx :all_tests\n```\n\n#### gcc\n1) Build separately (optional)\n```\nCC=g++-11 bazel build --config=gcc ...\n```\n\n2) Run tests\n```\nCC=g++-11 bazel test --config=gcc :all_tests\n```\n\n### clang-tidy\nRun with:\n```\nrun-clang-tidy -p . -extra-arg-before=\"-DFIXED_CONTAINERS_CLANG_TIDY_RUNNING\"\n```\nThe macro is needed to avoid analysis on some particularly slow places.\n\n## Tested Compilers\n\n- Clang  13\n- GCC 11\n- MSVC++ 14.29 / Visual Studio 2019\n\n## Licensed under the [MIT License](LICENSE)\n","funding_links":[],"categories":["Containers","C++"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteslamotors%2Ffixed-containers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fteslamotors%2Ffixed-containers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteslamotors%2Ffixed-containers/lists"}