1
//////////////////////////////////////////////////////////////////////////////
3
// (C) Copyright Ion Gaztanaga 2008-2012. Distributed under the Boost
4
// Software License, Version 1.0. (See accompanying file
5
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7
// See http://www.boost.org/libs/container for documentation.
9
//////////////////////////////////////////////////////////////////////////////
11
#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
12
#define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
18
#include "config_begin.hpp"
19
#include <boost/container/detail/workaround.hpp>
20
#include <boost/container/detail/type_traits.hpp>
21
#include <cstddef> //std::size_t
25
namespace container_detail {
27
template<typename... Values>
30
template<> class tuple<>
33
template<typename Head, typename... Tail>
34
class tuple<Head, Tail...>
35
: private tuple<Tail...>
37
typedef tuple<Tail...> inherited;
42
// implicit copy-constructor is okay
43
// Construct tuple from separate arguments.
44
tuple(typename add_const_reference<Head>::type v,
45
typename add_const_reference<Tail>::type... vtail)
46
: inherited(vtail...), m_head(v)
49
// Construct tuple from another tuple.
50
template<typename... VValues>
51
tuple(const tuple<VValues...>& other)
52
: m_head(other.head()), inherited(other.tail())
55
template<typename... VValues>
56
tuple& operator=(const tuple<VValues...>& other)
58
m_head = other.head();
59
tail() = other.tail();
63
typename add_reference<Head>::type head() { return m_head; }
64
typename add_reference<const Head>::type head() const { return m_head; }
66
inherited& tail() { return *this; }
67
const inherited& tail() const { return *this; }
74
template<typename... Values>
75
tuple<Values&&...> tie_forward(Values&&... values)
76
{ return tuple<Values&&...>(values...); }
78
template<int I, typename Tuple>
81
template<int I, typename Head, typename... Tail>
82
struct tuple_element<I, tuple<Head, Tail...> >
84
typedef typename tuple_element<I-1, tuple<Tail...> >::type type;
87
template<typename Head, typename... Tail>
88
struct tuple_element<0, tuple<Head, Tail...> >
93
template<int I, typename Tuple>
96
template<int I, typename Head, typename... Values>
97
class get_impl<I, tuple<Head, Values...> >
99
typedef typename tuple_element<I-1, tuple<Values...> >::type Element;
100
typedef get_impl<I-1, tuple<Values...> > Next;
103
typedef typename add_reference<Element>::type type;
104
typedef typename add_const_reference<Element>::type const_type;
105
static type get(tuple<Head, Values...>& t) { return Next::get(t.tail()); }
106
static const_type get(const tuple<Head, Values...>& t) { return Next::get(t.tail()); }
109
template<typename Head, typename... Values>
110
class get_impl<0, tuple<Head, Values...> >
113
typedef typename add_reference<Head>::type type;
114
typedef typename add_const_reference<Head>::type const_type;
115
static type get(tuple<Head, Values...>& t) { return t.head(); }
116
static const_type get(const tuple<Head, Values...>& t){ return t.head(); }
119
template<int I, typename... Values>
120
typename get_impl<I, tuple<Values...> >::type get(tuple<Values...>& t)
121
{ return get_impl<I, tuple<Values...> >::get(t); }
123
template<int I, typename... Values>
124
typename get_impl<I, tuple<Values...> >::const_type get(const tuple<Values...>& t)
125
{ return get_impl<I, tuple<Values...> >::get(t); }
127
////////////////////////////////////////////////////
128
// Builds an index_tuple<0, 1, 2, ..., Num-1>, that will
129
// be used to "unpack" into comma-separated values
130
// in a function call.
131
////////////////////////////////////////////////////
133
template<int... Indexes>
134
struct index_tuple{};
136
template<std::size_t Num, typename Tuple = index_tuple<> >
137
struct build_number_seq;
139
template<std::size_t Num, int... Indexes>
140
struct build_number_seq<Num, index_tuple<Indexes...> >
141
: build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
144
template<int... Indexes>
145
struct build_number_seq<0, index_tuple<Indexes...> >
146
{ typedef index_tuple<Indexes...> type; };
149
}}} //namespace boost { namespace container { namespace container_detail {
151
#include <boost/container/detail/config_end.hpp>
153
#endif //#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP