#include <utility>
#include <string>
using namespace std;
struct M {
virtual ~M(){};
//type information of instanced member
};
//Collection Interfaces
struct A {
virtual ~A(){};
virtual void Item( int* ) = 0;
};
struct B {
virtual ~B(){};
virtual void Item( string* ) = 0;
};
struct C {
virtual ~C(){};
virtual void Item( A** ) = 0;
};
//Collection CoClasses
struct X: public A, public M {
X(){ y = 5; };
~X(){};
int y;
virtual void Item( int* x ) { *x = y; };
};
struct Y: public B, public M {
Y(){ y.append("5"); };
~Y(){};
string y;
virtual void Item( string* x ) { *x = y; };
};
struct Z: public C, public M {
Z(){ y = new X; };
~Z(){};
A* y;
virtual void Item( A** x ) { *x = y; };
};
//Reflexion Wrapper
struct S {
M* m_p;
template <typename T>
auto operator()(T&& t, int i)->decltype(forward<T>(t))
{
switch(i)
{
case 1: {
A* temp = dynamic_cast<A*>(m_p);
temp->Item(&forward<T>(t));
break; }
case 2: {
B* temp = dynamic_cast<B*>(m_p);
temp->Item(&forward<T>(t));
break; }
case 3: {
C* temp = dynamic_cast<C*>(m_p);
temp->Item(&forward<T>(t));
break; }
}
return t;
}
};
//test
int main ()
{
S a;
a.m_p = static_cast< M* >( new X );
int u = 0;
a(u, 1);
S b;
b.m_p = static_cast< M* >( new Y );
string v;
b(v, 2);
S c;
c.m_p = static_cast< M* >( new Z );
A* w;
b(w, 3);
return 0;
}