Home

Awesome

Reflect

Small, flexible, single-header library for aggregate (struct / class) runtime reflection and meta data using C++11 features. Minimal STL usage, no other dependencies.

<br />

Installation

#define REGISTER_REFLECTION
#include "reflect.h"
#include "my_struct_1.h"
#include "my_struct_2.h"
#include etc...
InitializeReflection();
<br />

Usage

Registration in Header File, example: "transform.h"

#ifndef TRANSFORM2D_H
#define TRANSFORM2D_H

#include "reflect.h"
struct Transform2D {
    int width;
    int height;
    std::vector<double> position;
    std::string text;
    REFLECT();
}
#ifdef REGISTER_REFLECTION
    REFLECT_CLASS(Transform2D)
    REFLECT_MEMBER(width)
    REFLECT_MEMBER(height)
    REFLECT_MEMBER(position)
    REFLECT_MEMBER(text)
    REFLECT_END(Transform2D)
#endif

#endif // TRANSFORM2D_H
<br />

In Code

Initialize class instance

Transform2D t { };
t.width = 100;
t.height = 100;
t.position = std::vector<double>({1.0, 2.0, 3.0});
t.text = "Hello world!";

TypeData Object

// Class TypeData
TypeData data = ClassData<Transform2D>();           // By class type
TypeData data = ClassData(t);                       // By class instance
TypeData data = ClassData(type_hash);               // By class type hash
TypeData data = ClassData("Transform2D");           // By class name

// Member TypeData
TypeData data = MemberData<Transform2D>(0);         // By class type, member index
TypeData data = MemberData<Transform2D>("width");   // By class type, member name
TypeData data = MemberData(t, 0);                   // By class instance, member index
TypeData data = MemberData(t, "width");             // By class instance, member name
TypeData data = MemberData(type_hash, 0);           // By class type hash, member index
TypeData data = MemberData(type_hash, "width");     // By class type hash, member name

Get / Set Member Variables

// Member Variable by Index
TypeData member = MemberData(t, 0);
if (member.type_hash == TypeHashID<int>()) {
    // Create reference to member
    int& width = ClassMember<int>(&t, member);
    // Can now set member variable directly
    width = 120;
}

// Member Variable by Name
TypeData member = MemberData(t, "position");
if (member.type_hash == TypeHashID<std::vector<double>>()) {
    // Create reference to member
    std::vector<double>& position = ClassMember<std::vector<double>>(&t, member);
    // Can now set member variable directly
    position = { 2.0, 4.0, 6.0 };
}
<br />

Iterating Members / Properties

int member_count = ClassData(t).member_count;
for (int index = 0; index < member_count; ++index) {
    TypeData member = MemberData(t, index);
    std::cout << " Index: " << member.index << ", ";
    std::cout << " Name: "  << member.name  << ", ";
    std::cout << " Title: " << member.title << ", ";
    std::cout << " Value: ";
    if (member.type_hash == TypeHashID<int>()) {
        std::cout << ClassMember<int>(&t, member);
    } else if (member.type_hash == TypeHashID<std::string>()) {
        std::cout << ClassMember<std::string>(&t, member);
    } else if (member.type_hash == TypeHashID<std::vector<double>>()) {
        std::vector<double>& vec = ClassMember<std::vector<double>>(&t, member);
        for (auto& number : vec) {
            std::cout << number << ", ";
        }
    }
}
<br />

Data from Unknown Class Type

TypeHash saved_hash = ClassData(t).type_hash;
void* class_pointer = (void*)(&t);
using vec = std::vector<double>;
TypeData member = MemberData(saved_hash, 3);
if (member.type_hash == TypeHashID<vec>()) {
    vec& rotation = ClassMember<vec>(class_pointer, member);
    std::cout << "  Rotation X: " << rotation[0];
    std::cout << ", Rotation Y: " << rotation[1];
    std::cout << ", Rotation Z: " << rotation[2];
}
<br />

User Meta Data

Registration in Header File, example: "transform.h"

#ifdef REGISTER_REFLECTION
    REFLECT_CLASS(Transform2D)
        CLASS_META_DATA(META_DATA_DESCRIPTION, "Describes object in 2D space.")
        CLASS_META_DATA("icon", "assets/transform.png")
    REFLECT_MEMBER(width)
        MEMBER_META_DATA(META_DATA_DESCRIPTION, "Width of this object.")
    REFLECT_MEMBER(height)
        MEMBER_META_DATA(META_DATA_DESCRIPTION, "Height of this object.")
    REFLECT_MEMBER(position)
        MEMBER_META_DATA(META_DATA_HIDDEN, "true")
        MEMBER_META_DATA("tooltip", "Pos")
    REFLECT_END(Transform2D)
#endif

Get / Set Meta Data

// TypeData from class
TypeData& type_data = ClassData<Transform2D>();
// or from member variable
TypeData& type_data = MemberData<Transform2D>("width");

// Get meta data
std::string description = GetMetaData(type_data, META_DATA_DESCRIPTION);
std::string icon_file   = GetMetaData(type_data, "icon");

// Set meta data
SetMetaData(type_data, META_DATA_DESCRIPTION, description);
SetMetaData(type_data, "icon", icon_file);
<br />

Portability

Tested and compiled with: