GMP 0.3.0
Generative Metaprogramming library for C++
Loading...
Searching...
No Matches
Reflection Metaprogramming

Compile-time enum, aggregate, type-name, and payload-size reflection utilities. More...

Classes

struct  gmp::enum_traits< E >
 Customize the reflection range or explicit values for an enumeration. More...
 
struct  gmp::pretty_type_name< T >
 Format a type name for documentation-friendly display. More...
 
struct  gmp::pretty_type_name< std::string >
 Formatter specialization for std::string. More...
 
struct  gmp::pretty_type_name< std::string_view >
 Formatter specialization for std::string_view. More...
 
struct  gmp::pretty_type_name< std::vector< T > >
 Formatter specialization for std::vector<T>. More...
 
struct  gmp::pretty_type_name< std::array< T, N > >
 Formatter specialization for std::array<T, N>. More...
 

Macros

#define GMP_ENUM_RANGE(Enum, Min, Max)
 Specialize gmp::enum_traits with an explicit scan range.
 
#define GMP_ENUM_VALUES(Enum, ...)
 Specialize gmp::enum_traits with an explicit enumerator list.
 

Typedefs

template<std::size_t I, typename T >
using gmp::member_type_t = std::remove_cvref_t< decltype(*detail::field_getter< I, T >(constant_arg< member_count< T >()>))>
 Alias for the type of the I-th member of an aggregate type.
 

Functions

template<typename E , fixed_string P = type_name<E>() + fixed_string("::")>
consteval auto gmp::enum_values ()
 Get all enumerator values of an enumeration type at compile-time.
 
template<typename E , fixed_string P = type_name<E>() + fixed_string("::")>
consteval auto gmp::enum_count ()
 Count the number of enumerators in an enumeration type at compile-time.
 
template<auto E, fixed_string P = fixed_string("::")>
consteval auto gmp::enum_name ()
 Get the name of an enumerator at compile-time.
 
template<typename E >
consteval auto gmp::enum_names ()
 Get all enumerator names of an enumeration type at compile-time.
 
template<typename E >
consteval auto gmp::enum_entries ()
 Get all enumerator entries (value, name) of an enumeration type at compile-time.
 
template<typename E >
constexpr auto gmp::enum_index (E value) -> std::optional< std::size_t >
 Get the index of an enumerator value in enum_values<E>().
 
template<typename E >
constexpr auto gmp::enum_cast (std::string_view name) -> std::optional< E >
 Cast an enumerator name to its corresponding enumerator value.
 
template<typename T , typename... Args>
requires std::is_aggregate_v<std::remove_cvref_t<T>>
consteval int gmp::member_count ()
 Count the number of members in an aggregate type at compile-time.
 
template<std::size_t I, typename T >
requires std::is_aggregate_v<T> && (I < member_count<T>()) && (member_count<T>() <= GMP_MAX_SUPPORTED_FIELDS)
consteval auto gmp::member_name () noexcept
 Get the name of a specific member of an aggregate type at compile-time.
 
template<typename T >
consteval auto gmp::member_names ()
 Get all member names of an aggregate type at compile-time.
 
template<typename T >
constexpr auto gmp::member_type_names ()
 Returns an array of string_view containing the type names of all members of aggregate type T.
 
template<std::size_t I, typename T , typename UnqualifiedT = std::remove_cvref_t<T>>
requires std::is_aggregate_v<UnqualifiedT> && (I < member_count<UnqualifiedT>()) && (member_count<UnqualifiedT>() <= GMP_MAX_SUPPORTED_FIELDS)
decltype(autogmp::member_ref (T &&value) noexcept
 Get a reference to the I-th member of an aggregate object.
 
template<typename T , typename F >
requires std::is_aggregate_v<std::remove_cvref_t<T>>
void gmp::for_each_member (T &&value, F &&func) noexcept
 Visit each member of an aggregate object together with its member name.
 
template<typename T >
consteval auto gmp::type_name ()
 Get the string representation of a type at compile-time.
 
template<typename T >
consteval std::size_t gmp::type_size ()
 Calculate the actual payload size of a type without aggregate padding.
 

Variables

template<typename E >
constexpr int gmp::enum_min_v
 The minimum reflection scan value for enumeration type E.
 
template<typename E >
constexpr int gmp::enum_max_v
 The maximum reflection scan value for enumeration type E.
 

Detailed Description

Macro Definition Documentation

◆ GMP_ENUM_RANGE

#define GMP_ENUM_RANGE (   Enum,
  Min,
  Max 
)

