This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Attempt to make std::pair piecewise constructor noexcept


Hi

    I had a try to make std::pair piecewise constructor noexcept qualified as you'll see in the attached diff. It will help to have more move semantic in associative containers.

    But it doesn't work, is_nothrow_constructible<pair<int, int>, piecewise_construct_t, tuple<int>, tuple<int>>::value still false.

    Could you let me know before I lose too much time if it is feasible or not ? Or at least if I am on the right path.

Thanks for any help,

François

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index d45d937d3a7..c04faa01276 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -99,6 +99,7 @@ bits_headers = \
 	${bits_srcdir}/basic_string.h \
 	${bits_srcdir}/basic_string.tcc \
 	${bits_srcdir}/boost_concept_check.h \
+	${bits_srcdir}/build_index_tuple.h \
 	${bits_srcdir}/c++0x_warning.h \
 	${bits_srcdir}/char_traits.h \
 	${bits_srcdir}/codecvt.h \
@@ -198,6 +199,8 @@ bits_headers = \
 	${bits_srcdir}/streambuf.tcc \
 	${bits_srcdir}/stringfwd.h \
 	${bits_srcdir}/string_view.tcc \
+	${bits_srcdir}/tuple.h \
+	${bits_srcdir}/tuple_element.h \
 	${bits_srcdir}/uniform_int_dist.h \
 	${bits_srcdir}/unique_lock.h \
 	${bits_srcdir}/unique_ptr.h \
diff --git a/libstdc++-v3/include/bits/build_index_tuple.h b/libstdc++-v3/include/bits/build_index_tuple.h
new file mode 100644
index 00000000000..977441a25b6
--- /dev/null
+++ b/libstdc++-v3/include/bits/build_index_tuple.h
@@ -0,0 +1,64 @@
+// build index tuple implementation -*- C++ -*-
+
+// Copyright (C) 2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/bits/build_index_tuple.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{utility}
+ */
+
+#ifndef _GLIBCXX_BUILD_INDEX_TUPLE_H
+#define _GLIBCXX_BUILD_INDEX_TUPLE_H
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  // Stores a tuple of indices.  Used by tuple and pair, and by bind() to
+  // extract the elements in a tuple.
+  template<size_t... _Indexes> struct _Index_tuple { };
+
+#ifdef __has_builtin
+# if __has_builtin(__make_integer_seq)
+#  define _GLIBCXX_USE_MAKE_INTEGER_SEQ 1
+# endif
+#endif
+
+  // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
+  template<size_t _Num>
+    struct _Build_index_tuple
+    {
+#if _GLIBCXX_USE_MAKE_INTEGER_SEQ
+      template<typename, size_t... _Indices>
+        using _IdxTuple = _Index_tuple<_Indices...>;
+
+      using __type = __make_integer_seq<_IdxTuple, size_t, _Num>;
+#else
+      using __type = _Index_tuple<__integer_pack(_Num)...>;
+#endif
+    };
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
+
+#endif /* _GLIBCXX_BUILD_INDEX_TUPLE_H */
diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h
index 48af2b02ef9..806fde55c9f 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -59,7 +59,10 @@
 #include <bits/move.h> // for std::move / std::forward, and std::swap
 
 #if __cplusplus >= 201103L
-#include <type_traits> // for std::__decay_and_strip too
+# include <type_traits> // for std::__decay_and_strip too
+
+# include <bits/tuple.h>
+# include <bits/build_index_tuple.h>
 #endif
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -79,13 +82,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _GLIBCXX17_INLINE constexpr piecewise_construct_t piecewise_construct =
     piecewise_construct_t();
 
-  // Forward declarations.
-  template<typename...>
-    class tuple;
-
-  template<std::size_t...>
-    struct _Index_tuple;
-
   // Concept utility functions, reused in conditionally-explicit
   // constructors.
   // See PR 70437, don't look at is_constructible or
@@ -178,13 +174,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	return false;
       }
   };
-
-  // PR libstdc++/79141, a utility type for preventing
-  // initialization of an argument of a disabled assignment
-  // operator from a pair of empty braces.
-  struct __nonesuch_no_braces : std::__nonesuch {
-    explicit __nonesuch_no_braces(const __nonesuch&) = delete;
-  };
 #endif // C++11
 
   template<typename _U1, typename _U2> class __pair_base
@@ -372,7 +361,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  second(std::forward<_U2>(__p.second)) { }
 
       template<typename... _Args1, typename... _Args2>
