Lahzam is a modern C++17 header-only library for fast and simple compile-time reflection of aggregate types.
API contains very simple functions
lahzam::tie(aggregate)converts an aggregate to astd::tuple<Members&...>of references to apply algorithms on it.lahzam::member_count<T>gives the member count of aggregates orsize_t(-1)on errorlahzam::member_names<T>an object that iterates over all names of members. Requires C++20 atleast to work.lahzam::get<I>(aggregate)equalivent tostd::get<I>(lahzam::tie(aggregate))lahzam::get<"Name">(aggregate)gives the member of the specific name.lahzam::apply(f,aggregate)similar tostd::tupleapply.lahzam::for_each_member(f,aggregate)similar to apply except the callable only takes a single arguementlahzam::for_each_member_with_index(f,aggregate)similar tolahzam::for_each_memberexcept the callable takes the member and an indexlahzam::for_each_member_with_name(f,aggregate)similar tolahzam::for_each_memberexcept the callable takes the member and its member name requires C++20 atleast to work
Examples
#include <lahzam/lahzam.hpp>
#include <iostream>
struct Point { int x, y; };
int main() {
Point p{10,20};
static_assert(lahzam::member_count<Point> == 2);
static_assert(lahzam::member_names<Point>[0] == "x");
static_assert(lahzam::member_names<Point>[1] == "y");
static_assert(lahzam::member_names<Point>.size() == 2);
for(auto n : lahzam::member_names<Point>)
{
std::cout << n;
}
int x,y;
// Access members by index
x = lahzam::get<0>(p); // x == 10
y = lahzam::get<1>(p); // y == 20
// Access members by name
x = lahzam::get<"x">(p); // x == 10
y = lahzam::get<"y">(p); // y == 20
// Tie into a tuple
std::tuple<int&,int&> tuple_ref = lahzam::tie(p);
// Algorithms
lahzam::apply([](int x,int y)
{
std::cout << x << y;
},p)
lahzam::for_each_member([](auto& m)
{
std::cout << m;
},p);
lahzam::for_each_member_with_index([](auto& m,size_t idx)
{
std::cout << idx << m;
},p);
lahzam::for_each_member_with_name([](auto& m,std::string_view name)
{
std::cout << name << m;
},p);
}MEMBERS is the amount of members in each type tested.
TYPES is the amount of types in each test being tested.
[!NOTE] Tests were conducted on C++23 (glaze requires it), so no experimental C++26 language reflection was utilized. C++26 Reflective implementations will yield significantly different results.
Compiled using Clang 20.1.2 on Windows 10.
| MEMBERS | TYPES | boost::pfr::get |
lahzam::get |
glz::to_tie + get |
|---|---|---|---|---|
| 128 | 32 | 9.48s | 5.55s | 8.51s |
| 64 | 64 | 6.71s | 4.26s | 5.75s |
| 32 | 128 | 6.00s | 3.68s | 4.56s |
| 16 | 256 | 6.43s | 3.74s | 4.41s |
glazedoes not expose directly agetfunction it instead exposesto_tiewhich we can use.
lahzam is consistently ~1.7× faster than Boost and slightly faster than glaze.
| MEMBERS | TYPES | boost::pfr::get_name |
lahzam::member_names |
glz::reflect::keys |
|---|---|---|---|---|
| 128 | 32 | 14.55s | 3.84s | 21.87s |
| 64 | 64 | 13.23s | 3.69s | 17.72s |
| 32 | 128 | 13.00s | 4.34s | 15.97s |
| 16 | 256 | 13.93s | 4.52s | 15.49s |
Lahzam is up to ~3× faster member name access compared to Boost and ~4× faster than Glaze.
add_subdirectory(third_party/lahzam)
target_link_libraries(tests PRIVATE lahzam::lahzam)The library does not work if the type contains C arrays
struct X
{
int arr[4];
};
X x;
lahzam::get<0>(x); // errorGetting names of members with types who contain references does not work
struct X
{
int& ref;
};
X x{var};
lahzam::get<0>(x); // works
lahzam::get<"ref">(x); // error
lahzam::member_names<X>[0]; // errorIt does not support inheritance yet
struct X { int x;};
struct Y : X {int y;};
lahzam::get<0>(Y{}); // error