libstdc++
tuple
Go to the documentation of this file.
1 // <tuple> -*- C++ -*-
2 
3 // Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
24 
25 /** @file include/tuple
26  * This is a Standard C++ Library header.
27  */
28 
29 #ifndef _GLIBCXX_TUPLE
30 #define _GLIBCXX_TUPLE 1
31 
32 #pragma GCC system_header
33 
34 #ifndef __GXX_EXPERIMENTAL_CXX0X__
35 # include <bits/c++0x_warning.h>
36 #else
37 
38 #include <utility>
39 #include <bits/uses_allocator.h>
40 
41 namespace std _GLIBCXX_VISIBILITY(default)
42 {
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
44 
45  // Adds a const reference to a non-reference type.
46  template<typename _Tp>
47  struct __add_c_ref
48  { typedef const _Tp& type; };
49 
50  template<typename _Tp>
51  struct __add_c_ref<_Tp&>
52  { typedef _Tp& type; };
53 
54  // Adds a reference to a non-reference type.
55  template<typename _Tp>
56  struct __add_ref
57  { typedef _Tp& type; };
58 
59  template<typename _Tp>
60  struct __add_ref<_Tp&>
61  { typedef _Tp& type; };
62 
63  // Adds an rvalue reference to a non-reference type.
64  template<typename _Tp>
65  struct __add_r_ref
66  { typedef _Tp&& type; };
67 
68  template<typename _Tp>
69  struct __add_r_ref<_Tp&>
70  { typedef _Tp& type; };
71 
72  template<std::size_t _Idx, typename _Head, bool _IsEmptyNotFinal>
73  struct _Head_base;
74 
75  template<std::size_t _Idx, typename _Head>
76  struct _Head_base<_Idx, _Head, true>
77  : public _Head
78  {
79  constexpr _Head_base()
80  : _Head() { }
81 
82  constexpr _Head_base(const _Head& __h)
83  : _Head(__h) { }
84 
85  template<typename _UHead, typename = typename
86  enable_if<!is_convertible<_UHead,
87  __uses_alloc_base>::value>::type>
88  constexpr _Head_base(_UHead&& __h)
89  : _Head(std::forward<_UHead>(__h)) { }
90 
91  _Head_base(__uses_alloc0)
92  : _Head() { }
93 
94  template<typename _Alloc>
95  _Head_base(__uses_alloc1<_Alloc> __a)
96  : _Head(allocator_arg, *__a._M_a) { }
97 
98  template<typename _Alloc>
99  _Head_base(__uses_alloc2<_Alloc> __a)
100  : _Head(*__a._M_a) { }
101 
102  template<typename _UHead>
103  _Head_base(__uses_alloc0, _UHead&& __uhead)
104  : _Head(std::forward<_UHead>(__uhead)) { }
105 
106  template<typename _Alloc, typename _UHead>
107  _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
108  : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
109 
110  template<typename _Alloc, typename _UHead>
111  _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
112  : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
113 
114  static constexpr _Head&
115  _M_head(_Head_base& __b) noexcept { return __b; }
116 
117  static constexpr const _Head&
118  _M_head(const _Head_base& __b) noexcept { return __b; }
119  };
120 
121  template<std::size_t _Idx, typename _Head>
122  struct _Head_base<_Idx, _Head, false>
123  {
124  constexpr _Head_base()
125  : _M_head_impl() { }
126 
127  constexpr _Head_base(const _Head& __h)
128  : _M_head_impl(__h) { }
129 
130  template<typename _UHead, typename = typename
131  enable_if<!is_convertible<_UHead,
132  __uses_alloc_base>::value>::type>
133  constexpr _Head_base(_UHead&& __h)
134  : _M_head_impl(std::forward<_UHead>(__h)) { }
135 
136  _Head_base(__uses_alloc0)
137  : _M_head_impl() { }
138 
139  template<typename _Alloc>
140  _Head_base(__uses_alloc1<_Alloc> __a)
141  : _M_head_impl(allocator_arg, *__a._M_a) { }
142 
143  template<typename _Alloc>
144  _Head_base(__uses_alloc2<_Alloc> __a)
145  : _M_head_impl(*__a._M_a) { }
146 
147  template<typename _UHead>
148  _Head_base(__uses_alloc0, _UHead&& __uhead)
149  : _M_head_impl(std::forward<_UHead>(__uhead)) { }
150 
151  template<typename _Alloc, typename _UHead>
152  _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
153  : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
154  { }
155 
156  template<typename _Alloc, typename _UHead>
157  _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
158  : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
159 
160  static constexpr _Head&
161  _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
162 
163  static constexpr const _Head&
164  _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
165 
166  _Head _M_head_impl;
167  };
168 
169  /**
170  * Contains the actual implementation of the @c tuple template, stored
171  * as a recursive inheritance hierarchy from the first element (most
172  * derived class) to the last (least derived class). The @c Idx
173  * parameter gives the 0-based index of the element stored at this
174  * point in the hierarchy; we use it to implement a constant-time
175  * get() operation.
176  */
177  template<std::size_t _Idx, typename... _Elements>
178  struct _Tuple_impl;
179 
180  /**
181  * Zero-element tuple implementation. This is the basis case for the
182  * inheritance recursion.
183  */
184  template<std::size_t _Idx>
185  struct _Tuple_impl<_Idx>
186  {
187  template<std::size_t, typename...> friend class _Tuple_impl;
188 
189  _Tuple_impl() = default;
190 
191  template<typename _Alloc>
192  _Tuple_impl(allocator_arg_t, const _Alloc&) { }
193 
194  template<typename _Alloc>
195  _Tuple_impl(allocator_arg_t, const _Alloc&, const _Tuple_impl&) { }
196 
197  template<typename _Alloc>
198  _Tuple_impl(allocator_arg_t, const _Alloc&, _Tuple_impl&&) { }
199 
200  protected:
201  void _M_swap(_Tuple_impl&) noexcept { /* no-op */ }
202  };
203 
204  // Use the Empty Base-class Optimization for empty, non-final types.
205  template<typename _Tp>
206  using __empty_not_final
208 
209  /**
210  * Recursive tuple implementation. Here we store the @c Head element
211  * and derive from a @c Tuple_impl containing the remaining elements
212  * (which contains the @c Tail).
213  */
214  template<std::size_t _Idx, typename _Head, typename... _Tail>
215  struct _Tuple_impl<_Idx, _Head, _Tail...>
216  : public _Tuple_impl<_Idx + 1, _Tail...>,
217  private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value>
218  {
219  template<std::size_t, typename...> friend class _Tuple_impl;
220 
221  typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
222  typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base;
223 
224  static constexpr _Head&
225  _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
226 
227  static constexpr const _Head&
228  _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
229 
230  static constexpr _Inherited&
231  _M_tail(_Tuple_impl& __t) noexcept { return __t; }
232 
233  static constexpr const _Inherited&
234  _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
235 
236  constexpr _Tuple_impl()
237  : _Inherited(), _Base() { }
238 
239  explicit
240  constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
241  : _Inherited(__tail...), _Base(__head) { }
242 
243  template<typename _UHead, typename... _UTail, typename = typename
244  enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type>
245  explicit
246  constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
247  : _Inherited(std::forward<_UTail>(__tail)...),
248  _Base(std::forward<_UHead>(__head)) { }
249 
250  constexpr _Tuple_impl(const _Tuple_impl&) = default;
251 
252  constexpr
253  _Tuple_impl(_Tuple_impl&& __in)
254  noexcept(__and_<is_nothrow_move_constructible<_Head>,
256  : _Inherited(std::move(_M_tail(__in))),
257  _Base(std::forward<_Head>(_M_head(__in))) { }
258 
259  template<typename... _UElements>
260  constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
261  : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
262  _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
263 
264  template<typename _UHead, typename... _UTails>
265  constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
266  : _Inherited(std::move
267  (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
268  _Base(std::forward<_UHead>
269  (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
270 
271  template<typename _Alloc>
272  _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
273  : _Inherited(__tag, __a),
274  _Base(__use_alloc<_Head>(__a)) { }
275 
276  template<typename _Alloc>
277  _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
278  const _Head& __head, const _Tail&... __tail)
279  : _Inherited(__tag, __a, __tail...),
280  _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
281 
282  template<typename _Alloc, typename _UHead, typename... _UTail,
283  typename = typename enable_if<sizeof...(_Tail)
284  == sizeof...(_UTail)>::type>
285  _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
286  _UHead&& __head, _UTail&&... __tail)
287  : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
288  _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
289  std::forward<_UHead>(__head)) { }
290 
291  template<typename _Alloc>
292  _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
293  const _Tuple_impl& __in)
294  : _Inherited(__tag, __a, _M_tail(__in)),
295  _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
296 
297  template<typename _Alloc>
298  _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
299  _Tuple_impl&& __in)
300  : _Inherited(__tag, __a, std::move(_M_tail(__in))),
301  _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
302  std::forward<_Head>(_M_head(__in))) { }
303 
304  template<typename _Alloc, typename... _UElements>
305  _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
306  const _Tuple_impl<_Idx, _UElements...>& __in)
307  : _Inherited(__tag, __a,
308  _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
309  _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
310  _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
311 
312  template<typename _Alloc, typename _UHead, typename... _UTails>
313  _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
314  _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
315  : _Inherited(__tag, __a, std::move
316  (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
317  _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
318  std::forward<_UHead>
319  (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
320 
321  _Tuple_impl&
322  operator=(const _Tuple_impl& __in)
323  {
324  _M_head(*this) = _M_head(__in);
325  _M_tail(*this) = _M_tail(__in);
326  return *this;
327  }
328 
329  _Tuple_impl&
330  operator=(_Tuple_impl&& __in)
331  noexcept(__and_<is_nothrow_move_assignable<_Head>,
333  {
334  _M_head(*this) = std::forward<_Head>(_M_head(__in));
335  _M_tail(*this) = std::move(_M_tail(__in));
336  return *this;
337  }
338 
339  template<typename... _UElements>
340  _Tuple_impl&
341  operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
342  {
343  _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
344  _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in);
345  return *this;
346  }
347 
348  template<typename _UHead, typename... _UTails>
349  _Tuple_impl&
350  operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
351  {
352  _M_head(*this) = std::forward<_UHead>
353  (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
354  _M_tail(*this) = std::move
355  (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in));
356  return *this;
357  }
358 
359  protected:
360  void
361  _M_swap(_Tuple_impl& __in)
362  noexcept(noexcept(swap(std::declval<_Head&>(),
363  std::declval<_Head&>()))
364  && noexcept(_M_tail(__in)._M_swap(_M_tail(__in))))
365  {
366  using std::swap;
367  swap(_M_head(*this), _M_head(__in));
368  _Inherited::_M_swap(_M_tail(__in));
369  }
370  };
371 
372  /// Primary class template, tuple
373  template<typename... _Elements>
374  class tuple : public _Tuple_impl<0, _Elements...>
375  {
376  typedef _Tuple_impl<0, _Elements...> _Inherited;
377 
378  public:
379  constexpr tuple()
380  : _Inherited() { }
381 
382  explicit
383  constexpr tuple(const _Elements&... __elements)
384  : _Inherited(__elements...) { }
385 
386  template<typename... _UElements, typename = typename
387  enable_if<__and_<is_convertible<_UElements,
388  _Elements>...>::value>::type>
389  explicit
390  constexpr tuple(_UElements&&... __elements)
391  : _Inherited(std::forward<_UElements>(__elements)...) { }
392 
393  constexpr tuple(const tuple&) = default;
394 
395  constexpr tuple(tuple&&) = default;
396 
397  template<typename... _UElements, typename = typename
398  enable_if<__and_<is_convertible<const _UElements&,
399  _Elements>...>::value>::type>
400  constexpr tuple(const tuple<_UElements...>& __in)
401  : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
402  { }
403 
404  template<typename... _UElements, typename = typename
405  enable_if<__and_<is_convertible<_UElements,
406  _Elements>...>::value>::type>
407  constexpr tuple(tuple<_UElements...>&& __in)
408  : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
409 
410  // Allocator-extended constructors.
411 
412  template<typename _Alloc>
413  tuple(allocator_arg_t __tag, const _Alloc& __a)
414  : _Inherited(__tag, __a) { }
415 
416  template<typename _Alloc>
417  tuple(allocator_arg_t __tag, const _Alloc& __a,
418  const _Elements&... __elements)
419  : _Inherited(__tag, __a, __elements...) { }
420 
421  template<typename _Alloc, typename... _UElements, typename = typename
422  enable_if<sizeof...(_UElements)
423  == sizeof...(_Elements)>::type>
424  tuple(allocator_arg_t __tag, const _Alloc& __a,
425  _UElements&&... __elements)
426  : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
427  { }
428 
429  template<typename _Alloc>
430  tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
431  : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
432 
433  template<typename _Alloc>
434  tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
435  : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
436 
437  template<typename _Alloc, typename... _UElements, typename = typename
438  enable_if<sizeof...(_UElements)
439  == sizeof...(_Elements)>::type>
440  tuple(allocator_arg_t __tag, const _Alloc& __a,
441  const tuple<_UElements...>& __in)
442  : _Inherited(__tag, __a,
443  static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
444  { }
445 
446  template<typename _Alloc, typename... _UElements, typename = typename
447  enable_if<sizeof...(_UElements)
448  == sizeof...(_Elements)>::type>
449  tuple(allocator_arg_t __tag, const _Alloc& __a,
450  tuple<_UElements...>&& __in)
451  : _Inherited(__tag, __a,
452  static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
453  { }
454 
455  tuple&
456  operator=(const tuple& __in)
457  {
458  static_cast<_Inherited&>(*this) = __in;
459  return *this;
460  }
461 
462  tuple&
463  operator=(tuple&& __in)
465  {
466  static_cast<_Inherited&>(*this) = std::move(__in);
467  return *this;
468  }
469 
470  template<typename... _UElements, typename = typename
471  enable_if<sizeof...(_UElements)
472  == sizeof...(_Elements)>::type>
473  tuple&
474  operator=(const tuple<_UElements...>& __in)
475  {
476  static_cast<_Inherited&>(*this) = __in;
477  return *this;
478  }
479 
480  template<typename... _UElements, typename = typename
481  enable_if<sizeof...(_UElements)
482  == sizeof...(_Elements)>::type>
483  tuple&
484  operator=(tuple<_UElements...>&& __in)
485  {
486  static_cast<_Inherited&>(*this) = std::move(__in);
487  return *this;
488  }
489 
490  void
491  swap(tuple& __in)
492  noexcept(noexcept(__in._M_swap(__in)))
493  { _Inherited::_M_swap(__in); }
494  };
495 
496  // Explicit specialization, zero-element tuple.
497  template<>
498  class tuple<>
499  {
500  public:
501  void swap(tuple&) noexcept { /* no-op */ }
502  };
503 
504  /// Partial specialization, 2-element tuple.
505  /// Includes construction and assignment from a pair.
506  template<typename _T1, typename _T2>
507  class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
508  {
509  typedef _Tuple_impl<0, _T1, _T2> _Inherited;
510 
511  public:
512  constexpr tuple()
513  : _Inherited() { }
514 
515  explicit
516  constexpr tuple(const _T1& __a1, const _T2& __a2)
517  : _Inherited(__a1, __a2) { }
518 
519  template<typename _U1, typename _U2, typename = typename
521  is_convertible<_U2, _T2>>::value>::type>
522  explicit
523  constexpr tuple(_U1&& __a1, _U2&& __a2)
524  : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
525 
526  constexpr tuple(const tuple&) = default;
527 
528  constexpr tuple(tuple&&) = default;
529 
530  template<typename _U1, typename _U2, typename = typename
532  is_convertible<const _U2&, _T2>>::value>::type>
533  constexpr tuple(const tuple<_U1, _U2>& __in)
534  : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
535 
536  template<typename _U1, typename _U2, typename = typename
538  is_convertible<_U2, _T2>>::value>::type>
539  constexpr tuple(tuple<_U1, _U2>&& __in)
540  : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
541 
542  template<typename _U1, typename _U2, typename = typename
544  is_convertible<const _U2&, _T2>>::value>::type>
545  constexpr tuple(const pair<_U1, _U2>& __in)
546  : _Inherited(__in.first, __in.second) { }
547 
548  template<typename _U1, typename _U2, typename = typename
550  is_convertible<_U2, _T2>>::value>::type>
551  constexpr tuple(pair<_U1, _U2>&& __in)
552  : _Inherited(std::forward<_U1>(__in.first),
553  std::forward<_U2>(__in.second)) { }
554 
555  // Allocator-extended constructors.
556 
557  template<typename _Alloc>
558  tuple(allocator_arg_t __tag, const _Alloc& __a)
559  : _Inherited(__tag, __a) { }
560 
561  template<typename _Alloc>
562  tuple(allocator_arg_t __tag, const _Alloc& __a,
563  const _T1& __a1, const _T2& __a2)
564  : _Inherited(__tag, __a, __a1, __a2) { }
565 
566  template<typename _Alloc, typename _U1, typename _U2>
567  tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
568  : _Inherited(__tag, __a, std::forward<_U1>(__a1),
569  std::forward<_U2>(__a2)) { }
570 
571  template<typename _Alloc>
572  tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
573  : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
574 
575  template<typename _Alloc>
576  tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
577  : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
578 
579  template<typename _Alloc, typename _U1, typename _U2>
580  tuple(allocator_arg_t __tag, const _Alloc& __a,
581  const tuple<_U1, _U2>& __in)
582  : _Inherited(__tag, __a,
583  static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
584  { }
585 
586  template<typename _Alloc, typename _U1, typename _U2>
587  tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
588  : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
589  { }
590 
591  template<typename _Alloc, typename _U1, typename _U2>
592  tuple(allocator_arg_t __tag, const _Alloc& __a,
593  const pair<_U1, _U2>& __in)
594  : _Inherited(__tag, __a, __in.first, __in.second) { }
595 
596  template<typename _Alloc, typename _U1, typename _U2>
597  tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
598  : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
599  std::forward<_U2>(__in.second)) { }
600 
601  tuple&
602  operator=(const tuple& __in)
603  {
604  static_cast<_Inherited&>(*this) = __in;
605  return *this;
606  }
607 
608  tuple&
609  operator=(tuple&& __in)
611  {
612  static_cast<_Inherited&>(*this) = std::move(__in);
613  return *this;
614  }
615 
616  template<typename _U1, typename _U2>
617  tuple&
618  operator=(const tuple<_U1, _U2>& __in)
619  {
620  static_cast<_Inherited&>(*this) = __in;
621  return *this;
622  }
623 
624  template<typename _U1, typename _U2>
625  tuple&
626  operator=(tuple<_U1, _U2>&& __in)
627  {
628  static_cast<_Inherited&>(*this) = std::move(__in);
629  return *this;
630  }
631 
632  template<typename _U1, typename _U2>
633  tuple&
634  operator=(const pair<_U1, _U2>& __in)
635  {
636  this->_M_head(*this) = __in.first;
637  this->_M_tail(*this)._M_head(*this) = __in.second;
638  return *this;
639  }
640 
641  template<typename _U1, typename _U2>
642  tuple&
643  operator=(pair<_U1, _U2>&& __in)
644  {
645  this->_M_head(*this) = std::forward<_U1>(__in.first);
646  this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
647  return *this;
648  }
649 
650  void
651  swap(tuple& __in)
652  noexcept(noexcept(__in._M_swap(__in)))
653  { _Inherited::_M_swap(__in); }
654  };
655 
656 
657  /// Gives the type of the ith element of a given tuple type.
658  template<std::size_t __i, typename _Tp>
659  struct tuple_element;
660 
661  /**
662  * Recursive case for tuple_element: strip off the first element in
663  * the tuple and retrieve the (i-1)th element of the remaining tuple.
664  */
665  template<std::size_t __i, typename _Head, typename... _Tail>
666  struct tuple_element<__i, tuple<_Head, _Tail...> >
667  : tuple_element<__i - 1, tuple<_Tail...> > { };
668 
669  /**
670  * Basis case for tuple_element: The first element is the one we're seeking.
671  */
672  template<typename _Head, typename... _Tail>
673  struct tuple_element<0, tuple<_Head, _Tail...> >
674  {
675  typedef _Head type;
676  };
677 
678  template<std::size_t __i, typename _Tp>
679  struct tuple_element<__i, const _Tp>
680  {
681  typedef typename
683  };
684 
685  template<std::size_t __i, typename _Tp>
686  struct tuple_element<__i, volatile _Tp>
687  {
688  typedef typename
689  add_volatile<typename tuple_element<__i, _Tp>::type>::type type;
690  };
691 
692  template<std::size_t __i, typename _Tp>
693  struct tuple_element<__i, const volatile _Tp>
694  {
695  typedef typename
696  add_cv<typename tuple_element<__i, _Tp>::type>::type type;
697  };
698 
699  /// Finds the size of a given tuple type.
700  template<typename _Tp>
701  struct tuple_size;
702 
703  template<typename _Tp>
704  struct tuple_size<const _Tp>
705  : public integral_constant<
706  typename remove_cv<decltype(tuple_size<_Tp>::value)>::type,
707  tuple_size<_Tp>::value> { };
708 
709  template<typename _Tp>
710  struct tuple_size<volatile _Tp>
711  : public integral_constant<
712  typename remove_cv<decltype(tuple_size<_Tp>::value)>::type,
713  tuple_size<_Tp>::value> { };
714 
715  template<typename _Tp>
716  struct tuple_size<const volatile _Tp>
717  : public integral_constant<
718  typename remove_cv<decltype(tuple_size<_Tp>::value)>::type,
719  tuple_size<_Tp>::value> { };
720 
721  /// class tuple_size
722  template<typename... _Elements>
723  struct tuple_size<tuple<_Elements...>>
724  : public integral_constant<std::size_t, sizeof...(_Elements)> { };
725 
726  template<std::size_t __i, typename _Head, typename... _Tail>
727  constexpr typename __add_ref<_Head>::type
728  __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
729  { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
730 
731  template<std::size_t __i, typename _Head, typename... _Tail>
732  constexpr typename __add_c_ref<_Head>::type
733  __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
734  { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
735 
736  // Return a reference (const reference, rvalue reference) to the ith element
737  // of a tuple. Any const or non-const ref elements are returned with their
738  // original type.
739  template<std::size_t __i, typename... _Elements>
740  constexpr typename __add_ref<
741  typename tuple_element<__i, tuple<_Elements...>>::type
742  >::type
743  get(tuple<_Elements...>& __t) noexcept
744  { return __get_helper<__i>(__t); }
745 
746  template<std::size_t __i, typename... _Elements>
747  constexpr typename __add_c_ref<
748  typename tuple_element<__i, tuple<_Elements...>>::type
749  >::type
750  get(const tuple<_Elements...>& __t) noexcept
751  { return __get_helper<__i>(__t); }
752 
753  template<std::size_t __i, typename... _Elements>
754  constexpr typename __add_r_ref<
755  typename tuple_element<__i, tuple<_Elements...>>::type
756  >::type
757  get(tuple<_Elements...>&& __t) noexcept
758  { return std::forward<typename tuple_element<__i,
759  tuple<_Elements...>>::type&&>(get<__i>(__t)); }
760 
761  // This class helps construct the various comparison operations on tuples
762  template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j,
763  typename _Tp, typename _Up>
764  struct __tuple_compare;
765 
766  template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up>
767  struct __tuple_compare<0, __i, __j, _Tp, _Up>
768  {
769  static bool
770  __eq(const _Tp& __t, const _Up& __u)
771  {
772  return (get<__i>(__t) == get<__i>(__u) &&
773  __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u));
774  }
775 
776  static bool
777  __less(const _Tp& __t, const _Up& __u)
778  {
779  return ((get<__i>(__t) < get<__i>(__u))
780  || !(get<__i>(__u) < get<__i>(__t)) &&
781  __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u));
782  }
783  };
784 
785  template<std::size_t __i, typename _Tp, typename _Up>
786  struct __tuple_compare<0, __i, __i, _Tp, _Up>
787  {
788  static bool
789  __eq(const _Tp&, const _Up&) { return true; }
790 
791  static bool
792  __less(const _Tp&, const _Up&) { return false; }
793  };
794 
795  template<typename... _TElements, typename... _UElements>
796  bool
797  operator==(const tuple<_TElements...>& __t,
798  const tuple<_UElements...>& __u)
799  {
800  typedef tuple<_TElements...> _Tp;
801  typedef tuple<_UElements...> _Up;
802  return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
803  0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
804  }
805 
806  template<typename... _TElements, typename... _UElements>
807  bool
808  operator<(const tuple<_TElements...>& __t,
809  const tuple<_UElements...>& __u)
810  {
811  typedef tuple<_TElements...> _Tp;
812  typedef tuple<_UElements...> _Up;
813  return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
814  0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
815  }
816 
817  template<typename... _TElements, typename... _UElements>
818  inline bool
819  operator!=(const tuple<_TElements...>& __t,
820  const tuple<_UElements...>& __u)
821  { return !(__t == __u); }
822 
823  template<typename... _TElements, typename... _UElements>
824  inline bool
825  operator>(const tuple<_TElements...>& __t,
826  const tuple<_UElements...>& __u)
827  { return __u < __t; }
828 
829  template<typename... _TElements, typename... _UElements>
830  inline bool
831  operator<=(const tuple<_TElements...>& __t,
832  const tuple<_UElements...>& __u)
833  { return !(__u < __t); }
834 
835  template<typename... _TElements, typename... _UElements>
836  inline bool
837  operator>=(const tuple<_TElements...>& __t,
838  const tuple<_UElements...>& __u)
839  { return !(__t < __u); }
840 
841  // NB: DR 705.
842  template<typename... _Elements>
843  constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
844  make_tuple(_Elements&&... __args)
845  {
846  typedef tuple<typename __decay_and_strip<_Elements>::__type...>
847  __result_type;
848  return __result_type(std::forward<_Elements>(__args)...);
849  }
850 
851  template<typename... _Elements>
852  constexpr tuple<_Elements&&...>
853  forward_as_tuple(_Elements&&... __args) noexcept
854  { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
855 
856 
857  template<typename, std::size_t> struct array;
858 
859  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
860  constexpr _Tp& get(array<_Tp, _Nm>&) noexcept;
861 
862  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
863  constexpr _Tp&& get(array<_Tp, _Nm>&&) noexcept;
864 
865  template<std::size_t _Int, typename _Tp, std::size_t _Nm>
866  constexpr const _Tp& get(const array<_Tp, _Nm>&) noexcept;
867 
868  template<typename>
869  struct __is_tuple_like_impl : false_type
870  { };
871 
872  template<typename... _Tps>
873  struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
874  { };
875 
876  template<typename _T1, typename _T2>
877  struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
878  { };
879 
880  template<typename _Tp, std::size_t _Nm>
881  struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type
882  { };
883 
884  // Internal type trait that allows us to sfinae-protect tuple_cat.
885  template<typename _Tp>
886  struct __is_tuple_like
887  : public __is_tuple_like_impl<typename std::remove_cv
888  <typename std::remove_reference<_Tp>::type>::type>::type
889  { };
890 
891  // Stores a tuple of indices. Also used by bind() to extract the elements
892  // in a tuple.
893  template<std::size_t... _Indexes>
894  struct _Index_tuple
895  {
896  typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next;
897  };
898 
899  // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
900  template<std::size_t _Num>
901  struct _Build_index_tuple
902  {
903  typedef typename _Build_index_tuple<_Num - 1>::__type::__next __type;
904  };
905 
906  template<>
907  struct _Build_index_tuple<0>
908  {
909  typedef _Index_tuple<> __type;
910  };
911 
912  template<std::size_t, typename, typename, std::size_t>
913  struct __make_tuple_impl;
914 
915  template<std::size_t _Idx, typename _Tuple, typename... _Tp,
916  std::size_t _Nm>
917  struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
918  {
919  typedef typename __make_tuple_impl<_Idx + 1, tuple<_Tp...,
920  typename std::tuple_element<_Idx, _Tuple>::type>, _Tuple, _Nm>::__type
921  __type;
922  };
923 
924  template<std::size_t _Nm, typename _Tuple, typename... _Tp>
925  struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
926  {
927  typedef tuple<_Tp...> __type;
928  };
929 
930  template<typename _Tuple>
931  struct __do_make_tuple
932  : public __make_tuple_impl<0, tuple<>, _Tuple,
933  std::tuple_size<_Tuple>::value>
934  { };
935 
936  // Returns the std::tuple equivalent of a tuple-like type.
937  template<typename _Tuple>
938  struct __make_tuple
939  : public __do_make_tuple<typename std::remove_cv
940  <typename std::remove_reference<_Tuple>::type>::type>
941  { };
942 
943  // Combines several std::tuple's into a single one.
944  template<typename...>
945  struct __combine_tuples;
946 
947  template<>
948  struct __combine_tuples<>
949  {
950  typedef tuple<> __type;
951  };
952 
953  template<typename... _Ts>
954  struct __combine_tuples<tuple<_Ts...>>
955  {
956  typedef tuple<_Ts...> __type;
957  };
958 
959  template<typename... _T1s, typename... _T2s, typename... _Rem>
960  struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
961  {
962  typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
963  _Rem...>::__type __type;
964  };
965 
966  // Computes the result type of tuple_cat given a set of tuple-like types.
967  template<typename... _Tpls>
968  struct __tuple_cat_result
969  {
970  typedef typename __combine_tuples
971  <typename __make_tuple<_Tpls>::__type...>::__type __type;
972  };
973 
974  // Helper to determine the index set for the first tuple-like
975  // type of a given set.
976  template<typename...>
977  struct __make_1st_indices;
978 
979  template<>
980  struct __make_1st_indices<>
981  {
982  typedef std::_Index_tuple<> __type;
983  };
984 
985  template<typename _Tp, typename... _Tpls>
986  struct __make_1st_indices<_Tp, _Tpls...>
987  {
988  typedef typename std::_Build_index_tuple<std::tuple_size<
989  typename std::remove_reference<_Tp>::type>::value>::__type __type;
990  };
991 
992  // Performs the actual concatenation by step-wise expanding tuple-like
993  // objects into the elements, which are finally forwarded into the
994  // result tuple.
995  template<typename _Ret, typename _Indices, typename... _Tpls>
996  struct __tuple_concater;
997 
998  template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
999  struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
1000  {
1001  template<typename... _Us>
1002  static constexpr _Ret
1003  _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
1004  {
1005  typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1006  typedef __tuple_concater<_Ret, __idx, _Tpls...> __next;
1007  return __next::_S_do(std::forward<_Tpls>(__tps)...,
1008  std::forward<_Us>(__us)...,
1009  std::get<_Is>(std::forward<_Tp>(__tp))...);
1010  }
1011  };
1012 
1013  template<typename _Ret>
1014  struct __tuple_concater<_Ret, std::_Index_tuple<>>
1015  {
1016  template<typename... _Us>
1017  static constexpr _Ret
1018  _S_do(_Us&&... __us)
1019  {
1020  return _Ret(std::forward<_Us>(__us)...);
1021  }
1022  };
1023 
1024  template<typename... _Tpls, typename = typename
1025  enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
1026  constexpr auto
1027  tuple_cat(_Tpls&&... __tpls)
1028  -> typename __tuple_cat_result<_Tpls...>::__type
1029  {
1030  typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
1031  typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1032  typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
1033  return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
1034  }
1035 
1036  template<typename... _Elements>
1037  inline tuple<_Elements&...>
1038  tie(_Elements&... __args) noexcept
1039  { return tuple<_Elements&...>(__args...); }
1040 
1041  template<typename... _Elements>
1042  inline void
1043  swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
1044  noexcept(noexcept(__x.swap(__y)))
1045  { __x.swap(__y); }
1046 
1047  // A class (and instance) which can be used in 'tie' when an element
1048  // of a tuple is not required
1049  struct _Swallow_assign
1050  {
1051  template<class _Tp>
1052  const _Swallow_assign&
1053  operator=(const _Tp&) const
1054  { return *this; }
1055  };
1056 
1057  const _Swallow_assign ignore{};
1058 
1059  /// Partial specialization for tuples
1060  template<typename... _Types, typename _Alloc>
1061  struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
1062 
1063  // See stl_pair.h...
1064  template<class _T1, class _T2>
1065  template<typename... _Args1, typename... _Args2>
1066  inline
1069  tuple<_Args1...> __first, tuple<_Args2...> __second)
1070  : pair(__first, __second,
1071  typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
1072  typename _Build_index_tuple<sizeof...(_Args2)>::__type())
1073  { }
1074 
1075  template<class _T1, class _T2>
1076  template<typename... _Args1, std::size_t... _Indexes1,
1077  typename... _Args2, std::size_t... _Indexes2>
1078  inline
1080  pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
1081  _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
1082  : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
1083  second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
1084  { }
1085 
1086 _GLIBCXX_END_NAMESPACE_VERSION
1087 } // namespace
1088 
1089 #endif // __GXX_EXPERIMENTAL_CXX0X__
1090 
1091 #endif // _GLIBCXX_TUPLE