libstdc++: Add missing P0896 changes to <iterator>
I noticed that the following changes from this paper were not yet implemented. libstdc++-v3/ChangeLog: * include/bits/stl_iterator.h (reverse_iterator::iter_move): Define for C++20 as per P0896. (reverse_iterator::iter_swap): Likewise. (move_iterator::operator*): Apply P0896 changes for C++20. (move_iterator::operator[]): Likewise. * testsuite/24_iterators/reverse_iterator/cust.cc: New test.
This commit is contained in:
parent
251950d899
commit
080a23bce1
2 changed files with 85 additions and 0 deletions
|
@ -362,6 +362,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
operator[](difference_type __n) const
|
||||
{ return *(*this + __n); }
|
||||
|
||||
#if __cplusplus > 201703L && __cpp_lib_concepts
|
||||
friend constexpr iter_rvalue_reference_t<_Iterator>
|
||||
iter_move(const reverse_iterator& __i)
|
||||
noexcept(is_nothrow_copy_constructible_v<_Iterator>
|
||||
&& noexcept(ranges::iter_move(--std::declval<_Iterator&>())))
|
||||
{
|
||||
auto __tmp = __i.base();
|
||||
return ranges::iter_move(--__tmp);
|
||||
}
|
||||
|
||||
template<indirectly_swappable<_Iterator> _Iter2>
|
||||
friend constexpr void
|
||||
iter_swap(const reverse_iterator& __x,
|
||||
const reverse_iterator<_Iter2>& __y)
|
||||
noexcept(is_nothrow_copy_constructible_v<_Iterator>
|
||||
&& is_nothrow_copy_constructible_v<_Iter2>
|
||||
&& noexcept(ranges::iter_swap(--std::declval<_Iterator&>(),
|
||||
--std::declval<_Iter2&>())))
|
||||
{
|
||||
auto __xtmp = __x.base();
|
||||
auto __ytmp = __y.base();
|
||||
ranges::iter_swap(--__xtmp, --__ytmp);
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
template<typename _Tp>
|
||||
static _GLIBCXX17_CONSTEXPR _Tp*
|
||||
|
@ -1379,7 +1404,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
|
||||
_GLIBCXX17_CONSTEXPR reference
|
||||
operator*() const
|
||||
#if __cplusplus > 201703L && __cpp_lib_concepts
|
||||
{ return ranges::iter_move(_M_current); }
|
||||
#else
|
||||
{ return static_cast<reference>(*_M_current); }
|
||||
#endif
|
||||
|
||||
_GLIBCXX17_CONSTEXPR pointer
|
||||
operator->() const
|
||||
|
@ -1445,7 +1474,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||
|
||||
_GLIBCXX17_CONSTEXPR reference
|
||||
operator[](difference_type __n) const
|
||||
#if __cplusplus > 201703L && __cpp_lib_concepts
|
||||
{ return ranges::iter_move(_M_current + __n); }
|
||||
#else
|
||||
{ return std::move(_M_current[__n]); }
|
||||
#endif
|
||||
|
||||
#if __cplusplus > 201703L && __cpp_lib_concepts
|
||||
template<sentinel_for<_Iterator> _Sent>
|
||||
|
|
52
libstdc++-v3/testsuite/24_iterators/reverse_iterator/cust.cc
Normal file
52
libstdc++-v3/testsuite/24_iterators/reverse_iterator/cust.cc
Normal file
|
@ -0,0 +1,52 @@
|
|||
// Copyright (C) 2019-2020 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 <iterator>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
// This test is an adaptation of 24_iterators/move_iterator/cust.cc.
|
||||
|
||||
constexpr bool
|
||||
test01()
|
||||
{
|
||||
struct X
|
||||
{
|
||||
constexpr X(int i) noexcept : i(i) { }
|
||||
constexpr X(X&& x) noexcept : i(x.i) { x.i = -1; }
|
||||
constexpr X& operator=(X&& x) noexcept { i = x.i; x.i = 0; return *this; }
|
||||
int i;
|
||||
};
|
||||
|
||||
X arr[] = { 1, 2 };
|
||||
std::reverse_iterator<X*> i(arr + 1), j(arr + 2);
|
||||
static_assert(noexcept(std::ranges::iter_swap(i, j)));
|
||||
std::ranges::iter_swap(i, j);
|
||||
VERIFY( arr[0].i == 2 );
|
||||
VERIFY( arr[1].i == 1 );
|
||||
|
||||
static_assert(noexcept(std::ranges::iter_move(i)));
|
||||
X x = std::ranges::iter_move(i);
|
||||
VERIFY( arr[0].i == -1 );
|
||||
VERIFY( x.i == 2 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static_assert(test01());
|
Loading…
Add table
Reference in a new issue