From 097a33a616620f1ae07720e81dbff76b3116ce72 Mon Sep 17 00:00:00 2001 From: euvre <93761161+euvre@users.noreply.github.com> Date: Thu, 5 Sep 2024 08:32:57 +0000 Subject: [PATCH 01/13] fix 4879 --- stl/inc/spanstream | 7 ++++--- .../env.lst | 4 ++++ .../test.compile.pass.cpp | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/env.lst create mode 100644 tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/test.compile.pass.cpp diff --git a/stl/inc/spanstream b/stl/inc/spanstream index cf2347865b4..3c596cfc123 100644 --- a/stl/inc/spanstream +++ b/stl/inc/spanstream @@ -218,7 +218,8 @@ public: !convertible_to<_ReadOnlyRange, _STD span<_Elem>> && convertible_to<_ReadOnlyRange, _STD span>) explicit basic_ispanstream(_ReadOnlyRange&& _Range) : basic_ispanstream( - _STD span<_Elem>{const_cast<_Elem*>(_RANGES data(_Range)), static_cast(_RANGES size(_Range))}) {} + _STD span<_Elem>{const_cast<_Elem*>(_RANGES data(static_cast<_STD span>(_Range))), + static_cast(static_cast<_STD span>(_Range).size())}) {} basic_ispanstream& operator=(const basic_ispanstream&) = delete; @@ -251,8 +252,8 @@ public: requires ( !convertible_to<_ReadOnlyRange, _STD span<_Elem>> && convertible_to<_ReadOnlyRange, _STD span>) void span(_ReadOnlyRange&& _Range) noexcept { - this->span( - _STD span<_Elem>{const_cast<_Elem*>(_RANGES data(_Range)), static_cast(_RANGES size(_Range))}); + this->span(_STD span<_Elem>{const_cast<_Elem*>(_RANGES data(static_cast<_STD span>(_Range))), + static_cast(static_cast<_STD span>(_Range).size())}); } private: diff --git a/tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/env.lst b/tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/env.lst new file mode 100644 index 00000000000..642f530ffad --- /dev/null +++ b/tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_latest_matrix.lst diff --git a/tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/test.compile.pass.cpp b/tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/test.compile.pass.cpp new file mode 100644 index 00000000000..16ef1a776a1 --- /dev/null +++ b/tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/test.compile.pass.cpp @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// GH-4879 : The span constructed by basic_ispanstream's range constructor may be ill-formed + +#include + +struct R { + char* begin(); + std::unreachable_sentinel_t end(); + operator std::span(); +}; + +int main() { + R r{}; + std::basic_ispanstream is{ r }; + is.span(r); +} From 053dfb526333490aaf0faa5b4a64f029da4da7af Mon Sep 17 00:00:00 2001 From: euvre <93761161+euvre@users.noreply.github.com> Date: Thu, 5 Sep 2024 09:00:55 +0000 Subject: [PATCH 02/13] to make range operation consistent --- stl/inc/spanstream | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/spanstream b/stl/inc/spanstream index 3c596cfc123..dfdf599ad31 100644 --- a/stl/inc/spanstream +++ b/stl/inc/spanstream @@ -218,7 +218,7 @@ public: !convertible_to<_ReadOnlyRange, _STD span<_Elem>> && convertible_to<_ReadOnlyRange, _STD span>) explicit basic_ispanstream(_ReadOnlyRange&& _Range) : basic_ispanstream( - _STD span<_Elem>{const_cast<_Elem*>(_RANGES data(static_cast<_STD span>(_Range))), + _STD span<_Elem>{const_cast<_Elem*>(static_cast<_STD span>(_Range).data()), static_cast(static_cast<_STD span>(_Range).size())}) {} basic_ispanstream& operator=(const basic_ispanstream&) = delete; @@ -252,7 +252,7 @@ public: requires ( !convertible_to<_ReadOnlyRange, _STD span<_Elem>> && convertible_to<_ReadOnlyRange, _STD span>) void span(_ReadOnlyRange&& _Range) noexcept { - this->span(_STD span<_Elem>{const_cast<_Elem*>(_RANGES data(static_cast<_STD span>(_Range))), + this->span(_STD span<_Elem>{const_cast<_Elem*>(static_cast<_STD span>(_Range).data()), static_cast(static_cast<_STD span>(_Range).size())}); } From a1e4c47f36e16f7b18d2646bdef77e0fa0e28cb0 Mon Sep 17 00:00:00 2001 From: euvre <93761161+euvre@users.noreply.github.com> Date: Thu, 5 Sep 2024 10:58:02 +0000 Subject: [PATCH 03/13] fix double static_cast --- stl/inc/spanstream | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/spanstream b/stl/inc/spanstream index dfdf599ad31..6c90e56915b 100644 --- a/stl/inc/spanstream +++ b/stl/inc/spanstream @@ -219,7 +219,7 @@ public: explicit basic_ispanstream(_ReadOnlyRange&& _Range) : basic_ispanstream( _STD span<_Elem>{const_cast<_Elem*>(static_cast<_STD span>(_Range).data()), - static_cast(static_cast<_STD span>(_Range).size())}) {} + static_cast<_STD span>(_Range).size()}) {} basic_ispanstream& operator=(const basic_ispanstream&) = delete; @@ -253,7 +253,7 @@ public: !convertible_to<_ReadOnlyRange, _STD span<_Elem>> && convertible_to<_ReadOnlyRange, _STD span>) void span(_ReadOnlyRange&& _Range) noexcept { this->span(_STD span<_Elem>{const_cast<_Elem*>(static_cast<_STD span>(_Range).data()), - static_cast(static_cast<_STD span>(_Range).size())}); + static_cast<_STD span>(_Range).size()}); } private: From b0deca3fa5d6d6658e08c1d2c3358950143ae59a Mon Sep 17 00:00:00 2001 From: euvre <93761161+euvre@users.noreply.github.com> Date: Thu, 5 Sep 2024 11:02:04 +0000 Subject: [PATCH 04/13] make the code more concise --- stl/inc/spanstream | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/stl/inc/spanstream b/stl/inc/spanstream index 6c90e56915b..75278be644b 100644 --- a/stl/inc/spanstream +++ b/stl/inc/spanstream @@ -217,9 +217,8 @@ public: requires ( !convertible_to<_ReadOnlyRange, _STD span<_Elem>> && convertible_to<_ReadOnlyRange, _STD span>) explicit basic_ispanstream(_ReadOnlyRange&& _Range) - : basic_ispanstream( - _STD span<_Elem>{const_cast<_Elem*>(static_cast<_STD span>(_Range).data()), - static_cast<_STD span>(_Range).size()}) {} + : basic_ispanstream(_STD span<_Elem>{const_cast<_Elem*>(static_cast<_STD span>(_Range).data()), + static_cast<_STD span>(_Range).size()}) {} basic_ispanstream& operator=(const basic_ispanstream&) = delete; @@ -252,8 +251,8 @@ public: requires ( !convertible_to<_ReadOnlyRange, _STD span<_Elem>> && convertible_to<_ReadOnlyRange, _STD span>) void span(_ReadOnlyRange&& _Range) noexcept { - this->span(_STD span<_Elem>{const_cast<_Elem*>(static_cast<_STD span>(_Range).data()), - static_cast<_STD span>(_Range).size()}); + auto _Sp = static_cast<_STD span>(_Range); + this->span(_STD span<_Elem>{const_cast<_Elem*>(_Sp.data()), _Sp.size()}); } private: From 6e1770ae1e760271ce9cc4bb148ff1c1faf8eeb5 Mon Sep 17 00:00:00 2001 From: euvre <93761161+euvre@users.noreply.github.com> Date: Thu, 5 Sep 2024 11:34:35 +0000 Subject: [PATCH 05/13] correct the code formatting --- .../test.compile.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/test.compile.pass.cpp b/tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/test.compile.pass.cpp index 16ef1a776a1..4d4e0a00b14 100644 --- a/tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/test.compile.pass.cpp +++ b/tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/test.compile.pass.cpp @@ -13,6 +13,6 @@ struct R { int main() { R r{}; - std::basic_ispanstream is{ r }; + std::basic_ispanstream is{r}; is.span(r); } From 49de899068adc0ae41f64995ad7d59ac8194d175 Mon Sep 17 00:00:00 2001 From: euvre <93761161+euvre@users.noreply.github.com> Date: Fri, 6 Sep 2024 22:07:06 +0000 Subject: [PATCH 06/13] fix some relevant defects --- stl/inc/spanstream | 8 ++-- .../env.lst | 4 -- .../test.compile.pass.cpp | 18 --------- tests/std/tests/P0448R4_spanstream/test.cpp | 39 +++++++++++++++++++ 4 files changed, 44 insertions(+), 25 deletions(-) delete mode 100644 tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/env.lst delete mode 100644 tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/test.compile.pass.cpp diff --git a/stl/inc/spanstream b/stl/inc/spanstream index 75278be644b..34e0622ea2a 100644 --- a/stl/inc/spanstream +++ b/stl/inc/spanstream @@ -207,6 +207,9 @@ public: explicit basic_ispanstream(_STD span<_Elem> _Span, ios_base::openmode _Which = ios_base::in) : _Mybase(_STD addressof(_Buf)), _Buf(_Span, _Which | ios_base::in) {} + explicit basic_ispanstream(_STD span _Span) + : basic_ispanstream(_STD span<_Elem>{const_cast<_Elem*>(_Span.data()), _Span.size()}) {} + basic_ispanstream(const basic_ispanstream&) = delete; basic_ispanstream(basic_ispanstream&& _Right) : _Mybase(_STD move(_Right)), _Buf(_STD move(_Right._Buf)) { @@ -217,8 +220,7 @@ public: requires ( !convertible_to<_ReadOnlyRange, _STD span<_Elem>> && convertible_to<_ReadOnlyRange, _STD span>) explicit basic_ispanstream(_ReadOnlyRange&& _Range) - : basic_ispanstream(_STD span<_Elem>{const_cast<_Elem*>(static_cast<_STD span>(_Range).data()), - static_cast<_STD span>(_Range).size()}) {} + : basic_ispanstream(static_cast<_STD span>(_STD forward<_ReadOnlyRange>(_Range))) {} basic_ispanstream& operator=(const basic_ispanstream&) = delete; @@ -251,7 +253,7 @@ public: requires ( !convertible_to<_ReadOnlyRange, _STD span<_Elem>> && convertible_to<_ReadOnlyRange, _STD span>) void span(_ReadOnlyRange&& _Range) noexcept { - auto _Sp = static_cast<_STD span>(_Range); + const auto _Sp = static_cast<_STD span>(_STD forward<_ReadOnlyRange>(_Range)); this->span(_STD span<_Elem>{const_cast<_Elem*>(_Sp.data()), _Sp.size()}); } diff --git a/tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/env.lst b/tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/env.lst deleted file mode 100644 index 642f530ffad..00000000000 --- a/tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/env.lst +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright (c) Microsoft Corporation. -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -RUNALL_INCLUDE ..\usual_latest_matrix.lst diff --git a/tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/test.compile.pass.cpp b/tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/test.compile.pass.cpp deleted file mode 100644 index 4d4e0a00b14..00000000000 --- a/tests/std/tests/GH_004879_span_constructed_by_basic_ispanstream/test.compile.pass.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -// GH-4879 : The span constructed by basic_ispanstream's range constructor may be ill-formed - -#include - -struct R { - char* begin(); - std::unreachable_sentinel_t end(); - operator std::span(); -}; - -int main() { - R r{}; - std::basic_ispanstream is{r}; - is.span(r); -} diff --git a/tests/std/tests/P0448R4_spanstream/test.cpp b/tests/std/tests/P0448R4_spanstream/test.cpp index cf97ba7f317..fc7a631a700 100644 --- a/tests/std/tests/P0448R4_spanstream/test.cpp +++ b/tests/std/tests/P0448R4_spanstream/test.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,22 @@ constexpr array input_std_array{'1', ' ', '2', ' ', '3', ' ', '4', ' ', '5'}; template <> inline constexpr array input_std_array{L'1', L' ', L'2', L' ', L'3', L' ', L'4', L' ', L'5'}; +template +list li{}; +// Neither size_range nor continuous_range. +template +struct R { + auto begin() { + return std::begin(li); + } + auto end() { + return std::end(li); + } + operator span() const { + return span(input_view); + } +}; + template class basic_test_buf : public Spanbuf { public: @@ -624,6 +641,28 @@ void test_ispanstream() { assert(static_cast(range_constructed.rdbuf())->pbase() == nullptr); assert(static_cast(range_constructed.rdbuf())->pptr() == nullptr); assert(static_cast(range_constructed.rdbuf())->epptr() == nullptr); + + span span_const_elem; + basic_ispanstream span_const_elem_constructed{span_const_elem}; + assert(span_const_elem_constructed.span().data() == span_const_elem.data()); + assert(static_cast(span_const_elem_constructed.rdbuf())->eback() == span_const_elem.data()); + assert(static_cast(span_const_elem_constructed.rdbuf())->gptr() == span_const_elem.data()); + assert(static_cast(span_const_elem_constructed.rdbuf())->egptr() + == span_const_elem.data() + span_const_elem.size()); + assert(static_cast(span_const_elem_constructed.rdbuf())->pbase() == nullptr); + assert(static_cast(span_const_elem_constructed.rdbuf())->pptr() == nullptr); + assert(static_cast(span_const_elem_constructed.rdbuf())->epptr() == nullptr); + + R special_range{}; + auto rr = static_cast>(special_range); + basic_ispanstream special_range_constructed{special_range}; + assert(range_constructed.span().data() == rr.data()); + assert(static_cast(special_range_constructed.rdbuf())->eback() == rr.data()); + assert(static_cast(special_range_constructed.rdbuf())->gptr() == rr.data()); + assert(static_cast(special_range_constructed.rdbuf())->egptr() == rr.data() + rr.size()); + assert(static_cast(special_range_constructed.rdbuf())->pbase() == nullptr); + assert(static_cast(special_range_constructed.rdbuf())->pptr() == nullptr); + assert(static_cast(special_range_constructed.rdbuf())->epptr() == nullptr); } { // span From 03fa06436f091cfbf2191107e57adce14318ced8 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 6 Sep 2024 21:35:13 -0700 Subject: [PATCH 07/13] Fix comment typos. --- tests/std/tests/P0448R4_spanstream/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/P0448R4_spanstream/test.cpp b/tests/std/tests/P0448R4_spanstream/test.cpp index fc7a631a700..c2c7c16fd3f 100644 --- a/tests/std/tests/P0448R4_spanstream/test.cpp +++ b/tests/std/tests/P0448R4_spanstream/test.cpp @@ -32,7 +32,7 @@ inline constexpr array input_std_array{L'1', L' ', L'2', L' ', L'3', L' template list li{}; -// Neither size_range nor continuous_range. +// Neither sized_range nor contiguous_range. template struct R { auto begin() { From de86560a66023ac68756ccbe05186c35767b7f0d Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 6 Sep 2024 21:36:13 -0700 Subject: [PATCH 08/13] `R` => `SpecialRange` --- tests/std/tests/P0448R4_spanstream/test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/std/tests/P0448R4_spanstream/test.cpp b/tests/std/tests/P0448R4_spanstream/test.cpp index c2c7c16fd3f..30c40713eef 100644 --- a/tests/std/tests/P0448R4_spanstream/test.cpp +++ b/tests/std/tests/P0448R4_spanstream/test.cpp @@ -34,7 +34,7 @@ template list li{}; // Neither sized_range nor contiguous_range. template -struct R { +struct SpecialRange { auto begin() { return std::begin(li); } @@ -653,7 +653,7 @@ void test_ispanstream() { assert(static_cast(span_const_elem_constructed.rdbuf())->pptr() == nullptr); assert(static_cast(span_const_elem_constructed.rdbuf())->epptr() == nullptr); - R special_range{}; + SpecialRange special_range{}; auto rr = static_cast>(special_range); basic_ispanstream special_range_constructed{special_range}; assert(range_constructed.span().data() == rr.data()); From 5e806b69896e0349a1945a260f5ea28623a51645 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 6 Sep 2024 21:47:09 -0700 Subject: [PATCH 09/13] `enable_borrowed_range` and verify properties. --- tests/std/tests/P0448R4_spanstream/test.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/std/tests/P0448R4_spanstream/test.cpp b/tests/std/tests/P0448R4_spanstream/test.cpp index 30c40713eef..fe464ffcf96 100644 --- a/tests/std/tests/P0448R4_spanstream/test.cpp +++ b/tests/std/tests/P0448R4_spanstream/test.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +46,12 @@ struct SpecialRange { return span(input_view); } }; +template +constexpr bool ranges::enable_borrowed_range> = true; + +static_assert(!ranges::sized_range>); +static_assert(!ranges::contiguous_range>); +static_assert(ranges::borrowed_range>); template class basic_test_buf : public Spanbuf { From a41f4fa63d1d5c4d9f496cf72f2077acfe4b257c Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 6 Sep 2024 21:48:54 -0700 Subject: [PATCH 10/13] Create a new scope, cite the bug being tested. --- tests/std/tests/P0448R4_spanstream/test.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/std/tests/P0448R4_spanstream/test.cpp b/tests/std/tests/P0448R4_spanstream/test.cpp index fe464ffcf96..fb17fd8a009 100644 --- a/tests/std/tests/P0448R4_spanstream/test.cpp +++ b/tests/std/tests/P0448R4_spanstream/test.cpp @@ -648,7 +648,9 @@ void test_ispanstream() { assert(static_cast(range_constructed.rdbuf())->pbase() == nullptr); assert(static_cast(range_constructed.rdbuf())->pptr() == nullptr); assert(static_cast(range_constructed.rdbuf())->epptr() == nullptr); + } + { // GH-4879 : The span constructed by basic_ispanstream's range constructor may be ill-formed span span_const_elem; basic_ispanstream span_const_elem_constructed{span_const_elem}; assert(span_const_elem_constructed.span().data() == span_const_elem.data()); From c4fb512fecead2ef7cf83713f9142cc0b0bf62ec Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 6 Sep 2024 21:49:36 -0700 Subject: [PATCH 11/13] Fix mistaken mention of `range_constructed` => `special_range_constructed` --- tests/std/tests/P0448R4_spanstream/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/P0448R4_spanstream/test.cpp b/tests/std/tests/P0448R4_spanstream/test.cpp index fb17fd8a009..c2a7080b074 100644 --- a/tests/std/tests/P0448R4_spanstream/test.cpp +++ b/tests/std/tests/P0448R4_spanstream/test.cpp @@ -665,7 +665,7 @@ void test_ispanstream() { SpecialRange special_range{}; auto rr = static_cast>(special_range); basic_ispanstream special_range_constructed{special_range}; - assert(range_constructed.span().data() == rr.data()); + assert(special_range_constructed.span().data() == rr.data()); assert(static_cast(special_range_constructed.rdbuf())->eback() == rr.data()); assert(static_cast(special_range_constructed.rdbuf())->gptr() == rr.data()); assert(static_cast(special_range_constructed.rdbuf())->egptr() == rr.data() + rr.size()); From 4f424be01123c95cd1b218704b7832e2cdd84cca Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 6 Sep 2024 21:54:20 -0700 Subject: [PATCH 12/13] Improve coverage by constructing `span_const_elem` from a buffer. --- tests/std/tests/P0448R4_spanstream/test.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/std/tests/P0448R4_spanstream/test.cpp b/tests/std/tests/P0448R4_spanstream/test.cpp index c2a7080b074..7095716051b 100644 --- a/tests/std/tests/P0448R4_spanstream/test.cpp +++ b/tests/std/tests/P0448R4_spanstream/test.cpp @@ -651,13 +651,13 @@ void test_ispanstream() { } { // GH-4879 : The span constructed by basic_ispanstream's range constructor may be ill-formed - span span_const_elem; + const CharT buffer[17]{}; + span span_const_elem{buffer}; basic_ispanstream span_const_elem_constructed{span_const_elem}; - assert(span_const_elem_constructed.span().data() == span_const_elem.data()); - assert(static_cast(span_const_elem_constructed.rdbuf())->eback() == span_const_elem.data()); - assert(static_cast(span_const_elem_constructed.rdbuf())->gptr() == span_const_elem.data()); - assert(static_cast(span_const_elem_constructed.rdbuf())->egptr() - == span_const_elem.data() + span_const_elem.size()); + assert(span_const_elem_constructed.span().data() == buffer); + assert(static_cast(span_const_elem_constructed.rdbuf())->eback() == buffer); + assert(static_cast(span_const_elem_constructed.rdbuf())->gptr() == buffer); + assert(static_cast(span_const_elem_constructed.rdbuf())->egptr() == end(buffer)); assert(static_cast(span_const_elem_constructed.rdbuf())->pbase() == nullptr); assert(static_cast(span_const_elem_constructed.rdbuf())->pptr() == nullptr); assert(static_cast(span_const_elem_constructed.rdbuf())->epptr() == nullptr); From 530a0ce52586567600dd707ff67e3ec27fc7598c Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 6 Sep 2024 22:02:52 -0700 Subject: [PATCH 13/13] Also test `basic_ispanstream::span(ROS&&)`. --- tests/std/tests/P0448R4_spanstream/test.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/std/tests/P0448R4_spanstream/test.cpp b/tests/std/tests/P0448R4_spanstream/test.cpp index 7095716051b..77f69db28d8 100644 --- a/tests/std/tests/P0448R4_spanstream/test.cpp +++ b/tests/std/tests/P0448R4_spanstream/test.cpp @@ -694,6 +694,14 @@ void test_ispanstream() { assert(is.span().data() == input_range.data()); assert(is.span().size() == input_range.size()); + // also test GH-4879 for basic_ispanstream::span(ROS&&) + is.span(span{other_buffer}); + assert(is.span().data() == other_buffer); + assert(is.span().size() == size(other_buffer)); + is.span(SpecialRange{}); + assert(is.span().data() == input_range.data()); + assert(is.span().size() == input_range.size()); + if constexpr (is_same_v) { const char const_buffer[] = "1 2 3 4 5"; basic_ispanstream is_const_buffer{span{const_buffer}};