From 7a9942f52157987785e964fe602306d477d1885e Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 26 Sep 2019 17:08:39 +0100 Subject: [PATCH] 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. From-SVN: r276154 --- libstdc++-v3/ChangeLog | 8 ++++ libstdc++-v3/include/bits/stl_pair.h | 24 +++++++----- libstdc++-v3/include/std/tuple | 4 +- .../20_util/pair/constexpr_assign.cc | 39 +++++++++++++++++++ .../testsuite/20_util/pair/constexpr_swap.cc | 36 +++++++++++++++++ 5 files changed, 99 insertions(+), 12 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/pair/constexpr_assign.cc create mode 100644 libstdc++-v3/testsuite/20_util/pair/constexpr_swap.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 8484a7e1249..83e3225a432 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,13 @@ 2019-09-26 Jonathan Wakely + * 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. + * include/experimental/internet (operator==, operator<): Fix loop condition to avoid reading past the end of the array. 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 + _GLIBCXX20_CONSTEXPR pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>); - pair& + _GLIBCXX20_CONSTEXPR pair& operator=(typename conditional< __and_, 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<_T2>>::value, @@ -407,9 +408,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - typename enable_if<__and_, - is_assignable<_T2&, const _U2&>>::value, - pair&>::type + _GLIBCXX20_CONSTEXPR + typename enable_if<__and_, + 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 enable_if<__and_, - is_assignable<_T2&, _U2&&>>::value, - pair&>::type + _GLIBCXX20_CONSTEXPR + typename enable_if<__and_, + 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 + _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 - 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 template - 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 template - 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include +#include + +constexpr int +test01(int i, int j) +{ + using T = std::tuple; + std::pair p0, p1, p2, p3; + std::pair pij(std::piecewise_construct, T(i), T(j)); + p0 = pij; + p1 = std::move(pij); + std::pair 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do compile { target c++2a } } + +#include +#include + +constexpr int +test01(int i, int j) +{ + using T = std::tuple; + std::pair p0, p1; + std::pair pij(std::piecewise_construct, T(i), T(j)); + std::pair 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 );