* 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 <jwak...@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 --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 );