JH-Toolkit v1.4.1
An engineering-oriented C++20 toolkit with duck-typed concepts, static design, async coroutines, and semantic containers — header-only, RTTI-free, and concurrency-friendly.
Loading...
Searching...
No Matches
jh::meta Namespace Reference

Aggregated entry point for compile-time metaprogramming utilities. More...

Namespaces

namespace  extension
 Public customization points for compile-time key transformation and heterogeneous lookup in jh::meta.

Classes

struct  flatten_proxy
 Proxy wrapper that lazily exposes flattened tuple access. More...
struct  lookup_map
 Fixed-capacity hash-based flat map providing switch-like lookup semantics. More...
struct  t_str
 Compile-time string wrapper for use as a non-type template parameter (NTTP). More...

Concepts

concept  any_char
 Concept representing character-semantic 1-byte integral types.
concept  transparent_key
 Concept checking whether key conversion through key_traits<K> is valid.
concept  check_all
 Compile-time predicate applied to all alternatives in a variant.

Typedefs

template<std::uint16_t N>
using TStr = t_str<N>
 Alias for t_str<N> with template argument deduction.
template<std::size_t I, typename Variant, template< typename > typename TpTrans>
using deduce_type_t = typename detail::deduce_type<I, Variant, TpTrans>::type
 Extracts the transformed type of the I-th alternative in a variant.
template<typename Variant, template< typename > typename TpTrans>
using variant_transform_t = typename detail::variant_transform_impl<Variant, TpTrans>::type
 Applies a unary type transformation to every alternative in a variant.
template<typename Variant, template< typename > typename TpTrans>
using variant_collapse_t
 Attempts to collapse a transformed variant into a single uniform type.

Enumerations

enum class  c_hash : std::uint8_t {
  fnv1a64 = 0 , fnv1_64 = 1 , djb2 = 2 , sdbm = 3 ,
  murmur64 = 4 , xxhash64 = 5
}
 Compile-time selectable hash algorithm tag (FNV, DJB2, SDBM, etc.). More...

Functions

template<class F, class T, size_t... I>
constexpr decltype(auto) adl_apply_impl (F &&f, T &&t, std::index_sequence< I... >)
 Internal implementation helper for jh::meta::adl_apply.
template<class F, jh::concepts::tuple_like T>
constexpr decltype(auto) adl_apply (F &&f, T &&t) noexcept(noexcept(adl_apply_impl(std::forward< F >(f), std::forward< T >(t), std::make_index_sequence< std::tuple_size_v< std::remove_cvref_t< T > > >{})))
 ADL-enabled universal apply for tuple-like objects.
template<TStr S>
constexpr auto decode_base64 ()
 Decode a Base64-encoded TStr literal at compile time.
template<TStr S>
constexpr auto decode_base64url ()
 Decode a Base64URL-encoded TStr literal at compile time.
template<std::uint16_t N>
constexpr auto encode_base64 (const jh::pod::array< std::uint8_t, N > &raw)
 Encode a byte buffer into a Base64 literal at compile time.
template<std::uint16_t N, class PadT = std::false_type>
constexpr auto encode_base64url (const jh::pod::array< std::uint8_t, N > &raw, PadT={})
 Encode a byte buffer into a Base64URL literal at compile time.
template<any_char Char>
constexpr bool is_alpha (Char c) noexcept
 Check if character is an alphabetic letter (A-Z, a-z).
template<any_char Char>
constexpr bool is_digit (Char c) noexcept
 Check if character is a decimal digit (0-9).
template<any_char Char>
constexpr bool is_alnum (Char c) noexcept
 Check if character is alphanumeric (letter or digit).
template<any_char Char>
constexpr bool is_hex_char (Char c) noexcept
 Check if character is a valid hexadecimal digit.
template<any_char Char>
constexpr bool is_base64_core (Char c) noexcept
 Check if character belongs to standard Base64 alphabet.
template<any_char Char>
constexpr bool is_base64url_core (Char c) noexcept
 Check if character belongs to Base64URL alphabet.
template<any_char Char>
constexpr bool is_ascii (Char c) noexcept
 Check if character is ASCII.
template<any_char Char>
constexpr bool is_printable_ascii (Char c) noexcept
 Check if character is printable 7-bit ASCII (range 32-126).
