diff --git a/stl/inc/xstring b/stl/inc/xstring index e30f3b55c41..3613f07e03a 100644 --- a/stl/inc/xstring +++ b/stl/inc/xstring @@ -1289,6 +1289,25 @@ public: constexpr basic_string_view(_It _First, _Se _Last) noexcept(noexcept(_Last - _First)) // strengthened : _Mydata(_STD to_address(_First)), _Mysize(static_cast(_Last - _First)) {} // clang-format on + +#if _HAS_CXX23 + // clang-format off + template <_RANGES contiguous_range _Range> + requires _RANGES sized_range<_Range> + && same_as<_RANGES range_value_t<_Range>, _Elem> + && (!is_convertible_v<_Range, const _Elem*>) + && (!requires(remove_cvref_t<_Range>& _Rng) { + _Rng.operator _STD basic_string_view<_Elem, _Traits>(); + }) + && (!requires { + // per editorial or LWG issue not yet filed as of 2021-06-10 + typename remove_reference_t<_Range>::traits_type; + } || same_as::traits_type, _Traits>) + constexpr basic_string_view(_Range&& _Rng) noexcept( + noexcept(_RANGES data(_Rng)) && noexcept(_RANGES size(_Rng))) // strengthened + : _Mydata(_RANGES data(_Rng)), _Mysize(static_cast(_RANGES size(_Rng))) {} + // clang-format on +#endif // _HAS_CXX23 #endif // __cpp_lib_concepts _NODISCARD constexpr const_iterator begin() const noexcept { @@ -1696,6 +1715,11 @@ private: template _Se> basic_string_view(_It, _Se) -> basic_string_view>; +#if _HAS_CXX23 +template <_RANGES contiguous_range _Range> +basic_string_view(_Range&&) -> basic_string_view<_RANGES range_value_t<_Range>>; +#endif // _HAS_CXX23 + namespace ranges { template inline constexpr bool enable_view> = true; diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 974b914d7f8..6ddb9575e6c 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -263,6 +263,7 @@ // P1048R1 is_scoped_enum // P1679R3 contains() For basic_string/basic_string_view // P1682R3 to_underlying() For Enumerations +// P1989R2 Range Constructor For string_view // P2166R1 Prohibiting basic_string And basic_string_view Construction From nullptr // Parallel Algorithms Notes diff --git a/tests/std/tests/P0220R1_string_view/test.cpp b/tests/std/tests/P0220R1_string_view/test.cpp index 86a672ea1e3..c5da686d700 100644 --- a/tests/std/tests/P0220R1_string_view/test.cpp +++ b/tests/std/tests/P0220R1_string_view/test.cpp @@ -3,12 +3,14 @@ #include #include +#include #include #include #include #include #include #include +#include #include @@ -323,6 +325,31 @@ constexpr bool test_case_contiguous_constructor() { return true; } +constexpr bool test_case_range_constructor() { +#if _HAS_CXX23 && defined(__cpp_lib_concepts) + const array expectedData{'n', 'o', ' ', 'n', 'u', 'l', 'l'}; + // Also tests the corresponding deduction guide: + same_as auto sv = basic_string_view(expectedData); + assert(sv.data() == expectedData.data()); + assert(sv.size() == 7); + + // Also tests some of the constraints: + static_assert(is_constructible_v>); + static_assert(is_convertible_v, string_view>); + + static_assert(!is_constructible_v>); // not contiguous + static_assert(!is_convertible_v, string_view>); + + static_assert(!is_constructible_v>); // different elements + static_assert(!is_convertible_v, string_view>); + + static_assert(!is_constructible_v>); // different traits + static_assert(!is_convertible_v, string_view>); +#endif // _HAS_CXX23 && defined(__cpp_lib_concepts) + + return true; +} + template constexpr bool test_case_iterators() { using iterator = typename basic_string_view::iterator; @@ -1157,6 +1184,7 @@ static_assert(test_case_default_constructor()); static_assert(test_case_ntcts_constructor()); static_assert(test_case_buffer_constructor()); static_assert(test_case_contiguous_constructor()); +static_assert(test_case_range_constructor()); #if defined(__clang__) || defined(__EDG__) // TRANSITION, VSO-284079 "C1XX's C++14 constexpr emits bogus warnings C4146, // C4308, C4307 for basic_string_view::iterator" static_assert(test_case_iterators()); @@ -1212,6 +1240,7 @@ int main() { test_case_ntcts_constructor(); test_case_buffer_constructor(); test_case_contiguous_constructor(); + test_case_range_constructor(); test_case_iterators>(); test_case_iterators>(); test_case_prefix>();