{"id":17182332,"url":"https://github.com/greg7mdp/gtl","last_synced_at":"2025-10-27T00:05:25.784Z","repository":{"id":37491645,"uuid":"459707788","full_name":"greg7mdp/gtl","owner":"greg7mdp","description":"Greg's Template Library of useful classes.","archived":false,"fork":false,"pushed_at":"2025-02-09T14:40:21.000Z","size":2490,"stargazers_count":179,"open_issues_count":2,"forks_count":11,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-03-28T17:03:44.345Z","etag":null,"topics":["bit-vector","bit-vectors","bitset","bitvector","btree","concurrent","containers","dynamic-bitset","hash","hash-container","hashmap","lru-cache","memoize","soa","unordered","unordered-set"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/greg7mdp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"greg7mdp"}},"created_at":"2022-02-15T18:48:00.000Z","updated_at":"2025-03-24T08:47:19.000Z","dependencies_parsed_at":"2023-11-19T04:27:48.433Z","dependency_job_id":"80d04cc0-8b14-489a-9b81-f10f769b3f90","html_url":"https://github.com/greg7mdp/gtl","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/greg7mdp%2Fgtl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/greg7mdp%2Fgtl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/greg7mdp%2Fgtl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/greg7mdp%2Fgtl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/greg7mdp","download_url":"https://codeload.github.com/greg7mdp/gtl/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247226213,"owners_count":20904465,"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":["bit-vector","bit-vectors","bitset","bitvector","btree","concurrent","containers","dynamic-bitset","hash","hash-container","hashmap","lru-cache","memoize","soa","unordered","unordered-set"],"created_at":"2024-10-15T00:36:43.056Z","updated_at":"2025-10-27T00:05:20.740Z","avatar_url":"https://github.com/greg7mdp.png","language":"C++","funding_links":["https://github.com/sponsors/greg7mdp"],"categories":[],"sub_categories":[],"readme":"\n\u003cimg src=\"https://github.com/greg7mdp/gtl/blob/main/html/img/phash.png?raw=true\" width=\"120\" align=\"middle\"\u003e\n\n# Greg's Template Library of useful classes.\n\n  [![License: Apache-2.0](https://img.shields.io/badge/License-Apache-yellow.svg)](https://opensource.org/licenses/Apache-2.0) [![Linux](https://github.com/greg7mdp/gtl/actions/workflows/linux.yml/badge.svg)](https://github.com/greg7mdp/gtl/actions/workflows/linux.yml)  [![MacOS](https://github.com/greg7mdp/gtl/actions/workflows/macos.yml/badge.svg)](https://github.com/greg7mdp/gtl/actions/workflows/macos.yml) [![Windows](https://github.com/greg7mdp/gtl/actions/workflows/windows.yml/badge.svg)](https://github.com/greg7mdp/gtl/actions/workflows/windows.yml)\n\n## Overview\n\nThis repository aims to provide many classes that are commonly needed in substantial C++ projects, but that are either not available in the C++ standard library, or have a specification which makes them slower than they could be. In some cases, the C++ standard requirements prevents from providing faster alternatives (for example the  pointer stability requirement for unordered maps or sets prevents providing implementations using open addressing).\n\nAmong the many classes offered by [gtl](https://github.com/greg7mdp/gtl), we have a set of excellent **hash map** implementations, as well as a **btree** alternative to `std::map` and `std::set`. These are *drop-in replacements* for the standard C++ classes and provide the same API, but are significantly faster and use less memory.\n\nWe also have a fast `bit_vector` implementation, which is an alternative to `std::vector\u003cbool\u003e` or `std::bitset`, providing both dynamic resizing and a good assortment of bit manipulation primitives, as well as a novel `bit_view` class allowing to operate on subsets of the `bit_vector`.\n\nWe have `lru_cache` and `memoize` classes, both with very fast multi-thread versions relying of the mutex sharding of the parallel hashmap classes.\n\nWe also offer an `intrusive_ptr` class, which uses less memory than `std::shared_ptr`, and is simpler to construct.\n\nWe are happy to integrate new classes into [gtl](https://github.com/greg7mdp/gtl), provided the license is compatible with ours, and we feel they will be useful to most users. Often, when integrating classes from other sources, we are able to improve their performance both in time and space by using other classes already available in [gtl](https://github.com/greg7mdp/gtl) (such as hash maps, btree, bit_vector, etc...)  instead of the spandard ones.\n\n[gtl](https://github.com/greg7mdp/gtl) requires a C++20 compiler. We currently support:  `Visual Studio 2019 +`, `gcc 8 +`, and `clang 10 +` (or Xcode 12 + on MacOS).\n\nBecause [gtl](https://github.com/greg7mdp/gtl) is a header only library, installation is trivial, just copy the `include/gtl` directory to your project somewhere in your include path and you are good to go. We also support common package managers such as [Conan](https://conan.io/) (package name `greg7mdp-gtl`) and [vcpkg](https://vcpkg.io/en/index.html).\n\n## Installation\n\n#### Direct copy of the header files\n\nCopy the gtl directory to your project. Update your include path. That's all.\n\n#### Direct include in cmake project\n\nIf you are using cmake, you can use FetchContent to integrate gtl to your project, for example:\n\n```cmake\ninclude(FetchContent)\nFetchContent_Declare(\n    gtl\n    GIT_REPOSITORY https://github.com/greg7mdp/gtl.git\n    GIT_TAG        v1.2.0 # adjust tag/branch/commit as needed\n)\nFetchContent_MakeAvailable(gtl)\n\n...\ntarget_link_libraries (my_target PRIVATE gtl)\n```\n\n#### Using a package manager\n\nGTL supports both **vcpkg** and **Conan** package managers (package name in conan-io is `greg7mdp-gtl`).\n\n#### Debugger support\n\nIf you are using Visual Studio, you probably want to add `include/gtl/debug_vis/gtl.natvis` to your projects. This will allow for a user friendly display of gtl containers in the debugger. Similar debug visualizers are also provided for gdb and lldb in the `include/gtl/debug_vis` directory.\n\n#### Clone the repository and build it\n\n```\ngit clone https://github.com/greg7mdp/gtl.git\n```\n\n\u003e A cmake configuration files (CMakeLists.txt) is provided for building the tests and examples. Command for building and running the tests is: \u003cbr\u003e\n\u003e \n\n```sh\ncmake -DGTL_BUILD_TESTS=ON -DGTL_BUILD_EXAMPLES=ON -B build\ncmake --build build\nctest --test-dir build\n```\n\nFollowing is a short look at the various classes available in [gtl](https://github.com/greg7mdp/gtl). In many cases, a more complete description is linked.\n\n\n## Hash containers\n\n[Gtl](https://github.com/greg7mdp/gtl) provides a set of hash containers (maps and sets) implemented using open addressing (single array of values, very cache friendly), as well as advanced SSE lookup optimizations allowing for excellent performance even when the container is up to 87% full. These containers have the same API as the `unordered` versions from the STL, and are significantly outperforming the unordered version both in terms of speed and space.\n\nThe four provided hash containers are:\n    - `gtl::flat_hash_map`\n    - `gtl::flat_hash_set`\n    - `gtl::node_hash_map`\n    - `gtl::node_hash_set`\n\nFor more information on the hash containers, please see [gtl hash containers](https://github.com/greg7mdp/gtl/tree/main/docs/hmap.md)\n\n\u003e if using Visual Studio, make sure to add the [gtl natvis](https://github.com/greg7mdp/gtl/blob/main/gtl/debug_vis/gtl.natvis) file to your projects, which provides a user-friendly visualization of the content of gtl set and map containers. Debug visualizers are available for gdb and lldb as well.\n\n\nHere is a very basic example of using the gtl::flat_hash_map:\n\n```c++\n#include \u003ciostream\u003e\n#include \u003cstring\u003e\n#include \u003cgtl/phmap.hpp\u003e\n\nusing gtl::flat_hash_map;\n\nint main()\n{\n    // Create an unordered_map of three strings (that map to strings)\n    flat_hash_map\u003cstd::string, std::string\u003e email =\n    {\n        { \"tom\",  \"tom@gmail.com\"},\n        { \"jeff\", \"jk@gmail.com\"},\n        { \"jim\",  \"jimg@microsoft.com\"}\n    };\n\n    // Iterate and print keys and values\n    for (const auto\u0026 n : email)\n        std::cout \u003c\u003c n.first \u003c\u003c \"'s email is: \" \u003c\u003c n.second \u003c\u003c \"\\n\";\n\n    // Add a new entry\n    email[\"bill\"] = \"bg@whatever.com\";\n\n    // and print it\n    std::cout \u003c\u003c \"bill's email is: \" \u003c\u003c email[\"bill\"] \u003c\u003c \"\\n\";\n\n    return 0;\n}\n```\n\n**Key decision points for hash containers:**\n\n- The `flat` hash containers do not provide pointer stability. This means that when the container resizes, it will move the keys and values in memory. So pointers to something inside a `flat` hash container will become invalid when the container is resized. The `node` hash containers do provide pointer stability, and should be used instead if this is an issue.\n\n- The `flat` hash containers will use less memory, and usually are faster than the `node` hash containers, so use them if you can. the exception is when the values inserted in the hash container are large (say more than 100 bytes [*needs testing*]) and expensive to move.\n\n- The `parallel` hash containers are preferred when you have a few hash containers that will store a very large number of values. The `non-parallel` hash containers are preferred if you have a large number of hash containers, each storing a relatively small number of values.\n\n- The benefits of the `parallel` hash containers are: \n   a. reduced peak memory usage (when resizing), and \n   b. multithreading support (and inherent internal parallelism)\n\n**Acknowledgements**\n\nThanks to Google and the \"Swiss table\" team for the original [implementation](https://github.com/abseil/abseil-cpp), from which ours is derived.\n\n## Parallel hash containers\n\n\nThe four provided parallel hash containers are:\n    - `gtl::parallel_flat_hash_map`\n    - `gtl::parallel_flat_hash_set`\n    - `gtl::parallel_node_hash_map`\n    - `gtl::parallel_node_hash_set`\n\n\nFor a full writeup explaining the design and benefits of the parallel hash containers, [click here](https://greg7mdp.github.io/parallel-hashmap/).\n\nFor more information on the implementation, usage and characteristics of the parallel hash containers, please see [gtl parallel hash containers](https://github.com/greg7mdp/gtl/tree/main/docs/phmap.md)\n\n\n## Btree containers\n\nThe four provided btree containers (in `gtl/btree.hpp`)are:\n    - `gtl::btree_map`\n    - `gtl::btree_set`\n    - `gtl::btree_multimap`\n    - `gtl::btree_multiset`\n\nFor more information on the hash containers, please see [gtl btree containers](https://github.com/greg7mdp/gtl/tree/main/docs/btree.md)\n\n**Key decision points for btree containers:**\n\nBtree containers are ordered containers, which can be used as alternatives to `std::map` and `std::set`. They store multiple values in each tree node, and are therefore more cache friendly and use significantly less memory.\n\nBtree containers will usually be preferable to the default red-black trees of the STL, except when:\n- pointer stability or iterator stability is required\n- the value_type is large and expensive to move\n\nWhen an ordering is not needed, a hash container is typically a better choice than a btree one.\n\n## vector container\n\n[Gtl](https://github.com/greg7mdp/gtl) provides a `gtl::vector` class, which is an alternative to `std::vector`. This class is closely derived from [Folly's](https://github.com/facebook/folly) `fbvector`.\n\n## bit_vector (or dynamic bitset)\n\n[Gtl](https://github.com/greg7mdp/gtl) provides a `gtl::bit_vector` class, which is an alternative to `std::vector\u003cbool\u003e` or `std::bitset`, as it provides both dynamic resizing, and a good assortment of bit manipulation primitives.\n\nI implemented this container because I often needed the functionality it provides, and didn't find an open-source implementation I liked which didn't require pulling in a big library. The `gtl::bit_vector` implementation is self-contained in a single header [file](https://github.com/greg7mdp/gtl/blob/main/gtl/bit_vector.hpp) which can trivially  be added to any project (it currently requires a C++17 compiler).\n\nIn addition, I dreamed of the `gtl::bit_view` functionality, similar to `std::string_view` for strings, to refer and operate on a subset of a full `gtl::bit_vector`, and I thought it would be fun implementing it.\n\nClick [here](https://github.com/greg7mdp/gtl/blob/main/examples/misc/bit_vector.cpp) for an example demonstrating some of the capabilities of `gtl::bit_vector`.\n\n\u003e if using Visual Studio, make sure to add the [gtl natvis](https://github.com/greg7mdp/gtl/blob/main/gtl/debug_vis/gtl.natvis) file to your projects, which provides a user-friendly visualization of the content of a `gtl::bit_vector`.\n\nWhen printed, converted to `std::string`, or displayed in the debugger with the [gtl natvis](https://github.com/greg7mdp/gtl/blob/main/gtl/debug_vis/gtl.natvis), bits are displayed right to left, so for example a `gtl::bit_vector` of size 16, with the fist two bits set (index 0 and 1) would be displayed as `0x00000003`.\n\n## memoize\n\nThe classes from the `memoize.hpp` header provide a very efficient way to memoize the return values of pure functions, whether in a multi threaded context or a single threaded one. In particular, the `mt_memoize_lru` class internally uses the extended parallel hashmap APIs to minimize locking contention when the cache is used from concurrrent threads.\n\n\n* `gtl::lru_cache`: a basic lru (least recently used) cache, not internally thread-safe, providing APIs like `contains()` and`insert()` to look up and insert items if not already present.\n* `gtl::memoize`\n* `gtl::memoize_lru`\n* `gtl::mt_memoize`:\n* `gtl::mt_memoize_lru`:\n\n## intrusive\n\nThe classes from the `intrusive.hpp` header provide a smart pointer type which is missing from the standard library, the `intrusive_ptr`. It provides automatic life management of pointers to an object with an embedded reference count. If you don't need all the bells and whistles of `std::shared_ptr`, such as `weak_ptr` or custom deleter support, the `intrusive_ptr` provides a similar reference counting support with the following benefits:\n\n- The memory footprint of `intrusive_ptr` is the same as the corresponding raw pointer (typically half of std::shared_ptr);\n- The memory footprint of `intrusive_ref_counter` is also half of the std::shared_ptr reference count;\n- `intrusive_ptr\u003cT\u003e` can be constructed from an arbitrary raw pointer of type `T *`.\n\nClasses provided are:\n\n* `gtl::intrusive_ptr`: the intrusive_ptr class\n* `gtl::intrusive_ref_counter`: use this as a based class for objects needing to implement the two count APIs\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgreg7mdp%2Fgtl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgreg7mdp%2Fgtl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgreg7mdp%2Fgtl/lists"}