template<any_char Char>
constexpr bool is_uri_char (Char c) noexcept
 Check if character is a valid URI character (unencoded).
template<any_char Char>
constexpr bool is_valid_char (Char c) noexcept
 Validate ASCII: reject control chars and DEL, leave non-ASCII untouched.
template<any_char Char>
constexpr char to_upper (Char c) noexcept
 Convert letter to uppercase; leave others unchanged.
template<any_char Char>
constexpr char to_lower (Char c) noexcept
 Convert letter to lowercase; leave others unchanged.
template<any_char Char>
constexpr char flip_case (Char c) noexcept
 Flip case of alphabetic character.
template<typename Tuple>
constexpr auto tuple_materialize (const Tuple &t)
 Flattens a tuple-like object into a fully materialized std::tuple.
template<std::size_t I, typename Tuple>
constexpr decltype(auto) get (const flatten_proxy< Tuple > &p) noexcept
template<any_char Char>
constexpr std::uint64_t fnv1a64 (const Char *data, const std::uint64_t size) noexcept
 FNV-1a 64-bit hash implementation (default choice).
template<any_char Char>
constexpr std::uint64_t fnv1_64 (const Char *data, const std::uint64_t size) noexcept
 FNV-1 64-bit hash (multiply before xor).
template<any_char Char>
constexpr std::uint64_t djb2 (const Char *str, const std::uint64_t size) noexcept
 DJB2 hash (hash * 33 + c).
template<any_char Char>
constexpr std::uint64_t sdbm (const Char *str, const std::uint64_t size) noexcept
 SDBM hash (used in several DB engines).
template<any_char Char>
constexpr std::uint64_t murmur64 (const Char *data, const std::uint64_t size) noexcept
 constexpr MurmurHash-like 64-bit variant (seedless)
template<any_char Char>
constexpr std::uint64_t xxhash64 (const Char *data, std::uint64_t len) noexcept
 constexpr xxHash-like 64-bit variant (seedless)
template<any_char Char>
constexpr std::uint64_t hash (const c_hash algo, const Char *data, const std::uint64_t size) noexcept
 Dispatch to selected hash algorithm based on c_hash.
template<typename K, typename V, std::size_t N>
 lookup_map (std::array< std::pair< K, V >, N > &&) -> lookup_map< K, V, N, jh::hash< K > >
 Deduction guide for constructing lookup_map from an array of pairs.
template<typename K, typename V, std::size_t N>
 lookup_map (std::array< std::pair< K, V >, N > &&, V) -> lookup_map< K, V, N, jh::hash< K > >
 Deduction guide for constructing lookup_map with an explicit default value.
template<typename Hash, typename K, typename V, std::size_t N>
 lookup_map (std::array< std::pair< K, V >, N > &&, V, Hash) -> lookup_map< K, V, N, Hash >
 Deduction guide for constructing lookup_map using a user-provided hash.
template<typename Hash, typename K, typename V, std::size_t N>
consteval auto make_lookup_map (const std::array< std::pair< K, V >, N > &init, V default_value=V{}, Hash hash_fn=Hash{})
 Compile-time constructor for lookup_map with explicit hash.
template<typename K, typename V, std::size_t N>
consteval auto make_lookup_map (const std::array< std::pair< K, V >, N > &init, V default_value=V{})
 Compile-time constructor using automatically deduced jh::hash<K>.
template<typename V, std::size_t N>
consteval auto make_lookup_map (const std::array< std::pair< std::string_view, V >, N > &init, V default_value=V{})
 Compile-time constructor for tables declared with std::string_view keys.
template<std::uint16_t N>
std::ostream & operator<< (std::ostream &os, const t_str< N > &str)
 Stream output operator for t_str<N>.

Detailed Description

Aggregated entry point for compile-time metaprogramming utilities.

The <jh/meta> forwarding header provides a unified, engineering-oriented interface over the compile-time utilities implemented under jh/metax/.
This module defines the compile-time infrastructure layer of the JH Toolkit, supplying constexpr / consteval-safe building blocks for structural type manipulation, NTTP-based string identity, deterministic hashing, and static data modeling.
Rather than offering ad-hoc template helpers, jh::meta establishes a cohesive foundation for closed-world, heap-free, and runtime-independent computation during template instantiation.

