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
This commit is contained in:
parent
d5f7e04923
commit
7a9942f521
|
@ -1,5 +1,13 @@
|
||||||
2019-09-26 Jonathan Wakely <jwakely@redhat.com>
|
2019-09-26 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
* 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
|
* include/experimental/internet (operator==, operator<): Fix loop
|
||||||
condition to avoid reading past the end of the array.
|
condition to avoid reading past the end of the array.
|
||||||
|
|
||||||
|
|
|
@ -380,9 +380,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
second(std::forward<_U2>(__p.second)) { }
|
second(std::forward<_U2>(__p.second)) { }
|
||||||
|
|
||||||
template<typename... _Args1, typename... _Args2>
|
template<typename... _Args1, typename... _Args2>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
|
pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
|
||||||
|
|
||||||
pair&
|
_GLIBCXX20_CONSTEXPR pair&
|
||||||
operator=(typename conditional<
|
operator=(typename conditional<
|
||||||
__and_<is_copy_assignable<_T1>,
|
__and_<is_copy_assignable<_T1>,
|
||||||
is_copy_assignable<_T2>>::value,
|
is_copy_assignable<_T2>>::value,
|
||||||
|
@ -393,7 +394,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
pair&
|
_GLIBCXX20_CONSTEXPR pair&
|
||||||
operator=(typename conditional<
|
operator=(typename conditional<
|
||||||
__and_<is_move_assignable<_T1>,
|
__and_<is_move_assignable<_T1>,
|
||||||
is_move_assignable<_T2>>::value,
|
is_move_assignable<_T2>>::value,
|
||||||
|
@ -407,9 +408,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename _U1, typename _U2>
|
template<typename _U1, typename _U2>
|
||||||
typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
|
_GLIBCXX20_CONSTEXPR
|
||||||
is_assignable<_T2&, const _U2&>>::value,
|
typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
|
||||||
pair&>::type
|
is_assignable<_T2&, const _U2&>>::value,
|
||||||
|
pair&>::type
|
||||||
operator=(const pair<_U1, _U2>& __p)
|
operator=(const pair<_U1, _U2>& __p)
|
||||||
{
|
{
|
||||||
first = __p.first;
|
first = __p.first;
|
||||||
|
@ -418,9 +420,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename _U1, typename _U2>
|
template<typename _U1, typename _U2>
|
||||||
typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
|
_GLIBCXX20_CONSTEXPR
|
||||||
is_assignable<_T2&, _U2&&>>::value,
|
typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
|
||||||
pair&>::type
|
is_assignable<_T2&, _U2&&>>::value,
|
||||||
|
pair&>::type
|
||||||
operator=(pair<_U1, _U2>&& __p)
|
operator=(pair<_U1, _U2>&& __p)
|
||||||
{
|
{
|
||||||
first = std::forward<_U1>(__p.first);
|
first = std::forward<_U1>(__p.first);
|
||||||
|
@ -429,7 +432,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Swap the first members and then the second members.
|
/// Swap the first members and then the second members.
|
||||||
void
|
_GLIBCXX20_CONSTEXPR void
|
||||||
swap(pair& __p)
|
swap(pair& __p)
|
||||||
noexcept(__and_<__is_nothrow_swappable<_T1>,
|
noexcept(__and_<__is_nothrow_swappable<_T1>,
|
||||||
__is_nothrow_swappable<_T2>>::value)
|
__is_nothrow_swappable<_T2>>::value)
|
||||||
|
@ -442,6 +445,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
private:
|
private:
|
||||||
template<typename... _Args1, std::size_t... _Indexes1,
|
template<typename... _Args1, std::size_t... _Indexes1,
|
||||||
typename... _Args2, std::size_t... _Indexes2>
|
typename... _Args2, std::size_t... _Indexes2>
|
||||||
|
_GLIBCXX20_CONSTEXPR
|
||||||
pair(tuple<_Args1...>&, tuple<_Args2...>&,
|
pair(tuple<_Args1...>&, tuple<_Args2...>&,
|
||||||
_Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
|
_Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
|
||||||
#endif
|
#endif
|
||||||
|
@ -503,7 +507,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
* which has performance implications, e.g. see https://gcc.gnu.org/PR38466
|
* which has performance implications, e.g. see https://gcc.gnu.org/PR38466
|
||||||
*/
|
*/
|
||||||
template<typename _T1, typename _T2>
|
template<typename _T1, typename _T2>
|
||||||
inline
|
_GLIBCXX20_CONSTEXPR inline
|
||||||
#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
|
#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
|
||||||
// Constrained free swap overload, see p0185r1
|
// Constrained free swap overload, see p0185r1
|
||||||
typename enable_if<__and_<__is_swappable<_T1>,
|
typename enable_if<__and_<__is_swappable<_T1>,
|
||||||
|
|
|
@ -1570,7 +1570,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
*/
|
*/
|
||||||
template<class _T1, class _T2>
|
template<class _T1, class _T2>
|
||||||
template<typename... _Args1, typename... _Args2>
|
template<typename... _Args1, typename... _Args2>
|
||||||
inline
|
_GLIBCXX20_CONSTEXPR inline
|
||||||
pair<_T1, _T2>::
|
pair<_T1, _T2>::
|
||||||
pair(piecewise_construct_t,
|
pair(piecewise_construct_t,
|
||||||
tuple<_Args1...> __first, tuple<_Args2...> __second)
|
tuple<_Args1...> __first, tuple<_Args2...> __second)
|
||||||
|
@ -1582,7 +1582,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
template<class _T1, class _T2>
|
template<class _T1, class _T2>
|
||||||
template<typename... _Args1, std::size_t... _Indexes1,
|
template<typename... _Args1, std::size_t... _Indexes1,
|
||||||
typename... _Args2, std::size_t... _Indexes2>
|
typename... _Args2, std::size_t... _Indexes2>
|
||||||
inline
|
_GLIBCXX20_CONSTEXPR inline
|
||||||
pair<_T1, _T2>::
|
pair<_T1, _T2>::
|
||||||
pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
|
pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
|
||||||
_Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
|
_Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
|
||||||
|
|
|
@ -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 );
|
|
@ -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 );
|
Loading…
Reference in New Issue