2020-03-10 Jonathan Wakely <jwakely@redhat.com>
+ * include/std/ranges (transform_view::_Iterator::__iter_move): Remove.
+ (transform_view::_Iterator::operator*): Add noexcept-specifier.
+ (transform_view::_Iterator::iter_move): Inline __iter_move body here.
+ (split_view::_OuterIter::__current): Add noexcept.
+ (split_view::_InnerIter::__iter_swap): Remove.
+ (split_view::_InnerIter::__iter_move): Remove.
+ (split_view::_InnerIter::_M_i_current): New accessors.
+ (split_view::_InnerIter::__at_end): Use _M_i_current().
+ (split_view::_InnerIter::operator*): Likewise.
+ (split_view::_InnerIter::operator++): Likewise.
+ (iter_move(const _InnerIter&)): Likewise.
+ (iter_swap(const _InnerIter&, const _InnerIter&)): Likewise.
+ * testsuite/std/ranges/adaptors/split.cc: Check noexcept-specifier
+ for iter_move and iter_swap on split_view's inner iterator.
+
PR c++/94117
* include/std/ranges (ranges::transform_view::_Iterator::iter_move):
Change expression in noexcept-specifier to match function body.
return input_iterator_tag{};
}
- static constexpr decltype(auto)
- __iter_move(const _Iterator& __i = {})
- noexcept(noexcept(std::__invoke(*__i._M_parent->_M_fun,
- *__i._M_current)))
- {
- if constexpr (is_lvalue_reference_v<decltype(*__i)>)
- return std::move(*__i);
- else
- return *__i;
- }
-
using _Base_iter = iterator_t<_Base>;
_Base_iter _M_current = _Base_iter();
constexpr decltype(auto)
operator*() const
+ noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
{ return std::__invoke(*_M_parent->_M_fun, *_M_current); }
constexpr _Iterator&
{ return __x._M_current - __y._M_current; }
friend constexpr decltype(auto)
- iter_move(const _Iterator& __i) noexcept(noexcept(__iter_move(__i)))
- { return __iter_move(__i); }
+ iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
+ {
+ if constexpr (is_lvalue_reference_v<decltype(*__i)>)
+ return std::move(*__i);
+ else
+ return *__i;
+ }
friend constexpr void
iter_swap(const _Iterator& __x, const _Iterator& __y)
// current of outer-iterator. current is equivalent to current_ if
// V models forward_range, and parent_->current_ otherwise.
constexpr auto&
- __current()
+ __current() noexcept
{
if constexpr (forward_range<_Vp>)
return _M_current;
}
constexpr auto&
- __current() const
+ __current() const noexcept
{
if constexpr (forward_range<_Vp>)
return _M_current;
auto __end = ranges::end(_M_i._M_parent->_M_base);
if constexpr (__detail::__tiny_range<_Pattern>)
{
- const auto& __cur = _M_i.__current();
+ const auto& __cur = _M_i_current();
if (__cur == __end)
return true;
if (__pcur == __pend)
}
else
{
- auto __cur = _M_i.__current();
+ auto __cur = _M_i_current();
if (__cur == __end)
return true;
if (__pcur == __pend)
return _Cat{};
}
- static constexpr decltype(auto)
- __iter_move(const _InnerIter& __i = {})
- noexcept(noexcept(ranges::iter_move(__i._M_i.__current())))
- { return ranges::iter_move(__i._M_i.__current()); }
+ constexpr auto&
+ _M_i_current() noexcept
+ { return _M_i.__current(); }
- static constexpr void
- __iter_swap(const _InnerIter& __x = {}, const _InnerIter& __y = {})
- noexcept(noexcept(ranges::iter_swap(__x._M_i.__current(),
- __y._M_i.__current())))
- { ranges::iter_swap(__x._M_i.__current(), __y._M_i.__current()); }
+ constexpr auto&
+ _M_i_current() const noexcept
+ { return _M_i.__current(); }
_OuterIter<_Const> _M_i = _OuterIter<_Const>();
bool _M_incremented = false;
constexpr decltype(auto)
operator*() const
- { return *_M_i._M_current; }
+ { return *_M_i_current(); }
constexpr _InnerIter&
operator++()
if constexpr (!forward_range<_Base>)
if constexpr (_Pattern::size() == 0)
return *this;
- ++_M_i.__current();
+ ++_M_i_current();
return *this;
}
{ return __x.__at_end(); }
friend constexpr decltype(auto)
- iter_move(const _InnerIter& __i) noexcept(noexcept(__iter_move()))
- { return __iter_move(__i); }
+ iter_move(const _InnerIter& __i)
+ noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
+ { return ranges::iter_move(__i._M_i_current()); }
friend constexpr void
iter_swap(const _InnerIter& __x, const _InnerIter& __y)
- noexcept(noexcept(__iter_swap()))
+ noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
+ __y._M_i_current())))
requires indirectly_swappable<iterator_t<_Base>>
- { __iter_swap(__x, __y); }
+ { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
};
_Vp _M_base = _Vp();
begin()
{
if constexpr (forward_range<_Vp>)
- return _OuterIter<__detail::__simple_view<_Vp>>{*this,
- ranges::begin(_M_base)};
+ return _OuterIter<__detail::__simple_view<_Vp>>{
+ *this, ranges::begin(_M_base)};
else
{
_M_current = ranges::begin(_M_base);
constexpr auto
end() requires forward_range<_Vp> && common_range<_Vp>
{
- return _OuterIter<__detail::__simple_view<_Vp>>{*this, ranges::end(_M_base)};
+ return _OuterIter<__detail::__simple_view<_Vp>>{
+ *this, ranges::end(_M_base)};
}
constexpr auto