Typedef Documentation

◆ deduce_type_t

template<std::size_t I, typename Variant, template< typename > typename TpTrans>
using jh::meta::deduce_type_t = typename detail::deduce_type<I, Variant, TpTrans>::type

Extracts the transformed type of the I-th alternative in a variant.

This alias applies the user-provided transformation TpTrans to the I-th alternative of Variant. Before extraction, a full-variant validity check is performed: every alternative T in Variant must satisfy TpTrans<T>::type being a valid, non-void type. If any alternative fails this requirement, substitution fails and the alias cannot be instantiated.

Template Parameters
IIndex of the alternative in the variant.
VariantA std::variant whose alternatives are transformed.
TpTransA unary metafunction template exposing ::type.
Note
If the transformation is invalid for any alternative, this alias participates in SFINAE failure rather than producing a type.

◆ TStr

template<std::uint16_t N>
using jh::meta::TStr = t_str<N>

Alias for t_str<N> with template argument deduction.

Template Parameters
NSize of the string literal including the null terminator.
  • This alias allows t_str to be used directly as a non-type template parameter in C++20.
  • Simplifies template declarations by avoiding the explicit t_str<N> spelling.
  • Intended primarily for compile-time string literal binding in templates.

◆ variant_collapse_t

template<typename Variant, template< typename > typename TpTrans>
using jh::meta::variant_collapse_t
Initial value:
typename detail::variant_collapse_impl<Variant, TpTrans>::type

Attempts to collapse a transformed variant into a single uniform type.

Each alternative T in the input Variant is mapped through TpTrans<T>::type. If all mapped results are exactly the same type, that type is exposed as the result. If any alternative maps to a different type, collapse fails and the alias becomes void.

Template Parameters
VariantA std::variant whose alternatives may collapse.
TpTransA unary metafunction template providing ::type.
Note
Collapse does not permit mixed mappings. If uniformity cannot be proven, the resulting type is void. This mechanism allows users to detect the boundary at which alternatives can be considered belonging to the same external semantic family.

◆ variant_transform_t

template<typename Variant, template< typename > typename TpTrans>
using jh::meta::variant_transform_t = typename detail::variant_transform_impl<Variant, TpTrans>::type

Applies a unary type transformation to every alternative in a variant.

The alias constructs a new std::variant whose alternatives are precisely TpTrans<T>::type for each alternative T in Variant.

Note
No additional semantic validation is performed.
If the transformation leads to conflicting or duplicated alternatives, such as:

    std::variant<TA, TB, ..., TA>
the compiler's standard diagnostic for std::variant will report the error directly.
This intentional design helps users discover logical mistakes in their ADT mappings without silently suppressing them.
Template Parameters
VariantThe source std::variant.
TpTransA unary metafunction template providing ::type.
Note
Transformation failure for any alternative results in SFINAE failure of this alias. No collapse or uniformity assumptions are made.

Enumeration Type Documentation

◆ c_hash

enum class jh::meta::c_hash : std::uint8_t
strong

Compile-time selectable hash algorithm tag (FNV, DJB2, SDBM, etc.).

Enumerator
fnv1a64 

FNV-1a 64-bit hash.

fnv1_64 

FNV-1 64-bit hash.

djb2 

DJB2 hash (classic string hash).

sdbm 

SDBM hash (used in readdir, DBM).

murmur64 

constexpr-safe MurmurHash variant (seedless)

xxhash64 

constexpr xxHash64 variant (seedless)

Function Documentation

◆ adl_apply()

template<class F, jh::concepts::tuple_like T>
decltype(auto) jh::meta::adl_apply ( F && f,
T && t )
constexprnoexcept

ADL-enabled universal apply for tuple-like objects.

Invokes a callable object f with the unpacked elements of a tuple-like t, performing unqualified lookup for get so that both standard and user-defined tuple-likes are supported.

This function is conceptually equivalent to std::apply, but designed for broader compatibility: it requires only that the type model jh::concepts::tuple_like, not that std::get be specialized. Standard library tuples continue to resolve std::get normally, while user-defined types participate via ADL.

