зеркало из https://github.com/microsoft/STL.git
P2278R4: `cbegin` should always return a constant iterator ("Ranges" and "Span" sections) (#3187)
Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
This commit is contained in:
Родитель
0743f64584
Коммит
0b13eb07d2
|
@ -33,6 +33,17 @@ namespace ranges {
|
|||
template <class _Ty>
|
||||
inline constexpr bool _Is_initializer_list = _Is_specialization_v<remove_cvref_t<_Ty>, initializer_list>;
|
||||
|
||||
#if _HAS_CXX23
|
||||
_EXPORT_STD template <range _Rng>
|
||||
using const_iterator_t = const_iterator<iterator_t<_Rng>>;
|
||||
|
||||
_EXPORT_STD template <range _Rng>
|
||||
using const_sentinel_t = const_sentinel<sentinel_t<_Rng>>;
|
||||
|
||||
_EXPORT_STD template <range _Rng>
|
||||
using range_const_reference_t = iter_const_reference_t<iterator_t<_Rng>>;
|
||||
#endif // _HAS_CXX23
|
||||
|
||||
// clang-format off
|
||||
_EXPORT_STD template <class _Rng>
|
||||
concept viewable_range = range<_Rng>
|
||||
|
@ -45,20 +56,19 @@ namespace ranges {
|
|||
concept _Simple_view = view<_Rng> && range<const _Rng>
|
||||
&& same_as<iterator_t<_Rng>, iterator_t<const _Rng>>
|
||||
&& same_as<sentinel_t<_Rng>, sentinel_t<const _Rng>>;
|
||||
// clang-format on
|
||||
|
||||
template <class _Ty>
|
||||
concept _Valid_movable_box_object =
|
||||
#if _HAS_CXX23
|
||||
move_constructible<_Ty>
|
||||
move_constructible<_Ty>
|
||||
#else // ^^^ C++23 / C++20 vvv
|
||||
copy_constructible<_Ty>
|
||||
copy_constructible<_Ty>
|
||||
#endif // C++20
|
||||
&& _Destructible_object<_Ty>;
|
||||
&& _Destructible_object<_Ty>;
|
||||
|
||||
template <class _It>
|
||||
concept _Has_arrow = input_iterator<_It>
|
||||
&& (is_pointer_v<_It> || _Has_member_arrow<_It&>);
|
||||
// clang-format on
|
||||
concept _Has_arrow = input_iterator<_It> && (is_pointer_v<_It> || _Has_member_arrow<_It&>);
|
||||
|
||||
template <bool _IsConst, class _Ty>
|
||||
using _Maybe_const = conditional_t<_IsConst, const _Ty, _Ty>;
|
||||
|
|
45
stl/inc/span
45
stl/inc/span
|
@ -17,7 +17,6 @@ _EMIT_STL_WARNING(STL4038, "The contents of <span> are available only with C++20
|
|||
#include <type_traits>
|
||||
#include <xutility>
|
||||
|
||||
|
||||
#pragma pack(push, _CRT_PACKING)
|
||||
#pragma warning(push, _STL_WARNING_LEVEL)
|
||||
#pragma warning(disable : _STL_DISABLED_WARNINGS)
|
||||
|
@ -312,16 +311,20 @@ private:
|
|||
using _Mybase::_Mysize;
|
||||
|
||||
public:
|
||||
using element_type = _Ty;
|
||||
using value_type = remove_cv_t<_Ty>;
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
using pointer = _Ty*;
|
||||
using const_pointer = const _Ty*;
|
||||
using reference = _Ty&;
|
||||
using const_reference = const _Ty&;
|
||||
using iterator = _Span_iterator<_Ty>;
|
||||
using reverse_iterator = _STD reverse_iterator<iterator>;
|
||||
using element_type = _Ty;
|
||||
using value_type = remove_cv_t<_Ty>;
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
using pointer = _Ty*;
|
||||
using const_pointer = const _Ty*;
|
||||
using reference = _Ty&;
|
||||
using const_reference = const _Ty&;
|
||||
using iterator = _Span_iterator<_Ty>;
|
||||
using reverse_iterator = _STD reverse_iterator<iterator>;
|
||||
#if _HAS_CXX23 && defined(__cpp_lib_concepts)
|
||||
using const_iterator = _STD const_iterator<iterator>;
|
||||
using const_reverse_iterator = _STD const_iterator<reverse_iterator>;
|
||||
#endif // _HAS_CXX23 && defined(__cpp_lib_concepts)
|
||||
|
||||
static constexpr size_type extent = _Extent;
|
||||
|
||||
|
@ -617,6 +620,16 @@ public:
|
|||
#endif // _ITERATOR_DEBUG_LEVEL
|
||||
}
|
||||
|
||||
#if _HAS_CXX23 && defined(__cpp_lib_concepts)
|
||||
_NODISCARD constexpr const_iterator cbegin() const noexcept {
|
||||
return begin();
|
||||
}
|
||||
|
||||
_NODISCARD constexpr const_iterator cend() const noexcept {
|
||||
return end();
|
||||
}
|
||||
#endif // _HAS_CXX23 && defined(__cpp_lib_concepts)
|
||||
|
||||
_NODISCARD constexpr reverse_iterator rbegin() const noexcept {
|
||||
return reverse_iterator{end()};
|
||||
}
|
||||
|
@ -625,6 +638,16 @@ public:
|
|||
return reverse_iterator{begin()};
|
||||
}
|
||||
|
||||
#if _HAS_CXX23 && defined(__cpp_lib_concepts)
|
||||
_NODISCARD constexpr const_reverse_iterator crbegin() const noexcept {
|
||||
return rbegin();
|
||||
}
|
||||
|
||||
_NODISCARD constexpr const_reverse_iterator crend() const noexcept {
|
||||
return rend();
|
||||
}
|
||||
#endif // _HAS_CXX23 && defined(__cpp_lib_concepts)
|
||||
|
||||
_NODISCARD constexpr pointer _Unchecked_begin() const noexcept {
|
||||
return _Mydata;
|
||||
}
|
||||
|
|
213
stl/inc/xutility
213
stl/inc/xutility
|
@ -2233,6 +2233,9 @@ namespace ranges {
|
|||
_RANGES end(__r);
|
||||
};
|
||||
|
||||
_EXPORT_STD template <class _Rng>
|
||||
concept input_range = range<_Rng> && input_iterator<iterator_t<_Rng>>;
|
||||
|
||||
_EXPORT_STD template <range _Rng>
|
||||
using sentinel_t = decltype(_RANGES end(_STD declval<_Rng&>()));
|
||||
|
||||
|
@ -2426,15 +2429,44 @@ namespace ranges {
|
|||
_EXPORT_STD template <range _Rng>
|
||||
using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rng>>;
|
||||
|
||||
#if _HAS_CXX23
|
||||
_EXPORT_STD template <class _Rng>
|
||||
concept constant_range = input_range<_Rng> && _Constant_iterator<iterator_t<_Rng>>;
|
||||
|
||||
template <input_range _Rng>
|
||||
_NODISCARD constexpr auto& _Possibly_const_range(_Rng& _Range) noexcept {
|
||||
if constexpr (constant_range<const _Rng> && !constant_range<_Rng>) {
|
||||
return _STD as_const(_Range);
|
||||
} else {
|
||||
return _Range;
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Ty>
|
||||
_NODISCARD constexpr auto _As_const_pointer(const _Ty* _Ptr) noexcept {
|
||||
return _Ptr;
|
||||
}
|
||||
#endif // _HAS_CXX23
|
||||
|
||||
struct _Cbegin_fn {
|
||||
// clang-format off
|
||||
#if _HAS_CXX23
|
||||
template <_Should_range_access _Ty,
|
||||
class _Uty = decltype(_RANGES begin(_RANGES _Possibly_const_range(_STD declval<_Ty&>())))>
|
||||
_NODISCARD constexpr auto operator()(_Ty&& _Val) const
|
||||
noexcept(noexcept(const_iterator<_Uty>{_RANGES begin(_RANGES _Possibly_const_range(_Val))}))
|
||||
requires requires { const_iterator<_Uty>{_RANGES begin(_RANGES _Possibly_const_range(_Val))}; }
|
||||
{
|
||||
return const_iterator<_Uty>{_RANGES begin(_RANGES _Possibly_const_range(_Val))};
|
||||
}
|
||||
#else // ^^^ C++23 / C++20 vvv
|
||||
template <class _Ty, class _CTy = _Const_thru_ref<_Ty>>
|
||||
_NODISCARD constexpr auto operator()(_Ty&& _Val) const
|
||||
noexcept(noexcept(_RANGES begin(static_cast<_CTy&&>(_Val))))
|
||||
requires requires { _RANGES begin(static_cast<_CTy&&>(_Val)); } {
|
||||
requires requires { _RANGES begin(static_cast<_CTy&&>(_Val)); }
|
||||
{
|
||||
return _RANGES begin(static_cast<_CTy&&>(_Val));
|
||||
}
|
||||
// clang-format on
|
||||
#endif // C++20
|
||||
};
|
||||
|
||||
inline namespace _Cpos {
|
||||
|
@ -2442,14 +2474,24 @@ namespace ranges {
|
|||
}
|
||||
|
||||
struct _Cend_fn {
|
||||
// clang-format off
|
||||
#if _HAS_CXX23
|
||||
template <_Should_range_access _Ty,
|
||||
class _Uty = decltype(_RANGES end(_RANGES _Possibly_const_range(_STD declval<_Ty&>())))>
|
||||
_NODISCARD constexpr auto operator()(_Ty&& _Val) const
|
||||
noexcept(noexcept(const_sentinel<_Uty>{_RANGES end(_RANGES _Possibly_const_range(_Val))}))
|
||||
requires requires { const_sentinel<_Uty>{_RANGES end(_RANGES _Possibly_const_range(_Val))}; }
|
||||
{
|
||||
return const_sentinel<_Uty>{_RANGES end(_RANGES _Possibly_const_range(_Val))};
|
||||
}
|
||||
#else // ^^^ C++23 / C++20 vvv
|
||||
template <class _Ty, class _CTy = _Const_thru_ref<_Ty>>
|
||||
_NODISCARD constexpr auto operator()(_Ty&& _Val) const
|
||||
noexcept(noexcept(_RANGES end(static_cast<_CTy&&>(_Val))))
|
||||
requires requires { _RANGES end(static_cast<_CTy&&>(_Val)); } {
|
||||
requires requires { _RANGES end(static_cast<_CTy&&>(_Val)); }
|
||||
{
|
||||
return _RANGES end(static_cast<_CTy&&>(_Val));
|
||||
}
|
||||
// clang-format on
|
||||
#endif // C++20
|
||||
};
|
||||
|
||||
inline namespace _Cpos {
|
||||
|
@ -2592,14 +2634,24 @@ namespace ranges {
|
|||
}
|
||||
|
||||
struct _Crbegin_fn {
|
||||
// clang-format off
|
||||
#if _HAS_CXX23
|
||||
template <_Should_range_access _Ty,
|
||||
class _Uty = decltype(_RANGES rbegin(_RANGES _Possibly_const_range(_STD declval<_Ty&>())))>
|
||||
_NODISCARD constexpr auto operator()(_Ty&& _Val) const
|
||||
noexcept(noexcept(const_iterator<_Uty>{_RANGES rbegin(_RANGES _Possibly_const_range(_Val))}))
|
||||
requires requires { const_iterator<_Uty>{_RANGES rbegin(_RANGES _Possibly_const_range(_Val))}; }
|
||||
{
|
||||
return const_iterator<_Uty>{_RANGES rbegin(_RANGES _Possibly_const_range(_Val))};
|
||||
}
|
||||
#else // ^^^ C++23 / C++20 vvv
|
||||
template <class _Ty, class _CTy = _Const_thru_ref<_Ty>>
|
||||
_NODISCARD constexpr auto operator()(_Ty&& _Val) const
|
||||
noexcept(noexcept(_RANGES rbegin(static_cast<_CTy&&>(_Val))))
|
||||
requires requires { _RANGES rbegin(static_cast<_CTy&&>(_Val)); } {
|
||||
requires requires { _RANGES rbegin(static_cast<_CTy&&>(_Val)); }
|
||||
{
|
||||
return _RANGES rbegin(static_cast<_CTy&&>(_Val));
|
||||
}
|
||||
// clang-format on
|
||||
#endif // C++20
|
||||
};
|
||||
|
||||
inline namespace _Cpos {
|
||||
|
@ -2607,14 +2659,24 @@ namespace ranges {
|
|||
}
|
||||
|
||||
struct _Crend_fn {
|
||||
// clang-format off
|
||||
#if _HAS_CXX23
|
||||
template <_Should_range_access _Ty,
|
||||
class _Uty = decltype(_RANGES rend(_RANGES _Possibly_const_range(_STD declval<_Ty&>())))>
|
||||
_NODISCARD constexpr auto operator()(_Ty&& _Val) const
|
||||
noexcept(noexcept(const_sentinel<_Uty>{_RANGES rend(_RANGES _Possibly_const_range(_Val))}))
|
||||
requires requires { const_sentinel<_Uty>{_RANGES rend(_RANGES _Possibly_const_range(_Val))}; }
|
||||
{
|
||||
return const_sentinel<_Uty>{_RANGES rend(_RANGES _Possibly_const_range(_Val))};
|
||||
}
|
||||
#else // ^^^ C++23 / C++20 vvv
|
||||
template <class _Ty, class _CTy = _Const_thru_ref<_Ty>>
|
||||
_NODISCARD constexpr auto operator()(_Ty&& _Val) const
|
||||
noexcept(noexcept(_RANGES rend(static_cast<_CTy&&>(_Val))))
|
||||
requires requires { _RANGES rend(static_cast<_CTy&&>(_Val)); } {
|
||||
requires requires { _RANGES rend(static_cast<_CTy&&>(_Val)); }
|
||||
{
|
||||
return _RANGES rend(static_cast<_CTy&&>(_Val));
|
||||
}
|
||||
// clang-format on
|
||||
#endif // C++20
|
||||
};
|
||||
|
||||
inline namespace _Cpos {
|
||||
|
@ -2823,14 +2885,23 @@ namespace ranges {
|
|||
}
|
||||
|
||||
struct _Cdata_fn {
|
||||
// clang-format off
|
||||
#if _HAS_CXX23
|
||||
template <_Should_range_access _Ty>
|
||||
_NODISCARD constexpr auto operator()(_Ty&& _Val) const
|
||||
noexcept(noexcept(_RANGES data(_RANGES _Possibly_const_range(_Val))))
|
||||
requires requires { _RANGES _As_const_pointer(_RANGES data(_RANGES _Possibly_const_range(_Val))); }
|
||||
{
|
||||
return _RANGES _As_const_pointer(_RANGES data(_RANGES _Possibly_const_range(_Val)));
|
||||
}
|
||||
#else // ^^^ C++23 / C++20 vvv
|
||||
template <class _Ty, class _CTy = _Const_thru_ref<_Ty>>
|
||||
_NODISCARD constexpr auto operator()(_Ty&& _Val) const
|
||||
noexcept(noexcept(_RANGES data(static_cast<_CTy&&>(_Val))))
|
||||
requires requires { _RANGES data(static_cast<_CTy&&>(_Val)); } {
|
||||
requires requires { _RANGES data(static_cast<_CTy&&>(_Val)); }
|
||||
{
|
||||
return _RANGES data(static_cast<_CTy&&>(_Val));
|
||||
}
|
||||
// clang-format on
|
||||
#endif // C++20
|
||||
};
|
||||
|
||||
inline namespace _Cpos {
|
||||
|
@ -2869,9 +2940,6 @@ namespace ranges {
|
|||
_EXPORT_STD template <class _Rng, class _Ty>
|
||||
concept output_range = range<_Rng> && output_iterator<iterator_t<_Rng>, _Ty>;
|
||||
|
||||
_EXPORT_STD template <class _Rng>
|
||||
concept input_range = range<_Rng> && input_iterator<iterator_t<_Rng>>;
|
||||
|
||||
_EXPORT_STD template <class _Rng>
|
||||
concept forward_range = range<_Rng> && forward_iterator<iterator_t<_Rng>>;
|
||||
|
||||
|
@ -3192,7 +3260,6 @@ namespace ranges {
|
|||
template <class _Ty>
|
||||
concept _Can_empty = requires(_Ty __t) { _RANGES empty(__t); };
|
||||
|
||||
// clang-format off
|
||||
_EXPORT_STD template <class _Derived>
|
||||
requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
|
||||
class view_interface {
|
||||
|
@ -3216,9 +3283,11 @@ namespace ranges {
|
|||
public:
|
||||
#ifdef __clang__ // TRANSITION, LLVM-44833
|
||||
template <class _Dx = _Derived>
|
||||
_NODISCARD constexpr bool empty() requires sized_range<_Dx> || forward_range<_Dx>
|
||||
_NODISCARD constexpr bool empty()
|
||||
requires sized_range<_Dx> || forward_range<_Dx>
|
||||
#else // ^^^ workaround / no workaround vvv
|
||||
_NODISCARD constexpr bool empty() requires sized_range<_Derived> || forward_range<_Derived>
|
||||
_NODISCARD constexpr bool empty()
|
||||
requires sized_range<_Derived> || forward_range<_Derived>
|
||||
#endif // TRANSITION, LLVM-44833
|
||||
{
|
||||
auto& _Self = _Cast();
|
||||
|
@ -3231,9 +3300,11 @@ namespace ranges {
|
|||
|
||||
#ifdef __clang__ // TRANSITION, LLVM-44833
|
||||
template <class _Dx = _Derived>
|
||||
_NODISCARD constexpr bool empty() const requires sized_range<const _Dx> || forward_range<const _Dx>
|
||||
_NODISCARD constexpr bool empty() const
|
||||
requires sized_range<const _Dx> || forward_range<const _Dx>
|
||||
#else // ^^^ workaround / no workaround vvv
|
||||
_NODISCARD constexpr bool empty() const requires sized_range<const _Derived> || forward_range<const _Derived>
|
||||
_NODISCARD constexpr bool empty() const
|
||||
requires sized_range<const _Derived> || forward_range<const _Derived>
|
||||
#endif // TRANSITION, LLVM-44833
|
||||
{
|
||||
auto& _Self = _Cast();
|
||||
|
@ -3244,11 +3315,63 @@ namespace ranges {
|
|||
}
|
||||
}
|
||||
|
||||
#if _HAS_CXX23
|
||||
#ifdef __clang__ // TRANSITION, LLVM-44833
|
||||
template <class _Dx = _Derived>
|
||||
constexpr explicit operator bool() requires _Can_empty<_Dx>
|
||||
_NODISCARD constexpr auto cbegin()
|
||||
requires input_range<_Dx> // Per LWG-3766
|
||||
#else // ^^^ workaround / no workaround vvv
|
||||
constexpr explicit operator bool() requires _Can_empty<_Derived>
|
||||
_NODISCARD constexpr auto cbegin()
|
||||
requires input_range<_Derived> // Per LWG-3766
|
||||
#endif // TRANSITION, LLVM-44833
|
||||
{
|
||||
return _RANGES cbegin(_Cast());
|
||||
}
|
||||
|
||||
#ifdef __clang__ // TRANSITION, LLVM-44833
|
||||
template <class _Dx = _Derived>
|
||||
_NODISCARD constexpr auto cbegin() const
|
||||
requires input_range<const _Dx> // Per LWG-3766
|
||||
#else // ^^^ workaround / no workaround vvv
|
||||
_NODISCARD constexpr auto cbegin() const
|
||||
requires input_range<const _Derived> // Per LWG-3766
|
||||
#endif // TRANSITION, LLVM-44833
|
||||
{
|
||||
return _RANGES cbegin(_Cast());
|
||||
}
|
||||
|
||||
#ifdef __clang__ // TRANSITION, LLVM-44833
|
||||
template <class _Dx = _Derived>
|
||||
_NODISCARD constexpr auto cend()
|
||||
requires input_range<_Dx> // Per LWG-3766
|
||||
#else // ^^^ workaround / no workaround vvv
|
||||
_NODISCARD constexpr auto cend()
|
||||
requires input_range<_Derived> // Per LWG-3766
|
||||
#endif // TRANSITION, LLVM-44833
|
||||
{
|
||||
return _RANGES cend(_Cast());
|
||||
}
|
||||
|
||||
#ifdef __clang__ // TRANSITION, LLVM-44833
|
||||
template <class _Dx = _Derived>
|
||||
_NODISCARD constexpr auto cend() const
|
||||
requires input_range<const _Dx> // Per LWG-3766
|
||||
#else // ^^^ workaround / no workaround vvv
|
||||
_NODISCARD constexpr auto cend() const
|
||||
requires input_range<const _Derived> // Per LWG-3766
|
||||
#endif // TRANSITION, LLVM-44833
|
||||
{
|
||||
return _RANGES cend(_Cast());
|
||||
}
|
||||
#endif // _HAS_CXX23
|
||||
|
||||
#ifdef __clang__ // TRANSITION, LLVM-44833
|
||||
template <class _Dx = _Derived>
|
||||
constexpr explicit operator bool()
|
||||
requires _Can_empty<_Dx>
|
||||
#else // ^^^ workaround / no workaround vvv
|
||||
constexpr explicit operator bool()
|
||||
requires _Can_empty<_Derived>
|
||||
#endif // TRANSITION, LLVM-44833
|
||||
{
|
||||
return !_RANGES empty(_Cast());
|
||||
|
@ -3256,9 +3379,11 @@ namespace ranges {
|
|||
|
||||
#ifdef __clang__ // TRANSITION, LLVM-44833
|
||||
template <class _Dx = _Derived>
|
||||
constexpr explicit operator bool() const requires _Can_empty<const _Dx>
|
||||
constexpr explicit operator bool() const
|
||||
requires _Can_empty<const _Dx>
|
||||
#else // ^^^ workaround / no workaround vvv
|
||||
constexpr explicit operator bool() const requires _Can_empty<const _Derived>
|
||||
constexpr explicit operator bool() const
|
||||
requires _Can_empty<const _Derived>
|
||||
#endif // TRANSITION, LLVM-44833
|
||||
{
|
||||
return !_RANGES empty(_Cast());
|
||||
|
@ -3266,9 +3391,11 @@ namespace ranges {
|
|||
|
||||
#ifdef __clang__ // TRANSITION, LLVM-44833
|
||||
template <class _Dx = _Derived>
|
||||
_NODISCARD constexpr auto data() requires contiguous_iterator<iterator_t<_Dx>>
|
||||
_NODISCARD constexpr auto data()
|
||||
requires contiguous_iterator<iterator_t<_Dx>>
|
||||
#else // ^^^ workaround / no workaround vvv
|
||||
_NODISCARD constexpr auto data() requires contiguous_iterator<iterator_t<_Derived>>
|
||||
_NODISCARD constexpr auto data()
|
||||
requires contiguous_iterator<iterator_t<_Derived>>
|
||||
#endif // TRANSITION, LLVM-44833
|
||||
{
|
||||
return _STD to_address(_RANGES begin(_Cast()));
|
||||
|
@ -3301,11 +3428,12 @@ namespace ranges {
|
|||
|
||||
#ifdef __clang__ // TRANSITION, LLVM-44833
|
||||
template <class _Dx = _Derived>
|
||||
_NODISCARD constexpr auto size() const requires forward_range<const _Dx>
|
||||
&& sized_sentinel_for<sentinel_t<const _Dx>, iterator_t<const _Dx>>
|
||||
_NODISCARD constexpr auto size() const
|
||||
requires forward_range<const _Dx> && sized_sentinel_for<sentinel_t<const _Dx>, iterator_t<const _Dx>>
|
||||
#else // ^^^ workaround / no workaround vvv
|
||||
_NODISCARD constexpr auto size() const requires forward_range<const _Derived>
|
||||
&& sized_sentinel_for<sentinel_t<const _Derived>, iterator_t<const _Derived>>
|
||||
_NODISCARD constexpr auto size() const
|
||||
requires forward_range<const _Derived>
|
||||
&& sized_sentinel_for<sentinel_t<const _Derived>, iterator_t<const _Derived>>
|
||||
#endif // TRANSITION, LLVM-44833
|
||||
{
|
||||
auto& _Self = _Cast();
|
||||
|
@ -3314,9 +3442,11 @@ namespace ranges {
|
|||
|
||||
#ifdef __clang__ // TRANSITION, LLVM-44833
|
||||
template <class _Dx = _Derived>
|
||||
_NODISCARD constexpr decltype(auto) front() requires forward_range<_Dx>
|
||||
_NODISCARD constexpr decltype(auto) front()
|
||||
requires forward_range<_Dx>
|
||||
#else // ^^^ workaround / no workaround vvv
|
||||
_NODISCARD constexpr decltype(auto) front() requires forward_range<_Derived>
|
||||
_NODISCARD constexpr decltype(auto) front()
|
||||
requires forward_range<_Derived>
|
||||
#endif // TRANSITION, LLVM-44833
|
||||
{
|
||||
auto& _Self = _Cast();
|
||||
|
@ -3328,9 +3458,11 @@ namespace ranges {
|
|||
|
||||
#ifdef __clang__ // TRANSITION, LLVM-44833
|
||||
template <class _Dx = _Derived>
|
||||
_NODISCARD constexpr decltype(auto) front() const requires forward_range<const _Dx>
|
||||
_NODISCARD constexpr decltype(auto) front() const
|
||||
requires forward_range<const _Dx>
|
||||
#else // ^^^ workaround / no workaround vvv
|
||||
_NODISCARD constexpr decltype(auto) front() const requires forward_range<const _Derived>
|
||||
_NODISCARD constexpr decltype(auto) front() const
|
||||
requires forward_range<const _Derived>
|
||||
#endif // TRANSITION, LLVM-44833
|
||||
{
|
||||
auto& _Self = _Cast();
|
||||
|
@ -3342,9 +3474,11 @@ namespace ranges {
|
|||
|
||||
#ifdef __clang__ // TRANSITION, LLVM-44833
|
||||
template <class _Dx = _Derived>
|
||||
_NODISCARD constexpr decltype(auto) back() requires bidirectional_range<_Dx> && common_range<_Dx>
|
||||
_NODISCARD constexpr decltype(auto) back()
|
||||
requires bidirectional_range<_Dx> && common_range<_Dx>
|
||||
#else // ^^^ workaround / no workaround vvv
|
||||
_NODISCARD constexpr decltype(auto) back() requires bidirectional_range<_Derived> && common_range<_Derived>
|
||||
_NODISCARD constexpr decltype(auto) back()
|
||||
requires bidirectional_range<_Derived> && common_range<_Derived>
|
||||
#endif // TRANSITION, LLVM-44833
|
||||
{
|
||||
auto& _Self = _Cast();
|
||||
|
@ -3398,7 +3532,6 @@ namespace ranges {
|
|||
return _RANGES begin(_Self)[_Idx];
|
||||
}
|
||||
};
|
||||
// clang-format on
|
||||
} // namespace ranges
|
||||
|
||||
// These declarations must be visible to qualified name lookup for _STD get in _Pair_like below, even if <tuple> hasn't
|
||||
|
|
|
@ -325,7 +325,7 @@
|
|||
// P2186R2 Removing Garbage Collection Support
|
||||
// P2273R3 constexpr unique_ptr
|
||||
// P2278R4 cbegin Should Always Return A Constant Iterator
|
||||
// ("Iterators" section from the paper only)
|
||||
// (missing views::as_const)
|
||||
// P2291R3 constexpr Integral <charconv>
|
||||
// P2302R4 ranges::contains, ranges::contains_subrange
|
||||
// P2321R2 zip
|
||||
|
|
|
@ -58,6 +58,14 @@ std/strings/basic.string/string.nonmembers/string_op+/allocator_propagation.pass
|
|||
# libc++ hasn't updated move_iterator for P2520R0
|
||||
std/iterators/predef.iterators/move.iterators/move.iterator/types.pass.cpp FAIL
|
||||
|
||||
# libc++ has not implemented P2278R4: "cbegin should always return a constant iterator"
|
||||
std/containers/views/views.span/types.pass.cpp FAIL
|
||||
std/ranges/range.access/begin.pass.cpp FAIL
|
||||
std/ranges/range.access/data.pass.cpp FAIL
|
||||
std/ranges/range.access/end.pass.cpp FAIL
|
||||
std/ranges/range.access/rbegin.pass.cpp FAIL
|
||||
std/ranges/range.access/rend.pass.cpp FAIL
|
||||
|
||||
# libc++ doesn't implement LWG-3692: "zip_view::iterator's operator<=> is overconstrained"
|
||||
std/ranges/range.adaptors/range.zip/iterator/compare.pass.cpp FAIL
|
||||
|
||||
|
|
|
@ -58,6 +58,14 @@ strings\basic.string\string.nonmembers\string_op+\allocator_propagation.pass.cpp
|
|||
# libc++ hasn't updated move_iterator for P2520R0
|
||||
iterators\predef.iterators\move.iterators\move.iterator\types.pass.cpp
|
||||
|
||||
# libc++ has not implemented P2278R4: "cbegin should always return a constant iterator"
|
||||
containers\views\views.span\types.pass.cpp
|
||||
ranges\range.access\begin.pass.cpp
|
||||
ranges\range.access\data.pass.cpp
|
||||
ranges\range.access\end.pass.cpp
|
||||
ranges\range.access\rbegin.pass.cpp
|
||||
ranges\range.access\rend.pass.cpp
|
||||
|
||||
# libc++ doesn't implement LWG-3692: "zip_view::iterator's operator<=> is overconstrained"
|
||||
ranges\range.adaptors\range.zip\iterator\compare.pass.cpp
|
||||
|
||||
|
|
|
@ -1483,8 +1483,13 @@ concept CanMemberEnd = requires(R&& r) { std::forward<R>(r).end(); };
|
|||
|
||||
template <class R>
|
||||
concept CanCBegin = requires(R&& r) { ranges::cbegin(std::forward<R>(r)); };
|
||||
template <class R>
|
||||
concept CanMemberCBegin = requires(R&& r) { std::forward<R>(r).cbegin(); };
|
||||
|
||||
template <class R>
|
||||
concept CanCEnd = requires(R&& r) { ranges::cend(std::forward<R>(r)); };
|
||||
template <class R>
|
||||
concept CanMemberCEnd = requires(R&& r) { std::forward<R>(r).cend(); };
|
||||
|
||||
template <class R>
|
||||
concept CanRBegin = requires(R&& r) { ranges::rbegin(std::forward<R>(r)); };
|
||||
|
|
|
@ -548,7 +548,9 @@ tests\P2162R2_std_visit_for_derived_classes_from_variant
|
|||
tests\P2231R1_complete_constexpr_optional_variant
|
||||
tests\P2273R3_constexpr_unique_ptr
|
||||
tests\P2278R4_basic_const_iterator
|
||||
tests\P2278R4_const_span
|
||||
tests\P2278R4_ranges_const_iterator_machinery
|
||||
tests\P2278R4_ranges_const_range_machinery
|
||||
tests\P2302R4_ranges_alg_contains
|
||||
tests\P2302R4_ranges_alg_contains_subrange
|
||||
tests\P2321R2_proxy_reference
|
||||
|
|
|
@ -573,7 +573,6 @@ STATIC_ASSERT(!ranges::view<int const[]>);
|
|||
|
||||
STATIC_ASSERT(test_begin<int (&)[], int*>());
|
||||
STATIC_ASSERT(test_end<int (&)[]>());
|
||||
STATIC_ASSERT(test_cbegin<int (&)[], int const*>());
|
||||
STATIC_ASSERT(test_cend<int (&)[]>());
|
||||
STATIC_ASSERT(test_rbegin<int (&)[]>());
|
||||
STATIC_ASSERT(test_rend<int (&)[]>());
|
||||
|
@ -581,15 +580,22 @@ STATIC_ASSERT(test_crbegin<int (&)[]>());
|
|||
STATIC_ASSERT(test_crend<int (&)[]>());
|
||||
STATIC_ASSERT(test_size<int (&)[]>());
|
||||
STATIC_ASSERT(test_empty<int (&)[], false>());
|
||||
// Can't use test_data/_cdata here because they use range_value_t and this isn't a range
|
||||
// Can't use test_data here because it uses range_value_t and this isn't a range
|
||||
STATIC_ASSERT(std::same_as<decltype(ranges::data(std::declval<int (&)[]>())), int*>);
|
||||
STATIC_ASSERT(std::same_as<decltype(ranges::cdata(std::declval<int (&)[]>())), int const*>);
|
||||
STATIC_ASSERT(!ranges::range<int (&)[]>);
|
||||
STATIC_ASSERT(!ranges::view<int (&)[]>);
|
||||
|
||||
#if _HAS_CXX23 // ranges::cbegin and ranges::cdata behavior differs in C++20 and C++23 modes
|
||||
STATIC_ASSERT(test_cbegin<int (&)[]>());
|
||||
STATIC_ASSERT(test_cdata<int (&)[]>());
|
||||
#else // ^^^ C++23 / C++20 vvv
|
||||
STATIC_ASSERT(test_cbegin<int (&)[], int const*>());
|
||||
// Can't use test_cdata here because it uses range_value_t and this isn't a range
|
||||
STATIC_ASSERT(std::same_as<decltype(ranges::cdata(std::declval<int (&)[]>())), int const*>);
|
||||
#endif // C++20
|
||||
|
||||
STATIC_ASSERT(test_begin<int const (&)[], int const*>());
|
||||
STATIC_ASSERT(test_end<int const (&)[]>());
|
||||
STATIC_ASSERT(test_cbegin<int const (&)[], int const*>());
|
||||
STATIC_ASSERT(test_cend<int const (&)[]>());
|
||||
STATIC_ASSERT(test_rbegin<int const (&)[]>());
|
||||
STATIC_ASSERT(test_rend<int const (&)[]>());
|
||||
|
@ -597,17 +603,24 @@ STATIC_ASSERT(test_crbegin<int const (&)[]>());
|
|||
STATIC_ASSERT(test_crend<int const (&)[]>());
|
||||
STATIC_ASSERT(test_size<int const (&)[]>());
|
||||
STATIC_ASSERT(test_empty<int const (&)[], false>());
|
||||
// Can't use test_data/_cdata here because they use range_value_t and this isn't a range
|
||||
// Can't use test_data here because it uses range_value_t and this isn't a range
|
||||
STATIC_ASSERT(std::same_as<decltype(ranges::data(std::declval<int const (&)[]>())), int const*>);
|
||||
STATIC_ASSERT(std::same_as<decltype(ranges::cdata(std::declval<int const (&)[]>())), int const*>);
|
||||
STATIC_ASSERT(!ranges::range<int const (&)[]>);
|
||||
STATIC_ASSERT(!ranges::view<int const (&)[]>);
|
||||
|
||||
#if _HAS_CXX23 // ranges::cbegin and ranges::cdata behavior differs in C++20 and C++23 modes
|
||||
STATIC_ASSERT(test_cbegin<int const (&)[]>());
|
||||
STATIC_ASSERT(test_cdata<int const (&)[]>());
|
||||
#else // ^^^ C++23 / C++20 vvv
|
||||
STATIC_ASSERT(test_cbegin<int const (&)[], int const*>());
|
||||
// Can't use test_cdata here because it uses range_value_t and this isn't a range
|
||||
STATIC_ASSERT(std::same_as<decltype(ranges::cdata(std::declval<int const (&)[]>())), int const*>);
|
||||
#endif // C++20
|
||||
|
||||
// Validate behavior before/after completing the bound of an array
|
||||
extern int initially_unbounded[];
|
||||
STATIC_ASSERT(ranges::begin(initially_unbounded) == initially_unbounded);
|
||||
STATIC_ASSERT(!CanEnd<decltype((initially_unbounded))>);
|
||||
STATIC_ASSERT(ranges::cbegin(initially_unbounded) == initially_unbounded);
|
||||
STATIC_ASSERT(!CanCEnd<decltype((initially_unbounded))>);
|
||||
STATIC_ASSERT(!CanRBegin<decltype((initially_unbounded))>);
|
||||
STATIC_ASSERT(!CanREnd<decltype((initially_unbounded))>);
|
||||
|
@ -616,7 +629,15 @@ STATIC_ASSERT(!CanCREnd<decltype((initially_unbounded))>);
|
|||
STATIC_ASSERT(!CanSize<decltype((initially_unbounded))>);
|
||||
STATIC_ASSERT(!CanEmpty<decltype((initially_unbounded))>);
|
||||
STATIC_ASSERT(ranges::data(initially_unbounded) == initially_unbounded);
|
||||
|
||||
#if _HAS_CXX23 // ranges::cbegin and ranges::cdata behavior differs in C++20 and C++23 modes
|
||||
STATIC_ASSERT(!CanCBegin<decltype((initially_unbounded))>);
|
||||
STATIC_ASSERT(!CanCData<decltype((initially_unbounded))>);
|
||||
#else // ^^^ C++23 / C++20 vvv
|
||||
STATIC_ASSERT(ranges::cbegin(initially_unbounded) == initially_unbounded);
|
||||
STATIC_ASSERT(ranges::cdata(initially_unbounded) == initially_unbounded);
|
||||
#endif // C++20
|
||||
|
||||
int initially_unbounded[42];
|
||||
STATIC_ASSERT(ranges::begin(initially_unbounded) == initially_unbounded);
|
||||
STATIC_ASSERT(ranges::end(initially_unbounded) == initially_unbounded + ranges::size(initially_unbounded));
|
||||
|
@ -972,64 +993,100 @@ STATIC_ASSERT(!ranges::view<std::string_view const&>);
|
|||
|
||||
STATIC_ASSERT(test_begin<std::span<int>, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_end<std::span<int>, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_cbegin<std::span<int>, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_cend<std::span<int>, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_rbegin<std::span<int>, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_rend<std::span<int>, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_crbegin<std::span<int>, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_crend<std::span<int>, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_size<std::span<int>, std::size_t>());
|
||||
STATIC_ASSERT(test_empty<std::span<int>, true>());
|
||||
STATIC_ASSERT(test_data<std::span<int>, int*>());
|
||||
STATIC_ASSERT(test_cdata<std::span<int>, int*>());
|
||||
STATIC_ASSERT(test_contiguous_range<std::span<int>>());
|
||||
STATIC_ASSERT(ranges::view<std::span<int>>);
|
||||
|
||||
#if _HAS_CXX23 // behavior of span members differs in C++20 and C++23 modes
|
||||
STATIC_ASSERT(test_cbegin<std::span<int>, std::span<int>::const_iterator>());
|
||||
STATIC_ASSERT(test_cend<std::span<int>, std::span<int>::const_iterator>());
|
||||
STATIC_ASSERT(test_crbegin<std::span<int>, std::span<int>::const_reverse_iterator>());
|
||||
STATIC_ASSERT(test_crend<std::span<int>, std::span<int>::const_reverse_iterator>());
|
||||
STATIC_ASSERT(test_cdata<std::span<int>, const int*>());
|
||||
#else // ^^^ C++23 / C++20 vvv
|
||||
STATIC_ASSERT(test_cbegin<std::span<int>, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_cend<std::span<int>, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_crbegin<std::span<int>, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_crend<std::span<int>, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_cdata<std::span<int>, int*>());
|
||||
#endif // C++20
|
||||
|
||||
STATIC_ASSERT(test_begin<std::span<int> const, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_end<std::span<int> const, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_cbegin<std::span<int> const, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_cend<std::span<int> const, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_rbegin<std::span<int> const, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_rend<std::span<int> const, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_crbegin<std::span<int> const, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_crend<std::span<int> const, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_size<std::span<int> const, std::size_t>());
|
||||
STATIC_ASSERT(test_empty<std::span<int> const, true>());
|
||||
STATIC_ASSERT(test_data<std::span<int> const, int*>());
|
||||
STATIC_ASSERT(test_cdata<std::span<int> const, int*>());
|
||||
STATIC_ASSERT(test_contiguous_range<std::span<int> const>());
|
||||
STATIC_ASSERT(!ranges::view<std::span<int> const>);
|
||||
|
||||
#if _HAS_CXX23 // behavior of const span members differs in C++20 and C++23 modes
|
||||
STATIC_ASSERT(test_cbegin<std::span<int> const, std::span<int>::const_iterator>());
|
||||
STATIC_ASSERT(test_cend<std::span<int> const, std::span<int>::const_iterator>());
|
||||
STATIC_ASSERT(test_crbegin<std::span<int> const, std::span<int>::const_reverse_iterator>());
|
||||
STATIC_ASSERT(test_crend<std::span<int> const, std::span<int>::const_reverse_iterator>());
|
||||
STATIC_ASSERT(test_cdata<std::span<int> const, const int*>());
|
||||
#else // ^^^ C++23 / C++20 vvv
|
||||
STATIC_ASSERT(test_cbegin<std::span<int> const, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_cend<std::span<int> const, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_crbegin<std::span<int> const, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_crend<std::span<int> const, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_cdata<std::span<int> const, int*>());
|
||||
#endif // C++20
|
||||
|
||||
STATIC_ASSERT(test_begin<std::span<int>&, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_end<std::span<int>&, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_cbegin<std::span<int>&, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_cend<std::span<int>&, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_rbegin<std::span<int>&, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_rend<std::span<int>&, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_crbegin<std::span<int>&, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_crend<std::span<int>&, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_size<std::span<int>&, std::size_t>());
|
||||
STATIC_ASSERT(test_empty<std::span<int>&, true>());
|
||||
STATIC_ASSERT(test_data<std::span<int>&, int*>());
|
||||
STATIC_ASSERT(test_cdata<std::span<int>&, int*>());
|
||||
STATIC_ASSERT(test_contiguous_range<std::span<int>&>());
|
||||
STATIC_ASSERT(!ranges::view<std::span<int>&>);
|
||||
|
||||
#if _HAS_CXX23 // behavior of span& members differs in C++20 and C++23 modes
|
||||
STATIC_ASSERT(test_cbegin<std::span<int>&, std::span<int>::const_iterator>());
|
||||
STATIC_ASSERT(test_cend<std::span<int>&, std::span<int>::const_iterator>());
|
||||
STATIC_ASSERT(test_crbegin<std::span<int>&, std::span<int>::const_reverse_iterator>());
|
||||
STATIC_ASSERT(test_crend<std::span<int>&, std::span<int>::const_reverse_iterator>());
|
||||
STATIC_ASSERT(test_cdata<std::span<int>&, const int*>());
|
||||
#else // ^^^ C++23 / C++20 vvv
|
||||
STATIC_ASSERT(test_cbegin<std::span<int>&, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_cend<std::span<int>&, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_crbegin<std::span<int>&, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_crend<std::span<int>&, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_cdata<std::span<int>&, int*>());
|
||||
#endif // C++20
|
||||
|
||||
STATIC_ASSERT(test_begin<std::span<int> const&, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_end<std::span<int> const&, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_cbegin<std::span<int> const&, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_cend<std::span<int> const&, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_rbegin<std::span<int> const&, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_rend<std::span<int> const&, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_crbegin<std::span<int> const&, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_crend<std::span<int> const&, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_size<std::span<int> const&, std::size_t>());
|
||||
STATIC_ASSERT(test_empty<std::span<int> const&, true>());
|
||||
STATIC_ASSERT(test_data<std::span<int> const&, int*>());
|
||||
STATIC_ASSERT(test_cdata<std::span<int> const&, int*>());
|
||||
STATIC_ASSERT(test_contiguous_range<std::span<int> const&>());
|
||||
STATIC_ASSERT(!ranges::view<std::span<int> const&>);
|
||||
|
||||
#if _HAS_CXX23 // behavior of const span& members differs in C++20 and C++23 modes
|
||||
STATIC_ASSERT(test_cbegin<std::span<int> const&, std::span<int>::const_iterator>());
|
||||
STATIC_ASSERT(test_cend<std::span<int> const&, std::span<int>::const_iterator>());
|
||||
STATIC_ASSERT(test_crbegin<std::span<int> const&, std::span<int>::const_reverse_iterator>());
|
||||
STATIC_ASSERT(test_crend<std::span<int> const&, std::span<int>::const_reverse_iterator>());
|
||||
STATIC_ASSERT(test_cdata<std::span<int> const&, const int*>());
|
||||
#else // ^^^ C++23 / C++20 vvv
|
||||
STATIC_ASSERT(test_cbegin<std::span<int> const&, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_cend<std::span<int> const&, std::span<int>::iterator>());
|
||||
STATIC_ASSERT(test_crbegin<std::span<int> const&, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_crend<std::span<int> const&, std::reverse_iterator<std::span<int>::iterator>>());
|
||||
STATIC_ASSERT(test_cdata<std::span<int> const&, int*>());
|
||||
#endif // C++20
|
||||
|
||||
using valarray_int_iterator = decltype(std::begin(std::declval<std::valarray<int>&>()));
|
||||
using const_valarray_int_iterator = decltype(std::begin(std::declval<const std::valarray<int>&>()));
|
||||
STATIC_ASSERT(test_begin<std::valarray<int>>());
|
||||
|
|
|
@ -95,6 +95,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(!CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(!CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(!CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -116,6 +122,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(!CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(!CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(!CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -137,6 +149,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(!CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -158,6 +176,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(!CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -179,6 +203,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(!CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(!CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -200,6 +230,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(!CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(!CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -221,6 +257,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -242,6 +284,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -263,6 +311,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -284,6 +338,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -305,6 +365,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -326,6 +392,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -347,6 +419,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -368,6 +446,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -389,6 +473,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -410,6 +500,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -431,6 +527,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -452,6 +554,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -473,6 +581,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -494,6 +608,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -515,6 +635,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -536,6 +662,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -557,6 +689,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -578,6 +716,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -599,6 +743,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -620,6 +770,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -641,6 +797,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -662,6 +824,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(CanBool<V const&>);
|
||||
STATIC_ASSERT(!CanData<V&>);
|
||||
|
@ -683,6 +851,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(CanData<V&>);
|
||||
|
@ -704,6 +878,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(CanBool<V const&>);
|
||||
STATIC_ASSERT(CanData<V&>);
|
||||
|
@ -725,6 +905,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(!CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(!CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(!CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(!CanBool<V const&>);
|
||||
STATIC_ASSERT(CanData<V&>);
|
||||
|
@ -746,6 +932,12 @@ namespace test_view_interface {
|
|||
STATIC_ASSERT(ranges::view<V>);
|
||||
STATIC_ASSERT(CanEmpty<V&>);
|
||||
STATIC_ASSERT(CanEmpty<V const&>);
|
||||
#if _HAS_CXX23
|
||||
STATIC_ASSERT(CanMemberCBegin<V&>);
|
||||
STATIC_ASSERT(CanMemberCBegin<V const&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V&>);
|
||||
STATIC_ASSERT(CanMemberCEnd<V const&>);
|
||||
#endif // _HAS_CXX23
|
||||
STATIC_ASSERT(CanBool<V&>);
|
||||
STATIC_ASSERT(CanBool<V const&>);
|
||||
STATIC_ASSERT(CanData<V&>);
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
RUNALL_INCLUDE ..\concepts_latest_matrix.lst
|
|
@ -0,0 +1,82 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include <cassert>
|
||||
#include <concepts>
|
||||
#include <iterator>
|
||||
#include <span>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
using namespace std;
|
||||
|
||||
enum class Const : bool { no, yes };
|
||||
enum class Dynamic : bool { no, yes };
|
||||
|
||||
static_assert(!to_underlying(Const::no) && to_underlying(Const::yes));
|
||||
static_assert(!to_underlying(Dynamic::no) && to_underlying(Dynamic::yes));
|
||||
|
||||
template <Const IsConst, Dynamic IsDynamic>
|
||||
constexpr bool test() {
|
||||
using T = conditional_t<to_underlying(IsConst), const int, int>;
|
||||
using Span = span<T, to_underlying(IsDynamic) ? dynamic_extent : 3>;
|
||||
using CIt = typename Span::const_iterator;
|
||||
using CRevIt = typename Span::const_reverse_iterator;
|
||||
|
||||
// Validate iterator properties
|
||||
static_assert(contiguous_iterator<CIt>);
|
||||
static_assert(random_access_iterator<CRevIt>);
|
||||
static_assert(same_as<CIt, const_iterator<typename Span::iterator>>);
|
||||
static_assert(same_as<CRevIt, const_iterator<typename Span::reverse_iterator>>);
|
||||
static_assert(same_as<CIt, const_iterator<CIt>>);
|
||||
static_assert(same_as<CRevIt, const_iterator<CRevIt>>);
|
||||
static_assert(same_as<iter_value_t<CIt>, remove_cv_t<T>>);
|
||||
static_assert(same_as<iter_value_t<CRevIt>, remove_cv_t<T>>);
|
||||
static_assert(same_as<iter_reference_t<CIt>, const T&>);
|
||||
static_assert(same_as<iter_reference_t<CRevIt>, const T&>);
|
||||
|
||||
T elems[3] = {1, 22, 333};
|
||||
const Span s{elems};
|
||||
|
||||
{ // Validate span::cbegin
|
||||
same_as<CIt> auto it = s.cbegin();
|
||||
assert(it == s.begin());
|
||||
assert(*it == 1);
|
||||
static_assert(noexcept(s.cbegin()));
|
||||
}
|
||||
|
||||
{ // Validate span::cend
|
||||
same_as<CIt> auto it = s.cend();
|
||||
assert(it == s.end());
|
||||
assert(it[-1] == 333);
|
||||
static_assert(noexcept(s.cend()));
|
||||
}
|
||||
|
||||
{ // Validate span::crbegin
|
||||
same_as<CRevIt> auto it = s.crbegin();
|
||||
assert(it == s.rbegin());
|
||||
assert(*it == 333);
|
||||
static_assert(noexcept(s.crbegin()));
|
||||
}
|
||||
|
||||
{ // Validate span::crend
|
||||
same_as<CRevIt> auto it = s.crend();
|
||||
assert(it == s.rend());
|
||||
assert(it[-1] == 1);
|
||||
static_assert(noexcept(s.crend()));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main() {
|
||||
static_assert(test<Const::no, Dynamic::no>());
|
||||
static_assert(test<Const::yes, Dynamic::no>());
|
||||
static_assert(test<Const::no, Dynamic::yes>());
|
||||
static_assert(test<Const::yes, Dynamic::yes>());
|
||||
|
||||
test<Const::no, Dynamic::no>();
|
||||
test<Const::yes, Dynamic::no>();
|
||||
test<Const::no, Dynamic::yes>();
|
||||
test<Const::yes, Dynamic::yes>();
|
||||
}
|
|
@ -12,16 +12,16 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
template <typename It>
|
||||
template <class It>
|
||||
concept CanIterConstRef = requires { typename iter_const_reference_t<It>; };
|
||||
|
||||
template <typename It>
|
||||
template <class It>
|
||||
concept CanConstIterator = requires(It it) {
|
||||
typename const_iterator<It>;
|
||||
{ make_const_iterator(move(it)) } -> same_as<const_iterator<It>>;
|
||||
};
|
||||
|
||||
template <typename Se>
|
||||
template <class Se>
|
||||
concept CanConstSentinel = requires(Se se) {
|
||||
typename const_sentinel<Se>;
|
||||
{ make_const_sentinel(move(se)) } -> same_as<const_sentinel<Se>>;
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
RUNALL_INCLUDE ..\concepts_latest_matrix.lst
|
|
@ -0,0 +1,240 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include <cassert>
|
||||
#include <concepts>
|
||||
#include <deque>
|
||||
#include <forward_list>
|
||||
#include <istream>
|
||||
#include <list>
|
||||
#include <ranges>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include <range_algorithm_support.hpp>
|
||||
|
||||
// New members (cbegin and cend) of `view_interface` are tested in `P0896R4_ranges_subrange\test.cpp`.
|
||||
// Updated CPOs (cbegin, cdata, ...) are tested in `P0896R4_ranges_range_machinery\test.cpp`
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <class Rng>
|
||||
concept CanRangeConstIterator = requires { typename ranges::const_iterator_t<Rng>; };
|
||||
|
||||
template <class Rng>
|
||||
concept CanRangeConstSentinel = requires { typename ranges::const_sentinel_t<Rng>; };
|
||||
|
||||
template <class Rng>
|
||||
concept CanRangeConstReference = requires { typename ranges::range_const_reference_t<Rng>; };
|
||||
|
||||
static_assert(!CanRangeConstIterator<void*>);
|
||||
static_assert(!CanRangeConstSentinel<void*>);
|
||||
static_assert(!CanRangeConstReference<void*>);
|
||||
|
||||
namespace test_array {
|
||||
using Arr = int[10];
|
||||
static_assert(CanRangeConstIterator<Arr>);
|
||||
static_assert(CanRangeConstSentinel<Arr>);
|
||||
static_assert(CanRangeConstReference<Arr>);
|
||||
static_assert(same_as<ranges::const_iterator_t<Arr>, const_iterator<int*>>);
|
||||
static_assert(same_as<ranges::const_sentinel_t<Arr>, const_iterator<int*>>);
|
||||
static_assert(same_as<ranges::range_const_reference_t<Arr>, const int&>);
|
||||
static_assert(!ranges::constant_range<Arr>);
|
||||
|
||||
using ConstArr = const Arr;
|
||||
static_assert(CanRangeConstIterator<ConstArr>);
|
||||
static_assert(CanRangeConstSentinel<ConstArr>);
|
||||
static_assert(CanRangeConstReference<ConstArr>);
|
||||
static_assert(same_as<ranges::const_iterator_t<ConstArr>, const int*>);
|
||||
static_assert(same_as<ranges::const_sentinel_t<ConstArr>, const int*>);
|
||||
static_assert(same_as<ranges::range_const_reference_t<ConstArr>, const int&>);
|
||||
static_assert(ranges::constant_range<ConstArr>);
|
||||
} // namespace test_array
|
||||
|
||||
namespace test_random_access_range {
|
||||
using Rng = deque<int>;
|
||||
static_assert(CanRangeConstIterator<Rng>);
|
||||
static_assert(CanRangeConstSentinel<Rng>);
|
||||
static_assert(CanRangeConstReference<Rng>);
|
||||
static_assert(same_as<ranges::const_iterator_t<Rng>, const_iterator<Rng::iterator>>);
|
||||
static_assert(same_as<ranges::const_sentinel_t<Rng>, const_iterator<Rng::iterator>>);
|
||||
static_assert(same_as<ranges::range_const_reference_t<Rng>, const int&>);
|
||||
static_assert(!ranges::constant_range<Rng>);
|
||||
|
||||
using ConstRng = const deque<int>;
|
||||
static_assert(CanRangeConstIterator<ConstRng>);
|
||||
static_assert(CanRangeConstSentinel<ConstRng>);
|
||||
static_assert(CanRangeConstReference<ConstRng>);
|
||||
static_assert(same_as<ranges::const_iterator_t<ConstRng>, ConstRng::const_iterator>);
|
||||
static_assert(same_as<ranges::const_sentinel_t<ConstRng>, ConstRng::const_iterator>);
|
||||
static_assert(same_as<ranges::range_const_reference_t<ConstRng>, const int&>);
|
||||
static_assert(ranges::constant_range<ConstRng>);
|
||||
} // namespace test_random_access_range
|
||||
|
||||
namespace test_bidirectional_range {
|
||||
using Rng = list<int>;
|
||||
static_assert(CanRangeConstIterator<Rng>);
|
||||
static_assert(CanRangeConstSentinel<Rng>);
|
||||
static_assert(CanRangeConstReference<Rng>);
|
||||
static_assert(same_as<ranges::const_iterator_t<Rng>, const_iterator<Rng::iterator>>);
|
||||
static_assert(same_as<ranges::const_sentinel_t<Rng>, const_iterator<Rng::iterator>>);
|
||||
static_assert(same_as<ranges::range_const_reference_t<Rng>, const int&>);
|
||||
static_assert(!ranges::constant_range<Rng>);
|
||||
|
||||
using ConstRng = const list<int>;
|
||||
static_assert(CanRangeConstIterator<ConstRng>);
|
||||
static_assert(CanRangeConstSentinel<ConstRng>);
|
||||
static_assert(CanRangeConstReference<ConstRng>);
|
||||
static_assert(same_as<ranges::const_iterator_t<ConstRng>, ConstRng::const_iterator>);
|
||||
static_assert(same_as<ranges::const_sentinel_t<ConstRng>, ConstRng::const_iterator>);
|
||||
static_assert(same_as<ranges::range_const_reference_t<ConstRng>, const int&>);
|
||||
static_assert(ranges::constant_range<ConstRng>);
|
||||
} // namespace test_bidirectional_range
|
||||
|
||||
namespace test_forward_range {
|
||||
using Rng = forward_list<int>;
|
||||
static_assert(CanRangeConstIterator<Rng>);
|
||||
static_assert(CanRangeConstSentinel<Rng>);
|
||||
static_assert(CanRangeConstReference<Rng>);
|
||||
static_assert(same_as<ranges::const_iterator_t<Rng>, const_iterator<Rng::iterator>>);
|
||||
static_assert(same_as<ranges::const_sentinel_t<Rng>, const_iterator<Rng::iterator>>);
|
||||
static_assert(same_as<ranges::range_const_reference_t<Rng>, const int&>);
|
||||
static_assert(!ranges::constant_range<Rng>);
|
||||
|
||||
using ConstRng = const forward_list<int>;
|
||||
static_assert(CanRangeConstIterator<ConstRng>);
|
||||
static_assert(CanRangeConstSentinel<ConstRng>);
|
||||
static_assert(CanRangeConstReference<ConstRng>);
|
||||
static_assert(same_as<ranges::const_iterator_t<ConstRng>, ConstRng::const_iterator>);
|
||||
static_assert(same_as<ranges::const_sentinel_t<ConstRng>, ConstRng::const_iterator>);
|
||||
static_assert(same_as<ranges::range_const_reference_t<ConstRng>, const int&>);
|
||||
static_assert(ranges::constant_range<ConstRng>);
|
||||
} // namespace test_forward_range
|
||||
|
||||
namespace test_input_range {
|
||||
using Rng = ranges::istream_view<int>;
|
||||
static_assert(CanRangeConstIterator<Rng>);
|
||||
static_assert(CanRangeConstSentinel<Rng>);
|
||||
static_assert(CanRangeConstReference<Rng>);
|
||||
static_assert(same_as<ranges::const_iterator_t<Rng>, const_iterator<ranges::iterator_t<Rng>>>);
|
||||
static_assert(same_as<ranges::const_sentinel_t<Rng>, default_sentinel_t>);
|
||||
static_assert(same_as<ranges::range_const_reference_t<Rng>, const int&>);
|
||||
static_assert(!ranges::constant_range<Rng>);
|
||||
} // namespace test_input_range
|
||||
|
||||
namespace test_prvalue_range {
|
||||
using Rng = ranges::transform_view<ranges::ref_view<deque<float>>, int (*)(float)>;
|
||||
static_assert(CanRangeConstIterator<Rng>);
|
||||
static_assert(CanRangeConstSentinel<Rng>);
|
||||
static_assert(CanRangeConstReference<Rng>);
|
||||
static_assert(same_as<ranges::const_iterator_t<Rng>, const_iterator<ranges::iterator_t<Rng>>>);
|
||||
static_assert(same_as<ranges::const_sentinel_t<Rng>, const_iterator<ranges::iterator_t<Rng>>>);
|
||||
static_assert(same_as<ranges::range_const_reference_t<Rng>, int>);
|
||||
static_assert(ranges::constant_range<Rng>);
|
||||
|
||||
using ConstRng = const Rng;
|
||||
static_assert(CanRangeConstIterator<ConstRng>);
|
||||
static_assert(CanRangeConstSentinel<ConstRng>);
|
||||
static_assert(CanRangeConstReference<ConstRng>);
|
||||
static_assert(same_as<ranges::const_iterator_t<ConstRng>, const_iterator<ranges::iterator_t<ConstRng>>>);
|
||||
static_assert(same_as<ranges::const_sentinel_t<ConstRng>, const_iterator<ranges::iterator_t<ConstRng>>>);
|
||||
static_assert(same_as<ranges::range_const_reference_t<ConstRng>, int>);
|
||||
static_assert(ranges::constant_range<ConstRng>);
|
||||
} // namespace test_prvalue_range
|
||||
|
||||
namespace test_vector_bool {
|
||||
using Vb = vector<bool>;
|
||||
static_assert(CanRangeConstIterator<Vb>);
|
||||
static_assert(CanRangeConstSentinel<Vb>);
|
||||
static_assert(CanRangeConstReference<Vb>);
|
||||
static_assert(same_as<ranges::const_iterator_t<Vb>, const_iterator<Vb::iterator>>);
|
||||
static_assert(same_as<ranges::const_sentinel_t<Vb>, const_iterator<Vb::iterator>>);
|
||||
static_assert(same_as<ranges::range_const_reference_t<Vb>, bool>);
|
||||
static_assert(!ranges::constant_range<Vb>);
|
||||
|
||||
using ConstVb = const vector<bool>;
|
||||
static_assert(CanRangeConstIterator<ConstVb>);
|
||||
static_assert(CanRangeConstSentinel<ConstVb>);
|
||||
static_assert(CanRangeConstReference<ConstVb>);
|
||||
static_assert(same_as<ranges::const_iterator_t<ConstVb>, ConstVb::const_iterator>);
|
||||
static_assert(same_as<ranges::const_sentinel_t<ConstVb>, ConstVb::const_iterator>);
|
||||
static_assert(same_as<ranges::range_const_reference_t<ConstVb>, bool>);
|
||||
static_assert(ranges::constant_range<ConstVb>);
|
||||
} // namespace test_vector_bool
|
||||
|
||||
template <class Rng>
|
||||
static constexpr void test_cpos(Rng&& rng) {
|
||||
using ranges::iterator_t, ranges::sentinel_t;
|
||||
using R = conditional_t<ranges::constant_range<const Rng&> && !ranges::constant_range<Rng&>, const Rng&, Rng&>;
|
||||
|
||||
{ // Validate ranges::cbegin
|
||||
using It = iterator_t<R>;
|
||||
|
||||
const same_as<const_iterator<It>> auto it = ranges::cbegin(rng);
|
||||
if constexpr (equality_comparable<It>) {
|
||||
if (ranges::forward_range<Rng>) { // intentionally not if constexpr
|
||||
assert(it == ranges::begin(rng));
|
||||
}
|
||||
}
|
||||
|
||||
static_assert(noexcept(ranges::cbegin(rng))
|
||||
== (noexcept(ranges::begin(rng)) && is_nothrow_constructible_v<const_iterator<It>, It>) );
|
||||
}
|
||||
|
||||
{ // Validate ranges::cend
|
||||
using Se = sentinel_t<R>;
|
||||
|
||||
const same_as<const_sentinel<Se>> auto se = ranges::cend(rng);
|
||||
if constexpr (equality_comparable<Se>) {
|
||||
assert(se == ranges::end(rng));
|
||||
}
|
||||
|
||||
static_assert(noexcept(ranges::cend(rng))
|
||||
== (noexcept(ranges::end(rng)) && is_nothrow_constructible_v<const_sentinel<Se>, Se>) );
|
||||
}
|
||||
|
||||
if constexpr (ranges::bidirectional_range<Rng>) {
|
||||
if constexpr (CanRBegin<Rng>) { // Validate ranges::crbegin
|
||||
using RevIt = decltype(ranges::rbegin(declval<R&>()));
|
||||
|
||||
const same_as<const_iterator<RevIt>> auto it = ranges::crbegin(rng);
|
||||
assert(it == ranges::rbegin(rng));
|
||||
|
||||
static_assert(
|
||||
noexcept(ranges::crbegin(rng))
|
||||
== (noexcept(ranges::rbegin(rng)) && is_nothrow_constructible_v<const_iterator<RevIt>, RevIt>) );
|
||||
}
|
||||
|
||||
if constexpr (CanREnd<Rng>) { // Validate ranges::crend
|
||||
using RevSe = decltype(ranges::rend(declval<R&>()));
|
||||
|
||||
const same_as<const_sentinel<RevSe>> auto it = ranges::crend(rng);
|
||||
assert(it == ranges::rend(rng));
|
||||
|
||||
static_assert(
|
||||
noexcept(ranges::crend(rng))
|
||||
== (noexcept(ranges::rend(rng)) && is_nothrow_constructible_v<const_sentinel<RevSe>, RevSe>) );
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr (ranges::contiguous_range<Rng>) { // Validate ranges::cdata
|
||||
const same_as<const ranges::range_value_t<Rng>*> auto ptr = ranges::cdata(rng);
|
||||
assert(ptr == ranges::data(rng));
|
||||
|
||||
static_assert(noexcept(ranges::cdata(rng)) == noexcept(ranges::data(rng)));
|
||||
}
|
||||
}
|
||||
|
||||
struct instantiator {
|
||||
template <class Rng>
|
||||
static constexpr void call() {
|
||||
int some_ints[] = {1, 2, 3};
|
||||
Rng rng{some_ints};
|
||||
test_cpos(rng);
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
STATIC_ASSERT((test_in<instantiator, const int>(), true));
|
||||
test_in<instantiator, const int>();
|
||||
}
|
Загрузка…
Ссылка в новой задаче