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]

Re: Attempt to make std::pair piecewise constructor noexcept


Here is the working patch with a correct noexcept qualification on std::pair piecewise constructor.

But I won't propose it because I realized that it is not what I needed.

To eventually get the move I had to also qualify the copy constructor as noexcept. As we use noexcept qualification just to chose between move and copy, noexcept qualification on the copy part shouldn't be necessary to activate the move.

So the solution will be part of another mail thread. Here I just post the patch if anyone see any interest in it.

Thanks again for the help,
François


On 12/13/18 11:39 PM, Ville Voutilainen wrote:
On Fri, 14 Dec 2018 at 00:14, François Dumont <frs.dumont@gmail.com> wrote:
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,
std::pair isn't constructible from typename
_Build_index_tuple<sizeof...(_Args1)>::__type, so it's not
nothrow_constructible from it either. is_constructible (and
is_nothrow_constructible) requires public access, and can't detect
what
your private constructors do.


diff --git a/libstdc++-v3/Makefile.in b/libstdc++-v3/Makefile.in
index 7fe9efb23c9..d0d76237cec 100644
--- a/libstdc++-v3/Makefile.in
+++ b/libstdc++-v3/Makefile.in
@@ -365,6 +365,7 @@ prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
 python_mod_dir = @python_mod_dir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 77805e8680f..d88a9c65eb2 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -870,6 +870,7 @@ infodir
 docdir
 oldincludedir
 includedir
+runstatedir
 localstatedir
 sharedstatedir
 sysconfdir
@@ -994,6 +995,7 @@ datadir='${datarootdir}'
 sysconfdir='${prefix}/etc'
 sharedstatedir='${prefix}/com'
 localstatedir='${prefix}/var'
+runstatedir='${localstatedir}/run'
 includedir='${prefix}/include'
 oldincludedir='/usr/include'
 docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1246,6 +1248,15 @@ do
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
+  -runstatedir | --runstatedir | --runstatedi | --runstated \
+  | --runstate | --runstat | --runsta | --runst | --runs \
+  | --run | --ru | --r)
+    ac_prev=runstatedir ;;
+  -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
+  | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
+  | --run=* | --ru=* | --r=*)
+    runstatedir=$ac_optarg ;;
+
   -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
     ac_prev=sbindir ;;
   -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1383,7 +1394,7 @@ fi
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
-		libdir localedir mandir
+		libdir localedir mandir runstatedir
 do
   eval ac_val=\$$ac_var
   # Remove trailing slashes.
@@ -1536,6 +1547,7 @@ Fine tuning of the installation directories:
   --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
   --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
   --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --runstatedir=DIR       modifiable per-process data [LOCALSTATEDIR/run]
   --libdir=DIR            object code libraries [EPREFIX/lib]
   --includedir=DIR        C header files [PREFIX/include]
   --oldincludedir=DIR     C header files for non-gcc [/usr/include]
@@ -11844,7 +11856,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11847 "configure"
+#line 11859 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11950,7 +11962,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11953 "configure"
+#line 11965 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -15636,7 +15648,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; }
   # Fake what AC_TRY_COMPILE does.
 
     cat > conftest.$ac_ext << EOF
