2
#include <iostream>
#include <string>
#include <tuple>
#include <vector>
#include <cstdlib>

struct FieldBase
{
    // To enable dynamic_cast.
    virtual void fb()
    {

    }
};

template <typename A, typename B>
struct Field : public FieldBase
{
    Field(A B::* v) :
        value(v)
    {

    }

    A B::* value;
};

template <typename A>
struct MetaData
{
    static std::vector<FieldBase> fields;
};

struct Test
{
    unsigned int a;
    std::string b;
};

template <>
struct MetaData<Test>
{
    static const std::vector<FieldBase*> fields;
};

const std::vector<FieldBase*> MetaData<Test>::fields{ new Field<unsigned int, Test>(&Test::a), new Field<std::string, Test>(&Test::b) };

template <typename A>
void serialize(const A& object)
{
    std::cout << typeid(A).name() << std::endl;

    for (const FieldBase* field : MetaData<A>::fields)
    {
        const Field<unsigned int, A>* f1 = dynamic_cast<const Field<unsigned int, A>*>(field);

        if (f1 != 0)
            std::cout << object.*f1->value << std::endl;

        const Field<std::string, A>* f2 = dynamic_cast<const Field<std::string, A>*>(field);

        if (f2 != 0)
            std::cout << object.*f2->value << std::endl;
    }
}

int main()
{
    Test test;
    test.a = 2014;
    test.b = "Hello";

    serialize(test);

    std::cin.sync();
    std::cin.get();
    return EXIT_SUCCESS;
}

Here is something I could think of. But I do not think this is the right approach at all.

What I would really like to do is examining the stored fields without any dynamic casts.

Would it be meaningful to store Fields in a tuple and then go through all the tuple elements? Although I am not sure how to access tuple elements when the index comes from a loop counter.

std::tuple<Field<unsigned int, Test>, Field<std::string, Test>>

How does one iterate over that tuple when its size may vary?

NFRCR
  • 5,304
  • 6
  • 32
  • 37
  • Your explanation of what it does, what it should do, and what you are aiming for is a bit ... sparse. So much so that I'm not really sure what the question is. Hope that helps, and looking back in a few. – Deduplicator Sep 16 '14 at 22:42
  • @Deduplicator, I think the whole thing comes down to this (what would lead me to a solution). I think the right way to store field information is a tuple. But I do not know a way to access all elements of a tuple regardless of its size. – NFRCR Sep 16 '14 at 22:47
  • For `FieldBase` ctor, take a look at my answer here: http://stackoverflow.com/a/25873634 – Deduplicator Sep 16 '14 at 22:49
  • One question: Shall that be fully-evaluated and tested compile-time reflection, or more of a runtime-thing? First is probably superior in moderation, second in masses. Also, which C++ standard is the limit for you? C++14? – Deduplicator Sep 16 '14 at 22:54
  • @Deduplicator, whatever is easier. I don't have full C++14 support from my compiler yet. – NFRCR Sep 16 '14 at 22:58
  • 1
    The easiest way to programmatically access all elements of a tuple is template-recursion. Also, what you need to serialize a `struct` is a tuple containing: a pointer to the typeinfo and member-pointers for each element. You can easily make such a one, as a compile-time-constant in C++14: `make_tuple(&typeid(A),&A::element1,&A::element2);`. Store those like type_traits, so your serializer can easily find them. – Deduplicator Sep 16 '14 at 23:21

0 Answers0