This macro defines enum_traits<Enum>::min and enum_traits<Enum>::max, allowing enum reflection to scan a narrower or wider range than the default.

Parameters
EnumThe enumeration type to customize.
MinThe minimum integer value to scan.
MaxThe maximum integer value to scan.

Definition at line 57 of file meta.hpp.

◆ GMP_ENUM_VALUES

#define GMP_ENUM_VALUES (   Enum,
  ... 
)

This macro bypasses range scanning by providing the exact set of enumerator values to use for reflection.

Parameters
EnumThe enumeration type to customize.
...The explicit enumerator values of Enum.

Definition at line 74 of file meta.hpp.

Typedef Documentation

◆ member_type_t

template<std::size_t I, typename T >
gmp::member_type_t
Template Parameters
IZero-based member index.
TThe aggregate type to introspect.
Note
The resulting type is stripped of const, volatile, and reference qualifiers.
struct Point { int x; float y; };
using YType = member_type_t<1, Point>; // float
consteval auto enum_values()
Get all enumerator values of an enumeration type at compile-time.
Definition meta.hpp:155

Definition at line 568 of file meta.hpp.

Function Documentation

◆ enum_cast()

template<typename E >
constexpr auto gmp::enum_cast ( std::string_view  name) -> std::optional<E>
constexpr
Template Parameters
EThe enumeration type to cast into.
Parameters
nameThe enumerator name to search for.
Returns
std::optional<E> containing the enumerator if found, otherwise std::nullopt.

Definition at line 361 of file meta.hpp.

References gmp::enum_values().

◆ enum_count()

template<typename E , fixed_string P = type_name<E>() + fixed_string("::")>
consteval auto gmp::enum_count ( )
Template Parameters
EThe enumeration type to count enumerators for.
PThe prefix string used to identify enumerator names (defaults to type name + "::").
Returns
The number of valid enumerators in the enumeration.
Note
This function is consteval and evaluated entirely at compile-time.
enum class Color { Red, Green, Blue, Yellow };
enum class Empty {};
// Count enumerators
constexpr auto count = enum_count<Color>();
static_assert(count == 4);
static_assert(enum_count<Empty>() == 0);
// Can be used in template metaprogramming
struct EnumTraits {
static constexpr size_t size = N;
};
static_assert(EnumTraits<Color>::size == 4);

Definition at line 201 of file meta.hpp.

References gmp::enum_values().

◆ enum_entries()

template<typename E >
consteval auto gmp::enum_entries ( )

This function returns a compile-time array of (value, name) pairs for all reflected enumerators of E.

Template Parameters
EThe enumeration type to inspect.
Returns
A std::array<std::pair<E, std::string_view>, N> containing all reflected enumerators in declaration order.

Definition at line 317 of file meta.hpp.

References gmp::enum_values().

◆ enum_index()

template<typename E >
constexpr auto gmp::enum_index ( E  value) -> std::optional<std::size_t>
constexpr
Template Parameters
EThe enumeration type of the value being searched.
Parameters
valueThe enumerator value to locate.
Returns
std::optional<std::size_t> containing the index if found, otherwise std::nullopt.

Definition at line 342 of file meta.hpp.

References gmp::enum_values().

◆ enum_name()

