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]

Tuple: mark 2


OK, here is a submission I'm (reasonably) happy with to get started with of the tuple header.

Files attached:
maketuples.c
tuple, which is generated by running maketuples.c
assignment.cc, big_tuples.cc, comparisons.cc, constructor.cc, get.cc, make_tuple.cc, tie.cc, tuple_element.cc, tuple_size.cc : a bunch of tests for the tuple header.




The formatting still isn't perfect, but I think it's at least reasonable.

While there are a pack of positive tests, I haven't got a large set of negative tests yet (still trying to figure out this xfail business), so it's possible that there are some things allowed that should be forgiven.

One thing that I'd generally like to change is a nice way of testing the value of an expression is zero (for example two tuples are the same size). At the moment I do this with an extra template argument. I used to make a new template class defined as something like: "template<int i> struct _IsZero; struct _IsZero<0> {};" , but I'm not convinced this is perfect as it still lead to an unnessasary symbol being added.

The header tuple is generated by the file maketuple.c. By defining the symbol "SIZE", you can make different sized tuples. The tests are defined so that only one test has tuples of size larger than 3, so testing with smaller tuples only leads to one test failing. I only promise that maketuple.c works down to tuples of size 2, but I can't imagine why anyone would want to make smaller tuples!

Things to be done:

1) At the moment the last line is: "swallow_assign ignore;". This variable actually needs to be defined in the library, not in the header. At the moment you won't be able to use this header in more than one file and link it together (although obviously fixing that is easy).

2) The formatting is at least passable, but could be better

3) Was there a final decision that uglification can be removed?

4) I know some changes were made at the recent meeting. Once I get those I'll make the changes (in particular I've been told the comparison operators were changed, which is why the tests don't test if the implementation uses exactly the right operators, as they are changing). Once I get hold of the updates, I'll implement them!

5) No failing tests yet. There are a bunch that should probably be here.

Chris
// 2004-09-23 Chris Jefferson <chris@bubblescope.net>

// Copyright (C) 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// Tuple

#include<stdio.h>

#ifndef SIZE
#define SIZE 10
#endif

// This defines how far lines should be indented
int indent = 0;
// This defines how far the last drawn line went horizontally
int horizontalpos = 0;

// Just prints out as many spaces as the current indent
void
do_indent() 
{
  int i;
  for (i = 0; i < indent; i++)
    printf(" ");
}


/* Checks to see if printing the next line will overflow the line.
 * If so, go onto the next line
 */
void
check_horizontal(int length)
{
  horizontalpos += length;
  if(horizontalpos > 79)
    {
	printf("\n");
	indent+=6;
	do_indent();
	horizontalpos = indent + length;
	indent-=6;
    }
}

char buffer[1000];


/* 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");
  horizontalpos = 0;
}

/* 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_noindent(int loop, char* start, char* body, char *end)
{
  int i = 0;
  printf(start);
  horizontalpos += strlen(start);
  for (i = 0; i < loop-1; i++)
    {
      check_horizontal(strlen(body) + 2);
      printf(body, i, i, i, i, i);
      printf(", ");
    }
  if(loop != 0)
    {
      check_horizontal(strlen(body) + 2);
      printf(body, loop-1, loop-1, loop-1, loop-1, loop-1, loop-1);
    }
  check_horizontal(strlen(end));
  printf(end);
  if(strlen(end) != 0 && end[strlen(end)-1] == '\n')
    horizontalpos = 0;
}

void 
loopprint(int loop, char* start, char* body, char *end)
{
  do_indent();
  horizontalpos = indent;
  loopprint_noindent(loop, start, body, 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("");
}

//Now the functions that generate the various parts of the header
void
print_copyright()
{
  line("// 2004-09-23 Chris Jefferson <chris@bubblescope.net>");
  line("// This header is automatically generated.");
  line("// See maketuple.c for details");
  line("");
  line("// Copyright (C) 2004 Free Software Foundation, Inc.");
  line("//");
  line("// This file is part of the GNU ISO C++ Library.  This library is free");
  line("// software; you can redistribute it and/or modify it under the");
  line("// terms of the GNU General Public License as published by the");
  line("// Free Software Foundation; either version 2, or (at your option)");
  line("// any later version.");
  line("");
  line("// This library is distributed in the hope that it will be useful,");
  line("// but WITHOUT ANY WARRANTY; without even the implied warranty of");
  line("// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the");
  line("// GNU General Public License for more details.");
  line("");
  line("// You should have received a copy of the GNU General Public License along");
  line("// with this library; see the file COPYING.  If not, write to the Free");
  line("// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,");
  line("// USA.");
  line("");
  line("// Tuple");

}

void 
reference_wrapper() 
{
  line("/* reference_wrapper provides a way to annotate that a reference");
  line(" * to an object should be passed");
  line(" */");
  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("// ref denotes a reference should be taken to a variable");
  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("// cref denotes a const reference should be taken to a variable");
  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("// Adds a const reference to a non-reference type");
  line("template<typename _T>");
  indent += 2;
  line("struct __add_const_ref");
  braceopen();
  line("typedef const _T& type;");
  classclose();
  indent -= 2;

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

  line("template<typename _T>");
  indent += 2;
  line("struct __add_const_ref<const _T&>");
  braceopen();
  line("typedef const _T& type;");
  classclose();
  indent -= 2;
  line("");
  line("// adds a reference to a non-reference type");
  line("template<typename _T>");
  indent += 2;
  line("struct __add_ref");
  braceopen();
  line("typedef _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;
  line("");
}

