Creating a simpler, more intuitive means of C++ reflection
C++ Random Access Reflection & Extensions: adding a simple, intuitive means of reflection to C++
Component | Summary | Examples |
---|---|---|
RareTs | Reflection & type support | |
RareBuilder | Adaptive object builder | |
RareMapper | Dynamic type mapping | |
RareJson | Reflection-based JSON I/O |
#include <rarecpp/reflect.h>
#include <iostream>
struct MyObj
{
int a = 42;
float b = 1337.f;
REFLECT(MyObj, a, b)
};
int main()
{
MyObj myObj{};
RareTs::Members<MyObj>::forEach(myObj, [&](auto member, auto & value) {
std::cout << member.name << ": " << value << std::endl;
});
}
Output:
a: 42
b: 1337
struct Point
{
float x;
float y;
NOTE(hash, Json::Ignore) // Control behavior with member or class-level annotations!
size_t hash = 0;
REFLECT(Point, x, y, hash)
};
struct Descriptor
{
std::string name;
std::string address;
REFLECT(Descriptor, name, address)
};
struct Area
{
int id;
Descriptor descriptor;
std::vector<Point> points;
REFLECT(Area, id, descriptor, points)
};
int main()
{
auto area = RareBuilder<Area>()
.id(92)
.descriptor(RareBuilder<Descriptor>().name("some area").address("12345 main street").build())
.points({{1.1f, 2.2f}, {1.9f, 3.2f}, {1.3f, -2.5f}, {-4.2f, -1.2f}})
.build();
std::cout << Json::pretty(area) << std::endl;
}
Output:
{
"id": 92,
"descriptor": {
"name": "some area",
"address": "12345 main street"
},
"points": [
{"x": 1.1,"y": 2.2},
{"x": 1.9,"y": 3.2},
{"x": 1.3,"y": -2.5},
{"x": -4.2,"y": -1.2}
]
}
Auto-Reflection Example (requires C++20):
struct Item
{
int id = 0;
std::string name {};
};
struct Collection
{
std::string description {};
std::vector<Item> items {};
};
int main()
{
Collection collection { "my collection", {{0, "first"}, {1, "second"}} };
std::cout << Json::pretty(collection);
}
Output:
{
"description": "my collection",
"items": [
{ "id": 0, "name": "first" },
{ "id": 1, "name": "second" }
]
}
* Reflection from outside the class definition can be done on public and protected members - or - with more limitations than the in-class macro, on private members.
** Any members based on the class-level template parameters and any functions for which template parameters are inferred from parameters are reflectable, reflecting other templated members is not always possible.
RareCpp minimizes use of compiler-specific features wherever possible, other compilers may work without modification and may or may not be possible to add to supported compilers upon request.
Use of compiler versions lower than preferred may disable or cause bugs with certain features.