libstdc++
tuple
1 // <tuple> -*- C++ -*-
2 
3 // Copyright (C) 2007, 2008, 2009 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 <c++0x_warning.h>
36 #else
37 
38 #include <utility>
39 
40 namespace std
41 {
42  // Adds a const reference to a non-reference type.
43  template<typename _Tp>
44  struct __add_c_ref
45  { typedef const _Tp& type; };
46 
47  template<typename _Tp>
48  struct __add_c_ref<_Tp&>
49  { typedef _Tp& type; };
50 
51  // Adds a reference to a non-reference type.
52  template<typename _Tp>
53  struct __add_ref
54  { typedef _Tp& type; };
55 
56  template<typename _Tp>
57  struct __add_ref<_Tp&>
58  { typedef _Tp& type; };
59 
60  template<std::size_t _Idx, typename _Head, bool _IsEmpty>
61  struct _Head_base;
62 
63  template<std::size_t _Idx, typename _Head>
64  struct _Head_base<_Idx, _Head, true>
65  : public _Head
66  {
67  _Head_base()
68  : _Head() { }
69 
70  _Head_base(const _Head& __h)
71  : _Head(__h) { }
72 
73  template<typename _UHead>
74  _Head_base(_UHead&& __h)
75  : _Head(std::forward<_UHead>(__h)) { }
76 
77  _Head& _M_head() { return *this; }
78  const _Head& _M_head() const { return *this; }
79 
80  void _M_swap_impl(_Head&&) { /* no-op */ }
81  };
82 
83  template<std::size_t _Idx, typename _Head>
84  struct _Head_base<_Idx, _Head, false>
85  {
86  _Head_base()
87  : _M_head_impl() { }
88 
89  _Head_base(const _Head& __h)
90  : _M_head_impl(__h) { }
91 
92  template<typename _UHead>
93  _Head_base(_UHead&& __h)
94  : _M_head_impl(std::forward<_UHead>(__h)) { }
95 
96  _Head& _M_head() { return _M_head_impl; }
97  const _Head& _M_head() const { return _M_head_impl; }
98 
99  void
100  _M_swap_impl(_Head&& __h)
101  {
102  using std::swap;
103  swap(__h, _M_head_impl);
104  }
105 
106  _Head _M_head_impl;
107  };
108 
109  /**
110  * Contains the actual implementation of the @c tuple template, stored
111  * as a recursive inheritance hierarchy from the first element (most
112  * derived class) to the last (least derived class). The @c Idx
113  * parameter gives the 0-based index of the element stored at this
114  * point in the hierarchy; we use it to implement a constant-time
115  * get() operation.
116  */
117  template<std::size_t _Idx, typename... _Elements>
118  struct _Tuple_impl;
119 
120  /**
121  * Zero-element tuple implementation. This is the basis case for the
122  * inheritance recursion.
123  */
124  template<std::size_t _Idx>
125  struct _Tuple_impl<_Idx>
126  {
127  protected:
128  void _M_swap_impl(_Tuple_impl&&) { /* no-op */ }
129  };
130 
131  /**
132  * Recursive tuple implementation. Here we store the @c Head element
133  * and derive from a @c Tuple_impl containing the remaining elements
134  * (which contains the @c Tail).
135  */
136  template<std::size_t _Idx, typename _Head, typename... _Tail>
137  struct _Tuple_impl<_Idx, _Head, _Tail...>
138  : public _Tuple_impl<_Idx + 1, _Tail...>,
139  private _Head_base<_Idx, _Head, std::is_empty<_Head>::value>
140  {
141  typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
142  typedef _Head_base<_Idx, _Head, std::is_empty<_Head>::value> _Base;
143 
144  _Head& _M_head() { return _Base::_M_head(); }
145  const _Head& _M_head() const { return _Base::_M_head(); }
146 
147  _Inherited& _M_tail() { return *this; }
148  const _Inherited& _M_tail() const { return *this; }
149 
150  _Tuple_impl()
151  : _Inherited(), _Base() { }
152 
153  explicit
154  _Tuple_impl(const _Head& __head, const _Tail&... __tail)
155  : _Inherited(__tail...), _Base(__head) { }
156 
157  template<typename _UHead, typename... _UTail>
158  explicit
159  _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
160  : _Inherited(std::forward<_UTail>(__tail)...),
161  _Base(std::forward<_UHead>(__head)) { }
162 
163  _Tuple_impl(const _Tuple_impl& __in)
164  : _Inherited(__in._M_tail()), _Base(__in._M_head()) { }
165 
166  _Tuple_impl(_Tuple_impl&& __in)
167  : _Inherited(std::move<_Inherited&&>(__in._M_tail())),
168  _Base(std::forward<_Head>(__in._M_head())) { }
169 
170  template<typename... _UElements>
171  _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
172  : _Inherited(__in._M_tail()), _Base(__in._M_head()) { }
173 
174  template<typename... _UElements>
175  _Tuple_impl(_Tuple_impl<_Idx, _UElements...>&& __in)
176  : _Inherited(std::move<typename _Tuple_impl<_Idx, _UElements...>::
177  _Inherited&&>(__in._M_tail())),
178  _Base(std::forward<typename _Tuple_impl<_Idx, _UElements...>::
179  _Base>(__in._M_head())) { }
180 
181  _Tuple_impl&
182  operator=(const _Tuple_impl& __in)
183  {
184  _M_head() = __in._M_head();
185  _M_tail() = __in._M_tail();
186  return *this;
187  }
188 
189  _Tuple_impl&
190  operator=(_Tuple_impl&& __in)
191  {
192  _M_head() = std::move(__in._M_head());
193  _M_tail() = std::move(__in._M_tail());
194  return *this;
195  }
196 
197  template<typename... _UElements>
198  _Tuple_impl&
199  operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
200  {
201  _M_head() = __in._M_head();
202  _M_tail() = __in._M_tail();
203  return *this;
204  }
205 
206  template<typename... _UElements>
207  _Tuple_impl&
208  operator=(_Tuple_impl<_Idx, _UElements...>&& __in)
209  {
210  _M_head() = std::move(__in._M_head());
211  _M_tail() = std::move(__in._M_tail());
212  return *this;
213  }
214 
215  protected:
216  void
217  _M_swap_impl(_Tuple_impl&& __in)
218  {
219  _Base::_M_swap_impl(__in._M_head());
220  _Inherited::_M_swap_impl(__in._M_tail());
221  }
222  };
223 
224  /// tuple
225  template<typename... _Elements>
226  class tuple : public _Tuple_impl<0, _Elements...>
227  {
228  typedef _Tuple_impl<0, _Elements...> _Inherited;
229 
230  public:
231  tuple()
232  : _Inherited() { }
233 
234  explicit
235  tuple(const _Elements&... __elements)
236  : _Inherited(__elements...) { }
237 
238  template<typename... _UElements>
239  explicit
240  tuple(_UElements&&... __elements)
241  : _Inherited(std::forward<_UElements>(__elements)...) { }
242 
243  tuple(const tuple& __in)
244  : _Inherited(static_cast<const _Inherited&>(__in)) { }
245 
246  tuple(tuple&& __in)
247  : _Inherited(std::move<_Inherited>(__in)) { }
248 
249  template<typename... _UElements>
250  tuple(const tuple<_UElements...>& __in)
251  : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
252  { }
253 
254  template<typename... _UElements>
255  tuple(tuple<_UElements...>&& __in)
256  : _Inherited(std::move<_Tuple_impl<0, _UElements...> >(__in)) { }
257 
258  // XXX http://gcc.gnu.org/ml/libstdc++/2008-02/msg00047.html
259  template<typename... _UElements>
260  tuple(tuple<_UElements...>& __in)
261  : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
262  { }
263 
264  tuple&
265  operator=(const tuple& __in)
266  {
267  static_cast<_Inherited&>(*this) = __in;
268  return *this;
269  }
270 
271  tuple&
272  operator=(tuple&& __in)
273  {
274  static_cast<_Inherited&>(*this) = std::move(__in);
275  return *this;
276  }
277 
278  template<typename... _UElements>
279  tuple&
280  operator=(const tuple<_UElements...>& __in)
281  {
282  static_cast<_Inherited&>(*this) = __in;
283  return *this;
284  }
285 
286  template<typename... _UElements>
287  tuple&
288  operator=(tuple<_UElements...>&& __in)
289  {
290  static_cast<_Inherited&>(*this) = std::move(__in);
291  return *this;
292  }
293 
294  void
295  swap(tuple&& __in)
296  { _Inherited::_M_swap_impl(__in); }
297  };
298 
299 
300  template<>
301  class tuple<>
302  {
303  public:
304  void swap(tuple&&) { /* no-op */ }
305  };
306 
307  /// tuple (2-element), with construction and assignment from a pair.
308  template<typename _T1, typename _T2>
309  class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
310  {
311  typedef _Tuple_impl<0, _T1, _T2> _Inherited;
312 
313  public:
314  tuple()
315  : _Inherited() { }
316 
317  explicit
318  tuple(const _T1& __a1, const _T2& __a2)
319  : _Inherited(__a1, __a2) { }
320 
321  template<typename _U1, typename _U2>
322  explicit
323  tuple(_U1&& __a1, _U2&& __a2)
324  : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
325 
326  tuple(const tuple& __in)
327  : _Inherited(static_cast<const _Inherited&>(__in)) { }
328 
329  tuple(tuple&& __in)
330  : _Inherited(std::move<_Inherited>(__in)) { }
331 
332  template<typename _U1, typename _U2>
333  tuple(const tuple<_U1, _U2>& __in)
334  : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
335 
336  template<typename _U1, typename _U2>
337  tuple(tuple<_U1, _U2>&& __in)
338  : _Inherited(std::move<_Tuple_impl<0, _U1, _U2> >(__in)) { }
339 
340  template<typename _U1, typename _U2>
341  tuple(const pair<_U1, _U2>& __in)
342  : _Inherited(__in.first, __in.second) { }
343 
344  template<typename _U1, typename _U2>
345  tuple(pair<_U1, _U2>&& __in)
346  : _Inherited(std::move(__in.first), std::move(__in.second)) { }
347 
348  tuple&
349  operator=(const tuple& __in)
350  {
351  static_cast<_Inherited&>(*this) = __in;
352  return *this;
353  }
354 
355  tuple&
356  operator=(tuple&& __in)
357  {
358  static_cast<_Inherited&>(*this) = std::move(__in);
359  return *this;
360  }
361 
362  template<typename _U1, typename _U2>
363  tuple&
364  operator=(const tuple<_U1, _U2>& __in)
365  {
366  static_cast<_Inherited&>(*this) = __in;
367  return *this;
368  }
369 
370  template<typename _U1, typename _U2>
371  tuple&
372  operator=(tuple<_U1, _U2>&& __in)
373  {
374  static_cast<_Inherited&>(*this) = std::move(__in);
375  return *this;
376  }
377 
378  template<typename _U1, typename _U2>
379  tuple&
380  operator=(const pair<_U1, _U2>& __in)
381  {
382  this->_M_head() = __in.first;
383  this->_M_tail()._M_head() = __in.second;
384  return *this;
385  }
386 
387  template<typename _U1, typename _U2>
388  tuple&
389  operator=(pair<_U1, _U2>&& __in)
390  {
391  this->_M_head() = std::move(__in.first);
392  this->_M_tail()._M_head() = std::move(__in.second);
393  return *this;
394  }
395 
396  void
397  swap(tuple&& __in)
398  {
399  using std::swap;
400  swap(this->_M_head(), __in._M_head());
401  swap(this->_M_tail()._M_head(), __in._M_tail()._M_head());
402  }
403  };
404 
405 
406  /// Gives the type of the ith element of a given tuple type.
407  template<std::size_t __i, typename _Tp>
408  struct tuple_element;
409 
410  /**
411  * Recursive case for tuple_element: strip off the first element in
412  * the tuple and retrieve the (i-1)th element of the remaining tuple.
413  */
414  template<std::size_t __i, typename _Head, typename... _Tail>
415  struct tuple_element<__i, tuple<_Head, _Tail...> >
416  : tuple_element<__i - 1, tuple<_Tail...> > { };
417 
418  /**
419  * Basis case for tuple_element: The first element is the one we're seeking.
420  */
421  template<typename _Head, typename... _Tail>
422  struct tuple_element<0, tuple<_Head, _Tail...> >
423  {
424  typedef _Head type;
425  };
426 
427  /// Finds the size of a given tuple type.
428  template<typename _Tp>
429  struct tuple_size;
430 
431  /// class tuple_size
432  template<typename... _Elements>
433  struct tuple_size<tuple<_Elements...> >
434  {
435  static const std::size_t value = sizeof...(_Elements);
436  };
437 
438  template<typename... _Elements>
439  const std::size_t tuple_size<tuple<_Elements...> >::value;
440 
441  template<std::size_t __i, typename _Head, typename... _Tail>
442  inline typename __add_ref<_Head>::type
443  __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t)
444  { return __t._M_head(); }
445 
446  template<std::size_t __i, typename _Head, typename... _Tail>
447  inline typename __add_c_ref<_Head>::type
448  __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t)
449  { return __t._M_head(); }
450 
451  // Return a reference (const reference) to the ith element of a tuple.
452  // Any const or non-const ref elements are returned with their original type.
453  template<std::size_t __i, typename... _Elements>
454  inline typename __add_ref<
455  typename tuple_element<__i, tuple<_Elements...> >::type
456  >::type
457  get(tuple<_Elements...>& __t)
458  { return __get_helper<__i>(__t); }
459 
460  template<std::size_t __i, typename... _Elements>
461  inline typename __add_c_ref<
462  typename tuple_element<__i, tuple<_Elements...> >::type
463  >::type
464  get(const tuple<_Elements...>& __t)
465  { return __get_helper<__i>(__t); }
466 
467  // This class helps construct the various comparison operations on tuples
468  template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j,
469  typename _Tp, typename _Up>
470  struct __tuple_compare;
471 
472  template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up>
473  struct __tuple_compare<0, __i, __j, _Tp, _Up>
474  {
475  static bool __eq(const _Tp& __t, const _Up& __u)
476  {
477  return (get<__i>(__t) == get<__i>(__u) &&
478  __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u));
479  }
480 
481  static bool __less(const _Tp& __t, const _Up& __u)
482  {
483  return ((get<__i>(__t) < get<__i>(__u))
484  || !(get<__i>(__u) < get<__i>(__t)) &&
485  __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u));
486  }
487  };
488 
489  template<std::size_t __i, typename _Tp, typename _Up>
490  struct __tuple_compare<0, __i, __i, _Tp, _Up>
491  {
492  static bool __eq(const _Tp&, const _Up&)
493  { return true; }
494 
495  static bool __less(const _Tp&, const _Up&)
496  { return false; }
497  };
498 
499  template<typename... _TElements, typename... _UElements>
500  bool
501  operator==(const tuple<_TElements...>& __t,
502  const tuple<_UElements...>& __u)
503  {
504  typedef tuple<_TElements...> _Tp;
505  typedef tuple<_UElements...> _Up;
506  return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
507  0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
508  }
509 
510  template<typename... _TElements, typename... _UElements>
511  bool
512  operator<(const tuple<_TElements...>& __t,
513  const tuple<_UElements...>& __u)
514  {
515  typedef tuple<_TElements...> _Tp;
516  typedef tuple<_UElements...> _Up;
517  return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
518  0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
519  }
520 
521  template<typename... _TElements, typename... _UElements>
522  inline bool
523  operator!=(const tuple<_TElements...>& __t,
524  const tuple<_UElements...>& __u)
525  { return !(__t == __u); }
526 
527  template<typename... _TElements, typename... _UElements>
528  inline bool
529  operator>(const tuple<_TElements...>& __t,
530  const tuple<_UElements...>& __u)
531  { return __u < __t; }
532 
533  template<typename... _TElements, typename... _UElements>
534  inline bool
535  operator<=(const tuple<_TElements...>& __t,
536  const tuple<_UElements...>& __u)
537  { return !(__u < __t); }
538 
539  template<typename... _TElements, typename... _UElements>
540  inline bool
541  operator>=(const tuple<_TElements...>& __t,
542  const tuple<_UElements...>& __u)
543  { return !(__t < __u); }
544 
545  // NB: DR 705.
546  template<typename... _Elements>
547  inline tuple<typename __decay_and_strip<_Elements>::__type...>
548  make_tuple(_Elements&&... __args)
549  {
550  typedef tuple<typename __decay_and_strip<_Elements>::__type...>
551  __result_type;
552  return __result_type(std::forward<_Elements>(__args)...);
553  }
554 
555  template<std::size_t...> struct __index_holder { };
556 
557  template<std::size_t __i, typename _IdxHolder, typename... _Elements>
558  struct __index_holder_impl;
559 
560  template<std::size_t __i, std::size_t... _Indexes, typename _IdxHolder,
561  typename... _Elements>
562  struct __index_holder_impl<__i, __index_holder<_Indexes...>,
563  _IdxHolder, _Elements...>
564  {
565  typedef typename __index_holder_impl<__i + 1,
566  __index_holder<_Indexes..., __i>,
567  _Elements...>::type type;
568  };
569 
570  template<std::size_t __i, std::size_t... _Indexes>
571  struct __index_holder_impl<__i, __index_holder<_Indexes...> >
572  { typedef __index_holder<_Indexes...> type; };
573 
574  template<typename... _Elements>
575  struct __make_index_holder
576  : __index_holder_impl<0, __index_holder<>, _Elements...> { };
577 
578  template<typename... _TElements, std::size_t... _TIdx,
579  typename... _UElements, std::size_t... _UIdx>
580  inline tuple<_TElements..., _UElements...>
581  __tuple_cat_helper(const tuple<_TElements...>& __t,
582  const __index_holder<_TIdx...>&,
583  const tuple<_UElements...>& __u,
584  const __index_holder<_UIdx...>&)
585  { return tuple<_TElements..., _UElements...>(get<_TIdx>(__t)...,
586  get<_UIdx>(__u)...); }
587 
588  template<typename... _TElements, std::size_t... _TIdx,
589  typename... _UElements, std::size_t... _UIdx>
590  inline tuple<_TElements..., _UElements...>
591  __tuple_cat_helper(tuple<_TElements...>&& __t,
592  const __index_holder<_TIdx...>&,
593  const tuple<_UElements...>& __u,
594  const __index_holder<_UIdx...>&)
595  { return tuple<_TElements..., _UElements...>
596  (std::move(get<_TIdx>(__t))..., get<_UIdx>(__u)...); }
597 
598  template<typename... _TElements, std::size_t... _TIdx,
599  typename... _UElements, std::size_t... _UIdx>
600  inline tuple<_TElements..., _UElements...>
601  __tuple_cat_helper(const tuple<_TElements...>& __t,
602  const __index_holder<_TIdx...>&,
603  tuple<_UElements...>&& __u,
604  const __index_holder<_UIdx...>&)
605  { return tuple<_TElements..., _UElements...>
606  (get<_TIdx>(__t)..., std::move(get<_UIdx>(__u))...); }
607 
608  template<typename... _TElements, std::size_t... _TIdx,
609  typename... _UElements, std::size_t... _UIdx>
610  inline tuple<_TElements..., _UElements...>
611  __tuple_cat_helper(tuple<_TElements...>&& __t,
612  const __index_holder<_TIdx...>&,
613  tuple<_UElements...>&& __u,
614  const __index_holder<_UIdx...>&)
615  { return tuple<_TElements..., _UElements...>
616  (std::move(get<_TIdx>(__t))..., std::move(get<_UIdx>(__u))...); }
617 
618  template<typename... _TElements, typename... _UElements>
619  inline tuple<_TElements..., _UElements...>
620  tuple_cat(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u)
621  {
622  return __tuple_cat_helper(__t, typename
623  __make_index_holder<_TElements...>::type(),
624  __u, typename
625  __make_index_holder<_UElements...>::type());
626  }
627 
628  template<typename... _TElements, typename... _UElements>
629  inline tuple<_TElements..., _UElements...>
630  tuple_cat(tuple<_TElements...>&& __t, const tuple<_UElements...>& __u)
631  {
632  return __tuple_cat_helper(std::move(__t), typename
633  __make_index_holder<_TElements...>::type(),
634  __u, typename
635  __make_index_holder<_UElements...>::type());
636  }
637 
638  template<typename... _TElements, typename... _UElements>
639  inline tuple<_TElements..., _UElements...>
640  tuple_cat(const tuple<_TElements...>& __t, tuple<_UElements...>&& __u)
641  {
642  return __tuple_cat_helper(__t, typename
643  __make_index_holder<_TElements...>::type(),
644  std::move(__u), typename
645  __make_index_holder<_UElements...>::type());
646  }
647 
648  template<typename... _TElements, typename... _UElements>
649  inline tuple<_TElements..., _UElements...>
650  tuple_cat(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u)
651  {
652  return __tuple_cat_helper(std::move(__t), typename
653  __make_index_holder<_TElements...>::type(),
654  std::move(__u), typename
655  __make_index_holder<_UElements...>::type());
656  }
657 
658  template<typename... _Elements>
659  inline tuple<_Elements&...>
660  tie(_Elements&... __args)
661  { return tuple<_Elements&...>(__args...); }
662 
663  template<typename... _Elements>
664  inline void
665  swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
666  { __x.swap(__y); }
667 
668  template<typename... _Elements>
669  inline void
670  swap(tuple<_Elements...>&& __x, tuple<_Elements...>& __y)
671  { __x.swap(__y); }
672 
673  template<typename... _Elements>
674  inline void
675  swap(tuple<_Elements...>& __x, tuple<_Elements...>&& __y)
676  { __x.swap(__y); }
677 
678  // A class (and instance) which can be used in 'tie' when an element
679  // of a tuple is not required
680  struct _Swallow_assign
681  {
682  template<class _Tp>
683  _Swallow_assign&
684  operator=(const _Tp&)
685  { return *this; }
686  };
687 
688  // TODO: Put this in some kind of shared file.
689  namespace
690  {
691  _Swallow_assign ignore;
692  }; // anonymous namespace
693 }
694 
695 #endif // __GXX_EXPERIMENTAL_CXX0X__
696 
697 #endif // _GLIBCXX_TUPLE