Skip to content

Commit

Permalink
Initial code
Browse files Browse the repository at this point in the history
  • Loading branch information
d-b committed Jul 8, 2015
1 parent bdb3d90 commit 7b79bad
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
45 changes: 45 additions & 0 deletions example.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* >= C++11 Reflection
*
* - Daniel Bloemendal
*/

#include <tuple>
#include <iostream>

#include "reflection.hpp"

template<typename Klass>
class example_serializer {
Klass& _instance;

public:
example_serializer(Klass& instance) : _instance(instance) {}

template<typename T>
void operator()(const field<Klass, T>& field) {
std::cout << field.name << " (" << field.caption << "): " << (&_instance)->*field.pointer << std::endl;
}

void serialize() {
for_each(meta<Klass>::fields(), *this);
}
};

class example_class {
public:
int integer_field;
float float_field;
std::string string_field;
};

REFLECT_REGISTER(example_class,
REFLECT_FIELD(integer_field, "an integer field"),
REFLECT_FIELD(float_field, "a floating point field"),
REFLECT_FIELD(string_field, "a string field"))

int main() {
example_class ex{1, 2.0, "hello world"};
example_serializer<example_class> s(ex);
s.serialize();
}
64 changes: 64 additions & 0 deletions reflection.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* >= C++11 Reflection
*
* - Daniel Bloemendal
*/

#pragma once

struct for_each_impl {
template<std::size_t I = 0, typename Function, typename... Items>
inline typename std::enable_if<I == sizeof...(Items), void>::type
static for_each(std::tuple<Items...>& tuple, Function& fn) {}

template<std::size_t I = 0, typename Function, typename... Items>
inline typename std::enable_if<I < sizeof...(Items), void>::type
static for_each(std::tuple<Items...>& tuple, Function& fn) {
fn(std::get<I>(tuple));
for_each<I + 1, Function, Items...>(tuple, fn);
}
};

template<typename Function, typename... Items>
void for_each(std::tuple<Items...>& tuple, Function& fn) {
for_each_impl::for_each(tuple, fn);
}

template<typename Function, typename... Items>
void for_each(std::tuple<Items...>&& tuple, Function& fn) {
for_each_impl::for_each(tuple, fn);
}

template<typename Klass, typename Type>
struct field {
// Type definitions
enum { flags_constant = 1, flags_private = 2 };
typedef Type (Klass::*pointer_type);

// Field information
std::string name;
pointer_type pointer;
int flags;
std::string caption;
std::string doc;
};

template<typename Klass, typename Type>
field<Klass, Type> make_field(std::string name, Type (Klass::*pointer), int flags = 0, std::string caption = "", std::string doc = "") {
return field<Klass, Type>{std::move(name), pointer, flags, std::move(caption), std::move(doc)};
}

template<typename Klass>
struct meta {
std::tuple<> fields() { return std::tuple<>(); }
};

#define REFLECT_REGISTER(cls, ...) \
template<> \
struct meta<cls> { \
typedef cls klass; \
static auto fields() -> decltype(std::make_tuple(__VA_ARGS__)) { return std::make_tuple(__VA_ARGS__); } \
};

#define REFLECT_FIELD(name, caption) \
make_field(#name, &klass::name, 0, caption, "")

0 comments on commit 7b79bad

Please sign in to comment.