This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Tuples: draft 1


Here is a first draft of the tuple class.

Attached are:
maketuples.c : makes the tuple header
tuples.hpp : the tuple header
test_tuples.cpp : some tests

Whats missing:
1) Need to put the tuples into a namespace. Which one?
2) I declare "extern shallow_assign ignore". This needs to be actually created somewhere..
3) Lots most tests, and also a big bunch of "not compiling" tests.
4) While I think the header is at least passably readable, there are some strange formattings, and in particular lots of very, very long lines.


It is my intension to continue with the test suite over the next couple of days and fill it out much more completely, in particular with all the things that shouldn't compile, and being careful that I don't do anything wrong with either constness or references. However, I expect that both tuples.hpp and maketuples.c will remain at least broadly the same, so if anyone wants to make any comments, either for or against this form of header generation, this should hopefully be enough to get started with :)

Chris

#include<stdio.h>

#ifndef SIZE
#define SIZE 10
#endif

int indent=0;
char buffer[1000];

void
do_indent() 
{
  int i;
  for(i = 0; i < indent; i++)
    printf(" ");
}


/* line takes a line to print, and indents
 * it to the level set by the global 'indent'
 */
void 
line(char* str)
{
  do_indent();
  printf(str);
  printf("\n");
}

/* loopprint prints as follows:
 * 'start body(0) seperate body(1) ... body(loop-1) end'
 * where body(i) is the string body with up to 3 occurances of %d
 * replaced with i
 * if i=0; then simply 'start end' is outputted
 */ 

void 
loopprint(int loop,char* start,char* body,char *end)
{
  int i = 0;
  do_indent();
  printf(start);
  for(i = 0;i < loop-1;i++)
    {
      printf(body,i,i,i);
      printf(", ");
    }
  if(loop != 0)
    {
      printf(body,loop-1,loop-1,loop-1);
    }
  printf(end);
}

/* looplist just takes an integer loop and a char* body, and writes
 * body(0)\n body(1)\n body(2)\n ... body(loop-1)\n
 * where body(i) replaces all occurances of %d with i
 */
void 
looplist(int loop,char* body)
{
  int i;
  for(i = 0;i < loop;i++) 
    {
      do_indent();
      printf(body,i,i,i);
      printf("\n");
    }
}

// These are just a bunch of functions that generate commonly used things
void 
braceopen() 
{
  line("{");
  indent+=2;
}

void 
braceclose() 
{
  indent-=2;
  line("}");
}

void 
classclose() 
{
  indent-=2;
  line("};");
  line("");
}

void 
isZero(char* in_string)
{
  do_indent();
  printf("_IsZero<%s>();\n",in_string);
}

//Now the functions that generate the various parts of the header

void 
reference_wrapper() 
{
  line("template<typename _T>");
  indent+=2;
  line("class reference_wrapper");
  braceopen();
  line("_T& __data;");
  line("public:");
  indent+=2;
  line("typedef _T type;");
  line("explicit reference_wrapper(_T& __indata): __data(__indata)");
  line("{ }");
  line("");
  line("operator _T& () const"); 
  braceopen();
  line("return this->get();");
  braceclose();
  line("");
  line("_T&");
  line("get() const");
  braceopen();
  line("return __data;");
  braceclose();
  indent-=2;
  classclose();
  indent-=2;

  line("template<typename _T>");
  indent+=2;
  line("reference_wrapper<_T>");
  line("ref(_T& __t)");
  braceopen();
  line("return reference_wrapper<_T>(__t);");
  braceclose();
  indent-=2;
  line("");
  line("template<typename _T>");
  indent+=2;
  line("reference_wrapper<_T const>");
  line("cref(const _T& __t)");
  braceopen();
  line("return reference_wrapper<_T const>(__t);");
  braceclose();
  indent-=2;
  line("");
}


void 
add_reference() 
{
  line("template<typename _T>");
  indent+=2;
  line("struct __add_ref");
  braceopen();
  line("typedef const _T& type;");
  classclose();
  indent-=2;

  line("template<typename _T>");
  indent+=2;
  line("struct __add_ref<_T&>");
  braceopen();
  line("typedef _T& type;");
  classclose();
  indent-=2;

  line("template<typename _T>");
  indent+=2;
  line("struct __add_ref<const _T&>");
  braceopen();
  line("typedef const _T& type;");
  classclose();
  indent-=2;
}

void 
printClass(int in) 
{
  braceopen();
  looplist(in, "_T%d __t%d;");
  line("public:");
  // Blank constructor
  line("tuple()");
  line("{ }");
  line("");
  // Explicit constructor
  loopprint(in, "explicit tuple(", 
	    "typename __add_ref<_T%d>::type __in%d", "):\n");
  loopprint(in, "", "__t%d(__in%d)", "\n");
  line("{ }");
  line("");
  // Copy constructor
  line("tuple(const tuple& __in):");
  loopprint(in, "", "__t%d(__in.__t%d)", "\n");
  line("{ }");

  // Copy from other tuple constructor
 
  loopprint(in, "template <", "typename _U%d", ">\n");  
  loopprint(in, "tuple(const tuple<", "_U%d", ">& __in):\n");
  loopprint(in, "", "__t%d(__in.__t%d)", "\n");
  line("{ }");
  line("");
  // Pair goes here
  if(in == 2)
    {
      line("template<class _U1, class _U2>");
      line("  tuple(const std::pair<_U1, _U2>& __u): __t0(__u.first), __t1(__u.second)");
      line("  { }");
      line("");
    }
  // operator = from identical
  line("tuple& operator=(const tuple& __in)");
  braceopen();
  looplist(in, "__t%d=__in.__t%d;");
  line("return *this;");
  braceclose();
  line("");
  loopprint(in, "template <", "typename _U%d", ">\n");
  line("tuple&");
  loopprint(in, "operator=(const tuple<", "_U%d", ">& __in)\n");
  braceopen();
  looplist(in, "__t%d=__in.__t%d;");
  line("return *this;");
  braceclose();
  classclose();
}



void tuple_classes() {
  int i;

  // Next do the empty tuple class
  loopprint(SIZE, "struct tuple<", "_NullClass", ">\n"); 
  braceopen();
  line("public:");
  // Blank constructor
  line("tuple()");
  line("{ }");
  line("");
  // no explicit constructor
  // Copy constructor
  line("tuple(const tuple& __in)");
  line("{ }");
  line("");
  // no copy from other tuple constructor
  // operator = from identical
  line("tuple& operator=(const tuple& __in)");
  braceopen();
  line("return *this;");
  braceclose();
  // no operator = from other
  classclose();
 
  for(i=1;i<=SIZE;i++) 
    {
      loopprint(i, "template<", "typename _T%d", ">\n");
      indent+=2;
      if(i!=SIZE) 
	{
	  loopprint(i, "struct tuple<", "_T%d", ", ");
	  loopprint(SIZE-i, "", "_NullClass", ">\n");
	}
      else 
	{
	  line("struct tuple");
	}
      printClass(i);
      indent-=2;
    }
}

