// { dg-options "-std=gnu++0x" }
// { dg-do "run" }
// An implementation of TR1's <tuple> using variadic teplates
// Contributed by Douglas Gregor <doug.gregor@gmail.com>

#include <string>
#include <cassert>
#include <cstring>

// Trivial reference_wrapper
template<typename T>
struct reference_wrapper
{
  reference_wrapper(T& x) : ptr(&x) { }

  operator T&() const { return *ptr; }

  T* ptr;
};

template<typename T> reference_wrapper<T> ref(T& x) { return x; }
template<typename T> reference_wrapper<const T> cref(const T& x) { return x; }

// Simple type-traits we'll need
template<typename T>
struct add_reference
{
  typedef T& type;
};

template<typename T>
struct add_reference<T&>
{
  typedef T& type;
};

template<typename T, typename U>
struct is_same
{
  static const bool value = false;
};

template<typename T>
struct is_same<T, T>
{
  static const bool value = true;
};

// For creating the constructor parameters of tuple<>
template<typename T>
struct add_const_reference
{
  typedef const T& type;
};

template<typename T>
struct add_const_reference<T&>
{
  typedef T& type;
};

// 6.1.3 Class template tuple 
template<typename... Values>
class tuple;

template<> class tuple<> { };

template<typename Head, typename... Tail>
class tuple<Head, Tail...> 
  : private tuple<Tail...>
{
  typedef tuple<Tail...> inherited;

 public:
  tuple() { }

  // implicit copy-constructor is okay

  tuple(typename add_const_reference<Head>::type v, 
        typename add_const_reference<Tail>::type... vtail)
    : m_head(v), inherited(vtail...) { }

  template<typename... VValues>
  tuple(const tuple<VValues...>& other)
    : m_head(other.head()), inherited(other.tail()) { }

  template<typename... VValues>
  tuple& operator=(const tuple<VValues...>& other)
  {
    m_head = other.head();
    tail() = other.tail();
    return *this;
  }

  typename add_reference<Head>::type       head()       { return m_head; }
  typename add_reference<const Head>::type head() const { return m_head; }
  inherited&                               tail()       { return *this; }
  const inherited&                         tail() const { return *this; }

 protected:
  Head m_head;
};

template<typename T>
struct make_tuple_result
{
  typedef T type;
};

template<typename T>
struct make_tuple_result<reference_wrapper<T> >
{
  typedef T& type;
};

// 6.1.3.2 Tuple creation functions
struct ignore_t { 
  template<typename T> ignore_t& operator=(const T&) { return *this; }
} ignore;

template<typename... Values>
tuple<typename make_tuple_result<Values>::type...> 
make_tuple(const Values&... values)
{
  return tuple<typename make_tuple_result<Values>::type...>(values...);
}

template<typename... Values>
tuple<Values&...> tie(Values&... values)
{
  return tuple<Values&...>(values...);
}

// 6.1.3.3 Tuple helper classes
template<typename Tuple>
struct tuple_size;

template<>
struct tuple_size<tuple<> >
{
  static const std::size_t value = 0;
};

template<typename Head, typename... Tail>
struct tuple_size<tuple<Head, Tail...> >
{
  static const std::size_t value = 1 + tuple_size<tuple<Tail...> >::value;
};

template<int I, typename Tuple>
struct tuple_element;

template<int I, typename Head, typename... Tail>
struct tuple_element<I, tuple<Head, Tail...> >
{
  typedef typename tuple_element<I-1, tuple<Tail...> >::type type;
};

template<typename Head, typename... Tail>
struct tuple_element<0, tuple<Head, Tail...> >
{
  typedef Head type;
};

// 6.1.3.4 Element access
template<int I, typename Tuple>
class get_impl;

template<int I, typename Head, typename... Values> 
class get_impl<I, tuple<Head, Values...> >
{
  typedef typename tuple_element<I-1, tuple<Values...> >::type Element;
  typedef typename add_reference<Element>::type RJ;
  typedef typename add_const_reference<Element>::type PJ;
  typedef get_impl<I-1, tuple<Values...> > Next;

 public:
  static RJ get(tuple<Head, Values...>& t)       
  { return Next::get(t.tail()); }