Template Parameters
FCallable type.
TTuple-like type satisfying jh::concepts::tuple_like.
Parameters
fCallable object to invoke.
tTuple-like object whose elements are unpacked and forwarded.
Returns
The result of std::invoke(f, get<I>(t)...).
Note
ADL lookup ensures correctness for user-defined tuple-like proxies and prevents illegal specialization of std::get.
This approach is fully conforming and generates identical code to std::apply for standard tuple types.

◆ adl_apply_impl()

template<class F, class T, size_t... I>
decltype(auto) jh::meta::adl_apply_impl ( F && f,
T && t,
std::index_sequence< I... >  )
constexpr

Internal implementation helper for jh::meta::adl_apply.

Expands a tuple-like object t into individual elements and invokes f with them via unqualified get lookup.

Unlike std::apply, this implementation deliberately omits using std::get; to preserve Argument-Dependent Lookup (ADL). Bringing std::get into scope would suppress ADL resolution and force all get calls to bind to std::get, breaking compatibility with user-defined tuple-like types that rely on ADL-visible get overloads.

This choice allows both standard tuple-likes (std::tuple, std::pair, std::array) and user-defined tuple-like structures to be expanded uniformly without violating the one-definition rule for std::get.

In summary, using std::get is incorrect here because it prevents ADL participation, effectively disabling lookup of valid user-defined get functions.

Template Parameters
FCallable type.
TTuple-like object type satisfying jh::concepts::tuple_like.
I...Compile-time indices derived from std::tuple_size_v<T>.
Parameters
fCallable to be invoked with unpacked elements.
tTuple-like object to unpack.
Returns
The result of invoking f with the elements of t.

◆ decode_base64()

template<TStr S>
auto jh::meta::decode_base64 ( )
constexpr

Decode a Base64-encoded TStr literal at compile time.

Template Parameters
SA TStr literal representing a Base64-encoded string. The template is enabled only when S.is_base64() is true.

This function performs fully compile-time Base64 decoding when the encoded value is supplied as a non-type template parameter (NTTP). All validation is performed through the TStr constraint system, ensuring that the input literal satisfies Base64 structural rules at compile time.
The function returns a jh::pod::array whose size matches the decoded payload length. Since the operation is constexpr-capable, the result may be used in constexpr contexts, static initialization, or as further NTTP input to other compile-time facilities.

Returns
A jh::pod::array<std::uint8_t, N> containing the decoded bytes.
Note
Since decoding occurs entirely at compile time, invalid Base64 input results in a compilation error rather than a runtime error.

◆ decode_base64url()

template<TStr S>
auto jh::meta::decode_base64url ( )
constexpr

Decode a Base64URL-encoded TStr literal at compile time.

Template Parameters
SA TStr literal representing Base64URL text, with or without padding. The template participates in overload resolution only when S.is_base64url() is true.

This function evaluates Base64URL decoding entirely during compilation. Padded and non-padded Base64URL forms are supported, and the decoded output is produced as a POD-safe jh::pod::array.

Length rules for padded and non-padded Base64URL are applied through the TStr constraint rather than at runtime, guaranteeing correctness before code generation.

Returns
A jh::pod::array<std::uint8_t, N> containing the decoded bytes.

◆ encode_base64()

template<std::uint16_t N>
auto jh::meta::encode_base64 ( const jh::pod::array< std::uint8_t, N > & raw)
constexpr

Encode a byte buffer into a Base64 literal at compile time.

Template Parameters
NThe size of the input byte buffer. The encoded size is determined automatically based on N.
Parameters
rawA jh::pod::array<std::uint8_t, N> representing the binary payload to encode.

The function produces padded Base64 output (that is, with trailing '=' characters when required). The resulting text is stored in a TStr<M> compile-time string literal that includes a null terminator.

Because the output literal is returned as TStr, it may be used directly as an NTTP in subsequent compile-time operations such as:

  • constexpr decoding,
  • compile-time hashing,
  • static data construction,
  • constexpr reflection pipelines.
Returns
A TStr<M> containing the padded Base64 representation, terminated with a null character.

◆ encode_base64url()

template<std::uint16_t N, class PadT = std::false_type>
auto jh::meta::encode_base64url ( const jh::pod::array< std::uint8_t, N > & raw,
PadT = {} )
constexpr

Encode a byte buffer into a Base64URL literal at compile time.