void 
tuple_size() {
  int i;
  line("template<typename _T>");
  line("  struct tuple_size;");
  for(i=0;i<=SIZE;i++)
    {
      if(i!=0) loopprint(i,"template<","typename _T%d",">\n");
      indent+=2;
      loopprint(i,"struct tuple_size<tuple<","_T%d","");
      if(i==0 || i==SIZE)
	loopprint(SIZE-i,"","_NullClass","> >\n");
      else
	loopprint(SIZE-i,", ","_NullClass", "> >\n");
      braceopen();
      do_indent();
      printf("static const int value = %d;\n",i);
      classclose();
      indent-=2;
   }
}

void 
tuple_element()
{
  int i;
  line("template<int __i, typename _T>");
  line("  struct tuple_element;");
  line("");
  for( i=0;i<SIZE;i++)
    {
      loopprint(SIZE,"template<","typename _T%d",">\n");
      indent+=2;
      sprintf(buffer,"struct tuple_element<%d,tuple<",i);
      loopprint(SIZE,buffer,"_T%d","> >\n");
      braceopen();
      do_indent();
      printf("typedef _T%d type;\n",i);
      classclose();
      indent-=2;
    }
}

void 
tuple_value() 
{
  int i;
  line("template<int __i,typename _T>");
  line("struct __tuple_value;\n");
  for(i=0;i<SIZE;i++) {
    line("template<typename _T>");
    indent+=2;
    do_indent();
    printf("struct __tuple_value<%d,_T>\n",i);
    braceopen();
    do_indent();
    printf("static typename tuple_element<%d,_T>::type\n",i);
    line("get_value(_T& __in)");
    braceopen();
    do_indent();
    printf("return __in.__t%d;\n",i);
    braceclose();
    do_indent();
    printf("static typename tuple_element<%d,_T>::type\n",i);
    line("get_value(const _T& __in)");
    braceopen();
    do_indent();
    printf("return __in.__t%d;\n",i);
    braceclose();
    classclose();
    indent-=2;
  }
}

void 
get() 
{
  // non-const get
  loopprint(SIZE, "template<int __i, ", "typename _T%d", ">\n");
  loopprint(SIZE, "typename tuple_element<__i,tuple<", "_T%d", "> >::type\n");
  loopprint(SIZE, "get(tuple<", "_T%d", ">& __t)\n"); 
  braceopen();
  loopprint(SIZE, "return __tuple_value<__i,tuple<", "_T%d", "> >::get_value(__t);\n");
  braceclose();

  // const get
  loopprint(SIZE, "template<int __i, ", "typename _T%d", ">\n");
  loopprint(SIZE, "typename tuple_element<__i,tuple<", "_T%d", "> >::type\n");
  loopprint(SIZE, "get(const tuple<", "_T%d", ">& __t)\n"); 
  braceopen();
  loopprint(SIZE, "return __tuple_value<__i,tuple<", "_T%d", "> >::get_value(__t);\n");
  braceclose();
}


void 
make_compare(char* name, char* before_recurse, char* after_recurse)
{
  do_indent();
  printf("static bool __%s(const _T& __t, const _U& __u)\n",name);
  braceopen();
  do_indent();
  printf("return %s __tuple_compare<0, __i+1, __j, _T, _U>::__%s(__t, __u) %s;\n",
	 before_recurse,name,after_recurse);
  braceclose();
}

void
end_compare(char* name, int end_val)
{
  do_indent();
  printf("static bool __%s(const _T&, const _U&)\n",name);
  braceopen();
  if(end_val)
    line("return true;");
  else
    line("return false;");
  braceclose();
}

void 
tuple_compare() 
{
  //comparison helper
  line("template<int __check_equal_size, int __i, int __j, typename _T, typename _U>");
  line("  struct __tuple_compare;");
  line("");
  line("template<int __i, int __j, typename _T, typename _U>");
  indent+=2;
  line("struct __tuple_compare<0, __i, __j, _T, _U>");
  braceopen();
  make_compare("eq", "get<__i>(__t) == get<__i>(__u) &&", "");
  make_compare("neq", "get<__i>(__t) != get<__i>(__u) ||", "");
  make_compare("less", "(get<__i>(__t) < get<__i>(__u)) || !(get<__i>(__u) < get<__i>(__t)) &&", "");
  make_compare("greater", "(get<__i>(__t) > get<__i>(__u)) || !(get<__i>(__u) > get<__i>(__t)) &&", "");
  make_compare("leq", "(get<__i>(__t) <= get<__i>(__u)) && (!(get<__i>(__u)<=get<__i>(__t)) ||", ")");
  make_compare("geq", "(get<__i>(__t) >= get<__i>(__u)) && (!(get<__i>(__u)>=get<__i>(__t)) ||", ")");
  classclose();
  indent-=2;
  line("template<int __i, typename _T, typename _U>");
  line("struct __tuple_compare<0, __i, __i, _T, _U>");
  braceopen();
  end_compare("eq",1);
  end_compare("neq",0);
  end_compare("leq",1);
  end_compare("geq",1);
  end_compare("less",0);
  end_compare("greater",0);
  classclose();
}

void 
operator_definition(char* op,char* text_op_name)
{

  loopprint(SIZE, "template<", "typename _T%d", ", ");
  loopprint(SIZE, "", "typename _U%d", ">\n");
  sprintf(buffer, "bool operator%s(const tuple<",op);
  loopprint(SIZE,buffer, "_T%d", ">& __t, ");
  loopprint(SIZE, "const tuple<", "_U%d", ">& __u)\n");
  line("{");
  indent+=2;
  loopprint(SIZE, "typedef tuple<", "_T%d", "> __T_tuple;\n");
  loopprint(SIZE, "typedef tuple<", "_U%d", "> __U_tuple;\n");
  do_indent();
  printf("return __tuple_compare<tuple_size<__T_tuple>::value-tuple_size<__U_tuple>::value, 0, tuple_size<__T_tuple>::value, __T_tuple, __U_tuple>::__%s(__t, __u);",text_op_name);
  indent-=2;
  line("}");
}

void 
strip_reference_wrapper() 
{
  line("template<typename _T>");
  line("struct __strip_reference_wrapper");
  braceopen();
  line("  typedef _T __type;");
  classclose();
  line("template<typename _T>");
  line("struct __strip_reference_wrapper<reference_wrapper<_T> >");
  braceopen();
  line("typedef _T& __type;");
  classclose();
  line("template<typename _T>");
  line("struct __strip_reference_wrapper<const reference_wrapper<_T> >");
  braceopen();
  line("  typedef _T& __type;");
  classclose();

  loopprint(SIZE, "template<", "typename _T%d = _NullClass", ">\n");
  line("struct __stripped_tuple_type");
  braceopen();
  loopprint(SIZE, "typedef tuple<",
	    "typename __strip_reference_wrapper<_T%d>::__type", ">");
  line("__type;");
  classclose();
}

void
make_tuple()
{
  int i;
  line("tuple<>");
  line("make_tuple()");
  braceopen();
  line("  return tuple<>();");
  classclose();

  for(i=1;i<SIZE;i++) {
    loopprint(i, "template<", "typename _T%d", ">\n");
    loopprint(i, "typename __stripped_tuple_type<", "_T%d", ">::__type\n");
    loopprint(i, "make_tuple(", "_T%d __t%d", ")\n");
    braceopen();
    loopprint(i, "return typename  __stripped_tuple_type<", "_T%d", ">::");
    loopprint(i, "__type(", "__t%d", ");");
    classclose();
  }
}