  static PJ get(const tuple<Head, Values...>& t) 
  { return Next::get(t.tail()); }
};

template<typename Head, typename... Values> 
class get_impl<0, tuple<Head, Values...> >
{
  typedef typename add_reference<Head>::type RJ;
  typedef typename add_const_reference<Head>::type PJ;

 public:
  static RJ get(tuple<Head, Values...>& t)       { return t.head(); }
  static PJ get(const tuple<Head, Values...>& t) { return t.head(); }
};

template<int I, typename... Values>
typename add_reference<
           typename tuple_element<I, tuple<Values...> >::type
         >::type
get(tuple<Values...>& t)
{
  return get_impl<I, tuple<Values...> >::get(t);
}

template<int I, typename... Values>
typename add_const_reference<
           typename tuple_element<I, tuple<Values...> >::type
         >::type
get(const tuple<Values...>& t)
{
  return get_impl<I, tuple<Values...> >::get(t);
}

// 6.1.3.5 Relational operators
inline bool operator==(const tuple<>&, const tuple<>&) { return true; }

template<typename T, typename... TTail, typename U, typename... UTail>
bool operator==(const tuple<T, TTail...>& t, const tuple<U, UTail...>& u)
{
  return t.head() == u.head() && t.tail() == u.tail();
}

template<typename... TValues, typename... UValues>
bool operator!=(const tuple<TValues...>& t, const tuple<UValues...>& u)
{
  return !(t == u);
}

inline bool operator<(const tuple<>&, const tuple<>&) { return false; }

template<typename T, typename... TTail, typename U, typename... UTail>
bool operator<(const tuple<T, TTail...>& t, const tuple<U, UTail...>& u)
{
  return (t.head() < u.head() || 
          (!(t.head() < u.head()) && t.tail() < u.tail()));
}

template<typename... TValues, typename... UValues>
bool operator>(const tuple<TValues...>& t, const tuple<UValues...>& u)
{
  return u < t;
}

template<typename... TValues, typename... UValues>
bool operator<=(const tuple<TValues...>& t, const tuple<UValues...>& u)
{
  return !(u < t);
}

template<typename... TValues, typename... UValues>
bool operator>=(const tuple<TValues...>& t, const tuple<UValues...>& u)
{
  return !(t < u);
}

int a0[tuple_size<tuple<> >::value == 0? 1 : -1];
int a1[tuple_size<tuple<int, float, double> >::value == 3? 1 : -1];
int a2a[is_same<tuple_element<0, tuple<int, float, double> >::type, int>
         ::value? 1 : -1];
int a2b[is_same<tuple_element<1, tuple<int, float, double> >::type, float>
         ::value? 1 : -1];
int a2c[is_same<tuple_element<2, tuple<int, float, double> >::type, double>
         ::value? 1 : -1];

int main()
{
  tuple<> t0;
  tuple<int> t1(1);
  tuple<int, float> t2(1, 3.14159f);
  tuple<int, float, const char*> t3a(1, 3.14159f, "Hello, world!");
  tuple<long, double, std::string> t3b(t3a);
  t3b = t3a;
  //  t3a = t3b; DPG: triggers an error, as it should.

  tuple<int, float, std::string> t3c = 
    make_tuple(17, 2.718281828, std::string("Fun"));

  int seventeen = 17;
  double pi = 3.14159;
  tuple<int&, double&> seventeen_pi = make_tuple(ref(seventeen), ref(pi));
  tuple<int&, const double&> seventeen_pi2 = 
    make_tuple(ref(seventeen), cref(pi));
  tuple<int&, double&> seventeen_pi_tied = tie(seventeen, pi);
  assert(get<0>(t3a) == 1);
  assert(get<1>(t3a) == 3.14159f);
  assert(std::strcmp(get<2>(t3a), "Hello, world!") == 0);

  assert(t3a == t3b);
  assert(!(t3a != t3b));
  assert(!(t3a < t3b));
  assert(!(t3a > t3b));
  assert(t3a <= t3b && t3b <= t3a);
  assert(t3a >= t3b && t3b >= t3a);
}