void 
printClass(int in) 
{
  braceopen();
  looplist(in, "_T%d __t%d;");
  line("public:");
  indent += 2;
  // Blank constructor
  line("tuple()");
  line("{ }");
  line("");
  // Explicit constructor
  loopprint(in, "explicit tuple(", 
	    "typename __add_const_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();
  line("template<int __i, typename _U>");
  line("  friend class __get_helper;");
  loopprint(SIZE, "template<", "typename", ">\n");
  line("friend class tuple;");
  indent -= 2;
  classclose();
}

void tuple_classes() {
  int i;
  // Do the empty tuple class
  line("// The empty tuple");
  line("template<>");
  indent += 2;
  loopprint(SIZE, "class tuple<", "_NullClass", ">\n"); 
  braceopen();
  line("public:");
  indent += 2;
  // 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
  indent -= 2;
  classclose();
  indent -= 2;
 
  // Now do all the other classes
  for (i = 1; i <= SIZE; i++)
    {
      loopprint(i, "template<", "typename _T%d", ">\n");
      indent += 2;
      if(i != SIZE) 
	{
	  loopprint(i, "class tuple<", "_T%d", ", ");
	  loopprint_noindent(SIZE-i, "", "_NullClass", ">\n");
	}
      else 
	{
	  line("class tuple");
	}
      printClass(i);
      indent -= 2;
    }
}

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

void 
tuple_element()
{
  line("// Gives the type of the ith element of a given tuple type");
  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("// Class used in the implementation of get");
  line("template<int __i,typename _T>");
  line("struct __get_helper;\n");
  for (i = 0; i < SIZE; i++) {
    line("template<typename _T>");
    indent += 2;
    do_indent();
    printf("struct __get_helper<%d,_T>\n", i);
    braceopen();
    do_indent();
    printf("static typename __add_ref<typename tuple_element<%d,_T>::type>::type\n", i);
    line("get_value(_T& __in)");
    braceopen();
    do_indent();
    printf("return __in.__t%d;\n", i);
    braceclose();
    do_indent();
    printf("static typename __add_const_ref<typename tuple_element<%d,_T>::type>::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
  line("/* Returns a reference to the ith element of a tuple.");
  line(" * Any const or non-const ref elements are returned with their original type");
  line(" */");
  loopprint(SIZE, "template<int __i, ", "typename _T%d", ">\n");
  loopprint(SIZE, "typename __add_ref<typename tuple_element<__i,tuple<", "_T%d", "> >::type>::type\n");
  loopprint(SIZE, "get(tuple<", "_T%d", ">& __t)\n"); 
  braceopen();
  loopprint(SIZE, "return __get_helper<__i,tuple<", "_T%d", "> >::get_value(__t);\n");
  braceclose();
  line("");
  // const get
  line("/* Returns a const reference to the ith element of a tuple.");
  line(" * Any const or non-const ref elements are returned with their original type");
  line(" */");
  loopprint(SIZE, "template<int __i, ", "typename _T%d", ">\n");
  loopprint(SIZE, "typename __add_const_ref<typename tuple_element<__i,tuple<", 
	    "_T%d", "> >::type>::type\n");
  loopprint(SIZE, "get(const tuple<", "_T%d", ">& __t)\n"); 
  braceopen();
  loopprint(SIZE, "return __get_helper<__i,tuple<", "_T%d", "> >::get_value(__t);\n");
  braceclose();
  line("");
}

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\n", before_recurse);
  do_indent();
  printf(" __tuple_compare<0, __i+1, __j, _T, _U>" 
	 "::__%s(__t, __u) %s;\n", 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("// This class helps construct the various comparison operations on tuples");
  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_noindent(SIZE, "", "typename _U%d", ">\n");
  line("bool");
  sprintf(buffer, "operator%s(const tuple<",op);
  loopprint(SIZE,buffer, "_T%d", ">& __t, ");
  loopprint_noindent(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 -\n  tuple_size<__U_tuple>::value, 0,\n   tuple_size<__T_tuple>::value, __T_tuple, __U_tuple>::__%s(__t, __u);\n",text_op_name);
  indent -= 2;
  line("}");
  line("");
}

void 
strip_reference_wrapper() 
{
  line("// Helper which adds a reference to a type when given a 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;
  line("/* A class (and instance) which can be used in 'tie' when a");
  line(" * element is not required");
  line(" */");
  line("");
  line("struct swallow_assign");
  braceopen();
  line("template <class T>");
  line("swallow_assign&");
  line("operator=(const T&)");
  braceopen();
  line("return *this;");
  braceclose();  
  classclose();
  line("extern swallow_assign ignore;");
  line("");
  line("// tie allows forms a tuple of references to a list of variables"); 
  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("// Various functions which give std::pair a tuple-like interface");
  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) 
{
  print_copyright();
  line("#include<utility>");
  line("namespace std");
  line("{");
  line("namespace tr1");
  line("{");
  // This is just a helper object
  line("/* An implementation specific class which is used in the tuple");
  line(" * class when the tuple is not maximum possible size");
  line(" */");
  line("struct _NullClass");
  line("{ };");
  line("");
  

  // Forward definition of tuple class
  line("// Foward definition of the tuple class");
  loopprint(SIZE, "template<", "typename _T%d=_NullClass", ">\n");
  indent += 2;
  line("class tuple;");
  indent -= 2;
  line("");

  tuple_element();
  tuple_size();
  add_reference(); //Note: internal class!
  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");
  reference_wrapper();  
  strip_reference_wrapper(); //Note: this is a helper class for make_tuple
  make_tuple();
  make_tie();
  pair_things();
  line("");
  line("// TODO: Put this in some kind of shared file");
  line("swallow_assign ignore;");
  line("}");
  line("}");


  return 0;
}
// 2004-09-23 Chris Jefferson <chris@bubblescope.net>
// This header is automatically generated.
// See maketuple.c for details

// Copyright (C) 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// Tuple
#include<utility>
namespace std
{
namespace tr1
{
/* An implementation specific class which is used in the tuple
 * class when the tuple is not maximum possible size
 */
struct _NullClass
{ };

// Foward definition of the tuple class
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>
  class tuple;

// Gives the type of the ith element of a given tuple type
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;
  };
  
// Finds the size of a given tuple type
template<typename _T>
  struct tuple_size;

template<>
  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;
  };
  
// Adds a const reference to a non-reference type
template<typename _T>
  struct __add_const_ref
  {
    typedef const _T& type;
  };
  
template<typename _T>
  struct __add_const_ref<_T&>
  {
    typedef _T& type;
  };
  
template<typename _T>
  struct __add_const_ref<const _T&>
  {
    typedef const _T& type;
  };
  

// adds a reference to a non-reference type
template<typename _T>
  struct __add_ref
  {
    typedef _T& type;
  };
  
template<typename _T>
  struct __add_ref<_T&>
  {
    typedef _T& type;
  };
  
template<typename _T>
  struct __add_ref<const _T&>
  {
    typedef const _T& type;
  };
  

// The empty tuple
template<>
  class 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>
  class tuple<_T0, _NullClass, _NullClass, _NullClass, _NullClass, 
        _NullClass, _NullClass, _NullClass, _NullClass, _NullClass>
  {
    _T0 __t0;
    public:
      tuple()
      { }
      
      explicit tuple(typename __add_const_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<int __i, typename _U>
        friend class __get_helper;
      template<typename, typename, typename, typename, typename, typename, 
            typename, typename, typename, typename>
      friend class tuple;
  };
  
template<typename _T0, typename _T1>
  class tuple<_T0, _T1, _NullClass, _NullClass, _NullClass, _NullClass, 
        _NullClass, _NullClass, _NullClass, _NullClass>
  {
    _T0 __t0;
    _T1 __t1;
    public:
      tuple()
      { }
      
      explicit tuple(typename __add_const_ref<_T0>::type __in0, 
            typename __add_const_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<int __i, typename _U>
        friend class __get_helper;
      template<typename, typename, typename, typename, typename, typename, 
            typename, typename, typename, typename>
      friend class tuple;
  };
  
template<typename _T0, typename _T1, typename _T2>
  class tuple<_T0, _T1, _T2, _NullClass, _NullClass, _NullClass, 
        _NullClass, _NullClass, _NullClass, _NullClass>
  {
    _T0 __t0;
    _T1 __t1;
    _T2 __t2;
    public:
      tuple()
      { }
      
      explicit tuple(typename __add_const_ref<_T0>::type __in0, 
            typename __add_const_ref<_T1>::type __in1, 
            typename __add_const_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<int __i, typename _U>
        friend class __get_helper;
      template<typename, typename, typename, typename, typename, typename, 
            typename, typename, typename, typename>
      friend class tuple;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3>
  class 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_const_ref<_T0>::type __in0, 
            typename __add_const_ref<_T1>::type __in1, 
            typename __add_const_ref<_T2>::type __in2, 
            typename __add_const_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<int __i, typename _U>
        friend class __get_helper;
      template<typename, typename, typename, typename, typename, typename, 
            typename, typename, typename, typename>
      friend class tuple;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, 
      typename _T4>
  class 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_const_ref<_T0>::type __in0, 
            typename __add_const_ref<_T1>::type __in1, 
            typename __add_const_ref<_T2>::type __in2, 
            typename __add_const_ref<_T3>::type __in3, 
            typename __add_const_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<int __i, typename _U>
        friend class __get_helper;
      template<typename, typename, typename, typename, typename, typename, 
            typename, typename, typename, typename>
      friend class tuple;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, 
      typename _T4, typename _T5>
  class 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_const_ref<_T0>::type __in0, 
            typename __add_const_ref<_T1>::type __in1, 
            typename __add_const_ref<_T2>::type __in2, 
            typename __add_const_ref<_T3>::type __in3, 
            typename __add_const_ref<_T4>::type __in4, 
            typename __add_const_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<int __i, typename _U>
        friend class __get_helper;
      template<typename, typename, typename, typename, typename, typename, 
            typename, typename, typename, typename>
      friend class tuple;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, 
      typename _T4, typename _T5, typename _T6>
  class 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_const_ref<_T0>::type __in0, 
            typename __add_const_ref<_T1>::type __in1, 
            typename __add_const_ref<_T2>::type __in2, 
            typename __add_const_ref<_T3>::type __in3, 
            typename __add_const_ref<_T4>::type __in4, 
            typename __add_const_ref<_T5>::type __in5, 
            typename __add_const_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<int __i, typename _U>
        friend class __get_helper;
      template<typename, typename, typename, typename, typename, typename, 
            typename, typename, typename, typename>
      friend class tuple;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, 
      typename _T4, typename _T5, typename _T6, typename _T7>
  class 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_const_ref<_T0>::type __in0, 
            typename __add_const_ref<_T1>::type __in1, 
            typename __add_const_ref<_T2>::type __in2, 
            typename __add_const_ref<_T3>::type __in3, 
            typename __add_const_ref<_T4>::type __in4, 
            typename __add_const_ref<_T5>::type __in5, 
            typename __add_const_ref<_T6>::type __in6, 
            typename __add_const_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<int __i, typename _U>
        friend class __get_helper;
      template<typename, typename, typename, typename, typename, typename, 
            typename, typename, typename, typename>
      friend class tuple;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, 
      typename _T4, typename _T5, typename _T6, typename _T7, 
      typename _T8>
  class 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_const_ref<_T0>::type __in0, 
            typename __add_const_ref<_T1>::type __in1, 
            typename __add_const_ref<_T2>::type __in2, 
            typename __add_const_ref<_T3>::type __in3, 
            typename __add_const_ref<_T4>::type __in4, 
            typename __add_const_ref<_T5>::type __in5, 
            typename __add_const_ref<_T6>::type __in6, 
            typename __add_const_ref<_T7>::type __in7, 
            typename __add_const_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<int __i, typename _U>
        friend class __get_helper;
      template<typename, typename, typename, typename, typename, typename, 
            typename, typename, typename, typename>
      friend class tuple;
  };
  
template<typename _T0, typename _T1, typename _T2, typename _T3, 
      typename _T4, typename _T5, typename _T6, typename _T7, 
      typename _T8, typename _T9>
  class 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_const_ref<_T0>::type __in0, 
            typename __add_const_ref<_T1>::type __in1, 
            typename __add_const_ref<_T2>::type __in2, 
            typename __add_const_ref<_T3>::type __in3, 
            typename __add_const_ref<_T4>::type __in4, 
            typename __add_const_ref<_T5>::type __in5, 
            typename __add_const_ref<_T6>::type __in6, 
            typename __add_const_ref<_T7>::type __in7, 
            typename __add_const_ref<_T8>::type __in8, 
            typename __add_const_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 _U>
        friend class __get_helper;
      template<typename, typename, typename, typename, typename, typename, 
            typename, typename, typename, typename>
      friend class tuple;
  };
  
// Class used in the implementation of get
template<int __i,typename _T>
struct __get_helper;

template<typename _T>
  struct __get_helper<0,_T>
  {
    static typename __add_ref<typename tuple_element<0,_T>::type>::type
    get_value(_T& __in)
    {
      return __in.__t0;
    }
    static typename __add_const_ref<typename tuple_element<0,_T>::type>::type
    get_value(const _T& __in)
    {
      return __in.__t0;
    }
  };
  
template<typename _T>
  struct __get_helper<1,_T>
  {
    static typename __add_ref<typename tuple_element<1,_T>::type>::type
    get_value(_T& __in)
    {
      return __in.__t1;
    }
    static typename __add_const_ref<typename tuple_element<1,_T>::type>::type
    get_value(const _T& __in)
    {
      return __in.__t1;
    }
  };
  
template<typename _T>
  struct __get_helper<2,_T>
  {
    static typename __add_ref<typename tuple_element<2,_T>::type>::type
    get_value(_T& __in)
    {
      return __in.__t2;
    }
    static typename __add_const_ref<typename tuple_element<2,_T>::type>::type
    get_value(const _T& __in)
    {
      return __in.__t2;
    }
  };
  
template<typename _T>
  struct __get_helper<3,_T>
  {
    static typename __add_ref<typename tuple_element<3,_T>::type>::type
    get_value(_T& __in)
    {
      return __in.__t3;
    }
    static typename __add_const_ref<typename tuple_element<3,_T>::type>::type
    get_value(const _T& __in)
    {
      return __in.__t3;
    }
  };
  
template<typename _T>
  struct __get_helper<4,_T>
  {
    static typename __add_ref<typename tuple_element<4,_T>::type>::type
    get_value(_T& __in)
    {
      return __in.__t4;
    }
    static typename __add_const_ref<typename tuple_element<4,_T>::type>::type
    get_value(const _T& __in)
    {
      return __in.__t4;
    }
  };
  
template<typename _T>
  struct __get_helper<5,_T>
  {
    static typename __add_ref<typename tuple_element<5,_T>::type>::type
    get_value(_T& __in)
    {
      return __in.__t5;
    }
    static typename __add_const_ref<typename tuple_element<5,_T>::type>::type
    get_value(const _T& __in)
    {
      return __in.__t5;
    }
  };
  
template<typename _T>
  struct __get_helper<6,_T>
  {
    static typename __add_ref<typename tuple_element<6,_T>::type>::type
    get_value(_T& __in)
    {
      return __in.__t6;
    }
    static typename __add_const_ref<typename tuple_element<6,_T>::type>::type
    get_value(const _T& __in)
    {
      return __in.__t6;
    }
  };
  
template<typename _T>
  struct __get_helper<7,_T>
  {
    static typename __add_ref<typename tuple_element<7,_T>::type>::type
    get_value(_T& __in)
    {
      return __in.__t7;
    }
    static typename __add_const_ref<typename tuple_element<7,_T>::type>::type
    get_value(const _T& __in)
    {
      return __in.__t7;
    }
  };
  
template<typename _T>
  struct __get_helper<8,_T>
  {
    static typename __add_ref<typename tuple_element<8,_T>::type>::type
    get_value(_T& __in)
    {
      return __in.__t8;
    }
    static typename __add_const_ref<typename tuple_element<8,_T>::type>::type
    get_value(const _T& __in)
    {
      return __in.__t8;
    }
  };
  
template<typename _T>
  struct __get_helper<9,_T>
  {
    static typename __add_ref<typename tuple_element<9,_T>::type>::type
    get_value(_T& __in)
    {
      return __in.__t9;
    }
    static typename __add_const_ref<typename tuple_element<9,_T>::type>::type
    get_value(const _T& __in)
    {
      return __in.__t9;
    }
  };
  
/* Returns a reference to the ith element of a tuple.
 * Any const or non-const ref elements are returned with their original type
 */
template<int __i, typename _T0, typename _T1, typename _T2, typename _T3, 
      typename _T4, typename _T5, typename _T6, typename _T7, 
      typename _T8, typename _T9>
typename __add_ref<typename tuple_element<__i,tuple<_T0, _T1, _T2, _T3, 
      _T4, _T5, _T6, _T7, _T8, _T9> >::type>::type
get(tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9>& __t)
{
  return __get_helper<__i,tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, 
        _T7, _T8, _T9> >::get_value(__t);
}

/* Returns a const reference to the ith element of a tuple.
 * Any const or non-const ref elements are returned with their original type
 */
template<int __i, typename _T0, typename _T1, typename _T2, typename _T3, 
      typename _T4, typename _T5, typename _T6, typename _T7, 
      typename _T8, typename _T9>
typename __add_const_ref<typename tuple_element<__i,tuple<_T0, _T1, _T2, 
      _T3, _T4, _T5, _T6, _T7, _T8, _T9> >::type>::type
get(const tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, _T8, _T9
      >& __t)
{
  return __get_helper<__i,tuple<_T0, _T1, _T2, _T3, _T4, _T5, _T6, 
        _T7, _T8, _T9> >::get_value(__t);
}

// This class helps construct the various comparison operations on tuples
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);
}

/* reference_wrapper provides a way to annotate that a reference
 * to an object should be passed
 */
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;
      }
  };
  
// ref denotes a reference should be taken to a variable
template<typename _T>
  reference_wrapper<_T>
  ref(_T& __t)
  {
    return reference_wrapper<_T>(__t);
  }

// cref denotes a const reference should be taken to a variable
template<typename _T>
  reference_wrapper<_T const>
  cref(const _T& __t)
  {
    return reference_wrapper<_T const>(__t);
  }

// Helper which adds a reference to a type when given a reference_wrapper
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, typename _T1, typename _T2, typename _T3, 
      typename _T4, typename _T5, typename _T6, typename _T7, 
      typename _T8, typename _T9>
typename __stripped_tuple_type<_T0, _T1, _T2, _T3, _T4, _T5, _T6, _T7, 
      _T8, _T9>::__type
make_tuple(_T0 __t0, _T1 __t1, _T2 __t2, _T3 __t3, _T4 __t4, 
      _T5 __t5, _T6 __t6, _T7 __t7, _T8 __t8, _T9 __t9)
{
  return typename  __stripped_tuple_type<_T0, _T1, _T2, _T3, _T4, _T5, 
        _T6, _T7, _T8, _T9>::  __type(__t0, __t1, __t2, __t3, __t4, __t5, __t6, __t7, __t8, __t9
        );};

/* A class (and instance) which can be used in 'tie' when a
 * element is not required
 */

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

extern swallow_assign ignore;

// tie allows forms a tuple of references to a list of variables
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));
};

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