void
make_tie()
{
  int i;
  for(i=1;i<SIZE;i++) {
    loopprint(i, "template<", "typename _T%d", ">\n");
    loopprint(i, "tuple<", "_T%d&", ">\n");
    loopprint(i, "tie(", "_T%d& __t%d", ")\n");
    braceopen();
    loopprint(i, "return make_tuple(", "ref(__t%d)", ");\n");
    classclose();
  }
}

void
pair_things(void) 
{
line("template<class _T1, class _T2>");
  line("  struct tuple_size<std::pair<_T1, _T2> >");
  line("  {");
  line("    static const int value = 2;");
  line("  };");
  line("");
  line("template<class _T1, class _T2>");
  line("  struct tuple_element<0, std::pair<_T1, _T2> >");
  line("  {");
  line("    typedef _T1 type;");
  line("  };");
  line("");
  line("template<class _T1, class _T2>");
  line("  struct tuple_element<1, std::pair<_T1, _T2> >");
  line("  {");
  line("    typedef _T2 type;");
  line("  };");
  line("");
  line("template<int _I,class _T1,class _T2>");
  line("  typename tuple_element<_I,tuple<_T1, _T2> >::type");
  line("  get(pair<_T1, _T2>& __in)");
  line("  {");
  line("    return get<_I>(tie(__in.first, __in.second));");
  line("  }");
  line("");
  line("template<int _I,class _T1,class _T2>");
  line("  typename tuple_element<_I,tuple<_T1, _T2> >::type");
  line("  get(const pair<_T1, _T2>& __in)");
  line("  {");
  line("    return get<_I>(tie(__in.first, __in.second));");
  line("  }");
  line("");
}

int 
main(void) 
{
  line("#include<string>");
  line("#include<utility>");
  // This is just a helper object
  line("struct _NullClass");
  line("{ };");
  line("");
  line("struct swallow_assign");
  line("{");
  line("  template <class T>");
  line("  swallow_assign&");
  line("  operator=(const T&)");
  line("    {return *this;}");
  line("};");
  line("extern swallow_assign ignore;");
  line("");
 
  reference_wrapper();  
  add_reference(); //Note: internal class!
  // Forward definition of tuple class
  loopprint(SIZE, "template<", "typename _T%d=_NullClass", ">\n");
  indent+=2;
  line("struct tuple;");
  indent-=2;
  line("");
  tuple_element();
  tuple_size();
  tuple_classes();
  tuple_value(); //Note: this is an implemention-specific helper class used in get
  get();
  tuple_compare(); //Note: this is an implemention-specific helper class
  operator_definition("==", "eq");
  operator_definition("!=", "neq");
  operator_definition("<", "less");
  operator_definition(">", "greater");
  operator_definition("<=", "leq");
  operator_definition(">=", "geq");
  strip_reference_wrapper(); //Note: this is a helper class for make_tuple
  make_tuple();
  make_tie();
  return 0;
}
#include "tuples.hpp"
#include <stdio.h>
#include <stdlib.h>
#define VERIFY(i) {if(!(i)) {printf(#i "\n"); exit(0);} }
using namespace std;

struct foo
{ 
  bool operator==(const foo& in) {
    printf("check!\n");
    return true;
  }
};

int 
main(void) 
{
  int x1=0,x2=0,x3=0,x4=0;
  const int y1=1,y2=2;
  const int &z1=x1;
  const int &z2=x2;

  {
  // Test empty constructor
  tuple<int,int> ta;
  tuple<int,int> tb(x1,x2);
  tuple<int,int&> tc(x1,x2);
  tuple<const int&,const int&> td(z1,y2);
  // Test identical tuple copy constructor
  tuple<int,int> te(ta);
  tuple<int,int> tf(td);
  tuple<int,const int&> tg(tc);
  // Test different tuple copy constructor
  tuple<int,double> th(ta);
  tuple<int,double> ti(td);
  tuple<double,int&> tj(tc);
  x2=10;
  VERIFY(get<1>(tj)==10);
  // Test constructing from a pair
  pair<int,int> pair1(1,1);
  const pair<int,int> pair2(pair1);
  tuple<int,int> tk(pair1);
  tuple<int,const int&> tl(pair1);
  tuple<int,int> tm(pair2);
  tuple<int,const int&> tn(pair2);
  
  // Test identical operator=
  tb=ta;
  //Test different operator=
  th=ta;
  }
  //test make_tuple
  make_tuple(1,2,4.0);
  tuple<int,int> tk=make_tuple(1,x1);
  //test tie and make_tuple's refs
  x3=1;
  x4=1;
  
  make_tuple(ref(x1),ref(x2))=tk;
  make_tuple(ref(x1),ref(x2))=tuple<int,int>(1,1);
  VERIFY(x1==1 && x2==1);
  x3=2;x4=2;
  tie(x1,x2)=make_tuple(ref(x3),ref(x4));
  VERIFY(x1==2 && x4==2);
  tie(x1,x2)=make_tuple(cref(y1),cref(y2));
  // test tuple_size
  VERIFY(tuple_size<tuple<> >::value==0);
  VERIFY(tuple_size<tuple<int> >::value==1);
  typedef tuple<int,const int&> test_tuple1;
  VERIFY(tuple_size<test_tuple1>::value==2);
  VERIFY(tuple_size<tuple<void> >::value==1);
  // test tuple_element
  foo q1;
  tuple_element<0,tuple<foo,int,int> >::type q2(q1);
  tuple_element<1,tuple<int,foo,void> >::type q3(q1);
  //test get and const get
  {
    int j=1;
    const int k=2;
    tuple<int,int &,const int&> a(0,j,k);
    const tuple<int,int &,const int&> b(1,j,k); 
    VERIFY(get<0>(a)==0 && get<1>(a)==1 && get<2>(a)==2);
    VERIFY(get<0>(b)==1 && get<1>(b)==1 && get<2>(b)==2);
    VERIFY(a==a && (b==b) &&  !(a!=a) && !(b!=b));
    VERIFY(!(a<a) && !(b<b) && !(a>a) && !(b>b));
    VERIFY(a<b && !(b<a) && a<=b && !(b<=a));
    VERIFY(b>a && !(a>b) && b>=a && !(a>=b));
    }
}
#include<string>
#include<utility>
struct _NullClass
{ };

struct swallow_assign
{
  template <class T>
  swallow_assign&
  operator=(const T&)
    {return *this;}
};
extern swallow_assign ignore;

template<typename _T>
  class reference_wrapper
  {
    _T& __data;
    public:
      typedef _T type;
      explicit reference_wrapper(_T& __indata): __data(__indata)
      { }
      
      operator _T& () const
      {
        return this->get();
      }
      
      _T&
      get() const
      {
        return __data;
      }
  };
  
template<typename _T>
  reference_wrapper<_T>
  ref(_T& __t)
  {
    return reference_wrapper<_T>(__t);
  }

template<typename _T>
  reference_wrapper<_T const>
  cref(const _T& __t)
  {
    return reference_wrapper<_T const>(__t);
  }

template<typename _T>
  struct __add_ref
  {
    typedef const _T& type;
  };
  