-#line 15639 "configure"
+#line 15651 "configure"
 int main()
 {
   typedef bool atomic_type;
@@ -15671,7 +15683,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15674 "configure"
+#line 15686 "configure"
 int main()
 {
   typedef short atomic_type;
@@ -15706,7 +15718,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15709 "configure"
+#line 15721 "configure"
 int main()
 {
   // NB: _Atomic_word not necessarily int.
@@ -15742,7 +15754,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15745 "configure"
+#line 15757 "configure"
 int main()
 {
   typedef long long atomic_type;
@@ -15895,7 +15907,7 @@ $as_echo "mutex" >&6; }
   # unnecessary for this test.
 
     cat > conftest.$ac_ext << EOF
-#line 15898 "configure"
+#line 15910 "configure"
 int main()
 {
   _Decimal32 d1;
@@ -15937,7 +15949,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
   # unnecessary for this test.
 
     cat > conftest.$ac_ext << EOF
-#line 15940 "configure"
+#line 15952 "configure"
 template<typename T1, typename T2>
   struct same
   { typedef T2 type; };
@@ -15971,7 +15983,7 @@ $as_echo "$enable_int128" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15974 "configure"
+#line 15986 "configure"
 template<typename T1, typename T2>
   struct same
   { typedef T2 type; };
diff --git a/libstdc++-v3/doc/Makefile.in b/libstdc++-v3/doc/Makefile.in
index 0b2f6d663a2..8b31bb6389c 100644
--- a/libstdc++-v3/doc/Makefile.in
+++ b/libstdc++-v3/doc/Makefile.in
@@ -334,6 +334,7 @@ prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
 python_mod_dir = @python_mod_dir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 09aa1892a14..3b45e1f6fc3 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 \
@@ -199,6 +200,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/Makefile.in b/libstdc++-v3/include/Makefile.in
index 4d2642c8b78..9d2dcc055d8 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -324,6 +324,7 @@ prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
 python_mod_dir = @python_mod_dir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
@@ -442,6 +443,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 \
@@ -542,6 +544,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..28b72d315ba 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,16 @@ _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( noexcept(
+	  pair(declval<tuple<_Args1...>&>(), declval<tuple<_Args2...>&>(),
+	       declval<typename _Build_index_tuple<sizeof...(_Args1)>::__type>(),
+	       declval<typename _Build_index_tuple<sizeof...(_Args2)>::__type>())) )
+	: pair(__first, __second,
+	       typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
+	       typename _Build_index_tuple<sizeof...(_Args2)>::__type())
+	{ }
 
       pair&
       operator=(typename conditional<
@@ -432,9 +430,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 2171d13bf3b..1777f355d53 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
diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in
index 0bba2cfe94f..8156daa1f13 100644
--- a/libstdc++-v3/libsupc++/Makefile.in
+++ b/libstdc++-v3/libsupc++/Makefile.in
@@ -433,6 +433,7 @@ prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
 python_mod_dir = @python_mod_dir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
diff --git a/libstdc++-v3/po/Makefile.in b/libstdc++-v3/po/Makefile.in
index d0c57f332c4..a2ab08a4ef6 100644
--- a/libstdc++-v3/po/Makefile.in
+++ b/libstdc++-v3/po/Makefile.in
@@ -324,6 +324,7 @@ prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
 python_mod_dir = @python_mod_dir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
diff --git a/libstdc++-v3/python/Makefile.in b/libstdc++-v3/python/Makefile.in
index ee7387f05fc..a4b91ee29c1 100644
--- a/libstdc++-v3/python/Makefile.in
+++ b/libstdc++-v3/python/Makefile.in
@@ -354,6 +354,7 @@ prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
 python_mod_dir = @python_mod_dir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index de2324eaa5b..7ec78711955 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -419,6 +419,7 @@ prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
 python_mod_dir = @python_mod_dir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in
index 92816c8cb68..931b0dc29b9 100644
--- a/libstdc++-v3/src/c++11/Makefile.in
+++ b/libstdc++-v3/src/c++11/Makefile.in
@@ -390,6 +390,7 @@ prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
 python_mod_dir = @python_mod_dir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
diff --git a/libstdc++-v3/src/c++17/Makefile.in b/libstdc++-v3/src/c++17/Makefile.in
index 287b4b8bb69..fff6bbf1de7 100644
--- a/libstdc++-v3/src/c++17/Makefile.in
+++ b/libstdc++-v3/src/c++17/Makefile.in
@@ -366,6 +366,7 @@ prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
 python_mod_dir = @python_mod_dir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
diff --git a/libstdc++-v3/src/c++98/Makefile.in b/libstdc++-v3/src/c++98/Makefile.in
index 009cb1127e4..8d5e3997a87 100644
--- a/libstdc++-v3/src/c++98/Makefile.in
+++ b/libstdc++-v3/src/c++98/Makefile.in
@@ -386,6 +386,7 @@ prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
 python_mod_dir = @python_mod_dir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
diff --git a/libstdc++-v3/src/filesystem/Makefile.in b/libstdc++-v3/src/filesystem/Makefile.in
index f2345118033..3fd5724cc98 100644
--- a/libstdc++-v3/src/filesystem/Makefile.in
+++ b/libstdc++-v3/src/filesystem/Makefile.in
@@ -396,6 +396,7 @@ prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
 python_mod_dir = @python_mod_dir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move_assign.cc b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move_assign.cc
index 31f5accdffe..643c7ef2548 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move_assign.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_map/allocator/move_assign.cc
@@ -49,10 +49,9 @@ void test01()
   VERIFY( 1 == v1.get_allocator().get_personality() );
   VERIFY( 2 == v2.get_allocator().get_personality() );
 
-  // No noexcept qualification on std::pair piecewise constructor so no
-  // move for the moment.
-  VERIFY( counter_type::copy_count == 2  );
-  VERIFY( counter_type::move_count == 0  );
+  // Key is copied, value moved.
+  VERIFY( counter_type::copy_count == 1  );
+  VERIFY( counter_type::move_count == 1  );
   VERIFY( counter_type::destructor_count == 4 );
 }
 
diff --git a/libstdc++-v3/testsuite/Makefile.in b/libstdc++-v3/testsuite/Makefile.in
index 1033421eaeb..0042aa03df6 100644
--- a/libstdc++-v3/testsuite/Makefile.in
+++ b/libstdc++-v3/testsuite/Makefile.in
@@ -324,6 +324,7 @@ prefix = @prefix@
 program_transform_name = @program_transform_name@
 psdir = @psdir@
 python_mod_dir = @python_mod_dir@
+runstatedir = @runstatedir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
diff --git a/libstdc++-v3/testsuite/util/testsuite_counter_type.h b/libstdc++-v3/testsuite/util/testsuite_counter_type.h
index a1346d86a54..91feeb73d02 100644
--- a/libstdc++-v3/testsuite/util/testsuite_counter_type.h
+++ b/libstdc++-v3/testsuite/util/testsuite_counter_type.h
@@ -46,7 +46,8 @@ namespace __gnu_test
     counter_type(int inval) : val(inval)
     { ++specialize_count; }
 
-    counter_type(const counter_type& in) : val(in.val)
+    counter_type(const counter_type& in) throw()
+    : val(in.val)
     { ++copy_count; }
 
     ~counter_type()

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