Template Parameters
NThe size of the input byte buffer.
PadTA boolean tag type controlling whether padding is emitted. The caller supplies an instance of std::false_type{} to generate unpadded Base64URL, or std::true_type{} to generate padded Base64URL.
Parameters
rawA jh::pod::array<std::uint8_t, N> representing the input bytes.
pad_tagA value of type PadT. The caller must pass either std::false_type{} (no padding) or std::true_type{} (padding enabled). This parameter determines the encoding behavior and enables automatic type deduction for PadT.

This function encodes the provided byte buffer into a Base64URL literal. Unlike the standard Base64 variant, padding is optional in Base64URL. The padding behavior is determined solely by the pad_tag parameter.

The resulting encoded text is returned as a TStr<M> instance that includes a null terminator. This enables further usage as an NTTP value in downstream compile-time operations.

Returns
A TStr<M> containing either padded or non-padded Base64URL text depending on pad_tag.
Note
Use the following forms:
  • encode_base64url(bytes, std::false_type{}) or default encode_base64url(bytes)for no padding
  • encode_base64url(bytes, std::true_type{}) for padded output

◆ lookup_map() [1/3]

template<typename K, typename V, std::size_t N>
jh::meta::lookup_map ( std::array< std::pair< K, V >, N > && ) -> lookup_map< K, V, N, jh::hash< K > >

Deduction guide for constructing lookup_map from an array of pairs.

The hash functor deduced here is jh::hash<K>. This is not a fixed hash: it is a dispatcher whose resolution order is:

  1. std::hash<K> (always preferred if present)
  2. ADL-discovered hash(K)
  3. member function K::hash()

Note that most std::hash<T> implementations in the standard library are not constexpr. Therefore, when this deduction guide selects an std::hash<K> that is not constexpr-friendly, compile-time evaluation of lookup_map will fail. In such cases you must explicitly pass a constexpr hash.

Template Parameters
KKey type inferred from the pair array.
VValue type.
NNumber of entries.

◆ lookup_map() [2/3]

template<typename K, typename V, std::size_t N>
jh::meta::lookup_map ( std::array< std::pair< K, V >, N > && ,
V  ) -> lookup_map< K, V, N, jh::hash< K > >

Deduction guide for constructing lookup_map with an explicit default value.

Uses jh::hash<K> as the hash dispatcher. If the selected hash source (typically std::hash<K>) is not constexpr-capable, compile-time instantiation cannot succeed. To construct a constexpr table, provide a custom constexpr hash functor explicitly.

Template Parameters
KKey type.
VValue type.
NNumber of entries.

◆ lookup_map() [3/3]

template<typename Hash, typename K, typename V, std::size_t N>
jh::meta::lookup_map ( std::array< std::pair< K, V >, N > && ,
V ,
Hash  ) -> lookup_map< K, V, N, Hash >

Deduction guide for constructing lookup_map using a user-provided hash.

This overload bypasses the jh::hash<K> dispatcher entirely and uses the caller-specified Hash. When constexpr operation is required, supplying a constexpr-capable hash functor here is the recommended approach.

Template Parameters
HashUser-specified hash type.
KKey type.
VValue type.
NEntry count.

◆ make_lookup_map() [1/3]

template<typename K, typename V, std::size_t N>
auto jh::meta::make_lookup_map ( const std::array< std::pair< K, V >, N > & init,
V default_value = V{} )
consteval

Compile-time constructor using automatically deduced jh::hash<K>.

Deduces the hash functor as jh::hash<K>, which dispatches hashing by prioritizing std::hash<K>. Since most standard-library hash implementations are not constexpr, deduction may select a non-constexpr hash, causing compile-time construction to fail. In such cases, the explicit-hash overload must be used.

This overload is safe when K itself provides a constexpr-capable hashing mechanism. Types satisfying this condition include:

  • user-defined types supplying a constexpr std::hash<K>, or
  • jh::pod::string_view, which supports constexpr hashing.

Usage example

