[libcxx][ranges] removes default_initializable from weakly_incrementable and view
also: * removes default constructors from predefined iterators * makes span and string_view views Partially implements P2325. Partially resolves LWG3326. Differential Revision: https://reviews.llvm.org/D102468
This commit is contained in:
parent
933df6ca79
commit
462f8f0611
@ -246,7 +246,7 @@
|
||||
"`3323 <https://wg21.link/LWG3323>`__","``*has-tuple-element*``\ helper concept needs ``convertible_to``\ ","Prague","",""
|
||||
"`3324 <https://wg21.link/LWG3324>`__","Special-case ``std::strong/weak/partial_order``\ for pointers","Prague","",""
|
||||
"`3325 <https://wg21.link/LWG3325>`__","Constrain return type of transformation function for ``transform_view``\ ","Prague","",""
|
||||
"`3326 <https://wg21.link/LWG3326>`__","``enable_view``\ has false positives","Prague","",""
|
||||
"`3326 <https://wg21.link/LWG3326>`__","``enable_view``\ has false positives","Prague","|In progress|",""
|
||||
"`3327 <https://wg21.link/LWG3327>`__","Format alignment specifiers vs. text direction","Prague","|Nothing To Do|",""
|
||||
"`3328 <https://wg21.link/LWG3328>`__","Clarify that ``std::string``\ is not good for UTF-8","Prague","",""
|
||||
"`3329 <https://wg21.link/LWG3329>`__","``totally_ordered_with``\ both directly and indirectly requires ``common_reference_with``\ ","Prague","|Complete|","13.0"
|
||||
|
|
@ -194,3 +194,4 @@
|
||||
"`P2106 <https://wg21.link/P2106>`__","LWG","Alternative wording for GB315 and GB316","Prague","* *",""
|
||||
"`P2116 <https://wg21.link/P2116>`__","LWG","Remove tuple-like protocol support from fixed-extent span","Prague","|Complete|","11.0"
|
||||
"`P2231 <https://wg21.link/P2231>`__","LWG","Missing constexpr in std::optional and std::variant","February 2021","|In progress|","13.0"
|
||||
"`P2325 <https://wg21.link/P2325>`__","LWG","Views should not be required to be default constructible","June Telecon","|In progress|",""
|
||||
|
|
@ -71,7 +71,6 @@ concept __signed_integer_like = signed_integral<_Tp>;
|
||||
|
||||
template<class _Ip>
|
||||
concept weakly_incrementable =
|
||||
default_initializable<_Ip> &&
|
||||
movable<_Ip> &&
|
||||
requires(_Ip __i) {
|
||||
typename iter_difference_t<_Ip>;
|
||||
|
@ -73,7 +73,6 @@ namespace ranges {
|
||||
concept view =
|
||||
range<_Tp> &&
|
||||
movable<_Tp> &&
|
||||
default_initializable<_Tp> &&
|
||||
enable_view<_Tp>;
|
||||
|
||||
template<class _Range>
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <__config>
|
||||
#include <concepts>
|
||||
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
@ -254,7 +254,6 @@ public:
|
||||
typedef void reference;
|
||||
typedef void pointer;
|
||||
|
||||
constexpr back_insert_iterator() noexcept = default; // since C++20
|
||||
explicit back_insert_iterator(Container& x); // constexpr in C++20
|
||||
back_insert_iterator& operator=(const typename Container::value_type& value); // constexpr in C++20
|
||||
back_insert_iterator& operator*(); // constexpr in C++20
|
||||
@ -278,7 +277,6 @@ public:
|
||||
typedef void reference;
|
||||
typedef void pointer;
|
||||
|
||||
constexpr front_insert_iterator() noexcept = default; // since C++20
|
||||
explicit front_insert_iterator(Container& x); // constexpr in C++20
|
||||
front_insert_iterator& operator=(const typename Container::value_type& value); // constexpr in C++20
|
||||
front_insert_iterator& operator*(); // constexpr in C++20
|
||||
@ -303,7 +301,6 @@ public:
|
||||
typedef void reference;
|
||||
typedef void pointer;
|
||||
|
||||
insert_iterator() = default; // since C++20
|
||||
insert_iterator(Container& x, typename Container::iterator i); // constexpr in C++20
|
||||
insert_iterator& operator=(const typename Container::value_type& value); // constexpr in C++20
|
||||
insert_iterator& operator*(); // constexpr in C++20
|
||||
@ -436,7 +433,6 @@ public:
|
||||
typedef traits traits_type;
|
||||
typedef basic_ostream<charT,traits> ostream_type;
|
||||
|
||||
constexpr ostream_iterator() noexcept = default; // since C++20
|
||||
ostream_iterator(ostream_type& s);
|
||||
ostream_iterator(ostream_type& s, const charT* delimiter);
|
||||
ostream_iterator(const ostream_iterator& x);
|
||||
@ -502,7 +498,6 @@ public:
|
||||
typedef basic_streambuf<charT, traits> streambuf_type;
|
||||
typedef basic_ostream<charT, traits> ostream_type;
|
||||
|
||||
constexpr ostreambuf_iterator() noexcept = default; // since C++20
|
||||
ostreambuf_iterator(ostream_type& s) noexcept;
|
||||
ostreambuf_iterator(streambuf_type* s) noexcept;
|
||||
ostreambuf_iterator& operator=(charT c);
|
||||
@ -849,9 +844,6 @@ public:
|
||||
typedef void reference;
|
||||
typedef _Container container_type;
|
||||
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
_LIBCPP_INLINE_VISIBILITY constexpr back_insert_iterator() noexcept = default;
|
||||
#endif
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit back_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 back_insert_iterator& operator=(const typename _Container::value_type& __value_)
|
||||
{container->push_back(__value_); return *this;}
|
||||
@ -894,9 +886,6 @@ public:
|
||||
typedef void reference;
|
||||
typedef _Container container_type;
|
||||
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
_LIBCPP_INLINE_VISIBILITY constexpr front_insert_iterator() noexcept = default;
|
||||
#endif
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 explicit front_insert_iterator(_Container& __x) : container(_VSTD::addressof(__x)) {}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 front_insert_iterator& operator=(const typename _Container::value_type& __value_)
|
||||
{container->push_front(__value_); return *this;}
|
||||
@ -927,7 +916,7 @@ class _LIBCPP_TEMPLATE_VIS insert_iterator
|
||||
_LIBCPP_SUPPRESS_DEPRECATED_POP
|
||||
protected:
|
||||
_Container* container;
|
||||
typename _Container::iterator iter;
|
||||
typename _Container::iterator iter; // FIXME: `ranges::iterator_t<Container>` in C++20 mode
|
||||
public:
|
||||
typedef output_iterator_tag iterator_category;
|
||||
typedef void value_type;
|
||||
@ -940,9 +929,6 @@ public:
|
||||
typedef void reference;
|
||||
typedef _Container container_type;
|
||||
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
_LIBCPP_INLINE_VISIBILITY insert_iterator() = default;
|
||||
#endif
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator(_Container& __x, typename _Container::iterator __i)
|
||||
: container(_VSTD::addressof(__x)), iter(__i) {}
|
||||
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 insert_iterator& operator=(const typename _Container::value_type& __value_)
|
||||
@ -1061,9 +1047,6 @@ private:
|
||||
ostream_type* __out_stream_;
|
||||
const char_type* __delim_;
|
||||
public:
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
_LIBCPP_INLINE_VISIBILITY constexpr ostream_iterator() noexcept = default;
|
||||
#endif
|
||||
_LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s) _NOEXCEPT
|
||||
: __out_stream_(_VSTD::addressof(__s)), __delim_(nullptr) {}
|
||||
_LIBCPP_INLINE_VISIBILITY ostream_iterator(ostream_type& __s, const _CharT* __delimiter) _NOEXCEPT
|
||||
@ -1186,9 +1169,6 @@ public:
|
||||
private:
|
||||
streambuf_type* __sbuf_;
|
||||
public:
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
_LIBCPP_INLINE_VISIBILITY constexpr ostreambuf_iterator() noexcept = default;
|
||||
#endif
|
||||
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(ostream_type& __s) _NOEXCEPT
|
||||
: __sbuf_(__s.rdbuf()) {}
|
||||
_LIBCPP_INLINE_VISIBILITY ostreambuf_iterator(streambuf_type* __s) _NOEXCEPT
|
||||
|
@ -22,6 +22,9 @@ inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
|
||||
template <class ElementType, size_t Extent = dynamic_extent>
|
||||
class span;
|
||||
|
||||
template<class ElementType, size_t Extent>
|
||||
inline constexpr bool ranges::enable_view<span<ElementType, Extent>> = true;
|
||||
|
||||
template<class ElementType, size_t Extent>
|
||||
inline constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true;
|
||||
|
||||
@ -127,6 +130,7 @@ template<class Container>
|
||||
#include <__config>
|
||||
#include <__debug>
|
||||
#include <__ranges/enable_borrowed_range.h>
|
||||
#include <__ranges/enable_view.h>
|
||||
#include <array> // for array
|
||||
#include <cstddef> // for byte
|
||||
#include <iterator> // for iterators
|
||||
@ -531,6 +535,9 @@ private:
|
||||
#if !defined(_LIBCPP_HAS_NO_RANGES)
|
||||
template <class _Tp, size_t _Extent>
|
||||
inline constexpr bool ranges::enable_borrowed_range<span<_Tp, _Extent> > = true;
|
||||
|
||||
template <class _ElementType, size_t _Extent>
|
||||
inline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true;
|
||||
#endif // !defined(_LIBCPP_HAS_NO_RANGES)
|
||||
|
||||
// as_bytes & as_writable_bytes
|
||||
|
@ -19,6 +19,9 @@ namespace std {
|
||||
template<class charT, class traits = char_traits<charT>>
|
||||
class basic_string_view;
|
||||
|
||||
template<class charT, class traits>
|
||||
inline constexpr bool ranges::enable_view<basic_string_view<charT, traits>> = true;
|
||||
|
||||
template<class charT, class traits>
|
||||
inline constexpr bool ranges::enable_borrowed_range<basic_string_view<charT, traits>> = true; // C++20
|
||||
|
||||
@ -184,6 +187,7 @@ namespace std {
|
||||
#include <__config>
|
||||
#include <__debug>
|
||||
#include <__ranges/enable_borrowed_range.h>
|
||||
#include <__ranges/enable_view.h>
|
||||
#include <__string>
|
||||
#include <algorithm>
|
||||
#include <compare>
|
||||
@ -654,6 +658,9 @@ private:
|
||||
};
|
||||
|
||||
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
|
||||
template <class _CharT, class _Traits>
|
||||
inline constexpr bool ranges::enable_view<basic_string_view<_CharT, _Traits>> = true;
|
||||
|
||||
template <class _CharT, class _Traits>
|
||||
inline constexpr bool ranges::enable_borrowed_range<basic_string_view<_CharT, _Traits> > = true;
|
||||
#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES)
|
||||
|
@ -23,13 +23,13 @@ namespace stdr = std::ranges;
|
||||
static_assert(std::same_as<stdr::iterator_t<range>, range::iterator>);
|
||||
static_assert(stdr::common_range<range>);
|
||||
static_assert(stdr::random_access_range<range>);
|
||||
static_assert(!stdr::view<range>);
|
||||
static_assert(stdr::view<range> && stdr::enable_view<range>);
|
||||
static_assert(stdr::sized_range<range>);
|
||||
static_assert(stdr::borrowed_range<range>);
|
||||
|
||||
static_assert(std::same_as<stdr::iterator_t<range const>, range::iterator>);
|
||||
static_assert(stdr::common_range<range const>);
|
||||
static_assert(stdr::random_access_range<range const>);
|
||||
static_assert(!stdr::view<range const>);
|
||||
static_assert(!stdr::view<range const> && !stdr::enable_view<range const>);
|
||||
static_assert(stdr::sized_range<range const>);
|
||||
static_assert(stdr::borrowed_range<range const>);
|
||||
|
@ -1,33 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
// UNSUPPORTED: libcpp-no-concepts
|
||||
// UNSUPPORTED: gcc-10
|
||||
|
||||
// template<class T>
|
||||
// concept weakly_incrementable;
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#include <concepts>
|
||||
|
||||
// clang-format off
|
||||
template<std::default_initializable I>
|
||||
requires std::movable<I>
|
||||
[[nodiscard]] constexpr bool check_subsumption() {
|
||||
return false;
|
||||
}
|
||||
|
||||
template<std::weakly_incrementable>
|
||||
[[nodiscard]] constexpr bool check_subsumption() {
|
||||
return true;
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
static_assert(check_subsumption<int*>());
|
@ -58,10 +58,10 @@ static_assert(!std::weakly_incrementable<floating_difference_type>);
|
||||
static_assert(!std::weakly_incrementable<non_const_minus>);
|
||||
static_assert(!std::weakly_incrementable<non_integral_minus>);
|
||||
static_assert(!std::weakly_incrementable<bad_difference_type_good_minus>);
|
||||
static_assert(!std::weakly_incrementable<not_default_initializable>);
|
||||
static_assert(!std::weakly_incrementable<not_movable>);
|
||||
static_assert(!std::weakly_incrementable<preinc_not_declared>);
|
||||
static_assert(!std::weakly_incrementable<postinc_not_declared>);
|
||||
static_assert(std::weakly_incrementable<not_default_initializable>);
|
||||
static_assert(std::weakly_incrementable<incrementable_with_difference_type>);
|
||||
static_assert(std::weakly_incrementable<incrementable_without_difference_type>);
|
||||
static_assert(std::weakly_incrementable<difference_type_and_void_minus>);
|
||||
|
@ -1,38 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// <iterator>
|
||||
|
||||
// class back_insert_iterator
|
||||
|
||||
// constexpr back_insert_iterator() noexcept = default;
|
||||
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
struct T { };
|
||||
using Container = std::vector<T>;
|
||||
|
||||
constexpr bool test() {
|
||||
std::back_insert_iterator<Container> it;
|
||||
(void)it;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
ASSERT_NOEXCEPT(std::back_insert_iterator<Container>());
|
||||
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// <iterator>
|
||||
|
||||
// class front_insert_iterator
|
||||
|
||||
// constexpr front_insert_iterator() noexcept = default;
|
||||
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
struct T { };
|
||||
using Container = std::vector<T>;
|
||||
|
||||
constexpr bool test() {
|
||||
std::front_insert_iterator<Container> it;
|
||||
(void)it;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
ASSERT_NOEXCEPT(std::front_insert_iterator<Container>());
|
||||
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// <iterator>
|
||||
|
||||
// class insert_iterator
|
||||
|
||||
// insert_iterator() = default;
|
||||
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
struct T { };
|
||||
using Container = std::vector<T>;
|
||||
|
||||
int main(int, char**) {
|
||||
std::insert_iterator<Container> it; (void)it;
|
||||
return 0;
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// <iterator>
|
||||
|
||||
// class ostream_iterator
|
||||
|
||||
// constexpr ostream_iterator() noexcept = default;
|
||||
|
||||
#include <iterator>
|
||||
#include <string> // char_traits
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
struct MyTraits : std::char_traits<char> {
|
||||
MyTraits(); // This should not be called.
|
||||
};
|
||||
|
||||
constexpr bool test() {
|
||||
std::ostream_iterator<int> it;
|
||||
(void)it;
|
||||
std::ostream_iterator<int, char, MyTraits> wit;
|
||||
(void)wit;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
ASSERT_NOEXCEPT(std::ostream_iterator<int>());
|
||||
ASSERT_NOEXCEPT(std::ostream_iterator<int, char, MyTraits>());
|
||||
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03, c++11, c++14, c++17
|
||||
|
||||
// <iterator>
|
||||
|
||||
// class ostreambuf_iterator
|
||||
|
||||
// constexpr ostreambuf_iterator() noexcept = default;
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
constexpr bool test() {
|
||||
std::ostreambuf_iterator<char> it;
|
||||
(void)it;
|
||||
std::ostreambuf_iterator<wchar_t> wit;
|
||||
(void)wit;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int, char**) {
|
||||
ASSERT_NOEXCEPT(std::ostreambuf_iterator<char>());
|
||||
ASSERT_NOEXCEPT(std::ostreambuf_iterator<wchar_t>());
|
||||
|
||||
test();
|
||||
static_assert(test());
|
||||
|
||||
return 0;
|
||||
}
|
@ -46,7 +46,7 @@ static_assert(std::ranges::range<NotDefaultInit>);
|
||||
static_assert(std::movable<NotDefaultInit>);
|
||||
static_assert(!std::default_initializable<NotDefaultInit>);
|
||||
static_assert(std::ranges::enable_view<NotDefaultInit>);
|
||||
static_assert(!std::ranges::view<NotDefaultInit>);
|
||||
static_assert(std::ranges::view<NotDefaultInit>);
|
||||
|
||||
// The type would be a view, but it doesn't enable it with enable_view
|
||||
struct NotExplicitlyEnabled {
|
||||
|
@ -43,11 +43,3 @@ namespace subsume_movable {
|
||||
constexpr bool test() { return false; }
|
||||
static_assert(test<View>());
|
||||
}
|
||||
|
||||
namespace subsume_default_initializable {
|
||||
template <std::ranges::view>
|
||||
constexpr bool test() { return true; }
|
||||
template <std::default_initializable>
|
||||
constexpr bool test() { return false; }
|
||||
static_assert(test<View>());
|
||||
}
|
||||
|
@ -22,13 +22,13 @@ namespace stdr = std::ranges;
|
||||
static_assert(std::same_as<stdr::iterator_t<std::string_view>, std::string_view::iterator>);
|
||||
static_assert(stdr::common_range<std::string_view>);
|
||||
static_assert(stdr::random_access_range<std::string_view>);
|
||||
static_assert(!stdr::view<std::string_view>);
|
||||
static_assert(stdr::view<std::string_view> && stdr::enable_view<std::string_view>);
|
||||
static_assert(stdr::sized_range<std::string_view>);
|
||||
static_assert(stdr::borrowed_range<std::string_view>);
|
||||
|
||||
static_assert(std::same_as<stdr::iterator_t<std::string_view const>, std::string_view::const_iterator>);
|
||||
static_assert(stdr::common_range<std::string_view const>);
|
||||
static_assert(stdr::random_access_range<std::string_view const>);
|
||||
static_assert(!stdr::view<std::string_view const>); // FIXME: string_view needs to be patched so this is true
|
||||
static_assert(!stdr::view<std::string_view const> && !stdr::enable_view<std::string_view const>);
|
||||
static_assert(stdr::sized_range<std::string_view const>);
|
||||
static_assert(stdr::borrowed_range<std::string_view const>);
|
||||
|
Loading…
x
Reference in New Issue
Block a user