Chris@16
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 //
|
Chris@101
|
3 // (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost
|
Chris@16
|
4 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6 //
|
Chris@16
|
7 // See http://www.boost.org/libs/container for documentation.
|
Chris@16
|
8 //
|
Chris@16
|
9 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
Chris@16
|
12 #define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|
Chris@16
|
13
|
Chris@101
|
14 #ifndef BOOST_CONFIG_HPP
|
Chris@101
|
15 # include <boost/config.hpp>
|
Chris@101
|
16 #endif
|
Chris@101
|
17
|
Chris@101
|
18 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@16
|
19 # pragma once
|
Chris@16
|
20 #endif
|
Chris@16
|
21
|
Chris@101
|
22 #include <boost/container/detail/config_begin.hpp>
|
Chris@16
|
23 #include <boost/container/detail/workaround.hpp>
|
Chris@101
|
24
|
Chris@16
|
25 #include <boost/container/detail/type_traits.hpp>
|
Chris@16
|
26 #include <cstddef> //std::size_t
|
Chris@16
|
27
|
Chris@16
|
28 namespace boost {
|
Chris@16
|
29 namespace container {
|
Chris@16
|
30 namespace container_detail {
|
Chris@16
|
31
|
Chris@16
|
32 template<typename... Values>
|
Chris@16
|
33 class tuple;
|
Chris@16
|
34
|
Chris@16
|
35 template<> class tuple<>
|
Chris@16
|
36 {};
|
Chris@16
|
37
|
Chris@16
|
38 template<typename Head, typename... Tail>
|
Chris@16
|
39 class tuple<Head, Tail...>
|
Chris@16
|
40 : private tuple<Tail...>
|
Chris@16
|
41 {
|
Chris@16
|
42 typedef tuple<Tail...> inherited;
|
Chris@16
|
43
|
Chris@16
|
44 public:
|
Chris@16
|
45 tuple() { }
|
Chris@16
|
46
|
Chris@16
|
47 // implicit copy-constructor is okay
|
Chris@16
|
48 // Construct tuple from separate arguments.
|
Chris@16
|
49 tuple(typename add_const_reference<Head>::type v,
|
Chris@16
|
50 typename add_const_reference<Tail>::type... vtail)
|
Chris@16
|
51 : inherited(vtail...), m_head(v)
|
Chris@16
|
52 {}
|
Chris@16
|
53
|
Chris@16
|
54 // Construct tuple from another tuple.
|
Chris@16
|
55 template<typename... VValues>
|
Chris@16
|
56 tuple(const tuple<VValues...>& other)
|
Chris@16
|
57 : m_head(other.head()), inherited(other.tail())
|
Chris@16
|
58 {}
|
Chris@16
|
59
|
Chris@16
|
60 template<typename... VValues>
|
Chris@16
|
61 tuple& operator=(const tuple<VValues...>& other)
|
Chris@16
|
62 {
|
Chris@16
|
63 m_head = other.head();
|
Chris@16
|
64 tail() = other.tail();
|
Chris@16
|
65 return this;
|
Chris@16
|
66 }
|
Chris@16
|
67
|
Chris@16
|
68 typename add_reference<Head>::type head() { return m_head; }
|
Chris@16
|
69 typename add_reference<const Head>::type head() const { return m_head; }
|
Chris@16
|
70
|
Chris@16
|
71 inherited& tail() { return *this; }
|
Chris@16
|
72 const inherited& tail() const { return *this; }
|
Chris@16
|
73
|
Chris@16
|
74 protected:
|
Chris@16
|
75 Head m_head;
|
Chris@16
|
76 };
|
Chris@16
|
77
|
Chris@16
|
78
|
Chris@16
|
79 template<typename... Values>
|
Chris@16
|
80 tuple<Values&&...> tie_forward(Values&&... values)
|
Chris@16
|
81 { return tuple<Values&&...>(values...); }
|
Chris@16
|
82
|
Chris@16
|
83 template<int I, typename Tuple>
|
Chris@16
|
84 struct tuple_element;
|
Chris@16
|
85
|
Chris@16
|
86 template<int I, typename Head, typename... Tail>
|
Chris@16
|
87 struct tuple_element<I, tuple<Head, Tail...> >
|
Chris@16
|
88 {
|
Chris@16
|
89 typedef typename tuple_element<I-1, tuple<Tail...> >::type type;
|
Chris@16
|
90 };
|
Chris@16
|
91
|
Chris@16
|
92 template<typename Head, typename... Tail>
|
Chris@16
|
93 struct tuple_element<0, tuple<Head, Tail...> >
|
Chris@16
|
94 {
|
Chris@16
|
95 typedef Head type;
|
Chris@16
|
96 };
|
Chris@16
|
97
|
Chris@16
|
98 template<int I, typename Tuple>
|
Chris@16
|
99 class get_impl;
|
Chris@16
|
100
|
Chris@16
|
101 template<int I, typename Head, typename... Values>
|
Chris@16
|
102 class get_impl<I, tuple<Head, Values...> >
|
Chris@16
|
103 {
|
Chris@16
|
104 typedef typename tuple_element<I-1, tuple<Values...> >::type Element;
|
Chris@16
|
105 typedef get_impl<I-1, tuple<Values...> > Next;
|
Chris@16
|
106
|
Chris@16
|
107 public:
|
Chris@16
|
108 typedef typename add_reference<Element>::type type;
|
Chris@16
|
109 typedef typename add_const_reference<Element>::type const_type;
|
Chris@16
|
110 static type get(tuple<Head, Values...>& t) { return Next::get(t.tail()); }
|
Chris@16
|
111 static const_type get(const tuple<Head, Values...>& t) { return Next::get(t.tail()); }
|
Chris@16
|
112 };
|
Chris@16
|
113
|
Chris@16
|
114 template<typename Head, typename... Values>
|
Chris@16
|
115 class get_impl<0, tuple<Head, Values...> >
|
Chris@16
|
116 {
|
Chris@16
|
117 public:
|
Chris@16
|
118 typedef typename add_reference<Head>::type type;
|
Chris@16
|
119 typedef typename add_const_reference<Head>::type const_type;
|
Chris@16
|
120 static type get(tuple<Head, Values...>& t) { return t.head(); }
|
Chris@16
|
121 static const_type get(const tuple<Head, Values...>& t){ return t.head(); }
|
Chris@16
|
122 };
|
Chris@16
|
123
|
Chris@16
|
124 template<int I, typename... Values>
|
Chris@16
|
125 typename get_impl<I, tuple<Values...> >::type get(tuple<Values...>& t)
|
Chris@16
|
126 { return get_impl<I, tuple<Values...> >::get(t); }
|
Chris@16
|
127
|
Chris@16
|
128 template<int I, typename... Values>
|
Chris@16
|
129 typename get_impl<I, tuple<Values...> >::const_type get(const tuple<Values...>& t)
|
Chris@16
|
130 { return get_impl<I, tuple<Values...> >::get(t); }
|
Chris@16
|
131
|
Chris@16
|
132 ////////////////////////////////////////////////////
|
Chris@16
|
133 // Builds an index_tuple<0, 1, 2, ..., Num-1>, that will
|
Chris@16
|
134 // be used to "unpack" into comma-separated values
|
Chris@16
|
135 // in a function call.
|
Chris@16
|
136 ////////////////////////////////////////////////////
|
Chris@16
|
137
|
Chris@16
|
138 template<int... Indexes>
|
Chris@16
|
139 struct index_tuple{};
|
Chris@16
|
140
|
Chris@16
|
141 template<std::size_t Num, typename Tuple = index_tuple<> >
|
Chris@16
|
142 struct build_number_seq;
|
Chris@16
|
143
|
Chris@16
|
144 template<std::size_t Num, int... Indexes>
|
Chris@16
|
145 struct build_number_seq<Num, index_tuple<Indexes...> >
|
Chris@16
|
146 : build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
|
Chris@16
|
147 {};
|
Chris@16
|
148
|
Chris@16
|
149 template<int... Indexes>
|
Chris@16
|
150 struct build_number_seq<0, index_tuple<Indexes...> >
|
Chris@16
|
151 { typedef index_tuple<Indexes...> type; };
|
Chris@16
|
152
|
Chris@16
|
153
|
Chris@16
|
154 }}} //namespace boost { namespace container { namespace container_detail {
|
Chris@16
|
155
|
Chris@16
|
156 #include <boost/container/detail/config_end.hpp>
|
Chris@16
|
157
|
Chris@16
|
158 #endif //#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
|