template<auto E, fixed_string P = fixed_string("::")>
consteval auto gmp::enum_name ( )
Template Parameters
EThe enumerator value to get the name for.
PThe prefix string to remove from the full name (defaults to type name + "::").
Returns
A fixed_string containing the enumerator name, or "<unnamed>" if not found.
enum class Status { Ok = 200, NotFound = 404, Error = 500 };
enum { A, B, C }; // Unscoped enumeration
// Get individual enumerator names
constexpr auto ok_name = enum_name<Status::Ok>();
static_assert(ok_name == "Ok");
static_assert(not_found_name == "NotFound");
// Works with unscoped enums
constexpr auto a_name = enum_name<A>();
static_assert(a_name == "A");
// Compile-time string comparison
static_assert(enum_name<Status::Error>() == "Error");

Definition at line 235 of file meta.hpp.

References gmp::enum_values().

◆ enum_names()

template<typename E >
consteval auto gmp::enum_names ( )

This function returns an array containing the names of all enumerators in the enumeration type E.

Template Parameters
EThe enumeration type to get enumerator names for.
Returns
A std::array of std::string_view containing all enumerator names. Returns an empty array if the enumeration has no enumerators.
enum class Permission { Read, Write, Execute };
// Get all enumerator names
constexpr auto names = enum_names<Permission>();
static_assert(names.size() == 3);
static_assert(names[0] == "Read");
static_assert(names[1] == "Write");
static_assert(names[2] == "Execute");
// Iterate over enumerator names at compile-time
template<typename E>
constexpr bool has_enumerator(std::string_view name) {
constexpr auto names = enum_names<E>();
for (size_t i = 0; i < names.size(); ++i) {
if (names[i] == name) return true;
}
return false;
}
static_assert(has_enumerator<Permission>("Write"));
static_assert(!has_enumerator<Permission>("Delete"));
// Empty enum
enum class Empty {};
constexpr auto empty_names = enum_names<Empty>();
static_assert(empty_names.empty());

Definition at line 291 of file meta.hpp.

References gmp::enum_values().

◆ enum_values()

template<typename E , fixed_string P = type_name<E>() + fixed_string("::")>
consteval auto gmp::enum_values ( )

This function returns the full reflected enumerator set for E. If enum_traits<E>::values is provided, that explicit list is used. Otherwise, the function scans the integer range defined by enum_traits<E>::min and enum_traits<E>::max.

Template Parameters
EThe enumeration type to inspect.
PThe expected enumerator-name prefix used during range scanning.
Returns
A std::array containing all reflected enumerator values.
Note
This function is consteval and evaluated entirely at compile-time.
Examples
aggregate_reflection.cpp, reflection_enum.cpp, and type_name_and_size.cpp.

Definition at line 155 of file meta.hpp.

References gmp::enum_values().

Referenced by gmp::object_factory< AbstractProduct, ConstructorArgs >::create(), gmp::object_factory< AbstractProduct, ConstructorArgs >::create_shared(), gmp::object_factory< AbstractProduct, ConstructorArgs >::create_unique(), gmp::enum_cast(), gmp::enum_count(), gmp::enum_entries(), gmp::enum_index(), gmp::enum_name(), gmp::enum_names(), gmp::enum_values(), gmp::fixed_string< N >::find(), gmp::fixed_string< N >::fixed_string(), gmp::fixed_string< N >::fixed_string(), gmp::for_each_member(), gmp::singleton< T, false >::instance(), gmp::singleton< T, true >::instance(), gmp::is_equal(), gmp::make_named_operator(), gmp::member_count(), gmp::member_name(), gmp::member_names(), gmp::member_ref(), gmp::pretty_type_name< T >::operator()(), gmp::pretty_type_name< std::vector< T > >::operator()(), gmp::pretty_type_name< std::array< T, N > >::operator()(), gmp::operator+(), gmp::fixed_string< N >::operator[](), gmp::object_factory< AbstractProduct, ConstructorArgs >::register_type< T >::register_type(), gmp::remove_all(), gmp::fixed_string< N >::substr(), gmp::type_name(), and gmp::object_factory< AbstractProduct, ConstructorArgs >::unregister_type().