-        pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
+	pair(piecewise_construct_t,
+	     tuple<_Args1...> __first, tuple<_Args2...> __second)
+	noexcept(
+	  is_nothrow_constructible<
+	    pair, tuple<_Args1...>, tuple<_Args2...>,
+	    typename _Build_index_tuple<sizeof...(_Args1)>::__type,
+	    typename _Build_index_tuple<sizeof...(_Args2)>::__type>::value )
+	: pair(__first, __second,
+	       typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
+	       typename _Build_index_tuple<sizeof...(_Args2)>::__type())
+	{ }
 
       pair&
       operator=(typename conditional<
@@ -432,9 +431,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     private:
       template<typename... _Args1, std::size_t... _Indexes1,
-               typename... _Args2, std::size_t... _Indexes2>
-        pair(tuple<_Args1...>&, tuple<_Args2...>&,
-             _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
+	       typename... _Args2, std::size_t... _Indexes2>
+	pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
+	     _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
+	  noexcept(__and_<
+	is_nothrow_constructible<_T1,
+	  decltype(std::forward<_Args1>(std::get<_Indexes1>(__tuple1)))...>,
+	is_nothrow_constructible<_T2,
+	  decltype(std::forward<_Args2>(std::get<_Indexes2>(__tuple2)))...>>::value)
+      : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
+        second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
+      { }
 #endif
     };
 
diff --git a/libstdc++-v3/include/bits/tuple.h b/libstdc++-v3/include/bits/tuple.h
new file mode 100644
index 00000000000..da13f904d5a
--- /dev/null
+++ b/libstdc++-v3/include/bits/tuple.h
@@ -0,0 +1,899 @@
+// tuple primary implementation -*- C++ -*-
+
+// Copyright (C) 2007-2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/bits/tuple.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{tuple}
+ */
+
+#ifndef _GLIBCXX_TUPLE_H
+#define _GLIBCXX_TUPLE_H 1
+
+#include <bits/uses_allocator.h>
+#include <bits/tuple_element.h>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   *  @addtogroup utilities
+   *  @{
+   */
+
+  template<typename... _Elements>
+    class tuple;
+
+  template<typename _Tp>
+    struct __is_empty_non_tuple : is_empty<_Tp> { };
+
+  // Using EBO for elements that are tuples causes ambiguous base errors.
+  template<typename _El0, typename... _El>
+    struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
+
+  // Use the Empty Base-class Optimization for empty, non-final types.
+  template<typename _Tp>
+    using __empty_not_final
+    = typename conditional<__is_final(_Tp), false_type,
+			   __is_empty_non_tuple<_Tp>>::type;
+
+  template<std::size_t _Idx, typename _Head,
+	   bool = __empty_not_final<_Head>::value>
+    struct _Head_base;
+
+  template<std::size_t _Idx, typename _Head>
+    struct _Head_base<_Idx, _Head, true>
+    : public _Head
+    {
+      constexpr _Head_base()
+      : _Head() { }
+
+      constexpr _Head_base(const _Head& __h)
+      : _Head(__h) { }
+
+      constexpr _Head_base(const _Head_base&) = default;
+      constexpr _Head_base(_Head_base&&) = default;
+
+      template<typename _UHead>
+        constexpr _Head_base(_UHead&& __h)
+	: _Head(std::forward<_UHead>(__h)) { }
+
+      _Head_base(allocator_arg_t, __uses_alloc0)
+      : _Head() { }
+
+      template<typename _Alloc>
+	_Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
+	: _Head(allocator_arg, *__a._M_a) { }
+
+      template<typename _Alloc>
+	_Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
+	: _Head(*__a._M_a) { }
+
+      template<typename _UHead>
+	_Head_base(__uses_alloc0, _UHead&& __uhead)
+	: _Head(std::forward<_UHead>(__uhead)) { }
+
+      template<typename _Alloc, typename _UHead>
+	_Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
+	: _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
+
+      template<typename _Alloc, typename _UHead>
+	_Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
+	: _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
+
+      static constexpr _Head&
+      _M_head(_Head_base& __b) noexcept { return __b; }
+
+      static constexpr const _Head&
+      _M_head(const _Head_base& __b) noexcept { return __b; }
+    };
+
+  template<std::size_t _Idx, typename _Head>
+    struct _Head_base<_Idx, _Head, false>
+    {
+      constexpr _Head_base()
+      : _M_head_impl() { }
+
+      constexpr _Head_base(const _Head& __h)
+      : _M_head_impl(__h) { }
+
+      constexpr _Head_base(const _Head_base&) = default;
+      constexpr _Head_base(_Head_base&&) = default;
+
+      template<typename _UHead>
+        constexpr _Head_base(_UHead&& __h)
+	: _M_head_impl(std::forward<_UHead>(__h)) { }
+
+      _Head_base(allocator_arg_t, __uses_alloc0)
+      : _M_head_impl() { }
+
+      template<typename _Alloc>
+	_Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
+	: _M_head_impl(allocator_arg, *__a._M_a) { }
+
+      template<typename _Alloc>
+	_Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
+	: _M_head_impl(*__a._M_a) { }
+
+      template<typename _UHead>
+	_Head_base(__uses_alloc0, _UHead&& __uhead)
+	: _M_head_impl(std::forward<_UHead>(__uhead)) { }
+
+      template<typename _Alloc, typename _UHead>
+	_Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
+	: _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
+	{ }
+
+      template<typename _Alloc, typename _UHead>
+	_Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
+	: _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
+
+      static constexpr _Head&
+      _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
+
+      static constexpr const _Head&
+      _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
+
+      _Head _M_head_impl;
+    };
+
+  /**
+   * Contains the actual implementation of the @c tuple template, stored
+   * as a recursive inheritance hierarchy from the first element (most
+   * derived class) to the last (least derived class). The @c Idx
+   * parameter gives the 0-based index of the element stored at this
+   * point in the hierarchy; we use it to implement a constant-time
+   * get() operation.
+   */
+  template<std::size_t _Idx, typename... _Elements>
+    struct _Tuple_impl;
+
+  /**
+   * Recursive tuple implementation. Here we store the @c Head element
+   * and derive from a @c Tuple_impl containing the remaining elements
+   * (which contains the @c Tail).
+   */
+  template<std::size_t _Idx, typename _Head, typename... _Tail>
+    struct _Tuple_impl<_Idx, _Head, _Tail...>
+    : public _Tuple_impl<_Idx + 1, _Tail...>,
+      private _Head_base<_Idx, _Head>
+    {
+      template<std::size_t, typename...> friend class _Tuple_impl;
+
+      typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
+      typedef _Head_base<_Idx, _Head> _Base;
+
+      static constexpr _Head&
+      _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
+
+      static constexpr const _Head&
+      _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
+
+      static constexpr _Inherited&
+      _M_tail(_Tuple_impl& __t) noexcept { return __t; }
+
+      static constexpr const _Inherited&
+      _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
+
+      constexpr _Tuple_impl()
+      : _Inherited(), _Base() { }
+
+      explicit
+      constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
+      : _Inherited(__tail...), _Base(__head) { }
+
+      template<typename _UHead, typename... _UTail, typename = typename
+               enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type>
+        explicit
+        constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
+	: _Inherited(std::forward<_UTail>(__tail)...),
+	  _Base(std::forward<_UHead>(__head)) { }
+
+      constexpr _Tuple_impl(const _Tuple_impl&) = default;
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 2729. Missing SFINAE on std::pair::operator=
+      _Tuple_impl& operator=(const _Tuple_impl&) = delete;
+
+      constexpr
+      _Tuple_impl(_Tuple_impl&& __in)
+      noexcept(__and_<is_nothrow_move_constructible<_Head>,
+	              is_nothrow_move_constructible<_Inherited>>::value)
+      : _Inherited(std::move(_M_tail(__in))),
+	_Base(std::forward<_Head>(_M_head(__in))) { }
+
+      template<typename... _UElements>
+        constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
+	: _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
+	  _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
+
+      template<typename _UHead, typename... _UTails>
+        constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
+	: _Inherited(std::move
+		     (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
+	  _Base(std::forward<_UHead>
+		(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
+
+      template<typename _Alloc>
+	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
+	: _Inherited(__tag, __a),
+          _Base(__tag, __use_alloc<_Head>(__a)) { }
+
+      template<typename _Alloc>
+	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
+		    const _Head& __head, const _Tail&... __tail)
+	: _Inherited(__tag, __a, __tail...),
+          _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
+
+      template<typename _Alloc, typename _UHead, typename... _UTail,
+               typename = typename enable_if<sizeof...(_Tail)
+					     == sizeof...(_UTail)>::type>
+	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
+	            _UHead&& __head, _UTail&&... __tail)
+	: _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
+          _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
+	        std::forward<_UHead>(__head)) { }
+
+      template<typename _Alloc>
+        _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
+	            const _Tuple_impl& __in)
+	: _Inherited(__tag, __a, _M_tail(__in)),
+          _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
+
+      template<typename _Alloc>
+	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
+	            _Tuple_impl&& __in)
+	: _Inherited(__tag, __a, std::move(_M_tail(__in))),
+	  _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
+	        std::forward<_Head>(_M_head(__in))) { }
+
+      template<typename _Alloc, typename... _UElements>
+	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
+	            const _Tuple_impl<_Idx, _UElements...>& __in)
+	: _Inherited(__tag, __a,
+		     _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
+	  _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
+		_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
+
+      template<typename _Alloc, typename _UHead, typename... _UTails>
+	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
+	            _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
+	: _Inherited(__tag, __a, std::move
+		     (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
+	  _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
+                std::forward<_UHead>
+		(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
+
+      template<typename... _UElements>
+        void
+        _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in)
+        {
+	  _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
+	  _M_tail(*this)._M_assign(
+	      _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));
+	}
+
+      template<typename _UHead, typename... _UTails>
+        void
+        _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
+        {
+	  _M_head(*this) = std::forward<_UHead>
+	    (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
+	  _M_tail(*this)._M_assign(
+	      std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
+	}
+
+    protected:
+      void
+      _M_swap(_Tuple_impl& __in)
+      {
+	using std::swap;
+	swap(_M_head(*this), _M_head(__in));
+	_Inherited::_M_swap(_M_tail(__in));
+      }
+    };
+
+  // Basis case of inheritance recursion.
+  template<std::size_t _Idx, typename _Head>
+    struct _Tuple_impl<_Idx, _Head>
+    : private _Head_base<_Idx, _Head>
+    {
+      template<std::size_t, typename...> friend class _Tuple_impl;
+
+      typedef _Head_base<_Idx, _Head> _Base;
+
+      static constexpr _Head&
+      _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
+
+      static constexpr const _Head&
+      _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
+
+      constexpr _Tuple_impl()
+      : _Base() { }
+
+      explicit
+      constexpr _Tuple_impl(const _Head& __head)
+      : _Base(__head) { }
+
+      template<typename _UHead>
+        explicit
+        constexpr _Tuple_impl(_UHead&& __head)
+	: _Base(std::forward<_UHead>(__head)) { }
+
+      constexpr _Tuple_impl(const _Tuple_impl&) = default;
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 2729. Missing SFINAE on std::pair::operator=
+      _Tuple_impl& operator=(const _Tuple_impl&) = delete;
+
+      constexpr
+      _Tuple_impl(_Tuple_impl&& __in)
+      noexcept(is_nothrow_move_constructible<_Head>::value)
+      : _Base(std::forward<_Head>(_M_head(__in))) { }
+
+      template<typename _UHead>
+        constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
+	: _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
+
+      template<typename _UHead>
+        constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
+	: _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
+	{ }
+
+      template<typename _Alloc>
+	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
+	: _Base(__tag, __use_alloc<_Head>(__a)) { }
+
+      template<typename _Alloc>
+	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
+		    const _Head& __head)
+	: _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
+
+      template<typename _Alloc, typename _UHead>
+	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
+	            _UHead&& __head)
+	: _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
+	        std::forward<_UHead>(__head)) { }
+
+      template<typename _Alloc>
+        _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
+	            const _Tuple_impl& __in)
+	: _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
+
+      template<typename _Alloc>
+	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
+	            _Tuple_impl&& __in)
+	: _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
+	        std::forward<_Head>(_M_head(__in))) { }
+
+      template<typename _Alloc, typename _UHead>
+	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
+	            const _Tuple_impl<_Idx, _UHead>& __in)
+	: _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
+		_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
+
+      template<typename _Alloc, typename _UHead>
+	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
+	            _Tuple_impl<_Idx, _UHead>&& __in)
+	: _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
+                std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
+	{ }
+
+      template<typename _UHead>
+        void
+        _M_assign(const _Tuple_impl<_Idx, _UHead>& __in)
+        {
+	  _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
+	}
+
+      template<typename _UHead>
+        void
+        _M_assign(_Tuple_impl<_Idx, _UHead>&& __in)
+        {
+	  _M_head(*this)
+	    = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
+	}
+
+    protected:
+      void
+      _M_swap(_Tuple_impl& __in)
+      {
+	using std::swap;
+	swap(_M_head(*this), _M_head(__in));
+      }
+    };
+
+  // Concept utility functions, reused in conditionally-explicit
+  // constructors.
+  template<bool, typename... _Elements>
+  struct _TC
+  {
+    template<typename... _UElements>
+    static constexpr bool _ConstructibleTuple()
+    {
+      return __and_<is_constructible<_Elements, const _UElements&>...>::value;
+    }
+
+    template<typename... _UElements>
+    static constexpr bool _ImplicitlyConvertibleTuple()
+    {
+      return __and_<is_convertible<const _UElements&, _Elements>...>::value;
+    }
+
+    template<typename... _UElements>
+    static constexpr bool _MoveConstructibleTuple()
+    {
+      return __and_<is_constructible<_Elements, _UElements&&>...>::value;
+    }
+
+    template<typename... _UElements>
+    static constexpr bool _ImplicitlyMoveConvertibleTuple()
+    {
+      return __and_<is_convertible<_UElements&&, _Elements>...>::value;
+    }
+
+    template<typename _SrcTuple>
+    static constexpr bool _NonNestedTuple()
+    {
+      return  __and_<__not_<is_same<tuple<_Elements...>,
+				    __remove_cvref_t<_SrcTuple>>>,
+                     __not_<is_convertible<_SrcTuple, _Elements...>>,
+                     __not_<is_constructible<_Elements..., _SrcTuple>>
+              >::value;
+    }
+
+    template<typename... _UElements>
+    static constexpr bool _NotSameTuple()
+    {
+      return  __not_<is_same<tuple<_Elements...>,
+			     __remove_cvref_t<_UElements>...>>::value;
+    }
+  };
+
+  template<typename... _Elements>
+  struct _TC<false, _Elements...>
+  {
+    template<typename... _UElements>
+    static constexpr bool _ConstructibleTuple()
+    {
+      return false;
+    }
+
+    template<typename... _UElements>
+    static constexpr bool _ImplicitlyConvertibleTuple()
+    {
+      return false;
+    }
+
+    template<typename... _UElements>
+    static constexpr bool _MoveConstructibleTuple()
+    {
+      return false;
+    }
+
+    template<typename... _UElements>
+    static constexpr bool _ImplicitlyMoveConvertibleTuple()
+    {
+      return false;
+    }
+
+    template<typename... _UElements>
+    static constexpr bool _NonNestedTuple()
+    {
+      return true;
+    }
+
+    template<typename... _UElements>
+    static constexpr bool _NotSameTuple()
+    {
+      return true;
+    }
+  };
+
+  /// Primary class template, tuple
+  template<typename... _Elements>
+    class tuple : public _Tuple_impl<0, _Elements...>
+    {
+      typedef _Tuple_impl<0, _Elements...> _Inherited;
+
+      // Used for constraining the default constructor so
+      // that it becomes dependent on the constraints.
+      template<typename _Dummy>
+      struct _TC2
+      {
+        static constexpr bool _DefaultConstructibleTuple()
+        {
+          return __and_<is_default_constructible<_Elements>...>::value;
+        }
+        static constexpr bool _ImplicitlyDefaultConstructibleTuple()
+        {
+          return __and_<__is_implicitly_default_constructible<_Elements>...>
+            ::value;
+        }
+      };
+
+      template<typename... _UElements>
+	static constexpr
+	__enable_if_t<sizeof...(_UElements) == sizeof...(_Elements), bool>
+	__assignable()
+	{ return __and_<is_assignable<_Elements&, _UElements>...>::value; }
+
+      template<typename... _UElements>
+	static constexpr bool __nothrow_assignable()
+	{
+	  return
+	    __and_<is_nothrow_assignable<_Elements&, _UElements>...>::value;
+	}
+
+    public:
+      template<typename _Dummy = void,
+               typename enable_if<_TC2<_Dummy>::
+                                    _ImplicitlyDefaultConstructibleTuple(),
+                                  bool>::type = true>
+      constexpr tuple()
+      : _Inherited() { }
+
+      template<typename _Dummy = void,
+               typename enable_if<_TC2<_Dummy>::
+                                    _DefaultConstructibleTuple()
+                                  &&
+                                  !_TC2<_Dummy>::
+                                    _ImplicitlyDefaultConstructibleTuple(),
+                                  bool>::type = false>
+      explicit constexpr tuple()
+      : _Inherited() { }
+
+      // Shortcut for the cases where constructors taking _Elements...
+      // need to be constrained.
+      template<typename _Dummy> using _TCC =
+        _TC<is_same<_Dummy, void>::value,
+            _Elements...>;
+
+      template<typename _Dummy = void,
+               typename enable_if<
+                 _TCC<_Dummy>::template
+                   _ConstructibleTuple<_Elements...>()
+                 && _TCC<_Dummy>::template
+                   _ImplicitlyConvertibleTuple<_Elements...>()
+                 && (sizeof...(_Elements) >= 1),
+               bool>::type=true>
+        constexpr tuple(const _Elements&... __elements)
+      : _Inherited(__elements...) { }
+
+      template<typename _Dummy = void,
+               typename enable_if<
+                 _TCC<_Dummy>::template
+                   _ConstructibleTuple<_Elements...>()
+                 && !_TCC<_Dummy>::template
+                   _ImplicitlyConvertibleTuple<_Elements...>()
+                 && (sizeof...(_Elements) >= 1),
+               bool>::type=false>
+      explicit constexpr tuple(const _Elements&... __elements)
+      : _Inherited(__elements...) { }
+
+      // Shortcut for the cases where constructors taking _UElements...
+      // need to be constrained.
+      template<typename... _UElements> using _TMC =
+                  _TC<(sizeof...(_Elements) == sizeof...(_UElements))
+		      && (_TC<(sizeof...(_UElements)==1), _Elements...>::
+			  template _NotSameTuple<_UElements...>()),
+                      _Elements...>;
+
+      // Shortcut for the cases where constructors taking tuple<_UElements...>
+      // need to be constrained.
+      template<typename... _UElements> using _TMCT =
+                  _TC<(sizeof...(_Elements) == sizeof...(_UElements))
+		      && !is_same<tuple<_Elements...>,
+				  tuple<_UElements...>>::value,
+                      _Elements...>;
+
+      template<typename... _UElements, typename
+	       enable_if<
+		  _TMC<_UElements...>::template
+                    _MoveConstructibleTuple<_UElements...>()
+                  && _TMC<_UElements...>::template
+                    _ImplicitlyMoveConvertibleTuple<_UElements...>()
+                  && (sizeof...(_Elements) >= 1),
+        bool>::type=true>
+        constexpr tuple(_UElements&&... __elements)
+        : _Inherited(std::forward<_UElements>(__elements)...) { }
+
+      template<typename... _UElements, typename
+        enable_if<
+		  _TMC<_UElements...>::template
+                    _MoveConstructibleTuple<_UElements...>()
+                  && !_TMC<_UElements...>::template
+                    _ImplicitlyMoveConvertibleTuple<_UElements...>()
+                  && (sizeof...(_Elements) >= 1),
+        bool>::type=false>
+        explicit constexpr tuple(_UElements&&... __elements)
+	: _Inherited(std::forward<_UElements>(__elements)...) {	}
+
+      constexpr tuple(const tuple&) = default;
+
+      constexpr tuple(tuple&&) = default;
+
+      // Shortcut for the cases where constructors taking tuples
+      // must avoid creating temporaries.
+      template<typename _Dummy> using _TNTC =
+        _TC<is_same<_Dummy, void>::value && sizeof...(_Elements) == 1,
+            _Elements...>;
+
+      template<typename... _UElements, typename _Dummy = void, typename
+        enable_if<_TMCT<_UElements...>::template
+                    _ConstructibleTuple<_UElements...>()
+                  && _TMCT<_UElements...>::template
+                    _ImplicitlyConvertibleTuple<_UElements...>()
+                  && _TNTC<_Dummy>::template
+                    _NonNestedTuple<const tuple<_UElements...>&>(),
+        bool>::type=true>
+        constexpr tuple(const tuple<_UElements...>& __in)
+        : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
+        { }
+
+      template<typename... _UElements, typename _Dummy = void, typename
+        enable_if<_TMCT<_UElements...>::template
+                    _ConstructibleTuple<_UElements...>()
+                  && !_TMCT<_UElements...>::template
+                    _ImplicitlyConvertibleTuple<_UElements...>()
+                  && _TNTC<_Dummy>::template
+                    _NonNestedTuple<const tuple<_UElements...>&>(),
+        bool>::type=false>
+        explicit constexpr tuple(const tuple<_UElements...>& __in)
+        : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
+        { }
+
+      template<typename... _UElements, typename _Dummy = void, typename
+        enable_if<_TMCT<_UElements...>::template
+                    _MoveConstructibleTuple<_UElements...>()
+                  && _TMCT<_UElements...>::template
+                    _ImplicitlyMoveConvertibleTuple<_UElements...>()
+                  && _TNTC<_Dummy>::template
+                    _NonNestedTuple<tuple<_UElements...>&&>(),
+        bool>::type=true>
+        constexpr tuple(tuple<_UElements...>&& __in)
+        : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
+
+      template<typename... _UElements, typename _Dummy = void, typename
+        enable_if<_TMCT<_UElements...>::template
+                    _MoveConstructibleTuple<_UElements...>()
+                  && !_TMCT<_UElements...>::template
+                    _ImplicitlyMoveConvertibleTuple<_UElements...>()
+                  && _TNTC<_Dummy>::template
+                    _NonNestedTuple<tuple<_UElements...>&&>(),
+        bool>::type=false>
+        explicit constexpr tuple(tuple<_UElements...>&& __in)
+        : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
+
+      // Allocator-extended constructors.
+
+      template<typename _Alloc>
+	tuple(allocator_arg_t __tag, const _Alloc& __a)
+	: _Inherited(__tag, __a) { }
+
+      template<typename _Alloc, typename _Dummy = void,
+               typename enable_if<
+                 _TCC<_Dummy>::template
+                   _ConstructibleTuple<_Elements...>()
+                 && _TCC<_Dummy>::template
+                   _ImplicitlyConvertibleTuple<_Elements...>(),
+               bool>::type=true>
+	tuple(allocator_arg_t __tag, const _Alloc& __a,
+	      const _Elements&... __elements)
+	: _Inherited(__tag, __a, __elements...) { }
+
+      template<typename _Alloc, typename _Dummy = void,
+               typename enable_if<
+                 _TCC<_Dummy>::template
+                   _ConstructibleTuple<_Elements...>()
+                 && !_TCC<_Dummy>::template
+                   _ImplicitlyConvertibleTuple<_Elements...>(),
+               bool>::type=false>
+	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
+                       const _Elements&... __elements)
+	: _Inherited(__tag, __a, __elements...) { }
+
+      template<typename _Alloc, typename... _UElements, typename
+        enable_if<_TMC<_UElements...>::template
+                    _MoveConstructibleTuple<_UElements...>()
+                  && _TMC<_UElements...>::template
+                    _ImplicitlyMoveConvertibleTuple<_UElements...>(),
+        bool>::type=true>
+	tuple(allocator_arg_t __tag, const _Alloc& __a,
+	      _UElements&&... __elements)
+	: _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
+       	{ }
+
+      template<typename _Alloc, typename... _UElements, typename
+        enable_if<_TMC<_UElements...>::template
+                    _MoveConstructibleTuple<_UElements...>()
+                  && !_TMC<_UElements...>::template
+                    _ImplicitlyMoveConvertibleTuple<_UElements...>(),
+        bool>::type=false>
+	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
+	      _UElements&&... __elements)
+	: _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
+        { }
+
+      template<typename _Alloc>
+	tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
+	: _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
+
+      template<typename _Alloc>
+	tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
+	: _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
+
+      template<typename _Alloc, typename _Dummy = void,
+	       typename... _UElements, typename
+        enable_if<_TMCT<_UElements...>::template
+                    _ConstructibleTuple<_UElements...>()
+                  && _TMCT<_UElements...>::template
+                    _ImplicitlyConvertibleTuple<_UElements...>()
+                  && _TNTC<_Dummy>::template
+                    _NonNestedTuple<tuple<_UElements...>&&>(),
+        bool>::type=true>
+	tuple(allocator_arg_t __tag, const _Alloc& __a,
+	      const tuple<_UElements...>& __in)
+	: _Inherited(__tag, __a,
+	             static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
+	{ }
+
+      template<typename _Alloc, typename _Dummy = void,
+	       typename... _UElements, typename
+        enable_if<_TMCT<_UElements...>::template
+                    _ConstructibleTuple<_UElements...>()
+                  && !_TMCT<_UElements...>::template
+                    _ImplicitlyConvertibleTuple<_UElements...>()
+                  && _TNTC<_Dummy>::template
+                    _NonNestedTuple<tuple<_UElements...>&&>(),
+        bool>::type=false>
+	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
+	      const tuple<_UElements...>& __in)
+	: _Inherited(__tag, __a,
+	             static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
+	{ }
+
+      template<typename _Alloc, typename _Dummy = void,
+	       typename... _UElements, typename
+        enable_if<_TMCT<_UElements...>::template
+                    _MoveConstructibleTuple<_UElements...>()
+                  && _TMCT<_UElements...>::template
+                    _ImplicitlyMoveConvertibleTuple<_UElements...>()
+                  && _TNTC<_Dummy>::template
+                    _NonNestedTuple<tuple<_UElements...>&&>(),
+        bool>::type=true>
+	tuple(allocator_arg_t __tag, const _Alloc& __a,
+	      tuple<_UElements...>&& __in)
+	: _Inherited(__tag, __a,
+	             static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
+	{ }
+
+      template<typename _Alloc, typename _Dummy = void,
+	       typename... _UElements, typename
+        enable_if<_TMCT<_UElements...>::template
+                    _MoveConstructibleTuple<_UElements...>()
+                  && !_TMCT<_UElements...>::template
+                    _ImplicitlyMoveConvertibleTuple<_UElements...>()
+                  && _TNTC<_Dummy>::template
+                    _NonNestedTuple<tuple<_UElements...>&&>(),
+        bool>::type=false>
+	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
+	      tuple<_UElements...>&& __in)
+	: _Inherited(__tag, __a,
+	             static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
+	{ }
+
+      // tuple assignment
+
+      tuple&
+      operator=(typename conditional<__assignable<const _Elements&...>(),
+				     const tuple&,
+				     const __nonesuch_no_braces&>::type __in)
+      noexcept(__nothrow_assignable<const _Elements&...>())
+      {
+	this->_M_assign(__in);
+	return *this;
+      }
+
+      tuple&
+      operator=(typename conditional<__assignable<_Elements...>(),
+				     tuple&&,
+				     __nonesuch_no_braces&&>::type __in)
+      noexcept(__nothrow_assignable<_Elements...>())
+      {
+	this->_M_assign(std::move(__in));
+	return *this;
+      }
+
+      template<typename... _UElements>
+	__enable_if_t<__assignable<const _UElements&...>(), tuple&>
+	operator=(const tuple<_UElements...>& __in)
+	noexcept(__nothrow_assignable<const _UElements&...>())
+	{
+	  this->_M_assign(__in);
+	  return *this;
+	}
+
+      template<typename... _UElements>
+	__enable_if_t<__assignable<_UElements...>(), tuple&>
+	operator=(tuple<_UElements...>&& __in)
+	noexcept(__nothrow_assignable<_UElements...>())
+	{
+	  this->_M_assign(std::move(__in));
+	  return *this;
+	}
+
+      // tuple swap
+      void
+      swap(tuple& __in)
+      noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value)
+      { _Inherited::_M_swap(__in); }
+    };
+
+  template<std::size_t __i, typename _Head, typename... _Tail>
+    constexpr _Head&
+    __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
+    { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
+
+  template<std::size_t __i, typename _Head, typename... _Tail>
+    constexpr const _Head&
+    __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
+    { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
+
+  /// Return a reference to the ith element of a tuple.
+  template<std::size_t __i, typename... _Elements>
+    constexpr __tuple_element_t<__i, tuple<_Elements...>>&
+    get(tuple<_Elements...>& __t) noexcept
+    { return std::__get_helper<__i>(__t); }
+
+  /// Return a const reference to the ith element of a const tuple.
+  template<std::size_t __i, typename... _Elements>
+    constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
+    get(const tuple<_Elements...>& __t) noexcept
+    { return std::__get_helper<__i>(__t); }
+
+  /// Return an rvalue reference to the ith element of a tuple rvalue.
+  template<std::size_t __i, typename... _Elements>
+    constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
+    get(tuple<_Elements...>&& __t) noexcept
+    {
+      typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
+      return std::forward<__element_type&&>(std::get<__i>(__t));
+    }
+
+  /// Return a const rvalue reference to the ith element of a const tuple rvalue.
+  template<std::size_t __i, typename... _Elements>
+    constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
+    get(const tuple<_Elements...>&& __t) noexcept
+    {
+      typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
+      return std::forward<const __element_type&&>(std::get<__i>(__t));
+    }
+
+  /// @}
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif /* _GLIBCXX_TUPLE_H */
diff --git a/libstdc++-v3/include/bits/tuple_element.h b/libstdc++-v3/include/bits/tuple_element.h
new file mode 100644
index 00000000000..36ba5d4169b
--- /dev/null
+++ b/libstdc++-v3/include/bits/tuple_element.h
@@ -0,0 +1,67 @@
+// tuple_element primary implementation -*- C++ -*-
+
+// Copyright (C) 2007-2018 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/bits/tuple_element.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{utility}
+ */
+
+#ifndef _GLIBCXX_TUPLE_ELEMENT_H
+#define _GLIBCXX_TUPLE_ELEMENT_H 1
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /// Gives the type of the ith element of a given tuple type.
+  template<std::size_t __i, typename _Tp>
+    struct tuple_element;
+
+  // Duplicate of C++14's tuple_element_t for internal use in C++11 mode
+  template<std::size_t __i, typename _Tp>
+    using __tuple_element_t = typename tuple_element<__i, _Tp>::type;
+
+  template<std::size_t __i, typename _Tp>
+    struct tuple_element<__i, const _Tp>
+    {
+      typedef typename add_const<__tuple_element_t<__i, _Tp>>::type type;
+    };
+
+  template<std::size_t __i, typename _Tp>
+    struct tuple_element<__i, volatile _Tp>
+    {
+      typedef typename add_volatile<__tuple_element_t<__i, _Tp>>::type type;
+    };
+
+  template<std::size_t __i, typename _Tp>
+    struct tuple_element<__i, const volatile _Tp>
+    {
+      typedef typename add_cv<__tuple_element_t<__i, _Tp>>::type type;
+    };
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+
+#endif /* _GLIBCXX_TUPLE_ELEMENT_H */
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index b95449bf199..58fc50b8f5a 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -37,8 +37,8 @@
 
 #include <utility>
 #include <array>
-#include <bits/uses_allocator.h>
 #include <bits/invoke.h>
+#include <bits/tuple.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -49,815 +49,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
    *  @{
    */
 
-  template<typename... _Elements>
-    class tuple;
-
-  template<typename _Tp>
-    struct __is_empty_non_tuple : is_empty<_Tp> { };
-
-  // Using EBO for elements that are tuples causes ambiguous base errors.
-  template<typename _El0, typename... _El>
-    struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
-
-  // Use the Empty Base-class Optimization for empty, non-final types.
-  template<typename _Tp>
-    using __empty_not_final
-    = typename conditional<__is_final(_Tp), false_type,
-			   __is_empty_non_tuple<_Tp>>::type;
-
-  template<std::size_t _Idx, typename _Head,
-	   bool = __empty_not_final<_Head>::value>
-    struct _Head_base;
-
-  template<std::size_t _Idx, typename _Head>
-    struct _Head_base<_Idx, _Head, true>
-    : public _Head
-    {
-      constexpr _Head_base()
-      : _Head() { }
-
-      constexpr _Head_base(const _Head& __h)
-      : _Head(__h) { }
-
-      constexpr _Head_base(const _Head_base&) = default;
-      constexpr _Head_base(_Head_base&&) = default;
-
-      template<typename _UHead>
-        constexpr _Head_base(_UHead&& __h)
-	: _Head(std::forward<_UHead>(__h)) { }
-
-      _Head_base(allocator_arg_t, __uses_alloc0)
-      : _Head() { }
-
-      template<typename _Alloc>
-	_Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
-	: _Head(allocator_arg, *__a._M_a) { }
-
-      template<typename _Alloc>
-	_Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
-	: _Head(*__a._M_a) { }
-
-      template<typename _UHead>
-	_Head_base(__uses_alloc0, _UHead&& __uhead)
-	: _Head(std::forward<_UHead>(__uhead)) { }
-
-      template<typename _Alloc, typename _UHead>
-	_Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
-	: _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
-
-      template<typename _Alloc, typename _UHead>
-	_Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
-	: _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
-
-      static constexpr _Head&
-      _M_head(_Head_base& __b) noexcept { return __b; }
-
-      static constexpr const _Head&
-      _M_head(const _Head_base& __b) noexcept { return __b; }
-    };
-
-  template<std::size_t _Idx, typename _Head>
-    struct _Head_base<_Idx, _Head, false>
-    {
-      constexpr _Head_base()
-      : _M_head_impl() { }
-
-      constexpr _Head_base(const _Head& __h)
-      : _M_head_impl(__h) { }
-
-      constexpr _Head_base(const _Head_base&) = default;
-      constexpr _Head_base(_Head_base&&) = default;
-
-      template<typename _UHead>
-        constexpr _Head_base(_UHead&& __h)
-	: _M_head_impl(std::forward<_UHead>(__h)) { }
-
-      _Head_base(allocator_arg_t, __uses_alloc0)
-      : _M_head_impl() { }
-
-      template<typename _Alloc>
-	_Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
-	: _M_head_impl(allocator_arg, *__a._M_a) { }
-
-      template<typename _Alloc>
-	_Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
-	: _M_head_impl(*__a._M_a) { }
-
-      template<typename _UHead>
-	_Head_base(__uses_alloc0, _UHead&& __uhead)
-	: _M_head_impl(std::forward<_UHead>(__uhead)) { }
-
-      template<typename _Alloc, typename _UHead>
-	_Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
-	: _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
-	{ }
-
-      template<typename _Alloc, typename _UHead>
-	_Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
-	: _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
-
-      static constexpr _Head&
-      _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
-
-      static constexpr const _Head&
-      _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
-
-      _Head _M_head_impl;
-    };
-
-  /**
-   * Contains the actual implementation of the @c tuple template, stored
-   * as a recursive inheritance hierarchy from the first element (most
-   * derived class) to the last (least derived class). The @c Idx
-   * parameter gives the 0-based index of the element stored at this
-   * point in the hierarchy; we use it to implement a constant-time
-   * get() operation.
-   */
-  template<std::size_t _Idx, typename... _Elements>
-    struct _Tuple_impl;
-
-  /**
-   * Recursive tuple implementation. Here we store the @c Head element
-   * and derive from a @c Tuple_impl containing the remaining elements
-   * (which contains the @c Tail).
-   */
-  template<std::size_t _Idx, typename _Head, typename... _Tail>
-    struct _Tuple_impl<_Idx, _Head, _Tail...>
-    : public _Tuple_impl<_Idx + 1, _Tail...>,
-      private _Head_base<_Idx, _Head>
-    {
-      template<std::size_t, typename...> friend class _Tuple_impl;
-
-      typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
-      typedef _Head_base<_Idx, _Head> _Base;
-
-      static constexpr _Head&
-      _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
-
-      static constexpr const _Head&
-      _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
-
-      static constexpr _Inherited&
-      _M_tail(_Tuple_impl& __t) noexcept { return __t; }
-
-      static constexpr const _Inherited&
-      _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
-
-      constexpr _Tuple_impl()
-      : _Inherited(), _Base() { }
-
-      explicit
-      constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
-      : _Inherited(__tail...), _Base(__head) { }
-
-      template<typename _UHead, typename... _UTail, typename = typename
-               enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type>
-        explicit
-        constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
-	: _Inherited(std::forward<_UTail>(__tail)...),
-	  _Base(std::forward<_UHead>(__head)) { }
-
-      constexpr _Tuple_impl(const _Tuple_impl&) = default;
-
-      // _GLIBCXX_RESOLVE_LIB_DEFECTS
-      // 2729. Missing SFINAE on std::pair::operator=
-      _Tuple_impl& operator=(const _Tuple_impl&) = delete;
-
-      constexpr
-      _Tuple_impl(_Tuple_impl&& __in)
-      noexcept(__and_<is_nothrow_move_constructible<_Head>,
-	              is_nothrow_move_constructible<_Inherited>>::value)
-      : _Inherited(std::move(_M_tail(__in))),
-	_Base(std::forward<_Head>(_M_head(__in))) { }
-
-      template<typename... _UElements>
-        constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
-	: _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
-	  _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
-
-      template<typename _UHead, typename... _UTails>
-        constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
-	: _Inherited(std::move
-		     (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
-	  _Base(std::forward<_UHead>
-		(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
-
-      template<typename _Alloc>
-	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
-	: _Inherited(__tag, __a),
-          _Base(__tag, __use_alloc<_Head>(__a)) { }
-
-      template<typename _Alloc>
-	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
-		    const _Head& __head, const _Tail&... __tail)
-	: _Inherited(__tag, __a, __tail...),
-          _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
-
-      template<typename _Alloc, typename _UHead, typename... _UTail,
-               typename = typename enable_if<sizeof...(_Tail)
-					     == sizeof...(_UTail)>::type>
-	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
-	            _UHead&& __head, _UTail&&... __tail)
-	: _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
-          _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
-	        std::forward<_UHead>(__head)) { }
-
-      template<typename _Alloc>
-        _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
-	            const _Tuple_impl& __in)
-	: _Inherited(__tag, __a, _M_tail(__in)),
-          _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
-
-      template<typename _Alloc>
-	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
-	            _Tuple_impl&& __in)
-	: _Inherited(__tag, __a, std::move(_M_tail(__in))),
-	  _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
-	        std::forward<_Head>(_M_head(__in))) { }
-
-      template<typename _Alloc, typename... _UElements>
-	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
-	            const _Tuple_impl<_Idx, _UElements...>& __in)
-	: _Inherited(__tag, __a,
-		     _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
-	  _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
-		_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
-
-      template<typename _Alloc, typename _UHead, typename... _UTails>
-	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
-	            _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
-	: _Inherited(__tag, __a, std::move
-		     (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
-	  _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
-                std::forward<_UHead>
-		(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
-
-      template<typename... _UElements>
-        void
-        _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in)
-        {
-	  _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
-	  _M_tail(*this)._M_assign(
-	      _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));
-	}
-
-      template<typename _UHead, typename... _UTails>
-        void
-        _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
-        {
-	  _M_head(*this) = std::forward<_UHead>
-	    (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
-	  _M_tail(*this)._M_assign(
-	      std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
-	}
-
-    protected:
-      void
-      _M_swap(_Tuple_impl& __in)
-      {
-	using std::swap;
-	swap(_M_head(*this), _M_head(__in));
-	_Inherited::_M_swap(_M_tail(__in));
-      }
-    };
-
-  // Basis case of inheritance recursion.
-  template<std::size_t _Idx, typename _Head>
-    struct _Tuple_impl<_Idx, _Head>
-    : private _Head_base<_Idx, _Head>
-    {
-      template<std::size_t, typename...> friend class _Tuple_impl;
-
-      typedef _Head_base<_Idx, _Head> _Base;
-
-      static constexpr _Head&
-      _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
-
-      static constexpr const _Head&
-      _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
-
-      constexpr _Tuple_impl()
-      : _Base() { }
-
-      explicit
-      constexpr _Tuple_impl(const _Head& __head)
-      : _Base(__head) { }
-
-      template<typename _UHead>
-        explicit
-        constexpr _Tuple_impl(_UHead&& __head)
-	: _Base(std::forward<_UHead>(__head)) { }
-
-      constexpr _Tuple_impl(const _Tuple_impl&) = default;
-
-      // _GLIBCXX_RESOLVE_LIB_DEFECTS
-      // 2729. Missing SFINAE on std::pair::operator=
-      _Tuple_impl& operator=(const _Tuple_impl&) = delete;
-
-      constexpr
-      _Tuple_impl(_Tuple_impl&& __in)
-      noexcept(is_nothrow_move_constructible<_Head>::value)
-      : _Base(std::forward<_Head>(_M_head(__in))) { }
-
-      template<typename _UHead>
-        constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
-	: _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
-
-      template<typename _UHead>
-        constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
-	: _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
-	{ }
-
-      template<typename _Alloc>
-	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
-	: _Base(__tag, __use_alloc<_Head>(__a)) { }
-
-      template<typename _Alloc>
-	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
-		    const _Head& __head)
-	: _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
-
-      template<typename _Alloc, typename _UHead>
-	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
-	            _UHead&& __head)
-	: _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
-	        std::forward<_UHead>(__head)) { }
-
-      template<typename _Alloc>
-        _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
-	            const _Tuple_impl& __in)
-	: _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
-
-      template<typename _Alloc>
-	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
-	            _Tuple_impl&& __in)
-	: _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
-	        std::forward<_Head>(_M_head(__in))) { }
-
-      template<typename _Alloc, typename _UHead>
-	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
-	            const _Tuple_impl<_Idx, _UHead>& __in)
-	: _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
-		_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
-
-      template<typename _Alloc, typename _UHead>
-	_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
-	            _Tuple_impl<_Idx, _UHead>&& __in)
-	: _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
-                std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
-	{ }
-
-      template<typename _UHead>
-        void
-        _M_assign(const _Tuple_impl<_Idx, _UHead>& __in)
-        {
-	  _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
-	}
-
-      template<typename _UHead>
-        void
-        _M_assign(_Tuple_impl<_Idx, _UHead>&& __in)
-        {
-	  _M_head(*this)
-	    = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
-	}
-
-    protected:
-      void
-      _M_swap(_Tuple_impl& __in)
-      {
-	using std::swap;
-	swap(_M_head(*this), _M_head(__in));
-      }
-    };
-
-  // Concept utility functions, reused in conditionally-explicit
-  // constructors.
-  template<bool, typename... _Elements>
-  struct _TC
-  {
-    template<typename... _UElements>
-    static constexpr bool _ConstructibleTuple()
-    {
-      return __and_<is_constructible<_Elements, const _UElements&>...>::value;
-    }
-
-    template<typename... _UElements>
-    static constexpr bool _ImplicitlyConvertibleTuple()
-    {
-      return __and_<is_convertible<const _UElements&, _Elements>...>::value;
-    }
-
-    template<typename... _UElements>
-    static constexpr bool _MoveConstructibleTuple()
-    {
-      return __and_<is_constructible<_Elements, _UElements&&>...>::value;
-    }
-
-    template<typename... _UElements>
-    static constexpr bool _ImplicitlyMoveConvertibleTuple()
-    {
-      return __and_<is_convertible<_UElements&&, _Elements>...>::value;
-    }
-
-    template<typename _SrcTuple>
-    static constexpr bool _NonNestedTuple()
-    {
-      return  __and_<__not_<is_same<tuple<_Elements...>,
-				    __remove_cvref_t<_SrcTuple>>>,
-                     __not_<is_convertible<_SrcTuple, _Elements...>>,
-                     __not_<is_constructible<_Elements..., _SrcTuple>>
-              >::value;
-    }
-
-    template<typename... _UElements>
-    static constexpr bool _NotSameTuple()
-    {
-      return  __not_<is_same<tuple<_Elements...>,
-			     __remove_cvref_t<_UElements>...>>::value;
-    }
-  };
-
-  template<typename... _Elements>
-  struct _TC<false, _Elements...>
-  {
-    template<typename... _UElements>
-    static constexpr bool _ConstructibleTuple()
-    {
-      return false;
-    }
-
-    template<typename... _UElements>
-    static constexpr bool _ImplicitlyConvertibleTuple()
-    {
-      return false;
-    }
-
-    template<typename... _UElements>
-    static constexpr bool _MoveConstructibleTuple()
-    {
-      return false;
-    }
-
-    template<typename... _UElements>
-    static constexpr bool _ImplicitlyMoveConvertibleTuple()
-    {
-      return false;
-    }
-
-    template<typename... _UElements>
-    static constexpr bool _NonNestedTuple()
-    {
-      return true;
-    }
-
-    template<typename... _UElements>
-    static constexpr bool _NotSameTuple()
-    {
-      return true;
-    }
-  };
-
-  /// Primary class template, tuple
-  template<typename... _Elements>
-    class tuple : public _Tuple_impl<0, _Elements...>
-    {
-      typedef _Tuple_impl<0, _Elements...> _Inherited;
-
-      // Used for constraining the default constructor so
-      // that it becomes dependent on the constraints.
-      template<typename _Dummy>
-      struct _TC2
-      {
-        static constexpr bool _DefaultConstructibleTuple()
-        {
-          return __and_<is_default_constructible<_Elements>...>::value;
-        }
-        static constexpr bool _ImplicitlyDefaultConstructibleTuple()
-        {
-          return __and_<__is_implicitly_default_constructible<_Elements>...>
-            ::value;
-        }
-      };
-
-      template<typename... _UElements>
-	static constexpr
-	__enable_if_t<sizeof...(_UElements) == sizeof...(_Elements), bool>
-	__assignable()
-	{ return __and_<is_assignable<_Elements&, _UElements>...>::value; }
-
-      template<typename... _UElements>
-	static constexpr bool __nothrow_assignable()
-	{
-	  return
-	    __and_<is_nothrow_assignable<_Elements&, _UElements>...>::value;
-	}
-
-    public:
-      template<typename _Dummy = void,
-               typename enable_if<_TC2<_Dummy>::
-                                    _ImplicitlyDefaultConstructibleTuple(),
-                                  bool>::type = true>
-      constexpr tuple()
-      : _Inherited() { }
-
-      template<typename _Dummy = void,
-               typename enable_if<_TC2<_Dummy>::
-                                    _DefaultConstructibleTuple()
-                                  &&
-                                  !_TC2<_Dummy>::
-                                    _ImplicitlyDefaultConstructibleTuple(),
-                                  bool>::type = false>
-      explicit constexpr tuple()
-      : _Inherited() { }
-
-      // Shortcut for the cases where constructors taking _Elements...
-      // need to be constrained.
-      template<typename _Dummy> using _TCC =
-        _TC<is_same<_Dummy, void>::value,
-            _Elements...>;
-
-      template<typename _Dummy = void,
-               typename enable_if<
-                 _TCC<_Dummy>::template
-                   _ConstructibleTuple<_Elements...>()
-                 && _TCC<_Dummy>::template
-                   _ImplicitlyConvertibleTuple<_Elements...>()
-                 && (sizeof...(_Elements) >= 1),
-               bool>::type=true>
-        constexpr tuple(const _Elements&... __elements)
-      : _Inherited(__elements...) { }
-
-      template<typename _Dummy = void,
-               typename enable_if<
-                 _TCC<_Dummy>::template
-                   _ConstructibleTuple<_Elements...>()
-                 && !_TCC<_Dummy>::template
-                   _ImplicitlyConvertibleTuple<_Elements...>()
-                 && (sizeof...(_Elements) >= 1),
-               bool>::type=false>
-      explicit constexpr tuple(const _Elements&... __elements)
-      : _Inherited(__elements...) { }
-
-      // Shortcut for the cases where constructors taking _UElements...
-      // need to be constrained.
-      template<typename... _UElements> using _TMC =
-                  _TC<(sizeof...(_Elements) == sizeof...(_UElements))
-		      && (_TC<(sizeof...(_UElements)==1), _Elements...>::
-			  template _NotSameTuple<_UElements...>()),
-                      _Elements...>;
-
-      // Shortcut for the cases where constructors taking tuple<_UElements...>
-      // need to be constrained.
-      template<typename... _UElements> using _TMCT =
-                  _TC<(sizeof...(_Elements) == sizeof...(_UElements))
-		      && !is_same<tuple<_Elements...>,
-				  tuple<_UElements...>>::value,
-                      _Elements...>;
-
-      template<typename... _UElements, typename
-	       enable_if<
-		  _TMC<_UElements...>::template
-                    _MoveConstructibleTuple<_UElements...>()
-                  && _TMC<_UElements...>::template
-                    _ImplicitlyMoveConvertibleTuple<_UElements...>()
-                  && (sizeof...(_Elements) >= 1),
-        bool>::type=true>
-        constexpr tuple(_UElements&&... __elements)
-        : _Inherited(std::forward<_UElements>(__elements)...) { }
-
-      template<typename... _UElements, typename
-        enable_if<
-		  _TMC<_UElements...>::template
-                    _MoveConstructibleTuple<_UElements...>()
-                  && !_TMC<_UElements...>::template
-                    _ImplicitlyMoveConvertibleTuple<_UElements...>()
-                  && (sizeof...(_Elements) >= 1),
-        bool>::type=false>
-        explicit constexpr tuple(_UElements&&... __elements)
-	: _Inherited(std::forward<_UElements>(__elements)...) {	}
-
-      constexpr tuple(const tuple&) = default;
-
-      constexpr tuple(tuple&&) = default;
-
-      // Shortcut for the cases where constructors taking tuples
-      // must avoid creating temporaries.
-      template<typename _Dummy> using _TNTC =
-        _TC<is_same<_Dummy, void>::value && sizeof...(_Elements) == 1,
-            _Elements...>;
-
-      template<typename... _UElements, typename _Dummy = void, typename
-        enable_if<_TMCT<_UElements...>::template
-                    _ConstructibleTuple<_UElements...>()
-                  && _TMCT<_UElements...>::template
-                    _ImplicitlyConvertibleTuple<_UElements...>()
-                  && _TNTC<_Dummy>::template
-                    _NonNestedTuple<const tuple<_UElements...>&>(),
-        bool>::type=true>
-        constexpr tuple(const tuple<_UElements...>& __in)
-        : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
-        { }
-
-      template<typename... _UElements, typename _Dummy = void, typename
-        enable_if<_TMCT<_UElements...>::template
-                    _ConstructibleTuple<_UElements...>()
-                  && !_TMCT<_UElements...>::template
-                    _ImplicitlyConvertibleTuple<_UElements...>()
-                  && _TNTC<_Dummy>::template
-                    _NonNestedTuple<const tuple<_UElements...>&>(),
-        bool>::type=false>
-        explicit constexpr tuple(const tuple<_UElements...>& __in)
-        : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
-        { }
-
-      template<typename... _UElements, typename _Dummy = void, typename
-        enable_if<_TMCT<_UElements...>::template
-                    _MoveConstructibleTuple<_UElements...>()
-                  && _TMCT<_UElements...>::template
-                    _ImplicitlyMoveConvertibleTuple<_UElements...>()
-                  && _TNTC<_Dummy>::template
-                    _NonNestedTuple<tuple<_UElements...>&&>(),
-        bool>::type=true>
-        constexpr tuple(tuple<_UElements...>&& __in)
-        : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
-
-      template<typename... _UElements, typename _Dummy = void, typename
-        enable_if<_TMCT<_UElements...>::template
-                    _MoveConstructibleTuple<_UElements...>()
-                  && !_TMCT<_UElements...>::template
-                    _ImplicitlyMoveConvertibleTuple<_UElements...>()
-                  && _TNTC<_Dummy>::template
-                    _NonNestedTuple<tuple<_UElements...>&&>(),
-        bool>::type=false>
-        explicit constexpr tuple(tuple<_UElements...>&& __in)
-        : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
-
-      // Allocator-extended constructors.
-
-      template<typename _Alloc>
-	tuple(allocator_arg_t __tag, const _Alloc& __a)
-	: _Inherited(__tag, __a) { }
-
-      template<typename _Alloc, typename _Dummy = void,
-               typename enable_if<
-                 _TCC<_Dummy>::template
-                   _ConstructibleTuple<_Elements...>()
-                 && _TCC<_Dummy>::template
-                   _ImplicitlyConvertibleTuple<_Elements...>(),
-               bool>::type=true>
-	tuple(allocator_arg_t __tag, const _Alloc& __a,
-	      const _Elements&... __elements)
-	: _Inherited(__tag, __a, __elements...) { }
-
-      template<typename _Alloc, typename _Dummy = void,
-               typename enable_if<
-                 _TCC<_Dummy>::template
-                   _ConstructibleTuple<_Elements...>()
-                 && !_TCC<_Dummy>::template
-                   _ImplicitlyConvertibleTuple<_Elements...>(),
-               bool>::type=false>
-	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
-                       const _Elements&... __elements)
-	: _Inherited(__tag, __a, __elements...) { }
-
-      template<typename _Alloc, typename... _UElements, typename
-        enable_if<_TMC<_UElements...>::template
-                    _MoveConstructibleTuple<_UElements...>()
-                  && _TMC<_UElements...>::template
-                    _ImplicitlyMoveConvertibleTuple<_UElements...>(),
-        bool>::type=true>
-	tuple(allocator_arg_t __tag, const _Alloc& __a,
-	      _UElements&&... __elements)
-	: _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
-       	{ }
-
-      template<typename _Alloc, typename... _UElements, typename
-        enable_if<_TMC<_UElements...>::template
-                    _MoveConstructibleTuple<_UElements...>()
-                  && !_TMC<_UElements...>::template
-                    _ImplicitlyMoveConvertibleTuple<_UElements...>(),
-        bool>::type=false>
-	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
-	      _UElements&&... __elements)
-	: _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
-        { }
-
-      template<typename _Alloc>
-	tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
-	: _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
-
-      template<typename _Alloc>
-	tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
-	: _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
-
-      template<typename _Alloc, typename _Dummy = void,
-	       typename... _UElements, typename
-        enable_if<_TMCT<_UElements...>::template
-                    _ConstructibleTuple<_UElements...>()
-                  && _TMCT<_UElements...>::template
-                    _ImplicitlyConvertibleTuple<_UElements...>()
-                  && _TNTC<_Dummy>::template
-                    _NonNestedTuple<tuple<_UElements...>&&>(),
-        bool>::type=true>
-	tuple(allocator_arg_t __tag, const _Alloc& __a,
-	      const tuple<_UElements...>& __in)
-	: _Inherited(__tag, __a,
-	             static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
-	{ }
-
-      template<typename _Alloc, typename _Dummy = void,
-	       typename... _UElements, typename
-        enable_if<_TMCT<_UElements...>::template
-                    _ConstructibleTuple<_UElements...>()
-                  && !_TMCT<_UElements...>::template
-                    _ImplicitlyConvertibleTuple<_UElements...>()
-                  && _TNTC<_Dummy>::template
-                    _NonNestedTuple<tuple<_UElements...>&&>(),
-        bool>::type=false>
-	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
-	      const tuple<_UElements...>& __in)
-	: _Inherited(__tag, __a,
-	             static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
-	{ }
-
-      template<typename _Alloc, typename _Dummy = void,
-	       typename... _UElements, typename
-        enable_if<_TMCT<_UElements...>::template
-                    _MoveConstructibleTuple<_UElements...>()
-                  && _TMCT<_UElements...>::template
-                    _ImplicitlyMoveConvertibleTuple<_UElements...>()
-                  && _TNTC<_Dummy>::template
-                    _NonNestedTuple<tuple<_UElements...>&&>(),
-        bool>::type=true>
-	tuple(allocator_arg_t __tag, const _Alloc& __a,
-	      tuple<_UElements...>&& __in)
-	: _Inherited(__tag, __a,
-	             static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
-	{ }
-
-      template<typename _Alloc, typename _Dummy = void,
-	       typename... _UElements, typename
-        enable_if<_TMCT<_UElements...>::template
-                    _MoveConstructibleTuple<_UElements...>()
-                  && !_TMCT<_UElements...>::template
-                    _ImplicitlyMoveConvertibleTuple<_UElements...>()
-                  && _TNTC<_Dummy>::template
-                    _NonNestedTuple<tuple<_UElements...>&&>(),
-        bool>::type=false>
-	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
-	      tuple<_UElements...>&& __in)
-	: _Inherited(__tag, __a,
-	             static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
-	{ }
-
-      // tuple assignment
-
-      tuple&
-      operator=(typename conditional<__assignable<const _Elements&...>(),
-				     const tuple&,
-				     const __nonesuch_no_braces&>::type __in)
-      noexcept(__nothrow_assignable<const _Elements&...>())
-      {
-	this->_M_assign(__in);
-	return *this;
-      }
-
-      tuple&
-      operator=(typename conditional<__assignable<_Elements...>(),
-				     tuple&&,
-				     __nonesuch_no_braces&&>::type __in)
-      noexcept(__nothrow_assignable<_Elements...>())
-      {
-	this->_M_assign(std::move(__in));
-	return *this;
-      }
-
-      template<typename... _UElements>
-	__enable_if_t<__assignable<const _UElements&...>(), tuple&>
-	operator=(const tuple<_UElements...>& __in)
-	noexcept(__nothrow_assignable<const _UElements&...>())
-	{
-	  this->_M_assign(__in);
-	  return *this;
-	}
-
-      template<typename... _UElements>
-	__enable_if_t<__assignable<_UElements...>(), tuple&>
-	operator=(tuple<_UElements...>&& __in)
-	noexcept(__nothrow_assignable<_UElements...>())
-	{
-	  this->_M_assign(std::move(__in));
-	  return *this;
-	}
-
-      // tuple swap
-      void
-      swap(tuple& __in)
-      noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value)
-      { _Inherited::_M_swap(__in); }
-    };
-
 #if __cpp_deduction_guides >= 201606
   template<typename... _UTypes>
     tuple(_UTypes...) -> tuple<_UTypes...>;
