libstdc++: Implement LWG 3820/3849 changes to cartesian_product_view

The LWG 3820 testcase revealed a bug in _M_advance, which this patch
also fixes.

libstdc++-v3/ChangeLog:

	* include/std/ranges
	(cartesian_product_view::_Iterator::_Iterator): Remove
	constraint on default constructor as per LWG 3849.
	(cartesian_product_view::_Iterator::_M_prev): Adjust position
	of _Nm > 0 test as per LWG 3820.
	(cartesian_product_view::_Iterator::_M_advance): Perform bounds
	checking only on sized cartesian products.
	* testsuite/std/ranges/cartesian_product/1.cc (test08): New test.
This commit is contained in:
Patrick Palka 2023-03-09 13:41:03 -05:00
parent 065c93b89c
commit 96abc82224
2 changed files with 22 additions and 10 deletions

View File

@ -8224,7 +8224,7 @@ namespace views::__adaptor
range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
using difference_type = decltype(cartesian_product_view::_S_difference_type());
_Iterator() requires forward_range<__maybe_const_t<_Const, _First>> = default;
_Iterator() = default;
constexpr
_Iterator(_Iterator<!_Const> __i)
@ -8389,12 +8389,12 @@ namespace views::__adaptor
_M_prev()
{
auto& __it = std::get<_Nm>(_M_current);
if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
{
__it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
if constexpr (_Nm > 0)
if constexpr (_Nm > 0)
if (__it == ranges::begin(std::get<_Nm>(_M_parent->_M_bases)))
{
__it = __detail::__cartesian_common_arg_end(std::get<_Nm>(_M_parent->_M_bases));
_M_prev<_Nm - 1>();
}
}
--__it;
}
@ -8415,10 +8415,13 @@ namespace views::__adaptor
if constexpr (_Nm == 0)
{
#ifdef _GLIBCXX_ASSERTIONS
auto __size = ranges::ssize(__r);
auto __begin = ranges::begin(__r);
auto __offset = __it - __begin;
__glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
if constexpr (sized_range<__maybe_const_t<_Const, _First>>)
{
auto __size = ranges::ssize(__r);
auto __begin = ranges::begin(__r);
auto __offset = __it - __begin;
__glibcxx_assert(__offset + __x >= 0 && __offset + __x <= __size);
}
#endif
__it += __x;
}

View File

@ -201,6 +201,14 @@ test07()
VERIFY( i == 5 );
}
void
test08()
{
// LWG 3820
auto r = views::cartesian_product(views::iota(0));
r.begin() += 3;
}
int
main()
{
@ -211,4 +219,5 @@ main()
test05();
static_assert(test06());
test07();
test08();
}