◆ for_each_member()

template<typename T , typename F >
requires std::is_aggregate_v<std::remove_cvref_t<T>>
void gmp::for_each_member ( T &&  value,
F &&  func 
)
noexcept

func is invoked once per member in declaration order. Each invocation receives the member name as std::string_view and the corresponding member reference.

Template Parameters
TThe aggregate object type.
FThe callable visitor type.
Parameters
valueThe aggregate object to inspect.
funcThe visitor invoked for each member.
Examples
aggregate_reflection.cpp.

Definition at line 697 of file meta.hpp.

References gmp::constant_arg, and gmp::enum_values().

◆ member_count()

template<typename T , typename... Args>
requires std::is_aggregate_v<std::remove_cvref_t<T>>
consteval int gmp::member_count ( )
Template Parameters
TThe aggregate type to count members for.
ArgsThe accumulated parameter types for construction testing.
Returns
The number of members in the aggregate type.
Note
This function is consteval and only works with aggregate types.
Requires std::is_aggregate_v<T> to be true.
struct Point { int x; int y; };
struct Empty {};
struct Mixed { int i; double d; char c; };
// Count members of aggregate types
static_assert(member_count<Point>() == 2);
static_assert(member_count<Empty>() == 0);
static_assert(member_count<Mixed>() == 3);
// Can be used in template constraints
template<typename T>
concept HasTwoMembers = std::is_aggregate_v<T> && member_count<T>() == 2;
static_assert(HasTwoMembers<Point>);
static_assert(!HasTwoMembers<Mixed>);

Definition at line 402 of file meta.hpp.

References gmp::enum_values(), and gmp::member_count().

Referenced by gmp::member_count().

◆ member_name()

template<std::size_t I, typename T >
requires std::is_aggregate_v<T> && (I < member_count<T>()) && (member_count<T>() <= GMP_MAX_SUPPORTED_FIELDS)
consteval auto gmp::member_name ( )
noexcept
Template Parameters
IThe zero-based index of the member to get the name for.
TThe aggregate type containing the member.
Returns
A fixed_string containing the member name.
Note
This function is consteval and requires:
Exceptions
Compile-timeerror if any of the above requirements are not met.
struct Person {
std::string name;
int age;
double height;
};
struct Empty {};
// Get individual member names
static_assert(first_member == "name");
static_assert(second_member == "age");
static_assert(third_member == "height");
// Use in static assertions
static_assert(member_name<0, Person>().size() == 4);
// Template metaprogramming
template<typename T, size_t I>
struct MemberTraits {
static constexpr auto name = member_name<I, T>();
static constexpr size_t index = I;
};
static_assert(MemberTraits<Person, 1>::name == "age");
// These would cause compile-time errors:
// member_name<0, Empty>(); // Error: I < member_count<T>() fails
// member_name<3, Person>(); // Error: Index out of bounds
// member_name<0, int>(); // Error: Not an aggregate

Definition at line 467 of file meta.hpp.

References gmp::constant_arg, and gmp::enum_values().

◆ member_names()

template<typename T >
consteval auto gmp::member_names ( )

This function returns an array containing the names of all members of the aggregate type T.

Template Parameters
TThe aggregate type to get member names for.
Returns
A std::array of std::string_view containing all member names. Returns an empty array if the aggregate has no members.
struct Vector3 { float x; float y; float z; };
struct Empty {};
struct Config { int timeout; bool enabled; std::string host; };
// Get all member names
static_assert(vec_members.size() == 3);
static_assert(vec_members[0] == "x");
static_assert(vec_members[1] == "y");
static_assert(vec_members[2] == "z");
// Empty aggregate
static_assert(empty_members.empty());
// Compile-time iteration
template<typename T>
constexpr bool has_member(std::string_view name) {
constexpr auto names = member_names<T>();
for (size_t i = 0; i < names.size(); ++i) {
if (names[i] == name) return true;
}
return false;
}
static_assert(has_member<Config>("timeout"));
static_assert(has_member<Config>("host"));
static_assert(!has_member<Config>("port"));
// Generate compile-time member name list
template<typename T>
struct MemberList {
static constexpr auto names = member_names<T>();
static constexpr size_t size = names.size();
template<size_t I>
static constexpr auto get() { return names[I]; }
};
static_assert(Vector3Members::size == 3);
static_assert(Vector3Members::get<1>() == "y");

