From 7028b67f11b78d925f5aed83501f00b092edd3d9 Mon Sep 17 00:00:00 2001 From: Jakub Mazurkiewicz Date: Fri, 26 May 2023 00:30:24 +0200 Subject: [PATCH 1/3] Fix bug --- stl/inc/ranges | 22 ++++++++++++------- .../P2374R4_views_cartesian_product/test.cpp | 11 ++++++++++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/stl/inc/ranges b/stl/inc/ranges index cc5c841ba9..3929960146 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -10061,11 +10061,14 @@ namespace ranges { { return [&](index_sequence<_Indices...>) { #if _CONTAINER_DEBUG_LEVEL > 0 + const array _Sizes = {static_cast<_Size_type>(_RANGES size(_STD get<_Indices>(_Bases)))...}; + const bool _Any_zero = ((_Sizes[_Indices] == 0) || ...); + if (_Any_zero) { + return _Size_type{0}; + } + _Size_type _Product{1}; - const bool _Overflow = - (_Mul_overflow( - _Product, static_cast<_Size_type>(_RANGES size(_STD get<_Indices>(_Bases))), _Product) - || ...); + const bool _Overflow = (_Mul_overflow(_Product, _Sizes[_Indices], _Product) || ...); _STL_VERIFY(!_Overflow, "Size of cartesian product cannot be represented by size type (N4950 " "[range.cartesian.view]/10)."); return _Product; @@ -10080,11 +10083,14 @@ namespace ranges { { return [&](index_sequence<_Indices...>) { #if _CONTAINER_DEBUG_LEVEL > 0 + const array _Sizes = {static_cast<_Size_type>(_RANGES size(_STD get<_Indices>(_Bases)))...}; + const bool _Any_zero = ((_Sizes[_Indices] == 0) || ...); + if (_Any_zero) { + return _Size_type{0}; + } + _Size_type _Product{1}; - const bool _Overflow = - (_Mul_overflow( - _Product, static_cast<_Size_type>(_RANGES size(_STD get<_Indices>(_Bases))), _Product) - || ...); + const bool _Overflow = (_Mul_overflow(_Product, _Sizes[_Indices], _Product) || ...); _STL_VERIFY(!_Overflow, "Size of cartesian product cannot be represented by size type (N4950 " "[range.cartesian.view]/10)."); return _Product; diff --git a/tests/std/tests/P2374R4_views_cartesian_product/test.cpp b/tests/std/tests/P2374R4_views_cartesian_product/test.cpp index d9e657cdeb..f1ce49af23 100644 --- a/tests/std/tests/P2374R4_views_cartesian_product/test.cpp +++ b/tests/std/tests/P2374R4_views_cartesian_product/test.cpp @@ -973,6 +973,14 @@ namespace check_recommended_practice_implementation { // MSVC STL specific behav STATIC_ASSERT(sizeof(range_difference_t, all_t>>) > sizeof(ptrdiff_t)); } // namespace check_recommended_practice_implementation +constexpr void test_gh_NNNN() { + const auto r1 = views::repeat(0, (numeric_limits::max)()); + const auto r2 = views::repeat(1, 0); + const auto cart = views::cartesian_product(r1, r1, r1, r2); + assert(cart.size() == 0); + assert(as_const(cart).size() == 0); +} + int main() { // Check views { // ... copyable @@ -1029,4 +1037,7 @@ int main() { STATIC_ASSERT((instantiation_test(), true)); #endif // TRANSITION, GH-1030 instantiation_test(); + + STATIC_ASSERT((test_gh_NNNN(), true)); + test_gh_NNNN(); } From 297fd7f840c7bdd907027a42290922f4fbcf9b51 Mon Sep 17 00:00:00 2001 From: Jakub Mazurkiewicz Date: Fri, 26 May 2023 00:40:29 +0200 Subject: [PATCH 2/3] GH-3733 --- tests/std/tests/P2374R4_views_cartesian_product/test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/std/tests/P2374R4_views_cartesian_product/test.cpp b/tests/std/tests/P2374R4_views_cartesian_product/test.cpp index f1ce49af23..262ce736a6 100644 --- a/tests/std/tests/P2374R4_views_cartesian_product/test.cpp +++ b/tests/std/tests/P2374R4_views_cartesian_product/test.cpp @@ -973,7 +973,7 @@ namespace check_recommended_practice_implementation { // MSVC STL specific behav STATIC_ASSERT(sizeof(range_difference_t, all_t>>) > sizeof(ptrdiff_t)); } // namespace check_recommended_practice_implementation -constexpr void test_gh_NNNN() { +constexpr void test_gh_3733() { const auto r1 = views::repeat(0, (numeric_limits::max)()); const auto r2 = views::repeat(1, 0); const auto cart = views::cartesian_product(r1, r1, r1, r2); @@ -1038,6 +1038,6 @@ int main() { #endif // TRANSITION, GH-1030 instantiation_test(); - STATIC_ASSERT((test_gh_NNNN(), true)); - test_gh_NNNN(); + STATIC_ASSERT((test_gh_3733(), true)); + test_gh_3733(); } From 015cee30ffa4e4ad0ccb666b9c5131be90b07e36 Mon Sep 17 00:00:00 2001 From: Jakub Mazurkiewicz Date: Fri, 26 May 2023 01:05:25 +0200 Subject: [PATCH 3/3] forgot about comment --- tests/std/tests/P2374R4_views_cartesian_product/test.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/std/tests/P2374R4_views_cartesian_product/test.cpp b/tests/std/tests/P2374R4_views_cartesian_product/test.cpp index 262ce736a6..7a3daa44fa 100644 --- a/tests/std/tests/P2374R4_views_cartesian_product/test.cpp +++ b/tests/std/tests/P2374R4_views_cartesian_product/test.cpp @@ -973,6 +973,8 @@ namespace check_recommended_practice_implementation { // MSVC STL specific behav STATIC_ASSERT(sizeof(range_difference_t, all_t>>) > sizeof(ptrdiff_t)); } // namespace check_recommended_practice_implementation +// GH-3733: cartesian_product_view would incorrectly reject a call to size() claiming that big*big*big*0 is not +// representable as range_size_t because big*big*big is not. constexpr void test_gh_3733() { const auto r1 = views::repeat(0, (numeric_limits::max)()); const auto r2 = views::repeat(1, 0);