using namespace jh::pod::literals;
// KeyType = jh::pod::string_view, which provides constexpr hashing.
constexpr auto table =
std::array{
std::pair{ "..."_psv, ValueType{...} },
...
std::pair{ "..."_psv, ValueType{...} }
},
ValueType{...});
consteval auto make_lookup_map(const std::array< std::pair< K, V >, N > &init, V default_value=V{}, Hash hash_fn=Hash{})
Compile-time constructor for lookup_map with explicit hash.
Definition lookup_map.h:655
Official literal helpers for jh::pod types.
Definition string_view.h:802
Template Parameters
KKey type satisfying extended_hashable.
VValue type.
NEntry count.
Parameters
initKey-value pairs.
default_valueFallback value.

◆ make_lookup_map() [2/3]

template<typename Hash, typename K, typename V, std::size_t N>
auto jh::meta::make_lookup_map ( const std::array< std::pair< K, V >, N > & init,
V default_value = V{},
Hash hash_fn = Hash{} )
consteval

Compile-time constructor for lookup_map with explicit hash.

Requires Hash to be explicitly provided. This is the most reliable way to construct a constexpr lookup table because no automatic hash deduction is used. Use this overload when:

  • the deduced jh::hash<K> is not constexpr, or
  • full control of hashing behavior is required.

Standard-library std::hash<T> is usually not constexpr. If deduction would select such a hash, constexpr construction will fail; providing an explicit constexpr hash functor avoids this issue.

Usage example

struct MyHash {
constexpr std::size_t operator()(KeyType k) const noexcept {
return ...; // constexpr-capable hashing
}
};
constexpr auto table =
std::array{
std::pair{ KeyType{...}, ValueType{...} },
...
std::pair{ KeyType{...}, ValueType{...} }
},
ValueType{...});
Template Parameters
HashHash functor used for all entries.
KKey type.
VValue type.
NNumber of entries.
Parameters
initKey-value pairs.
default_valueValue returned on lookup failure.
hash_fnExplicit hash functor instance.
Returns
A fully constexpr lookup table.

◆ make_lookup_map() [3/3]

template<typename V, std::size_t N>
auto jh::meta::make_lookup_map ( const std::array< std::pair< std::string_view, V >, N > & init,
V default_value = V{} )
consteval

Compile-time constructor for tables declared with std::string_view keys.

This overload exists because std::hash<std::string_view> is not constexpr, which makes a compile-time table using K = std::string_view invalid. To preserve a natural declaration syntax using "..."sv while still supporting constexpr construction, this function converts all keys into jh::pod::string_view, whose hashing is constexpr-capable and whose literal-backed storage never dangles.

Conceptually, this is a syntactic convenience: although the user writes keys as std::string_view, the actual stored key type is jh::pod::string_view. The conversion is performed via key_traits<jh::pod::string_view>.

Usage example

using namespace std::literals;
constexpr auto table =
std::array{
std::pair{ "..."sv, ValueType{...} },
...
std::pair{ "..."sv, ValueType{...} }
},
ValueType{...});
// The table stores keys as jh::pod::string_view internally.
Template Parameters
VValue type.
NNumber of entries.
Parameters
initKey-value pairs whose keys are written as std::string_view.
default_valueFallback value for missing keys.

◆ operator<<()

template<std::uint16_t N>
std::ostream & jh::meta::operator<< ( std::ostream & os,
const t_str< N > & str )
inline

Stream output operator for t_str<N>.

Template Parameters
NSize of the compile-time string (including null terminator).
Parameters
osThe output stream.
strThe t_str<N> instance to print.
Returns
Reference to the output stream.

Writes the string's std::string_view to the given output stream.

  • This is the default output representation.
  • It may be overridden by providing a higher-priority overload or explicitly bringing another overload into scope with using.
  • The function is declared inline, which in C++17 and later does not guarantee inlining, but instead gives the function weak, foldable linkage semantics across translation units.
Note
The printed form is identical to the underlying string literal content (no quotes, escapes, or formatting applied).

◆ tuple_materialize()

template<typename Tuple>
auto jh::meta::tuple_materialize ( const Tuple & t)
constexpr

Flattens a tuple-like object into a fully materialized std::tuple.

Public entry point for tuple flattening.

Recursively expands all nested tuple_like members within T and produces a single-level std::tuple containing their underlying elements.

Template Parameters
TupleThe input type modeling jh::concepts::tuple_like.
Parameters
tThe tuple-like object to flatten.
Returns
A std::tuple with all nested contents expanded.