Chris@16
|
1 // tuple_basic.hpp -----------------------------------------------------
|
Chris@16
|
2
|
Chris@16
|
3 // Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
|
Chris@16
|
4 //
|
Chris@16
|
5 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
6 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8
|
Chris@16
|
9 // For more information, see http://www.boost.org
|
Chris@16
|
10
|
Chris@16
|
11 // Outside help:
|
Chris@16
|
12 // This and that, Gary Powell.
|
Chris@16
|
13 // Fixed return types for get_head/get_tail
|
Chris@16
|
14 // ( and other bugs ) per suggestion of Jens Maurer
|
Chris@16
|
15 // simplified element type accessors + bug fix (Jeremy Siek)
|
Chris@16
|
16 // Several changes/additions according to suggestions by Douglas Gregor,
|
Chris@16
|
17 // William Kempf, Vesa Karvonen, John Max Skaller, Ed Brey, Beman Dawes,
|
Chris@16
|
18 // David Abrahams.
|
Chris@16
|
19
|
Chris@16
|
20 // Revision history:
|
Chris@16
|
21 // 2002 05 01 Hugo Duncan: Fix for Borland after Jaakko's previous changes
|
Chris@16
|
22 // 2002 04 18 Jaakko: tuple element types can be void or plain function
|
Chris@16
|
23 // types, as long as no object is created.
|
Chris@16
|
24 // Tuple objects can no hold even noncopyable types
|
Chris@16
|
25 // such as arrays.
|
Chris@16
|
26 // 2001 10 22 John Maddock
|
Chris@16
|
27 // Fixes for Borland C++
|
Chris@16
|
28 // 2001 08 30 David Abrahams
|
Chris@16
|
29 // Added default constructor for cons<>.
|
Chris@16
|
30 // -----------------------------------------------------------------
|
Chris@16
|
31
|
Chris@16
|
32 #ifndef BOOST_TUPLE_BASIC_HPP
|
Chris@16
|
33 #define BOOST_TUPLE_BASIC_HPP
|
Chris@16
|
34
|
Chris@16
|
35
|
Chris@16
|
36 #include <utility> // needed for the assignment from pair to tuple
|
Chris@16
|
37
|
Chris@16
|
38 #include "boost/type_traits/cv_traits.hpp"
|
Chris@16
|
39 #include "boost/type_traits/function_traits.hpp"
|
Chris@16
|
40 #include "boost/utility/swap.hpp"
|
Chris@16
|
41
|
Chris@16
|
42 #include "boost/detail/workaround.hpp" // needed for BOOST_WORKAROUND
|
Chris@16
|
43
|
Chris@16
|
44 namespace boost {
|
Chris@16
|
45 namespace tuples {
|
Chris@16
|
46
|
Chris@16
|
47 // -- null_type --------------------------------------------------------
|
Chris@16
|
48 struct null_type {};
|
Chris@16
|
49
|
Chris@16
|
50 // a helper function to provide a const null_type type temporary
|
Chris@16
|
51 namespace detail {
|
Chris@16
|
52 inline const null_type cnull() { return null_type(); }
|
Chris@16
|
53
|
Chris@16
|
54
|
Chris@16
|
55 // -- if construct ------------------------------------------------
|
Chris@16
|
56 // Proposed by Krzysztof Czarnecki and Ulrich Eisenecker
|
Chris@16
|
57
|
Chris@16
|
58 template <bool If, class Then, class Else> struct IF { typedef Then RET; };
|
Chris@16
|
59
|
Chris@16
|
60 template <class Then, class Else> struct IF<false, Then, Else> {
|
Chris@16
|
61 typedef Else RET;
|
Chris@16
|
62 };
|
Chris@16
|
63
|
Chris@16
|
64 } // end detail
|
Chris@16
|
65
|
Chris@16
|
66 // - cons forward declaration -----------------------------------------------
|
Chris@16
|
67 template <class HT, class TT> struct cons;
|
Chris@16
|
68
|
Chris@16
|
69
|
Chris@16
|
70 // - tuple forward declaration -----------------------------------------------
|
Chris@16
|
71 template <
|
Chris@16
|
72 class T0 = null_type, class T1 = null_type, class T2 = null_type,
|
Chris@16
|
73 class T3 = null_type, class T4 = null_type, class T5 = null_type,
|
Chris@16
|
74 class T6 = null_type, class T7 = null_type, class T8 = null_type,
|
Chris@16
|
75 class T9 = null_type>
|
Chris@16
|
76 class tuple;
|
Chris@16
|
77
|
Chris@16
|
78 // tuple_length forward declaration
|
Chris@16
|
79 template<class T> struct length;
|
Chris@16
|
80
|
Chris@16
|
81
|
Chris@16
|
82
|
Chris@16
|
83 namespace detail {
|
Chris@16
|
84
|
Chris@16
|
85 // -- generate error template, referencing to non-existing members of this
|
Chris@16
|
86 // template is used to produce compilation errors intentionally
|
Chris@16
|
87 template<class T>
|
Chris@16
|
88 class generate_error;
|
Chris@16
|
89
|
Chris@16
|
90 template<int N>
|
Chris@16
|
91 struct drop_front {
|
Chris@16
|
92 template<class Tuple>
|
Chris@16
|
93 struct apply {
|
Chris@16
|
94 typedef BOOST_DEDUCED_TYPENAME drop_front<N-1>::BOOST_NESTED_TEMPLATE
|
Chris@16
|
95 apply<Tuple> next;
|
Chris@16
|
96 typedef BOOST_DEDUCED_TYPENAME next::type::tail_type type;
|
Chris@16
|
97 static const type& call(const Tuple& tup) {
|
Chris@16
|
98 return next::call(tup).tail;
|
Chris@16
|
99 }
|
Chris@16
|
100 };
|
Chris@16
|
101 };
|
Chris@16
|
102
|
Chris@16
|
103 template<>
|
Chris@16
|
104 struct drop_front<0> {
|
Chris@16
|
105 template<class Tuple>
|
Chris@16
|
106 struct apply {
|
Chris@16
|
107 typedef Tuple type;
|
Chris@16
|
108 static const type& call(const Tuple& tup) {
|
Chris@16
|
109 return tup;
|
Chris@16
|
110 }
|
Chris@16
|
111 };
|
Chris@16
|
112 };
|
Chris@16
|
113
|
Chris@16
|
114 } // end of namespace detail
|
Chris@16
|
115
|
Chris@16
|
116
|
Chris@16
|
117 // -cons type accessors ----------------------------------------
|
Chris@16
|
118 // typename tuples::element<N,T>::type gets the type of the
|
Chris@16
|
119 // Nth element ot T, first element is at index 0
|
Chris@16
|
120 // -------------------------------------------------------
|
Chris@16
|
121
|
Chris@16
|
122 #ifndef BOOST_NO_CV_SPECIALIZATIONS
|
Chris@16
|
123
|
Chris@16
|
124 template<int N, class T>
|
Chris@16
|
125 struct element
|
Chris@16
|
126 {
|
Chris@16
|
127 typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
Chris@16
|
128 apply<T>::type::head_type type;
|
Chris@16
|
129 };
|
Chris@16
|
130
|
Chris@16
|
131 template<int N, class T>
|
Chris@16
|
132 struct element<N, const T>
|
Chris@16
|
133 {
|
Chris@16
|
134 private:
|
Chris@16
|
135 typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
Chris@16
|
136 apply<T>::type::head_type unqualified_type;
|
Chris@16
|
137 public:
|
Chris@16
|
138 #if BOOST_WORKAROUND(__BORLANDC__,<0x600)
|
Chris@16
|
139 typedef const unqualified_type type;
|
Chris@16
|
140 #else
|
Chris@16
|
141 typedef BOOST_DEDUCED_TYPENAME boost::add_const<unqualified_type>::type type;
|
Chris@16
|
142 #endif
|
Chris@16
|
143 };
|
Chris@16
|
144 #else // def BOOST_NO_CV_SPECIALIZATIONS
|
Chris@16
|
145
|
Chris@16
|
146 namespace detail {
|
Chris@16
|
147
|
Chris@16
|
148 template<int N, class T, bool IsConst>
|
Chris@16
|
149 struct element_impl
|
Chris@16
|
150 {
|
Chris@16
|
151 typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
Chris@16
|
152 apply<T>::type::head_type type;
|
Chris@16
|
153 };
|
Chris@16
|
154
|
Chris@16
|
155 template<int N, class T>
|
Chris@16
|
156 struct element_impl<N, T, true /* IsConst */>
|
Chris@16
|
157 {
|
Chris@16
|
158 typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
Chris@16
|
159 apply<T>::type::head_type unqualified_type;
|
Chris@16
|
160 typedef const unqualified_type type;
|
Chris@16
|
161 };
|
Chris@16
|
162
|
Chris@16
|
163 } // end of namespace detail
|
Chris@16
|
164
|
Chris@16
|
165
|
Chris@16
|
166 template<int N, class T>
|
Chris@16
|
167 struct element:
|
Chris@16
|
168 public detail::element_impl<N, T, ::boost::is_const<T>::value>
|
Chris@16
|
169 {
|
Chris@16
|
170 };
|
Chris@16
|
171
|
Chris@16
|
172 #endif
|
Chris@16
|
173
|
Chris@16
|
174
|
Chris@16
|
175 // -get function templates -----------------------------------------------
|
Chris@16
|
176 // Usage: get<N>(aTuple)
|
Chris@16
|
177
|
Chris@16
|
178 // -- some traits classes for get functions
|
Chris@16
|
179
|
Chris@16
|
180 // access traits lifted from detail namespace to be part of the interface,
|
Chris@16
|
181 // (Joel de Guzman's suggestion). Rationale: get functions are part of the
|
Chris@16
|
182 // interface, so should the way to express their return types be.
|
Chris@16
|
183
|
Chris@16
|
184 template <class T> struct access_traits {
|
Chris@16
|
185 typedef const T& const_type;
|
Chris@16
|
186 typedef T& non_const_type;
|
Chris@16
|
187
|
Chris@16
|
188 typedef const typename boost::remove_cv<T>::type& parameter_type;
|
Chris@16
|
189
|
Chris@16
|
190 // used as the tuple constructors parameter types
|
Chris@16
|
191 // Rationale: non-reference tuple element types can be cv-qualified.
|
Chris@16
|
192 // It should be possible to initialize such types with temporaries,
|
Chris@16
|
193 // and when binding temporaries to references, the reference must
|
Chris@16
|
194 // be non-volatile and const. 8.5.3. (5)
|
Chris@16
|
195 };
|
Chris@16
|
196
|
Chris@16
|
197 template <class T> struct access_traits<T&> {
|
Chris@16
|
198
|
Chris@16
|
199 typedef T& const_type;
|
Chris@16
|
200 typedef T& non_const_type;
|
Chris@16
|
201
|
Chris@16
|
202 typedef T& parameter_type;
|
Chris@16
|
203 };
|
Chris@16
|
204
|
Chris@16
|
205 // get function for non-const cons-lists, returns a reference to the element
|
Chris@16
|
206
|
Chris@16
|
207 template<int N, class HT, class TT>
|
Chris@16
|
208 inline typename access_traits<
|
Chris@16
|
209 typename element<N, cons<HT, TT> >::type
|
Chris@16
|
210 >::non_const_type
|
Chris@16
|
211 get(cons<HT, TT>& c BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int, N)) {
|
Chris@16
|
212 typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
Chris@16
|
213 apply<cons<HT, TT> > impl;
|
Chris@16
|
214 typedef BOOST_DEDUCED_TYPENAME impl::type cons_element;
|
Chris@16
|
215 return const_cast<cons_element&>(impl::call(c)).head;
|
Chris@16
|
216 }
|
Chris@16
|
217
|
Chris@16
|
218 // get function for const cons-lists, returns a const reference to
|
Chris@16
|
219 // the element. If the element is a reference, returns the reference
|
Chris@16
|
220 // as such (that is, can return a non-const reference)
|
Chris@16
|
221 template<int N, class HT, class TT>
|
Chris@16
|
222 inline typename access_traits<
|
Chris@16
|
223 typename element<N, cons<HT, TT> >::type
|
Chris@16
|
224 >::const_type
|
Chris@16
|
225 get(const cons<HT, TT>& c BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int, N)) {
|
Chris@16
|
226 typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
Chris@16
|
227 apply<cons<HT, TT> > impl;
|
Chris@16
|
228 typedef BOOST_DEDUCED_TYPENAME impl::type cons_element;
|
Chris@16
|
229 return impl::call(c).head;
|
Chris@16
|
230 }
|
Chris@16
|
231
|
Chris@16
|
232 // -- the cons template --------------------------------------------------
|
Chris@16
|
233 namespace detail {
|
Chris@16
|
234
|
Chris@16
|
235 // These helper templates wrap void types and plain function types.
|
Chris@16
|
236 // The reationale is to allow one to write tuple types with those types
|
Chris@16
|
237 // as elements, even though it is not possible to instantiate such object.
|
Chris@16
|
238 // E.g: typedef tuple<void> some_type; // ok
|
Chris@16
|
239 // but: some_type x; // fails
|
Chris@16
|
240
|
Chris@16
|
241 template <class T> class non_storeable_type {
|
Chris@16
|
242 non_storeable_type();
|
Chris@16
|
243 };
|
Chris@16
|
244
|
Chris@16
|
245 template <class T> struct wrap_non_storeable_type {
|
Chris@16
|
246 typedef typename IF<
|
Chris@16
|
247 ::boost::is_function<T>::value, non_storeable_type<T>, T
|
Chris@16
|
248 >::RET type;
|
Chris@16
|
249 };
|
Chris@16
|
250 template <> struct wrap_non_storeable_type<void> {
|
Chris@16
|
251 typedef non_storeable_type<void> type;
|
Chris@16
|
252 };
|
Chris@16
|
253
|
Chris@16
|
254 } // detail
|
Chris@16
|
255
|
Chris@16
|
256 template <class HT, class TT>
|
Chris@16
|
257 struct cons {
|
Chris@16
|
258
|
Chris@16
|
259 typedef HT head_type;
|
Chris@16
|
260 typedef TT tail_type;
|
Chris@16
|
261
|
Chris@16
|
262 typedef typename
|
Chris@16
|
263 detail::wrap_non_storeable_type<head_type>::type stored_head_type;
|
Chris@16
|
264
|
Chris@16
|
265 stored_head_type head;
|
Chris@16
|
266 tail_type tail;
|
Chris@16
|
267
|
Chris@16
|
268 typename access_traits<stored_head_type>::non_const_type
|
Chris@16
|
269 get_head() { return head; }
|
Chris@16
|
270
|
Chris@16
|
271 typename access_traits<tail_type>::non_const_type
|
Chris@16
|
272 get_tail() { return tail; }
|
Chris@16
|
273
|
Chris@16
|
274 typename access_traits<stored_head_type>::const_type
|
Chris@16
|
275 get_head() const { return head; }
|
Chris@16
|
276
|
Chris@16
|
277 typename access_traits<tail_type>::const_type
|
Chris@16
|
278 get_tail() const { return tail; }
|
Chris@16
|
279
|
Chris@16
|
280 cons() : head(), tail() {}
|
Chris@16
|
281 // cons() : head(detail::default_arg<HT>::f()), tail() {}
|
Chris@16
|
282
|
Chris@16
|
283 // the argument for head is not strictly needed, but it prevents
|
Chris@16
|
284 // array type elements. This is good, since array type elements
|
Chris@16
|
285 // cannot be supported properly in any case (no assignment,
|
Chris@16
|
286 // copy works only if the tails are exactly the same type, ...)
|
Chris@16
|
287
|
Chris@16
|
288 cons(typename access_traits<stored_head_type>::parameter_type h,
|
Chris@16
|
289 const tail_type& t)
|
Chris@16
|
290 : head (h), tail(t) {}
|
Chris@16
|
291
|
Chris@16
|
292 template <class T1, class T2, class T3, class T4, class T5,
|
Chris@16
|
293 class T6, class T7, class T8, class T9, class T10>
|
Chris@16
|
294 cons( T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
|
Chris@16
|
295 T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )
|
Chris@16
|
296 : head (t1),
|
Chris@16
|
297 tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())
|
Chris@16
|
298 {}
|
Chris@16
|
299
|
Chris@16
|
300 template <class T2, class T3, class T4, class T5,
|
Chris@16
|
301 class T6, class T7, class T8, class T9, class T10>
|
Chris@16
|
302 cons( const null_type& /*t1*/, T2& t2, T3& t3, T4& t4, T5& t5,
|
Chris@16
|
303 T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )
|
Chris@16
|
304 : head (),
|
Chris@16
|
305 tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())
|
Chris@16
|
306 {}
|
Chris@16
|
307
|
Chris@16
|
308
|
Chris@16
|
309 template <class HT2, class TT2>
|
Chris@16
|
310 cons( const cons<HT2, TT2>& u ) : head(u.head), tail(u.tail) {}
|
Chris@16
|
311
|
Chris@16
|
312 template <class HT2, class TT2>
|
Chris@16
|
313 cons& operator=( const cons<HT2, TT2>& u ) {
|
Chris@16
|
314 head=u.head; tail=u.tail; return *this;
|
Chris@16
|
315 }
|
Chris@16
|
316
|
Chris@16
|
317 // must define assignment operator explicitly, implicit version is
|
Chris@16
|
318 // illformed if HT is a reference (12.8. (12))
|
Chris@16
|
319 cons& operator=(const cons& u) {
|
Chris@16
|
320 head = u.head; tail = u.tail; return *this;
|
Chris@16
|
321 }
|
Chris@16
|
322
|
Chris@16
|
323 template <class T1, class T2>
|
Chris@16
|
324 cons& operator=( const std::pair<T1, T2>& u ) {
|
Chris@16
|
325 BOOST_STATIC_ASSERT(length<cons>::value == 2); // check length = 2
|
Chris@16
|
326 head = u.first; tail.head = u.second; return *this;
|
Chris@16
|
327 }
|
Chris@16
|
328
|
Chris@16
|
329 // get member functions (non-const and const)
|
Chris@16
|
330 template <int N>
|
Chris@16
|
331 typename access_traits<
|
Chris@16
|
332 typename element<N, cons<HT, TT> >::type
|
Chris@16
|
333 >::non_const_type
|
Chris@16
|
334 get() {
|
Chris@16
|
335 return boost::tuples::get<N>(*this); // delegate to non-member get
|
Chris@16
|
336 }
|
Chris@16
|
337
|
Chris@16
|
338 template <int N>
|
Chris@16
|
339 typename access_traits<
|
Chris@16
|
340 typename element<N, cons<HT, TT> >::type
|
Chris@16
|
341 >::const_type
|
Chris@16
|
342 get() const {
|
Chris@16
|
343 return boost::tuples::get<N>(*this); // delegate to non-member get
|
Chris@16
|
344 }
|
Chris@16
|
345 };
|
Chris@16
|
346
|
Chris@16
|
347 template <class HT>
|
Chris@16
|
348 struct cons<HT, null_type> {
|
Chris@16
|
349
|
Chris@16
|
350 typedef HT head_type;
|
Chris@16
|
351 typedef null_type tail_type;
|
Chris@16
|
352 typedef cons<HT, null_type> self_type;
|
Chris@16
|
353
|
Chris@16
|
354 typedef typename
|
Chris@16
|
355 detail::wrap_non_storeable_type<head_type>::type stored_head_type;
|
Chris@16
|
356 stored_head_type head;
|
Chris@16
|
357
|
Chris@16
|
358 typename access_traits<stored_head_type>::non_const_type
|
Chris@16
|
359 get_head() { return head; }
|
Chris@16
|
360
|
Chris@16
|
361 null_type get_tail() { return null_type(); }
|
Chris@16
|
362
|
Chris@16
|
363 typename access_traits<stored_head_type>::const_type
|
Chris@16
|
364 get_head() const { return head; }
|
Chris@16
|
365
|
Chris@16
|
366 const null_type get_tail() const { return null_type(); }
|
Chris@16
|
367
|
Chris@16
|
368 // cons() : head(detail::default_arg<HT>::f()) {}
|
Chris@16
|
369 cons() : head() {}
|
Chris@16
|
370
|
Chris@16
|
371 cons(typename access_traits<stored_head_type>::parameter_type h,
|
Chris@16
|
372 const null_type& = null_type())
|
Chris@16
|
373 : head (h) {}
|
Chris@16
|
374
|
Chris@16
|
375 template<class T1>
|
Chris@16
|
376 cons(T1& t1, const null_type&, const null_type&, const null_type&,
|
Chris@16
|
377 const null_type&, const null_type&, const null_type&,
|
Chris@16
|
378 const null_type&, const null_type&, const null_type&)
|
Chris@16
|
379 : head (t1) {}
|
Chris@16
|
380
|
Chris@16
|
381 cons(const null_type&,
|
Chris@16
|
382 const null_type&, const null_type&, const null_type&,
|
Chris@16
|
383 const null_type&, const null_type&, const null_type&,
|
Chris@16
|
384 const null_type&, const null_type&, const null_type&)
|
Chris@16
|
385 : head () {}
|
Chris@16
|
386
|
Chris@16
|
387 template <class HT2>
|
Chris@16
|
388 cons( const cons<HT2, null_type>& u ) : head(u.head) {}
|
Chris@16
|
389
|
Chris@16
|
390 template <class HT2>
|
Chris@16
|
391 cons& operator=(const cons<HT2, null_type>& u )
|
Chris@16
|
392 { head = u.head; return *this; }
|
Chris@16
|
393
|
Chris@16
|
394 // must define assignment operator explicitely, implicit version
|
Chris@16
|
395 // is illformed if HT is a reference
|
Chris@16
|
396 cons& operator=(const cons& u) { head = u.head; return *this; }
|
Chris@16
|
397
|
Chris@16
|
398 template <int N>
|
Chris@16
|
399 typename access_traits<
|
Chris@16
|
400 typename element<N, self_type>::type
|
Chris@16
|
401 >::non_const_type
|
Chris@16
|
402 get(BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int, N)) {
|
Chris@16
|
403 return boost::tuples::get<N>(*this);
|
Chris@16
|
404 }
|
Chris@16
|
405
|
Chris@16
|
406 template <int N>
|
Chris@16
|
407 typename access_traits<
|
Chris@16
|
408 typename element<N, self_type>::type
|
Chris@16
|
409 >::const_type
|
Chris@16
|
410 get(BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int, N)) const {
|
Chris@16
|
411 return boost::tuples::get<N>(*this);
|
Chris@16
|
412 }
|
Chris@16
|
413
|
Chris@16
|
414 };
|
Chris@16
|
415
|
Chris@16
|
416 // templates for finding out the length of the tuple -------------------
|
Chris@16
|
417
|
Chris@16
|
418 template<class T>
|
Chris@16
|
419 struct length {
|
Chris@16
|
420 BOOST_STATIC_CONSTANT(int, value = 1 + length<typename T::tail_type>::value);
|
Chris@16
|
421 };
|
Chris@16
|
422
|
Chris@16
|
423 template<>
|
Chris@16
|
424 struct length<tuple<> > {
|
Chris@16
|
425 BOOST_STATIC_CONSTANT(int, value = 0);
|
Chris@16
|
426 };
|
Chris@16
|
427
|
Chris@16
|
428 template<>
|
Chris@16
|
429 struct length<tuple<> const> {
|
Chris@16
|
430 BOOST_STATIC_CONSTANT(int, value = 0);
|
Chris@16
|
431 };
|
Chris@16
|
432
|
Chris@16
|
433 template<>
|
Chris@16
|
434 struct length<null_type> {
|
Chris@16
|
435 BOOST_STATIC_CONSTANT(int, value = 0);
|
Chris@16
|
436 };
|
Chris@16
|
437
|
Chris@16
|
438 template<>
|
Chris@16
|
439 struct length<null_type const> {
|
Chris@16
|
440 BOOST_STATIC_CONSTANT(int, value = 0);
|
Chris@16
|
441 };
|
Chris@16
|
442
|
Chris@16
|
443 namespace detail {
|
Chris@16
|
444
|
Chris@16
|
445 // Tuple to cons mapper --------------------------------------------------
|
Chris@16
|
446 template <class T0, class T1, class T2, class T3, class T4,
|
Chris@16
|
447 class T5, class T6, class T7, class T8, class T9>
|
Chris@16
|
448 struct map_tuple_to_cons
|
Chris@16
|
449 {
|
Chris@16
|
450 typedef cons<T0,
|
Chris@16
|
451 typename map_tuple_to_cons<T1, T2, T3, T4, T5,
|
Chris@16
|
452 T6, T7, T8, T9, null_type>::type
|
Chris@16
|
453 > type;
|
Chris@16
|
454 };
|
Chris@16
|
455
|
Chris@16
|
456 // The empty tuple is a null_type
|
Chris@16
|
457 template <>
|
Chris@16
|
458 struct map_tuple_to_cons<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type>
|
Chris@16
|
459 {
|
Chris@16
|
460 typedef null_type type;
|
Chris@16
|
461 };
|
Chris@16
|
462
|
Chris@16
|
463 } // end detail
|
Chris@16
|
464
|
Chris@16
|
465 // -------------------------------------------------------------------
|
Chris@16
|
466 // -- tuple ------------------------------------------------------
|
Chris@16
|
467 template <class T0, class T1, class T2, class T3, class T4,
|
Chris@16
|
468 class T5, class T6, class T7, class T8, class T9>
|
Chris@16
|
469
|
Chris@16
|
470 class tuple :
|
Chris@16
|
471 public detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
|
Chris@16
|
472 {
|
Chris@16
|
473 public:
|
Chris@16
|
474 typedef typename
|
Chris@16
|
475 detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type inherited;
|
Chris@16
|
476 typedef typename inherited::head_type head_type;
|
Chris@16
|
477 typedef typename inherited::tail_type tail_type;
|
Chris@16
|
478
|
Chris@16
|
479
|
Chris@16
|
480 // access_traits<T>::parameter_type takes non-reference types as const T&
|
Chris@16
|
481 tuple() {}
|
Chris@16
|
482
|
Chris@16
|
483 tuple(typename access_traits<T0>::parameter_type t0)
|
Chris@16
|
484 : inherited(t0, detail::cnull(), detail::cnull(), detail::cnull(),
|
Chris@16
|
485 detail::cnull(), detail::cnull(), detail::cnull(),
|
Chris@16
|
486 detail::cnull(), detail::cnull(), detail::cnull()) {}
|
Chris@16
|
487
|
Chris@16
|
488 tuple(typename access_traits<T0>::parameter_type t0,
|
Chris@16
|
489 typename access_traits<T1>::parameter_type t1)
|
Chris@16
|
490 : inherited(t0, t1, detail::cnull(), detail::cnull(),
|
Chris@16
|
491 detail::cnull(), detail::cnull(), detail::cnull(),
|
Chris@16
|
492 detail::cnull(), detail::cnull(), detail::cnull()) {}
|
Chris@16
|
493
|
Chris@16
|
494 tuple(typename access_traits<T0>::parameter_type t0,
|
Chris@16
|
495 typename access_traits<T1>::parameter_type t1,
|
Chris@16
|
496 typename access_traits<T2>::parameter_type t2)
|
Chris@16
|
497 : inherited(t0, t1, t2, detail::cnull(), detail::cnull(),
|
Chris@16
|
498 detail::cnull(), detail::cnull(), detail::cnull(),
|
Chris@16
|
499 detail::cnull(), detail::cnull()) {}
|
Chris@16
|
500
|
Chris@16
|
501 tuple(typename access_traits<T0>::parameter_type t0,
|
Chris@16
|
502 typename access_traits<T1>::parameter_type t1,
|
Chris@16
|
503 typename access_traits<T2>::parameter_type t2,
|
Chris@16
|
504 typename access_traits<T3>::parameter_type t3)
|
Chris@16
|
505 : inherited(t0, t1, t2, t3, detail::cnull(), detail::cnull(),
|
Chris@16
|
506 detail::cnull(), detail::cnull(), detail::cnull(),
|
Chris@16
|
507 detail::cnull()) {}
|
Chris@16
|
508
|
Chris@16
|
509 tuple(typename access_traits<T0>::parameter_type t0,
|
Chris@16
|
510 typename access_traits<T1>::parameter_type t1,
|
Chris@16
|
511 typename access_traits<T2>::parameter_type t2,
|
Chris@16
|
512 typename access_traits<T3>::parameter_type t3,
|
Chris@16
|
513 typename access_traits<T4>::parameter_type t4)
|
Chris@16
|
514 : inherited(t0, t1, t2, t3, t4, detail::cnull(), detail::cnull(),
|
Chris@16
|
515 detail::cnull(), detail::cnull(), detail::cnull()) {}
|
Chris@16
|
516
|
Chris@16
|
517 tuple(typename access_traits<T0>::parameter_type t0,
|
Chris@16
|
518 typename access_traits<T1>::parameter_type t1,
|
Chris@16
|
519 typename access_traits<T2>::parameter_type t2,
|
Chris@16
|
520 typename access_traits<T3>::parameter_type t3,
|
Chris@16
|
521 typename access_traits<T4>::parameter_type t4,
|
Chris@16
|
522 typename access_traits<T5>::parameter_type t5)
|
Chris@16
|
523 : inherited(t0, t1, t2, t3, t4, t5, detail::cnull(), detail::cnull(),
|
Chris@16
|
524 detail::cnull(), detail::cnull()) {}
|
Chris@16
|
525
|
Chris@16
|
526 tuple(typename access_traits<T0>::parameter_type t0,
|
Chris@16
|
527 typename access_traits<T1>::parameter_type t1,
|
Chris@16
|
528 typename access_traits<T2>::parameter_type t2,
|
Chris@16
|
529 typename access_traits<T3>::parameter_type t3,
|
Chris@16
|
530 typename access_traits<T4>::parameter_type t4,
|
Chris@16
|
531 typename access_traits<T5>::parameter_type t5,
|
Chris@16
|
532 typename access_traits<T6>::parameter_type t6)
|
Chris@16
|
533 : inherited(t0, t1, t2, t3, t4, t5, t6, detail::cnull(),
|
Chris@16
|
534 detail::cnull(), detail::cnull()) {}
|
Chris@16
|
535
|
Chris@16
|
536 tuple(typename access_traits<T0>::parameter_type t0,
|
Chris@16
|
537 typename access_traits<T1>::parameter_type t1,
|
Chris@16
|
538 typename access_traits<T2>::parameter_type t2,
|
Chris@16
|
539 typename access_traits<T3>::parameter_type t3,
|
Chris@16
|
540 typename access_traits<T4>::parameter_type t4,
|
Chris@16
|
541 typename access_traits<T5>::parameter_type t5,
|
Chris@16
|
542 typename access_traits<T6>::parameter_type t6,
|
Chris@16
|
543 typename access_traits<T7>::parameter_type t7)
|
Chris@16
|
544 : inherited(t0, t1, t2, t3, t4, t5, t6, t7, detail::cnull(),
|
Chris@16
|
545 detail::cnull()) {}
|
Chris@16
|
546
|
Chris@16
|
547 tuple(typename access_traits<T0>::parameter_type t0,
|
Chris@16
|
548 typename access_traits<T1>::parameter_type t1,
|
Chris@16
|
549 typename access_traits<T2>::parameter_type t2,
|
Chris@16
|
550 typename access_traits<T3>::parameter_type t3,
|
Chris@16
|
551 typename access_traits<T4>::parameter_type t4,
|
Chris@16
|
552 typename access_traits<T5>::parameter_type t5,
|
Chris@16
|
553 typename access_traits<T6>::parameter_type t6,
|
Chris@16
|
554 typename access_traits<T7>::parameter_type t7,
|
Chris@16
|
555 typename access_traits<T8>::parameter_type t8)
|
Chris@16
|
556 : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, detail::cnull()) {}
|
Chris@16
|
557
|
Chris@16
|
558 tuple(typename access_traits<T0>::parameter_type t0,
|
Chris@16
|
559 typename access_traits<T1>::parameter_type t1,
|
Chris@16
|
560 typename access_traits<T2>::parameter_type t2,
|
Chris@16
|
561 typename access_traits<T3>::parameter_type t3,
|
Chris@16
|
562 typename access_traits<T4>::parameter_type t4,
|
Chris@16
|
563 typename access_traits<T5>::parameter_type t5,
|
Chris@16
|
564 typename access_traits<T6>::parameter_type t6,
|
Chris@16
|
565 typename access_traits<T7>::parameter_type t7,
|
Chris@16
|
566 typename access_traits<T8>::parameter_type t8,
|
Chris@16
|
567 typename access_traits<T9>::parameter_type t9)
|
Chris@16
|
568 : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) {}
|
Chris@16
|
569
|
Chris@16
|
570
|
Chris@16
|
571 template<class U1, class U2>
|
Chris@16
|
572 tuple(const cons<U1, U2>& p) : inherited(p) {}
|
Chris@16
|
573
|
Chris@16
|
574 template <class U1, class U2>
|
Chris@16
|
575 tuple& operator=(const cons<U1, U2>& k) {
|
Chris@16
|
576 inherited::operator=(k);
|
Chris@16
|
577 return *this;
|
Chris@16
|
578 }
|
Chris@16
|
579
|
Chris@16
|
580 template <class U1, class U2>
|
Chris@16
|
581 tuple& operator=(const std::pair<U1, U2>& k) {
|
Chris@16
|
582 BOOST_STATIC_ASSERT(length<tuple>::value == 2);// check_length = 2
|
Chris@16
|
583 this->head = k.first;
|
Chris@16
|
584 this->tail.head = k.second;
|
Chris@16
|
585 return *this;
|
Chris@16
|
586 }
|
Chris@16
|
587
|
Chris@16
|
588 };
|
Chris@16
|
589
|
Chris@16
|
590 // The empty tuple
|
Chris@16
|
591 template <>
|
Chris@16
|
592 class tuple<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type> :
|
Chris@16
|
593 public null_type
|
Chris@16
|
594 {
|
Chris@16
|
595 public:
|
Chris@16
|
596 typedef null_type inherited;
|
Chris@16
|
597 };
|
Chris@16
|
598
|
Chris@16
|
599
|
Chris@16
|
600 // Swallows any assignment (by Doug Gregor)
|
Chris@16
|
601 namespace detail {
|
Chris@16
|
602
|
Chris@16
|
603 struct swallow_assign;
|
Chris@16
|
604 typedef void (detail::swallow_assign::*ignore_t)();
|
Chris@16
|
605 struct swallow_assign {
|
Chris@16
|
606 swallow_assign(ignore_t(*)(ignore_t)) {}
|
Chris@16
|
607 template<typename T>
|
Chris@16
|
608 swallow_assign const& operator=(const T&) const {
|
Chris@16
|
609 return *this;
|
Chris@16
|
610 }
|
Chris@16
|
611 };
|
Chris@16
|
612
|
Chris@16
|
613
|
Chris@16
|
614 } // namespace detail
|
Chris@16
|
615
|
Chris@16
|
616 // "ignore" allows tuple positions to be ignored when using "tie".
|
Chris@16
|
617 inline detail::ignore_t ignore(detail::ignore_t) { return 0; }
|
Chris@16
|
618
|
Chris@16
|
619 // ---------------------------------------------------------------------------
|
Chris@16
|
620 // The call_traits for make_tuple
|
Chris@16
|
621 // Honours the reference_wrapper class.
|
Chris@16
|
622
|
Chris@16
|
623 // Must be instantiated with plain or const plain types (not with references)
|
Chris@16
|
624
|
Chris@16
|
625 // from template<class T> foo(const T& t) : make_tuple_traits<const T>::type
|
Chris@16
|
626 // from template<class T> foo(T& t) : make_tuple_traits<T>::type
|
Chris@16
|
627
|
Chris@16
|
628 // Conversions:
|
Chris@16
|
629 // T -> T,
|
Chris@16
|
630 // references -> compile_time_error
|
Chris@16
|
631 // reference_wrapper<T> -> T&
|
Chris@16
|
632 // const reference_wrapper<T> -> T&
|
Chris@16
|
633 // array -> const ref array
|
Chris@16
|
634
|
Chris@16
|
635
|
Chris@16
|
636 template<class T>
|
Chris@16
|
637 struct make_tuple_traits {
|
Chris@16
|
638 typedef T type;
|
Chris@16
|
639
|
Chris@16
|
640 // commented away, see below (JJ)
|
Chris@16
|
641 // typedef typename IF<
|
Chris@16
|
642 // boost::is_function<T>::value,
|
Chris@16
|
643 // T&,
|
Chris@16
|
644 // T>::RET type;
|
Chris@16
|
645
|
Chris@16
|
646 };
|
Chris@16
|
647
|
Chris@16
|
648 // The is_function test was there originally for plain function types,
|
Chris@16
|
649 // which can't be stored as such (we must either store them as references or
|
Chris@16
|
650 // pointers). Such a type could be formed if make_tuple was called with a
|
Chris@16
|
651 // reference to a function.
|
Chris@16
|
652 // But this would mean that a const qualified function type was formed in
|
Chris@16
|
653 // the make_tuple function and hence make_tuple can't take a function
|
Chris@16
|
654 // reference as a parameter, and thus T can't be a function type.
|
Chris@16
|
655 // So is_function test was removed.
|
Chris@16
|
656 // (14.8.3. says that type deduction fails if a cv-qualified function type
|
Chris@16
|
657 // is created. (It only applies for the case of explicitly specifying template
|
Chris@16
|
658 // args, though?)) (JJ)
|
Chris@16
|
659
|
Chris@16
|
660 template<class T>
|
Chris@16
|
661 struct make_tuple_traits<T&> {
|
Chris@16
|
662 typedef typename
|
Chris@16
|
663 detail::generate_error<T&>::
|
Chris@16
|
664 do_not_use_with_reference_type error;
|
Chris@16
|
665 };
|
Chris@16
|
666
|
Chris@16
|
667 // Arrays can't be stored as plain types; convert them to references.
|
Chris@16
|
668 // All arrays are converted to const. This is because make_tuple takes its
|
Chris@16
|
669 // parameters as const T& and thus the knowledge of the potential
|
Chris@16
|
670 // non-constness of actual argument is lost.
|
Chris@16
|
671 template<class T, int n> struct make_tuple_traits <T[n]> {
|
Chris@16
|
672 typedef const T (&type)[n];
|
Chris@16
|
673 };
|
Chris@16
|
674
|
Chris@16
|
675 template<class T, int n>
|
Chris@16
|
676 struct make_tuple_traits<const T[n]> {
|
Chris@16
|
677 typedef const T (&type)[n];
|
Chris@16
|
678 };
|
Chris@16
|
679
|
Chris@16
|
680 template<class T, int n> struct make_tuple_traits<volatile T[n]> {
|
Chris@16
|
681 typedef const volatile T (&type)[n];
|
Chris@16
|
682 };
|
Chris@16
|
683
|
Chris@16
|
684 template<class T, int n>
|
Chris@16
|
685 struct make_tuple_traits<const volatile T[n]> {
|
Chris@16
|
686 typedef const volatile T (&type)[n];
|
Chris@16
|
687 };
|
Chris@16
|
688
|
Chris@16
|
689 template<class T>
|
Chris@16
|
690 struct make_tuple_traits<reference_wrapper<T> >{
|
Chris@16
|
691 typedef T& type;
|
Chris@16
|
692 };
|
Chris@16
|
693
|
Chris@16
|
694 template<class T>
|
Chris@16
|
695 struct make_tuple_traits<const reference_wrapper<T> >{
|
Chris@16
|
696 typedef T& type;
|
Chris@16
|
697 };
|
Chris@16
|
698
|
Chris@16
|
699 template<>
|
Chris@16
|
700 struct make_tuple_traits<detail::ignore_t(detail::ignore_t)> {
|
Chris@16
|
701 typedef detail::swallow_assign type;
|
Chris@16
|
702 };
|
Chris@16
|
703
|
Chris@16
|
704
|
Chris@16
|
705
|
Chris@16
|
706 namespace detail {
|
Chris@16
|
707
|
Chris@16
|
708 // a helper traits to make the make_tuple functions shorter (Vesa Karvonen's
|
Chris@16
|
709 // suggestion)
|
Chris@16
|
710 template <
|
Chris@16
|
711 class T0 = null_type, class T1 = null_type, class T2 = null_type,
|
Chris@16
|
712 class T3 = null_type, class T4 = null_type, class T5 = null_type,
|
Chris@16
|
713 class T6 = null_type, class T7 = null_type, class T8 = null_type,
|
Chris@16
|
714 class T9 = null_type
|
Chris@16
|
715 >
|
Chris@16
|
716 struct make_tuple_mapper {
|
Chris@16
|
717 typedef
|
Chris@16
|
718 tuple<typename make_tuple_traits<T0>::type,
|
Chris@16
|
719 typename make_tuple_traits<T1>::type,
|
Chris@16
|
720 typename make_tuple_traits<T2>::type,
|
Chris@16
|
721 typename make_tuple_traits<T3>::type,
|
Chris@16
|
722 typename make_tuple_traits<T4>::type,
|
Chris@16
|
723 typename make_tuple_traits<T5>::type,
|
Chris@16
|
724 typename make_tuple_traits<T6>::type,
|
Chris@16
|
725 typename make_tuple_traits<T7>::type,
|
Chris@16
|
726 typename make_tuple_traits<T8>::type,
|
Chris@16
|
727 typename make_tuple_traits<T9>::type> type;
|
Chris@16
|
728 };
|
Chris@16
|
729
|
Chris@16
|
730 } // end detail
|
Chris@16
|
731
|
Chris@16
|
732 // -make_tuple function templates -----------------------------------
|
Chris@16
|
733 inline tuple<> make_tuple() {
|
Chris@16
|
734 return tuple<>();
|
Chris@16
|
735 }
|
Chris@16
|
736
|
Chris@16
|
737 template<class T0>
|
Chris@16
|
738 inline typename detail::make_tuple_mapper<T0>::type
|
Chris@16
|
739 make_tuple(const T0& t0) {
|
Chris@16
|
740 typedef typename detail::make_tuple_mapper<T0>::type t;
|
Chris@16
|
741 return t(t0);
|
Chris@16
|
742 }
|
Chris@16
|
743
|
Chris@16
|
744 template<class T0, class T1>
|
Chris@16
|
745 inline typename detail::make_tuple_mapper<T0, T1>::type
|
Chris@16
|
746 make_tuple(const T0& t0, const T1& t1) {
|
Chris@16
|
747 typedef typename detail::make_tuple_mapper<T0, T1>::type t;
|
Chris@16
|
748 return t(t0, t1);
|
Chris@16
|
749 }
|
Chris@16
|
750
|
Chris@16
|
751 template<class T0, class T1, class T2>
|
Chris@16
|
752 inline typename detail::make_tuple_mapper<T0, T1, T2>::type
|
Chris@16
|
753 make_tuple(const T0& t0, const T1& t1, const T2& t2) {
|
Chris@16
|
754 typedef typename detail::make_tuple_mapper<T0, T1, T2>::type t;
|
Chris@16
|
755 return t(t0, t1, t2);
|
Chris@16
|
756 }
|
Chris@16
|
757
|
Chris@16
|
758 template<class T0, class T1, class T2, class T3>
|
Chris@16
|
759 inline typename detail::make_tuple_mapper<T0, T1, T2, T3>::type
|
Chris@16
|
760 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3) {
|
Chris@16
|
761 typedef typename detail::make_tuple_mapper<T0, T1, T2, T3>::type t;
|
Chris@16
|
762 return t(t0, t1, t2, t3);
|
Chris@16
|
763 }
|
Chris@16
|
764
|
Chris@16
|
765 template<class T0, class T1, class T2, class T3, class T4>
|
Chris@16
|
766 inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4>::type
|
Chris@16
|
767 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
|
Chris@16
|
768 const T4& t4) {
|
Chris@16
|
769 typedef typename detail::make_tuple_mapper<T0, T1, T2, T3, T4>::type t;
|
Chris@16
|
770 return t(t0, t1, t2, t3, t4);
|
Chris@16
|
771 }
|
Chris@16
|
772
|
Chris@16
|
773 template<class T0, class T1, class T2, class T3, class T4, class T5>
|
Chris@16
|
774 inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5>::type
|
Chris@16
|
775 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
|
Chris@16
|
776 const T4& t4, const T5& t5) {
|
Chris@16
|
777 typedef typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5>::type t;
|
Chris@16
|
778 return t(t0, t1, t2, t3, t4, t5);
|
Chris@16
|
779 }
|
Chris@16
|
780
|
Chris@16
|
781 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6>
|
Chris@16
|
782 inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5, T6>::type
|
Chris@16
|
783 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
|
Chris@16
|
784 const T4& t4, const T5& t5, const T6& t6) {
|
Chris@16
|
785 typedef typename detail::make_tuple_mapper
|
Chris@16
|
786 <T0, T1, T2, T3, T4, T5, T6>::type t;
|
Chris@16
|
787 return t(t0, t1, t2, t3, t4, t5, t6);
|
Chris@16
|
788 }
|
Chris@16
|
789
|
Chris@16
|
790 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
|
Chris@16
|
791 class T7>
|
Chris@16
|
792 inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5, T6, T7>::type
|
Chris@16
|
793 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
|
Chris@16
|
794 const T4& t4, const T5& t5, const T6& t6, const T7& t7) {
|
Chris@16
|
795 typedef typename detail::make_tuple_mapper
|
Chris@16
|
796 <T0, T1, T2, T3, T4, T5, T6, T7>::type t;
|
Chris@16
|
797 return t(t0, t1, t2, t3, t4, t5, t6, t7);
|
Chris@16
|
798 }
|
Chris@16
|
799
|
Chris@16
|
800 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
|
Chris@16
|
801 class T7, class T8>
|
Chris@16
|
802 inline typename detail::make_tuple_mapper
|
Chris@16
|
803 <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type
|
Chris@16
|
804 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
|
Chris@16
|
805 const T4& t4, const T5& t5, const T6& t6, const T7& t7,
|
Chris@16
|
806 const T8& t8) {
|
Chris@16
|
807 typedef typename detail::make_tuple_mapper
|
Chris@16
|
808 <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type t;
|
Chris@16
|
809 return t(t0, t1, t2, t3, t4, t5, t6, t7, t8);
|
Chris@16
|
810 }
|
Chris@16
|
811
|
Chris@16
|
812 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
|
Chris@16
|
813 class T7, class T8, class T9>
|
Chris@16
|
814 inline typename detail::make_tuple_mapper
|
Chris@16
|
815 <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
|
Chris@16
|
816 make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
|
Chris@16
|
817 const T4& t4, const T5& t5, const T6& t6, const T7& t7,
|
Chris@16
|
818 const T8& t8, const T9& t9) {
|
Chris@16
|
819 typedef typename detail::make_tuple_mapper
|
Chris@16
|
820 <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type t;
|
Chris@16
|
821 return t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9);
|
Chris@16
|
822 }
|
Chris@16
|
823
|
Chris@16
|
824 namespace detail {
|
Chris@16
|
825
|
Chris@16
|
826 template<class T>
|
Chris@16
|
827 struct tie_traits {
|
Chris@16
|
828 typedef T& type;
|
Chris@16
|
829 };
|
Chris@16
|
830
|
Chris@16
|
831 template<>
|
Chris@16
|
832 struct tie_traits<ignore_t(ignore_t)> {
|
Chris@16
|
833 typedef swallow_assign type;
|
Chris@16
|
834 };
|
Chris@16
|
835
|
Chris@16
|
836 template<>
|
Chris@16
|
837 struct tie_traits<void> {
|
Chris@16
|
838 typedef null_type type;
|
Chris@16
|
839 };
|
Chris@16
|
840
|
Chris@16
|
841 template <
|
Chris@16
|
842 class T0 = void, class T1 = void, class T2 = void,
|
Chris@16
|
843 class T3 = void, class T4 = void, class T5 = void,
|
Chris@16
|
844 class T6 = void, class T7 = void, class T8 = void,
|
Chris@16
|
845 class T9 = void
|
Chris@16
|
846 >
|
Chris@16
|
847 struct tie_mapper {
|
Chris@16
|
848 typedef
|
Chris@16
|
849 tuple<typename tie_traits<T0>::type,
|
Chris@16
|
850 typename tie_traits<T1>::type,
|
Chris@16
|
851 typename tie_traits<T2>::type,
|
Chris@16
|
852 typename tie_traits<T3>::type,
|
Chris@16
|
853 typename tie_traits<T4>::type,
|
Chris@16
|
854 typename tie_traits<T5>::type,
|
Chris@16
|
855 typename tie_traits<T6>::type,
|
Chris@16
|
856 typename tie_traits<T7>::type,
|
Chris@16
|
857 typename tie_traits<T8>::type,
|
Chris@16
|
858 typename tie_traits<T9>::type> type;
|
Chris@16
|
859 };
|
Chris@16
|
860
|
Chris@16
|
861 }
|
Chris@16
|
862
|
Chris@16
|
863 // Tie function templates -------------------------------------------------
|
Chris@16
|
864 template<class T0>
|
Chris@16
|
865 inline typename detail::tie_mapper<T0>::type
|
Chris@16
|
866 tie(T0& t0) {
|
Chris@16
|
867 typedef typename detail::tie_mapper<T0>::type t;
|
Chris@16
|
868 return t(t0);
|
Chris@16
|
869 }
|
Chris@16
|
870
|
Chris@16
|
871 template<class T0, class T1>
|
Chris@16
|
872 inline typename detail::tie_mapper<T0, T1>::type
|
Chris@16
|
873 tie(T0& t0, T1& t1) {
|
Chris@16
|
874 typedef typename detail::tie_mapper<T0, T1>::type t;
|
Chris@16
|
875 return t(t0, t1);
|
Chris@16
|
876 }
|
Chris@16
|
877
|
Chris@16
|
878 template<class T0, class T1, class T2>
|
Chris@16
|
879 inline typename detail::tie_mapper<T0, T1, T2>::type
|
Chris@16
|
880 tie(T0& t0, T1& t1, T2& t2) {
|
Chris@16
|
881 typedef typename detail::tie_mapper<T0, T1, T2>::type t;
|
Chris@16
|
882 return t(t0, t1, t2);
|
Chris@16
|
883 }
|
Chris@16
|
884
|
Chris@16
|
885 template<class T0, class T1, class T2, class T3>
|
Chris@16
|
886 inline typename detail::tie_mapper<T0, T1, T2, T3>::type
|
Chris@16
|
887 tie(T0& t0, T1& t1, T2& t2, T3& t3) {
|
Chris@16
|
888 typedef typename detail::tie_mapper<T0, T1, T2, T3>::type t;
|
Chris@16
|
889 return t(t0, t1, t2, t3);
|
Chris@16
|
890 }
|
Chris@16
|
891
|
Chris@16
|
892 template<class T0, class T1, class T2, class T3, class T4>
|
Chris@16
|
893 inline typename detail::tie_mapper<T0, T1, T2, T3, T4>::type
|
Chris@16
|
894 tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
Chris@16
|
895 T4& t4) {
|
Chris@16
|
896 typedef typename detail::tie_mapper<T0, T1, T2, T3, T4>::type t;
|
Chris@16
|
897 return t(t0, t1, t2, t3, t4);
|
Chris@16
|
898 }
|
Chris@16
|
899
|
Chris@16
|
900 template<class T0, class T1, class T2, class T3, class T4, class T5>
|
Chris@16
|
901 inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5>::type
|
Chris@16
|
902 tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
Chris@16
|
903 T4& t4, T5& t5) {
|
Chris@16
|
904 typedef typename detail::tie_mapper<T0, T1, T2, T3, T4, T5>::type t;
|
Chris@16
|
905 return t(t0, t1, t2, t3, t4, t5);
|
Chris@16
|
906 }
|
Chris@16
|
907
|
Chris@16
|
908 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6>
|
Chris@16
|
909 inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5, T6>::type
|
Chris@16
|
910 tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
Chris@16
|
911 T4& t4, T5& t5, T6& t6) {
|
Chris@16
|
912 typedef typename detail::tie_mapper
|
Chris@16
|
913 <T0, T1, T2, T3, T4, T5, T6>::type t;
|
Chris@16
|
914 return t(t0, t1, t2, t3, t4, t5, t6);
|
Chris@16
|
915 }
|
Chris@16
|
916
|
Chris@16
|
917 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
|
Chris@16
|
918 class T7>
|
Chris@16
|
919 inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5, T6, T7>::type
|
Chris@16
|
920 tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
Chris@16
|
921 T4& t4, T5& t5, T6& t6, T7& t7) {
|
Chris@16
|
922 typedef typename detail::tie_mapper
|
Chris@16
|
923 <T0, T1, T2, T3, T4, T5, T6, T7>::type t;
|
Chris@16
|
924 return t(t0, t1, t2, t3, t4, t5, t6, t7);
|
Chris@16
|
925 }
|
Chris@16
|
926
|
Chris@16
|
927 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
|
Chris@16
|
928 class T7, class T8>
|
Chris@16
|
929 inline typename detail::tie_mapper
|
Chris@16
|
930 <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type
|
Chris@16
|
931 tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
Chris@16
|
932 T4& t4, T5& t5, T6& t6, T7& t7,
|
Chris@16
|
933 T8& t8) {
|
Chris@16
|
934 typedef typename detail::tie_mapper
|
Chris@16
|
935 <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type t;
|
Chris@16
|
936 return t(t0, t1, t2, t3, t4, t5, t6, t7, t8);
|
Chris@16
|
937 }
|
Chris@16
|
938
|
Chris@16
|
939 template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
|
Chris@16
|
940 class T7, class T8, class T9>
|
Chris@16
|
941 inline typename detail::tie_mapper
|
Chris@16
|
942 <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
|
Chris@16
|
943 tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
Chris@16
|
944 T4& t4, T5& t5, T6& t6, T7& t7,
|
Chris@16
|
945 T8& t8, T9& t9) {
|
Chris@16
|
946 typedef typename detail::tie_mapper
|
Chris@16
|
947 <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type t;
|
Chris@16
|
948 return t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9);
|
Chris@16
|
949 }
|
Chris@16
|
950
|
Chris@16
|
951 template <class T0, class T1, class T2, class T3, class T4,
|
Chris@16
|
952 class T5, class T6, class T7, class T8, class T9>
|
Chris@16
|
953 void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
|
Chris@16
|
954 tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs);
|
Chris@16
|
955 inline void swap(null_type&, null_type&) {}
|
Chris@16
|
956 template<class HH>
|
Chris@16
|
957 inline void swap(cons<HH, null_type>& lhs, cons<HH, null_type>& rhs) {
|
Chris@16
|
958 ::boost::swap(lhs.head, rhs.head);
|
Chris@16
|
959 }
|
Chris@16
|
960 template<class HH, class TT>
|
Chris@16
|
961 inline void swap(cons<HH, TT>& lhs, cons<HH, TT>& rhs) {
|
Chris@16
|
962 ::boost::swap(lhs.head, rhs.head);
|
Chris@16
|
963 ::boost::tuples::swap(lhs.tail, rhs.tail);
|
Chris@16
|
964 }
|
Chris@16
|
965 template <class T0, class T1, class T2, class T3, class T4,
|
Chris@16
|
966 class T5, class T6, class T7, class T8, class T9>
|
Chris@16
|
967 inline void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
|
Chris@16
|
968 tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs) {
|
Chris@16
|
969 typedef tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> tuple_type;
|
Chris@16
|
970 typedef typename tuple_type::inherited base;
|
Chris@16
|
971 ::boost::tuples::swap(static_cast<base&>(lhs), static_cast<base&>(rhs));
|
Chris@16
|
972 }
|
Chris@16
|
973
|
Chris@16
|
974 } // end of namespace tuples
|
Chris@16
|
975 } // end of namespace boost
|
Chris@16
|
976
|
Chris@16
|
977
|
Chris@16
|
978 #endif // BOOST_TUPLE_BASIC_HPP
|
Chris@16
|
979
|
Chris@16
|
980
|