https://github.com/eggs-cpp/keyed_set
Eggs.KeyedSet is C++23 member-keyed ordered set
https://github.com/eggs-cpp/keyed_set
Last synced: 1 day ago
JSON representation
Eggs.KeyedSet is C++23 member-keyed ordered set
- Host: GitHub
- URL: https://github.com/eggs-cpp/keyed_set
- Owner: eggs-cpp
- License: bsl-1.0
- Created: 2026-04-25T06:58:44.000Z (2 months ago)
- Default Branch: main
- Last Pushed: 2026-06-09T07:21:11.000Z (20 days ago)
- Last Synced: 2026-06-09T08:26:06.866Z (20 days ago)
- Language: C++
- Homepage: https://eggs-cpp.github.io/keyed_set/
- Size: 229 KB
- Stars: 1
- Watchers: 0
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# Eggs.KeyedSet
**Eggs.KeyedSet** is a C++23/26 single-header ordered associative container
that stores unique `Value` objects indexed by a designated member field,
satisfying all requirements of the C++26 `AssociativeContainer` named
requirement ([associative.reqmts]).
See the library header at
[`include/eggs/keyed_set.hpp`](include/eggs/keyed_set.hpp).
---
## Synopsis
```cpp
namespace eggs
{
template <
typename Value,
auto Key,
typename Compare = std::less,
typename Allocator = std::allocator
>
class keyed_set;
}
```
`keyed_set` behaves like a `std::set` but exposes
`key_type = decltype(v.*Key)` and orders elements by that member.
All heterogeneous lookup operations (`find`, `count`, `contains`,
`lower_bound`, `upper_bound`, `equal_range`, `extract`, `erase`) accept
`key_type` directly, with no `Value` object construction required.
## Example
```cpp
#include
struct Employee { int id; std::string name; double salary; };
eggs::keyed_set roster;
roster.insert({101, "Alice", 95'000.0});
roster.insert({102, "Bob", 80'000.0});
// Heterogeneous lookup by int — no Employee constructed
if (auto it = roster.find(101); it != roster.end())
std::cout << it->name << '\n'; // Alice
// Iteration is in ascending key order
for (auto const& e : roster)
std::cout << e.id << ' ' << e.name << '\n';
// from_range constructor
std::vector vec{ {1, "Carol", 70'000.0}, {2, "Dave", 80'000.0} };
eggs::keyed_set from_vec(std::from_range, vec);
```
## Requirements
The library requires a C++23-conformant compiler and standard library.
It is continuously tested with:
- GCC 14 and 16
- Clang 18 and 22 (libstdc++ and libc++)
- MSVC 2022 and 2026
- Clang-CL 20 (Windows)
There are no external dependencies.
## Building
The library is header-only. Copy `include/eggs/keyed_set.hpp` into your
project, or use CMake:
```cmake
# As a subdirectory
add_subdirectory(eggs-keyed_set)
target_link_libraries(my_target PRIVATE Eggs::KeyedSet)
# Or via find_package after installation
find_package(Eggs.KeyedSet REQUIRED)
target_link_libraries(my_target PRIVATE Eggs::KeyedSet)
```
### CMake options
| Option (top-level) | Option (subdirectory) | Default | Description |
|---|---|---|---|
| `BUILD_TESTING` | `EGGS_KEYED_SET_BUILD_TESTING` | `ON` / `OFF` | Build the test suite |
| `BUILD_EXAMPLES` | `EGGS_KEYED_SET_BUILD_EXAMPLES` | `ON` / `OFF` | Build the examples |
| `ENABLE_INSTALL` | `EGGS_KEYED_SET_ENABLE_INSTALL` | `ON` / `OFF` | Install the library |
### Configuring and building with presets
The project ships a `CMakePresets.json` with named configurations for the
most common workflows. CMake 3.25 or later is required to use presets.
```sh
# List all available presets
cmake --list-presets
# Configure, build, and test (GCC, Debug)
cmake --preset dev-gcc
cmake --build --preset dev-gcc-debug
ctest --preset dev-gcc-debug
# Other toolchain variants
cmake --preset dev-clang # Clang with libstdc++
cmake --preset dev-clang-libcxx # Clang with libc++
cmake --preset dev-msvc # MSVC x64
cmake --preset dev-clang-cl # Clang-CL x64
```
Build trees land in `build//` so all presets coexist without
interfering.
## C++26 AssociativeContainer conformance
`keyed_set` satisfies every expression listed in
[associative.reqmts.general], including:
- All required nested types (`key_type`, `value_type`, `key_compare`,
`value_compare`, `allocator_type`, `node_type`, `insert_return_type`, …)
- Constant bidirectional iterators (`iterator == const_iterator`)
- All constructor forms: default, comparator, iterator-range,
`from_range`, initializer-list, copy, move, allocator-extended variants
- `operator=(initializer_list)`
- `emplace`, `emplace_hint`
- `insert` (lvalue, rvalue, hint, iterator-range, `insert_range`, initializer-list,
node-handle, hint + node-handle)
- `extract` (by iterator, by key, transparent)
- `erase` (by key, transparent, by iterator, by range)
- `clear`, `merge`
- `erase_if(keyed_set&, Predicate)` (free function)
- `key_comp`, `value_comp`
- `find`, `count`, `contains`, `lower_bound`, `upper_bound`, `equal_range`
— all with both exact and transparent (`K const&`) overloads
- `operator==` and `operator<=>` (synthesises all six relational operators)
- Member and non-member `swap`
## License
Distributed under the Boost Software License, Version 1.0.
(See accompanying file [LICENSE.txt](LICENSE.txt) or copy at
)
Copyright Agustin K-ballo Berge, Fusion Fenix 2026