#include <iostream>
template <class T, class U>
struct Typelist
{
typedef T head;
typedef U Tail;
};
class NullType
{ };
template <typename T1 = NullType, typename T2 = NullType, typename T3 = NullType,
typename T4 = NullType, typename T5 = NullType>
class MakeList
{
typedef typename MakeList< T2, T3, T4, T5 >::Result Tail;
public:
typedef Typelist<T1, Tail> Result;
};
template <>
class MakeList<>
{
public:
typedef NullType Result;
};
template <class TList> struct Length;
template <>
struct Length< NullType >
{
enum { value = 0 };
};
template <class T, class U>
struct Length< Typelist<T, U> >
{
enum { value = 1 + Length<U>::value };
};
template <class TList, unsigned int Index> struct TypeAt;
template <class Head, class Tail>
struct TypeAt<Typelist<Head, Tail>, 0>
{
typedef Head Result;
};
template <class Head, class Tail, unsigned int Index>
struct TypeAt<Typelist<Head, Tail>, Index>
{
typedef typename TypeAt<Tail, Index - 1>::Result Result;
};
//============ ΠΡΠΈΠΌΠΈΡΠΈΠ²Π½Π°Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ Tuple Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΡΠΏΠΈΡΠΊΠ° ΡΠΈΠΏΠΎΠ² ==================
template <typename T, unsigned int I>
class TupleElement
{
public:
T & get()
{
return m_value;
}
private:
T m_value;
};
template <typename List, unsigned int I = 0>
class TupleImpl;
template <typename T, typename U, unsigned int I>
class TupleImpl<Typelist<T, U>, I>
: public TupleElement<T, I>
, public TupleImpl<U, I + 1>
{ };
template <unsigned int I>
class TupleImpl<NullType, I>
{ };
template <
typename T1 = NullType, typename T2 = NullType, typename T3 = NullType,
typename T4 = NullType, typename T5 = NullType
>
class Tuple : public TupleImpl<typename MakeList<T1, T2, T3, T4, T5>::Result>
{
typedef typename MakeList<T1, T2, T3, T4, T5>::Result ElementsList;
public:
template <unsigned int Index>
typename TypeAt<ElementsList, Index>::Result & get()
{
TupleElement<typename TypeAt<ElementsList, Index>::Result, Index> & el = *this;
return el.get();
}
enum
{
Size = Length<ElementsList>::value
};
};
//======================== ΠΠΌΡΠ»ΡΡΠΈΡ ΠΏΠ΅ΡΠ΅Π±ΠΎΡΠ° Π² ΡΠΈΠΊΠ»Π΅ ====================================
template <typename Tuple, unsigned int I = Tuple::Size>
struct TupleForEach_
{
template <typename F>
static void run(Tuple & tpl, F f)
{
TupleForEach_<Tuple, (I - 1)>::run(tpl, f);
f(tpl.template get<(I - 1)>());
}
};
template <typename Tuple>
struct TupleForEach_<Tuple, 0>
{
template <typename F>
static void run(Tuple & tpl, F f) { }
};
template <typename Tuple, typename F>
void TupleForEeach(Tuple & x, F f)
{
TupleForEach_<Tuple>::run(x, f);
}
//=======================================================================
template<typename Tuple, unsigned int I = Tuple::Size>
struct TupleFor__
{
template<typename F>
static void run(Tuple& tpl, F f, unsigned int i)
{
if
(i == I - 1) f(tpl.template get<(I - 1)>());
else
TupleFor__<Tuple, (I - 1)>::run(tpl, f, i);
}
};
template <typename Tuple>
struct TupleFor__<Tuple, 0>
{
template <typename F>
static void run(Tuple& tpl, F f, unsigned int i) { }
};
template <typename Tuple, typename F>
void TupleFor_(Tuple& t, F f, unsigned int i)
{
TupleFor__<Tuple>::run(t, f, i);
}
template<typename Tuple, typename F>
void TupleFor(unsigned int first, unsigned int last, Tuple t, F f)
{
for (unsigned int i = first; i <= last; ++i)
TupleFor_(t, f, i);
}
//=======================================================================
struct CoutPrinter {
template <typename T>
void operator()(T const & v) const
{
std::cout << v << ' ';
}
};
int main()
{
Tuple<int, char, double, unsigned int> tpl;
tpl.get<0>() = -12;
tpl.get<1>() = 'a';
tpl.get<2>() = 3.14;
tpl.get<3>() = 50;
unsigned int a = 0;
unsigned int b = 0;
std::cin >> a;
std::cin >> b;
TupleFor(a, b, tpl, CoutPrinter());
}