diff mbox series

Implement C++20 constexpr changes to std::pair (P1032R1)

Message ID 20190926160754.GA29062@redhat.com
State New
Headers show
Series Implement C++20 constexpr changes to std::pair (P1032R1) | expand

Commit Message

Jonathan Wakely Sept. 26, 2019, 4:07 p.m. UTC
* include/bits/stl_pair.h (pair): Add _GLIBCXX20_CONSTEXPR to
	piecewise construction constructor, assignment operators, and swap.
	* include/std/tuple (pair::pair(piecewise_construct_t, tuple, tuple)):
	Add _GLIBCXX20_CONSTEXPR.
	(pair::pair(tuple, tuple, _Index_tuple, _Index_tuple)): Likewise.
	* testsuite/20_util/pair/constexpr_assign.cc: New test.
	* testsuite/20_util/pair/constexpr_swap.cc: New test.

There are still more pieces of P1032R1 that need to be implemented,
including (at least) the std::tuple bits.

Tested x86_64-linux, committed to trunk.
commit 30fc6a7e208ba88bd874145fc9a1570862964a5f
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Thu Sep 26 15:42:10 2019 +0100

    Implement C++20 constexpr changes to std::pair (P1032R1)
    
            * include/bits/stl_pair.h (pair): Add _GLIBCXX20_CONSTEXPR to
            piecewise construction constructor, assignment operators, and swap.
            * include/std/tuple (pair::pair(piecewise_construct_t, tuple, tuple)):
            Add _GLIBCXX20_CONSTEXPR.
            (pair::pair(tuple, tuple, _Index_tuple, _Index_tuple)): Likewise.
            * testsuite/20_util/pair/constexpr_assign.cc: New test.
            * testsuite/20_util/pair/constexpr_swap.cc: New test.
diff mbox series

Patch

diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h
index c04f169bb6c..f7ad1696545 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -380,9 +380,10 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  second(std::forward<_U2>(__p.second)) { }
 
       template<typename... _Args1, typename... _Args2>
+	_GLIBCXX20_CONSTEXPR
         pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
 
-      pair&
+      _GLIBCXX20_CONSTEXPR pair&
       operator=(typename conditional<
 		__and_<is_copy_assignable<_T1>,
 		       is_copy_assignable<_T2>>::value,
@@ -393,7 +394,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	return *this;
       }
 
-      pair&
+      _GLIBCXX20_CONSTEXPR pair&
       operator=(typename conditional<
 		__and_<is_move_assignable<_T1>,
 		       is_move_assignable<_T2>>::value,
@@ -407,9 +408,10 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
       template<typename _U1, typename _U2>
-      typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
-				is_assignable<_T2&, const _U2&>>::value,
-			 pair&>::type
+	_GLIBCXX20_CONSTEXPR
+	typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
+				  is_assignable<_T2&, const _U2&>>::value,
+			   pair&>::type
 	operator=(const pair<_U1, _U2>& __p)
 	{
 	  first = __p.first;
@@ -418,9 +420,10 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
 
       template<typename _U1, typename _U2>
-      typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
-				is_assignable<_T2&, _U2&&>>::value,
-			 pair&>::type
+	_GLIBCXX20_CONSTEXPR
+	typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
+				  is_assignable<_T2&, _U2&&>>::value,
+			   pair&>::type
 	operator=(pair<_U1, _U2>&& __p)
 	{
 	  first = std::forward<_U1>(__p.first);
@@ -429,7 +432,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
 
       /// Swap the first members and then the second members.
-      void
+      _GLIBCXX20_CONSTEXPR void
       swap(pair& __p)
       noexcept(__and_<__is_nothrow_swappable<_T1>,
                       __is_nothrow_swappable<_T2>>::value)
@@ -442,6 +445,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
     private:
       template<typename... _Args1, std::size_t... _Indexes1,
                typename... _Args2, std::size_t... _Indexes2>
+	_GLIBCXX20_CONSTEXPR
         pair(tuple<_Args1...>&, tuple<_Args2...>&,
              _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
 #endif
@@ -503,7 +507,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
    * which has performance implications, e.g. see https://gcc.gnu.org/PR38466
   */
   template<typename _T1, typename _T2>
-    inline
+    _GLIBCXX20_CONSTEXPR inline
 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
     // Constrained free swap overload, see p0185r1
     typename enable_if<__and_<__is_swappable<_T1>,
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index dd966b3a0bc..ae1a3d0d18b 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -1570,7 +1570,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   */
   template<class _T1, class _T2>
     template<typename... _Args1, typename... _Args2>
-      inline
+      _GLIBCXX20_CONSTEXPR inline
       pair<_T1, _T2>::
       pair(piecewise_construct_t,
 	   tuple<_Args1...> __first, tuple<_Args2...> __second)
@@ -1582,7 +1582,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<class _T1, class _T2>
     template<typename... _Args1, std::size_t... _Indexes1,
              typename... _Args2, std::size_t... _Indexes2>
-      inline
+      _GLIBCXX20_CONSTEXPR inline
       pair<_T1, _T2>::
       pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
 	   _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
diff --git a/libstdc++-v3/testsuite/20_util/pair/constexpr_assign.cc b/libstdc++-v3/testsuite/20_util/pair/constexpr_assign.cc
new file mode 100644
index 00000000000..7abf2370658
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/pair/constexpr_assign.cc
@@ -0,0 +1,39 @@ 
+// Copyright (C) 2019 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <utility>
+#include <tuple>
+
+constexpr int
+test01(int i, int j)
+{
+  using T = std::tuple<int>;
+  std::pair<int, int> p0, p1, p2, p3;
+  std::pair<int, int> pij(std::piecewise_construct, T(i), T(j));
+  p0 = pij;
+  p1 = std::move(pij);
+  std::pair<long, long> pijl(i, j);
+  p2 = pijl;
+  p3 = std::move(pijl);
+  return p0.first + p0.second + p1.first + p1.second
+    + p2.first + p2.second + p3.first + p3.second;
+}
+
+static_assert( test01(3, 100) == 412 );
diff --git a/libstdc++-v3/testsuite/20_util/pair/constexpr_swap.cc b/libstdc++-v3/testsuite/20_util/pair/constexpr_swap.cc
new file mode 100644
index 00000000000..a69308b1d5e
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/pair/constexpr_swap.cc
@@ -0,0 +1,36 @@ 
+// Copyright (C) 2019 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.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <utility>
+#include <tuple>
+
+constexpr int
+test01(int i, int j)
+{
+  using T = std::tuple<int>;
+  std::pair<int, int> p0, p1;
+  std::pair<int, int> pij(std::piecewise_construct, T(i), T(j));
+  std::pair<int, int> pji(std::piecewise_construct, T(j), T(i));
+  p0.swap(pij);
+  swap(p1, pji);
+  return p0.first - p0.second - p1.first + p1.second;
+}
+
+static_assert( test01(5, 100) == -190 );