@@ -1304,46 +495,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  "tuple index is in range");
     };
 
-  template<std::size_t __i, typename _Head, typename... _Tail>
-    constexpr _Head&
-    __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
-    { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
-
-  template<std::size_t __i, typename _Head, typename... _Tail>
-    constexpr const _Head&
-    __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
-    { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
-
-  /// Return a reference to the ith element of a tuple.
-  template<std::size_t __i, typename... _Elements>
-    constexpr __tuple_element_t<__i, tuple<_Elements...>>&
-    get(tuple<_Elements...>& __t) noexcept
-    { return std::__get_helper<__i>(__t); }
-
-  /// Return a const reference to the ith element of a const tuple.
-  template<std::size_t __i, typename... _Elements>
-    constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
-    get(const tuple<_Elements...>& __t) noexcept
-    { return std::__get_helper<__i>(__t); }
-
-  /// Return an rvalue reference to the ith element of a tuple rvalue.
-  template<std::size_t __i, typename... _Elements>
-    constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
-    get(tuple<_Elements...>&& __t) noexcept
-    {
-      typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
-      return std::forward<__element_type&&>(std::get<__i>(__t));
-    }
-
-  /// Return a const rvalue reference to the ith element of a const tuple rvalue.
-  template<std::size_t __i, typename... _Elements>
-    constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
-    get(const tuple<_Elements...>&& __t) noexcept
-    {
-      typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
-      return std::forward<const __element_type&&>(std::get<__i>(__t));
-    }
-
 #if __cplusplus >= 201402L
 
 #define __cpp_lib_tuples_by_type 201304
@@ -1651,29 +802,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename... _Types, typename _Alloc>
     struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
 
-  // See stl_pair.h...
-  template<class _T1, class _T2>
-    template<typename... _Args1, typename... _Args2>
-      inline
-      pair<_T1, _T2>::
-      pair(piecewise_construct_t,
-	   tuple<_Args1...> __first, tuple<_Args2...> __second)
-      : pair(__first, __second,
-	     typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
-	     typename _Build_index_tuple<sizeof...(_Args2)>::__type())
-      { }
-
-  template<class _T1, class _T2>
-    template<typename... _Args1, std::size_t... _Indexes1,
-             typename... _Args2, std::size_t... _Indexes2>
-      inline
-      pair<_T1, _T2>::
-      pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
-	   _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
-      : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
-        second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
-      { }
-
 #if __cplusplus > 201402L
 # define __cpp_lib_apply 201603
 
@@ -1724,14 +852,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 			       pair<const _Up1, _Up2>& __orig)
     noexcept( noexcept(allocator_traits<_Allocator>::construct(__alloc,
 			__dest,
-			std::piecewise_construct,
-			std::tuple<const _Up1&>(__orig.first),
-			std::forward_as_tuple(std::move(__orig.second)))) )
+			piecewise_construct,
+			tuple<const _Up1&>(__orig.first),
+			forward_as_tuple(std::move(__orig.second)))) )
     {
       typedef allocator_traits<_Allocator> __traits;
-      __traits::construct(__alloc, __dest, std::piecewise_construct,
-			  std::tuple<const _Up1&>(__orig.first),
-			  std::forward_as_tuple(std::move(__orig.second)));
+      __traits::construct(__alloc, __dest, piecewise_construct,
+			  tuple<const _Up1&>(__orig.first),
+			  forward_as_tuple(std::move(__orig.second)));
     }
 
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 60094f9897b..f3cc9a17e43 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -2732,6 +2732,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     void operator=(__nonesuch const&) = delete;
   };
 
