template<typename K, typename V, std::size_t N, typename Hash>
requires requires(K k) { { Hash{}(k) } -> std::convertible_to<std::size_t>; }
struct jh::meta::lookup_map< K, V, N, Hash >
Fixed-capacity hash-based flat map providing switch-like lookup semantics.
Provides a switch-style lookup mechanism for types supporting hashing and equality. Designed to deliver predictable performance across constexpr and runtime paths.
Design motivations
-
The lookup cost is
O(log(N)), based on binary search over precomputed hashes.
-
For small
N, the dominant cost is computing the hash. If a type would require hashing before participating in a switch-like dispatch, the total cost closely matches a switch under small-table conditions.
-
For large
N, both this structure and a compiler-lowered switch typically operate in O(log(N)), so asymptotic behavior does not differ significantly.
-
Poor hash quality is tolerated: the structure remains correct and performance degrades safely toward
O(N).
-
Hash collisions are resolved by short linear scans inside the equal-hash range.
-
The structure generalizes switch semantics to types that are not natively switchable, capturing the complete hash-then-dispatch pattern while ensuring deterministic layout and constexpr capability.
Transparent lookup behavior
-
Transparent
operator[] queries are enabled through jh::meta::extension::key_traits<K>, which defines how an apparent input type KeyIn is converted into the canonical key type K.
-
This conversion is explicit: a canonical
K object will be constructed from the apparent input. Therefore K is expected to be lightweight, such as a POD key or a full-lifetime literal-based string view ("..."_psv).
-
This differs from heterogeneous lookup in
unordered_map; the goal here is predictable constexpr behavior, not amortized dynamic optimization.
Implementation
-
Entries are pre-hashed using
Hash and stored as a fixed-size array.
-
The array is sorted by hash, enabling binary search on the hash field.
-
Equal-hash entries are resolved by a short linear comparison scan.
-
Construction uses constexpr sorting when evaluated at compile time and runtime sorting otherwise.
-
The container uses no dynamic allocation and provides deterministic layout.
- Template Parameters
-
| K | Canonical key type stored in the map. |
| V | Value type associated with each key. |
| N | Number of stored entries. |
| Hash | Hash functor producing std::size_t. |
- Note
- Prefer compile-time construction with lightweight POD keys or full-lifetime string-view literals (e.g.
"..."_psv) to ensure zero-overhead canonical conversions through key_traits.
template<typename K, typename V, std::size_t N, typename Hash>
Initial value:decltype([]() {
else
return std::type_identity<std::array<entry, N>>{};
}())::type
Concept for types that are safe to treat as plain old data (POD).
Definition pod_like.h:44
constexpr std::uint16_t max_pod_array_bytes
Maximum size of a POD array (16KB). This is a compile-time constant.
Definition array.h:32
POD-compatible fixed-size array, similar in shape to std::array, but simpler and fully POD.
Definition array.h:68
Storage type selected based on POD suitability.
If entry is POD-like and the total size does not exceed jh::pod::max_pod_array_bytes, jh::pod::array<entry, N> is used; otherwise std::array<entry, N> is selected.
Using the POD variant enables placement in read-only segments.
template<typename K, typename V, std::size_t N, typename Hash>
template<typename Arr>
| jh::meta::lookup_map< K, V, N, Hash >::lookup_map |
( |
Arr && | init, |
|
|
V | default_val = {}, |
|
|
Hash | hasher = {} ) |
|
inlineexplicitconstexpr |
Construct from an array of std::pair<K,V>.
Computes hashes, stores entries and sorts them by hash. Performs constexpr or runtime sorting depending on evaluation context.
- Parameters
-
| init | Array of key-value pairs. |
| default_val | Value returned when lookup fails. |
| hasher | Hash functor. |