template<typename _T>
  struct __add_ref<_T&>
  {
    typedef _T& type;
  };
  
template<typename _T>
  struct __add_ref<const _T&>
  {
    typedef const _T& type;
  };
  
template<typename _T0=_NullClass, typename _T1=_NullClass, typename _T2=_NullClass, typename _T3=_NullClass, typename _T4=_NullClass, typename _T5=_NullClass, typename _T6=_NullClass, typename _T7=_NullClass, typename _T8=_NullClass, typename _T9=_NullClass>
  struct tuple;

template<int __i, typename _T>
  struct tuple_element;

template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9>
  struct tuple_element<0,tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> >
  {
    typedef _T0 type;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9>
  struct tuple_element<1,tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> >
  {
    typedef _T1 type;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9>
  struct tuple_element<2,tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> >
  {
    typedef _T2 type;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9>
  struct tuple_element<3,tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> >
  {
    typedef _T3 type;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9>
  struct tuple_element<4,tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> >
  {
    typedef _T4 type;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9>
  struct tuple_element<5,tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> >
  {
    typedef _T5 type;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9>
  struct tuple_element<6,tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> >
  {
    typedef _T6 type;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9>
  struct tuple_element<7,tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> >
  {
    typedef _T7 type;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9>
  struct tuple_element<8,tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> >
  {
    typedef _T8 type;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9>
  struct tuple_element<9,tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> >
  {
    typedef _T9 type;
  };
  
template<typename _T>
  struct tuple_size;
  struct tuple_size<tuple<  _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass> >
  {
    static const int value = 0;
  };
  
template<typename _T0>
  struct tuple_size<tuple<_T0  , _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass> >
  {
    static const int value = 1;
  };
  
template<typename _T0, typename _T1>
  struct tuple_size<tuple<_T0, _T1  , _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass> >
  {
    static const int value = 2;
  };
  
template<typename _T0, typename _T1, typename _T2>
  struct tuple_size<tuple<_T0, _T1, _T2  , _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass> >
  {
    static const int value = 3;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3>
  struct tuple_size<tuple<_T0, _T1, _T2, _T3  , _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass> >
  {
    static const int value = 4;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4>
  struct tuple_size<tuple<_T0, _T1, _T2, _T3, _T4  , _NullClass, _NullClass, _NullClass, _NullClass, _NullClass> >
  {
    static const int value = 5;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5>
  struct tuple_size<tuple<_T0, _T1, _T2, _T3, _T4, _T5  , _NullClass, _NullClass, _NullClass, _NullClass> >
  {
    static const int value = 6;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6>
  struct tuple_size<tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6  , _NullClass, _NullClass, _NullClass> >
  {
    static const int value = 7;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7>
  struct tuple_size<tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7  , _NullClass, _NullClass> >
  {
    static const int value = 8;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8>
  struct tuple_size<tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8  , _NullClass> >
  {
    static const int value = 9;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9>
  struct tuple_size<tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9  > >
  {
    static const int value = 10;
  };
  
struct tuple<_NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass>
{
  public:
  tuple()
  { }
  
  tuple(const tuple& __in)
  { }
  
  tuple& operator=(const tuple& __in)
  {
    return *this;
  }
};

template<typename _T0>
  struct tuple<_T0,   _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass>
  {
    _T0 __t0;
    public:
    tuple()
    { }
    
    explicit tuple(typename __add_ref<_T0>::type __in0):
    __t0(__in0)
    { }
    
    tuple(const tuple& __in):
    __t0(__in.__t0)
    { }
    template <typename _U0>
    tuple(const tuple<_U0>& __in):
    __t0(__in.__t0)
    { }
    
    tuple& operator=(const tuple& __in)
    {
      __t0=__in.__t0;
      return *this;
    }
    
    template <typename _U0>
    tuple&
    operator=(const tuple<_U0>& __in)
    {
      __t0=__in.__t0;
      return *this;
    }
  };
  
template<typename _T0, typename _T1>
  struct tuple<_T0, _T1,   _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass>
  {
    _T0 __t0;
    _T1 __t1;
    public:
    tuple()
    { }
    
    explicit tuple(typename __add_ref<_T0>::type __in0, typename __add_ref<_T1>::type __in1):
    __t0(__in0), __t1(__in1)
    { }
    
    tuple(const tuple& __in):
    __t0(__in.__t0), __t1(__in.__t1)
    { }
    template <typename _U0, typename _U1>
    tuple(const tuple<_U0, _U1>& __in):
    __t0(__in.__t0), __t1(__in.__t1)
    { }
    
    template<class _U1, class _U2>
      tuple(const std::pair<_U1, _U2>& __u): __t0(__u.first), __t1(__u.second)
      { }
    
    tuple& operator=(const tuple& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      return *this;
    }
    
    template <typename _U0, typename _U1>
    tuple&
    operator=(const tuple<_U0, _U1>& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      return *this;
    }
  };
  
template<typename _T0, typename _T1, typename _T2>
  struct tuple<_T0, _T1, _T2,   _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass>
  {
    _T0 __t0;
    _T1 __t1;
    _T2 __t2;
    public:
    tuple()
    { }
    
    explicit tuple(typename __add_ref<_T0>::type __in0, typename __add_ref<_T1>::type __in1, typename __add_ref<_T2>::type __in2):
    __t0(__in0), __t1(__in1), __t2(__in2)
    { }
    
    tuple(const tuple& __in):
    __t0(__in.__t0), __t1(__in.__t1), __t2(__in.__t2)
    { }
    template <typename _U0, typename _U1, typename _U2>
    tuple(const tuple<_U0, _U1, _U2>& __in):
    __t0(__in.__t0), __t1(__in.__t1), __t2(__in.__t2)
    { }
    
    tuple& operator=(const tuple& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      __t2=__in.__t2;
      return *this;
    }
    
    template <typename _U0, typename _U1, typename _U2>
    tuple&
    operator=(const tuple<_U0, _U1, _U2>& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      __t2=__in.__t2;
      return *this;
    }
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3>
  struct tuple<_T0, _T1, _T2, _T3,   _NullClass, _NullClass, _NullClass, _NullClass, _NullClass, _NullClass>
  {
    _T0 __t0;
    _T1 __t1;
    _T2 __t2;
    _T3 __t3;
    public:
    tuple()
    { }
    
    explicit tuple(typename __add_ref<_T0>::type __in0, typename __add_ref<_T1>::type __in1, typename __add_ref<_T2>::type __in2, typename __add_ref<_T3>::type __in3):
    __t0(__in0), __t1(__in1), __t2(__in2), __t3(__in3)
    { }
    
    tuple(const tuple& __in):
    __t0(__in.__t0), __t1(__in.__t1), __t2(__in.__t2), __t3(__in.__t3)
    { }
    template <typename _U0, typename _U1, typename _U2, typename _U3>
    tuple(const tuple<_U0, _U1, _U2, _U3>& __in):
    __t0(__in.__t0), __t1(__in.__t1), __t2(__in.__t2), __t3(__in.__t3)
    { }
    
    tuple& operator=(const tuple& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      __t2=__in.__t2;
      __t3=__in.__t3;
      return *this;
    }
    
    template <typename _U0, typename _U1, typename _U2, typename _U3>
    tuple&
    operator=(const tuple<_U0, _U1, _U2, _U3>& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      __t2=__in.__t2;
      __t3=__in.__t3;
      return *this;
    }
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4>
  struct tuple<_T0, _T1, _T2, _T3, _T4,   _NullClass, _NullClass, _NullClass, _NullClass, _NullClass>
  {
    _T0 __t0;
    _T1 __t1;
    _T2 __t2;
    _T3 __t3;
    _T4 __t4;
    public:
    tuple()
    { }
    
    explicit tuple(typename __add_ref<_T0>::type __in0, typename __add_ref<_T1>::type __in1, typename __add_ref<_T2>::type __in2, typename __add_ref<_T3>::type __in3, typename __add_ref<_T4>::type __in4):
    __t0(__in0), __t1(__in1), __t2(__in2), __t3(__in3), __t4(__in4)
    { }
    
    tuple(const tuple& __in):
    __t0(__in.__t0), __t1(__in.__t1), __t2(__in.__t2), __t3(__in.__t3), __t4(__in.__t4)
    { }
    template <typename _U0, typename _U1, typename _U2, typename _U3, typename _U4>
    tuple(const tuple<_U0, _U1, _U2, _U3, _U4>& __in):
    __t0(__in.__t0), __t1(__in.__t1), __t2(__in.__t2), __t3(__in.__t3), __t4(__in.__t4)
    { }
    
    tuple& operator=(const tuple& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      __t2=__in.__t2;
      __t3=__in.__t3;
      __t4=__in.__t4;
      return *this;
    }
    
    template <typename _U0, typename _U1, typename _U2, typename _U3, typename _U4>
    tuple&
    operator=(const tuple<_U0, _U1, _U2, _U3, _U4>& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      __t2=__in.__t2;
      __t3=__in.__t3;
      __t4=__in.__t4;
      return *this;
    }
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5>
  struct tuple<_T0, _T1, _T2, _T3, _T4, _T5,   _NullClass, _NullClass, _NullClass, _NullClass>
  {
    _T0 __t0;
    _T1 __t1;
    _T2 __t2;
    _T3 __t3;
    _T4 __t4;
    _T5 __t5;
    public:
    tuple()
    { }
    
    explicit tuple(typename __add_ref<_T0>::type __in0, typename __add_ref<_T1>::type __in1, typename __add_ref<_T2>::type __in2, typename __add_ref<_T3>::type __in3, typename __add_ref<_T4>::type __in4, typename __add_ref<_T5>::type __in5):
    __t0(__in0), __t1(__in1), __t2(__in2), __t3(__in3), __t4(__in4), __t5(__in5)
    { }
    
    tuple(const tuple& __in):
    __t0(__in.__t0), __t1(__in.__t1), __t2(__in.__t2), __t3(__in.__t3), __t4(__in.__t4), __t5(__in.__t5)
    { }
    template <typename _U0, typename _U1, typename _U2, typename _U3, typename _U4, typename _U5>
    tuple(const tuple<_U0, _U1, _U2, _U3, _U4, _U5>& __in):
    __t0(__in.__t0), __t1(__in.__t1), __t2(__in.__t2), __t3(__in.__t3), __t4(__in.__t4), __t5(__in.__t5)
    { }
    
    tuple& operator=(const tuple& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      __t2=__in.__t2;
      __t3=__in.__t3;
      __t4=__in.__t4;
      __t5=__in.__t5;
      return *this;
    }
    
    template <typename _U0, typename _U1, typename _U2, typename _U3, typename _U4, typename _U5>
    tuple&
    operator=(const tuple<_U0, _U1, _U2, _U3, _U4, _U5>& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      __t2=__in.__t2;
      __t3=__in.__t3;
      __t4=__in.__t4;
      __t5=__in.__t5;
      return *this;
    }
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6>
  struct tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6,   _NullClass, _NullClass, _NullClass>
  {
    _T0 __t0;
    _T1 __t1;
    _T2 __t2;
    _T3 __t3;
    _T4 __t4;
    _T5 __t5;
    _T6 __t6;
    public:
    tuple()
    { }
    
    explicit tuple(typename __add_ref<_T0>::type __in0, typename __add_ref<_T1>::type __in1, typename __add_ref<_T2>::type __in2, typename __add_ref<_T3>::type __in3, typename __add_ref<_T4>::type __in4, typename __add_ref<_T5>::type __in5, typename __add_ref<_T6>::type __in6):
    __t0(__in0), __t1(__in1), __t2(__in2), __t3(__in3), __t4(__in4), __t5(__in5), __t6(__in6)
    { }
    
    tuple(const tuple& __in):
    __t0(__in.__t0), __t1(__in.__t1), __t2(__in.__t2), __t3(__in.__t3), __t4(__in.__t4), __t5(__in.__t5), __t6(__in.__t6)
    { }
    template <typename _U0, typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6>
    tuple(const tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6>& __in):
    __t0(__in.__t0), __t1(__in.__t1), __t2(__in.__t2), __t3(__in.__t3), __t4(__in.__t4), __t5(__in.__t5), __t6(__in.__t6)
    { }
    
    tuple& operator=(const tuple& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      __t2=__in.__t2;
      __t3=__in.__t3;
      __t4=__in.__t4;
      __t5=__in.__t5;
      __t6=__in.__t6;
      return *this;
    }
    
    template <typename _U0, typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6>
    tuple&
    operator=(const tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6>& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      __t2=__in.__t2;
      __t3=__in.__t3;
      __t4=__in.__t4;
      __t5=__in.__t5;
      __t6=__in.__t6;
      return *this;
    }
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7>
  struct tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7,   _NullClass, _NullClass>
  {
    _T0 __t0;
    _T1 __t1;
    _T2 __t2;
    _T3 __t3;
    _T4 __t4;
    _T5 __t5;
    _T6 __t6;
    _T7 __t7;
    public:
    tuple()
    { }
    
    explicit tuple(typename __add_ref<_T0>::type __in0, typename __add_ref<_T1>::type __in1, typename __add_ref<_T2>::type __in2, typename __add_ref<_T3>::type __in3, typename __add_ref<_T4>::type __in4, typename __add_ref<_T5>::type __in5, typename __add_ref<_T6>::type __in6, typename __add_ref<_T7>::type __in7):
    __t0(__in0), __t1(__in1), __t2(__in2), __t3(__in3), __t4(__in4), __t5(__in5), __t6(__in6), __t7(__in7)
    { }
    
    tuple(const tuple& __in):
    __t0(__in.__t0), __t1(__in.__t1), __t2(__in.__t2), __t3(__in.__t3), __t4(__in.__t4), __t5(__in.__t5), __t6(__in.__t6), __t7(__in.__t7)
    { }
    template <typename _U0, typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7>
    tuple(const tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7>& __in):
    __t0(__in.__t0), __t1(__in.__t1), __t2(__in.__t2), __t3(__in.__t3), __t4(__in.__t4), __t5(__in.__t5), __t6(__in.__t6), __t7(__in.__t7)
    { }
    
    tuple& operator=(const tuple& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      __t2=__in.__t2;
      __t3=__in.__t3;
      __t4=__in.__t4;
      __t5=__in.__t5;
      __t6=__in.__t6;
      __t7=__in.__t7;
      return *this;
    }
    
    template <typename _U0, typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7>
    tuple&
    operator=(const tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7>& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      __t2=__in.__t2;
      __t3=__in.__t3;
      __t4=__in.__t4;
      __t5=__in.__t5;
      __t6=__in.__t6;
      __t7=__in.__t7;
      return *this;
    }
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8>
  struct tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8,   _NullClass>
  {
    _T0 __t0;
    _T1 __t1;
    _T2 __t2;
    _T3 __t3;
    _T4 __t4;
    _T5 __t5;
    _T6 __t6;
    _T7 __t7;
    _T8 __t8;
    public:
    tuple()
    { }
    
    explicit tuple(typename __add_ref<_T0>::type __in0, typename __add_ref<_T1>::type __in1, typename __add_ref<_T2>::type __in2, typename __add_ref<_T3>::type __in3, typename __add_ref<_T4>::type __in4, typename __add_ref<_T5>::type __in5, typename __add_ref<_T6>::type __in6, typename __add_ref<_T7>::type __in7, typename __add_ref<_T8>::type __in8):
    __t0(__in0), __t1(__in1), __t2(__in2), __t3(__in3), __t4(__in4), __t5(__in5), __t6(__in6), __t7(__in7), __t8(__in8)
    { }
    
    tuple(const tuple& __in):
    __t0(__in.__t0), __t1(__in.__t1), __t2(__in.__t2), __t3(__in.__t3), __t4(__in.__t4), __t5(__in.__t5), __t6(__in.__t6), __t7(__in.__t7), __t8(__in.__t8)
    { }
    template <typename _U0, typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7, typename _U8>
    tuple(const tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8>& __in):
    __t0(__in.__t0), __t1(__in.__t1), __t2(__in.__t2), __t3(__in.__t3), __t4(__in.__t4), __t5(__in.__t5), __t6(__in.__t6), __t7(__in.__t7), __t8(__in.__t8)
    { }
    
    tuple& operator=(const tuple& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      __t2=__in.__t2;
      __t3=__in.__t3;
      __t4=__in.__t4;
      __t5=__in.__t5;
      __t6=__in.__t6;
      __t7=__in.__t7;
      __t8=__in.__t8;
      return *this;
    }
    
    template <typename _U0, typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7, typename _U8>
    tuple&
    operator=(const tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8>& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      __t2=__in.__t2;
      __t3=__in.__t3;
      __t4=__in.__t4;
      __t5=__in.__t5;
      __t6=__in.__t6;
      __t7=__in.__t7;
      __t8=__in.__t8;
      return *this;
    }
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9>
  struct tuple
  {
    _T0 __t0;
    _T1 __t1;
    _T2 __t2;
    _T3 __t3;
    _T4 __t4;
    _T5 __t5;
    _T6 __t6;
    _T7 __t7;
    _T8 __t8;
    _T9 __t9;
    public:
    tuple()
    { }
    
    explicit tuple(typename __add_ref<_T0>::type __in0, typename __add_ref<_T1>::type __in1, typename __add_ref<_T2>::type __in2, typename __add_ref<_T3>::type __in3, typename __add_ref<_T4>::type __in4, typename __add_ref<_T5>::type __in5, typename __add_ref<_T6>::type __in6, typename __add_ref<_T7>::type __in7, typename __add_ref<_T8>::type __in8, typename __add_ref<_T9>::type __in9):
    __t0(__in0), __t1(__in1), __t2(__in2), __t3(__in3), __t4(__in4), __t5(__in5), __t6(__in6), __t7(__in7), __t8(__in8), __t9(__in9)
    { }
    
    tuple(const tuple& __in):
    __t0(__in.__t0), __t1(__in.__t1), __t2(__in.__t2), __t3(__in.__t3), __t4(__in.__t4), __t5(__in.__t5), __t6(__in.__t6), __t7(__in.__t7), __t8(__in.__t8), __t9(__in.__t9)
    { }
    template <typename _U0, typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7, typename _U8, typename _U9>
    tuple(const tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9>& __in):
    __t0(__in.__t0), __t1(__in.__t1), __t2(__in.__t2), __t3(__in.__t3), __t4(__in.__t4), __t5(__in.__t5), __t6(__in.__t6), __t7(__in.__t7), __t8(__in.__t8), __t9(__in.__t9)
    { }
    
    tuple& operator=(const tuple& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      __t2=__in.__t2;
      __t3=__in.__t3;
      __t4=__in.__t4;
      __t5=__in.__t5;
      __t6=__in.__t6;
      __t7=__in.__t7;
      __t8=__in.__t8;
      __t9=__in.__t9;
      return *this;
    }
    
    template <typename _U0, typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7, typename _U8, typename _U9>
    tuple&
    operator=(const tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9>& __in)
    {
      __t0=__in.__t0;
      __t1=__in.__t1;
      __t2=__in.__t2;
      __t3=__in.__t3;
      __t4=__in.__t4;
      __t5=__in.__t5;
      __t6=__in.__t6;
      __t7=__in.__t7;
      __t8=__in.__t8;
      __t9=__in.__t9;
      return *this;
    }
  };
  
template<int __i,typename _T>
struct __tuple_value;

template<typename _T>
  struct __tuple_value<0,_T>
  {
    static typename tuple_element<0,_T>::type
    get_value(_T& __in)
    {
      return __in.__t0;
    }
    static typename tuple_element<0,_T>::type
    get_value(const _T& __in)
    {
      return __in.__t0;
    }
  };
  
template<typename _T>
  struct __tuple_value<1,_T>
  {
    static typename tuple_element<1,_T>::type
    get_value(_T& __in)
    {
      return __in.__t1;
    }
    static typename tuple_element<1,_T>::type
    get_value(const _T& __in)
    {
      return __in.__t1;
    }
  };
  
template<typename _T>
  struct __tuple_value<2,_T>
  {
    static typename tuple_element<2,_T>::type
    get_value(_T& __in)
    {
      return __in.__t2;
    }
    static typename tuple_element<2,_T>::type
    get_value(const _T& __in)
    {
      return __in.__t2;
    }
  };
  
template<typename _T>
  struct __tuple_value<3,_T>
  {
    static typename tuple_element<3,_T>::type
    get_value(_T& __in)
    {
      return __in.__t3;
    }
    static typename tuple_element<3,_T>::type
    get_value(const _T& __in)
    {
      return __in.__t3;
    }
  };
  
template<typename _T>
  struct __tuple_value<4,_T>
  {
    static typename tuple_element<4,_T>::type
    get_value(_T& __in)
    {
      return __in.__t4;
    }
    static typename tuple_element<4,_T>::type
    get_value(const _T& __in)
    {
      return __in.__t4;
    }
  };
  
template<typename _T>
  struct __tuple_value<5,_T>
  {
    static typename tuple_element<5,_T>::type
    get_value(_T& __in)
    {
      return __in.__t5;
    }
    static typename tuple_element<5,_T>::type
    get_value(const _T& __in)
    {
      return __in.__t5;
    }
  };
  
template<typename _T>
  struct __tuple_value<6,_T>
  {
    static typename tuple_element<6,_T>::type
    get_value(_T& __in)
    {
      return __in.__t6;
    }
    static typename tuple_element<6,_T>::type
    get_value(const _T& __in)
    {
      return __in.__t6;
    }
  };
  
template<typename _T>
  struct __tuple_value<7,_T>
  {
    static typename tuple_element<7,_T>::type
    get_value(_T& __in)
    {
      return __in.__t7;
    }
    static typename tuple_element<7,_T>::type
    get_value(const _T& __in)
    {
      return __in.__t7;
    }
  };
  
template<typename _T>
  struct __tuple_value<8,_T>
  {
    static typename tuple_element<8,_T>::type
    get_value(_T& __in)
    {
      return __in.__t8;
    }
    static typename tuple_element<8,_T>::type
    get_value(const _T& __in)
    {
      return __in.__t8;
    }
  };
  
template<typename _T>
  struct __tuple_value<9,_T>
  {
    static typename tuple_element<9,_T>::type
    get_value(_T& __in)
    {
      return __in.__t9;
    }
    static typename tuple_element<9,_T>::type
    get_value(const _T& __in)
    {
      return __in.__t9;
    }
  };
  
template<int __i, typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9>
typename tuple_element<__i,tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> >::type
get(tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>& __t)
{
  return __tuple_value<__i,tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> >::get_value(__t);
}
template<int __i, typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9>
typename tuple_element<__i,tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> >::type
get(const tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>& __t)
{
  return __tuple_value<__i,tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> >::get_value(__t);
}
template<int __check_equal_size, int __i, int __j, typename _T, typename _U>
  struct __tuple_compare;

template<int __i, int __j, typename _T, typename _U>
  struct __tuple_compare<0, __i, __j, _T, _U>
  {
    static bool __eq(const _T& __t, const _U& __u)
    {
      return get<__i>(__t) == get<__i>(__u) && __tuple_compare<0, __i+1, __j, _T, _U>::__eq(__t, __u) ;
    }
    static bool __neq(const _T& __t, const _U& __u)
    {
      return get<__i>(__t) != get<__i>(__u) || __tuple_compare<0, __i+1, __j, _T, _U>::__neq(__t, __u) ;
    }
    static bool __less(const _T& __t, const _U& __u)
    {
      return (get<__i>(__t) < get<__i>(__u)) || !(get<__i>(__u) < get<__i>(__t)) && __tuple_compare<0, __i+1, __j, _T, _U>::__less(__t, __u) ;
    }
    static bool __greater(const _T& __t, const _U& __u)
    {
      return (get<__i>(__t) > get<__i>(__u)) || !(get<__i>(__u) > get<__i>(__t)) && __tuple_compare<0, __i+1, __j, _T, _U>::__greater(__t, __u) ;
    }
    static bool __leq(const _T& __t, const _U& __u)
    {
      return (get<__i>(__t) <= get<__i>(__u)) && (!(get<__i>(__u)<=get<__i>(__t)) || __tuple_compare<0, __i+1, __j, _T, _U>::__leq(__t, __u) );
    }
    static bool __geq(const _T& __t, const _U& __u)
    {
      return (get<__i>(__t) >= get<__i>(__u)) && (!(get<__i>(__u)>=get<__i>(__t)) || __tuple_compare<0, __i+1, __j, _T, _U>::__geq(__t, __u) );
    }
  };
  
template<int __i, typename _T, typename _U>
struct __tuple_compare<0, __i, __i, _T, _U>
{
  static bool __eq(const _T&, const _U&)
  {
    return true;
  }
  static bool __neq(const _T&, const _U&)
  {
    return false;
  }
  static bool __leq(const _T&, const _U&)
  {
    return true;
  }
  static bool __geq(const _T&, const _U&)
  {
    return true;
  }
  static bool __less(const _T&, const _U&)
  {
    return false;
  }
  static bool __greater(const _T&, const _U&)
  {
    return false;
  }
};

template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _U0, typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7, typename _U8, typename _U9>
bool operator==(const tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>& __t, const tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9>& __u)
{
  typedef tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> __T_tuple;
  typedef tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9> __U_tuple;
  return __tuple_compare<tuple_size<__T_tuple>::value-tuple_size<__U_tuple>::value, 0, tuple_size<__T_tuple>::value, __T_tuple, __U_tuple>::__eq(__t, __u);}
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _U0, typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7, typename _U8, typename _U9>
bool operator!=(const tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>& __t, const tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9>& __u)
{
  typedef tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> __T_tuple;
  typedef tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9> __U_tuple;
  return __tuple_compare<tuple_size<__T_tuple>::value-tuple_size<__U_tuple>::value, 0, tuple_size<__T_tuple>::value, __T_tuple, __U_tuple>::__neq(__t, __u);}
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _U0, typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7, typename _U8, typename _U9>
bool operator<(const tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>& __t, const tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9>& __u)
{
  typedef tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> __T_tuple;
  typedef tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9> __U_tuple;
  return __tuple_compare<tuple_size<__T_tuple>::value-tuple_size<__U_tuple>::value, 0, tuple_size<__T_tuple>::value, __T_tuple, __U_tuple>::__less(__t, __u);}
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _U0, typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7, typename _U8, typename _U9>
bool operator>(const tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>& __t, const tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9>& __u)
{
  typedef tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> __T_tuple;
  typedef tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9> __U_tuple;
  return __tuple_compare<tuple_size<__T_tuple>::value-tuple_size<__U_tuple>::value, 0, tuple_size<__T_tuple>::value, __T_tuple, __U_tuple>::__greater(__t, __u);}
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _U0, typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7, typename _U8, typename _U9>
bool operator<=(const tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>& __t, const tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9>& __u)
{
  typedef tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> __T_tuple;
  typedef tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9> __U_tuple;
  return __tuple_compare<tuple_size<__T_tuple>::value-tuple_size<__U_tuple>::value, 0, tuple_size<__T_tuple>::value, __T_tuple, __U_tuple>::__leq(__t, __u);}
template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8, typename _T9, typename _U0, typename _U1, typename _U2, typename _U3, typename _U4, typename _U5, typename _U6, typename _U7, typename _U8, typename _U9>
bool operator>=(const tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>& __t, const tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9>& __u)
{
  typedef tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9> __T_tuple;
  typedef tuple<_U0, _U1, _U2, _U3, _U4, _U5, _U6, _U7, _U8, _U9> __U_tuple;
  return __tuple_compare<tuple_size<__T_tuple>::value-tuple_size<__U_tuple>::value, 0, tuple_size<__T_tuple>::value, __T_tuple, __U_tuple>::__geq(__t, __u);}
template<typename _T>
struct __strip_reference_wrapper
{
    typedef _T __type;
};

template<typename _T>
struct __strip_reference_wrapper<reference_wrapper<_T> >
{
  typedef _T& __type;
};

template<typename _T>
struct __strip_reference_wrapper<const reference_wrapper<_T> >
{
    typedef _T& __type;
};

template<typename _T0 = _NullClass, typename _T1 = _NullClass, typename _T2 = _NullClass, typename _T3 = _NullClass, typename _T4 = _NullClass, typename _T5 = _NullClass, typename _T6 = _NullClass, typename _T7 = _NullClass, typename _T8 = _NullClass, typename _T9 = _NullClass>
struct __stripped_tuple_type
{
  typedef tuple<typename __strip_reference_wrapper<_T0>::__type, typename __strip_reference_wrapper<_T1>::__type, typename __strip_reference_wrapper<_T2>::__type, typename __strip_reference_wrapper<_T3>::__type, typename __strip_reference_wrapper<_T4>::__type, typename __strip_reference_wrapper<_T5>::__type, typename __strip_reference_wrapper<_T6>::__type, typename __strip_reference_wrapper<_T7>::__type, typename __strip_reference_wrapper<_T8>::__type, typename __strip_reference_wrapper<_T9>::__type>  __type;
};

tuple<>
make_tuple()
{
    return tuple<>();
};

template<typename _T0>
typename __stripped_tuple_type<_T0>::__type
make_tuple(_T0 __t0)
{
  return typename  __stripped_tuple_type<_T0>::  __type(__t0);};

template<typename _T0, typename _T1>
typename __stripped_tuple_type<_T0, _T1>::__type
make_tuple(_T0 __t0, _T1 __t1)
{
  return typename  __stripped_tuple_type<_T0, _T1>::  __type(__t0, __t1);};

template<typename _T0, typename _T1, typename _T2>
typename __stripped_tuple_type<_T0, _T1, _T2>::__type
make_tuple(_T0 __t0, _T1 __t1, _T2 __t2)
{
  return typename  __stripped_tuple_type<_T0, _T1, _T2>::  __type(__t0, __t1, __t2);};

template<typename _T0, typename _T1, typename _T2, typename _T3>
typename __stripped_tuple_type<_T0, _T1, _T2, _T3>::__type
make_tuple(_T0 __t0, _T1 __t1, _T2 __t2, _T3 __t3)
{
  return typename  __stripped_tuple_type<_T0, _T1, _T2, _T3>::  __type(__t0, __t1, __t2, __t3);};

template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4>
typename __stripped_tuple_type<_T0, _T1, _T2, _T3, _T4>::__type
make_tuple(_T0 __t0, _T1 __t1, _T2 __t2, _T3 __t3, _T4 __t4)
{
  return typename  __stripped_tuple_type<_T0, _T1, _T2, _T3, _T4>::  __type(__t0, __t1, __t2, __t3, __t4);};

template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5>
typename __stripped_tuple_type<_T0, _T1, _T2, _T3, _T4, _T5>::__type
make_tuple(_T0 __t0, _T1 __t1, _T2 __t2, _T3 __t3, _T4 __t4, _T5 __t5)
{
  return typename  __stripped_tuple_type<_T0, _T1, _T2, _T3, _T4, _T5>::  __type(__t0, __t1, __t2, __t3, __t4, __t5);};

template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6>
typename __stripped_tuple_type<_T0, _T1, _T2, _T3, _T4, _T5, _T6>::__type
make_tuple(_T0 __t0, _T1 __t1, _T2 __t2, _T3 __t3, _T4 __t4, _T5 __t5, _T6 __t6)
{
  return typename  __stripped_tuple_type<_T0, _T1, _T2, _T3, _T4, _T5, _T6>::  __type(__t0, __t1, __t2, __t3, __t4, __t5, __t6);};

template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7>
typename __stripped_tuple_type<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7>::__type
make_tuple(_T0 __t0, _T1 __t1, _T2 __t2, _T3 __t3, _T4 __t4, _T5 __t5, _T6 __t6, _T7 __t7)
{
  return typename  __stripped_tuple_type<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7>::  __type(__t0, __t1, __t2, __t3, __t4, __t5, __t6, __t7);};

template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8>
typename __stripped_tuple_type<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8>::__type
make_tuple(_T0 __t0, _T1 __t1, _T2 __t2, _T3 __t3, _T4 __t4, _T5 __t5, _T6 __t6, _T7 __t7, _T8 __t8)
{
  return typename  __stripped_tuple_type<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8>::  __type(__t0, __t1, __t2, __t3, __t4, __t5, __t6, __t7, __t8);};

template<typename _T0>
tuple<_T0&>
tie(_T0& __t0)
{
  return make_tuple(ref(__t0));
};

template<typename _T0, typename _T1>
tuple<_T0&, _T1&>
tie(_T0& __t0, _T1& __t1)
{
  return make_tuple(ref(__t0), ref(__t1));
};

template<typename _T0, typename _T1, typename _T2>
tuple<_T0&, _T1&, _T2&>
tie(_T0& __t0, _T1& __t1, _T2& __t2)
{
  return make_tuple(ref(__t0), ref(__t1), ref(__t2));
};

template<typename _T0, typename _T1, typename _T2, typename _T3>
tuple<_T0&, _T1&, _T2&, _T3&>
tie(_T0& __t0, _T1& __t1, _T2& __t2, _T3& __t3)
{
  return make_tuple(ref(__t0), ref(__t1), ref(__t2), ref(__t3));
};

template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4>
tuple<_T0&, _T1&, _T2&, _T3&, _T4&>
tie(_T0& __t0, _T1& __t1, _T2& __t2, _T3& __t3, _T4& __t4)
{
  return make_tuple(ref(__t0), ref(__t1), ref(__t2), ref(__t3), ref(__t4));
};

template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5>
tuple<_T0&, _T1&, _T2&, _T3&, _T4&, _T5&>
tie(_T0& __t0, _T1& __t1, _T2& __t2, _T3& __t3, _T4& __t4, _T5& __t5)
{
  return make_tuple(ref(__t0), ref(__t1), ref(__t2), ref(__t3), ref(__t4), ref(__t5));
};

template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6>
tuple<_T0&, _T1&, _T2&, _T3&, _T4&, _T5&, _T6&>
tie(_T0& __t0, _T1& __t1, _T2& __t2, _T3& __t3, _T4& __t4, _T5& __t5, _T6& __t6)
{
  return make_tuple(ref(__t0), ref(__t1), ref(__t2), ref(__t3), ref(__t4), ref(__t5), ref(__t6));
};

template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7>
tuple<_T0&, _T1&, _T2&, _T3&, _T4&, _T5&, _T6&, _T7&>
tie(_T0& __t0, _T1& __t1, _T2& __t2, _T3& __t3, _T4& __t4, _T5& __t5, _T6& __t6, _T7& __t7)
{
  return make_tuple(ref(__t0), ref(__t1), ref(__t2), ref(__t3), ref(__t4), ref(__t5), ref(__t6), ref(__t7));
};

template<typename _T0, typename _T1, typename _T2, typename _T3, typename _T4, typename _T5, typename _T6, typename _T7, typename _T8>
tuple<_T0&, _T1&, _T2&, _T3&, _T4&, _T5&, _T6&, _T7&, _T8&>
tie(_T0& __t0, _T1& __t1, _T2& __t2, _T3& __t3, _T4& __t4, _T5& __t5, _T6& __t6, _T7& __t7, _T8& __t8)
{
  return make_tuple(ref(__t0), ref(__t1), ref(__t2), ref(__t3), ref(__t4), ref(__t5), ref(__t6), ref(__t7), ref(__t8));
};


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]