+  // PR libstdc++/79141, a utility type for preventing
+  // initialization of an argument of a disabled assignment
+  // operator from a pair of empty braces.
+  struct __nonesuch_no_braces : std::__nonesuch {
+    explicit __nonesuch_no_braces(const __nonesuch&) = delete;
+  };
+
 #if __cplusplus >= 201703L
 # define __cpp_lib_is_invocable 201703
 
diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility
index 273c0f838b8..f887f14912e 100644
--- a/libstdc++-v3/include/std/utility
+++ b/libstdc++-v3/include/std/utility
@@ -74,6 +74,8 @@
 #include <type_traits>
 #include <bits/move.h>
 #include <initializer_list>
+#include <bits/build_index_tuple.h>
+#include <bits/tuple_element.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -105,32 +107,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     struct tuple_size<const volatile __enable_if_has_tuple_size<_Tp>>
     : public tuple_size<_Tp> { };
 
-  /// Gives the type of the ith element of a given tuple type.
-  template<std::size_t __i, typename _Tp>
-    struct tuple_element;
-
-  // Duplicate of C++14's tuple_element_t for internal use in C++11 mode
-  template<std::size_t __i, typename _Tp>
-    using __tuple_element_t = typename tuple_element<__i, _Tp>::type;
-
-  template<std::size_t __i, typename _Tp>
-    struct tuple_element<__i, const _Tp>
-    {
-      typedef typename add_const<__tuple_element_t<__i, _Tp>>::type type;
-    };
-
-  template<std::size_t __i, typename _Tp>
-    struct tuple_element<__i, volatile _Tp>
-    {
-      typedef typename add_volatile<__tuple_element_t<__i, _Tp>>::type type;
-    };
-
-  template<std::size_t __i, typename _Tp>
-    struct tuple_element<__i, const volatile _Tp>
-    {
-      typedef typename add_cv<__tuple_element_t<__i, _Tp>>::type type;
-    };
-
 #if __cplusplus >= 201402L
 // The standard says this macro and alias template should be in <tuple>
 // but we define them here, to be available when the partial specializations
@@ -287,30 +263,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { return std::__exchange(__obj, std::forward<_Up>(__new_val)); }
 #endif
 
-  // Stores a tuple of indices.  Used by tuple and pair, and by bind() to
-  // extract the elements in a tuple.
-  template<size_t... _Indexes> struct _Index_tuple { };
-
-#ifdef __has_builtin
-# if __has_builtin(__make_integer_seq)
-#  define _GLIBCXX_USE_MAKE_INTEGER_SEQ 1
-# endif
-#endif
-
-  // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
-  template<size_t _Num>
-    struct _Build_index_tuple
-    {
-#if _GLIBCXX_USE_MAKE_INTEGER_SEQ
-      template<typename, size_t... _Indices>
-        using _IdxTuple = _Index_tuple<_Indices...>;
-
-      using __type = __make_integer_seq<_IdxTuple, size_t, _Num>;
-#else
-      using __type = _Index_tuple<__integer_pack(_Num)...>;
-#endif
-    };
-
 #if __cplusplus > 201103L
 
 #define __cpp_lib_integer_sequence 201304

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]