-
-
/***********************************************/
-
struct NIL {
-
typedef NIL head;
-
typedef NIL tail;
-
};
-
-
template < class H, class T=NIL> struct LST {
-
typedef H head;
-
typedef T tail;
-
};
-
/***********************************************/
-
-
/***********************************************/
-
template <class X, class Y> struct Eq { static const bool result = false; };
-
template <class X> struct Eq<X, X> { static const bool result = true; };
-
/***********************************************/
-
-
/***********************************************/
-
template <class Elm, class LST> struct Position {
-
private:
-
typedef typename LST::head H;
-
typedef typename LST::tail T;
-
static const bool found = Eq<H, Elm>::result;
-
public:
-
static const int result = found? 1 : 1 + Position<Elm, T>::result;
-
};
-
-
template <class Elm> struct Position<Elm, NIL> {
-
static const int result = 0;
-
};
-
/***********************************************/
-
-
-
/***********************************************/
-
template <typename LST, int N> struct Nth {
-
typedef typename LST::Tail Tail;
-
typedef typename Nth<Tail, N-1>::result result;
-
};
-
-
template <typename LST> struct Nth<LST, 0> {
-
typedef typename LST::head result;
-
};
-
/***********************************************/
-
-
-
/***********************************************/
-
template <class Lst> struct Instances {
-
typedef typename Lst::head Elm;
-
Elm instance;
-
Instances< typename Lst::tail > next;
-
};
-
template <> struct Instances<NIL> {};
-
/***********************************************/
-
-
void f(void *x) {}
-
-
/***********************************************/
-
template <class TypeLst, int N> struct NthInstance {
-
// This one isnt easy…
-
-
// This is the next type in the list
-
typedef typename TypeLst::tail TypeNext;
-
// * Nth::result is the Nth type in Lst (i.e. char, int, …)
-
typedef typename NthInstance< TypeNext, N-1 >::NthInstanceType NthInstanceType;
-
// * typename Nth::result & is a reference to said type and the ret type
-
template <class InstancesLst>
-
static NthInstanceType& get(InstancesLst &instances_lst) {
-
return NthInstance< TypeNext, N-1 >::get(instances_lst.next);
-
}
-
};
-
-
// Remember we chose a 1-based system (wtf..)
-
template <class TypeLst> struct NthInstance<TypeLst, 1> {
-
typedef typename TypeLst::head NthInstanceType;
-
-
template <class InstancesLst>
-
static NthInstanceType& get(InstancesLst &instances_lst) {
-
return instances_lst.instance;
-
}
-
};
-
/***********************************************/
-
-
-
class Facade {
-
typedef LST<int, LST<char, LST<float> > > Lst;
-
Instances<Lst> instances;
-
-
public:
-
template <class PK> int find(PK) {
-
return Position< PK, Lst >::result;
-
}
-
-
template <class PK>
-
// This is a difficult one… it should be parsed like this:
-
// 1) Get the desired instance position using Position< PK, Lst >::result
-
// 2) Get the type @ the desired position with NthInstance::Type
-
// 3) Define said type as a return type (with an & at the end, i.e. make
-
// it a reference to the return type)
-
typename NthInstance< Lst, Position< PK, Lst >::result >::NthInstanceType&
-
get_instance(PK) {
-
const int idx_position = Position< PK, Lst >::result;
-
typedef typename NthInstance< Lst, idx_position >::NthInstanceType IdxType;
-
IdxType &idx = NthInstance< Lst, idx_position >::get( instances );
-
return idx;
-
}
-
};
-
-
#include <iostream>
-
-
int main() {
-
Facade f;
-
int &a = f.get_instance(1);
-
char &b = f.get_instance(‘a’);
-
float &c = f.get_instance(1.0);
-
a = 42; b = ‘n’; c = 4.2;
-
std::
cout << f.
get_instance(1) <<
"\n";
-
std::
cout << f.
get_instance(‘a’) <<
"\n";
-
std::
cout << f.
get_instance(1.0) <<
"\n";
-
a = 43; b = ‘m’; c = 5.2;
-
std::
cout << f.
get_instance(1) <<
"\n";
-
std::
cout << f.
get_instance(‘a’) <<
"\n";
-
std::
cout << f.
get_instance(1.0) <<
"\n";
-
return 0;
-
}
-