// Various functions which give std::pair a tuple-like interface
template<class _T1, class _T2>
  struct tuple_size<std::pair<_T1, _T2> >
  {
    static const int value = 2;
  };

template<class _T1, class _T2>
  struct tuple_element<0, std::pair<_T1, _T2> >
  {
    typedef _T1 type;
  };

template<class _T1, class _T2>
  struct tuple_element<1, std::pair<_T1, _T2> >
  {
    typedef _T2 type;
  };

template<int _I,class _T1,class _T2>
  typename tuple_element<_I,tuple<_T1, _T2> >::type
  get(pair<_T1, _T2>& __in)
  {
    return get<_I>(tie(__in.first, __in.second));
  }

template<int _I,class _T1,class _T2>
  typename tuple_element<_I,tuple<_T1, _T2> >::type
  get(const pair<_T1, _T2>& __in)
  {
    return get<_I>(tie(__in.first, __in.second));
  }


// TODO: Put this in some kind of shared file
swallow_assign ignore;
}
}
// 2004-09-23 Chris Jefferson <chris@bubblescope.net>

// Copyright (C) 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// Tuple

#include <tr1/tuple>
#include <testsuite_hooks.h>

using namespace std;
using namespace tr1;

int
main()
{
  tuple<> ta;
  tuple<> tb;
  ta = tb;

  tuple<int> tc(1);
  tuple<int> td(0);
  td = tc;
  VERIFY(get<0>(td) == 1);

  int i=0;
  tuple<int&> te(i);
  te = tc;
  VERIFY(i == 1);

  tuple<const int&> tf(tc);

  get<0>(tc) = 2;
  VERIFY(get<0>(tf) == 2);
  tuple<double> tg;
  tg = tc;
}
// 2004-09-23 Chris Jefferson <chris@bubblescope.net>