Definition at line 538 of file meta.hpp.

References gmp::enum_values().

◆ member_ref()

template<std::size_t I, typename T , typename UnqualifiedT = std::remove_cvref_t<T>>
requires std::is_aggregate_v<UnqualifiedT> && (I < member_count<UnqualifiedT>()) && (member_count<UnqualifiedT>() <= GMP_MAX_SUPPORTED_FIELDS)
decltype(auto) gmp::member_ref ( T &&  value)
noexcept

This function returns the selected member while preserving the value category of the aggregate object passed in.

Template Parameters
IThe zero-based member index.
TThe aggregate object type.
UnqualifiedTThe cvref-stripped aggregate type.
Parameters
valueThe aggregate object whose member is requested.
Returns
A reference to the I-th member.

Definition at line 645 of file meta.hpp.

References gmp::constant_arg, and gmp::enum_values().

◆ member_type_names()

template<typename T >
constexpr auto gmp::member_type_names ( )
constexpr
Template Parameters
T- The aggregate type to introspect (struct/class with public members)
Returns
std::array<std::string_view, N> where N is the member count of T, containing the demangled/pretty type names of each member in declaration order
Note
The type names are generated at compile time and stored as static data
The returned string_views remain valid for the entire program lifetime
Requires T to be an aggregate type with known member count at compile time
struct Person {
int age;
std::string name;
double height;
};
// names[0] == "int"
// names[1] == "std::string" (or "std::basic_string<char>")
// names[2] == "double"
See also
member_type_t, member_count

Definition at line 625 of file meta.hpp.

◆ type_name()

template<typename T >
consteval auto gmp::type_name ( )

This function returns a compile-time string representing the name of the given type T. The implementation is compiler-specific and extracts the type name from compiler-generated function signatures.

Template Parameters
TThe type whose name is to be retrieved.
Returns
A fixed_string containing the type name. If the compiler is not supported (currently GCC, Clang, and MSVC are supported), returns "Unknown type name".
Note
This function is marked as consteval, ensuring it's evaluated entirely at compile-time. The returned string is suitable for compile-time string manipulation and comparison.
auto int_name = type_name<int>(); // "int" on all compilers
auto vec_name = type_name<std::vector<int>>(); // Compiler-specific representation
// Can be used in static assertions
static_assert(type_name<int>().size() == 3);

Definition at line 53 of file type_name.hpp.

References gmp::enum_values(), gmp::remove_all(), and gmp::fixed_string< N >::size().

◆ type_size()

template<typename T >
consteval std::size_t gmp::type_size ( )

For aggregate types, this function sums the sizes of members in declaration order and does not count padding bytes inserted between members or after the final member. Nested aggregate members and bounded array types are calculated recursively. Non-aggregate leaf types use sizeof(T).

Template Parameters
TThe type to calculate.
Returns
The payload size of T, excluding aggregate padding.
struct Packet {
char tag;
int value;
};
static_assert(gmp::type_size<Packet>() == sizeof(char) + sizeof(int));
static_assert(gmp::type_size<Packet>() <= sizeof(Packet));

Definition at line 81 of file type_size.hpp.

Variable Documentation

◆ enum_max_v

template<typename E >
constexpr int gmp::enum_max_v
inlineconstexpr
Template Parameters
EThe enumeration type.

Definition at line 94 of file meta.hpp.

◆ enum_min_v

template<typename E >
constexpr int gmp::enum_min_v
inlineconstexpr
Template Parameters
EThe enumeration type.

Definition at line 86 of file meta.hpp.