// Copyright (C) 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// Tuple

#include <tr1/tuple>
#include <testsuite_hooks.h>

using namespace std;
using namespace tr1;

// A simple class without conversions to check some things
struct foo
{ };

void
test_constructors()
{
  int x1=0,x2=0;
  const int &z1=x1;

  // Test empty constructor
  tuple<> ta;
  tuple<int,int> tb;
  // Test construction from values
  tuple<int,int> tc(x1,x2);
  tuple<int,int&> td(x1,x2);
  tuple<const int&> te(z1);
  x1=1;
  x2=1;
  VERIFY(get<0>(td) == 0 && get<1>(td) == 1 && get<0>(te) == 1);

  // Test identical tuple copy constructor
  tuple<int,int> tf(tc);
  tuple<int,int> tg(td);
  tuple<const int&> th(te);
  // Test different tuple copy constructor
  tuple<int,double> ti(tc);
  tuple<int,double> tj(td);
  // Test constructing from a pair
  pair<int,int> pair1(1,1);
  const pair<int,int> pair2(pair1);
  tuple<int,int> tl(pair1);
  tuple<int,const int&> tm(pair1);
  tuple<int,int> tn(pair2);
  tuple<int,const int&> to(pair2);  
}

int 
main(void) 
{
  //test construction
  typedef tuple<int,int,int,int,int,int,int,int,int,int> type1;
  type1 a(0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
  type1 b(0, 0, 0, 0, 0, 0, 0, 0, 0, 2);
  type1 c(a);
  typedef tuple<int,int,int,int,int,int,int,int,int,char> type2;
  type2 d(0, 0, 0, 0, 0, 0, 0, 0, 0, 3);
  type1 e(d);
  typedef tuple<foo,int,int,int,int,int,int,int,int,foo> type3;
  // get
  VERIFY(get<9>(a)==1 && get<9>(b)==2);
  // comparisons
  VERIFY(a==a && !(a!=a) && a<=a && a>=a && !(a<a) && !(a>a));
  VERIFY(!(a==b) && a!=b && a<=b && a<b && !(a>=b) && !(a>b));
  //tie
  {
    int i = 0;
  tie(ignore, ignore, ignore, ignore, ignore, ignore, ignore, ignore, 
      ignore, i) = a;
  VERIFY(i == 1);
  }
  //test_assignment
  a=d;
  a=b;
  //make_tuple
  make_tuple(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  
  //tuple_size
  VERIFY(tuple_size<type3>::value == 10);
  //tuple_element
  {  
    foo q1;
    tuple_element<0,type3>::type q2(q1);
    tuple_element<9,type3>::type q3(q1);
  }
  
}
// 2004-09-23 Chris Jefferson <chris@bubblescope.net>

// Copyright (C) 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// Tuple

#include <tr1/tuple>
#include <testsuite_hooks.h>

using namespace std;
using namespace tr1;

#define TEST1(x) VERIFY( x == x && !(x != x) && x <= x && !(x < x) )

int
main()
{
  int i=0;
  int j=0;
  int k=2;
  tuple<int, int, int> a(0, 0, 0);
  tuple<int, int, int> b(0, 0, 1);
  tuple<int& , int& , int&> c(i,j,k);
  tuple<const int&, const int&, const int&> d(c);
  TEST1(a);
  TEST1(b);
  TEST1(c);
  TEST1(d);
  VERIFY(!(a > a) && !(b > b));
  VERIFY(a >= a && b >= b);
  VERIFY(a < b && !(b < a) && a <= b && !(b <= a));
  VERIFY(b > a && !(a > b) && b >= a && !(a >= b));  
}
// 2004-09-23 Chris Jefferson <chris@bubblescope.net>

// Copyright (C) 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// Tuple

#include <tr1/tuple>
#include <testsuite_hooks.h>

using namespace std;
using namespace tr1;

int
main()
{
  int x1=0,x2=0;
  const int &z1=x1;

  // Test empty constructor
  tuple<> ta;
  tuple<int,int> tb;
  // Test construction from values
  tuple<int,int> tc(x1,x2);
  tuple<int,int&> td(x1,x2);
  tuple<const int&> te(z1);
  x1=1;
  x2=1;
  VERIFY(get<0>(td) == 0 && get<1>(td) == 1 && get<0>(te) == 1);

  // Test identical tuple copy constructor
  tuple<int,int> tf(tc);
  tuple<int,int> tg(td);
  tuple<const int&> th(te);
  // Test different tuple copy constructor
  tuple<int,double> ti(tc);
  tuple<int,double> tj(td);
  //tuple<int&, int&> tk(tc);
  tuple<const int&, const int&> tl(tc);
  tuple<const int&, const int&> tm(tl);
  // Test constructing from a pair
  pair<int,int> pair1(1,1);
  const pair<int,int> pair2(pair1);
  tuple<int,int> tn(pair1);
  tuple<int,const int&> to(pair1);
  tuple<int,int> tp(pair2);
  tuple<int,const int&> tq(pair2);  
  return 0;
}
// 2004-09-23 Chris Jefferson <chris@bubblescope.net>

// Copyright (C) 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// Tuple

#include <tr1/tuple>
#include <testsuite_hooks.h>

using namespace std;
using namespace tr1;

int
main()
{
  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);
  get<0>(a)=3;
  get<1>(a)=4;  
  VERIFY(get<0>(a)==3 && get<1>(a)==4);
  VERIFY(j==4);
  get<1>(b)=5;
  VERIFY(get<0>(b)==1 && get<1>(b)==5 && get<2>(b)==2);
  VERIFY(j==5);
}
// 2004-09-23 Chris Jefferson <chris@bubblescope.net>

// Copyright (C) 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// Tuple

#include <tr1/tuple>
#include <testsuite_hooks.h>

using namespace std;
using namespace tr1;

int
main()
{
  int i=0;
  make_tuple(1,2,4.0);
  make_tuple(ref(i)) = tuple<int>(1);
  VERIFY(i == 1);
}
// 2004-09-23 Chris Jefferson <chris@bubblescope.net>

// Copyright (C) 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// Tuple

#include <tr1/tuple>
#include <testsuite_hooks.h>

using namespace std;
using namespace tr1;

int
main()
{
  int x1 = 0;
  int x2 = 0;
  int y1 = 0;
  int y2 = 0;
  tuple<int,int> ta(1,1);
  tuple<const int&,const int&> tc(x1,x2);
  tie(y1,y2)=ta;
  VERIFY(y1 == 1 && y2 == 1);
  tie(y1,y2)=tc;
  VERIFY(y1 == 0 && y2 == 0);
}
// 2004-09-23 Chris Jefferson <chris@bubblescope.net>

// Copyright (C) 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// Tuple

#include <tr1/tuple>
#include <testsuite_hooks.h>

using namespace std;
using namespace tr1;

struct foo
{ };

int
main()
{
  // As foo isn't constructable from anything else, this
  // lets us check if type is returning foo when it should
  foo q1;
  tuple_element<0,tuple<foo,void,int> >::type q2(q1);
  tuple_element<2,tuple<void,int,foo> >::type q3(q1);
}
// 2004-09-23 Chris Jefferson <chris@bubblescope.net>

// Copyright (C) 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING.  If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.

// Tuple

#include <tr1/tuple>
#include <testsuite_hooks.h>

using namespace std;
using namespace tr1;

int
main()
{
  VERIFY(tuple_size<tuple<> >::value == 0);
  VERIFY(tuple_size<tuple<int> >::value == 1);
  VERIFY(tuple_size<tuple<void> >::value == 1);
  typedef tuple<int,const int&,void> test_tuple1;
  VERIFY(tuple_size<test_tuple1>::value == 3);
  VERIFY(tuple_size<tuple<tuple<void> > >::value == 1);
}
2004-09-23  Chris Jefferson <chris@bubblescope.net>

	* include/tr1/tuple : Implementation of tuple from library TR
	* make_tuple.c : automatically generate /include/tr1/tuple
	* testsuite/tr1/2_general_utilities/tuple/assignment.cc : New
        * testsuite/tr1/2_general_utilities/tuple/big_tuples.cc : New
        * testsuite/tr1/2_general_utilities/tuple/comparisons.cc : New
        * testsuite/tr1/2_general_utilities/tuple/constructor.cc : New
        * testsuite/tr1/2_general_utilities/tuple/get.cc : New
        * testsuite/tr1/2_general_utilities/tuple/make_tuple.cc : New
        * testsuite/tr1/2_general_utilities/tuple/tie.cc : New
        * testsuite/tr1/2_general_utilities/tuple/tuple_element.cc : New
        * testsuite/tr1/2_general_utilities/tuple/tuple_size.cc : New


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