From 0565c46aa089f7e872825af7dd2e5be1161fafcd Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Tue, 8 Aug 2023 01:04:17 -0400 Subject: [PATCH 001/179] WIP: [libc++][ranges] Implement `ranges::stride_view`. Differential Revision: https://reviews.llvm.org/D156924 Signed-off-by: Will Hawkins --- libcxx/docs/FeatureTestMacroTable.rst | 2 + libcxx/include/CMakeLists.txt | 1 + libcxx/include/__ranges/stride_view.h | 421 + libcxx/include/ranges | 1 + libcxx/include/version | 7 +- libcxx/modules/std/ranges.inc | 2 +- .../ranges.version.compile.pass.cpp | 78 +- .../version.version.compile.pass.cpp | 14056 ++++++++-------- .../range.stride.view/adaptor.pass.cpp | 193 + .../range.stride.view/base.pass.cpp | 70 + .../range.stride.view/begin.pass.cpp | 22 + .../range.stride.view/ctad.compile.pass.cpp | 22 + .../enable_borrowed_range.compile.pass.cpp | 32 + .../range.stride.view/end.pass.cpp | 22 + .../iterator/ctor.default.pass.cpp | 49 + .../range.stride.view/iterator/equal.pass.cpp | 89 + .../sentinel/ctor.default.pass.cpp | 22 + .../range.stride.view/sentinel/equal.pass.cpp | 22 + .../range.stride.view/size.pass.cpp | 46 + .../range.adaptors/range.stride.view/test.h | 183 + .../generate_feature_test_macro_components.py | 5 + 21 files changed, 8349 insertions(+), 6996 deletions(-) create mode 100644 libcxx/include/__ranges/stride_view.h create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.compile.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/sentinel/ctor.default.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/sentinel/equal.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/size.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst index c7f01e6868395..77f183237dab5 100644 --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -386,6 +386,8 @@ Status ---------------------------------------------------------- ----------------- ``__cpp_lib_ranges_slide`` *unimplemented* ---------------------------------------------------------- ----------------- + ``__cpp_lib_ranges_stride`` ``202207L`` + ---------------------------------------------------------- ----------------- ``__cpp_lib_ranges_starts_ends_with`` ``202106L`` ---------------------------------------------------------- ----------------- ``__cpp_lib_ranges_to_container`` ``202202L`` diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index ddace8bf8c728..529ebfc86375f 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -731,6 +731,7 @@ set(files __ranges/single_view.h __ranges/size.h __ranges/split_view.h + __ranges/stride_view.h __ranges/subrange.h __ranges/take_view.h __ranges/take_while_view.h diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h new file mode 100644 index 0000000000000..880c8ce2950e4 --- /dev/null +++ b/libcxx/include/__ranges/stride_view.h @@ -0,0 +1,421 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___RANGES_STRIDE_VIEW_H +#define _LIBCPP___RANGES_STRIDE_VIEW_H + +#include <__config> + +#include <__compare/three_way_comparable.h> +#include <__concepts/constructible.h> +#include <__concepts/convertible_to.h> +#include <__concepts/derived_from.h> +#include <__functional/bind_back.h> +#include <__iterator/advance.h> +#include <__iterator/concepts.h> +#include <__iterator/default_sentinel.h> +#include <__iterator/distance.h> +#include <__iterator/iter_move.h> +#include <__iterator/iter_swap.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/next.h> +#include <__iterator/reverse_iterator.h> +#include <__ranges/access.h> +#include <__ranges/all.h> +#include <__ranges/concepts.h> +#include <__ranges/enable_borrowed_range.h> +#include <__ranges/non_propagating_cache.h> +#include <__ranges/range_adaptor.h> +#include <__ranges/size.h> +#include <__ranges/subrange.h> +#include <__ranges/view_interface.h> +#include <__ranges/views.h> +#include <__type_traits/conditional.h> +#include <__type_traits/maybe_const.h> +#include <__type_traits/remove_cvref.h> +#include <__utility/forward.h> +#include <__utility/move.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER >= 23 + +namespace ranges { + +template +_LIBCPP_HIDE_FROM_ABI constexpr _Value __div_ceil(_Value __left, _Value __right) { + _Value __r = __left / __right; + if (__left % __right) { + __r++; + } + return __r; +} + +template + requires view<_View> +class stride_view : public view_interface> { + _LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View(); + range_difference_t<_View> __stride_ = 0; + + template + class __iterator; + template + class __sentinel; + +public: + _LIBCPP_HIDE_FROM_ABI constexpr explicit stride_view(_View __base, range_difference_t<_View> __stride) + : __base_(std::move(__base)), __stride_(__stride) {} + + _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& + requires copy_constructible<_View> + { + return __base_; + } + + _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } + + _LIBCPP_HIDE_FROM_ABI constexpr auto stride() { return __stride_; } + + _LIBCPP_HIDE_FROM_ABI constexpr auto size() + requires ranges::sized_range<_View> + { + return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __stride_)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto size() const + requires ranges::sized_range + { + return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __stride_)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto begin() + requires(!__simple_view<_View>) + { + return __iterator{*this, ranges::begin(__base_)}; + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const + requires ranges::range + { + return __iterator{*this, ranges::begin(__base_)}; + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto end() + requires(!__simple_view<_View> && common_range<_View> && sized_range<_View> && forward_range<_View>) + { + auto __missing = (__stride_ - ranges::distance(__base_) % __stride_) % __stride_; + return __iterator{*this, ranges::end(__base_), __missing}; + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto end() + requires(!__simple_view<_View> && common_range<_View> && !bidirectional_range<_View>) + { + return __iterator{*this, ranges::end(__base_)}; + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto end() + requires(!__simple_view<_View>) + { + return std::default_sentinel; + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto end() const + requires(range && common_range && sized_range && forward_range) + { + auto __missing = (__stride_ - ranges::distance(__base_) % __stride_) % __stride_; + return __iterator{*this, ranges::end(__base_), __missing}; + } + _LIBCPP_HIDE_FROM_ABI constexpr auto end() const + requires(range && common_range<_View> && !bidirectional_range<_View>) + { + return __iterator{*this, ranges::end(__base_)}; + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto end() const + requires(range) + { + return std::default_sentinel; + } +}; // class stride_view + +template +struct __stride_iterator_category {}; + +template +struct __stride_iterator_category<_View> { + using _Cat = typename iterator_traits>::iterator_category; + using iterator_category = + _If, + random_access_iterator_tag, + /* else */ _Cat >; +}; + +template + requires view<_View> +template +class stride_view<_View>::__iterator : public __stride_iterator_category<_View> { + using _Parent = __maybe_const<_Const, stride_view<_View>>; + using _Base = __maybe_const<_Const, _View>; + +public: + using difference_type = range_difference_t<_Base>; + using value_type = range_value_t<_Base>; + using iterator_concept = + _If, + random_access_iterator_tag, + _If, + bidirectional_iterator_tag, + _If, + forward_iterator_tag, + /* else */ input_iterator_tag >>>; + + _LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_Base> __current_ = iterator_t<_Base>(); + _LIBCPP_NO_UNIQUE_ADDRESS ranges::sentinel_t<_Base> __end_ = ranges::sentinel_t<_Base>(); + difference_type __stride_ = 0; + difference_type __missing_ = 0; + + // using iterator_category = inherited; + _LIBCPP_HIDE_FROM_ABI __iterator() + requires default_initializable> + = default; + + _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator __i) + requires _Const && std::convertible_to, ranges::iterator_t<_Base>> && + std::convertible_to, ranges::sentinel_t<_Base>> + : __current_(std::move(__i.__current_)), + __end_(std::move(__i.__end_)), + __stride_(__i.__stride_), + __missing_(__i.__missing_) {} + + _LIBCPP_HIDE_FROM_ABI constexpr __iterator( + _Parent& __parent, ranges::iterator_t<_Base> __current, difference_type __missing = 0) + : __current_(std::move(__current)), + __end_(ranges::end(__parent.__base_)), + __stride_(__parent.__stride_), + __missing_(__missing) {} + + _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> const& base() const& noexcept { return __current_; } + _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> base() && { return std::move(__current_); } + + _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return *__current_; } + + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() { + __missing_ = ranges::advance(__current_, __stride_, __end_); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; } + _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) + requires forward_range<_Base> + { + auto __tmp = *this; + ++*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--() + requires bidirectional_range<_Base> + { + ranges::advance(__current_, __missing_ - __stride_); + __missing_ = 0; + return *this; + } + _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int) + requires bidirectional_range<_Base> + { + auto __tmp = *this; + --*this; + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __s) + requires random_access_range<_Base> + { + if (__s > 0) { + ranges::advance(__current_, __stride_ * (__s - 1)); + __missing_ = ranges::advance(__current_, __stride_, __end_); + } else if (__s < 0) { + ranges::advance(__current_, __stride_ * __s + __missing_); + __missing_ = 0; + } + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __s) + requires random_access_range<_Base> + { + return *this += -__s; + } + + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator[](difference_type __s) const + requires random_access_range<_Base> + { + return *(*this + __s); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(__iterator const& __x, default_sentinel_t) { + return __x.__current_ == __x.__end_; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(__iterator const& __x, __iterator const& __y) + requires equality_comparable> + { + return __x.__current_ == __y.__current_; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(__iterator const& __x, __iterator const& __y) + requires random_access_range<_Base> + { + return __x.__current_ < __y.__current_; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(__iterator const& __x, __iterator const& __y) + requires random_access_range<_Base> + { + return __y < __x; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(__iterator const& __x, __iterator const& __y) + requires random_access_range<_Base> + { + return !(__y < __x); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(__iterator const& __x, __iterator const& __y) + requires random_access_range<_Base> + { + return !(__x < __y); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=>(__iterator const& __x, __iterator const& __y) + requires random_access_range<_Base> && three_way_comparable> + { + return __x.__current_ <=> __y.__current_; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator const& __i, difference_type __s) + requires random_access_range<_Base> + { + auto __r = __i; + __r += __s; + return __r; + } + _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __s, __iterator const& __i) + requires random_access_range<_Base> + { + auto __r = __i; + __r += __s; + return __r; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator const& __i, difference_type __s) + requires random_access_range<_Base> + { + auto __r = __i; + __r -= __s; + return __r; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(__iterator const& __x, __iterator const& __y) + requires sized_sentinel_for, iterator_t<_Base>> && forward_range<_Base> + { + auto __n = __x.__current_ - __y.__current_; + return (__n + __x.__missing_ - __y.__missing_) / __x.__stride_; + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(__iterator const& __x, __iterator const& __y) + requires sized_sentinel_for, iterator_t<_Base>> + { + auto __n = __x.__current_ - __y.__current_; + if (__n < 0) { + return -ranges::__div_ceil(-__n, __x.__stride_); + } + return ranges::__div_ceil(__n, __x.__stride_); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(default_sentinel_t, __iterator const& __x) + requires sized_sentinel_for, iterator_t<_Base>> + { + return ranges::__div_ceil(__x.__end_ - __x.__current_, __x.__stride_); + } + _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(__iterator const& __x, default_sentinel_t __y) + requires sized_sentinel_for, iterator_t<_Base>> + { + return -(__y - __x); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr range_rvalue_reference_t<_Base> + iter_move(__iterator const& __it) noexcept(noexcept(ranges::iter_move(__it.__current_))) { + return ranges::iter_move(__it.__current_); + } + + _LIBCPP_HIDE_FROM_ABI friend constexpr void + iter_swap(__iterator const& __x, + __iterator const& __y) noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) + requires indirectly_swappable> + { + return ranges::iter_swap(__x.__current_, __y.__current_); + } +}; // class stride_view::__iterator + +template + requires view<_View> +template +class stride_view<_View>::__sentinel { +public: + sentinel_t<_View> __end_ = sentinel_t<_View>(); + + _LIBCPP_HIDE_FROM_ABI __sentinel() = default; + + _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(stride_view<_View>& __parent) + : __end_(ranges::end(__parent.__base_)) {} + + _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_View> base() const { return __end_; } + + _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(__iterator const& __x, __sentinel const& __y) { + return __x.__current_ == __y.__end_; + } +}; // class stride_view::__sentinel + +template +stride_view(_Range&&) -> stride_view>; + +namespace views { +namespace __stride { +// removed this. +struct __fn { + template + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) const + noexcept(noexcept(stride_view{std::forward<_Range>(__range), __n})) + -> decltype(stride_view{std::forward<_Range>(__range), __n}) { + return stride_view{std::forward<_Range>(__range), __n}; + } + + template + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Np&& __n) const { + return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Np>(__n))); + } +}; +} // namespace __stride + +inline namespace __cpo { +inline constexpr auto stride = __stride::__fn{}; +} // namespace __cpo +} // namespace views +} // namespace ranges + +#endif // _LIBCPP_STD_VER >= 23 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___RANGES_STRIDE_VIEW_H diff --git a/libcxx/include/ranges b/libcxx/include/ranges index cfaa66a0831b3..5f656d523ded9 100644 --- a/libcxx/include/ranges +++ b/libcxx/include/ranges @@ -435,6 +435,7 @@ namespace std { # include <__ranges/single_view.h> # include <__ranges/size.h> # include <__ranges/split_view.h> +# include <__ranges/stride_view.h> # include <__ranges/subrange.h> # include <__ranges/take_view.h> # include <__ranges/take_while_view.h> diff --git a/libcxx/include/version b/libcxx/include/version index 99e69299921fa..5e3e5b98e3bd6 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -211,7 +211,11 @@ __cpp_lib_ranges_join_with 202202L __cpp_lib_ranges_repeat 202207L __cpp_lib_ranges_slide 202202L __cpp_lib_ranges_starts_ends_with 202106L -__cpp_lib_ranges_to_container 202202L +__cpp_lib_ranges_stride 202207L +__cpp_lib_ranges_to_container 202202L + + + __cpp_lib_ranges_zip 202110L __cpp_lib_ratio 202306L __cpp_lib_raw_memory_algorithms 201606L @@ -529,6 +533,7 @@ __cpp_lib_void_t 201411L # define __cpp_lib_ranges_repeat 202207L // # define __cpp_lib_ranges_slide 202202L # define __cpp_lib_ranges_starts_ends_with 202106L +# define __cpp_lib_ranges_stride 202207L # define __cpp_lib_ranges_to_container 202202L // # define __cpp_lib_ranges_zip 202110L // # define __cpp_lib_reference_from_temporary 202202L diff --git a/libcxx/modules/std/ranges.inc b/libcxx/modules/std/ranges.inc index cc7daa3cd1aec..b238389a393b8 100644 --- a/libcxx/modules/std/ranges.inc +++ b/libcxx/modules/std/ranges.inc @@ -340,7 +340,6 @@ export namespace std { } #endif // _LIBCPP_STD_VER >= 23 -#if 0 // [range.stride], stride view using std::ranges::stride_view; @@ -348,6 +347,7 @@ export namespace std { using std::ranges::views::stride; } +#if 0 using std::ranges::cartesian_product_view; namespace views { diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp index 5116864879485..7a548c1bf2635 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp @@ -64,9 +64,13 @@ # error "__cpp_lib_ranges_slide should not be defined before c++23" # endif -# ifdef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should not be defined before c++23" -# endif +# ifdef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should not be defined before c++23" +# endif # ifdef __cpp_lib_ranges_zip # error "__cpp_lib_ranges_zip should not be defined before c++23" @@ -118,9 +122,13 @@ # error "__cpp_lib_ranges_slide should not be defined before c++23" # endif -# ifdef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should not be defined before c++23" -# endif +# ifdef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should not be defined before c++23" +# endif # ifdef __cpp_lib_ranges_zip # error "__cpp_lib_ranges_zip should not be defined before c++23" @@ -172,9 +180,13 @@ # error "__cpp_lib_ranges_slide should not be defined before c++23" # endif -# ifdef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should not be defined before c++23" -# endif +# ifdef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should not be defined before c++23" +# endif # ifdef __cpp_lib_ranges_zip # error "__cpp_lib_ranges_zip should not be defined before c++23" @@ -229,9 +241,13 @@ # error "__cpp_lib_ranges_slide should not be defined before c++23" # endif -# ifdef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should not be defined before c++23" -# endif +# ifdef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should not be defined before c++23" +# endif # ifdef __cpp_lib_ranges_zip # error "__cpp_lib_ranges_zip should not be defined before c++23" @@ -325,12 +341,19 @@ # endif # endif -# ifndef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should be defined in c++23" -# endif -# if __cpp_lib_ranges_to_container != 202202L -# error "__cpp_lib_ranges_to_container should have the value 202202L in c++23" -# endif +# ifndef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should be defined in c++23" +# endif +# if __cpp_lib_ranges_stride != 202207L +# error "__cpp_lib_ranges_stride should have the value 202207L in c++23" +# endif + +# ifndef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should be defined in c++23" +# endif +# if __cpp_lib_ranges_to_container != 202202L +# error "__cpp_lib_ranges_to_container should have the value 202202L in c++23" +# endif # if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_ranges_zip @@ -454,12 +477,19 @@ # endif # endif -# ifndef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should be defined in c++26" -# endif -# if __cpp_lib_ranges_to_container != 202202L -# error "__cpp_lib_ranges_to_container should have the value 202202L in c++26" -# endif +# ifndef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should be defined in c++26" +# endif +# if __cpp_lib_ranges_stride != 202207L +# error "__cpp_lib_ranges_stride should have the value 202207L in c++26" +# endif + +# ifndef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should be defined in c++26" +# endif +# if __cpp_lib_ranges_to_container != 202202L +# error "__cpp_lib_ranges_to_container should have the value 202202L in c++26" +# endif # if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_ranges_zip diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp index 9a8a1da88ee8f..955229761437a 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp @@ -13,7 +13,244 @@ // Test the feature test macros defined by -// clang-format off +/* Constant Value + __cpp_lib_adaptor_iterator_pair_constructor 202106L [C++23] + __cpp_lib_addressof_constexpr 201603L [C++17] + __cpp_lib_allocate_at_least 202302L [C++23] + __cpp_lib_allocator_traits_is_always_equal 201411L [C++17] + __cpp_lib_any 201606L [C++17] + __cpp_lib_apply 201603L [C++17] + __cpp_lib_array_constexpr 201603L [C++17] + 201811L [C++20] + __cpp_lib_as_const 201510L [C++17] + __cpp_lib_associative_heterogeneous_erasure 202110L [C++23] + __cpp_lib_associative_heterogeneous_insertion 202306L [C++26] + __cpp_lib_assume_aligned 201811L [C++20] + __cpp_lib_atomic_flag_test 201907L [C++20] + __cpp_lib_atomic_float 201711L [C++20] + __cpp_lib_atomic_is_always_lock_free 201603L [C++17] + __cpp_lib_atomic_lock_free_type_aliases 201907L [C++20] + __cpp_lib_atomic_min_max 202403L [C++26] + __cpp_lib_atomic_ref 201806L [C++20] + __cpp_lib_atomic_shared_ptr 201711L [C++20] + __cpp_lib_atomic_value_initialization 201911L [C++20] + __cpp_lib_atomic_wait 201907L [C++20] + __cpp_lib_barrier 201907L [C++20] + __cpp_lib_bind_back 202202L [C++23] + __cpp_lib_bind_front 201907L [C++20] + 202306L [C++26] + __cpp_lib_bit_cast 201806L [C++20] + __cpp_lib_bitops 201907L [C++20] + __cpp_lib_bitset 202306L [C++26] + __cpp_lib_bool_constant 201505L [C++17] + __cpp_lib_bounded_array_traits 201902L [C++20] + __cpp_lib_boyer_moore_searcher 201603L [C++17] + __cpp_lib_byte 201603L [C++17] + __cpp_lib_byteswap 202110L [C++23] + __cpp_lib_char8_t 201907L [C++20] + __cpp_lib_chrono 201611L [C++17] + __cpp_lib_chrono_udls 201304L [C++14] + __cpp_lib_clamp 201603L [C++17] + __cpp_lib_complex_udls 201309L [C++14] + __cpp_lib_concepts 202002L [C++20] + __cpp_lib_constexpr_algorithms 201806L [C++20] + __cpp_lib_constexpr_bitset 202207L [C++23] + __cpp_lib_constexpr_charconv 202207L [C++23] + __cpp_lib_constexpr_cmath 202202L [C++23] + __cpp_lib_constexpr_complex 201711L [C++20] + __cpp_lib_constexpr_dynamic_alloc 201907L [C++20] + __cpp_lib_constexpr_functional 201907L [C++20] + __cpp_lib_constexpr_iterator 201811L [C++20] + __cpp_lib_constexpr_memory 201811L [C++20] + 202202L [C++23] + __cpp_lib_constexpr_new 202406L [C++26] + __cpp_lib_constexpr_numeric 201911L [C++20] + __cpp_lib_constexpr_string 201907L [C++20] + __cpp_lib_constexpr_string_view 201811L [C++20] + __cpp_lib_constexpr_tuple 201811L [C++20] + __cpp_lib_constexpr_typeinfo 202106L [C++23] + __cpp_lib_constexpr_utility 201811L [C++20] + __cpp_lib_constexpr_vector 201907L [C++20] + __cpp_lib_constrained_equality 202403L [C++26] + __cpp_lib_containers_ranges 202202L [C++23] + __cpp_lib_copyable_function 202306L [C++26] + __cpp_lib_coroutine 201902L [C++20] + __cpp_lib_debugging 202311L [C++26] + __cpp_lib_default_template_type_for_algorithm_values 202403L [C++26] + __cpp_lib_destroying_delete 201806L [C++20] + __cpp_lib_enable_shared_from_this 201603L [C++17] + __cpp_lib_endian 201907L [C++20] + __cpp_lib_erase_if 202002L [C++20] + __cpp_lib_exchange_function 201304L [C++14] + __cpp_lib_execution 201603L [C++17] + 201902L [C++20] + __cpp_lib_expected 202211L [C++23] + __cpp_lib_filesystem 201703L [C++17] + __cpp_lib_flat_map 202207L [C++23] + __cpp_lib_flat_set 202207L [C++23] + __cpp_lib_format 202110L [C++20] + __cpp_lib_format_path 202403L [C++26] + __cpp_lib_format_ranges 202207L [C++23] + __cpp_lib_format_uchar 202311L [C++20] + __cpp_lib_formatters 202302L [C++23] + __cpp_lib_forward_like 202207L [C++23] + __cpp_lib_freestanding_algorithm 202311L [C++26] + __cpp_lib_freestanding_array 202311L [C++26] + __cpp_lib_freestanding_cstring 202306L [C++26] + __cpp_lib_freestanding_expected 202311L [C++26] + __cpp_lib_freestanding_mdspan 202311L [C++26] + __cpp_lib_freestanding_optional 202311L [C++26] + __cpp_lib_freestanding_string_view 202311L [C++26] + __cpp_lib_freestanding_variant 202311L [C++26] + __cpp_lib_fstream_native_handle 202306L [C++26] + __cpp_lib_function_ref 202306L [C++26] + __cpp_lib_gcd_lcm 201606L [C++17] + __cpp_lib_generate_random 202403L [C++26] + __cpp_lib_generic_associative_lookup 201304L [C++14] + __cpp_lib_generic_unordered_lookup 201811L [C++20] + __cpp_lib_hardware_interference_size 201703L [C++17] + __cpp_lib_has_unique_object_representations 201606L [C++17] + __cpp_lib_hazard_pointer 202306L [C++26] + __cpp_lib_hypot 201603L [C++17] + __cpp_lib_incomplete_container_elements 201505L [C++17] + __cpp_lib_inplace_vector 202406L [C++26] + __cpp_lib_int_pow2 202002L [C++20] + __cpp_lib_integer_comparison_functions 202002L [C++20] + __cpp_lib_integer_sequence 201304L [C++14] + __cpp_lib_integral_constant_callable 201304L [C++14] + __cpp_lib_interpolate 201902L [C++20] + __cpp_lib_invoke 201411L [C++17] + __cpp_lib_invoke_r 202106L [C++23] + __cpp_lib_ios_noreplace 202207L [C++23] + __cpp_lib_is_aggregate 201703L [C++17] + __cpp_lib_is_constant_evaluated 201811L [C++20] + __cpp_lib_is_final 201402L [C++14] + __cpp_lib_is_implicit_lifetime 202302L [C++23] + __cpp_lib_is_invocable 201703L [C++17] + __cpp_lib_is_layout_compatible 201907L [C++20] + __cpp_lib_is_nothrow_convertible 201806L [C++20] + __cpp_lib_is_null_pointer 201309L [C++14] + __cpp_lib_is_pointer_interconvertible 201907L [C++20] + __cpp_lib_is_scoped_enum 202011L [C++23] + __cpp_lib_is_swappable 201603L [C++17] + __cpp_lib_is_virtual_base_of 202406L [C++26] + __cpp_lib_is_within_lifetime 202306L [C++26] + __cpp_lib_jthread 201911L [C++20] + __cpp_lib_latch 201907L [C++20] + __cpp_lib_launder 201606L [C++17] + __cpp_lib_linalg 202311L [C++26] + __cpp_lib_list_remove_return_type 201806L [C++20] + __cpp_lib_logical_traits 201510L [C++17] + __cpp_lib_make_from_tuple 201606L [C++17] + __cpp_lib_make_reverse_iterator 201402L [C++14] + __cpp_lib_make_unique 201304L [C++14] + __cpp_lib_map_try_emplace 201411L [C++17] + __cpp_lib_math_constants 201907L [C++20] + __cpp_lib_math_special_functions 201603L [C++17] + __cpp_lib_mdspan 202207L [C++23] + 202406L [C++26] + __cpp_lib_memory_resource 201603L [C++17] + __cpp_lib_modules 202207L [C++23] + __cpp_lib_move_iterator_concept 202207L [C++20] + __cpp_lib_move_only_function 202110L [C++23] + __cpp_lib_node_extract 201606L [C++17] + __cpp_lib_nonmember_container_access 201411L [C++17] + __cpp_lib_not_fn 201603L [C++17] + 202306L [C++26] + __cpp_lib_null_iterators 201304L [C++14] + __cpp_lib_optional 201606L [C++17] + 202106L [C++20] + 202110L [C++23] + __cpp_lib_optional_range_support 202406L [C++26] + __cpp_lib_out_ptr 202106L [C++23] + 202311L [C++26] + __cpp_lib_parallel_algorithm 201603L [C++17] + __cpp_lib_philox_engine 202406L [C++26] + __cpp_lib_polymorphic_allocator 201902L [C++20] + __cpp_lib_print 202207L [C++23] + __cpp_lib_quoted_string_io 201304L [C++14] + __cpp_lib_ranges 202110L [C++20] + 202406L [C++23] + __cpp_lib_ranges_as_const 202207L [C++23] + __cpp_lib_ranges_as_rvalue 202207L [C++23] + __cpp_lib_ranges_chunk 202202L [C++23] + __cpp_lib_ranges_chunk_by 202202L [C++23] + __cpp_lib_ranges_concat 202403L [C++26] + __cpp_lib_ranges_contains 202207L [C++23] + __cpp_lib_ranges_find_last 202207L [C++23] + __cpp_lib_ranges_iota 202202L [C++23] + __cpp_lib_ranges_join_with 202202L [C++23] + __cpp_lib_ranges_repeat 202207L [C++23] + __cpp_lib_ranges_slide 202202L [C++23] + __cpp_lib_ranges_starts_ends_with 202106L [C++23] + __cpp_lib_ranges_stride 202207L [C++23] + __cpp_lib_ranges_to_container 202202L [C++23] + __cpp_lib_ranges_zip 202110L [C++23] + __cpp_lib_ratio 202306L [C++26] + __cpp_lib_raw_memory_algorithms 201606L [C++17] + __cpp_lib_rcu 202306L [C++26] + __cpp_lib_reference_from_temporary 202202L [C++23] + __cpp_lib_reference_wrapper 202403L [C++26] + __cpp_lib_remove_cvref 201711L [C++20] + __cpp_lib_result_of_sfinae 201210L [C++14] + __cpp_lib_robust_nonmodifying_seq_ops 201304L [C++14] + __cpp_lib_sample 201603L [C++17] + __cpp_lib_saturation_arithmetic 202311L [C++26] + __cpp_lib_scoped_lock 201703L [C++17] + __cpp_lib_semaphore 201907L [C++20] + __cpp_lib_senders 202406L [C++26] + __cpp_lib_shared_mutex 201505L [C++17] + __cpp_lib_shared_ptr_arrays 201611L [C++17] + 201707L [C++20] + __cpp_lib_shared_ptr_weak_type 201606L [C++17] + __cpp_lib_shared_timed_mutex 201402L [C++14] + __cpp_lib_shift 201806L [C++20] + __cpp_lib_smart_ptr_for_overwrite 202002L [C++20] + __cpp_lib_smart_ptr_owner_equality 202306L [C++26] + __cpp_lib_source_location 201907L [C++20] + __cpp_lib_span 202002L [C++20] + __cpp_lib_span_at 202311L [C++26] + __cpp_lib_span_initializer_list 202311L [C++26] + __cpp_lib_spanstream 202106L [C++23] + __cpp_lib_ssize 201902L [C++20] + __cpp_lib_sstream_from_string_view 202306L [C++26] + __cpp_lib_stacktrace 202011L [C++23] + __cpp_lib_starts_ends_with 201711L [C++20] + __cpp_lib_stdatomic_h 202011L [C++23] + __cpp_lib_string_contains 202011L [C++23] + __cpp_lib_string_resize_and_overwrite 202110L [C++23] + __cpp_lib_string_udls 201304L [C++14] + __cpp_lib_string_view 201606L [C++17] + 201803L [C++20] + 202403L [C++26] + __cpp_lib_submdspan 202306L [C++26] + __cpp_lib_syncbuf 201803L [C++20] + __cpp_lib_text_encoding 202306L [C++26] + __cpp_lib_three_way_comparison 201907L [C++20] + __cpp_lib_to_address 201711L [C++20] + __cpp_lib_to_array 201907L [C++20] + __cpp_lib_to_chars 201611L [C++17] + 202306L [C++26] + __cpp_lib_to_string 202306L [C++26] + __cpp_lib_to_underlying 202102L [C++23] + __cpp_lib_transformation_trait_aliases 201304L [C++14] + __cpp_lib_transparent_operators 201210L [C++14] + 201510L [C++17] + __cpp_lib_tuple_element_t 201402L [C++14] + __cpp_lib_tuple_like 202207L [C++23] + 202311L [C++26] + __cpp_lib_tuples_by_type 201304L [C++14] + __cpp_lib_type_identity 201806L [C++20] + __cpp_lib_type_trait_variable_templates 201510L [C++17] + __cpp_lib_uncaught_exceptions 201411L [C++17] + __cpp_lib_unordered_map_try_emplace 201411L [C++17] + __cpp_lib_unreachable 202202L [C++23] + __cpp_lib_unwrap_ref 201811L [C++20] + __cpp_lib_variant 202102L [C++17] + 202106L [C++20] + 202306L [C++26] + __cpp_lib_void_t 201411L [C++17] +*/ #include #include "test_macros.h" @@ -680,9 +917,13 @@ # error "__cpp_lib_ranges_repeat should not be defined before c++23" # endif -# ifdef __cpp_lib_ranges_slide -# error "__cpp_lib_ranges_slide should not be defined before c++23" -# endif +# ifdef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should not be defined before c++23" +# endif # ifdef __cpp_lib_ranges_starts_ends_with # error "__cpp_lib_ranges_starts_ends_with should not be defined before c++23" @@ -1208,6990 +1449,6865 @@ # error "__cpp_lib_endian should not be defined before c++20" # endif -# ifdef __cpp_lib_erase_if -# error "__cpp_lib_erase_if should not be defined before c++20" -# endif - -# ifndef __cpp_lib_exchange_function -# error "__cpp_lib_exchange_function should be defined in c++14" -# endif -# if __cpp_lib_exchange_function != 201304L -# error "__cpp_lib_exchange_function should have the value 201304L in c++14" -# endif - -# ifdef __cpp_lib_execution -# error "__cpp_lib_execution should not be defined before c++17" -# endif - -# ifdef __cpp_lib_expected -# error "__cpp_lib_expected should not be defined before c++23" -# endif - -# ifdef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should not be defined before c++17" -# endif - -# ifdef __cpp_lib_flat_map -# error "__cpp_lib_flat_map should not be defined before c++23" -# endif - -# ifdef __cpp_lib_flat_set -# error "__cpp_lib_flat_set should not be defined before c++23" -# endif - -# ifdef __cpp_lib_format -# error "__cpp_lib_format should not be defined before c++20" -# endif - -# ifdef __cpp_lib_format_path -# error "__cpp_lib_format_path should not be defined before c++26" -# endif - -# ifdef __cpp_lib_format_ranges -# error "__cpp_lib_format_ranges should not be defined before c++23" -# endif - -# ifdef __cpp_lib_format_uchar -# error "__cpp_lib_format_uchar should not be defined before c++20" -# endif - -# ifdef __cpp_lib_formatters -# error "__cpp_lib_formatters should not be defined before c++23" -# endif - -# ifdef __cpp_lib_forward_like -# error "__cpp_lib_forward_like should not be defined before c++23" -# endif - -# ifdef __cpp_lib_freestanding_algorithm -# error "__cpp_lib_freestanding_algorithm should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_array -# error "__cpp_lib_freestanding_array should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_cstring -# error "__cpp_lib_freestanding_cstring should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_expected -# error "__cpp_lib_freestanding_expected should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_mdspan -# error "__cpp_lib_freestanding_mdspan should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_optional -# error "__cpp_lib_freestanding_optional should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_string_view -# error "__cpp_lib_freestanding_string_view should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_variant -# error "__cpp_lib_freestanding_variant should not be defined before c++26" -# endif - -# ifdef __cpp_lib_fstream_native_handle -# error "__cpp_lib_fstream_native_handle should not be defined before c++26" -# endif - -# ifdef __cpp_lib_function_ref -# error "__cpp_lib_function_ref should not be defined before c++26" -# endif - -# ifdef __cpp_lib_gcd_lcm -# error "__cpp_lib_gcd_lcm should not be defined before c++17" -# endif - -# ifdef __cpp_lib_generate_random -# error "__cpp_lib_generate_random should not be defined before c++26" -# endif - -# ifndef __cpp_lib_generic_associative_lookup -# error "__cpp_lib_generic_associative_lookup should be defined in c++14" -# endif -# if __cpp_lib_generic_associative_lookup != 201304L -# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++14" -# endif - -# ifdef __cpp_lib_generic_unordered_lookup -# error "__cpp_lib_generic_unordered_lookup should not be defined before c++20" -# endif - -# ifdef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should not be defined before c++17" -# endif - -# ifdef __cpp_lib_has_unique_object_representations -# error "__cpp_lib_has_unique_object_representations should not be defined before c++17" -# endif - -# ifdef __cpp_lib_hazard_pointer -# error "__cpp_lib_hazard_pointer should not be defined before c++26" -# endif - -# ifdef __cpp_lib_hypot -# error "__cpp_lib_hypot should not be defined before c++17" -# endif - -# ifdef __cpp_lib_incomplete_container_elements -# error "__cpp_lib_incomplete_container_elements should not be defined before c++17" -# endif - -# ifdef __cpp_lib_inplace_vector -# error "__cpp_lib_inplace_vector should not be defined before c++26" -# endif - -# ifdef __cpp_lib_int_pow2 -# error "__cpp_lib_int_pow2 should not be defined before c++20" -# endif - -# ifdef __cpp_lib_integer_comparison_functions -# error "__cpp_lib_integer_comparison_functions should not be defined before c++20" -# endif - -# ifndef __cpp_lib_integer_sequence -# error "__cpp_lib_integer_sequence should be defined in c++14" -# endif -# if __cpp_lib_integer_sequence != 201304L -# error "__cpp_lib_integer_sequence should have the value 201304L in c++14" -# endif - -# ifndef __cpp_lib_integral_constant_callable -# error "__cpp_lib_integral_constant_callable should be defined in c++14" -# endif -# if __cpp_lib_integral_constant_callable != 201304L -# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++14" -# endif - -# ifdef __cpp_lib_interpolate -# error "__cpp_lib_interpolate should not be defined before c++20" -# endif - -# ifdef __cpp_lib_invoke -# error "__cpp_lib_invoke should not be defined before c++17" -# endif - -# ifdef __cpp_lib_invoke_r -# error "__cpp_lib_invoke_r should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ios_noreplace -# error "__cpp_lib_ios_noreplace should not be defined before c++23" -# endif - -# ifdef __cpp_lib_is_aggregate -# error "__cpp_lib_is_aggregate should not be defined before c++17" -# endif - -# ifdef __cpp_lib_is_constant_evaluated -# error "__cpp_lib_is_constant_evaluated should not be defined before c++20" -# endif - -# ifndef __cpp_lib_is_final -# error "__cpp_lib_is_final should be defined in c++14" -# endif -# if __cpp_lib_is_final != 201402L -# error "__cpp_lib_is_final should have the value 201402L in c++14" -# endif - -# ifdef __cpp_lib_is_implicit_lifetime -# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" -# endif - -# ifdef __cpp_lib_is_invocable -# error "__cpp_lib_is_invocable should not be defined before c++17" -# endif - -# ifdef __cpp_lib_is_layout_compatible -# error "__cpp_lib_is_layout_compatible should not be defined before c++20" -# endif - -# ifdef __cpp_lib_is_nothrow_convertible -# error "__cpp_lib_is_nothrow_convertible should not be defined before c++20" -# endif - -# ifndef __cpp_lib_is_null_pointer -# error "__cpp_lib_is_null_pointer should be defined in c++14" -# endif -# if __cpp_lib_is_null_pointer != 201309L -# error "__cpp_lib_is_null_pointer should have the value 201309L in c++14" -# endif - -# ifdef __cpp_lib_is_pointer_interconvertible -# error "__cpp_lib_is_pointer_interconvertible should not be defined before c++20" -# endif - -# ifdef __cpp_lib_is_scoped_enum -# error "__cpp_lib_is_scoped_enum should not be defined before c++23" -# endif - -# ifdef __cpp_lib_is_sufficiently_aligned -# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" -# endif +# ifndef __cpp_lib_exchange_function +# error "__cpp_lib_exchange_function should be defined in c++14" +# endif +# if __cpp_lib_exchange_function != 201304L +# error "__cpp_lib_exchange_function should have the value 201304L in c++14" +# endif -# ifdef __cpp_lib_is_swappable -# error "__cpp_lib_is_swappable should not be defined before c++17" -# endif +# ifdef __cpp_lib_execution +# error "__cpp_lib_execution should not be defined before c++17" +# endif -# ifdef __cpp_lib_is_virtual_base_of -# error "__cpp_lib_is_virtual_base_of should not be defined before c++26" -# endif +# ifdef __cpp_lib_expected +# error "__cpp_lib_expected should not be defined before c++23" +# endif -# ifdef __cpp_lib_is_within_lifetime -# error "__cpp_lib_is_within_lifetime should not be defined before c++26" -# endif +# ifdef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should not be defined before c++17" +# endif -# ifdef __cpp_lib_jthread -# error "__cpp_lib_jthread should not be defined before c++20" -# endif +# ifdef __cpp_lib_flat_map +# error "__cpp_lib_flat_map should not be defined before c++23" +# endif -# ifdef __cpp_lib_latch -# error "__cpp_lib_latch should not be defined before c++20" -# endif +# ifdef __cpp_lib_flat_set +# error "__cpp_lib_flat_set should not be defined before c++23" +# endif -# ifdef __cpp_lib_launder -# error "__cpp_lib_launder should not be defined before c++17" -# endif +# ifdef __cpp_lib_format +# error "__cpp_lib_format should not be defined before c++20" +# endif -# ifdef __cpp_lib_linalg -# error "__cpp_lib_linalg should not be defined before c++26" -# endif +# ifdef __cpp_lib_format_path +# error "__cpp_lib_format_path should not be defined before c++26" +# endif -# ifdef __cpp_lib_list_remove_return_type -# error "__cpp_lib_list_remove_return_type should not be defined before c++20" -# endif +# ifdef __cpp_lib_format_ranges +# error "__cpp_lib_format_ranges should not be defined before c++23" +# endif -# ifdef __cpp_lib_logical_traits -# error "__cpp_lib_logical_traits should not be defined before c++17" -# endif +# ifdef __cpp_lib_format_uchar +# error "__cpp_lib_format_uchar should not be defined before c++20" +# endif -# ifdef __cpp_lib_make_from_tuple -# error "__cpp_lib_make_from_tuple should not be defined before c++17" -# endif +# ifdef __cpp_lib_formatters +# error "__cpp_lib_formatters should not be defined before c++23" +# endif + +# ifdef __cpp_lib_forward_like +# error "__cpp_lib_forward_like should not be defined before c++23" +# endif + +# ifdef __cpp_lib_freestanding_algorithm +# error "__cpp_lib_freestanding_algorithm should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_array +# error "__cpp_lib_freestanding_array should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_cstring +# error "__cpp_lib_freestanding_cstring should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_expected +# error "__cpp_lib_freestanding_expected should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_mdspan +# error "__cpp_lib_freestanding_mdspan should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_optional +# error "__cpp_lib_freestanding_optional should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_string_view +# error "__cpp_lib_freestanding_string_view should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_variant +# error "__cpp_lib_freestanding_variant should not be defined before c++26" +# endif + +# ifdef __cpp_lib_fstream_native_handle +# error "__cpp_lib_fstream_native_handle should not be defined before c++26" +# endif + +# ifdef __cpp_lib_function_ref +# error "__cpp_lib_function_ref should not be defined before c++26" +# endif + +# ifdef __cpp_lib_gcd_lcm +# error "__cpp_lib_gcd_lcm should not be defined before c++17" +# endif + +# ifdef __cpp_lib_generate_random +# error "__cpp_lib_generate_random should not be defined before c++26" +# endif + +# ifndef __cpp_lib_generic_associative_lookup +# error "__cpp_lib_generic_associative_lookup should be defined in c++14" +# endif +# if __cpp_lib_generic_associative_lookup != 201304L +# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++14" +# endif + +# ifdef __cpp_lib_generic_unordered_lookup +# error "__cpp_lib_generic_unordered_lookup should not be defined before c++20" +# endif + +# ifdef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should not be defined before c++17" +# endif + +# ifdef __cpp_lib_has_unique_object_representations +# error "__cpp_lib_has_unique_object_representations should not be defined before c++17" +# endif + +# ifdef __cpp_lib_hazard_pointer +# error "__cpp_lib_hazard_pointer should not be defined before c++26" +# endif + +# ifdef __cpp_lib_hypot +# error "__cpp_lib_hypot should not be defined before c++17" +# endif + +# ifdef __cpp_lib_incomplete_container_elements +# error "__cpp_lib_incomplete_container_elements should not be defined before c++17" +# endif + +# ifdef __cpp_lib_inplace_vector +# error "__cpp_lib_inplace_vector should not be defined before c++26" +# endif + +# ifdef __cpp_lib_int_pow2 +# error "__cpp_lib_int_pow2 should not be defined before c++20" +# endif + +# ifdef __cpp_lib_integer_comparison_functions +# error "__cpp_lib_integer_comparison_functions should not be defined before c++20" +# endif + +# ifndef __cpp_lib_integer_sequence +# error "__cpp_lib_integer_sequence should be defined in c++14" +# endif +# if __cpp_lib_integer_sequence != 201304L +# error "__cpp_lib_integer_sequence should have the value 201304L in c++14" +# endif + +# ifndef __cpp_lib_integral_constant_callable +# error "__cpp_lib_integral_constant_callable should be defined in c++14" +# endif +# if __cpp_lib_integral_constant_callable != 201304L +# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++14" +# endif + +# ifdef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should not be defined before c++20" +# endif + +# ifdef __cpp_lib_invoke +# error "__cpp_lib_invoke should not be defined before c++17" +# endif + +# ifdef __cpp_lib_invoke_r +# error "__cpp_lib_invoke_r should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ios_noreplace +# error "__cpp_lib_ios_noreplace should not be defined before c++23" +# endif + +# ifdef __cpp_lib_is_aggregate +# error "__cpp_lib_is_aggregate should not be defined before c++17" +# endif + +# ifdef __cpp_lib_is_constant_evaluated +# error "__cpp_lib_is_constant_evaluated should not be defined before c++20" +# endif + +# ifndef __cpp_lib_is_final +# error "__cpp_lib_is_final should be defined in c++14" +# endif +# if __cpp_lib_is_final != 201402L +# error "__cpp_lib_is_final should have the value 201402L in c++14" +# endif + +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" +# endif + +# ifdef __cpp_lib_is_invocable +# error "__cpp_lib_is_invocable should not be defined before c++17" +# endif + +# ifdef __cpp_lib_is_layout_compatible +# error "__cpp_lib_is_layout_compatible should not be defined before c++20" +# endif + +# ifdef __cpp_lib_is_nothrow_convertible +# error "__cpp_lib_is_nothrow_convertible should not be defined before c++20" +# endif + +# ifndef __cpp_lib_is_null_pointer +# error "__cpp_lib_is_null_pointer should be defined in c++14" +# endif +# if __cpp_lib_is_null_pointer != 201309L +# error "__cpp_lib_is_null_pointer should have the value 201309L in c++14" +# endif + +# ifdef __cpp_lib_is_pointer_interconvertible +# error "__cpp_lib_is_pointer_interconvertible should not be defined before c++20" +# endif + +# ifdef __cpp_lib_is_scoped_enum +# error "__cpp_lib_is_scoped_enum should not be defined before c++23" +# endif + +# ifdef __cpp_lib_is_swappable +# error "__cpp_lib_is_swappable should not be defined before c++17" +# endif + +# ifdef __cpp_lib_is_virtual_base_of +# error "__cpp_lib_is_virtual_base_of should not be defined before c++26" +# endif + +# ifdef __cpp_lib_is_within_lifetime +# error "__cpp_lib_is_within_lifetime should not be defined before c++26" +# endif + +# ifdef __cpp_lib_jthread +# error "__cpp_lib_jthread should not be defined before c++20" +# endif + +# ifdef __cpp_lib_latch +# error "__cpp_lib_latch should not be defined before c++20" +# endif + +# ifdef __cpp_lib_launder +# error "__cpp_lib_launder should not be defined before c++17" +# endif + +# ifdef __cpp_lib_linalg +# error "__cpp_lib_linalg should not be defined before c++26" +# endif + +# ifdef __cpp_lib_list_remove_return_type +# error "__cpp_lib_list_remove_return_type should not be defined before c++20" +# endif + +# ifdef __cpp_lib_logical_traits +# error "__cpp_lib_logical_traits should not be defined before c++17" +# endif + +# ifdef __cpp_lib_make_from_tuple +# error "__cpp_lib_make_from_tuple should not be defined before c++17" +# endif + +# ifndef __cpp_lib_make_reverse_iterator +# error "__cpp_lib_make_reverse_iterator should be defined in c++14" +# endif +# if __cpp_lib_make_reverse_iterator != 201402L +# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++14" +# endif + +# ifndef __cpp_lib_make_unique +# error "__cpp_lib_make_unique should be defined in c++14" +# endif +# if __cpp_lib_make_unique != 201304L +# error "__cpp_lib_make_unique should have the value 201304L in c++14" +# endif + +# ifdef __cpp_lib_map_try_emplace +# error "__cpp_lib_map_try_emplace should not be defined before c++17" +# endif + +# ifdef __cpp_lib_math_constants +# error "__cpp_lib_math_constants should not be defined before c++20" +# endif + +# ifdef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should not be defined before c++17" +# endif + +# ifdef __cpp_lib_mdspan +# error "__cpp_lib_mdspan should not be defined before c++23" +# endif + +# ifdef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should not be defined before c++17" +# endif + +# ifdef __cpp_lib_modules +# error "__cpp_lib_modules should not be defined before c++23" +# endif + +# ifdef __cpp_lib_move_iterator_concept +# error "__cpp_lib_move_iterator_concept should not be defined before c++20" +# endif + +# ifdef __cpp_lib_move_only_function +# error "__cpp_lib_move_only_function should not be defined before c++23" +# endif + +# ifdef __cpp_lib_node_extract +# error "__cpp_lib_node_extract should not be defined before c++17" +# endif + +# ifdef __cpp_lib_nonmember_container_access +# error "__cpp_lib_nonmember_container_access should not be defined before c++17" +# endif + +# ifdef __cpp_lib_not_fn +# error "__cpp_lib_not_fn should not be defined before c++17" +# endif + +# ifndef __cpp_lib_null_iterators +# error "__cpp_lib_null_iterators should be defined in c++14" +# endif +# if __cpp_lib_null_iterators != 201304L +# error "__cpp_lib_null_iterators should have the value 201304L in c++14" +# endif + +# ifdef __cpp_lib_optional +# error "__cpp_lib_optional should not be defined before c++17" +# endif + +# ifdef __cpp_lib_optional_range_support +# error "__cpp_lib_optional_range_support should not be defined before c++26" +# endif + +# ifdef __cpp_lib_out_ptr +# error "__cpp_lib_out_ptr should not be defined before c++23" +# endif + +# ifdef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should not be defined before c++17" +# endif + +# ifdef __cpp_lib_philox_engine +# error "__cpp_lib_philox_engine should not be defined before c++26" +# endif + +# ifdef __cpp_lib_polymorphic_allocator +# error "__cpp_lib_polymorphic_allocator should not be defined before c++20" +# endif + +# ifdef __cpp_lib_print +# error "__cpp_lib_print should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION +# ifndef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should be defined in c++14" +# endif +# if __cpp_lib_quoted_string_io != 201304L +# error "__cpp_lib_quoted_string_io should have the value 201304L in c++14" +# endif +# else +# ifdef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" +# endif +# endif + +# ifdef __cpp_lib_ranges +# error "__cpp_lib_ranges should not be defined before c++20" +# endif + +# ifdef __cpp_lib_ranges_as_const +# error "__cpp_lib_ranges_as_const should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_as_rvalue +# error "__cpp_lib_ranges_as_rvalue should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_chunk_by +# error "__cpp_lib_ranges_chunk_by should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_concat +# error "__cpp_lib_ranges_concat should not be defined before c++26" +# endif + +# ifdef __cpp_lib_ranges_contains +# error "__cpp_lib_ranges_contains should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_find_last +# error "__cpp_lib_ranges_find_last should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_iota +# error "__cpp_lib_ranges_iota should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_join_with +# error "__cpp_lib_ranges_join_with should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_repeat +# error "__cpp_lib_ranges_repeat should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_slide +# error "__cpp_lib_ranges_slide should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_starts_ends_with +# error "__cpp_lib_ranges_starts_ends_with should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_zip +# error "__cpp_lib_ranges_zip should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ratio +# error "__cpp_lib_ratio should not be defined before c++26" +# endif + +# ifdef __cpp_lib_raw_memory_algorithms +# error "__cpp_lib_raw_memory_algorithms should not be defined before c++17" +# endif + +# ifdef __cpp_lib_rcu +# error "__cpp_lib_rcu should not be defined before c++26" +# endif + +# ifdef __cpp_lib_reference_from_temporary +# error "__cpp_lib_reference_from_temporary should not be defined before c++23" +# endif + +# ifdef __cpp_lib_reference_wrapper +# error "__cpp_lib_reference_wrapper should not be defined before c++26" +# endif + +# ifdef __cpp_lib_remove_cvref +# error "__cpp_lib_remove_cvref should not be defined before c++20" +# endif + +# ifndef __cpp_lib_result_of_sfinae +# error "__cpp_lib_result_of_sfinae should be defined in c++14" +# endif +# if __cpp_lib_result_of_sfinae != 201210L +# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++14" +# endif + +# ifndef __cpp_lib_robust_nonmodifying_seq_ops +# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++14" +# endif +# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L +# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++14" +# endif + +# ifdef __cpp_lib_sample +# error "__cpp_lib_sample should not be defined before c++17" +# endif + +# ifdef __cpp_lib_saturation_arithmetic +# error "__cpp_lib_saturation_arithmetic should not be defined before c++26" +# endif + +# ifdef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should not be defined before c++17" +# endif + +# ifdef __cpp_lib_semaphore +# error "__cpp_lib_semaphore should not be defined before c++20" +# endif + +# ifdef __cpp_lib_senders +# error "__cpp_lib_senders should not be defined before c++26" +# endif + +# ifdef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should not be defined before c++17" +# endif + +# ifdef __cpp_lib_shared_ptr_arrays +# error "__cpp_lib_shared_ptr_arrays should not be defined before c++17" +# endif + +# ifdef __cpp_lib_shared_ptr_weak_type +# error "__cpp_lib_shared_ptr_weak_type should not be defined before c++17" +# endif + +# if _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should be defined in c++14" +# endif +# if __cpp_lib_shared_timed_mutex != 201402L +# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++14" +# endif +# else +# ifdef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifdef __cpp_lib_shift +# error "__cpp_lib_shift should not be defined before c++20" +# endif + +# ifdef __cpp_lib_smart_ptr_for_overwrite +# error "__cpp_lib_smart_ptr_for_overwrite should not be defined before c++20" +# endif + +# ifdef __cpp_lib_smart_ptr_owner_equality +# error "__cpp_lib_smart_ptr_owner_equality should not be defined before c++26" +# endif + +# ifdef __cpp_lib_source_location +# error "__cpp_lib_source_location should not be defined before c++20" +# endif + +# ifdef __cpp_lib_span +# error "__cpp_lib_span should not be defined before c++20" +# endif + +# ifdef __cpp_lib_span_at +# error "__cpp_lib_span_at should not be defined before c++26" +# endif + +# ifdef __cpp_lib_span_initializer_list +# error "__cpp_lib_span_initializer_list should not be defined before c++26" +# endif + +# ifdef __cpp_lib_spanstream +# error "__cpp_lib_spanstream should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ssize +# error "__cpp_lib_ssize should not be defined before c++20" +# endif + +# ifdef __cpp_lib_sstream_from_string_view +# error "__cpp_lib_sstream_from_string_view should not be defined before c++26" +# endif + +# ifdef __cpp_lib_stacktrace +# error "__cpp_lib_stacktrace should not be defined before c++23" +# endif + +# ifdef __cpp_lib_starts_ends_with +# error "__cpp_lib_starts_ends_with should not be defined before c++20" +# endif + +# ifdef __cpp_lib_stdatomic_h +# error "__cpp_lib_stdatomic_h should not be defined before c++23" +# endif + +# ifdef __cpp_lib_string_contains +# error "__cpp_lib_string_contains should not be defined before c++23" +# endif + +# ifdef __cpp_lib_string_resize_and_overwrite +# error "__cpp_lib_string_resize_and_overwrite should not be defined before c++23" +# endif + +# ifndef __cpp_lib_string_udls +# error "__cpp_lib_string_udls should be defined in c++14" +# endif +# if __cpp_lib_string_udls != 201304L +# error "__cpp_lib_string_udls should have the value 201304L in c++14" +# endif + +# ifdef __cpp_lib_string_view +# error "__cpp_lib_string_view should not be defined before c++17" +# endif + +# ifdef __cpp_lib_submdspan +# error "__cpp_lib_submdspan should not be defined before c++26" +# endif + +# ifdef __cpp_lib_syncbuf +# error "__cpp_lib_syncbuf should not be defined before c++20" +# endif + +# ifdef __cpp_lib_text_encoding +# error "__cpp_lib_text_encoding should not be defined before c++26" +# endif + +# ifdef __cpp_lib_three_way_comparison +# error "__cpp_lib_three_way_comparison should not be defined before c++20" +# endif + +# ifdef __cpp_lib_to_address +# error "__cpp_lib_to_address should not be defined before c++20" +# endif + +# ifdef __cpp_lib_to_array +# error "__cpp_lib_to_array should not be defined before c++20" +# endif + +# ifdef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should not be defined before c++17" +# endif + +# ifdef __cpp_lib_to_string +# error "__cpp_lib_to_string should not be defined before c++26" +# endif + +# ifdef __cpp_lib_to_underlying +# error "__cpp_lib_to_underlying should not be defined before c++23" +# endif + +# ifndef __cpp_lib_transformation_trait_aliases +# error "__cpp_lib_transformation_trait_aliases should be defined in c++14" +# endif +# if __cpp_lib_transformation_trait_aliases != 201304L +# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++14" +# endif + +# ifndef __cpp_lib_transparent_operators +# error "__cpp_lib_transparent_operators should be defined in c++14" +# endif +# if __cpp_lib_transparent_operators != 201210L +# error "__cpp_lib_transparent_operators should have the value 201210L in c++14" +# endif + +# ifndef __cpp_lib_tuple_element_t +# error "__cpp_lib_tuple_element_t should be defined in c++14" +# endif +# if __cpp_lib_tuple_element_t != 201402L +# error "__cpp_lib_tuple_element_t should have the value 201402L in c++14" +# endif + +# ifdef __cpp_lib_tuple_like +# error "__cpp_lib_tuple_like should not be defined before c++23" +# endif + +# ifndef __cpp_lib_tuples_by_type +# error "__cpp_lib_tuples_by_type should be defined in c++14" +# endif +# if __cpp_lib_tuples_by_type != 201304L +# error "__cpp_lib_tuples_by_type should have the value 201304L in c++14" +# endif + +# ifdef __cpp_lib_type_identity +# error "__cpp_lib_type_identity should not be defined before c++20" +# endif + +# ifdef __cpp_lib_type_trait_variable_templates +# error "__cpp_lib_type_trait_variable_templates should not be defined before c++17" +# endif + +# ifdef __cpp_lib_uncaught_exceptions +# error "__cpp_lib_uncaught_exceptions should not be defined before c++17" +# endif + +# ifdef __cpp_lib_unordered_map_try_emplace +# error "__cpp_lib_unordered_map_try_emplace should not be defined before c++17" +# endif + +# ifdef __cpp_lib_unreachable +# error "__cpp_lib_unreachable should not be defined before c++23" +# endif + +# ifdef __cpp_lib_unwrap_ref +# error "__cpp_lib_unwrap_ref should not be defined before c++20" +# endif + +# ifdef __cpp_lib_variant +# error "__cpp_lib_variant should not be defined before c++17" +# endif + +# ifdef __cpp_lib_void_t +# error "__cpp_lib_void_t should not be defined before c++17" +# endif -# ifndef __cpp_lib_make_reverse_iterator -# error "__cpp_lib_make_reverse_iterator should be defined in c++14" -# endif -# if __cpp_lib_make_reverse_iterator != 201402L -# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++14" -# endif +#elif TEST_STD_VER == 17 -# ifndef __cpp_lib_make_unique -# error "__cpp_lib_make_unique should be defined in c++14" -# endif -# if __cpp_lib_make_unique != 201304L -# error "__cpp_lib_make_unique should have the value 201304L in c++14" -# endif +# ifdef __cpp_lib_adaptor_iterator_pair_constructor +# error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++23" +# endif + +# ifndef __cpp_lib_addressof_constexpr +# error "__cpp_lib_addressof_constexpr should be defined in c++17" +# endif +# if __cpp_lib_addressof_constexpr != 201603L +# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++17" +# endif + +# ifdef __cpp_lib_allocate_at_least +# error "__cpp_lib_allocate_at_least should not be defined before c++23" +# endif + +# ifndef __cpp_lib_allocator_traits_is_always_equal +# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++17" +# endif +# if __cpp_lib_allocator_traits_is_always_equal != 201411L +# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17" +# endif + +# ifndef __cpp_lib_any +# error "__cpp_lib_any should be defined in c++17" +# endif +# if __cpp_lib_any != 201606L +# error "__cpp_lib_any should have the value 201606L in c++17" +# endif + +# ifndef __cpp_lib_apply +# error "__cpp_lib_apply should be defined in c++17" +# endif +# if __cpp_lib_apply != 201603L +# error "__cpp_lib_apply should have the value 201603L in c++17" +# endif + +# ifndef __cpp_lib_array_constexpr +# error "__cpp_lib_array_constexpr should be defined in c++17" +# endif +# if __cpp_lib_array_constexpr != 201603L +# error "__cpp_lib_array_constexpr should have the value 201603L in c++17" +# endif + +# ifndef __cpp_lib_as_const +# error "__cpp_lib_as_const should be defined in c++17" +# endif +# if __cpp_lib_as_const != 201510L +# error "__cpp_lib_as_const should have the value 201510L in c++17" +# endif + +# ifdef __cpp_lib_associative_heterogeneous_erasure +# error "__cpp_lib_associative_heterogeneous_erasure should not be defined before c++23" +# endif + +# ifdef __cpp_lib_associative_heterogeneous_insertion +# error "__cpp_lib_associative_heterogeneous_insertion should not be defined before c++26" +# endif + +# ifdef __cpp_lib_assume_aligned +# error "__cpp_lib_assume_aligned should not be defined before c++20" +# endif + +# ifdef __cpp_lib_atomic_flag_test +# error "__cpp_lib_atomic_flag_test should not be defined before c++20" +# endif + +# ifdef __cpp_lib_atomic_float +# error "__cpp_lib_atomic_float should not be defined before c++20" +# endif + +# ifndef __cpp_lib_atomic_is_always_lock_free +# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++17" +# endif +# if __cpp_lib_atomic_is_always_lock_free != 201603L +# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++17" +# endif + +# ifdef __cpp_lib_atomic_lock_free_type_aliases +# error "__cpp_lib_atomic_lock_free_type_aliases should not be defined before c++20" +# endif + +# ifdef __cpp_lib_atomic_min_max +# error "__cpp_lib_atomic_min_max should not be defined before c++26" +# endif + +# ifdef __cpp_lib_atomic_ref +# error "__cpp_lib_atomic_ref should not be defined before c++20" +# endif + +# ifdef __cpp_lib_atomic_shared_ptr +# error "__cpp_lib_atomic_shared_ptr should not be defined before c++20" +# endif + +# ifdef __cpp_lib_atomic_value_initialization +# error "__cpp_lib_atomic_value_initialization should not be defined before c++20" +# endif + +# ifdef __cpp_lib_atomic_wait +# error "__cpp_lib_atomic_wait should not be defined before c++20" +# endif + +# ifdef __cpp_lib_barrier +# error "__cpp_lib_barrier should not be defined before c++20" +# endif + +# ifdef __cpp_lib_bind_back +# error "__cpp_lib_bind_back should not be defined before c++23" +# endif + +# ifdef __cpp_lib_bind_front +# error "__cpp_lib_bind_front should not be defined before c++20" +# endif + +# ifdef __cpp_lib_bit_cast +# error "__cpp_lib_bit_cast should not be defined before c++20" +# endif + +# ifdef __cpp_lib_bitops +# error "__cpp_lib_bitops should not be defined before c++20" +# endif + +# ifdef __cpp_lib_bitset +# error "__cpp_lib_bitset should not be defined before c++26" +# endif + +# ifndef __cpp_lib_bool_constant +# error "__cpp_lib_bool_constant should be defined in c++17" +# endif +# if __cpp_lib_bool_constant != 201505L +# error "__cpp_lib_bool_constant should have the value 201505L in c++17" +# endif + +# ifdef __cpp_lib_bounded_array_traits +# error "__cpp_lib_bounded_array_traits should not be defined before c++20" +# endif + +# ifndef __cpp_lib_boyer_moore_searcher +# error "__cpp_lib_boyer_moore_searcher should be defined in c++17" +# endif +# if __cpp_lib_boyer_moore_searcher != 201603L +# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++17" +# endif + +# ifndef __cpp_lib_byte +# error "__cpp_lib_byte should be defined in c++17" +# endif +# if __cpp_lib_byte != 201603L +# error "__cpp_lib_byte should have the value 201603L in c++17" +# endif + +# ifdef __cpp_lib_byteswap +# error "__cpp_lib_byteswap should not be defined before c++23" +# endif + +# ifdef __cpp_lib_char8_t +# error "__cpp_lib_char8_t should not be defined before c++20" +# endif + +# ifndef __cpp_lib_chrono +# error "__cpp_lib_chrono should be defined in c++17" +# endif +# if __cpp_lib_chrono != 201611L +# error "__cpp_lib_chrono should have the value 201611L in c++17" +# endif + +# ifndef __cpp_lib_chrono_udls +# error "__cpp_lib_chrono_udls should be defined in c++17" +# endif +# if __cpp_lib_chrono_udls != 201304L +# error "__cpp_lib_chrono_udls should have the value 201304L in c++17" +# endif + +# ifndef __cpp_lib_clamp +# error "__cpp_lib_clamp should be defined in c++17" +# endif +# if __cpp_lib_clamp != 201603L +# error "__cpp_lib_clamp should have the value 201603L in c++17" +# endif + +# ifndef __cpp_lib_complex_udls +# error "__cpp_lib_complex_udls should be defined in c++17" +# endif +# if __cpp_lib_complex_udls != 201309L +# error "__cpp_lib_complex_udls should have the value 201309L in c++17" +# endif + +# ifdef __cpp_lib_concepts +# error "__cpp_lib_concepts should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_algorithms +# error "__cpp_lib_constexpr_algorithms should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_bitset +# error "__cpp_lib_constexpr_bitset should not be defined before c++23" +# endif + +# ifdef __cpp_lib_constexpr_charconv +# error "__cpp_lib_constexpr_charconv should not be defined before c++23" +# endif + +# ifdef __cpp_lib_constexpr_cmath +# error "__cpp_lib_constexpr_cmath should not be defined before c++23" +# endif + +# ifdef __cpp_lib_constexpr_complex +# error "__cpp_lib_constexpr_complex should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_dynamic_alloc +# error "__cpp_lib_constexpr_dynamic_alloc should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_functional +# error "__cpp_lib_constexpr_functional should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_iterator +# error "__cpp_lib_constexpr_iterator should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_memory +# error "__cpp_lib_constexpr_memory should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_new +# error "__cpp_lib_constexpr_new should not be defined before c++26" +# endif + +# ifdef __cpp_lib_constexpr_numeric +# error "__cpp_lib_constexpr_numeric should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_string +# error "__cpp_lib_constexpr_string should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_string_view +# error "__cpp_lib_constexpr_string_view should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_tuple +# error "__cpp_lib_constexpr_tuple should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_typeinfo +# error "__cpp_lib_constexpr_typeinfo should not be defined before c++23" +# endif + +# ifdef __cpp_lib_constexpr_utility +# error "__cpp_lib_constexpr_utility should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_vector +# error "__cpp_lib_constexpr_vector should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constrained_equality +# error "__cpp_lib_constrained_equality should not be defined before c++26" +# endif + +# ifdef __cpp_lib_containers_ranges +# error "__cpp_lib_containers_ranges should not be defined before c++23" +# endif + +# ifdef __cpp_lib_copyable_function +# error "__cpp_lib_copyable_function should not be defined before c++26" +# endif + +# ifdef __cpp_lib_coroutine +# error "__cpp_lib_coroutine should not be defined before c++20" +# endif + +# ifdef __cpp_lib_debugging +# error "__cpp_lib_debugging should not be defined before c++26" +# endif + +# ifdef __cpp_lib_default_template_type_for_algorithm_values +# error "__cpp_lib_default_template_type_for_algorithm_values should not be defined before c++26" +# endif + +# ifdef __cpp_lib_destroying_delete +# error "__cpp_lib_destroying_delete should not be defined before c++20" +# endif + +# ifndef __cpp_lib_enable_shared_from_this +# error "__cpp_lib_enable_shared_from_this should be defined in c++17" +# endif +# if __cpp_lib_enable_shared_from_this != 201603L +# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++17" +# endif + +# ifdef __cpp_lib_endian +# error "__cpp_lib_endian should not be defined before c++20" +# endif + +# ifdef __cpp_lib_erase_if +# error "__cpp_lib_erase_if should not be defined before c++20" +# endif + +# ifndef __cpp_lib_exchange_function +# error "__cpp_lib_exchange_function should be defined in c++17" +# endif +# if __cpp_lib_exchange_function != 201304L +# error "__cpp_lib_exchange_function should have the value 201304L in c++17" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_execution +# error "__cpp_lib_execution should be defined in c++17" +# endif +# if __cpp_lib_execution != 201603L +# error "__cpp_lib_execution should have the value 201603L in c++17" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_execution +# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_expected +# error "__cpp_lib_expected should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY) +# ifndef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should be defined in c++17" +# endif +# if __cpp_lib_filesystem != 201703L +# error "__cpp_lib_filesystem should have the value 201703L in c++17" +# endif +# else +# ifdef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)' is not met!" +# endif +# endif + +# ifdef __cpp_lib_flat_map +# error "__cpp_lib_flat_map should not be defined before c++23" +# endif + +# ifdef __cpp_lib_flat_set +# error "__cpp_lib_flat_set should not be defined before c++23" +# endif + +# ifdef __cpp_lib_format +# error "__cpp_lib_format should not be defined before c++20" +# endif + +# ifdef __cpp_lib_format_path +# error "__cpp_lib_format_path should not be defined before c++26" +# endif + +# ifdef __cpp_lib_format_ranges +# error "__cpp_lib_format_ranges should not be defined before c++23" +# endif + +# ifdef __cpp_lib_format_uchar +# error "__cpp_lib_format_uchar should not be defined before c++20" +# endif + +# ifdef __cpp_lib_formatters +# error "__cpp_lib_formatters should not be defined before c++23" +# endif + +# ifdef __cpp_lib_forward_like +# error "__cpp_lib_forward_like should not be defined before c++23" +# endif + +# ifdef __cpp_lib_freestanding_algorithm +# error "__cpp_lib_freestanding_algorithm should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_array +# error "__cpp_lib_freestanding_array should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_cstring +# error "__cpp_lib_freestanding_cstring should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_expected +# error "__cpp_lib_freestanding_expected should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_mdspan +# error "__cpp_lib_freestanding_mdspan should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_optional +# error "__cpp_lib_freestanding_optional should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_string_view +# error "__cpp_lib_freestanding_string_view should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_variant +# error "__cpp_lib_freestanding_variant should not be defined before c++26" +# endif + +# ifdef __cpp_lib_fstream_native_handle +# error "__cpp_lib_fstream_native_handle should not be defined before c++26" +# endif + +# ifdef __cpp_lib_function_ref +# error "__cpp_lib_function_ref should not be defined before c++26" +# endif + +# ifndef __cpp_lib_gcd_lcm +# error "__cpp_lib_gcd_lcm should be defined in c++17" +# endif +# if __cpp_lib_gcd_lcm != 201606L +# error "__cpp_lib_gcd_lcm should have the value 201606L in c++17" +# endif + +# ifdef __cpp_lib_generate_random +# error "__cpp_lib_generate_random should not be defined before c++26" +# endif + +# ifndef __cpp_lib_generic_associative_lookup +# error "__cpp_lib_generic_associative_lookup should be defined in c++17" +# endif +# if __cpp_lib_generic_associative_lookup != 201304L +# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++17" +# endif + +# ifdef __cpp_lib_generic_unordered_lookup +# error "__cpp_lib_generic_unordered_lookup should not be defined before c++20" +# endif + +# if !defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)) +# ifndef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should be defined in c++17" +# endif +# if __cpp_lib_hardware_interference_size != 201703L +# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++17" +# endif +# else +# ifdef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))' is not met!" +# endif +# endif + +# ifndef __cpp_lib_has_unique_object_representations +# error "__cpp_lib_has_unique_object_representations should be defined in c++17" +# endif +# if __cpp_lib_has_unique_object_representations != 201606L +# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++17" +# endif + +# ifdef __cpp_lib_hazard_pointer +# error "__cpp_lib_hazard_pointer should not be defined before c++26" +# endif + +# ifndef __cpp_lib_hypot +# error "__cpp_lib_hypot should be defined in c++17" +# endif +# if __cpp_lib_hypot != 201603L +# error "__cpp_lib_hypot should have the value 201603L in c++17" +# endif + +# ifndef __cpp_lib_incomplete_container_elements +# error "__cpp_lib_incomplete_container_elements should be defined in c++17" +# endif +# if __cpp_lib_incomplete_container_elements != 201505L +# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++17" +# endif + +# ifdef __cpp_lib_inplace_vector +# error "__cpp_lib_inplace_vector should not be defined before c++26" +# endif + +# ifdef __cpp_lib_int_pow2 +# error "__cpp_lib_int_pow2 should not be defined before c++20" +# endif + +# ifdef __cpp_lib_integer_comparison_functions +# error "__cpp_lib_integer_comparison_functions should not be defined before c++20" +# endif + +# ifndef __cpp_lib_integer_sequence +# error "__cpp_lib_integer_sequence should be defined in c++17" +# endif +# if __cpp_lib_integer_sequence != 201304L +# error "__cpp_lib_integer_sequence should have the value 201304L in c++17" +# endif + +# ifndef __cpp_lib_integral_constant_callable +# error "__cpp_lib_integral_constant_callable should be defined in c++17" +# endif +# if __cpp_lib_integral_constant_callable != 201304L +# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++17" +# endif + +# ifdef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should not be defined before c++20" +# endif + +# ifndef __cpp_lib_invoke +# error "__cpp_lib_invoke should be defined in c++17" +# endif +# if __cpp_lib_invoke != 201411L +# error "__cpp_lib_invoke should have the value 201411L in c++17" +# endif + +# ifdef __cpp_lib_invoke_r +# error "__cpp_lib_invoke_r should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ios_noreplace +# error "__cpp_lib_ios_noreplace should not be defined before c++23" +# endif + +# ifndef __cpp_lib_is_aggregate +# error "__cpp_lib_is_aggregate should be defined in c++17" +# endif +# if __cpp_lib_is_aggregate != 201703L +# error "__cpp_lib_is_aggregate should have the value 201703L in c++17" +# endif + +# ifdef __cpp_lib_is_constant_evaluated +# error "__cpp_lib_is_constant_evaluated should not be defined before c++20" +# endif + +# ifndef __cpp_lib_is_final +# error "__cpp_lib_is_final should be defined in c++17" +# endif +# if __cpp_lib_is_final != 201402L +# error "__cpp_lib_is_final should have the value 201402L in c++17" +# endif + +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" +# endif + +# ifndef __cpp_lib_is_invocable +# error "__cpp_lib_is_invocable should be defined in c++17" +# endif +# if __cpp_lib_is_invocable != 201703L +# error "__cpp_lib_is_invocable should have the value 201703L in c++17" +# endif + +# ifdef __cpp_lib_is_layout_compatible +# error "__cpp_lib_is_layout_compatible should not be defined before c++20" +# endif + +# ifdef __cpp_lib_is_nothrow_convertible +# error "__cpp_lib_is_nothrow_convertible should not be defined before c++20" +# endif + +# ifndef __cpp_lib_is_null_pointer +# error "__cpp_lib_is_null_pointer should be defined in c++17" +# endif +# if __cpp_lib_is_null_pointer != 201309L +# error "__cpp_lib_is_null_pointer should have the value 201309L in c++17" +# endif + +# ifdef __cpp_lib_is_pointer_interconvertible +# error "__cpp_lib_is_pointer_interconvertible should not be defined before c++20" +# endif + +# ifdef __cpp_lib_is_scoped_enum +# error "__cpp_lib_is_scoped_enum should not be defined before c++23" +# endif + +# ifndef __cpp_lib_is_swappable +# error "__cpp_lib_is_swappable should be defined in c++17" +# endif +# if __cpp_lib_is_swappable != 201603L +# error "__cpp_lib_is_swappable should have the value 201603L in c++17" +# endif + +# ifdef __cpp_lib_is_virtual_base_of +# error "__cpp_lib_is_virtual_base_of should not be defined before c++26" +# endif + +# ifdef __cpp_lib_is_within_lifetime +# error "__cpp_lib_is_within_lifetime should not be defined before c++26" +# endif + +# ifdef __cpp_lib_jthread +# error "__cpp_lib_jthread should not be defined before c++20" +# endif + +# ifdef __cpp_lib_latch +# error "__cpp_lib_latch should not be defined before c++20" +# endif + +# ifndef __cpp_lib_launder +# error "__cpp_lib_launder should be defined in c++17" +# endif +# if __cpp_lib_launder != 201606L +# error "__cpp_lib_launder should have the value 201606L in c++17" +# endif + +# ifdef __cpp_lib_linalg +# error "__cpp_lib_linalg should not be defined before c++26" +# endif + +# ifdef __cpp_lib_list_remove_return_type +# error "__cpp_lib_list_remove_return_type should not be defined before c++20" +# endif + +# ifndef __cpp_lib_logical_traits +# error "__cpp_lib_logical_traits should be defined in c++17" +# endif +# if __cpp_lib_logical_traits != 201510L +# error "__cpp_lib_logical_traits should have the value 201510L in c++17" +# endif + +# ifndef __cpp_lib_make_from_tuple +# error "__cpp_lib_make_from_tuple should be defined in c++17" +# endif +# if __cpp_lib_make_from_tuple != 201606L +# error "__cpp_lib_make_from_tuple should have the value 201606L in c++17" +# endif + +# ifndef __cpp_lib_make_reverse_iterator +# error "__cpp_lib_make_reverse_iterator should be defined in c++17" +# endif +# if __cpp_lib_make_reverse_iterator != 201402L +# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++17" +# endif + +# ifndef __cpp_lib_make_unique +# error "__cpp_lib_make_unique should be defined in c++17" +# endif +# if __cpp_lib_make_unique != 201304L +# error "__cpp_lib_make_unique should have the value 201304L in c++17" +# endif + +# ifndef __cpp_lib_map_try_emplace +# error "__cpp_lib_map_try_emplace should be defined in c++17" +# endif +# if __cpp_lib_map_try_emplace != 201411L +# error "__cpp_lib_map_try_emplace should have the value 201411L in c++17" +# endif + +# ifdef __cpp_lib_math_constants +# error "__cpp_lib_math_constants should not be defined before c++20" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should be defined in c++17" +# endif +# if __cpp_lib_math_special_functions != 201603L +# error "__cpp_lib_math_special_functions should have the value 201603L in c++17" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_mdspan +# error "__cpp_lib_mdspan should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR +# ifndef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should be defined in c++17" +# endif +# if __cpp_lib_memory_resource != 201603L +# error "__cpp_lib_memory_resource should have the value 201603L in c++17" +# endif +# else +# ifdef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" +# endif +# endif + +# ifdef __cpp_lib_modules +# error "__cpp_lib_modules should not be defined before c++23" +# endif + +# ifdef __cpp_lib_move_iterator_concept +# error "__cpp_lib_move_iterator_concept should not be defined before c++20" +# endif + +# ifdef __cpp_lib_move_only_function +# error "__cpp_lib_move_only_function should not be defined before c++23" +# endif + +# ifndef __cpp_lib_node_extract +# error "__cpp_lib_node_extract should be defined in c++17" +# endif +# if __cpp_lib_node_extract != 201606L +# error "__cpp_lib_node_extract should have the value 201606L in c++17" +# endif + +# ifndef __cpp_lib_nonmember_container_access +# error "__cpp_lib_nonmember_container_access should be defined in c++17" +# endif +# if __cpp_lib_nonmember_container_access != 201411L +# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++17" +# endif + +# ifndef __cpp_lib_not_fn +# error "__cpp_lib_not_fn should be defined in c++17" +# endif +# if __cpp_lib_not_fn != 201603L +# error "__cpp_lib_not_fn should have the value 201603L in c++17" +# endif + +# ifndef __cpp_lib_null_iterators +# error "__cpp_lib_null_iterators should be defined in c++17" +# endif +# if __cpp_lib_null_iterators != 201304L +# error "__cpp_lib_null_iterators should have the value 201304L in c++17" +# endif + +# ifndef __cpp_lib_optional +# error "__cpp_lib_optional should be defined in c++17" +# endif +# if __cpp_lib_optional != 201606L +# error "__cpp_lib_optional should have the value 201606L in c++17" +# endif + +# ifdef __cpp_lib_optional_range_support +# error "__cpp_lib_optional_range_support should not be defined before c++26" +# endif + +# ifdef __cpp_lib_out_ptr +# error "__cpp_lib_out_ptr should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should be defined in c++17" +# endif +# if __cpp_lib_parallel_algorithm != 201603L +# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++17" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_philox_engine +# error "__cpp_lib_philox_engine should not be defined before c++26" +# endif + +# ifdef __cpp_lib_polymorphic_allocator +# error "__cpp_lib_polymorphic_allocator should not be defined before c++20" +# endif + +# ifdef __cpp_lib_print +# error "__cpp_lib_print should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION +# ifndef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should be defined in c++17" +# endif +# if __cpp_lib_quoted_string_io != 201304L +# error "__cpp_lib_quoted_string_io should have the value 201304L in c++17" +# endif +# else +# ifdef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" +# endif +# endif + +# ifdef __cpp_lib_ranges +# error "__cpp_lib_ranges should not be defined before c++20" +# endif + +# ifdef __cpp_lib_ranges_as_const +# error "__cpp_lib_ranges_as_const should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_as_rvalue +# error "__cpp_lib_ranges_as_rvalue should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_chunk_by +# error "__cpp_lib_ranges_chunk_by should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_concat +# error "__cpp_lib_ranges_concat should not be defined before c++26" +# endif + +# ifdef __cpp_lib_ranges_contains +# error "__cpp_lib_ranges_contains should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_find_last +# error "__cpp_lib_ranges_find_last should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_iota +# error "__cpp_lib_ranges_iota should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_join_with +# error "__cpp_lib_ranges_join_with should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_repeat +# error "__cpp_lib_ranges_repeat should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_slide +# error "__cpp_lib_ranges_slide should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_starts_ends_with +# error "__cpp_lib_ranges_starts_ends_with should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_zip +# error "__cpp_lib_ranges_zip should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ratio +# error "__cpp_lib_ratio should not be defined before c++26" +# endif + +# ifndef __cpp_lib_raw_memory_algorithms +# error "__cpp_lib_raw_memory_algorithms should be defined in c++17" +# endif +# if __cpp_lib_raw_memory_algorithms != 201606L +# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++17" +# endif + +# ifdef __cpp_lib_rcu +# error "__cpp_lib_rcu should not be defined before c++26" +# endif + +# ifdef __cpp_lib_reference_from_temporary +# error "__cpp_lib_reference_from_temporary should not be defined before c++23" +# endif + +# ifdef __cpp_lib_reference_wrapper +# error "__cpp_lib_reference_wrapper should not be defined before c++26" +# endif + +# ifdef __cpp_lib_remove_cvref +# error "__cpp_lib_remove_cvref should not be defined before c++20" +# endif + +# ifndef __cpp_lib_result_of_sfinae +# error "__cpp_lib_result_of_sfinae should be defined in c++17" +# endif +# if __cpp_lib_result_of_sfinae != 201210L +# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++17" +# endif + +# ifndef __cpp_lib_robust_nonmodifying_seq_ops +# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++17" +# endif +# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L +# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++17" +# endif + +# ifndef __cpp_lib_sample +# error "__cpp_lib_sample should be defined in c++17" +# endif +# if __cpp_lib_sample != 201603L +# error "__cpp_lib_sample should have the value 201603L in c++17" +# endif + +# ifdef __cpp_lib_saturation_arithmetic +# error "__cpp_lib_saturation_arithmetic should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should be defined in c++17" +# endif +# if __cpp_lib_scoped_lock != 201703L +# error "__cpp_lib_scoped_lock should have the value 201703L in c++17" +# endif +# else +# ifdef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifdef __cpp_lib_semaphore +# error "__cpp_lib_semaphore should not be defined before c++20" +# endif + +# ifdef __cpp_lib_senders +# error "__cpp_lib_senders should not be defined before c++26" +# endif + +# if _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should be defined in c++17" +# endif +# if __cpp_lib_shared_mutex != 201505L +# error "__cpp_lib_shared_mutex should have the value 201505L in c++17" +# endif +# else +# ifdef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifndef __cpp_lib_shared_ptr_arrays +# error "__cpp_lib_shared_ptr_arrays should be defined in c++17" +# endif +# if __cpp_lib_shared_ptr_arrays != 201611L +# error "__cpp_lib_shared_ptr_arrays should have the value 201611L in c++17" +# endif + +# ifndef __cpp_lib_shared_ptr_weak_type +# error "__cpp_lib_shared_ptr_weak_type should be defined in c++17" +# endif +# if __cpp_lib_shared_ptr_weak_type != 201606L +# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++17" +# endif + +# if _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should be defined in c++17" +# endif +# if __cpp_lib_shared_timed_mutex != 201402L +# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++17" +# endif +# else +# ifdef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifdef __cpp_lib_shift +# error "__cpp_lib_shift should not be defined before c++20" +# endif + +# ifdef __cpp_lib_smart_ptr_for_overwrite +# error "__cpp_lib_smart_ptr_for_overwrite should not be defined before c++20" +# endif + +# ifdef __cpp_lib_smart_ptr_owner_equality +# error "__cpp_lib_smart_ptr_owner_equality should not be defined before c++26" +# endif + +# ifdef __cpp_lib_source_location +# error "__cpp_lib_source_location should not be defined before c++20" +# endif + +# ifdef __cpp_lib_span +# error "__cpp_lib_span should not be defined before c++20" +# endif + +# ifdef __cpp_lib_span_at +# error "__cpp_lib_span_at should not be defined before c++26" +# endif + +# ifdef __cpp_lib_span_initializer_list +# error "__cpp_lib_span_initializer_list should not be defined before c++26" +# endif + +# ifdef __cpp_lib_spanstream +# error "__cpp_lib_spanstream should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ssize +# error "__cpp_lib_ssize should not be defined before c++20" +# endif + +# ifdef __cpp_lib_sstream_from_string_view +# error "__cpp_lib_sstream_from_string_view should not be defined before c++26" +# endif + +# ifdef __cpp_lib_stacktrace +# error "__cpp_lib_stacktrace should not be defined before c++23" +# endif + +# ifdef __cpp_lib_starts_ends_with +# error "__cpp_lib_starts_ends_with should not be defined before c++20" +# endif + +# ifdef __cpp_lib_stdatomic_h +# error "__cpp_lib_stdatomic_h should not be defined before c++23" +# endif + +# ifdef __cpp_lib_string_contains +# error "__cpp_lib_string_contains should not be defined before c++23" +# endif + +# ifdef __cpp_lib_string_resize_and_overwrite +# error "__cpp_lib_string_resize_and_overwrite should not be defined before c++23" +# endif + +# ifndef __cpp_lib_string_udls +# error "__cpp_lib_string_udls should be defined in c++17" +# endif +# if __cpp_lib_string_udls != 201304L +# error "__cpp_lib_string_udls should have the value 201304L in c++17" +# endif + +# ifndef __cpp_lib_string_view +# error "__cpp_lib_string_view should be defined in c++17" +# endif +# if __cpp_lib_string_view != 201606L +# error "__cpp_lib_string_view should have the value 201606L in c++17" +# endif + +# ifdef __cpp_lib_submdspan +# error "__cpp_lib_submdspan should not be defined before c++26" +# endif + +# ifdef __cpp_lib_syncbuf +# error "__cpp_lib_syncbuf should not be defined before c++20" +# endif + +# ifdef __cpp_lib_text_encoding +# error "__cpp_lib_text_encoding should not be defined before c++26" +# endif + +# ifdef __cpp_lib_three_way_comparison +# error "__cpp_lib_three_way_comparison should not be defined before c++20" +# endif + +# ifdef __cpp_lib_to_address +# error "__cpp_lib_to_address should not be defined before c++20" +# endif + +# ifdef __cpp_lib_to_array +# error "__cpp_lib_to_array should not be defined before c++20" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should be defined in c++17" +# endif +# if __cpp_lib_to_chars != 201611L +# error "__cpp_lib_to_chars should have the value 201611L in c++17" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_to_string +# error "__cpp_lib_to_string should not be defined before c++26" +# endif + +# ifdef __cpp_lib_to_underlying +# error "__cpp_lib_to_underlying should not be defined before c++23" +# endif + +# ifndef __cpp_lib_transformation_trait_aliases +# error "__cpp_lib_transformation_trait_aliases should be defined in c++17" +# endif +# if __cpp_lib_transformation_trait_aliases != 201304L +# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++17" +# endif + +# ifndef __cpp_lib_transparent_operators +# error "__cpp_lib_transparent_operators should be defined in c++17" +# endif +# if __cpp_lib_transparent_operators != 201510L +# error "__cpp_lib_transparent_operators should have the value 201510L in c++17" +# endif + +# ifndef __cpp_lib_tuple_element_t +# error "__cpp_lib_tuple_element_t should be defined in c++17" +# endif +# if __cpp_lib_tuple_element_t != 201402L +# error "__cpp_lib_tuple_element_t should have the value 201402L in c++17" +# endif + +# ifdef __cpp_lib_tuple_like +# error "__cpp_lib_tuple_like should not be defined before c++23" +# endif + +# ifndef __cpp_lib_tuples_by_type +# error "__cpp_lib_tuples_by_type should be defined in c++17" +# endif +# if __cpp_lib_tuples_by_type != 201304L +# error "__cpp_lib_tuples_by_type should have the value 201304L in c++17" +# endif + +# ifdef __cpp_lib_type_identity +# error "__cpp_lib_type_identity should not be defined before c++20" +# endif + +# ifndef __cpp_lib_type_trait_variable_templates +# error "__cpp_lib_type_trait_variable_templates should be defined in c++17" +# endif +# if __cpp_lib_type_trait_variable_templates != 201510L +# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++17" +# endif + +# ifndef __cpp_lib_uncaught_exceptions +# error "__cpp_lib_uncaught_exceptions should be defined in c++17" +# endif +# if __cpp_lib_uncaught_exceptions != 201411L +# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++17" +# endif + +# ifndef __cpp_lib_unordered_map_try_emplace +# error "__cpp_lib_unordered_map_try_emplace should be defined in c++17" +# endif +# if __cpp_lib_unordered_map_try_emplace != 201411L +# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++17" +# endif + +# ifdef __cpp_lib_unreachable +# error "__cpp_lib_unreachable should not be defined before c++23" +# endif + +# ifdef __cpp_lib_unwrap_ref +# error "__cpp_lib_unwrap_ref should not be defined before c++20" +# endif + +# ifndef __cpp_lib_variant +# error "__cpp_lib_variant should be defined in c++17" +# endif +# if __cpp_lib_variant != 202102L +# error "__cpp_lib_variant should have the value 202102L in c++17" +# endif + +# ifndef __cpp_lib_void_t +# error "__cpp_lib_void_t should be defined in c++17" +# endif +# if __cpp_lib_void_t != 201411L +# error "__cpp_lib_void_t should have the value 201411L in c++17" +# endif -# ifdef __cpp_lib_map_try_emplace -# error "__cpp_lib_map_try_emplace should not be defined before c++17" -# endif +#elif TEST_STD_VER == 20 -# ifdef __cpp_lib_math_constants -# error "__cpp_lib_math_constants should not be defined before c++20" -# endif +# ifdef __cpp_lib_adaptor_iterator_pair_constructor +# error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++23" +# endif + +# ifndef __cpp_lib_addressof_constexpr +# error "__cpp_lib_addressof_constexpr should be defined in c++20" +# endif +# if __cpp_lib_addressof_constexpr != 201603L +# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++20" +# endif + +# ifdef __cpp_lib_allocate_at_least +# error "__cpp_lib_allocate_at_least should not be defined before c++23" +# endif + +# ifndef __cpp_lib_allocator_traits_is_always_equal +# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++20" +# endif +# if __cpp_lib_allocator_traits_is_always_equal != 201411L +# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++20" +# endif + +# ifndef __cpp_lib_any +# error "__cpp_lib_any should be defined in c++20" +# endif +# if __cpp_lib_any != 201606L +# error "__cpp_lib_any should have the value 201606L in c++20" +# endif + +# ifndef __cpp_lib_apply +# error "__cpp_lib_apply should be defined in c++20" +# endif +# if __cpp_lib_apply != 201603L +# error "__cpp_lib_apply should have the value 201603L in c++20" +# endif + +# ifndef __cpp_lib_array_constexpr +# error "__cpp_lib_array_constexpr should be defined in c++20" +# endif +# if __cpp_lib_array_constexpr != 201811L +# error "__cpp_lib_array_constexpr should have the value 201811L in c++20" +# endif + +# ifndef __cpp_lib_as_const +# error "__cpp_lib_as_const should be defined in c++20" +# endif +# if __cpp_lib_as_const != 201510L +# error "__cpp_lib_as_const should have the value 201510L in c++20" +# endif + +# ifdef __cpp_lib_associative_heterogeneous_erasure +# error "__cpp_lib_associative_heterogeneous_erasure should not be defined before c++23" +# endif + +# ifdef __cpp_lib_associative_heterogeneous_insertion +# error "__cpp_lib_associative_heterogeneous_insertion should not be defined before c++26" +# endif + +# ifndef __cpp_lib_assume_aligned +# error "__cpp_lib_assume_aligned should be defined in c++20" +# endif +# if __cpp_lib_assume_aligned != 201811L +# error "__cpp_lib_assume_aligned should have the value 201811L in c++20" +# endif + +# ifndef __cpp_lib_atomic_flag_test +# error "__cpp_lib_atomic_flag_test should be defined in c++20" +# endif +# if __cpp_lib_atomic_flag_test != 201907L +# error "__cpp_lib_atomic_flag_test should have the value 201907L in c++20" +# endif + +# ifndef __cpp_lib_atomic_float +# error "__cpp_lib_atomic_float should be defined in c++20" +# endif +# if __cpp_lib_atomic_float != 201711L +# error "__cpp_lib_atomic_float should have the value 201711L in c++20" +# endif + +# ifndef __cpp_lib_atomic_is_always_lock_free +# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++20" +# endif +# if __cpp_lib_atomic_is_always_lock_free != 201603L +# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++20" +# endif + +# ifndef __cpp_lib_atomic_lock_free_type_aliases +# error "__cpp_lib_atomic_lock_free_type_aliases should be defined in c++20" +# endif +# if __cpp_lib_atomic_lock_free_type_aliases != 201907L +# error "__cpp_lib_atomic_lock_free_type_aliases should have the value 201907L in c++20" +# endif + +# ifdef __cpp_lib_atomic_min_max +# error "__cpp_lib_atomic_min_max should not be defined before c++26" +# endif + +# ifndef __cpp_lib_atomic_ref +# error "__cpp_lib_atomic_ref should be defined in c++20" +# endif +# if __cpp_lib_atomic_ref != 201806L +# error "__cpp_lib_atomic_ref should have the value 201806L in c++20" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_atomic_shared_ptr +# error "__cpp_lib_atomic_shared_ptr should be defined in c++20" +# endif +# if __cpp_lib_atomic_shared_ptr != 201711L +# error "__cpp_lib_atomic_shared_ptr should have the value 201711L in c++20" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_atomic_shared_ptr +# error "__cpp_lib_atomic_shared_ptr should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_atomic_value_initialization +# error "__cpp_lib_atomic_value_initialization should be defined in c++20" +# endif +# if __cpp_lib_atomic_value_initialization != 201911L +# error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++20" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC +# ifndef __cpp_lib_atomic_wait +# error "__cpp_lib_atomic_wait should be defined in c++20" +# endif +# if __cpp_lib_atomic_wait != 201907L +# error "__cpp_lib_atomic_wait should have the value 201907L in c++20" +# endif +# else +# ifdef __cpp_lib_atomic_wait +# error "__cpp_lib_atomic_wait should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_barrier +# error "__cpp_lib_barrier should be defined in c++20" +# endif +# if __cpp_lib_barrier != 201907L +# error "__cpp_lib_barrier should have the value 201907L in c++20" +# endif +# else +# ifdef __cpp_lib_barrier +# error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# ifdef __cpp_lib_bind_back +# error "__cpp_lib_bind_back should not be defined before c++23" +# endif + +# ifndef __cpp_lib_bind_front +# error "__cpp_lib_bind_front should be defined in c++20" +# endif +# if __cpp_lib_bind_front != 201907L +# error "__cpp_lib_bind_front should have the value 201907L in c++20" +# endif + +# ifndef __cpp_lib_bit_cast +# error "__cpp_lib_bit_cast should be defined in c++20" +# endif +# if __cpp_lib_bit_cast != 201806L +# error "__cpp_lib_bit_cast should have the value 201806L in c++20" +# endif + +# ifndef __cpp_lib_bitops +# error "__cpp_lib_bitops should be defined in c++20" +# endif +# if __cpp_lib_bitops != 201907L +# error "__cpp_lib_bitops should have the value 201907L in c++20" +# endif + +# ifdef __cpp_lib_bitset +# error "__cpp_lib_bitset should not be defined before c++26" +# endif + +# ifndef __cpp_lib_bool_constant +# error "__cpp_lib_bool_constant should be defined in c++20" +# endif +# if __cpp_lib_bool_constant != 201505L +# error "__cpp_lib_bool_constant should have the value 201505L in c++20" +# endif + +# ifndef __cpp_lib_bounded_array_traits +# error "__cpp_lib_bounded_array_traits should be defined in c++20" +# endif +# if __cpp_lib_bounded_array_traits != 201902L +# error "__cpp_lib_bounded_array_traits should have the value 201902L in c++20" +# endif + +# ifndef __cpp_lib_boyer_moore_searcher +# error "__cpp_lib_boyer_moore_searcher should be defined in c++20" +# endif +# if __cpp_lib_boyer_moore_searcher != 201603L +# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++20" +# endif + +# ifndef __cpp_lib_byte +# error "__cpp_lib_byte should be defined in c++20" +# endif +# if __cpp_lib_byte != 201603L +# error "__cpp_lib_byte should have the value 201603L in c++20" +# endif + +# ifdef __cpp_lib_byteswap +# error "__cpp_lib_byteswap should not be defined before c++23" +# endif + +# if defined(__cpp_char8_t) +# ifndef __cpp_lib_char8_t +# error "__cpp_lib_char8_t should be defined in c++20" +# endif +# if __cpp_lib_char8_t != 201907L +# error "__cpp_lib_char8_t should have the value 201907L in c++20" +# endif +# else +# ifdef __cpp_lib_char8_t +# error "__cpp_lib_char8_t should not be defined when the requirement 'defined(__cpp_char8_t)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_chrono +# error "__cpp_lib_chrono should be defined in c++20" +# endif +# if __cpp_lib_chrono != 201611L +# error "__cpp_lib_chrono should have the value 201611L in c++20" +# endif + +# ifndef __cpp_lib_chrono_udls +# error "__cpp_lib_chrono_udls should be defined in c++20" +# endif +# if __cpp_lib_chrono_udls != 201304L +# error "__cpp_lib_chrono_udls should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_clamp +# error "__cpp_lib_clamp should be defined in c++20" +# endif +# if __cpp_lib_clamp != 201603L +# error "__cpp_lib_clamp should have the value 201603L in c++20" +# endif + +# ifndef __cpp_lib_complex_udls +# error "__cpp_lib_complex_udls should be defined in c++20" +# endif +# if __cpp_lib_complex_udls != 201309L +# error "__cpp_lib_complex_udls should have the value 201309L in c++20" +# endif + +# ifndef __cpp_lib_concepts +# error "__cpp_lib_concepts should be defined in c++20" +# endif +# if __cpp_lib_concepts != 202002L +# error "__cpp_lib_concepts should have the value 202002L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_algorithms +# error "__cpp_lib_constexpr_algorithms should be defined in c++20" +# endif +# if __cpp_lib_constexpr_algorithms != 201806L +# error "__cpp_lib_constexpr_algorithms should have the value 201806L in c++20" +# endif + +# ifdef __cpp_lib_constexpr_bitset +# error "__cpp_lib_constexpr_bitset should not be defined before c++23" +# endif + +# ifdef __cpp_lib_constexpr_charconv +# error "__cpp_lib_constexpr_charconv should not be defined before c++23" +# endif + +# ifdef __cpp_lib_constexpr_cmath +# error "__cpp_lib_constexpr_cmath should not be defined before c++23" +# endif + +# ifndef __cpp_lib_constexpr_complex +# error "__cpp_lib_constexpr_complex should be defined in c++20" +# endif +# if __cpp_lib_constexpr_complex != 201711L +# error "__cpp_lib_constexpr_complex should have the value 201711L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_dynamic_alloc +# error "__cpp_lib_constexpr_dynamic_alloc should be defined in c++20" +# endif +# if __cpp_lib_constexpr_dynamic_alloc != 201907L +# error "__cpp_lib_constexpr_dynamic_alloc should have the value 201907L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_functional +# error "__cpp_lib_constexpr_functional should be defined in c++20" +# endif +# if __cpp_lib_constexpr_functional != 201907L +# error "__cpp_lib_constexpr_functional should have the value 201907L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_iterator +# error "__cpp_lib_constexpr_iterator should be defined in c++20" +# endif +# if __cpp_lib_constexpr_iterator != 201811L +# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_memory +# error "__cpp_lib_constexpr_memory should be defined in c++20" +# endif +# if __cpp_lib_constexpr_memory != 201811L +# error "__cpp_lib_constexpr_memory should have the value 201811L in c++20" +# endif + +# ifdef __cpp_lib_constexpr_new +# error "__cpp_lib_constexpr_new should not be defined before c++26" +# endif + +# ifndef __cpp_lib_constexpr_numeric +# error "__cpp_lib_constexpr_numeric should be defined in c++20" +# endif +# if __cpp_lib_constexpr_numeric != 201911L +# error "__cpp_lib_constexpr_numeric should have the value 201911L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_string +# error "__cpp_lib_constexpr_string should be defined in c++20" +# endif +# if __cpp_lib_constexpr_string != 201907L +# error "__cpp_lib_constexpr_string should have the value 201907L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_string_view +# error "__cpp_lib_constexpr_string_view should be defined in c++20" +# endif +# if __cpp_lib_constexpr_string_view != 201811L +# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_tuple +# error "__cpp_lib_constexpr_tuple should be defined in c++20" +# endif +# if __cpp_lib_constexpr_tuple != 201811L +# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++20" +# endif + +# ifdef __cpp_lib_constexpr_typeinfo +# error "__cpp_lib_constexpr_typeinfo should not be defined before c++23" +# endif + +# ifndef __cpp_lib_constexpr_utility +# error "__cpp_lib_constexpr_utility should be defined in c++20" +# endif +# if __cpp_lib_constexpr_utility != 201811L +# error "__cpp_lib_constexpr_utility should have the value 201811L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_vector +# error "__cpp_lib_constexpr_vector should be defined in c++20" +# endif +# if __cpp_lib_constexpr_vector != 201907L +# error "__cpp_lib_constexpr_vector should have the value 201907L in c++20" +# endif + +# ifdef __cpp_lib_constrained_equality +# error "__cpp_lib_constrained_equality should not be defined before c++26" +# endif + +# ifdef __cpp_lib_containers_ranges +# error "__cpp_lib_containers_ranges should not be defined before c++23" +# endif + +# ifdef __cpp_lib_copyable_function +# error "__cpp_lib_copyable_function should not be defined before c++26" +# endif + +# ifndef __cpp_lib_coroutine +# error "__cpp_lib_coroutine should be defined in c++20" +# endif +# if __cpp_lib_coroutine != 201902L +# error "__cpp_lib_coroutine should have the value 201902L in c++20" +# endif + +# ifdef __cpp_lib_debugging +# error "__cpp_lib_debugging should not be defined before c++26" +# endif + +# ifdef __cpp_lib_default_template_type_for_algorithm_values +# error "__cpp_lib_default_template_type_for_algorithm_values should not be defined before c++26" +# endif + +# if TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L +# ifndef __cpp_lib_destroying_delete +# error "__cpp_lib_destroying_delete should be defined in c++20" +# endif +# if __cpp_lib_destroying_delete != 201806L +# error "__cpp_lib_destroying_delete should have the value 201806L in c++20" +# endif +# else +# ifdef __cpp_lib_destroying_delete +# error "__cpp_lib_destroying_delete should not be defined when the requirement 'TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L' is not met!" +# endif +# endif + +# ifndef __cpp_lib_enable_shared_from_this +# error "__cpp_lib_enable_shared_from_this should be defined in c++20" +# endif +# if __cpp_lib_enable_shared_from_this != 201603L +# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++20" +# endif + +# ifndef __cpp_lib_endian +# error "__cpp_lib_endian should be defined in c++20" +# endif +# if __cpp_lib_endian != 201907L +# error "__cpp_lib_endian should have the value 201907L in c++20" +# endif + +# ifndef __cpp_lib_erase_if +# error "__cpp_lib_erase_if should be defined in c++20" +# endif +# if __cpp_lib_erase_if != 202002L +# error "__cpp_lib_erase_if should have the value 202002L in c++20" +# endif + +# ifndef __cpp_lib_exchange_function +# error "__cpp_lib_exchange_function should be defined in c++20" +# endif +# if __cpp_lib_exchange_function != 201304L +# error "__cpp_lib_exchange_function should have the value 201304L in c++20" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_execution +# error "__cpp_lib_execution should be defined in c++20" +# endif +# if __cpp_lib_execution != 201902L +# error "__cpp_lib_execution should have the value 201902L in c++20" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_execution +# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_expected +# error "__cpp_lib_expected should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY) +# ifndef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should be defined in c++20" +# endif +# if __cpp_lib_filesystem != 201703L +# error "__cpp_lib_filesystem should have the value 201703L in c++20" +# endif +# else +# ifdef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)' is not met!" +# endif +# endif + +# ifdef __cpp_lib_flat_map +# error "__cpp_lib_flat_map should not be defined before c++23" +# endif + +# ifdef __cpp_lib_flat_set +# error "__cpp_lib_flat_set should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT +# ifndef __cpp_lib_format +# error "__cpp_lib_format should be defined in c++20" +# endif +# if __cpp_lib_format != 202110L +# error "__cpp_lib_format should have the value 202110L in c++20" +# endif +# else +# ifdef __cpp_lib_format +# error "__cpp_lib_format should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" +# endif +# endif + +# ifdef __cpp_lib_format_path +# error "__cpp_lib_format_path should not be defined before c++26" +# endif + +# ifdef __cpp_lib_format_ranges +# error "__cpp_lib_format_ranges should not be defined before c++23" +# endif + +# ifndef __cpp_lib_format_uchar +# error "__cpp_lib_format_uchar should be defined in c++20" +# endif +# if __cpp_lib_format_uchar != 202311L +# error "__cpp_lib_format_uchar should have the value 202311L in c++20" +# endif + +# ifdef __cpp_lib_formatters +# error "__cpp_lib_formatters should not be defined before c++23" +# endif + +# ifdef __cpp_lib_forward_like +# error "__cpp_lib_forward_like should not be defined before c++23" +# endif + +# ifdef __cpp_lib_freestanding_algorithm +# error "__cpp_lib_freestanding_algorithm should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_array +# error "__cpp_lib_freestanding_array should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_cstring +# error "__cpp_lib_freestanding_cstring should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_expected +# error "__cpp_lib_freestanding_expected should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_mdspan +# error "__cpp_lib_freestanding_mdspan should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_optional +# error "__cpp_lib_freestanding_optional should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_string_view +# error "__cpp_lib_freestanding_string_view should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_variant +# error "__cpp_lib_freestanding_variant should not be defined before c++26" +# endif + +# ifdef __cpp_lib_fstream_native_handle +# error "__cpp_lib_fstream_native_handle should not be defined before c++26" +# endif + +# ifdef __cpp_lib_function_ref +# error "__cpp_lib_function_ref should not be defined before c++26" +# endif + +# ifndef __cpp_lib_gcd_lcm +# error "__cpp_lib_gcd_lcm should be defined in c++20" +# endif +# if __cpp_lib_gcd_lcm != 201606L +# error "__cpp_lib_gcd_lcm should have the value 201606L in c++20" +# endif + +# ifdef __cpp_lib_generate_random +# error "__cpp_lib_generate_random should not be defined before c++26" +# endif + +# ifndef __cpp_lib_generic_associative_lookup +# error "__cpp_lib_generic_associative_lookup should be defined in c++20" +# endif +# if __cpp_lib_generic_associative_lookup != 201304L +# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_generic_unordered_lookup +# error "__cpp_lib_generic_unordered_lookup should be defined in c++20" +# endif +# if __cpp_lib_generic_unordered_lookup != 201811L +# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++20" +# endif + +# if !defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)) +# ifndef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should be defined in c++20" +# endif +# if __cpp_lib_hardware_interference_size != 201703L +# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++20" +# endif +# else +# ifdef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))' is not met!" +# endif +# endif + +# ifndef __cpp_lib_has_unique_object_representations +# error "__cpp_lib_has_unique_object_representations should be defined in c++20" +# endif +# if __cpp_lib_has_unique_object_representations != 201606L +# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++20" +# endif + +# ifdef __cpp_lib_hazard_pointer +# error "__cpp_lib_hazard_pointer should not be defined before c++26" +# endif + +# ifndef __cpp_lib_hypot +# error "__cpp_lib_hypot should be defined in c++20" +# endif +# if __cpp_lib_hypot != 201603L +# error "__cpp_lib_hypot should have the value 201603L in c++20" +# endif + +# ifndef __cpp_lib_incomplete_container_elements +# error "__cpp_lib_incomplete_container_elements should be defined in c++20" +# endif +# if __cpp_lib_incomplete_container_elements != 201505L +# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++20" +# endif + +# ifdef __cpp_lib_inplace_vector +# error "__cpp_lib_inplace_vector should not be defined before c++26" +# endif + +# ifndef __cpp_lib_int_pow2 +# error "__cpp_lib_int_pow2 should be defined in c++20" +# endif +# if __cpp_lib_int_pow2 != 202002L +# error "__cpp_lib_int_pow2 should have the value 202002L in c++20" +# endif + +# ifndef __cpp_lib_integer_comparison_functions +# error "__cpp_lib_integer_comparison_functions should be defined in c++20" +# endif +# if __cpp_lib_integer_comparison_functions != 202002L +# error "__cpp_lib_integer_comparison_functions should have the value 202002L in c++20" +# endif + +# ifndef __cpp_lib_integer_sequence +# error "__cpp_lib_integer_sequence should be defined in c++20" +# endif +# if __cpp_lib_integer_sequence != 201304L +# error "__cpp_lib_integer_sequence should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_integral_constant_callable +# error "__cpp_lib_integral_constant_callable should be defined in c++20" +# endif +# if __cpp_lib_integral_constant_callable != 201304L +# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should be defined in c++20" +# endif +# if __cpp_lib_interpolate != 201902L +# error "__cpp_lib_interpolate should have the value 201902L in c++20" +# endif + +# ifndef __cpp_lib_invoke +# error "__cpp_lib_invoke should be defined in c++20" +# endif +# if __cpp_lib_invoke != 201411L +# error "__cpp_lib_invoke should have the value 201411L in c++20" +# endif + +# ifdef __cpp_lib_invoke_r +# error "__cpp_lib_invoke_r should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ios_noreplace +# error "__cpp_lib_ios_noreplace should not be defined before c++23" +# endif + +# ifndef __cpp_lib_is_aggregate +# error "__cpp_lib_is_aggregate should be defined in c++20" +# endif +# if __cpp_lib_is_aggregate != 201703L +# error "__cpp_lib_is_aggregate should have the value 201703L in c++20" +# endif + +# ifndef __cpp_lib_is_constant_evaluated +# error "__cpp_lib_is_constant_evaluated should be defined in c++20" +# endif +# if __cpp_lib_is_constant_evaluated != 201811L +# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++20" +# endif + +# ifndef __cpp_lib_is_final +# error "__cpp_lib_is_final should be defined in c++20" +# endif +# if __cpp_lib_is_final != 201402L +# error "__cpp_lib_is_final should have the value 201402L in c++20" +# endif + +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" +# endif + +# ifndef __cpp_lib_is_invocable +# error "__cpp_lib_is_invocable should be defined in c++20" +# endif +# if __cpp_lib_is_invocable != 201703L +# error "__cpp_lib_is_invocable should have the value 201703L in c++20" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_is_layout_compatible +# error "__cpp_lib_is_layout_compatible should be defined in c++20" +# endif +# if __cpp_lib_is_layout_compatible != 201907L +# error "__cpp_lib_is_layout_compatible should have the value 201907L in c++20" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_is_layout_compatible +# error "__cpp_lib_is_layout_compatible should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_is_nothrow_convertible +# error "__cpp_lib_is_nothrow_convertible should be defined in c++20" +# endif +# if __cpp_lib_is_nothrow_convertible != 201806L +# error "__cpp_lib_is_nothrow_convertible should have the value 201806L in c++20" +# endif + +# ifndef __cpp_lib_is_null_pointer +# error "__cpp_lib_is_null_pointer should be defined in c++20" +# endif +# if __cpp_lib_is_null_pointer != 201309L +# error "__cpp_lib_is_null_pointer should have the value 201309L in c++20" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_is_pointer_interconvertible +# error "__cpp_lib_is_pointer_interconvertible should be defined in c++20" +# endif +# if __cpp_lib_is_pointer_interconvertible != 201907L +# error "__cpp_lib_is_pointer_interconvertible should have the value 201907L in c++20" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_is_pointer_interconvertible +# error "__cpp_lib_is_pointer_interconvertible should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_is_scoped_enum +# error "__cpp_lib_is_scoped_enum should not be defined before c++23" +# endif + +# ifndef __cpp_lib_is_swappable +# error "__cpp_lib_is_swappable should be defined in c++20" +# endif +# if __cpp_lib_is_swappable != 201603L +# error "__cpp_lib_is_swappable should have the value 201603L in c++20" +# endif + +# ifdef __cpp_lib_is_virtual_base_of +# error "__cpp_lib_is_virtual_base_of should not be defined before c++26" +# endif + +# ifdef __cpp_lib_is_within_lifetime +# error "__cpp_lib_is_within_lifetime should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_jthread +# error "__cpp_lib_jthread should be defined in c++20" +# endif +# if __cpp_lib_jthread != 201911L +# error "__cpp_lib_jthread should have the value 201911L in c++20" +# endif +# else +# ifdef __cpp_lib_jthread +# error "__cpp_lib_jthread should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_latch +# error "__cpp_lib_latch should be defined in c++20" +# endif +# if __cpp_lib_latch != 201907L +# error "__cpp_lib_latch should have the value 201907L in c++20" +# endif +# else +# ifdef __cpp_lib_latch +# error "__cpp_lib_latch should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_launder +# error "__cpp_lib_launder should be defined in c++20" +# endif +# if __cpp_lib_launder != 201606L +# error "__cpp_lib_launder should have the value 201606L in c++20" +# endif + +# ifdef __cpp_lib_linalg +# error "__cpp_lib_linalg should not be defined before c++26" +# endif + +# ifndef __cpp_lib_list_remove_return_type +# error "__cpp_lib_list_remove_return_type should be defined in c++20" +# endif +# if __cpp_lib_list_remove_return_type != 201806L +# error "__cpp_lib_list_remove_return_type should have the value 201806L in c++20" +# endif + +# ifndef __cpp_lib_logical_traits +# error "__cpp_lib_logical_traits should be defined in c++20" +# endif +# if __cpp_lib_logical_traits != 201510L +# error "__cpp_lib_logical_traits should have the value 201510L in c++20" +# endif + +# ifndef __cpp_lib_make_from_tuple +# error "__cpp_lib_make_from_tuple should be defined in c++20" +# endif +# if __cpp_lib_make_from_tuple != 201606L +# error "__cpp_lib_make_from_tuple should have the value 201606L in c++20" +# endif + +# ifndef __cpp_lib_make_reverse_iterator +# error "__cpp_lib_make_reverse_iterator should be defined in c++20" +# endif +# if __cpp_lib_make_reverse_iterator != 201402L +# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++20" +# endif + +# ifndef __cpp_lib_make_unique +# error "__cpp_lib_make_unique should be defined in c++20" +# endif +# if __cpp_lib_make_unique != 201304L +# error "__cpp_lib_make_unique should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_map_try_emplace +# error "__cpp_lib_map_try_emplace should be defined in c++20" +# endif +# if __cpp_lib_map_try_emplace != 201411L +# error "__cpp_lib_map_try_emplace should have the value 201411L in c++20" +# endif + +# ifndef __cpp_lib_math_constants +# error "__cpp_lib_math_constants should be defined in c++20" +# endif +# if __cpp_lib_math_constants != 201907L +# error "__cpp_lib_math_constants should have the value 201907L in c++20" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should be defined in c++20" +# endif +# if __cpp_lib_math_special_functions != 201603L +# error "__cpp_lib_math_special_functions should have the value 201603L in c++20" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_mdspan +# error "__cpp_lib_mdspan should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR +# ifndef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should be defined in c++20" +# endif +# if __cpp_lib_memory_resource != 201603L +# error "__cpp_lib_memory_resource should have the value 201603L in c++20" +# endif +# else +# ifdef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" +# endif +# endif + +# ifdef __cpp_lib_modules +# error "__cpp_lib_modules should not be defined before c++23" +# endif + +# ifndef __cpp_lib_move_iterator_concept +# error "__cpp_lib_move_iterator_concept should be defined in c++20" +# endif +# if __cpp_lib_move_iterator_concept != 202207L +# error "__cpp_lib_move_iterator_concept should have the value 202207L in c++20" +# endif + +# ifdef __cpp_lib_move_only_function +# error "__cpp_lib_move_only_function should not be defined before c++23" +# endif + +# ifndef __cpp_lib_node_extract +# error "__cpp_lib_node_extract should be defined in c++20" +# endif +# if __cpp_lib_node_extract != 201606L +# error "__cpp_lib_node_extract should have the value 201606L in c++20" +# endif + +# ifndef __cpp_lib_nonmember_container_access +# error "__cpp_lib_nonmember_container_access should be defined in c++20" +# endif +# if __cpp_lib_nonmember_container_access != 201411L +# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++20" +# endif + +# ifndef __cpp_lib_not_fn +# error "__cpp_lib_not_fn should be defined in c++20" +# endif +# if __cpp_lib_not_fn != 201603L +# error "__cpp_lib_not_fn should have the value 201603L in c++20" +# endif + +# ifndef __cpp_lib_null_iterators +# error "__cpp_lib_null_iterators should be defined in c++20" +# endif +# if __cpp_lib_null_iterators != 201304L +# error "__cpp_lib_null_iterators should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_optional +# error "__cpp_lib_optional should be defined in c++20" +# endif +# if __cpp_lib_optional != 202106L +# error "__cpp_lib_optional should have the value 202106L in c++20" +# endif + +# ifdef __cpp_lib_optional_range_support +# error "__cpp_lib_optional_range_support should not be defined before c++26" +# endif + +# ifdef __cpp_lib_out_ptr +# error "__cpp_lib_out_ptr should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should be defined in c++20" +# endif +# if __cpp_lib_parallel_algorithm != 201603L +# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++20" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_philox_engine +# error "__cpp_lib_philox_engine should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR +# ifndef __cpp_lib_polymorphic_allocator +# error "__cpp_lib_polymorphic_allocator should be defined in c++20" +# endif +# if __cpp_lib_polymorphic_allocator != 201902L +# error "__cpp_lib_polymorphic_allocator should have the value 201902L in c++20" +# endif +# else +# ifdef __cpp_lib_polymorphic_allocator +# error "__cpp_lib_polymorphic_allocator should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" +# endif +# endif + +# ifdef __cpp_lib_print +# error "__cpp_lib_print should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION +# ifndef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should be defined in c++20" +# endif +# if __cpp_lib_quoted_string_io != 201304L +# error "__cpp_lib_quoted_string_io should have the value 201304L in c++20" +# endif +# else +# ifdef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" +# endif +# endif + +# ifndef __cpp_lib_ranges +# error "__cpp_lib_ranges should be defined in c++20" +# endif +# if __cpp_lib_ranges != 202110L +# error "__cpp_lib_ranges should have the value 202110L in c++20" +# endif + +# ifdef __cpp_lib_ranges_as_const +# error "__cpp_lib_ranges_as_const should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_as_rvalue +# error "__cpp_lib_ranges_as_rvalue should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_chunk_by +# error "__cpp_lib_ranges_chunk_by should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_concat +# error "__cpp_lib_ranges_concat should not be defined before c++26" +# endif + +# ifdef __cpp_lib_ranges_contains +# error "__cpp_lib_ranges_contains should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_find_last +# error "__cpp_lib_ranges_find_last should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_iota +# error "__cpp_lib_ranges_iota should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_join_with +# error "__cpp_lib_ranges_join_with should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_repeat +# error "__cpp_lib_ranges_repeat should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_slide +# error "__cpp_lib_ranges_slide should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_starts_ends_with +# error "__cpp_lib_ranges_starts_ends_with should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_zip +# error "__cpp_lib_ranges_zip should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ratio +# error "__cpp_lib_ratio should not be defined before c++26" +# endif + +# ifndef __cpp_lib_raw_memory_algorithms +# error "__cpp_lib_raw_memory_algorithms should be defined in c++20" +# endif +# if __cpp_lib_raw_memory_algorithms != 201606L +# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++20" +# endif + +# ifdef __cpp_lib_rcu +# error "__cpp_lib_rcu should not be defined before c++26" +# endif + +# ifdef __cpp_lib_reference_from_temporary +# error "__cpp_lib_reference_from_temporary should not be defined before c++23" +# endif + +# ifdef __cpp_lib_reference_wrapper +# error "__cpp_lib_reference_wrapper should not be defined before c++26" +# endif + +# ifndef __cpp_lib_remove_cvref +# error "__cpp_lib_remove_cvref should be defined in c++20" +# endif +# if __cpp_lib_remove_cvref != 201711L +# error "__cpp_lib_remove_cvref should have the value 201711L in c++20" +# endif + +# ifndef __cpp_lib_result_of_sfinae +# error "__cpp_lib_result_of_sfinae should be defined in c++20" +# endif +# if __cpp_lib_result_of_sfinae != 201210L +# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++20" +# endif + +# ifndef __cpp_lib_robust_nonmodifying_seq_ops +# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++20" +# endif +# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L +# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_sample +# error "__cpp_lib_sample should be defined in c++20" +# endif +# if __cpp_lib_sample != 201603L +# error "__cpp_lib_sample should have the value 201603L in c++20" +# endif + +# ifdef __cpp_lib_saturation_arithmetic +# error "__cpp_lib_saturation_arithmetic should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should be defined in c++20" +# endif +# if __cpp_lib_scoped_lock != 201703L +# error "__cpp_lib_scoped_lock should have the value 201703L in c++20" +# endif +# else +# ifdef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_semaphore +# error "__cpp_lib_semaphore should be defined in c++20" +# endif +# if __cpp_lib_semaphore != 201907L +# error "__cpp_lib_semaphore should have the value 201907L in c++20" +# endif +# else +# ifdef __cpp_lib_semaphore +# error "__cpp_lib_semaphore should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# ifdef __cpp_lib_senders +# error "__cpp_lib_senders should not be defined before c++26" +# endif + +# if _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should be defined in c++20" +# endif +# if __cpp_lib_shared_mutex != 201505L +# error "__cpp_lib_shared_mutex should have the value 201505L in c++20" +# endif +# else +# ifdef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifndef __cpp_lib_shared_ptr_arrays +# error "__cpp_lib_shared_ptr_arrays should be defined in c++20" +# endif +# if __cpp_lib_shared_ptr_arrays != 201707L +# error "__cpp_lib_shared_ptr_arrays should have the value 201707L in c++20" +# endif + +# ifndef __cpp_lib_shared_ptr_weak_type +# error "__cpp_lib_shared_ptr_weak_type should be defined in c++20" +# endif +# if __cpp_lib_shared_ptr_weak_type != 201606L +# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++20" +# endif + +# if _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should be defined in c++20" +# endif +# if __cpp_lib_shared_timed_mutex != 201402L +# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++20" +# endif +# else +# ifdef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifndef __cpp_lib_shift +# error "__cpp_lib_shift should be defined in c++20" +# endif +# if __cpp_lib_shift != 201806L +# error "__cpp_lib_shift should have the value 201806L in c++20" +# endif + +# ifndef __cpp_lib_smart_ptr_for_overwrite +# error "__cpp_lib_smart_ptr_for_overwrite should be defined in c++20" +# endif +# if __cpp_lib_smart_ptr_for_overwrite != 202002L +# error "__cpp_lib_smart_ptr_for_overwrite should have the value 202002L in c++20" +# endif + +# ifdef __cpp_lib_smart_ptr_owner_equality +# error "__cpp_lib_smart_ptr_owner_equality should not be defined before c++26" +# endif + +# ifndef __cpp_lib_source_location +# error "__cpp_lib_source_location should be defined in c++20" +# endif +# if __cpp_lib_source_location != 201907L +# error "__cpp_lib_source_location should have the value 201907L in c++20" +# endif + +# ifndef __cpp_lib_span +# error "__cpp_lib_span should be defined in c++20" +# endif +# if __cpp_lib_span != 202002L +# error "__cpp_lib_span should have the value 202002L in c++20" +# endif + +# ifdef __cpp_lib_span_at +# error "__cpp_lib_span_at should not be defined before c++26" +# endif + +# ifdef __cpp_lib_span_initializer_list +# error "__cpp_lib_span_initializer_list should not be defined before c++26" +# endif + +# ifdef __cpp_lib_spanstream +# error "__cpp_lib_spanstream should not be defined before c++23" +# endif + +# ifndef __cpp_lib_ssize +# error "__cpp_lib_ssize should be defined in c++20" +# endif +# if __cpp_lib_ssize != 201902L +# error "__cpp_lib_ssize should have the value 201902L in c++20" +# endif + +# ifdef __cpp_lib_sstream_from_string_view +# error "__cpp_lib_sstream_from_string_view should not be defined before c++26" +# endif + +# ifdef __cpp_lib_stacktrace +# error "__cpp_lib_stacktrace should not be defined before c++23" +# endif + +# ifndef __cpp_lib_starts_ends_with +# error "__cpp_lib_starts_ends_with should be defined in c++20" +# endif +# if __cpp_lib_starts_ends_with != 201711L +# error "__cpp_lib_starts_ends_with should have the value 201711L in c++20" +# endif + +# ifdef __cpp_lib_stdatomic_h +# error "__cpp_lib_stdatomic_h should not be defined before c++23" +# endif + +# ifdef __cpp_lib_string_contains +# error "__cpp_lib_string_contains should not be defined before c++23" +# endif + +# ifdef __cpp_lib_string_resize_and_overwrite +# error "__cpp_lib_string_resize_and_overwrite should not be defined before c++23" +# endif + +# ifndef __cpp_lib_string_udls +# error "__cpp_lib_string_udls should be defined in c++20" +# endif +# if __cpp_lib_string_udls != 201304L +# error "__cpp_lib_string_udls should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_string_view +# error "__cpp_lib_string_view should be defined in c++20" +# endif +# if __cpp_lib_string_view != 201803L +# error "__cpp_lib_string_view should have the value 201803L in c++20" +# endif + +# ifdef __cpp_lib_submdspan +# error "__cpp_lib_submdspan should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM +# ifndef __cpp_lib_syncbuf +# error "__cpp_lib_syncbuf should be defined in c++20" +# endif +# if __cpp_lib_syncbuf != 201803L +# error "__cpp_lib_syncbuf should have the value 201803L in c++20" +# endif +# else +# ifdef __cpp_lib_syncbuf +# error "__cpp_lib_syncbuf should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM' is not met!" +# endif +# endif + +# ifdef __cpp_lib_text_encoding +# error "__cpp_lib_text_encoding should not be defined before c++26" +# endif + +# ifndef __cpp_lib_three_way_comparison +# error "__cpp_lib_three_way_comparison should be defined in c++20" +# endif +# if __cpp_lib_three_way_comparison != 201907L +# error "__cpp_lib_three_way_comparison should have the value 201907L in c++20" +# endif + +# ifndef __cpp_lib_to_address +# error "__cpp_lib_to_address should be defined in c++20" +# endif +# if __cpp_lib_to_address != 201711L +# error "__cpp_lib_to_address should have the value 201711L in c++20" +# endif + +# ifndef __cpp_lib_to_array +# error "__cpp_lib_to_array should be defined in c++20" +# endif +# if __cpp_lib_to_array != 201907L +# error "__cpp_lib_to_array should have the value 201907L in c++20" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should be defined in c++20" +# endif +# if __cpp_lib_to_chars != 201611L +# error "__cpp_lib_to_chars should have the value 201611L in c++20" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_to_string +# error "__cpp_lib_to_string should not be defined before c++26" +# endif + +# ifdef __cpp_lib_to_underlying +# error "__cpp_lib_to_underlying should not be defined before c++23" +# endif + +# ifndef __cpp_lib_transformation_trait_aliases +# error "__cpp_lib_transformation_trait_aliases should be defined in c++20" +# endif +# if __cpp_lib_transformation_trait_aliases != 201304L +# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_transparent_operators +# error "__cpp_lib_transparent_operators should be defined in c++20" +# endif +# if __cpp_lib_transparent_operators != 201510L +# error "__cpp_lib_transparent_operators should have the value 201510L in c++20" +# endif + +# ifndef __cpp_lib_tuple_element_t +# error "__cpp_lib_tuple_element_t should be defined in c++20" +# endif +# if __cpp_lib_tuple_element_t != 201402L +# error "__cpp_lib_tuple_element_t should have the value 201402L in c++20" +# endif + +# ifdef __cpp_lib_tuple_like +# error "__cpp_lib_tuple_like should not be defined before c++23" +# endif + +# ifndef __cpp_lib_tuples_by_type +# error "__cpp_lib_tuples_by_type should be defined in c++20" +# endif +# if __cpp_lib_tuples_by_type != 201304L +# error "__cpp_lib_tuples_by_type should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_type_identity +# error "__cpp_lib_type_identity should be defined in c++20" +# endif +# if __cpp_lib_type_identity != 201806L +# error "__cpp_lib_type_identity should have the value 201806L in c++20" +# endif + +# ifndef __cpp_lib_type_trait_variable_templates +# error "__cpp_lib_type_trait_variable_templates should be defined in c++20" +# endif +# if __cpp_lib_type_trait_variable_templates != 201510L +# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++20" +# endif + +# ifndef __cpp_lib_uncaught_exceptions +# error "__cpp_lib_uncaught_exceptions should be defined in c++20" +# endif +# if __cpp_lib_uncaught_exceptions != 201411L +# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++20" +# endif + +# ifndef __cpp_lib_unordered_map_try_emplace +# error "__cpp_lib_unordered_map_try_emplace should be defined in c++20" +# endif +# if __cpp_lib_unordered_map_try_emplace != 201411L +# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++20" +# endif + +# ifdef __cpp_lib_unreachable +# error "__cpp_lib_unreachable should not be defined before c++23" +# endif + +# ifndef __cpp_lib_unwrap_ref +# error "__cpp_lib_unwrap_ref should be defined in c++20" +# endif +# if __cpp_lib_unwrap_ref != 201811L +# error "__cpp_lib_unwrap_ref should have the value 201811L in c++20" +# endif + +# ifndef __cpp_lib_variant +# error "__cpp_lib_variant should be defined in c++20" +# endif +# if __cpp_lib_variant != 202106L +# error "__cpp_lib_variant should have the value 202106L in c++20" +# endif + +# ifndef __cpp_lib_void_t +# error "__cpp_lib_void_t should be defined in c++20" +# endif +# if __cpp_lib_void_t != 201411L +# error "__cpp_lib_void_t should have the value 201411L in c++20" +# endif -# ifdef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should not be defined before c++17" -# endif +#elif TEST_STD_VER == 23 -# ifdef __cpp_lib_mdspan -# error "__cpp_lib_mdspan should not be defined before c++23" -# endif +# ifndef __cpp_lib_adaptor_iterator_pair_constructor +# error "__cpp_lib_adaptor_iterator_pair_constructor should be defined in c++23" +# endif +# if __cpp_lib_adaptor_iterator_pair_constructor != 202106L +# error "__cpp_lib_adaptor_iterator_pair_constructor should have the value 202106L in c++23" +# endif + +# ifndef __cpp_lib_addressof_constexpr +# error "__cpp_lib_addressof_constexpr should be defined in c++23" +# endif +# if __cpp_lib_addressof_constexpr != 201603L +# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++23" +# endif + +# ifndef __cpp_lib_allocate_at_least +# error "__cpp_lib_allocate_at_least should be defined in c++23" +# endif +# if __cpp_lib_allocate_at_least != 202302L +# error "__cpp_lib_allocate_at_least should have the value 202302L in c++23" +# endif + +# ifndef __cpp_lib_allocator_traits_is_always_equal +# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++23" +# endif +# if __cpp_lib_allocator_traits_is_always_equal != 201411L +# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++23" +# endif + +# ifndef __cpp_lib_any +# error "__cpp_lib_any should be defined in c++23" +# endif +# if __cpp_lib_any != 201606L +# error "__cpp_lib_any should have the value 201606L in c++23" +# endif + +# ifndef __cpp_lib_apply +# error "__cpp_lib_apply should be defined in c++23" +# endif +# if __cpp_lib_apply != 201603L +# error "__cpp_lib_apply should have the value 201603L in c++23" +# endif + +# ifndef __cpp_lib_array_constexpr +# error "__cpp_lib_array_constexpr should be defined in c++23" +# endif +# if __cpp_lib_array_constexpr != 201811L +# error "__cpp_lib_array_constexpr should have the value 201811L in c++23" +# endif + +# ifndef __cpp_lib_as_const +# error "__cpp_lib_as_const should be defined in c++23" +# endif +# if __cpp_lib_as_const != 201510L +# error "__cpp_lib_as_const should have the value 201510L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_associative_heterogeneous_erasure +# error "__cpp_lib_associative_heterogeneous_erasure should be defined in c++23" +# endif +# if __cpp_lib_associative_heterogeneous_erasure != 202110L +# error "__cpp_lib_associative_heterogeneous_erasure should have the value 202110L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_associative_heterogeneous_erasure +# error "__cpp_lib_associative_heterogeneous_erasure should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_associative_heterogeneous_insertion +# error "__cpp_lib_associative_heterogeneous_insertion should not be defined before c++26" +# endif + +# ifndef __cpp_lib_assume_aligned +# error "__cpp_lib_assume_aligned should be defined in c++23" +# endif +# if __cpp_lib_assume_aligned != 201811L +# error "__cpp_lib_assume_aligned should have the value 201811L in c++23" +# endif + +# ifndef __cpp_lib_atomic_flag_test +# error "__cpp_lib_atomic_flag_test should be defined in c++23" +# endif +# if __cpp_lib_atomic_flag_test != 201907L +# error "__cpp_lib_atomic_flag_test should have the value 201907L in c++23" +# endif + +# ifndef __cpp_lib_atomic_float +# error "__cpp_lib_atomic_float should be defined in c++23" +# endif +# if __cpp_lib_atomic_float != 201711L +# error "__cpp_lib_atomic_float should have the value 201711L in c++23" +# endif + +# ifndef __cpp_lib_atomic_is_always_lock_free +# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++23" +# endif +# if __cpp_lib_atomic_is_always_lock_free != 201603L +# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++23" +# endif + +# ifndef __cpp_lib_atomic_lock_free_type_aliases +# error "__cpp_lib_atomic_lock_free_type_aliases should be defined in c++23" +# endif +# if __cpp_lib_atomic_lock_free_type_aliases != 201907L +# error "__cpp_lib_atomic_lock_free_type_aliases should have the value 201907L in c++23" +# endif + +# ifdef __cpp_lib_atomic_min_max +# error "__cpp_lib_atomic_min_max should not be defined before c++26" +# endif + +# ifndef __cpp_lib_atomic_ref +# error "__cpp_lib_atomic_ref should be defined in c++23" +# endif +# if __cpp_lib_atomic_ref != 201806L +# error "__cpp_lib_atomic_ref should have the value 201806L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_atomic_shared_ptr +# error "__cpp_lib_atomic_shared_ptr should be defined in c++23" +# endif +# if __cpp_lib_atomic_shared_ptr != 201711L +# error "__cpp_lib_atomic_shared_ptr should have the value 201711L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_atomic_shared_ptr +# error "__cpp_lib_atomic_shared_ptr should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_atomic_value_initialization +# error "__cpp_lib_atomic_value_initialization should be defined in c++23" +# endif +# if __cpp_lib_atomic_value_initialization != 201911L +# error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC +# ifndef __cpp_lib_atomic_wait +# error "__cpp_lib_atomic_wait should be defined in c++23" +# endif +# if __cpp_lib_atomic_wait != 201907L +# error "__cpp_lib_atomic_wait should have the value 201907L in c++23" +# endif +# else +# ifdef __cpp_lib_atomic_wait +# error "__cpp_lib_atomic_wait should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_barrier +# error "__cpp_lib_barrier should be defined in c++23" +# endif +# if __cpp_lib_barrier != 201907L +# error "__cpp_lib_barrier should have the value 201907L in c++23" +# endif +# else +# ifdef __cpp_lib_barrier +# error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_bind_back +# error "__cpp_lib_bind_back should be defined in c++23" +# endif +# if __cpp_lib_bind_back != 202202L +# error "__cpp_lib_bind_back should have the value 202202L in c++23" +# endif + +# ifndef __cpp_lib_bind_front +# error "__cpp_lib_bind_front should be defined in c++23" +# endif +# if __cpp_lib_bind_front != 201907L +# error "__cpp_lib_bind_front should have the value 201907L in c++23" +# endif + +# ifndef __cpp_lib_bit_cast +# error "__cpp_lib_bit_cast should be defined in c++23" +# endif +# if __cpp_lib_bit_cast != 201806L +# error "__cpp_lib_bit_cast should have the value 201806L in c++23" +# endif + +# ifndef __cpp_lib_bitops +# error "__cpp_lib_bitops should be defined in c++23" +# endif +# if __cpp_lib_bitops != 201907L +# error "__cpp_lib_bitops should have the value 201907L in c++23" +# endif + +# ifdef __cpp_lib_bitset +# error "__cpp_lib_bitset should not be defined before c++26" +# endif + +# ifndef __cpp_lib_bool_constant +# error "__cpp_lib_bool_constant should be defined in c++23" +# endif +# if __cpp_lib_bool_constant != 201505L +# error "__cpp_lib_bool_constant should have the value 201505L in c++23" +# endif + +# ifndef __cpp_lib_bounded_array_traits +# error "__cpp_lib_bounded_array_traits should be defined in c++23" +# endif +# if __cpp_lib_bounded_array_traits != 201902L +# error "__cpp_lib_bounded_array_traits should have the value 201902L in c++23" +# endif + +# ifndef __cpp_lib_boyer_moore_searcher +# error "__cpp_lib_boyer_moore_searcher should be defined in c++23" +# endif +# if __cpp_lib_boyer_moore_searcher != 201603L +# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++23" +# endif + +# ifndef __cpp_lib_byte +# error "__cpp_lib_byte should be defined in c++23" +# endif +# if __cpp_lib_byte != 201603L +# error "__cpp_lib_byte should have the value 201603L in c++23" +# endif + +# ifndef __cpp_lib_byteswap +# error "__cpp_lib_byteswap should be defined in c++23" +# endif +# if __cpp_lib_byteswap != 202110L +# error "__cpp_lib_byteswap should have the value 202110L in c++23" +# endif + +# if defined(__cpp_char8_t) +# ifndef __cpp_lib_char8_t +# error "__cpp_lib_char8_t should be defined in c++23" +# endif +# if __cpp_lib_char8_t != 201907L +# error "__cpp_lib_char8_t should have the value 201907L in c++23" +# endif +# else +# ifdef __cpp_lib_char8_t +# error "__cpp_lib_char8_t should not be defined when the requirement 'defined(__cpp_char8_t)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_chrono +# error "__cpp_lib_chrono should be defined in c++23" +# endif +# if __cpp_lib_chrono != 201611L +# error "__cpp_lib_chrono should have the value 201611L in c++23" +# endif + +# ifndef __cpp_lib_chrono_udls +# error "__cpp_lib_chrono_udls should be defined in c++23" +# endif +# if __cpp_lib_chrono_udls != 201304L +# error "__cpp_lib_chrono_udls should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_clamp +# error "__cpp_lib_clamp should be defined in c++23" +# endif +# if __cpp_lib_clamp != 201603L +# error "__cpp_lib_clamp should have the value 201603L in c++23" +# endif + +# ifndef __cpp_lib_complex_udls +# error "__cpp_lib_complex_udls should be defined in c++23" +# endif +# if __cpp_lib_complex_udls != 201309L +# error "__cpp_lib_complex_udls should have the value 201309L in c++23" +# endif + +# ifndef __cpp_lib_concepts +# error "__cpp_lib_concepts should be defined in c++23" +# endif +# if __cpp_lib_concepts != 202002L +# error "__cpp_lib_concepts should have the value 202002L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_algorithms +# error "__cpp_lib_constexpr_algorithms should be defined in c++23" +# endif +# if __cpp_lib_constexpr_algorithms != 201806L +# error "__cpp_lib_constexpr_algorithms should have the value 201806L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_bitset +# error "__cpp_lib_constexpr_bitset should be defined in c++23" +# endif +# if __cpp_lib_constexpr_bitset != 202207L +# error "__cpp_lib_constexpr_bitset should have the value 202207L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_charconv +# error "__cpp_lib_constexpr_charconv should be defined in c++23" +# endif +# if __cpp_lib_constexpr_charconv != 202207L +# error "__cpp_lib_constexpr_charconv should have the value 202207L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_constexpr_cmath +# error "__cpp_lib_constexpr_cmath should be defined in c++23" +# endif +# if __cpp_lib_constexpr_cmath != 202202L +# error "__cpp_lib_constexpr_cmath should have the value 202202L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_constexpr_cmath +# error "__cpp_lib_constexpr_cmath should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_constexpr_complex +# error "__cpp_lib_constexpr_complex should be defined in c++23" +# endif +# if __cpp_lib_constexpr_complex != 201711L +# error "__cpp_lib_constexpr_complex should have the value 201711L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_dynamic_alloc +# error "__cpp_lib_constexpr_dynamic_alloc should be defined in c++23" +# endif +# if __cpp_lib_constexpr_dynamic_alloc != 201907L +# error "__cpp_lib_constexpr_dynamic_alloc should have the value 201907L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_functional +# error "__cpp_lib_constexpr_functional should be defined in c++23" +# endif +# if __cpp_lib_constexpr_functional != 201907L +# error "__cpp_lib_constexpr_functional should have the value 201907L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_iterator +# error "__cpp_lib_constexpr_iterator should be defined in c++23" +# endif +# if __cpp_lib_constexpr_iterator != 201811L +# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_memory +# error "__cpp_lib_constexpr_memory should be defined in c++23" +# endif +# if __cpp_lib_constexpr_memory != 202202L +# error "__cpp_lib_constexpr_memory should have the value 202202L in c++23" +# endif + +# ifdef __cpp_lib_constexpr_new +# error "__cpp_lib_constexpr_new should not be defined before c++26" +# endif + +# ifndef __cpp_lib_constexpr_numeric +# error "__cpp_lib_constexpr_numeric should be defined in c++23" +# endif +# if __cpp_lib_constexpr_numeric != 201911L +# error "__cpp_lib_constexpr_numeric should have the value 201911L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_string +# error "__cpp_lib_constexpr_string should be defined in c++23" +# endif +# if __cpp_lib_constexpr_string != 201907L +# error "__cpp_lib_constexpr_string should have the value 201907L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_string_view +# error "__cpp_lib_constexpr_string_view should be defined in c++23" +# endif +# if __cpp_lib_constexpr_string_view != 201811L +# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_tuple +# error "__cpp_lib_constexpr_tuple should be defined in c++23" +# endif +# if __cpp_lib_constexpr_tuple != 201811L +# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_typeinfo +# error "__cpp_lib_constexpr_typeinfo should be defined in c++23" +# endif +# if __cpp_lib_constexpr_typeinfo != 202106L +# error "__cpp_lib_constexpr_typeinfo should have the value 202106L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_utility +# error "__cpp_lib_constexpr_utility should be defined in c++23" +# endif +# if __cpp_lib_constexpr_utility != 201811L +# error "__cpp_lib_constexpr_utility should have the value 201811L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_vector +# error "__cpp_lib_constexpr_vector should be defined in c++23" +# endif +# if __cpp_lib_constexpr_vector != 201907L +# error "__cpp_lib_constexpr_vector should have the value 201907L in c++23" +# endif + +# ifdef __cpp_lib_constrained_equality +# error "__cpp_lib_constrained_equality should not be defined before c++26" +# endif + +# ifndef __cpp_lib_containers_ranges +# error "__cpp_lib_containers_ranges should be defined in c++23" +# endif +# if __cpp_lib_containers_ranges != 202202L +# error "__cpp_lib_containers_ranges should have the value 202202L in c++23" +# endif + +# ifdef __cpp_lib_copyable_function +# error "__cpp_lib_copyable_function should not be defined before c++26" +# endif + +# ifndef __cpp_lib_coroutine +# error "__cpp_lib_coroutine should be defined in c++23" +# endif +# if __cpp_lib_coroutine != 201902L +# error "__cpp_lib_coroutine should have the value 201902L in c++23" +# endif + +# ifdef __cpp_lib_debugging +# error "__cpp_lib_debugging should not be defined before c++26" +# endif + +# ifdef __cpp_lib_default_template_type_for_algorithm_values +# error "__cpp_lib_default_template_type_for_algorithm_values should not be defined before c++26" +# endif + +# if TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L +# ifndef __cpp_lib_destroying_delete +# error "__cpp_lib_destroying_delete should be defined in c++23" +# endif +# if __cpp_lib_destroying_delete != 201806L +# error "__cpp_lib_destroying_delete should have the value 201806L in c++23" +# endif +# else +# ifdef __cpp_lib_destroying_delete +# error "__cpp_lib_destroying_delete should not be defined when the requirement 'TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L' is not met!" +# endif +# endif + +# ifndef __cpp_lib_enable_shared_from_this +# error "__cpp_lib_enable_shared_from_this should be defined in c++23" +# endif +# if __cpp_lib_enable_shared_from_this != 201603L +# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++23" +# endif + +# ifndef __cpp_lib_endian +# error "__cpp_lib_endian should be defined in c++23" +# endif +# if __cpp_lib_endian != 201907L +# error "__cpp_lib_endian should have the value 201907L in c++23" +# endif + +# ifndef __cpp_lib_erase_if +# error "__cpp_lib_erase_if should be defined in c++23" +# endif +# if __cpp_lib_erase_if != 202002L +# error "__cpp_lib_erase_if should have the value 202002L in c++23" +# endif + +# ifndef __cpp_lib_exchange_function +# error "__cpp_lib_exchange_function should be defined in c++23" +# endif +# if __cpp_lib_exchange_function != 201304L +# error "__cpp_lib_exchange_function should have the value 201304L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_execution +# error "__cpp_lib_execution should be defined in c++23" +# endif +# if __cpp_lib_execution != 201902L +# error "__cpp_lib_execution should have the value 201902L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_execution +# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_expected +# error "__cpp_lib_expected should be defined in c++23" +# endif +# if __cpp_lib_expected != 202211L +# error "__cpp_lib_expected should have the value 202211L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY) +# ifndef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should be defined in c++23" +# endif +# if __cpp_lib_filesystem != 201703L +# error "__cpp_lib_filesystem should have the value 201703L in c++23" +# endif +# else +# ifdef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_flat_map +# error "__cpp_lib_flat_map should be defined in c++23" +# endif +# if __cpp_lib_flat_map != 202207L +# error "__cpp_lib_flat_map should have the value 202207L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_flat_set +# error "__cpp_lib_flat_set should be defined in c++23" +# endif +# if __cpp_lib_flat_set != 202207L +# error "__cpp_lib_flat_set should have the value 202207L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_flat_set +# error "__cpp_lib_flat_set should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT +# ifndef __cpp_lib_format +# error "__cpp_lib_format should be defined in c++23" +# endif +# if __cpp_lib_format != 202110L +# error "__cpp_lib_format should have the value 202110L in c++23" +# endif +# else +# ifdef __cpp_lib_format +# error "__cpp_lib_format should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" +# endif +# endif + +# ifdef __cpp_lib_format_path +# error "__cpp_lib_format_path should not be defined before c++26" +# endif + +# ifndef __cpp_lib_format_ranges +# error "__cpp_lib_format_ranges should be defined in c++23" +# endif +# if __cpp_lib_format_ranges != 202207L +# error "__cpp_lib_format_ranges should have the value 202207L in c++23" +# endif + +# ifndef __cpp_lib_format_uchar +# error "__cpp_lib_format_uchar should be defined in c++23" +# endif +# if __cpp_lib_format_uchar != 202311L +# error "__cpp_lib_format_uchar should have the value 202311L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_formatters +# error "__cpp_lib_formatters should be defined in c++23" +# endif +# if __cpp_lib_formatters != 202302L +# error "__cpp_lib_formatters should have the value 202302L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_formatters +# error "__cpp_lib_formatters should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_forward_like +# error "__cpp_lib_forward_like should be defined in c++23" +# endif +# if __cpp_lib_forward_like != 202207L +# error "__cpp_lib_forward_like should have the value 202207L in c++23" +# endif + +# ifdef __cpp_lib_freestanding_algorithm +# error "__cpp_lib_freestanding_algorithm should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_array +# error "__cpp_lib_freestanding_array should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_cstring +# error "__cpp_lib_freestanding_cstring should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_expected +# error "__cpp_lib_freestanding_expected should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_mdspan +# error "__cpp_lib_freestanding_mdspan should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_optional +# error "__cpp_lib_freestanding_optional should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_string_view +# error "__cpp_lib_freestanding_string_view should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_variant +# error "__cpp_lib_freestanding_variant should not be defined before c++26" +# endif + +# ifdef __cpp_lib_fstream_native_handle +# error "__cpp_lib_fstream_native_handle should not be defined before c++26" +# endif + +# ifdef __cpp_lib_function_ref +# error "__cpp_lib_function_ref should not be defined before c++26" +# endif + +# ifndef __cpp_lib_gcd_lcm +# error "__cpp_lib_gcd_lcm should be defined in c++23" +# endif +# if __cpp_lib_gcd_lcm != 201606L +# error "__cpp_lib_gcd_lcm should have the value 201606L in c++23" +# endif + +# ifdef __cpp_lib_generate_random +# error "__cpp_lib_generate_random should not be defined before c++26" +# endif + +# ifndef __cpp_lib_generic_associative_lookup +# error "__cpp_lib_generic_associative_lookup should be defined in c++23" +# endif +# if __cpp_lib_generic_associative_lookup != 201304L +# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_generic_unordered_lookup +# error "__cpp_lib_generic_unordered_lookup should be defined in c++23" +# endif +# if __cpp_lib_generic_unordered_lookup != 201811L +# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)) +# ifndef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should be defined in c++23" +# endif +# if __cpp_lib_hardware_interference_size != 201703L +# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++23" +# endif +# else +# ifdef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))' is not met!" +# endif +# endif + +# ifndef __cpp_lib_has_unique_object_representations +# error "__cpp_lib_has_unique_object_representations should be defined in c++23" +# endif +# if __cpp_lib_has_unique_object_representations != 201606L +# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++23" +# endif + +# ifdef __cpp_lib_hazard_pointer +# error "__cpp_lib_hazard_pointer should not be defined before c++26" +# endif + +# ifndef __cpp_lib_hypot +# error "__cpp_lib_hypot should be defined in c++23" +# endif +# if __cpp_lib_hypot != 201603L +# error "__cpp_lib_hypot should have the value 201603L in c++23" +# endif + +# ifndef __cpp_lib_incomplete_container_elements +# error "__cpp_lib_incomplete_container_elements should be defined in c++23" +# endif +# if __cpp_lib_incomplete_container_elements != 201505L +# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++23" +# endif + +# ifdef __cpp_lib_inplace_vector +# error "__cpp_lib_inplace_vector should not be defined before c++26" +# endif + +# ifndef __cpp_lib_int_pow2 +# error "__cpp_lib_int_pow2 should be defined in c++23" +# endif +# if __cpp_lib_int_pow2 != 202002L +# error "__cpp_lib_int_pow2 should have the value 202002L in c++23" +# endif + +# ifndef __cpp_lib_integer_comparison_functions +# error "__cpp_lib_integer_comparison_functions should be defined in c++23" +# endif +# if __cpp_lib_integer_comparison_functions != 202002L +# error "__cpp_lib_integer_comparison_functions should have the value 202002L in c++23" +# endif + +# ifndef __cpp_lib_integer_sequence +# error "__cpp_lib_integer_sequence should be defined in c++23" +# endif +# if __cpp_lib_integer_sequence != 201304L +# error "__cpp_lib_integer_sequence should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_integral_constant_callable +# error "__cpp_lib_integral_constant_callable should be defined in c++23" +# endif +# if __cpp_lib_integral_constant_callable != 201304L +# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should be defined in c++23" +# endif +# if __cpp_lib_interpolate != 201902L +# error "__cpp_lib_interpolate should have the value 201902L in c++23" +# endif + +# ifndef __cpp_lib_invoke +# error "__cpp_lib_invoke should be defined in c++23" +# endif +# if __cpp_lib_invoke != 201411L +# error "__cpp_lib_invoke should have the value 201411L in c++23" +# endif + +# ifndef __cpp_lib_invoke_r +# error "__cpp_lib_invoke_r should be defined in c++23" +# endif +# if __cpp_lib_invoke_r != 202106L +# error "__cpp_lib_invoke_r should have the value 202106L in c++23" +# endif + +# ifndef __cpp_lib_ios_noreplace +# error "__cpp_lib_ios_noreplace should be defined in c++23" +# endif +# if __cpp_lib_ios_noreplace != 202207L +# error "__cpp_lib_ios_noreplace should have the value 202207L in c++23" +# endif + +# ifndef __cpp_lib_is_aggregate +# error "__cpp_lib_is_aggregate should be defined in c++23" +# endif +# if __cpp_lib_is_aggregate != 201703L +# error "__cpp_lib_is_aggregate should have the value 201703L in c++23" +# endif + +# ifndef __cpp_lib_is_constant_evaluated +# error "__cpp_lib_is_constant_evaluated should be defined in c++23" +# endif +# if __cpp_lib_is_constant_evaluated != 201811L +# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++23" +# endif + +# ifndef __cpp_lib_is_final +# error "__cpp_lib_is_final should be defined in c++23" +# endif +# if __cpp_lib_is_final != 201402L +# error "__cpp_lib_is_final should have the value 201402L in c++23" +# endif + +# if __has_builtin(__builtin_is_implicit_lifetime) +# ifndef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should be defined in c++23" +# endif +# if __cpp_lib_is_implicit_lifetime != 202302L +# error "__cpp_lib_is_implicit_lifetime should have the value 202302L in c++23" +# endif +# else +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_implicit_lifetime)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_is_invocable +# error "__cpp_lib_is_invocable should be defined in c++23" +# endif +# if __cpp_lib_is_invocable != 201703L +# error "__cpp_lib_is_invocable should have the value 201703L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_is_layout_compatible +# error "__cpp_lib_is_layout_compatible should be defined in c++23" +# endif +# if __cpp_lib_is_layout_compatible != 201907L +# error "__cpp_lib_is_layout_compatible should have the value 201907L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_is_layout_compatible +# error "__cpp_lib_is_layout_compatible should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_is_nothrow_convertible +# error "__cpp_lib_is_nothrow_convertible should be defined in c++23" +# endif +# if __cpp_lib_is_nothrow_convertible != 201806L +# error "__cpp_lib_is_nothrow_convertible should have the value 201806L in c++23" +# endif + +# ifndef __cpp_lib_is_null_pointer +# error "__cpp_lib_is_null_pointer should be defined in c++23" +# endif +# if __cpp_lib_is_null_pointer != 201309L +# error "__cpp_lib_is_null_pointer should have the value 201309L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_is_pointer_interconvertible +# error "__cpp_lib_is_pointer_interconvertible should be defined in c++23" +# endif +# if __cpp_lib_is_pointer_interconvertible != 201907L +# error "__cpp_lib_is_pointer_interconvertible should have the value 201907L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_is_pointer_interconvertible +# error "__cpp_lib_is_pointer_interconvertible should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_is_scoped_enum +# error "__cpp_lib_is_scoped_enum should be defined in c++23" +# endif +# if __cpp_lib_is_scoped_enum != 202011L +# error "__cpp_lib_is_scoped_enum should have the value 202011L in c++23" +# endif + +# ifndef __cpp_lib_is_swappable +# error "__cpp_lib_is_swappable should be defined in c++23" +# endif +# if __cpp_lib_is_swappable != 201603L +# error "__cpp_lib_is_swappable should have the value 201603L in c++23" +# endif + +# ifdef __cpp_lib_is_virtual_base_of +# error "__cpp_lib_is_virtual_base_of should not be defined before c++26" +# endif + +# ifdef __cpp_lib_is_within_lifetime +# error "__cpp_lib_is_within_lifetime should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_jthread +# error "__cpp_lib_jthread should be defined in c++23" +# endif +# if __cpp_lib_jthread != 201911L +# error "__cpp_lib_jthread should have the value 201911L in c++23" +# endif +# else +# ifdef __cpp_lib_jthread +# error "__cpp_lib_jthread should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_latch +# error "__cpp_lib_latch should be defined in c++23" +# endif +# if __cpp_lib_latch != 201907L +# error "__cpp_lib_latch should have the value 201907L in c++23" +# endif +# else +# ifdef __cpp_lib_latch +# error "__cpp_lib_latch should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_launder +# error "__cpp_lib_launder should be defined in c++23" +# endif +# if __cpp_lib_launder != 201606L +# error "__cpp_lib_launder should have the value 201606L in c++23" +# endif + +# ifdef __cpp_lib_linalg +# error "__cpp_lib_linalg should not be defined before c++26" +# endif + +# ifndef __cpp_lib_list_remove_return_type +# error "__cpp_lib_list_remove_return_type should be defined in c++23" +# endif +# if __cpp_lib_list_remove_return_type != 201806L +# error "__cpp_lib_list_remove_return_type should have the value 201806L in c++23" +# endif + +# ifndef __cpp_lib_logical_traits +# error "__cpp_lib_logical_traits should be defined in c++23" +# endif +# if __cpp_lib_logical_traits != 201510L +# error "__cpp_lib_logical_traits should have the value 201510L in c++23" +# endif + +# ifndef __cpp_lib_make_from_tuple +# error "__cpp_lib_make_from_tuple should be defined in c++23" +# endif +# if __cpp_lib_make_from_tuple != 201606L +# error "__cpp_lib_make_from_tuple should have the value 201606L in c++23" +# endif + +# ifndef __cpp_lib_make_reverse_iterator +# error "__cpp_lib_make_reverse_iterator should be defined in c++23" +# endif +# if __cpp_lib_make_reverse_iterator != 201402L +# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++23" +# endif + +# ifndef __cpp_lib_make_unique +# error "__cpp_lib_make_unique should be defined in c++23" +# endif +# if __cpp_lib_make_unique != 201304L +# error "__cpp_lib_make_unique should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_map_try_emplace +# error "__cpp_lib_map_try_emplace should be defined in c++23" +# endif +# if __cpp_lib_map_try_emplace != 201411L +# error "__cpp_lib_map_try_emplace should have the value 201411L in c++23" +# endif + +# ifndef __cpp_lib_math_constants +# error "__cpp_lib_math_constants should be defined in c++23" +# endif +# if __cpp_lib_math_constants != 201907L +# error "__cpp_lib_math_constants should have the value 201907L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should be defined in c++23" +# endif +# if __cpp_lib_math_special_functions != 201603L +# error "__cpp_lib_math_special_functions should have the value 201603L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_mdspan +# error "__cpp_lib_mdspan should be defined in c++23" +# endif +# if __cpp_lib_mdspan != 202207L +# error "__cpp_lib_mdspan should have the value 202207L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR +# ifndef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should be defined in c++23" +# endif +# if __cpp_lib_memory_resource != 201603L +# error "__cpp_lib_memory_resource should have the value 201603L in c++23" +# endif +# else +# ifdef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" +# endif +# endif + +# ifndef __cpp_lib_modules +# error "__cpp_lib_modules should be defined in c++23" +# endif +# if __cpp_lib_modules != 202207L +# error "__cpp_lib_modules should have the value 202207L in c++23" +# endif + +# ifndef __cpp_lib_move_iterator_concept +# error "__cpp_lib_move_iterator_concept should be defined in c++23" +# endif +# if __cpp_lib_move_iterator_concept != 202207L +# error "__cpp_lib_move_iterator_concept should have the value 202207L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_move_only_function +# error "__cpp_lib_move_only_function should be defined in c++23" +# endif +# if __cpp_lib_move_only_function != 202110L +# error "__cpp_lib_move_only_function should have the value 202110L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_move_only_function +# error "__cpp_lib_move_only_function should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_node_extract +# error "__cpp_lib_node_extract should be defined in c++23" +# endif +# if __cpp_lib_node_extract != 201606L +# error "__cpp_lib_node_extract should have the value 201606L in c++23" +# endif + +# ifndef __cpp_lib_nonmember_container_access +# error "__cpp_lib_nonmember_container_access should be defined in c++23" +# endif +# if __cpp_lib_nonmember_container_access != 201411L +# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++23" +# endif + +# ifndef __cpp_lib_not_fn +# error "__cpp_lib_not_fn should be defined in c++23" +# endif +# if __cpp_lib_not_fn != 201603L +# error "__cpp_lib_not_fn should have the value 201603L in c++23" +# endif + +# ifndef __cpp_lib_null_iterators +# error "__cpp_lib_null_iterators should be defined in c++23" +# endif +# if __cpp_lib_null_iterators != 201304L +# error "__cpp_lib_null_iterators should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_optional +# error "__cpp_lib_optional should be defined in c++23" +# endif +# if __cpp_lib_optional != 202110L +# error "__cpp_lib_optional should have the value 202110L in c++23" +# endif + +# ifdef __cpp_lib_optional_range_support +# error "__cpp_lib_optional_range_support should not be defined before c++26" +# endif + +# ifndef __cpp_lib_out_ptr +# error "__cpp_lib_out_ptr should be defined in c++23" +# endif +# if __cpp_lib_out_ptr != 202106L +# error "__cpp_lib_out_ptr should have the value 202106L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should be defined in c++23" +# endif +# if __cpp_lib_parallel_algorithm != 201603L +# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_philox_engine +# error "__cpp_lib_philox_engine should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR +# ifndef __cpp_lib_polymorphic_allocator +# error "__cpp_lib_polymorphic_allocator should be defined in c++23" +# endif +# if __cpp_lib_polymorphic_allocator != 201902L +# error "__cpp_lib_polymorphic_allocator should have the value 201902L in c++23" +# endif +# else +# ifdef __cpp_lib_polymorphic_allocator +# error "__cpp_lib_polymorphic_allocator should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT +# ifndef __cpp_lib_print +# error "__cpp_lib_print should be defined in c++23" +# endif +# if __cpp_lib_print != 202207L +# error "__cpp_lib_print should have the value 202207L in c++23" +# endif +# else +# ifdef __cpp_lib_print +# error "__cpp_lib_print should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION +# ifndef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should be defined in c++23" +# endif +# if __cpp_lib_quoted_string_io != 201304L +# error "__cpp_lib_quoted_string_io should have the value 201304L in c++23" +# endif +# else +# ifdef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" +# endif +# endif + +# ifndef __cpp_lib_ranges +# error "__cpp_lib_ranges should be defined in c++23" +# endif +# if __cpp_lib_ranges != 202406L +# error "__cpp_lib_ranges should have the value 202406L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_as_const +# error "__cpp_lib_ranges_as_const should be defined in c++23" +# endif +# if __cpp_lib_ranges_as_const != 202207L +# error "__cpp_lib_ranges_as_const should have the value 202207L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_ranges_as_const +# error "__cpp_lib_ranges_as_const should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_as_rvalue +# error "__cpp_lib_ranges_as_rvalue should be defined in c++23" +# endif +# if __cpp_lib_ranges_as_rvalue != 202207L +# error "__cpp_lib_ranges_as_rvalue should have the value 202207L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should be defined in c++23" +# endif +# if __cpp_lib_ranges_chunk != 202202L +# error "__cpp_lib_ranges_chunk should have the value 202202L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_chunk_by +# error "__cpp_lib_ranges_chunk_by should be defined in c++23" +# endif +# if __cpp_lib_ranges_chunk_by != 202202L +# error "__cpp_lib_ranges_chunk_by should have the value 202202L in c++23" +# endif + +# ifdef __cpp_lib_ranges_concat +# error "__cpp_lib_ranges_concat should not be defined before c++26" +# endif + +# ifndef __cpp_lib_ranges_contains +# error "__cpp_lib_ranges_contains should be defined in c++23" +# endif +# if __cpp_lib_ranges_contains != 202207L +# error "__cpp_lib_ranges_contains should have the value 202207L in c++23" +# endif + +# ifndef __cpp_lib_ranges_find_last +# error "__cpp_lib_ranges_find_last should be defined in c++23" +# endif +# if __cpp_lib_ranges_find_last != 202207L +# error "__cpp_lib_ranges_find_last should have the value 202207L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_iota +# error "__cpp_lib_ranges_iota should be defined in c++23" +# endif +# if __cpp_lib_ranges_iota != 202202L +# error "__cpp_lib_ranges_iota should have the value 202202L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_ranges_iota +# error "__cpp_lib_ranges_iota should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_join_with +# error "__cpp_lib_ranges_join_with should be defined in c++23" +# endif +# if __cpp_lib_ranges_join_with != 202202L +# error "__cpp_lib_ranges_join_with should have the value 202202L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_ranges_join_with +# error "__cpp_lib_ranges_join_with should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_repeat +# error "__cpp_lib_ranges_repeat should be defined in c++23" +# endif +# if __cpp_lib_ranges_repeat != 202207L +# error "__cpp_lib_ranges_repeat should have the value 202207L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_slide +# error "__cpp_lib_ranges_slide should be defined in c++23" +# endif +# if __cpp_lib_ranges_slide != 202202L +# error "__cpp_lib_ranges_slide should have the value 202202L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_ranges_slide +# error "__cpp_lib_ranges_slide should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_starts_ends_with +# error "__cpp_lib_ranges_starts_ends_with should be defined in c++23" +# endif +# if __cpp_lib_ranges_starts_ends_with != 202106L +# error "__cpp_lib_ranges_starts_ends_with should have the value 202106L in c++23" +# endif + +# ifndef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should be defined in c++23" +# endif +# if __cpp_lib_ranges_stride != 202207L +# error "__cpp_lib_ranges_stride should have the value 202207L in c++23" +# endif + +# ifndef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should be defined in c++23" +# endif +# if __cpp_lib_ranges_to_container != 202202L +# error "__cpp_lib_ranges_to_container should have the value 202202L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_zip +# error "__cpp_lib_ranges_zip should be defined in c++23" +# endif +# if __cpp_lib_ranges_zip != 202110L +# error "__cpp_lib_ranges_zip should have the value 202110L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_ranges_zip +# error "__cpp_lib_ranges_zip should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_ratio +# error "__cpp_lib_ratio should not be defined before c++26" +# endif + +# ifndef __cpp_lib_raw_memory_algorithms +# error "__cpp_lib_raw_memory_algorithms should be defined in c++23" +# endif +# if __cpp_lib_raw_memory_algorithms != 201606L +# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++23" +# endif + +# ifdef __cpp_lib_rcu +# error "__cpp_lib_rcu should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_reference_from_temporary +# error "__cpp_lib_reference_from_temporary should be defined in c++23" +# endif +# if __cpp_lib_reference_from_temporary != 202202L +# error "__cpp_lib_reference_from_temporary should have the value 202202L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_reference_from_temporary +# error "__cpp_lib_reference_from_temporary should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_reference_wrapper +# error "__cpp_lib_reference_wrapper should not be defined before c++26" +# endif + +# ifndef __cpp_lib_remove_cvref +# error "__cpp_lib_remove_cvref should be defined in c++23" +# endif +# if __cpp_lib_remove_cvref != 201711L +# error "__cpp_lib_remove_cvref should have the value 201711L in c++23" +# endif + +# ifndef __cpp_lib_result_of_sfinae +# error "__cpp_lib_result_of_sfinae should be defined in c++23" +# endif +# if __cpp_lib_result_of_sfinae != 201210L +# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++23" +# endif + +# ifndef __cpp_lib_robust_nonmodifying_seq_ops +# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++23" +# endif +# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L +# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_sample +# error "__cpp_lib_sample should be defined in c++23" +# endif +# if __cpp_lib_sample != 201603L +# error "__cpp_lib_sample should have the value 201603L in c++23" +# endif + +# ifdef __cpp_lib_saturation_arithmetic +# error "__cpp_lib_saturation_arithmetic should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should be defined in c++23" +# endif +# if __cpp_lib_scoped_lock != 201703L +# error "__cpp_lib_scoped_lock should have the value 201703L in c++23" +# endif +# else +# ifdef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_semaphore +# error "__cpp_lib_semaphore should be defined in c++23" +# endif +# if __cpp_lib_semaphore != 201907L +# error "__cpp_lib_semaphore should have the value 201907L in c++23" +# endif +# else +# ifdef __cpp_lib_semaphore +# error "__cpp_lib_semaphore should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# ifdef __cpp_lib_senders +# error "__cpp_lib_senders should not be defined before c++26" +# endif + +# if _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should be defined in c++23" +# endif +# if __cpp_lib_shared_mutex != 201505L +# error "__cpp_lib_shared_mutex should have the value 201505L in c++23" +# endif +# else +# ifdef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifndef __cpp_lib_shared_ptr_arrays +# error "__cpp_lib_shared_ptr_arrays should be defined in c++23" +# endif +# if __cpp_lib_shared_ptr_arrays != 201707L +# error "__cpp_lib_shared_ptr_arrays should have the value 201707L in c++23" +# endif + +# ifndef __cpp_lib_shared_ptr_weak_type +# error "__cpp_lib_shared_ptr_weak_type should be defined in c++23" +# endif +# if __cpp_lib_shared_ptr_weak_type != 201606L +# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++23" +# endif + +# if _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should be defined in c++23" +# endif +# if __cpp_lib_shared_timed_mutex != 201402L +# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++23" +# endif +# else +# ifdef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifndef __cpp_lib_shift +# error "__cpp_lib_shift should be defined in c++23" +# endif +# if __cpp_lib_shift != 201806L +# error "__cpp_lib_shift should have the value 201806L in c++23" +# endif + +# ifndef __cpp_lib_smart_ptr_for_overwrite +# error "__cpp_lib_smart_ptr_for_overwrite should be defined in c++23" +# endif +# if __cpp_lib_smart_ptr_for_overwrite != 202002L +# error "__cpp_lib_smart_ptr_for_overwrite should have the value 202002L in c++23" +# endif + +# ifdef __cpp_lib_smart_ptr_owner_equality +# error "__cpp_lib_smart_ptr_owner_equality should not be defined before c++26" +# endif + +# ifndef __cpp_lib_source_location +# error "__cpp_lib_source_location should be defined in c++23" +# endif +# if __cpp_lib_source_location != 201907L +# error "__cpp_lib_source_location should have the value 201907L in c++23" +# endif + +# ifndef __cpp_lib_span +# error "__cpp_lib_span should be defined in c++23" +# endif +# if __cpp_lib_span != 202002L +# error "__cpp_lib_span should have the value 202002L in c++23" +# endif + +# ifdef __cpp_lib_span_at +# error "__cpp_lib_span_at should not be defined before c++26" +# endif + +# ifdef __cpp_lib_span_initializer_list +# error "__cpp_lib_span_initializer_list should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_spanstream +# error "__cpp_lib_spanstream should be defined in c++23" +# endif +# if __cpp_lib_spanstream != 202106L +# error "__cpp_lib_spanstream should have the value 202106L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_spanstream +# error "__cpp_lib_spanstream should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ssize +# error "__cpp_lib_ssize should be defined in c++23" +# endif +# if __cpp_lib_ssize != 201902L +# error "__cpp_lib_ssize should have the value 201902L in c++23" +# endif + +# ifdef __cpp_lib_sstream_from_string_view +# error "__cpp_lib_sstream_from_string_view should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_stacktrace +# error "__cpp_lib_stacktrace should be defined in c++23" +# endif +# if __cpp_lib_stacktrace != 202011L +# error "__cpp_lib_stacktrace should have the value 202011L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_stacktrace +# error "__cpp_lib_stacktrace should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_starts_ends_with +# error "__cpp_lib_starts_ends_with should be defined in c++23" +# endif +# if __cpp_lib_starts_ends_with != 201711L +# error "__cpp_lib_starts_ends_with should have the value 201711L in c++23" +# endif + +# ifndef __cpp_lib_stdatomic_h +# error "__cpp_lib_stdatomic_h should be defined in c++23" +# endif +# if __cpp_lib_stdatomic_h != 202011L +# error "__cpp_lib_stdatomic_h should have the value 202011L in c++23" +# endif + +# ifndef __cpp_lib_string_contains +# error "__cpp_lib_string_contains should be defined in c++23" +# endif +# if __cpp_lib_string_contains != 202011L +# error "__cpp_lib_string_contains should have the value 202011L in c++23" +# endif + +# ifndef __cpp_lib_string_resize_and_overwrite +# error "__cpp_lib_string_resize_and_overwrite should be defined in c++23" +# endif +# if __cpp_lib_string_resize_and_overwrite != 202110L +# error "__cpp_lib_string_resize_and_overwrite should have the value 202110L in c++23" +# endif + +# ifndef __cpp_lib_string_udls +# error "__cpp_lib_string_udls should be defined in c++23" +# endif +# if __cpp_lib_string_udls != 201304L +# error "__cpp_lib_string_udls should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_string_view +# error "__cpp_lib_string_view should be defined in c++23" +# endif +# if __cpp_lib_string_view != 201803L +# error "__cpp_lib_string_view should have the value 201803L in c++23" +# endif + +# ifdef __cpp_lib_submdspan +# error "__cpp_lib_submdspan should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM +# ifndef __cpp_lib_syncbuf +# error "__cpp_lib_syncbuf should be defined in c++23" +# endif +# if __cpp_lib_syncbuf != 201803L +# error "__cpp_lib_syncbuf should have the value 201803L in c++23" +# endif +# else +# ifdef __cpp_lib_syncbuf +# error "__cpp_lib_syncbuf should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM' is not met!" +# endif +# endif + +# ifdef __cpp_lib_text_encoding +# error "__cpp_lib_text_encoding should not be defined before c++26" +# endif + +# ifndef __cpp_lib_three_way_comparison +# error "__cpp_lib_three_way_comparison should be defined in c++23" +# endif +# if __cpp_lib_three_way_comparison != 201907L +# error "__cpp_lib_three_way_comparison should have the value 201907L in c++23" +# endif + +# ifndef __cpp_lib_to_address +# error "__cpp_lib_to_address should be defined in c++23" +# endif +# if __cpp_lib_to_address != 201711L +# error "__cpp_lib_to_address should have the value 201711L in c++23" +# endif + +# ifndef __cpp_lib_to_array +# error "__cpp_lib_to_array should be defined in c++23" +# endif +# if __cpp_lib_to_array != 201907L +# error "__cpp_lib_to_array should have the value 201907L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should be defined in c++23" +# endif +# if __cpp_lib_to_chars != 201611L +# error "__cpp_lib_to_chars should have the value 201611L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_to_string +# error "__cpp_lib_to_string should not be defined before c++26" +# endif + +# ifndef __cpp_lib_to_underlying +# error "__cpp_lib_to_underlying should be defined in c++23" +# endif +# if __cpp_lib_to_underlying != 202102L +# error "__cpp_lib_to_underlying should have the value 202102L in c++23" +# endif + +# ifndef __cpp_lib_transformation_trait_aliases +# error "__cpp_lib_transformation_trait_aliases should be defined in c++23" +# endif +# if __cpp_lib_transformation_trait_aliases != 201304L +# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_transparent_operators +# error "__cpp_lib_transparent_operators should be defined in c++23" +# endif +# if __cpp_lib_transparent_operators != 201510L +# error "__cpp_lib_transparent_operators should have the value 201510L in c++23" +# endif + +# ifndef __cpp_lib_tuple_element_t +# error "__cpp_lib_tuple_element_t should be defined in c++23" +# endif +# if __cpp_lib_tuple_element_t != 201402L +# error "__cpp_lib_tuple_element_t should have the value 201402L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_tuple_like +# error "__cpp_lib_tuple_like should be defined in c++23" +# endif +# if __cpp_lib_tuple_like != 202207L +# error "__cpp_lib_tuple_like should have the value 202207L in c++23" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_tuple_like +# error "__cpp_lib_tuple_like should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_tuples_by_type +# error "__cpp_lib_tuples_by_type should be defined in c++23" +# endif +# if __cpp_lib_tuples_by_type != 201304L +# error "__cpp_lib_tuples_by_type should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_type_identity +# error "__cpp_lib_type_identity should be defined in c++23" +# endif +# if __cpp_lib_type_identity != 201806L +# error "__cpp_lib_type_identity should have the value 201806L in c++23" +# endif + +# ifndef __cpp_lib_type_trait_variable_templates +# error "__cpp_lib_type_trait_variable_templates should be defined in c++23" +# endif +# if __cpp_lib_type_trait_variable_templates != 201510L +# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++23" +# endif + +# ifndef __cpp_lib_uncaught_exceptions +# error "__cpp_lib_uncaught_exceptions should be defined in c++23" +# endif +# if __cpp_lib_uncaught_exceptions != 201411L +# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++23" +# endif + +# ifndef __cpp_lib_unordered_map_try_emplace +# error "__cpp_lib_unordered_map_try_emplace should be defined in c++23" +# endif +# if __cpp_lib_unordered_map_try_emplace != 201411L +# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++23" +# endif + +# ifndef __cpp_lib_unreachable +# error "__cpp_lib_unreachable should be defined in c++23" +# endif +# if __cpp_lib_unreachable != 202202L +# error "__cpp_lib_unreachable should have the value 202202L in c++23" +# endif + +# ifndef __cpp_lib_unwrap_ref +# error "__cpp_lib_unwrap_ref should be defined in c++23" +# endif +# if __cpp_lib_unwrap_ref != 201811L +# error "__cpp_lib_unwrap_ref should have the value 201811L in c++23" +# endif + +# ifndef __cpp_lib_variant +# error "__cpp_lib_variant should be defined in c++23" +# endif +# if __cpp_lib_variant != 202106L +# error "__cpp_lib_variant should have the value 202106L in c++23" +# endif + +# ifndef __cpp_lib_void_t +# error "__cpp_lib_void_t should be defined in c++23" +# endif +# if __cpp_lib_void_t != 201411L +# error "__cpp_lib_void_t should have the value 201411L in c++23" +# endif -# ifdef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should not be defined before c++17" -# endif +#elif TEST_STD_VER > 23 -# ifdef __cpp_lib_modules -# error "__cpp_lib_modules should not be defined before c++23" -# endif - -# ifdef __cpp_lib_move_iterator_concept -# error "__cpp_lib_move_iterator_concept should not be defined before c++20" -# endif - -# ifdef __cpp_lib_move_only_function -# error "__cpp_lib_move_only_function should not be defined before c++23" -# endif - -# ifdef __cpp_lib_node_extract -# error "__cpp_lib_node_extract should not be defined before c++17" -# endif - -# ifdef __cpp_lib_nonmember_container_access -# error "__cpp_lib_nonmember_container_access should not be defined before c++17" -# endif - -# ifdef __cpp_lib_not_fn -# error "__cpp_lib_not_fn should not be defined before c++17" -# endif - -# ifndef __cpp_lib_null_iterators -# error "__cpp_lib_null_iterators should be defined in c++14" -# endif -# if __cpp_lib_null_iterators != 201304L -# error "__cpp_lib_null_iterators should have the value 201304L in c++14" -# endif - -# ifdef __cpp_lib_optional -# error "__cpp_lib_optional should not be defined before c++17" -# endif - -# ifdef __cpp_lib_optional_range_support -# error "__cpp_lib_optional_range_support should not be defined before c++26" -# endif - -# ifdef __cpp_lib_out_ptr -# error "__cpp_lib_out_ptr should not be defined before c++23" -# endif - -# ifdef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should not be defined before c++17" -# endif - -# ifdef __cpp_lib_philox_engine -# error "__cpp_lib_philox_engine should not be defined before c++26" -# endif - -# ifdef __cpp_lib_polymorphic_allocator -# error "__cpp_lib_polymorphic_allocator should not be defined before c++20" -# endif - -# ifdef __cpp_lib_print -# error "__cpp_lib_print should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION -# ifndef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should be defined in c++14" -# endif -# if __cpp_lib_quoted_string_io != 201304L -# error "__cpp_lib_quoted_string_io should have the value 201304L in c++14" -# endif -# else -# ifdef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" -# endif -# endif - -# ifdef __cpp_lib_ranges -# error "__cpp_lib_ranges should not be defined before c++20" -# endif - -# ifdef __cpp_lib_ranges_as_const -# error "__cpp_lib_ranges_as_const should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_as_rvalue -# error "__cpp_lib_ranges_as_rvalue should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_chunk_by -# error "__cpp_lib_ranges_chunk_by should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_concat -# error "__cpp_lib_ranges_concat should not be defined before c++26" -# endif - -# ifdef __cpp_lib_ranges_contains -# error "__cpp_lib_ranges_contains should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_find_last -# error "__cpp_lib_ranges_find_last should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_indices -# error "__cpp_lib_ranges_indices should not be defined before c++26" -# endif - -# ifdef __cpp_lib_ranges_iota -# error "__cpp_lib_ranges_iota should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_join_with -# error "__cpp_lib_ranges_join_with should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_repeat -# error "__cpp_lib_ranges_repeat should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_slide -# error "__cpp_lib_ranges_slide should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_starts_ends_with -# error "__cpp_lib_ranges_starts_ends_with should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_zip -# error "__cpp_lib_ranges_zip should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ratio -# error "__cpp_lib_ratio should not be defined before c++26" -# endif - -# ifdef __cpp_lib_raw_memory_algorithms -# error "__cpp_lib_raw_memory_algorithms should not be defined before c++17" -# endif - -# ifdef __cpp_lib_rcu -# error "__cpp_lib_rcu should not be defined before c++26" -# endif - -# ifdef __cpp_lib_reference_from_temporary -# error "__cpp_lib_reference_from_temporary should not be defined before c++23" -# endif - -# ifdef __cpp_lib_reference_wrapper -# error "__cpp_lib_reference_wrapper should not be defined before c++26" -# endif - -# ifdef __cpp_lib_remove_cvref -# error "__cpp_lib_remove_cvref should not be defined before c++20" -# endif - -# ifndef __cpp_lib_result_of_sfinae -# error "__cpp_lib_result_of_sfinae should be defined in c++14" -# endif -# if __cpp_lib_result_of_sfinae != 201210L -# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++14" -# endif - -# ifndef __cpp_lib_robust_nonmodifying_seq_ops -# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++14" -# endif -# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L -# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++14" -# endif - -# ifdef __cpp_lib_sample -# error "__cpp_lib_sample should not be defined before c++17" -# endif - -# ifdef __cpp_lib_saturation_arithmetic -# error "__cpp_lib_saturation_arithmetic should not be defined before c++26" -# endif - -# ifdef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should not be defined before c++17" -# endif - -# ifdef __cpp_lib_semaphore -# error "__cpp_lib_semaphore should not be defined before c++20" -# endif - -# ifdef __cpp_lib_senders -# error "__cpp_lib_senders should not be defined before c++26" -# endif - -# ifdef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should not be defined before c++17" -# endif - -# ifdef __cpp_lib_shared_ptr_arrays -# error "__cpp_lib_shared_ptr_arrays should not be defined before c++17" -# endif - -# ifdef __cpp_lib_shared_ptr_weak_type -# error "__cpp_lib_shared_ptr_weak_type should not be defined before c++17" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should be defined in c++14" -# endif -# if __cpp_lib_shared_timed_mutex != 201402L -# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++14" -# endif -# else -# ifdef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifdef __cpp_lib_shift -# error "__cpp_lib_shift should not be defined before c++20" -# endif - -# ifdef __cpp_lib_smart_ptr_for_overwrite -# error "__cpp_lib_smart_ptr_for_overwrite should not be defined before c++20" -# endif - -# ifdef __cpp_lib_smart_ptr_owner_equality -# error "__cpp_lib_smart_ptr_owner_equality should not be defined before c++26" -# endif - -# ifdef __cpp_lib_source_location -# error "__cpp_lib_source_location should not be defined before c++20" -# endif - -# ifdef __cpp_lib_span -# error "__cpp_lib_span should not be defined before c++20" -# endif - -# ifdef __cpp_lib_span_at -# error "__cpp_lib_span_at should not be defined before c++26" -# endif - -# ifdef __cpp_lib_span_initializer_list -# error "__cpp_lib_span_initializer_list should not be defined before c++26" -# endif - -# ifdef __cpp_lib_spanstream -# error "__cpp_lib_spanstream should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ssize -# error "__cpp_lib_ssize should not be defined before c++20" -# endif - -# ifdef __cpp_lib_sstream_from_string_view -# error "__cpp_lib_sstream_from_string_view should not be defined before c++26" -# endif - -# ifdef __cpp_lib_stacktrace -# error "__cpp_lib_stacktrace should not be defined before c++23" -# endif - -# ifdef __cpp_lib_starts_ends_with -# error "__cpp_lib_starts_ends_with should not be defined before c++20" -# endif - -# ifdef __cpp_lib_stdatomic_h -# error "__cpp_lib_stdatomic_h should not be defined before c++23" -# endif - -# ifdef __cpp_lib_string_contains -# error "__cpp_lib_string_contains should not be defined before c++23" -# endif - -# ifdef __cpp_lib_string_resize_and_overwrite -# error "__cpp_lib_string_resize_and_overwrite should not be defined before c++23" -# endif - -# ifdef __cpp_lib_string_subview -# error "__cpp_lib_string_subview should not be defined before c++26" -# endif - -# ifndef __cpp_lib_string_udls -# error "__cpp_lib_string_udls should be defined in c++14" -# endif -# if __cpp_lib_string_udls != 201304L -# error "__cpp_lib_string_udls should have the value 201304L in c++14" -# endif - -# ifdef __cpp_lib_string_view -# error "__cpp_lib_string_view should not be defined before c++17" -# endif - -# ifdef __cpp_lib_submdspan -# error "__cpp_lib_submdspan should not be defined before c++26" -# endif - -# ifdef __cpp_lib_syncbuf -# error "__cpp_lib_syncbuf should not be defined before c++20" -# endif - -# ifdef __cpp_lib_text_encoding -# error "__cpp_lib_text_encoding should not be defined before c++26" -# endif - -# ifdef __cpp_lib_three_way_comparison -# error "__cpp_lib_three_way_comparison should not be defined before c++20" -# endif - -# ifdef __cpp_lib_to_address -# error "__cpp_lib_to_address should not be defined before c++20" -# endif - -# ifdef __cpp_lib_to_array -# error "__cpp_lib_to_array should not be defined before c++20" -# endif - -# ifdef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should not be defined before c++17" -# endif - -# ifdef __cpp_lib_to_string -# error "__cpp_lib_to_string should not be defined before c++26" -# endif - -# ifdef __cpp_lib_to_underlying -# error "__cpp_lib_to_underlying should not be defined before c++23" -# endif - -# ifndef __cpp_lib_transformation_trait_aliases -# error "__cpp_lib_transformation_trait_aliases should be defined in c++14" -# endif -# if __cpp_lib_transformation_trait_aliases != 201304L -# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++14" -# endif - -# ifndef __cpp_lib_transparent_operators -# error "__cpp_lib_transparent_operators should be defined in c++14" -# endif -# if __cpp_lib_transparent_operators != 201210L -# error "__cpp_lib_transparent_operators should have the value 201210L in c++14" -# endif - -# ifndef __cpp_lib_tuple_element_t -# error "__cpp_lib_tuple_element_t should be defined in c++14" -# endif -# if __cpp_lib_tuple_element_t != 201402L -# error "__cpp_lib_tuple_element_t should have the value 201402L in c++14" -# endif - -# ifdef __cpp_lib_tuple_like -# error "__cpp_lib_tuple_like should not be defined before c++23" -# endif - -# ifndef __cpp_lib_tuples_by_type -# error "__cpp_lib_tuples_by_type should be defined in c++14" -# endif -# if __cpp_lib_tuples_by_type != 201304L -# error "__cpp_lib_tuples_by_type should have the value 201304L in c++14" -# endif - -# ifdef __cpp_lib_type_identity -# error "__cpp_lib_type_identity should not be defined before c++20" -# endif - -# ifdef __cpp_lib_type_trait_variable_templates -# error "__cpp_lib_type_trait_variable_templates should not be defined before c++17" -# endif - -# ifdef __cpp_lib_uncaught_exceptions -# error "__cpp_lib_uncaught_exceptions should not be defined before c++17" -# endif - -# ifdef __cpp_lib_unordered_map_try_emplace -# error "__cpp_lib_unordered_map_try_emplace should not be defined before c++17" -# endif - -# ifdef __cpp_lib_unreachable -# error "__cpp_lib_unreachable should not be defined before c++23" -# endif - -# ifdef __cpp_lib_unwrap_ref -# error "__cpp_lib_unwrap_ref should not be defined before c++20" -# endif - -# ifdef __cpp_lib_variant -# error "__cpp_lib_variant should not be defined before c++17" -# endif - -# ifdef __cpp_lib_void_t -# error "__cpp_lib_void_t should not be defined before c++17" -# endif - -#elif TEST_STD_VER == 17 - -# ifdef __cpp_lib_adaptor_iterator_pair_constructor -# error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++23" -# endif - -# ifndef __cpp_lib_addressof_constexpr -# error "__cpp_lib_addressof_constexpr should be defined in c++17" -# endif -# if __cpp_lib_addressof_constexpr != 201603L -# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++17" -# endif - -# ifdef __cpp_lib_aligned_accessor -# error "__cpp_lib_aligned_accessor should not be defined before c++26" -# endif - -# ifdef __cpp_lib_allocate_at_least -# error "__cpp_lib_allocate_at_least should not be defined before c++23" -# endif - -# ifndef __cpp_lib_allocator_traits_is_always_equal -# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++17" -# endif -# if __cpp_lib_allocator_traits_is_always_equal != 201411L -# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17" -# endif - -# ifndef __cpp_lib_any -# error "__cpp_lib_any should be defined in c++17" -# endif -# if __cpp_lib_any != 201606L -# error "__cpp_lib_any should have the value 201606L in c++17" -# endif - -# ifndef __cpp_lib_apply -# error "__cpp_lib_apply should be defined in c++17" -# endif -# if __cpp_lib_apply != 201603L -# error "__cpp_lib_apply should have the value 201603L in c++17" -# endif - -# ifndef __cpp_lib_array_constexpr -# error "__cpp_lib_array_constexpr should be defined in c++17" -# endif -# if __cpp_lib_array_constexpr != 201603L -# error "__cpp_lib_array_constexpr should have the value 201603L in c++17" -# endif - -# ifndef __cpp_lib_as_const -# error "__cpp_lib_as_const should be defined in c++17" -# endif -# if __cpp_lib_as_const != 201510L -# error "__cpp_lib_as_const should have the value 201510L in c++17" -# endif - -# ifdef __cpp_lib_associative_heterogeneous_erasure -# error "__cpp_lib_associative_heterogeneous_erasure should not be defined before c++23" -# endif - -# ifdef __cpp_lib_associative_heterogeneous_insertion -# error "__cpp_lib_associative_heterogeneous_insertion should not be defined before c++26" -# endif - -# ifdef __cpp_lib_assume_aligned -# error "__cpp_lib_assume_aligned should not be defined before c++20" -# endif - -# ifdef __cpp_lib_atomic_flag_test -# error "__cpp_lib_atomic_flag_test should not be defined before c++20" -# endif - -# ifdef __cpp_lib_atomic_float -# error "__cpp_lib_atomic_float should not be defined before c++20" -# endif - -# ifndef __cpp_lib_atomic_is_always_lock_free -# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++17" -# endif -# if __cpp_lib_atomic_is_always_lock_free != 201603L -# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++17" -# endif - -# ifdef __cpp_lib_atomic_lock_free_type_aliases -# error "__cpp_lib_atomic_lock_free_type_aliases should not be defined before c++20" -# endif - -# ifdef __cpp_lib_atomic_min_max -# error "__cpp_lib_atomic_min_max should not be defined before c++26" -# endif - -# ifdef __cpp_lib_atomic_ref -# error "__cpp_lib_atomic_ref should not be defined before c++20" -# endif - -# ifdef __cpp_lib_atomic_shared_ptr -# error "__cpp_lib_atomic_shared_ptr should not be defined before c++20" -# endif - -# ifdef __cpp_lib_atomic_value_initialization -# error "__cpp_lib_atomic_value_initialization should not be defined before c++20" -# endif - -# ifdef __cpp_lib_atomic_wait -# error "__cpp_lib_atomic_wait should not be defined before c++20" -# endif - -# ifdef __cpp_lib_barrier -# error "__cpp_lib_barrier should not be defined before c++20" -# endif - -# ifdef __cpp_lib_bind_back -# error "__cpp_lib_bind_back should not be defined before c++23" -# endif - -# ifdef __cpp_lib_bind_front -# error "__cpp_lib_bind_front should not be defined before c++20" -# endif - -# ifdef __cpp_lib_bit_cast -# error "__cpp_lib_bit_cast should not be defined before c++20" -# endif - -# ifdef __cpp_lib_bitops -# error "__cpp_lib_bitops should not be defined before c++20" -# endif - -# ifdef __cpp_lib_bitset -# error "__cpp_lib_bitset should not be defined before c++26" -# endif - -# ifndef __cpp_lib_bool_constant -# error "__cpp_lib_bool_constant should be defined in c++17" -# endif -# if __cpp_lib_bool_constant != 201505L -# error "__cpp_lib_bool_constant should have the value 201505L in c++17" -# endif - -# ifdef __cpp_lib_bounded_array_traits -# error "__cpp_lib_bounded_array_traits should not be defined before c++20" -# endif - -# ifndef __cpp_lib_boyer_moore_searcher -# error "__cpp_lib_boyer_moore_searcher should be defined in c++17" -# endif -# if __cpp_lib_boyer_moore_searcher != 201603L -# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++17" -# endif - -# ifndef __cpp_lib_byte -# error "__cpp_lib_byte should be defined in c++17" -# endif -# if __cpp_lib_byte != 201603L -# error "__cpp_lib_byte should have the value 201603L in c++17" -# endif - -# ifdef __cpp_lib_byteswap -# error "__cpp_lib_byteswap should not be defined before c++23" -# endif - -# ifdef __cpp_lib_char8_t -# error "__cpp_lib_char8_t should not be defined before c++20" -# endif - -# ifndef __cpp_lib_chrono -# error "__cpp_lib_chrono should be defined in c++17" -# endif -# if __cpp_lib_chrono != 201611L -# error "__cpp_lib_chrono should have the value 201611L in c++17" -# endif - -# ifndef __cpp_lib_chrono_udls -# error "__cpp_lib_chrono_udls should be defined in c++17" -# endif -# if __cpp_lib_chrono_udls != 201304L -# error "__cpp_lib_chrono_udls should have the value 201304L in c++17" -# endif - -# ifndef __cpp_lib_clamp -# error "__cpp_lib_clamp should be defined in c++17" -# endif -# if __cpp_lib_clamp != 201603L -# error "__cpp_lib_clamp should have the value 201603L in c++17" -# endif - -# ifdef __cpp_lib_common_reference -# error "__cpp_lib_common_reference should not be defined before c++20" -# endif - -# ifdef __cpp_lib_common_reference_wrapper -# error "__cpp_lib_common_reference_wrapper should not be defined before c++20" -# endif - -# ifndef __cpp_lib_complex_udls -# error "__cpp_lib_complex_udls should be defined in c++17" -# endif -# if __cpp_lib_complex_udls != 201309L -# error "__cpp_lib_complex_udls should have the value 201309L in c++17" -# endif - -# ifdef __cpp_lib_concepts -# error "__cpp_lib_concepts should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_algorithms -# error "__cpp_lib_constexpr_algorithms should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_bitset -# error "__cpp_lib_constexpr_bitset should not be defined before c++23" -# endif - -# ifdef __cpp_lib_constexpr_charconv -# error "__cpp_lib_constexpr_charconv should not be defined before c++23" -# endif - -# ifdef __cpp_lib_constexpr_cmath -# error "__cpp_lib_constexpr_cmath should not be defined before c++23" -# endif - -# ifdef __cpp_lib_constexpr_complex -# error "__cpp_lib_constexpr_complex should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_dynamic_alloc -# error "__cpp_lib_constexpr_dynamic_alloc should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_forward_list -# error "__cpp_lib_constexpr_forward_list should not be defined before c++26" -# endif - -# ifdef __cpp_lib_constexpr_functional -# error "__cpp_lib_constexpr_functional should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_iterator -# error "__cpp_lib_constexpr_iterator should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_list -# error "__cpp_lib_constexpr_list should not be defined before c++26" -# endif - -# ifdef __cpp_lib_constexpr_memory -# error "__cpp_lib_constexpr_memory should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_new -# error "__cpp_lib_constexpr_new should not be defined before c++26" -# endif - -# ifdef __cpp_lib_constexpr_numeric -# error "__cpp_lib_constexpr_numeric should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_queue -# error "__cpp_lib_constexpr_queue should not be defined before c++26" -# endif - -# ifdef __cpp_lib_constexpr_string -# error "__cpp_lib_constexpr_string should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_string_view -# error "__cpp_lib_constexpr_string_view should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_tuple -# error "__cpp_lib_constexpr_tuple should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_typeinfo -# error "__cpp_lib_constexpr_typeinfo should not be defined before c++23" -# endif - -# ifdef __cpp_lib_constexpr_utility -# error "__cpp_lib_constexpr_utility should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_vector -# error "__cpp_lib_constexpr_vector should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constrained_equality -# error "__cpp_lib_constrained_equality should not be defined before c++26" -# endif - -# ifdef __cpp_lib_containers_ranges -# error "__cpp_lib_containers_ranges should not be defined before c++23" -# endif - -# ifdef __cpp_lib_copyable_function -# error "__cpp_lib_copyable_function should not be defined before c++26" -# endif - -# ifdef __cpp_lib_coroutine -# error "__cpp_lib_coroutine should not be defined before c++20" -# endif - -# ifdef __cpp_lib_debugging -# error "__cpp_lib_debugging should not be defined before c++26" -# endif - -# ifdef __cpp_lib_default_template_type_for_algorithm_values -# error "__cpp_lib_default_template_type_for_algorithm_values should not be defined before c++26" -# endif - -# ifdef __cpp_lib_destroying_delete -# error "__cpp_lib_destroying_delete should not be defined before c++20" -# endif - -# ifndef __cpp_lib_enable_shared_from_this -# error "__cpp_lib_enable_shared_from_this should be defined in c++17" -# endif -# if __cpp_lib_enable_shared_from_this != 201603L -# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++17" -# endif - -# ifdef __cpp_lib_endian -# error "__cpp_lib_endian should not be defined before c++20" -# endif - -# ifdef __cpp_lib_erase_if -# error "__cpp_lib_erase_if should not be defined before c++20" -# endif - -# ifndef __cpp_lib_exchange_function -# error "__cpp_lib_exchange_function should be defined in c++17" -# endif -# if __cpp_lib_exchange_function != 201304L -# error "__cpp_lib_exchange_function should have the value 201304L in c++17" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_execution -# error "__cpp_lib_execution should be defined in c++17" -# endif -# if __cpp_lib_execution != 201603L -# error "__cpp_lib_execution should have the value 201603L in c++17" -# endif -# else -# ifdef __cpp_lib_execution -# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_expected -# error "__cpp_lib_expected should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY) -# ifndef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should be defined in c++17" -# endif -# if __cpp_lib_filesystem != 201703L -# error "__cpp_lib_filesystem should have the value 201703L in c++17" -# endif -# else -# ifdef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)' is not met!" -# endif -# endif - -# ifdef __cpp_lib_flat_map -# error "__cpp_lib_flat_map should not be defined before c++23" -# endif - -# ifdef __cpp_lib_flat_set -# error "__cpp_lib_flat_set should not be defined before c++23" -# endif - -# ifdef __cpp_lib_format -# error "__cpp_lib_format should not be defined before c++20" -# endif - -# ifdef __cpp_lib_format_path -# error "__cpp_lib_format_path should not be defined before c++26" -# endif - -# ifdef __cpp_lib_format_ranges -# error "__cpp_lib_format_ranges should not be defined before c++23" -# endif - -# ifdef __cpp_lib_format_uchar -# error "__cpp_lib_format_uchar should not be defined before c++20" -# endif - -# ifdef __cpp_lib_formatters -# error "__cpp_lib_formatters should not be defined before c++23" -# endif - -# ifdef __cpp_lib_forward_like -# error "__cpp_lib_forward_like should not be defined before c++23" -# endif - -# ifdef __cpp_lib_freestanding_algorithm -# error "__cpp_lib_freestanding_algorithm should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_array -# error "__cpp_lib_freestanding_array should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_cstring -# error "__cpp_lib_freestanding_cstring should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_expected -# error "__cpp_lib_freestanding_expected should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_mdspan -# error "__cpp_lib_freestanding_mdspan should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_optional -# error "__cpp_lib_freestanding_optional should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_string_view -# error "__cpp_lib_freestanding_string_view should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_variant -# error "__cpp_lib_freestanding_variant should not be defined before c++26" -# endif - -# ifdef __cpp_lib_fstream_native_handle -# error "__cpp_lib_fstream_native_handle should not be defined before c++26" -# endif - -# ifdef __cpp_lib_function_ref -# error "__cpp_lib_function_ref should not be defined before c++26" -# endif - -# ifndef __cpp_lib_gcd_lcm -# error "__cpp_lib_gcd_lcm should be defined in c++17" -# endif -# if __cpp_lib_gcd_lcm != 201606L -# error "__cpp_lib_gcd_lcm should have the value 201606L in c++17" -# endif - -# ifdef __cpp_lib_generate_random -# error "__cpp_lib_generate_random should not be defined before c++26" -# endif - -# ifndef __cpp_lib_generic_associative_lookup -# error "__cpp_lib_generic_associative_lookup should be defined in c++17" -# endif -# if __cpp_lib_generic_associative_lookup != 201304L -# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++17" -# endif - -# ifdef __cpp_lib_generic_unordered_lookup -# error "__cpp_lib_generic_unordered_lookup should not be defined before c++20" -# endif - -# if !defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)) -# ifndef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should be defined in c++17" -# endif -# if __cpp_lib_hardware_interference_size != 201703L -# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++17" -# endif -# else -# ifdef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))' is not met!" -# endif -# endif - -# ifndef __cpp_lib_has_unique_object_representations -# error "__cpp_lib_has_unique_object_representations should be defined in c++17" -# endif -# if __cpp_lib_has_unique_object_representations != 201606L -# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++17" -# endif - -# ifdef __cpp_lib_hazard_pointer -# error "__cpp_lib_hazard_pointer should not be defined before c++26" -# endif - -# ifndef __cpp_lib_hypot -# error "__cpp_lib_hypot should be defined in c++17" -# endif -# if __cpp_lib_hypot != 201603L -# error "__cpp_lib_hypot should have the value 201603L in c++17" -# endif - -# ifndef __cpp_lib_incomplete_container_elements -# error "__cpp_lib_incomplete_container_elements should be defined in c++17" -# endif -# if __cpp_lib_incomplete_container_elements != 201505L -# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++17" -# endif - -# ifdef __cpp_lib_inplace_vector -# error "__cpp_lib_inplace_vector should not be defined before c++26" -# endif - -# ifdef __cpp_lib_int_pow2 -# error "__cpp_lib_int_pow2 should not be defined before c++20" -# endif - -# ifdef __cpp_lib_integer_comparison_functions -# error "__cpp_lib_integer_comparison_functions should not be defined before c++20" -# endif - -# ifndef __cpp_lib_integer_sequence -# error "__cpp_lib_integer_sequence should be defined in c++17" -# endif -# if __cpp_lib_integer_sequence != 201304L -# error "__cpp_lib_integer_sequence should have the value 201304L in c++17" -# endif - -# ifndef __cpp_lib_integral_constant_callable -# error "__cpp_lib_integral_constant_callable should be defined in c++17" -# endif -# if __cpp_lib_integral_constant_callable != 201304L -# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++17" -# endif - -# ifdef __cpp_lib_interpolate -# error "__cpp_lib_interpolate should not be defined before c++20" -# endif - -# ifndef __cpp_lib_invoke -# error "__cpp_lib_invoke should be defined in c++17" -# endif -# if __cpp_lib_invoke != 201411L -# error "__cpp_lib_invoke should have the value 201411L in c++17" -# endif - -# ifdef __cpp_lib_invoke_r -# error "__cpp_lib_invoke_r should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ios_noreplace -# error "__cpp_lib_ios_noreplace should not be defined before c++23" -# endif - -# ifndef __cpp_lib_is_aggregate -# error "__cpp_lib_is_aggregate should be defined in c++17" -# endif -# if __cpp_lib_is_aggregate != 201703L -# error "__cpp_lib_is_aggregate should have the value 201703L in c++17" -# endif - -# ifdef __cpp_lib_is_constant_evaluated -# error "__cpp_lib_is_constant_evaluated should not be defined before c++20" -# endif - -# ifndef __cpp_lib_is_final -# error "__cpp_lib_is_final should be defined in c++17" -# endif -# if __cpp_lib_is_final != 201402L -# error "__cpp_lib_is_final should have the value 201402L in c++17" -# endif - -# ifdef __cpp_lib_is_implicit_lifetime -# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" -# endif - -# ifndef __cpp_lib_is_invocable -# error "__cpp_lib_is_invocable should be defined in c++17" -# endif -# if __cpp_lib_is_invocable != 201703L -# error "__cpp_lib_is_invocable should have the value 201703L in c++17" -# endif - -# ifdef __cpp_lib_is_layout_compatible -# error "__cpp_lib_is_layout_compatible should not be defined before c++20" -# endif - -# ifdef __cpp_lib_is_nothrow_convertible -# error "__cpp_lib_is_nothrow_convertible should not be defined before c++20" -# endif - -# ifndef __cpp_lib_is_null_pointer -# error "__cpp_lib_is_null_pointer should be defined in c++17" -# endif -# if __cpp_lib_is_null_pointer != 201309L -# error "__cpp_lib_is_null_pointer should have the value 201309L in c++17" -# endif - -# ifdef __cpp_lib_is_pointer_interconvertible -# error "__cpp_lib_is_pointer_interconvertible should not be defined before c++20" -# endif - -# ifdef __cpp_lib_is_scoped_enum -# error "__cpp_lib_is_scoped_enum should not be defined before c++23" -# endif - -# ifdef __cpp_lib_is_sufficiently_aligned -# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" -# endif - -# ifndef __cpp_lib_is_swappable -# error "__cpp_lib_is_swappable should be defined in c++17" -# endif -# if __cpp_lib_is_swappable != 201603L -# error "__cpp_lib_is_swappable should have the value 201603L in c++17" -# endif - -# ifdef __cpp_lib_is_virtual_base_of -# error "__cpp_lib_is_virtual_base_of should not be defined before c++26" -# endif - -# ifdef __cpp_lib_is_within_lifetime -# error "__cpp_lib_is_within_lifetime should not be defined before c++26" -# endif - -# ifdef __cpp_lib_jthread -# error "__cpp_lib_jthread should not be defined before c++20" -# endif - -# ifdef __cpp_lib_latch -# error "__cpp_lib_latch should not be defined before c++20" -# endif - -# ifndef __cpp_lib_launder -# error "__cpp_lib_launder should be defined in c++17" -# endif -# if __cpp_lib_launder != 201606L -# error "__cpp_lib_launder should have the value 201606L in c++17" -# endif - -# ifdef __cpp_lib_linalg -# error "__cpp_lib_linalg should not be defined before c++26" -# endif - -# ifdef __cpp_lib_list_remove_return_type -# error "__cpp_lib_list_remove_return_type should not be defined before c++20" -# endif - -# ifndef __cpp_lib_logical_traits -# error "__cpp_lib_logical_traits should be defined in c++17" -# endif -# if __cpp_lib_logical_traits != 201510L -# error "__cpp_lib_logical_traits should have the value 201510L in c++17" -# endif - -# ifndef __cpp_lib_make_from_tuple -# error "__cpp_lib_make_from_tuple should be defined in c++17" -# endif -# if __cpp_lib_make_from_tuple != 201606L -# error "__cpp_lib_make_from_tuple should have the value 201606L in c++17" -# endif - -# ifndef __cpp_lib_make_reverse_iterator -# error "__cpp_lib_make_reverse_iterator should be defined in c++17" -# endif -# if __cpp_lib_make_reverse_iterator != 201402L -# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++17" -# endif - -# ifndef __cpp_lib_make_unique -# error "__cpp_lib_make_unique should be defined in c++17" -# endif -# if __cpp_lib_make_unique != 201304L -# error "__cpp_lib_make_unique should have the value 201304L in c++17" -# endif - -# ifndef __cpp_lib_map_try_emplace -# error "__cpp_lib_map_try_emplace should be defined in c++17" -# endif -# if __cpp_lib_map_try_emplace != 201411L -# error "__cpp_lib_map_try_emplace should have the value 201411L in c++17" -# endif - -# ifdef __cpp_lib_math_constants -# error "__cpp_lib_math_constants should not be defined before c++20" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should be defined in c++17" -# endif -# if __cpp_lib_math_special_functions != 201603L -# error "__cpp_lib_math_special_functions should have the value 201603L in c++17" -# endif -# else -# ifdef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_mdspan -# error "__cpp_lib_mdspan should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR -# ifndef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should be defined in c++17" -# endif -# if __cpp_lib_memory_resource != 201603L -# error "__cpp_lib_memory_resource should have the value 201603L in c++17" -# endif -# else -# ifdef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" -# endif -# endif - -# ifdef __cpp_lib_modules -# error "__cpp_lib_modules should not be defined before c++23" -# endif - -# ifdef __cpp_lib_move_iterator_concept -# error "__cpp_lib_move_iterator_concept should not be defined before c++20" -# endif - -# ifdef __cpp_lib_move_only_function -# error "__cpp_lib_move_only_function should not be defined before c++23" -# endif - -# ifndef __cpp_lib_node_extract -# error "__cpp_lib_node_extract should be defined in c++17" -# endif -# if __cpp_lib_node_extract != 201606L -# error "__cpp_lib_node_extract should have the value 201606L in c++17" -# endif - -# ifndef __cpp_lib_nonmember_container_access -# error "__cpp_lib_nonmember_container_access should be defined in c++17" -# endif -# if __cpp_lib_nonmember_container_access != 201411L -# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++17" -# endif - -# ifndef __cpp_lib_not_fn -# error "__cpp_lib_not_fn should be defined in c++17" -# endif -# if __cpp_lib_not_fn != 201603L -# error "__cpp_lib_not_fn should have the value 201603L in c++17" -# endif - -# ifndef __cpp_lib_null_iterators -# error "__cpp_lib_null_iterators should be defined in c++17" -# endif -# if __cpp_lib_null_iterators != 201304L -# error "__cpp_lib_null_iterators should have the value 201304L in c++17" -# endif - -# ifndef __cpp_lib_optional -# error "__cpp_lib_optional should be defined in c++17" -# endif -# if __cpp_lib_optional != 201606L -# error "__cpp_lib_optional should have the value 201606L in c++17" -# endif - -# ifdef __cpp_lib_optional_range_support -# error "__cpp_lib_optional_range_support should not be defined before c++26" -# endif - -# ifdef __cpp_lib_out_ptr -# error "__cpp_lib_out_ptr should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should be defined in c++17" -# endif -# if __cpp_lib_parallel_algorithm != 201603L -# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++17" -# endif -# else -# ifdef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_philox_engine -# error "__cpp_lib_philox_engine should not be defined before c++26" -# endif - -# ifdef __cpp_lib_polymorphic_allocator -# error "__cpp_lib_polymorphic_allocator should not be defined before c++20" -# endif - -# ifdef __cpp_lib_print -# error "__cpp_lib_print should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION -# ifndef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should be defined in c++17" -# endif -# if __cpp_lib_quoted_string_io != 201304L -# error "__cpp_lib_quoted_string_io should have the value 201304L in c++17" -# endif -# else -# ifdef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" -# endif -# endif - -# ifdef __cpp_lib_ranges -# error "__cpp_lib_ranges should not be defined before c++20" -# endif - -# ifdef __cpp_lib_ranges_as_const -# error "__cpp_lib_ranges_as_const should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_as_rvalue -# error "__cpp_lib_ranges_as_rvalue should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_chunk_by -# error "__cpp_lib_ranges_chunk_by should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_concat -# error "__cpp_lib_ranges_concat should not be defined before c++26" -# endif - -# ifdef __cpp_lib_ranges_contains -# error "__cpp_lib_ranges_contains should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_find_last -# error "__cpp_lib_ranges_find_last should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_indices -# error "__cpp_lib_ranges_indices should not be defined before c++26" -# endif - -# ifdef __cpp_lib_ranges_iota -# error "__cpp_lib_ranges_iota should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_join_with -# error "__cpp_lib_ranges_join_with should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_repeat -# error "__cpp_lib_ranges_repeat should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_slide -# error "__cpp_lib_ranges_slide should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_starts_ends_with -# error "__cpp_lib_ranges_starts_ends_with should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_zip -# error "__cpp_lib_ranges_zip should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ratio -# error "__cpp_lib_ratio should not be defined before c++26" -# endif - -# ifndef __cpp_lib_raw_memory_algorithms -# error "__cpp_lib_raw_memory_algorithms should be defined in c++17" -# endif -# if __cpp_lib_raw_memory_algorithms != 201606L -# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++17" -# endif - -# ifdef __cpp_lib_rcu -# error "__cpp_lib_rcu should not be defined before c++26" -# endif - -# ifdef __cpp_lib_reference_from_temporary -# error "__cpp_lib_reference_from_temporary should not be defined before c++23" -# endif - -# ifdef __cpp_lib_reference_wrapper -# error "__cpp_lib_reference_wrapper should not be defined before c++26" -# endif - -# ifdef __cpp_lib_remove_cvref -# error "__cpp_lib_remove_cvref should not be defined before c++20" -# endif - -# ifndef __cpp_lib_result_of_sfinae -# error "__cpp_lib_result_of_sfinae should be defined in c++17" -# endif -# if __cpp_lib_result_of_sfinae != 201210L -# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++17" -# endif - -# ifndef __cpp_lib_robust_nonmodifying_seq_ops -# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++17" -# endif -# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L -# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++17" -# endif - -# ifndef __cpp_lib_sample -# error "__cpp_lib_sample should be defined in c++17" -# endif -# if __cpp_lib_sample != 201603L -# error "__cpp_lib_sample should have the value 201603L in c++17" -# endif - -# ifdef __cpp_lib_saturation_arithmetic -# error "__cpp_lib_saturation_arithmetic should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should be defined in c++17" -# endif -# if __cpp_lib_scoped_lock != 201703L -# error "__cpp_lib_scoped_lock should have the value 201703L in c++17" -# endif -# else -# ifdef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifdef __cpp_lib_semaphore -# error "__cpp_lib_semaphore should not be defined before c++20" -# endif - -# ifdef __cpp_lib_senders -# error "__cpp_lib_senders should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should be defined in c++17" -# endif -# if __cpp_lib_shared_mutex != 201505L -# error "__cpp_lib_shared_mutex should have the value 201505L in c++17" -# endif -# else -# ifdef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifndef __cpp_lib_shared_ptr_arrays -# error "__cpp_lib_shared_ptr_arrays should be defined in c++17" -# endif -# if __cpp_lib_shared_ptr_arrays != 201611L -# error "__cpp_lib_shared_ptr_arrays should have the value 201611L in c++17" -# endif - -# ifndef __cpp_lib_shared_ptr_weak_type -# error "__cpp_lib_shared_ptr_weak_type should be defined in c++17" -# endif -# if __cpp_lib_shared_ptr_weak_type != 201606L -# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++17" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should be defined in c++17" -# endif -# if __cpp_lib_shared_timed_mutex != 201402L -# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++17" -# endif -# else -# ifdef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifdef __cpp_lib_shift -# error "__cpp_lib_shift should not be defined before c++20" -# endif - -# ifdef __cpp_lib_smart_ptr_for_overwrite -# error "__cpp_lib_smart_ptr_for_overwrite should not be defined before c++20" -# endif - -# ifdef __cpp_lib_smart_ptr_owner_equality -# error "__cpp_lib_smart_ptr_owner_equality should not be defined before c++26" -# endif - -# ifdef __cpp_lib_source_location -# error "__cpp_lib_source_location should not be defined before c++20" -# endif - -# ifdef __cpp_lib_span -# error "__cpp_lib_span should not be defined before c++20" -# endif - -# ifdef __cpp_lib_span_at -# error "__cpp_lib_span_at should not be defined before c++26" -# endif - -# ifdef __cpp_lib_span_initializer_list -# error "__cpp_lib_span_initializer_list should not be defined before c++26" -# endif - -# ifdef __cpp_lib_spanstream -# error "__cpp_lib_spanstream should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ssize -# error "__cpp_lib_ssize should not be defined before c++20" -# endif - -# ifdef __cpp_lib_sstream_from_string_view -# error "__cpp_lib_sstream_from_string_view should not be defined before c++26" -# endif - -# ifdef __cpp_lib_stacktrace -# error "__cpp_lib_stacktrace should not be defined before c++23" -# endif - -# ifdef __cpp_lib_starts_ends_with -# error "__cpp_lib_starts_ends_with should not be defined before c++20" -# endif - -# ifdef __cpp_lib_stdatomic_h -# error "__cpp_lib_stdatomic_h should not be defined before c++23" -# endif - -# ifdef __cpp_lib_string_contains -# error "__cpp_lib_string_contains should not be defined before c++23" -# endif - -# ifdef __cpp_lib_string_resize_and_overwrite -# error "__cpp_lib_string_resize_and_overwrite should not be defined before c++23" -# endif - -# ifdef __cpp_lib_string_subview -# error "__cpp_lib_string_subview should not be defined before c++26" -# endif - -# ifndef __cpp_lib_string_udls -# error "__cpp_lib_string_udls should be defined in c++17" -# endif -# if __cpp_lib_string_udls != 201304L -# error "__cpp_lib_string_udls should have the value 201304L in c++17" -# endif - -# ifndef __cpp_lib_string_view -# error "__cpp_lib_string_view should be defined in c++17" -# endif -# if __cpp_lib_string_view != 201606L -# error "__cpp_lib_string_view should have the value 201606L in c++17" -# endif - -# ifdef __cpp_lib_submdspan -# error "__cpp_lib_submdspan should not be defined before c++26" -# endif - -# ifdef __cpp_lib_syncbuf -# error "__cpp_lib_syncbuf should not be defined before c++20" -# endif - -# ifdef __cpp_lib_text_encoding -# error "__cpp_lib_text_encoding should not be defined before c++26" -# endif - -# ifdef __cpp_lib_three_way_comparison -# error "__cpp_lib_three_way_comparison should not be defined before c++20" -# endif - -# ifdef __cpp_lib_to_address -# error "__cpp_lib_to_address should not be defined before c++20" -# endif - -# ifdef __cpp_lib_to_array -# error "__cpp_lib_to_array should not be defined before c++20" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should be defined in c++17" -# endif -# if __cpp_lib_to_chars != 201611L -# error "__cpp_lib_to_chars should have the value 201611L in c++17" -# endif -# else -# ifdef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_to_string -# error "__cpp_lib_to_string should not be defined before c++26" -# endif - -# ifdef __cpp_lib_to_underlying -# error "__cpp_lib_to_underlying should not be defined before c++23" -# endif - -# ifndef __cpp_lib_transformation_trait_aliases -# error "__cpp_lib_transformation_trait_aliases should be defined in c++17" -# endif -# if __cpp_lib_transformation_trait_aliases != 201304L -# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++17" -# endif - -# ifndef __cpp_lib_transparent_operators -# error "__cpp_lib_transparent_operators should be defined in c++17" -# endif -# if __cpp_lib_transparent_operators != 201510L -# error "__cpp_lib_transparent_operators should have the value 201510L in c++17" -# endif - -# ifndef __cpp_lib_tuple_element_t -# error "__cpp_lib_tuple_element_t should be defined in c++17" -# endif -# if __cpp_lib_tuple_element_t != 201402L -# error "__cpp_lib_tuple_element_t should have the value 201402L in c++17" -# endif - -# ifdef __cpp_lib_tuple_like -# error "__cpp_lib_tuple_like should not be defined before c++23" -# endif - -# ifndef __cpp_lib_tuples_by_type -# error "__cpp_lib_tuples_by_type should be defined in c++17" -# endif -# if __cpp_lib_tuples_by_type != 201304L -# error "__cpp_lib_tuples_by_type should have the value 201304L in c++17" -# endif - -# ifdef __cpp_lib_type_identity -# error "__cpp_lib_type_identity should not be defined before c++20" -# endif - -# ifndef __cpp_lib_type_trait_variable_templates -# error "__cpp_lib_type_trait_variable_templates should be defined in c++17" -# endif -# if __cpp_lib_type_trait_variable_templates != 201510L -# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++17" -# endif - -# ifndef __cpp_lib_uncaught_exceptions -# error "__cpp_lib_uncaught_exceptions should be defined in c++17" -# endif -# if __cpp_lib_uncaught_exceptions != 201411L -# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++17" -# endif - -# ifndef __cpp_lib_unordered_map_try_emplace -# error "__cpp_lib_unordered_map_try_emplace should be defined in c++17" -# endif -# if __cpp_lib_unordered_map_try_emplace != 201411L -# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++17" -# endif - -# ifdef __cpp_lib_unreachable -# error "__cpp_lib_unreachable should not be defined before c++23" -# endif - -# ifdef __cpp_lib_unwrap_ref -# error "__cpp_lib_unwrap_ref should not be defined before c++20" -# endif - -# ifndef __cpp_lib_variant -# error "__cpp_lib_variant should be defined in c++17" -# endif -# if __cpp_lib_variant != 202102L -# error "__cpp_lib_variant should have the value 202102L in c++17" -# endif - -# ifndef __cpp_lib_void_t -# error "__cpp_lib_void_t should be defined in c++17" -# endif -# if __cpp_lib_void_t != 201411L -# error "__cpp_lib_void_t should have the value 201411L in c++17" -# endif - -#elif TEST_STD_VER == 20 - -# ifdef __cpp_lib_adaptor_iterator_pair_constructor -# error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++23" -# endif - -# ifndef __cpp_lib_addressof_constexpr -# error "__cpp_lib_addressof_constexpr should be defined in c++20" -# endif -# if __cpp_lib_addressof_constexpr != 201603L -# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++20" -# endif - -# ifdef __cpp_lib_aligned_accessor -# error "__cpp_lib_aligned_accessor should not be defined before c++26" -# endif - -# ifdef __cpp_lib_allocate_at_least -# error "__cpp_lib_allocate_at_least should not be defined before c++23" -# endif - -# ifndef __cpp_lib_allocator_traits_is_always_equal -# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++20" -# endif -# if __cpp_lib_allocator_traits_is_always_equal != 201411L -# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++20" -# endif - -# ifndef __cpp_lib_any -# error "__cpp_lib_any should be defined in c++20" -# endif -# if __cpp_lib_any != 201606L -# error "__cpp_lib_any should have the value 201606L in c++20" -# endif - -# ifndef __cpp_lib_apply -# error "__cpp_lib_apply should be defined in c++20" -# endif -# if __cpp_lib_apply != 201603L -# error "__cpp_lib_apply should have the value 201603L in c++20" -# endif - -# ifndef __cpp_lib_array_constexpr -# error "__cpp_lib_array_constexpr should be defined in c++20" -# endif -# if __cpp_lib_array_constexpr != 201811L -# error "__cpp_lib_array_constexpr should have the value 201811L in c++20" -# endif - -# ifndef __cpp_lib_as_const -# error "__cpp_lib_as_const should be defined in c++20" -# endif -# if __cpp_lib_as_const != 201510L -# error "__cpp_lib_as_const should have the value 201510L in c++20" -# endif - -# ifdef __cpp_lib_associative_heterogeneous_erasure -# error "__cpp_lib_associative_heterogeneous_erasure should not be defined before c++23" -# endif - -# ifdef __cpp_lib_associative_heterogeneous_insertion -# error "__cpp_lib_associative_heterogeneous_insertion should not be defined before c++26" -# endif - -# ifndef __cpp_lib_assume_aligned -# error "__cpp_lib_assume_aligned should be defined in c++20" -# endif -# if __cpp_lib_assume_aligned != 201811L -# error "__cpp_lib_assume_aligned should have the value 201811L in c++20" -# endif - -# ifndef __cpp_lib_atomic_flag_test -# error "__cpp_lib_atomic_flag_test should be defined in c++20" -# endif -# if __cpp_lib_atomic_flag_test != 201907L -# error "__cpp_lib_atomic_flag_test should have the value 201907L in c++20" -# endif - -# ifndef __cpp_lib_atomic_float -# error "__cpp_lib_atomic_float should be defined in c++20" -# endif -# if __cpp_lib_atomic_float != 201711L -# error "__cpp_lib_atomic_float should have the value 201711L in c++20" -# endif - -# ifndef __cpp_lib_atomic_is_always_lock_free -# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++20" -# endif -# if __cpp_lib_atomic_is_always_lock_free != 201603L -# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++20" -# endif - -# ifndef __cpp_lib_atomic_lock_free_type_aliases -# error "__cpp_lib_atomic_lock_free_type_aliases should be defined in c++20" -# endif -# if __cpp_lib_atomic_lock_free_type_aliases != 201907L -# error "__cpp_lib_atomic_lock_free_type_aliases should have the value 201907L in c++20" -# endif - -# ifdef __cpp_lib_atomic_min_max -# error "__cpp_lib_atomic_min_max should not be defined before c++26" -# endif - -# ifndef __cpp_lib_atomic_ref -# error "__cpp_lib_atomic_ref should be defined in c++20" -# endif -# if __cpp_lib_atomic_ref != 201806L -# error "__cpp_lib_atomic_ref should have the value 201806L in c++20" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_atomic_shared_ptr -# error "__cpp_lib_atomic_shared_ptr should be defined in c++20" -# endif -# if __cpp_lib_atomic_shared_ptr != 201711L -# error "__cpp_lib_atomic_shared_ptr should have the value 201711L in c++20" -# endif -# else -# ifdef __cpp_lib_atomic_shared_ptr -# error "__cpp_lib_atomic_shared_ptr should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_atomic_value_initialization -# error "__cpp_lib_atomic_value_initialization should be defined in c++20" -# endif -# if __cpp_lib_atomic_value_initialization != 201911L -# error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++20" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC -# ifndef __cpp_lib_atomic_wait -# error "__cpp_lib_atomic_wait should be defined in c++20" -# endif -# if __cpp_lib_atomic_wait != 201907L -# error "__cpp_lib_atomic_wait should have the value 201907L in c++20" -# endif -# else -# ifdef __cpp_lib_atomic_wait -# error "__cpp_lib_atomic_wait should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_barrier -# error "__cpp_lib_barrier should be defined in c++20" -# endif -# if __cpp_lib_barrier != 201907L -# error "__cpp_lib_barrier should have the value 201907L in c++20" -# endif -# else -# ifdef __cpp_lib_barrier -# error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# ifdef __cpp_lib_bind_back -# error "__cpp_lib_bind_back should not be defined before c++23" -# endif - -# ifndef __cpp_lib_bind_front -# error "__cpp_lib_bind_front should be defined in c++20" -# endif -# if __cpp_lib_bind_front != 201907L -# error "__cpp_lib_bind_front should have the value 201907L in c++20" -# endif - -# ifndef __cpp_lib_bit_cast -# error "__cpp_lib_bit_cast should be defined in c++20" -# endif -# if __cpp_lib_bit_cast != 201806L -# error "__cpp_lib_bit_cast should have the value 201806L in c++20" -# endif - -# ifndef __cpp_lib_bitops -# error "__cpp_lib_bitops should be defined in c++20" -# endif -# if __cpp_lib_bitops != 201907L -# error "__cpp_lib_bitops should have the value 201907L in c++20" -# endif - -# ifdef __cpp_lib_bitset -# error "__cpp_lib_bitset should not be defined before c++26" -# endif - -# ifndef __cpp_lib_bool_constant -# error "__cpp_lib_bool_constant should be defined in c++20" -# endif -# if __cpp_lib_bool_constant != 201505L -# error "__cpp_lib_bool_constant should have the value 201505L in c++20" -# endif - -# ifndef __cpp_lib_bounded_array_traits -# error "__cpp_lib_bounded_array_traits should be defined in c++20" -# endif -# if __cpp_lib_bounded_array_traits != 201902L -# error "__cpp_lib_bounded_array_traits should have the value 201902L in c++20" -# endif - -# ifndef __cpp_lib_boyer_moore_searcher -# error "__cpp_lib_boyer_moore_searcher should be defined in c++20" -# endif -# if __cpp_lib_boyer_moore_searcher != 201603L -# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++20" -# endif - -# ifndef __cpp_lib_byte -# error "__cpp_lib_byte should be defined in c++20" -# endif -# if __cpp_lib_byte != 201603L -# error "__cpp_lib_byte should have the value 201603L in c++20" -# endif - -# ifdef __cpp_lib_byteswap -# error "__cpp_lib_byteswap should not be defined before c++23" -# endif - -# if defined(__cpp_char8_t) -# ifndef __cpp_lib_char8_t -# error "__cpp_lib_char8_t should be defined in c++20" -# endif -# if __cpp_lib_char8_t != 201907L -# error "__cpp_lib_char8_t should have the value 201907L in c++20" -# endif -# else -# ifdef __cpp_lib_char8_t -# error "__cpp_lib_char8_t should not be defined when the requirement 'defined(__cpp_char8_t)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_chrono -# error "__cpp_lib_chrono should be defined in c++20" -# endif -# if __cpp_lib_chrono != 201611L -# error "__cpp_lib_chrono should have the value 201611L in c++20" -# endif - -# ifndef __cpp_lib_chrono_udls -# error "__cpp_lib_chrono_udls should be defined in c++20" -# endif -# if __cpp_lib_chrono_udls != 201304L -# error "__cpp_lib_chrono_udls should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_clamp -# error "__cpp_lib_clamp should be defined in c++20" -# endif -# if __cpp_lib_clamp != 201603L -# error "__cpp_lib_clamp should have the value 201603L in c++20" -# endif - -# ifndef __cpp_lib_common_reference -# error "__cpp_lib_common_reference should be defined in c++20" -# endif -# if __cpp_lib_common_reference != 202302L -# error "__cpp_lib_common_reference should have the value 202302L in c++20" -# endif - -# ifndef __cpp_lib_common_reference_wrapper -# error "__cpp_lib_common_reference_wrapper should be defined in c++20" -# endif -# if __cpp_lib_common_reference_wrapper != 202302L -# error "__cpp_lib_common_reference_wrapper should have the value 202302L in c++20" -# endif - -# ifndef __cpp_lib_complex_udls -# error "__cpp_lib_complex_udls should be defined in c++20" -# endif -# if __cpp_lib_complex_udls != 201309L -# error "__cpp_lib_complex_udls should have the value 201309L in c++20" -# endif - -# ifndef __cpp_lib_concepts -# error "__cpp_lib_concepts should be defined in c++20" -# endif -# if __cpp_lib_concepts != 202002L -# error "__cpp_lib_concepts should have the value 202002L in c++20" -# endif - -# ifndef __cpp_lib_constexpr_algorithms -# error "__cpp_lib_constexpr_algorithms should be defined in c++20" -# endif -# if __cpp_lib_constexpr_algorithms != 201806L -# error "__cpp_lib_constexpr_algorithms should have the value 201806L in c++20" -# endif - -# ifdef __cpp_lib_constexpr_bitset -# error "__cpp_lib_constexpr_bitset should not be defined before c++23" -# endif - -# ifdef __cpp_lib_constexpr_charconv -# error "__cpp_lib_constexpr_charconv should not be defined before c++23" -# endif - -# ifdef __cpp_lib_constexpr_cmath -# error "__cpp_lib_constexpr_cmath should not be defined before c++23" -# endif - -# ifndef __cpp_lib_constexpr_complex -# error "__cpp_lib_constexpr_complex should be defined in c++20" -# endif -# if __cpp_lib_constexpr_complex != 201711L -# error "__cpp_lib_constexpr_complex should have the value 201711L in c++20" -# endif - -# ifndef __cpp_lib_constexpr_dynamic_alloc -# error "__cpp_lib_constexpr_dynamic_alloc should be defined in c++20" -# endif -# if __cpp_lib_constexpr_dynamic_alloc != 201907L -# error "__cpp_lib_constexpr_dynamic_alloc should have the value 201907L in c++20" -# endif - -# ifdef __cpp_lib_constexpr_forward_list -# error "__cpp_lib_constexpr_forward_list should not be defined before c++26" -# endif - -# ifndef __cpp_lib_constexpr_functional -# error "__cpp_lib_constexpr_functional should be defined in c++20" -# endif -# if __cpp_lib_constexpr_functional != 201907L -# error "__cpp_lib_constexpr_functional should have the value 201907L in c++20" -# endif - -# ifndef __cpp_lib_constexpr_iterator -# error "__cpp_lib_constexpr_iterator should be defined in c++20" -# endif -# if __cpp_lib_constexpr_iterator != 201811L -# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++20" -# endif - -# ifdef __cpp_lib_constexpr_list -# error "__cpp_lib_constexpr_list should not be defined before c++26" -# endif - -# ifndef __cpp_lib_constexpr_memory -# error "__cpp_lib_constexpr_memory should be defined in c++20" -# endif -# if __cpp_lib_constexpr_memory != 201811L -# error "__cpp_lib_constexpr_memory should have the value 201811L in c++20" -# endif - -# ifdef __cpp_lib_constexpr_new -# error "__cpp_lib_constexpr_new should not be defined before c++26" -# endif - -# ifndef __cpp_lib_constexpr_numeric -# error "__cpp_lib_constexpr_numeric should be defined in c++20" -# endif -# if __cpp_lib_constexpr_numeric != 201911L -# error "__cpp_lib_constexpr_numeric should have the value 201911L in c++20" -# endif - -# ifdef __cpp_lib_constexpr_queue -# error "__cpp_lib_constexpr_queue should not be defined before c++26" -# endif - -# ifndef __cpp_lib_constexpr_string -# error "__cpp_lib_constexpr_string should be defined in c++20" -# endif -# if __cpp_lib_constexpr_string != 201907L -# error "__cpp_lib_constexpr_string should have the value 201907L in c++20" -# endif - -# ifndef __cpp_lib_constexpr_string_view -# error "__cpp_lib_constexpr_string_view should be defined in c++20" -# endif -# if __cpp_lib_constexpr_string_view != 201811L -# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++20" -# endif - -# ifndef __cpp_lib_constexpr_tuple -# error "__cpp_lib_constexpr_tuple should be defined in c++20" -# endif -# if __cpp_lib_constexpr_tuple != 201811L -# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++20" -# endif - -# ifdef __cpp_lib_constexpr_typeinfo -# error "__cpp_lib_constexpr_typeinfo should not be defined before c++23" -# endif - -# ifndef __cpp_lib_constexpr_utility -# error "__cpp_lib_constexpr_utility should be defined in c++20" -# endif -# if __cpp_lib_constexpr_utility != 201811L -# error "__cpp_lib_constexpr_utility should have the value 201811L in c++20" -# endif - -# ifndef __cpp_lib_constexpr_vector -# error "__cpp_lib_constexpr_vector should be defined in c++20" -# endif -# if __cpp_lib_constexpr_vector != 201907L -# error "__cpp_lib_constexpr_vector should have the value 201907L in c++20" -# endif - -# ifdef __cpp_lib_constrained_equality -# error "__cpp_lib_constrained_equality should not be defined before c++26" -# endif - -# ifdef __cpp_lib_containers_ranges -# error "__cpp_lib_containers_ranges should not be defined before c++23" -# endif - -# ifdef __cpp_lib_copyable_function -# error "__cpp_lib_copyable_function should not be defined before c++26" -# endif - -# ifndef __cpp_lib_coroutine -# error "__cpp_lib_coroutine should be defined in c++20" -# endif -# if __cpp_lib_coroutine != 201902L -# error "__cpp_lib_coroutine should have the value 201902L in c++20" -# endif - -# ifdef __cpp_lib_debugging -# error "__cpp_lib_debugging should not be defined before c++26" -# endif - -# ifdef __cpp_lib_default_template_type_for_algorithm_values -# error "__cpp_lib_default_template_type_for_algorithm_values should not be defined before c++26" -# endif - -# if TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L -# ifndef __cpp_lib_destroying_delete -# error "__cpp_lib_destroying_delete should be defined in c++20" -# endif -# if __cpp_lib_destroying_delete != 201806L -# error "__cpp_lib_destroying_delete should have the value 201806L in c++20" -# endif -# else -# ifdef __cpp_lib_destroying_delete -# error "__cpp_lib_destroying_delete should not be defined when the requirement 'TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L' is not met!" -# endif -# endif - -# ifndef __cpp_lib_enable_shared_from_this -# error "__cpp_lib_enable_shared_from_this should be defined in c++20" -# endif -# if __cpp_lib_enable_shared_from_this != 201603L -# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++20" -# endif - -# ifndef __cpp_lib_endian -# error "__cpp_lib_endian should be defined in c++20" -# endif -# if __cpp_lib_endian != 201907L -# error "__cpp_lib_endian should have the value 201907L in c++20" -# endif - -# ifndef __cpp_lib_erase_if -# error "__cpp_lib_erase_if should be defined in c++20" -# endif -# if __cpp_lib_erase_if != 202002L -# error "__cpp_lib_erase_if should have the value 202002L in c++20" -# endif - -# ifndef __cpp_lib_exchange_function -# error "__cpp_lib_exchange_function should be defined in c++20" -# endif -# if __cpp_lib_exchange_function != 201304L -# error "__cpp_lib_exchange_function should have the value 201304L in c++20" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_execution -# error "__cpp_lib_execution should be defined in c++20" -# endif -# if __cpp_lib_execution != 201902L -# error "__cpp_lib_execution should have the value 201902L in c++20" -# endif -# else -# ifdef __cpp_lib_execution -# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_expected -# error "__cpp_lib_expected should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY) -# ifndef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should be defined in c++20" -# endif -# if __cpp_lib_filesystem != 201703L -# error "__cpp_lib_filesystem should have the value 201703L in c++20" -# endif -# else -# ifdef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)' is not met!" -# endif -# endif - -# ifdef __cpp_lib_flat_map -# error "__cpp_lib_flat_map should not be defined before c++23" -# endif - -# ifdef __cpp_lib_flat_set -# error "__cpp_lib_flat_set should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT -# ifndef __cpp_lib_format -# error "__cpp_lib_format should be defined in c++20" -# endif -# if __cpp_lib_format != 202110L -# error "__cpp_lib_format should have the value 202110L in c++20" -# endif -# else -# ifdef __cpp_lib_format -# error "__cpp_lib_format should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" -# endif -# endif - -# ifdef __cpp_lib_format_path -# error "__cpp_lib_format_path should not be defined before c++26" -# endif - -# ifdef __cpp_lib_format_ranges -# error "__cpp_lib_format_ranges should not be defined before c++23" -# endif - -# ifndef __cpp_lib_format_uchar -# error "__cpp_lib_format_uchar should be defined in c++20" -# endif -# if __cpp_lib_format_uchar != 202311L -# error "__cpp_lib_format_uchar should have the value 202311L in c++20" -# endif - -# ifdef __cpp_lib_formatters -# error "__cpp_lib_formatters should not be defined before c++23" -# endif - -# ifdef __cpp_lib_forward_like -# error "__cpp_lib_forward_like should not be defined before c++23" -# endif - -# ifdef __cpp_lib_freestanding_algorithm -# error "__cpp_lib_freestanding_algorithm should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_array -# error "__cpp_lib_freestanding_array should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_cstring -# error "__cpp_lib_freestanding_cstring should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_expected -# error "__cpp_lib_freestanding_expected should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_mdspan -# error "__cpp_lib_freestanding_mdspan should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_optional -# error "__cpp_lib_freestanding_optional should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_string_view -# error "__cpp_lib_freestanding_string_view should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_variant -# error "__cpp_lib_freestanding_variant should not be defined before c++26" -# endif - -# ifdef __cpp_lib_fstream_native_handle -# error "__cpp_lib_fstream_native_handle should not be defined before c++26" -# endif - -# ifdef __cpp_lib_function_ref -# error "__cpp_lib_function_ref should not be defined before c++26" -# endif - -# ifndef __cpp_lib_gcd_lcm -# error "__cpp_lib_gcd_lcm should be defined in c++20" -# endif -# if __cpp_lib_gcd_lcm != 201606L -# error "__cpp_lib_gcd_lcm should have the value 201606L in c++20" -# endif - -# ifdef __cpp_lib_generate_random -# error "__cpp_lib_generate_random should not be defined before c++26" -# endif - -# ifndef __cpp_lib_generic_associative_lookup -# error "__cpp_lib_generic_associative_lookup should be defined in c++20" -# endif -# if __cpp_lib_generic_associative_lookup != 201304L -# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_generic_unordered_lookup -# error "__cpp_lib_generic_unordered_lookup should be defined in c++20" -# endif -# if __cpp_lib_generic_unordered_lookup != 201811L -# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++20" -# endif - -# if !defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)) -# ifndef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should be defined in c++20" -# endif -# if __cpp_lib_hardware_interference_size != 201703L -# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++20" -# endif -# else -# ifdef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))' is not met!" -# endif -# endif - -# ifndef __cpp_lib_has_unique_object_representations -# error "__cpp_lib_has_unique_object_representations should be defined in c++20" -# endif -# if __cpp_lib_has_unique_object_representations != 201606L -# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++20" -# endif - -# ifdef __cpp_lib_hazard_pointer -# error "__cpp_lib_hazard_pointer should not be defined before c++26" -# endif - -# ifndef __cpp_lib_hypot -# error "__cpp_lib_hypot should be defined in c++20" -# endif -# if __cpp_lib_hypot != 201603L -# error "__cpp_lib_hypot should have the value 201603L in c++20" -# endif - -# ifndef __cpp_lib_incomplete_container_elements -# error "__cpp_lib_incomplete_container_elements should be defined in c++20" -# endif -# if __cpp_lib_incomplete_container_elements != 201505L -# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++20" -# endif - -# ifdef __cpp_lib_inplace_vector -# error "__cpp_lib_inplace_vector should not be defined before c++26" -# endif - -# ifndef __cpp_lib_int_pow2 -# error "__cpp_lib_int_pow2 should be defined in c++20" -# endif -# if __cpp_lib_int_pow2 != 202002L -# error "__cpp_lib_int_pow2 should have the value 202002L in c++20" -# endif - -# ifndef __cpp_lib_integer_comparison_functions -# error "__cpp_lib_integer_comparison_functions should be defined in c++20" -# endif -# if __cpp_lib_integer_comparison_functions != 202002L -# error "__cpp_lib_integer_comparison_functions should have the value 202002L in c++20" -# endif - -# ifndef __cpp_lib_integer_sequence -# error "__cpp_lib_integer_sequence should be defined in c++20" -# endif -# if __cpp_lib_integer_sequence != 201304L -# error "__cpp_lib_integer_sequence should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_integral_constant_callable -# error "__cpp_lib_integral_constant_callable should be defined in c++20" -# endif -# if __cpp_lib_integral_constant_callable != 201304L -# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_interpolate -# error "__cpp_lib_interpolate should be defined in c++20" -# endif -# if __cpp_lib_interpolate != 201902L -# error "__cpp_lib_interpolate should have the value 201902L in c++20" -# endif - -# ifndef __cpp_lib_invoke -# error "__cpp_lib_invoke should be defined in c++20" -# endif -# if __cpp_lib_invoke != 201411L -# error "__cpp_lib_invoke should have the value 201411L in c++20" -# endif - -# ifdef __cpp_lib_invoke_r -# error "__cpp_lib_invoke_r should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ios_noreplace -# error "__cpp_lib_ios_noreplace should not be defined before c++23" -# endif - -# ifndef __cpp_lib_is_aggregate -# error "__cpp_lib_is_aggregate should be defined in c++20" -# endif -# if __cpp_lib_is_aggregate != 201703L -# error "__cpp_lib_is_aggregate should have the value 201703L in c++20" -# endif - -# ifndef __cpp_lib_is_constant_evaluated -# error "__cpp_lib_is_constant_evaluated should be defined in c++20" -# endif -# if __cpp_lib_is_constant_evaluated != 201811L -# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++20" -# endif - -# ifndef __cpp_lib_is_final -# error "__cpp_lib_is_final should be defined in c++20" -# endif -# if __cpp_lib_is_final != 201402L -# error "__cpp_lib_is_final should have the value 201402L in c++20" -# endif - -# ifdef __cpp_lib_is_implicit_lifetime -# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" -# endif - -# ifndef __cpp_lib_is_invocable -# error "__cpp_lib_is_invocable should be defined in c++20" -# endif -# if __cpp_lib_is_invocable != 201703L -# error "__cpp_lib_is_invocable should have the value 201703L in c++20" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_is_layout_compatible -# error "__cpp_lib_is_layout_compatible should be defined in c++20" -# endif -# if __cpp_lib_is_layout_compatible != 201907L -# error "__cpp_lib_is_layout_compatible should have the value 201907L in c++20" -# endif -# else -# ifdef __cpp_lib_is_layout_compatible -# error "__cpp_lib_is_layout_compatible should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_is_nothrow_convertible -# error "__cpp_lib_is_nothrow_convertible should be defined in c++20" -# endif -# if __cpp_lib_is_nothrow_convertible != 201806L -# error "__cpp_lib_is_nothrow_convertible should have the value 201806L in c++20" -# endif - -# ifndef __cpp_lib_is_null_pointer -# error "__cpp_lib_is_null_pointer should be defined in c++20" -# endif -# if __cpp_lib_is_null_pointer != 201309L -# error "__cpp_lib_is_null_pointer should have the value 201309L in c++20" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_is_pointer_interconvertible -# error "__cpp_lib_is_pointer_interconvertible should be defined in c++20" -# endif -# if __cpp_lib_is_pointer_interconvertible != 201907L -# error "__cpp_lib_is_pointer_interconvertible should have the value 201907L in c++20" -# endif -# else -# ifdef __cpp_lib_is_pointer_interconvertible -# error "__cpp_lib_is_pointer_interconvertible should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_is_scoped_enum -# error "__cpp_lib_is_scoped_enum should not be defined before c++23" -# endif - -# ifdef __cpp_lib_is_sufficiently_aligned -# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" -# endif - -# ifndef __cpp_lib_is_swappable -# error "__cpp_lib_is_swappable should be defined in c++20" -# endif -# if __cpp_lib_is_swappable != 201603L -# error "__cpp_lib_is_swappable should have the value 201603L in c++20" -# endif - -# ifdef __cpp_lib_is_virtual_base_of -# error "__cpp_lib_is_virtual_base_of should not be defined before c++26" -# endif - -# ifdef __cpp_lib_is_within_lifetime -# error "__cpp_lib_is_within_lifetime should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_jthread -# error "__cpp_lib_jthread should be defined in c++20" -# endif -# if __cpp_lib_jthread != 201911L -# error "__cpp_lib_jthread should have the value 201911L in c++20" -# endif -# else -# ifdef __cpp_lib_jthread -# error "__cpp_lib_jthread should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_latch -# error "__cpp_lib_latch should be defined in c++20" -# endif -# if __cpp_lib_latch != 201907L -# error "__cpp_lib_latch should have the value 201907L in c++20" -# endif -# else -# ifdef __cpp_lib_latch -# error "__cpp_lib_latch should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_launder -# error "__cpp_lib_launder should be defined in c++20" -# endif -# if __cpp_lib_launder != 201606L -# error "__cpp_lib_launder should have the value 201606L in c++20" -# endif - -# ifdef __cpp_lib_linalg -# error "__cpp_lib_linalg should not be defined before c++26" -# endif - -# ifndef __cpp_lib_list_remove_return_type -# error "__cpp_lib_list_remove_return_type should be defined in c++20" -# endif -# if __cpp_lib_list_remove_return_type != 201806L -# error "__cpp_lib_list_remove_return_type should have the value 201806L in c++20" -# endif - -# ifndef __cpp_lib_logical_traits -# error "__cpp_lib_logical_traits should be defined in c++20" -# endif -# if __cpp_lib_logical_traits != 201510L -# error "__cpp_lib_logical_traits should have the value 201510L in c++20" -# endif - -# ifndef __cpp_lib_make_from_tuple -# error "__cpp_lib_make_from_tuple should be defined in c++20" -# endif -# if __cpp_lib_make_from_tuple != 201606L -# error "__cpp_lib_make_from_tuple should have the value 201606L in c++20" -# endif - -# ifndef __cpp_lib_make_reverse_iterator -# error "__cpp_lib_make_reverse_iterator should be defined in c++20" -# endif -# if __cpp_lib_make_reverse_iterator != 201402L -# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++20" -# endif - -# ifndef __cpp_lib_make_unique -# error "__cpp_lib_make_unique should be defined in c++20" -# endif -# if __cpp_lib_make_unique != 201304L -# error "__cpp_lib_make_unique should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_map_try_emplace -# error "__cpp_lib_map_try_emplace should be defined in c++20" -# endif -# if __cpp_lib_map_try_emplace != 201411L -# error "__cpp_lib_map_try_emplace should have the value 201411L in c++20" -# endif - -# ifndef __cpp_lib_math_constants -# error "__cpp_lib_math_constants should be defined in c++20" -# endif -# if __cpp_lib_math_constants != 201907L -# error "__cpp_lib_math_constants should have the value 201907L in c++20" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should be defined in c++20" -# endif -# if __cpp_lib_math_special_functions != 201603L -# error "__cpp_lib_math_special_functions should have the value 201603L in c++20" -# endif -# else -# ifdef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_mdspan -# error "__cpp_lib_mdspan should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR -# ifndef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should be defined in c++20" -# endif -# if __cpp_lib_memory_resource != 201603L -# error "__cpp_lib_memory_resource should have the value 201603L in c++20" -# endif -# else -# ifdef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" -# endif -# endif - -# ifdef __cpp_lib_modules -# error "__cpp_lib_modules should not be defined before c++23" -# endif - -# ifndef __cpp_lib_move_iterator_concept -# error "__cpp_lib_move_iterator_concept should be defined in c++20" -# endif -# if __cpp_lib_move_iterator_concept != 202207L -# error "__cpp_lib_move_iterator_concept should have the value 202207L in c++20" -# endif - -# ifdef __cpp_lib_move_only_function -# error "__cpp_lib_move_only_function should not be defined before c++23" -# endif - -# ifndef __cpp_lib_node_extract -# error "__cpp_lib_node_extract should be defined in c++20" -# endif -# if __cpp_lib_node_extract != 201606L -# error "__cpp_lib_node_extract should have the value 201606L in c++20" -# endif - -# ifndef __cpp_lib_nonmember_container_access -# error "__cpp_lib_nonmember_container_access should be defined in c++20" -# endif -# if __cpp_lib_nonmember_container_access != 201411L -# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++20" -# endif - -# ifndef __cpp_lib_not_fn -# error "__cpp_lib_not_fn should be defined in c++20" -# endif -# if __cpp_lib_not_fn != 201603L -# error "__cpp_lib_not_fn should have the value 201603L in c++20" -# endif - -# ifndef __cpp_lib_null_iterators -# error "__cpp_lib_null_iterators should be defined in c++20" -# endif -# if __cpp_lib_null_iterators != 201304L -# error "__cpp_lib_null_iterators should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_optional -# error "__cpp_lib_optional should be defined in c++20" -# endif -# if __cpp_lib_optional != 202106L -# error "__cpp_lib_optional should have the value 202106L in c++20" -# endif - -# ifdef __cpp_lib_optional_range_support -# error "__cpp_lib_optional_range_support should not be defined before c++26" -# endif - -# ifdef __cpp_lib_out_ptr -# error "__cpp_lib_out_ptr should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should be defined in c++20" -# endif -# if __cpp_lib_parallel_algorithm != 201603L -# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++20" -# endif -# else -# ifdef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_philox_engine -# error "__cpp_lib_philox_engine should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR -# ifndef __cpp_lib_polymorphic_allocator -# error "__cpp_lib_polymorphic_allocator should be defined in c++20" -# endif -# if __cpp_lib_polymorphic_allocator != 201902L -# error "__cpp_lib_polymorphic_allocator should have the value 201902L in c++20" -# endif -# else -# ifdef __cpp_lib_polymorphic_allocator -# error "__cpp_lib_polymorphic_allocator should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" -# endif -# endif - -# ifdef __cpp_lib_print -# error "__cpp_lib_print should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION -# ifndef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should be defined in c++20" -# endif -# if __cpp_lib_quoted_string_io != 201304L -# error "__cpp_lib_quoted_string_io should have the value 201304L in c++20" -# endif -# else -# ifdef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" -# endif -# endif - -# ifndef __cpp_lib_ranges -# error "__cpp_lib_ranges should be defined in c++20" -# endif -# if __cpp_lib_ranges != 202110L -# error "__cpp_lib_ranges should have the value 202110L in c++20" -# endif - -# ifdef __cpp_lib_ranges_as_const -# error "__cpp_lib_ranges_as_const should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_as_rvalue -# error "__cpp_lib_ranges_as_rvalue should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_chunk_by -# error "__cpp_lib_ranges_chunk_by should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_concat -# error "__cpp_lib_ranges_concat should not be defined before c++26" -# endif - -# ifdef __cpp_lib_ranges_contains -# error "__cpp_lib_ranges_contains should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_find_last -# error "__cpp_lib_ranges_find_last should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_indices -# error "__cpp_lib_ranges_indices should not be defined before c++26" -# endif - -# ifdef __cpp_lib_ranges_iota -# error "__cpp_lib_ranges_iota should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_join_with -# error "__cpp_lib_ranges_join_with should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_repeat -# error "__cpp_lib_ranges_repeat should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_slide -# error "__cpp_lib_ranges_slide should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_starts_ends_with -# error "__cpp_lib_ranges_starts_ends_with should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_zip -# error "__cpp_lib_ranges_zip should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ratio -# error "__cpp_lib_ratio should not be defined before c++26" -# endif - -# ifndef __cpp_lib_raw_memory_algorithms -# error "__cpp_lib_raw_memory_algorithms should be defined in c++20" -# endif -# if __cpp_lib_raw_memory_algorithms != 201606L -# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++20" -# endif - -# ifdef __cpp_lib_rcu -# error "__cpp_lib_rcu should not be defined before c++26" -# endif - -# ifdef __cpp_lib_reference_from_temporary -# error "__cpp_lib_reference_from_temporary should not be defined before c++23" -# endif - -# ifdef __cpp_lib_reference_wrapper -# error "__cpp_lib_reference_wrapper should not be defined before c++26" -# endif - -# ifndef __cpp_lib_remove_cvref -# error "__cpp_lib_remove_cvref should be defined in c++20" -# endif -# if __cpp_lib_remove_cvref != 201711L -# error "__cpp_lib_remove_cvref should have the value 201711L in c++20" -# endif - -# ifndef __cpp_lib_result_of_sfinae -# error "__cpp_lib_result_of_sfinae should be defined in c++20" -# endif -# if __cpp_lib_result_of_sfinae != 201210L -# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++20" -# endif - -# ifndef __cpp_lib_robust_nonmodifying_seq_ops -# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++20" -# endif -# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L -# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_sample -# error "__cpp_lib_sample should be defined in c++20" -# endif -# if __cpp_lib_sample != 201603L -# error "__cpp_lib_sample should have the value 201603L in c++20" -# endif - -# ifdef __cpp_lib_saturation_arithmetic -# error "__cpp_lib_saturation_arithmetic should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should be defined in c++20" -# endif -# if __cpp_lib_scoped_lock != 201703L -# error "__cpp_lib_scoped_lock should have the value 201703L in c++20" -# endif -# else -# ifdef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_semaphore -# error "__cpp_lib_semaphore should be defined in c++20" -# endif -# if __cpp_lib_semaphore != 201907L -# error "__cpp_lib_semaphore should have the value 201907L in c++20" -# endif -# else -# ifdef __cpp_lib_semaphore -# error "__cpp_lib_semaphore should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# ifdef __cpp_lib_senders -# error "__cpp_lib_senders should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should be defined in c++20" -# endif -# if __cpp_lib_shared_mutex != 201505L -# error "__cpp_lib_shared_mutex should have the value 201505L in c++20" -# endif -# else -# ifdef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifndef __cpp_lib_shared_ptr_arrays -# error "__cpp_lib_shared_ptr_arrays should be defined in c++20" -# endif -# if __cpp_lib_shared_ptr_arrays != 201707L -# error "__cpp_lib_shared_ptr_arrays should have the value 201707L in c++20" -# endif - -# ifndef __cpp_lib_shared_ptr_weak_type -# error "__cpp_lib_shared_ptr_weak_type should be defined in c++20" -# endif -# if __cpp_lib_shared_ptr_weak_type != 201606L -# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++20" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should be defined in c++20" -# endif -# if __cpp_lib_shared_timed_mutex != 201402L -# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++20" -# endif -# else -# ifdef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifndef __cpp_lib_shift -# error "__cpp_lib_shift should be defined in c++20" -# endif -# if __cpp_lib_shift != 201806L -# error "__cpp_lib_shift should have the value 201806L in c++20" -# endif - -# ifndef __cpp_lib_smart_ptr_for_overwrite -# error "__cpp_lib_smart_ptr_for_overwrite should be defined in c++20" -# endif -# if __cpp_lib_smart_ptr_for_overwrite != 202002L -# error "__cpp_lib_smart_ptr_for_overwrite should have the value 202002L in c++20" -# endif - -# ifdef __cpp_lib_smart_ptr_owner_equality -# error "__cpp_lib_smart_ptr_owner_equality should not be defined before c++26" -# endif - -# ifndef __cpp_lib_source_location -# error "__cpp_lib_source_location should be defined in c++20" -# endif -# if __cpp_lib_source_location != 201907L -# error "__cpp_lib_source_location should have the value 201907L in c++20" -# endif - -# ifndef __cpp_lib_span -# error "__cpp_lib_span should be defined in c++20" -# endif -# if __cpp_lib_span != 202002L -# error "__cpp_lib_span should have the value 202002L in c++20" -# endif - -# ifdef __cpp_lib_span_at -# error "__cpp_lib_span_at should not be defined before c++26" -# endif - -# ifdef __cpp_lib_span_initializer_list -# error "__cpp_lib_span_initializer_list should not be defined before c++26" -# endif - -# ifdef __cpp_lib_spanstream -# error "__cpp_lib_spanstream should not be defined before c++23" -# endif - -# ifndef __cpp_lib_ssize -# error "__cpp_lib_ssize should be defined in c++20" -# endif -# if __cpp_lib_ssize != 201902L -# error "__cpp_lib_ssize should have the value 201902L in c++20" -# endif - -# ifdef __cpp_lib_sstream_from_string_view -# error "__cpp_lib_sstream_from_string_view should not be defined before c++26" -# endif - -# ifdef __cpp_lib_stacktrace -# error "__cpp_lib_stacktrace should not be defined before c++23" -# endif - -# ifndef __cpp_lib_starts_ends_with -# error "__cpp_lib_starts_ends_with should be defined in c++20" -# endif -# if __cpp_lib_starts_ends_with != 201711L -# error "__cpp_lib_starts_ends_with should have the value 201711L in c++20" -# endif - -# ifdef __cpp_lib_stdatomic_h -# error "__cpp_lib_stdatomic_h should not be defined before c++23" -# endif - -# ifdef __cpp_lib_string_contains -# error "__cpp_lib_string_contains should not be defined before c++23" -# endif - -# ifdef __cpp_lib_string_resize_and_overwrite -# error "__cpp_lib_string_resize_and_overwrite should not be defined before c++23" -# endif - -# ifdef __cpp_lib_string_subview -# error "__cpp_lib_string_subview should not be defined before c++26" -# endif - -# ifndef __cpp_lib_string_udls -# error "__cpp_lib_string_udls should be defined in c++20" -# endif -# if __cpp_lib_string_udls != 201304L -# error "__cpp_lib_string_udls should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_string_view -# error "__cpp_lib_string_view should be defined in c++20" -# endif -# if __cpp_lib_string_view != 201803L -# error "__cpp_lib_string_view should have the value 201803L in c++20" -# endif - -# ifdef __cpp_lib_submdspan -# error "__cpp_lib_submdspan should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM -# ifndef __cpp_lib_syncbuf -# error "__cpp_lib_syncbuf should be defined in c++20" -# endif -# if __cpp_lib_syncbuf != 201803L -# error "__cpp_lib_syncbuf should have the value 201803L in c++20" -# endif -# else -# ifdef __cpp_lib_syncbuf -# error "__cpp_lib_syncbuf should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM' is not met!" -# endif -# endif - -# ifdef __cpp_lib_text_encoding -# error "__cpp_lib_text_encoding should not be defined before c++26" -# endif - -# ifndef __cpp_lib_three_way_comparison -# error "__cpp_lib_three_way_comparison should be defined in c++20" -# endif -# if __cpp_lib_three_way_comparison != 201907L -# error "__cpp_lib_three_way_comparison should have the value 201907L in c++20" -# endif - -# ifndef __cpp_lib_to_address -# error "__cpp_lib_to_address should be defined in c++20" -# endif -# if __cpp_lib_to_address != 201711L -# error "__cpp_lib_to_address should have the value 201711L in c++20" -# endif - -# ifndef __cpp_lib_to_array -# error "__cpp_lib_to_array should be defined in c++20" -# endif -# if __cpp_lib_to_array != 201907L -# error "__cpp_lib_to_array should have the value 201907L in c++20" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should be defined in c++20" -# endif -# if __cpp_lib_to_chars != 201611L -# error "__cpp_lib_to_chars should have the value 201611L in c++20" -# endif -# else -# ifdef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_to_string -# error "__cpp_lib_to_string should not be defined before c++26" -# endif - -# ifdef __cpp_lib_to_underlying -# error "__cpp_lib_to_underlying should not be defined before c++23" -# endif - -# ifndef __cpp_lib_transformation_trait_aliases -# error "__cpp_lib_transformation_trait_aliases should be defined in c++20" -# endif -# if __cpp_lib_transformation_trait_aliases != 201304L -# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_transparent_operators -# error "__cpp_lib_transparent_operators should be defined in c++20" -# endif -# if __cpp_lib_transparent_operators != 201510L -# error "__cpp_lib_transparent_operators should have the value 201510L in c++20" -# endif - -# ifndef __cpp_lib_tuple_element_t -# error "__cpp_lib_tuple_element_t should be defined in c++20" -# endif -# if __cpp_lib_tuple_element_t != 201402L -# error "__cpp_lib_tuple_element_t should have the value 201402L in c++20" -# endif - -# ifdef __cpp_lib_tuple_like -# error "__cpp_lib_tuple_like should not be defined before c++23" -# endif - -# ifndef __cpp_lib_tuples_by_type -# error "__cpp_lib_tuples_by_type should be defined in c++20" -# endif -# if __cpp_lib_tuples_by_type != 201304L -# error "__cpp_lib_tuples_by_type should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_type_identity -# error "__cpp_lib_type_identity should be defined in c++20" -# endif -# if __cpp_lib_type_identity != 201806L -# error "__cpp_lib_type_identity should have the value 201806L in c++20" -# endif - -# ifndef __cpp_lib_type_trait_variable_templates -# error "__cpp_lib_type_trait_variable_templates should be defined in c++20" -# endif -# if __cpp_lib_type_trait_variable_templates != 201510L -# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++20" -# endif - -# ifndef __cpp_lib_uncaught_exceptions -# error "__cpp_lib_uncaught_exceptions should be defined in c++20" -# endif -# if __cpp_lib_uncaught_exceptions != 201411L -# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++20" -# endif - -# ifndef __cpp_lib_unordered_map_try_emplace -# error "__cpp_lib_unordered_map_try_emplace should be defined in c++20" -# endif -# if __cpp_lib_unordered_map_try_emplace != 201411L -# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++20" -# endif - -# ifdef __cpp_lib_unreachable -# error "__cpp_lib_unreachable should not be defined before c++23" -# endif - -# ifndef __cpp_lib_unwrap_ref -# error "__cpp_lib_unwrap_ref should be defined in c++20" -# endif -# if __cpp_lib_unwrap_ref != 201811L -# error "__cpp_lib_unwrap_ref should have the value 201811L in c++20" -# endif - -# ifndef __cpp_lib_variant -# error "__cpp_lib_variant should be defined in c++20" -# endif -# if __cpp_lib_variant != 202106L -# error "__cpp_lib_variant should have the value 202106L in c++20" -# endif - -# ifndef __cpp_lib_void_t -# error "__cpp_lib_void_t should be defined in c++20" -# endif -# if __cpp_lib_void_t != 201411L -# error "__cpp_lib_void_t should have the value 201411L in c++20" -# endif - -#elif TEST_STD_VER == 23 - -# ifndef __cpp_lib_adaptor_iterator_pair_constructor -# error "__cpp_lib_adaptor_iterator_pair_constructor should be defined in c++23" -# endif -# if __cpp_lib_adaptor_iterator_pair_constructor != 202106L -# error "__cpp_lib_adaptor_iterator_pair_constructor should have the value 202106L in c++23" -# endif - -# ifndef __cpp_lib_addressof_constexpr -# error "__cpp_lib_addressof_constexpr should be defined in c++23" -# endif -# if __cpp_lib_addressof_constexpr != 201603L -# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++23" -# endif - -# ifdef __cpp_lib_aligned_accessor -# error "__cpp_lib_aligned_accessor should not be defined before c++26" -# endif - -# ifndef __cpp_lib_allocate_at_least -# error "__cpp_lib_allocate_at_least should be defined in c++23" -# endif -# if __cpp_lib_allocate_at_least != 202302L -# error "__cpp_lib_allocate_at_least should have the value 202302L in c++23" -# endif - -# ifndef __cpp_lib_allocator_traits_is_always_equal -# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++23" -# endif -# if __cpp_lib_allocator_traits_is_always_equal != 201411L -# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++23" -# endif - -# ifndef __cpp_lib_any -# error "__cpp_lib_any should be defined in c++23" -# endif -# if __cpp_lib_any != 201606L -# error "__cpp_lib_any should have the value 201606L in c++23" -# endif - -# ifndef __cpp_lib_apply -# error "__cpp_lib_apply should be defined in c++23" -# endif -# if __cpp_lib_apply != 201603L -# error "__cpp_lib_apply should have the value 201603L in c++23" -# endif - -# ifndef __cpp_lib_array_constexpr -# error "__cpp_lib_array_constexpr should be defined in c++23" -# endif -# if __cpp_lib_array_constexpr != 201811L -# error "__cpp_lib_array_constexpr should have the value 201811L in c++23" -# endif - -# ifndef __cpp_lib_as_const -# error "__cpp_lib_as_const should be defined in c++23" -# endif -# if __cpp_lib_as_const != 201510L -# error "__cpp_lib_as_const should have the value 201510L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_associative_heterogeneous_erasure -# error "__cpp_lib_associative_heterogeneous_erasure should be defined in c++23" -# endif -# if __cpp_lib_associative_heterogeneous_erasure != 202110L -# error "__cpp_lib_associative_heterogeneous_erasure should have the value 202110L in c++23" -# endif -# else -# ifdef __cpp_lib_associative_heterogeneous_erasure -# error "__cpp_lib_associative_heterogeneous_erasure should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_associative_heterogeneous_insertion -# error "__cpp_lib_associative_heterogeneous_insertion should not be defined before c++26" -# endif - -# ifndef __cpp_lib_assume_aligned -# error "__cpp_lib_assume_aligned should be defined in c++23" -# endif -# if __cpp_lib_assume_aligned != 201811L -# error "__cpp_lib_assume_aligned should have the value 201811L in c++23" -# endif - -# ifndef __cpp_lib_atomic_flag_test -# error "__cpp_lib_atomic_flag_test should be defined in c++23" -# endif -# if __cpp_lib_atomic_flag_test != 201907L -# error "__cpp_lib_atomic_flag_test should have the value 201907L in c++23" -# endif - -# ifndef __cpp_lib_atomic_float -# error "__cpp_lib_atomic_float should be defined in c++23" -# endif -# if __cpp_lib_atomic_float != 201711L -# error "__cpp_lib_atomic_float should have the value 201711L in c++23" -# endif - -# ifndef __cpp_lib_atomic_is_always_lock_free -# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++23" -# endif -# if __cpp_lib_atomic_is_always_lock_free != 201603L -# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++23" -# endif - -# ifndef __cpp_lib_atomic_lock_free_type_aliases -# error "__cpp_lib_atomic_lock_free_type_aliases should be defined in c++23" -# endif -# if __cpp_lib_atomic_lock_free_type_aliases != 201907L -# error "__cpp_lib_atomic_lock_free_type_aliases should have the value 201907L in c++23" -# endif - -# ifdef __cpp_lib_atomic_min_max -# error "__cpp_lib_atomic_min_max should not be defined before c++26" -# endif - -# ifndef __cpp_lib_atomic_ref -# error "__cpp_lib_atomic_ref should be defined in c++23" -# endif -# if __cpp_lib_atomic_ref != 201806L -# error "__cpp_lib_atomic_ref should have the value 201806L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_atomic_shared_ptr -# error "__cpp_lib_atomic_shared_ptr should be defined in c++23" -# endif -# if __cpp_lib_atomic_shared_ptr != 201711L -# error "__cpp_lib_atomic_shared_ptr should have the value 201711L in c++23" -# endif -# else -# ifdef __cpp_lib_atomic_shared_ptr -# error "__cpp_lib_atomic_shared_ptr should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_atomic_value_initialization -# error "__cpp_lib_atomic_value_initialization should be defined in c++23" -# endif -# if __cpp_lib_atomic_value_initialization != 201911L -# error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC -# ifndef __cpp_lib_atomic_wait -# error "__cpp_lib_atomic_wait should be defined in c++23" -# endif -# if __cpp_lib_atomic_wait != 201907L -# error "__cpp_lib_atomic_wait should have the value 201907L in c++23" -# endif -# else -# ifdef __cpp_lib_atomic_wait -# error "__cpp_lib_atomic_wait should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_barrier -# error "__cpp_lib_barrier should be defined in c++23" -# endif -# if __cpp_lib_barrier != 201907L -# error "__cpp_lib_barrier should have the value 201907L in c++23" -# endif -# else -# ifdef __cpp_lib_barrier -# error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_bind_back -# error "__cpp_lib_bind_back should be defined in c++23" -# endif -# if __cpp_lib_bind_back != 202202L -# error "__cpp_lib_bind_back should have the value 202202L in c++23" -# endif - -# ifndef __cpp_lib_bind_front -# error "__cpp_lib_bind_front should be defined in c++23" -# endif -# if __cpp_lib_bind_front != 201907L -# error "__cpp_lib_bind_front should have the value 201907L in c++23" -# endif - -# ifndef __cpp_lib_bit_cast -# error "__cpp_lib_bit_cast should be defined in c++23" -# endif -# if __cpp_lib_bit_cast != 201806L -# error "__cpp_lib_bit_cast should have the value 201806L in c++23" -# endif - -# ifndef __cpp_lib_bitops -# error "__cpp_lib_bitops should be defined in c++23" -# endif -# if __cpp_lib_bitops != 201907L -# error "__cpp_lib_bitops should have the value 201907L in c++23" -# endif - -# ifdef __cpp_lib_bitset -# error "__cpp_lib_bitset should not be defined before c++26" -# endif - -# ifndef __cpp_lib_bool_constant -# error "__cpp_lib_bool_constant should be defined in c++23" -# endif -# if __cpp_lib_bool_constant != 201505L -# error "__cpp_lib_bool_constant should have the value 201505L in c++23" -# endif - -# ifndef __cpp_lib_bounded_array_traits -# error "__cpp_lib_bounded_array_traits should be defined in c++23" -# endif -# if __cpp_lib_bounded_array_traits != 201902L -# error "__cpp_lib_bounded_array_traits should have the value 201902L in c++23" -# endif - -# ifndef __cpp_lib_boyer_moore_searcher -# error "__cpp_lib_boyer_moore_searcher should be defined in c++23" -# endif -# if __cpp_lib_boyer_moore_searcher != 201603L -# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++23" -# endif - -# ifndef __cpp_lib_byte -# error "__cpp_lib_byte should be defined in c++23" -# endif -# if __cpp_lib_byte != 201603L -# error "__cpp_lib_byte should have the value 201603L in c++23" -# endif - -# ifndef __cpp_lib_byteswap -# error "__cpp_lib_byteswap should be defined in c++23" -# endif -# if __cpp_lib_byteswap != 202110L -# error "__cpp_lib_byteswap should have the value 202110L in c++23" -# endif - -# if defined(__cpp_char8_t) -# ifndef __cpp_lib_char8_t -# error "__cpp_lib_char8_t should be defined in c++23" -# endif -# if __cpp_lib_char8_t != 201907L -# error "__cpp_lib_char8_t should have the value 201907L in c++23" -# endif -# else -# ifdef __cpp_lib_char8_t -# error "__cpp_lib_char8_t should not be defined when the requirement 'defined(__cpp_char8_t)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_chrono -# error "__cpp_lib_chrono should be defined in c++23" -# endif -# if __cpp_lib_chrono != 201611L -# error "__cpp_lib_chrono should have the value 201611L in c++23" -# endif - -# ifndef __cpp_lib_chrono_udls -# error "__cpp_lib_chrono_udls should be defined in c++23" -# endif -# if __cpp_lib_chrono_udls != 201304L -# error "__cpp_lib_chrono_udls should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_clamp -# error "__cpp_lib_clamp should be defined in c++23" -# endif -# if __cpp_lib_clamp != 201603L -# error "__cpp_lib_clamp should have the value 201603L in c++23" -# endif - -# ifndef __cpp_lib_common_reference -# error "__cpp_lib_common_reference should be defined in c++23" -# endif -# if __cpp_lib_common_reference != 202302L -# error "__cpp_lib_common_reference should have the value 202302L in c++23" -# endif - -# ifndef __cpp_lib_common_reference_wrapper -# error "__cpp_lib_common_reference_wrapper should be defined in c++23" -# endif -# if __cpp_lib_common_reference_wrapper != 202302L -# error "__cpp_lib_common_reference_wrapper should have the value 202302L in c++23" -# endif - -# ifndef __cpp_lib_complex_udls -# error "__cpp_lib_complex_udls should be defined in c++23" -# endif -# if __cpp_lib_complex_udls != 201309L -# error "__cpp_lib_complex_udls should have the value 201309L in c++23" -# endif - -# ifndef __cpp_lib_concepts -# error "__cpp_lib_concepts should be defined in c++23" -# endif -# if __cpp_lib_concepts != 202002L -# error "__cpp_lib_concepts should have the value 202002L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_algorithms -# error "__cpp_lib_constexpr_algorithms should be defined in c++23" -# endif -# if __cpp_lib_constexpr_algorithms != 201806L -# error "__cpp_lib_constexpr_algorithms should have the value 201806L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_bitset -# error "__cpp_lib_constexpr_bitset should be defined in c++23" -# endif -# if __cpp_lib_constexpr_bitset != 202207L -# error "__cpp_lib_constexpr_bitset should have the value 202207L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_charconv -# error "__cpp_lib_constexpr_charconv should be defined in c++23" -# endif -# if __cpp_lib_constexpr_charconv != 202207L -# error "__cpp_lib_constexpr_charconv should have the value 202207L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_constexpr_cmath -# error "__cpp_lib_constexpr_cmath should be defined in c++23" -# endif -# if __cpp_lib_constexpr_cmath != 202202L -# error "__cpp_lib_constexpr_cmath should have the value 202202L in c++23" -# endif -# else -# ifdef __cpp_lib_constexpr_cmath -# error "__cpp_lib_constexpr_cmath should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_constexpr_complex -# error "__cpp_lib_constexpr_complex should be defined in c++23" -# endif -# if __cpp_lib_constexpr_complex != 201711L -# error "__cpp_lib_constexpr_complex should have the value 201711L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_dynamic_alloc -# error "__cpp_lib_constexpr_dynamic_alloc should be defined in c++23" -# endif -# if __cpp_lib_constexpr_dynamic_alloc != 201907L -# error "__cpp_lib_constexpr_dynamic_alloc should have the value 201907L in c++23" -# endif - -# ifdef __cpp_lib_constexpr_forward_list -# error "__cpp_lib_constexpr_forward_list should not be defined before c++26" -# endif - -# ifndef __cpp_lib_constexpr_functional -# error "__cpp_lib_constexpr_functional should be defined in c++23" -# endif -# if __cpp_lib_constexpr_functional != 201907L -# error "__cpp_lib_constexpr_functional should have the value 201907L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_iterator -# error "__cpp_lib_constexpr_iterator should be defined in c++23" -# endif -# if __cpp_lib_constexpr_iterator != 201811L -# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++23" -# endif - -# ifdef __cpp_lib_constexpr_list -# error "__cpp_lib_constexpr_list should not be defined before c++26" -# endif - -# ifndef __cpp_lib_constexpr_memory -# error "__cpp_lib_constexpr_memory should be defined in c++23" -# endif -# if __cpp_lib_constexpr_memory != 202202L -# error "__cpp_lib_constexpr_memory should have the value 202202L in c++23" -# endif - -# ifdef __cpp_lib_constexpr_new -# error "__cpp_lib_constexpr_new should not be defined before c++26" -# endif - -# ifndef __cpp_lib_constexpr_numeric -# error "__cpp_lib_constexpr_numeric should be defined in c++23" -# endif -# if __cpp_lib_constexpr_numeric != 201911L -# error "__cpp_lib_constexpr_numeric should have the value 201911L in c++23" -# endif - -# ifdef __cpp_lib_constexpr_queue -# error "__cpp_lib_constexpr_queue should not be defined before c++26" -# endif - -# ifndef __cpp_lib_constexpr_string -# error "__cpp_lib_constexpr_string should be defined in c++23" -# endif -# if __cpp_lib_constexpr_string != 201907L -# error "__cpp_lib_constexpr_string should have the value 201907L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_string_view -# error "__cpp_lib_constexpr_string_view should be defined in c++23" -# endif -# if __cpp_lib_constexpr_string_view != 201811L -# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_tuple -# error "__cpp_lib_constexpr_tuple should be defined in c++23" -# endif -# if __cpp_lib_constexpr_tuple != 201811L -# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_typeinfo -# error "__cpp_lib_constexpr_typeinfo should be defined in c++23" -# endif -# if __cpp_lib_constexpr_typeinfo != 202106L -# error "__cpp_lib_constexpr_typeinfo should have the value 202106L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_utility -# error "__cpp_lib_constexpr_utility should be defined in c++23" -# endif -# if __cpp_lib_constexpr_utility != 201811L -# error "__cpp_lib_constexpr_utility should have the value 201811L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_vector -# error "__cpp_lib_constexpr_vector should be defined in c++23" -# endif -# if __cpp_lib_constexpr_vector != 201907L -# error "__cpp_lib_constexpr_vector should have the value 201907L in c++23" -# endif - -# ifdef __cpp_lib_constrained_equality -# error "__cpp_lib_constrained_equality should not be defined before c++26" -# endif - -# ifndef __cpp_lib_containers_ranges -# error "__cpp_lib_containers_ranges should be defined in c++23" -# endif -# if __cpp_lib_containers_ranges != 202202L -# error "__cpp_lib_containers_ranges should have the value 202202L in c++23" -# endif - -# ifdef __cpp_lib_copyable_function -# error "__cpp_lib_copyable_function should not be defined before c++26" -# endif - -# ifndef __cpp_lib_coroutine -# error "__cpp_lib_coroutine should be defined in c++23" -# endif -# if __cpp_lib_coroutine != 201902L -# error "__cpp_lib_coroutine should have the value 201902L in c++23" -# endif - -# ifdef __cpp_lib_debugging -# error "__cpp_lib_debugging should not be defined before c++26" -# endif - -# ifdef __cpp_lib_default_template_type_for_algorithm_values -# error "__cpp_lib_default_template_type_for_algorithm_values should not be defined before c++26" -# endif - -# if TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L -# ifndef __cpp_lib_destroying_delete -# error "__cpp_lib_destroying_delete should be defined in c++23" -# endif -# if __cpp_lib_destroying_delete != 201806L -# error "__cpp_lib_destroying_delete should have the value 201806L in c++23" -# endif -# else -# ifdef __cpp_lib_destroying_delete -# error "__cpp_lib_destroying_delete should not be defined when the requirement 'TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L' is not met!" -# endif -# endif - -# ifndef __cpp_lib_enable_shared_from_this -# error "__cpp_lib_enable_shared_from_this should be defined in c++23" -# endif -# if __cpp_lib_enable_shared_from_this != 201603L -# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++23" -# endif - -# ifndef __cpp_lib_endian -# error "__cpp_lib_endian should be defined in c++23" -# endif -# if __cpp_lib_endian != 201907L -# error "__cpp_lib_endian should have the value 201907L in c++23" -# endif - -# ifndef __cpp_lib_erase_if -# error "__cpp_lib_erase_if should be defined in c++23" -# endif -# if __cpp_lib_erase_if != 202002L -# error "__cpp_lib_erase_if should have the value 202002L in c++23" -# endif - -# ifndef __cpp_lib_exchange_function -# error "__cpp_lib_exchange_function should be defined in c++23" -# endif -# if __cpp_lib_exchange_function != 201304L -# error "__cpp_lib_exchange_function should have the value 201304L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_execution -# error "__cpp_lib_execution should be defined in c++23" -# endif -# if __cpp_lib_execution != 201902L -# error "__cpp_lib_execution should have the value 201902L in c++23" -# endif -# else -# ifdef __cpp_lib_execution -# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_expected -# error "__cpp_lib_expected should be defined in c++23" -# endif -# if __cpp_lib_expected != 202211L -# error "__cpp_lib_expected should have the value 202211L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY) -# ifndef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should be defined in c++23" -# endif -# if __cpp_lib_filesystem != 201703L -# error "__cpp_lib_filesystem should have the value 201703L in c++23" -# endif -# else -# ifdef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_flat_map -# error "__cpp_lib_flat_map should be defined in c++23" -# endif -# if __cpp_lib_flat_map != 202207L -# error "__cpp_lib_flat_map should have the value 202207L in c++23" -# endif - -# ifndef __cpp_lib_flat_set -# error "__cpp_lib_flat_set should be defined in c++23" -# endif -# if __cpp_lib_flat_set != 202207L -# error "__cpp_lib_flat_set should have the value 202207L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT -# ifndef __cpp_lib_format -# error "__cpp_lib_format should be defined in c++23" -# endif -# if __cpp_lib_format != 202110L -# error "__cpp_lib_format should have the value 202110L in c++23" -# endif -# else -# ifdef __cpp_lib_format -# error "__cpp_lib_format should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" -# endif -# endif - -# ifdef __cpp_lib_format_path -# error "__cpp_lib_format_path should not be defined before c++26" -# endif - -# ifndef __cpp_lib_format_ranges -# error "__cpp_lib_format_ranges should be defined in c++23" -# endif -# if __cpp_lib_format_ranges != 202207L -# error "__cpp_lib_format_ranges should have the value 202207L in c++23" -# endif - -# ifndef __cpp_lib_format_uchar -# error "__cpp_lib_format_uchar should be defined in c++23" -# endif -# if __cpp_lib_format_uchar != 202311L -# error "__cpp_lib_format_uchar should have the value 202311L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_formatters -# error "__cpp_lib_formatters should be defined in c++23" -# endif -# if __cpp_lib_formatters != 202302L -# error "__cpp_lib_formatters should have the value 202302L in c++23" -# endif -# else -# ifdef __cpp_lib_formatters -# error "__cpp_lib_formatters should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_forward_like -# error "__cpp_lib_forward_like should be defined in c++23" -# endif -# if __cpp_lib_forward_like != 202207L -# error "__cpp_lib_forward_like should have the value 202207L in c++23" -# endif - -# ifdef __cpp_lib_freestanding_algorithm -# error "__cpp_lib_freestanding_algorithm should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_array -# error "__cpp_lib_freestanding_array should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_cstring -# error "__cpp_lib_freestanding_cstring should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_expected -# error "__cpp_lib_freestanding_expected should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_mdspan -# error "__cpp_lib_freestanding_mdspan should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_optional -# error "__cpp_lib_freestanding_optional should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_string_view -# error "__cpp_lib_freestanding_string_view should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_variant -# error "__cpp_lib_freestanding_variant should not be defined before c++26" -# endif - -# ifdef __cpp_lib_fstream_native_handle -# error "__cpp_lib_fstream_native_handle should not be defined before c++26" -# endif - -# ifdef __cpp_lib_function_ref -# error "__cpp_lib_function_ref should not be defined before c++26" -# endif - -# ifndef __cpp_lib_gcd_lcm -# error "__cpp_lib_gcd_lcm should be defined in c++23" -# endif -# if __cpp_lib_gcd_lcm != 201606L -# error "__cpp_lib_gcd_lcm should have the value 201606L in c++23" -# endif - -# ifdef __cpp_lib_generate_random -# error "__cpp_lib_generate_random should not be defined before c++26" -# endif - -# ifndef __cpp_lib_generic_associative_lookup -# error "__cpp_lib_generic_associative_lookup should be defined in c++23" -# endif -# if __cpp_lib_generic_associative_lookup != 201304L -# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_generic_unordered_lookup -# error "__cpp_lib_generic_unordered_lookup should be defined in c++23" -# endif -# if __cpp_lib_generic_unordered_lookup != 201811L -# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)) -# ifndef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should be defined in c++23" -# endif -# if __cpp_lib_hardware_interference_size != 201703L -# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++23" -# endif -# else -# ifdef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))' is not met!" -# endif -# endif - -# ifndef __cpp_lib_has_unique_object_representations -# error "__cpp_lib_has_unique_object_representations should be defined in c++23" -# endif -# if __cpp_lib_has_unique_object_representations != 201606L -# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++23" -# endif - -# ifdef __cpp_lib_hazard_pointer -# error "__cpp_lib_hazard_pointer should not be defined before c++26" -# endif - -# ifndef __cpp_lib_hypot -# error "__cpp_lib_hypot should be defined in c++23" -# endif -# if __cpp_lib_hypot != 201603L -# error "__cpp_lib_hypot should have the value 201603L in c++23" -# endif - -# ifndef __cpp_lib_incomplete_container_elements -# error "__cpp_lib_incomplete_container_elements should be defined in c++23" -# endif -# if __cpp_lib_incomplete_container_elements != 201505L -# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++23" -# endif - -# ifdef __cpp_lib_inplace_vector -# error "__cpp_lib_inplace_vector should not be defined before c++26" -# endif - -# ifndef __cpp_lib_int_pow2 -# error "__cpp_lib_int_pow2 should be defined in c++23" -# endif -# if __cpp_lib_int_pow2 != 202002L -# error "__cpp_lib_int_pow2 should have the value 202002L in c++23" -# endif - -# ifndef __cpp_lib_integer_comparison_functions -# error "__cpp_lib_integer_comparison_functions should be defined in c++23" -# endif -# if __cpp_lib_integer_comparison_functions != 202002L -# error "__cpp_lib_integer_comparison_functions should have the value 202002L in c++23" -# endif - -# ifndef __cpp_lib_integer_sequence -# error "__cpp_lib_integer_sequence should be defined in c++23" -# endif -# if __cpp_lib_integer_sequence != 201304L -# error "__cpp_lib_integer_sequence should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_integral_constant_callable -# error "__cpp_lib_integral_constant_callable should be defined in c++23" -# endif -# if __cpp_lib_integral_constant_callable != 201304L -# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_interpolate -# error "__cpp_lib_interpolate should be defined in c++23" -# endif -# if __cpp_lib_interpolate != 201902L -# error "__cpp_lib_interpolate should have the value 201902L in c++23" -# endif - -# ifndef __cpp_lib_invoke -# error "__cpp_lib_invoke should be defined in c++23" -# endif -# if __cpp_lib_invoke != 201411L -# error "__cpp_lib_invoke should have the value 201411L in c++23" -# endif - -# ifndef __cpp_lib_invoke_r -# error "__cpp_lib_invoke_r should be defined in c++23" -# endif -# if __cpp_lib_invoke_r != 202106L -# error "__cpp_lib_invoke_r should have the value 202106L in c++23" -# endif - -# ifndef __cpp_lib_ios_noreplace -# error "__cpp_lib_ios_noreplace should be defined in c++23" -# endif -# if __cpp_lib_ios_noreplace != 202207L -# error "__cpp_lib_ios_noreplace should have the value 202207L in c++23" -# endif - -# ifndef __cpp_lib_is_aggregate -# error "__cpp_lib_is_aggregate should be defined in c++23" -# endif -# if __cpp_lib_is_aggregate != 201703L -# error "__cpp_lib_is_aggregate should have the value 201703L in c++23" -# endif - -# ifndef __cpp_lib_is_constant_evaluated -# error "__cpp_lib_is_constant_evaluated should be defined in c++23" -# endif -# if __cpp_lib_is_constant_evaluated != 201811L -# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++23" -# endif - -# ifndef __cpp_lib_is_final -# error "__cpp_lib_is_final should be defined in c++23" -# endif -# if __cpp_lib_is_final != 201402L -# error "__cpp_lib_is_final should have the value 201402L in c++23" -# endif - -# if __has_builtin(__builtin_is_implicit_lifetime) -# ifndef __cpp_lib_is_implicit_lifetime -# error "__cpp_lib_is_implicit_lifetime should be defined in c++23" -# endif -# if __cpp_lib_is_implicit_lifetime != 202302L -# error "__cpp_lib_is_implicit_lifetime should have the value 202302L in c++23" -# endif -# else -# ifdef __cpp_lib_is_implicit_lifetime -# error "__cpp_lib_is_implicit_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_implicit_lifetime)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_is_invocable -# error "__cpp_lib_is_invocable should be defined in c++23" -# endif -# if __cpp_lib_is_invocable != 201703L -# error "__cpp_lib_is_invocable should have the value 201703L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_is_layout_compatible -# error "__cpp_lib_is_layout_compatible should be defined in c++23" -# endif -# if __cpp_lib_is_layout_compatible != 201907L -# error "__cpp_lib_is_layout_compatible should have the value 201907L in c++23" -# endif -# else -# ifdef __cpp_lib_is_layout_compatible -# error "__cpp_lib_is_layout_compatible should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_is_nothrow_convertible -# error "__cpp_lib_is_nothrow_convertible should be defined in c++23" -# endif -# if __cpp_lib_is_nothrow_convertible != 201806L -# error "__cpp_lib_is_nothrow_convertible should have the value 201806L in c++23" -# endif - -# ifndef __cpp_lib_is_null_pointer -# error "__cpp_lib_is_null_pointer should be defined in c++23" -# endif -# if __cpp_lib_is_null_pointer != 201309L -# error "__cpp_lib_is_null_pointer should have the value 201309L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_is_pointer_interconvertible -# error "__cpp_lib_is_pointer_interconvertible should be defined in c++23" -# endif -# if __cpp_lib_is_pointer_interconvertible != 201907L -# error "__cpp_lib_is_pointer_interconvertible should have the value 201907L in c++23" -# endif -# else -# ifdef __cpp_lib_is_pointer_interconvertible -# error "__cpp_lib_is_pointer_interconvertible should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_is_scoped_enum -# error "__cpp_lib_is_scoped_enum should be defined in c++23" -# endif -# if __cpp_lib_is_scoped_enum != 202011L -# error "__cpp_lib_is_scoped_enum should have the value 202011L in c++23" -# endif - -# ifdef __cpp_lib_is_sufficiently_aligned -# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" -# endif - -# ifndef __cpp_lib_is_swappable -# error "__cpp_lib_is_swappable should be defined in c++23" -# endif -# if __cpp_lib_is_swappable != 201603L -# error "__cpp_lib_is_swappable should have the value 201603L in c++23" -# endif - -# ifdef __cpp_lib_is_virtual_base_of -# error "__cpp_lib_is_virtual_base_of should not be defined before c++26" -# endif - -# ifdef __cpp_lib_is_within_lifetime -# error "__cpp_lib_is_within_lifetime should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_jthread -# error "__cpp_lib_jthread should be defined in c++23" -# endif -# if __cpp_lib_jthread != 201911L -# error "__cpp_lib_jthread should have the value 201911L in c++23" -# endif -# else -# ifdef __cpp_lib_jthread -# error "__cpp_lib_jthread should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_latch -# error "__cpp_lib_latch should be defined in c++23" -# endif -# if __cpp_lib_latch != 201907L -# error "__cpp_lib_latch should have the value 201907L in c++23" -# endif -# else -# ifdef __cpp_lib_latch -# error "__cpp_lib_latch should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_launder -# error "__cpp_lib_launder should be defined in c++23" -# endif -# if __cpp_lib_launder != 201606L -# error "__cpp_lib_launder should have the value 201606L in c++23" -# endif - -# ifdef __cpp_lib_linalg -# error "__cpp_lib_linalg should not be defined before c++26" -# endif - -# ifndef __cpp_lib_list_remove_return_type -# error "__cpp_lib_list_remove_return_type should be defined in c++23" -# endif -# if __cpp_lib_list_remove_return_type != 201806L -# error "__cpp_lib_list_remove_return_type should have the value 201806L in c++23" -# endif - -# ifndef __cpp_lib_logical_traits -# error "__cpp_lib_logical_traits should be defined in c++23" -# endif -# if __cpp_lib_logical_traits != 201510L -# error "__cpp_lib_logical_traits should have the value 201510L in c++23" -# endif - -# ifndef __cpp_lib_make_from_tuple -# error "__cpp_lib_make_from_tuple should be defined in c++23" -# endif -# if __cpp_lib_make_from_tuple != 201606L -# error "__cpp_lib_make_from_tuple should have the value 201606L in c++23" -# endif - -# ifndef __cpp_lib_make_reverse_iterator -# error "__cpp_lib_make_reverse_iterator should be defined in c++23" -# endif -# if __cpp_lib_make_reverse_iterator != 201402L -# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++23" -# endif - -# ifndef __cpp_lib_make_unique -# error "__cpp_lib_make_unique should be defined in c++23" -# endif -# if __cpp_lib_make_unique != 201304L -# error "__cpp_lib_make_unique should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_map_try_emplace -# error "__cpp_lib_map_try_emplace should be defined in c++23" -# endif -# if __cpp_lib_map_try_emplace != 201411L -# error "__cpp_lib_map_try_emplace should have the value 201411L in c++23" -# endif - -# ifndef __cpp_lib_math_constants -# error "__cpp_lib_math_constants should be defined in c++23" -# endif -# if __cpp_lib_math_constants != 201907L -# error "__cpp_lib_math_constants should have the value 201907L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should be defined in c++23" -# endif -# if __cpp_lib_math_special_functions != 201603L -# error "__cpp_lib_math_special_functions should have the value 201603L in c++23" -# endif -# else -# ifdef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_mdspan -# error "__cpp_lib_mdspan should be defined in c++23" -# endif -# if __cpp_lib_mdspan != 202207L -# error "__cpp_lib_mdspan should have the value 202207L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR -# ifndef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should be defined in c++23" -# endif -# if __cpp_lib_memory_resource != 201603L -# error "__cpp_lib_memory_resource should have the value 201603L in c++23" -# endif -# else -# ifdef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" -# endif -# endif - -# ifndef __cpp_lib_modules -# error "__cpp_lib_modules should be defined in c++23" -# endif -# if __cpp_lib_modules != 202207L -# error "__cpp_lib_modules should have the value 202207L in c++23" -# endif - -# ifndef __cpp_lib_move_iterator_concept -# error "__cpp_lib_move_iterator_concept should be defined in c++23" -# endif -# if __cpp_lib_move_iterator_concept != 202207L -# error "__cpp_lib_move_iterator_concept should have the value 202207L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_move_only_function -# error "__cpp_lib_move_only_function should be defined in c++23" -# endif -# if __cpp_lib_move_only_function != 202110L -# error "__cpp_lib_move_only_function should have the value 202110L in c++23" -# endif -# else -# ifdef __cpp_lib_move_only_function -# error "__cpp_lib_move_only_function should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_node_extract -# error "__cpp_lib_node_extract should be defined in c++23" -# endif -# if __cpp_lib_node_extract != 201606L -# error "__cpp_lib_node_extract should have the value 201606L in c++23" -# endif - -# ifndef __cpp_lib_nonmember_container_access -# error "__cpp_lib_nonmember_container_access should be defined in c++23" -# endif -# if __cpp_lib_nonmember_container_access != 201411L -# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++23" -# endif - -# ifndef __cpp_lib_not_fn -# error "__cpp_lib_not_fn should be defined in c++23" -# endif -# if __cpp_lib_not_fn != 201603L -# error "__cpp_lib_not_fn should have the value 201603L in c++23" -# endif - -# ifndef __cpp_lib_null_iterators -# error "__cpp_lib_null_iterators should be defined in c++23" -# endif -# if __cpp_lib_null_iterators != 201304L -# error "__cpp_lib_null_iterators should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_optional -# error "__cpp_lib_optional should be defined in c++23" -# endif -# if __cpp_lib_optional != 202110L -# error "__cpp_lib_optional should have the value 202110L in c++23" -# endif - -# ifdef __cpp_lib_optional_range_support -# error "__cpp_lib_optional_range_support should not be defined before c++26" -# endif - -# ifndef __cpp_lib_out_ptr -# error "__cpp_lib_out_ptr should be defined in c++23" -# endif -# if __cpp_lib_out_ptr != 202106L -# error "__cpp_lib_out_ptr should have the value 202106L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should be defined in c++23" -# endif -# if __cpp_lib_parallel_algorithm != 201603L -# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++23" -# endif -# else -# ifdef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_philox_engine -# error "__cpp_lib_philox_engine should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR -# ifndef __cpp_lib_polymorphic_allocator -# error "__cpp_lib_polymorphic_allocator should be defined in c++23" -# endif -# if __cpp_lib_polymorphic_allocator != 201902L -# error "__cpp_lib_polymorphic_allocator should have the value 201902L in c++23" -# endif -# else -# ifdef __cpp_lib_polymorphic_allocator -# error "__cpp_lib_polymorphic_allocator should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT -# ifndef __cpp_lib_print -# error "__cpp_lib_print should be defined in c++23" -# endif -# if __cpp_lib_print != 202207L -# error "__cpp_lib_print should have the value 202207L in c++23" -# endif -# else -# ifdef __cpp_lib_print -# error "__cpp_lib_print should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION -# ifndef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should be defined in c++23" -# endif -# if __cpp_lib_quoted_string_io != 201304L -# error "__cpp_lib_quoted_string_io should have the value 201304L in c++23" -# endif -# else -# ifdef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" -# endif -# endif - -# ifndef __cpp_lib_ranges -# error "__cpp_lib_ranges should be defined in c++23" -# endif -# if __cpp_lib_ranges != 202406L -# error "__cpp_lib_ranges should have the value 202406L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_as_const -# error "__cpp_lib_ranges_as_const should be defined in c++23" -# endif -# if __cpp_lib_ranges_as_const != 202207L -# error "__cpp_lib_ranges_as_const should have the value 202207L in c++23" -# endif -# else -# ifdef __cpp_lib_ranges_as_const -# error "__cpp_lib_ranges_as_const should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ranges_as_rvalue -# error "__cpp_lib_ranges_as_rvalue should be defined in c++23" -# endif -# if __cpp_lib_ranges_as_rvalue != 202207L -# error "__cpp_lib_ranges_as_rvalue should have the value 202207L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should be defined in c++23" -# endif -# if __cpp_lib_ranges_chunk != 202202L -# error "__cpp_lib_ranges_chunk should have the value 202202L in c++23" -# endif -# else -# ifdef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ranges_chunk_by -# error "__cpp_lib_ranges_chunk_by should be defined in c++23" -# endif -# if __cpp_lib_ranges_chunk_by != 202202L -# error "__cpp_lib_ranges_chunk_by should have the value 202202L in c++23" -# endif - -# ifdef __cpp_lib_ranges_concat -# error "__cpp_lib_ranges_concat should not be defined before c++26" -# endif - -# ifndef __cpp_lib_ranges_contains -# error "__cpp_lib_ranges_contains should be defined in c++23" -# endif -# if __cpp_lib_ranges_contains != 202207L -# error "__cpp_lib_ranges_contains should have the value 202207L in c++23" -# endif - -# ifndef __cpp_lib_ranges_find_last -# error "__cpp_lib_ranges_find_last should be defined in c++23" -# endif -# if __cpp_lib_ranges_find_last != 202207L -# error "__cpp_lib_ranges_find_last should have the value 202207L in c++23" -# endif - -# ifdef __cpp_lib_ranges_indices -# error "__cpp_lib_ranges_indices should not be defined before c++26" -# endif - -# ifndef __cpp_lib_ranges_iota -# error "__cpp_lib_ranges_iota should be defined in c++23" -# endif -# if __cpp_lib_ranges_iota != 202202L -# error "__cpp_lib_ranges_iota should have the value 202202L in c++23" -# endif - -# ifndef __cpp_lib_ranges_join_with -# error "__cpp_lib_ranges_join_with should be defined in c++23" -# endif -# if __cpp_lib_ranges_join_with != 202202L -# error "__cpp_lib_ranges_join_with should have the value 202202L in c++23" -# endif - -# ifndef __cpp_lib_ranges_repeat -# error "__cpp_lib_ranges_repeat should be defined in c++23" -# endif -# if __cpp_lib_ranges_repeat != 202207L -# error "__cpp_lib_ranges_repeat should have the value 202207L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_slide -# error "__cpp_lib_ranges_slide should be defined in c++23" -# endif -# if __cpp_lib_ranges_slide != 202202L -# error "__cpp_lib_ranges_slide should have the value 202202L in c++23" -# endif -# else -# ifdef __cpp_lib_ranges_slide -# error "__cpp_lib_ranges_slide should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ranges_starts_ends_with -# error "__cpp_lib_ranges_starts_ends_with should be defined in c++23" -# endif -# if __cpp_lib_ranges_starts_ends_with != 202106L -# error "__cpp_lib_ranges_starts_ends_with should have the value 202106L in c++23" -# endif - -# ifndef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should be defined in c++23" -# endif -# if __cpp_lib_ranges_to_container != 202202L -# error "__cpp_lib_ranges_to_container should have the value 202202L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_zip -# error "__cpp_lib_ranges_zip should be defined in c++23" -# endif -# if __cpp_lib_ranges_zip != 202110L -# error "__cpp_lib_ranges_zip should have the value 202110L in c++23" -# endif -# else -# ifdef __cpp_lib_ranges_zip -# error "__cpp_lib_ranges_zip should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_ratio -# error "__cpp_lib_ratio should not be defined before c++26" -# endif - -# ifndef __cpp_lib_raw_memory_algorithms -# error "__cpp_lib_raw_memory_algorithms should be defined in c++23" -# endif -# if __cpp_lib_raw_memory_algorithms != 201606L -# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++23" -# endif - -# ifdef __cpp_lib_rcu -# error "__cpp_lib_rcu should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_reference_from_temporary -# error "__cpp_lib_reference_from_temporary should be defined in c++23" -# endif -# if __cpp_lib_reference_from_temporary != 202202L -# error "__cpp_lib_reference_from_temporary should have the value 202202L in c++23" -# endif -# else -# ifdef __cpp_lib_reference_from_temporary -# error "__cpp_lib_reference_from_temporary should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_reference_wrapper -# error "__cpp_lib_reference_wrapper should not be defined before c++26" -# endif - -# ifndef __cpp_lib_remove_cvref -# error "__cpp_lib_remove_cvref should be defined in c++23" -# endif -# if __cpp_lib_remove_cvref != 201711L -# error "__cpp_lib_remove_cvref should have the value 201711L in c++23" -# endif - -# ifndef __cpp_lib_result_of_sfinae -# error "__cpp_lib_result_of_sfinae should be defined in c++23" -# endif -# if __cpp_lib_result_of_sfinae != 201210L -# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++23" -# endif - -# ifndef __cpp_lib_robust_nonmodifying_seq_ops -# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++23" -# endif -# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L -# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_sample -# error "__cpp_lib_sample should be defined in c++23" -# endif -# if __cpp_lib_sample != 201603L -# error "__cpp_lib_sample should have the value 201603L in c++23" -# endif - -# ifdef __cpp_lib_saturation_arithmetic -# error "__cpp_lib_saturation_arithmetic should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should be defined in c++23" -# endif -# if __cpp_lib_scoped_lock != 201703L -# error "__cpp_lib_scoped_lock should have the value 201703L in c++23" -# endif -# else -# ifdef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_semaphore -# error "__cpp_lib_semaphore should be defined in c++23" -# endif -# if __cpp_lib_semaphore != 201907L -# error "__cpp_lib_semaphore should have the value 201907L in c++23" -# endif -# else -# ifdef __cpp_lib_semaphore -# error "__cpp_lib_semaphore should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# ifdef __cpp_lib_senders -# error "__cpp_lib_senders should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should be defined in c++23" -# endif -# if __cpp_lib_shared_mutex != 201505L -# error "__cpp_lib_shared_mutex should have the value 201505L in c++23" -# endif -# else -# ifdef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifndef __cpp_lib_shared_ptr_arrays -# error "__cpp_lib_shared_ptr_arrays should be defined in c++23" -# endif -# if __cpp_lib_shared_ptr_arrays != 201707L -# error "__cpp_lib_shared_ptr_arrays should have the value 201707L in c++23" -# endif - -# ifndef __cpp_lib_shared_ptr_weak_type -# error "__cpp_lib_shared_ptr_weak_type should be defined in c++23" -# endif -# if __cpp_lib_shared_ptr_weak_type != 201606L -# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should be defined in c++23" -# endif -# if __cpp_lib_shared_timed_mutex != 201402L -# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++23" -# endif -# else -# ifdef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifndef __cpp_lib_shift -# error "__cpp_lib_shift should be defined in c++23" -# endif -# if __cpp_lib_shift != 201806L -# error "__cpp_lib_shift should have the value 201806L in c++23" -# endif - -# ifndef __cpp_lib_smart_ptr_for_overwrite -# error "__cpp_lib_smart_ptr_for_overwrite should be defined in c++23" -# endif -# if __cpp_lib_smart_ptr_for_overwrite != 202002L -# error "__cpp_lib_smart_ptr_for_overwrite should have the value 202002L in c++23" -# endif - -# ifdef __cpp_lib_smart_ptr_owner_equality -# error "__cpp_lib_smart_ptr_owner_equality should not be defined before c++26" -# endif - -# ifndef __cpp_lib_source_location -# error "__cpp_lib_source_location should be defined in c++23" -# endif -# if __cpp_lib_source_location != 201907L -# error "__cpp_lib_source_location should have the value 201907L in c++23" -# endif - -# ifndef __cpp_lib_span -# error "__cpp_lib_span should be defined in c++23" -# endif -# if __cpp_lib_span != 202002L -# error "__cpp_lib_span should have the value 202002L in c++23" -# endif - -# ifdef __cpp_lib_span_at -# error "__cpp_lib_span_at should not be defined before c++26" -# endif - -# ifdef __cpp_lib_span_initializer_list -# error "__cpp_lib_span_initializer_list should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_spanstream -# error "__cpp_lib_spanstream should be defined in c++23" -# endif -# if __cpp_lib_spanstream != 202106L -# error "__cpp_lib_spanstream should have the value 202106L in c++23" -# endif -# else -# ifdef __cpp_lib_spanstream -# error "__cpp_lib_spanstream should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ssize -# error "__cpp_lib_ssize should be defined in c++23" -# endif -# if __cpp_lib_ssize != 201902L -# error "__cpp_lib_ssize should have the value 201902L in c++23" -# endif - -# ifdef __cpp_lib_sstream_from_string_view -# error "__cpp_lib_sstream_from_string_view should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_stacktrace -# error "__cpp_lib_stacktrace should be defined in c++23" -# endif -# if __cpp_lib_stacktrace != 202011L -# error "__cpp_lib_stacktrace should have the value 202011L in c++23" -# endif -# else -# ifdef __cpp_lib_stacktrace -# error "__cpp_lib_stacktrace should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_starts_ends_with -# error "__cpp_lib_starts_ends_with should be defined in c++23" -# endif -# if __cpp_lib_starts_ends_with != 201711L -# error "__cpp_lib_starts_ends_with should have the value 201711L in c++23" -# endif - -# ifndef __cpp_lib_stdatomic_h -# error "__cpp_lib_stdatomic_h should be defined in c++23" -# endif -# if __cpp_lib_stdatomic_h != 202011L -# error "__cpp_lib_stdatomic_h should have the value 202011L in c++23" -# endif - -# ifndef __cpp_lib_string_contains -# error "__cpp_lib_string_contains should be defined in c++23" -# endif -# if __cpp_lib_string_contains != 202011L -# error "__cpp_lib_string_contains should have the value 202011L in c++23" -# endif - -# ifndef __cpp_lib_string_resize_and_overwrite -# error "__cpp_lib_string_resize_and_overwrite should be defined in c++23" -# endif -# if __cpp_lib_string_resize_and_overwrite != 202110L -# error "__cpp_lib_string_resize_and_overwrite should have the value 202110L in c++23" -# endif - -# ifdef __cpp_lib_string_subview -# error "__cpp_lib_string_subview should not be defined before c++26" -# endif - -# ifndef __cpp_lib_string_udls -# error "__cpp_lib_string_udls should be defined in c++23" -# endif -# if __cpp_lib_string_udls != 201304L -# error "__cpp_lib_string_udls should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_string_view -# error "__cpp_lib_string_view should be defined in c++23" -# endif -# if __cpp_lib_string_view != 201803L -# error "__cpp_lib_string_view should have the value 201803L in c++23" -# endif - -# ifdef __cpp_lib_submdspan -# error "__cpp_lib_submdspan should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM -# ifndef __cpp_lib_syncbuf -# error "__cpp_lib_syncbuf should be defined in c++23" -# endif -# if __cpp_lib_syncbuf != 201803L -# error "__cpp_lib_syncbuf should have the value 201803L in c++23" -# endif -# else -# ifdef __cpp_lib_syncbuf -# error "__cpp_lib_syncbuf should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM' is not met!" -# endif -# endif - -# ifdef __cpp_lib_text_encoding -# error "__cpp_lib_text_encoding should not be defined before c++26" -# endif - -# ifndef __cpp_lib_three_way_comparison -# error "__cpp_lib_three_way_comparison should be defined in c++23" -# endif -# if __cpp_lib_three_way_comparison != 201907L -# error "__cpp_lib_three_way_comparison should have the value 201907L in c++23" -# endif - -# ifndef __cpp_lib_to_address -# error "__cpp_lib_to_address should be defined in c++23" -# endif -# if __cpp_lib_to_address != 201711L -# error "__cpp_lib_to_address should have the value 201711L in c++23" -# endif - -# ifndef __cpp_lib_to_array -# error "__cpp_lib_to_array should be defined in c++23" -# endif -# if __cpp_lib_to_array != 201907L -# error "__cpp_lib_to_array should have the value 201907L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should be defined in c++23" -# endif -# if __cpp_lib_to_chars != 201611L -# error "__cpp_lib_to_chars should have the value 201611L in c++23" -# endif -# else -# ifdef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_to_string -# error "__cpp_lib_to_string should not be defined before c++26" -# endif - -# ifndef __cpp_lib_to_underlying -# error "__cpp_lib_to_underlying should be defined in c++23" -# endif -# if __cpp_lib_to_underlying != 202102L -# error "__cpp_lib_to_underlying should have the value 202102L in c++23" -# endif - -# ifndef __cpp_lib_transformation_trait_aliases -# error "__cpp_lib_transformation_trait_aliases should be defined in c++23" -# endif -# if __cpp_lib_transformation_trait_aliases != 201304L -# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_transparent_operators -# error "__cpp_lib_transparent_operators should be defined in c++23" -# endif -# if __cpp_lib_transparent_operators != 201510L -# error "__cpp_lib_transparent_operators should have the value 201510L in c++23" -# endif - -# ifndef __cpp_lib_tuple_element_t -# error "__cpp_lib_tuple_element_t should be defined in c++23" -# endif -# if __cpp_lib_tuple_element_t != 201402L -# error "__cpp_lib_tuple_element_t should have the value 201402L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_tuple_like -# error "__cpp_lib_tuple_like should be defined in c++23" -# endif -# if __cpp_lib_tuple_like != 202207L -# error "__cpp_lib_tuple_like should have the value 202207L in c++23" -# endif -# else -# ifdef __cpp_lib_tuple_like -# error "__cpp_lib_tuple_like should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_tuples_by_type -# error "__cpp_lib_tuples_by_type should be defined in c++23" -# endif -# if __cpp_lib_tuples_by_type != 201304L -# error "__cpp_lib_tuples_by_type should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_type_identity -# error "__cpp_lib_type_identity should be defined in c++23" -# endif -# if __cpp_lib_type_identity != 201806L -# error "__cpp_lib_type_identity should have the value 201806L in c++23" -# endif - -# ifndef __cpp_lib_type_trait_variable_templates -# error "__cpp_lib_type_trait_variable_templates should be defined in c++23" -# endif -# if __cpp_lib_type_trait_variable_templates != 201510L -# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++23" -# endif - -# ifndef __cpp_lib_uncaught_exceptions -# error "__cpp_lib_uncaught_exceptions should be defined in c++23" -# endif -# if __cpp_lib_uncaught_exceptions != 201411L -# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++23" -# endif - -# ifndef __cpp_lib_unordered_map_try_emplace -# error "__cpp_lib_unordered_map_try_emplace should be defined in c++23" -# endif -# if __cpp_lib_unordered_map_try_emplace != 201411L -# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++23" -# endif - -# ifndef __cpp_lib_unreachable -# error "__cpp_lib_unreachable should be defined in c++23" -# endif -# if __cpp_lib_unreachable != 202202L -# error "__cpp_lib_unreachable should have the value 202202L in c++23" -# endif - -# ifndef __cpp_lib_unwrap_ref -# error "__cpp_lib_unwrap_ref should be defined in c++23" -# endif -# if __cpp_lib_unwrap_ref != 201811L -# error "__cpp_lib_unwrap_ref should have the value 201811L in c++23" -# endif - -# ifndef __cpp_lib_variant -# error "__cpp_lib_variant should be defined in c++23" -# endif -# if __cpp_lib_variant != 202106L -# error "__cpp_lib_variant should have the value 202106L in c++23" -# endif - -# ifndef __cpp_lib_void_t -# error "__cpp_lib_void_t should be defined in c++23" -# endif -# if __cpp_lib_void_t != 201411L -# error "__cpp_lib_void_t should have the value 201411L in c++23" -# endif - -#elif TEST_STD_VER > 23 - -# ifndef __cpp_lib_adaptor_iterator_pair_constructor -# error "__cpp_lib_adaptor_iterator_pair_constructor should be defined in c++26" -# endif -# if __cpp_lib_adaptor_iterator_pair_constructor != 202106L -# error "__cpp_lib_adaptor_iterator_pair_constructor should have the value 202106L in c++26" -# endif - -# ifndef __cpp_lib_addressof_constexpr -# error "__cpp_lib_addressof_constexpr should be defined in c++26" -# endif -# if __cpp_lib_addressof_constexpr != 201603L -# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_aligned_accessor -# error "__cpp_lib_aligned_accessor should be defined in c++26" -# endif -# if __cpp_lib_aligned_accessor != 202411L -# error "__cpp_lib_aligned_accessor should have the value 202411L in c++26" -# endif - -# ifndef __cpp_lib_allocate_at_least -# error "__cpp_lib_allocate_at_least should be defined in c++26" -# endif -# if __cpp_lib_allocate_at_least != 202302L -# error "__cpp_lib_allocate_at_least should have the value 202302L in c++26" -# endif - -# ifndef __cpp_lib_allocator_traits_is_always_equal -# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++26" -# endif -# if __cpp_lib_allocator_traits_is_always_equal != 201411L -# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++26" -# endif - -# ifndef __cpp_lib_any -# error "__cpp_lib_any should be defined in c++26" -# endif -# if __cpp_lib_any != 201606L -# error "__cpp_lib_any should have the value 201606L in c++26" -# endif - -# ifndef __cpp_lib_apply -# error "__cpp_lib_apply should be defined in c++26" -# endif -# if __cpp_lib_apply != 201603L -# error "__cpp_lib_apply should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_array_constexpr -# error "__cpp_lib_array_constexpr should be defined in c++26" -# endif -# if __cpp_lib_array_constexpr != 201811L -# error "__cpp_lib_array_constexpr should have the value 201811L in c++26" -# endif - -# ifndef __cpp_lib_as_const -# error "__cpp_lib_as_const should be defined in c++26" -# endif -# if __cpp_lib_as_const != 201510L -# error "__cpp_lib_as_const should have the value 201510L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_associative_heterogeneous_erasure -# error "__cpp_lib_associative_heterogeneous_erasure should be defined in c++26" -# endif -# if __cpp_lib_associative_heterogeneous_erasure != 202110L -# error "__cpp_lib_associative_heterogeneous_erasure should have the value 202110L in c++26" -# endif -# else -# ifdef __cpp_lib_associative_heterogeneous_erasure -# error "__cpp_lib_associative_heterogeneous_erasure should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_associative_heterogeneous_insertion -# error "__cpp_lib_associative_heterogeneous_insertion should be defined in c++26" -# endif -# if __cpp_lib_associative_heterogeneous_insertion != 202306L -# error "__cpp_lib_associative_heterogeneous_insertion should have the value 202306L in c++26" -# endif -# else -# ifdef __cpp_lib_associative_heterogeneous_insertion -# error "__cpp_lib_associative_heterogeneous_insertion should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_assume_aligned -# error "__cpp_lib_assume_aligned should be defined in c++26" -# endif -# if __cpp_lib_assume_aligned != 201811L -# error "__cpp_lib_assume_aligned should have the value 201811L in c++26" -# endif - -# ifndef __cpp_lib_atomic_flag_test -# error "__cpp_lib_atomic_flag_test should be defined in c++26" -# endif -# if __cpp_lib_atomic_flag_test != 201907L -# error "__cpp_lib_atomic_flag_test should have the value 201907L in c++26" -# endif - -# ifndef __cpp_lib_atomic_float -# error "__cpp_lib_atomic_float should be defined in c++26" -# endif -# if __cpp_lib_atomic_float != 201711L -# error "__cpp_lib_atomic_float should have the value 201711L in c++26" -# endif - -# ifndef __cpp_lib_atomic_is_always_lock_free -# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++26" -# endif -# if __cpp_lib_atomic_is_always_lock_free != 201603L -# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_atomic_lock_free_type_aliases -# error "__cpp_lib_atomic_lock_free_type_aliases should be defined in c++26" -# endif -# if __cpp_lib_atomic_lock_free_type_aliases != 201907L -# error "__cpp_lib_atomic_lock_free_type_aliases should have the value 201907L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_atomic_min_max -# error "__cpp_lib_atomic_min_max should be defined in c++26" -# endif -# if __cpp_lib_atomic_min_max != 202403L -# error "__cpp_lib_atomic_min_max should have the value 202403L in c++26" -# endif -# else -# ifdef __cpp_lib_atomic_min_max -# error "__cpp_lib_atomic_min_max should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_atomic_ref -# error "__cpp_lib_atomic_ref should be defined in c++26" -# endif -# if __cpp_lib_atomic_ref != 201806L -# error "__cpp_lib_atomic_ref should have the value 201806L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_atomic_shared_ptr -# error "__cpp_lib_atomic_shared_ptr should be defined in c++26" -# endif -# if __cpp_lib_atomic_shared_ptr != 201711L -# error "__cpp_lib_atomic_shared_ptr should have the value 201711L in c++26" -# endif -# else -# ifdef __cpp_lib_atomic_shared_ptr -# error "__cpp_lib_atomic_shared_ptr should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_atomic_value_initialization -# error "__cpp_lib_atomic_value_initialization should be defined in c++26" -# endif -# if __cpp_lib_atomic_value_initialization != 201911L -# error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC -# ifndef __cpp_lib_atomic_wait -# error "__cpp_lib_atomic_wait should be defined in c++26" -# endif -# if __cpp_lib_atomic_wait != 201907L -# error "__cpp_lib_atomic_wait should have the value 201907L in c++26" -# endif -# else -# ifdef __cpp_lib_atomic_wait -# error "__cpp_lib_atomic_wait should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_barrier -# error "__cpp_lib_barrier should be defined in c++26" -# endif -# if __cpp_lib_barrier != 201907L -# error "__cpp_lib_barrier should have the value 201907L in c++26" -# endif -# else -# ifdef __cpp_lib_barrier -# error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_bind_back -# error "__cpp_lib_bind_back should be defined in c++26" -# endif -# if __cpp_lib_bind_back != 202202L -# error "__cpp_lib_bind_back should have the value 202202L in c++26" -# endif - -# ifndef __cpp_lib_bind_front -# error "__cpp_lib_bind_front should be defined in c++26" -# endif -# if __cpp_lib_bind_front != 202306L -# error "__cpp_lib_bind_front should have the value 202306L in c++26" -# endif - -# ifndef __cpp_lib_bit_cast -# error "__cpp_lib_bit_cast should be defined in c++26" -# endif -# if __cpp_lib_bit_cast != 201806L -# error "__cpp_lib_bit_cast should have the value 201806L in c++26" -# endif - -# ifndef __cpp_lib_bitops -# error "__cpp_lib_bitops should be defined in c++26" -# endif -# if __cpp_lib_bitops != 201907L -# error "__cpp_lib_bitops should have the value 201907L in c++26" -# endif - -# ifndef __cpp_lib_bitset -# error "__cpp_lib_bitset should be defined in c++26" -# endif -# if __cpp_lib_bitset != 202306L -# error "__cpp_lib_bitset should have the value 202306L in c++26" -# endif - -# ifndef __cpp_lib_bool_constant -# error "__cpp_lib_bool_constant should be defined in c++26" -# endif -# if __cpp_lib_bool_constant != 201505L -# error "__cpp_lib_bool_constant should have the value 201505L in c++26" -# endif - -# ifndef __cpp_lib_bounded_array_traits -# error "__cpp_lib_bounded_array_traits should be defined in c++26" -# endif -# if __cpp_lib_bounded_array_traits != 201902L -# error "__cpp_lib_bounded_array_traits should have the value 201902L in c++26" -# endif - -# ifndef __cpp_lib_boyer_moore_searcher -# error "__cpp_lib_boyer_moore_searcher should be defined in c++26" -# endif -# if __cpp_lib_boyer_moore_searcher != 201603L -# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_byte -# error "__cpp_lib_byte should be defined in c++26" -# endif -# if __cpp_lib_byte != 201603L -# error "__cpp_lib_byte should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_byteswap -# error "__cpp_lib_byteswap should be defined in c++26" -# endif -# if __cpp_lib_byteswap != 202110L -# error "__cpp_lib_byteswap should have the value 202110L in c++26" -# endif - -# if defined(__cpp_char8_t) -# ifndef __cpp_lib_char8_t -# error "__cpp_lib_char8_t should be defined in c++26" -# endif -# if __cpp_lib_char8_t != 201907L -# error "__cpp_lib_char8_t should have the value 201907L in c++26" -# endif -# else -# ifdef __cpp_lib_char8_t -# error "__cpp_lib_char8_t should not be defined when the requirement 'defined(__cpp_char8_t)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_chrono -# error "__cpp_lib_chrono should be defined in c++26" -# endif -# if __cpp_lib_chrono != 201611L -# error "__cpp_lib_chrono should have the value 201611L in c++26" -# endif - -# ifndef __cpp_lib_chrono_udls -# error "__cpp_lib_chrono_udls should be defined in c++26" -# endif -# if __cpp_lib_chrono_udls != 201304L -# error "__cpp_lib_chrono_udls should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_clamp -# error "__cpp_lib_clamp should be defined in c++26" -# endif -# if __cpp_lib_clamp != 201603L -# error "__cpp_lib_clamp should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_common_reference -# error "__cpp_lib_common_reference should be defined in c++26" -# endif -# if __cpp_lib_common_reference != 202302L -# error "__cpp_lib_common_reference should have the value 202302L in c++26" -# endif - -# ifndef __cpp_lib_common_reference_wrapper -# error "__cpp_lib_common_reference_wrapper should be defined in c++26" -# endif -# if __cpp_lib_common_reference_wrapper != 202302L -# error "__cpp_lib_common_reference_wrapper should have the value 202302L in c++26" -# endif - -# ifndef __cpp_lib_complex_udls -# error "__cpp_lib_complex_udls should be defined in c++26" -# endif -# if __cpp_lib_complex_udls != 201309L -# error "__cpp_lib_complex_udls should have the value 201309L in c++26" -# endif - -# ifndef __cpp_lib_concepts -# error "__cpp_lib_concepts should be defined in c++26" -# endif -# if __cpp_lib_concepts != 202002L -# error "__cpp_lib_concepts should have the value 202002L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_algorithms -# error "__cpp_lib_constexpr_algorithms should be defined in c++26" -# endif -# if __cpp_lib_constexpr_algorithms != 202306L -# error "__cpp_lib_constexpr_algorithms should have the value 202306L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_bitset -# error "__cpp_lib_constexpr_bitset should be defined in c++26" -# endif -# if __cpp_lib_constexpr_bitset != 202207L -# error "__cpp_lib_constexpr_bitset should have the value 202207L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_charconv -# error "__cpp_lib_constexpr_charconv should be defined in c++26" -# endif -# if __cpp_lib_constexpr_charconv != 202207L -# error "__cpp_lib_constexpr_charconv should have the value 202207L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_constexpr_cmath -# error "__cpp_lib_constexpr_cmath should be defined in c++26" -# endif -# if __cpp_lib_constexpr_cmath != 202202L -# error "__cpp_lib_constexpr_cmath should have the value 202202L in c++26" -# endif -# else -# ifdef __cpp_lib_constexpr_cmath -# error "__cpp_lib_constexpr_cmath should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_constexpr_complex -# error "__cpp_lib_constexpr_complex should be defined in c++26" -# endif -# if __cpp_lib_constexpr_complex != 201711L -# error "__cpp_lib_constexpr_complex should have the value 201711L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_dynamic_alloc -# error "__cpp_lib_constexpr_dynamic_alloc should be defined in c++26" -# endif -# if __cpp_lib_constexpr_dynamic_alloc != 201907L -# error "__cpp_lib_constexpr_dynamic_alloc should have the value 201907L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_forward_list -# error "__cpp_lib_constexpr_forward_list should be defined in c++26" -# endif -# if __cpp_lib_constexpr_forward_list != 202502L -# error "__cpp_lib_constexpr_forward_list should have the value 202502L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_functional -# error "__cpp_lib_constexpr_functional should be defined in c++26" -# endif -# if __cpp_lib_constexpr_functional != 201907L -# error "__cpp_lib_constexpr_functional should have the value 201907L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_iterator -# error "__cpp_lib_constexpr_iterator should be defined in c++26" -# endif -# if __cpp_lib_constexpr_iterator != 201811L -# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_list -# error "__cpp_lib_constexpr_list should be defined in c++26" -# endif -# if __cpp_lib_constexpr_list != 202502L -# error "__cpp_lib_constexpr_list should have the value 202502L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_memory -# error "__cpp_lib_constexpr_memory should be defined in c++26" -# endif -# if __cpp_lib_constexpr_memory != 202202L -# error "__cpp_lib_constexpr_memory should have the value 202202L in c++26" -# endif - -# if !defined(_LIBCPP_ABI_VCRUNTIME) -# ifndef __cpp_lib_constexpr_new -# error "__cpp_lib_constexpr_new should be defined in c++26" -# endif -# if __cpp_lib_constexpr_new != 202406L -# error "__cpp_lib_constexpr_new should have the value 202406L in c++26" -# endif -# else -# ifdef __cpp_lib_constexpr_new -# error "__cpp_lib_constexpr_new should not be defined when the requirement '!defined(_LIBCPP_ABI_VCRUNTIME)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_constexpr_numeric -# error "__cpp_lib_constexpr_numeric should be defined in c++26" -# endif -# if __cpp_lib_constexpr_numeric != 201911L -# error "__cpp_lib_constexpr_numeric should have the value 201911L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_queue -# error "__cpp_lib_constexpr_queue should be defined in c++26" -# endif -# if __cpp_lib_constexpr_queue != 202502L -# error "__cpp_lib_constexpr_queue should have the value 202502L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_string -# error "__cpp_lib_constexpr_string should be defined in c++26" -# endif -# if __cpp_lib_constexpr_string != 201907L -# error "__cpp_lib_constexpr_string should have the value 201907L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_string_view -# error "__cpp_lib_constexpr_string_view should be defined in c++26" -# endif -# if __cpp_lib_constexpr_string_view != 201811L -# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_tuple -# error "__cpp_lib_constexpr_tuple should be defined in c++26" -# endif -# if __cpp_lib_constexpr_tuple != 201811L -# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_typeinfo -# error "__cpp_lib_constexpr_typeinfo should be defined in c++26" -# endif -# if __cpp_lib_constexpr_typeinfo != 202106L -# error "__cpp_lib_constexpr_typeinfo should have the value 202106L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_utility -# error "__cpp_lib_constexpr_utility should be defined in c++26" -# endif -# if __cpp_lib_constexpr_utility != 201811L -# error "__cpp_lib_constexpr_utility should have the value 201811L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_vector -# error "__cpp_lib_constexpr_vector should be defined in c++26" -# endif -# if __cpp_lib_constexpr_vector != 201907L -# error "__cpp_lib_constexpr_vector should have the value 201907L in c++26" -# endif - -# ifndef __cpp_lib_constrained_equality -# error "__cpp_lib_constrained_equality should be defined in c++26" -# endif -# if __cpp_lib_constrained_equality != 202411L -# error "__cpp_lib_constrained_equality should have the value 202411L in c++26" -# endif - -# ifndef __cpp_lib_containers_ranges -# error "__cpp_lib_containers_ranges should be defined in c++26" -# endif -# if __cpp_lib_containers_ranges != 202202L -# error "__cpp_lib_containers_ranges should have the value 202202L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_copyable_function -# error "__cpp_lib_copyable_function should be defined in c++26" -# endif -# if __cpp_lib_copyable_function != 202306L -# error "__cpp_lib_copyable_function should have the value 202306L in c++26" -# endif -# else -# ifdef __cpp_lib_copyable_function -# error "__cpp_lib_copyable_function should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_coroutine -# error "__cpp_lib_coroutine should be defined in c++26" -# endif -# if __cpp_lib_coroutine != 201902L -# error "__cpp_lib_coroutine should have the value 201902L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_debugging -# error "__cpp_lib_debugging should be defined in c++26" -# endif -# if __cpp_lib_debugging != 202311L -# error "__cpp_lib_debugging should have the value 202311L in c++26" -# endif -# else -# ifdef __cpp_lib_debugging -# error "__cpp_lib_debugging should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_default_template_type_for_algorithm_values -# error "__cpp_lib_default_template_type_for_algorithm_values should be defined in c++26" -# endif -# if __cpp_lib_default_template_type_for_algorithm_values != 202403L -# error "__cpp_lib_default_template_type_for_algorithm_values should have the value 202403L in c++26" -# endif -# else -# ifdef __cpp_lib_default_template_type_for_algorithm_values -# error "__cpp_lib_default_template_type_for_algorithm_values should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L -# ifndef __cpp_lib_destroying_delete -# error "__cpp_lib_destroying_delete should be defined in c++26" -# endif -# if __cpp_lib_destroying_delete != 201806L -# error "__cpp_lib_destroying_delete should have the value 201806L in c++26" -# endif -# else -# ifdef __cpp_lib_destroying_delete -# error "__cpp_lib_destroying_delete should not be defined when the requirement 'TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L' is not met!" -# endif -# endif - -# ifndef __cpp_lib_enable_shared_from_this -# error "__cpp_lib_enable_shared_from_this should be defined in c++26" -# endif -# if __cpp_lib_enable_shared_from_this != 201603L -# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_endian -# error "__cpp_lib_endian should be defined in c++26" -# endif -# if __cpp_lib_endian != 201907L -# error "__cpp_lib_endian should have the value 201907L in c++26" -# endif - -# ifndef __cpp_lib_erase_if -# error "__cpp_lib_erase_if should be defined in c++26" -# endif -# if __cpp_lib_erase_if != 202002L -# error "__cpp_lib_erase_if should have the value 202002L in c++26" -# endif - -# ifndef __cpp_lib_exchange_function -# error "__cpp_lib_exchange_function should be defined in c++26" -# endif -# if __cpp_lib_exchange_function != 201304L -# error "__cpp_lib_exchange_function should have the value 201304L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_execution -# error "__cpp_lib_execution should be defined in c++26" -# endif -# if __cpp_lib_execution != 201902L -# error "__cpp_lib_execution should have the value 201902L in c++26" -# endif -# else -# ifdef __cpp_lib_execution -# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_expected -# error "__cpp_lib_expected should be defined in c++26" -# endif -# if __cpp_lib_expected != 202211L -# error "__cpp_lib_expected should have the value 202211L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY) -# ifndef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should be defined in c++26" -# endif -# if __cpp_lib_filesystem != 201703L -# error "__cpp_lib_filesystem should have the value 201703L in c++26" -# endif -# else -# ifdef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_flat_map -# error "__cpp_lib_flat_map should be defined in c++26" -# endif -# if __cpp_lib_flat_map != 202207L -# error "__cpp_lib_flat_map should have the value 202207L in c++26" -# endif - -# ifndef __cpp_lib_flat_set -# error "__cpp_lib_flat_set should be defined in c++26" -# endif -# if __cpp_lib_flat_set != 202207L -# error "__cpp_lib_flat_set should have the value 202207L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT -# ifndef __cpp_lib_format -# error "__cpp_lib_format should be defined in c++26" -# endif -# if __cpp_lib_format != 202110L -# error "__cpp_lib_format should have the value 202110L in c++26" -# endif -# else -# ifdef __cpp_lib_format -# error "__cpp_lib_format should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_format_path -# error "__cpp_lib_format_path should be defined in c++26" -# endif -# if __cpp_lib_format_path != 202403L -# error "__cpp_lib_format_path should have the value 202403L in c++26" -# endif -# else -# ifdef __cpp_lib_format_path -# error "__cpp_lib_format_path should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_format_ranges -# error "__cpp_lib_format_ranges should be defined in c++26" -# endif -# if __cpp_lib_format_ranges != 202207L -# error "__cpp_lib_format_ranges should have the value 202207L in c++26" -# endif - -# ifndef __cpp_lib_format_uchar -# error "__cpp_lib_format_uchar should be defined in c++26" -# endif -# if __cpp_lib_format_uchar != 202311L -# error "__cpp_lib_format_uchar should have the value 202311L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_formatters -# error "__cpp_lib_formatters should be defined in c++26" -# endif -# if __cpp_lib_formatters != 202302L -# error "__cpp_lib_formatters should have the value 202302L in c++26" -# endif -# else -# ifdef __cpp_lib_formatters -# error "__cpp_lib_formatters should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_forward_like -# error "__cpp_lib_forward_like should be defined in c++26" -# endif -# if __cpp_lib_forward_like != 202207L -# error "__cpp_lib_forward_like should have the value 202207L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_freestanding_algorithm -# error "__cpp_lib_freestanding_algorithm should be defined in c++26" -# endif -# if __cpp_lib_freestanding_algorithm != 202311L -# error "__cpp_lib_freestanding_algorithm should have the value 202311L in c++26" -# endif -# else -# ifdef __cpp_lib_freestanding_algorithm -# error "__cpp_lib_freestanding_algorithm should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_freestanding_array -# error "__cpp_lib_freestanding_array should be defined in c++26" -# endif -# if __cpp_lib_freestanding_array != 202311L -# error "__cpp_lib_freestanding_array should have the value 202311L in c++26" -# endif -# else -# ifdef __cpp_lib_freestanding_array -# error "__cpp_lib_freestanding_array should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_freestanding_cstring -# error "__cpp_lib_freestanding_cstring should be defined in c++26" -# endif -# if __cpp_lib_freestanding_cstring != 202306L -# error "__cpp_lib_freestanding_cstring should have the value 202306L in c++26" -# endif -# else -# ifdef __cpp_lib_freestanding_cstring -# error "__cpp_lib_freestanding_cstring should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_freestanding_expected -# error "__cpp_lib_freestanding_expected should be defined in c++26" -# endif -# if __cpp_lib_freestanding_expected != 202311L -# error "__cpp_lib_freestanding_expected should have the value 202311L in c++26" -# endif -# else -# ifdef __cpp_lib_freestanding_expected -# error "__cpp_lib_freestanding_expected should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_freestanding_mdspan -# error "__cpp_lib_freestanding_mdspan should be defined in c++26" -# endif -# if __cpp_lib_freestanding_mdspan != 202311L -# error "__cpp_lib_freestanding_mdspan should have the value 202311L in c++26" -# endif -# else -# ifdef __cpp_lib_freestanding_mdspan -# error "__cpp_lib_freestanding_mdspan should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_freestanding_optional -# error "__cpp_lib_freestanding_optional should be defined in c++26" -# endif -# if __cpp_lib_freestanding_optional != 202311L -# error "__cpp_lib_freestanding_optional should have the value 202311L in c++26" -# endif -# else -# ifdef __cpp_lib_freestanding_optional -# error "__cpp_lib_freestanding_optional should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_freestanding_string_view -# error "__cpp_lib_freestanding_string_view should be defined in c++26" -# endif -# if __cpp_lib_freestanding_string_view != 202311L -# error "__cpp_lib_freestanding_string_view should have the value 202311L in c++26" -# endif -# else -# ifdef __cpp_lib_freestanding_string_view -# error "__cpp_lib_freestanding_string_view should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_freestanding_variant -# error "__cpp_lib_freestanding_variant should be defined in c++26" -# endif -# if __cpp_lib_freestanding_variant != 202311L -# error "__cpp_lib_freestanding_variant should have the value 202311L in c++26" -# endif -# else -# ifdef __cpp_lib_freestanding_variant -# error "__cpp_lib_freestanding_variant should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION) -# ifndef __cpp_lib_fstream_native_handle -# error "__cpp_lib_fstream_native_handle should be defined in c++26" -# endif -# if __cpp_lib_fstream_native_handle != 202306L -# error "__cpp_lib_fstream_native_handle should have the value 202306L in c++26" -# endif -# else -# ifdef __cpp_lib_fstream_native_handle -# error "__cpp_lib_fstream_native_handle should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION)' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_function_ref -# error "__cpp_lib_function_ref should be defined in c++26" -# endif -# if __cpp_lib_function_ref != 202306L -# error "__cpp_lib_function_ref should have the value 202306L in c++26" -# endif -# else -# ifdef __cpp_lib_function_ref -# error "__cpp_lib_function_ref should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_gcd_lcm -# error "__cpp_lib_gcd_lcm should be defined in c++26" -# endif -# if __cpp_lib_gcd_lcm != 201606L -# error "__cpp_lib_gcd_lcm should have the value 201606L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_generate_random -# error "__cpp_lib_generate_random should be defined in c++26" -# endif -# if __cpp_lib_generate_random != 202403L -# error "__cpp_lib_generate_random should have the value 202403L in c++26" -# endif -# else -# ifdef __cpp_lib_generate_random -# error "__cpp_lib_generate_random should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_generic_associative_lookup -# error "__cpp_lib_generic_associative_lookup should be defined in c++26" -# endif -# if __cpp_lib_generic_associative_lookup != 201304L -# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_generic_unordered_lookup -# error "__cpp_lib_generic_unordered_lookup should be defined in c++26" -# endif -# if __cpp_lib_generic_unordered_lookup != 201811L -# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)) -# ifndef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should be defined in c++26" -# endif -# if __cpp_lib_hardware_interference_size != 201703L -# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++26" -# endif -# else -# ifdef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))' is not met!" -# endif -# endif - -# ifndef __cpp_lib_has_unique_object_representations -# error "__cpp_lib_has_unique_object_representations should be defined in c++26" -# endif -# if __cpp_lib_has_unique_object_representations != 201606L -# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_hazard_pointer -# error "__cpp_lib_hazard_pointer should be defined in c++26" -# endif -# if __cpp_lib_hazard_pointer != 202306L -# error "__cpp_lib_hazard_pointer should have the value 202306L in c++26" -# endif -# else -# ifdef __cpp_lib_hazard_pointer -# error "__cpp_lib_hazard_pointer should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_hypot -# error "__cpp_lib_hypot should be defined in c++26" -# endif -# if __cpp_lib_hypot != 201603L -# error "__cpp_lib_hypot should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_incomplete_container_elements -# error "__cpp_lib_incomplete_container_elements should be defined in c++26" -# endif -# if __cpp_lib_incomplete_container_elements != 201505L -# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_inplace_vector -# error "__cpp_lib_inplace_vector should be defined in c++26" -# endif -# if __cpp_lib_inplace_vector != 202406L -# error "__cpp_lib_inplace_vector should have the value 202406L in c++26" -# endif -# else -# ifdef __cpp_lib_inplace_vector -# error "__cpp_lib_inplace_vector should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_int_pow2 -# error "__cpp_lib_int_pow2 should be defined in c++26" -# endif -# if __cpp_lib_int_pow2 != 202002L -# error "__cpp_lib_int_pow2 should have the value 202002L in c++26" -# endif - -# ifndef __cpp_lib_integer_comparison_functions -# error "__cpp_lib_integer_comparison_functions should be defined in c++26" -# endif -# if __cpp_lib_integer_comparison_functions != 202002L -# error "__cpp_lib_integer_comparison_functions should have the value 202002L in c++26" -# endif - -# ifndef __cpp_lib_integer_sequence -# error "__cpp_lib_integer_sequence should be defined in c++26" -# endif -# if __cpp_lib_integer_sequence != 201304L -# error "__cpp_lib_integer_sequence should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_integral_constant_callable -# error "__cpp_lib_integral_constant_callable should be defined in c++26" -# endif -# if __cpp_lib_integral_constant_callable != 201304L -# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_interpolate -# error "__cpp_lib_interpolate should be defined in c++26" -# endif -# if __cpp_lib_interpolate != 201902L -# error "__cpp_lib_interpolate should have the value 201902L in c++26" -# endif - -# ifndef __cpp_lib_invoke -# error "__cpp_lib_invoke should be defined in c++26" -# endif -# if __cpp_lib_invoke != 201411L -# error "__cpp_lib_invoke should have the value 201411L in c++26" -# endif - -# ifndef __cpp_lib_invoke_r -# error "__cpp_lib_invoke_r should be defined in c++26" -# endif -# if __cpp_lib_invoke_r != 202106L -# error "__cpp_lib_invoke_r should have the value 202106L in c++26" -# endif - -# ifndef __cpp_lib_ios_noreplace -# error "__cpp_lib_ios_noreplace should be defined in c++26" -# endif -# if __cpp_lib_ios_noreplace != 202207L -# error "__cpp_lib_ios_noreplace should have the value 202207L in c++26" -# endif - -# ifndef __cpp_lib_is_aggregate -# error "__cpp_lib_is_aggregate should be defined in c++26" -# endif -# if __cpp_lib_is_aggregate != 201703L -# error "__cpp_lib_is_aggregate should have the value 201703L in c++26" -# endif - -# ifndef __cpp_lib_is_constant_evaluated -# error "__cpp_lib_is_constant_evaluated should be defined in c++26" -# endif -# if __cpp_lib_is_constant_evaluated != 201811L -# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++26" -# endif - -# ifndef __cpp_lib_is_final -# error "__cpp_lib_is_final should be defined in c++26" -# endif -# if __cpp_lib_is_final != 201402L -# error "__cpp_lib_is_final should have the value 201402L in c++26" -# endif - -# if __has_builtin(__builtin_is_implicit_lifetime) -# ifndef __cpp_lib_is_implicit_lifetime -# error "__cpp_lib_is_implicit_lifetime should be defined in c++26" -# endif -# if __cpp_lib_is_implicit_lifetime != 202302L -# error "__cpp_lib_is_implicit_lifetime should have the value 202302L in c++26" -# endif -# else -# ifdef __cpp_lib_is_implicit_lifetime -# error "__cpp_lib_is_implicit_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_implicit_lifetime)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_is_invocable -# error "__cpp_lib_is_invocable should be defined in c++26" -# endif -# if __cpp_lib_is_invocable != 201703L -# error "__cpp_lib_is_invocable should have the value 201703L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_is_layout_compatible -# error "__cpp_lib_is_layout_compatible should be defined in c++26" -# endif -# if __cpp_lib_is_layout_compatible != 201907L -# error "__cpp_lib_is_layout_compatible should have the value 201907L in c++26" -# endif -# else -# ifdef __cpp_lib_is_layout_compatible -# error "__cpp_lib_is_layout_compatible should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_is_nothrow_convertible -# error "__cpp_lib_is_nothrow_convertible should be defined in c++26" -# endif -# if __cpp_lib_is_nothrow_convertible != 201806L -# error "__cpp_lib_is_nothrow_convertible should have the value 201806L in c++26" -# endif - -# ifndef __cpp_lib_is_null_pointer -# error "__cpp_lib_is_null_pointer should be defined in c++26" -# endif -# if __cpp_lib_is_null_pointer != 201309L -# error "__cpp_lib_is_null_pointer should have the value 201309L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_is_pointer_interconvertible -# error "__cpp_lib_is_pointer_interconvertible should be defined in c++26" -# endif -# if __cpp_lib_is_pointer_interconvertible != 201907L -# error "__cpp_lib_is_pointer_interconvertible should have the value 201907L in c++26" -# endif -# else -# ifdef __cpp_lib_is_pointer_interconvertible -# error "__cpp_lib_is_pointer_interconvertible should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_is_scoped_enum -# error "__cpp_lib_is_scoped_enum should be defined in c++26" -# endif -# if __cpp_lib_is_scoped_enum != 202011L -# error "__cpp_lib_is_scoped_enum should have the value 202011L in c++26" -# endif - -# ifndef __cpp_lib_is_sufficiently_aligned -# error "__cpp_lib_is_sufficiently_aligned should be defined in c++26" -# endif -# if __cpp_lib_is_sufficiently_aligned != 202411L -# error "__cpp_lib_is_sufficiently_aligned should have the value 202411L in c++26" -# endif - -# ifndef __cpp_lib_is_swappable -# error "__cpp_lib_is_swappable should be defined in c++26" -# endif -# if __cpp_lib_is_swappable != 201603L -# error "__cpp_lib_is_swappable should have the value 201603L in c++26" -# endif - -# if __has_builtin(__builtin_is_virtual_base_of) -# ifndef __cpp_lib_is_virtual_base_of -# error "__cpp_lib_is_virtual_base_of should be defined in c++26" -# endif -# if __cpp_lib_is_virtual_base_of != 202406L -# error "__cpp_lib_is_virtual_base_of should have the value 202406L in c++26" -# endif -# else -# ifdef __cpp_lib_is_virtual_base_of -# error "__cpp_lib_is_virtual_base_of should not be defined when the requirement '__has_builtin(__builtin_is_virtual_base_of)' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_is_within_lifetime -# error "__cpp_lib_is_within_lifetime should be defined in c++26" -# endif -# if __cpp_lib_is_within_lifetime != 202306L -# error "__cpp_lib_is_within_lifetime should have the value 202306L in c++26" -# endif -# else -# ifdef __cpp_lib_is_within_lifetime -# error "__cpp_lib_is_within_lifetime should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_jthread -# error "__cpp_lib_jthread should be defined in c++26" -# endif -# if __cpp_lib_jthread != 201911L -# error "__cpp_lib_jthread should have the value 201911L in c++26" -# endif -# else -# ifdef __cpp_lib_jthread -# error "__cpp_lib_jthread should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_latch -# error "__cpp_lib_latch should be defined in c++26" -# endif -# if __cpp_lib_latch != 201907L -# error "__cpp_lib_latch should have the value 201907L in c++26" -# endif -# else -# ifdef __cpp_lib_latch -# error "__cpp_lib_latch should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_launder -# error "__cpp_lib_launder should be defined in c++26" -# endif -# if __cpp_lib_launder != 201606L -# error "__cpp_lib_launder should have the value 201606L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_linalg -# error "__cpp_lib_linalg should be defined in c++26" -# endif -# if __cpp_lib_linalg != 202311L -# error "__cpp_lib_linalg should have the value 202311L in c++26" -# endif -# else -# ifdef __cpp_lib_linalg -# error "__cpp_lib_linalg should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_list_remove_return_type -# error "__cpp_lib_list_remove_return_type should be defined in c++26" -# endif -# if __cpp_lib_list_remove_return_type != 201806L -# error "__cpp_lib_list_remove_return_type should have the value 201806L in c++26" -# endif - -# ifndef __cpp_lib_logical_traits -# error "__cpp_lib_logical_traits should be defined in c++26" -# endif -# if __cpp_lib_logical_traits != 201510L -# error "__cpp_lib_logical_traits should have the value 201510L in c++26" -# endif - -# ifndef __cpp_lib_make_from_tuple -# error "__cpp_lib_make_from_tuple should be defined in c++26" -# endif -# if __cpp_lib_make_from_tuple != 201606L -# error "__cpp_lib_make_from_tuple should have the value 201606L in c++26" -# endif - -# ifndef __cpp_lib_make_reverse_iterator -# error "__cpp_lib_make_reverse_iterator should be defined in c++26" -# endif -# if __cpp_lib_make_reverse_iterator != 201402L -# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++26" -# endif - -# ifndef __cpp_lib_make_unique -# error "__cpp_lib_make_unique should be defined in c++26" -# endif -# if __cpp_lib_make_unique != 201304L -# error "__cpp_lib_make_unique should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_map_try_emplace -# error "__cpp_lib_map_try_emplace should be defined in c++26" -# endif -# if __cpp_lib_map_try_emplace != 201411L -# error "__cpp_lib_map_try_emplace should have the value 201411L in c++26" -# endif - -# ifndef __cpp_lib_math_constants -# error "__cpp_lib_math_constants should be defined in c++26" -# endif -# if __cpp_lib_math_constants != 201907L -# error "__cpp_lib_math_constants should have the value 201907L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should be defined in c++26" -# endif -# if __cpp_lib_math_special_functions != 201603L -# error "__cpp_lib_math_special_functions should have the value 201603L in c++26" -# endif -# else -# ifdef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_mdspan -# error "__cpp_lib_mdspan should be defined in c++26" -# endif -# if __cpp_lib_mdspan != 202406L -# error "__cpp_lib_mdspan should have the value 202406L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR -# ifndef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should be defined in c++26" -# endif -# if __cpp_lib_memory_resource != 201603L -# error "__cpp_lib_memory_resource should have the value 201603L in c++26" -# endif -# else -# ifdef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" -# endif -# endif - -# ifndef __cpp_lib_modules -# error "__cpp_lib_modules should be defined in c++26" -# endif -# if __cpp_lib_modules != 202207L -# error "__cpp_lib_modules should have the value 202207L in c++26" -# endif - -# ifndef __cpp_lib_move_iterator_concept -# error "__cpp_lib_move_iterator_concept should be defined in c++26" -# endif -# if __cpp_lib_move_iterator_concept != 202207L -# error "__cpp_lib_move_iterator_concept should have the value 202207L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_move_only_function -# error "__cpp_lib_move_only_function should be defined in c++26" -# endif -# if __cpp_lib_move_only_function != 202110L -# error "__cpp_lib_move_only_function should have the value 202110L in c++26" -# endif -# else -# ifdef __cpp_lib_move_only_function -# error "__cpp_lib_move_only_function should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_node_extract -# error "__cpp_lib_node_extract should be defined in c++26" -# endif -# if __cpp_lib_node_extract != 201606L -# error "__cpp_lib_node_extract should have the value 201606L in c++26" -# endif - -# ifndef __cpp_lib_nonmember_container_access -# error "__cpp_lib_nonmember_container_access should be defined in c++26" -# endif -# if __cpp_lib_nonmember_container_access != 201411L -# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++26" -# endif - -# ifndef __cpp_lib_not_fn -# error "__cpp_lib_not_fn should be defined in c++26" -# endif -# if __cpp_lib_not_fn != 202306L -# error "__cpp_lib_not_fn should have the value 202306L in c++26" -# endif - -# ifndef __cpp_lib_null_iterators -# error "__cpp_lib_null_iterators should be defined in c++26" -# endif -# if __cpp_lib_null_iterators != 201304L -# error "__cpp_lib_null_iterators should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_optional -# error "__cpp_lib_optional should be defined in c++26" -# endif -# if __cpp_lib_optional != 202110L -# error "__cpp_lib_optional should have the value 202110L in c++26" -# endif - -# ifndef __cpp_lib_optional_range_support -# error "__cpp_lib_optional_range_support should be defined in c++26" -# endif -# if __cpp_lib_optional_range_support != 202406L -# error "__cpp_lib_optional_range_support should have the value 202406L in c++26" -# endif - -# ifndef __cpp_lib_out_ptr -# error "__cpp_lib_out_ptr should be defined in c++26" -# endif -# if __cpp_lib_out_ptr != 202311L -# error "__cpp_lib_out_ptr should have the value 202311L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should be defined in c++26" -# endif -# if __cpp_lib_parallel_algorithm != 201603L -# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++26" -# endif -# else -# ifdef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_philox_engine -# error "__cpp_lib_philox_engine should be defined in c++26" -# endif -# if __cpp_lib_philox_engine != 202406L -# error "__cpp_lib_philox_engine should have the value 202406L in c++26" -# endif -# else -# ifdef __cpp_lib_philox_engine -# error "__cpp_lib_philox_engine should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR -# ifndef __cpp_lib_polymorphic_allocator -# error "__cpp_lib_polymorphic_allocator should be defined in c++26" -# endif -# if __cpp_lib_polymorphic_allocator != 201902L -# error "__cpp_lib_polymorphic_allocator should have the value 201902L in c++26" -# endif -# else -# ifdef __cpp_lib_polymorphic_allocator -# error "__cpp_lib_polymorphic_allocator should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT -# ifndef __cpp_lib_print -# error "__cpp_lib_print should be defined in c++26" -# endif -# if __cpp_lib_print != 202207L -# error "__cpp_lib_print should have the value 202207L in c++26" -# endif -# else -# ifdef __cpp_lib_print -# error "__cpp_lib_print should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION -# ifndef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should be defined in c++26" -# endif -# if __cpp_lib_quoted_string_io != 201304L -# error "__cpp_lib_quoted_string_io should have the value 201304L in c++26" -# endif -# else -# ifdef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" -# endif -# endif - -# ifndef __cpp_lib_ranges -# error "__cpp_lib_ranges should be defined in c++26" -# endif -# if __cpp_lib_ranges != 202406L -# error "__cpp_lib_ranges should have the value 202406L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_as_const -# error "__cpp_lib_ranges_as_const should be defined in c++26" -# endif -# if __cpp_lib_ranges_as_const != 202207L -# error "__cpp_lib_ranges_as_const should have the value 202207L in c++26" -# endif -# else -# ifdef __cpp_lib_ranges_as_const -# error "__cpp_lib_ranges_as_const should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ranges_as_rvalue -# error "__cpp_lib_ranges_as_rvalue should be defined in c++26" -# endif -# if __cpp_lib_ranges_as_rvalue != 202207L -# error "__cpp_lib_ranges_as_rvalue should have the value 202207L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should be defined in c++26" -# endif -# if __cpp_lib_ranges_chunk != 202202L -# error "__cpp_lib_ranges_chunk should have the value 202202L in c++26" -# endif -# else -# ifdef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ranges_chunk_by -# error "__cpp_lib_ranges_chunk_by should be defined in c++26" -# endif -# if __cpp_lib_ranges_chunk_by != 202202L -# error "__cpp_lib_ranges_chunk_by should have the value 202202L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_concat -# error "__cpp_lib_ranges_concat should be defined in c++26" -# endif -# if __cpp_lib_ranges_concat != 202403L -# error "__cpp_lib_ranges_concat should have the value 202403L in c++26" -# endif -# else -# ifdef __cpp_lib_ranges_concat -# error "__cpp_lib_ranges_concat should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ranges_contains -# error "__cpp_lib_ranges_contains should be defined in c++26" -# endif -# if __cpp_lib_ranges_contains != 202207L -# error "__cpp_lib_ranges_contains should have the value 202207L in c++26" -# endif - -# ifndef __cpp_lib_ranges_find_last -# error "__cpp_lib_ranges_find_last should be defined in c++26" -# endif -# if __cpp_lib_ranges_find_last != 202207L -# error "__cpp_lib_ranges_find_last should have the value 202207L in c++26" -# endif - -# ifndef __cpp_lib_ranges_indices -# error "__cpp_lib_ranges_indices should be defined in c++26" -# endif -# if __cpp_lib_ranges_indices != 202506L -# error "__cpp_lib_ranges_indices should have the value 202506L in c++26" -# endif - -# ifndef __cpp_lib_ranges_iota -# error "__cpp_lib_ranges_iota should be defined in c++26" -# endif -# if __cpp_lib_ranges_iota != 202202L -# error "__cpp_lib_ranges_iota should have the value 202202L in c++26" -# endif - -# ifndef __cpp_lib_ranges_join_with -# error "__cpp_lib_ranges_join_with should be defined in c++26" -# endif -# if __cpp_lib_ranges_join_with != 202202L -# error "__cpp_lib_ranges_join_with should have the value 202202L in c++26" -# endif - -# ifndef __cpp_lib_ranges_repeat -# error "__cpp_lib_ranges_repeat should be defined in c++26" -# endif -# if __cpp_lib_ranges_repeat != 202207L -# error "__cpp_lib_ranges_repeat should have the value 202207L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_slide -# error "__cpp_lib_ranges_slide should be defined in c++26" -# endif -# if __cpp_lib_ranges_slide != 202202L -# error "__cpp_lib_ranges_slide should have the value 202202L in c++26" -# endif -# else -# ifdef __cpp_lib_ranges_slide -# error "__cpp_lib_ranges_slide should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ranges_starts_ends_with -# error "__cpp_lib_ranges_starts_ends_with should be defined in c++26" -# endif -# if __cpp_lib_ranges_starts_ends_with != 202106L -# error "__cpp_lib_ranges_starts_ends_with should have the value 202106L in c++26" -# endif - -# ifndef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should be defined in c++26" -# endif -# if __cpp_lib_ranges_to_container != 202202L -# error "__cpp_lib_ranges_to_container should have the value 202202L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_zip -# error "__cpp_lib_ranges_zip should be defined in c++26" -# endif -# if __cpp_lib_ranges_zip != 202110L -# error "__cpp_lib_ranges_zip should have the value 202110L in c++26" -# endif -# else -# ifdef __cpp_lib_ranges_zip -# error "__cpp_lib_ranges_zip should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ratio -# error "__cpp_lib_ratio should be defined in c++26" -# endif -# if __cpp_lib_ratio != 202306L -# error "__cpp_lib_ratio should have the value 202306L in c++26" -# endif - -# ifndef __cpp_lib_raw_memory_algorithms -# error "__cpp_lib_raw_memory_algorithms should be defined in c++26" -# endif -# if __cpp_lib_raw_memory_algorithms != 201606L -# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_rcu -# error "__cpp_lib_rcu should be defined in c++26" -# endif -# if __cpp_lib_rcu != 202306L -# error "__cpp_lib_rcu should have the value 202306L in c++26" -# endif -# else -# ifdef __cpp_lib_rcu -# error "__cpp_lib_rcu should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_reference_from_temporary -# error "__cpp_lib_reference_from_temporary should be defined in c++26" -# endif -# if __cpp_lib_reference_from_temporary != 202202L -# error "__cpp_lib_reference_from_temporary should have the value 202202L in c++26" -# endif -# else -# ifdef __cpp_lib_reference_from_temporary -# error "__cpp_lib_reference_from_temporary should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_reference_wrapper -# error "__cpp_lib_reference_wrapper should be defined in c++26" -# endif -# if __cpp_lib_reference_wrapper != 202403L -# error "__cpp_lib_reference_wrapper should have the value 202403L in c++26" -# endif - -# ifndef __cpp_lib_remove_cvref -# error "__cpp_lib_remove_cvref should be defined in c++26" -# endif -# if __cpp_lib_remove_cvref != 201711L -# error "__cpp_lib_remove_cvref should have the value 201711L in c++26" -# endif - -# ifndef __cpp_lib_result_of_sfinae -# error "__cpp_lib_result_of_sfinae should be defined in c++26" -# endif -# if __cpp_lib_result_of_sfinae != 201210L -# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++26" -# endif - -# ifndef __cpp_lib_robust_nonmodifying_seq_ops -# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++26" -# endif -# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L -# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_sample -# error "__cpp_lib_sample should be defined in c++26" -# endif -# if __cpp_lib_sample != 201603L -# error "__cpp_lib_sample should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_saturation_arithmetic -# error "__cpp_lib_saturation_arithmetic should be defined in c++26" -# endif -# if __cpp_lib_saturation_arithmetic != 202311L -# error "__cpp_lib_saturation_arithmetic should have the value 202311L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should be defined in c++26" -# endif -# if __cpp_lib_scoped_lock != 201703L -# error "__cpp_lib_scoped_lock should have the value 201703L in c++26" -# endif -# else -# ifdef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_semaphore -# error "__cpp_lib_semaphore should be defined in c++26" -# endif -# if __cpp_lib_semaphore != 201907L -# error "__cpp_lib_semaphore should have the value 201907L in c++26" -# endif -# else -# ifdef __cpp_lib_semaphore -# error "__cpp_lib_semaphore should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_senders -# error "__cpp_lib_senders should be defined in c++26" -# endif -# if __cpp_lib_senders != 202406L -# error "__cpp_lib_senders should have the value 202406L in c++26" -# endif -# else -# ifdef __cpp_lib_senders -# error "__cpp_lib_senders should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should be defined in c++26" -# endif -# if __cpp_lib_shared_mutex != 201505L -# error "__cpp_lib_shared_mutex should have the value 201505L in c++26" -# endif -# else -# ifdef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifndef __cpp_lib_shared_ptr_arrays -# error "__cpp_lib_shared_ptr_arrays should be defined in c++26" -# endif -# if __cpp_lib_shared_ptr_arrays != 201707L -# error "__cpp_lib_shared_ptr_arrays should have the value 201707L in c++26" -# endif - -# ifndef __cpp_lib_shared_ptr_weak_type -# error "__cpp_lib_shared_ptr_weak_type should be defined in c++26" -# endif -# if __cpp_lib_shared_ptr_weak_type != 201606L -# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should be defined in c++26" -# endif -# if __cpp_lib_shared_timed_mutex != 201402L -# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++26" -# endif -# else -# ifdef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifndef __cpp_lib_shift -# error "__cpp_lib_shift should be defined in c++26" -# endif -# if __cpp_lib_shift != 201806L -# error "__cpp_lib_shift should have the value 201806L in c++26" -# endif - -# ifndef __cpp_lib_smart_ptr_for_overwrite -# error "__cpp_lib_smart_ptr_for_overwrite should be defined in c++26" -# endif -# if __cpp_lib_smart_ptr_for_overwrite != 202002L -# error "__cpp_lib_smart_ptr_for_overwrite should have the value 202002L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_smart_ptr_owner_equality -# error "__cpp_lib_smart_ptr_owner_equality should be defined in c++26" -# endif -# if __cpp_lib_smart_ptr_owner_equality != 202306L -# error "__cpp_lib_smart_ptr_owner_equality should have the value 202306L in c++26" -# endif -# else -# ifdef __cpp_lib_smart_ptr_owner_equality -# error "__cpp_lib_smart_ptr_owner_equality should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_source_location -# error "__cpp_lib_source_location should be defined in c++26" -# endif -# if __cpp_lib_source_location != 201907L -# error "__cpp_lib_source_location should have the value 201907L in c++26" -# endif - -# ifndef __cpp_lib_span -# error "__cpp_lib_span should be defined in c++26" -# endif -# if __cpp_lib_span != 202002L -# error "__cpp_lib_span should have the value 202002L in c++26" -# endif - -# ifndef __cpp_lib_span_at -# error "__cpp_lib_span_at should be defined in c++26" -# endif -# if __cpp_lib_span_at != 202311L -# error "__cpp_lib_span_at should have the value 202311L in c++26" -# endif - -# ifndef __cpp_lib_span_initializer_list -# error "__cpp_lib_span_initializer_list should be defined in c++26" -# endif -# if __cpp_lib_span_initializer_list != 202311L -# error "__cpp_lib_span_initializer_list should have the value 202311L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_spanstream -# error "__cpp_lib_spanstream should be defined in c++26" -# endif -# if __cpp_lib_spanstream != 202106L -# error "__cpp_lib_spanstream should have the value 202106L in c++26" -# endif -# else -# ifdef __cpp_lib_spanstream -# error "__cpp_lib_spanstream should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ssize -# error "__cpp_lib_ssize should be defined in c++26" -# endif -# if __cpp_lib_ssize != 201902L -# error "__cpp_lib_ssize should have the value 201902L in c++26" -# endif - -# ifndef __cpp_lib_sstream_from_string_view -# error "__cpp_lib_sstream_from_string_view should be defined in c++26" -# endif -# if __cpp_lib_sstream_from_string_view != 202306L -# error "__cpp_lib_sstream_from_string_view should have the value 202306L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_stacktrace -# error "__cpp_lib_stacktrace should be defined in c++26" -# endif -# if __cpp_lib_stacktrace != 202011L -# error "__cpp_lib_stacktrace should have the value 202011L in c++26" -# endif -# else -# ifdef __cpp_lib_stacktrace -# error "__cpp_lib_stacktrace should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_starts_ends_with -# error "__cpp_lib_starts_ends_with should be defined in c++26" -# endif -# if __cpp_lib_starts_ends_with != 201711L -# error "__cpp_lib_starts_ends_with should have the value 201711L in c++26" -# endif - -# ifndef __cpp_lib_stdatomic_h -# error "__cpp_lib_stdatomic_h should be defined in c++26" -# endif -# if __cpp_lib_stdatomic_h != 202011L -# error "__cpp_lib_stdatomic_h should have the value 202011L in c++26" -# endif - -# ifndef __cpp_lib_string_contains -# error "__cpp_lib_string_contains should be defined in c++26" -# endif -# if __cpp_lib_string_contains != 202011L -# error "__cpp_lib_string_contains should have the value 202011L in c++26" -# endif - -# ifndef __cpp_lib_string_resize_and_overwrite -# error "__cpp_lib_string_resize_and_overwrite should be defined in c++26" -# endif -# if __cpp_lib_string_resize_and_overwrite != 202110L -# error "__cpp_lib_string_resize_and_overwrite should have the value 202110L in c++26" -# endif - -# ifndef __cpp_lib_string_subview -# error "__cpp_lib_string_subview should be defined in c++26" -# endif -# if __cpp_lib_string_subview != 202506L -# error "__cpp_lib_string_subview should have the value 202506L in c++26" -# endif - -# ifndef __cpp_lib_string_udls -# error "__cpp_lib_string_udls should be defined in c++26" -# endif -# if __cpp_lib_string_udls != 201304L -# error "__cpp_lib_string_udls should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_string_view -# error "__cpp_lib_string_view should be defined in c++26" -# endif -# if __cpp_lib_string_view != 202403L -# error "__cpp_lib_string_view should have the value 202403L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_submdspan -# error "__cpp_lib_submdspan should be defined in c++26" -# endif -# if __cpp_lib_submdspan != 202306L -# error "__cpp_lib_submdspan should have the value 202306L in c++26" -# endif -# else -# ifdef __cpp_lib_submdspan -# error "__cpp_lib_submdspan should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM -# ifndef __cpp_lib_syncbuf -# error "__cpp_lib_syncbuf should be defined in c++26" -# endif -# if __cpp_lib_syncbuf != 201803L -# error "__cpp_lib_syncbuf should have the value 201803L in c++26" -# endif -# else -# ifdef __cpp_lib_syncbuf -# error "__cpp_lib_syncbuf should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_text_encoding -# error "__cpp_lib_text_encoding should be defined in c++26" -# endif -# if __cpp_lib_text_encoding != 202306L -# error "__cpp_lib_text_encoding should have the value 202306L in c++26" -# endif -# else -# ifdef __cpp_lib_text_encoding -# error "__cpp_lib_text_encoding should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_three_way_comparison -# error "__cpp_lib_three_way_comparison should be defined in c++26" -# endif -# if __cpp_lib_three_way_comparison != 201907L -# error "__cpp_lib_three_way_comparison should have the value 201907L in c++26" -# endif - -# ifndef __cpp_lib_to_address -# error "__cpp_lib_to_address should be defined in c++26" -# endif -# if __cpp_lib_to_address != 201711L -# error "__cpp_lib_to_address should have the value 201711L in c++26" -# endif - -# ifndef __cpp_lib_to_array -# error "__cpp_lib_to_array should be defined in c++26" -# endif -# if __cpp_lib_to_array != 201907L -# error "__cpp_lib_to_array should have the value 201907L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should be defined in c++26" -# endif -# if __cpp_lib_to_chars != 202306L -# error "__cpp_lib_to_chars should have the value 202306L in c++26" -# endif -# else -# ifdef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_to_string -# error "__cpp_lib_to_string should be defined in c++26" -# endif -# if __cpp_lib_to_string != 202306L -# error "__cpp_lib_to_string should have the value 202306L in c++26" -# endif -# else -# ifdef __cpp_lib_to_string -# error "__cpp_lib_to_string should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_to_underlying -# error "__cpp_lib_to_underlying should be defined in c++26" -# endif -# if __cpp_lib_to_underlying != 202102L -# error "__cpp_lib_to_underlying should have the value 202102L in c++26" -# endif - -# ifndef __cpp_lib_transformation_trait_aliases -# error "__cpp_lib_transformation_trait_aliases should be defined in c++26" -# endif -# if __cpp_lib_transformation_trait_aliases != 201304L -# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_transparent_operators -# error "__cpp_lib_transparent_operators should be defined in c++26" -# endif -# if __cpp_lib_transparent_operators != 201510L -# error "__cpp_lib_transparent_operators should have the value 201510L in c++26" -# endif - -# ifndef __cpp_lib_tuple_element_t -# error "__cpp_lib_tuple_element_t should be defined in c++26" -# endif -# if __cpp_lib_tuple_element_t != 201402L -# error "__cpp_lib_tuple_element_t should have the value 201402L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_tuple_like -# error "__cpp_lib_tuple_like should be defined in c++26" -# endif -# if __cpp_lib_tuple_like != 202311L -# error "__cpp_lib_tuple_like should have the value 202311L in c++26" -# endif -# else -# ifdef __cpp_lib_tuple_like -# error "__cpp_lib_tuple_like should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_tuples_by_type -# error "__cpp_lib_tuples_by_type should be defined in c++26" -# endif -# if __cpp_lib_tuples_by_type != 201304L -# error "__cpp_lib_tuples_by_type should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_type_identity -# error "__cpp_lib_type_identity should be defined in c++26" -# endif -# if __cpp_lib_type_identity != 201806L -# error "__cpp_lib_type_identity should have the value 201806L in c++26" -# endif - -# ifndef __cpp_lib_type_trait_variable_templates -# error "__cpp_lib_type_trait_variable_templates should be defined in c++26" -# endif -# if __cpp_lib_type_trait_variable_templates != 201510L -# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++26" -# endif - -# ifndef __cpp_lib_uncaught_exceptions -# error "__cpp_lib_uncaught_exceptions should be defined in c++26" -# endif -# if __cpp_lib_uncaught_exceptions != 201411L -# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++26" -# endif - -# ifndef __cpp_lib_unordered_map_try_emplace -# error "__cpp_lib_unordered_map_try_emplace should be defined in c++26" -# endif -# if __cpp_lib_unordered_map_try_emplace != 201411L -# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++26" -# endif - -# ifndef __cpp_lib_unreachable -# error "__cpp_lib_unreachable should be defined in c++26" -# endif -# if __cpp_lib_unreachable != 202202L -# error "__cpp_lib_unreachable should have the value 202202L in c++26" -# endif - -# ifndef __cpp_lib_unwrap_ref -# error "__cpp_lib_unwrap_ref should be defined in c++26" -# endif -# if __cpp_lib_unwrap_ref != 201811L -# error "__cpp_lib_unwrap_ref should have the value 201811L in c++26" -# endif - -# ifndef __cpp_lib_variant -# error "__cpp_lib_variant should be defined in c++26" -# endif -# if __cpp_lib_variant != 202306L -# error "__cpp_lib_variant should have the value 202306L in c++26" -# endif - -# ifndef __cpp_lib_void_t -# error "__cpp_lib_void_t should be defined in c++26" -# endif -# if __cpp_lib_void_t != 201411L -# error "__cpp_lib_void_t should have the value 201411L in c++26" -# endif +# ifndef __cpp_lib_adaptor_iterator_pair_constructor +# error "__cpp_lib_adaptor_iterator_pair_constructor should be defined in c++26" +# endif +# if __cpp_lib_adaptor_iterator_pair_constructor != 202106L +# error "__cpp_lib_adaptor_iterator_pair_constructor should have the value 202106L in c++26" +# endif + +# ifndef __cpp_lib_addressof_constexpr +# error "__cpp_lib_addressof_constexpr should be defined in c++26" +# endif +# if __cpp_lib_addressof_constexpr != 201603L +# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_allocate_at_least +# error "__cpp_lib_allocate_at_least should be defined in c++26" +# endif +# if __cpp_lib_allocate_at_least != 202302L +# error "__cpp_lib_allocate_at_least should have the value 202302L in c++26" +# endif + +# ifndef __cpp_lib_allocator_traits_is_always_equal +# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++26" +# endif +# if __cpp_lib_allocator_traits_is_always_equal != 201411L +# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++26" +# endif + +# ifndef __cpp_lib_any +# error "__cpp_lib_any should be defined in c++26" +# endif +# if __cpp_lib_any != 201606L +# error "__cpp_lib_any should have the value 201606L in c++26" +# endif + +# ifndef __cpp_lib_apply +# error "__cpp_lib_apply should be defined in c++26" +# endif +# if __cpp_lib_apply != 201603L +# error "__cpp_lib_apply should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_array_constexpr +# error "__cpp_lib_array_constexpr should be defined in c++26" +# endif +# if __cpp_lib_array_constexpr != 201811L +# error "__cpp_lib_array_constexpr should have the value 201811L in c++26" +# endif + +# ifndef __cpp_lib_as_const +# error "__cpp_lib_as_const should be defined in c++26" +# endif +# if __cpp_lib_as_const != 201510L +# error "__cpp_lib_as_const should have the value 201510L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_associative_heterogeneous_erasure +# error "__cpp_lib_associative_heterogeneous_erasure should be defined in c++26" +# endif +# if __cpp_lib_associative_heterogeneous_erasure != 202110L +# error "__cpp_lib_associative_heterogeneous_erasure should have the value 202110L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_associative_heterogeneous_erasure +# error "__cpp_lib_associative_heterogeneous_erasure should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_associative_heterogeneous_insertion +# error "__cpp_lib_associative_heterogeneous_insertion should be defined in c++26" +# endif +# if __cpp_lib_associative_heterogeneous_insertion != 202306L +# error "__cpp_lib_associative_heterogeneous_insertion should have the value 202306L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_associative_heterogeneous_insertion +# error "__cpp_lib_associative_heterogeneous_insertion should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_assume_aligned +# error "__cpp_lib_assume_aligned should be defined in c++26" +# endif +# if __cpp_lib_assume_aligned != 201811L +# error "__cpp_lib_assume_aligned should have the value 201811L in c++26" +# endif + +# ifndef __cpp_lib_atomic_flag_test +# error "__cpp_lib_atomic_flag_test should be defined in c++26" +# endif +# if __cpp_lib_atomic_flag_test != 201907L +# error "__cpp_lib_atomic_flag_test should have the value 201907L in c++26" +# endif + +# ifndef __cpp_lib_atomic_float +# error "__cpp_lib_atomic_float should be defined in c++26" +# endif +# if __cpp_lib_atomic_float != 201711L +# error "__cpp_lib_atomic_float should have the value 201711L in c++26" +# endif + +# ifndef __cpp_lib_atomic_is_always_lock_free +# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++26" +# endif +# if __cpp_lib_atomic_is_always_lock_free != 201603L +# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_atomic_lock_free_type_aliases +# error "__cpp_lib_atomic_lock_free_type_aliases should be defined in c++26" +# endif +# if __cpp_lib_atomic_lock_free_type_aliases != 201907L +# error "__cpp_lib_atomic_lock_free_type_aliases should have the value 201907L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_atomic_min_max +# error "__cpp_lib_atomic_min_max should be defined in c++26" +# endif +# if __cpp_lib_atomic_min_max != 202403L +# error "__cpp_lib_atomic_min_max should have the value 202403L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_atomic_min_max +# error "__cpp_lib_atomic_min_max should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_atomic_ref +# error "__cpp_lib_atomic_ref should be defined in c++26" +# endif +# if __cpp_lib_atomic_ref != 201806L +# error "__cpp_lib_atomic_ref should have the value 201806L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_atomic_shared_ptr +# error "__cpp_lib_atomic_shared_ptr should be defined in c++26" +# endif +# if __cpp_lib_atomic_shared_ptr != 201711L +# error "__cpp_lib_atomic_shared_ptr should have the value 201711L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_atomic_shared_ptr +# error "__cpp_lib_atomic_shared_ptr should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_atomic_value_initialization +# error "__cpp_lib_atomic_value_initialization should be defined in c++26" +# endif +# if __cpp_lib_atomic_value_initialization != 201911L +# error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC +# ifndef __cpp_lib_atomic_wait +# error "__cpp_lib_atomic_wait should be defined in c++26" +# endif +# if __cpp_lib_atomic_wait != 201907L +# error "__cpp_lib_atomic_wait should have the value 201907L in c++26" +# endif +# else +# ifdef __cpp_lib_atomic_wait +# error "__cpp_lib_atomic_wait should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_barrier +# error "__cpp_lib_barrier should be defined in c++26" +# endif +# if __cpp_lib_barrier != 201907L +# error "__cpp_lib_barrier should have the value 201907L in c++26" +# endif +# else +# ifdef __cpp_lib_barrier +# error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_bind_back +# error "__cpp_lib_bind_back should be defined in c++26" +# endif +# if __cpp_lib_bind_back != 202202L +# error "__cpp_lib_bind_back should have the value 202202L in c++26" +# endif + +# ifndef __cpp_lib_bind_front +# error "__cpp_lib_bind_front should be defined in c++26" +# endif +# if __cpp_lib_bind_front != 202306L +# error "__cpp_lib_bind_front should have the value 202306L in c++26" +# endif + +# ifndef __cpp_lib_bit_cast +# error "__cpp_lib_bit_cast should be defined in c++26" +# endif +# if __cpp_lib_bit_cast != 201806L +# error "__cpp_lib_bit_cast should have the value 201806L in c++26" +# endif + +# ifndef __cpp_lib_bitops +# error "__cpp_lib_bitops should be defined in c++26" +# endif +# if __cpp_lib_bitops != 201907L +# error "__cpp_lib_bitops should have the value 201907L in c++26" +# endif + +# ifndef __cpp_lib_bitset +# error "__cpp_lib_bitset should be defined in c++26" +# endif +# if __cpp_lib_bitset != 202306L +# error "__cpp_lib_bitset should have the value 202306L in c++26" +# endif + +# ifndef __cpp_lib_bool_constant +# error "__cpp_lib_bool_constant should be defined in c++26" +# endif +# if __cpp_lib_bool_constant != 201505L +# error "__cpp_lib_bool_constant should have the value 201505L in c++26" +# endif + +# ifndef __cpp_lib_bounded_array_traits +# error "__cpp_lib_bounded_array_traits should be defined in c++26" +# endif +# if __cpp_lib_bounded_array_traits != 201902L +# error "__cpp_lib_bounded_array_traits should have the value 201902L in c++26" +# endif + +# ifndef __cpp_lib_boyer_moore_searcher +# error "__cpp_lib_boyer_moore_searcher should be defined in c++26" +# endif +# if __cpp_lib_boyer_moore_searcher != 201603L +# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_byte +# error "__cpp_lib_byte should be defined in c++26" +# endif +# if __cpp_lib_byte != 201603L +# error "__cpp_lib_byte should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_byteswap +# error "__cpp_lib_byteswap should be defined in c++26" +# endif +# if __cpp_lib_byteswap != 202110L +# error "__cpp_lib_byteswap should have the value 202110L in c++26" +# endif + +# if defined(__cpp_char8_t) +# ifndef __cpp_lib_char8_t +# error "__cpp_lib_char8_t should be defined in c++26" +# endif +# if __cpp_lib_char8_t != 201907L +# error "__cpp_lib_char8_t should have the value 201907L in c++26" +# endif +# else +# ifdef __cpp_lib_char8_t +# error "__cpp_lib_char8_t should not be defined when the requirement 'defined(__cpp_char8_t)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_chrono +# error "__cpp_lib_chrono should be defined in c++26" +# endif +# if __cpp_lib_chrono != 201611L +# error "__cpp_lib_chrono should have the value 201611L in c++26" +# endif + +# ifndef __cpp_lib_chrono_udls +# error "__cpp_lib_chrono_udls should be defined in c++26" +# endif +# if __cpp_lib_chrono_udls != 201304L +# error "__cpp_lib_chrono_udls should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_clamp +# error "__cpp_lib_clamp should be defined in c++26" +# endif +# if __cpp_lib_clamp != 201603L +# error "__cpp_lib_clamp should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_complex_udls +# error "__cpp_lib_complex_udls should be defined in c++26" +# endif +# if __cpp_lib_complex_udls != 201309L +# error "__cpp_lib_complex_udls should have the value 201309L in c++26" +# endif + +# ifndef __cpp_lib_concepts +# error "__cpp_lib_concepts should be defined in c++26" +# endif +# if __cpp_lib_concepts != 202002L +# error "__cpp_lib_concepts should have the value 202002L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_algorithms +# error "__cpp_lib_constexpr_algorithms should be defined in c++26" +# endif +# if __cpp_lib_constexpr_algorithms != 201806L +# error "__cpp_lib_constexpr_algorithms should have the value 201806L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_bitset +# error "__cpp_lib_constexpr_bitset should be defined in c++26" +# endif +# if __cpp_lib_constexpr_bitset != 202207L +# error "__cpp_lib_constexpr_bitset should have the value 202207L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_charconv +# error "__cpp_lib_constexpr_charconv should be defined in c++26" +# endif +# if __cpp_lib_constexpr_charconv != 202207L +# error "__cpp_lib_constexpr_charconv should have the value 202207L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_constexpr_cmath +# error "__cpp_lib_constexpr_cmath should be defined in c++26" +# endif +# if __cpp_lib_constexpr_cmath != 202202L +# error "__cpp_lib_constexpr_cmath should have the value 202202L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_constexpr_cmath +# error "__cpp_lib_constexpr_cmath should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_constexpr_complex +# error "__cpp_lib_constexpr_complex should be defined in c++26" +# endif +# if __cpp_lib_constexpr_complex != 201711L +# error "__cpp_lib_constexpr_complex should have the value 201711L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_dynamic_alloc +# error "__cpp_lib_constexpr_dynamic_alloc should be defined in c++26" +# endif +# if __cpp_lib_constexpr_dynamic_alloc != 201907L +# error "__cpp_lib_constexpr_dynamic_alloc should have the value 201907L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_functional +# error "__cpp_lib_constexpr_functional should be defined in c++26" +# endif +# if __cpp_lib_constexpr_functional != 201907L +# error "__cpp_lib_constexpr_functional should have the value 201907L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_iterator +# error "__cpp_lib_constexpr_iterator should be defined in c++26" +# endif +# if __cpp_lib_constexpr_iterator != 201811L +# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_memory +# error "__cpp_lib_constexpr_memory should be defined in c++26" +# endif +# if __cpp_lib_constexpr_memory != 202202L +# error "__cpp_lib_constexpr_memory should have the value 202202L in c++26" +# endif + +# if !defined(_LIBCPP_ABI_VCRUNTIME) +# ifndef __cpp_lib_constexpr_new +# error "__cpp_lib_constexpr_new should be defined in c++26" +# endif +# if __cpp_lib_constexpr_new != 202406L +# error "__cpp_lib_constexpr_new should have the value 202406L in c++26" +# endif +# else +# ifdef __cpp_lib_constexpr_new +# error "__cpp_lib_constexpr_new should not be defined when the requirement '!defined(_LIBCPP_ABI_VCRUNTIME)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_constexpr_numeric +# error "__cpp_lib_constexpr_numeric should be defined in c++26" +# endif +# if __cpp_lib_constexpr_numeric != 201911L +# error "__cpp_lib_constexpr_numeric should have the value 201911L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_string +# error "__cpp_lib_constexpr_string should be defined in c++26" +# endif +# if __cpp_lib_constexpr_string != 201907L +# error "__cpp_lib_constexpr_string should have the value 201907L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_string_view +# error "__cpp_lib_constexpr_string_view should be defined in c++26" +# endif +# if __cpp_lib_constexpr_string_view != 201811L +# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_tuple +# error "__cpp_lib_constexpr_tuple should be defined in c++26" +# endif +# if __cpp_lib_constexpr_tuple != 201811L +# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_typeinfo +# error "__cpp_lib_constexpr_typeinfo should be defined in c++26" +# endif +# if __cpp_lib_constexpr_typeinfo != 202106L +# error "__cpp_lib_constexpr_typeinfo should have the value 202106L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_utility +# error "__cpp_lib_constexpr_utility should be defined in c++26" +# endif +# if __cpp_lib_constexpr_utility != 201811L +# error "__cpp_lib_constexpr_utility should have the value 201811L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_vector +# error "__cpp_lib_constexpr_vector should be defined in c++26" +# endif +# if __cpp_lib_constexpr_vector != 201907L +# error "__cpp_lib_constexpr_vector should have the value 201907L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_constrained_equality +# error "__cpp_lib_constrained_equality should be defined in c++26" +# endif +# if __cpp_lib_constrained_equality != 202403L +# error "__cpp_lib_constrained_equality should have the value 202403L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_constrained_equality +# error "__cpp_lib_constrained_equality should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_containers_ranges +# error "__cpp_lib_containers_ranges should be defined in c++26" +# endif +# if __cpp_lib_containers_ranges != 202202L +# error "__cpp_lib_containers_ranges should have the value 202202L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_copyable_function +# error "__cpp_lib_copyable_function should be defined in c++26" +# endif +# if __cpp_lib_copyable_function != 202306L +# error "__cpp_lib_copyable_function should have the value 202306L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_copyable_function +# error "__cpp_lib_copyable_function should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_coroutine +# error "__cpp_lib_coroutine should be defined in c++26" +# endif +# if __cpp_lib_coroutine != 201902L +# error "__cpp_lib_coroutine should have the value 201902L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_debugging +# error "__cpp_lib_debugging should be defined in c++26" +# endif +# if __cpp_lib_debugging != 202311L +# error "__cpp_lib_debugging should have the value 202311L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_debugging +# error "__cpp_lib_debugging should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_default_template_type_for_algorithm_values +# error "__cpp_lib_default_template_type_for_algorithm_values should be defined in c++26" +# endif +# if __cpp_lib_default_template_type_for_algorithm_values != 202403L +# error "__cpp_lib_default_template_type_for_algorithm_values should have the value 202403L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_default_template_type_for_algorithm_values +# error "__cpp_lib_default_template_type_for_algorithm_values should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L +# ifndef __cpp_lib_destroying_delete +# error "__cpp_lib_destroying_delete should be defined in c++26" +# endif +# if __cpp_lib_destroying_delete != 201806L +# error "__cpp_lib_destroying_delete should have the value 201806L in c++26" +# endif +# else +# ifdef __cpp_lib_destroying_delete +# error "__cpp_lib_destroying_delete should not be defined when the requirement 'TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L' is not met!" +# endif +# endif + +# ifndef __cpp_lib_enable_shared_from_this +# error "__cpp_lib_enable_shared_from_this should be defined in c++26" +# endif +# if __cpp_lib_enable_shared_from_this != 201603L +# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_endian +# error "__cpp_lib_endian should be defined in c++26" +# endif +# if __cpp_lib_endian != 201907L +# error "__cpp_lib_endian should have the value 201907L in c++26" +# endif + +# ifndef __cpp_lib_erase_if +# error "__cpp_lib_erase_if should be defined in c++26" +# endif +# if __cpp_lib_erase_if != 202002L +# error "__cpp_lib_erase_if should have the value 202002L in c++26" +# endif + +# ifndef __cpp_lib_exchange_function +# error "__cpp_lib_exchange_function should be defined in c++26" +# endif +# if __cpp_lib_exchange_function != 201304L +# error "__cpp_lib_exchange_function should have the value 201304L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_execution +# error "__cpp_lib_execution should be defined in c++26" +# endif +# if __cpp_lib_execution != 201902L +# error "__cpp_lib_execution should have the value 201902L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_execution +# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_expected +# error "__cpp_lib_expected should be defined in c++26" +# endif +# if __cpp_lib_expected != 202211L +# error "__cpp_lib_expected should have the value 202211L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY) +# ifndef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should be defined in c++26" +# endif +# if __cpp_lib_filesystem != 201703L +# error "__cpp_lib_filesystem should have the value 201703L in c++26" +# endif +# else +# ifdef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_flat_map +# error "__cpp_lib_flat_map should be defined in c++26" +# endif +# if __cpp_lib_flat_map != 202207L +# error "__cpp_lib_flat_map should have the value 202207L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_flat_set +# error "__cpp_lib_flat_set should be defined in c++26" +# endif +# if __cpp_lib_flat_set != 202207L +# error "__cpp_lib_flat_set should have the value 202207L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_flat_set +# error "__cpp_lib_flat_set should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT +# ifndef __cpp_lib_format +# error "__cpp_lib_format should be defined in c++26" +# endif +# if __cpp_lib_format != 202110L +# error "__cpp_lib_format should have the value 202110L in c++26" +# endif +# else +# ifdef __cpp_lib_format +# error "__cpp_lib_format should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_format_path +# error "__cpp_lib_format_path should be defined in c++26" +# endif +# if __cpp_lib_format_path != 202403L +# error "__cpp_lib_format_path should have the value 202403L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_format_path +# error "__cpp_lib_format_path should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_format_ranges +# error "__cpp_lib_format_ranges should be defined in c++26" +# endif +# if __cpp_lib_format_ranges != 202207L +# error "__cpp_lib_format_ranges should have the value 202207L in c++26" +# endif + +# ifndef __cpp_lib_format_uchar +# error "__cpp_lib_format_uchar should be defined in c++26" +# endif +# if __cpp_lib_format_uchar != 202311L +# error "__cpp_lib_format_uchar should have the value 202311L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_formatters +# error "__cpp_lib_formatters should be defined in c++26" +# endif +# if __cpp_lib_formatters != 202302L +# error "__cpp_lib_formatters should have the value 202302L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_formatters +# error "__cpp_lib_formatters should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_forward_like +# error "__cpp_lib_forward_like should be defined in c++26" +# endif +# if __cpp_lib_forward_like != 202207L +# error "__cpp_lib_forward_like should have the value 202207L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_freestanding_algorithm +# error "__cpp_lib_freestanding_algorithm should be defined in c++26" +# endif +# if __cpp_lib_freestanding_algorithm != 202311L +# error "__cpp_lib_freestanding_algorithm should have the value 202311L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_freestanding_algorithm +# error "__cpp_lib_freestanding_algorithm should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_freestanding_array +# error "__cpp_lib_freestanding_array should be defined in c++26" +# endif +# if __cpp_lib_freestanding_array != 202311L +# error "__cpp_lib_freestanding_array should have the value 202311L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_freestanding_array +# error "__cpp_lib_freestanding_array should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_freestanding_cstring +# error "__cpp_lib_freestanding_cstring should be defined in c++26" +# endif +# if __cpp_lib_freestanding_cstring != 202306L +# error "__cpp_lib_freestanding_cstring should have the value 202306L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_freestanding_cstring +# error "__cpp_lib_freestanding_cstring should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_freestanding_expected +# error "__cpp_lib_freestanding_expected should be defined in c++26" +# endif +# if __cpp_lib_freestanding_expected != 202311L +# error "__cpp_lib_freestanding_expected should have the value 202311L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_freestanding_expected +# error "__cpp_lib_freestanding_expected should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_freestanding_mdspan +# error "__cpp_lib_freestanding_mdspan should be defined in c++26" +# endif +# if __cpp_lib_freestanding_mdspan != 202311L +# error "__cpp_lib_freestanding_mdspan should have the value 202311L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_freestanding_mdspan +# error "__cpp_lib_freestanding_mdspan should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_freestanding_optional +# error "__cpp_lib_freestanding_optional should be defined in c++26" +# endif +# if __cpp_lib_freestanding_optional != 202311L +# error "__cpp_lib_freestanding_optional should have the value 202311L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_freestanding_optional +# error "__cpp_lib_freestanding_optional should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_freestanding_string_view +# error "__cpp_lib_freestanding_string_view should be defined in c++26" +# endif +# if __cpp_lib_freestanding_string_view != 202311L +# error "__cpp_lib_freestanding_string_view should have the value 202311L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_freestanding_string_view +# error "__cpp_lib_freestanding_string_view should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_freestanding_variant +# error "__cpp_lib_freestanding_variant should be defined in c++26" +# endif +# if __cpp_lib_freestanding_variant != 202311L +# error "__cpp_lib_freestanding_variant should have the value 202311L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_freestanding_variant +# error "__cpp_lib_freestanding_variant should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION) +# ifndef __cpp_lib_fstream_native_handle +# error "__cpp_lib_fstream_native_handle should be defined in c++26" +# endif +# if __cpp_lib_fstream_native_handle != 202306L +# error "__cpp_lib_fstream_native_handle should have the value 202306L in c++26" +# endif +# else +# ifdef __cpp_lib_fstream_native_handle +# error "__cpp_lib_fstream_native_handle should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION)' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_function_ref +# error "__cpp_lib_function_ref should be defined in c++26" +# endif +# if __cpp_lib_function_ref != 202306L +# error "__cpp_lib_function_ref should have the value 202306L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_function_ref +# error "__cpp_lib_function_ref should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_gcd_lcm +# error "__cpp_lib_gcd_lcm should be defined in c++26" +# endif +# if __cpp_lib_gcd_lcm != 201606L +# error "__cpp_lib_gcd_lcm should have the value 201606L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_generate_random +# error "__cpp_lib_generate_random should be defined in c++26" +# endif +# if __cpp_lib_generate_random != 202403L +# error "__cpp_lib_generate_random should have the value 202403L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_generate_random +# error "__cpp_lib_generate_random should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_generic_associative_lookup +# error "__cpp_lib_generic_associative_lookup should be defined in c++26" +# endif +# if __cpp_lib_generic_associative_lookup != 201304L +# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_generic_unordered_lookup +# error "__cpp_lib_generic_unordered_lookup should be defined in c++26" +# endif +# if __cpp_lib_generic_unordered_lookup != 201811L +# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)) +# ifndef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should be defined in c++26" +# endif +# if __cpp_lib_hardware_interference_size != 201703L +# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++26" +# endif +# else +# ifdef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))' is not met!" +# endif +# endif + +# ifndef __cpp_lib_has_unique_object_representations +# error "__cpp_lib_has_unique_object_representations should be defined in c++26" +# endif +# if __cpp_lib_has_unique_object_representations != 201606L +# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_hazard_pointer +# error "__cpp_lib_hazard_pointer should be defined in c++26" +# endif +# if __cpp_lib_hazard_pointer != 202306L +# error "__cpp_lib_hazard_pointer should have the value 202306L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_hazard_pointer +# error "__cpp_lib_hazard_pointer should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_hypot +# error "__cpp_lib_hypot should be defined in c++26" +# endif +# if __cpp_lib_hypot != 201603L +# error "__cpp_lib_hypot should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_incomplete_container_elements +# error "__cpp_lib_incomplete_container_elements should be defined in c++26" +# endif +# if __cpp_lib_incomplete_container_elements != 201505L +# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_inplace_vector +# error "__cpp_lib_inplace_vector should be defined in c++26" +# endif +# if __cpp_lib_inplace_vector != 202406L +# error "__cpp_lib_inplace_vector should have the value 202406L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_inplace_vector +# error "__cpp_lib_inplace_vector should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_int_pow2 +# error "__cpp_lib_int_pow2 should be defined in c++26" +# endif +# if __cpp_lib_int_pow2 != 202002L +# error "__cpp_lib_int_pow2 should have the value 202002L in c++26" +# endif + +# ifndef __cpp_lib_integer_comparison_functions +# error "__cpp_lib_integer_comparison_functions should be defined in c++26" +# endif +# if __cpp_lib_integer_comparison_functions != 202002L +# error "__cpp_lib_integer_comparison_functions should have the value 202002L in c++26" +# endif + +# ifndef __cpp_lib_integer_sequence +# error "__cpp_lib_integer_sequence should be defined in c++26" +# endif +# if __cpp_lib_integer_sequence != 201304L +# error "__cpp_lib_integer_sequence should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_integral_constant_callable +# error "__cpp_lib_integral_constant_callable should be defined in c++26" +# endif +# if __cpp_lib_integral_constant_callable != 201304L +# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should be defined in c++26" +# endif +# if __cpp_lib_interpolate != 201902L +# error "__cpp_lib_interpolate should have the value 201902L in c++26" +# endif + +# ifndef __cpp_lib_invoke +# error "__cpp_lib_invoke should be defined in c++26" +# endif +# if __cpp_lib_invoke != 201411L +# error "__cpp_lib_invoke should have the value 201411L in c++26" +# endif + +# ifndef __cpp_lib_invoke_r +# error "__cpp_lib_invoke_r should be defined in c++26" +# endif +# if __cpp_lib_invoke_r != 202106L +# error "__cpp_lib_invoke_r should have the value 202106L in c++26" +# endif + +# ifndef __cpp_lib_ios_noreplace +# error "__cpp_lib_ios_noreplace should be defined in c++26" +# endif +# if __cpp_lib_ios_noreplace != 202207L +# error "__cpp_lib_ios_noreplace should have the value 202207L in c++26" +# endif + +# ifndef __cpp_lib_is_aggregate +# error "__cpp_lib_is_aggregate should be defined in c++26" +# endif +# if __cpp_lib_is_aggregate != 201703L +# error "__cpp_lib_is_aggregate should have the value 201703L in c++26" +# endif + +# ifndef __cpp_lib_is_constant_evaluated +# error "__cpp_lib_is_constant_evaluated should be defined in c++26" +# endif +# if __cpp_lib_is_constant_evaluated != 201811L +# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++26" +# endif + +# ifndef __cpp_lib_is_final +# error "__cpp_lib_is_final should be defined in c++26" +# endif +# if __cpp_lib_is_final != 201402L +# error "__cpp_lib_is_final should have the value 201402L in c++26" +# endif + +# if __has_builtin(__builtin_is_implicit_lifetime) +# ifndef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should be defined in c++26" +# endif +# if __cpp_lib_is_implicit_lifetime != 202302L +# error "__cpp_lib_is_implicit_lifetime should have the value 202302L in c++26" +# endif +# else +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_implicit_lifetime)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_is_invocable +# error "__cpp_lib_is_invocable should be defined in c++26" +# endif +# if __cpp_lib_is_invocable != 201703L +# error "__cpp_lib_is_invocable should have the value 201703L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_is_layout_compatible +# error "__cpp_lib_is_layout_compatible should be defined in c++26" +# endif +# if __cpp_lib_is_layout_compatible != 201907L +# error "__cpp_lib_is_layout_compatible should have the value 201907L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_is_layout_compatible +# error "__cpp_lib_is_layout_compatible should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_is_nothrow_convertible +# error "__cpp_lib_is_nothrow_convertible should be defined in c++26" +# endif +# if __cpp_lib_is_nothrow_convertible != 201806L +# error "__cpp_lib_is_nothrow_convertible should have the value 201806L in c++26" +# endif + +# ifndef __cpp_lib_is_null_pointer +# error "__cpp_lib_is_null_pointer should be defined in c++26" +# endif +# if __cpp_lib_is_null_pointer != 201309L +# error "__cpp_lib_is_null_pointer should have the value 201309L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_is_pointer_interconvertible +# error "__cpp_lib_is_pointer_interconvertible should be defined in c++26" +# endif +# if __cpp_lib_is_pointer_interconvertible != 201907L +# error "__cpp_lib_is_pointer_interconvertible should have the value 201907L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_is_pointer_interconvertible +# error "__cpp_lib_is_pointer_interconvertible should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_is_scoped_enum +# error "__cpp_lib_is_scoped_enum should be defined in c++26" +# endif +# if __cpp_lib_is_scoped_enum != 202011L +# error "__cpp_lib_is_scoped_enum should have the value 202011L in c++26" +# endif + +# ifndef __cpp_lib_is_swappable +# error "__cpp_lib_is_swappable should be defined in c++26" +# endif +# if __cpp_lib_is_swappable != 201603L +# error "__cpp_lib_is_swappable should have the value 201603L in c++26" +# endif + +# if __has_builtin(__builtin_is_virtual_base_of) +# ifndef __cpp_lib_is_virtual_base_of +# error "__cpp_lib_is_virtual_base_of should be defined in c++26" +# endif +# if __cpp_lib_is_virtual_base_of != 202406L +# error "__cpp_lib_is_virtual_base_of should have the value 202406L in c++26" +# endif +# else +# ifdef __cpp_lib_is_virtual_base_of +# error "__cpp_lib_is_virtual_base_of should not be defined when the requirement '__has_builtin(__builtin_is_virtual_base_of)' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_is_within_lifetime +# error "__cpp_lib_is_within_lifetime should be defined in c++26" +# endif +# if __cpp_lib_is_within_lifetime != 202306L +# error "__cpp_lib_is_within_lifetime should have the value 202306L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_is_within_lifetime +# error "__cpp_lib_is_within_lifetime should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_jthread +# error "__cpp_lib_jthread should be defined in c++26" +# endif +# if __cpp_lib_jthread != 201911L +# error "__cpp_lib_jthread should have the value 201911L in c++26" +# endif +# else +# ifdef __cpp_lib_jthread +# error "__cpp_lib_jthread should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_latch +# error "__cpp_lib_latch should be defined in c++26" +# endif +# if __cpp_lib_latch != 201907L +# error "__cpp_lib_latch should have the value 201907L in c++26" +# endif +# else +# ifdef __cpp_lib_latch +# error "__cpp_lib_latch should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_launder +# error "__cpp_lib_launder should be defined in c++26" +# endif +# if __cpp_lib_launder != 201606L +# error "__cpp_lib_launder should have the value 201606L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_linalg +# error "__cpp_lib_linalg should be defined in c++26" +# endif +# if __cpp_lib_linalg != 202311L +# error "__cpp_lib_linalg should have the value 202311L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_linalg +# error "__cpp_lib_linalg should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_list_remove_return_type +# error "__cpp_lib_list_remove_return_type should be defined in c++26" +# endif +# if __cpp_lib_list_remove_return_type != 201806L +# error "__cpp_lib_list_remove_return_type should have the value 201806L in c++26" +# endif + +# ifndef __cpp_lib_logical_traits +# error "__cpp_lib_logical_traits should be defined in c++26" +# endif +# if __cpp_lib_logical_traits != 201510L +# error "__cpp_lib_logical_traits should have the value 201510L in c++26" +# endif + +# ifndef __cpp_lib_make_from_tuple +# error "__cpp_lib_make_from_tuple should be defined in c++26" +# endif +# if __cpp_lib_make_from_tuple != 201606L +# error "__cpp_lib_make_from_tuple should have the value 201606L in c++26" +# endif + +# ifndef __cpp_lib_make_reverse_iterator +# error "__cpp_lib_make_reverse_iterator should be defined in c++26" +# endif +# if __cpp_lib_make_reverse_iterator != 201402L +# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++26" +# endif + +# ifndef __cpp_lib_make_unique +# error "__cpp_lib_make_unique should be defined in c++26" +# endif +# if __cpp_lib_make_unique != 201304L +# error "__cpp_lib_make_unique should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_map_try_emplace +# error "__cpp_lib_map_try_emplace should be defined in c++26" +# endif +# if __cpp_lib_map_try_emplace != 201411L +# error "__cpp_lib_map_try_emplace should have the value 201411L in c++26" +# endif + +# ifndef __cpp_lib_math_constants +# error "__cpp_lib_math_constants should be defined in c++26" +# endif +# if __cpp_lib_math_constants != 201907L +# error "__cpp_lib_math_constants should have the value 201907L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should be defined in c++26" +# endif +# if __cpp_lib_math_special_functions != 201603L +# error "__cpp_lib_math_special_functions should have the value 201603L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_mdspan +# error "__cpp_lib_mdspan should be defined in c++26" +# endif +# if __cpp_lib_mdspan != 202406L +# error "__cpp_lib_mdspan should have the value 202406L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR +# ifndef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should be defined in c++26" +# endif +# if __cpp_lib_memory_resource != 201603L +# error "__cpp_lib_memory_resource should have the value 201603L in c++26" +# endif +# else +# ifdef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" +# endif +# endif + +# ifndef __cpp_lib_modules +# error "__cpp_lib_modules should be defined in c++26" +# endif +# if __cpp_lib_modules != 202207L +# error "__cpp_lib_modules should have the value 202207L in c++26" +# endif + +# ifndef __cpp_lib_move_iterator_concept +# error "__cpp_lib_move_iterator_concept should be defined in c++26" +# endif +# if __cpp_lib_move_iterator_concept != 202207L +# error "__cpp_lib_move_iterator_concept should have the value 202207L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_move_only_function +# error "__cpp_lib_move_only_function should be defined in c++26" +# endif +# if __cpp_lib_move_only_function != 202110L +# error "__cpp_lib_move_only_function should have the value 202110L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_move_only_function +# error "__cpp_lib_move_only_function should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_node_extract +# error "__cpp_lib_node_extract should be defined in c++26" +# endif +# if __cpp_lib_node_extract != 201606L +# error "__cpp_lib_node_extract should have the value 201606L in c++26" +# endif + +# ifndef __cpp_lib_nonmember_container_access +# error "__cpp_lib_nonmember_container_access should be defined in c++26" +# endif +# if __cpp_lib_nonmember_container_access != 201411L +# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++26" +# endif + +# ifndef __cpp_lib_not_fn +# error "__cpp_lib_not_fn should be defined in c++26" +# endif +# if __cpp_lib_not_fn != 202306L +# error "__cpp_lib_not_fn should have the value 202306L in c++26" +# endif + +# ifndef __cpp_lib_null_iterators +# error "__cpp_lib_null_iterators should be defined in c++26" +# endif +# if __cpp_lib_null_iterators != 201304L +# error "__cpp_lib_null_iterators should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_optional +# error "__cpp_lib_optional should be defined in c++26" +# endif +# if __cpp_lib_optional != 202110L +# error "__cpp_lib_optional should have the value 202110L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_optional_range_support +# error "__cpp_lib_optional_range_support should be defined in c++26" +# endif +# if __cpp_lib_optional_range_support != 202406L +# error "__cpp_lib_optional_range_support should have the value 202406L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_optional_range_support +# error "__cpp_lib_optional_range_support should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_out_ptr +# error "__cpp_lib_out_ptr should be defined in c++26" +# endif +# if __cpp_lib_out_ptr != 202311L +# error "__cpp_lib_out_ptr should have the value 202311L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should be defined in c++26" +# endif +# if __cpp_lib_parallel_algorithm != 201603L +# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_philox_engine +# error "__cpp_lib_philox_engine should be defined in c++26" +# endif +# if __cpp_lib_philox_engine != 202406L +# error "__cpp_lib_philox_engine should have the value 202406L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_philox_engine +# error "__cpp_lib_philox_engine should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR +# ifndef __cpp_lib_polymorphic_allocator +# error "__cpp_lib_polymorphic_allocator should be defined in c++26" +# endif +# if __cpp_lib_polymorphic_allocator != 201902L +# error "__cpp_lib_polymorphic_allocator should have the value 201902L in c++26" +# endif +# else +# ifdef __cpp_lib_polymorphic_allocator +# error "__cpp_lib_polymorphic_allocator should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT +# ifndef __cpp_lib_print +# error "__cpp_lib_print should be defined in c++26" +# endif +# if __cpp_lib_print != 202207L +# error "__cpp_lib_print should have the value 202207L in c++26" +# endif +# else +# ifdef __cpp_lib_print +# error "__cpp_lib_print should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION +# ifndef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should be defined in c++26" +# endif +# if __cpp_lib_quoted_string_io != 201304L +# error "__cpp_lib_quoted_string_io should have the value 201304L in c++26" +# endif +# else +# ifdef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" +# endif +# endif + +# ifndef __cpp_lib_ranges +# error "__cpp_lib_ranges should be defined in c++26" +# endif +# if __cpp_lib_ranges != 202406L +# error "__cpp_lib_ranges should have the value 202406L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_as_const +# error "__cpp_lib_ranges_as_const should be defined in c++26" +# endif +# if __cpp_lib_ranges_as_const != 202207L +# error "__cpp_lib_ranges_as_const should have the value 202207L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_ranges_as_const +# error "__cpp_lib_ranges_as_const should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_as_rvalue +# error "__cpp_lib_ranges_as_rvalue should be defined in c++26" +# endif +# if __cpp_lib_ranges_as_rvalue != 202207L +# error "__cpp_lib_ranges_as_rvalue should have the value 202207L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should be defined in c++26" +# endif +# if __cpp_lib_ranges_chunk != 202202L +# error "__cpp_lib_ranges_chunk should have the value 202202L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_chunk_by +# error "__cpp_lib_ranges_chunk_by should be defined in c++26" +# endif +# if __cpp_lib_ranges_chunk_by != 202202L +# error "__cpp_lib_ranges_chunk_by should have the value 202202L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_concat +# error "__cpp_lib_ranges_concat should be defined in c++26" +# endif +# if __cpp_lib_ranges_concat != 202403L +# error "__cpp_lib_ranges_concat should have the value 202403L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_ranges_concat +# error "__cpp_lib_ranges_concat should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_contains +# error "__cpp_lib_ranges_contains should be defined in c++26" +# endif +# if __cpp_lib_ranges_contains != 202207L +# error "__cpp_lib_ranges_contains should have the value 202207L in c++26" +# endif + +# ifndef __cpp_lib_ranges_find_last +# error "__cpp_lib_ranges_find_last should be defined in c++26" +# endif +# if __cpp_lib_ranges_find_last != 202207L +# error "__cpp_lib_ranges_find_last should have the value 202207L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_iota +# error "__cpp_lib_ranges_iota should be defined in c++26" +# endif +# if __cpp_lib_ranges_iota != 202202L +# error "__cpp_lib_ranges_iota should have the value 202202L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_ranges_iota +# error "__cpp_lib_ranges_iota should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_join_with +# error "__cpp_lib_ranges_join_with should be defined in c++26" +# endif +# if __cpp_lib_ranges_join_with != 202202L +# error "__cpp_lib_ranges_join_with should have the value 202202L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_ranges_join_with +# error "__cpp_lib_ranges_join_with should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_repeat +# error "__cpp_lib_ranges_repeat should be defined in c++26" +# endif +# if __cpp_lib_ranges_repeat != 202207L +# error "__cpp_lib_ranges_repeat should have the value 202207L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_slide +# error "__cpp_lib_ranges_slide should be defined in c++26" +# endif +# if __cpp_lib_ranges_slide != 202202L +# error "__cpp_lib_ranges_slide should have the value 202202L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_ranges_slide +# error "__cpp_lib_ranges_slide should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_starts_ends_with +# error "__cpp_lib_ranges_starts_ends_with should be defined in c++26" +# endif +# if __cpp_lib_ranges_starts_ends_with != 202106L +# error "__cpp_lib_ranges_starts_ends_with should have the value 202106L in c++26" +# endif + +# ifndef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should be defined in c++26" +# endif +# if __cpp_lib_ranges_stride != 202207L +# error "__cpp_lib_ranges_stride should have the value 202207L in c++26" +# endif + +# ifndef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should be defined in c++26" +# endif +# if __cpp_lib_ranges_to_container != 202202L +# error "__cpp_lib_ranges_to_container should have the value 202202L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_zip +# error "__cpp_lib_ranges_zip should be defined in c++26" +# endif +# if __cpp_lib_ranges_zip != 202110L +# error "__cpp_lib_ranges_zip should have the value 202110L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_ranges_zip +# error "__cpp_lib_ranges_zip should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ratio +# error "__cpp_lib_ratio should be defined in c++26" +# endif +# if __cpp_lib_ratio != 202306L +# error "__cpp_lib_ratio should have the value 202306L in c++26" +# endif + +# ifndef __cpp_lib_raw_memory_algorithms +# error "__cpp_lib_raw_memory_algorithms should be defined in c++26" +# endif +# if __cpp_lib_raw_memory_algorithms != 201606L +# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_rcu +# error "__cpp_lib_rcu should be defined in c++26" +# endif +# if __cpp_lib_rcu != 202306L +# error "__cpp_lib_rcu should have the value 202306L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_rcu +# error "__cpp_lib_rcu should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_reference_from_temporary +# error "__cpp_lib_reference_from_temporary should be defined in c++26" +# endif +# if __cpp_lib_reference_from_temporary != 202202L +# error "__cpp_lib_reference_from_temporary should have the value 202202L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_reference_from_temporary +# error "__cpp_lib_reference_from_temporary should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_reference_wrapper +# error "__cpp_lib_reference_wrapper should be defined in c++26" +# endif +# if __cpp_lib_reference_wrapper != 202403L +# error "__cpp_lib_reference_wrapper should have the value 202403L in c++26" +# endif + +# ifndef __cpp_lib_remove_cvref +# error "__cpp_lib_remove_cvref should be defined in c++26" +# endif +# if __cpp_lib_remove_cvref != 201711L +# error "__cpp_lib_remove_cvref should have the value 201711L in c++26" +# endif + +# ifndef __cpp_lib_result_of_sfinae +# error "__cpp_lib_result_of_sfinae should be defined in c++26" +# endif +# if __cpp_lib_result_of_sfinae != 201210L +# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++26" +# endif + +# ifndef __cpp_lib_robust_nonmodifying_seq_ops +# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++26" +# endif +# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L +# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_sample +# error "__cpp_lib_sample should be defined in c++26" +# endif +# if __cpp_lib_sample != 201603L +# error "__cpp_lib_sample should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_saturation_arithmetic +# error "__cpp_lib_saturation_arithmetic should be defined in c++26" +# endif +# if __cpp_lib_saturation_arithmetic != 202311L +# error "__cpp_lib_saturation_arithmetic should have the value 202311L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should be defined in c++26" +# endif +# if __cpp_lib_scoped_lock != 201703L +# error "__cpp_lib_scoped_lock should have the value 201703L in c++26" +# endif +# else +# ifdef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_semaphore +# error "__cpp_lib_semaphore should be defined in c++26" +# endif +# if __cpp_lib_semaphore != 201907L +# error "__cpp_lib_semaphore should have the value 201907L in c++26" +# endif +# else +# ifdef __cpp_lib_semaphore +# error "__cpp_lib_semaphore should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_senders +# error "__cpp_lib_senders should be defined in c++26" +# endif +# if __cpp_lib_senders != 202406L +# error "__cpp_lib_senders should have the value 202406L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_senders +# error "__cpp_lib_senders should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should be defined in c++26" +# endif +# if __cpp_lib_shared_mutex != 201505L +# error "__cpp_lib_shared_mutex should have the value 201505L in c++26" +# endif +# else +# ifdef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifndef __cpp_lib_shared_ptr_arrays +# error "__cpp_lib_shared_ptr_arrays should be defined in c++26" +# endif +# if __cpp_lib_shared_ptr_arrays != 201707L +# error "__cpp_lib_shared_ptr_arrays should have the value 201707L in c++26" +# endif + +# ifndef __cpp_lib_shared_ptr_weak_type +# error "__cpp_lib_shared_ptr_weak_type should be defined in c++26" +# endif +# if __cpp_lib_shared_ptr_weak_type != 201606L +# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++26" +# endif + +# if _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should be defined in c++26" +# endif +# if __cpp_lib_shared_timed_mutex != 201402L +# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++26" +# endif +# else +# ifdef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifndef __cpp_lib_shift +# error "__cpp_lib_shift should be defined in c++26" +# endif +# if __cpp_lib_shift != 201806L +# error "__cpp_lib_shift should have the value 201806L in c++26" +# endif + +# ifndef __cpp_lib_smart_ptr_for_overwrite +# error "__cpp_lib_smart_ptr_for_overwrite should be defined in c++26" +# endif +# if __cpp_lib_smart_ptr_for_overwrite != 202002L +# error "__cpp_lib_smart_ptr_for_overwrite should have the value 202002L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_smart_ptr_owner_equality +# error "__cpp_lib_smart_ptr_owner_equality should be defined in c++26" +# endif +# if __cpp_lib_smart_ptr_owner_equality != 202306L +# error "__cpp_lib_smart_ptr_owner_equality should have the value 202306L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_smart_ptr_owner_equality +# error "__cpp_lib_smart_ptr_owner_equality should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_source_location +# error "__cpp_lib_source_location should be defined in c++26" +# endif +# if __cpp_lib_source_location != 201907L +# error "__cpp_lib_source_location should have the value 201907L in c++26" +# endif + +# ifndef __cpp_lib_span +# error "__cpp_lib_span should be defined in c++26" +# endif +# if __cpp_lib_span != 202002L +# error "__cpp_lib_span should have the value 202002L in c++26" +# endif + +# ifndef __cpp_lib_span_at +# error "__cpp_lib_span_at should be defined in c++26" +# endif +# if __cpp_lib_span_at != 202311L +# error "__cpp_lib_span_at should have the value 202311L in c++26" +# endif + +# ifndef __cpp_lib_span_initializer_list +# error "__cpp_lib_span_initializer_list should be defined in c++26" +# endif +# if __cpp_lib_span_initializer_list != 202311L +# error "__cpp_lib_span_initializer_list should have the value 202311L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_spanstream +# error "__cpp_lib_spanstream should be defined in c++26" +# endif +# if __cpp_lib_spanstream != 202106L +# error "__cpp_lib_spanstream should have the value 202106L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_spanstream +# error "__cpp_lib_spanstream should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ssize +# error "__cpp_lib_ssize should be defined in c++26" +# endif +# if __cpp_lib_ssize != 201902L +# error "__cpp_lib_ssize should have the value 201902L in c++26" +# endif + +# ifndef __cpp_lib_sstream_from_string_view +# error "__cpp_lib_sstream_from_string_view should be defined in c++26" +# endif +# if __cpp_lib_sstream_from_string_view != 202306L +# error "__cpp_lib_sstream_from_string_view should have the value 202306L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_stacktrace +# error "__cpp_lib_stacktrace should be defined in c++26" +# endif +# if __cpp_lib_stacktrace != 202011L +# error "__cpp_lib_stacktrace should have the value 202011L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_stacktrace +# error "__cpp_lib_stacktrace should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_starts_ends_with +# error "__cpp_lib_starts_ends_with should be defined in c++26" +# endif +# if __cpp_lib_starts_ends_with != 201711L +# error "__cpp_lib_starts_ends_with should have the value 201711L in c++26" +# endif + +# ifndef __cpp_lib_stdatomic_h +# error "__cpp_lib_stdatomic_h should be defined in c++26" +# endif +# if __cpp_lib_stdatomic_h != 202011L +# error "__cpp_lib_stdatomic_h should have the value 202011L in c++26" +# endif + +# ifndef __cpp_lib_string_contains +# error "__cpp_lib_string_contains should be defined in c++26" +# endif +# if __cpp_lib_string_contains != 202011L +# error "__cpp_lib_string_contains should have the value 202011L in c++26" +# endif + +# ifndef __cpp_lib_string_resize_and_overwrite +# error "__cpp_lib_string_resize_and_overwrite should be defined in c++26" +# endif +# if __cpp_lib_string_resize_and_overwrite != 202110L +# error "__cpp_lib_string_resize_and_overwrite should have the value 202110L in c++26" +# endif + +# ifndef __cpp_lib_string_udls +# error "__cpp_lib_string_udls should be defined in c++26" +# endif +# if __cpp_lib_string_udls != 201304L +# error "__cpp_lib_string_udls should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_string_view +# error "__cpp_lib_string_view should be defined in c++26" +# endif +# if __cpp_lib_string_view != 202403L +# error "__cpp_lib_string_view should have the value 202403L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_submdspan +# error "__cpp_lib_submdspan should be defined in c++26" +# endif +# if __cpp_lib_submdspan != 202306L +# error "__cpp_lib_submdspan should have the value 202306L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_submdspan +# error "__cpp_lib_submdspan should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM +# ifndef __cpp_lib_syncbuf +# error "__cpp_lib_syncbuf should be defined in c++26" +# endif +# if __cpp_lib_syncbuf != 201803L +# error "__cpp_lib_syncbuf should have the value 201803L in c++26" +# endif +# else +# ifdef __cpp_lib_syncbuf +# error "__cpp_lib_syncbuf should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_text_encoding +# error "__cpp_lib_text_encoding should be defined in c++26" +# endif +# if __cpp_lib_text_encoding != 202306L +# error "__cpp_lib_text_encoding should have the value 202306L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_text_encoding +# error "__cpp_lib_text_encoding should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_three_way_comparison +# error "__cpp_lib_three_way_comparison should be defined in c++26" +# endif +# if __cpp_lib_three_way_comparison != 201907L +# error "__cpp_lib_three_way_comparison should have the value 201907L in c++26" +# endif + +# ifndef __cpp_lib_to_address +# error "__cpp_lib_to_address should be defined in c++26" +# endif +# if __cpp_lib_to_address != 201711L +# error "__cpp_lib_to_address should have the value 201711L in c++26" +# endif + +# ifndef __cpp_lib_to_array +# error "__cpp_lib_to_array should be defined in c++26" +# endif +# if __cpp_lib_to_array != 201907L +# error "__cpp_lib_to_array should have the value 201907L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should be defined in c++26" +# endif +# if __cpp_lib_to_chars != 202306L +# error "__cpp_lib_to_chars should have the value 202306L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_to_string +# error "__cpp_lib_to_string should be defined in c++26" +# endif +# if __cpp_lib_to_string != 202306L +# error "__cpp_lib_to_string should have the value 202306L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_to_string +# error "__cpp_lib_to_string should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_to_underlying +# error "__cpp_lib_to_underlying should be defined in c++26" +# endif +# if __cpp_lib_to_underlying != 202102L +# error "__cpp_lib_to_underlying should have the value 202102L in c++26" +# endif + +# ifndef __cpp_lib_transformation_trait_aliases +# error "__cpp_lib_transformation_trait_aliases should be defined in c++26" +# endif +# if __cpp_lib_transformation_trait_aliases != 201304L +# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_transparent_operators +# error "__cpp_lib_transparent_operators should be defined in c++26" +# endif +# if __cpp_lib_transparent_operators != 201510L +# error "__cpp_lib_transparent_operators should have the value 201510L in c++26" +# endif + +# ifndef __cpp_lib_tuple_element_t +# error "__cpp_lib_tuple_element_t should be defined in c++26" +# endif +# if __cpp_lib_tuple_element_t != 201402L +# error "__cpp_lib_tuple_element_t should have the value 201402L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_tuple_like +# error "__cpp_lib_tuple_like should be defined in c++26" +# endif +# if __cpp_lib_tuple_like != 202311L +# error "__cpp_lib_tuple_like should have the value 202311L in c++26" +# endif +# else // _LIBCPP_VERSION +# ifdef __cpp_lib_tuple_like +# error "__cpp_lib_tuple_like should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_tuples_by_type +# error "__cpp_lib_tuples_by_type should be defined in c++26" +# endif +# if __cpp_lib_tuples_by_type != 201304L +# error "__cpp_lib_tuples_by_type should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_type_identity +# error "__cpp_lib_type_identity should be defined in c++26" +# endif +# if __cpp_lib_type_identity != 201806L +# error "__cpp_lib_type_identity should have the value 201806L in c++26" +# endif + +# ifndef __cpp_lib_type_trait_variable_templates +# error "__cpp_lib_type_trait_variable_templates should be defined in c++26" +# endif +# if __cpp_lib_type_trait_variable_templates != 201510L +# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++26" +# endif + +# ifndef __cpp_lib_uncaught_exceptions +# error "__cpp_lib_uncaught_exceptions should be defined in c++26" +# endif +# if __cpp_lib_uncaught_exceptions != 201411L +# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++26" +# endif + +# ifndef __cpp_lib_unordered_map_try_emplace +# error "__cpp_lib_unordered_map_try_emplace should be defined in c++26" +# endif +# if __cpp_lib_unordered_map_try_emplace != 201411L +# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++26" +# endif + +# ifndef __cpp_lib_unreachable +# error "__cpp_lib_unreachable should be defined in c++26" +# endif +# if __cpp_lib_unreachable != 202202L +# error "__cpp_lib_unreachable should have the value 202202L in c++26" +# endif + +# ifndef __cpp_lib_unwrap_ref +# error "__cpp_lib_unwrap_ref should be defined in c++26" +# endif +# if __cpp_lib_unwrap_ref != 201811L +# error "__cpp_lib_unwrap_ref should have the value 201811L in c++26" +# endif + +# ifndef __cpp_lib_variant +# error "__cpp_lib_variant should be defined in c++26" +# endif +# if __cpp_lib_variant != 202306L +# error "__cpp_lib_variant should have the value 202306L in c++26" +# endif + +# ifndef __cpp_lib_void_t +# error "__cpp_lib_void_t should be defined in c++26" +# endif +# if __cpp_lib_void_t != 201411L +# error "__cpp_lib_void_t should have the value 201411L in c++26" +# endif #endif // TEST_STD_VER > 23 diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp new file mode 100644 index 0000000000000..8ad758a953426 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -0,0 +1,193 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::views::stride_view + +#include "test.h" +#include +#include +#include + +template +concept CanBePiped = requires(View&& view, T&& t) { + { std::forward(view) | std::forward(t) }; +}; + +constexpr bool test() { + int arr[] = {1, 2, 3}; + + // Simple use cases. + { + { + BidirRange view(arr, arr + 3); + std::ranges::stride_view strided(view, 1); + auto strided_iter = strided.begin(); + + assert(*strided_iter == arr[0]); + + std::ranges::advance(strided_iter, 2); + assert(*strided_iter == arr[2]); + } + { + BidirRange view(arr, arr + 3); + std::ranges::stride_view strided(view, 2); + auto strided_iter = strided.begin(); + + assert(*strided_iter == arr[0]); + + std::ranges::advance(strided_iter, 1); + assert(*strided_iter == arr[2]); + } + } + +#if 0 + // views::reverse(x) is equivalent to subrange{end, begin, size} if x is a + // sized subrange over reverse iterators + { + using It = bidirectional_iterator; + using Subrange = std::ranges::subrange; + + using ReverseIt = std::reverse_iterator; + using ReverseSubrange = std::ranges::subrange; + + { + BidirRange view(buf, buf + 3); + ReverseSubrange subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view)), /* size */3); + std::same_as auto result = std::views::reverse(subrange); + assert(base(result.begin()) == buf); + assert(base(result.end()) == buf + 3); + } + { + // std::move into views::reverse + BidirRange view(buf, buf + 3); + ReverseSubrange subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view)), /* size */3); + std::same_as auto result = std::views::reverse(std::move(subrange)); + assert(base(result.begin()) == buf); + assert(base(result.end()) == buf + 3); + } + { + // with a const subrange + BidirRange view(buf, buf + 3); + ReverseSubrange const subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view)), /* size */3); + std::same_as auto result = std::views::reverse(subrange); + assert(base(result.begin()) == buf); + assert(base(result.end()) == buf + 3); + } + } + + // views::reverse(x) is equivalent to subrange{end, begin} if x is an + // unsized subrange over reverse iterators + { + using It = bidirectional_iterator; + using Subrange = std::ranges::subrange; + + using ReverseIt = std::reverse_iterator; + using ReverseSubrange = std::ranges::subrange; + + { + BidirRange view(buf, buf + 3); + ReverseSubrange subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view))); + std::same_as auto result = std::views::reverse(subrange); + assert(base(result.begin()) == buf); + assert(base(result.end()) == buf + 3); + } + { + // std::move into views::reverse + BidirRange view(buf, buf + 3); + ReverseSubrange subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view))); + std::same_as auto result = std::views::reverse(std::move(subrange)); + assert(base(result.begin()) == buf); + assert(base(result.end()) == buf + 3); + } + { + // with a const subrange + BidirRange view(buf, buf + 3); + ReverseSubrange const subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view))); + std::same_as auto result = std::views::reverse(subrange); + assert(base(result.begin()) == buf); + assert(base(result.end()) == buf + 3); + } + } + + // Otherwise, views::reverse(x) is equivalent to ranges::reverse_view{x} + { + BidirRange view(buf, buf + 3); + std::same_as> auto result = std::views::reverse(view); + assert(base(result.begin().base()) == buf + 3); + assert(base(result.end().base()) == buf); + } + + // Test that std::views::reverse is a range adaptor + { + // Test `v | views::reverse` + { + BidirRange view(buf, buf + 3); + std::same_as> auto result = view | std::views::reverse; + assert(base(result.begin().base()) == buf + 3); + assert(base(result.end().base()) == buf); + } + + // Test `adaptor | views::reverse` + { + BidirRange view(buf, buf + 3); + auto f = [](int i) { return i; }; + auto const partial = std::views::transform(f) | std::views::reverse; + using Result = std::ranges::reverse_view>; + std::same_as auto result = partial(view); + assert(base(result.begin().base().base()) == buf + 3); + assert(base(result.end().base().base()) == buf); + } + + // Test `views::reverse | adaptor` + { + BidirRange view(buf, buf + 3); + auto f = [](int i) { return i; }; + auto const partial = std::views::reverse | std::views::transform(f); + using Result = std::ranges::transform_view, decltype(f)>; + std::same_as auto result = partial(view); + assert(base(result.begin().base().base()) == buf + 3); + assert(base(result.end().base().base()) == buf); + } + } +#endif // big block + + // From: + // Test that std::views::reverse is a range adaptor + // Check SFINAE friendliness + { + struct NotAViewableRange {}; + struct NotABidirRange {}; + // Not invocable because there is no parameter. + static_assert(!std::is_invocable_v); + // Not invocable because NotAViewableRange is, well, not a viewable range. + static_assert(!std::is_invocable_v); + // Is invocable because BidirRange is a viewable range. + static_assert(std::is_invocable_v); + + // Make sure that pipe operations work! + static_assert(CanBePiped{}))>); + static_assert(CanBePiped{}))>); + static_assert( + !CanBePiped{}))>); + } + // A final sanity check. + { static_assert(std::same_as); } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp new file mode 100644 index 0000000000000..badfd53245315 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::views::stride_view + +#include "test.h" +#include +#include + +template +concept can_call_base_on = requires(T t) { std::forward(t).base(); }; + +constexpr bool test() { + int buff[] = {1, 2, 3, 4, 5, 6, 7, 8}; + + // Check the const& overload + { + Range range(buff, buff + 8); + std::ranges::stride_view> const view(range, 3); + std::same_as> decltype(auto) result = view.base(); + assert(result.wasCopyInitialized); + assert(result.begin() == buff); + assert(result.end() == buff + 8); + } + + // Check the && overload + { + Range range(buff, buff + 8); + std::ranges::stride_view> view(range, 3); + std::same_as> decltype(auto) result = std::move(view).base(); + assert(result.wasMoveInitialized); + assert(result.begin() == buff); + assert(result.end() == buff + 8); + } + + // Check the && overload (again) + { + Range range(buff, buff + 8); + std::same_as> decltype(auto) result = std::ranges::stride_view>(range, 3).base(); + assert(result.wasMoveInitialized); + assert(result.begin() == buff); + assert(result.end() == buff + 8); + } + + // Ensure the const& overload is not considered when the base is not copy-constructible + { + static_assert(!can_call_base_on const&>); + static_assert(!can_call_base_on&>); + static_assert(can_call_base_on&&>); + static_assert(can_call_base_on>); + } + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp new file mode 100644 index 0000000000000..68556f32f875b --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::views::stride_view + +constexpr bool test() { return true; } + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp new file mode 100644 index 0000000000000..68556f32f875b --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::views::stride_view + +constexpr bool test() { return true; } + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.compile.pass.cpp new file mode 100644 index 0000000000000..646a9423f4523 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.compile.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::views::stride_view + +#include "test.h" +#include + +constexpr bool test() { + using std::ranges::enable_borrowed_range; + // Make sure that a stride_view over neither a borrowable nor an unborrowable view + // is itself borrowable. + static_assert(!enable_borrowed_range>>); + static_assert(!enable_borrowed_range>>); + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp new file mode 100644 index 0000000000000..68556f32f875b --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::views::stride_view + +constexpr bool test() { return true; } + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp new file mode 100644 index 0000000000000..cfc38b3292680 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::views::stride_view + +#include "../test.h" +#include +#include + +bool non_simple_view_iter_ctor_test() { + using StrideView = std::ranges::stride_view; + using StrideViewIterNonConst = std::ranges::iterator_t; + using StrideViewIterConst = std::ranges::iterator_t; + + StrideView sv{NotSimpleView{}, 1}; + StrideViewIterNonConst iter = {sv, sv.base().begin(), 0}; + StrideViewIterConst iterb = {iter}; + assert(iterb.__end_.moved_from_a == true); + return true; +} + +constexpr bool simpleview_iter_ctor_test() { + using StrideView = std::ranges::stride_view; + using StrideViewIter = std::ranges::iterator_t; + + StrideView sv{ForwardTracedMoveView{}, 1}; + StrideViewIter iter = {sv, sv.base().begin(), 0}; + // Guarantee that when the iterator is given to the constructor that + // it is moved there. + assert(iter.base().moved); + + return true; +} + +int main(int, char**) { + simpleview_iter_ctor_test(); + non_simple_view_iter_ctor_test(); + static_assert(simpleview_iter_ctor_test()); + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp new file mode 100644 index 0000000000000..7f2711adc5179 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::views::stride_view + +#include +#include + +#include "test_iterators.h" + +template +constexpr void testOne() { + using Range = std::ranges::subrange; + using StrideView = std::ranges::stride_view; + static_assert(std::ranges::common_range); + + { + // simple test + { + int buffer[] = {0, 1, 2, -1, 4, 5, 6}; + Range input(Iter{buffer}, Iter{buffer + 7}); + StrideView sv(input, 1); + StrideView sv_too(input, 2); + auto b = sv.begin(), e = sv.end(); + auto b_too = sv_too.begin(); + + assert(b == b); + assert(!(b != b)); + + assert(e == e); + assert(!(e != e)); + + assert(!(b == e)); + assert(b != e); + + std::advance(b, 8); + std::advance(b_too, 4); + + assert(b == b_too); + assert(!(b != b_too)); + + assert(b == b); + assert(!(b != b)); + + assert(e == e); + assert(!(e != e)); + + assert(b == e); + assert(!(b != e)); + } + + // Default-constructed iterators compare equal. + { + int buffer[] = {0, 1, 2, -1, 4, 5, 6}; + Range input(Iter{buffer}, Iter{buffer + 7}); + std::ranges::stride_view sv(input, 1); + using StrideViewIter = decltype(sv.begin()); + StrideViewIter i1, i2; + assert(i1 == i2); + assert(!(i1 != i2)); + } + } +} + +constexpr bool test() { + testOne>(); + //testOne>(); + //testOne>(); + //testOne>(); + testOne(); + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/sentinel/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/sentinel/ctor.default.pass.cpp new file mode 100644 index 0000000000000..68556f32f875b --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/sentinel/ctor.default.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::views::stride_view + +constexpr bool test() { return true; } + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/sentinel/equal.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/sentinel/equal.pass.cpp new file mode 100644 index 0000000000000..68556f32f875b --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/sentinel/equal.pass.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::views::stride_view + +constexpr bool test() { return true; } + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.pass.cpp new file mode 100644 index 0000000000000..981395f9e2c32 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::ranges::stride_view + +#include +#include + +bool runtime_test() { + auto iot = std::views::iota(1, 22); + auto str = std::views::stride(iot, 3); + auto result = str.size(); + assert(result == 7); + return true; +} + +constexpr bool test() { + { + constexpr auto iot = std::views::iota(1, 12); + constexpr auto str = std::views::stride(iot, 3); + assert(4 == str.size()); + static_assert(4 == str.size(), "Striding by 3 through a 12 member list has size 4."); + } + { + constexpr auto iot = std::views::iota(1, 22); + constexpr auto str = std::views::stride(iot, 3); + assert(7 == str.size()); + static_assert(7 == str.size(), "Striding by 3 through a 12 member list has size 4."); + } + return true; +} + +int main(int, char**) { + runtime_test(); + static_assert(test()); + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h new file mode 100644 index 0000000000000..4d13f05d48c01 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -0,0 +1,183 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H +#define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H + +#include "test_iterators.h" +#include +#include + +template +struct Range : std::ranges::view_base { + constexpr explicit Range(T* b, T* e) : begin_(b), end_(e) {} + constexpr Range(Range const& other) : begin_(other.begin_), end_(other.end_), wasCopyInitialized(true) {} + constexpr Range(Range&& other) : begin_(other.begin_), end_(other.end_), wasMoveInitialized(true) {} + Range& operator=(Range const&) = default; + Range& operator=(Range&&) = default; + constexpr T* begin() const { return begin_; } + constexpr T* end() const { return end_; } + + T* begin_; + T* end_; + bool wasCopyInitialized = false; + bool wasMoveInitialized = false; +}; + +template +Range(T, T) -> Range; + +template +struct BorrowedRange : public Range {}; + +template +inline constexpr bool std::ranges::enable_borrowed_range> = true; + +struct NoCopyRange : std::ranges::view_base { + explicit NoCopyRange(int*, int*); + NoCopyRange(NoCopyRange const&) = delete; + NoCopyRange(NoCopyRange&&) = default; + NoCopyRange& operator=(NoCopyRange const&) = default; + NoCopyRange& operator=(NoCopyRange&&) = default; + int* begin() const; + int* end() const; +}; + +template +struct ForwardIterBase { + using iterator_concept = std::forward_iterator_tag; + using value_type = int; + using difference_type = std::intptr_t; + + constexpr int operator*() const { return 5; } + + constexpr Derived& operator++() { return static_cast(*this); } + constexpr Derived operator++(int) { return {}; } + + friend constexpr bool operator==(const ForwardIterBase&, const ForwardIterBase&) { return true; } +}; + +template +struct InputIterBase { + using iterator_concept = std::input_iterator_tag; + using value_type = int; + using difference_type = std::intptr_t; + + constexpr int operator*() const { return 5; } + + constexpr Derived& operator++() { return static_cast(*this); } + constexpr Derived operator++(int) { return {}; } + + friend constexpr bool operator==(const InputIterBase&, const InputIterBase&) { return true; } +}; + +struct NotSimpleViewIterB : ForwardIterBase { + bool moved = false; + + constexpr NotSimpleViewIterB() = default; + constexpr NotSimpleViewIterB(const NotSimpleViewIterB&) = default; + constexpr NotSimpleViewIterB(NotSimpleViewIterB&&) : moved{true} {} + constexpr NotSimpleViewIterB& operator=(NotSimpleViewIterB&&) = default; + constexpr NotSimpleViewIterB& operator=(const NotSimpleViewIterB&) = default; +}; + +struct NotSimpleViewIterA : ForwardIterBase { + bool moved = false; + bool moved_from_a = false; + bool copied_from_a = false; + + constexpr NotSimpleViewIterA() = default; + constexpr NotSimpleViewIterA(const NotSimpleViewIterA&) = default; + constexpr NotSimpleViewIterA(const NotSimpleViewIterB&) : copied_from_a{true} {} + constexpr NotSimpleViewIterA(NotSimpleViewIterA&&) : moved{true} {} + constexpr NotSimpleViewIterA(NotSimpleViewIterB&&) : moved_from_a{true} {} + constexpr NotSimpleViewIterA& operator=(NotSimpleViewIterA&&) = default; + constexpr NotSimpleViewIterA& operator=(const NotSimpleViewIterA&) = default; +}; + +struct NotSimpleView : std::ranges::view_base { + constexpr NotSimpleViewIterA begin() const { return {}; } + constexpr NotSimpleViewIterB begin() { return {}; } + constexpr NotSimpleViewIterA end() const { return {}; } + constexpr NotSimpleViewIterB end() { return {}; } + + int* begin_; + int* end_; + bool wasCopyInitialized = false; + bool wasMoveInitialized = false; +}; + +struct ForwardTracedMoveIter : ForwardIterBase { + bool moved = false; + + constexpr ForwardTracedMoveIter() = default; + constexpr ForwardTracedMoveIter(const ForwardTracedMoveIter&) = default; + constexpr ForwardTracedMoveIter(ForwardTracedMoveIter&&) : moved{true} {} + constexpr ForwardTracedMoveIter& operator=(ForwardTracedMoveIter&&) = default; + constexpr ForwardTracedMoveIter& operator=(const ForwardTracedMoveIter&) = default; +}; + +struct ForwardTracedMoveView : std::ranges::view_base { + constexpr ForwardTracedMoveIter begin() const { return {}; } + constexpr ForwardTracedMoveIter end() const { return {}; } +}; + +struct BidirRange : std::ranges::view_base { + int* begin_; + int* end_; + + constexpr BidirRange(int* b, int* e) : begin_(b), end_(e) {} + + constexpr bidirectional_iterator begin() { return bidirectional_iterator{begin_}; } + constexpr bidirectional_iterator begin() const { return bidirectional_iterator{begin_}; } + constexpr bidirectional_iterator end() { return bidirectional_iterator{end_}; } + constexpr bidirectional_iterator end() const { return bidirectional_iterator{end_}; } +}; +static_assert(std::ranges::bidirectional_range); +static_assert(std::ranges::common_range); +static_assert(std::ranges::view); +static_assert(std::copyable); + +enum CopyCategory { MoveOnly, Copyable }; +template +struct BidirSentRange : std::ranges::view_base { + using sent_t = sentinel_wrapper>; + using sent_const_t = sentinel_wrapper>; + + int* begin_; + int* end_; + + constexpr BidirSentRange(int* b, int* e) : begin_(b), end_(e) {} + constexpr BidirSentRange(const BidirSentRange&) + requires(CC == Copyable) + = default; + constexpr BidirSentRange(BidirSentRange&&) + requires(CC == MoveOnly) + = default; + constexpr BidirSentRange& operator=(const BidirSentRange&) + requires(CC == Copyable) + = default; + constexpr BidirSentRange& operator=(BidirSentRange&&) + requires(CC == MoveOnly) + = default; + + constexpr bidirectional_iterator begin() { return bidirectional_iterator{begin_}; } + constexpr bidirectional_iterator begin() const { return bidirectional_iterator{begin_}; } + constexpr sent_t end() { return sent_t{bidirectional_iterator{end_}}; } + constexpr sent_const_t end() const { return sent_const_t{bidirectional_iterator{end_}}; } +}; +static_assert(std::ranges::bidirectional_range>); +static_assert(!std::ranges::common_range>); +static_assert(std::ranges::view>); +static_assert(!std::copyable>); +static_assert(std::ranges::bidirectional_range>); +static_assert(!std::ranges::common_range>); +static_assert(std::ranges::view>); +static_assert(std::copyable>); + +#endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py index 2d5b66d994da0..aba8eebfabb54 100644 --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -1144,6 +1144,11 @@ def add_version_header(tc): "values": {"c++23": 202106}, "headers": ["algorithm"], }, + { + "name": "__cpp_lib_ranges_stride", + "values": {"c++23": 202207}, + "headers": ["ranges"], + }, { "name": "__cpp_lib_ranges_to_container", "values": {"c++23": 202202}, From dcf3bea83fdb430d055c34441a5f2da486e290b6 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 4 Sep 2023 10:20:04 -0400 Subject: [PATCH 002/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add CTAD testing and refactor test classes. --- .../range.stride.view/ctad.compile.pass.cpp | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp index 68556f32f875b..7831d792d64e7 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp @@ -12,7 +12,37 @@ // std::views::stride_view -constexpr bool test() { return true; } +#include +#include +#include +#include "test.h" + +constexpr bool test() { + int arr[]{1, 2, 3}; + + InstrumentedBasicView bv{arr, arr + 3}; + InstrumentedBasicRange br{}; + + static_assert(std::same_as< + decltype(std::ranges::stride_view(bv, 2)), + std::ranges::stride_view + >); + static_assert(std::same_as< + decltype(std::ranges::stride_view(std::move(bv), 2)), + std::ranges::stride_view + >); + + static_assert(std::same_as< + decltype(std::ranges::drop_view(br, 0)), + std::ranges::drop_view>> + >); + + static_assert(std::same_as< + decltype(std::ranges::drop_view(std::move(br), 0)), + std::ranges::drop_view>> + >); + return true; +} int main(int, char**) { test(); @@ -20,3 +50,4 @@ int main(int, char**) { return 0; } + From c4422785a6405c04edb0b48c18ad1cace51ee1ad Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 4 Sep 2023 10:23:04 -0400 Subject: [PATCH 003/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Refactor test classes. (previous fixup message was incorrect) --- .../range.stride.view/adaptor.pass.cpp | 18 ++-- .../range.stride.view/base.pass.cpp | 24 +++--- .../enable_borrowed_range.compile.pass.cpp | 4 +- .../iterator/ctor.default.pass.cpp | 4 +- .../range.adaptors/range.stride.view/test.h | 82 ++++++++++--------- 5 files changed, 70 insertions(+), 62 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index 8ad758a953426..0de98ba259517 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -28,8 +28,8 @@ constexpr bool test() { // Simple use cases. { { - BidirRange view(arr, arr + 3); - std::ranges::stride_view strided(view, 1); + BidirView view(arr, arr + 3); + std::ranges::stride_view strided(view, 1); auto strided_iter = strided.begin(); assert(*strided_iter == arr[0]); @@ -38,8 +38,8 @@ constexpr bool test() { assert(*strided_iter == arr[2]); } { - BidirRange view(arr, arr + 3); - std::ranges::stride_view strided(view, 2); + BidirView view(arr, arr + 3); + std::ranges::stride_view strided(view, 2); auto strided_iter = strided.begin(); assert(*strided_iter == arr[0]); @@ -170,14 +170,14 @@ constexpr bool test() { static_assert(!std::is_invocable_v); // Not invocable because NotAViewableRange is, well, not a viewable range. static_assert(!std::is_invocable_v); - // Is invocable because BidirRange is a viewable range. - static_assert(std::is_invocable_v); + // Is invocable because BidirView is a viewable range. + static_assert(std::is_invocable_v); // Make sure that pipe operations work! - static_assert(CanBePiped{}))>); - static_assert(CanBePiped{}))>); + static_assert(CanBePiped{}))>); + static_assert(CanBePiped{}))>); static_assert( - !CanBePiped{}))>); + !CanBePiped{}))>); } // A final sanity check. { static_assert(std::same_as); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp index badfd53245315..6b22b7e89c015 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp @@ -24,9 +24,9 @@ constexpr bool test() { // Check the const& overload { - Range range(buff, buff + 8); - std::ranges::stride_view> const view(range, 3); - std::same_as> decltype(auto) result = view.base(); + InstrumentedBasicView range(buff, buff + 8); + std::ranges::stride_view> const view(range, 3); + std::same_as> decltype(auto) result = view.base(); assert(result.wasCopyInitialized); assert(result.begin() == buff); assert(result.end() == buff + 8); @@ -34,9 +34,9 @@ constexpr bool test() { // Check the && overload { - Range range(buff, buff + 8); - std::ranges::stride_view> view(range, 3); - std::same_as> decltype(auto) result = std::move(view).base(); + InstrumentedBasicView range(buff, buff + 8); + std::ranges::stride_view> view(range, 3); + std::same_as> decltype(auto) result = std::move(view).base(); assert(result.wasMoveInitialized); assert(result.begin() == buff); assert(result.end() == buff + 8); @@ -44,8 +44,8 @@ constexpr bool test() { // Check the && overload (again) { - Range range(buff, buff + 8); - std::same_as> decltype(auto) result = std::ranges::stride_view>(range, 3).base(); + InstrumentedBasicView range(buff, buff + 8); + std::same_as> decltype(auto) result = std::ranges::stride_view>(range, 3).base(); assert(result.wasMoveInitialized); assert(result.begin() == buff); assert(result.end() == buff + 8); @@ -53,10 +53,10 @@ constexpr bool test() { // Ensure the const& overload is not considered when the base is not copy-constructible { - static_assert(!can_call_base_on const&>); - static_assert(!can_call_base_on&>); - static_assert(can_call_base_on&&>); - static_assert(can_call_base_on>); + static_assert(!can_call_base_on const&>); + static_assert(!can_call_base_on&>); + static_assert(can_call_base_on&&>); + static_assert(can_call_base_on>); } return true; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.compile.pass.cpp index 646a9423f4523..7c28842fe65f6 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.compile.pass.cpp @@ -19,8 +19,8 @@ constexpr bool test() { using std::ranges::enable_borrowed_range; // Make sure that a stride_view over neither a borrowable nor an unborrowable view // is itself borrowable. - static_assert(!enable_borrowed_range>>); - static_assert(!enable_borrowed_range>>); + static_assert(!enable_borrowed_range>>); + static_assert(!enable_borrowed_range>>); return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp index cfc38b3292680..d0f466d3adeae 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp @@ -17,11 +17,11 @@ #include bool non_simple_view_iter_ctor_test() { - using StrideView = std::ranges::stride_view; + using StrideView = std::ranges::stride_view; using StrideViewIterNonConst = std::ranges::iterator_t; using StrideViewIterConst = std::ranges::iterator_t; - StrideView sv{NotSimpleView{}, 1}; + StrideView sv{InstrumentedNotSimpleView{}, 1}; StrideViewIterNonConst iter = {sv, sv.base().begin(), 0}; StrideViewIterConst iterb = {iter}; assert(iterb.__end_.moved_from_a == true); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index 4d13f05d48c01..d9931cb6e6320 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -14,12 +14,18 @@ #include template -struct Range : std::ranges::view_base { - constexpr explicit Range(T* b, T* e) : begin_(b), end_(e) {} - constexpr Range(Range const& other) : begin_(other.begin_), end_(other.end_), wasCopyInitialized(true) {} - constexpr Range(Range&& other) : begin_(other.begin_), end_(other.end_), wasMoveInitialized(true) {} - Range& operator=(Range const&) = default; - Range& operator=(Range&&) = default; +struct InstrumentedBasicRange { + T *begin() const; + T *end() const; +}; + +template +struct InstrumentedBasicView : std::ranges::view_base { + constexpr explicit InstrumentedBasicView(T* b, T* e) : begin_(b), end_(e) {} + constexpr InstrumentedBasicView(InstrumentedBasicView const& other) : begin_(other.begin_), end_(other.end_), wasCopyInitialized(true) {} + constexpr InstrumentedBasicView(InstrumentedBasicView&& other) : begin_(other.begin_), end_(other.end_), wasMoveInitialized(true) {} + InstrumentedBasicView& operator=(InstrumentedBasicView const&) = default; + InstrumentedBasicView& operator=(InstrumentedBasicView&&) = default; constexpr T* begin() const { return begin_; } constexpr T* end() const { return end_; } @@ -30,20 +36,20 @@ struct Range : std::ranges::view_base { }; template -Range(T, T) -> Range; +InstrumentedBasicView(T, T) -> InstrumentedBasicView; template -struct BorrowedRange : public Range {}; +struct InstrumentedBorrowedRange : public InstrumentedBasicView {}; template -inline constexpr bool std::ranges::enable_borrowed_range> = true; - -struct NoCopyRange : std::ranges::view_base { - explicit NoCopyRange(int*, int*); - NoCopyRange(NoCopyRange const&) = delete; - NoCopyRange(NoCopyRange&&) = default; - NoCopyRange& operator=(NoCopyRange const&) = default; - NoCopyRange& operator=(NoCopyRange&&) = default; +inline constexpr bool std::ranges::enable_borrowed_range> = true; + +struct NoCopyView : std::ranges::view_base { + explicit NoCopyView(int*, int*); + NoCopyView(NoCopyView const&) = delete; + NoCopyView(NoCopyView&&) = default; + NoCopyView& operator=(NoCopyView const&) = default; + NoCopyView& operator=(NoCopyView&&) = default; int* begin() const; int* end() const; }; @@ -100,7 +106,7 @@ struct NotSimpleViewIterA : ForwardIterBase { constexpr NotSimpleViewIterA& operator=(const NotSimpleViewIterA&) = default; }; -struct NotSimpleView : std::ranges::view_base { +struct InstrumentedNotSimpleView : std::ranges::view_base { constexpr NotSimpleViewIterA begin() const { return {}; } constexpr NotSimpleViewIterB begin() { return {}; } constexpr NotSimpleViewIterA end() const { return {}; } @@ -127,42 +133,42 @@ struct ForwardTracedMoveView : std::ranges::view_base { constexpr ForwardTracedMoveIter end() const { return {}; } }; -struct BidirRange : std::ranges::view_base { +struct BidirView : std::ranges::view_base { int* begin_; int* end_; - constexpr BidirRange(int* b, int* e) : begin_(b), end_(e) {} + constexpr BidirView(int* b, int* e) : begin_(b), end_(e) {} constexpr bidirectional_iterator begin() { return bidirectional_iterator{begin_}; } constexpr bidirectional_iterator begin() const { return bidirectional_iterator{begin_}; } constexpr bidirectional_iterator end() { return bidirectional_iterator{end_}; } constexpr bidirectional_iterator end() const { return bidirectional_iterator{end_}; } }; -static_assert(std::ranges::bidirectional_range); -static_assert(std::ranges::common_range); -static_assert(std::ranges::view); -static_assert(std::copyable); +static_assert(std::ranges::view); +static_assert(std::copyable); + +/* enum CopyCategory { MoveOnly, Copyable }; template -struct BidirSentRange : std::ranges::view_base { +struct BidirSentView : std::ranges::view_base { using sent_t = sentinel_wrapper>; using sent_const_t = sentinel_wrapper>; int* begin_; int* end_; - constexpr BidirSentRange(int* b, int* e) : begin_(b), end_(e) {} - constexpr BidirSentRange(const BidirSentRange&) + constexpr BidirSentView(int* b, int* e) : begin_(b), end_(e) {} + constexpr BidirSentView(const BidirSentView&) requires(CC == Copyable) = default; - constexpr BidirSentRange(BidirSentRange&&) + constexpr BidirSentView(BidirSentView&&) requires(CC == MoveOnly) = default; - constexpr BidirSentRange& operator=(const BidirSentRange&) + constexpr BidirSentView& operator=(const BidirSentView&) requires(CC == Copyable) = default; - constexpr BidirSentRange& operator=(BidirSentRange&&) + constexpr BidirSentView& operator=(BidirSentView&&) requires(CC == MoveOnly) = default; @@ -171,13 +177,15 @@ struct BidirSentRange : std::ranges::view_base { constexpr sent_t end() { return sent_t{bidirectional_iterator{end_}}; } constexpr sent_const_t end() const { return sent_const_t{bidirectional_iterator{end_}}; } }; -static_assert(std::ranges::bidirectional_range>); -static_assert(!std::ranges::common_range>); -static_assert(std::ranges::view>); -static_assert(!std::copyable>); -static_assert(std::ranges::bidirectional_range>); -static_assert(!std::ranges::common_range>); -static_assert(std::ranges::view>); -static_assert(std::copyable>); +// TODO: Clean up. +static_assert(std::ranges::bidirectional_range>); +static_assert(!std::ranges::common_range>); +static_assert(std::ranges::view>); +static_assert(!std::copyable>); +static_assert(std::ranges::bidirectional_range>); +static_assert(!std::ranges::common_range>); +static_assert(std::ranges::view>); +static_assert(std::copyable>); +*/ #endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H From 6595e6a3a860656582f4c7c110c8492a0138db77 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 8 Sep 2023 23:26:02 -0400 Subject: [PATCH 004/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Cleanup adaptor tests and fix typo in category definition. --- .../range.stride.view/adaptor.pass.cpp | 186 ++++++------------ .../range.adaptors/range.stride.view/test.h | 56 +++++- 2 files changed, 111 insertions(+), 131 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index 0de98ba259517..ba0efe36b9824 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -12,7 +12,9 @@ // std::views::stride_view +#include "__ranges/stride_view.h" #include "test.h" +#include #include #include #include @@ -23,149 +25,84 @@ concept CanBePiped = requires(View&& view, T&& t) { }; constexpr bool test() { - int arr[] = {1, 2, 3}; + constexpr int array_n = 3; + int arr[array_n] = {1, 2, 3}; - // Simple use cases. + // Test that `std::views::stride` is a range adaptor. { + // Check various forms of + // view | stride { - BidirView view(arr, arr + 3); - std::ranges::stride_view strided(view, 1); - auto strided_iter = strided.begin(); - - assert(*strided_iter == arr[0]); - - std::ranges::advance(strided_iter, 2); - assert(*strided_iter == arr[2]); - } - { - BidirView view(arr, arr + 3); - std::ranges::stride_view strided(view, 2); - auto strided_iter = strided.begin(); - - assert(*strided_iter == arr[0]); - - std::ranges::advance(strided_iter, 1); - assert(*strided_iter == arr[2]); + { + BidirView view(arr, arr + array_n); + //std::ranges::stride_view strided(view, 1); + std::same_as> decltype(auto) strided = view | std::views::stride(1); + auto strided_iter = strided.begin(); + + // Check that the begin() iter views arr[0] + assert(*strided_iter == arr[0]); + + // Check that the strided_iter, after advancing it 2 * 1 steps, views arr[2]. + std::ranges::advance(strided_iter, 2); + assert(*strided_iter == arr[2]); + } + { + BidirView view(arr, arr + array_n); + std::same_as> decltype(auto) strided = view | std::views::stride(2); + auto strided_iter = strided.begin(); + + assert(*strided_iter == arr[0]); + + // Same test as above, just advance one time with a bigger step (1 * 2 steps). + std::ranges::advance(strided_iter, 1); + assert(*strided_iter == arr[2]); + } } } -#if 0 - // views::reverse(x) is equivalent to subrange{end, begin, size} if x is a - // sized subrange over reverse iterators + // Check various forms of + // adaptor | stride { - using It = bidirectional_iterator; - using Subrange = std::ranges::subrange; - - using ReverseIt = std::reverse_iterator; - using ReverseSubrange = std::ranges::subrange; - + // Parallels the two tests from above. + constexpr auto identity_lambda = [](int i) { return i * 2; }; { - BidirRange view(buf, buf + 3); - ReverseSubrange subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view)), /* size */3); - std::same_as auto result = std::views::reverse(subrange); - assert(base(result.begin()) == buf); - assert(base(result.end()) == buf + 3); + BidirView view(arr, arr + array_n); + const auto transform_stride_partial = std::views::transform(identity_lambda) | std::views::stride(1); + + const auto transform_stride_applied = transform_stride_partial(view); + auto transform_stride_applied_iter = transform_stride_applied.begin(); + assert(*transform_stride_applied_iter == std::invoke(identity_lambda, arr[0])); + std::ranges::advance(transform_stride_applied_iter, 2); + assert(*transform_stride_applied_iter == std::invoke(identity_lambda, arr[2])); } - { - // std::move into views::reverse - BidirRange view(buf, buf + 3); - ReverseSubrange subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view)), /* size */3); - std::same_as auto result = std::views::reverse(std::move(subrange)); - assert(base(result.begin()) == buf); - assert(base(result.end()) == buf + 3); - } - { - // with a const subrange - BidirRange view(buf, buf + 3); - ReverseSubrange const subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view)), /* size */3); - std::same_as auto result = std::views::reverse(subrange); - assert(base(result.begin()) == buf); - assert(base(result.end()) == buf + 3); - } - } - - // views::reverse(x) is equivalent to subrange{end, begin} if x is an - // unsized subrange over reverse iterators - { - using It = bidirectional_iterator; - using Subrange = std::ranges::subrange; - - using ReverseIt = std::reverse_iterator; - using ReverseSubrange = std::ranges::subrange; { - BidirRange view(buf, buf + 3); - ReverseSubrange subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view))); - std::same_as auto result = std::views::reverse(subrange); - assert(base(result.begin()) == buf); - assert(base(result.end()) == buf + 3); - } - { - // std::move into views::reverse - BidirRange view(buf, buf + 3); - ReverseSubrange subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view))); - std::same_as auto result = std::views::reverse(std::move(subrange)); - assert(base(result.begin()) == buf); - assert(base(result.end()) == buf + 3); - } - { - // with a const subrange - BidirRange view(buf, buf + 3); - ReverseSubrange const subrange(ReverseIt(std::ranges::end(view)), ReverseIt(std::ranges::begin(view))); - std::same_as auto result = std::views::reverse(subrange); - assert(base(result.begin()) == buf); - assert(base(result.end()) == buf + 3); + BidirView view(arr, arr + array_n); + const auto transform_stride_partial = std::views::transform(identity_lambda) | std::views::stride(2); + + const auto transform_stride_applied = transform_stride_partial(view); + auto transform_stride_applied_iter = transform_stride_applied.begin(); + assert(*transform_stride_applied_iter == std::invoke(identity_lambda, arr[0])); + std::ranges::advance(transform_stride_applied_iter, 1); + assert(*transform_stride_applied_iter == std::invoke(identity_lambda, arr[2])); } } - // Otherwise, views::reverse(x) is equivalent to ranges::reverse_view{x} { - BidirRange view(buf, buf + 3); - std::same_as> auto result = std::views::reverse(view); - assert(base(result.begin().base()) == buf + 3); - assert(base(result.end().base()) == buf); - } - - // Test that std::views::reverse is a range adaptor - { - // Test `v | views::reverse` - { - BidirRange view(buf, buf + 3); - std::same_as> auto result = view | std::views::reverse; - assert(base(result.begin().base()) == buf + 3); - assert(base(result.end().base()) == buf); - } - - // Test `adaptor | views::reverse` - { - BidirRange view(buf, buf + 3); - auto f = [](int i) { return i; }; - auto const partial = std::views::transform(f) | std::views::reverse; - using Result = std::ranges::reverse_view>; - std::same_as auto result = partial(view); - assert(base(result.begin().base().base()) == buf + 3); - assert(base(result.end().base().base()) == buf); - } - - // Test `views::reverse | adaptor` - { - BidirRange view(buf, buf + 3); - auto f = [](int i) { return i; }; - auto const partial = std::views::reverse | std::views::transform(f); - using Result = std::ranges::transform_view, decltype(f)>; - std::same_as auto result = partial(view); - assert(base(result.begin().base().base()) == buf + 3); - assert(base(result.end().base().base()) == buf); - } + using ForwardStrideView = std::ranges::stride_view; + using BidirStrideView = std::ranges::stride_view; + using RandomAccessStrideView = std::ranges::stride_view; + + static_assert(std::ranges::forward_range); + static_assert(std::ranges::bidirectional_range); + static_assert(std::ranges::random_access_range); + // TODO: check sized_range } -#endif // big block - // From: - // Test that std::views::reverse is a range adaptor // Check SFINAE friendliness { struct NotAViewableRange {}; - struct NotABidirRange {}; + struct NotARange {}; // Not invocable because there is no parameter. static_assert(!std::is_invocable_v); // Not invocable because NotAViewableRange is, well, not a viewable range. @@ -176,8 +113,7 @@ constexpr bool test() { // Make sure that pipe operations work! static_assert(CanBePiped{}))>); static_assert(CanBePiped{}))>); - static_assert( - !CanBePiped{}))>); + static_assert(!CanBePiped{}))>); } // A final sanity check. { static_assert(std::same_as); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index d9931cb6e6320..d06ef2c3b923c 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -15,15 +15,17 @@ template struct InstrumentedBasicRange { - T *begin() const; - T *end() const; + T* begin() const; + T* end() const; }; template struct InstrumentedBasicView : std::ranges::view_base { constexpr explicit InstrumentedBasicView(T* b, T* e) : begin_(b), end_(e) {} - constexpr InstrumentedBasicView(InstrumentedBasicView const& other) : begin_(other.begin_), end_(other.end_), wasCopyInitialized(true) {} - constexpr InstrumentedBasicView(InstrumentedBasicView&& other) : begin_(other.begin_), end_(other.end_), wasMoveInitialized(true) {} + constexpr InstrumentedBasicView(InstrumentedBasicView const& other) + : begin_(other.begin_), end_(other.end_), wasCopyInitialized(true) {} + constexpr InstrumentedBasicView(InstrumentedBasicView&& other) + : begin_(other.begin_), end_(other.end_), wasMoveInitialized(true) {} InstrumentedBasicView& operator=(InstrumentedBasicView const&) = default; InstrumentedBasicView& operator=(InstrumentedBasicView&&) = default; constexpr T* begin() const { return begin_; } @@ -141,13 +143,55 @@ struct BidirView : std::ranges::view_base { constexpr bidirectional_iterator begin() { return bidirectional_iterator{begin_}; } constexpr bidirectional_iterator begin() const { return bidirectional_iterator{begin_}; } - constexpr bidirectional_iterator end() { return bidirectional_iterator{end_}; } - constexpr bidirectional_iterator end() const { return bidirectional_iterator{end_}; } + constexpr sentinel_wrapper> end() { + return sentinel_wrapper>{bidirectional_iterator{end_}}; + } + constexpr sentinel_wrapper> end() const { + return sentinel_wrapper>{bidirectional_iterator{end_}}; + } }; static_assert(std::ranges::view); static_assert(std::copyable); +struct ForwardView : public std::ranges::view_base { + int* begin_; + int* end_; + + constexpr ForwardView(int* b, int* e) : begin_(b), end_(e) {} + + constexpr forward_iterator begin() { return forward_iterator{begin_}; } + constexpr forward_iterator begin() const { return forward_iterator{begin_}; } + constexpr sentinel_wrapper> end() { + return sentinel_wrapper>{forward_iterator{end_}}; + } + constexpr sentinel_wrapper> end() const { + return sentinel_wrapper>{forward_iterator{end_}}; + } +}; + +static_assert(std::ranges::view); +static_assert(std::copyable); + +struct RandomAccessView : std::ranges::view_base { + int* begin_; + int* end_; + + constexpr RandomAccessView(int* b, int* e) : begin_(b), end_(e) {} + + constexpr random_access_iterator begin() { return random_access_iterator{begin_}; } + //constexpr random_access_iterator begin() const { return random_access_iterator{begin_}; } + constexpr sentinel_wrapper> end() { + return sentinel_wrapper>{random_access_iterator{end_}}; + } + //constexpr sentinel_wrapper> end() const { return sentinel_wrapper>{random_access_iterator{end_}}; } + constexpr std::size_t size() const { return end_ - begin_; } +}; + +static_assert(std::ranges::view); +static_assert(std::ranges::random_access_range); +static_assert(std::copyable); + /* enum CopyCategory { MoveOnly, Copyable }; template From 2ac51b81331765b608a3b483cf26fa61dcb8fefc Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sun, 10 Sep 2023 14:01:14 -0400 Subject: [PATCH 005/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix typo in begin for random_access_range. --- libcxx/include/__ranges/stride_view.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 880c8ce2950e4..f85247c825d81 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -257,7 +257,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> return *this += -__s; } - _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator[](difference_type __s) const + _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __s) const requires random_access_range<_Base> { return *(*this + __s); From 3465f88df025d28b5feead29c835132b99063356 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 11 Sep 2023 10:03:21 -0400 Subject: [PATCH 006/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add test for no default ctor. --- .../range.stride.view/ctor.default.pass.cpp | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.default.pass.cpp diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.default.pass.cpp new file mode 100644 index 0000000000000..09cb8c20ea318 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.default.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::views::stride_view + +#include "test.h" +#include + +constexpr bool test() { + // There is no default ctor for stride_view. + static_assert(!std::is_default_constructible_v>); + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} From 80bd67ab800d4ebe695029d6d4a9e6598f97791c Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 11 Sep 2023 17:47:05 -0400 Subject: [PATCH 007/179] amend! WIP: [libc++][ranges] Implement `ranges::stride_view`. [libc++][ranges] Implement `ranges::stride_view`. Signed-off-by: Will Hawkins From 62a3a61d49c55cc083c9ecb778fbdaac0d17c55e Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 13 Sep 2023 09:29:41 -0400 Subject: [PATCH 008/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Address comments from @EricWF. --- libcxx/include/__ranges/stride_view.h | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index f85247c825d81..ff3b36073efa1 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -148,6 +148,18 @@ class stride_view : public view_interface> { } }; // class stride_view +template +struct __stride_view_iterator_concept { using type = input_iterator_tag; }; + +template +struct __stride_view_iterator_concept<_View> { using type = random_access_iterator_tag; }; + +template +struct __stride_view_iterator_concept<_View> { using type = bidirectional_iterator_tag; }; + +template +struct __stride_view_iterator_concept<_View> { using type = forward_iterator_tag; }; + template struct __stride_iterator_category {}; @@ -170,14 +182,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> public: using difference_type = range_difference_t<_Base>; using value_type = range_value_t<_Base>; - using iterator_concept = - _If, - random_access_iterator_tag, - _If, - bidirectional_iterator_tag, - _If, - forward_iterator_tag, - /* else */ input_iterator_tag >>>; + using iterator_concept = typename __stride_view_iterator_concept<_View>::type; _LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_Base> __current_ = iterator_t<_Base>(); _LIBCPP_NO_UNIQUE_ADDRESS ranges::sentinel_t<_Base> __end_ = ranges::sentinel_t<_Base>(); @@ -392,7 +397,6 @@ stride_view(_Range&&) -> stride_view>; namespace views { namespace __stride { -// removed this. struct __fn { template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) const From 89c88fc1cbdfb86c2e8dd303967742082d55affa Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 13 Sep 2023 09:47:11 -0400 Subject: [PATCH 009/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Forgot to run clang-format before commiting. --- libcxx/include/__ranges/stride_view.h | 28 +++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index ff3b36073efa1..fc1fb89b3ba0e 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -148,17 +148,25 @@ class stride_view : public view_interface> { } }; // class stride_view -template -struct __stride_view_iterator_concept { using type = input_iterator_tag; }; +template +struct __stride_view_iterator_concept { + using type = input_iterator_tag; +}; -template -struct __stride_view_iterator_concept<_View> { using type = random_access_iterator_tag; }; +template +struct __stride_view_iterator_concept<_View> { + using type = random_access_iterator_tag; +}; -template -struct __stride_view_iterator_concept<_View> { using type = bidirectional_iterator_tag; }; +template +struct __stride_view_iterator_concept<_View> { + using type = bidirectional_iterator_tag; +}; -template -struct __stride_view_iterator_concept<_View> { using type = forward_iterator_tag; }; +template +struct __stride_view_iterator_concept<_View> { + using type = forward_iterator_tag; +}; template struct __stride_iterator_category {}; @@ -180,8 +188,8 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> using _Base = __maybe_const<_Const, _View>; public: - using difference_type = range_difference_t<_Base>; - using value_type = range_value_t<_Base>; + using difference_type = range_difference_t<_Base>; + using value_type = range_value_t<_Base>; using iterator_concept = typename __stride_view_iterator_concept<_View>::type; _LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_Base> __current_ = iterator_t<_Base>(); From 2c6a336b0d51793f797fe2fa87d88e2f49b32c01 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 15 Sep 2023 09:54:24 -0400 Subject: [PATCH 010/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Respond to JMazurkiewicz's helpful comments. --- libcxx/include/__ranges/stride_view.h | 34 ++++--------------- libcxx/modules/std/ranges.inc | 10 ++++++ .../range.stride.view/stride.pass.cpp | 32 +++++++++++++++++ 3 files changed, 48 insertions(+), 28 deletions(-) create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index fc1fb89b3ba0e..9bf30e6c2815b 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -25,7 +25,6 @@ #include <__iterator/iter_swap.h> #include <__iterator/iterator_traits.h> #include <__iterator/next.h> -#include <__iterator/reverse_iterator.h> #include <__ranges/access.h> #include <__ranges/all.h> #include <__ranges/concepts.h> @@ -69,8 +68,6 @@ class stride_view : public view_interface> { template class __iterator; - template - class __sentinel; public: _LIBCPP_HIDE_FROM_ABI constexpr explicit stride_view(_View __base, range_difference_t<_View> __stride) @@ -84,16 +81,16 @@ class stride_view : public view_interface> { _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } - _LIBCPP_HIDE_FROM_ABI constexpr auto stride() { return __stride_; } + _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_View> stride() const noexcept { return __stride_; } _LIBCPP_HIDE_FROM_ABI constexpr auto size() - requires ranges::sized_range<_View> + requires sized_range<_View> { return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __stride_)); } _LIBCPP_HIDE_FROM_ABI constexpr auto size() const - requires ranges::sized_range + requires sized_range { return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __stride_)); } @@ -105,7 +102,7 @@ class stride_view : public view_interface> { } _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const - requires ranges::range + requires range { return __iterator{*this, ranges::begin(__base_)}; } @@ -203,8 +200,8 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> = default; _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator __i) - requires _Const && std::convertible_to, ranges::iterator_t<_Base>> && - std::convertible_to, ranges::sentinel_t<_Base>> + requires _Const && std::convertible_to, iterator_t<_Base>> && + std::convertible_to, sentinel_t<_Base>> : __current_(std::move(__i.__current_)), __end_(std::move(__i.__end_)), __stride_(__i.__stride_), @@ -381,25 +378,6 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> } }; // class stride_view::__iterator -template - requires view<_View> -template -class stride_view<_View>::__sentinel { -public: - sentinel_t<_View> __end_ = sentinel_t<_View>(); - - _LIBCPP_HIDE_FROM_ABI __sentinel() = default; - - _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(stride_view<_View>& __parent) - : __end_(ranges::end(__parent.__base_)) {} - - _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_View> base() const { return __end_; } - - _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(__iterator const& __x, __sentinel const& __y) { - return __x.__current_ == __y.__end_; - } -}; // class stride_view::__sentinel - template stride_view(_Range&&) -> stride_view>; diff --git a/libcxx/modules/std/ranges.inc b/libcxx/modules/std/ranges.inc index b238389a393b8..a616d8223489b 100644 --- a/libcxx/modules/std/ranges.inc +++ b/libcxx/modules/std/ranges.inc @@ -293,6 +293,16 @@ export namespace std { using std::ranges::views::zip; } // namespace views +#if _LIBCPP_STD_VER >= 23 + // [range.stride], stride view + using std::ranges::stride_view; + + namespace views { + using std::ranges::views::stride; + } +#endif // _LIBCPP_STD_VER >= 23 + +#if 0 // [range.zip.transform], zip transform view using std::ranges::zip_transform_view; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp new file mode 100644 index 0000000000000..80092fc673870 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::views::stride_view + +#include "test.h" +#include +#include +#include + +constexpr bool test() { + static_assert(noexcept(std::declval>().stride())); + static_assert(std::is_same_v, + decltype(std::declval>().stride())>); + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} From 69738b3258c895493d41cb6ac9c86d2d80628420 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 15 Sep 2023 18:21:54 -0400 Subject: [PATCH 011/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Make aspects of std::ranges::stride_view::__iterator private. --- libcxx/include/__ranges/stride_view.h | 12 ++-- .../iterator/ctor.default.pass.cpp | 13 +++-- .../range.adaptors/range.stride.view/test.h | 58 +++++++++---------- 3 files changed, 44 insertions(+), 39 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 9bf30e6c2815b..e2ef0cdc30ee5 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -184,16 +184,18 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> using _Parent = __maybe_const<_Const, stride_view<_View>>; using _Base = __maybe_const<_Const, _View>; + _LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_Base> __current_ = iterator_t<_Base>(); + _LIBCPP_NO_UNIQUE_ADDRESS ranges::sentinel_t<_Base> __end_ = ranges::sentinel_t<_Base>(); + range_difference_t<_Base> __stride_ = 0; + range_difference_t<_Base> __missing_ = 0; + + friend stride_view; + public: using difference_type = range_difference_t<_Base>; using value_type = range_value_t<_Base>; using iterator_concept = typename __stride_view_iterator_concept<_View>::type; - _LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_Base> __current_ = iterator_t<_Base>(); - _LIBCPP_NO_UNIQUE_ADDRESS ranges::sentinel_t<_Base> __end_ = ranges::sentinel_t<_Base>(); - difference_type __stride_ = 0; - difference_type __missing_ = 0; - // using iterator_category = inherited; _LIBCPP_HIDE_FROM_ABI __iterator() requires default_initializable> diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp index d0f466d3adeae..a4a6ba5672766 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp @@ -15,16 +15,19 @@ #include "../test.h" #include #include +#include -bool non_simple_view_iter_ctor_test() { - using StrideView = std::ranges::stride_view; +constexpr bool non_simple_view_iter_ctor_test() { + using StrideView = std::ranges::stride_view; using StrideViewIterNonConst = std::ranges::iterator_t; using StrideViewIterConst = std::ranges::iterator_t; - StrideView sv{InstrumentedNotSimpleView{}, 1}; + StrideView sv{NotSimpleView{}, 1}; StrideViewIterNonConst iter = {sv, sv.base().begin(), 0}; - StrideViewIterConst iterb = {iter}; - assert(iterb.__end_.moved_from_a == true); + // StrideViewIterNonConst constructs its new __current_ and __end_ by + // moving the same members from the given iterator. When that is not possible + // for either of those two values, it should fail. + static_assert(!std::is_constructible_v); return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index d06ef2c3b923c..e6640cd892e9d 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -84,40 +84,40 @@ struct InputIterBase { friend constexpr bool operator==(const InputIterBase&, const InputIterBase&) { return true; } }; -struct NotSimpleViewIterB : ForwardIterBase { - bool moved = false; - - constexpr NotSimpleViewIterB() = default; - constexpr NotSimpleViewIterB(const NotSimpleViewIterB&) = default; - constexpr NotSimpleViewIterB(NotSimpleViewIterB&&) : moved{true} {} - constexpr NotSimpleViewIterB& operator=(NotSimpleViewIterB&&) = default; - constexpr NotSimpleViewIterB& operator=(const NotSimpleViewIterB&) = default; +struct NotSimpleViewIter : ForwardIterBase { + constexpr NotSimpleViewIter() = default; + constexpr NotSimpleViewIter(const NotSimpleViewIter&) = default; + constexpr NotSimpleViewIter(NotSimpleViewIter&&) = default; + constexpr NotSimpleViewIter& operator=(NotSimpleViewIter&&) = default; + constexpr NotSimpleViewIter& operator=(const NotSimpleViewIter&) = default; }; -struct NotSimpleViewIterA : ForwardIterBase { - bool moved = false; - bool moved_from_a = false; - bool copied_from_a = false; - - constexpr NotSimpleViewIterA() = default; - constexpr NotSimpleViewIterA(const NotSimpleViewIterA&) = default; - constexpr NotSimpleViewIterA(const NotSimpleViewIterB&) : copied_from_a{true} {} - constexpr NotSimpleViewIterA(NotSimpleViewIterA&&) : moved{true} {} - constexpr NotSimpleViewIterA(NotSimpleViewIterB&&) : moved_from_a{true} {} - constexpr NotSimpleViewIterA& operator=(NotSimpleViewIterA&&) = default; - constexpr NotSimpleViewIterA& operator=(const NotSimpleViewIterA&) = default; +struct NotSimpleViewIterEnd : ForwardIterBase { + constexpr NotSimpleViewIterEnd() = default; + constexpr NotSimpleViewIterEnd(const NotSimpleViewIterEnd&) = default; + constexpr NotSimpleViewIterEnd(NotSimpleViewIterEnd&&) = default; + constexpr NotSimpleViewIterEnd& operator=(NotSimpleViewIterEnd&&) = default; + constexpr NotSimpleViewIterEnd& operator=(const NotSimpleViewIterEnd&) = default; }; -struct InstrumentedNotSimpleView : std::ranges::view_base { - constexpr NotSimpleViewIterA begin() const { return {}; } - constexpr NotSimpleViewIterB begin() { return {}; } - constexpr NotSimpleViewIterA end() const { return {}; } - constexpr NotSimpleViewIterB end() { return {}; } +struct ConstNotSimpleViewIter : ForwardIterBase { + constexpr ConstNotSimpleViewIter() = default; + constexpr ConstNotSimpleViewIter(const ConstNotSimpleViewIter&) = default; + constexpr ConstNotSimpleViewIter(const NotSimpleViewIter&) {} + constexpr ConstNotSimpleViewIter(ConstNotSimpleViewIter&&) = default; - int* begin_; - int* end_; - bool wasCopyInitialized = false; - bool wasMoveInitialized = false; + constexpr ConstNotSimpleViewIter(NotSimpleViewIter&&) {} + constexpr ConstNotSimpleViewIter(NotSimpleViewIterEnd&&) = delete; + + constexpr ConstNotSimpleViewIter& operator=(ConstNotSimpleViewIter&&) = default; + constexpr ConstNotSimpleViewIter& operator=(const ConstNotSimpleViewIter&) = default; +}; + +struct NotSimpleView : std::ranges::view_base { + constexpr ConstNotSimpleViewIter begin() const { return {}; } + constexpr NotSimpleViewIter begin() { return {}; } + constexpr ConstNotSimpleViewIter end() const { return {}; } + constexpr NotSimpleViewIterEnd end() { return {}; } }; struct ForwardTracedMoveIter : ForwardIterBase { From afe11f000ae2e4646273abbfc3b10481f23c4a4f Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 18 Sep 2023 12:31:07 -0400 Subject: [PATCH 012/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Remove duplicate module declaration of stride_view. --- libcxx/modules/std/ranges.inc | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/libcxx/modules/std/ranges.inc b/libcxx/modules/std/ranges.inc index a616d8223489b..c13db6be6e4ac 100644 --- a/libcxx/modules/std/ranges.inc +++ b/libcxx/modules/std/ranges.inc @@ -299,7 +299,7 @@ export namespace std { namespace views { using std::ranges::views::stride; - } + } // namespace views #endif // _LIBCPP_STD_VER >= 23 #if 0 @@ -350,13 +350,6 @@ export namespace std { } #endif // _LIBCPP_STD_VER >= 23 - // [range.stride], stride view - using std::ranges::stride_view; - - namespace views { - using std::ranges::views::stride; - } - #if 0 using std::ranges::cartesian_product_view; From 64e6c1728c4ad12c73800acb421133b5e0826baa Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 4 Oct 2023 19:44:22 -0400 Subject: [PATCH 013/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Address first of Konstantin's helpful comments. --- libcxx/include/__ranges/stride_view.h | 92 ++++++++++--------- .../range.stride.view/ctor.pass.cpp | 32 +++++++ .../iterator/ctor.default.pass.cpp | 44 ++++----- 3 files changed, 101 insertions(+), 67 deletions(-) create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index e2ef0cdc30ee5..47ecf3c585066 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -71,7 +71,9 @@ class stride_view : public view_interface> { public: _LIBCPP_HIDE_FROM_ABI constexpr explicit stride_view(_View __base, range_difference_t<_View> __stride) - : __base_(std::move(__base)), __stride_(__stride) {} + : __base_(std::move(__base)), __stride_(__stride) { + _LIBCPP_ASSERT_UNCATEGORIZED(__stride > 0, "The value of stride must be greater than 0"); + } _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& requires copy_constructible<_View> @@ -83,68 +85,72 @@ class stride_view : public view_interface> { _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_View> stride() const noexcept { return __stride_; } - _LIBCPP_HIDE_FROM_ABI constexpr auto size() - requires sized_range<_View> - { - return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __stride_)); - } - - _LIBCPP_HIDE_FROM_ABI constexpr auto size() const - requires sized_range - { - return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __stride_)); - } - _LIBCPP_HIDE_FROM_ABI constexpr auto begin() requires(!__simple_view<_View>) { - return __iterator{*this, ranges::begin(__base_)}; + return __iterator(this, ranges::begin(__base_)); } _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const requires range { - return __iterator{*this, ranges::begin(__base_)}; + return __iterator(this, ranges::begin(__base_)); } _LIBCPP_HIDE_FROM_ABI constexpr auto end() requires(!__simple_view<_View> && common_range<_View> && sized_range<_View> && forward_range<_View>) { auto __missing = (__stride_ - ranges::distance(__base_) % __stride_) % __stride_; - return __iterator{*this, ranges::end(__base_), __missing}; + return __iterator(this, ranges::end(__base_), __missing); } _LIBCPP_HIDE_FROM_ABI constexpr auto end() requires(!__simple_view<_View> && common_range<_View> && !bidirectional_range<_View>) { - return __iterator{*this, ranges::end(__base_)}; + return __iterator(this, ranges::end(__base_)); } _LIBCPP_HIDE_FROM_ABI constexpr auto end() requires(!__simple_view<_View>) { - return std::default_sentinel; + return default_sentinel; } _LIBCPP_HIDE_FROM_ABI constexpr auto end() const requires(range && common_range && sized_range && forward_range) { auto __missing = (__stride_ - ranges::distance(__base_) % __stride_) % __stride_; - return __iterator{*this, ranges::end(__base_), __missing}; + return __iterator(this, ranges::end(__base_), __missing); } _LIBCPP_HIDE_FROM_ABI constexpr auto end() const requires(range && common_range<_View> && !bidirectional_range<_View>) { - return __iterator{*this, ranges::end(__base_)}; + return __iterator(this, ranges::end(__base_)); } _LIBCPP_HIDE_FROM_ABI constexpr auto end() const requires(range) { - return std::default_sentinel; + return default_sentinel; + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto size() + requires sized_range<_View> + { + return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __stride_)); + } + + _LIBCPP_HIDE_FROM_ABI constexpr auto size() const + requires sized_range + { + return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __stride_)); } }; // class stride_view +template +stride_view(_Range&&, range_difference_t<_Range>) -> stride_view>; + +namespace views { template struct __stride_view_iterator_concept { using type = input_iterator_tag; @@ -191,31 +197,31 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> friend stride_view; + _LIBCPP_HIDE_FROM_ABI constexpr __iterator( + _Parent* __parent, ranges::iterator_t<_Base> __current, range_difference_t<_Base> __missing = 0) + : __current_(std::move(__current)), + __end_(ranges::end(__parent->__base_)), + __stride_(__parent->__stride_), + __missing_(__missing) {} + public: using difference_type = range_difference_t<_Base>; using value_type = range_value_t<_Base>; using iterator_concept = typename __stride_view_iterator_concept<_View>::type; - // using iterator_category = inherited; + _LIBCPP_HIDE_FROM_ABI __iterator() requires default_initializable> = default; _LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator __i) - requires _Const && std::convertible_to, iterator_t<_Base>> && - std::convertible_to, sentinel_t<_Base>> + requires _Const && convertible_to, iterator_t<_Base>> && + convertible_to, sentinel_t<_Base>> : __current_(std::move(__i.__current_)), __end_(std::move(__i.__end_)), __stride_(__i.__stride_), __missing_(__i.__missing_) {} - _LIBCPP_HIDE_FROM_ABI constexpr __iterator( - _Parent& __parent, ranges::iterator_t<_Base> __current, difference_type __missing = 0) - : __current_(std::move(__current)), - __end_(ranges::end(__parent.__base_)), - __stride_(__parent.__stride_), - __missing_(__missing) {} - _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> const& base() const& noexcept { return __current_; } _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> base() && { return std::move(__current_); } @@ -250,29 +256,29 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> return __tmp; } - _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __s) + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n) requires random_access_range<_Base> { - if (__s > 0) { - ranges::advance(__current_, __stride_ * (__s - 1)); + if (__n > 0) { + ranges::advance(__current_, __stride_ * (__n - 1)); __missing_ = ranges::advance(__current_, __stride_, __end_); - } else if (__s < 0) { - ranges::advance(__current_, __stride_ * __s + __missing_); + } else if (__n < 0) { + ranges::advance(__current_, __stride_ * __n + __missing_); __missing_ = 0; } return *this; } - _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __s) + _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n) requires random_access_range<_Base> { - return *this += -__s; + return *this += -__n; } - _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __s) const + _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const requires random_access_range<_Base> { - return *(*this + __s); + return *(*this + __n); } _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(__iterator const& __x, default_sentinel_t) { @@ -380,17 +386,13 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> } }; // class stride_view::__iterator -template -stride_view(_Range&&) -> stride_view>; - -namespace views { namespace __stride { struct __fn { template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) const noexcept(noexcept(stride_view{std::forward<_Range>(__range), __n})) -> decltype(stride_view{std::forward<_Range>(__range), __n}) { - return stride_view{std::forward<_Range>(__range), __n}; + return stride_view(std::forward<_Range>(__range), __n); } template diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp new file mode 100644 index 0000000000000..126a7af66093e --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::views::stride_view + +#include "test.h" +#include +#include +#include + +bool test() { + // Make sure that a constructor with a negative stride asserts. + + int arr[] = {1, 2, 3}; + ForwardView sc{arr, arr + 3}; + auto sv = std::ranges::stride_view(sc, 0); + return true; +} + +int main(int, char**) { + test(); + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp index a4a6ba5672766..acd26c35a5db2 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp @@ -13,40 +13,40 @@ // std::views::stride_view #include "../test.h" +#include "__concepts/same_as.h" +#include "__ranges/stride_view.h" #include #include #include constexpr bool non_simple_view_iter_ctor_test() { - using StrideView = std::ranges::stride_view; - using StrideViewIterNonConst = std::ranges::iterator_t; - using StrideViewIterConst = std::ranges::iterator_t; - - StrideView sv{NotSimpleView{}, 1}; - StrideViewIterNonConst iter = {sv, sv.base().begin(), 0}; - // StrideViewIterNonConst constructs its new __current_ and __end_ by - // moving the same members from the given iterator. When that is not possible - // for either of those two values, it should fail. - static_assert(!std::is_constructible_v); - return true; -} + using NotSimpleStrideView = std::ranges::stride_view; + using NotSimpleStrideViewIter = std::ranges::iterator_t; + + using SimpleStrideView = std::ranges::stride_view; + using SimpleStrideViewIter = std::ranges::iterator_t; + + NotSimpleStrideView nsv{NotSimpleView{}, 1}; + [[maybe_unused]] NotSimpleStrideViewIter nsv_iter = nsv.begin(); -constexpr bool simpleview_iter_ctor_test() { - using StrideView = std::ranges::stride_view; - using StrideViewIter = std::ranges::iterator_t; + SimpleStrideView sv{ForwardTracedMoveView{}, 1}; + [[maybe_unused]] SimpleStrideViewIter ssv_iter = sv.begin(); - StrideView sv{ForwardTracedMoveView{}, 1}; - StrideViewIter iter = {sv, sv.base().begin(), 0}; - // Guarantee that when the iterator is given to the constructor that - // it is moved there. - assert(iter.base().moved); + using NotSimpleStrideViewIterConst = std::ranges::iterator_t; + using SimpleStrideViewIterConst = std::ranges::iterator_t; + // .begin on a stride view over a non-simple view will give us a + // stride_view iterator with its _Const == false. Compare that type + // with an iterator on a stride view over a simple view that will give + // us an iterator with its _Const == true. They should *not* be the same. + static_assert(!std::is_same_v); + static_assert(!std::is_same_v); + static_assert(std::is_same_v); return true; } int main(int, char**) { - simpleview_iter_ctor_test(); non_simple_view_iter_ctor_test(); - static_assert(simpleview_iter_ctor_test()); + static_assert(non_simple_view_iter_ctor_test()); return 0; } From ae1c13a06a63fcac53b7b0e44bc7064a5d261562 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Thu, 5 Oct 2023 22:47:19 -0400 Subject: [PATCH 014/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add the first (of hopefully many more) precondition check tests. --- .../range.stride.view/ctor.assert.pass.cpp | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp new file mode 100644 index 0000000000000..89c55d434745d --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 +// UNSUPPORTED: no-exceptions +// UNSUPPORTED: !libcpp-hardening-mode=debug +// XFAIL: availability-verbose_abort-missing + +// + +// Call stride_view() ctor empty stride <= 0 + +#include "check_assertion.h" +#include + +void test() { + int range[] = {1, 2, 3}; + // Keep up to date with assertion message from the ctor. + TEST_LIBCPP_ASSERT_FAILURE( + [&range] { std::ranges::stride_view sv(range, 0); }(), "The value of stride must be greater than 0"); + TEST_LIBCPP_ASSERT_FAILURE( + [&range] { std::ranges::stride_view sv(range, -1); }(), "The value of stride must be greater than 0"); +} + +int main() { + test(); + return 0; +} From e13ce518785818976b3af4b4333daea03b035921 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Thu, 5 Oct 2023 23:04:20 -0400 Subject: [PATCH 015/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Remove unneeded includes and a redundant test. --- libcxx/include/__ranges/stride_view.h | 21 ------------ .../range.stride.view/ctor.pass.cpp | 32 ------------------- 2 files changed, 53 deletions(-) delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 47ecf3c585066..4ccd7051a4c23 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -12,34 +12,13 @@ #include <__config> -#include <__compare/three_way_comparable.h> -#include <__concepts/constructible.h> -#include <__concepts/convertible_to.h> -#include <__concepts/derived_from.h> #include <__functional/bind_back.h> -#include <__iterator/advance.h> -#include <__iterator/concepts.h> #include <__iterator/default_sentinel.h> #include <__iterator/distance.h> -#include <__iterator/iter_move.h> #include <__iterator/iter_swap.h> -#include <__iterator/iterator_traits.h> -#include <__iterator/next.h> -#include <__ranges/access.h> #include <__ranges/all.h> #include <__ranges/concepts.h> -#include <__ranges/enable_borrowed_range.h> -#include <__ranges/non_propagating_cache.h> -#include <__ranges/range_adaptor.h> -#include <__ranges/size.h> -#include <__ranges/subrange.h> #include <__ranges/view_interface.h> -#include <__ranges/views.h> -#include <__type_traits/conditional.h> -#include <__type_traits/maybe_const.h> -#include <__type_traits/remove_cvref.h> -#include <__utility/forward.h> -#include <__utility/move.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp deleted file mode 100644 index 126a7af66093e..0000000000000 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp +++ /dev/null @@ -1,32 +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, c++20 - -// ranges - -// std::views::stride_view - -#include "test.h" -#include -#include -#include - -bool test() { - // Make sure that a constructor with a negative stride asserts. - - int arr[] = {1, 2, 3}; - ForwardView sc{arr, arr + 3}; - auto sv = std::ranges::stride_view(sc, 0); - return true; -} - -int main(int, char**) { - test(); - return 0; -} From bee9a0be8159a28f2df67b5261cace90fd9281b0 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 6 Oct 2023 08:58:05 -0400 Subject: [PATCH 016/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Remove sentinel tests -- that class no longer exists. --- .../sentinel/ctor.default.pass.cpp | 22 ------------------- .../range.stride.view/sentinel/equal.pass.cpp | 22 ------------------- 2 files changed, 44 deletions(-) delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/sentinel/ctor.default.pass.cpp delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/sentinel/equal.pass.cpp diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/sentinel/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/sentinel/ctor.default.pass.cpp deleted file mode 100644 index 68556f32f875b..0000000000000 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/sentinel/ctor.default.pass.cpp +++ /dev/null @@ -1,22 +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, c++20 - -// ranges - -// std::views::stride_view - -constexpr bool test() { return true; } - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/sentinel/equal.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/sentinel/equal.pass.cpp deleted file mode 100644 index 68556f32f875b..0000000000000 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/sentinel/equal.pass.cpp +++ /dev/null @@ -1,22 +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, c++20 - -// ranges - -// std::views::stride_view - -constexpr bool test() { return true; } - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} From dd1d4248298766d97c672fd6486e1589cd194b4a Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 6 Oct 2023 09:04:27 -0400 Subject: [PATCH 017/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix formatting of some test files. --- .../range.stride.view/base.pass.cpp | 3 +- .../range.stride.view/ctad.compile.pass.cpp | 28 ++++++------------- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp index 6b22b7e89c015..4d06840ff7f8f 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp @@ -45,7 +45,8 @@ constexpr bool test() { // Check the && overload (again) { InstrumentedBasicView range(buff, buff + 8); - std::same_as> decltype(auto) result = std::ranges::stride_view>(range, 3).base(); + std::same_as> decltype(auto) result = + std::ranges::stride_view>(range, 3).base(); assert(result.wasMoveInitialized); assert(result.begin() == buff); assert(result.end() == buff + 8); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp index 7831d792d64e7..ab8768502b1d0 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp @@ -23,24 +23,15 @@ constexpr bool test() { InstrumentedBasicView bv{arr, arr + 3}; InstrumentedBasicRange br{}; - static_assert(std::same_as< - decltype(std::ranges::stride_view(bv, 2)), - std::ranges::stride_view - >); - static_assert(std::same_as< - decltype(std::ranges::stride_view(std::move(bv), 2)), - std::ranges::stride_view - >); - - static_assert(std::same_as< - decltype(std::ranges::drop_view(br, 0)), - std::ranges::drop_view>> - >); - - static_assert(std::same_as< - decltype(std::ranges::drop_view(std::move(br), 0)), - std::ranges::drop_view>> - >); + static_assert(std::same_as< decltype(std::ranges::stride_view(bv, 2)), std::ranges::stride_view >); + static_assert( + std::same_as< decltype(std::ranges::stride_view(std::move(bv), 2)), std::ranges::stride_view >); + + static_assert(std::same_as< decltype(std::ranges::drop_view(br, 0)), + std::ranges::drop_view>> >); + + static_assert(std::same_as< decltype(std::ranges::drop_view(std::move(br), 0)), + std::ranges::drop_view>> >); return true; } @@ -50,4 +41,3 @@ int main(int, char**) { return 0; } - From 6cb870a1d1b4b8793be760dd450b36e5526ed275 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 6 Oct 2023 17:20:49 -0400 Subject: [PATCH 018/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Rename ctor assertion tests. --- .../range.adaptors/range.stride.view/ctor.assert.pass.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp index 89c55d434745d..5433657658480 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp @@ -18,7 +18,7 @@ #include "check_assertion.h" #include -void test() { +void stride_view_over_only_input_ranges() { int range[] = {1, 2, 3}; // Keep up to date with assertion message from the ctor. TEST_LIBCPP_ASSERT_FAILURE( @@ -28,6 +28,6 @@ void test() { } int main() { - test(); + stride_view_over_only_input_ranges(); return 0; } From 1694a37fd2c6607fad1e3e640b383f561bce7c67 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 6 Oct 2023 17:21:38 -0400 Subject: [PATCH 019/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add test for input_range requirement. --- .../range.stride.view/concept.pass.cpp | 57 +++++++++++++++++++ .../range.adaptors/range.stride.view/test.h | 5 ++ 2 files changed, 62 insertions(+) create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.pass.cpp diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.pass.cpp new file mode 100644 index 0000000000000..ad23f7284fdd9 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::views::stride_view + +#include "__ranges/stride_view.h" +#include "test.h" + +// Do not use for execution -- only useful for testing compilation/type conditions. +template +struct non_input_iterator { + struct __invalid_iterator_tag {}; + using value_type = T; + using difference_type = int; + using iterator_concept = __invalid_iterator_tag; + + constexpr non_input_iterator& operator++() { return *this; } + constexpr void operator++(int) {} + constexpr T operator*() const { return T{}; } + + friend constexpr bool operator==(const non_input_iterator&, const non_input_iterator&) { return true; } +}; + +template +inline constexpr bool std::ranges::enable_borrowed_range> = true; + +class almost_input_range : public std::ranges::view_base { +public: + constexpr auto begin() const { return non_input_iterator{}; } + constexpr auto end() const { return non_input_iterator{}; } +}; + +constexpr bool test() { + // Ensure that the almost_input_range is a valid range. + static_assert(std::ranges::range); + // Ensure that the non_input_iterator is, well, not an input iterator. + static_assert(!std::input_iterator>); + + static_assert(!CanStrideView, "A non input range cannot be the subject of a stride view."); + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index e6640cd892e9d..87c57d19d337c 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -13,6 +13,11 @@ #include #include +template D> +concept CanStrideView = requires { + std::ranges::stride_view{I{}, D}; +}; + template struct InstrumentedBasicRange { T* begin() const; From 2d22db15a490298b7bd566baad83e9aa1341e0fb Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 9 Oct 2023 12:27:21 -0400 Subject: [PATCH 020/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add additional testing for view requirements and explicit ctor. --- .../range.stride.view/concept.pass.cpp | 13 ++++++++++++- .../{ctor.default.pass.cpp => ctor.pass.cpp} | 16 ++++++++++++---- .../range.adaptors/range.stride.view/test.h | 2 ++ 3 files changed, 26 insertions(+), 5 deletions(-) rename libcxx/test/std/ranges/range.adaptors/range.stride.view/{ctor.default.pass.cpp => ctor.pass.cpp} (61%) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.pass.cpp index ad23f7284fdd9..395ab4a55b9b8 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.pass.cpp @@ -39,13 +39,24 @@ class almost_input_range : public std::ranges::view_base { constexpr auto end() const { return non_input_iterator{}; } }; +class non_view_range { +public: + constexpr int* begin() const { return nullptr; } + constexpr int* end() const { return nullptr; } +}; + constexpr bool test() { // Ensure that the almost_input_range is a valid range. static_assert(std::ranges::range); // Ensure that the non_input_iterator is, well, not an input iterator. static_assert(!std::input_iterator>); - static_assert(!CanStrideView, "A non input range cannot be the subject of a stride view."); + + // Ensure that a range that is not a view cannot be the subject of a stride_view. + static_assert(std::ranges::range, "non_view_range must be a range."); + static_assert(std::movable, "non_view_range must be movable."); + static_assert(!std::ranges::view, "A non-view range cannot be the subject of a stride_view.\n"); + return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp similarity index 61% rename from libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.default.pass.cpp rename to libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp index 09cb8c20ea318..6891b5e62a187 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.default.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp @@ -13,17 +13,25 @@ // std::views::stride_view #include "test.h" +#include "test_convertible.h" #include -constexpr bool test() { +constexpr bool test_no_default_ctor() { // There is no default ctor for stride_view. static_assert(!std::is_default_constructible_v>); return true; } -int main(int, char**) { - test(); - static_assert(test()); +constexpr bool test_no_implicit_ctor() { + // Test that the stride_view can only be explicitly constructed. + static_assert(!test_convertible, ForwardView, int>()); + return true; +} +int main(int, char**) { + test_no_implicit_ctor(); + static_assert(test_no_implicit_ctor()); + test_no_default_ctor(); + static_assert(test_no_default_ctor()); return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index 87c57d19d337c..a0d5540c53f0f 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -9,6 +9,8 @@ #ifndef TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H #define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H +#include "__concepts/movable.h" +#include "__ranges/concepts.h" #include "test_iterators.h" #include #include From fbec0e8b4dc91f8c4b18c260e2f69a536924cae0 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 13 Oct 2023 01:00:59 -0400 Subject: [PATCH 021/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add additional testing for stride views over move-only types. --- .../range.stride.view/base.pass.cpp | 38 +++++++----- .../range.stride.view/ctad.compile.pass.cpp | 4 +- .../range.stride.view/ctor.pass.cpp | 16 +++++ .../enable_borrowed_range.compile.pass.cpp | 2 +- .../range.adaptors/range.stride.view/test.h | 62 +++++++++++++------ 5 files changed, 83 insertions(+), 39 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp index 4d06840ff7f8f..062262ffde577 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp @@ -24,40 +24,46 @@ constexpr bool test() { // Check the const& overload { - InstrumentedBasicView range(buff, buff + 8); - std::ranges::stride_view> const view(range, 3); - std::same_as> decltype(auto) result = view.base(); - assert(result.wasCopyInitialized); + bool moved(false), copied(false); + MovedCopiedTrackedBasicView range(buff, buff + 8, &moved, &copied); + std::ranges::stride_view> const view(std::move(range), 3); + assert(moved); + assert(!copied); + std::same_as> decltype(auto) result = view.base(); assert(result.begin() == buff); assert(result.end() == buff + 8); } // Check the && overload { - InstrumentedBasicView range(buff, buff + 8); - std::ranges::stride_view> view(range, 3); - std::same_as> decltype(auto) result = std::move(view).base(); - assert(result.wasMoveInitialized); + bool moved(false), copied(false); + MovedCopiedTrackedBasicView range(buff, buff + 8, &moved, &copied); + std::ranges::stride_view> view(std::move(range), 3); + assert(moved); + assert(!copied); + std::same_as> decltype(auto) result = std::move(view).base(); assert(result.begin() == buff); assert(result.end() == buff + 8); } // Check the && overload (again) { - InstrumentedBasicView range(buff, buff + 8); - std::same_as> decltype(auto) result = - std::ranges::stride_view>(range, 3).base(); - assert(result.wasMoveInitialized); + bool moved(false), copied(false); + MovedCopiedTrackedBasicView range(buff, buff + 8, &moved, &copied); + std::same_as> decltype(auto) result = + std::ranges::stride_view>(std::move(range), 3).base(); + assert(moved); + assert(!copied); assert(result.begin() == buff); assert(result.end() == buff + 8); } // Ensure the const& overload is not considered when the base is not copy-constructible { - static_assert(!can_call_base_on const&>); - static_assert(!can_call_base_on&>); - static_assert(can_call_base_on&&>); - static_assert(can_call_base_on>); + static_assert(!can_call_base_on> const&>); + static_assert(!can_call_base_on>&>); + static_assert(can_call_base_on>&&>); + static_assert(can_call_base_on>>); } return true; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp index ab8768502b1d0..4cceca699d215 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp @@ -12,15 +12,15 @@ // std::views::stride_view +#include "test.h" #include #include #include -#include "test.h" constexpr bool test() { int arr[]{1, 2, 3}; - InstrumentedBasicView bv{arr, arr + 3}; + MovedCopiedTrackedBasicView bv{arr, arr + 3}; InstrumentedBasicRange br{}; static_assert(std::same_as< decltype(std::ranges::stride_view(bv, 2)), std::ranges::stride_view >); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp index 6891b5e62a187..a205386fa0a9d 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp @@ -28,10 +28,26 @@ constexpr bool test_no_implicit_ctor() { return true; } +constexpr bool test_move_ctor() { + int arr[] = {1, 2, 3}; + // Test that the stride_view ctor properly moves from the base (and works with a move-only type). + static_assert(!std::is_copy_constructible_v>); + static_assert(std::is_move_constructible_v>); + + bool moved(false), copied(false); + MovedOnlyTrackedBasicView mov(arr, arr + 3, &moved, &copied); + std::ranges::stride_view> mosv(std::move(mov), 2); + assert(moved); + assert(!copied); + return true; +} + int main(int, char**) { test_no_implicit_ctor(); static_assert(test_no_implicit_ctor()); test_no_default_ctor(); static_assert(test_no_default_ctor()); + test_move_ctor(); + static_assert(test_move_ctor()); return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.compile.pass.cpp index 7c28842fe65f6..4add46949a6ae 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.compile.pass.cpp @@ -19,7 +19,7 @@ constexpr bool test() { using std::ranges::enable_borrowed_range; // Make sure that a stride_view over neither a borrowable nor an unborrowable view // is itself borrowable. - static_assert(!enable_borrowed_range>>); + static_assert(!enable_borrowed_range>>); static_assert(!enable_borrowed_range>>); return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index a0d5540c53f0f..71120fb357741 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -26,41 +26,63 @@ struct InstrumentedBasicRange { T* end() const; }; +struct MovedCopiedTrackedView { + constexpr explicit MovedCopiedTrackedView(bool* moved = nullptr, bool* copied = nullptr) + : wasMoveInitialized_(moved), wasCopyInitialized_(copied) {} + constexpr MovedCopiedTrackedView(MovedCopiedTrackedView const& other) + : wasMoveInitialized_(other.wasMoveInitialized_), wasCopyInitialized_(other.wasCopyInitialized_) { + *wasCopyInitialized_ = true; + } + constexpr MovedCopiedTrackedView(MovedCopiedTrackedView&& other) + : wasMoveInitialized_(other.wasMoveInitialized_), wasCopyInitialized_(other.wasCopyInitialized_) { + *wasMoveInitialized_ = true; + } + MovedCopiedTrackedView& operator=(MovedCopiedTrackedView const&) = default; + MovedCopiedTrackedView& operator=(MovedCopiedTrackedView&&) = default; + + bool* wasMoveInitialized_ = nullptr; + bool* wasCopyInitialized_ = nullptr; +}; + template -struct InstrumentedBasicView : std::ranges::view_base { - constexpr explicit InstrumentedBasicView(T* b, T* e) : begin_(b), end_(e) {} - constexpr InstrumentedBasicView(InstrumentedBasicView const& other) - : begin_(other.begin_), end_(other.end_), wasCopyInitialized(true) {} - constexpr InstrumentedBasicView(InstrumentedBasicView&& other) - : begin_(other.begin_), end_(other.end_), wasMoveInitialized(true) {} - InstrumentedBasicView& operator=(InstrumentedBasicView const&) = default; - InstrumentedBasicView& operator=(InstrumentedBasicView&&) = default; +struct MovedCopiedTrackedBasicView : MovedCopiedTrackedView, std::ranges::view_base { + constexpr explicit MovedCopiedTrackedBasicView(T* b, T* e, bool* moved = nullptr, bool* copied = nullptr) + : MovedCopiedTrackedView(moved, copied), begin_(b), end_(e) {} + constexpr MovedCopiedTrackedBasicView(const MovedCopiedTrackedBasicView& other) + : MovedCopiedTrackedView(other), begin_(other.begin_), end_(other.end_) {} + constexpr MovedCopiedTrackedBasicView(MovedCopiedTrackedBasicView&& other) + : MovedCopiedTrackedView(std::move(other)), begin_(other.begin_), end_(other.end_) {} + MovedCopiedTrackedBasicView& operator=(MovedCopiedTrackedBasicView const&) = default; + MovedCopiedTrackedBasicView& operator=(MovedCopiedTrackedBasicView&&) = default; constexpr T* begin() const { return begin_; } constexpr T* end() const { return end_; } T* begin_; T* end_; - bool wasCopyInitialized = false; - bool wasMoveInitialized = false; }; template -InstrumentedBasicView(T, T) -> InstrumentedBasicView; +MovedCopiedTrackedBasicView(T, T, bool*, bool*) -> MovedCopiedTrackedBasicView; template -struct InstrumentedBorrowedRange : public InstrumentedBasicView {}; +struct InstrumentedBorrowedRange : public MovedCopiedTrackedBasicView {}; template inline constexpr bool std::ranges::enable_borrowed_range> = true; -struct NoCopyView : std::ranges::view_base { - explicit NoCopyView(int*, int*); - NoCopyView(NoCopyView const&) = delete; - NoCopyView(NoCopyView&&) = default; - NoCopyView& operator=(NoCopyView const&) = default; - NoCopyView& operator=(NoCopyView&&) = default; - int* begin() const; - int* end() const; +template +struct MovedOnlyTrackedBasicView : MovedCopiedTrackedView, std::ranges::view_base { + constexpr explicit MovedOnlyTrackedBasicView(T* b, T* e, bool* moved = nullptr, bool* copied = nullptr) + : MovedCopiedTrackedView(moved, copied), begin_(b), end_(e) {} + constexpr MovedOnlyTrackedBasicView(MovedOnlyTrackedBasicView&& other) + : MovedCopiedTrackedView(std::move(other)), begin_(other.begin_), end_(other.end_) {} + MovedOnlyTrackedBasicView& operator=(MovedOnlyTrackedBasicView const&) = delete; + MovedOnlyTrackedBasicView& operator=(MovedOnlyTrackedBasicView&&) = default; + constexpr T* begin() const { return begin_; } + constexpr T* end() const { return end_; } + + T* begin_; + T* end_; }; template From 7f630e4dc807639aaceaf40576bd1371be8a2a7f Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 13 Oct 2023 01:59:35 -0400 Subject: [PATCH 022/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix formatting issue with adaptor.pass.cpp. --- .../ranges/range.adaptors/range.stride.view/adaptor.pass.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index ba0efe36b9824..60ed5587933a0 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -29,8 +29,7 @@ constexpr bool test() { int arr[array_n] = {1, 2, 3}; // Test that `std::views::stride` is a range adaptor. - { - // Check various forms of + { // Check various forms of // view | stride { { From 1d51e6a6689714f3b61a5ea58cfbf92857eef045 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 13 Oct 2023 10:12:35 -0400 Subject: [PATCH 023/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add test for enable/disable size() when strided range is unsized. --- .../range.stride.view/size.pass.cpp | 30 ++++++++++++++----- .../range.adaptors/range.stride.view/test.h | 9 ++++++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.pass.cpp index 981395f9e2c32..c270c77f6f9f3 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.pass.cpp @@ -12,6 +12,7 @@ // std::ranges::stride_view +#include "test.h" #include #include @@ -25,16 +26,29 @@ bool runtime_test() { constexpr bool test() { { - constexpr auto iot = std::views::iota(1, 12); - constexpr auto str = std::views::stride(iot, 3); - assert(4 == str.size()); - static_assert(4 == str.size(), "Striding by 3 through a 12 member list has size 4."); + // Test with ranges that are sized_range true. + constexpr auto iot_twelve = std::views::iota(1, 12); + static_assert(std::ranges::sized_range); + constexpr auto str_iot_twelve = std::views::stride(iot_twelve, 3); + static_assert(std::ranges::sized_range); + assert(4 == str_iot_twelve.size()); + static_assert(4 == str_iot_twelve.size(), "Striding by 3 through a 12 member list has size 4."); + + constexpr auto iot_twenty_two = std::views::iota(1, 22); + static_assert(std::ranges::sized_range); + constexpr auto str_iot_twenty_two = std::views::stride(iot_twenty_two, 3); + static_assert(std::ranges::sized_range); + + assert(7 == str_iot_twenty_two.size()); + static_assert(7 == str_iot_twenty_two.size(), "Striding by 3 through a 22 member list has size 4."); } + { - constexpr auto iot = std::views::iota(1, 22); - constexpr auto str = std::views::stride(iot, 3); - assert(7 == str.size()); - static_assert(7 == str.size(), "Striding by 3 through a 12 member list has size 4."); + // Test with ranges that are not sized_range true. + constexpr auto unsized_range = UnsizedBasicRange(); + static_assert(!std::ranges::sized_range); + constexpr auto str_unsized = std::views::stride(unsized_range, 3); + static_assert(!std::ranges::sized_range); } return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index 71120fb357741..8eb7423e03f65 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -11,6 +11,8 @@ #include "__concepts/movable.h" #include "__ranges/concepts.h" +#include "__ranges/enable_view.h" +#include "__ranges/size.h" #include "test_iterators.h" #include #include @@ -261,4 +263,11 @@ static_assert(std::ranges::view>); static_assert(std::copyable>); */ +struct UnsizedBasicRangeIterator : ForwardIterBase {}; + +struct UnsizedBasicRange : std::ranges::view_base { + UnsizedBasicRangeIterator begin() const; + UnsizedBasicRangeIterator end() const; +}; + #endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H From af926f7708fef6e05d894ac4f7335addb21d5ce3 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 13 Oct 2023 18:11:49 -0400 Subject: [PATCH 024/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add test for iterator concept type and cleanup end() implementations. --- libcxx/include/__ranges/stride_view.h | 76 +++++-------- .../range.stride.view/iterator/begin.pass.cpp | 76 +++++++++++++ .../range.adaptors/range.stride.view/test.h | 100 +++++++----------- 3 files changed, 145 insertions(+), 107 deletions(-) create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 4ccd7051a4c23..0239a6c595df8 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -76,41 +76,30 @@ class stride_view : public view_interface> { return __iterator(this, ranges::begin(__base_)); } - _LIBCPP_HIDE_FROM_ABI constexpr auto end() - requires(!__simple_view<_View> && common_range<_View> && sized_range<_View> && forward_range<_View>) - { - auto __missing = (__stride_ - ranges::distance(__base_) % __stride_) % __stride_; - return __iterator(this, ranges::end(__base_), __missing); - } - - _LIBCPP_HIDE_FROM_ABI constexpr auto end() - requires(!__simple_view<_View> && common_range<_View> && !bidirectional_range<_View>) - { - return __iterator(this, ranges::end(__base_)); - } - _LIBCPP_HIDE_FROM_ABI constexpr auto end() requires(!__simple_view<_View>) { - return default_sentinel; - } - - _LIBCPP_HIDE_FROM_ABI constexpr auto end() const - requires(range && common_range && sized_range && forward_range) - { - auto __missing = (__stride_ - ranges::distance(__base_) % __stride_) % __stride_; - return __iterator(this, ranges::end(__base_), __missing); - } - _LIBCPP_HIDE_FROM_ABI constexpr auto end() const - requires(range && common_range<_View> && !bidirectional_range<_View>) - { - return __iterator(this, ranges::end(__base_)); + if constexpr (common_range<_View> && sized_range<_View> && forward_range<_View>) { + auto __missing = (__stride_ - ranges::distance(__base_) % __stride_) % __stride_; + return __iterator(this, ranges::end(__base_), __missing); + } else if constexpr (common_range<_View> && !bidirectional_range<_View>) { + return __iterator(this, ranges::end(__base_)); + } else { + return default_sentinel; + } } _LIBCPP_HIDE_FROM_ABI constexpr auto end() const requires(range) { - return default_sentinel; + if constexpr (common_range && sized_range && forward_range) { + auto __missing = (__stride_ - ranges::distance(__base_) % __stride_) % __stride_; + return __iterator(this, ranges::end(__base_), __missing); + } else if constexpr (common_range<_View> && !bidirectional_range<_View>) { + return __iterator(this, ranges::end(__base_)); + } else { + return default_sentinel; + } } _LIBCPP_HIDE_FROM_ABI constexpr auto size() @@ -130,25 +119,6 @@ template stride_view(_Range&&, range_difference_t<_Range>) -> stride_view>; namespace views { -template -struct __stride_view_iterator_concept { - using type = input_iterator_tag; -}; - -template -struct __stride_view_iterator_concept<_View> { - using type = random_access_iterator_tag; -}; - -template -struct __stride_view_iterator_concept<_View> { - using type = bidirectional_iterator_tag; -}; - -template -struct __stride_view_iterator_concept<_View> { - using type = forward_iterator_tag; -}; template struct __stride_iterator_category {}; @@ -183,10 +153,22 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> __stride_(__parent->__stride_), __missing_(__missing) {} + static consteval auto __get_stride_view_iterator_concept() { + if constexpr (random_access_range<_Base>) { + return random_access_iterator_tag{}; + } else if constexpr (bidirectional_range<_Base>) { + return bidirectional_iterator_tag{}; + } else if constexpr (forward_range<_Base>) { + return forward_iterator_tag{}; + } else { + return input_iterator_tag{}; + } + } + public: using difference_type = range_difference_t<_Base>; using value_type = range_value_t<_Base>; - using iterator_concept = typename __stride_view_iterator_concept<_View>::type; + using iterator_concept = decltype(__get_stride_view_iterator_concept()); // using iterator_category = inherited; _LIBCPP_HIDE_FROM_ABI __iterator() diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp new file mode 100644 index 0000000000000..3216a9ab85e84 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::views::stride_view::iterator + +#include "../test.h" +#include "__iterator/concepts.h" +#include "__ranges/stride_view.h" +#include +#include + +constexpr bool iterator_concept_test() { + { + int arr[] = {1, 2, 3}; + // Iterator of stride over random access view should have random access concept. + auto rav = RandomAccessView(arr, arr + 3); + auto str = std::ranges::stride_view(rav, 1); + static_assert(std::random_access_iterator); + static_assert(std::random_access_iterator); + } + + { + int arr[] = {1, 2, 3}; + // Iterator of stride over bidirectional view should have bidirectional view concept. + auto rav = BidirView(arr, arr + 3); + auto str = std::ranges::stride_view(rav, 1); + static_assert(std::bidirectional_iterator); + static_assert(std::bidirectional_iterator); + static_assert(!std::random_access_iterator); + static_assert(!std::random_access_iterator); + } + + { + int arr[] = {1, 2, 3}; + // Iterator of stride over forward view should have forward view concept. + auto rav = ForwardView(arr, arr + 3); + auto str = std::ranges::stride_view(rav, 1); + static_assert(std::forward_iterator); + static_assert(std::forward_iterator); + static_assert(!std::bidirectional_iterator); + static_assert(!std::bidirectional_iterator); + static_assert(!std::random_access_iterator); + static_assert(!std::random_access_iterator); + } + + { + int arr[] = {1, 2, 3}; + // Iterator of stride over forward view should have forward view concept. + auto rav = InputView(arr, arr + 3); + auto str = std::ranges::stride_view(rav, 1); + static_assert(std::input_iterator); + static_assert(std::input_iterator); + static_assert(!std::forward_iterator); + static_assert(!std::forward_iterator); + static_assert(!std::bidirectional_iterator); + static_assert(!std::bidirectional_iterator); + static_assert(!std::random_access_iterator); + static_assert(!std::random_access_iterator); + } + return true; +} + +int main(int, char**) { + iterator_concept_test(); + static_assert(iterator_concept_test()); + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index 8eb7423e03f65..6bef25b861888 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -151,21 +151,25 @@ struct NotSimpleView : std::ranges::view_base { constexpr NotSimpleViewIterEnd end() { return {}; } }; -struct ForwardTracedMoveIter : ForwardIterBase { - bool moved = false; +struct RandomAccessView : std::ranges::view_base { + int* begin_; + int* end_; - constexpr ForwardTracedMoveIter() = default; - constexpr ForwardTracedMoveIter(const ForwardTracedMoveIter&) = default; - constexpr ForwardTracedMoveIter(ForwardTracedMoveIter&&) : moved{true} {} - constexpr ForwardTracedMoveIter& operator=(ForwardTracedMoveIter&&) = default; - constexpr ForwardTracedMoveIter& operator=(const ForwardTracedMoveIter&) = default; -}; + constexpr RandomAccessView(int* b, int* e) : begin_(b), end_(e) {} -struct ForwardTracedMoveView : std::ranges::view_base { - constexpr ForwardTracedMoveIter begin() const { return {}; } - constexpr ForwardTracedMoveIter end() const { return {}; } + constexpr random_access_iterator begin() { return random_access_iterator{begin_}; } + //constexpr random_access_iterator begin() const { return random_access_iterator{begin_}; } + constexpr sentinel_wrapper> end() { + return sentinel_wrapper>{random_access_iterator{end_}}; + } + //constexpr sentinel_wrapper> end() const { return sentinel_wrapper>{random_access_iterator{end_}}; } + constexpr std::size_t size() const { return end_ - begin_; } }; +static_assert(std::ranges::view); +static_assert(std::ranges::random_access_range); +static_assert(std::copyable); + struct BidirView : std::ranges::view_base { int* begin_; int* end_; @@ -182,7 +186,23 @@ struct BidirView : std::ranges::view_base { } }; +struct ForwardTracedMoveIter : ForwardIterBase { + bool moved = false; + + constexpr ForwardTracedMoveIter() = default; + constexpr ForwardTracedMoveIter(const ForwardTracedMoveIter&) = default; + constexpr ForwardTracedMoveIter(ForwardTracedMoveIter&&) : moved{true} {} + constexpr ForwardTracedMoveIter& operator=(ForwardTracedMoveIter&&) = default; + constexpr ForwardTracedMoveIter& operator=(const ForwardTracedMoveIter&) = default; +}; + +struct ForwardTracedMoveView : std::ranges::view_base { + constexpr ForwardTracedMoveIter begin() const { return {}; } + constexpr ForwardTracedMoveIter end() const { return {}; } +}; + static_assert(std::ranges::view); +static_assert(std::ranges::bidirectional_range); static_assert(std::copyable); struct ForwardView : public std::ranges::view_base { @@ -202,66 +222,26 @@ struct ForwardView : public std::ranges::view_base { }; static_assert(std::ranges::view); +static_assert(std::ranges::forward_range); static_assert(std::copyable); -struct RandomAccessView : std::ranges::view_base { +struct InputView : std::ranges::view_base { int* begin_; int* end_; - constexpr RandomAccessView(int* b, int* e) : begin_(b), end_(e) {} + constexpr InputView(int* b, int* e) : begin_(b), end_(e) {} - constexpr random_access_iterator begin() { return random_access_iterator{begin_}; } + constexpr cpp20_input_iterator begin() { return cpp20_input_iterator{begin_}; } //constexpr random_access_iterator begin() const { return random_access_iterator{begin_}; } - constexpr sentinel_wrapper> end() { - return sentinel_wrapper>{random_access_iterator{end_}}; + constexpr sentinel_wrapper> end() { + return sentinel_wrapper>{cpp20_input_iterator{end_}}; } - //constexpr sentinel_wrapper> end() const { return sentinel_wrapper>{random_access_iterator{end_}}; } constexpr std::size_t size() const { return end_ - begin_; } }; -static_assert(std::ranges::view); -static_assert(std::ranges::random_access_range); -static_assert(std::copyable); - -/* -enum CopyCategory { MoveOnly, Copyable }; -template -struct BidirSentView : std::ranges::view_base { - using sent_t = sentinel_wrapper>; - using sent_const_t = sentinel_wrapper>; - - int* begin_; - int* end_; - - constexpr BidirSentView(int* b, int* e) : begin_(b), end_(e) {} - constexpr BidirSentView(const BidirSentView&) - requires(CC == Copyable) - = default; - constexpr BidirSentView(BidirSentView&&) - requires(CC == MoveOnly) - = default; - constexpr BidirSentView& operator=(const BidirSentView&) - requires(CC == Copyable) - = default; - constexpr BidirSentView& operator=(BidirSentView&&) - requires(CC == MoveOnly) - = default; - - constexpr bidirectional_iterator begin() { return bidirectional_iterator{begin_}; } - constexpr bidirectional_iterator begin() const { return bidirectional_iterator{begin_}; } - constexpr sent_t end() { return sent_t{bidirectional_iterator{end_}}; } - constexpr sent_const_t end() const { return sent_const_t{bidirectional_iterator{end_}}; } -}; -// TODO: Clean up. -static_assert(std::ranges::bidirectional_range>); -static_assert(!std::ranges::common_range>); -static_assert(std::ranges::view>); -static_assert(!std::copyable>); -static_assert(std::ranges::bidirectional_range>); -static_assert(!std::ranges::common_range>); -static_assert(std::ranges::view>); -static_assert(std::copyable>); -*/ +static_assert(std::ranges::view); +static_assert(std::ranges::input_range); +static_assert(std::copyable); struct UnsizedBasicRangeIterator : ForwardIterBase {}; From 340687907f5ffe5c02ca746be51f5b58159bf963 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 13 Oct 2023 18:42:20 -0400 Subject: [PATCH 025/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fixed typo in comment in documentation of iterator concept testing. --- .../range.adaptors/range.stride.view/iterator/begin.pass.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp index 3216a9ab85e84..b6b871bd69106 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp @@ -14,7 +14,6 @@ #include "../test.h" #include "__iterator/concepts.h" -#include "__ranges/stride_view.h" #include #include @@ -54,7 +53,7 @@ constexpr bool iterator_concept_test() { { int arr[] = {1, 2, 3}; - // Iterator of stride over forward view should have forward view concept. + // Iterator of stride over input view should have input view concept. auto rav = InputView(arr, arr + 3); auto str = std::ranges::stride_view(rav, 1); static_assert(std::input_iterator); From 4b10ddfeeddf15a8ab8d26ef048e507884d929d6 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 13 Oct 2023 18:44:57 -0400 Subject: [PATCH 026/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add operator++ precondition assertion (and test that it works). --- libcxx/include/__ranges/stride_view.h | 1 + .../iterator/increment.pass.cpp | 34 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 0239a6c595df8..ba05c34553fcf 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -189,6 +189,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return *__current_; } _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() { + _LIBCPP_ASSERT_UNCATEGORIZED(__current_ != __end_, "Cannot increment an iterator already at the end."); __missing_ = ranges::advance(__current_, __stride_, __end_); return *this; } diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp new file mode 100644 index 0000000000000..0100dd1708b0d --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 +// UNSUPPORTED: no-exceptions +// UNSUPPORTED: !libcpp-hardening-mode=debug +// XFAIL: availability-verbose_abort-missing + +// + +// Call .... + +#include "check_assertion.h" +#include "../../test/std/ranges/range.adaptors/range.stride.view/test.h" +#include + +void cannot_increment_at_the_end_iterator() { + int range[] = {1, 2, 3}; + auto iv = InputView(range, range + 3); + auto striv = std::ranges::views::stride(iv, 3); + auto striv_it = striv.begin(); + striv_it++; + TEST_LIBCPP_ASSERT_FAILURE(striv_it++, "Cannot increment an iterator already at the end."); +} + +int main() { + cannot_increment_at_the_end_iterator(); + return 0; +} From 3361ec3f2955e1d5789043519380834e47a800d5 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 16 Oct 2023 10:30:07 -0400 Subject: [PATCH 027/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix off-by-one error in iterator equal test. --- .../range.adaptors/range.stride.view/iterator/equal.pass.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp index 7f2711adc5179..ff5196d26476c 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp @@ -26,8 +26,8 @@ constexpr void testOne() { { // simple test { - int buffer[] = {0, 1, 2, -1, 4, 5, 6}; - Range input(Iter{buffer}, Iter{buffer + 7}); + int buffer[] = {0, 1, 2, -1, 4, 5, 6, 7}; + Range input(Iter{buffer}, Iter{buffer + 8}); StrideView sv(input, 1); StrideView sv_too(input, 2); auto b = sv.begin(), e = sv.end(); From cfe70d19b4586b3d8e4dc38b097b775571b529da Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 16 Oct 2023 10:32:30 -0400 Subject: [PATCH 028/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add test for non-default constructible iterator of strided-over range. --- .../iterator/ctor.default.pass.cpp | 38 ++++++++++++++++++- .../range.adaptors/range.stride.view/test.h | 5 +++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp index acd26c35a5db2..02c261db28017 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp @@ -13,8 +13,6 @@ // std::views::stride_view #include "../test.h" -#include "__concepts/same_as.h" -#include "__ranges/stride_view.h" #include #include #include @@ -45,8 +43,44 @@ constexpr bool non_simple_view_iter_ctor_test() { return true; } +struct NonDefaultConstructibleIterator : InputIterBase { + NonDefaultConstructibleIterator() = delete; + constexpr NonDefaultConstructibleIterator(int) {} +}; + +struct View : std::ranges::view_base { + constexpr NonDefaultConstructibleIterator begin() const { return NonDefaultConstructibleIterator{5}; } + constexpr std::default_sentinel_t end() const { return {}; } +}; +template <> +inline constexpr bool std::ranges::enable_borrowed_range = true; + +constexpr bool iterator_default_constructible() { + { + // If the type of the iterator of the range being strided is non-default + // constructible, then the stride view's iterator should not be default + // constructible, either! + constexpr View v{}; + constexpr auto stride = std::ranges::stride_view(v, 1); + using stride_iterator_t = decltype(stride.begin()); + static_assert(!std::is_default_constructible(), ""); + } + { + // If the type of the iterator of the range being strided is default + // constructible, then the stride view's iterator should be default + // constructible, too! + constexpr int arr[] = {1, 2, 3}; + auto stride = std::ranges::stride_view(arr, 1); + using stride_iterator_t = decltype(stride.begin()); + static_assert(std::is_default_constructible(), ""); + } + + return true; +} + int main(int, char**) { non_simple_view_iter_ctor_test(); static_assert(non_simple_view_iter_ctor_test()); + static_assert(iterator_default_constructible()); return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index 6bef25b861888..3bf7d7b8a4f00 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -10,6 +10,7 @@ #define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H #include "__concepts/movable.h" +#include "__iterator/default_sentinel.h" #include "__ranges/concepts.h" #include "__ranges/enable_view.h" #include "__ranges/size.h" @@ -99,6 +100,8 @@ struct ForwardIterBase { constexpr Derived operator++(int) { return {}; } friend constexpr bool operator==(const ForwardIterBase&, const ForwardIterBase&) { return true; } + friend constexpr bool operator==(const std::default_sentinel_t&, const ForwardIterBase&) { return true; } + friend constexpr bool operator==(const ForwardIterBase&, const std::default_sentinel_t&) { return true; } }; template @@ -113,6 +116,8 @@ struct InputIterBase { constexpr Derived operator++(int) { return {}; } friend constexpr bool operator==(const InputIterBase&, const InputIterBase&) { return true; } + friend constexpr bool operator==(const std::default_sentinel_t&, const InputIterBase&) { return true; } + friend constexpr bool operator==(const InputIterBase&, const std::default_sentinel_t&) { return true; } }; struct NotSimpleViewIter : ForwardIterBase { From dd65af934e26e8d8692926a57e10e5e4dc5feea2 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 16 Oct 2023 16:27:26 -0400 Subject: [PATCH 029/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Move stride_view::iterator out of the views namespace. --- libcxx/include/__ranges/stride_view.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index ba05c34553fcf..b699868c0234a 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -118,8 +118,6 @@ class stride_view : public view_interface> { template stride_view(_Range&&, range_difference_t<_Range>) -> stride_view>; -namespace views { - template struct __stride_iterator_category {}; @@ -348,6 +346,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> } }; // class stride_view::__iterator +namespace views { namespace __stride { struct __fn { template From 57f9ee9fbb67983236c15bfacaa777ac48f1e106 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 23 Oct 2023 17:50:37 -0400 Subject: [PATCH 030/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix incorrect return type of base method in iterator. --- libcxx/include/__ranges/stride_view.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index b699868c0234a..f923e7f3795fa 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -181,8 +181,8 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> __stride_(__i.__stride_), __missing_(__i.__missing_) {} - _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> const& base() const& noexcept { return __current_; } - _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> base() && { return std::move(__current_); } + _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> const& base() const& noexcept { return __current_; } + _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); } _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return *__current_; } From b7d3ebd26a0fd89899399bc2b86f0cbf93402351 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 23 Oct 2023 17:52:06 -0400 Subject: [PATCH 031/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Refactor stride_view test types. --- .../range.adaptors/range.stride.view/test.h | 193 ++++++++++-------- 1 file changed, 112 insertions(+), 81 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index 3bf7d7b8a4f00..b2ea7098d75bc 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -9,11 +9,16 @@ #ifndef TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H #define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H +#include "__concepts/equality_comparable.h" #include "__concepts/movable.h" +#include "__concepts/semiregular.h" #include "__iterator/default_sentinel.h" +#include "__ranges/access.h" #include "__ranges/concepts.h" +#include "__ranges/enable_borrowed_range.h" #include "__ranges/enable_view.h" #include "__ranges/size.h" +#include "__ranges/stride_view.h" #include "test_iterators.h" #include #include @@ -115,12 +120,12 @@ struct InputIterBase { constexpr Derived& operator++() { return static_cast(*this); } constexpr Derived operator++(int) { return {}; } - friend constexpr bool operator==(const InputIterBase&, const InputIterBase&) { return true; } - friend constexpr bool operator==(const std::default_sentinel_t&, const InputIterBase&) { return true; } - friend constexpr bool operator==(const InputIterBase&, const std::default_sentinel_t&) { return true; } + friend constexpr bool operator==(const Derived&, const Derived&) { return true; } + friend constexpr bool operator==(const std::default_sentinel_t&, const Derived&) { return true; } + friend constexpr bool operator==(const Derived&, const std::default_sentinel_t&) { return true; } }; -struct NotSimpleViewIter : ForwardIterBase { +struct NotSimpleViewIter : InputIterBase { constexpr NotSimpleViewIter() = default; constexpr NotSimpleViewIter(const NotSimpleViewIter&) = default; constexpr NotSimpleViewIter(NotSimpleViewIter&&) = default; @@ -128,7 +133,7 @@ struct NotSimpleViewIter : ForwardIterBase { constexpr NotSimpleViewIter& operator=(const NotSimpleViewIter&) = default; }; -struct NotSimpleViewIterEnd : ForwardIterBase { +struct NotSimpleViewIterEnd : InputIterBase { constexpr NotSimpleViewIterEnd() = default; constexpr NotSimpleViewIterEnd(const NotSimpleViewIterEnd&) = default; constexpr NotSimpleViewIterEnd(NotSimpleViewIterEnd&&) = default; @@ -136,60 +141,128 @@ struct NotSimpleViewIterEnd : ForwardIterBase { constexpr NotSimpleViewIterEnd& operator=(const NotSimpleViewIterEnd&) = default; }; -struct ConstNotSimpleViewIter : ForwardIterBase { - constexpr ConstNotSimpleViewIter() = default; - constexpr ConstNotSimpleViewIter(const ConstNotSimpleViewIter&) = default; - constexpr ConstNotSimpleViewIter(const NotSimpleViewIter&) {} - constexpr ConstNotSimpleViewIter(ConstNotSimpleViewIter&&) = default; +template +struct NotSimpleViewConstIter : InputIterBase> { + constexpr NotSimpleViewConstIter() = default; + constexpr NotSimpleViewConstIter(const NotSimpleViewConstIter&) = default; + constexpr NotSimpleViewConstIter(const NotSimpleViewIter&) + requires Convertible + {} + constexpr NotSimpleViewConstIter(NotSimpleViewConstIter&&) = default; - constexpr ConstNotSimpleViewIter(NotSimpleViewIter&&) {} - constexpr ConstNotSimpleViewIter(NotSimpleViewIterEnd&&) = delete; + constexpr NotSimpleViewConstIter(NotSimpleViewIterEnd&&) = delete; - constexpr ConstNotSimpleViewIter& operator=(ConstNotSimpleViewIter&&) = default; - constexpr ConstNotSimpleViewIter& operator=(const ConstNotSimpleViewIter&) = default; + constexpr NotSimpleViewConstIter& operator=(NotSimpleViewConstIter&&) = default; + constexpr NotSimpleViewConstIter& operator=(const NotSimpleViewConstIter&) = default; }; -struct NotSimpleView : std::ranges::view_base { - constexpr ConstNotSimpleViewIter begin() const { return {}; } +template +constexpr bool operator==(const NotSimpleViewConstIter&, const NotSimpleViewIterEnd&) { + return true; +} +template +constexpr bool operator==(const NotSimpleViewIterEnd&, const NotSimpleViewConstIter&) { + return true; +} + +constexpr bool operator==(const NotSimpleViewIter&, const NotSimpleViewIterEnd&) { return true; } +constexpr bool operator==(const NotSimpleViewIterEnd&, const NotSimpleViewIter&) { return true; } + +template +struct NotSimpleViewDifferentBegin : std::ranges::view_base { + constexpr NotSimpleViewConstIter begin() const { return {}; } constexpr NotSimpleViewIter begin() { return {}; } - constexpr ConstNotSimpleViewIter end() const { return {}; } + constexpr NotSimpleViewIterEnd end() const { return {}; } constexpr NotSimpleViewIterEnd end() { return {}; } }; -struct RandomAccessView : std::ranges::view_base { - int* begin_; - int* end_; +template <> +inline constexpr bool std::ranges::enable_borrowed_range> = true; +template <> +inline constexpr bool std::ranges::enable_borrowed_range> = true; - constexpr RandomAccessView(int* b, int* e) : begin_(b), end_(e) {} +/* + * XXXArrayView classes for use throughout the stride view tests. + */ - constexpr random_access_iterator begin() { return random_access_iterator{begin_}; } - //constexpr random_access_iterator begin() const { return random_access_iterator{begin_}; } - constexpr sentinel_wrapper> end() { - return sentinel_wrapper>{random_access_iterator{end_}}; +template +struct RandomAccessArrayView : std::ranges::view_base { + T* begin_; + T* end_; + + constexpr RandomAccessArrayView(T* b, T* e) : begin_(b), end_(e) {} + + constexpr random_access_iterator begin() { return random_access_iterator{begin_}; } + constexpr random_access_iterator begin() const { return random_access_iterator{begin_}; } + constexpr sentinel_wrapper> end() { + return sentinel_wrapper>{random_access_iterator{end_}}; + } + constexpr sentinel_wrapper> end() const { + return sentinel_wrapper>{random_access_iterator{end_}}; } - //constexpr sentinel_wrapper> end() const { return sentinel_wrapper>{random_access_iterator{end_}}; } constexpr std::size_t size() const { return end_ - begin_; } }; +static_assert(std::ranges::view>); +static_assert(std::ranges::random_access_range>); +static_assert(std::copyable>); -static_assert(std::ranges::view); -static_assert(std::ranges::random_access_range); -static_assert(std::copyable); +template +struct BidirArrayView : std::ranges::view_base { + T* begin_; + T* end_; -struct BidirView : std::ranges::view_base { - int* begin_; - int* end_; + constexpr BidirArrayView(T* b, T* e) : begin_(b), end_(e) {} - constexpr BidirView(int* b, int* e) : begin_(b), end_(e) {} + constexpr bidirectional_iterator begin() { return bidirectional_iterator{begin_}; } + constexpr bidirectional_iterator begin() const { return bidirectional_iterator{begin_}; } + constexpr sentinel_wrapper> end() { + return sentinel_wrapper>{bidirectional_iterator{end_}}; + } + constexpr sentinel_wrapper> end() const { + return sentinel_wrapper>{bidirectional_iterator{end_}}; + } +}; +static_assert(std::ranges::view>); +static_assert(std::ranges::bidirectional_range>); +static_assert(std::copyable>); + +template +struct ForwardArrayView : public std::ranges::view_base { + T* begin_; + T* end_; - constexpr bidirectional_iterator begin() { return bidirectional_iterator{begin_}; } - constexpr bidirectional_iterator begin() const { return bidirectional_iterator{begin_}; } - constexpr sentinel_wrapper> end() { - return sentinel_wrapper>{bidirectional_iterator{end_}}; + constexpr ForwardArrayView(T* b, T* e) : begin_(b), end_(e) {} + + constexpr forward_iterator begin() { return forward_iterator{begin_}; } + constexpr forward_iterator begin() const { return forward_iterator{begin_}; } + constexpr sentinel_wrapper> end() { + return sentinel_wrapper>{forward_iterator{end_}}; } - constexpr sentinel_wrapper> end() const { - return sentinel_wrapper>{bidirectional_iterator{end_}}; + constexpr sentinel_wrapper> end() const { + return sentinel_wrapper>{forward_iterator{end_}}; } }; +static_assert(std::ranges::view>); +static_assert(std::ranges::forward_range>); +static_assert(std::copyable>); + +template +struct InputArrayView : std::ranges::view_base { + T* begin_; + T* end_; + + constexpr InputArrayView(T* b, T* e) : begin_(b), end_(e) {} + + constexpr cpp20_input_iterator begin() { return cpp20_input_iterator{begin_}; } + constexpr random_access_iterator begin() const { return random_access_iterator{begin_}; } + constexpr sentinel_wrapper> end() { + return sentinel_wrapper>{cpp20_input_iterator{end_}}; + } + constexpr std::size_t size() const { return end_ - begin_; } +}; +static_assert(std::ranges::view>); +static_assert(std::ranges::input_range>); +static_assert(std::copyable>); struct ForwardTracedMoveIter : ForwardIterBase { bool moved = false; @@ -206,48 +279,6 @@ struct ForwardTracedMoveView : std::ranges::view_base { constexpr ForwardTracedMoveIter end() const { return {}; } }; -static_assert(std::ranges::view); -static_assert(std::ranges::bidirectional_range); -static_assert(std::copyable); - -struct ForwardView : public std::ranges::view_base { - int* begin_; - int* end_; - - constexpr ForwardView(int* b, int* e) : begin_(b), end_(e) {} - - constexpr forward_iterator begin() { return forward_iterator{begin_}; } - constexpr forward_iterator begin() const { return forward_iterator{begin_}; } - constexpr sentinel_wrapper> end() { - return sentinel_wrapper>{forward_iterator{end_}}; - } - constexpr sentinel_wrapper> end() const { - return sentinel_wrapper>{forward_iterator{end_}}; - } -}; - -static_assert(std::ranges::view); -static_assert(std::ranges::forward_range); -static_assert(std::copyable); - -struct InputView : std::ranges::view_base { - int* begin_; - int* end_; - - constexpr InputView(int* b, int* e) : begin_(b), end_(e) {} - - constexpr cpp20_input_iterator begin() { return cpp20_input_iterator{begin_}; } - //constexpr random_access_iterator begin() const { return random_access_iterator{begin_}; } - constexpr sentinel_wrapper> end() { - return sentinel_wrapper>{cpp20_input_iterator{end_}}; - } - constexpr std::size_t size() const { return end_ - begin_; } -}; - -static_assert(std::ranges::view); -static_assert(std::ranges::input_range); -static_assert(std::copyable); - struct UnsizedBasicRangeIterator : ForwardIterBase {}; struct UnsizedBasicRange : std::ranges::view_base { From 36df533e7f66fe331baf15f71256010488d57dee Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 23 Oct 2023 17:55:20 -0400 Subject: [PATCH 032/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. More refactoring and adding a (first test) for convertible iterators. --- .../range.stride.view/adaptor.pass.cpp | 35 ++++++----- .../range.stride.view/ctor.pass.cpp | 4 +- .../range.stride.view/iterator/begin.pass.cpp | 16 ++--- .../iterator/ctor.default.pass.cpp | 61 ++++++++++++------- .../range.stride.view/stride.pass.cpp | 6 +- 5 files changed, 71 insertions(+), 51 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index 60ed5587933a0..02e57c8865709 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -33,10 +33,11 @@ constexpr bool test() { // view | stride { { - BidirView view(arr, arr + array_n); + BidirArrayView view(arr, arr + array_n); //std::ranges::stride_view strided(view, 1); - std::same_as> decltype(auto) strided = view | std::views::stride(1); - auto strided_iter = strided.begin(); + std::same_as>> decltype(auto) strided = + view | std::views::stride(1); + auto strided_iter = strided.begin(); // Check that the begin() iter views arr[0] assert(*strided_iter == arr[0]); @@ -46,9 +47,10 @@ constexpr bool test() { assert(*strided_iter == arr[2]); } { - BidirView view(arr, arr + array_n); - std::same_as> decltype(auto) strided = view | std::views::stride(2); - auto strided_iter = strided.begin(); + BidirArrayView view(arr, arr + array_n); + std::same_as>> decltype(auto) strided = + view | std::views::stride(2); + auto strided_iter = strided.begin(); assert(*strided_iter == arr[0]); @@ -65,7 +67,7 @@ constexpr bool test() { // Parallels the two tests from above. constexpr auto identity_lambda = [](int i) { return i * 2; }; { - BidirView view(arr, arr + array_n); + BidirArrayView view(arr, arr + array_n); const auto transform_stride_partial = std::views::transform(identity_lambda) | std::views::stride(1); const auto transform_stride_applied = transform_stride_partial(view); @@ -76,7 +78,7 @@ constexpr bool test() { } { - BidirView view(arr, arr + array_n); + BidirArrayView view(arr, arr + array_n); const auto transform_stride_partial = std::views::transform(identity_lambda) | std::views::stride(2); const auto transform_stride_applied = transform_stride_partial(view); @@ -88,9 +90,9 @@ constexpr bool test() { } { - using ForwardStrideView = std::ranges::stride_view; - using BidirStrideView = std::ranges::stride_view; - using RandomAccessStrideView = std::ranges::stride_view; + using ForwardStrideView = std::ranges::stride_view>; + using BidirStrideView = std::ranges::stride_view>; + using RandomAccessStrideView = std::ranges::stride_view>; static_assert(std::ranges::forward_range); static_assert(std::ranges::bidirectional_range); @@ -107,12 +109,15 @@ constexpr bool test() { // Not invocable because NotAViewableRange is, well, not a viewable range. static_assert(!std::is_invocable_v); // Is invocable because BidirView is a viewable range. - static_assert(std::is_invocable_v); + static_assert(std::is_invocable_v>); // Make sure that pipe operations work! - static_assert(CanBePiped{}))>); - static_assert(CanBePiped{}))>); - static_assert(!CanBePiped{}))>); + static_assert(CanBePiped, + decltype(std::views::stride(std::ranges::range_difference_t>{}))>); + static_assert(CanBePiped&, + decltype(std::views::stride(std::ranges::range_difference_t>{}))>); + static_assert( + !CanBePiped>{}))>); } // A final sanity check. { static_assert(std::same_as); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp index a205386fa0a9d..30256ac12b77e 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp @@ -18,13 +18,13 @@ constexpr bool test_no_default_ctor() { // There is no default ctor for stride_view. - static_assert(!std::is_default_constructible_v>); + static_assert(!std::is_default_constructible_v>>); return true; } constexpr bool test_no_implicit_ctor() { // Test that the stride_view can only be explicitly constructed. - static_assert(!test_convertible, ForwardView, int>()); + static_assert(!test_convertible>, ForwardArrayView, int>()); return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp index b6b871bd69106..6a9b1df59961b 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp @@ -21,8 +21,8 @@ constexpr bool iterator_concept_test() { { int arr[] = {1, 2, 3}; // Iterator of stride over random access view should have random access concept. - auto rav = RandomAccessView(arr, arr + 3); - auto str = std::ranges::stride_view(rav, 1); + auto rav = RandomAccessArrayView(arr, arr + 3); + auto str = std::ranges::stride_view>(rav, 1); static_assert(std::random_access_iterator); static_assert(std::random_access_iterator); } @@ -30,8 +30,8 @@ constexpr bool iterator_concept_test() { { int arr[] = {1, 2, 3}; // Iterator of stride over bidirectional view should have bidirectional view concept. - auto rav = BidirView(arr, arr + 3); - auto str = std::ranges::stride_view(rav, 1); + auto rav = BidirArrayView(arr, arr + 3); + auto str = std::ranges::stride_view>(rav, 1); static_assert(std::bidirectional_iterator); static_assert(std::bidirectional_iterator); static_assert(!std::random_access_iterator); @@ -41,8 +41,8 @@ constexpr bool iterator_concept_test() { { int arr[] = {1, 2, 3}; // Iterator of stride over forward view should have forward view concept. - auto rav = ForwardView(arr, arr + 3); - auto str = std::ranges::stride_view(rav, 1); + auto rav = ForwardArrayView(arr, arr + 3); + auto str = std::ranges::stride_view>(rav, 1); static_assert(std::forward_iterator); static_assert(std::forward_iterator); static_assert(!std::bidirectional_iterator); @@ -54,8 +54,8 @@ constexpr bool iterator_concept_test() { { int arr[] = {1, 2, 3}; // Iterator of stride over input view should have input view concept. - auto rav = InputView(arr, arr + 3); - auto str = std::ranges::stride_view(rav, 1); + auto rav = InputArrayView(arr, arr + 3); + auto str = std::ranges::stride_view>(rav, 1); static_assert(std::input_iterator); static_assert(std::input_iterator); static_assert(!std::forward_iterator); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp index 02c261db28017..567c9b1af0be0 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp @@ -13,33 +13,19 @@ // std::views::stride_view #include "../test.h" +#include "__concepts/convertible_to.h" +#include "__ranges/access.h" +#include "__ranges/concepts.h" +#include "__ranges/stride_view.h" #include #include #include constexpr bool non_simple_view_iter_ctor_test() { - using NotSimpleStrideView = std::ranges::stride_view; - using NotSimpleStrideViewIter = std::ranges::iterator_t; - - using SimpleStrideView = std::ranges::stride_view; - using SimpleStrideViewIter = std::ranges::iterator_t; - - NotSimpleStrideView nsv{NotSimpleView{}, 1}; - [[maybe_unused]] NotSimpleStrideViewIter nsv_iter = nsv.begin(); - - SimpleStrideView sv{ForwardTracedMoveView{}, 1}; - [[maybe_unused]] SimpleStrideViewIter ssv_iter = sv.begin(); - + using NotSimpleStrideView = std::ranges::stride_view>; + using NotSimpleStrideViewIter = std::ranges::iterator_t; using NotSimpleStrideViewIterConst = std::ranges::iterator_t; - using SimpleStrideViewIterConst = std::ranges::iterator_t; - - // .begin on a stride view over a non-simple view will give us a - // stride_view iterator with its _Const == false. Compare that type - // with an iterator on a stride view over a simple view that will give - // us an iterator with its _Const == true. They should *not* be the same. - static_assert(!std::is_same_v); - static_assert(!std::is_same_v); - static_assert(std::is_same_v); + static_assert(!std::is_same_v); return true; } @@ -63,7 +49,7 @@ constexpr bool iterator_default_constructible() { constexpr View v{}; constexpr auto stride = std::ranges::stride_view(v, 1); using stride_iterator_t = decltype(stride.begin()); - static_assert(!std::is_default_constructible(), ""); + static_assert(!std::is_default_constructible()); } { // If the type of the iterator of the range being strided is default @@ -72,9 +58,37 @@ constexpr bool iterator_default_constructible() { constexpr int arr[] = {1, 2, 3}; auto stride = std::ranges::stride_view(arr, 1); using stride_iterator_t = decltype(stride.begin()); - static_assert(std::is_default_constructible(), ""); + static_assert(std::is_default_constructible()); + } + + return true; +} + +constexpr bool non_const_iterator_copy_ctor() { + { + // Instantiate a stride view over a non-simple view whose const/non-const iterators are not-convertible. + using NotSimpleStrideView = std::ranges::stride_view>; + using NotSimpleStrideViewIter = std::ranges::iterator_t; + using NotSimpleStrideViewConstIter = std::ranges::iterator_t; + + // It should not be possible to construct a stride view iterator from a non-const stride view iterator + // when the strided-over type has inconvertible iterator types. + static_assert(!std::ranges::__simple_view); + static_assert(!std::convertible_to); + static_assert(!std::is_constructible_v); } + { + // Instantiate a stride view over a non-simple view whose const/non-const iterators are convertible. + using NotSimpleStrideView = std::ranges::stride_view>; + using NotSimpleStrideViewIter = std::ranges::iterator_t; + using NotSimpleStrideViewConstIter = std::ranges::iterator_t; + // It should be possible to construct a stride view iterator from a non-const stride view iterator + // when the strided-over type has convertible iterator types. + static_assert(!std::ranges::__simple_view); + static_assert(std::convertible_to); + static_assert(std::is_constructible_v); + } return true; } @@ -82,5 +96,6 @@ int main(int, char**) { non_simple_view_iter_ctor_test(); static_assert(non_simple_view_iter_ctor_test()); static_assert(iterator_default_constructible()); + static_assert(non_const_iterator_copy_ctor()); return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp index 80092fc673870..154f747f49bd7 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp @@ -18,9 +18,9 @@ #include constexpr bool test() { - static_assert(noexcept(std::declval>().stride())); - static_assert(std::is_same_v, - decltype(std::declval>().stride())>); + static_assert(noexcept(std::declval>>().stride())); + static_assert(std::is_same_v>, + decltype(std::declval>>().stride())>); return true; } From a8002bf9b327d8821e3a0559f86bdb80f3642fb5 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Thu, 26 Oct 2023 23:05:18 -0400 Subject: [PATCH 033/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Make sure that all necessary includes are, well, included.. --- libcxx/include/__ranges/stride_view.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index f923e7f3795fa..93eb4a4737178 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -12,12 +12,21 @@ #include <__config> +#include <__compare/three_way_comparable.h> +#include <__concepts/convertible_to.h> +#include <__concepts/derived_from.h> +#include <__concepts/equality_comparable.h> #include <__functional/bind_back.h> +#include <__iterator/concepts.h> #include <__iterator/default_sentinel.h> #include <__iterator/distance.h> +#include <__iterator/iter_move.h> #include <__iterator/iter_swap.h> +#include <__iterator/iterator_traits.h> +#include <__ranges/access.h> #include <__ranges/all.h> #include <__ranges/concepts.h> +#include <__ranges/range_adaptor.h> #include <__ranges/view_interface.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) From 30c4eb6f4f36f26cefd5e34a19c9bda1fa6a1339 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Thu, 26 Oct 2023 23:07:41 -0400 Subject: [PATCH 034/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add additional iterator copy constructor covertible to tests. --- .../iterator/ctor.default.pass.cpp | 34 ++++++++++++++++--- .../range.adaptors/range.stride.view/test.h | 34 +++++++++++++++++++ 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp index 567c9b1af0be0..d782413375e4d 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp @@ -66,25 +66,51 @@ constexpr bool iterator_default_constructible() { constexpr bool non_const_iterator_copy_ctor() { { - // Instantiate a stride view over a non-simple view whose const/non-const iterators are not-convertible. + // Instantiate a stride view over a non-simple view whose const/non-const begin iterators are not-convertible. using NotSimpleStrideView = std::ranges::stride_view>; using NotSimpleStrideViewIter = std::ranges::iterator_t; using NotSimpleStrideViewConstIter = std::ranges::iterator_t; // It should not be possible to construct a stride view iterator from a non-const stride view iterator - // when the strided-over type has inconvertible iterator types. + // when the strided-over type has inconvertible begin iterator types. static_assert(!std::ranges::__simple_view); static_assert(!std::convertible_to); static_assert(!std::is_constructible_v); } { - // Instantiate a stride view over a non-simple view whose const/non-const iterators are convertible. + // Instantiate a stride view over a non-simple view whose const/non-const begin iterators are convertible. using NotSimpleStrideView = std::ranges::stride_view>; using NotSimpleStrideViewIter = std::ranges::iterator_t; using NotSimpleStrideViewConstIter = std::ranges::iterator_t; // It should be possible to construct a stride view iterator from a non-const stride view iterator - // when the strided-over type has convertible iterator types. + // when the strided-over type has convertible begin iterator types. + static_assert(!std::ranges::__simple_view); + static_assert(std::convertible_to); + static_assert(std::is_constructible_v); + } + + { + // Instantiate a stride view over a non-simple view whose const/non-const end iterators are not convertible. + using NotSimpleStrideView = std::ranges::stride_view>; + using NotSimpleStrideViewIter = std::ranges::iterator_t; + using NotSimpleStrideViewConstIter = std::ranges::iterator_t; + + // It should not be possible to construct a stride view iterator from a non-const stride view iterator + // when the strided-over type has inconvertible end iterator types. + static_assert(!std::ranges::__simple_view); + static_assert(!std::convertible_to); + static_assert(!std::is_constructible_v); + } + + { + // Instantiate a stride view over a non-simple view whose const/non-const end iterators are convertible. + using NotSimpleStrideView = std::ranges::stride_view>; + using NotSimpleStrideViewIter = std::ranges::iterator_t; + using NotSimpleStrideViewConstIter = std::ranges::iterator_t; + + // It should not be possible to construct a stride view iterator from a non-const stride view iterator + // when the strided-over type has inconvertible end iterator types. static_assert(!std::ranges::__simple_view); static_assert(std::convertible_to); static_assert(std::is_constructible_v); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index b2ea7098d75bc..993b595093f04 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -141,6 +141,18 @@ struct NotSimpleViewIterEnd : InputIterBase { constexpr NotSimpleViewIterEnd& operator=(const NotSimpleViewIterEnd&) = default; }; +template +struct NotSimpleViewConstIterEnd : InputIterBase> { + constexpr NotSimpleViewConstIterEnd() = default; + constexpr NotSimpleViewConstIterEnd(const NotSimpleViewConstIterEnd&) = default; + constexpr NotSimpleViewConstIterEnd(const NotSimpleViewIterEnd&) + requires Convertible + {} + constexpr NotSimpleViewConstIterEnd(NotSimpleViewConstIterEnd&&) = default; + constexpr NotSimpleViewConstIterEnd& operator=(NotSimpleViewConstIterEnd&&) = default; + constexpr NotSimpleViewConstIterEnd& operator=(const NotSimpleViewConstIterEnd&) = default; +}; + template struct NotSimpleViewConstIter : InputIterBase> { constexpr NotSimpleViewConstIter() = default; @@ -168,6 +180,15 @@ constexpr bool operator==(const NotSimpleViewIterEnd&, const NotSimpleViewConstI constexpr bool operator==(const NotSimpleViewIter&, const NotSimpleViewIterEnd&) { return true; } constexpr bool operator==(const NotSimpleViewIterEnd&, const NotSimpleViewIter&) { return true; } +template +constexpr bool operator==(const NotSimpleViewConstIter&, const NotSimpleViewConstIterEnd&) { + return true; +} +template +constexpr bool operator==(const NotSimpleViewConstIterEnd&, const NotSimpleViewConstIter&) { + return true; +} + template struct NotSimpleViewDifferentBegin : std::ranges::view_base { constexpr NotSimpleViewConstIter begin() const { return {}; } @@ -181,6 +202,19 @@ inline constexpr bool std::ranges::enable_borrowed_range inline constexpr bool std::ranges::enable_borrowed_range> = true; +template +struct NotSimpleViewDifferentEnd : std::ranges::view_base { + constexpr NotSimpleViewConstIter begin() const { return {}; } + constexpr NotSimpleViewConstIter begin() { return {}; } + constexpr NotSimpleViewConstIterEnd end() const { return {}; } + constexpr NotSimpleViewIterEnd end() { return {}; } +}; + +template <> +inline constexpr bool std::ranges::enable_borrowed_range> = true; +template <> +inline constexpr bool std::ranges::enable_borrowed_range> = true; + /* * XXXArrayView classes for use throughout the stride view tests. */ From af49bf3b04452001f0ab38cf108bef68c5ab24e2 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 27 Oct 2023 01:53:03 -0400 Subject: [PATCH 035/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Include __iterator/advance.h to support ranges::advance. --- libcxx/include/__ranges/stride_view.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 93eb4a4737178..add002687a869 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -17,6 +17,7 @@ #include <__concepts/derived_from.h> #include <__concepts/equality_comparable.h> #include <__functional/bind_back.h> +#include <__iterator/advance.h> #include <__iterator/concepts.h> #include <__iterator/default_sentinel.h> #include <__iterator/distance.h> From 308ede48e7f5592c14df439a8bb71f088fed1dc1 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 27 Oct 2023 09:08:17 -0400 Subject: [PATCH 036/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fixup libcxx iterator increment assertion test. --- .../range.stride.view/iterator/increment.pass.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp index 0100dd1708b0d..667b74e4c3d51 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp @@ -16,13 +16,11 @@ // Call .... #include "check_assertion.h" -#include "../../test/std/ranges/range.adaptors/range.stride.view/test.h" #include void cannot_increment_at_the_end_iterator() { int range[] = {1, 2, 3}; - auto iv = InputView(range, range + 3); - auto striv = std::ranges::views::stride(iv, 3); + auto striv = std::ranges::views::stride(range, 3); auto striv_it = striv.begin(); striv_it++; TEST_LIBCPP_ASSERT_FAILURE(striv_it++, "Cannot increment an iterator already at the end."); From f699402ee26c7e91c7df5a4a69b9200d72d255db Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sun, 29 Oct 2023 15:55:29 -0400 Subject: [PATCH 037/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add test for move-only constructor for iterators for stride views over non simple views. --- .../iterator/ctor.default.pass.cpp | 133 +++++++++++++++++- .../range.adaptors/range.stride.view/test.h | 90 ------------ 2 files changed, 126 insertions(+), 97 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp index d782413375e4d..b27c686ccaf10 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp @@ -14,12 +14,107 @@ #include "../test.h" #include "__concepts/convertible_to.h" +#include "__iterator/concepts.h" #include "__ranges/access.h" #include "__ranges/concepts.h" #include "__ranges/stride_view.h" #include #include #include +#include + +struct NotSimpleViewIter : InputIterBase {}; +struct NotSimpleViewIterEnd : InputIterBase {}; +constexpr bool operator==(const NotSimpleViewIter&, const NotSimpleViewIterEnd&) { return true; } +constexpr bool operator==(const NotSimpleViewIterEnd&, const NotSimpleViewIter&) { return true; } + +template +struct NotSimpleViewConstIterEnd : InputIterBase> { + constexpr NotSimpleViewConstIterEnd() = default; + constexpr NotSimpleViewConstIterEnd(const NotSimpleViewConstIterEnd&&) {} + constexpr NotSimpleViewConstIterEnd& operator=(const NotSimpleViewConstIterEnd&) {} + constexpr NotSimpleViewConstIterEnd& operator=(const NotSimpleViewConstIterEnd&&) {} + + constexpr NotSimpleViewConstIterEnd(const NotSimpleViewConstIterEnd&) + requires Copyable + {} + constexpr NotSimpleViewConstIterEnd(const NotSimpleViewIterEnd&) + requires Convertible + {} +}; + +template +struct NotSimpleViewConstIter : InputIterBase> { + constexpr NotSimpleViewConstIter() = default; + constexpr NotSimpleViewConstIter(const NotSimpleViewConstIter&&) {} + constexpr NotSimpleViewConstIter& operator=(const NotSimpleViewConstIter&&) {} + constexpr NotSimpleViewConstIter& operator=(const NotSimpleViewConstIter&) {} + + constexpr NotSimpleViewConstIter(const NotSimpleViewConstIter&) + requires Copyable + {} + constexpr NotSimpleViewConstIter(const NotSimpleViewIter&) + requires Convertible + {} +}; + +template +constexpr bool operator==(const NotSimpleViewConstIter&, const NotSimpleViewIterEnd&) { + return true; +} +template +constexpr bool operator==(const NotSimpleViewIterEnd&, const NotSimpleViewConstIter&) { + return true; +} +template +constexpr bool operator==(const NotSimpleViewConstIterEnd&, const NotSimpleViewIterEnd&) { + return true; +} +template +constexpr bool operator==(const NotSimpleViewIterEnd&, const NotSimpleViewConstIterEnd&) { + return true; +} +template +constexpr bool operator==(const NotSimpleViewIter&, const NotSimpleViewConstIterEnd&) { + return true; +} +template +constexpr bool operator==(const NotSimpleViewConstIterEnd&, const NotSimpleViewIter&) { + return true; +} + +/* + * There are (at least) two ways that a view can be non-simple: + * 1. The iterator type for const begin is different than the iterator type for begin + * 2. The iterator type for const end is different that the iterator type for end + * + * So, let's create two different classes where that is the case so that we can test + * for those conditions individually. We parameterize with a template to decide + * whether to + * 1. enable converting constructors between the non-const and the const version. + * That feature is important for testing the stride_view::__iterator converting + * constructor from a stride_view::_iterator iterator. + * 2. enable copyability. That feature is important for testing whether the requirement + * the that copy constructor for the stride_view::__iterator type actually moves + * the underlying iterator. + */ +template +struct NotSimpleViewDifferentBegin : std::ranges::view_base { + constexpr NotSimpleViewConstIter begin() const { return {}; } + constexpr NotSimpleViewIter begin() { return {}; } + constexpr NotSimpleViewIterEnd end() const { return {}; } + constexpr NotSimpleViewIterEnd end() { return {}; } +}; + +template +struct NotSimpleViewDifferentEnd : std::ranges::view_base { + constexpr NotSimpleViewIter begin() const { return {}; } + constexpr NotSimpleViewIter begin() { return {}; } + constexpr NotSimpleViewConstIterEnd end() const { + return std::move(NotSimpleViewConstIterEnd{}); + } + constexpr NotSimpleViewIterEnd end() { return {}; } +}; constexpr bool non_simple_view_iter_ctor_test() { using NotSimpleStrideView = std::ranges::stride_view>; @@ -34,19 +129,19 @@ struct NonDefaultConstructibleIterator : InputIterBase -inline constexpr bool std::ranges::enable_borrowed_range = true; +inline constexpr bool std::ranges::enable_borrowed_range = true; constexpr bool iterator_default_constructible() { { // If the type of the iterator of the range being strided is non-default // constructible, then the stride view's iterator should not be default // constructible, either! - constexpr View v{}; + constexpr ViewWithNonDefaultConstructibleIterator v{}; constexpr auto stride = std::ranges::stride_view(v, 1); using stride_iterator_t = decltype(stride.begin()); static_assert(!std::is_default_constructible()); @@ -67,7 +162,7 @@ constexpr bool iterator_default_constructible() { constexpr bool non_const_iterator_copy_ctor() { { // Instantiate a stride view over a non-simple view whose const/non-const begin iterators are not-convertible. - using NotSimpleStrideView = std::ranges::stride_view>; + using NotSimpleStrideView = std::ranges::stride_view>; using NotSimpleStrideViewIter = std::ranges::iterator_t; using NotSimpleStrideViewConstIter = std::ranges::iterator_t; @@ -79,7 +174,7 @@ constexpr bool non_const_iterator_copy_ctor() { } { // Instantiate a stride view over a non-simple view whose const/non-const begin iterators are convertible. - using NotSimpleStrideView = std::ranges::stride_view>; + using NotSimpleStrideView = std::ranges::stride_view>; using NotSimpleStrideViewIter = std::ranges::iterator_t; using NotSimpleStrideViewConstIter = std::ranges::iterator_t; @@ -92,10 +187,12 @@ constexpr bool non_const_iterator_copy_ctor() { { // Instantiate a stride view over a non-simple view whose const/non-const end iterators are not convertible. - using NotSimpleStrideView = std::ranges::stride_view>; + using NotSimpleStrideView = std::ranges::stride_view>; using NotSimpleStrideViewIter = std::ranges::iterator_t; using NotSimpleStrideViewConstIter = std::ranges::iterator_t; + static_assert(std::ranges::__can_borrow); + // It should not be possible to construct a stride view iterator from a non-const stride view iterator // when the strided-over type has inconvertible end iterator types. static_assert(!std::ranges::__simple_view); @@ -105,14 +202,36 @@ constexpr bool non_const_iterator_copy_ctor() { { // Instantiate a stride view over a non-simple view whose const/non-const end iterators are convertible. - using NotSimpleStrideView = std::ranges::stride_view>; + using NotSimpleStrideView = std::ranges::stride_view>; using NotSimpleStrideViewIter = std::ranges::iterator_t; using NotSimpleStrideViewConstIter = std::ranges::iterator_t; // It should not be possible to construct a stride view iterator from a non-const stride view iterator // when the strided-over type has inconvertible end iterator types. + static_assert(std::is_copy_constructible_v); + static_assert(!std::ranges::__simple_view); + static_assert(std::convertible_to); + static_assert(std::is_constructible_v); + } + + { + // Instantiate a stride view over a non-simple view whose iterators are not copyable but whose const + // and non-const end iterators are convertible. + using NotSimpleStrideView = std::ranges::stride_view>; + using NotSimpleStrideViewIter = std::ranges::iterator_t; + using NotSimpleStrideViewConstIter = std::ranges::iterator_t; + + // It should not be possible to copy construct a stride view iterator from a non-const stride view iterator + // when the strided-over type has non copyable end iterator type. + static_assert(!std::is_copy_constructible_v); + + // Given the difference between the (non-) constness of the end iterator types and the fact that + // they can be converted between, it should + // 1. not be a simple view static_assert(!std::ranges::__simple_view); + // 2. the types should be convertible static_assert(std::convertible_to); + // 3. and a const thing should be constructible from a non const thing because they are convertible. static_assert(std::is_constructible_v); } return true; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index 993b595093f04..967c75c9cf002 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -125,96 +125,6 @@ struct InputIterBase { friend constexpr bool operator==(const Derived&, const std::default_sentinel_t&) { return true; } }; -struct NotSimpleViewIter : InputIterBase { - constexpr NotSimpleViewIter() = default; - constexpr NotSimpleViewIter(const NotSimpleViewIter&) = default; - constexpr NotSimpleViewIter(NotSimpleViewIter&&) = default; - constexpr NotSimpleViewIter& operator=(NotSimpleViewIter&&) = default; - constexpr NotSimpleViewIter& operator=(const NotSimpleViewIter&) = default; -}; - -struct NotSimpleViewIterEnd : InputIterBase { - constexpr NotSimpleViewIterEnd() = default; - constexpr NotSimpleViewIterEnd(const NotSimpleViewIterEnd&) = default; - constexpr NotSimpleViewIterEnd(NotSimpleViewIterEnd&&) = default; - constexpr NotSimpleViewIterEnd& operator=(NotSimpleViewIterEnd&&) = default; - constexpr NotSimpleViewIterEnd& operator=(const NotSimpleViewIterEnd&) = default; -}; - -template -struct NotSimpleViewConstIterEnd : InputIterBase> { - constexpr NotSimpleViewConstIterEnd() = default; - constexpr NotSimpleViewConstIterEnd(const NotSimpleViewConstIterEnd&) = default; - constexpr NotSimpleViewConstIterEnd(const NotSimpleViewIterEnd&) - requires Convertible - {} - constexpr NotSimpleViewConstIterEnd(NotSimpleViewConstIterEnd&&) = default; - constexpr NotSimpleViewConstIterEnd& operator=(NotSimpleViewConstIterEnd&&) = default; - constexpr NotSimpleViewConstIterEnd& operator=(const NotSimpleViewConstIterEnd&) = default; -}; - -template -struct NotSimpleViewConstIter : InputIterBase> { - constexpr NotSimpleViewConstIter() = default; - constexpr NotSimpleViewConstIter(const NotSimpleViewConstIter&) = default; - constexpr NotSimpleViewConstIter(const NotSimpleViewIter&) - requires Convertible - {} - constexpr NotSimpleViewConstIter(NotSimpleViewConstIter&&) = default; - - constexpr NotSimpleViewConstIter(NotSimpleViewIterEnd&&) = delete; - - constexpr NotSimpleViewConstIter& operator=(NotSimpleViewConstIter&&) = default; - constexpr NotSimpleViewConstIter& operator=(const NotSimpleViewConstIter&) = default; -}; - -template -constexpr bool operator==(const NotSimpleViewConstIter&, const NotSimpleViewIterEnd&) { - return true; -} -template -constexpr bool operator==(const NotSimpleViewIterEnd&, const NotSimpleViewConstIter&) { - return true; -} - -constexpr bool operator==(const NotSimpleViewIter&, const NotSimpleViewIterEnd&) { return true; } -constexpr bool operator==(const NotSimpleViewIterEnd&, const NotSimpleViewIter&) { return true; } - -template -constexpr bool operator==(const NotSimpleViewConstIter&, const NotSimpleViewConstIterEnd&) { - return true; -} -template -constexpr bool operator==(const NotSimpleViewConstIterEnd&, const NotSimpleViewConstIter&) { - return true; -} - -template -struct NotSimpleViewDifferentBegin : std::ranges::view_base { - constexpr NotSimpleViewConstIter begin() const { return {}; } - constexpr NotSimpleViewIter begin() { return {}; } - constexpr NotSimpleViewIterEnd end() const { return {}; } - constexpr NotSimpleViewIterEnd end() { return {}; } -}; - -template <> -inline constexpr bool std::ranges::enable_borrowed_range> = true; -template <> -inline constexpr bool std::ranges::enable_borrowed_range> = true; - -template -struct NotSimpleViewDifferentEnd : std::ranges::view_base { - constexpr NotSimpleViewConstIter begin() const { return {}; } - constexpr NotSimpleViewConstIter begin() { return {}; } - constexpr NotSimpleViewConstIterEnd end() const { return {}; } - constexpr NotSimpleViewIterEnd end() { return {}; } -}; - -template <> -inline constexpr bool std::ranges::enable_borrowed_range> = true; -template <> -inline constexpr bool std::ranges::enable_borrowed_range> = true; - /* * XXXArrayView classes for use throughout the stride view tests. */ From 2687ed8d2e128de2389fc4f1f3b0fc59df4efbf9 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 30 Oct 2023 09:15:46 -0400 Subject: [PATCH 038/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix formatting issue with iterator/ctor.default.pass.cpp. --- .../range.stride.view/iterator/ctor.default.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp index b27c686ccaf10..5a954fc73ef3e 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp @@ -90,7 +90,7 @@ constexpr bool operator==(const NotSimpleViewConstIterEnd * * So, let's create two different classes where that is the case so that we can test * for those conditions individually. We parameterize with a template to decide - * whether to + * whether to * 1. enable converting constructors between the non-const and the const version. * That feature is important for testing the stride_view::__iterator converting * constructor from a stride_view::_iterator iterator. From c281f85ac653cb021c83abcbe84ebb45720289f0 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 30 Oct 2023 10:28:15 -0400 Subject: [PATCH 039/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Remove default parameter missing in __iterator ctor. --- libcxx/include/__ranges/stride_view.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index add002687a869..ecf6065e20b70 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -77,13 +77,13 @@ class stride_view : public view_interface> { _LIBCPP_HIDE_FROM_ABI constexpr auto begin() requires(!__simple_view<_View>) { - return __iterator(this, ranges::begin(__base_)); + return __iterator(this, ranges::begin(__base_), 0); } _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const requires range { - return __iterator(this, ranges::begin(__base_)); + return __iterator(this, ranges::begin(__base_), 0); } _LIBCPP_HIDE_FROM_ABI constexpr auto end() @@ -93,7 +93,7 @@ class stride_view : public view_interface> { auto __missing = (__stride_ - ranges::distance(__base_) % __stride_) % __stride_; return __iterator(this, ranges::end(__base_), __missing); } else if constexpr (common_range<_View> && !bidirectional_range<_View>) { - return __iterator(this, ranges::end(__base_)); + return __iterator(this, ranges::end(__base_), 0); } else { return default_sentinel; } @@ -106,7 +106,7 @@ class stride_view : public view_interface> { auto __missing = (__stride_ - ranges::distance(__base_) % __stride_) % __stride_; return __iterator(this, ranges::end(__base_), __missing); } else if constexpr (common_range<_View> && !bidirectional_range<_View>) { - return __iterator(this, ranges::end(__base_)); + return __iterator(this, ranges::end(__base_), 0); } else { return default_sentinel; } @@ -155,7 +155,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> friend stride_view; _LIBCPP_HIDE_FROM_ABI constexpr __iterator( - _Parent* __parent, ranges::iterator_t<_Base> __current, range_difference_t<_Base> __missing = 0) + _Parent* __parent, ranges::iterator_t<_Base> __current, range_difference_t<_Base> __missing) : __current_(std::move(__current)), __end_(ranges::end(__parent->__base_)), __stride_(__parent->__stride_), From 1d2ec9f2f7db83e7175cc46fb5962f2b5da4324c Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 30 Oct 2023 22:44:57 -0400 Subject: [PATCH 040/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix minor formatting nit. --- .../range.stride.view/iterator/ctor.default.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp index 5a954fc73ef3e..56620b758ad6b 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp @@ -83,7 +83,7 @@ constexpr bool operator==(const NotSimpleViewConstIterEnd return true; } -/* +/* * There are (at least) two ways that a view can be non-simple: * 1. The iterator type for const begin is different than the iterator type for begin * 2. The iterator type for const end is different that the iterator type for end From 76e2a6e3c3254fc64df9b0236f8f80ddccf69e67 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 30 Oct 2023 22:45:25 -0400 Subject: [PATCH 041/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add test for __iterator::base noexcept. --- .../range.stride.view/iterator/base.pass.cpp | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp new file mode 100644 index 0000000000000..3fbc312b9f307 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::views::stride_view + +#include "../test.h" +#include + +constexpr bool base_noexcept() { + { + // If the type of the iterator of the range being strided is default + // constructible, then the stride view's iterator should be default + // constructible, too! + int arr[] = {1, 2, 3}; + auto stride = std::ranges::stride_view(arr, 1); + [[maybe_unused]] auto stride_iter = stride.begin(); + + static_assert(noexcept(stride_iter.base())); + static_assert(!noexcept((std::move(stride_iter).base()))); + } + + return true; +} + +int main(int, char**) { + base_noexcept(); + static_assert(base_noexcept()); + return 0; +} From 19783ae5854f2ecc36e14bb2119e4f168277d915 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 1 Nov 2023 09:40:27 -0400 Subject: [PATCH 042/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Test for (non) constness of iterator returned by __iterator::base. --- .../range.stride.view/iterator/base.pass.cpp | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp index 3fbc312b9f307..579bcea2d7186 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp @@ -14,25 +14,42 @@ #include "../test.h" #include +#include constexpr bool base_noexcept() { { - // If the type of the iterator of the range being strided is default - // constructible, then the stride view's iterator should be default - // constructible, too! int arr[] = {1, 2, 3}; auto stride = std::ranges::stride_view(arr, 1); [[maybe_unused]] auto stride_iter = stride.begin(); + // Check that calling base on an iterator where this is an lvalue reference + // is noexcept. static_assert(noexcept(stride_iter.base())); + // Calling base on an iterator where this is an rvalue reference may except. static_assert(!noexcept((std::move(stride_iter).base()))); } return true; } +constexpr bool base_const() { + { + int arr[] = {1, 2, 3}; + auto stride = std::ranges::stride_view(arr, 1); + [[maybe_unused]] auto stride_iter = stride.begin(); + + // Calling base on an iterator where this is lvalue returns a const ref to an iterator. + static_assert(std::is_const_v>); + // Calling base on an iterator where this is an rvalue reference returns a non-const iterator. + static_assert(!std::is_const_v); + } + + return true; +} int main(int, char**) { base_noexcept(); static_assert(base_noexcept()); + base_const(); + static_assert(base_const()); return 0; } From fa42b3bd5f226a62be74498d08958f4e55cc6216 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 1 Nov 2023 12:53:19 -0400 Subject: [PATCH 043/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add assertion for valid __current_ in __iterator::operator* (and test). --- libcxx/include/__ranges/stride_view.h | 13 ++++-- .../range.stride.view/iterator/end.pass.cpp | 41 +++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/end.pass.cpp diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index ecf6065e20b70..ea8cfc730d483 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -10,6 +10,9 @@ #ifndef _LIBCPP___RANGES_STRIDE_VIEW_H #define _LIBCPP___RANGES_STRIDE_VIEW_H +#include "__concepts/relation.h" +#include "__functional/ranges_operations.h" +#include "__iterator/indirectly_comparable.h" #include <__config> #include <__compare/three_way_comparable.h> @@ -17,6 +20,7 @@ #include <__concepts/derived_from.h> #include <__concepts/equality_comparable.h> #include <__functional/bind_back.h> +#include <__functional/operations.h> #include <__iterator/advance.h> #include <__iterator/concepts.h> #include <__iterator/default_sentinel.h> @@ -194,7 +198,10 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> const& base() const& noexcept { return __current_; } _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); } - _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return *__current_; } + _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { + _LIBCPP_ASSERT_UNCATEGORIZED(__current_ != __end_, "Cannot dereference an iterator at the end."); + return *__current_; + } _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() { _LIBCPP_ASSERT_UNCATEGORIZED(__current_ != __end_, "Cannot increment an iterator already at the end."); @@ -361,8 +368,8 @@ namespace __stride { struct __fn { template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) const - noexcept(noexcept(stride_view{std::forward<_Range>(__range), __n})) - -> decltype(stride_view{std::forward<_Range>(__range), __n}) { + noexcept(noexcept(stride_view{ + std::forward<_Range>(__range), __n})) -> decltype(stride_view{std::forward<_Range>(__range), __n}) { return stride_view(std::forward<_Range>(__range), __n); } diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/end.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/end.pass.cpp new file mode 100644 index 0000000000000..16516574070a0 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/end.pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 +// UNSUPPORTED: no-exceptions +// UNSUPPORTED: !libcpp-hardening-mode=debug +// XFAIL: availability-verbose_abort-missing + +// + +// Call .... + +#include "check_assertion.h" +#include + +void cannot_dereference_at_the_end_iterator() { + int range[] = {1, 2, 3}; + auto striv = std::ranges::views::stride(range, 3); + auto striv_it = striv.begin(); + striv_it++; + TEST_LIBCPP_ASSERT_FAILURE(*striv_it, "Cannot dereference an iterator at the end."); +} + +void cannot_dereference_past_the_end_iterator() { + int range[] = {1, 2, 3}; + auto striv = std::ranges::views::stride(range, 4); + auto striv_it = striv.begin(); + striv_it++; + TEST_LIBCPP_ASSERT_FAILURE(*striv_it, "Cannot dereference an iterator at the end."); +} + +int main() { + cannot_dereference_at_the_end_iterator(); + cannot_dereference_past_the_end_iterator(); + return 0; +} From 9c3b8af63cda504802115936ff76f64ac9b330db Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 1 Nov 2023 17:13:24 -0400 Subject: [PATCH 044/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix small formatting error in noexcept specification. --- libcxx/include/__ranges/stride_view.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index ea8cfc730d483..c2f7a9d35135d 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -368,8 +368,8 @@ namespace __stride { struct __fn { template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) const - noexcept(noexcept(stride_view{ - std::forward<_Range>(__range), __n})) -> decltype(stride_view{std::forward<_Range>(__range), __n}) { + noexcept(noexcept(stride_view{std::forward<_Range>(__range), __n})) + -> decltype(stride_view{std::forward<_Range>(__range), __n}) { return stride_view(std::forward<_Range>(__range), __n); } From 6de857da15d47aceedbd45d75b6b7a0df00ed14c Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 3 Nov 2023 09:05:01 -0400 Subject: [PATCH 045/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add assertion to __iterator::operator+= for valid stride length and test. --- libcxx/include/__ranges/stride_view.h | 6 ++-- .../iterator/operator_plus_equal.pass.cpp | 30 +++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index c2f7a9d35135d..8be633b65d914 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -237,6 +237,8 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> requires random_access_range<_Base> { if (__n > 0) { + _LIBCPP_ASSERT_UNCATEGORIZED(ranges::distance(__current_, __end_) > __stride_ * (__n - 1), + "Advancing the iterator beyond the end is not allowed."); ranges::advance(__current_, __stride_ * (__n - 1)); __missing_ = ranges::advance(__current_, __stride_, __end_); } else if (__n < 0) { @@ -368,8 +370,8 @@ namespace __stride { struct __fn { template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) const - noexcept(noexcept(stride_view{std::forward<_Range>(__range), __n})) - -> decltype(stride_view{std::forward<_Range>(__range), __n}) { + noexcept(noexcept(stride_view{ + std::forward<_Range>(__range), __n})) -> decltype(stride_view{std::forward<_Range>(__range), __n}) { return stride_view(std::forward<_Range>(__range), __n); } diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp new file mode 100644 index 0000000000000..caec0a2de71c6 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 +// UNSUPPORTED: no-exceptions +// UNSUPPORTED: !libcpp-hardening-mode=debug +// XFAIL: availability-verbose_abort-missing + +// + +// Call .... + +#include "check_assertion.h" +#include + +void operator_plus_equal_past_end_is_illegal() { + int range[] = {1, 2, 3}; + auto striv = std::ranges::views::stride(range, 2); + auto striv_it = striv.begin(); + TEST_LIBCPP_ASSERT_FAILURE(striv_it += 3, "Advancing the iterator beyond the end is not allowed."); +} +int main() { + operator_plus_equal_past_end_is_illegal(); + return 0; +} From e1ba6049d0b44d2bb11e9d95cdf9cdd23354e90a Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 3 Nov 2023 09:52:38 -0400 Subject: [PATCH 046/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add tests for __iterator::operator@. --- libcxx/include/__ranges/stride_view.h | 1 + .../iterator/operator.pass.cpp | 132 ++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 8be633b65d914..c7f9a4922f7d0 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -241,6 +241,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> "Advancing the iterator beyond the end is not allowed."); ranges::advance(__current_, __stride_ * (__n - 1)); __missing_ = ranges::advance(__current_, __stride_, __end_); + } else if (__n < 0) { ranges::advance(__current_, __stride_ * __n + __missing_); __missing_ = 0; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp new file mode 100644 index 0000000000000..b3672765e891a --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -0,0 +1,132 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// ranges + +// std::views::stride_view::iterator + +#include "../test.h" +#include "__iterator/concepts.h" +#include "__ranges/access.h" +#include +#include + +template +concept is_plus_equalable = requires(T& __t) { __t += 1; }; +template +concept is_minus_equalable = requires(T& __t) { __t -= 1; }; + +template +concept is_plusable = requires(T& __t) { __t + 1; }; +template +concept is_minusable = requires(T& __t) { __t - 1; }; + +template +concept is_relationally_comparable = requires(T& __t) { + __t < __t; + __t > __t; + __t <= __t; + __t >= __t; +}; + +template +concept is_plus_plusable_post = requires(T& __t) { __t++; }; +template +concept is_plus_plusable_pre = requires(T& __t) { ++__t; }; +template +concept is_minus_minusable_post = requires(T& __t) { __t--; }; +template +concept is_minus_minusable_pre = requires(T& __t) { --__t; }; + +constexpr bool operator_tests() { + { + // What operators are valid for an iterator derived from a stride view + // over an input view. + int arr[] = {1, 2, 3}; + auto rav = InputArrayView(arr, arr + 3); + auto str = std::ranges::stride_view>(rav, 1); + + auto strb = str.begin(); + + static_assert(is_plus_plusable_post); + static_assert(is_plus_plusable_pre); + static_assert(!is_minus_minusable_post); + static_assert(!is_minus_minusable_pre); + static_assert(!is_plus_equalable); + static_assert(!is_minus_equalable); + static_assert(!is_plusable); + static_assert(!is_minusable); + static_assert(!is_relationally_comparable); + } + { + // What operators are valid for an iterator derived from a stride view + // over a forward view. + int arr[] = {1, 2, 3}; + auto rav = ForwardArrayView(arr, arr + 3); + auto str = std::ranges::stride_view>(rav, 1); + + auto strb = str.begin(); + + static_assert(is_plus_plusable_post); + static_assert(is_plus_plusable_pre); + static_assert(!is_minus_minusable_post); + static_assert(!is_minus_minusable_pre); + static_assert(!is_plus_equalable); + static_assert(!is_minus_equalable); + static_assert(!is_plusable); + static_assert(!is_minusable); + static_assert(!is_relationally_comparable); + } + { + // What operators are valid for an iterator derived from a stride view + // over a bidirectional view. + int arr[] = {1, 2, 3}; + auto rav = BidirArrayView(arr, arr + 3); + auto str = std::ranges::stride_view>(rav, 1); + + auto strb = str.begin(); + + static_assert(is_plus_plusable_post); + static_assert(is_plus_plusable_pre); + static_assert(is_minus_minusable_post); + static_assert(is_minus_minusable_pre); + static_assert(!is_plus_equalable); + static_assert(!is_minus_equalable); + static_assert(!is_plusable); + static_assert(!is_minusable); + static_assert(!is_relationally_comparable); + } + { + // What operators are valid for an iterator derived from a stride view + // over a random access view. + int arr[] = {1, 2, 3}; + auto rav = RandomAccessArrayView(arr, arr + 3); + auto str = std::ranges::stride_view>(rav, 1); + + auto strb = str.begin(); + + static_assert(is_plus_plusable_post); + static_assert(is_plus_plusable_pre); + static_assert(is_minus_minusable_post); + static_assert(is_minus_minusable_pre); + static_assert(is_plus_equalable); + static_assert(is_minus_equalable); + static_assert(is_plusable); + static_assert(is_minusable); + static_assert(is_relationally_comparable); + } + return true; +} + +int main(int, char**) { + operator_tests(); + static_assert(operator_tests()); + return 0; +} From 22c2366e8ea5f9fadd1a01568103222114ee1a80 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 10 Nov 2023 10:55:55 -0500 Subject: [PATCH 047/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add new support for interator-to-range support. --- .../ranges/range.adaptors/range.stride.view/test.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index 967c75c9cf002..957cab3044697 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -12,6 +12,7 @@ #include "__concepts/equality_comparable.h" #include "__concepts/movable.h" #include "__concepts/semiregular.h" +#include "__iterator/concepts.h" #include "__iterator/default_sentinel.h" #include "__ranges/access.h" #include "__ranges/concepts.h" @@ -208,6 +209,17 @@ static_assert(std::ranges::view>); static_assert(std::ranges::input_range>); static_assert(std::copyable>); +template S = sentinel_wrapper> +struct InputArrayViewNp : std::ranges::view_base { + T begin_; + T end_; + + constexpr InputArrayViewNp(T b, T e) : begin_(b), end_(e) {} + + constexpr T begin() { return begin_; } + constexpr sentinel_wrapper end() { return sentinel_wrapper{end_}; } +}; + struct ForwardTracedMoveIter : ForwardIterBase { bool moved = false; From 48420c493e054d4941dfcef694e07277e4ed9521 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 10 Nov 2023 10:56:31 -0500 Subject: [PATCH 048/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Test operator- between two stride_view::_iterator-s. --- .../iterator/operator.pass.cpp | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index b3672765e891a..2b2f17b9feed6 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -13,10 +13,14 @@ // std::views::stride_view::iterator #include "../test.h" +#include "__concepts/constructible.h" #include "__iterator/concepts.h" #include "__ranges/access.h" +#include "__ranges/concepts.h" +#include "test_iterators.h" #include #include +#include template concept is_plus_equalable = requires(T& __t) { __t += 1; }; @@ -45,6 +49,9 @@ concept is_minus_minusable_post = requires(T& __t) { __t--; }; template concept is_minus_minusable_pre = requires(T& __t) { --__t; }; +template +concept can_calculate_distance_between_non_sentinel = requires(T& __t) { __t - __t; }; + constexpr bool operator_tests() { { // What operators are valid for an iterator derived from a stride view @@ -122,6 +129,50 @@ constexpr bool operator_tests() { static_assert(is_minusable); static_assert(is_relationally_comparable); } + + { + // Test the non-forward-range operator- between two iterators. + int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + auto rav_zero = InputArrayViewNp(arr, arr + 10); + auto rav_one = InputArrayViewNp(arr + 1, arr + 10); + auto stride_zoff = std::ranges::stride_view(rav_zero, 3); + auto stride_ooff = std::ranges::stride_view(rav_one, 3); + + auto stride_zoff_base = stride_zoff.begin(); + auto stride_ooff_base = stride_ooff.begin(); + + auto stride_zoff_one = stride_zoff_base; + auto stride_zoff_four = stride_zoff_base + 1; + auto stride_zoff_seven = stride_zoff_base + 2; + + auto stride_ooff_two = stride_ooff_base; + auto stride_ooff_five = stride_ooff_base + 1; + + static_assert(!std::ranges::forward_range); + static_assert(std::sized_sentinel_for); + static_assert(can_calculate_distance_between_non_sentinel); + + assert(*stride_zoff_one == 1); + assert(*stride_zoff_four == 4); + + assert(*stride_ooff_two == 2); + assert(*stride_ooff_five == 5); + + // Check positive __n with exact multiple of left's stride. + assert(stride_zoff_four - stride_zoff_one == 1); + assert(stride_zoff_seven - stride_zoff_one == 2); + // Check positive __n with non-exact multiple of left's stride. + assert(stride_ooff_two - stride_zoff_one == 1); + assert(stride_ooff_five - stride_zoff_one == 2); + + // Check negative __n with exact multiple of left's stride. + assert(stride_zoff_one - stride_zoff_four == -1); + assert(stride_zoff_one - stride_zoff_seven == -2); + // Check negative __n with non-exact multiple of left's stride. + assert(stride_zoff_one - stride_ooff_two == -1); + assert(stride_zoff_one - stride_ooff_five == -2); + } return true; } From b334eb4640692705de2229150425e0805b2294f5 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 10 Nov 2023 16:11:10 -0500 Subject: [PATCH 049/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix small formatting error. --- libcxx/include/__ranges/stride_view.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index c7f9a4922f7d0..772551abadc39 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -371,8 +371,8 @@ namespace __stride { struct __fn { template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) const - noexcept(noexcept(stride_view{ - std::forward<_Range>(__range), __n})) -> decltype(stride_view{std::forward<_Range>(__range), __n}) { + noexcept(noexcept(stride_view{std::forward<_Range>(__range), __n})) + -> decltype(stride_view{std::forward<_Range>(__range), __n}) { return stride_view(std::forward<_Range>(__range), __n); } From ffd0c3348183c92d204b6a4036592d562966266c Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 13 Nov 2023 19:01:36 -0500 Subject: [PATCH 050/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Remove extraneous testing view classes. --- .../range.stride.view/adaptor.pass.cpp | 48 +++---- .../range.stride.view/ctor.pass.cpp | 7 +- .../range.stride.view/iterator/begin.pass.cpp | 17 +-- .../iterator/operator.pass.cpp | 44 ++++--- .../range.stride.view/stride.pass.cpp | 8 +- .../range.adaptors/range.stride.view/test.h | 120 +++++------------- 6 files changed, 103 insertions(+), 141 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index 02e57c8865709..50a349cd6207d 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -14,6 +14,7 @@ #include "__ranges/stride_view.h" #include "test.h" +#include "test_iterators.h" #include #include #include @@ -33,11 +34,10 @@ constexpr bool test() { // view | stride { { - BidirArrayView view(arr, arr + array_n); - //std::ranges::stride_view strided(view, 1); - std::same_as>> decltype(auto) strided = - view | std::views::stride(1); - auto strided_iter = strided.begin(); + using View = InputView>; + View view(bidirectional_iterator(arr), bidirectional_iterator(arr + array_n)); + std::same_as> decltype(auto) strided = view | std::views::stride(1); + auto strided_iter = strided.begin(); // Check that the begin() iter views arr[0] assert(*strided_iter == arr[0]); @@ -47,10 +47,10 @@ constexpr bool test() { assert(*strided_iter == arr[2]); } { - BidirArrayView view(arr, arr + array_n); - std::same_as>> decltype(auto) strided = - view | std::views::stride(2); - auto strided_iter = strided.begin(); + using View = InputView>; + View view(bidirectional_iterator(arr), bidirectional_iterator(arr + array_n)); + std::same_as> decltype(auto) strided = view | std::views::stride(2); + auto strided_iter = strided.begin(); assert(*strided_iter == arr[0]); @@ -65,20 +65,22 @@ constexpr bool test() { // adaptor | stride { // Parallels the two tests from above. - constexpr auto identity_lambda = [](int i) { return i * 2; }; + constexpr const auto identity_lambda = [](const int i) { return i * 2; }; { - BidirArrayView view(arr, arr + array_n); + using View = InputView>; + View view(bidirectional_iterator(arr), bidirectional_iterator(arr + array_n)); const auto transform_stride_partial = std::views::transform(identity_lambda) | std::views::stride(1); - const auto transform_stride_applied = transform_stride_partial(view); - auto transform_stride_applied_iter = transform_stride_applied.begin(); + auto transform_stride_applied = transform_stride_partial(view); + auto transform_stride_applied_iter = transform_stride_applied.begin(); assert(*transform_stride_applied_iter == std::invoke(identity_lambda, arr[0])); std::ranges::advance(transform_stride_applied_iter, 2); assert(*transform_stride_applied_iter == std::invoke(identity_lambda, arr[2])); } { - BidirArrayView view(arr, arr + array_n); + using View = InputView>; + View view(bidirectional_iterator(arr), bidirectional_iterator(arr + array_n)); const auto transform_stride_partial = std::views::transform(identity_lambda) | std::views::stride(2); const auto transform_stride_applied = transform_stride_partial(view); @@ -90,9 +92,9 @@ constexpr bool test() { } { - using ForwardStrideView = std::ranges::stride_view>; - using BidirStrideView = std::ranges::stride_view>; - using RandomAccessStrideView = std::ranges::stride_view>; + using ForwardStrideView = std::ranges::stride_view>>; + using BidirStrideView = std::ranges::stride_view>>; + using RandomAccessStrideView = std::ranges::stride_view>>; static_assert(std::ranges::forward_range); static_assert(std::ranges::bidirectional_range); @@ -102,6 +104,7 @@ constexpr bool test() { // Check SFINAE friendliness { + using View = InputView>; struct NotAViewableRange {}; struct NotARange {}; // Not invocable because there is no parameter. @@ -109,15 +112,12 @@ constexpr bool test() { // Not invocable because NotAViewableRange is, well, not a viewable range. static_assert(!std::is_invocable_v); // Is invocable because BidirView is a viewable range. - static_assert(std::is_invocable_v>); + static_assert(std::is_invocable_v); // Make sure that pipe operations work! - static_assert(CanBePiped, - decltype(std::views::stride(std::ranges::range_difference_t>{}))>); - static_assert(CanBePiped&, - decltype(std::views::stride(std::ranges::range_difference_t>{}))>); - static_assert( - !CanBePiped>{}))>); + static_assert(CanBePiped{}))>); + static_assert(CanBePiped{}))>); + static_assert(!CanBePiped{}))>); } // A final sanity check. { static_assert(std::same_as); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp index 30256ac12b77e..8d3cbcd1463cf 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp @@ -14,17 +14,20 @@ #include "test.h" #include "test_convertible.h" +#include "test_iterators.h" #include constexpr bool test_no_default_ctor() { // There is no default ctor for stride_view. - static_assert(!std::is_default_constructible_v>>); + using View = InputView>; + static_assert(!std::is_default_constructible_v>); return true; } constexpr bool test_no_implicit_ctor() { + using View = InputView>; // Test that the stride_view can only be explicitly constructed. - static_assert(!test_convertible>, ForwardArrayView, int>()); + static_assert(!test_convertible, View, int>()); return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp index 6a9b1df59961b..270d5cd0caaff 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp @@ -14,6 +14,7 @@ #include "../test.h" #include "__iterator/concepts.h" +#include "test_iterators.h" #include #include @@ -21,8 +22,8 @@ constexpr bool iterator_concept_test() { { int arr[] = {1, 2, 3}; // Iterator of stride over random access view should have random access concept. - auto rav = RandomAccessArrayView(arr, arr + 3); - auto str = std::ranges::stride_view>(rav, 1); + auto rav = InputView>(random_access_iterator(arr), random_access_iterator(arr + 3)); + auto str = std::ranges::stride_view>>(rav, 1); static_assert(std::random_access_iterator); static_assert(std::random_access_iterator); } @@ -30,8 +31,8 @@ constexpr bool iterator_concept_test() { { int arr[] = {1, 2, 3}; // Iterator of stride over bidirectional view should have bidirectional view concept. - auto rav = BidirArrayView(arr, arr + 3); - auto str = std::ranges::stride_view>(rav, 1); + auto rav = InputView>(bidirectional_iterator(arr), bidirectional_iterator(arr + 3)); + auto str = std::ranges::stride_view>>(rav, 1); static_assert(std::bidirectional_iterator); static_assert(std::bidirectional_iterator); static_assert(!std::random_access_iterator); @@ -41,8 +42,8 @@ constexpr bool iterator_concept_test() { { int arr[] = {1, 2, 3}; // Iterator of stride over forward view should have forward view concept. - auto rav = ForwardArrayView(arr, arr + 3); - auto str = std::ranges::stride_view>(rav, 1); + auto rav = InputView>(forward_iterator(arr), forward_iterator(arr + 3)); + auto str = std::ranges::stride_view>>(rav, 1); static_assert(std::forward_iterator); static_assert(std::forward_iterator); static_assert(!std::bidirectional_iterator); @@ -54,8 +55,8 @@ constexpr bool iterator_concept_test() { { int arr[] = {1, 2, 3}; // Iterator of stride over input view should have input view concept. - auto rav = InputArrayView(arr, arr + 3); - auto str = std::ranges::stride_view>(rav, 1); + auto rav = InputView>(cpp17_input_iterator(arr), cpp17_input_iterator(arr + 3)); + auto str = std::ranges::stride_view>>(rav, 1); static_assert(std::input_iterator); static_assert(std::input_iterator); static_assert(!std::forward_iterator); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index 2b2f17b9feed6..5118b35db8204 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -56,9 +56,10 @@ constexpr bool operator_tests() { { // What operators are valid for an iterator derived from a stride view // over an input view. - int arr[] = {1, 2, 3}; - auto rav = InputArrayView(arr, arr + 3); - auto str = std::ranges::stride_view>(rav, 1); + int arr[] = {1, 2, 3}; + using View = InputView>; + auto rav = View(cpp17_input_iterator(arr), cpp17_input_iterator(arr + 3)); + auto str = std::ranges::stride_view(rav, 1); auto strb = str.begin(); @@ -75,9 +76,10 @@ constexpr bool operator_tests() { { // What operators are valid for an iterator derived from a stride view // over a forward view. - int arr[] = {1, 2, 3}; - auto rav = ForwardArrayView(arr, arr + 3); - auto str = std::ranges::stride_view>(rav, 1); + int arr[] = {1, 2, 3}; + using View = InputView>; + auto rav = View(forward_iterator(arr), forward_iterator(arr + 3)); + auto str = std::ranges::stride_view(rav, 1); auto strb = str.begin(); @@ -94,9 +96,10 @@ constexpr bool operator_tests() { { // What operators are valid for an iterator derived from a stride view // over a bidirectional view. - int arr[] = {1, 2, 3}; - auto rav = BidirArrayView(arr, arr + 3); - auto str = std::ranges::stride_view>(rav, 1); + int arr[] = {1, 2, 3}; + using View = InputView>; + auto rav = View(bidirectional_iterator(arr), bidirectional_iterator(arr + 3)); + auto str = std::ranges::stride_view(rav, 1); auto strb = str.begin(); @@ -113,9 +116,10 @@ constexpr bool operator_tests() { { // What operators are valid for an iterator derived from a stride view // over a random access view. - int arr[] = {1, 2, 3}; - auto rav = RandomAccessArrayView(arr, arr + 3); - auto str = std::ranges::stride_view>(rav, 1); + int arr[] = {1, 2, 3}; + using View = InputView>; + auto rav = View(random_access_iterator(arr), random_access_iterator(arr + 3)); + auto str = std::ranges::stride_view(rav, 1); auto strb = str.begin(); @@ -131,10 +135,12 @@ constexpr bool operator_tests() { } { - // Test the non-forward-range operator- between two iterators. + // Test the non-forward-range operator- between two iterators (i.e., ceil). int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - auto rav_zero = InputArrayViewNp(arr, arr + 10); - auto rav_one = InputArrayViewNp(arr + 1, arr + 10); + auto rav_zero = + InputView(SizedInputIterator(arr), SizedInputIterator(arr + 10)); + auto rav_one = + InputView(SizedInputIterator(arr + 1), SizedInputIterator(arr + 10)); auto stride_zoff = std::ranges::stride_view(rav_zero, 3); auto stride_ooff = std::ranges::stride_view(rav_one, 3); @@ -142,19 +148,19 @@ constexpr bool operator_tests() { auto stride_ooff_base = stride_ooff.begin(); auto stride_zoff_one = stride_zoff_base; - auto stride_zoff_four = stride_zoff_base + 1; - auto stride_zoff_seven = stride_zoff_base + 2; + auto stride_zoff_four = ++stride_zoff_base; + auto stride_zoff_seven = ++stride_zoff_base; auto stride_ooff_two = stride_ooff_base; - auto stride_ooff_five = stride_ooff_base + 1; + auto stride_ooff_five = ++stride_ooff_base; - static_assert(!std::ranges::forward_range); static_assert(std::sized_sentinel_for); static_assert(can_calculate_distance_between_non_sentinel); assert(*stride_zoff_one == 1); assert(*stride_zoff_four == 4); + assert(*stride_zoff_seven == 7); assert(*stride_ooff_two == 2); assert(*stride_ooff_five == 5); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp index 154f747f49bd7..25ffcce838bd4 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp @@ -13,14 +13,16 @@ // std::views::stride_view #include "test.h" +#include "test_iterators.h" #include #include #include constexpr bool test() { - static_assert(noexcept(std::declval>>().stride())); - static_assert(std::is_same_v>, - decltype(std::declval>>().stride())>); + using View = InputView>; + static_assert(noexcept(std::declval>().stride())); + static_assert(std::is_same_v, + decltype(std::declval>().stride())>); return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index 957cab3044697..4bda90fcf0e28 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -126,98 +126,18 @@ struct InputIterBase { friend constexpr bool operator==(const Derived&, const std::default_sentinel_t&) { return true; } }; -/* - * XXXArrayView classes for use throughout the stride view tests. - */ - -template -struct RandomAccessArrayView : std::ranges::view_base { - T* begin_; - T* end_; - - constexpr RandomAccessArrayView(T* b, T* e) : begin_(b), end_(e) {} - - constexpr random_access_iterator begin() { return random_access_iterator{begin_}; } - constexpr random_access_iterator begin() const { return random_access_iterator{begin_}; } - constexpr sentinel_wrapper> end() { - return sentinel_wrapper>{random_access_iterator{end_}}; - } - constexpr sentinel_wrapper> end() const { - return sentinel_wrapper>{random_access_iterator{end_}}; - } - constexpr std::size_t size() const { return end_ - begin_; } -}; -static_assert(std::ranges::view>); -static_assert(std::ranges::random_access_range>); -static_assert(std::copyable>); - -template -struct BidirArrayView : std::ranges::view_base { - T* begin_; - T* end_; - - constexpr BidirArrayView(T* b, T* e) : begin_(b), end_(e) {} - - constexpr bidirectional_iterator begin() { return bidirectional_iterator{begin_}; } - constexpr bidirectional_iterator begin() const { return bidirectional_iterator{begin_}; } - constexpr sentinel_wrapper> end() { - return sentinel_wrapper>{bidirectional_iterator{end_}}; - } - constexpr sentinel_wrapper> end() const { - return sentinel_wrapper>{bidirectional_iterator{end_}}; - } -}; -static_assert(std::ranges::view>); -static_assert(std::ranges::bidirectional_range>); -static_assert(std::copyable>); - -template -struct ForwardArrayView : public std::ranges::view_base { - T* begin_; - T* end_; - - constexpr ForwardArrayView(T* b, T* e) : begin_(b), end_(e) {} - - constexpr forward_iterator begin() { return forward_iterator{begin_}; } - constexpr forward_iterator begin() const { return forward_iterator{begin_}; } - constexpr sentinel_wrapper> end() { - return sentinel_wrapper>{forward_iterator{end_}}; - } - constexpr sentinel_wrapper> end() const { - return sentinel_wrapper>{forward_iterator{end_}}; - } -}; -static_assert(std::ranges::view>); -static_assert(std::ranges::forward_range>); -static_assert(std::copyable>); - -template -struct InputArrayView : std::ranges::view_base { - T* begin_; - T* end_; - - constexpr InputArrayView(T* b, T* e) : begin_(b), end_(e) {} - - constexpr cpp20_input_iterator begin() { return cpp20_input_iterator{begin_}; } - constexpr random_access_iterator begin() const { return random_access_iterator{begin_}; } - constexpr sentinel_wrapper> end() { - return sentinel_wrapper>{cpp20_input_iterator{end_}}; - } - constexpr std::size_t size() const { return end_ - begin_; } -}; -static_assert(std::ranges::view>); -static_assert(std::ranges::input_range>); -static_assert(std::copyable>); - +//TODO: Rename as View. template S = sentinel_wrapper> -struct InputArrayViewNp : std::ranges::view_base { +struct InputView : std::ranges::view_base { T begin_; T end_; - constexpr InputArrayViewNp(T b, T e) : begin_(b), end_(e) {} + constexpr InputView(T b, T e) : begin_(b), end_(e) {} constexpr T begin() { return begin_; } + constexpr T begin() const { return begin_; } constexpr sentinel_wrapper end() { return sentinel_wrapper{end_}; } + constexpr sentinel_wrapper end() const { return sentinel_wrapper{end_}; } }; struct ForwardTracedMoveIter : ForwardIterBase { @@ -242,4 +162,34 @@ struct UnsizedBasicRange : std::ranges::view_base { UnsizedBasicRangeIterator end() const; }; +// TODO: Cleanup +struct SizedInputIterator { + using iterator_concept = std::input_iterator_tag; + using value_type = int; + using difference_type = std::intptr_t; + + int* __v_; + + constexpr SizedInputIterator() { __v_ = nullptr; } + constexpr SizedInputIterator(int* __v) { __v_ = __v; } + constexpr SizedInputIterator(const SizedInputIterator& sii) { __v_ = sii.__v_; } + + constexpr int operator*() const { return *__v_; } + constexpr SizedInputIterator& operator++() { + __v_++; + return *this; + } + constexpr SizedInputIterator operator++(int) { + auto nv = __v_; + nv++; + return SizedInputIterator(nv); + } + friend constexpr bool operator==(const SizedInputIterator& left, const SizedInputIterator& right) { + return left.__v_ == right.__v_; + } + friend constexpr difference_type operator-(const SizedInputIterator& left, const SizedInputIterator& right) { + return left.__v_ - right.__v_; + } +}; + #endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H From b24b13e25e55654bc3f1542c8537d822aa35d4c8 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 15 Nov 2023 10:42:54 -0500 Subject: [PATCH 051/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Update stride() tests per @var-const feedback. --- .../range.stride.view/stride.pass.cpp | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp index 25ffcce838bd4..9b84817be4abb 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp @@ -8,27 +8,33 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// ranges +// constexpr range_difference_t<_View> stride() const noexcept; -// std::views::stride_view - -#include "test.h" #include "test_iterators.h" +#include "test.h" #include #include #include constexpr bool test() { - using View = InputView>; - static_assert(noexcept(std::declval>().stride())); - static_assert(std::is_same_v, - decltype(std::declval>().stride())>); + using View = InputView>; + int arr[]{1, 2, 3}; + auto arrv(View(cpp17_input_iterator(arr), cpp17_input_iterator(arr + 3))); + // Mark str const so that we confirm that stride is a const member function. + const std::ranges::stride_view str(arrv, 1); + + // Make sure that stride member function is noexcept. + static_assert(noexcept(str.stride())); + // Make sure that the type returned by stride matches what is expected. + static_assert(std::is_same_v, decltype(str.stride())>); + // Make sure that we get back a stride equal to the one that we gave in the ctor. + assert(str.stride() == 1); + return true; } int main(int, char**) { test(); static_assert(test()); - return 0; } From 71351a259ea8045ae6830b068cfd1d08049eb10c Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 15 Nov 2023 23:56:02 -0500 Subject: [PATCH 052/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Update stride_view ctor tests per @var-const feedback. --- .../range.stride.view/ctor.pass.cpp | 68 ++++++++++--------- .../range.adaptors/range.stride.view/test.h | 20 +++++- 2 files changed, 55 insertions(+), 33 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp index 8d3cbcd1463cf..a34d3cbb3863f 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp @@ -8,49 +8,53 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// ranges +// constexpr explicit stride_view(_View, range_difference_t<_View>) -// std::views::stride_view +#include #include "test.h" #include "test_convertible.h" #include "test_iterators.h" -#include -constexpr bool test_no_default_ctor() { - // There is no default ctor for stride_view. - using View = InputView>; - static_assert(!std::is_default_constructible_v>); - return true; -} +// There is no default ctor for stride_view. +using View = InputView>; +static_assert(!std::is_default_constructible_v>); -constexpr bool test_no_implicit_ctor() { - using View = InputView>; - // Test that the stride_view can only be explicitly constructed. - static_assert(!test_convertible, View, int>()); - return true; -} +// Test that the stride_view can only be explicitly constructed. +static_assert(!test_convertible, View, int>()); + +constexpr bool test() { + { + int arr[] = {1, 2, 3}; + // Test that what we will stride over is move only. + static_assert(!std::is_copy_constructible_v>>); + static_assert(std::is_move_constructible_v>>); + + MoveOnlyView> mov(cpp17_input_iterator(arr), cpp17_input_iterator(arr + 3)); + // Because MoveOnlyView is, well, move only, we can test that it is moved + // from when the stride view is constructed. + std::ranges::stride_view>> mosv(std::move(mov), 1); + + // While we are here, make sure that the ctor captured the proper things + assert(mosv.stride() == 1); + + auto mosv_i = mosv.begin(); + assert(*mosv_i == 1); + + mosv_i++; + assert(*mosv_i == 2); + + mosv_i++; + assert(*mosv_i == 3); -constexpr bool test_move_ctor() { - int arr[] = {1, 2, 3}; - // Test that the stride_view ctor properly moves from the base (and works with a move-only type). - static_assert(!std::is_copy_constructible_v>); - static_assert(std::is_move_constructible_v>); - - bool moved(false), copied(false); - MovedOnlyTrackedBasicView mov(arr, arr + 3, &moved, &copied); - std::ranges::stride_view> mosv(std::move(mov), 2); - assert(moved); - assert(!copied); + mosv_i++; + assert(mosv_i == mosv.end()); + } return true; } int main(int, char**) { - test_no_implicit_ctor(); - static_assert(test_no_implicit_ctor()); - test_no_default_ctor(); - static_assert(test_no_default_ctor()); - test_move_ctor(); - static_assert(test_move_ctor()); + test(); + static_assert(test()); return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index 4bda90fcf0e28..159de0f78f583 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -126,6 +126,24 @@ struct InputIterBase { friend constexpr bool operator==(const Derived&, const std::default_sentinel_t&) { return true; } }; +template S = sentinel_wrapper> +struct MoveOnlyView : std::ranges::view_base { + T begin_; + T end_; + + constexpr MoveOnlyView(T b, T e) : begin_(b), end_(e) {} + + constexpr MoveOnlyView(const MoveOnlyView&) = delete; + constexpr MoveOnlyView(MoveOnlyView&& other) = default; + constexpr MoveOnlyView& operator=(MoveOnlyView&&) = default; + constexpr MoveOnlyView& operator=(const MoveOnlyView&) = delete; + + constexpr T begin() { return begin_; } + constexpr T begin() const { return begin_; } + constexpr sentinel_wrapper end() { return sentinel_wrapper{end_}; } + constexpr sentinel_wrapper end() const { return sentinel_wrapper{end_}; } +}; + //TODO: Rename as View. template S = sentinel_wrapper> struct InputView : std::ranges::view_base { @@ -171,7 +189,7 @@ struct SizedInputIterator { int* __v_; constexpr SizedInputIterator() { __v_ = nullptr; } - constexpr SizedInputIterator(int* __v) { __v_ = __v; } + constexpr SizedInputIterator(int* v) { __v_ = v; } constexpr SizedInputIterator(const SizedInputIterator& sii) { __v_ = sii.__v_; } constexpr int operator*() const { return *__v_; } From 6b0eeff5f46c07e6bb836395ea8f03834ff3b33f Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 17 Nov 2023 21:07:57 -0500 Subject: [PATCH 053/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. --- .../range.stride.view/adaptor.pass.cpp | 8 +-- .../range.stride.view/ctor.pass.cpp | 2 +- .../range.stride.view/size.pass.cpp | 60 ------------------- .../range.stride.view/size.verify.cpp | 49 +++++++++++++++ .../range.stride.view/stride.pass.cpp | 2 +- 5 files changed, 55 insertions(+), 66 deletions(-) delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/size.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index 50a349cd6207d..d3dcd7b73436c 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -35,7 +35,7 @@ constexpr bool test() { { { using View = InputView>; - View view(bidirectional_iterator(arr), bidirectional_iterator(arr + array_n)); + View view(bidirectional_iterator(arr), bidirectional_iterator(arr + array_n)); std::same_as> decltype(auto) strided = view | std::views::stride(1); auto strided_iter = strided.begin(); @@ -48,7 +48,7 @@ constexpr bool test() { } { using View = InputView>; - View view(bidirectional_iterator(arr), bidirectional_iterator(arr + array_n)); + View view(bidirectional_iterator(arr), bidirectional_iterator(arr + array_n)); std::same_as> decltype(auto) strided = view | std::views::stride(2); auto strided_iter = strided.begin(); @@ -68,7 +68,7 @@ constexpr bool test() { constexpr const auto identity_lambda = [](const int i) { return i * 2; }; { using View = InputView>; - View view(bidirectional_iterator(arr), bidirectional_iterator(arr + array_n)); + View view(bidirectional_iterator(arr), bidirectional_iterator(arr + array_n)); const auto transform_stride_partial = std::views::transform(identity_lambda) | std::views::stride(1); auto transform_stride_applied = transform_stride_partial(view); @@ -80,7 +80,7 @@ constexpr bool test() { { using View = InputView>; - View view(bidirectional_iterator(arr), bidirectional_iterator(arr + array_n)); + View view(bidirectional_iterator(arr), bidirectional_iterator(arr + array_n)); const auto transform_stride_partial = std::views::transform(identity_lambda) | std::views::stride(2); const auto transform_stride_applied = transform_stride_partial(view); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp index a34d3cbb3863f..b705d30a6c74e 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp @@ -30,7 +30,7 @@ constexpr bool test() { static_assert(!std::is_copy_constructible_v>>); static_assert(std::is_move_constructible_v>>); - MoveOnlyView> mov(cpp17_input_iterator(arr), cpp17_input_iterator(arr + 3)); + MoveOnlyView> mov(cpp17_input_iterator(arr), cpp17_input_iterator(arr + 3)); // Because MoveOnlyView is, well, move only, we can test that it is moved // from when the stride view is constructed. std::ranges::stride_view>> mosv(std::move(mov), 1); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.pass.cpp deleted file mode 100644 index c270c77f6f9f3..0000000000000 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.pass.cpp +++ /dev/null @@ -1,60 +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, c++20 - -// ranges - -// std::ranges::stride_view - -#include "test.h" -#include -#include - -bool runtime_test() { - auto iot = std::views::iota(1, 22); - auto str = std::views::stride(iot, 3); - auto result = str.size(); - assert(result == 7); - return true; -} - -constexpr bool test() { - { - // Test with ranges that are sized_range true. - constexpr auto iot_twelve = std::views::iota(1, 12); - static_assert(std::ranges::sized_range); - constexpr auto str_iot_twelve = std::views::stride(iot_twelve, 3); - static_assert(std::ranges::sized_range); - assert(4 == str_iot_twelve.size()); - static_assert(4 == str_iot_twelve.size(), "Striding by 3 through a 12 member list has size 4."); - - constexpr auto iot_twenty_two = std::views::iota(1, 22); - static_assert(std::ranges::sized_range); - constexpr auto str_iot_twenty_two = std::views::stride(iot_twenty_two, 3); - static_assert(std::ranges::sized_range); - - assert(7 == str_iot_twenty_two.size()); - static_assert(7 == str_iot_twenty_two.size(), "Striding by 3 through a 22 member list has size 4."); - } - - { - // Test with ranges that are not sized_range true. - constexpr auto unsized_range = UnsizedBasicRange(); - static_assert(!std::ranges::sized_range); - constexpr auto str_unsized = std::views::stride(unsized_range, 3); - static_assert(!std::ranges::sized_range); - } - return true; -} - -int main(int, char**) { - runtime_test(); - static_assert(test()); - return 0; -} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp new file mode 100644 index 0000000000000..c3d87a1dac7b2 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// constexpr auto size() + +#include +#include + +#include "test.h" + +// There is no size member function on a stride view over a view that +// is *not* a sized range +static_assert(!std::ranges::sized_range); // expected-no-diagnostics +static_assert(!std::ranges::sized_range>); // expected-no-diagnosticss + +constexpr bool test() { + { + // Test with stride as exact multiple of number of elements in view strided over. + constexpr auto iota_twelve = std::views::iota(0, 12); + static_assert(std::ranges::sized_range); // expected-no-diagnostics + constexpr auto stride_iota_twelve = std::views::stride(iota_twelve, 3); + static_assert(std::ranges::sized_range); // expected-no-diagnostics + static_assert(4 == stride_iota_twelve.size(), + "Striding by 3 through a 12 member list has size 4."); // expected-no-diagnostics + } + + { + // Test with stride as inexact multiple of number of elements in view strided over. + constexpr auto iota_twenty_two = std::views::iota(0, 22); + static_assert(std::ranges::sized_range); // expected-no-diagnostics + constexpr auto stride_iota_twenty_two = std::views::stride(iota_twenty_two, 3); + static_assert(std::ranges::sized_range); // expected-no-diagnostics + static_assert(8 == stride_iota_twenty_two.size(), + "Striding by 3 through a 22 member list has size 8."); // expected-no-diagnostics + } + return true; +} + +int main(int, char**) { + static_assert(test()); + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp index 9b84817be4abb..12c8338c22fb3 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp @@ -19,7 +19,7 @@ constexpr bool test() { using View = InputView>; int arr[]{1, 2, 3}; - auto arrv(View(cpp17_input_iterator(arr), cpp17_input_iterator(arr + 3))); + auto arrv(View(cpp17_input_iterator(arr), cpp17_input_iterator(arr + 3))); // Mark str const so that we confirm that stride is a const member function. const std::ranges::stride_view str(arrv, 1); From a1f9cb9f0d87c5d9d6c4c8728671e964f69ab4ca Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 17 Nov 2023 21:48:08 -0500 Subject: [PATCH 054/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Move borrowed_range testing to a verify test (and other formatting). --- .../enable_borrowed_range.compile.pass.cpp | 32 ------------------- .../enable_borrowed_range.verify.cpp | 28 ++++++++++++++++ 2 files changed, 28 insertions(+), 32 deletions(-) delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.compile.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.verify.cpp diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.compile.pass.cpp deleted file mode 100644 index 4add46949a6ae..0000000000000 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.compile.pass.cpp +++ /dev/null @@ -1,32 +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, c++20 - -// ranges - -// std::views::stride_view - -#include "test.h" -#include - -constexpr bool test() { - using std::ranges::enable_borrowed_range; - // Make sure that a stride_view over neither a borrowable nor an unborrowable view - // is itself borrowable. - static_assert(!enable_borrowed_range>>); - static_assert(!enable_borrowed_range>>); - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.verify.cpp new file mode 100644 index 0000000000000..a17c813527a44 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.verify.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +#include + +#include "test.h" + +// template +// inline constexpr bool enable_borrowed_range> = false; + +// The stride_view is not one of those range adaptors that (under any circumstances) +// is enabled as a borrowable range by default. In other words, we will have to make +// a positively test case explicity + +template <> +inline constexpr bool + std::ranges::enable_borrowed_range>>> = true; + +static_assert(std::ranges::borrowed_range< + std::ranges::stride_view>>>); // expected-no-diagnostics +static_assert(!std::ranges::borrowed_range>>); // expected-no-diagnostics From cbf6ced318597fb73660fa19a2078eabec4a8280 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 20 Nov 2023 09:59:23 -0500 Subject: [PATCH 055/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Move concept testing to a verification test. --- .../range.stride.view/concept.pass.cpp | 68 ------------------- .../range.stride.view/concept.verify.cpp | 40 +++++++++++ .../range.adaptors/range.stride.view/test.h | 7 ++ 3 files changed, 47 insertions(+), 68 deletions(-) delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.pass.cpp deleted file mode 100644 index 395ab4a55b9b8..0000000000000 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.pass.cpp +++ /dev/null @@ -1,68 +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, c++20 - -// ranges - -// std::views::stride_view - -#include "__ranges/stride_view.h" -#include "test.h" - -// Do not use for execution -- only useful for testing compilation/type conditions. -template -struct non_input_iterator { - struct __invalid_iterator_tag {}; - using value_type = T; - using difference_type = int; - using iterator_concept = __invalid_iterator_tag; - - constexpr non_input_iterator& operator++() { return *this; } - constexpr void operator++(int) {} - constexpr T operator*() const { return T{}; } - - friend constexpr bool operator==(const non_input_iterator&, const non_input_iterator&) { return true; } -}; - -template -inline constexpr bool std::ranges::enable_borrowed_range> = true; - -class almost_input_range : public std::ranges::view_base { -public: - constexpr auto begin() const { return non_input_iterator{}; } - constexpr auto end() const { return non_input_iterator{}; } -}; - -class non_view_range { -public: - constexpr int* begin() const { return nullptr; } - constexpr int* end() const { return nullptr; } -}; - -constexpr bool test() { - // Ensure that the almost_input_range is a valid range. - static_assert(std::ranges::range); - // Ensure that the non_input_iterator is, well, not an input iterator. - static_assert(!std::input_iterator>); - static_assert(!CanStrideView, "A non input range cannot be the subject of a stride view."); - - // Ensure that a range that is not a view cannot be the subject of a stride_view. - static_assert(std::ranges::range, "non_view_range must be a range."); - static_assert(std::movable, "non_view_range must be movable."); - static_assert(!std::ranges::view, "A non-view range cannot be the subject of a stride_view.\n"); - - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); - - return 0; -} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp new file mode 100644 index 0000000000000..8a9a38eb9f302 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// template requires view<_View> + +#include "__ranges/stride_view.h" +#include "almost_satisfies_types.h" +#include "test.h" +#include "test_iterators.h" +#include "test_range.h" + +// Ensure that the InputRangeNotIndirectlyReadable is a valid range. +static_assert(std::ranges::range); // expected-no-diagnostics +// Ensure that the InputRangeNotIndirectlyReadable's is not an input range ... +static_assert( + !std::ranges::input_range>); // expected-no-diagnostics +// Because CanStrideView requires that the range/view type be default constructible, let's double check that ... +static_assert(std::is_constructible_v); // expected-no-diagnostics +// And now, finally, let's make sure that we cannot stride over a range whose iterator is not an input iterator ... +static_assert(!CanStrideView); // expected-no-diagnostics + +// Ensure that a range that is not a view cannot be the subject of a stride_view. +static_assert(std::ranges::range); // expected-no-diagnostics +static_assert(std::ranges::input_range); // expected-no-diagnostics +static_assert(std::movable); // expected-no-diagnostics +static_assert(!std::ranges::view); // expected-no-diagnostics +static_assert(!CanStrideView); // expected-no-diagnostics + +// And now, let's satisfy all the prerequisites and make sure that we can stride over a range (that is an input range and is a view!) +static_assert(std::ranges::range>); // expected-no-diagnostics +static_assert(std::ranges::input_range>); // expected-no-diagnostics +static_assert(std::ranges::view>); // expected-no-diagnostics +static_assert(CanStrideView, 1>); // expected-no-diagnostics diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index 159de0f78f583..113efa3704a40 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -21,6 +21,7 @@ #include "__ranges/size.h" #include "__ranges/stride_view.h" #include "test_iterators.h" +#include "test_range.h" #include #include @@ -35,6 +36,12 @@ struct InstrumentedBasicRange { T* end() const; }; +class non_view_range { +public: + constexpr int* begin() const { return nullptr; } + constexpr int* end() const { return nullptr; } +}; + struct MovedCopiedTrackedView { constexpr explicit MovedCopiedTrackedView(bool* moved = nullptr, bool* copied = nullptr) : wasMoveInitialized_(moved), wasCopyInitialized_(copied) {} From 86c4e20116c6bf4419a05260cadf0ebfb30192f2 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 22 Nov 2023 08:52:51 -0500 Subject: [PATCH 056/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Cleanup base tests per @varconst feedback. --- .../range.stride.view/base.pass.cpp | 64 ++++++------------- .../range.adaptors/range.stride.view/test.h | 22 ++++++- 2 files changed, 40 insertions(+), 46 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp index 062262ffde577..83e768c3badea 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp @@ -8,64 +8,42 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// ranges +// constexpr _View base() const& requires copy_constructible<_View>; +// constexpr _View base() &&; -// std::views::stride_view - -#include "test.h" #include #include +#include "test.h" +#include "test_iterators.h" + template -concept can_call_base_on = requires(T t) { std::forward(t).base(); }; +concept hasLValueQualifiedBase = requires(T&& t) { t.base(); }; constexpr bool test() { int buff[] = {1, 2, 3, 4, 5, 6, 7, 8}; - // Check the const& overload - { - bool moved(false), copied(false); - MovedCopiedTrackedBasicView range(buff, buff + 8, &moved, &copied); - std::ranges::stride_view> const view(std::move(range), 3); - assert(moved); - assert(!copied); - std::same_as> decltype(auto) result = view.base(); - assert(result.begin() == buff); - assert(result.end() == buff + 8); - } - - // Check the && overload { - bool moved(false), copied(false); - MovedCopiedTrackedBasicView range(buff, buff + 8, &moved, &copied); - std::ranges::stride_view> view(std::move(range), 3); - assert(moved); - assert(!copied); - std::same_as> decltype(auto) result = std::move(view).base(); - assert(result.begin() == buff); - assert(result.end() == buff + 8); + using CopyableInputView = CopyableView>; + auto str(std::ranges::stride_view( + CopyableInputView(cpp17_input_iterator(buff), cpp17_input_iterator(buff + 8)), 1)); + assert(*str.base().begin() == *buff); + assert(*(std::move(str)).base().begin() == *buff); + + ASSERT_SAME_TYPE(decltype(str.base()), CopyableInputView); + ASSERT_SAME_TYPE(decltype(std::move(str).base()), CopyableInputView); + static_assert(hasLValueQualifiedBase); } - // Check the && overload (again) { - bool moved(false), copied(false); - MovedCopiedTrackedBasicView range(buff, buff + 8, &moved, &copied); - std::same_as> decltype(auto) result = - std::ranges::stride_view>(std::move(range), 3).base(); - assert(moved); - assert(!copied); - assert(result.begin() == buff); - assert(result.end() == buff + 8); - } + using MoveOnlyInputView = MoveOnlyView>; + auto str(std::ranges::stride_view( + MoveOnlyInputView(cpp17_input_iterator(buff), cpp17_input_iterator(buff + 8)), 1)); + assert(*(std::move(str)).base().begin() == *buff); - // Ensure the const& overload is not considered when the base is not copy-constructible - { - static_assert(!can_call_base_on> const&>); - static_assert(!can_call_base_on>&>); - static_assert(can_call_base_on>&&>); - static_assert(can_call_base_on>>); + ASSERT_SAME_TYPE(decltype(std::move(str).base()), MoveOnlyInputView); + static_assert(!hasLValueQualifiedBase); } - return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index 113efa3704a40..634b8a34991ef 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -138,18 +138,34 @@ struct MoveOnlyView : std::ranges::view_base { T begin_; T end_; - constexpr MoveOnlyView(T b, T e) : begin_(b), end_(e) {} + constexpr explicit MoveOnlyView(T b, T e) : begin_(b), end_(e) {} constexpr MoveOnlyView(const MoveOnlyView&) = delete; constexpr MoveOnlyView(MoveOnlyView&& other) = default; constexpr MoveOnlyView& operator=(MoveOnlyView&&) = default; constexpr MoveOnlyView& operator=(const MoveOnlyView&) = delete; - constexpr T begin() { return begin_; } constexpr T begin() const { return begin_; } - constexpr sentinel_wrapper end() { return sentinel_wrapper{end_}; } constexpr sentinel_wrapper end() const { return sentinel_wrapper{end_}; } }; +static_assert(std::ranges::view>>); +static_assert(!std::copyable>>); + +template S = sentinel_wrapper> +struct CopyableView : std::ranges::view_base { + T begin_; + T end_; + + constexpr explicit CopyableView(T b, T e) : begin_(b), end_(e) {} + + constexpr CopyableView(const CopyableView&) = default; + constexpr CopyableView& operator=(const CopyableView&) = default; + + constexpr T begin() const { return begin_; } + constexpr sentinel_wrapper end() const { return sentinel_wrapper{end_}; } +}; +static_assert(std::ranges::view>>); +static_assert(std::copyable>>); //TODO: Rename as View. template S = sentinel_wrapper> From 5d357565f2592b8a5168795518d9db0f226953a8 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 22 Nov 2023 09:08:36 -0500 Subject: [PATCH 057/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Clean libcxx assertion test main signature per @varconst feedback. --- .../range.adaptors/range.stride.view/ctor.assert.pass.cpp | 3 ++- .../range.adaptors/range.stride.view/iterator/end.pass.cpp | 3 ++- .../range.stride.view/iterator/increment.pass.cpp | 3 ++- .../range.stride.view/iterator/operator_plus_equal.pass.cpp | 4 +++- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp index 5433657658480..ced1aa5ac6776 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp @@ -27,7 +27,8 @@ void stride_view_over_only_input_ranges() { [&range] { std::ranges::stride_view sv(range, -1); }(), "The value of stride must be greater than 0"); } -int main() { +int main(int, char**) { stride_view_over_only_input_ranges(); + return 0; } diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/end.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/end.pass.cpp index 16516574070a0..bf199f2adc22f 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/end.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/end.pass.cpp @@ -34,8 +34,9 @@ void cannot_dereference_past_the_end_iterator() { TEST_LIBCPP_ASSERT_FAILURE(*striv_it, "Cannot dereference an iterator at the end."); } -int main() { +int main(int, char**) { cannot_dereference_at_the_end_iterator(); cannot_dereference_past_the_end_iterator(); + return 0; } diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp index 667b74e4c3d51..093076f21aa7f 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp @@ -26,7 +26,8 @@ void cannot_increment_at_the_end_iterator() { TEST_LIBCPP_ASSERT_FAILURE(striv_it++, "Cannot increment an iterator already at the end."); } -int main() { +int main(int, char**) { cannot_increment_at_the_end_iterator(); + return 0; } diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp index caec0a2de71c6..db5373780d9e0 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp @@ -24,7 +24,9 @@ void operator_plus_equal_past_end_is_illegal() { auto striv_it = striv.begin(); TEST_LIBCPP_ASSERT_FAILURE(striv_it += 3, "Advancing the iterator beyond the end is not allowed."); } -int main() { + +int main(int, char**) { operator_plus_equal_past_end_is_illegal(); + return 0; } From df65cc919fae545b851ed78a87078179c51008f3 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 27 Nov 2023 09:54:22 -0500 Subject: [PATCH 058/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. (Finally) remove all unneeded comments. --- .../ranges/range.adaptors/range.stride.view/adaptor.pass.cpp | 3 --- .../std/ranges/range.adaptors/range.stride.view/begin.pass.cpp | 2 -- .../range.adaptors/range.stride.view/ctad.compile.pass.cpp | 2 -- .../std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp | 1 + .../std/ranges/range.adaptors/range.stride.view/end.pass.cpp | 2 -- .../range.adaptors/range.stride.view/iterator/base.pass.cpp | 3 +-- .../range.adaptors/range.stride.view/iterator/begin.pass.cpp | 3 +-- .../range.stride.view/iterator/ctor.default.pass.cpp | 3 +-- .../range.adaptors/range.stride.view/iterator/equal.pass.cpp | 2 -- .../range.stride.view/iterator/operator.pass.cpp | 3 +-- .../ranges/range.adaptors/range.stride.view/size.verify.cpp | 1 + .../ranges/range.adaptors/range.stride.view/stride.pass.cpp | 1 + 12 files changed, 7 insertions(+), 19 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index d3dcd7b73436c..f70f2302caf55 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -8,11 +8,8 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// ranges - // std::views::stride_view -#include "__ranges/stride_view.h" #include "test.h" #include "test_iterators.h" #include diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp index 68556f32f875b..3c4e6ff75fc5f 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// ranges - // std::views::stride_view constexpr bool test() { return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp index 4cceca699d215..f6f71802f861b 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// ranges - // std::views::stride_view #include "test.h" diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp index b705d30a6c74e..445552873f5fb 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp @@ -56,5 +56,6 @@ constexpr bool test() { int main(int, char**) { test(); static_assert(test()); + return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp index 68556f32f875b..3c4e6ff75fc5f 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// ranges - // std::views::stride_view constexpr bool test() { return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp index 579bcea2d7186..e4e5d319dac87 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// ranges - // std::views::stride_view #include "../test.h" @@ -51,5 +49,6 @@ int main(int, char**) { static_assert(base_noexcept()); base_const(); static_assert(base_const()); + return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp index 270d5cd0caaff..d797613499545 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// ranges - // std::views::stride_view::iterator #include "../test.h" @@ -72,5 +70,6 @@ constexpr bool iterator_concept_test() { int main(int, char**) { iterator_concept_test(); static_assert(iterator_concept_test()); + return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp index 56620b758ad6b..ad6a18e77d075 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// ranges - // std::views::stride_view #include "../test.h" @@ -242,5 +240,6 @@ int main(int, char**) { static_assert(non_simple_view_iter_ctor_test()); static_assert(iterator_default_constructible()); static_assert(non_const_iterator_copy_ctor()); + return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp index ff5196d26476c..a116141f942df 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// ranges - // std::views::stride_view #include diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index 5118b35db8204..6723c6acb6046 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// ranges - // std::views::stride_view::iterator #include "../test.h" @@ -185,5 +183,6 @@ constexpr bool operator_tests() { int main(int, char**) { operator_tests(); static_assert(operator_tests()); + return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp index c3d87a1dac7b2..62cbd3ccd2708 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp @@ -45,5 +45,6 @@ constexpr bool test() { int main(int, char**) { static_assert(test()); + return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp index 12c8338c22fb3..5107f809e6345 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp @@ -36,5 +36,6 @@ constexpr bool test() { int main(int, char**) { test(); static_assert(test()); + return 0; } From 22422065e0d1273b4619b309d4371ef23b2aa500 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 27 Nov 2023 10:36:53 -0500 Subject: [PATCH 059/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Address (some) of the comments on the adaptor tests. More work needed. --- .../range.stride.view/adaptor.pass.cpp | 143 ++++++++---------- 1 file changed, 64 insertions(+), 79 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index f70f2302caf55..dda02680d1ced 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -10,111 +10,96 @@ // std::views::stride_view +#include + #include "test.h" #include "test_iterators.h" -#include -#include -#include -#include template concept CanBePiped = requires(View&& view, T&& t) { { std::forward(view) | std::forward(t) }; }; +constexpr InputView> make_input_view(int* begin, int* end) { + return InputView>(cpp17_input_iterator(begin), cpp17_input_iterator(end)); +} + +using ForwardStrideView = std::ranges::stride_view>>; +using BidirStrideView = std::ranges::stride_view>>; +using RandomAccessStrideView = std::ranges::stride_view>>; + +static_assert(std::ranges::forward_range); +static_assert(std::ranges::bidirectional_range); +static_assert(std::ranges::random_access_range); +// TODO: check sized_range + constexpr bool test() { - constexpr int array_n = 3; - int arr[array_n] = {1, 2, 3}; + constexpr int N = 3; + int arr[N] = {1, 2, 3}; // Test that `std::views::stride` is a range adaptor. - { // Check various forms of - // view | stride - { - { - using View = InputView>; - View view(bidirectional_iterator(arr), bidirectional_iterator(arr + array_n)); - std::same_as> decltype(auto) strided = view | std::views::stride(1); - auto strided_iter = strided.begin(); - - // Check that the begin() iter views arr[0] - assert(*strided_iter == arr[0]); - - // Check that the strided_iter, after advancing it 2 * 1 steps, views arr[2]. - std::ranges::advance(strided_iter, 2); - assert(*strided_iter == arr[2]); - } - { - using View = InputView>; - View view(bidirectional_iterator(arr), bidirectional_iterator(arr + array_n)); - std::same_as> decltype(auto) strided = view | std::views::stride(2); - auto strided_iter = strided.begin(); - - assert(*strided_iter == arr[0]); - - // Same test as above, just advance one time with a bigger step (1 * 2 steps). - std::ranges::advance(strided_iter, 1); - assert(*strided_iter == arr[2]); - } - } + // Check various forms of + + // view | stride + { + using View = InputView>; + auto view = make_input_view(arr, arr + N); + std::same_as> decltype(auto) strided = view | std::views::stride(1); + auto strided_iter = strided.begin(); + + // Check that the begin() iter views arr[0] + assert(*strided_iter == arr[0]); + + // Check that the strided_iter, after advancing it 2 * 1 steps, views arr[2]. + std::ranges::advance(strided_iter, 2); + assert(*strided_iter == arr[2]); + } + { + using View = InputView>; + auto view = make_input_view(arr, arr + N); + std::same_as> decltype(auto) strided = view | std::views::stride(2); + auto strided_iter = strided.begin(); + + assert(*strided_iter == arr[0]); } - // Check various forms of // adaptor | stride + // Parallels the two tests from above. + const auto i2 = [](int i) { return i * 2; }; { - // Parallels the two tests from above. - constexpr const auto identity_lambda = [](const int i) { return i * 2; }; - { - using View = InputView>; - View view(bidirectional_iterator(arr), bidirectional_iterator(arr + array_n)); - const auto transform_stride_partial = std::views::transform(identity_lambda) | std::views::stride(1); - - auto transform_stride_applied = transform_stride_partial(view); - auto transform_stride_applied_iter = transform_stride_applied.begin(); - assert(*transform_stride_applied_iter == std::invoke(identity_lambda, arr[0])); - std::ranges::advance(transform_stride_applied_iter, 2); - assert(*transform_stride_applied_iter == std::invoke(identity_lambda, arr[2])); - } - - { - using View = InputView>; - View view(bidirectional_iterator(arr), bidirectional_iterator(arr + array_n)); - const auto transform_stride_partial = std::views::transform(identity_lambda) | std::views::stride(2); - - const auto transform_stride_applied = transform_stride_partial(view); - auto transform_stride_applied_iter = transform_stride_applied.begin(); - assert(*transform_stride_applied_iter == std::invoke(identity_lambda, arr[0])); - std::ranges::advance(transform_stride_applied_iter, 1); - assert(*transform_stride_applied_iter == std::invoke(identity_lambda, arr[2])); - } + auto view = make_input_view(arr, arr + N); + const auto transform_stride_partial = std::views::transform(i2) | std::views::stride(1); + + auto transform_stride_applied = transform_stride_partial(view); + auto transform_stride_applied_iter = transform_stride_applied.begin(); + assert(*transform_stride_applied_iter == std::invoke(i2, arr[0])); + std::ranges::advance(transform_stride_applied_iter, 2); + assert(*transform_stride_applied_iter == std::invoke(i2, arr[2])); } { - using ForwardStrideView = std::ranges::stride_view>>; - using BidirStrideView = std::ranges::stride_view>>; - using RandomAccessStrideView = std::ranges::stride_view>>; - - static_assert(std::ranges::forward_range); - static_assert(std::ranges::bidirectional_range); - static_assert(std::ranges::random_access_range); - // TODO: check sized_range - } + auto view = make_input_view(arr, arr + N); + const auto transform_stride_partial = std::views::transform(i2) | std::views::stride(2); + const auto transform_stride_applied = transform_stride_partial(view); + auto transform_stride_applied_iter = transform_stride_applied.begin(); + assert(*transform_stride_applied_iter == i2(arr[0])); + } // Check SFINAE friendliness { using View = InputView>; struct NotAViewableRange {}; - struct NotARange {}; - // Not invocable because there is no parameter. + + // TODO: WORK HERE. static_assert(!std::is_invocable_v); - // Not invocable because NotAViewableRange is, well, not a viewable range. - static_assert(!std::is_invocable_v); - // Is invocable because BidirView is a viewable range. - static_assert(std::is_invocable_v); + static_assert(!std::is_invocable_v); + static_assert(std::is_invocable_v); // Make sure that pipe operations work! - static_assert(CanBePiped{}))>); - static_assert(CanBePiped{}))>); - static_assert(!CanBePiped{}))>); + static_assert(CanBePiped); + static_assert(CanBePiped); + static_assert(!CanBePiped); + static_assert(!CanBePiped); } // A final sanity check. { static_assert(std::same_as); } From 8a51d5cd98001203cda9fb5c61f6638dccf00bc7 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 27 Nov 2023 22:18:58 -0500 Subject: [PATCH 060/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Address (remainder) of the comments on the adaptor tests. --- .../range.adaptors/range.stride.view/adaptor.pass.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index dda02680d1ced..6d3f0bd4c3535 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -72,9 +72,9 @@ constexpr bool test() { auto transform_stride_applied = transform_stride_partial(view); auto transform_stride_applied_iter = transform_stride_applied.begin(); - assert(*transform_stride_applied_iter == std::invoke(i2, arr[0])); + assert(*transform_stride_applied_iter == i2(arr[0])); std::ranges::advance(transform_stride_applied_iter, 2); - assert(*transform_stride_applied_iter == std::invoke(i2, arr[2])); + assert(*transform_stride_applied_iter == i2(arr[2])); } { @@ -87,15 +87,12 @@ constexpr bool test() { } // Check SFINAE friendliness { - using View = InputView>; struct NotAViewableRange {}; + using View = InputView>; - // TODO: WORK HERE. static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); - static_assert(std::is_invocable_v); - // Make sure that pipe operations work! static_assert(CanBePiped); static_assert(CanBePiped); static_assert(!CanBePiped); @@ -109,7 +106,7 @@ constexpr bool test() { int main(int, char**) { test(); - static_assert(test()); + //static_assert(test()); return 0; } From b3086879682ed6b8e4058f37b7f2d26755caa799 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 29 Nov 2023 09:37:31 -0500 Subject: [PATCH 061/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Complete cleanup of ctad tests. --- .../range.stride.view/ctad.compile.pass.cpp | 42 +++++++++---------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp index f6f71802f861b..c65e6a2c87d1a 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp @@ -8,34 +8,30 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// std::views::stride_view +// template +// stride_view(_Range&&, range_difference_t<_Range>) -> stride_view>; -#include "test.h" #include #include -#include -constexpr bool test() { - int arr[]{1, 2, 3}; +struct View : std::ranges::view_base { + int* begin() const; + int* end() const; +}; - MovedCopiedTrackedBasicView bv{arr, arr + 3}; - InstrumentedBasicRange br{}; +struct Range { + int* begin() const; + int* end() const; +}; - static_assert(std::same_as< decltype(std::ranges::stride_view(bv, 2)), std::ranges::stride_view >); - static_assert( - std::same_as< decltype(std::ranges::stride_view(std::move(bv), 2)), std::ranges::stride_view >); - - static_assert(std::same_as< decltype(std::ranges::drop_view(br, 0)), - std::ranges::drop_view>> >); - - static_assert(std::same_as< decltype(std::ranges::drop_view(std::move(br), 0)), - std::ranges::drop_view>> >); - return true; -} - -int main(int, char**) { - test(); - static_assert(test()); +void testCTAD() { + View v; + Range r; - return 0; + static_assert(std::same_as< decltype(std::ranges::stride_view(v, 5)), std::ranges::stride_view >); + static_assert(std::same_as< decltype(std::ranges::stride_view(std::move(v), 5)), std::ranges::stride_view >); + static_assert( + std::same_as< decltype(std::ranges::stride_view(r, 5)), std::ranges::stride_view> >); + static_assert(std::same_as< decltype(std::ranges::stride_view(std::move(r), 5)), + std::ranges::stride_view> >); } From a1966476fb579f0deb63d5587f8eecf492c15ac4 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 29 Nov 2023 09:45:44 -0500 Subject: [PATCH 062/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Clean erroneous comment in assert test of iterator::operator++. --- .../range.stride.view/iterator/increment.pass.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp index 093076f21aa7f..509d5f909c573 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp @@ -11,9 +11,7 @@ // UNSUPPORTED: !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing -// - -// Call .... +// constexpr stride_view::& operator++() { #include "check_assertion.h" #include From 9120926f99664900e831e372fab342d8704f8d5e Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 29 Nov 2023 17:39:47 -0500 Subject: [PATCH 063/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Line up expressions in std::views::stride function object. --- libcxx/include/__ranges/stride_view.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 772551abadc39..59378d2a67aa0 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -371,9 +371,9 @@ namespace __stride { struct __fn { template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) const - noexcept(noexcept(stride_view{std::forward<_Range>(__range), __n})) - -> decltype(stride_view{std::forward<_Range>(__range), __n}) { - return stride_view(std::forward<_Range>(__range), __n); + noexcept(noexcept(/**/ stride_view{std::forward<_Range>(__range), __n})) + -> decltype(/*--*/ stride_view{std::forward<_Range>(__range), __n}) { + return /*-------------*/ stride_view(std::forward<_Range>(__range), __n); } template From 2e36b430d9fd90d834ea8d6bfbf853ddf2afe192 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 29 Nov 2023 18:21:01 -0500 Subject: [PATCH 064/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. (For real\!) complete removing unnecessary comments. --- .../range.adaptors/range.stride.view/ctor.assert.pass.cpp | 2 -- .../range.adaptors/range.stride.view/iterator/end.pass.cpp | 4 ---- .../range.stride.view/iterator/operator_plus_equal.pass.cpp | 4 ---- 3 files changed, 10 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp index ced1aa5ac6776..58e604cdcd8e2 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp @@ -11,8 +11,6 @@ // UNSUPPORTED: !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing -// - // Call stride_view() ctor empty stride <= 0 #include "check_assertion.h" diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/end.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/end.pass.cpp index bf199f2adc22f..30b74d3d383da 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/end.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/end.pass.cpp @@ -11,10 +11,6 @@ // UNSUPPORTED: !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing -// - -// Call .... - #include "check_assertion.h" #include diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp index db5373780d9e0..13a56b4e12917 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp @@ -11,10 +11,6 @@ // UNSUPPORTED: !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing -// - -// Call .... - #include "check_assertion.h" #include From 3597506ce7fa73a6c1e4eaad4c0d60244ebea801 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 29 Nov 2023 21:33:44 -0500 Subject: [PATCH 065/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Upload test for stride_view::iterator == presence when base is not equalable. --- .../iterator/operator.pass.cpp | 68 ++++++++++++------- .../range.adaptors/range.stride.view/test.h | 20 ++++++ 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index 6723c6acb6046..8bae7e110a749 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -10,45 +10,43 @@ // std::views::stride_view::iterator +#include + #include "../test.h" -#include "__concepts/constructible.h" -#include "__iterator/concepts.h" -#include "__ranges/access.h" -#include "__ranges/concepts.h" #include "test_iterators.h" -#include -#include -#include template -concept is_plus_equalable = requires(T& __t) { __t += 1; }; +concept is_plus_equalable = requires(T& t) { t += 1; }; template -concept is_minus_equalable = requires(T& __t) { __t -= 1; }; +concept is_minus_equalable = requires(T& t) { t -= 1; }; template -concept is_plusable = requires(T& __t) { __t + 1; }; +concept is_plusable = requires(T& t) { t + 1; }; template -concept is_minusable = requires(T& __t) { __t - 1; }; +concept is_minusable = requires(T& t) { t - 1; }; template -concept is_relationally_comparable = requires(T& __t) { - __t < __t; - __t > __t; - __t <= __t; - __t >= __t; +concept is_relationally_comparable = requires(T& t) { + t < t; + t > t; + t <= t; + t >= t; }; template -concept is_plus_plusable_post = requires(T& __t) { __t++; }; +concept is_relationally_equalable = requires(T& t) { t == t; }; + template -concept is_plus_plusable_pre = requires(T& __t) { ++__t; }; +concept is_plus_plusable_post = requires(T& t) { t++; }; template -concept is_minus_minusable_post = requires(T& __t) { __t--; }; +concept is_plus_plusable_pre = requires(T& t) { ++t; }; template -concept is_minus_minusable_pre = requires(T& __t) { --__t; }; +concept is_minus_minusable_post = requires(T& t) { t--; }; +template +concept is_minus_minusable_pre = requires(T& t) { --t; }; template -concept can_calculate_distance_between_non_sentinel = requires(T& __t) { __t - __t; }; +concept can_calculate_distance_between_non_sentinel = requires(T& t) { t - t; }; constexpr bool operator_tests() { { @@ -59,7 +57,7 @@ constexpr bool operator_tests() { auto rav = View(cpp17_input_iterator(arr), cpp17_input_iterator(arr + 3)); auto str = std::ranges::stride_view(rav, 1); - auto strb = str.begin(); + [[maybe_unused]] auto strb = str.begin(); static_assert(is_plus_plusable_post); static_assert(is_plus_plusable_pre); @@ -79,7 +77,7 @@ constexpr bool operator_tests() { auto rav = View(forward_iterator(arr), forward_iterator(arr + 3)); auto str = std::ranges::stride_view(rav, 1); - auto strb = str.begin(); + [[maybe_unused]] auto strb = str.begin(); static_assert(is_plus_plusable_post); static_assert(is_plus_plusable_pre); @@ -99,7 +97,7 @@ constexpr bool operator_tests() { auto rav = View(bidirectional_iterator(arr), bidirectional_iterator(arr + 3)); auto str = std::ranges::stride_view(rav, 1); - auto strb = str.begin(); + [[maybe_unused]] auto strb = str.begin(); static_assert(is_plus_plusable_post); static_assert(is_plus_plusable_pre); @@ -119,7 +117,7 @@ constexpr bool operator_tests() { auto rav = View(random_access_iterator(arr), random_access_iterator(arr + 3)); auto str = std::ranges::stride_view(rav, 1); - auto strb = str.begin(); + [[maybe_unused]] auto strb = str.begin(); static_assert(is_plus_plusable_post); static_assert(is_plus_plusable_pre); @@ -177,6 +175,26 @@ constexpr bool operator_tests() { assert(stride_zoff_one - stride_ooff_two == -1); assert(stride_zoff_one - stride_ooff_five == -2); } + + { + using EqualableView = InputView>; + using Stride = std::ranges::stride_view; + using StrideIter = std::ranges::iterator_t; + + static_assert(is_relationally_equalable>); + static_assert(is_relationally_equalable); + } + + { + using UnEqualableView = + ViewOverNonCopyable, sentinel_wrapper>>; + using Stride = std::ranges::stride_view; + using StrideIter = std::ranges::iterator_t; + + static_assert(!is_relationally_equalable>); + static_assert(!is_relationally_equalable); + } + return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index 634b8a34991ef..fc7f528a22196 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -181,6 +181,26 @@ struct InputView : std::ranges::view_base { constexpr sentinel_wrapper end() const { return sentinel_wrapper{end_}; } }; +// Don't move/hold the iterator itself, move/hold the base +// of that iterator and reconstruct the iterator on demand. +// May result in aliasing (if, e.g., Iterator is an iterator +// over int *). +template +struct ViewOverNonCopyable : std::ranges::view_base { + constexpr explicit ViewOverNonCopyable(Iterator it, Sentinel sent) + : it_(base(std::move(it))), sent_(base(std::move(sent))) {} + + ViewOverNonCopyable(ViewOverNonCopyable&&) = default; + ViewOverNonCopyable& operator=(ViewOverNonCopyable&&) = default; + + constexpr Iterator begin() const { return Iterator(it_); } + constexpr Sentinel end() const { return Sentinel(sent_); } + +private: + decltype(base(std::declval())) it_; + decltype(base(std::declval())) sent_; +}; + struct ForwardTracedMoveIter : ForwardIterBase { bool moved = false; From 38e6a60ced80787515803072f0ec2d26343ddb09 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 1 Dec 2023 10:28:43 -0500 Subject: [PATCH 066/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Cleanup (and add) iterator::operator@ tests. --- .../iterator/operator.pass.cpp | 163 ++++++++++-------- 1 file changed, 93 insertions(+), 70 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index 8bae7e110a749..3520ae116c01c 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -8,7 +8,20 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// std::views::stride_view::iterator +// constexpr __iterator& operator++() +// constexpr void operator++(int) +// constexpr __iterator operator++(int) +// constexpr __iterator& operator--() +// constexpr __iterator operator--(int) +// constexpr __iterator& operator+=(difference_type __n) +// constexpr __iterator& operator-=(difference_type __n) +// friend constexpr bool operator==(__iterator const& __x, default_sentinel_t) +// friend constexpr bool operator==(__iterator const& __x, __iterator const& __y) +// friend constexpr bool operator<(__iterator const& __x, __iterator const& __y) +// friend constexpr bool operator>(__iterator const& __x, __iterator const& __y) +// friend constexpr bool operator<=(__iterator const& __x, __iterator const& __y) +// friend constexpr bool operator>=(__iterator const& __x, __iterator const& __y) +// friend constexpr bool operator<=>(__iterator const& __x, __iterator const& __y) #include @@ -21,9 +34,11 @@ template concept is_minus_equalable = requires(T& t) { t -= 1; }; template -concept is_plusable = requires(T& t) { t + 1; }; +concept is_iterator_minusable = requires(T& t) { t - t; }; template -concept is_minusable = requires(T& t) { t - 1; }; +concept is_difference_plusable = requires(T& t) { t + 1; }; +template +concept is_difference_minusable = requires(T& t) { t - 1; }; template concept is_relationally_comparable = requires(T& t) { @@ -36,6 +51,9 @@ concept is_relationally_comparable = requires(T& t) { template concept is_relationally_equalable = requires(T& t) { t == t; }; +template +concept is_three_way_comparable = requires(T& t) { t <=> t; }; + template concept is_plus_plusable_post = requires(T& t) { t++; }; template @@ -52,85 +70,75 @@ constexpr bool operator_tests() { { // What operators are valid for an iterator derived from a stride view // over an input view. - int arr[] = {1, 2, 3}; - using View = InputView>; - auto rav = View(cpp17_input_iterator(arr), cpp17_input_iterator(arr + 3)); - auto str = std::ranges::stride_view(rav, 1); - - [[maybe_unused]] auto strb = str.begin(); - - static_assert(is_plus_plusable_post); - static_assert(is_plus_plusable_pre); - static_assert(!is_minus_minusable_post); - static_assert(!is_minus_minusable_pre); - static_assert(!is_plus_equalable); - static_assert(!is_minus_equalable); - static_assert(!is_plusable); - static_assert(!is_minusable); - static_assert(!is_relationally_comparable); + using View = InputView>; + using StrideViewIterator = std::ranges::iterator_t>; + + static_assert(is_plus_plusable_post); + static_assert(is_plus_plusable_pre); + static_assert(!is_minus_minusable_post); + static_assert(!is_minus_minusable_pre); + static_assert(!is_plus_equalable); + static_assert(!is_minus_equalable); + static_assert(!is_iterator_minusable); + static_assert(!is_difference_plusable); + static_assert(!is_difference_minusable); + static_assert(!is_relationally_comparable); } { // What operators are valid for an iterator derived from a stride view - // over a forward view. - int arr[] = {1, 2, 3}; - using View = InputView>; - auto rav = View(forward_iterator(arr), forward_iterator(arr + 3)); - auto str = std::ranges::stride_view(rav, 1); - - [[maybe_unused]] auto strb = str.begin(); - - static_assert(is_plus_plusable_post); - static_assert(is_plus_plusable_pre); - static_assert(!is_minus_minusable_post); - static_assert(!is_minus_minusable_pre); - static_assert(!is_plus_equalable); - static_assert(!is_minus_equalable); - static_assert(!is_plusable); - static_assert(!is_minusable); - static_assert(!is_relationally_comparable); + // over a forward view. + using View = InputView>; + using StrideViewIterator = std::ranges::iterator_t>; + + static_assert(is_plus_plusable_post); + static_assert(is_plus_plusable_pre); + static_assert(!is_minus_minusable_post); + static_assert(!is_minus_minusable_pre); + static_assert(!is_plus_equalable); + static_assert(!is_minus_equalable); + static_assert(!is_iterator_minusable); + static_assert(!is_difference_plusable); + static_assert(!is_difference_minusable); + static_assert(!is_relationally_comparable); } { // What operators are valid for an iterator derived from a stride view // over a bidirectional view. - int arr[] = {1, 2, 3}; - using View = InputView>; - auto rav = View(bidirectional_iterator(arr), bidirectional_iterator(arr + 3)); - auto str = std::ranges::stride_view(rav, 1); - - [[maybe_unused]] auto strb = str.begin(); - - static_assert(is_plus_plusable_post); - static_assert(is_plus_plusable_pre); - static_assert(is_minus_minusable_post); - static_assert(is_minus_minusable_pre); - static_assert(!is_plus_equalable); - static_assert(!is_minus_equalable); - static_assert(!is_plusable); - static_assert(!is_minusable); - static_assert(!is_relationally_comparable); + using View = InputView>; + using StrideViewIterator = std::ranges::iterator_t>; + + static_assert(is_plus_plusable_post); + static_assert(is_plus_plusable_pre); + static_assert(is_minus_minusable_post); + static_assert(is_minus_minusable_pre); + static_assert(!is_plus_equalable); + static_assert(!is_minus_equalable); + static_assert(!is_iterator_minusable); + static_assert(!is_difference_plusable); + static_assert(!is_difference_minusable); + static_assert(!is_relationally_comparable); } { // What operators are valid for an iterator derived from a stride view // over a random access view. - int arr[] = {1, 2, 3}; - using View = InputView>; - auto rav = View(random_access_iterator(arr), random_access_iterator(arr + 3)); - auto str = std::ranges::stride_view(rav, 1); - - [[maybe_unused]] auto strb = str.begin(); - - static_assert(is_plus_plusable_post); - static_assert(is_plus_plusable_pre); - static_assert(is_minus_minusable_post); - static_assert(is_minus_minusable_pre); - static_assert(is_plus_equalable); - static_assert(is_minus_equalable); - static_assert(is_plusable); - static_assert(is_minusable); - static_assert(is_relationally_comparable); + using View = InputView>; + using StrideViewIterator = std::ranges::iterator_t>; + + static_assert(is_plus_plusable_post); + static_assert(is_plus_plusable_pre); + static_assert(is_minus_minusable_post); + static_assert(is_minus_minusable_pre); + static_assert(is_plus_equalable); + static_assert(is_minus_equalable); + static_assert(is_iterator_minusable); + static_assert(is_difference_plusable); + static_assert(is_difference_minusable); + static_assert(is_relationally_comparable); } - { + // Test the forward-range operator- between two iterators (i.e., no ceil). + // TODO + } { // Test the non-forward-range operator- between two iterators (i.e., ceil). int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; auto rav_zero = @@ -175,7 +183,6 @@ constexpr bool operator_tests() { assert(stride_zoff_one - stride_ooff_two == -1); assert(stride_zoff_one - stride_ooff_five == -2); } - { using EqualableView = InputView>; using Stride = std::ranges::stride_view; @@ -183,8 +190,20 @@ constexpr bool operator_tests() { static_assert(is_relationally_equalable>); static_assert(is_relationally_equalable); + + static_assert(!std::three_way_comparable>); + static_assert(!std::ranges::random_access_range); + static_assert(!is_three_way_comparable); } + { + using ThreeWayComparableView = InputView>; + using Stride = std::ranges::stride_view; + using StrideIter = std::ranges::iterator_t; + static_assert(std::three_way_comparable>); + static_assert(std::ranges::random_access_range); + static_assert(is_three_way_comparable); + } { using UnEqualableView = ViewOverNonCopyable, sentinel_wrapper>>; @@ -193,6 +212,10 @@ constexpr bool operator_tests() { static_assert(!is_relationally_equalable>); static_assert(!is_relationally_equalable); + + static_assert(!std::three_way_comparable>); + static_assert(!std::ranges::random_access_range); + static_assert(!is_three_way_comparable); } return true; From fb172114b76841310a9a565c5d702137b1207569 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 1 Dec 2023 10:34:46 -0500 Subject: [PATCH 067/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Remove extraneous comment from libcxx assertion test on ctor. --- .../ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp index 58e604cdcd8e2..b100996836433 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp @@ -18,7 +18,6 @@ void stride_view_over_only_input_ranges() { int range[] = {1, 2, 3}; - // Keep up to date with assertion message from the ctor. TEST_LIBCPP_ASSERT_FAILURE( [&range] { std::ranges::stride_view sv(range, 0); }(), "The value of stride must be greater than 0"); TEST_LIBCPP_ASSERT_FAILURE( From 7c5488810158b6d3ad4a9c8b50c5b8f3469c7db2 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 4 Dec 2023 11:45:14 -0500 Subject: [PATCH 068/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add test for iterator::operator- on forward iterators (and clean up other iterator::operator- test). --- .../iterator/operator.pass.cpp | 75 ++++++++++++++----- .../range.adaptors/range.stride.view/test.h | 30 ++++++++ 2 files changed, 88 insertions(+), 17 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index 3520ae116c01c..f0276453ec9c4 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -136,31 +136,72 @@ constexpr bool operator_tests() { static_assert(is_relationally_comparable); } { - // Test the forward-range operator- between two iterators (i.e., no ceil). - // TODO - } { + using Base = InputView; + // Test the forward-range operator- between two iterators (i.e., no ceil). + int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + auto rav_zero = Base(SizedForwardIterator(arr), SizedForwardIterator(arr + 10)); + auto rav_one = Base(SizedForwardIterator(arr + 1), SizedForwardIterator(arr + 10)); + auto stride_zoff = std::ranges::stride_view(rav_zero, 3); + auto stride_ooff = std::ranges::stride_view(rav_one, 3); + + auto stride_zoff_begin = stride_zoff.begin(); + auto stride_ooff_begin = stride_ooff.begin(); + + auto stride_zoff_one = stride_zoff_begin; + auto stride_zoff_four = ++stride_zoff_begin; + auto stride_zoff_seven = ++stride_zoff_begin; + + auto stride_ooff_two = stride_ooff_begin; + auto stride_ooff_five = ++stride_ooff_begin; + + static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); + static_assert(can_calculate_distance_between_non_sentinel); + static_assert(std::forward_iterator); + + assert(*stride_zoff_one == 1); + assert(*stride_zoff_four == 4); + assert(*stride_zoff_seven == 7); + + assert(*stride_ooff_two == 2); + assert(*stride_ooff_five == 5); + // Check positive __n with exact multiple of left's stride. + assert(stride_zoff_four - stride_zoff_one == 1); + assert(stride_zoff_seven - stride_zoff_one == 2); + + // Check positive __n with non-exact multiple of left's stride. + assert(stride_ooff_two - stride_zoff_one == 0); + assert(stride_ooff_five - stride_zoff_one == 1); + + // Check negative __n with exact multiple of left's stride. + assert(stride_zoff_one - stride_zoff_four == -1); + assert(stride_zoff_one - stride_zoff_seven == -2); + + // Check negative __n with non-exact multiple of left's stride. + assert(stride_zoff_one - stride_ooff_two == 0); + assert(stride_zoff_one - stride_ooff_five == -1); + } + + { + using Base = InputView; // Test the non-forward-range operator- between two iterators (i.e., ceil). int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - auto rav_zero = - InputView(SizedInputIterator(arr), SizedInputIterator(arr + 10)); - auto rav_one = - InputView(SizedInputIterator(arr + 1), SizedInputIterator(arr + 10)); + auto rav_zero = Base(SizedInputIterator(arr), SizedInputIterator(arr + 10)); + auto rav_one = Base(SizedInputIterator(arr + 1), SizedInputIterator(arr + 10)); auto stride_zoff = std::ranges::stride_view(rav_zero, 3); auto stride_ooff = std::ranges::stride_view(rav_one, 3); - auto stride_zoff_base = stride_zoff.begin(); - auto stride_ooff_base = stride_ooff.begin(); + auto stride_zoff_begin = stride_zoff.begin(); + auto stride_ooff_begin = stride_ooff.begin(); - auto stride_zoff_one = stride_zoff_base; - auto stride_zoff_four = ++stride_zoff_base; - auto stride_zoff_seven = ++stride_zoff_base; + auto stride_zoff_one = stride_zoff_begin; + auto stride_zoff_four = ++stride_zoff_begin; + auto stride_zoff_seven = ++stride_zoff_begin; - auto stride_ooff_two = stride_ooff_base; - auto stride_ooff_five = ++stride_ooff_base; + auto stride_ooff_two = stride_ooff_begin; + auto stride_ooff_five = ++stride_ooff_begin; - static_assert(std::sized_sentinel_for); - static_assert(can_calculate_distance_between_non_sentinel); + static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); + static_assert(can_calculate_distance_between_non_sentinel); assert(*stride_zoff_one == 1); assert(*stride_zoff_four == 4); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index fc7f528a22196..86f225ef37993 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -253,4 +253,34 @@ struct SizedInputIterator { } }; +// TODO: Cleanup +struct SizedForwardIterator { + using iterator_concept = std::forward_iterator_tag; + using value_type = int; + using difference_type = std::intptr_t; + + int* __v_; + + constexpr SizedForwardIterator() { __v_ = nullptr; } + constexpr SizedForwardIterator(int* v) { __v_ = v; } + constexpr SizedForwardIterator(const SizedInputIterator& sii) { __v_ = sii.__v_; } + + constexpr int operator*() const { return *__v_; } + constexpr SizedForwardIterator& operator++() { + __v_++; + return *this; + } + constexpr SizedForwardIterator operator++(int) { + auto nv = __v_; + nv++; + return SizedForwardIterator(nv); + } + friend constexpr bool operator==(const SizedForwardIterator& left, const SizedForwardIterator& right) { + return left.__v_ == right.__v_; + } + friend constexpr difference_type operator-(const SizedForwardIterator& left, const SizedForwardIterator& right) { + return left.__v_ - right.__v_; + } +}; + #endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H From 36c356a1d5c3986079073de796f989b1887e8763 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 8 Dec 2023 11:49:24 -0500 Subject: [PATCH 069/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Clean up iterator ctor (copy and default) tests. --- .../iterator/ctor.copy.pass.cpp | 372 ++++++++++++++++++ .../iterator/ctor.default.pass.cpp | 245 ------------ .../iterator/ctor.default.verify.cpp | 39 ++ 3 files changed, 411 insertions(+), 245 deletions(-) create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp new file mode 100644 index 0000000000000..aa4183105eca1 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp @@ -0,0 +1,372 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// constexpr __iterator(__iterator __i) +// requires _Const && convertible_to, iterator_t<_Base>> && +// convertible_to, sentinel_t<_Base>> + +#include + +#include "../test.h" +#include "test_iterators.h" + +struct NotSimpleViewIterBegin : InputIterBase {}; + +template +struct NotSimpleViewConstIterBegin : InputIterBase> { + constexpr NotSimpleViewConstIterBegin() = default; + constexpr NotSimpleViewConstIterBegin(NotSimpleViewConstIterBegin&&) {} + constexpr NotSimpleViewConstIterBegin& operator=(const NotSimpleViewConstIterBegin&) {} + constexpr NotSimpleViewConstIterBegin& operator=(NotSimpleViewConstIterBegin&&) {} + + constexpr NotSimpleViewConstIterBegin(const NotSimpleViewConstIterBegin&) {} + constexpr NotSimpleViewConstIterBegin(const NotSimpleViewIterBegin&) + requires CopyConvertible + {} + constexpr NotSimpleViewConstIterBegin(NotSimpleViewIterBegin&&) + requires MoveConvertible + {} +}; + +struct NotSimpleViewIterEnd : InputIterBase {}; + +template +struct NotSimpleViewConstIterEnd : InputIterBase> { + constexpr NotSimpleViewConstIterEnd() = default; + constexpr NotSimpleViewConstIterEnd(NotSimpleViewConstIterEnd&&) {} + constexpr NotSimpleViewConstIterEnd& operator=(const NotSimpleViewConstIterEnd&) {} + constexpr NotSimpleViewConstIterEnd& operator=(NotSimpleViewConstIterEnd&&) {} + + constexpr NotSimpleViewConstIterEnd(const NotSimpleViewConstIterEnd&) {} + constexpr NotSimpleViewConstIterEnd(const NotSimpleViewIterEnd&) + requires CopyConvertible + {} + constexpr NotSimpleViewConstIterEnd(NotSimpleViewIterEnd&&) + requires MoveConvertible + {} +}; + +constexpr bool operator==(const NotSimpleViewIterBegin&, const NotSimpleViewIterEnd&) { return true; } +constexpr bool operator==(const NotSimpleViewIterEnd&, const NotSimpleViewIterBegin&) { return true; } + +template +constexpr bool +operator==(const NotSimpleViewConstIterBegin&, const NotSimpleViewIterEnd&) { + return true; +} +template +constexpr bool +operator==(const NotSimpleViewConstIterBegin&, const NotSimpleViewIterBegin&) { + return true; +} +template +constexpr bool +operator==(const NotSimpleViewIterBegin&, const NotSimpleViewConstIterEnd&) { + return true; +} +template +constexpr bool +operator==(const NotSimpleViewIterBegin&, const NotSimpleViewConstIterBegin&) { + return true; +} + +template +constexpr bool +operator==(const NotSimpleViewConstIterEnd&, const NotSimpleViewIterEnd&) { + return true; +} +template +constexpr bool +operator==(const NotSimpleViewConstIterEnd&, const NotSimpleViewIterBegin&) { + return true; +} +template +constexpr bool +operator==(const NotSimpleViewIterEnd&, const NotSimpleViewConstIterBegin&) { + return true; +} +template +constexpr bool +operator==(const NotSimpleViewIterEnd&, const NotSimpleViewConstIterEnd&) { + return true; +} + +/* + * Goal: We will need a way to get a stride_view::__iterator and a + * stride_view::__iterator because those are the two possible types + * of the stride_view::__iterator constructor. The template value is determined + * by whether the stride_view::__iterator is derivative of a stride_view over a + * view that is simple. + * + * So, first things first, we need to build a stride_view over a (non-)simple view. + * There are (at least) two ways that a view can be non-simple: + * 1. The iterator type for const begin is different than the iterator type for begin + * 2. The iterator type for const end is different that the iterator type for end + * + * So, let's create two different classes where that is the case so that we can test + * for those conditions individually. We parameterize with a template to decide + * whether to + * 1. enable converting constructors between the non-const and the const version. + * That feature is important for testing the stride_view::__iterator converting + * constructor from a stride_view::_iterator iterator. + * 2. enable copyability. That feature is important for testing whether the requirement + * the that copy constructor for the stride_view::__iterator type actually moves + * the underlying iterator. + */ +template +struct NotSimpleViewDifferentBegin : std::ranges::view_base { + constexpr NotSimpleViewConstIterBegin begin() const { return {}; } + constexpr NotSimpleViewIterBegin begin() { return {}; } + + constexpr NotSimpleViewIterEnd end() const { return {}; } +}; + +template +struct NotSimpleViewDifferentEnd : std::ranges::view_base { + constexpr NotSimpleViewIterBegin begin() const { return {}; } + constexpr NotSimpleViewConstIterEnd end() const { return {}; } + constexpr NotSimpleViewIterEnd end() { return {}; } +}; + +constexpr bool non_simple_view_iter_ctor_test() { + using NotSimpleStrideView = std::ranges::stride_view>; + using NotSimpleStrideViewIter = std::ranges::iterator_t; + using NotSimpleStrideViewIterConst = std::ranges::iterator_t; + static_assert(!std::is_same_v); + return true; +} + +constexpr bool non_const_iterator_copy_ctor() { + // All tests share the following general configuration. + // + // Instantiate a stride view StrideView over a non-simple view (NotSimpleViewBeingStrided) whose + // 1. std::ranges::iterator_t base's type is NotSimpleViewBeingStridedIterator + // 2. std::ranges::iterator_t base's type is NotSimpleViewBeingStridedConstIterator + // 3. NotSimpleViewBeingStridedIterator is ONLY move-convertible to NotSimpleViewBeingStridedConstIterator + // 4. std::ranges::sentinel_t are the same whether SV is const or not. + // 4. the type of StrideView::end is the same whether StrideView is const or not. + // 5. the type of StrideView::begin is stride_view::iterator when StrideView is const and + // stride_view::iterator when StrideView is non const. + // Visually, it looks like this: + // + // NotSimpleViewBeingStrided(Const)Iterator <----- + // ^ | + // | | + // | begin (const?) | + // | | + // NotSimpleViewBeingStrided | + // ^ | + // | | + // | Strides over | + // | | + // StrideView | + // | | + // | begin (const?) | + // | | + // \/ | + // StrideView(Const)Iter | + // | | + // | base | + // | | + // --------------------------------- + + { + // Stride over non-simple view over whose iterators are copy convertible -- should look (statically) + // like it is possible copy construct the stride view's iterator (the move-only requirement comes from + // a move of the current between the copied-from iterator to the copied-to iterator). + using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; + using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + + using StrideView = std::ranges::stride_view; + + using StrideViewIter = std::ranges::iterator_t; + using StrideViewConstIter = std::ranges::iterator_t; + + using StrideViewSentinel = std::ranges::sentinel_t; + using StrideViewConstSentinel = std::ranges::sentinel_t; + + static_assert(std::convertible_to); + static_assert(std::constructible_from); + } + + { + // Stride over non-simple view over whose iterators are move convertible -- should look (statically) + // like it is possible copy construct the stride view's iterator (the move-only requirement comes from + // a move of the current between the copied-from iterator to the copied-to iterator). + using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; + using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + + using StrideView = std::ranges::stride_view; + + using StrideViewIter = std::ranges::iterator_t; + using StrideViewConstIter = std::ranges::iterator_t; + + using StrideViewSentinel = std::ranges::sentinel_t; + using StrideViewConstSentinel = std::ranges::sentinel_t; + + static_assert(std::convertible_to); + static_assert(std::constructible_from); + } + + { + // Stride over non-simple view over whose iterators are not convertible -- should not be able + // to copy construct the stride view's iterator. + using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; + using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + + using StrideView = std::ranges::stride_view; + + using StrideViewIter = std::ranges::iterator_t; + using StrideViewConstIter = std::ranges::iterator_t; + + using StrideViewSentinel = std::ranges::sentinel_t; + using StrideViewConstSentinel = std::ranges::sentinel_t; + + static_assert(!std::convertible_to); + static_assert(!std::constructible_from); + } + + { + // Stride over non-simple view over whose iterators are not convertible -- should not be able + // to copy construct the stride view's iterator. + using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; + using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + + using StrideView = std::ranges::stride_view; + + using StrideViewIter = std::ranges::iterator_t; + using StrideViewConstIter = std::ranges::iterator_t; + + using StrideViewSentinel = std::ranges::sentinel_t; + using StrideViewConstSentinel = std::ranges::sentinel_t; + + static_assert(std::convertible_to); + static_assert(std::convertible_to); + + StrideView str{NotSimpleViewBeingStrided{}, 5}; + // Confirm (5) + static_assert(std::is_same_v); + + // Now, do what we wanted the whole time: make sure that we can copy construct a + // stride_view::iterator from a stride_view::iterator. The copy + // constructor requires that the new __current_ StrideViewConstIter (type + // NotSimpleViewBeingStridedConstIterator) be constructable + // from the moved str.begin() __current_ (type NotSimpleViewBeingStridedConstIterator). + StrideViewConstIter iterator_copy{str.begin()}; + } + + { + // Stride over non-simple view over whose iterators are copy convertible -- should look (statically) + // like it is possible copy construct the stride view's iterator (the move-only requirement comes from + // a move of the current between the copied-from iterator to the copied-to iterator). + using NotSimpleViewBeingStrided = NotSimpleViewDifferentBegin; + using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + + using StrideView = std::ranges::stride_view; + + using StrideViewIter = std::ranges::iterator_t; + using StrideViewConstIter = std::ranges::iterator_t; + + using StrideViewSentinel = std::ranges::sentinel_t; + using StrideViewConstSentinel = std::ranges::sentinel_t; + + static_assert(std::convertible_to); + static_assert(std::constructible_from); + } + + { + // Stride over non-simple view over whose iterators are move convertible -- should look (statically) + // like it is possible copy construct the stride view's iterator (the move-only requirement comes from + // a move of the current between the copied-from iterator to the copied-to iterator). + using NotSimpleViewBeingStrided = NotSimpleViewDifferentBegin; + using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + + using StrideView = std::ranges::stride_view; + + using StrideViewIter = std::ranges::iterator_t; + using StrideViewConstIter = std::ranges::iterator_t; + + using StrideViewSentinel = std::ranges::sentinel_t; + using StrideViewConstSentinel = std::ranges::sentinel_t; + + static_assert(std::convertible_to); + static_assert(std::constructible_from); + } + + { + // Stride over non-simple view over whose iterators are not convertible -- should not be able + // to copy construct the stride view's iterator. + using NotSimpleViewBeingStrided = NotSimpleViewDifferentBegin; + using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + + using StrideView = std::ranges::stride_view; + + using StrideViewIter = std::ranges::iterator_t; + using StrideViewConstIter = std::ranges::iterator_t; + + using StrideViewSentinel = std::ranges::sentinel_t; + using StrideViewConstSentinel = std::ranges::sentinel_t; + + static_assert(!std::convertible_to); + static_assert(!std::constructible_from); + } + + { + // The NotSimpleViewBeingStrided template parameters mean that NotSimpleViewBeingStridedIterator + // can be move-converted to NotSimpleViewBeingStridedConstIterator but not copy-converted. + using NotSimpleViewBeingStrided = NotSimpleViewDifferentBegin; + using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + + using StrideView = std::ranges::stride_view; + + using StrideViewIter = std::ranges::iterator_t; + using StrideViewConstIter = std::ranges::iterator_t; + + using StrideViewSentinel = std::ranges::sentinel_t; + using StrideViewConstSentinel = std::ranges::sentinel_t; + + // Confirm (1) and (2) + static_assert(std::is_same_v().base())>); + static_assert( + std::is_same_v().base())>); + // Confirm (3) + static_assert(std::convertible_to); + static_assert(std::convertible_to); + // Confirm (4) + static_assert(std::is_same_v); + + StrideView str{NotSimpleViewBeingStrided{}, 5}; + // Confirm (5) + static_assert(std::is_same_v); + + // Now, do what we wanted the whole time: make sure that we can copy construct a + // stride_view::iterator from a stride_view::iterator. The copy + // constructor requires that the new __current_ StrideViewConstIter (type + // NotSimpleViewBeingStridedConstIterator) be constructable + // from the moved str.begin() __current_ (type NotSimpleViewBeingStridedConstIterator). + StrideViewConstIter iterator_copy{str.begin()}; + } + return true; +} + +int main(int, char**) { + non_simple_view_iter_ctor_test(); + static_assert(non_simple_view_iter_ctor_test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp deleted file mode 100644 index ad6a18e77d075..0000000000000 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.pass.cpp +++ /dev/null @@ -1,245 +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, c++20 - -// std::views::stride_view - -#include "../test.h" -#include "__concepts/convertible_to.h" -#include "__iterator/concepts.h" -#include "__ranges/access.h" -#include "__ranges/concepts.h" -#include "__ranges/stride_view.h" -#include -#include -#include -#include - -struct NotSimpleViewIter : InputIterBase {}; -struct NotSimpleViewIterEnd : InputIterBase {}; -constexpr bool operator==(const NotSimpleViewIter&, const NotSimpleViewIterEnd&) { return true; } -constexpr bool operator==(const NotSimpleViewIterEnd&, const NotSimpleViewIter&) { return true; } - -template -struct NotSimpleViewConstIterEnd : InputIterBase> { - constexpr NotSimpleViewConstIterEnd() = default; - constexpr NotSimpleViewConstIterEnd(const NotSimpleViewConstIterEnd&&) {} - constexpr NotSimpleViewConstIterEnd& operator=(const NotSimpleViewConstIterEnd&) {} - constexpr NotSimpleViewConstIterEnd& operator=(const NotSimpleViewConstIterEnd&&) {} - - constexpr NotSimpleViewConstIterEnd(const NotSimpleViewConstIterEnd&) - requires Copyable - {} - constexpr NotSimpleViewConstIterEnd(const NotSimpleViewIterEnd&) - requires Convertible - {} -}; - -template -struct NotSimpleViewConstIter : InputIterBase> { - constexpr NotSimpleViewConstIter() = default; - constexpr NotSimpleViewConstIter(const NotSimpleViewConstIter&&) {} - constexpr NotSimpleViewConstIter& operator=(const NotSimpleViewConstIter&&) {} - constexpr NotSimpleViewConstIter& operator=(const NotSimpleViewConstIter&) {} - - constexpr NotSimpleViewConstIter(const NotSimpleViewConstIter&) - requires Copyable - {} - constexpr NotSimpleViewConstIter(const NotSimpleViewIter&) - requires Convertible - {} -}; - -template -constexpr bool operator==(const NotSimpleViewConstIter&, const NotSimpleViewIterEnd&) { - return true; -} -template -constexpr bool operator==(const NotSimpleViewIterEnd&, const NotSimpleViewConstIter&) { - return true; -} -template -constexpr bool operator==(const NotSimpleViewConstIterEnd&, const NotSimpleViewIterEnd&) { - return true; -} -template -constexpr bool operator==(const NotSimpleViewIterEnd&, const NotSimpleViewConstIterEnd&) { - return true; -} -template -constexpr bool operator==(const NotSimpleViewIter&, const NotSimpleViewConstIterEnd&) { - return true; -} -template -constexpr bool operator==(const NotSimpleViewConstIterEnd&, const NotSimpleViewIter&) { - return true; -} - -/* - * There are (at least) two ways that a view can be non-simple: - * 1. The iterator type for const begin is different than the iterator type for begin - * 2. The iterator type for const end is different that the iterator type for end - * - * So, let's create two different classes where that is the case so that we can test - * for those conditions individually. We parameterize with a template to decide - * whether to - * 1. enable converting constructors between the non-const and the const version. - * That feature is important for testing the stride_view::__iterator converting - * constructor from a stride_view::_iterator iterator. - * 2. enable copyability. That feature is important for testing whether the requirement - * the that copy constructor for the stride_view::__iterator type actually moves - * the underlying iterator. - */ -template -struct NotSimpleViewDifferentBegin : std::ranges::view_base { - constexpr NotSimpleViewConstIter begin() const { return {}; } - constexpr NotSimpleViewIter begin() { return {}; } - constexpr NotSimpleViewIterEnd end() const { return {}; } - constexpr NotSimpleViewIterEnd end() { return {}; } -}; - -template -struct NotSimpleViewDifferentEnd : std::ranges::view_base { - constexpr NotSimpleViewIter begin() const { return {}; } - constexpr NotSimpleViewIter begin() { return {}; } - constexpr NotSimpleViewConstIterEnd end() const { - return std::move(NotSimpleViewConstIterEnd{}); - } - constexpr NotSimpleViewIterEnd end() { return {}; } -}; - -constexpr bool non_simple_view_iter_ctor_test() { - using NotSimpleStrideView = std::ranges::stride_view>; - using NotSimpleStrideViewIter = std::ranges::iterator_t; - using NotSimpleStrideViewIterConst = std::ranges::iterator_t; - static_assert(!std::is_same_v); - return true; -} - -struct NonDefaultConstructibleIterator : InputIterBase { - NonDefaultConstructibleIterator() = delete; - constexpr NonDefaultConstructibleIterator(int) {} -}; - -struct ViewWithNonDefaultConstructibleIterator : std::ranges::view_base { - constexpr NonDefaultConstructibleIterator begin() const { return NonDefaultConstructibleIterator{5}; } - constexpr std::default_sentinel_t end() const { return {}; } -}; -template <> -inline constexpr bool std::ranges::enable_borrowed_range = true; - -constexpr bool iterator_default_constructible() { - { - // If the type of the iterator of the range being strided is non-default - // constructible, then the stride view's iterator should not be default - // constructible, either! - constexpr ViewWithNonDefaultConstructibleIterator v{}; - constexpr auto stride = std::ranges::stride_view(v, 1); - using stride_iterator_t = decltype(stride.begin()); - static_assert(!std::is_default_constructible()); - } - { - // If the type of the iterator of the range being strided is default - // constructible, then the stride view's iterator should be default - // constructible, too! - constexpr int arr[] = {1, 2, 3}; - auto stride = std::ranges::stride_view(arr, 1); - using stride_iterator_t = decltype(stride.begin()); - static_assert(std::is_default_constructible()); - } - - return true; -} - -constexpr bool non_const_iterator_copy_ctor() { - { - // Instantiate a stride view over a non-simple view whose const/non-const begin iterators are not-convertible. - using NotSimpleStrideView = std::ranges::stride_view>; - using NotSimpleStrideViewIter = std::ranges::iterator_t; - using NotSimpleStrideViewConstIter = std::ranges::iterator_t; - - // It should not be possible to construct a stride view iterator from a non-const stride view iterator - // when the strided-over type has inconvertible begin iterator types. - static_assert(!std::ranges::__simple_view); - static_assert(!std::convertible_to); - static_assert(!std::is_constructible_v); - } - { - // Instantiate a stride view over a non-simple view whose const/non-const begin iterators are convertible. - using NotSimpleStrideView = std::ranges::stride_view>; - using NotSimpleStrideViewIter = std::ranges::iterator_t; - using NotSimpleStrideViewConstIter = std::ranges::iterator_t; - - // It should be possible to construct a stride view iterator from a non-const stride view iterator - // when the strided-over type has convertible begin iterator types. - static_assert(!std::ranges::__simple_view); - static_assert(std::convertible_to); - static_assert(std::is_constructible_v); - } - - { - // Instantiate a stride view over a non-simple view whose const/non-const end iterators are not convertible. - using NotSimpleStrideView = std::ranges::stride_view>; - using NotSimpleStrideViewIter = std::ranges::iterator_t; - using NotSimpleStrideViewConstIter = std::ranges::iterator_t; - - static_assert(std::ranges::__can_borrow); - - // It should not be possible to construct a stride view iterator from a non-const stride view iterator - // when the strided-over type has inconvertible end iterator types. - static_assert(!std::ranges::__simple_view); - static_assert(!std::convertible_to); - static_assert(!std::is_constructible_v); - } - - { - // Instantiate a stride view over a non-simple view whose const/non-const end iterators are convertible. - using NotSimpleStrideView = std::ranges::stride_view>; - using NotSimpleStrideViewIter = std::ranges::iterator_t; - using NotSimpleStrideViewConstIter = std::ranges::iterator_t; - - // It should not be possible to construct a stride view iterator from a non-const stride view iterator - // when the strided-over type has inconvertible end iterator types. - static_assert(std::is_copy_constructible_v); - static_assert(!std::ranges::__simple_view); - static_assert(std::convertible_to); - static_assert(std::is_constructible_v); - } - - { - // Instantiate a stride view over a non-simple view whose iterators are not copyable but whose const - // and non-const end iterators are convertible. - using NotSimpleStrideView = std::ranges::stride_view>; - using NotSimpleStrideViewIter = std::ranges::iterator_t; - using NotSimpleStrideViewConstIter = std::ranges::iterator_t; - - // It should not be possible to copy construct a stride view iterator from a non-const stride view iterator - // when the strided-over type has non copyable end iterator type. - static_assert(!std::is_copy_constructible_v); - - // Given the difference between the (non-) constness of the end iterator types and the fact that - // they can be converted between, it should - // 1. not be a simple view - static_assert(!std::ranges::__simple_view); - // 2. the types should be convertible - static_assert(std::convertible_to); - // 3. and a const thing should be constructible from a non const thing because they are convertible. - static_assert(std::is_constructible_v); - } - return true; -} - -int main(int, char**) { - non_simple_view_iter_ctor_test(); - static_assert(non_simple_view_iter_ctor_test()); - static_assert(iterator_default_constructible()); - static_assert(non_const_iterator_copy_ctor()); - - return 0; -} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp new file mode 100644 index 0000000000000..a2842e7d26928 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// __iterator() requires default_initializable> = default; + +#include + +#include "../test.h" +#include "test_iterators.h" + +struct NonDefaultConstructibleIterator : InputIterBase { + NonDefaultConstructibleIterator() = delete; + constexpr NonDefaultConstructibleIterator(int) {} +}; + +struct ViewWithNonDefaultConstructibleIterator : std::ranges::view_base { + constexpr NonDefaultConstructibleIterator begin() const { return NonDefaultConstructibleIterator{5}; } + constexpr std::default_sentinel_t end() const { return {}; } +}; +template <> +inline constexpr bool std::ranges::enable_borrowed_range = true; + +// If the type of the iterator of the range being strided is non-default +// constructible, then the stride view's iterator should not be default +// constructible, either! +static_assert(!std::is_default_constructible< + std::ranges::iterator_t>()); // expected-no-diagnostics +// If the type of the iterator of the range being strided is default +// constructible, then the stride view's iterator should be default +// constructible, too! +static_assert(std::is_default_constructible>>>()); // expected-no-diagnostics From b8710bffe355878944b99dd119098a5d5a3d67eb Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 8 Dec 2023 11:50:27 -0500 Subject: [PATCH 070/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add additional iterator operator (that's fun to say) tests. --- .../iterator/operator.pass.cpp | 34 +++++++++++++++++++ .../range.adaptors/range.stride.view/test.h | 6 ++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index f0276453ec9c4..280090bf1c09d 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -101,6 +101,40 @@ constexpr bool operator_tests() { static_assert(!is_difference_minusable); static_assert(!is_relationally_comparable); } + { + // What operators are valid for an iterator derived from a stride view + // over a sized input view. + using View = InputView; + using StrideViewIterator = std::ranges::iterator_t>; + + static_assert(is_plus_plusable_post); + static_assert(is_plus_plusable_pre); + static_assert(!is_minus_minusable_post); + static_assert(!is_minus_minusable_pre); + static_assert(!is_plus_equalable); + static_assert(!is_minus_equalable); + static_assert(is_iterator_minusable); + static_assert(!is_difference_plusable); + static_assert(!is_difference_minusable); + static_assert(!is_relationally_comparable); + } + { + // What operators are valid for an iterator derived from a stride view + // over a sized forward view. + using View = InputView; + using StrideViewIterator = std::ranges::iterator_t>; + + static_assert(is_plus_plusable_post); + static_assert(is_plus_plusable_pre); + static_assert(!is_minus_minusable_post); + static_assert(!is_minus_minusable_pre); + static_assert(!is_plus_equalable); + static_assert(!is_minus_equalable); + static_assert(is_iterator_minusable); + static_assert(!is_difference_plusable); + static_assert(!is_difference_minusable); + static_assert(!is_relationally_comparable); + } { // What operators are valid for an iterator derived from a stride view // over a bidirectional view. diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h index 86f225ef37993..f2a9fa4b6ca5d 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h @@ -129,8 +129,6 @@ struct InputIterBase { constexpr Derived operator++(int) { return {}; } friend constexpr bool operator==(const Derived&, const Derived&) { return true; } - friend constexpr bool operator==(const std::default_sentinel_t&, const Derived&) { return true; } - friend constexpr bool operator==(const Derived&, const std::default_sentinel_t&) { return true; } }; template S = sentinel_wrapper> @@ -252,6 +250,8 @@ struct SizedInputIterator { return left.__v_ - right.__v_; } }; +static_assert(std::input_iterator); +static_assert(std::sized_sentinel_for); // TODO: Cleanup struct SizedForwardIterator { @@ -282,5 +282,7 @@ struct SizedForwardIterator { return left.__v_ - right.__v_; } }; +static_assert(std::input_iterator); +static_assert(std::sized_sentinel_for); #endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H From 748229ce9de38cd0e7d844dce905d165e6e72c5c Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 11 Dec 2023 09:40:04 -0500 Subject: [PATCH 071/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Cleanup enable_borrowed_range tests. --- .../enable_borrowed_range.verify.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.verify.cpp index a17c813527a44..eafc9a2bedae0 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.verify.cpp @@ -8,21 +8,21 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -#include - -#include "test.h" - // template // inline constexpr bool enable_borrowed_range> = false; +#include +#include + // The stride_view is not one of those range adaptors that (under any circumstances) // is enabled as a borrowable range by default. In other words, we will have to make -// a positively test case explicity +// a positive test case explicit. template <> inline constexpr bool - std::ranges::enable_borrowed_range>>> = true; + std::ranges::enable_borrowed_range>>> = true; -static_assert(std::ranges::borrowed_range< - std::ranges::stride_view>>>); // expected-no-diagnostics -static_assert(!std::ranges::borrowed_range>>); // expected-no-diagnostics +static_assert(!std::ranges::enable_borrowed_range< + std::ranges::stride_view>>); // expected-no-diagnostics +static_assert(std::ranges::enable_borrowed_range< + std::ranges::stride_view>>>); // expected-no-diagnostics From b56b0adc4edb39b67027584c83bd6d4359ec40b2 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 11 Dec 2023 10:20:38 -0500 Subject: [PATCH 072/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Update dereference-past-the-end assertions using the new hardening modes. --- libcxx/include/__ranges/stride_view.h | 2 +- .../iterator/{end.pass.cpp => dereference.pass.cpp} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/{end.pass.cpp => dereference.pass.cpp} (96%) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 59378d2a67aa0..df5080455ab03 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -199,7 +199,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); } _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { - _LIBCPP_ASSERT_UNCATEGORIZED(__current_ != __end_, "Cannot dereference an iterator at the end."); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__current_ != __end_, "Cannot dereference an iterator at the end."); return *__current_; } diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/end.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp similarity index 96% rename from libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/end.pass.cpp rename to libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp index 30b74d3d383da..a9a9facd6ead5 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/end.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp @@ -8,7 +8,7 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 // UNSUPPORTED: no-exceptions -// UNSUPPORTED: !libcpp-hardening-mode=debug +// UNSUPPORTED: libcpp-hardening-mode=none // XFAIL: availability-verbose_abort-missing #include "check_assertion.h" From 5a5429b708a3ba70a1a009689aafb5296aedd999 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 11 Dec 2023 10:52:24 -0500 Subject: [PATCH 073/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add adaptor tests for sized ranges. --- .../range.stride.view/adaptor.pass.cpp | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index 6d3f0bd4c3535..fd62022534d7e 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -12,6 +12,8 @@ #include +#include "__iterator/concepts.h" +#include "__ranges/concepts.h" #include "test.h" #include "test_iterators.h" @@ -27,11 +29,14 @@ constexpr InputView> make_input_view(int* begin, int* using ForwardStrideView = std::ranges::stride_view>>; using BidirStrideView = std::ranges::stride_view>>; using RandomAccessStrideView = std::ranges::stride_view>>; +using SizedForwardStrideView = std::ranges::stride_view>; static_assert(std::ranges::forward_range); static_assert(std::ranges::bidirectional_range); static_assert(std::ranges::random_access_range); -// TODO: check sized_range +static_assert(std::ranges::forward_range); +static_assert(std::sized_sentinel_for, + std::ranges::iterator_t>); constexpr bool test() { constexpr int N = 3; @@ -85,6 +90,21 @@ constexpr bool test() { auto transform_stride_applied_iter = transform_stride_applied.begin(); assert(*transform_stride_applied_iter == i2(arr[0])); } + + { + using View = InputView; + auto view = View(SizedForwardIterator(arr), SizedForwardIterator(arr + N)); + std::same_as> decltype(auto) strided = view | std::views::stride(1); + auto strided_iter = strided.begin(); + auto strided_iter_next = strided_iter; + + strided_iter_next++; + + assert(*strided_iter == arr[0]); + assert(*strided_iter_next == arr[1]); + assert(strided_iter_next - strided_iter == 1); + } + // Check SFINAE friendliness { struct NotAViewableRange {}; @@ -106,7 +126,7 @@ constexpr bool test() { int main(int, char**) { test(); - //static_assert(test()); + static_assert(test()); return 0; } From ee3277c30f7ba20bb2897df4c2bd667fc55e6132 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 11 Dec 2023 10:56:06 -0500 Subject: [PATCH 074/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Update test comment. --- .../range.adaptors/range.stride.view/ctor.assert.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp index b100996836433..6669aee4a38aa 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp @@ -11,7 +11,7 @@ // UNSUPPORTED: !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing -// Call stride_view() ctor empty stride <= 0 +// Call stride_view() ctor with stride <= 0. #include "check_assertion.h" #include From a69898261c5bf634ea87e13ccf4a985d09ce2aa1 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 11 Dec 2023 21:10:33 -0500 Subject: [PATCH 075/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Reformat (begrudgingly) ranges.inc. --- libcxx/modules/std/ranges.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/modules/std/ranges.inc b/libcxx/modules/std/ranges.inc index c13db6be6e4ac..020f2a1de21f4 100644 --- a/libcxx/modules/std/ranges.inc +++ b/libcxx/modules/std/ranges.inc @@ -299,7 +299,7 @@ export namespace std { namespace views { using std::ranges::views::stride; - } // namespace views + } // namespace views #endif // _LIBCPP_STD_VER >= 23 #if 0 From a868c87693737b42003b04900c8149c3e08fd6bb Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 11 Dec 2023 21:11:09 -0500 Subject: [PATCH 076/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Use only on expected-no-diagnostics per verify. --- .../enable_borrowed_range.compile.pass.cpp | 5 ++++ .../range.stride.view/concept.verify.cpp | 28 +++++++++---------- .../enable_borrowed_range.verify.cpp | 7 ++--- .../iterator/ctor.default.verify.cpp | 5 ++-- .../range.stride.view/size.verify.cpp | 19 ++++++------- 5 files changed, 34 insertions(+), 30 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/enable_borrowed_range.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/enable_borrowed_range.compile.pass.cpp index 48d1d96b02482..3859f5ad3dee8 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/enable_borrowed_range.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/enable_borrowed_range.compile.pass.cpp @@ -11,6 +11,11 @@ #include #include +static_assert(std::ranges::enable_borrowed_range>); static_assert(std::ranges::enable_borrowed_range>>); + +static_assert(std::ranges::enable_borrowed_range&>>); static_assert(std::ranges::enable_borrowed_range&>>>); + +static_assert(!std::ranges::enable_borrowed_range>>); static_assert(!std::ranges::enable_borrowed_range>>>); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp index 8a9a38eb9f302..6e961b38a4f1c 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// expected-no-diagnostics // template requires view<_View> @@ -17,24 +18,23 @@ #include "test_range.h" // Ensure that the InputRangeNotIndirectlyReadable is a valid range. -static_assert(std::ranges::range); // expected-no-diagnostics +static_assert(std::ranges::range); // Ensure that the InputRangeNotIndirectlyReadable's is not an input range ... -static_assert( - !std::ranges::input_range>); // expected-no-diagnostics +static_assert(!std::ranges::input_range>); // Because CanStrideView requires that the range/view type be default constructible, let's double check that ... -static_assert(std::is_constructible_v); // expected-no-diagnostics +static_assert(std::is_constructible_v); // And now, finally, let's make sure that we cannot stride over a range whose iterator is not an input iterator ... -static_assert(!CanStrideView); // expected-no-diagnostics +static_assert(!CanStrideView); // Ensure that a range that is not a view cannot be the subject of a stride_view. -static_assert(std::ranges::range); // expected-no-diagnostics -static_assert(std::ranges::input_range); // expected-no-diagnostics -static_assert(std::movable); // expected-no-diagnostics -static_assert(!std::ranges::view); // expected-no-diagnostics -static_assert(!CanStrideView); // expected-no-diagnostics +static_assert(std::ranges::range); +static_assert(std::ranges::input_range); +static_assert(std::movable); +static_assert(!std::ranges::view); +static_assert(!CanStrideView); // And now, let's satisfy all the prerequisites and make sure that we can stride over a range (that is an input range and is a view!) -static_assert(std::ranges::range>); // expected-no-diagnostics -static_assert(std::ranges::input_range>); // expected-no-diagnostics -static_assert(std::ranges::view>); // expected-no-diagnostics -static_assert(CanStrideView, 1>); // expected-no-diagnostics +static_assert(std::ranges::range>); +static_assert(std::ranges::input_range>); +static_assert(std::ranges::view>); +static_assert(CanStrideView, 1>); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.verify.cpp index eafc9a2bedae0..142c4d126fa6d 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.verify.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// expected-no-diagnostics // template // inline constexpr bool enable_borrowed_range> = false; @@ -22,7 +23,5 @@ template <> inline constexpr bool std::ranges::enable_borrowed_range>>> = true; -static_assert(!std::ranges::enable_borrowed_range< - std::ranges::stride_view>>); // expected-no-diagnostics -static_assert(std::ranges::enable_borrowed_range< - std::ranges::stride_view>>>); // expected-no-diagnostics +static_assert(!std::ranges::enable_borrowed_range< std::ranges::stride_view>>); +static_assert(std::ranges::enable_borrowed_range< std::ranges::stride_view>>>); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp index a2842e7d26928..81fd8ecb6cd36 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// expected-no-diagnostics // __iterator() requires default_initializable> = default; @@ -31,9 +32,9 @@ inline constexpr bool std::ranges::enable_borrowed_range>()); // expected-no-diagnostics + std::ranges::iterator_t>()); // If the type of the iterator of the range being strided is default // constructible, then the stride view's iterator should be default // constructible, too! static_assert(std::is_default_constructible>>>()); // expected-no-diagnostics + std::ranges::stride_view>>>()); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp index 62cbd3ccd2708..a80382bf12e8f 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 +// expected-no-diagnostics // constexpr auto size() @@ -17,28 +18,26 @@ // There is no size member function on a stride view over a view that // is *not* a sized range -static_assert(!std::ranges::sized_range); // expected-no-diagnostics -static_assert(!std::ranges::sized_range>); // expected-no-diagnosticss +static_assert(!std::ranges::sized_range); +static_assert(!std::ranges::sized_range>); constexpr bool test() { { // Test with stride as exact multiple of number of elements in view strided over. constexpr auto iota_twelve = std::views::iota(0, 12); - static_assert(std::ranges::sized_range); // expected-no-diagnostics + static_assert(std::ranges::sized_range); constexpr auto stride_iota_twelve = std::views::stride(iota_twelve, 3); - static_assert(std::ranges::sized_range); // expected-no-diagnostics - static_assert(4 == stride_iota_twelve.size(), - "Striding by 3 through a 12 member list has size 4."); // expected-no-diagnostics + static_assert(std::ranges::sized_range); + static_assert(4 == stride_iota_twelve.size(), "Striding by 3 through a 12 member list has size 4."); } { // Test with stride as inexact multiple of number of elements in view strided over. constexpr auto iota_twenty_two = std::views::iota(0, 22); - static_assert(std::ranges::sized_range); // expected-no-diagnostics + static_assert(std::ranges::sized_range); constexpr auto stride_iota_twenty_two = std::views::stride(iota_twenty_two, 3); - static_assert(std::ranges::sized_range); // expected-no-diagnostics - static_assert(8 == stride_iota_twenty_two.size(), - "Striding by 3 through a 22 member list has size 8."); // expected-no-diagnostics + static_assert(std::ranges::sized_range); + static_assert(8 == stride_iota_twenty_two.size(), "Striding by 3 through a 22 member list has size 8."); } return true; } From 905606230abb8910227b85ec0fd1bb4a4566bd3b Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 13 Dec 2023 12:41:56 -0500 Subject: [PATCH 077/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add tests for std::ranges::iter_swap and std::ranges::iter_move customization point objects. --- .../iterator/iter_move.pass.cpp | 92 +++++++++++++++ .../iterator/iter_swap.pass.cpp | 107 ++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp new file mode 100644 index 0000000000000..993c2b4b19c69 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp @@ -0,0 +1,92 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// friend constexpr range_rvalue_reference_t<_Base> iter_move(__iterator const& __it) +// noexcept(noexcept(ranges::iter_move(__it.__current_))) + +#include + +#include "../test.h" + +template +concept iter_moveable = requires(T&& t) { std::ranges::iter_move(t); }; + +template +struct MaybeExceptIterSwapIterator : InputIterBase> { + int* counter_{nullptr}; + constexpr MaybeExceptIterSwapIterator() = default; + constexpr MaybeExceptIterSwapIterator(const MaybeExceptIterSwapIterator&) = default; + constexpr MaybeExceptIterSwapIterator(MaybeExceptIterSwapIterator&&) = default; + constexpr MaybeExceptIterSwapIterator& operator=(const MaybeExceptIterSwapIterator& other) = default; + constexpr MaybeExceptIterSwapIterator& operator=(MaybeExceptIterSwapIterator&& other) = default; + + constexpr explicit MaybeExceptIterSwapIterator(int* counter) : counter_(counter) {} + + friend constexpr int iter_move(const MaybeExceptIterSwapIterator& t) { + (*t.counter_)++; + return 5; + } + friend constexpr int iter_move(const MaybeExceptIterSwapIterator& t) noexcept + requires NoExcept + { + (*t.counter_)++; + return 5; + } + + constexpr int operator*() const { return 5; } +}; + +template +struct IterSwapRange : std::ranges::view_base { + MaybeExceptIterSwapIterator begin_; + MaybeExceptIterSwapIterator end_; + constexpr IterSwapRange(int* counter) + : begin_(MaybeExceptIterSwapIterator(counter)), end_(MaybeExceptIterSwapIterator(counter)) {} + constexpr MaybeExceptIterSwapIterator begin() const { return begin_; } + constexpr MaybeExceptIterSwapIterator end() const { return end_; } +}; + +constexpr bool test() { + { + int iter_move_counter(0); + using View = IterSwapRange; + using StrideView = std::ranges::stride_view; + auto svb = StrideView(View(&iter_move_counter), 1).begin(); + + static_assert(iter_moveable>); + static_assert(std::is_same_v); + static_assert(noexcept(std::ranges::iter_move(svb))); + + [[maybe_unused]] auto&& result = std::ranges::iter_move(svb); + assert(iter_move_counter == 1); + } + + { + int iter_move_counter(0); + using View = IterSwapRange; + using StrideView = std::ranges::stride_view; + auto svb = StrideView(View(&iter_move_counter), 1).begin(); + + static_assert(iter_moveable>); + static_assert(std::is_same_v); + static_assert(!noexcept(std::ranges::iter_move(svb))); + + [[maybe_unused]] auto&& result = std::ranges::iter_move(svb); + assert(iter_move_counter == 1); + } + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp new file mode 100644 index 0000000000000..98638259146de --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp @@ -0,0 +1,107 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// friend constexpr void iter_swap(__iterator const& __x, __iterator const& __y) +// noexcept(noexcept(ranges::iter_swap(__x.__current_, __y.__current_))) +// requires indirectly_swappable> + +#include + +#include "../test.h" + +template +concept swappable = requires(T&& t, T&& u) { std::ranges::iter_swap(t, u); }; + +template +struct MaybeExceptIterSwapIterator : InputIterBase> { + int* counter_{nullptr}; + constexpr MaybeExceptIterSwapIterator() = default; + constexpr MaybeExceptIterSwapIterator(const MaybeExceptIterSwapIterator&) = default; + constexpr MaybeExceptIterSwapIterator(MaybeExceptIterSwapIterator&&) = default; + constexpr MaybeExceptIterSwapIterator& operator=(const MaybeExceptIterSwapIterator& other) = default; + constexpr MaybeExceptIterSwapIterator& operator=(MaybeExceptIterSwapIterator&& other) = default; + + constexpr explicit MaybeExceptIterSwapIterator(int* counter) : counter_(counter) {} + + friend constexpr void iter_swap(const MaybeExceptIterSwapIterator& t, const MaybeExceptIterSwapIterator& u) noexcept + requires Swappable && NoExcept + { + (*t.counter_)++; + (*u.counter_)++; + } + + friend constexpr void iter_swap(const MaybeExceptIterSwapIterator& t, const MaybeExceptIterSwapIterator& u) + requires Swappable && (!NoExcept) + { + (*t.counter_)++; + (*u.counter_)++; + } + constexpr int operator*() const { return 5; } +}; + +template +struct IterSwapRange : std::ranges::view_base { + MaybeExceptIterSwapIterator begin_; + MaybeExceptIterSwapIterator end_; + constexpr IterSwapRange(int* counter) + : begin_(MaybeExceptIterSwapIterator(counter)), + end_(MaybeExceptIterSwapIterator(counter)) {} + constexpr MaybeExceptIterSwapIterator begin() const { return begin_; } + constexpr MaybeExceptIterSwapIterator end() const { return end_; } +}; + +constexpr bool test() { + { + int iter_move_counter_one(0); + int iter_move_counter_two(0); + using View = IterSwapRange; + using StrideView = std::ranges::stride_view; + auto svba = StrideView(View(&iter_move_counter_one), 1).begin(); + auto svbb = StrideView(View(&iter_move_counter_two), 1).begin(); + + static_assert(swappable>); + static_assert(noexcept(std::ranges::iter_swap(svba, svbb))); + + std::ranges::iter_swap(svba, svbb); + assert(iter_move_counter_one == 1); + assert(iter_move_counter_two == 1); + } + + { + int iter_move_counter_one(0); + int iter_move_counter_two(0); + using View = IterSwapRange; + using StrideView = std::ranges::stride_view; + auto svba = StrideView(View(&iter_move_counter_one), 1).begin(); + auto svbb = StrideView(View(&iter_move_counter_two), 1).begin(); + + static_assert(swappable>); + static_assert(!noexcept(std::ranges::iter_swap(svba, svbb))); + + std::ranges::iter_swap(svba, svbb); + assert(iter_move_counter_one == 1); + assert(iter_move_counter_two == 1); + } + + { + using View = IterSwapRange; + using StrideView = std::ranges::stride_view; + + static_assert(!swappable>); + } + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} From 6af7431e925f47d491085c2808e2746ebb97091a Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Thu, 21 Dec 2023 23:03:31 -0500 Subject: [PATCH 078/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Inline assertion test for ctor into main. --- .../range.stride.view/ctor.assert.pass.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp index 6669aee4a38aa..92a5cd999798e 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp @@ -11,21 +11,18 @@ // UNSUPPORTED: !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing -// Call stride_view() ctor with stride <= 0. +// constexpr explicit stride_view(_View, range_difference_t<_View>) -#include "check_assertion.h" #include -void stride_view_over_only_input_ranges() { +#include "check_assertion.h" + +int main(int, char**) { int range[] = {1, 2, 3}; TEST_LIBCPP_ASSERT_FAILURE( [&range] { std::ranges::stride_view sv(range, 0); }(), "The value of stride must be greater than 0"); TEST_LIBCPP_ASSERT_FAILURE( [&range] { std::ranges::stride_view sv(range, -1); }(), "The value of stride must be greater than 0"); -} - -int main(int, char**) { - stride_view_over_only_input_ranges(); return 0; } From 8e0657d757459a15e7498d6b012005eef3c7e0e4 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Thu, 21 Dec 2023 23:24:36 -0500 Subject: [PATCH 079/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Inline assertion test for incrementing and dereferencing into main. --- .../range.stride.view/iterator/increment.pass.cpp | 10 +++------- .../iterator/operator_plus_equal.pass.cpp | 9 +++------ 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp index 509d5f909c573..896d4661015c0 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp @@ -13,19 +13,15 @@ // constexpr stride_view::& operator++() { -#include "check_assertion.h" #include -void cannot_increment_at_the_end_iterator() { +#include "check_assertion.h" + +int main(int, char**) { int range[] = {1, 2, 3}; auto striv = std::ranges::views::stride(range, 3); auto striv_it = striv.begin(); striv_it++; TEST_LIBCPP_ASSERT_FAILURE(striv_it++, "Cannot increment an iterator already at the end."); -} - -int main(int, char**) { - cannot_increment_at_the_end_iterator(); - return 0; } diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp index 13a56b4e12917..5a1e018085f5f 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp @@ -11,18 +11,15 @@ // UNSUPPORTED: !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing -#include "check_assertion.h" #include -void operator_plus_equal_past_end_is_illegal() { +#include "check_assertion.h" + +int main(int, char**) { int range[] = {1, 2, 3}; auto striv = std::ranges::views::stride(range, 2); auto striv_it = striv.begin(); TEST_LIBCPP_ASSERT_FAILURE(striv_it += 3, "Advancing the iterator beyond the end is not allowed."); -} - -int main(int, char**) { - operator_plus_equal_past_end_is_illegal(); return 0; } From ec8fac2badc5335707a6e092e3f1904d29c472a7 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Thu, 21 Dec 2023 23:29:10 -0500 Subject: [PATCH 080/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. A few simple updates for noexcept status of base. --- .../range.adaptors/range.stride.view/iterator/base.pass.cpp | 6 ++++-- .../range.stride.view/iterator/iter_swap.pass.cpp | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp index e4e5d319dac87..9a1e1a2e43806 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp @@ -8,12 +8,14 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// std::views::stride_view +// constexpr iterator_t<_Base> const& base() const& noexcept +// constexpr iterator_t<_Base> base() && -#include "../test.h" #include #include +#include "../test.h" + constexpr bool base_noexcept() { { int arr[] = {1, 2, 3}; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp index 98638259146de..466ad92851110 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp @@ -15,6 +15,7 @@ #include #include "../test.h" +#include "__ranges/concepts.h" template concept swappable = requires(T&& t, T&& u) { std::ranges::iter_swap(t, u); }; @@ -96,6 +97,7 @@ constexpr bool test() { static_assert(!swappable>); } + return true; } From 6d07bdcd1a563f7e6bc9ca695cb2061966404ac3 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Thu, 21 Dec 2023 23:42:15 -0500 Subject: [PATCH 081/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Rename test.h to types.h. --- .../range.adaptors/range.stride.view/adaptor.pass.cpp | 2 +- .../range.adaptors/range.stride.view/base.pass.cpp | 2 +- .../range.adaptors/range.stride.view/concept.verify.cpp | 2 +- .../range.adaptors/range.stride.view/ctor.pass.cpp | 2 +- .../range.stride.view/iterator/base.pass.cpp | 2 +- .../range.stride.view/iterator/begin.pass.cpp | 7 ++++--- .../range.stride.view/iterator/ctor.copy.pass.cpp | 2 +- .../range.stride.view/iterator/ctor.default.verify.cpp | 9 ++++----- .../range.stride.view/iterator/iter_move.pass.cpp | 2 +- .../range.stride.view/iterator/iter_swap.pass.cpp | 2 +- .../range.stride.view/iterator/operator.pass.cpp | 2 +- .../range.adaptors/range.stride.view/size.verify.cpp | 2 +- .../range.adaptors/range.stride.view/stride.pass.cpp | 5 +++-- .../range.adaptors/range.stride.view/{test.h => types.h} | 0 14 files changed, 21 insertions(+), 20 deletions(-) rename libcxx/test/std/ranges/range.adaptors/range.stride.view/{test.h => types.h} (100%) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index fd62022534d7e..9cb398482149e 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -14,8 +14,8 @@ #include "__iterator/concepts.h" #include "__ranges/concepts.h" -#include "test.h" #include "test_iterators.h" +#include "types.h" template concept CanBePiped = requires(View&& view, T&& t) { diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp index 83e768c3badea..bfd4ed4940c4e 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp @@ -14,8 +14,8 @@ #include #include -#include "test.h" #include "test_iterators.h" +#include "types.h" template concept hasLValueQualifiedBase = requires(T&& t) { t.base(); }; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp index 6e961b38a4f1c..f4287b4e321e9 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp @@ -13,9 +13,9 @@ #include "__ranges/stride_view.h" #include "almost_satisfies_types.h" -#include "test.h" #include "test_iterators.h" #include "test_range.h" +#include "types.h" // Ensure that the InputRangeNotIndirectlyReadable is a valid range. static_assert(std::ranges::range); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp index 445552873f5fb..0c4342dae74b2 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp @@ -12,9 +12,9 @@ #include -#include "test.h" #include "test_convertible.h" #include "test_iterators.h" +#include "types.h" // There is no default ctor for stride_view. using View = InputView>; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp index 9a1e1a2e43806..f007ffcf84d6e 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp @@ -14,7 +14,7 @@ #include #include -#include "../test.h" +#include "../types.h" constexpr bool base_noexcept() { { diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp index d797613499545..76fb866ea3920 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp @@ -10,12 +10,13 @@ // std::views::stride_view::iterator -#include "../test.h" -#include "__iterator/concepts.h" -#include "test_iterators.h" #include #include +#include "__iterator/concepts.h" +#include "test_iterators.h" +#include "../types.h" + constexpr bool iterator_concept_test() { { int arr[] = {1, 2, 3}; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp index aa4183105eca1..9a607d3e12a0a 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp @@ -14,7 +14,7 @@ #include -#include "../test.h" +#include "../types.h" #include "test_iterators.h" struct NotSimpleViewIterBegin : InputIterBase {}; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp index 81fd8ecb6cd36..4fbe9c0d2498e 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp @@ -13,7 +13,7 @@ #include -#include "../test.h" +#include "../types.h" #include "test_iterators.h" struct NonDefaultConstructibleIterator : InputIterBase { @@ -31,10 +31,9 @@ inline constexpr bool std::ranges::enable_borrowed_range>()); +static_assert(!std::is_default_constructible< std::ranges::iterator_t>()); // If the type of the iterator of the range being strided is default // constructible, then the stride view's iterator should be default // constructible, too! -static_assert(std::is_default_constructible>>>()); +static_assert(std::is_default_constructible< + std::ranges::iterator_t< std::ranges::stride_view>>>()); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp index 993c2b4b19c69..32bebf581de51 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp @@ -13,7 +13,7 @@ #include -#include "../test.h" +#include "../types.h" template concept iter_moveable = requires(T&& t) { std::ranges::iter_move(t); }; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp index 466ad92851110..885862fcfdf53 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp @@ -14,7 +14,7 @@ #include -#include "../test.h" +#include "../types.h" #include "__ranges/concepts.h" template diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index 280090bf1c09d..67887ef52582e 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -25,7 +25,7 @@ #include -#include "../test.h" +#include "../types.h" #include "test_iterators.h" template diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp index a80382bf12e8f..dbb5d99983216 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp @@ -14,7 +14,7 @@ #include #include -#include "test.h" +#include "types.h" // There is no size member function on a stride view over a view that // is *not* a sized range diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp index 5107f809e6345..482144d941989 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp @@ -10,12 +10,13 @@ // constexpr range_difference_t<_View> stride() const noexcept; -#include "test_iterators.h" -#include "test.h" #include #include #include +#include "test_iterators.h" +#include "types.h" + constexpr bool test() { using View = InputView>; int arr[]{1, 2, 3}; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h similarity index 100% rename from libcxx/test/std/ranges/range.adaptors/range.stride.view/test.h rename to libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h From 294bc2a3231504886a169f62ac453a5c68d6e051 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sat, 23 Dec 2023 00:36:37 -0500 Subject: [PATCH 082/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. clang-tidy order of includes fix. --- .../range.adaptors/range.stride.view/iterator/begin.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp index 76fb866ea3920..05b8e6c86ec84 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp @@ -13,9 +13,9 @@ #include #include +#include "../types.h" #include "__iterator/concepts.h" #include "test_iterators.h" -#include "../types.h" constexpr bool iterator_concept_test() { { From fe6ab693fbb11c27ef78699a28cca6296aec9e0b Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sat, 23 Dec 2023 00:38:25 -0500 Subject: [PATCH 083/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add tests for begin. --- .../range.stride.view/begin.pass.cpp | 48 +++++++++++++++++-- .../range.adaptors/range.stride.view/types.h | 14 ++++++ 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp index 3c4e6ff75fc5f..5f38214b951d6 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp @@ -8,13 +8,51 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// std::views::stride_view +// constexpr auto begin() requires(!__simple_view<_View>) +// constexpr auto begin() const requires range -constexpr bool test() { return true; } +#include +#include -int main(int, char**) { - test(); - static_assert(test()); +#include "test_range.h" +#include "types.h" + +template +concept HasConstBegin = requires(const T& ct) { ct.begin(); }; + +template +concept HasBegin = requires(T& t) { t.begin(); }; + +template +concept HasConstAndNonConstBegin = HasConstBegin && requires(T& t, const T& ct) { + requires !std::same_as; +}; + +template +concept HasOnlyNonConstBegin = HasBegin && !HasConstBegin; +template +concept HasOnlyConstBegin = HasConstBegin && !HasConstAndNonConstBegin; + +struct NoConstView : std::ranges::view_base { + int* begin(); + int* end(); +}; + +struct UnsimpleConstView : std::ranges::view_base { + double* begin(); + int* begin() const; + + double* end(); + int* end() const; +}; +static_assert(HasOnlyNonConstBegin>); +static_assert(HasOnlyConstBegin>); +static_assert(HasConstAndNonConstBegin>); + +int main(int, char**) { + int buffer[] = {1, 2, 3}; + auto sv = std::ranges::stride_view(SimpleView(buffer, buffer + 3), 1); + assert(1 == *(sv.begin())); return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index f2a9fa4b6ca5d..5f77944272ca3 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -21,9 +21,12 @@ #include "__ranges/size.h" #include "__ranges/stride_view.h" #include "test_iterators.h" +#include "test_macros.h" #include "test_range.h" #include #include +#include +#include template D> concept CanStrideView = requires { @@ -285,4 +288,15 @@ struct SizedForwardIterator { static_assert(std::input_iterator); static_assert(std::sized_sentinel_for); +struct SimpleView : std::ranges::view_base { + int* begin_; + int* end_; + + constexpr SimpleView(int* b, int* e) : begin_(b), end_(e) {} + + constexpr const int* begin() const { return begin_; } + constexpr const int* end() const { return end_; } +}; +LIBCPP_STATIC_ASSERT(std::ranges::__simple_view); + #endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H From c13fdd45fb573d0b907eea36b0e32a176f847589 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Tue, 26 Dec 2023 12:39:18 -0500 Subject: [PATCH 084/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add tests for __missing_. --- .../iterator/operator.pass.cpp | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index 67887ef52582e..024a4afe58552 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -23,9 +23,12 @@ // friend constexpr bool operator>=(__iterator const& __x, __iterator const& __y) // friend constexpr bool operator<=>(__iterator const& __x, __iterator const& __y) +#include #include #include "../types.h" +#include "__ranges/concepts.h" +#include "__ranges/stride_view.h" #include "test_iterators.h" template @@ -258,6 +261,39 @@ constexpr bool operator_tests() { assert(stride_zoff_one - stride_ooff_two == -1); assert(stride_zoff_one - stride_ooff_five == -2); } + { + // Check whether __missing_ gets handled properly. + using Base = SimpleView; + int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + auto base = Base(arr, arr + 10); + auto strider = std::ranges::stride_view(base, 7); + + auto strider_iter = strider.end(); + + strider_iter--; + assert(*strider_iter == 8); + + // Now that we are back among the valid, we should + // have a normal stride length back (i.e., __missing_ + // should be equal to 0). + strider_iter--; + assert(*strider_iter == 1); + + strider_iter++; + assert(*strider_iter == 8); + + // By striding past the end, we are going to generate + // another __missing_ != 0 value. Let's make sure + // that it gets generated and used. + strider_iter++; + assert(strider_iter == strider.end()); + + strider_iter--; + assert(*strider_iter == 8); + + strider_iter--; + assert(*strider_iter == 1); + } { using EqualableView = InputView>; using Stride = std::ranges::stride_view; From 1b5a734646880f6966907d4717a3bcc5f96fbffe Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Tue, 26 Dec 2023 12:57:15 -0500 Subject: [PATCH 085/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add test for iterator indexable. --- .../range.stride.view/iterator/operator.pass.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index 024a4afe58552..ff8b354f3b169 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -66,6 +66,9 @@ concept is_minus_minusable_post = requires(T& t) { t--; }; template concept is_minus_minusable_pre = requires(T& t) { --t; }; +template +concept is_indexable = requires(T& t) { t[5]; }; + template concept can_calculate_distance_between_non_sentinel = requires(T& t) { t - t; }; @@ -86,6 +89,7 @@ constexpr bool operator_tests() { static_assert(!is_difference_plusable); static_assert(!is_difference_minusable); static_assert(!is_relationally_comparable); + static_assert(!is_indexable); } { // What operators are valid for an iterator derived from a stride view @@ -103,6 +107,7 @@ constexpr bool operator_tests() { static_assert(!is_difference_plusable); static_assert(!is_difference_minusable); static_assert(!is_relationally_comparable); + static_assert(!is_indexable); } { // What operators are valid for an iterator derived from a stride view @@ -120,6 +125,7 @@ constexpr bool operator_tests() { static_assert(!is_difference_plusable); static_assert(!is_difference_minusable); static_assert(!is_relationally_comparable); + static_assert(!is_indexable); } { // What operators are valid for an iterator derived from a stride view @@ -137,6 +143,7 @@ constexpr bool operator_tests() { static_assert(!is_difference_plusable); static_assert(!is_difference_minusable); static_assert(!is_relationally_comparable); + static_assert(!is_indexable); } { // What operators are valid for an iterator derived from a stride view @@ -154,6 +161,7 @@ constexpr bool operator_tests() { static_assert(!is_difference_plusable); static_assert(!is_difference_minusable); static_assert(!is_relationally_comparable); + static_assert(!is_indexable); } { // What operators are valid for an iterator derived from a stride view @@ -171,6 +179,7 @@ constexpr bool operator_tests() { static_assert(is_difference_plusable); static_assert(is_difference_minusable); static_assert(is_relationally_comparable); + static_assert(is_indexable); } { using Base = InputView; From 8ae85a57c7b2283ea9dd8917a62ae843e70ec382 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Tue, 26 Dec 2023 13:02:16 -0500 Subject: [PATCH 086/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Remove silly small test functions in checking assertions beyond the end. --- .../iterator/dereference.pass.cpp | 33 ++++++++----------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp index a9a9facd6ead5..6ee731d5d4e47 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp @@ -14,25 +14,20 @@ #include "check_assertion.h" #include -void cannot_dereference_at_the_end_iterator() { - int range[] = {1, 2, 3}; - auto striv = std::ranges::views::stride(range, 3); - auto striv_it = striv.begin(); - striv_it++; - TEST_LIBCPP_ASSERT_FAILURE(*striv_it, "Cannot dereference an iterator at the end."); -} - -void cannot_dereference_past_the_end_iterator() { - int range[] = {1, 2, 3}; - auto striv = std::ranges::views::stride(range, 4); - auto striv_it = striv.begin(); - striv_it++; - TEST_LIBCPP_ASSERT_FAILURE(*striv_it, "Cannot dereference an iterator at the end."); -} - int main(int, char**) { - cannot_dereference_at_the_end_iterator(); - cannot_dereference_past_the_end_iterator(); - + { + int range[] = {1, 2, 3}; + auto striv = std::ranges::views::stride(range, 3); + auto striv_it = striv.begin(); + striv_it++; + TEST_LIBCPP_ASSERT_FAILURE(*striv_it, "Cannot dereference an iterator at the end."); + } + { + int range[] = {1, 2, 3}; + auto striv = std::ranges::views::stride(range, 4); + auto striv_it = striv.begin(); + striv_it++; + TEST_LIBCPP_ASSERT_FAILURE(*striv_it, "Cannot dereference an iterator at the end."); + } return 0; } From f7b6bd946f9fbe10d292aa6c90f6a1f0ec99db9b Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Thu, 28 Dec 2023 12:20:06 -0500 Subject: [PATCH 087/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add tests for stride_view::end. --- .../range.stride.view/begin.pass.cpp | 6 +- .../range.stride.view/end.pass.cpp | 114 +++++++++++++++++- 2 files changed, 114 insertions(+), 6 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp index 5f38214b951d6..3b4461fc07aaf 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp @@ -11,10 +11,11 @@ // constexpr auto begin() requires(!__simple_view<_View>) // constexpr auto begin() const requires range -#include +// Note: Checks here are augmented by checks in +// iterator/ctor.copy.pass.cpp. + #include -#include "test_range.h" #include "types.h" template @@ -54,5 +55,6 @@ int main(int, char**) { int buffer[] = {1, 2, 3}; auto sv = std::ranges::stride_view(SimpleView(buffer, buffer + 3), 1); assert(1 == *(sv.begin())); + return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp index 3c4e6ff75fc5f..cb08da44039af 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp @@ -8,13 +8,119 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// std::views::stride_view +// constexpr auto end() requires(!__simple_view<_View>) +// constexpr auto end() const requires(range) -constexpr bool test() { return true; } +// Note: Checks here are augmented by checks in +// iterator/ctor.copy.pass.cpp. + +#include + +#include "types.h" + +template +concept HasConstEnd = requires(const T& ct) { ct.end(); }; + +template +concept HasEnd = requires(T& t) { t.end(); }; + +template +concept HasConstAndNonConstEnd = + HasConstEnd && requires(T& t, const T& ct) { requires !std::same_as; }; + +template +concept HasOnlyNonConstEnd = HasEnd && !HasConstEnd; + +template +concept HasOnlyConstEnd = HasConstEnd && !HasConstAndNonConstEnd; + +struct NoConstView : std::ranges::view_base { + int* begin(); + int* end(); +}; + +struct UnsimpleConstView : std::ranges::view_base { + double* begin(); + int* begin() const; + + double* end(); + int* end() const; +}; + +struct UnsimpleUnCommonView : std::ranges::view_base { + double* begin(); + char* begin() const; + + void* end(); + void* end() const; +}; + +struct SimpleUnCommonView : std::ranges::view_base { + int* begin(); + int* begin() const; + + void* end(); + void* end() const; +}; + +static_assert(HasOnlyNonConstEnd>); +static_assert(HasOnlyConstEnd>); +static_assert(HasConstAndNonConstEnd>); + +constexpr bool test_non_default_sentinel() { + { + LIBCPP_STATIC_ASSERT(std::ranges::__simple_view); + static_assert(std::ranges::common_range); + static_assert(std::ranges::sized_range); + static_assert(std::ranges::forward_range); + + auto v = SimpleView{nullptr, nullptr}; + auto sv = std::ranges::stride_view(v, 1); + static_assert(!std::is_same_v); + } + + { + LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view); + static_assert(std::ranges::common_range); + static_assert(std::ranges::sized_range); + static_assert(std::ranges::forward_range); + + auto v = NoConstView{}; + auto sv = std::ranges::stride_view(v, 1); + static_assert(!std::is_same_v); + } + return true; +} + +constexpr bool test_default_sentinel() { + { + LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view); + static_assert(!std::ranges::common_range); + static_assert(std::ranges::sized_range); + static_assert(std::ranges::forward_range); + + auto v = UnsimpleUnCommonView{}; + auto sv = std::ranges::stride_view(v, 1); + static_assert(std::is_same_v); + } + + { + LIBCPP_STATIC_ASSERT(std::ranges::__simple_view); + static_assert(!std::ranges::common_range); + + auto v = SimpleUnCommonView{}; + auto sv = std::ranges::stride_view(v, 1); + + static_assert(std::is_same_v); + } + return true; +} int main(int, char**) { - test(); - static_assert(test()); + test_non_default_sentinel(); + test_default_sentinel(); + static_assert(test_non_default_sentinel()); + static_assert(test_default_sentinel()); return 0; } From c2f0fda82f14e79f78f940b4a11ec8b875baa4c3 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Tue, 2 Jan 2024 14:25:43 -0500 Subject: [PATCH 088/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Do some much-needed refactoring of test code -- we are getting close. --- .../range.stride.view/adaptor.pass.cpp | 21 +- .../range.stride.view/begin.pass.cpp | 4 +- .../range.stride.view/concept.verify.cpp | 10 +- .../range.stride.view/ctor.pass.cpp | 2 +- .../range.stride.view/end.pass.cpp | 14 +- .../range.stride.view/iterator/begin.pass.cpp | 18 +- .../iterator/iter_move.pass.cpp | 39 +- .../iterator/iter_swap.pass.cpp | 38 -- .../iterator/operator.pass.cpp | 529 +++++++++--------- .../range.stride.view/size.verify.cpp | 4 +- .../range.stride.view/stride.pass.cpp | 2 +- .../range.adaptors/range.stride.view/types.h | 287 ++++------ 12 files changed, 426 insertions(+), 542 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index 9cb398482149e..e600a1c9aac44 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -22,14 +22,14 @@ concept CanBePiped = requires(View&& view, T&& t) { { std::forward(view) | std::forward(t) }; }; -constexpr InputView> make_input_view(int* begin, int* end) { - return InputView>(cpp17_input_iterator(begin), cpp17_input_iterator(end)); +constexpr BasicTestView> make_input_view(int* begin, int* end) { + return BasicTestView>(cpp17_input_iterator(begin), cpp17_input_iterator(end)); } -using ForwardStrideView = std::ranges::stride_view>>; -using BidirStrideView = std::ranges::stride_view>>; -using RandomAccessStrideView = std::ranges::stride_view>>; -using SizedForwardStrideView = std::ranges::stride_view>; +using ForwardStrideView = std::ranges::stride_view>>; +using BidirStrideView = std::ranges::stride_view>>; +using RandomAccessStrideView = std::ranges::stride_view>>; +using SizedForwardStrideView = std::ranges::stride_view>; static_assert(std::ranges::forward_range); static_assert(std::ranges::bidirectional_range); @@ -47,7 +47,7 @@ constexpr bool test() { // view | stride { - using View = InputView>; + using View = BasicTestView>; auto view = make_input_view(arr, arr + N); std::same_as> decltype(auto) strided = view | std::views::stride(1); auto strided_iter = strided.begin(); @@ -60,7 +60,7 @@ constexpr bool test() { assert(*strided_iter == arr[2]); } { - using View = InputView>; + using View = BasicTestView>; auto view = make_input_view(arr, arr + N); std::same_as> decltype(auto) strided = view | std::views::stride(2); auto strided_iter = strided.begin(); @@ -92,7 +92,7 @@ constexpr bool test() { } { - using View = InputView; + using View = BasicTestView; auto view = View(SizedForwardIterator(arr), SizedForwardIterator(arr + N)); std::same_as> decltype(auto) strided = view | std::views::stride(1); auto strided_iter = strided.begin(); @@ -108,7 +108,7 @@ constexpr bool test() { // Check SFINAE friendliness { struct NotAViewableRange {}; - using View = InputView>; + using View = BasicTestView>; static_assert(!std::is_invocable_v); static_assert(!std::is_invocable_v); @@ -118,6 +118,7 @@ constexpr bool test() { static_assert(!CanBePiped); static_assert(!CanBePiped); } + // A final sanity check. { static_assert(std::same_as); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp index 3b4461fc07aaf..e0dcef0490b94 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp @@ -48,12 +48,12 @@ struct UnsimpleConstView : std::ranges::view_base { int* end() const; }; static_assert(HasOnlyNonConstBegin>); -static_assert(HasOnlyConstBegin>); +static_assert(HasOnlyConstBegin>>); static_assert(HasConstAndNonConstBegin>); int main(int, char**) { int buffer[] = {1, 2, 3}; - auto sv = std::ranges::stride_view(SimpleView(buffer, buffer + 3), 1); + auto sv = std::ranges::stride_view(BasicTestView(buffer, buffer + 3), 1); assert(1 == *(sv.begin())); return 0; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp index f4287b4e321e9..6cbbd1d40015d 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp @@ -27,11 +27,11 @@ static_assert(std::is_constructible_v); static_assert(!CanStrideView); // Ensure that a range that is not a view cannot be the subject of a stride_view. -static_assert(std::ranges::range); -static_assert(std::ranges::input_range); -static_assert(std::movable); -static_assert(!std::ranges::view); -static_assert(!CanStrideView); +static_assert(std::ranges::range>); +static_assert(std::ranges::input_range>); +static_assert(std::movable>); +static_assert(!std::ranges::view>); +static_assert(!CanStrideView, 1>); // And now, let's satisfy all the prerequisites and make sure that we can stride over a range (that is an input range and is a view!) static_assert(std::ranges::range>); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp index 0c4342dae74b2..3207565e4c5bf 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp @@ -17,7 +17,7 @@ #include "types.h" // There is no default ctor for stride_view. -using View = InputView>; +using View = BasicTestView>; static_assert(!std::is_default_constructible_v>); // Test that the stride_view can only be explicitly constructed. diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp index cb08da44039af..38399d5b20982 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp @@ -64,18 +64,18 @@ struct SimpleUnCommonView : std::ranges::view_base { }; static_assert(HasOnlyNonConstEnd>); -static_assert(HasOnlyConstEnd>); +static_assert(HasOnlyConstEnd>>); static_assert(HasConstAndNonConstEnd>); constexpr bool test_non_default_sentinel() { { - LIBCPP_STATIC_ASSERT(std::ranges::__simple_view); - static_assert(std::ranges::common_range); - static_assert(std::ranges::sized_range); - static_assert(std::ranges::forward_range); + LIBCPP_STATIC_ASSERT(std::ranges::__simple_view>); + static_assert(std::ranges::common_range>); + static_assert(std::ranges::sized_range>); + static_assert(std::ranges::forward_range>); - auto v = SimpleView{nullptr, nullptr}; - auto sv = std::ranges::stride_view(v, 1); + auto v = BasicTestView{nullptr, nullptr}; + auto sv = std::ranges::stride_view>(v, 1); static_assert(!std::is_same_v); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp index 05b8e6c86ec84..a4c7a567c2119 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp @@ -21,8 +21,9 @@ constexpr bool iterator_concept_test() { { int arr[] = {1, 2, 3}; // Iterator of stride over random access view should have random access concept. - auto rav = InputView>(random_access_iterator(arr), random_access_iterator(arr + 3)); - auto str = std::ranges::stride_view>>(rav, 1); + auto rav = + BasicTestView>(random_access_iterator(arr), random_access_iterator(arr + 3)); + auto str = std::ranges::stride_view>>(rav, 1); static_assert(std::random_access_iterator); static_assert(std::random_access_iterator); } @@ -30,8 +31,9 @@ constexpr bool iterator_concept_test() { { int arr[] = {1, 2, 3}; // Iterator of stride over bidirectional view should have bidirectional view concept. - auto rav = InputView>(bidirectional_iterator(arr), bidirectional_iterator(arr + 3)); - auto str = std::ranges::stride_view>>(rav, 1); + auto rav = + BasicTestView>(bidirectional_iterator(arr), bidirectional_iterator(arr + 3)); + auto str = std::ranges::stride_view>>(rav, 1); static_assert(std::bidirectional_iterator); static_assert(std::bidirectional_iterator); static_assert(!std::random_access_iterator); @@ -41,8 +43,8 @@ constexpr bool iterator_concept_test() { { int arr[] = {1, 2, 3}; // Iterator of stride over forward view should have forward view concept. - auto rav = InputView>(forward_iterator(arr), forward_iterator(arr + 3)); - auto str = std::ranges::stride_view>>(rav, 1); + auto rav = BasicTestView>(forward_iterator(arr), forward_iterator(arr + 3)); + auto str = std::ranges::stride_view>>(rav, 1); static_assert(std::forward_iterator); static_assert(std::forward_iterator); static_assert(!std::bidirectional_iterator); @@ -54,8 +56,8 @@ constexpr bool iterator_concept_test() { { int arr[] = {1, 2, 3}; // Iterator of stride over input view should have input view concept. - auto rav = InputView>(cpp17_input_iterator(arr), cpp17_input_iterator(arr + 3)); - auto str = std::ranges::stride_view>>(rav, 1); + auto rav = BasicTestView>(cpp17_input_iterator(arr), cpp17_input_iterator(arr + 3)); + auto str = std::ranges::stride_view>>(rav, 1); static_assert(std::input_iterator); static_assert(std::input_iterator); static_assert(!std::forward_iterator); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp index 32bebf581de51..bc96588db4577 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp @@ -18,45 +18,10 @@ template concept iter_moveable = requires(T&& t) { std::ranges::iter_move(t); }; -template -struct MaybeExceptIterSwapIterator : InputIterBase> { - int* counter_{nullptr}; - constexpr MaybeExceptIterSwapIterator() = default; - constexpr MaybeExceptIterSwapIterator(const MaybeExceptIterSwapIterator&) = default; - constexpr MaybeExceptIterSwapIterator(MaybeExceptIterSwapIterator&&) = default; - constexpr MaybeExceptIterSwapIterator& operator=(const MaybeExceptIterSwapIterator& other) = default; - constexpr MaybeExceptIterSwapIterator& operator=(MaybeExceptIterSwapIterator&& other) = default; - - constexpr explicit MaybeExceptIterSwapIterator(int* counter) : counter_(counter) {} - - friend constexpr int iter_move(const MaybeExceptIterSwapIterator& t) { - (*t.counter_)++; - return 5; - } - friend constexpr int iter_move(const MaybeExceptIterSwapIterator& t) noexcept - requires NoExcept - { - (*t.counter_)++; - return 5; - } - - constexpr int operator*() const { return 5; } -}; - -template -struct IterSwapRange : std::ranges::view_base { - MaybeExceptIterSwapIterator begin_; - MaybeExceptIterSwapIterator end_; - constexpr IterSwapRange(int* counter) - : begin_(MaybeExceptIterSwapIterator(counter)), end_(MaybeExceptIterSwapIterator(counter)) {} - constexpr MaybeExceptIterSwapIterator begin() const { return begin_; } - constexpr MaybeExceptIterSwapIterator end() const { return end_; } -}; - constexpr bool test() { { int iter_move_counter(0); - using View = IterSwapRange; + using View = IterSwapRange; using StrideView = std::ranges::stride_view; auto svb = StrideView(View(&iter_move_counter), 1).begin(); @@ -70,7 +35,7 @@ constexpr bool test() { { int iter_move_counter(0); - using View = IterSwapRange; + using View = IterSwapRange; using StrideView = std::ranges::stride_view; auto svb = StrideView(View(&iter_move_counter), 1).begin(); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp index 885862fcfdf53..959512891fa98 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp @@ -20,44 +20,6 @@ template concept swappable = requires(T&& t, T&& u) { std::ranges::iter_swap(t, u); }; -template -struct MaybeExceptIterSwapIterator : InputIterBase> { - int* counter_{nullptr}; - constexpr MaybeExceptIterSwapIterator() = default; - constexpr MaybeExceptIterSwapIterator(const MaybeExceptIterSwapIterator&) = default; - constexpr MaybeExceptIterSwapIterator(MaybeExceptIterSwapIterator&&) = default; - constexpr MaybeExceptIterSwapIterator& operator=(const MaybeExceptIterSwapIterator& other) = default; - constexpr MaybeExceptIterSwapIterator& operator=(MaybeExceptIterSwapIterator&& other) = default; - - constexpr explicit MaybeExceptIterSwapIterator(int* counter) : counter_(counter) {} - - friend constexpr void iter_swap(const MaybeExceptIterSwapIterator& t, const MaybeExceptIterSwapIterator& u) noexcept - requires Swappable && NoExcept - { - (*t.counter_)++; - (*u.counter_)++; - } - - friend constexpr void iter_swap(const MaybeExceptIterSwapIterator& t, const MaybeExceptIterSwapIterator& u) - requires Swappable && (!NoExcept) - { - (*t.counter_)++; - (*u.counter_)++; - } - constexpr int operator*() const { return 5; } -}; - -template -struct IterSwapRange : std::ranges::view_base { - MaybeExceptIterSwapIterator begin_; - MaybeExceptIterSwapIterator end_; - constexpr IterSwapRange(int* counter) - : begin_(MaybeExceptIterSwapIterator(counter)), - end_(MaybeExceptIterSwapIterator(counter)) {} - constexpr MaybeExceptIterSwapIterator begin() const { return begin_; } - constexpr MaybeExceptIterSwapIterator end() const { return end_; } -}; - constexpr bool test() { { int iter_move_counter_one(0); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index ff8b354f3b169..2436ff3b5ebc6 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -72,278 +72,273 @@ concept is_indexable = requires(T& t) { t[5]; }; template concept can_calculate_distance_between_non_sentinel = requires(T& t) { t - t; }; -constexpr bool operator_tests() { - { - // What operators are valid for an iterator derived from a stride view - // over an input view. - using View = InputView>; - using StrideViewIterator = std::ranges::iterator_t>; - - static_assert(is_plus_plusable_post); - static_assert(is_plus_plusable_pre); - static_assert(!is_minus_minusable_post); - static_assert(!is_minus_minusable_pre); - static_assert(!is_plus_equalable); - static_assert(!is_minus_equalable); - static_assert(!is_iterator_minusable); - static_assert(!is_difference_plusable); - static_assert(!is_difference_minusable); - static_assert(!is_relationally_comparable); - static_assert(!is_indexable); - } - { - // What operators are valid for an iterator derived from a stride view - // over a forward view. - using View = InputView>; - using StrideViewIterator = std::ranges::iterator_t>; - - static_assert(is_plus_plusable_post); - static_assert(is_plus_plusable_pre); - static_assert(!is_minus_minusable_post); - static_assert(!is_minus_minusable_pre); - static_assert(!is_plus_equalable); - static_assert(!is_minus_equalable); - static_assert(!is_iterator_minusable); - static_assert(!is_difference_plusable); - static_assert(!is_difference_minusable); - static_assert(!is_relationally_comparable); - static_assert(!is_indexable); - } - { - // What operators are valid for an iterator derived from a stride view - // over a sized input view. - using View = InputView; - using StrideViewIterator = std::ranges::iterator_t>; - - static_assert(is_plus_plusable_post); - static_assert(is_plus_plusable_pre); - static_assert(!is_minus_minusable_post); - static_assert(!is_minus_minusable_pre); - static_assert(!is_plus_equalable); - static_assert(!is_minus_equalable); - static_assert(is_iterator_minusable); - static_assert(!is_difference_plusable); - static_assert(!is_difference_minusable); - static_assert(!is_relationally_comparable); - static_assert(!is_indexable); - } - { - // What operators are valid for an iterator derived from a stride view - // over a sized forward view. - using View = InputView; - using StrideViewIterator = std::ranges::iterator_t>; - - static_assert(is_plus_plusable_post); - static_assert(is_plus_plusable_pre); - static_assert(!is_minus_minusable_post); - static_assert(!is_minus_minusable_pre); - static_assert(!is_plus_equalable); - static_assert(!is_minus_equalable); - static_assert(is_iterator_minusable); - static_assert(!is_difference_plusable); - static_assert(!is_difference_minusable); - static_assert(!is_relationally_comparable); - static_assert(!is_indexable); - } - { - // What operators are valid for an iterator derived from a stride view - // over a bidirectional view. - using View = InputView>; - using StrideViewIterator = std::ranges::iterator_t>; - - static_assert(is_plus_plusable_post); - static_assert(is_plus_plusable_pre); - static_assert(is_minus_minusable_post); - static_assert(is_minus_minusable_pre); - static_assert(!is_plus_equalable); - static_assert(!is_minus_equalable); - static_assert(!is_iterator_minusable); - static_assert(!is_difference_plusable); - static_assert(!is_difference_minusable); - static_assert(!is_relationally_comparable); - static_assert(!is_indexable); - } - { - // What operators are valid for an iterator derived from a stride view - // over a random access view. - using View = InputView>; - using StrideViewIterator = std::ranges::iterator_t>; - - static_assert(is_plus_plusable_post); - static_assert(is_plus_plusable_pre); - static_assert(is_minus_minusable_post); - static_assert(is_minus_minusable_pre); - static_assert(is_plus_equalable); - static_assert(is_minus_equalable); - static_assert(is_iterator_minusable); - static_assert(is_difference_plusable); - static_assert(is_difference_minusable); - static_assert(is_relationally_comparable); - static_assert(is_indexable); - } - { - using Base = InputView; - // Test the forward-range operator- between two iterators (i.e., no ceil). - int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - auto rav_zero = Base(SizedForwardIterator(arr), SizedForwardIterator(arr + 10)); - auto rav_one = Base(SizedForwardIterator(arr + 1), SizedForwardIterator(arr + 10)); - auto stride_zoff = std::ranges::stride_view(rav_zero, 3); - auto stride_ooff = std::ranges::stride_view(rav_one, 3); - - auto stride_zoff_begin = stride_zoff.begin(); - auto stride_ooff_begin = stride_ooff.begin(); - - auto stride_zoff_one = stride_zoff_begin; - auto stride_zoff_four = ++stride_zoff_begin; - auto stride_zoff_seven = ++stride_zoff_begin; - - auto stride_ooff_two = stride_ooff_begin; - auto stride_ooff_five = ++stride_ooff_begin; - - static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); - static_assert(can_calculate_distance_between_non_sentinel); - static_assert(std::forward_iterator); - - assert(*stride_zoff_one == 1); - assert(*stride_zoff_four == 4); - assert(*stride_zoff_seven == 7); - - assert(*stride_ooff_two == 2); - assert(*stride_ooff_five == 5); - // Check positive __n with exact multiple of left's stride. - assert(stride_zoff_four - stride_zoff_one == 1); - assert(stride_zoff_seven - stride_zoff_one == 2); - - // Check positive __n with non-exact multiple of left's stride. - assert(stride_ooff_two - stride_zoff_one == 0); - assert(stride_ooff_five - stride_zoff_one == 1); - - // Check negative __n with exact multiple of left's stride. - assert(stride_zoff_one - stride_zoff_four == -1); - assert(stride_zoff_one - stride_zoff_seven == -2); - - // Check negative __n with non-exact multiple of left's stride. - assert(stride_zoff_one - stride_ooff_two == 0); - assert(stride_zoff_one - stride_ooff_five == -1); - } - - { - using Base = InputView; - // Test the non-forward-range operator- between two iterators (i.e., ceil). - int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - auto rav_zero = Base(SizedInputIterator(arr), SizedInputIterator(arr + 10)); - auto rav_one = Base(SizedInputIterator(arr + 1), SizedInputIterator(arr + 10)); - auto stride_zoff = std::ranges::stride_view(rav_zero, 3); - auto stride_ooff = std::ranges::stride_view(rav_one, 3); - - auto stride_zoff_begin = stride_zoff.begin(); - auto stride_ooff_begin = stride_ooff.begin(); - - auto stride_zoff_one = stride_zoff_begin; - auto stride_zoff_four = ++stride_zoff_begin; - auto stride_zoff_seven = ++stride_zoff_begin; - - auto stride_ooff_two = stride_ooff_begin; - auto stride_ooff_five = ++stride_ooff_begin; - - static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); - static_assert(can_calculate_distance_between_non_sentinel); - - assert(*stride_zoff_one == 1); - assert(*stride_zoff_four == 4); - assert(*stride_zoff_seven == 7); - - assert(*stride_ooff_two == 2); - assert(*stride_ooff_five == 5); - - // Check positive __n with exact multiple of left's stride. - assert(stride_zoff_four - stride_zoff_one == 1); - assert(stride_zoff_seven - stride_zoff_one == 2); - // Check positive __n with non-exact multiple of left's stride. - assert(stride_ooff_two - stride_zoff_one == 1); - assert(stride_ooff_five - stride_zoff_one == 2); - - // Check negative __n with exact multiple of left's stride. - assert(stride_zoff_one - stride_zoff_four == -1); - assert(stride_zoff_one - stride_zoff_seven == -2); - // Check negative __n with non-exact multiple of left's stride. - assert(stride_zoff_one - stride_ooff_two == -1); - assert(stride_zoff_one - stride_ooff_five == -2); - } - { - // Check whether __missing_ gets handled properly. - using Base = SimpleView; - int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - auto base = Base(arr, arr + 10); - auto strider = std::ranges::stride_view(base, 7); - - auto strider_iter = strider.end(); - - strider_iter--; - assert(*strider_iter == 8); - - // Now that we are back among the valid, we should - // have a normal stride length back (i.e., __missing_ - // should be equal to 0). - strider_iter--; - assert(*strider_iter == 1); - - strider_iter++; - assert(*strider_iter == 8); - - // By striding past the end, we are going to generate - // another __missing_ != 0 value. Let's make sure - // that it gets generated and used. - strider_iter++; - assert(strider_iter == strider.end()); - - strider_iter--; - assert(*strider_iter == 8); - - strider_iter--; - assert(*strider_iter == 1); - } - { - using EqualableView = InputView>; - using Stride = std::ranges::stride_view; - using StrideIter = std::ranges::iterator_t; - - static_assert(is_relationally_equalable>); - static_assert(is_relationally_equalable); - - static_assert(!std::three_way_comparable>); - static_assert(!std::ranges::random_access_range); - static_assert(!is_three_way_comparable); - } - { - using ThreeWayComparableView = InputView>; - using Stride = std::ranges::stride_view; - using StrideIter = std::ranges::iterator_t; - - static_assert(std::three_way_comparable>); - static_assert(std::ranges::random_access_range); - static_assert(is_three_way_comparable); - } - { - using UnEqualableView = - ViewOverNonCopyable, sentinel_wrapper>>; - using Stride = std::ranges::stride_view; - using StrideIter = std::ranges::iterator_t; - - static_assert(!is_relationally_equalable>); - static_assert(!is_relationally_equalable); - - static_assert(!std::three_way_comparable>); - static_assert(!std::ranges::random_access_range); - static_assert(!is_three_way_comparable); - } +// What operators are valid for an iterator derived from a stride view +// over an input view. +using StrideViewOverInputViewIterator = + std::ranges::iterator_t>>>; + +static_assert(is_plus_plusable_post); +static_assert(is_plus_plusable_pre); +static_assert(!is_minus_minusable_post); +static_assert(!is_minus_minusable_pre); +static_assert(!is_plus_equalable); +static_assert(!is_minus_equalable); +static_assert(!is_iterator_minusable); +static_assert(!is_difference_plusable); +static_assert(!is_difference_minusable); +static_assert(!is_relationally_comparable); +static_assert(!is_indexable); + +// What operators are valid for an iterator derived from a stride view +// over a forward view. +using ForwardView = BasicTestView>; +using StrideViewOverForwardViewIterator = std::ranges::iterator_t>; + +static_assert(is_plus_plusable_post); +static_assert(is_plus_plusable_pre); +static_assert(!is_minus_minusable_post); +static_assert(!is_minus_minusable_pre); +static_assert(!is_plus_equalable); +static_assert(!is_minus_equalable); +static_assert(!is_iterator_minusable); +static_assert(!is_difference_plusable); +static_assert(!is_difference_minusable); +static_assert(!is_relationally_comparable); +static_assert(!is_indexable); + +// What operators are valid for an iterator derived from a stride view +// over a bidirectional view. +using BidirectionalView = BasicTestView>; +using StrideViewOverBidirectionalViewIterator = std::ranges::iterator_t>; + +static_assert(is_plus_plusable_post); +static_assert(is_plus_plusable_pre); +static_assert(is_minus_minusable_post); +static_assert(is_minus_minusable_pre); +static_assert(!is_plus_equalable); +static_assert(!is_minus_equalable); +static_assert(!is_iterator_minusable); +static_assert(!is_difference_plusable); +static_assert(!is_difference_minusable); +static_assert(!is_relationally_comparable); +static_assert(!is_indexable); + +// What operators are valid for an iterator derived from a stride view +// over a random access view. +using RandomAccessView = BasicTestView>; +using StrideViewOverRandomAccessViewIterator = std::ranges::iterator_t>; + +static_assert(is_plus_plusable_post); +static_assert(is_plus_plusable_pre); +static_assert(is_minus_minusable_post); +static_assert(is_minus_minusable_pre); +static_assert(is_plus_equalable); +static_assert(is_minus_equalable); +static_assert(is_iterator_minusable); +static_assert(is_difference_plusable); +static_assert(is_difference_minusable); +static_assert(is_relationally_comparable); +static_assert(is_indexable); + +using EqualableView = BasicTestView>; +using EqualableViewStrideView = std::ranges::stride_view; +using EqualableViewStrideViewIter = std::ranges::iterator_t; + +static_assert(is_relationally_equalable>); +static_assert(is_relationally_equalable); + +static_assert(!std::three_way_comparable>); +static_assert(!std::ranges::random_access_range); +static_assert(!is_three_way_comparable); + +using ThreeWayComparableView = BasicTestView>; +using ThreeWayComparableViewStrideView = std::ranges::stride_view; +using ThreeWayComparableStrideViewIter = std::ranges::iterator_t; + +static_assert(std::three_way_comparable>); +static_assert(std::ranges::random_access_range); +static_assert(is_three_way_comparable); + +using UnEqualableView = + ViewOverNonCopyableIterator, sentinel_wrapper>>; +using UnEqualableViewStrideView = std::ranges::stride_view; +using UnEqualableViewStrideViewIter = std::ranges::iterator_t; + +static_assert(!is_relationally_equalable>); +static_assert(!is_relationally_equalable); + +static_assert(!std::three_way_comparable>); +static_assert(!std::ranges::random_access_range); +static_assert(!is_three_way_comparable); + +constexpr bool test_non_forward_operator_minus() { + using Base = BasicTestView; + // Test the non-forward-range operator- between two iterators (i.e., ceil). + int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + // First, what operators are valid for an iterator derived from a stride view + // over a sized input view. + using StrideViewIterator = std::ranges::iterator_t>; + + static_assert(is_plus_plusable_post); + static_assert(is_plus_plusable_pre); + static_assert(!is_minus_minusable_post); + static_assert(!is_minus_minusable_pre); + static_assert(!is_plus_equalable); + static_assert(!is_minus_equalable); + static_assert(!is_difference_plusable); + static_assert(!is_difference_minusable); + static_assert(!is_relationally_comparable); + static_assert(!is_indexable); + + auto rav_zero = Base(SizedInputIterator(arr), SizedInputIterator(arr + 10)); + auto rav_one = Base(SizedInputIterator(arr + 1), SizedInputIterator(arr + 10)); + auto stride_zoff = std::ranges::stride_view(rav_zero, 3); + auto stride_ooff = std::ranges::stride_view(rav_one, 3); + + auto stride_zoff_begin = stride_zoff.begin(); + auto stride_ooff_begin = stride_ooff.begin(); + + auto stride_zoff_one = stride_zoff_begin; + auto stride_zoff_four = ++stride_zoff_begin; + auto stride_zoff_seven = ++stride_zoff_begin; + + auto stride_ooff_two = stride_ooff_begin; + auto stride_ooff_five = ++stride_ooff_begin; + + static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); + static_assert(can_calculate_distance_between_non_sentinel); + + assert(*stride_zoff_one == 1); + assert(*stride_zoff_four == 4); + assert(*stride_zoff_seven == 7); + + assert(*stride_ooff_two == 2); + assert(*stride_ooff_five == 5); + + // Check positive __n with exact multiple of left's stride. + assert(stride_zoff_four - stride_zoff_one == 1); + assert(stride_zoff_seven - stride_zoff_one == 2); + // Check positive __n with non-exact multiple of left's stride. + assert(stride_ooff_two - stride_zoff_one == 1); + assert(stride_ooff_five - stride_zoff_one == 2); + + // Check negative __n with exact multiple of left's stride. + assert(stride_zoff_one - stride_zoff_four == -1); + assert(stride_zoff_one - stride_zoff_seven == -2); + // Check negative __n with non-exact multiple of left's stride. + assert(stride_zoff_one - stride_ooff_two == -1); + assert(stride_zoff_one - stride_ooff_five == -2); return true; } +constexpr bool test_forward_operator_minus() { + using Base = BasicTestView; + // Test the forward-range operator- between two iterators (i.e., no ceil). + int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + + // First, what operators are valid for an iterator derived from a stride view + // over a sized forward view. + using StrideViewIterator = std::ranges::iterator_t>; + + static_assert(is_plus_plusable_post); + static_assert(is_plus_plusable_pre); + static_assert(!is_minus_minusable_post); + static_assert(!is_minus_minusable_pre); + static_assert(!is_plus_equalable); + static_assert(!is_minus_equalable); + static_assert(is_iterator_minusable); + static_assert(!is_difference_plusable); + static_assert(!is_difference_minusable); + static_assert(!is_relationally_comparable); + static_assert(!is_indexable); + + auto rav_zero = Base(SizedForwardIterator(arr), SizedForwardIterator(arr + 10)); + auto rav_one = Base(SizedForwardIterator(arr + 1), SizedForwardIterator(arr + 10)); + auto stride_zoff = std::ranges::stride_view(rav_zero, 3); + auto stride_ooff = std::ranges::stride_view(rav_one, 3); + + auto stride_zoff_begin = stride_zoff.begin(); + auto stride_ooff_begin = stride_ooff.begin(); + + auto stride_zoff_one = stride_zoff_begin; + auto stride_zoff_four = ++stride_zoff_begin; + auto stride_zoff_seven = ++stride_zoff_begin; + + auto stride_ooff_two = stride_ooff_begin; + auto stride_ooff_five = ++stride_ooff_begin; + + static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); + static_assert(can_calculate_distance_between_non_sentinel); + static_assert(std::forward_iterator); + + assert(*stride_zoff_one == 1); + assert(*stride_zoff_four == 4); + assert(*stride_zoff_seven == 7); + + assert(*stride_ooff_two == 2); + assert(*stride_ooff_five == 5); + // Check positive __n with exact multiple of left's stride. + assert(stride_zoff_four - stride_zoff_one == 1); + assert(stride_zoff_seven - stride_zoff_one == 2); + + // Check positive __n with non-exact multiple of left's stride. + assert(stride_ooff_two - stride_zoff_one == 0); + assert(stride_ooff_five - stride_zoff_one == 1); + + // Check negative __n with exact multiple of left's stride. + assert(stride_zoff_one - stride_zoff_four == -1); + assert(stride_zoff_one - stride_zoff_seven == -2); + + // Check negative __n with non-exact multiple of left's stride. + assert(stride_zoff_one - stride_ooff_two == 0); + assert(stride_zoff_one - stride_ooff_five == -1); + return true; +} + +constexpr bool test_properly_handling_missing() { + // Check whether __missing_ gets handled properly. + using Base = BasicTestView; + int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + auto base = Base(arr, arr + 10); + auto strider = std::ranges::stride_view(base, 7); + + auto strider_iter = strider.end(); + + strider_iter--; + assert(*strider_iter == 8); + + // Now that we are back among the valid, we should + // have a normal stride length back (i.e., __missing_ + // should be equal to 0). + strider_iter--; + assert(*strider_iter == 1); + + strider_iter++; + assert(*strider_iter == 8); + + // By striding past the end, we are going to generate + // another __missing_ != 0 value. Let's make sure + // that it gets generated and used. + strider_iter++; + assert(strider_iter == strider.end()); + + strider_iter--; + assert(*strider_iter == 8); + + strider_iter--; + assert(*strider_iter == 1); + return true; +} + int main(int, char**) { - operator_tests(); - static_assert(operator_tests()); + test_forward_operator_minus(); + static_assert(test_forward_operator_minus()); + + test_non_forward_operator_minus(); + static_assert(test_non_forward_operator_minus()); + test_properly_handling_missing(); + static_assert(test_properly_handling_missing()); return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp index dbb5d99983216..95ee761e98726 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp @@ -18,8 +18,8 @@ // There is no size member function on a stride view over a view that // is *not* a sized range -static_assert(!std::ranges::sized_range); -static_assert(!std::ranges::sized_range>); +static_assert(!std::ranges::sized_range); +static_assert(!std::ranges::sized_range>); constexpr bool test() { { diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp index 482144d941989..037b02938b89d 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp @@ -18,7 +18,7 @@ #include "types.h" constexpr bool test() { - using View = InputView>; + using View = BasicTestView>; int arr[]{1, 2, 3}; auto arrv(View(cpp17_input_iterator(arr), cpp17_input_iterator(arr + 3))); // Mark str const so that we confirm that stride is a const member function. diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index 5f77944272ca3..ce213b8b416dd 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -28,81 +28,7 @@ #include #include -template D> -concept CanStrideView = requires { - std::ranges::stride_view{I{}, D}; -}; - -template -struct InstrumentedBasicRange { - T* begin() const; - T* end() const; -}; - -class non_view_range { -public: - constexpr int* begin() const { return nullptr; } - constexpr int* end() const { return nullptr; } -}; - -struct MovedCopiedTrackedView { - constexpr explicit MovedCopiedTrackedView(bool* moved = nullptr, bool* copied = nullptr) - : wasMoveInitialized_(moved), wasCopyInitialized_(copied) {} - constexpr MovedCopiedTrackedView(MovedCopiedTrackedView const& other) - : wasMoveInitialized_(other.wasMoveInitialized_), wasCopyInitialized_(other.wasCopyInitialized_) { - *wasCopyInitialized_ = true; - } - constexpr MovedCopiedTrackedView(MovedCopiedTrackedView&& other) - : wasMoveInitialized_(other.wasMoveInitialized_), wasCopyInitialized_(other.wasCopyInitialized_) { - *wasMoveInitialized_ = true; - } - MovedCopiedTrackedView& operator=(MovedCopiedTrackedView const&) = default; - MovedCopiedTrackedView& operator=(MovedCopiedTrackedView&&) = default; - - bool* wasMoveInitialized_ = nullptr; - bool* wasCopyInitialized_ = nullptr; -}; - -template -struct MovedCopiedTrackedBasicView : MovedCopiedTrackedView, std::ranges::view_base { - constexpr explicit MovedCopiedTrackedBasicView(T* b, T* e, bool* moved = nullptr, bool* copied = nullptr) - : MovedCopiedTrackedView(moved, copied), begin_(b), end_(e) {} - constexpr MovedCopiedTrackedBasicView(const MovedCopiedTrackedBasicView& other) - : MovedCopiedTrackedView(other), begin_(other.begin_), end_(other.end_) {} - constexpr MovedCopiedTrackedBasicView(MovedCopiedTrackedBasicView&& other) - : MovedCopiedTrackedView(std::move(other)), begin_(other.begin_), end_(other.end_) {} - MovedCopiedTrackedBasicView& operator=(MovedCopiedTrackedBasicView const&) = default; - MovedCopiedTrackedBasicView& operator=(MovedCopiedTrackedBasicView&&) = default; - constexpr T* begin() const { return begin_; } - constexpr T* end() const { return end_; } - - T* begin_; - T* end_; -}; - -template -MovedCopiedTrackedBasicView(T, T, bool*, bool*) -> MovedCopiedTrackedBasicView; - -template -struct InstrumentedBorrowedRange : public MovedCopiedTrackedBasicView {}; - -template -inline constexpr bool std::ranges::enable_borrowed_range> = true; - -template -struct MovedOnlyTrackedBasicView : MovedCopiedTrackedView, std::ranges::view_base { - constexpr explicit MovedOnlyTrackedBasicView(T* b, T* e, bool* moved = nullptr, bool* copied = nullptr) - : MovedCopiedTrackedView(moved, copied), begin_(b), end_(e) {} - constexpr MovedOnlyTrackedBasicView(MovedOnlyTrackedBasicView&& other) - : MovedCopiedTrackedView(std::move(other)), begin_(other.begin_), end_(other.end_) {} - MovedOnlyTrackedBasicView& operator=(MovedOnlyTrackedBasicView const&) = delete; - MovedOnlyTrackedBasicView& operator=(MovedOnlyTrackedBasicView&&) = default; - constexpr T* begin() const { return begin_; } - constexpr T* end() const { return end_; } - - T* begin_; - T* end_; -}; +// Iterators template struct ForwardIterBase { @@ -134,65 +60,16 @@ struct InputIterBase { friend constexpr bool operator==(const Derived&, const Derived&) { return true; } }; -template S = sentinel_wrapper> -struct MoveOnlyView : std::ranges::view_base { - T begin_; - T end_; - - constexpr explicit MoveOnlyView(T b, T e) : begin_(b), end_(e) {} - - constexpr MoveOnlyView(const MoveOnlyView&) = delete; - constexpr MoveOnlyView(MoveOnlyView&& other) = default; - constexpr MoveOnlyView& operator=(MoveOnlyView&&) = default; - constexpr MoveOnlyView& operator=(const MoveOnlyView&) = delete; - - constexpr T begin() const { return begin_; } - constexpr sentinel_wrapper end() const { return sentinel_wrapper{end_}; } -}; -static_assert(std::ranges::view>>); -static_assert(!std::copyable>>); - -template S = sentinel_wrapper> -struct CopyableView : std::ranges::view_base { - T begin_; - T end_; - - constexpr explicit CopyableView(T b, T e) : begin_(b), end_(e) {} - - constexpr CopyableView(const CopyableView&) = default; - constexpr CopyableView& operator=(const CopyableView&) = default; - - constexpr T begin() const { return begin_; } - constexpr sentinel_wrapper end() const { return sentinel_wrapper{end_}; } -}; -static_assert(std::ranges::view>>); -static_assert(std::copyable>>); - -//TODO: Rename as View. -template S = sentinel_wrapper> -struct InputView : std::ranges::view_base { - T begin_; - T end_; - - constexpr InputView(T b, T e) : begin_(b), end_(e) {} - - constexpr T begin() { return begin_; } - constexpr T begin() const { return begin_; } - constexpr sentinel_wrapper end() { return sentinel_wrapper{end_}; } - constexpr sentinel_wrapper end() const { return sentinel_wrapper{end_}; } -}; - -// Don't move/hold the iterator itself, move/hold the base +// Don't move/hold the iterator itself, copy/hold the base // of that iterator and reconstruct the iterator on demand. // May result in aliasing (if, e.g., Iterator is an iterator // over int *). template -struct ViewOverNonCopyable : std::ranges::view_base { - constexpr explicit ViewOverNonCopyable(Iterator it, Sentinel sent) - : it_(base(std::move(it))), sent_(base(std::move(sent))) {} +struct ViewOverNonCopyableIterator : std::ranges::view_base { + constexpr explicit ViewOverNonCopyableIterator(Iterator it, Sentinel sent) : it_(base(it)), sent_(base(sent)) {} - ViewOverNonCopyable(ViewOverNonCopyable&&) = default; - ViewOverNonCopyable& operator=(ViewOverNonCopyable&&) = default; + ViewOverNonCopyableIterator(ViewOverNonCopyableIterator&&) = default; + ViewOverNonCopyableIterator& operator=(ViewOverNonCopyableIterator&&) = default; constexpr Iterator begin() const { return Iterator(it_); } constexpr Sentinel end() const { return Sentinel(sent_); } @@ -202,39 +79,20 @@ struct ViewOverNonCopyable : std::ranges::view_base { decltype(base(std::declval())) sent_; }; -struct ForwardTracedMoveIter : ForwardIterBase { - bool moved = false; - - constexpr ForwardTracedMoveIter() = default; - constexpr ForwardTracedMoveIter(const ForwardTracedMoveIter&) = default; - constexpr ForwardTracedMoveIter(ForwardTracedMoveIter&&) : moved{true} {} - constexpr ForwardTracedMoveIter& operator=(ForwardTracedMoveIter&&) = default; - constexpr ForwardTracedMoveIter& operator=(const ForwardTracedMoveIter&) = default; -}; - -struct ForwardTracedMoveView : std::ranges::view_base { - constexpr ForwardTracedMoveIter begin() const { return {}; } - constexpr ForwardTracedMoveIter end() const { return {}; } -}; - struct UnsizedBasicRangeIterator : ForwardIterBase {}; -struct UnsizedBasicRange : std::ranges::view_base { - UnsizedBasicRangeIterator begin() const; - UnsizedBasicRangeIterator end() const; -}; - -// TODO: Cleanup struct SizedInputIterator { using iterator_concept = std::input_iterator_tag; using value_type = int; using difference_type = std::intptr_t; - int* __v_; + int* __v_ = nullptr; - constexpr SizedInputIterator() { __v_ = nullptr; } + constexpr SizedInputIterator() = default; constexpr SizedInputIterator(int* v) { __v_ = v; } - constexpr SizedInputIterator(const SizedInputIterator& sii) { __v_ = sii.__v_; } + constexpr SizedInputIterator(const SizedInputIterator& sii) = default; + constexpr SizedInputIterator& operator=(const SizedInputIterator&) = default; + constexpr SizedInputIterator& operator=(SizedInputIterator&&) = default; constexpr int operator*() const { return *__v_; } constexpr SizedInputIterator& operator++() { @@ -256,17 +114,18 @@ struct SizedInputIterator { static_assert(std::input_iterator); static_assert(std::sized_sentinel_for); -// TODO: Cleanup struct SizedForwardIterator { using iterator_concept = std::forward_iterator_tag; using value_type = int; using difference_type = std::intptr_t; - int* __v_; + int* __v_ = nullptr; - constexpr SizedForwardIterator() { __v_ = nullptr; } + constexpr SizedForwardIterator() = default; constexpr SizedForwardIterator(int* v) { __v_ = v; } - constexpr SizedForwardIterator(const SizedInputIterator& sii) { __v_ = sii.__v_; } + constexpr SizedForwardIterator(const SizedForwardIterator& sii) = default; + constexpr SizedForwardIterator& operator=(const SizedForwardIterator&) = default; + constexpr SizedForwardIterator& operator=(SizedForwardIterator&&) = default; constexpr int operator*() const { return *__v_; } constexpr SizedForwardIterator& operator++() { @@ -288,15 +147,115 @@ struct SizedForwardIterator { static_assert(std::input_iterator); static_assert(std::sized_sentinel_for); -struct SimpleView : std::ranges::view_base { - int* begin_; - int* end_; +template +struct MaybeExceptIterSwapIterator : InputIterBase> { + int* counter_{nullptr}; + constexpr MaybeExceptIterSwapIterator() = default; + constexpr MaybeExceptIterSwapIterator(const MaybeExceptIterSwapIterator&) = default; + constexpr MaybeExceptIterSwapIterator(MaybeExceptIterSwapIterator&&) = default; + constexpr MaybeExceptIterSwapIterator& operator=(const MaybeExceptIterSwapIterator& other) = default; + constexpr MaybeExceptIterSwapIterator& operator=(MaybeExceptIterSwapIterator&& other) = default; + + constexpr explicit MaybeExceptIterSwapIterator(int* counter) : counter_(counter) {} + + friend constexpr void iter_swap(const MaybeExceptIterSwapIterator& t, const MaybeExceptIterSwapIterator& u) noexcept + requires Swappable && NoExcept + { + (*t.counter_)++; + (*u.counter_)++; + } + + friend constexpr void iter_swap(const MaybeExceptIterSwapIterator& t, const MaybeExceptIterSwapIterator& u) + requires Swappable && (!NoExcept) + { + (*t.counter_)++; + (*u.counter_)++; + } + + friend constexpr int iter_move(const MaybeExceptIterSwapIterator& t) { + (*t.counter_)++; + return 5; + } + friend constexpr int iter_move(const MaybeExceptIterSwapIterator& t) noexcept + requires NoExcept + { + (*t.counter_)++; + return 5; + } + + constexpr int operator*() const { return 5; } +}; + +template +struct IterSwapRange : std::ranges::view_base { + MaybeExceptIterSwapIterator begin_; + MaybeExceptIterSwapIterator end_; + constexpr IterSwapRange(int* counter) + : begin_(MaybeExceptIterSwapIterator(counter)), + end_(MaybeExceptIterSwapIterator(counter)) {} + constexpr MaybeExceptIterSwapIterator begin() const { return begin_; } + constexpr MaybeExceptIterSwapIterator end() const { return end_; } +}; + +// Concepts + +template D> +concept CanStrideView = requires { + std::ranges::stride_view{I{}, D}; +}; + +// Views + +template S = sentinel_wrapper> +struct MoveOnlyView : std::ranges::view_base { + T begin_; + T end_; + + constexpr explicit MoveOnlyView(T b, T e) : begin_(b), end_(e) {} + + constexpr MoveOnlyView(const MoveOnlyView&) = delete; + constexpr MoveOnlyView(MoveOnlyView&& other) = default; + constexpr MoveOnlyView& operator=(MoveOnlyView&&) = default; + constexpr MoveOnlyView& operator=(const MoveOnlyView&) = delete; + + constexpr T begin() const { return begin_; } + constexpr sentinel_wrapper end() const { return sentinel_wrapper{end_}; } +}; +static_assert(std::ranges::view>>); +static_assert(!std::copyable>>); + +template S = sentinel_wrapper> +struct CopyableView : std::ranges::view_base { + T begin_; + T end_; + + constexpr explicit CopyableView(T b, T e) : begin_(b), end_(e) {} + + constexpr CopyableView(const CopyableView&) = default; + constexpr CopyableView& operator=(const CopyableView&) = default; + + constexpr T begin() const { return begin_; } + constexpr sentinel_wrapper end() const { return sentinel_wrapper{end_}; } +}; +static_assert(std::ranges::view>>); +static_assert(std::copyable>>); - constexpr SimpleView(int* b, int* e) : begin_(b), end_(e) {} +template S = sentinel_wrapper> +struct BasicTestView : std::ranges::view_base { + T begin_; + T end_; + + constexpr BasicTestView(T b, T e) : begin_(b), end_(e) {} + + constexpr T begin() { return begin_; } + constexpr T begin() const { return begin_; } + constexpr S end() { return S{end_}; } + constexpr S end() const { return S{end_}; } +}; - constexpr const int* begin() const { return begin_; } - constexpr const int* end() const { return end_; } +struct UnsizedBasicView : std::ranges::view_base { + UnsizedBasicRangeIterator begin() const; + UnsizedBasicRangeIterator end() const; }; -LIBCPP_STATIC_ASSERT(std::ranges::__simple_view); #endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H From 158781111dea29fdc5fd3af66ca6c6e3b7546180 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Tue, 2 Jan 2024 22:20:41 -0500 Subject: [PATCH 089/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Address easiest parts of reviewer feedback. --- libcxx/include/__ranges/stride_view.h | 55 ++++++---- .../iterator/dereference.pass.cpp | 8 +- .../iterator/increment.pass.cpp | 2 +- .../range.stride.view/adaptor.pass.cpp | 2 +- .../iterator/ctor.copy.pass.cpp | 101 +++++++++--------- .../range.stride.view/iterator/equal.pass.cpp | 19 ++-- .../iterator/operator.pass.cpp | 12 +-- 7 files changed, 107 insertions(+), 92 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index df5080455ab03..4dcee437c7d3a 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -48,7 +48,7 @@ template _LIBCPP_HIDE_FROM_ABI constexpr _Value __div_ceil(_Value __left, _Value __right) { _Value __r = __left / __right; if (__left % __right) { - __r++; + ++__r; } return __r; } @@ -68,29 +68,31 @@ class stride_view : public view_interface> { _LIBCPP_ASSERT_UNCATEGORIZED(__stride > 0, "The value of stride must be greater than 0"); } - _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& requires copy_constructible<_View> { return __base_; } - _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } - _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_View> stride() const noexcept { return __stride_; } + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_View> stride() const noexcept { + return __stride_; + } - _LIBCPP_HIDE_FROM_ABI constexpr auto begin() + _LIBCPP_NODISCARD _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr auto begin() requires(!__simple_view<_View>) { return __iterator(this, ranges::begin(__base_), 0); } - _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const requires range { return __iterator(this, ranges::begin(__base_), 0); } - _LIBCPP_HIDE_FROM_ABI constexpr auto end() + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr auto end() requires(!__simple_view<_View>) { if constexpr (common_range<_View> && sized_range<_View> && forward_range<_View>) { @@ -103,7 +105,7 @@ class stride_view : public view_interface> { } } - _LIBCPP_HIDE_FROM_ABI constexpr auto end() const + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr auto end() const requires(range) { if constexpr (common_range && sized_range && forward_range) { @@ -116,13 +118,13 @@ class stride_view : public view_interface> { } } - _LIBCPP_HIDE_FROM_ABI constexpr auto size() + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr auto size() requires sized_range<_View> { return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __stride_)); } - _LIBCPP_HIDE_FROM_ABI constexpr auto size() const + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr auto size() const requires sized_range { return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __stride_)); @@ -140,7 +142,7 @@ struct __stride_iterator_category<_View> { using _Cat = typename iterator_traits>::iterator_category; using iterator_category = _If, - random_access_iterator_tag, + /* then */ random_access_iterator_tag, /* else */ _Cat >; }; @@ -198,7 +200,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> const& base() const& noexcept { return __current_; } _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); } - _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__current_ != __end_, "Cannot dereference an iterator at the end."); return *__current_; } @@ -210,7 +212,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> } _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; } - _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) requires forward_range<_Base> { auto __tmp = *this; @@ -225,7 +227,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> __missing_ = 0; return *this; } - _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int) + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int) requires bidirectional_range<_Base> { auto __tmp = *this; @@ -255,7 +257,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> return *this += -__n; } - _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const requires random_access_range<_Base> { return *(*this + __n); @@ -301,14 +303,16 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> return __x.__current_ <=> __y.__current_; } - _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator const& __i, difference_type __s) + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator + operator+(__iterator const& __i, difference_type __s) requires random_access_range<_Base> { auto __r = __i; __r += __s; return __r; } - _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __s, __iterator const& __i) + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator + operator+(difference_type __s, __iterator const& __i) requires random_access_range<_Base> { auto __r = __i; @@ -316,7 +320,8 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> return __r; } - _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator const& __i, difference_type __s) + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator + operator-(__iterator const& __i, difference_type __s) requires random_access_range<_Base> { auto __r = __i; @@ -324,14 +329,16 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> return __r; } - _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(__iterator const& __x, __iterator const& __y) + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type + operator-(__iterator const& __x, __iterator const& __y) requires sized_sentinel_for, iterator_t<_Base>> && forward_range<_Base> { auto __n = __x.__current_ - __y.__current_; return (__n + __x.__missing_ - __y.__missing_) / __x.__stride_; } - _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(__iterator const& __x, __iterator const& __y) + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type + operator-(__iterator const& __x, __iterator const& __y) requires sized_sentinel_for, iterator_t<_Base>> { auto __n = __x.__current_ - __y.__current_; @@ -341,18 +348,20 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> return ranges::__div_ceil(__n, __x.__stride_); } - _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(default_sentinel_t, __iterator const& __x) + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type + operator-(default_sentinel_t, __iterator const& __x) requires sized_sentinel_for, iterator_t<_Base>> { return ranges::__div_ceil(__x.__end_ - __x.__current_, __x.__stride_); } - _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(__iterator const& __x, default_sentinel_t __y) + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type + operator-(__iterator const& __x, default_sentinel_t __y) requires sized_sentinel_for, iterator_t<_Base>> { return -(__y - __x); } - _LIBCPP_HIDE_FROM_ABI friend constexpr range_rvalue_reference_t<_Base> + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI friend constexpr range_rvalue_reference_t<_Base> iter_move(__iterator const& __it) noexcept(noexcept(ranges::iter_move(__it.__current_))) { return ranges::iter_move(__it.__current_); } diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp index 6ee731d5d4e47..2bbebd6db5fa8 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp @@ -19,15 +19,15 @@ int main(int, char**) { int range[] = {1, 2, 3}; auto striv = std::ranges::views::stride(range, 3); auto striv_it = striv.begin(); - striv_it++; - TEST_LIBCPP_ASSERT_FAILURE(*striv_it, "Cannot dereference an iterator at the end."); + ++striv_it; + TEST_LIBCPP_ASSERT_FAILURE(*std::as_const(striv_it), "Cannot dereference an iterator at the end."); } { int range[] = {1, 2, 3}; auto striv = std::ranges::views::stride(range, 4); auto striv_it = striv.begin(); - striv_it++; - TEST_LIBCPP_ASSERT_FAILURE(*striv_it, "Cannot dereference an iterator at the end."); + ++striv_it; + TEST_LIBCPP_ASSERT_FAILURE(*std::as_const(striv_it), "Cannot dereference an iterator at the end."); } return 0; } diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp index 896d4661015c0..10e471a8805f5 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp @@ -21,7 +21,7 @@ int main(int, char**) { int range[] = {1, 2, 3}; auto striv = std::ranges::views::stride(range, 3); auto striv_it = striv.begin(); - striv_it++; + ++striv_it; TEST_LIBCPP_ASSERT_FAILURE(striv_it++, "Cannot increment an iterator already at the end."); return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index e600a1c9aac44..5d8bb73c366bb 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -98,7 +98,7 @@ constexpr bool test() { auto strided_iter = strided.begin(); auto strided_iter_next = strided_iter; - strided_iter_next++; + (void)strided_iter_next++; assert(*strided_iter == arr[0]); assert(*strided_iter_next == arr[1]); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp index 9a607d3e12a0a..716a8ade50328 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp @@ -17,7 +17,24 @@ #include "../types.h" #include "test_iterators.h" -struct NotSimpleViewIterBegin : InputIterBase {}; +struct NotSimpleViewIterEnd; +template +struct NotSimpleViewConstIterEnd; +template +struct NotSimpleViewConstIterBegin; + +struct NotSimpleViewIterBegin : InputIterBase { + template + friend constexpr bool + operator==(const NotSimpleViewIterBegin&, const NotSimpleViewConstIterEnd&) { + return true; + } + template + friend constexpr bool + operator==(const NotSimpleViewIterBegin&, const NotSimpleViewConstIterBegin&) { + return true; + } +}; template struct NotSimpleViewConstIterBegin : InputIterBase> { @@ -33,9 +50,31 @@ struct NotSimpleViewConstIterBegin : InputIterBase&, const NotSimpleViewIterEnd&) { + return true; + } + friend constexpr bool + operator==(const NotSimpleViewConstIterBegin&, const NotSimpleViewIterBegin&) { + return true; + } }; -struct NotSimpleViewIterEnd : InputIterBase {}; +struct NotSimpleViewIterEnd : InputIterBase { + template + friend constexpr bool + operator==(const NotSimpleViewIterEnd&, const NotSimpleViewConstIterBegin&) { + return true; + } + template + friend constexpr bool + operator==(const NotSimpleViewIterEnd&, const NotSimpleViewConstIterEnd&) { + return true; + } + + friend constexpr bool operator==(const NotSimpleViewIterEnd&, const NotSimpleViewIterBegin&) { return true; } +}; template struct NotSimpleViewConstIterEnd : InputIterBase> { @@ -51,52 +90,16 @@ struct NotSimpleViewConstIterEnd : InputIterBase -constexpr bool -operator==(const NotSimpleViewConstIterBegin&, const NotSimpleViewIterEnd&) { - return true; -} -template -constexpr bool -operator==(const NotSimpleViewConstIterBegin&, const NotSimpleViewIterBegin&) { - return true; -} -template -constexpr bool -operator==(const NotSimpleViewIterBegin&, const NotSimpleViewConstIterEnd&) { - return true; -} -template -constexpr bool -operator==(const NotSimpleViewIterBegin&, const NotSimpleViewConstIterBegin&) { - return true; -} -template -constexpr bool -operator==(const NotSimpleViewConstIterEnd&, const NotSimpleViewIterEnd&) { - return true; -} -template -constexpr bool -operator==(const NotSimpleViewConstIterEnd&, const NotSimpleViewIterBegin&) { - return true; -} -template -constexpr bool -operator==(const NotSimpleViewIterEnd&, const NotSimpleViewConstIterBegin&) { - return true; -} -template -constexpr bool -operator==(const NotSimpleViewIterEnd&, const NotSimpleViewConstIterEnd&) { - return true; -} + friend constexpr bool + operator==(const NotSimpleViewConstIterEnd&, const NotSimpleViewIterEnd&) { + return true; + } + friend constexpr bool + operator==(const NotSimpleViewConstIterEnd&, const NotSimpleViewIterBegin&) { + return true; + } +}; /* * Goal: We will need a way to get a stride_view::__iterator and a @@ -151,8 +154,8 @@ constexpr bool non_const_iterator_copy_ctor() { // 2. std::ranges::iterator_t base's type is NotSimpleViewBeingStridedConstIterator // 3. NotSimpleViewBeingStridedIterator is ONLY move-convertible to NotSimpleViewBeingStridedConstIterator // 4. std::ranges::sentinel_t are the same whether SV is const or not. - // 4. the type of StrideView::end is the same whether StrideView is const or not. - // 5. the type of StrideView::begin is stride_view::iterator when StrideView is const and + // 5. the type of StrideView::end is the same whether StrideView is const or not. + // 6. the type of StrideView::begin is stride_view::iterator when StrideView is const and // stride_view::iterator when StrideView is non const. // Visually, it looks like this: // diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp index a116141f942df..1900c04752271 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp @@ -9,6 +9,7 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 // std::views::stride_view +// TODO #include #include @@ -25,10 +26,11 @@ constexpr void testOne() { // simple test { int buffer[] = {0, 1, 2, -1, 4, 5, 6, 7}; - Range input(Iter{buffer}, Iter{buffer + 8}); - StrideView sv(input, 1); - StrideView sv_too(input, 2); - auto b = sv.begin(), e = sv.end(); + const Range input(Iter{buffer}, Iter{buffer + 8}); + const StrideView sv(input, 1); + const StrideView sv_too(input, 2); + auto b = sv.begin(); + auto e = sv.end(); auto b_too = sv_too.begin(); assert(b == b); @@ -59,10 +61,11 @@ constexpr void testOne() { // Default-constructed iterators compare equal. { int buffer[] = {0, 1, 2, -1, 4, 5, 6}; - Range input(Iter{buffer}, Iter{buffer + 7}); - std::ranges::stride_view sv(input, 1); + const Range input(Iter{buffer}, Iter{buffer + 7}); + const std::ranges::stride_view sv(input, 1); using StrideViewIter = decltype(sv.begin()); - StrideViewIter i1, i2; + StrideViewIter i1; + StrideViewIter i2; assert(i1 == i2); assert(!(i1 != i2)); } @@ -74,7 +77,7 @@ constexpr bool test() { //testOne>(); //testOne>(); //testOne>(); - testOne(); + //testOne(); return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index 2436ff3b5ebc6..be190f1336c94 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -305,28 +305,28 @@ constexpr bool test_properly_handling_missing() { auto strider_iter = strider.end(); - strider_iter--; + (void)strider_iter--; assert(*strider_iter == 8); // Now that we are back among the valid, we should // have a normal stride length back (i.e., __missing_ // should be equal to 0). - strider_iter--; + (void)strider_iter--; assert(*strider_iter == 1); - strider_iter++; + (void)strider_iter++; assert(*strider_iter == 8); // By striding past the end, we are going to generate // another __missing_ != 0 value. Let's make sure // that it gets generated and used. - strider_iter++; + (void)strider_iter++; assert(strider_iter == strider.end()); - strider_iter--; + (void)strider_iter--; assert(*strider_iter == 8); - strider_iter--; + (void)strider_iter--; assert(*strider_iter == 1); return true; } From e3512cbf63cd8fca05f1f7e1f37f0e07db25fdab Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 3 Jan 2024 02:50:50 -0500 Subject: [PATCH 090/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Remove SizedForwardIterator. --- .../range.stride.view/adaptor.pass.cpp | 11 ++- .../range.stride.view/iterator/begin.pass.cpp | 78 ------------------- .../iterator/operator.pass.cpp | 19 ++--- .../range.adaptors/range.stride.view/types.h | 33 -------- 4 files changed, 14 insertions(+), 127 deletions(-) delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index 5d8bb73c366bb..352dfcc995eec 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -29,7 +29,10 @@ constexpr BasicTestView> make_input_view(int* begin, using ForwardStrideView = std::ranges::stride_view>>; using BidirStrideView = std::ranges::stride_view>>; using RandomAccessStrideView = std::ranges::stride_view>>; -using SizedForwardStrideView = std::ranges::stride_view>; + +using SizedForwardStrideView = + std::ranges::stride_view, random_access_iterator>>; +using SizedInputStrideView = std::ranges::stride_view>; static_assert(std::ranges::forward_range); static_assert(std::ranges::bidirectional_range); @@ -37,6 +40,8 @@ static_assert(std::ranges::random_access_range); static_assert(std::ranges::forward_range); static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); +static_assert(std::sized_sentinel_for, + std::ranges::iterator_t>); constexpr bool test() { constexpr int N = 3; @@ -92,8 +97,8 @@ constexpr bool test() { } { - using View = BasicTestView; - auto view = View(SizedForwardIterator(arr), SizedForwardIterator(arr + N)); + using View = BasicTestView; + auto view = View(arr, arr + N); std::same_as> decltype(auto) strided = view | std::views::stride(1); auto strided_iter = strided.begin(); auto strided_iter_next = strided_iter; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp deleted file mode 100644 index a4c7a567c2119..0000000000000 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/begin.pass.cpp +++ /dev/null @@ -1,78 +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, c++20 - -// std::views::stride_view::iterator - -#include -#include - -#include "../types.h" -#include "__iterator/concepts.h" -#include "test_iterators.h" - -constexpr bool iterator_concept_test() { - { - int arr[] = {1, 2, 3}; - // Iterator of stride over random access view should have random access concept. - auto rav = - BasicTestView>(random_access_iterator(arr), random_access_iterator(arr + 3)); - auto str = std::ranges::stride_view>>(rav, 1); - static_assert(std::random_access_iterator); - static_assert(std::random_access_iterator); - } - - { - int arr[] = {1, 2, 3}; - // Iterator of stride over bidirectional view should have bidirectional view concept. - auto rav = - BasicTestView>(bidirectional_iterator(arr), bidirectional_iterator(arr + 3)); - auto str = std::ranges::stride_view>>(rav, 1); - static_assert(std::bidirectional_iterator); - static_assert(std::bidirectional_iterator); - static_assert(!std::random_access_iterator); - static_assert(!std::random_access_iterator); - } - - { - int arr[] = {1, 2, 3}; - // Iterator of stride over forward view should have forward view concept. - auto rav = BasicTestView>(forward_iterator(arr), forward_iterator(arr + 3)); - auto str = std::ranges::stride_view>>(rav, 1); - static_assert(std::forward_iterator); - static_assert(std::forward_iterator); - static_assert(!std::bidirectional_iterator); - static_assert(!std::bidirectional_iterator); - static_assert(!std::random_access_iterator); - static_assert(!std::random_access_iterator); - } - - { - int arr[] = {1, 2, 3}; - // Iterator of stride over input view should have input view concept. - auto rav = BasicTestView>(cpp17_input_iterator(arr), cpp17_input_iterator(arr + 3)); - auto str = std::ranges::stride_view>>(rav, 1); - static_assert(std::input_iterator); - static_assert(std::input_iterator); - static_assert(!std::forward_iterator); - static_assert(!std::forward_iterator); - static_assert(!std::bidirectional_iterator); - static_assert(!std::bidirectional_iterator); - static_assert(!std::random_access_iterator); - static_assert(!std::random_access_iterator); - } - return true; -} - -int main(int, char**) { - iterator_concept_test(); - static_assert(iterator_concept_test()); - - return 0; -} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index be190f1336c94..0ef77effdf6c4 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -25,6 +25,7 @@ #include #include +#include #include "../types.h" #include "__ranges/concepts.h" @@ -233,28 +234,20 @@ constexpr bool test_non_forward_operator_minus() { } constexpr bool test_forward_operator_minus() { - using Base = BasicTestView; // Test the forward-range operator- between two iterators (i.e., no ceil). + using Base = BasicTestView; int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // First, what operators are valid for an iterator derived from a stride view - // over a sized forward view. + // over a sized forward view (even though it is actually much more than that!). using StrideViewIterator = std::ranges::iterator_t>; static_assert(is_plus_plusable_post); static_assert(is_plus_plusable_pre); - static_assert(!is_minus_minusable_post); - static_assert(!is_minus_minusable_pre); - static_assert(!is_plus_equalable); - static_assert(!is_minus_equalable); static_assert(is_iterator_minusable); - static_assert(!is_difference_plusable); - static_assert(!is_difference_minusable); - static_assert(!is_relationally_comparable); - static_assert(!is_indexable); - auto rav_zero = Base(SizedForwardIterator(arr), SizedForwardIterator(arr + 10)); - auto rav_one = Base(SizedForwardIterator(arr + 1), SizedForwardIterator(arr + 10)); + auto rav_zero = Base(arr, arr + 10); + auto rav_one = Base(arr + 1, arr + 10); auto stride_zoff = std::ranges::stride_view(rav_zero, 3); auto stride_ooff = std::ranges::stride_view(rav_one, 3); @@ -270,7 +263,7 @@ constexpr bool test_forward_operator_minus() { static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); static_assert(can_calculate_distance_between_non_sentinel); - static_assert(std::forward_iterator); + static_assert(std::forward_iterator>); assert(*stride_zoff_one == 1); assert(*stride_zoff_four == 4); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index ce213b8b416dd..44ce51a3e6d61 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -114,39 +114,6 @@ struct SizedInputIterator { static_assert(std::input_iterator); static_assert(std::sized_sentinel_for); -struct SizedForwardIterator { - using iterator_concept = std::forward_iterator_tag; - using value_type = int; - using difference_type = std::intptr_t; - - int* __v_ = nullptr; - - constexpr SizedForwardIterator() = default; - constexpr SizedForwardIterator(int* v) { __v_ = v; } - constexpr SizedForwardIterator(const SizedForwardIterator& sii) = default; - constexpr SizedForwardIterator& operator=(const SizedForwardIterator&) = default; - constexpr SizedForwardIterator& operator=(SizedForwardIterator&&) = default; - - constexpr int operator*() const { return *__v_; } - constexpr SizedForwardIterator& operator++() { - __v_++; - return *this; - } - constexpr SizedForwardIterator operator++(int) { - auto nv = __v_; - nv++; - return SizedForwardIterator(nv); - } - friend constexpr bool operator==(const SizedForwardIterator& left, const SizedForwardIterator& right) { - return left.__v_ == right.__v_; - } - friend constexpr difference_type operator-(const SizedForwardIterator& left, const SizedForwardIterator& right) { - return left.__v_ - right.__v_; - } -}; -static_assert(std::input_iterator); -static_assert(std::sized_sentinel_for); - template struct MaybeExceptIterSwapIterator : InputIterBase> { int* counter_{nullptr}; From 749572fe3d509b8ffcb3c3c8170182ed192b7207 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Thu, 4 Jan 2024 11:41:56 -0500 Subject: [PATCH 091/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Refactor iter_swap and iter_move tests. --- .../iterator/iter_move.pass.cpp | 4 +- .../iterator/iter_swap.pass.cpp | 7 +- .../range.adaptors/range.stride.view/types.h | 65 ++++++++++--------- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp index bc96588db4577..54defff1696d7 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp @@ -21,7 +21,7 @@ concept iter_moveable = requires(T&& t) { std::ranges::iter_move(t); }; constexpr bool test() { { int iter_move_counter(0); - using View = IterSwapRange; + using View = IterMoveIterSwapTestRange; using StrideView = std::ranges::stride_view; auto svb = StrideView(View(&iter_move_counter), 1).begin(); @@ -35,7 +35,7 @@ constexpr bool test() { { int iter_move_counter(0); - using View = IterSwapRange; + using View = IterMoveIterSwapTestRange; using StrideView = std::ranges::stride_view; auto svb = StrideView(View(&iter_move_counter), 1).begin(); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp index 959512891fa98..aebbbbe728c4a 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp @@ -15,7 +15,6 @@ #include #include "../types.h" -#include "__ranges/concepts.h" template concept swappable = requires(T&& t, T&& u) { std::ranges::iter_swap(t, u); }; @@ -24,7 +23,7 @@ constexpr bool test() { { int iter_move_counter_one(0); int iter_move_counter_two(0); - using View = IterSwapRange; + using View = IterMoveIterSwapTestRange; using StrideView = std::ranges::stride_view; auto svba = StrideView(View(&iter_move_counter_one), 1).begin(); auto svbb = StrideView(View(&iter_move_counter_two), 1).begin(); @@ -40,7 +39,7 @@ constexpr bool test() { { int iter_move_counter_one(0); int iter_move_counter_two(0); - using View = IterSwapRange; + using View = IterMoveIterSwapTestRange; using StrideView = std::ranges::stride_view; auto svba = StrideView(View(&iter_move_counter_one), 1).begin(); auto svbb = StrideView(View(&iter_move_counter_two), 1).begin(); @@ -54,7 +53,7 @@ constexpr bool test() { } { - using View = IterSwapRange; + using View = IterMoveIterSwapTestRange; using StrideView = std::ranges::stride_view; static_assert(!swappable>); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index 44ce51a3e6d61..b25609307b11e 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -114,37 +114,44 @@ struct SizedInputIterator { static_assert(std::input_iterator); static_assert(std::sized_sentinel_for); -template -struct MaybeExceptIterSwapIterator : InputIterBase> { +// Put IterMoveIterSwapTestRangeIterator in a namespace to test ADL of CPOs iter_swap and iter_move +// (see iter_swap.pass.cpp and iter_move.pass.cpp). +namespace adl { +template +struct IterMoveIterSwapTestRangeIterator : InputIterBase> { int* counter_{nullptr}; - constexpr MaybeExceptIterSwapIterator() = default; - constexpr MaybeExceptIterSwapIterator(const MaybeExceptIterSwapIterator&) = default; - constexpr MaybeExceptIterSwapIterator(MaybeExceptIterSwapIterator&&) = default; - constexpr MaybeExceptIterSwapIterator& operator=(const MaybeExceptIterSwapIterator& other) = default; - constexpr MaybeExceptIterSwapIterator& operator=(MaybeExceptIterSwapIterator&& other) = default; + constexpr IterMoveIterSwapTestRangeIterator() = default; + constexpr IterMoveIterSwapTestRangeIterator(const IterMoveIterSwapTestRangeIterator&) = default; + constexpr IterMoveIterSwapTestRangeIterator(IterMoveIterSwapTestRangeIterator&&) = default; + constexpr IterMoveIterSwapTestRangeIterator& operator=(const IterMoveIterSwapTestRangeIterator& other) = default; + constexpr IterMoveIterSwapTestRangeIterator& operator=(IterMoveIterSwapTestRangeIterator&& other) = default; - constexpr explicit MaybeExceptIterSwapIterator(int* counter) : counter_(counter) {} + constexpr explicit IterMoveIterSwapTestRangeIterator(int* counter) : counter_(counter) {} - friend constexpr void iter_swap(const MaybeExceptIterSwapIterator& t, const MaybeExceptIterSwapIterator& u) noexcept - requires Swappable && NoExcept + friend constexpr void + iter_swap(const IterMoveIterSwapTestRangeIterator& t, const IterMoveIterSwapTestRangeIterator& u) noexcept + requires IsSwappable && IsNoExcept { (*t.counter_)++; (*u.counter_)++; } - friend constexpr void iter_swap(const MaybeExceptIterSwapIterator& t, const MaybeExceptIterSwapIterator& u) - requires Swappable && (!NoExcept) + friend constexpr void + iter_swap(const IterMoveIterSwapTestRangeIterator& t, const IterMoveIterSwapTestRangeIterator& u) + requires IsSwappable && (!IsNoExcept) { (*t.counter_)++; (*u.counter_)++; } - friend constexpr int iter_move(const MaybeExceptIterSwapIterator& t) { + friend constexpr int iter_move(const IterMoveIterSwapTestRangeIterator& t) + requires(!IsNoExcept) + { (*t.counter_)++; return 5; } - friend constexpr int iter_move(const MaybeExceptIterSwapIterator& t) noexcept - requires NoExcept + friend constexpr int iter_move(const IterMoveIterSwapTestRangeIterator& t) noexcept + requires IsNoExcept { (*t.counter_)++; return 5; @@ -152,23 +159,17 @@ struct MaybeExceptIterSwapIterator : InputIterBase -struct IterSwapRange : std::ranges::view_base { - MaybeExceptIterSwapIterator begin_; - MaybeExceptIterSwapIterator end_; - constexpr IterSwapRange(int* counter) - : begin_(MaybeExceptIterSwapIterator(counter)), - end_(MaybeExceptIterSwapIterator(counter)) {} - constexpr MaybeExceptIterSwapIterator begin() const { return begin_; } - constexpr MaybeExceptIterSwapIterator end() const { return end_; } -}; - -// Concepts - -template D> -concept CanStrideView = requires { - std::ranges::stride_view{I{}, D}; +} // namespace adl + +template +struct IterMoveIterSwapTestRange : std::ranges::view_base { + adl::IterMoveIterSwapTestRangeIterator begin_; + adl::IterMoveIterSwapTestRangeIterator end_; + constexpr IterMoveIterSwapTestRange(int* counter) + : begin_(adl::IterMoveIterSwapTestRangeIterator(counter)), + end_(adl::IterMoveIterSwapTestRangeIterator(counter)) {} + constexpr adl::IterMoveIterSwapTestRangeIterator begin() const { return begin_; } + constexpr adl::IterMoveIterSwapTestRangeIterator end() const { return end_; } }; // Views From e7660cd9534ac36f23437490efdd9b8a1e148a3d Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Thu, 4 Jan 2024 18:30:58 -0500 Subject: [PATCH 092/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Remove [[nodiscard]] attribute from postfix operators. --- libcxx/include/__ranges/stride_view.h | 4 ++-- .../range.stride.view/concept.verify.cpp | 5 +++++ .../range.stride.view/iterator/operator.pass.cpp | 12 ++++++------ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 4dcee437c7d3a..11078e8c26316 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -212,7 +212,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> } _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) + _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) requires forward_range<_Base> { auto __tmp = *this; @@ -227,7 +227,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> __missing_ = 0; return *this; } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int) + _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int) requires bidirectional_range<_Base> { auto __tmp = *this; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp index 6cbbd1d40015d..527651b66fb64 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp @@ -17,6 +17,11 @@ #include "test_range.h" #include "types.h" +template D> +concept CanStrideView = requires { + std::ranges::stride_view{I{}, D}; +}; + // Ensure that the InputRangeNotIndirectlyReadable is a valid range. static_assert(std::ranges::range); // Ensure that the InputRangeNotIndirectlyReadable's is not an input range ... diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index 0ef77effdf6c4..f2889580f7a89 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -298,28 +298,28 @@ constexpr bool test_properly_handling_missing() { auto strider_iter = strider.end(); - (void)strider_iter--; + strider_iter--; assert(*strider_iter == 8); // Now that we are back among the valid, we should // have a normal stride length back (i.e., __missing_ // should be equal to 0). - (void)strider_iter--; + strider_iter--; assert(*strider_iter == 1); - (void)strider_iter++; + strider_iter++; assert(*strider_iter == 8); // By striding past the end, we are going to generate // another __missing_ != 0 value. Let's make sure // that it gets generated and used. - (void)strider_iter++; + strider_iter++; assert(strider_iter == strider.end()); - (void)strider_iter--; + strider_iter--; assert(*strider_iter == 8); - (void)strider_iter--; + strider_iter--; assert(*strider_iter == 1); return true; } From 7d237e0fa90186292f5f91870faccdf31b7d6b56 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 5 Jan 2024 00:44:26 -0500 Subject: [PATCH 093/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. More iterator type refactoring. --- .../iterator/ctor.copy.pass.cpp | 17 +- .../iterator/iter_move.pass.cpp | 52 +++++- .../iterator/iter_swap.pass.cpp | 32 +++- .../range.stride.view/size.verify.cpp | 2 +- .../range.adaptors/range.stride.view/types.h | 159 +++++++++--------- 5 files changed, 157 insertions(+), 105 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp index 716a8ade50328..ad5489a526f84 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp @@ -12,6 +12,7 @@ // requires _Const && convertible_to, iterator_t<_Base>> && // convertible_to, sentinel_t<_Base>> +#include #include #include "../types.h" @@ -38,10 +39,10 @@ struct NotSimpleViewIterBegin : InputIterBase { template struct NotSimpleViewConstIterBegin : InputIterBase> { - constexpr NotSimpleViewConstIterBegin() = default; - constexpr NotSimpleViewConstIterBegin(NotSimpleViewConstIterBegin&&) {} - constexpr NotSimpleViewConstIterBegin& operator=(const NotSimpleViewConstIterBegin&) {} - constexpr NotSimpleViewConstIterBegin& operator=(NotSimpleViewConstIterBegin&&) {} + constexpr NotSimpleViewConstIterBegin() = default; + constexpr NotSimpleViewConstIterBegin(NotSimpleViewConstIterBegin&&) = default; + constexpr NotSimpleViewConstIterBegin& operator=(const NotSimpleViewConstIterBegin&) = default; + constexpr NotSimpleViewConstIterBegin& operator=(NotSimpleViewConstIterBegin&&) = default; constexpr NotSimpleViewConstIterBegin(const NotSimpleViewConstIterBegin&) {} constexpr NotSimpleViewConstIterBegin(const NotSimpleViewIterBegin&) @@ -78,10 +79,10 @@ struct NotSimpleViewIterEnd : InputIterBase { template struct NotSimpleViewConstIterEnd : InputIterBase> { - constexpr NotSimpleViewConstIterEnd() = default; - constexpr NotSimpleViewConstIterEnd(NotSimpleViewConstIterEnd&&) {} - constexpr NotSimpleViewConstIterEnd& operator=(const NotSimpleViewConstIterEnd&) {} - constexpr NotSimpleViewConstIterEnd& operator=(NotSimpleViewConstIterEnd&&) {} + constexpr NotSimpleViewConstIterEnd() = default; + constexpr NotSimpleViewConstIterEnd(NotSimpleViewConstIterEnd&&) = default; + constexpr NotSimpleViewConstIterEnd& operator=(const NotSimpleViewConstIterEnd&) = default; + constexpr NotSimpleViewConstIterEnd& operator=(NotSimpleViewConstIterEnd&&) = default; constexpr NotSimpleViewConstIterEnd(const NotSimpleViewConstIterEnd&) {} constexpr NotSimpleViewConstIterEnd(const NotSimpleViewIterEnd&) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp index 54defff1696d7..3dd4bb90d35f0 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp @@ -12,40 +12,80 @@ // noexcept(noexcept(ranges::iter_move(__it.__current_))) #include +#include #include "../types.h" +#include "__ranges/access.h" template concept iter_moveable = requires(T&& t) { std::ranges::iter_move(t); }; constexpr bool test() { { + int a[] = {4, 3, 2, 1}; + int iter_move_counter(0); - using View = IterMoveIterSwapTestRange; + using View = IterMoveIterSwapTestRange; using StrideView = std::ranges::stride_view; - auto svb = StrideView(View(&iter_move_counter), 1).begin(); + auto svb = StrideView(View(a, a + 4, &iter_move_counter), 1).begin(); static_assert(iter_moveable>); static_assert(std::is_same_v); static_assert(noexcept(std::ranges::iter_move(svb))); - [[maybe_unused]] auto&& result = std::ranges::iter_move(svb); + auto&& result = std::ranges::iter_move(svb); assert(iter_move_counter == 1); + assert(result == 4); + + svb++; + result = std::ranges::iter_move(svb); + assert(iter_move_counter == 2); + assert(result == 3); } { + int a[] = {1, 2, 3, 4}; + int iter_move_counter(0); - using View = IterMoveIterSwapTestRange; + using View = IterMoveIterSwapTestRange; using StrideView = std::ranges::stride_view; - auto svb = StrideView(View(&iter_move_counter), 1).begin(); + auto svb = StrideView(View(a, a + 4, &iter_move_counter), 1).begin(); static_assert(iter_moveable>); static_assert(std::is_same_v); static_assert(!noexcept(std::ranges::iter_move(svb))); - [[maybe_unused]] auto&& result = std::ranges::iter_move(svb); + auto&& result = std::ranges::iter_move(svb); assert(iter_move_counter == 1); + assert(result == 1); + + svb++; + result = std::ranges::iter_move(svb); + assert(iter_move_counter == 2); + assert(result == 2); } + + { + std::vector a = {4, 5, 6, 7, 8}; + + int iter_move_counter(0); + using View = IterMoveIterSwapTestRange::iterator, true, false>; + + using StrideView = std::ranges::stride_view; + auto svb = StrideView(View(a.begin(), a.end(), &iter_move_counter), 1).begin(); + + static_assert(!noexcept(std::ranges::iter_move(svb))); + + auto&& result = std::ranges::iter_move(svb); + assert(iter_move_counter == 1); + assert(result == 4); + + svb++; + result = std::ranges::iter_move(svb); + assert(iter_move_counter == 2); + assert(result == 5); + } + return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp index aebbbbe728c4a..238cb3568cb2f 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp @@ -21,39 +21,57 @@ concept swappable = requires(T&& t, T&& u) { std::ranges::iter_swap(t, u); }; constexpr bool test() { { + int a[] = {1, 2, 3, 4}; + int b[] = {5, 6, 7, 8}; + int iter_move_counter_one(0); int iter_move_counter_two(0); - using View = IterMoveIterSwapTestRange; + using View = IterMoveIterSwapTestRange; using StrideView = std::ranges::stride_view; - auto svba = StrideView(View(&iter_move_counter_one), 1).begin(); - auto svbb = StrideView(View(&iter_move_counter_two), 1).begin(); + auto svba = StrideView(View(a, a + 4, &iter_move_counter_one), 1).begin(); + auto svbb = StrideView(View(b, b + 4, &iter_move_counter_two), 1).begin(); static_assert(swappable>); static_assert(noexcept(std::ranges::iter_swap(svba, svbb))); + assert(a[0] == 1); + assert(b[0] == 5); + std::ranges::iter_swap(svba, svbb); + assert(iter_move_counter_one == 1); assert(iter_move_counter_two == 1); + assert(a[0] == 5); + assert(b[0] == 1); } { + int a[] = {1, 2, 3, 4}; + int b[] = {5, 6, 7, 8}; + int iter_move_counter_one(0); int iter_move_counter_two(0); - using View = IterMoveIterSwapTestRange; + using View = IterMoveIterSwapTestRange; using StrideView = std::ranges::stride_view; - auto svba = StrideView(View(&iter_move_counter_one), 1).begin(); - auto svbb = StrideView(View(&iter_move_counter_two), 1).begin(); + auto svba = StrideView(View(a, a + 4, &iter_move_counter_one), 1).begin(); + auto svbb = StrideView(View(b, b + 4, &iter_move_counter_two), 1).begin(); static_assert(swappable>); static_assert(!noexcept(std::ranges::iter_swap(svba, svbb))); + assert(a[0] == 1); + assert(b[0] == 5); + std::ranges::iter_swap(svba, svbb); + assert(iter_move_counter_one == 1); assert(iter_move_counter_two == 1); + assert(a[0] == 5); + assert(b[0] == 1); } { - using View = IterMoveIterSwapTestRange; + using View = IterMoveIterSwapTestRange; using StrideView = std::ranges::stride_view; static_assert(!swappable>); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp index 95ee761e98726..73d2ac1ac62be 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp @@ -11,7 +11,6 @@ // constexpr auto size() -#include #include #include "types.h" @@ -43,6 +42,7 @@ constexpr bool test() { } int main(int, char**) { + test(); static_assert(test()); return 0; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index b25609307b11e..df18e971cec50 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -28,37 +28,45 @@ #include #include -// Iterators - -template -struct ForwardIterBase { - using iterator_concept = std::forward_iterator_tag; - using value_type = int; - using difference_type = std::intptr_t; - - constexpr int operator*() const { return 5; } - - constexpr Derived& operator++() { return static_cast(*this); } - constexpr Derived operator++(int) { return {}; } - - friend constexpr bool operator==(const ForwardIterBase&, const ForwardIterBase&) { return true; } - friend constexpr bool operator==(const std::default_sentinel_t&, const ForwardIterBase&) { return true; } - friend constexpr bool operator==(const ForwardIterBase&, const std::default_sentinel_t&) { return true; } -}; - -template +template struct InputIterBase { using iterator_concept = std::input_iterator_tag; - using value_type = int; - using difference_type = std::intptr_t; - - constexpr int operator*() const { return 5; } - - constexpr Derived& operator++() { return static_cast(*this); } - constexpr Derived operator++(int) { return {}; } + using value_type = typename std::iterator_traits::value_type; + using difference_type = typename std::iterator_traits::difference_type; + + Iter value_{}; + + constexpr InputIterBase() = default; + constexpr InputIterBase(const InputIterBase&) = default; + constexpr InputIterBase(InputIterBase&&) = default; + constexpr InputIterBase& operator=(const InputIterBase& other) = default; + constexpr InputIterBase& operator=(InputIterBase&& other) = default; + constexpr explicit InputIterBase(Iter value) : value_(value) {} + + constexpr value_type operator*() const { return *value_; } + constexpr Derived& operator++() { + value_++; + return static_cast(*this); + } + constexpr Derived operator++(int) { + auto nv = *this; + value_++; + return nv; + } + friend constexpr bool operator==(const Derived& left, const Derived& right) { return left.value_ == right.value_; } + friend constexpr difference_type operator-(const Derived& left, const Derived& right) + requires Sized + { + return left.value_ - right.value_; + } +}; - friend constexpr bool operator==(const Derived&, const Derived&) { return true; } +struct UnsizedBasicRangeIterator : InputIterBase {}; +struct SizedInputIterator : InputIterBase { + using InputIterBase::InputIterBase; }; +static_assert(std::input_iterator); +static_assert(std::sized_sentinel_for); // Don't move/hold the iterator itself, copy/hold the base // of that iterator and reconstruct the iterator on demand. @@ -79,46 +87,12 @@ struct ViewOverNonCopyableIterator : std::ranges::view_base { decltype(base(std::declval())) sent_; }; -struct UnsizedBasicRangeIterator : ForwardIterBase {}; - -struct SizedInputIterator { - using iterator_concept = std::input_iterator_tag; - using value_type = int; - using difference_type = std::intptr_t; - - int* __v_ = nullptr; - - constexpr SizedInputIterator() = default; - constexpr SizedInputIterator(int* v) { __v_ = v; } - constexpr SizedInputIterator(const SizedInputIterator& sii) = default; - constexpr SizedInputIterator& operator=(const SizedInputIterator&) = default; - constexpr SizedInputIterator& operator=(SizedInputIterator&&) = default; - - constexpr int operator*() const { return *__v_; } - constexpr SizedInputIterator& operator++() { - __v_++; - return *this; - } - constexpr SizedInputIterator operator++(int) { - auto nv = __v_; - nv++; - return SizedInputIterator(nv); - } - friend constexpr bool operator==(const SizedInputIterator& left, const SizedInputIterator& right) { - return left.__v_ == right.__v_; - } - friend constexpr difference_type operator-(const SizedInputIterator& left, const SizedInputIterator& right) { - return left.__v_ - right.__v_; - } -}; -static_assert(std::input_iterator); -static_assert(std::sized_sentinel_for); - // Put IterMoveIterSwapTestRangeIterator in a namespace to test ADL of CPOs iter_swap and iter_move // (see iter_swap.pass.cpp and iter_move.pass.cpp). namespace adl { -template -struct IterMoveIterSwapTestRangeIterator : InputIterBase> { +template +struct IterMoveIterSwapTestRangeIterator { + T value_{}; int* counter_{nullptr}; constexpr IterMoveIterSwapTestRangeIterator() = default; constexpr IterMoveIterSwapTestRangeIterator(const IterMoveIterSwapTestRangeIterator&) = default; @@ -126,50 +100,69 @@ struct IterMoveIterSwapTestRangeIterator : InputIterBase::value_type; + using difference_type = typename std::iterator_traits::difference_type; + + constexpr auto operator*() const { return *value_; } + + constexpr IterMoveIterSwapTestRangeIterator& operator++() { + value_++; + return *this; + } + constexpr IterMoveIterSwapTestRangeIterator operator++(int) { + auto tmp = value_; + value_++; + return *this; + } - friend constexpr void - iter_swap(const IterMoveIterSwapTestRangeIterator& t, const IterMoveIterSwapTestRangeIterator& u) noexcept + friend constexpr bool + operator==(const IterMoveIterSwapTestRangeIterator& left, const IterMoveIterSwapTestRangeIterator& right) { + return left.value_ == right.value_; + } + + friend constexpr void iter_swap(IterMoveIterSwapTestRangeIterator t, IterMoveIterSwapTestRangeIterator u) noexcept requires IsSwappable && IsNoExcept { (*t.counter_)++; (*u.counter_)++; + std::swap(*t.value_, *u.value_); } - friend constexpr void - iter_swap(const IterMoveIterSwapTestRangeIterator& t, const IterMoveIterSwapTestRangeIterator& u) + friend constexpr void iter_swap(IterMoveIterSwapTestRangeIterator t, IterMoveIterSwapTestRangeIterator u) requires IsSwappable && (!IsNoExcept) { (*t.counter_)++; (*u.counter_)++; + std::swap(*t.value_, *u.value_); } - friend constexpr int iter_move(const IterMoveIterSwapTestRangeIterator& t) + friend constexpr auto iter_move(const IterMoveIterSwapTestRangeIterator& t) requires(!IsNoExcept) { (*t.counter_)++; - return 5; + return *t.value_; } - friend constexpr int iter_move(const IterMoveIterSwapTestRangeIterator& t) noexcept + friend constexpr auto iter_move(const IterMoveIterSwapTestRangeIterator& t) noexcept requires IsNoExcept { (*t.counter_)++; - return 5; + return *t.value_; } - - constexpr int operator*() const { return 5; } }; } // namespace adl -template +template struct IterMoveIterSwapTestRange : std::ranges::view_base { - adl::IterMoveIterSwapTestRangeIterator begin_; - adl::IterMoveIterSwapTestRangeIterator end_; - constexpr IterMoveIterSwapTestRange(int* counter) - : begin_(adl::IterMoveIterSwapTestRangeIterator(counter)), - end_(adl::IterMoveIterSwapTestRangeIterator(counter)) {} - constexpr adl::IterMoveIterSwapTestRangeIterator begin() const { return begin_; } - constexpr adl::IterMoveIterSwapTestRangeIterator end() const { return end_; } + adl::IterMoveIterSwapTestRangeIterator begin_; + adl::IterMoveIterSwapTestRangeIterator end_; + constexpr IterMoveIterSwapTestRange(const T& begin, const T& end, int* counter) + : begin_(adl::IterMoveIterSwapTestRangeIterator(begin, counter)), + end_(adl::IterMoveIterSwapTestRangeIterator(end, counter)) {} + constexpr adl::IterMoveIterSwapTestRangeIterator begin() const { return begin_; } + constexpr adl::IterMoveIterSwapTestRangeIterator end() const { return end_; } }; // Views From 91070c7ceb413aeb80e27ed029df289a422444bd Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 5 Jan 2024 19:30:40 -0500 Subject: [PATCH 094/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. More refactoring of support types. --- .../iterator/iter_swap.pass.cpp | 2 +- .../range.stride.view/size.verify.cpp | 11 +- .../range.adaptors/range.stride.view/types.h | 105 ++++++++---------- 3 files changed, 56 insertions(+), 62 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp index 238cb3568cb2f..c9b87dfec6ecd 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_swap.pass.cpp @@ -38,9 +38,9 @@ constexpr bool test() { assert(b[0] == 5); std::ranges::iter_swap(svba, svbb); - assert(iter_move_counter_one == 1); assert(iter_move_counter_two == 1); + assert(a[0] == 5); assert(b[0] == 1); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp index 73d2ac1ac62be..0accfc43258c4 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp @@ -13,12 +13,19 @@ #include +#include "__ranges/stride_view.h" +#include "test_iterators.h" #include "types.h" // There is no size member function on a stride view over a view that // is *not* a sized range -static_assert(!std::ranges::sized_range); -static_assert(!std::ranges::sized_range>); +static_assert(!std::ranges::sized_range>>); +static_assert(!std::ranges::sized_range>>>); + +// There is a size member function on a stride view over a view that +// *is* a sized range +static_assert(std::ranges::sized_range, true>>); +static_assert(std::ranges::sized_range, true>>>); constexpr bool test() { { diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index df18e971cec50..d20a78c421109 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -28,7 +28,7 @@ #include #include -template +template struct InputIterBase { using iterator_concept = std::input_iterator_tag; using value_type = typename std::iterator_traits::value_type; @@ -62,7 +62,8 @@ struct InputIterBase { }; struct UnsizedBasicRangeIterator : InputIterBase {}; -struct SizedInputIterator : InputIterBase { + +struct SizedInputIterator : InputIterBase { using InputIterBase::InputIterBase; }; static_assert(std::input_iterator); @@ -91,37 +92,15 @@ struct ViewOverNonCopyableIterator : std::ranges::view_base { // (see iter_swap.pass.cpp and iter_move.pass.cpp). namespace adl { template -struct IterMoveIterSwapTestRangeIterator { - T value_{}; +struct IterMoveIterSwapTestRangeIterator + : InputIterBase, T, false> { int* counter_{nullptr}; - constexpr IterMoveIterSwapTestRangeIterator() = default; - constexpr IterMoveIterSwapTestRangeIterator(const IterMoveIterSwapTestRangeIterator&) = default; - constexpr IterMoveIterSwapTestRangeIterator(IterMoveIterSwapTestRangeIterator&&) = default; - constexpr IterMoveIterSwapTestRangeIterator& operator=(const IterMoveIterSwapTestRangeIterator& other) = default; - constexpr IterMoveIterSwapTestRangeIterator& operator=(IterMoveIterSwapTestRangeIterator&& other) = default; - - constexpr explicit IterMoveIterSwapTestRangeIterator(T value, int* counter) : value_(value), counter_(counter) {} - - using iterator_concept = std::input_iterator_tag; - using value_type = typename std::iterator_traits::value_type; - using difference_type = typename std::iterator_traits::difference_type; - constexpr auto operator*() const { return *value_; } - - constexpr IterMoveIterSwapTestRangeIterator& operator++() { - value_++; - return *this; - } - constexpr IterMoveIterSwapTestRangeIterator operator++(int) { - auto tmp = value_; - value_++; - return *this; - } + using InputIterBase, T, false>::InputIterBase; - friend constexpr bool - operator==(const IterMoveIterSwapTestRangeIterator& left, const IterMoveIterSwapTestRangeIterator& right) { - return left.value_ == right.value_; - } + constexpr IterMoveIterSwapTestRangeIterator(T value, int* counter) + : InputIterBase, T, false>(value), + counter_(counter) {} friend constexpr void iter_swap(IterMoveIterSwapTestRangeIterator t, IterMoveIterSwapTestRangeIterator u) noexcept requires IsSwappable && IsNoExcept @@ -167,44 +146,50 @@ struct IterMoveIterSwapTestRange : std::ranges::view_base { // Views -template S = sentinel_wrapper> -struct MoveOnlyView : std::ranges::view_base { +template S = sentinel_wrapper, bool IsCopyable = true> +struct MaybeCopyableAlwaysMoveableView : std::ranges::view_base { T begin_; T end_; - constexpr explicit MoveOnlyView(T b, T e) : begin_(b), end_(e) {} - - constexpr MoveOnlyView(const MoveOnlyView&) = delete; - constexpr MoveOnlyView(MoveOnlyView&& other) = default; - constexpr MoveOnlyView& operator=(MoveOnlyView&&) = default; - constexpr MoveOnlyView& operator=(const MoveOnlyView&) = delete; - - constexpr T begin() const { return begin_; } - constexpr sentinel_wrapper end() const { return sentinel_wrapper{end_}; } -}; -static_assert(std::ranges::view>>); -static_assert(!std::copyable>>); + constexpr explicit MaybeCopyableAlwaysMoveableView(T b, T e) : begin_(b), end_(e) {} -template S = sentinel_wrapper> -struct CopyableView : std::ranges::view_base { - T begin_; - T end_; + constexpr MaybeCopyableAlwaysMoveableView(MaybeCopyableAlwaysMoveableView&& other) = default; + constexpr MaybeCopyableAlwaysMoveableView& operator=(MaybeCopyableAlwaysMoveableView&&) = default; - constexpr explicit CopyableView(T b, T e) : begin_(b), end_(e) {} + constexpr MaybeCopyableAlwaysMoveableView(const MaybeCopyableAlwaysMoveableView&) + requires(!IsCopyable) + = delete; + constexpr MaybeCopyableAlwaysMoveableView(const MaybeCopyableAlwaysMoveableView&) + requires IsCopyable + = default; - constexpr CopyableView(const CopyableView&) = default; - constexpr CopyableView& operator=(const CopyableView&) = default; + constexpr MaybeCopyableAlwaysMoveableView& operator=(const MaybeCopyableAlwaysMoveableView&) + requires(!IsCopyable) + = delete; + constexpr MaybeCopyableAlwaysMoveableView& operator=(const MaybeCopyableAlwaysMoveableView&) + requires IsCopyable + = default; constexpr T begin() const { return begin_; } constexpr sentinel_wrapper end() const { return sentinel_wrapper{end_}; } }; -static_assert(std::ranges::view>>); -static_assert(std::copyable>>); +static_assert(std::ranges::view>>); + +static_assert(std::copyable>>); +static_assert(!std::copyable, + sentinel_wrapper>, + false>>); + +template S = sentinel_wrapper> +using CopyableView = MaybeCopyableAlwaysMoveableView; template S = sentinel_wrapper> +using MoveOnlyView = MaybeCopyableAlwaysMoveableView; + +template S = sentinel_wrapper, bool IsSized = false> struct BasicTestView : std::ranges::view_base { - T begin_; - T end_; + T begin_{}; + T end_{}; constexpr BasicTestView(T b, T e) : begin_(b), end_(e) {} @@ -212,11 +197,13 @@ struct BasicTestView : std::ranges::view_base { constexpr T begin() const { return begin_; } constexpr S end() { return S{end_}; } constexpr S end() const { return S{end_}; } -}; -struct UnsizedBasicView : std::ranges::view_base { - UnsizedBasicRangeIterator begin() const; - UnsizedBasicRangeIterator end() const; + constexpr auto size() const + requires IsSized + { + return begin_ - end_; + } }; +static_assert(std::ranges::sized_range, true>>); #endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H From d7773a13e46b5dcfcc7ed5eb6533b82a47395c04 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 5 Jan 2024 19:34:10 -0500 Subject: [PATCH 095/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Remove extraneous include files. --- .../range.adaptors/range.stride.view/types.h | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index d20a78c421109..6358985a89bd7 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -9,24 +9,12 @@ #ifndef TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H #define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H -#include "__concepts/equality_comparable.h" -#include "__concepts/movable.h" -#include "__concepts/semiregular.h" -#include "__iterator/concepts.h" -#include "__iterator/default_sentinel.h" -#include "__ranges/access.h" -#include "__ranges/concepts.h" -#include "__ranges/enable_borrowed_range.h" -#include "__ranges/enable_view.h" -#include "__ranges/size.h" -#include "__ranges/stride_view.h" -#include "test_iterators.h" -#include "test_macros.h" -#include "test_range.h" #include #include #include -#include + +#include "test_iterators.h" +#include "test_range.h" template struct InputIterBase { From 0e6d3c74bb5eebbad850887888a678b1bf5eef35 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sat, 6 Jan 2024 03:13:44 -0500 Subject: [PATCH 096/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Another round of types.h cleanup. --- .../iterator/operator.pass.cpp | 3 +- .../range.adaptors/range.stride.view/types.h | 150 ++++++++++-------- 2 files changed, 83 insertions(+), 70 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index f2889580f7a89..57c190f4836a9 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -160,8 +160,7 @@ static_assert(std::three_way_comparable); static_assert(is_three_way_comparable); -using UnEqualableView = - ViewOverNonCopyableIterator, sentinel_wrapper>>; +using UnEqualableView = ViewOverNonCopyableIterator>; using UnEqualableViewStrideView = std::ranges::stride_view; using UnEqualableViewStrideViewIter = std::ranges::iterator_t; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index 6358985a89bd7..edfe039c8cf07 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -13,10 +13,19 @@ #include #include +#include "__iterator/concepts.h" #include "test_iterators.h" #include "test_range.h" -template +// Concepts + +template +concept IterDifferable = requires(Iter& t) { t - t; }; + +// Iterators + +template + requires((!IsSized) || (IsSized && IterDifferable)) struct InputIterBase { using iterator_concept = std::input_iterator_tag; using value_type = typename std::iterator_traits::value_type; @@ -43,13 +52,15 @@ struct InputIterBase { } friend constexpr bool operator==(const Derived& left, const Derived& right) { return left.value_ == right.value_; } friend constexpr difference_type operator-(const Derived& left, const Derived& right) - requires Sized + requires IsSized { return left.value_ - right.value_; } }; -struct UnsizedBasicRangeIterator : InputIterBase {}; +struct UnsizedInputIterator : InputIterBase {}; +static_assert(std::input_iterator); +static_assert(!std::sized_sentinel_for); struct SizedInputIterator : InputIterBase { using InputIterBase::InputIterBase; @@ -57,41 +68,24 @@ struct SizedInputIterator : InputIterBase { static_assert(std::input_iterator); static_assert(std::sized_sentinel_for); -// Don't move/hold the iterator itself, copy/hold the base -// of that iterator and reconstruct the iterator on demand. -// May result in aliasing (if, e.g., Iterator is an iterator -// over int *). -template -struct ViewOverNonCopyableIterator : std::ranges::view_base { - constexpr explicit ViewOverNonCopyableIterator(Iterator it, Sentinel sent) : it_(base(it)), sent_(base(sent)) {} - - ViewOverNonCopyableIterator(ViewOverNonCopyableIterator&&) = default; - ViewOverNonCopyableIterator& operator=(ViewOverNonCopyableIterator&&) = default; - - constexpr Iterator begin() const { return Iterator(it_); } - constexpr Sentinel end() const { return Sentinel(sent_); } - -private: - decltype(base(std::declval())) it_; - decltype(base(std::declval())) sent_; -}; - // Put IterMoveIterSwapTestRangeIterator in a namespace to test ADL of CPOs iter_swap and iter_move // (see iter_swap.pass.cpp and iter_move.pass.cpp). namespace adl { -template +template struct IterMoveIterSwapTestRangeIterator - : InputIterBase, T, false> { + : InputIterBase, Iter, false> { int* counter_{nullptr}; - using InputIterBase, T, false>::InputIterBase; + using InputIterBase, Iter, false>:: + InputIterBase; - constexpr IterMoveIterSwapTestRangeIterator(T value, int* counter) - : InputIterBase, T, false>(value), + constexpr IterMoveIterSwapTestRangeIterator(Iter value, int* counter) + : InputIterBase, Iter, false>( + value), counter_(counter) {} friend constexpr void iter_swap(IterMoveIterSwapTestRangeIterator t, IterMoveIterSwapTestRangeIterator u) noexcept - requires IsSwappable && IsNoExcept + requires IsIterSwappable && IsNoExceptIterMoveable { (*t.counter_)++; (*u.counter_)++; @@ -99,7 +93,7 @@ struct IterMoveIterSwapTestRangeIterator } friend constexpr void iter_swap(IterMoveIterSwapTestRangeIterator t, IterMoveIterSwapTestRangeIterator u) - requires IsSwappable && (!IsNoExcept) + requires IsIterSwappable && (!IsNoExceptIterMoveable) { (*t.counter_)++; (*u.counter_)++; @@ -107,13 +101,13 @@ struct IterMoveIterSwapTestRangeIterator } friend constexpr auto iter_move(const IterMoveIterSwapTestRangeIterator& t) - requires(!IsNoExcept) + requires(!IsNoExceptIterMoveable) { (*t.counter_)++; return *t.value_; } friend constexpr auto iter_move(const IterMoveIterSwapTestRangeIterator& t) noexcept - requires IsNoExcept + requires IsNoExceptIterMoveable { (*t.counter_)++; return *t.value_; @@ -121,25 +115,45 @@ struct IterMoveIterSwapTestRangeIterator }; } // namespace adl -template +template struct IterMoveIterSwapTestRange : std::ranges::view_base { - adl::IterMoveIterSwapTestRangeIterator begin_; - adl::IterMoveIterSwapTestRangeIterator end_; - constexpr IterMoveIterSwapTestRange(const T& begin, const T& end, int* counter) - : begin_(adl::IterMoveIterSwapTestRangeIterator(begin, counter)), - end_(adl::IterMoveIterSwapTestRangeIterator(end, counter)) {} - constexpr adl::IterMoveIterSwapTestRangeIterator begin() const { return begin_; } - constexpr adl::IterMoveIterSwapTestRangeIterator end() const { return end_; } + adl::IterMoveIterSwapTestRangeIterator begin_; + adl::IterMoveIterSwapTestRangeIterator end_; + constexpr IterMoveIterSwapTestRange(const Iter& begin, const Iter& end, int* counter) + : begin_(adl::IterMoveIterSwapTestRangeIterator(begin, counter)), + end_(adl::IterMoveIterSwapTestRangeIterator(end, counter)) {} + constexpr adl::IterMoveIterSwapTestRangeIterator begin() const { return begin_; } + constexpr adl::IterMoveIterSwapTestRangeIterator end() const { return end_; } }; // Views -template S = sentinel_wrapper, bool IsCopyable = true> +template Sent = sentinel_wrapper, bool IsSized = false> + requires((!IsSized) || (IsSized && IterDifferable)) +struct BasicTestView : std::ranges::view_base { + Iter begin_{}; + Iter end_{}; + + constexpr BasicTestView(Iter b, Iter e) : begin_(b), end_(e) {} + + constexpr Iter begin() { return begin_; } + constexpr Iter begin() const { return begin_; } + constexpr Sent end() { return Sent{end_}; } + constexpr Sent end() const { return Sent{end_}; } + + constexpr auto size() const + requires IsSized + { + return begin_ - end_; + } +}; + +template Sent = sentinel_wrapper, bool IsCopyable = true> struct MaybeCopyableAlwaysMoveableView : std::ranges::view_base { - T begin_; - T end_; + Iter begin_; + Iter end_; - constexpr explicit MaybeCopyableAlwaysMoveableView(T b, T e) : begin_(b), end_(e) {} + constexpr explicit MaybeCopyableAlwaysMoveableView(Iter b, Iter e) : begin_(b), end_(e) {} constexpr MaybeCopyableAlwaysMoveableView(MaybeCopyableAlwaysMoveableView&& other) = default; constexpr MaybeCopyableAlwaysMoveableView& operator=(MaybeCopyableAlwaysMoveableView&&) = default; @@ -158,40 +172,40 @@ struct MaybeCopyableAlwaysMoveableView : std::ranges::view_base { requires IsCopyable = default; - constexpr T begin() const { return begin_; } - constexpr sentinel_wrapper end() const { return sentinel_wrapper{end_}; } + constexpr Iter begin() const { return begin_; } + constexpr Sent end() const { return Sent{end_}; } }; static_assert(std::ranges::view>>); +static_assert(std::ranges::view, + sentinel_wrapper>, + false>>); static_assert(std::copyable>>); -static_assert(!std::copyable, - sentinel_wrapper>, - false>>); +template Sent = sentinel_wrapper> +using CopyableView = MaybeCopyableAlwaysMoveableView; +static_assert(std::copyable>>); -template S = sentinel_wrapper> -using CopyableView = MaybeCopyableAlwaysMoveableView; +template Sent = sentinel_wrapper> +using MoveOnlyView = MaybeCopyableAlwaysMoveableView; +static_assert(!std::copyable>>); -template S = sentinel_wrapper> -using MoveOnlyView = MaybeCopyableAlwaysMoveableView; - -template S = sentinel_wrapper, bool IsSized = false> -struct BasicTestView : std::ranges::view_base { - T begin_{}; - T end_{}; +// Don't move/hold the iterator itself, copy/hold the base +// of that iterator and reconstruct the iterator on demand. +// May result in aliasing (if, e.g., Iterator is an iterator +// over int *). +template Sent = sentinel_wrapper> +struct ViewOverNonCopyableIterator : std::ranges::view_base { + constexpr explicit ViewOverNonCopyableIterator(Iter it, Sent sent) : it_(base(it)), sent_(base(sent)) {} - constexpr BasicTestView(T b, T e) : begin_(b), end_(e) {} + ViewOverNonCopyableIterator(ViewOverNonCopyableIterator&&) = default; + ViewOverNonCopyableIterator& operator=(ViewOverNonCopyableIterator&&) = default; - constexpr T begin() { return begin_; } - constexpr T begin() const { return begin_; } - constexpr S end() { return S{end_}; } - constexpr S end() const { return S{end_}; } + constexpr Iter begin() const { return Iter(it_); } + constexpr Sent end() const { return Sent(sent_); } - constexpr auto size() const - requires IsSized - { - return begin_ - end_; - } +private: + decltype(base(std::declval())) it_; + decltype(base(std::declval())) sent_; }; -static_assert(std::ranges::sized_range, true>>); #endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H From 15d06f8fe7b27e02cccf413f1b7e6805b9fafb26 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sat, 6 Jan 2024 19:03:04 -0500 Subject: [PATCH 097/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Use pre-existing concepts in operator tests (and fix a major oversight in actual implementation.. --- libcxx/include/__ranges/stride_view.h | 2 +- .../iterator/operator.pass.cpp | 223 ++++++++++-------- .../range.adaptors/range.stride.view/types.h | 7 +- 3 files changed, 133 insertions(+), 99 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 11078e8c26316..0e4f1945eabc2 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -297,7 +297,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> return !(__x < __y); } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=>(__iterator const& __x, __iterator const& __y) + _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(__iterator const& __x, __iterator const& __y) requires random_access_range<_Base> && three_way_comparable> { return __x.__current_ <=> __y.__current_; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index 57c190f4836a9..d57ab6586ca85 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -23,153 +23,182 @@ // friend constexpr bool operator>=(__iterator const& __x, __iterator const& __y) // friend constexpr bool operator<=>(__iterator const& __x, __iterator const& __y) +#include #include #include #include +#include #include "../types.h" +#include "__compare/three_way_comparable.h" +#include "__concepts/equality_comparable.h" +#include "__iterator/concepts.h" #include "__ranges/concepts.h" #include "__ranges/stride_view.h" #include "test_iterators.h" template -concept is_plus_equalable = requires(T& t) { t += 1; }; +concept CanPlusEqual = std::is_same_v() += 1)> && requires(T& t) { t += 1; }; template -concept is_minus_equalable = requires(T& t) { t -= 1; }; +concept CanMinusEqual = std::is_same_v() -= 1)> && requires(T& t) { t -= 1; }; template -concept is_iterator_minusable = requires(T& t) { t - t; }; -template -concept is_difference_plusable = requires(T& t) { t + 1; }; -template -concept is_difference_minusable = requires(T& t) { t - 1; }; +concept CanMinus = + // Note: Do *not* use std::iterator_traits here because T may not have + // all the required pieces when it is not a forward_range. + std::is_same_v() - std::declval())> && + requires(T& t) { t - t; }; template -concept is_relationally_comparable = requires(T& t) { - t < t; - t > t; - t <= t; - t >= t; -}; - -template -concept is_relationally_equalable = requires(T& t) { t == t; }; - +concept CanDifferencePlus = std::is_same_v() + 1)> && requires(T& t) { t + 1; }; template -concept is_three_way_comparable = requires(T& t) { t <=> t; }; +concept CanDifferenceMinus = std::is_same_v() - 1)> && requires(T& t) { t - 1; }; template -concept is_plus_plusable_post = requires(T& t) { t++; }; -template -concept is_plus_plusable_pre = requires(T& t) { ++t; }; -template -concept is_minus_minusable_post = requires(T& t) { t--; }; -template -concept is_minus_minusable_pre = requires(T& t) { --t; }; - +concept CanPostDecrement = std::is_same_v()--)> && requires(T& t) { t--; }; template -concept is_indexable = requires(T& t) { t[5]; }; +concept CanPreDecrement = std::is_same_v())> && requires(T& t) { --t; }; template -concept can_calculate_distance_between_non_sentinel = requires(T& t) { t - t; }; +concept CanSubscript = requires(T& t) { t[5]; }; // What operators are valid for an iterator derived from a stride view // over an input view. using StrideViewOverInputViewIterator = std::ranges::iterator_t>>>; -static_assert(is_plus_plusable_post); -static_assert(is_plus_plusable_pre); -static_assert(!is_minus_minusable_post); -static_assert(!is_minus_minusable_pre); -static_assert(!is_plus_equalable); -static_assert(!is_minus_equalable); -static_assert(!is_iterator_minusable); -static_assert(!is_difference_plusable); -static_assert(!is_difference_minusable); -static_assert(!is_relationally_comparable); -static_assert(!is_indexable); +static_assert(std::weakly_incrementable); + +static_assert(!CanPostDecrement); +static_assert(!CanPreDecrement); +static_assert(!CanPlusEqual); +static_assert(!CanMinusEqual); +static_assert(!CanMinus); +static_assert(!CanDifferencePlus); +static_assert(!CanDifferenceMinus); + +static_assert(!std::is_invocable_v, StrideViewOverInputViewIterator, StrideViewOverInputViewIterator>); +static_assert( + !std::is_invocable_v, StrideViewOverInputViewIterator, StrideViewOverInputViewIterator>); +static_assert(!std::is_invocable_v, StrideViewOverInputViewIterator, StrideViewOverInputViewIterator>); +static_assert( + !std::is_invocable_v, StrideViewOverInputViewIterator, StrideViewOverInputViewIterator>); + +static_assert(!CanSubscript); // What operators are valid for an iterator derived from a stride view // over a forward view. using ForwardView = BasicTestView>; using StrideViewOverForwardViewIterator = std::ranges::iterator_t>; -static_assert(is_plus_plusable_post); -static_assert(is_plus_plusable_pre); -static_assert(!is_minus_minusable_post); -static_assert(!is_minus_minusable_pre); -static_assert(!is_plus_equalable); -static_assert(!is_minus_equalable); -static_assert(!is_iterator_minusable); -static_assert(!is_difference_plusable); -static_assert(!is_difference_minusable); -static_assert(!is_relationally_comparable); -static_assert(!is_indexable); +static_assert(std::weakly_incrementable); + +static_assert(!CanPostDecrement); +static_assert(!CanPreDecrement); +static_assert(!CanPlusEqual); +static_assert(!CanMinusEqual); +static_assert(!CanMinus); +static_assert(!CanDifferencePlus); +static_assert(!CanDifferenceMinus); + +static_assert(!std::is_invocable_v, StrideViewOverForwardViewIterator, StrideViewOverForwardViewIterator>); +static_assert( + !std::is_invocable_v, StrideViewOverForwardViewIterator, StrideViewOverForwardViewIterator>); +static_assert( + !std::is_invocable_v, StrideViewOverForwardViewIterator, StrideViewOverForwardViewIterator>); +static_assert( + !std::is_invocable_v, StrideViewOverForwardViewIterator, StrideViewOverForwardViewIterator>); + +static_assert(!CanSubscript); // What operators are valid for an iterator derived from a stride view // over a bidirectional view. using BidirectionalView = BasicTestView>; using StrideViewOverBidirectionalViewIterator = std::ranges::iterator_t>; -static_assert(is_plus_plusable_post); -static_assert(is_plus_plusable_pre); -static_assert(is_minus_minusable_post); -static_assert(is_minus_minusable_pre); -static_assert(!is_plus_equalable); -static_assert(!is_minus_equalable); -static_assert(!is_iterator_minusable); -static_assert(!is_difference_plusable); -static_assert(!is_difference_minusable); -static_assert(!is_relationally_comparable); -static_assert(!is_indexable); +static_assert(std::weakly_incrementable); + +static_assert(CanPostDecrement); +static_assert(CanPreDecrement); +static_assert(!CanPlusEqual); +static_assert(!CanMinusEqual); +static_assert(!CanMinus); +static_assert(!CanDifferencePlus); +static_assert(!CanDifferenceMinus); + +static_assert(!std::is_invocable_v, + StrideViewOverBidirectionalViewIterator, + StrideViewOverBidirectionalViewIterator>); +static_assert(!std::is_invocable_v, + StrideViewOverBidirectionalViewIterator, + StrideViewOverBidirectionalViewIterator>); +static_assert(!std::is_invocable_v, + StrideViewOverBidirectionalViewIterator, + StrideViewOverBidirectionalViewIterator>); +static_assert(!std::is_invocable_v, + StrideViewOverBidirectionalViewIterator, + StrideViewOverBidirectionalViewIterator>); + +static_assert(!CanSubscript); // What operators are valid for an iterator derived from a stride view // over a random access view. using RandomAccessView = BasicTestView>; using StrideViewOverRandomAccessViewIterator = std::ranges::iterator_t>; -static_assert(is_plus_plusable_post); -static_assert(is_plus_plusable_pre); -static_assert(is_minus_minusable_post); -static_assert(is_minus_minusable_pre); -static_assert(is_plus_equalable); -static_assert(is_minus_equalable); -static_assert(is_iterator_minusable); -static_assert(is_difference_plusable); -static_assert(is_difference_minusable); -static_assert(is_relationally_comparable); -static_assert(is_indexable); +static_assert(std::weakly_incrementable); + +static_assert(CanPostDecrement); +static_assert(CanPreDecrement); +static_assert(CanPlusEqual); +static_assert(CanMinusEqual); +static_assert(CanMinus); +static_assert(CanDifferencePlus); +static_assert(CanDifferenceMinus); + +static_assert( + std::is_invocable_v, StrideViewOverRandomAccessViewIterator, StrideViewOverRandomAccessViewIterator>); +static_assert(std::is_invocable_v, + StrideViewOverRandomAccessViewIterator, + StrideViewOverRandomAccessViewIterator>); +static_assert(std::is_invocable_v, + StrideViewOverRandomAccessViewIterator, + StrideViewOverRandomAccessViewIterator>); +static_assert(std::is_invocable_v, + StrideViewOverRandomAccessViewIterator, + StrideViewOverRandomAccessViewIterator>); + +static_assert(CanSubscript); using EqualableView = BasicTestView>; using EqualableViewStrideView = std::ranges::stride_view; using EqualableViewStrideViewIter = std::ranges::iterator_t; -static_assert(is_relationally_equalable>); -static_assert(is_relationally_equalable); +static_assert(std::equality_comparable>); +static_assert(std::equality_comparable); static_assert(!std::three_way_comparable>); static_assert(!std::ranges::random_access_range); -static_assert(!is_three_way_comparable); +static_assert(!std::three_way_comparable); -using ThreeWayComparableView = BasicTestView>; +using ThreeWayComparableView = BasicTestView>; using ThreeWayComparableViewStrideView = std::ranges::stride_view; using ThreeWayComparableStrideViewIter = std::ranges::iterator_t; static_assert(std::three_way_comparable>); static_assert(std::ranges::random_access_range); -static_assert(is_three_way_comparable); +static_assert(std::three_way_comparable); using UnEqualableView = ViewOverNonCopyableIterator>; using UnEqualableViewStrideView = std::ranges::stride_view; using UnEqualableViewStrideViewIter = std::ranges::iterator_t; -static_assert(!is_relationally_equalable>); -static_assert(!is_relationally_equalable); +static_assert(!std::equality_comparable>); +static_assert(!std::equality_comparable); static_assert(!std::three_way_comparable>); static_assert(!std::ranges::random_access_range); -static_assert(!is_three_way_comparable); +static_assert(!std::three_way_comparable); constexpr bool test_non_forward_operator_minus() { using Base = BasicTestView; @@ -179,16 +208,20 @@ constexpr bool test_non_forward_operator_minus() { // over a sized input view. using StrideViewIterator = std::ranges::iterator_t>; - static_assert(is_plus_plusable_post); - static_assert(is_plus_plusable_pre); - static_assert(!is_minus_minusable_post); - static_assert(!is_minus_minusable_pre); - static_assert(!is_plus_equalable); - static_assert(!is_minus_equalable); - static_assert(!is_difference_plusable); - static_assert(!is_difference_minusable); - static_assert(!is_relationally_comparable); - static_assert(!is_indexable); + static_assert(std::weakly_incrementable); + + static_assert(!CanPostDecrement); + static_assert(!CanPreDecrement); + static_assert(!CanPlusEqual); + static_assert(!CanMinusEqual); + static_assert(!CanDifferencePlus); + static_assert(!CanDifferenceMinus); + + static_assert(!std::is_invocable_v, StrideViewIterator, StrideViewIterator>); + static_assert(!std::is_invocable_v, StrideViewIterator, StrideViewIterator>); + static_assert(!std::is_invocable_v, StrideViewIterator, StrideViewIterator>); + static_assert(!std::is_invocable_v, StrideViewIterator, StrideViewIterator>); + static_assert(!CanSubscript); auto rav_zero = Base(SizedInputIterator(arr), SizedInputIterator(arr + 10)); auto rav_one = Base(SizedInputIterator(arr + 1), SizedInputIterator(arr + 10)); @@ -206,7 +239,7 @@ constexpr bool test_non_forward_operator_minus() { auto stride_ooff_five = ++stride_ooff_begin; static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); - static_assert(can_calculate_distance_between_non_sentinel); + static_assert(CanMinus); assert(*stride_zoff_one == 1); assert(*stride_zoff_four == 4); @@ -241,9 +274,9 @@ constexpr bool test_forward_operator_minus() { // over a sized forward view (even though it is actually much more than that!). using StrideViewIterator = std::ranges::iterator_t>; - static_assert(is_plus_plusable_post); - static_assert(is_plus_plusable_pre); - static_assert(is_iterator_minusable); + static_assert(std::weakly_incrementable); + + static_assert(CanMinus); auto rav_zero = Base(arr, arr + 10); auto rav_one = Base(arr + 1, arr + 10); @@ -261,7 +294,7 @@ constexpr bool test_forward_operator_minus() { auto stride_ooff_five = ++stride_ooff_begin; static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); - static_assert(can_calculate_distance_between_non_sentinel); + static_assert(CanMinus); static_assert(std::forward_iterator>); assert(*stride_zoff_one == 1); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index edfe039c8cf07..240cc43465a26 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -27,9 +27,10 @@ concept IterDifferable = requires(Iter& t) { t - t; }; template requires((!IsSized) || (IsSized && IterDifferable)) struct InputIterBase { - using iterator_concept = std::input_iterator_tag; - using value_type = typename std::iterator_traits::value_type; - using difference_type = typename std::iterator_traits::difference_type; + using iterator_concept = std::input_iterator_tag; + using iterator_category = std::input_iterator_tag; + using value_type = typename std::iterator_traits::value_type; + using difference_type = typename std::iterator_traits::difference_type; Iter value_{}; From 923cc1c7f790bcb60a7a714c9f06deb24ee96b03 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 10 Jan 2024 12:35:28 -0500 Subject: [PATCH 098/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Use simple_view concept from test_range.h. --- .../ranges/range.adaptors/range.stride.view/end.pass.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp index 38399d5b20982..fc25dfa1488ae 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp @@ -69,7 +69,7 @@ static_assert(HasConstAndNonConstEnd constexpr bool test_non_default_sentinel() { { - LIBCPP_STATIC_ASSERT(std::ranges::__simple_view>); + static_assert(simple_view>); static_assert(std::ranges::common_range>); static_assert(std::ranges::sized_range>); static_assert(std::ranges::forward_range>); @@ -80,7 +80,7 @@ constexpr bool test_non_default_sentinel() { } { - LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view); + static_assert(!simple_view); static_assert(std::ranges::common_range); static_assert(std::ranges::sized_range); static_assert(std::ranges::forward_range); @@ -94,7 +94,7 @@ constexpr bool test_non_default_sentinel() { constexpr bool test_default_sentinel() { { - LIBCPP_STATIC_ASSERT(!std::ranges::__simple_view); + static_assert(!simple_view); static_assert(!std::ranges::common_range); static_assert(std::ranges::sized_range); static_assert(std::ranges::forward_range); @@ -105,7 +105,7 @@ constexpr bool test_default_sentinel() { } { - LIBCPP_STATIC_ASSERT(std::ranges::__simple_view); + static_assert(simple_view); static_assert(!std::ranges::common_range); auto v = SimpleUnCommonView{}; From 2fa42772473f88a83c58ef5c731fe901245dc598 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 10 Jan 2024 12:35:55 -0500 Subject: [PATCH 099/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Start to add tests for non-pointer-based iterators. --- .../iterator/operator.pass.cpp | 132 +++++++++--------- 1 file changed, 69 insertions(+), 63 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index d57ab6586ca85..2366c1231ee7d 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -200,10 +200,11 @@ static_assert(!std::three_way_comparable); static_assert(!std::three_way_comparable); -constexpr bool test_non_forward_operator_minus() { - using Base = BasicTestView; +template + requires std::sized_sentinel_for && (!std::forward_iterator) +constexpr bool test_non_forward_operator_minus(Iter zero_begin, Iter one_begin, Iter end) { + using Base = BasicTestView; // Test the non-forward-range operator- between two iterators (i.e., ceil). - int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // First, what operators are valid for an iterator derived from a stride view // over a sized input view. using StrideViewIterator = std::ranges::iterator_t>; @@ -223,101 +224,100 @@ constexpr bool test_non_forward_operator_minus() { static_assert(!std::is_invocable_v, StrideViewIterator, StrideViewIterator>); static_assert(!CanSubscript); - auto rav_zero = Base(SizedInputIterator(arr), SizedInputIterator(arr + 10)); - auto rav_one = Base(SizedInputIterator(arr + 1), SizedInputIterator(arr + 10)); - auto stride_zoff = std::ranges::stride_view(rav_zero, 3); - auto stride_ooff = std::ranges::stride_view(rav_one, 3); + auto base_view_offset_zero = Base(zero_begin, end); + auto base_view_offset_one = Base(one_begin, end); + auto stride_view_over_base_zero_offset = std::ranges::stride_view(base_view_offset_zero, 3); + auto stride_view_over_base_one_offset = std::ranges::stride_view(base_view_offset_one, 3); - auto stride_zoff_begin = stride_zoff.begin(); - auto stride_ooff_begin = stride_ooff.begin(); + auto sv_zero_offset_begin = stride_view_over_base_zero_offset.begin(); + auto sv_one_offset_begin = stride_view_over_base_one_offset.begin(); - auto stride_zoff_one = stride_zoff_begin; - auto stride_zoff_four = ++stride_zoff_begin; - auto stride_zoff_seven = ++stride_zoff_begin; + auto sv_zero_offset_should_be_one = sv_zero_offset_begin; + auto sv_zero_offset_should_be_four = ++sv_zero_offset_begin; + auto sv_zero_offset_should_be_seven = ++sv_zero_offset_begin; - auto stride_ooff_two = stride_ooff_begin; - auto stride_ooff_five = ++stride_ooff_begin; + auto sv_one_offset_should_be_two = sv_one_offset_begin; + auto sv_one_offset_should_be_five = ++sv_one_offset_begin; static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); - static_assert(CanMinus); + static_assert(CanMinus); - assert(*stride_zoff_one == 1); - assert(*stride_zoff_four == 4); - assert(*stride_zoff_seven == 7); + assert(*sv_zero_offset_should_be_one == 1); + assert(*sv_zero_offset_should_be_four == 4); + assert(*sv_zero_offset_should_be_seven == 7); - assert(*stride_ooff_two == 2); - assert(*stride_ooff_five == 5); + assert(*sv_one_offset_should_be_two == 2); + assert(*sv_one_offset_should_be_five == 5); // Check positive __n with exact multiple of left's stride. - assert(stride_zoff_four - stride_zoff_one == 1); - assert(stride_zoff_seven - stride_zoff_one == 2); + assert(sv_zero_offset_should_be_four - sv_zero_offset_should_be_one == 1); + assert(sv_zero_offset_should_be_seven - sv_zero_offset_should_be_one == 2); // Check positive __n with non-exact multiple of left's stride. - assert(stride_ooff_two - stride_zoff_one == 1); - assert(stride_ooff_five - stride_zoff_one == 2); + assert(sv_one_offset_should_be_two - sv_zero_offset_should_be_one == 1); + assert(sv_one_offset_should_be_five - sv_zero_offset_should_be_one == 2); // Check negative __n with exact multiple of left's stride. - assert(stride_zoff_one - stride_zoff_four == -1); - assert(stride_zoff_one - stride_zoff_seven == -2); + assert(sv_zero_offset_should_be_one - sv_zero_offset_should_be_four == -1); + assert(sv_zero_offset_should_be_one - sv_zero_offset_should_be_seven == -2); // Check negative __n with non-exact multiple of left's stride. - assert(stride_zoff_one - stride_ooff_two == -1); - assert(stride_zoff_one - stride_ooff_five == -2); + assert(sv_zero_offset_should_be_one - sv_one_offset_should_be_two == -1); + assert(sv_zero_offset_should_be_one - sv_one_offset_should_be_five == -2); return true; } -constexpr bool test_forward_operator_minus() { +template +constexpr bool test_forward_operator_minus(Iter begin, Iter end) { // Test the forward-range operator- between two iterators (i.e., no ceil). - using Base = BasicTestView; - int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + using Base = BasicTestView; + //int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // First, what operators are valid for an iterator derived from a stride view // over a sized forward view (even though it is actually much more than that!). using StrideViewIterator = std::ranges::iterator_t>; static_assert(std::weakly_incrementable); - static_assert(CanMinus); - auto rav_zero = Base(arr, arr + 10); - auto rav_one = Base(arr + 1, arr + 10); - auto stride_zoff = std::ranges::stride_view(rav_zero, 3); - auto stride_ooff = std::ranges::stride_view(rav_one, 3); + auto base_view_offset_zero = Base(begin, end); + auto base_view_offset_one = Base(begin + 1, end); + auto stride_view_over_base_zero_offset = std::ranges::stride_view(base_view_offset_zero, 3); + auto stride_view_over_base_one_offset = std::ranges::stride_view(base_view_offset_one, 3); - auto stride_zoff_begin = stride_zoff.begin(); - auto stride_ooff_begin = stride_ooff.begin(); + auto sv_zero_offset_begin = stride_view_over_base_zero_offset.begin(); + auto sv_one_offset_begin = stride_view_over_base_one_offset.begin(); - auto stride_zoff_one = stride_zoff_begin; - auto stride_zoff_four = ++stride_zoff_begin; - auto stride_zoff_seven = ++stride_zoff_begin; + auto sv_zero_offset_should_be_one = sv_zero_offset_begin; + auto sv_zero_offset_should_be_four = ++sv_zero_offset_begin; + auto sv_zero_offset_should_be_seven = ++sv_zero_offset_begin; - auto stride_ooff_two = stride_ooff_begin; - auto stride_ooff_five = ++stride_ooff_begin; + auto sv_one_offset_should_be_two = sv_one_offset_begin; + auto sv_one_offset_should_be_five = ++sv_one_offset_begin; static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); - static_assert(CanMinus); + static_assert(CanMinus); static_assert(std::forward_iterator>); + assert(*sv_zero_offset_should_be_one == 1); + assert(*sv_zero_offset_should_be_four == 4); + assert(*sv_zero_offset_should_be_seven == 7); - assert(*stride_zoff_one == 1); - assert(*stride_zoff_four == 4); - assert(*stride_zoff_seven == 7); - - assert(*stride_ooff_two == 2); - assert(*stride_ooff_five == 5); + assert(*sv_one_offset_should_be_two == 2); + assert(*sv_one_offset_should_be_five == 5); // Check positive __n with exact multiple of left's stride. - assert(stride_zoff_four - stride_zoff_one == 1); - assert(stride_zoff_seven - stride_zoff_one == 2); + assert(sv_zero_offset_should_be_four - sv_zero_offset_should_be_one == 1); + assert(sv_zero_offset_should_be_seven - sv_zero_offset_should_be_one == 2); // Check positive __n with non-exact multiple of left's stride. - assert(stride_ooff_two - stride_zoff_one == 0); - assert(stride_ooff_five - stride_zoff_one == 1); + assert(sv_one_offset_should_be_two - sv_zero_offset_should_be_one == 0); + assert(sv_one_offset_should_be_five - sv_zero_offset_should_be_one == 1); // Check negative __n with exact multiple of left's stride. - assert(stride_zoff_one - stride_zoff_four == -1); - assert(stride_zoff_one - stride_zoff_seven == -2); + assert(sv_zero_offset_should_be_one - sv_zero_offset_should_be_four == -1); + assert(sv_zero_offset_should_be_one - sv_zero_offset_should_be_seven == -2); // Check negative __n with non-exact multiple of left's stride. - assert(stride_zoff_one - stride_ooff_two == 0); - assert(stride_zoff_one - stride_ooff_five == -1); + assert(sv_zero_offset_should_be_one - sv_one_offset_should_be_two == 0); + assert(sv_zero_offset_should_be_one - sv_one_offset_should_be_five == -1); return true; } @@ -357,11 +357,17 @@ constexpr bool test_properly_handling_missing() { } int main(int, char**) { - test_forward_operator_minus(); - static_assert(test_forward_operator_minus()); - - test_non_forward_operator_minus(); - static_assert(test_non_forward_operator_minus()); + { + constexpr int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + std::vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + test_forward_operator_minus(arr, arr + 10); + test_forward_operator_minus(vec.begin(), vec.end()); + } + + { + int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + test_non_forward_operator_minus(SizedInputIterator(arr), SizedInputIterator(arr + 1), SizedInputIterator(arr + 10)); + } test_properly_handling_missing(); static_assert(test_properly_handling_missing()); From f11e072edba401a106bc70410526bae3c9061b86 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 10 Jan 2024 17:21:25 -0500 Subject: [PATCH 100/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Round out testing for operator== on iterators. --- .../range.stride.view/iterator/equal.pass.cpp | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp index 1900c04752271..29156e0fe0db6 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp @@ -8,19 +8,20 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// std::views::stride_view -// TODO +// friend constexpr bool operator==(__iterator const& __x, default_sentinel_t) +// friend constexpr bool operator==(__iterator const& __x, __iterator const& __y) #include #include #include "test_iterators.h" +#include "../types.h" template constexpr void testOne() { - using Range = std::ranges::subrange; + using Range = BasicTestView; + static_assert(std::ranges::common_range); using StrideView = std::ranges::stride_view; - static_assert(std::ranges::common_range); { // simple test @@ -36,9 +37,12 @@ constexpr void testOne() { assert(b == b); assert(!(b != b)); - assert(e == e); - assert(!(e != e)); - + // When Range is a bidirectional_range, the type of e is + // default_sentinel_t and those do not compare to one another. + if constexpr (!std::ranges::bidirectional_range) { + assert(e == e); + assert(!(e != e)); + } assert(!(b == e)); assert(b != e); @@ -51,8 +55,11 @@ constexpr void testOne() { assert(b == b); assert(!(b != b)); - assert(e == e); - assert(!(e != e)); + // See above. + if constexpr (!std::ranges::bidirectional_range) { + assert(e == e); + assert(!(e != e)); + } assert(b == e); assert(!(b != e)); @@ -74,10 +81,10 @@ constexpr void testOne() { constexpr bool test() { testOne>(); - //testOne>(); - //testOne>(); - //testOne>(); - //testOne(); + testOne>(); + testOne>(); + testOne>(); + testOne(); return true; } From d6f0126aaa31cb04d6ed10a6e51755a937a6325e Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 10 Jan 2024 18:23:32 -0500 Subject: [PATCH 101/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add (and test) for additional end-of-iterator assertions. --- libcxx/include/__ranges/stride_view.h | 6 ++++- .../iterator/increment.pass.cpp | 26 +++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 0e4f1945eabc2..561e2914c1642 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -211,10 +211,14 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> return *this; } - _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; } + _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { + _LIBCPP_ASSERT_UNCATEGORIZED(__current_ != __end_, "Cannot increment an iterator already at the end."); + ++*this; + } _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) requires forward_range<_Base> { + _LIBCPP_ASSERT_UNCATEGORIZED(__current_ != __end_, "Cannot increment an iterator already at the end."); auto __tmp = *this; ++*this; return __tmp; diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp index 10e471a8805f5..97a8845438443 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp @@ -16,12 +16,28 @@ #include #include "check_assertion.h" +#include "test_iterators.h" + +#include "../../../../../std/ranges/range.adaptors/range.stride.view/types.h" int main(int, char**) { - int range[] = {1, 2, 3}; - auto striv = std::ranges::views::stride(range, 3); - auto striv_it = striv.begin(); - ++striv_it; - TEST_LIBCPP_ASSERT_FAILURE(striv_it++, "Cannot increment an iterator already at the end."); + { + int range[] = {1, 2, 3}; + using Base = BasicTestView>; + auto striv = std::ranges::views::stride(Base(cpp17_input_iterator(range), cpp17_input_iterator(range + 3)), 3); + auto striv_it = striv.begin(); + ++striv_it; + TEST_LIBCPP_ASSERT_FAILURE(striv_it++, "Cannot increment an iterator already at the end."); + TEST_LIBCPP_ASSERT_FAILURE(++striv_it, "Cannot increment an iterator already at the end."); + } + { + int range[] = {1, 2, 3}; + using Base = BasicTestView, forward_iterator>; + auto striv = std::ranges::views::stride(Base(forward_iterator(range), forward_iterator(range + 3)), 3); + auto striv_it = striv.begin(); + ++striv_it; + TEST_LIBCPP_ASSERT_FAILURE(striv_it++, "Cannot increment an iterator already at the end."); + TEST_LIBCPP_ASSERT_FAILURE(++striv_it, "Cannot increment an iterator already at the end."); + } return 0; } From ceb2c54c2f00ab2c57231de0a5b35aab28fe78b9 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 10 Jan 2024 22:25:51 -0500 Subject: [PATCH 102/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add verify tests for no discard. --- .../iterator/dereference.nodiscard.verify.cpp | 24 ++++++++ .../iterator/iter_move.nodiscard.verify.cpp | 36 ++++++++++++ .../iterator/operator.nodiscard.verify.cpp | 58 +++++++++++++++++++ .../iterator/subscript.nodiscard.verify.cpp | 22 +++++++ 4 files changed, 140 insertions(+) create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/iter_move.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/subscript.nodiscard.verify.cpp diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.nodiscard.verify.cpp new file mode 100644 index 0000000000000..d10a1aa2066a0 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.nodiscard.verify.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// constexpr decltype(auto) operator*() const { + +#include +#include + +void test() { + { + int range[] = {1, 2, 3}; + auto view = std::ranges::views::stride(range, 3); + auto it = view.begin(); + ++it; + *std::as_const(it); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } +} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/iter_move.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/iter_move.nodiscard.verify.cpp new file mode 100644 index 0000000000000..9b2108a3361dd --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/iter_move.nodiscard.verify.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// friend constexpr range_rvalue_reference_t<_Base> iter_move(__iterator const& __it) noexcept(noexcept(ranges::iter_move(__it.__current_))) + +#include + +#include "../../../../../std/ranges/range.adaptors/range.stride.view/types.h" + +constexpr bool test() { + { + int a[] = {4, 3, 2, 1}; + + int iter_move_counter(0); + using View = IterMoveIterSwapTestRange; + using StrideView = std::ranges::stride_view; + auto svb = StrideView(View(a, a + 4, &iter_move_counter), 1).begin(); + + static_assert(std::is_same_v); + static_assert(noexcept(std::ranges::iter_move(svb))); + + // These lines need to be in sync so that clang-verify knows where the warning comes from. + // clang-format off + std::ranges::iter_move( // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + svb); + // clang-format on + } + return true; +} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp new file mode 100644 index 0000000000000..18304d72e5965 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// constexpr decltype(auto) operator[](difference_type __n) const + +#include + +#include "../../../../../std/ranges/range.adaptors/range.stride.view/types.h" + +constexpr bool test_non_forward_operator_minus() { + int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + + using Base = BasicTestView; + + auto base_view_offset_zero = Base(SizedInputIterator(arr), SizedInputIterator(arr + 10)); + auto base_view_offset_one = Base(SizedInputIterator(arr + 1), SizedInputIterator(arr + 10)); + auto stride_view_over_base_zero_offset = std::ranges::stride_view(base_view_offset_zero, 3); + auto stride_view_over_base_one_offset = std::ranges::stride_view(base_view_offset_one, 3); + + auto sv_zero_offset_begin = stride_view_over_base_zero_offset.begin(); + auto sv_one_offset_begin = stride_view_over_base_one_offset.begin(); + + sv_one_offset_begin - // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv_zero_offset_begin; + return true; +} + +constexpr bool test_forward_operator_minus() { + // Test the forward-range operator- between two iterators (i.e., no ceil). + using Base = BasicTestView; + int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + + auto base_view_offset_zero = Base(arr, arr + 10); + auto base_view_offset_one = Base(arr + 1, arr + 10); + auto stride_view_over_base_zero_offset = std::ranges::stride_view(base_view_offset_zero, 3); + auto stride_view_over_base_one_offset = std::ranges::stride_view(base_view_offset_one, 3); + + auto sv_zero_offset_begin = stride_view_over_base_zero_offset.begin(); + auto sv_one_offset_begin = stride_view_over_base_one_offset.begin(); + + sv_zero_offset_begin + // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + 1; + 1 + sv_zero_offset_begin; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + sv_one_offset_begin - 1; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + sv_one_offset_begin - // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv_zero_offset_begin; + + return true; +} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/subscript.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/subscript.nodiscard.verify.cpp new file mode 100644 index 0000000000000..cfd048b66afe4 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/subscript.nodiscard.verify.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// constexpr decltype(auto) operator[](difference_type __n) const + +#include + +void test() { + { + int range[] = {1, 2, 3}; + auto view = std::ranges::views::stride(range, 3); + auto it = view.begin(); + it[0]; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } +} From b41f4840c82215aff025f9d7b1e980faca58d1ef Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 10 Jan 2024 22:26:22 -0500 Subject: [PATCH 103/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Cleanup libcxx assertion tests. --- .../range.stride.view/ctor.assert.pass.cpp | 1 - .../iterator/dereference.pass.cpp | 23 +++++++------ .../iterator/increment.pass.cpp | 34 ++++++++++--------- .../iterator/operator_plus_equal.pass.cpp | 11 +++--- 4 files changed, 36 insertions(+), 33 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp index 92a5cd999798e..b62ce15d7c93b 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// UNSUPPORTED: no-exceptions // UNSUPPORTED: !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp index 2bbebd6db5fa8..40400cc91137c 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp @@ -7,27 +7,28 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// UNSUPPORTED: no-exceptions // UNSUPPORTED: libcpp-hardening-mode=none // XFAIL: availability-verbose_abort-missing +// constexpr decltype(auto) operator*() const + #include "check_assertion.h" #include int main(int, char**) { { - int range[] = {1, 2, 3}; - auto striv = std::ranges::views::stride(range, 3); - auto striv_it = striv.begin(); - ++striv_it; - TEST_LIBCPP_ASSERT_FAILURE(*std::as_const(striv_it), "Cannot dereference an iterator at the end."); + int range[] = {1, 2, 3}; + auto view = std::ranges::views::stride(range, 3); + auto it = view.begin(); + ++it; + TEST_LIBCPP_ASSERT_FAILURE(*std::as_const(it), "Cannot dereference an iterator at the end."); } { - int range[] = {1, 2, 3}; - auto striv = std::ranges::views::stride(range, 4); - auto striv_it = striv.begin(); - ++striv_it; - TEST_LIBCPP_ASSERT_FAILURE(*std::as_const(striv_it), "Cannot dereference an iterator at the end."); + int range[] = {1, 2, 3}; + auto view = std::ranges::views::stride(range, 4); + auto it = view.begin(); + ++it; + TEST_LIBCPP_ASSERT_FAILURE(*std::as_const(it), "Cannot dereference an iterator at the end."); } return 0; } diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp index 97a8845438443..bd818ecc48b8e 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp @@ -7,11 +7,13 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// UNSUPPORTED: no-exceptions // UNSUPPORTED: !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing -// constexpr stride_view::& operator++() { +// constexpr stride_view::& operator++() +// constexpr __iterator& operator++() +// constexpr void operator++(int) { +// constexpr __iterator operator++(int) #include @@ -22,22 +24,22 @@ int main(int, char**) { { - int range[] = {1, 2, 3}; - using Base = BasicTestView>; - auto striv = std::ranges::views::stride(Base(cpp17_input_iterator(range), cpp17_input_iterator(range + 3)), 3); - auto striv_it = striv.begin(); - ++striv_it; - TEST_LIBCPP_ASSERT_FAILURE(striv_it++, "Cannot increment an iterator already at the end."); - TEST_LIBCPP_ASSERT_FAILURE(++striv_it, "Cannot increment an iterator already at the end."); + int range[] = {1, 2, 3}; + using Base = BasicTestView>; + auto view = std::ranges::views::stride(Base(cpp17_input_iterator(range), cpp17_input_iterator(range + 3)), 3); + auto it = view.begin(); + ++it; + TEST_LIBCPP_ASSERT_FAILURE(it++, "Cannot increment an iterator already at the end."); + TEST_LIBCPP_ASSERT_FAILURE(++it, "Cannot increment an iterator already at the end."); } { - int range[] = {1, 2, 3}; - using Base = BasicTestView, forward_iterator>; - auto striv = std::ranges::views::stride(Base(forward_iterator(range), forward_iterator(range + 3)), 3); - auto striv_it = striv.begin(); - ++striv_it; - TEST_LIBCPP_ASSERT_FAILURE(striv_it++, "Cannot increment an iterator already at the end."); - TEST_LIBCPP_ASSERT_FAILURE(++striv_it, "Cannot increment an iterator already at the end."); + int range[] = {1, 2, 3}; + using Base = BasicTestView, forward_iterator>; + auto view = std::ranges::views::stride(Base(forward_iterator(range), forward_iterator(range + 3)), 3); + auto it = view.begin(); + ++it; + TEST_LIBCPP_ASSERT_FAILURE(it++, "Cannot increment an iterator already at the end."); + TEST_LIBCPP_ASSERT_FAILURE(++it, "Cannot increment an iterator already at the end."); } return 0; } diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp index 5a1e018085f5f..766d99223dc8d 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp @@ -7,19 +7,20 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// UNSUPPORTED: no-exceptions // UNSUPPORTED: !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing +// constexpr __iterator& operator+=(difference_type __n) + #include #include "check_assertion.h" int main(int, char**) { - int range[] = {1, 2, 3}; - auto striv = std::ranges::views::stride(range, 2); - auto striv_it = striv.begin(); - TEST_LIBCPP_ASSERT_FAILURE(striv_it += 3, "Advancing the iterator beyond the end is not allowed."); + int range[] = {1, 2, 3}; + auto view = std::ranges::views::stride(range, 2); + auto it = view.begin(); + TEST_LIBCPP_ASSERT_FAILURE(it += 3, "Advancing the iterator beyond the end is not allowed."); return 0; } From 289405e348974d45e1f0a6908888c8df68b3217d Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 15 Jan 2024 22:44:16 -0500 Subject: [PATCH 104/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add testing for iterator operations with sentinel --- .../iterator/operator.pass.cpp | 89 +++++++++++++++---- 1 file changed, 74 insertions(+), 15 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index 2366c1231ee7d..04384ac595672 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -33,6 +33,9 @@ #include "__compare/three_way_comparable.h" #include "__concepts/equality_comparable.h" #include "__iterator/concepts.h" +#include "__iterator/default_sentinel.h" +#include "__iterator/distance.h" +#include "__ranges/access.h" #include "__ranges/concepts.h" #include "__ranges/stride_view.h" #include "test_iterators.h" @@ -49,6 +52,16 @@ concept CanMinus = std::is_same_v() - std::declval())> && requires(T& t) { t - t; }; +template +concept CanSentinelMinus = + // Note: Do *not* use std::iterator_traits here because T may not have + // all the required pieces when it is not a forward_range. + std::is_same_v() - std::default_sentinel)> && + std::is_same_v())> && requires(T& t) { + t - std::default_sentinel; + std::default_sentinel - t; + }; + template concept CanDifferencePlus = std::is_same_v() + 1)> && requires(T& t) { t + 1; }; template @@ -63,9 +76,9 @@ template concept CanSubscript = requires(T& t) { t[5]; }; // What operators are valid for an iterator derived from a stride view -// over an input view. -using StrideViewOverInputViewIterator = - std::ranges::iterator_t>>>; +// over an input view.(sized sentinel) +using InputView = BasicTestView, sized_sentinel>>; +using StrideViewOverInputViewIterator = std::ranges::iterator_t>; static_assert(std::weakly_incrementable); @@ -76,6 +89,10 @@ static_assert(!CanMinusEqual); static_assert(!CanMinus); static_assert(!CanDifferencePlus); static_assert(!CanDifferenceMinus); +static_assert(CanSentinelMinus); +static_assert(std::invocable, StrideViewOverInputViewIterator, StrideViewOverInputViewIterator>); +static_assert(std::invocable, StrideViewOverInputViewIterator, std::default_sentinel_t>); +static_assert(std::invocable, std::default_sentinel_t, StrideViewOverInputViewIterator>); static_assert(!std::is_invocable_v, StrideViewOverInputViewIterator, StrideViewOverInputViewIterator>); static_assert( @@ -87,8 +104,8 @@ static_assert( static_assert(!CanSubscript); // What operators are valid for an iterator derived from a stride view -// over a forward view. -using ForwardView = BasicTestView>; +// over a forward view.(sized sentinel) +using ForwardView = BasicTestView, sized_sentinel>>; using StrideViewOverForwardViewIterator = std::ranges::iterator_t>; static_assert(std::weakly_incrementable); @@ -100,6 +117,10 @@ static_assert(!CanMinusEqual); static_assert(!CanMinus); static_assert(!CanDifferencePlus); static_assert(!CanDifferenceMinus); +static_assert(CanSentinelMinus); +static_assert(std::invocable, StrideViewOverForwardViewIterator, StrideViewOverForwardViewIterator>); +static_assert(std::invocable, StrideViewOverForwardViewIterator, std::default_sentinel_t>); +static_assert(std::invocable, std::default_sentinel_t, StrideViewOverForwardViewIterator>); static_assert(!std::is_invocable_v, StrideViewOverForwardViewIterator, StrideViewOverForwardViewIterator>); static_assert( @@ -112,12 +133,10 @@ static_assert( static_assert(!CanSubscript); // What operators are valid for an iterator derived from a stride view -// over a bidirectional view. -using BidirectionalView = BasicTestView>; +// over a bidirectional view. (sized sentinel) +using BidirectionalView = BasicTestView, sized_sentinel>>; using StrideViewOverBidirectionalViewIterator = std::ranges::iterator_t>; -static_assert(std::weakly_incrementable); - static_assert(CanPostDecrement); static_assert(CanPreDecrement); static_assert(!CanPlusEqual); @@ -125,6 +144,11 @@ static_assert(!CanMinusEqual); static_assert(!CanMinus); static_assert(!CanDifferencePlus); static_assert(!CanDifferenceMinus); +static_assert(CanSentinelMinus); +static_assert( + std::invocable, StrideViewOverBidirectionalViewIterator, StrideViewOverBidirectionalViewIterator>); +static_assert(std::invocable, StrideViewOverBidirectionalViewIterator, std::default_sentinel_t>); +static_assert(std::invocable, std::default_sentinel_t, StrideViewOverBidirectionalViewIterator>); static_assert(!std::is_invocable_v, StrideViewOverBidirectionalViewIterator, @@ -142,7 +166,7 @@ static_assert(!std::is_invocable_v, static_assert(!CanSubscript); // What operators are valid for an iterator derived from a stride view -// over a random access view. +// over a random access view. (non sized sentinel) using RandomAccessView = BasicTestView>; using StrideViewOverRandomAccessViewIterator = std::ranges::iterator_t>; @@ -155,6 +179,11 @@ static_assert(CanMinusEqual); static_assert(CanMinus); static_assert(CanDifferencePlus); static_assert(CanDifferenceMinus); +static_assert(!CanSentinelMinus); +static_assert( + std::invocable, StrideViewOverRandomAccessViewIterator, StrideViewOverRandomAccessViewIterator>); +static_assert(std::invocable, StrideViewOverRandomAccessViewIterator, std::default_sentinel_t>); +static_assert(std::invocable, std::default_sentinel_t, StrideViewOverRandomAccessViewIterator>); static_assert( std::is_invocable_v, StrideViewOverRandomAccessViewIterator, StrideViewOverRandomAccessViewIterator>); @@ -217,11 +246,15 @@ constexpr bool test_non_forward_operator_minus(Iter zero_begin, Iter one_begin, static_assert(!CanMinusEqual); static_assert(!CanDifferencePlus); static_assert(!CanDifferenceMinus); + static_assert(CanSentinelMinus); static_assert(!std::is_invocable_v, StrideViewIterator, StrideViewIterator>); static_assert(!std::is_invocable_v, StrideViewIterator, StrideViewIterator>); static_assert(!std::is_invocable_v, StrideViewIterator, StrideViewIterator>); static_assert(!std::is_invocable_v, StrideViewIterator, StrideViewIterator>); + static_assert(std::is_invocable_v, StrideViewIterator, StrideViewIterator>); + static_assert(std::is_invocable_v, std::default_sentinel_t, StrideViewIterator>); + static_assert(std::is_invocable_v, StrideViewIterator, std::default_sentinel_t>); static_assert(!CanSubscript); auto base_view_offset_zero = Base(zero_begin, end); @@ -263,6 +296,15 @@ constexpr bool test_non_forward_operator_minus(Iter zero_begin, Iter one_begin, assert(sv_zero_offset_should_be_one - sv_one_offset_should_be_two == -1); assert(sv_zero_offset_should_be_one - sv_one_offset_should_be_five == -2); + assert(stride_view_over_base_zero_offset.end() == std::default_sentinel); + assert(std::default_sentinel == stride_view_over_base_zero_offset.end()); + + assert(stride_view_over_base_zero_offset.end() - std::default_sentinel == 0); + assert(std::default_sentinel - stride_view_over_base_zero_offset.begin() == + std::ranges::distance(stride_view_over_base_zero_offset)); + assert(stride_view_over_base_zero_offset.begin() - std::default_sentinel == + -std::ranges::distance(stride_view_over_base_zero_offset)); + return true; } @@ -278,6 +320,7 @@ constexpr bool test_forward_operator_minus(Iter begin, Iter end) { static_assert(std::weakly_incrementable); static_assert(CanMinus); + static_assert(CanSentinelMinus); auto base_view_offset_zero = Base(begin, end); auto base_view_offset_one = Base(begin + 1, end); @@ -318,6 +361,16 @@ constexpr bool test_forward_operator_minus(Iter begin, Iter end) { // Check negative __n with non-exact multiple of left's stride. assert(sv_zero_offset_should_be_one - sv_one_offset_should_be_two == 0); assert(sv_zero_offset_should_be_one - sv_one_offset_should_be_five == -1); + + // Make sure that all sentinel operations work! + assert(stride_view_over_base_zero_offset.end() == std::default_sentinel); + assert(std::default_sentinel == stride_view_over_base_zero_offset.end()); + + assert(stride_view_over_base_zero_offset.end() - std::default_sentinel == 0); + assert(std::default_sentinel - stride_view_over_base_zero_offset.begin() == + std::ranges::distance(stride_view_over_base_zero_offset)); + assert(stride_view_over_base_zero_offset.begin() - std::default_sentinel == + -std::ranges::distance(stride_view_over_base_zero_offset)); return true; } @@ -343,16 +396,22 @@ constexpr bool test_properly_handling_missing() { assert(*strider_iter == 8); // By striding past the end, we are going to generate - // another __missing_ != 0 value. Let's make sure - // that it gets generated and used. + // another __missing_ != 0 value. strider_iter++; assert(strider_iter == strider.end()); - strider_iter--; - assert(*strider_iter == 8); + // Make sure that all sentinel operations work! + assert(strider.end() == std::default_sentinel); + assert(std::default_sentinel == strider.end()); - strider_iter--; + assert(strider_iter - std::default_sentinel == 0); + assert(std::default_sentinel - strider.end() == 0); + assert(std::default_sentinel - strider_iter == 0); + + // Let's make sure that the newly regenerated __missing_ gets used. + strider_iter += -2; assert(*strider_iter == 1); + return true; } From c6e640de7726c1cb3b6ea6647809f7bfb9870281 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Tue, 16 Jan 2024 00:28:32 -0500 Subject: [PATCH 105/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add runtime testing for ctad. --- .../range.stride.view/ctad.compile.pass.cpp | 37 -------- .../range.stride.view/ctad.pass.cpp | 93 +++++++++++++++++++ .../range.adaptors/range.stride.view/types.h | 21 +++++ 3 files changed, 114 insertions(+), 37 deletions(-) delete mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.pass.cpp diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp deleted file mode 100644 index c65e6a2c87d1a..0000000000000 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.compile.pass.cpp +++ /dev/null @@ -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, c++20 - -// template -// stride_view(_Range&&, range_difference_t<_Range>) -> stride_view>; - -#include -#include - -struct View : std::ranges::view_base { - int* begin() const; - int* end() const; -}; - -struct Range { - int* begin() const; - int* end() const; -}; - -void testCTAD() { - View v; - Range r; - - static_assert(std::same_as< decltype(std::ranges::stride_view(v, 5)), std::ranges::stride_view >); - static_assert(std::same_as< decltype(std::ranges::stride_view(std::move(v), 5)), std::ranges::stride_view >); - static_assert( - std::same_as< decltype(std::ranges::stride_view(r, 5)), std::ranges::stride_view> >); - static_assert(std::same_as< decltype(std::ranges::stride_view(std::move(r), 5)), - std::ranges::stride_view> >); -} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.pass.cpp new file mode 100644 index 0000000000000..d8f19116810c8 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.pass.cpp @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// template +// stride_view(_Range&&, range_difference_t<_Range>) -> stride_view>; + +#include "types.h" +#include +#include + +struct View : std::ranges::view_base { + int* begin() const; + int* end() const; +}; + +struct Range { + int* begin() const; + int* end() const; +}; + +constexpr bool testCTAD() { + int a[] = {1, 2, 3, 4, 5}; + + using BaseRange = BasicTestRange>; + using BaseView = BasicTestView; + + auto base_view = BaseView(a, a + 5); + auto base_range = BaseRange(cpp17_input_iterator(a), cpp17_input_iterator(a + 5)); + + auto copied_stride_base_view = std::ranges::stride_view(base_view, 2); + auto moved_stride_base_view = std::ranges::stride_view(std::move(base_view), 2); + + auto copied_stride_base_range = std::ranges::stride_view(base_range, 2); + auto moved_stride_base_range = std::ranges::stride_view(std::move(base_range), 2); + + static_assert(std::same_as< decltype(copied_stride_base_view), std::ranges::stride_view>); + static_assert(std::same_as< decltype(moved_stride_base_view), std::ranges::stride_view>); + + static_assert( + std::same_as< decltype(copied_stride_base_range), std::ranges::stride_view> >); + static_assert( + std::same_as< decltype(moved_stride_base_range), std::ranges::stride_view> >); + + assert(*copied_stride_base_range.begin() == 1); + assert(*moved_stride_base_range.begin() == 1); + + assert(*copied_stride_base_view.begin() == 1); + assert(*moved_stride_base_view.begin() == 1); + + auto copied_stride_range_it = copied_stride_base_range.begin(); + copied_stride_range_it++; + assert(*copied_stride_range_it == 3); + copied_stride_range_it++; + copied_stride_range_it++; + assert(copied_stride_range_it == copied_stride_base_range.end()); + + auto moved_stride_range_it = moved_stride_base_range.begin(); + moved_stride_range_it++; + moved_stride_range_it++; + assert(*moved_stride_range_it == 5); + moved_stride_range_it++; + assert(moved_stride_range_it == moved_stride_base_range.end()); + + auto copied_stride_view_it = copied_stride_base_view.begin(); + copied_stride_view_it++; + assert(*copied_stride_view_it == 3); + copied_stride_view_it++; + copied_stride_view_it++; + assert(copied_stride_view_it == copied_stride_base_view.end()); + + auto moved_stride_view_it = copied_stride_base_view.begin(); + moved_stride_view_it++; + moved_stride_view_it++; + assert(*moved_stride_view_it == 5); + moved_stride_view_it++; + assert(moved_stride_view_it == moved_stride_base_view.end()); + + return true; +} + +int main(int, char**) { + testCTAD(); + static_assert(testCTAD()); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index 240cc43465a26..83dac4ab1ba7c 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -209,4 +209,25 @@ struct ViewOverNonCopyableIterator : std::ranges::view_base { decltype(base(std::declval())) sent_; }; +// Ranges +template Sent = sentinel_wrapper, bool IsSized = false> + requires((!IsSized) || (IsSized && IterDifferable)) +struct BasicTestRange { + Iter begin_{}; + Iter end_{}; + + constexpr BasicTestRange(Iter b, Iter e) : begin_(b), end_(e) {} + + constexpr Iter begin() { return begin_; } + constexpr Iter begin() const { return begin_; } + constexpr Sent end() { return Sent{end_}; } + constexpr Sent end() const { return Sent{end_}; } + + constexpr auto size() const + requires IsSized + { + return begin_ - end_; + } +}; + #endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H From 8f3e8ebe8ac4dc7c41b3e84b1ed484efd07eaed5 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 24 Jan 2024 10:25:40 -0500 Subject: [PATCH 106/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. --- .../iterator/operator.pass.cpp | 42 +++++++------------ 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index 04384ac595672..44dd560a38d1a 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -265,36 +265,29 @@ constexpr bool test_non_forward_operator_minus(Iter zero_begin, Iter one_begin, auto sv_zero_offset_begin = stride_view_over_base_zero_offset.begin(); auto sv_one_offset_begin = stride_view_over_base_one_offset.begin(); - auto sv_zero_offset_should_be_one = sv_zero_offset_begin; - auto sv_zero_offset_should_be_four = ++sv_zero_offset_begin; - auto sv_zero_offset_should_be_seven = ++sv_zero_offset_begin; + auto sv_zero_offset_zeroth_index = sv_zero_offset_begin; + auto sv_zero_offset_third_index = ++sv_zero_offset_begin; + auto sv_zero_offset_sixth_index = ++sv_zero_offset_begin; - auto sv_one_offset_should_be_two = sv_one_offset_begin; - auto sv_one_offset_should_be_five = ++sv_one_offset_begin; + auto sv_one_offset_oneth_index = sv_one_offset_begin; + auto sv_one_offset_fourth_index = ++sv_one_offset_begin; static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); static_assert(CanMinus); - assert(*sv_zero_offset_should_be_one == 1); - assert(*sv_zero_offset_should_be_four == 4); - assert(*sv_zero_offset_should_be_seven == 7); - - assert(*sv_one_offset_should_be_two == 2); - assert(*sv_one_offset_should_be_five == 5); - // Check positive __n with exact multiple of left's stride. - assert(sv_zero_offset_should_be_four - sv_zero_offset_should_be_one == 1); - assert(sv_zero_offset_should_be_seven - sv_zero_offset_should_be_one == 2); - // Check positive __n with non-exact multiple of left's stride. - assert(sv_one_offset_should_be_two - sv_zero_offset_should_be_one == 1); - assert(sv_one_offset_should_be_five - sv_zero_offset_should_be_one == 2); + assert(sv_zero_offset_third_index - sv_zero_offset_zeroth_index == 1); + assert(sv_zero_offset_sixth_index - sv_zero_offset_zeroth_index == 2); + // Check positive __n with non-exact multiple of left's stride (will do ceil here). + assert(sv_one_offset_oneth_index - sv_zero_offset_zeroth_index == 1); + assert(sv_one_offset_fourth_index - sv_zero_offset_zeroth_index == 2); // Check negative __n with exact multiple of left's stride. - assert(sv_zero_offset_should_be_one - sv_zero_offset_should_be_four == -1); - assert(sv_zero_offset_should_be_one - sv_zero_offset_should_be_seven == -2); - // Check negative __n with non-exact multiple of left's stride. - assert(sv_zero_offset_should_be_one - sv_one_offset_should_be_two == -1); - assert(sv_zero_offset_should_be_one - sv_one_offset_should_be_five == -2); + assert(sv_zero_offset_zeroth_index - sv_zero_offset_third_index == -1); + assert(sv_zero_offset_zeroth_index - sv_zero_offset_sixth_index == -2); + // Check negative __n with non-exact multiple of left's stride (will do ceil here). + assert(sv_zero_offset_zeroth_index - sv_one_offset_oneth_index == -1); + assert(sv_zero_offset_zeroth_index - sv_one_offset_fourth_index == -2); assert(stride_view_over_base_zero_offset.end() == std::default_sentinel); assert(std::default_sentinel == stride_view_over_base_zero_offset.end()); @@ -340,12 +333,7 @@ constexpr bool test_forward_operator_minus(Iter begin, Iter end) { static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); static_assert(CanMinus); static_assert(std::forward_iterator>); - assert(*sv_zero_offset_should_be_one == 1); - assert(*sv_zero_offset_should_be_four == 4); - assert(*sv_zero_offset_should_be_seven == 7); - assert(*sv_one_offset_should_be_two == 2); - assert(*sv_one_offset_should_be_five == 5); // Check positive __n with exact multiple of left's stride. assert(sv_zero_offset_should_be_four - sv_zero_offset_should_be_one == 1); assert(sv_zero_offset_should_be_seven - sv_zero_offset_should_be_one == 2); From fecd435e873a76dcda9b587054063cc747798428 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 24 Jan 2024 12:15:13 -0500 Subject: [PATCH 107/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add stride_view to IWYU. --- libcxx/include/libcxx.imp | 869 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 869 insertions(+) create mode 100644 libcxx/include/libcxx.imp diff --git a/libcxx/include/libcxx.imp b/libcxx/include/libcxx.imp new file mode 100644 index 0000000000000..26397c1216a76 --- /dev/null +++ b/libcxx/include/libcxx.imp @@ -0,0 +1,869 @@ +[ + { include: [ "<__algorithm/adjacent_find.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/all_of.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/any_of.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/binary_search.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/clamp.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/comp.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/comp_ref_type.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/copy_backward.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/copy_if.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/copy_move_common.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/copy_n.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/count.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/count_if.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/equal.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/equal_range.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/fill.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/fill_n.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/find.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/find_end.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/find_first_of.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/find_if.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/find_if_not.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/find_segment_if.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/fold.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/for_each.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/for_each_n.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/for_each_segment.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/generate.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/generate_n.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/half_positive.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/in_found_result.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/in_fun_result.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/in_in_out_result.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/in_in_result.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/in_out_out_result.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/in_out_result.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/includes.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/inplace_merge.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/is_heap.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/is_heap_until.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/is_partitioned.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/is_permutation.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/is_sorted.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/is_sorted_until.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/iter_swap.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/iterator_operations.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/lexicographical_compare.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/lexicographical_compare_three_way.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/lower_bound.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/make_heap.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/make_projected.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/max.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/max_element.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/merge.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/min.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/min_element.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/min_max_result.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/minmax.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/minmax_element.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/mismatch.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/move.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/move_backward.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/next_permutation.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/none_of.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/nth_element.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/partial_sort.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/partial_sort_copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/partition.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/partition_copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/partition_point.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pop_heap.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/prev_permutation.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_any_all_none_of.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_backend.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_backends/cpu_backend.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_backends/cpu_backends/any_of.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_backends/cpu_backends/backend.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_backends/cpu_backends/fill.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_backends/cpu_backends/find_if.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_backends/cpu_backends/for_each.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_backends/cpu_backends/libdispatch.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_backends/cpu_backends/merge.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_backends/cpu_backends/serial.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_backends/cpu_backends/stable_sort.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_backends/cpu_backends/thread.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_backends/cpu_backends/transform.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_backends/cpu_backends/transform_reduce.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_count.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_equal.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_fill.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_find.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_for_each.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_frontend_dispatch.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_generate.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_is_partitioned.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_merge.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_move.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_replace.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_rotate_copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_sort.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_stable_sort.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/pstl_transform.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/push_heap.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_adjacent_find.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_all_of.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_any_of.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_binary_search.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_clamp.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_contains.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_copy_backward.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_copy_if.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_copy_n.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_count.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_count_if.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_ends_with.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_equal.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_equal_range.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_fill.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_fill_n.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_find.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_find_end.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_find_first_of.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_find_if.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_find_if_not.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_for_each.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_for_each_n.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_generate.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_generate_n.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_includes.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_inplace_merge.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_is_heap.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_is_heap_until.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_is_partitioned.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_is_permutation.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_is_sorted.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_is_sorted_until.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_iterator_concept.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_lexicographical_compare.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_lower_bound.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_make_heap.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_max.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_max_element.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_merge.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_min.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_min_element.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_minmax.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_minmax_element.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_mismatch.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_move.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_move_backward.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_next_permutation.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_none_of.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_nth_element.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_partial_sort.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_partial_sort_copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_partition.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_partition_copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_partition_point.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_pop_heap.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_prev_permutation.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_push_heap.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_remove.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_remove_copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_remove_copy_if.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_remove_if.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_replace.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_replace_copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_replace_copy_if.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_replace_if.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_reverse.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_reverse_copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_rotate.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_rotate_copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_sample.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_search.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_search_n.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_set_difference.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_set_intersection.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_set_symmetric_difference.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_set_union.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_shuffle.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_sort.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_sort_heap.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_stable_partition.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_stable_sort.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_starts_with.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_swap_ranges.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_transform.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_unique.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_unique_copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/ranges_upper_bound.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/remove.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/remove_copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/remove_copy_if.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/remove_if.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/replace.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/replace_copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/replace_copy_if.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/replace_if.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/reverse.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/reverse_copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/rotate.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/rotate_copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/sample.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/search.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/search_n.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/set_difference.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/set_intersection.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/set_symmetric_difference.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/set_union.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/shift_left.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/shift_right.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/shuffle.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/sift_down.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/sort.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/sort_heap.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/stable_partition.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/stable_sort.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/swap_ranges.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/three_way_comp_ref_type.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/transform.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/uniform_random_bit_generator_adaptor.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/unique.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/unique_copy.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/unwrap_iter.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/unwrap_range.h>", "private", "", "public" ] }, + { include: [ "<__algorithm/upper_bound.h>", "private", "", "public" ] }, + { include: [ "<__atomic/aliases.h>", "private", "", "public" ] }, + { include: [ "<__atomic/atomic.h>", "private", "", "public" ] }, + { include: [ "<__atomic/atomic_base.h>", "private", "", "public" ] }, + { include: [ "<__atomic/atomic_flag.h>", "private", "", "public" ] }, + { include: [ "<__atomic/atomic_init.h>", "private", "", "public" ] }, + { include: [ "<__atomic/atomic_lock_free.h>", "private", "", "public" ] }, + { include: [ "<__atomic/atomic_sync.h>", "private", "", "public" ] }, + { include: [ "<__atomic/check_memory_order.h>", "private", "", "public" ] }, + { include: [ "<__atomic/contention_t.h>", "private", "", "public" ] }, + { include: [ "<__atomic/cxx_atomic_impl.h>", "private", "", "public" ] }, + { include: [ "<__atomic/fence.h>", "private", "", "public" ] }, + { include: [ "<__atomic/is_always_lock_free.h>", "private", "", "public" ] }, + { include: [ "<__atomic/kill_dependency.h>", "private", "", "public" ] }, + { include: [ "<__atomic/memory_order.h>", "private", "", "public" ] }, + { include: [ "<__bit/bit_cast.h>", "private", "", "public" ] }, + { include: [ "<__bit/bit_ceil.h>", "private", "", "public" ] }, + { include: [ "<__bit/bit_floor.h>", "private", "", "public" ] }, + { include: [ "<__bit/bit_log2.h>", "private", "", "public" ] }, + { include: [ "<__bit/bit_width.h>", "private", "", "public" ] }, + { include: [ "<__bit/blsr.h>", "private", "", "public" ] }, + { include: [ "<__bit/byteswap.h>", "private", "", "public" ] }, + { include: [ "<__bit/countl.h>", "private", "", "public" ] }, + { include: [ "<__bit/countr.h>", "private", "", "public" ] }, + { include: [ "<__bit/endian.h>", "private", "", "public" ] }, + { include: [ "<__bit/has_single_bit.h>", "private", "", "public" ] }, + { include: [ "<__bit/invert_if.h>", "private", "", "public" ] }, + { include: [ "<__bit/popcount.h>", "private", "", "public" ] }, + { include: [ "<__bit/rotate.h>", "private", "", "public" ] }, + { include: [ "<__charconv/chars_format.h>", "private", "", "public" ] }, + { include: [ "<__charconv/from_chars_integral.h>", "private", "", "public" ] }, + { include: [ "<__charconv/from_chars_result.h>", "private", "", "public" ] }, + { include: [ "<__charconv/tables.h>", "private", "", "public" ] }, + { include: [ "<__charconv/to_chars.h>", "private", "", "public" ] }, + { include: [ "<__charconv/to_chars_base_10.h>", "private", "", "public" ] }, + { include: [ "<__charconv/to_chars_floating_point.h>", "private", "", "public" ] }, + { include: [ "<__charconv/to_chars_integral.h>", "private", "", "public" ] }, + { include: [ "<__charconv/to_chars_result.h>", "private", "", "public" ] }, + { include: [ "<__charconv/traits.h>", "private", "", "public" ] }, + { include: [ "<__chrono/calendar.h>", "private", "", "public" ] }, + { include: [ "<__chrono/concepts.h>", "private", "", "public" ] }, + { include: [ "<__chrono/convert_to_timespec.h>", "private", "", "public" ] }, + { include: [ "<__chrono/convert_to_tm.h>", "private", "", "public" ] }, + { include: [ "<__chrono/day.h>", "private", "", "public" ] }, + { include: [ "<__chrono/duration.h>", "private", "", "public" ] }, + { include: [ "<__chrono/file_clock.h>", "private", "", "public" ] }, + { include: [ "<__chrono/formatter.h>", "private", "", "public" ] }, + { include: [ "<__chrono/hh_mm_ss.h>", "private", "", "public" ] }, + { include: [ "<__chrono/high_resolution_clock.h>", "private", "", "public" ] }, + { include: [ "<__chrono/literals.h>", "private", "", "public" ] }, + { include: [ "<__chrono/month.h>", "private", "", "public" ] }, + { include: [ "<__chrono/month_weekday.h>", "private", "", "public" ] }, + { include: [ "<__chrono/monthday.h>", "private", "", "public" ] }, + { include: [ "<__chrono/ostream.h>", "private", "", "public" ] }, + { include: [ "<__chrono/parser_std_format_spec.h>", "private", "", "public" ] }, + { include: [ "<__chrono/statically_widen.h>", "private", "", "public" ] }, + { include: [ "<__chrono/steady_clock.h>", "private", "", "public" ] }, + { include: [ "<__chrono/system_clock.h>", "private", "", "public" ] }, + { include: [ "<__chrono/time_point.h>", "private", "", "public" ] }, + { include: [ "<__chrono/tzdb.h>", "private", "", "public" ] }, + { include: [ "<__chrono/tzdb_list.h>", "private", "", "public" ] }, + { include: [ "<__chrono/weekday.h>", "private", "", "public" ] }, + { include: [ "<__chrono/year.h>", "private", "", "public" ] }, + { include: [ "<__chrono/year_month.h>", "private", "", "public" ] }, + { include: [ "<__chrono/year_month_day.h>", "private", "", "public" ] }, + { include: [ "<__chrono/year_month_weekday.h>", "private", "", "public" ] }, + { include: [ "<__compare/common_comparison_category.h>", "private", "", "public" ] }, + { include: [ "<__compare/compare_partial_order_fallback.h>", "private", "", "public" ] }, + { include: [ "<__compare/compare_strong_order_fallback.h>", "private", "", "public" ] }, + { include: [ "<__compare/compare_three_way.h>", "private", "", "public" ] }, + { include: [ "<__compare/compare_three_way_result.h>", "private", "", "public" ] }, + { include: [ "<__compare/compare_weak_order_fallback.h>", "private", "", "public" ] }, + { include: [ "<__compare/is_eq.h>", "private", "", "public" ] }, + { include: [ "<__compare/ordering.h>", "private", "", "public" ] }, + { include: [ "<__compare/partial_order.h>", "private", "", "public" ] }, + { include: [ "<__compare/strong_order.h>", "private", "", "public" ] }, + { include: [ "<__compare/synth_three_way.h>", "private", "", "public" ] }, + { include: [ "<__compare/three_way_comparable.h>", "private", "", "public" ] }, + { include: [ "<__compare/weak_order.h>", "private", "", "public" ] }, + { include: [ "<__concepts/arithmetic.h>", "private", "", "public" ] }, + { include: [ "<__concepts/assignable.h>", "private", "", "public" ] }, + { include: [ "<__concepts/boolean_testable.h>", "private", "", "public" ] }, + { include: [ "<__concepts/class_or_enum.h>", "private", "", "public" ] }, + { include: [ "<__concepts/common_reference_with.h>", "private", "", "public" ] }, + { include: [ "<__concepts/common_with.h>", "private", "", "public" ] }, + { include: [ "<__concepts/constructible.h>", "private", "", "public" ] }, + { include: [ "<__concepts/convertible_to.h>", "private", "", "public" ] }, + { include: [ "<__concepts/copyable.h>", "private", "", "public" ] }, + { include: [ "<__concepts/derived_from.h>", "private", "", "public" ] }, + { include: [ "<__concepts/destructible.h>", "private", "", "public" ] }, + { include: [ "<__concepts/different_from.h>", "private", "", "public" ] }, + { include: [ "<__concepts/equality_comparable.h>", "private", "", "public" ] }, + { include: [ "<__concepts/invocable.h>", "private", "", "public" ] }, + { include: [ "<__concepts/movable.h>", "private", "", "public" ] }, + { include: [ "<__concepts/predicate.h>", "private", "", "public" ] }, + { include: [ "<__concepts/regular.h>", "private", "", "public" ] }, + { include: [ "<__concepts/relation.h>", "private", "", "public" ] }, + { include: [ "<__concepts/same_as.h>", "private", "", "public" ] }, + { include: [ "<__concepts/semiregular.h>", "private", "", "public" ] }, + { include: [ "<__concepts/swappable.h>", "private", "", "public" ] }, + { include: [ "<__concepts/totally_ordered.h>", "private", "", "public" ] }, + { include: [ "<__condition_variable/condition_variable.h>", "private", "", "public" ] }, + { include: [ "<__coroutine/coroutine_handle.h>", "private", "", "public" ] }, + { include: [ "<__coroutine/coroutine_traits.h>", "private", "", "public" ] }, + { include: [ "<__coroutine/noop_coroutine_handle.h>", "private", "", "public" ] }, + { include: [ "<__coroutine/trivial_awaitables.h>", "private", "", "public" ] }, + { include: [ "<__exception/exception.h>", "private", "", "public" ] }, + { include: [ "<__exception/exception_ptr.h>", "private", "", "public" ] }, + { include: [ "<__exception/nested_exception.h>", "private", "", "public" ] }, + { include: [ "<__exception/operations.h>", "private", "", "public" ] }, + { include: [ "<__exception/terminate.h>", "private", "", "public" ] }, + { include: [ "<__expected/bad_expected_access.h>", "private", "", "public" ] }, + { include: [ "<__expected/expected.h>", "private", "", "public" ] }, + { include: [ "<__expected/unexpect.h>", "private", "", "public" ] }, + { include: [ "<__expected/unexpected.h>", "private", "", "public" ] }, + { include: [ "<__filesystem/copy_options.h>", "private", "", "public" ] }, + { include: [ "<__filesystem/directory_entry.h>", "private", "", "public" ] }, + { include: [ "<__filesystem/directory_iterator.h>", "private", "", "public" ] }, + { include: [ "<__filesystem/directory_options.h>", "private", "", "public" ] }, + { include: [ "<__filesystem/file_status.h>", "private", "", "public" ] }, + { include: [ "<__filesystem/file_time_type.h>", "private", "", "public" ] }, + { include: [ "<__filesystem/file_type.h>", "private", "", "public" ] }, + { include: [ "<__filesystem/filesystem_error.h>", "private", "", "public" ] }, + { include: [ "<__filesystem/operations.h>", "private", "", "public" ] }, + { include: [ "<__filesystem/path.h>", "private", "", "public" ] }, + { include: [ "<__filesystem/path_iterator.h>", "private", "", "public" ] }, + { include: [ "<__filesystem/perm_options.h>", "private", "", "public" ] }, + { include: [ "<__filesystem/perms.h>", "private", "", "public" ] }, + { include: [ "<__filesystem/recursive_directory_iterator.h>", "private", "", "public" ] }, + { include: [ "<__filesystem/space_info.h>", "private", "", "public" ] }, + { include: [ "<__filesystem/u8path.h>", "private", "", "public" ] }, + { include: [ "<__format/buffer.h>", "private", "", "public" ] }, + { include: [ "<__format/concepts.h>", "private", "", "public" ] }, + { include: [ "<__format/container_adaptor.h>", "private", "", "public" ] }, + { include: [ "<__format/enable_insertable.h>", "private", "", "public" ] }, + { include: [ "<__format/escaped_output_table.h>", "private", "", "public" ] }, + { include: [ "<__format/extended_grapheme_cluster_table.h>", "private", "", "public" ] }, + { include: [ "<__format/format_arg.h>", "private", "", "public" ] }, + { include: [ "<__format/format_arg_store.h>", "private", "", "public" ] }, + { include: [ "<__format/format_args.h>", "private", "", "public" ] }, + { include: [ "<__format/format_context.h>", "private", "", "public" ] }, + { include: [ "<__format/format_error.h>", "private", "", "public" ] }, + { include: [ "<__format/format_functions.h>", "private", "", "public" ] }, + { include: [ "<__format/format_fwd.h>", "private", "", "public" ] }, + { include: [ "<__format/format_parse_context.h>", "private", "", "public" ] }, + { include: [ "<__format/format_string.h>", "private", "", "public" ] }, + { include: [ "<__format/format_to_n_result.h>", "private", "", "public" ] }, + { include: [ "<__format/formatter.h>", "private", "", "public" ] }, + { include: [ "<__format/formatter_bool.h>", "private", "", "public" ] }, + { include: [ "<__format/formatter_char.h>", "private", "", "public" ] }, + { include: [ "<__format/formatter_floating_point.h>", "private", "", "public" ] }, + { include: [ "<__format/formatter_integer.h>", "private", "", "public" ] }, + { include: [ "<__format/formatter_integral.h>", "private", "", "public" ] }, + { include: [ "<__format/formatter_output.h>", "private", "", "public" ] }, + { include: [ "<__format/formatter_pointer.h>", "private", "", "public" ] }, + { include: [ "<__format/formatter_string.h>", "private", "", "public" ] }, + { include: [ "<__format/formatter_tuple.h>", "private", "", "public" ] }, + { include: [ "<__format/parser_std_format_spec.h>", "private", "", "public" ] }, + { include: [ "<__format/range_default_formatter.h>", "private", "", "public" ] }, + { include: [ "<__format/range_formatter.h>", "private", "", "public" ] }, + { include: [ "<__format/unicode.h>", "private", "", "public" ] }, + { include: [ "<__format/width_estimation_table.h>", "private", "", "public" ] }, + { include: [ "<__format/write_escaped.h>", "private", "", "public" ] }, + { include: [ "<__functional/binary_function.h>", "private", "", "public" ] }, + { include: [ "<__functional/binary_negate.h>", "private", "", "public" ] }, + { include: [ "<__functional/bind.h>", "private", "", "public" ] }, + { include: [ "<__functional/bind_back.h>", "private", "", "public" ] }, + { include: [ "<__functional/bind_front.h>", "private", "", "public" ] }, + { include: [ "<__functional/binder1st.h>", "private", "", "public" ] }, + { include: [ "<__functional/binder2nd.h>", "private", "", "public" ] }, + { include: [ "<__functional/boyer_moore_searcher.h>", "private", "", "public" ] }, + { include: [ "<__functional/compose.h>", "private", "", "public" ] }, + { include: [ "<__functional/default_searcher.h>", "private", "", "public" ] }, + { include: [ "<__functional/function.h>", "private", "", "public" ] }, + { include: [ "<__functional/hash.h>", "private", "", "public" ] }, + { include: [ "<__functional/identity.h>", "private", "", "public" ] }, + { include: [ "<__functional/invoke.h>", "private", "", "public" ] }, + { include: [ "<__functional/is_transparent.h>", "private", "", "public" ] }, + { include: [ "<__functional/mem_fn.h>", "private", "", "public" ] }, + { include: [ "<__functional/mem_fun_ref.h>", "private", "", "public" ] }, + { include: [ "<__functional/not_fn.h>", "private", "", "public" ] }, + { include: [ "<__functional/operations.h>", "private", "", "public" ] }, + { include: [ "<__functional/perfect_forward.h>", "private", "", "public" ] }, + { include: [ "<__functional/pointer_to_binary_function.h>", "private", "", "public" ] }, + { include: [ "<__functional/pointer_to_unary_function.h>", "private", "", "public" ] }, + { include: [ "<__functional/ranges_operations.h>", "private", "", "public" ] }, + { include: [ "<__functional/reference_wrapper.h>", "private", "", "public" ] }, + { include: [ "<__functional/unary_function.h>", "private", "", "public" ] }, + { include: [ "<__functional/unary_negate.h>", "private", "", "public" ] }, + { include: [ "<__functional/weak_result_type.h>", "private", "", "public" ] }, + { include: [ "<__fwd/array.h>", "private", "", "public" ] }, + { include: [ "<__fwd/bit_reference.h>", "private", "", "public" ] }, + { include: [ "<__fwd/bit_reference.h>", "private", "", "public" ] }, + { include: [ "<__fwd/fstream.h>", "private", "", "public" ] }, + { include: [ "<__fwd/hash.h>", "private", "", "public" ] }, + { include: [ "<__fwd/ios.h>", "private", "", "public" ] }, + { include: [ "<__fwd/istream.h>", "private", "", "public" ] }, + { include: [ "<__fwd/mdspan.h>", "private", "", "public" ] }, + { include: [ "<__fwd/memory_resource.h>", "private", "", "public" ] }, + { include: [ "<__fwd/ostream.h>", "private", "", "public" ] }, + { include: [ "<__fwd/pair.h>", "private", "", "public" ] }, + { include: [ "<__fwd/span.h>", "private", "", "public" ] }, + { include: [ "<__fwd/sstream.h>", "private", "", "public" ] }, + { include: [ "<__fwd/streambuf.h>", "private", "", "public" ] }, + { include: [ "<__fwd/string.h>", "private", "", "public" ] }, + { include: [ "<__fwd/string_view.h>", "private", "", "public" ] }, + { include: [ "<__fwd/subrange.h>", "private", "", "public" ] }, + { include: [ "<__fwd/tuple.h>", "private", "", "public" ] }, + { include: [ "<__ios/fpos.h>", "private", "", "public" ] }, + { include: [ "<__iterator/access.h>", "private", "", "public" ] }, + { include: [ "<__iterator/advance.h>", "private", "", "public" ] }, + { include: [ "<__iterator/back_insert_iterator.h>", "private", "", "public" ] }, + { include: [ "<__iterator/bounded_iter.h>", "private", "", "public" ] }, + { include: [ "<__iterator/common_iterator.h>", "private", "", "public" ] }, + { include: [ "<__iterator/concepts.h>", "private", "", "public" ] }, + { include: [ "<__iterator/counted_iterator.h>", "private", "", "public" ] }, + { include: [ "<__iterator/cpp17_iterator_concepts.h>", "private", "", "public" ] }, + { include: [ "<__iterator/data.h>", "private", "", "public" ] }, + { include: [ "<__iterator/default_sentinel.h>", "private", "", "public" ] }, + { include: [ "<__iterator/distance.h>", "private", "", "public" ] }, + { include: [ "<__iterator/empty.h>", "private", "", "public" ] }, + { include: [ "<__iterator/erase_if_container.h>", "private", "", "public" ] }, + { include: [ "<__iterator/front_insert_iterator.h>", "private", "", "public" ] }, + { include: [ "<__iterator/incrementable_traits.h>", "private", "", "public" ] }, + { include: [ "<__iterator/indirectly_comparable.h>", "private", "", "public" ] }, + { include: [ "<__iterator/insert_iterator.h>", "private", "", "public" ] }, + { include: [ "<__iterator/istream_iterator.h>", "private", "", "public" ] }, + { include: [ "<__iterator/istreambuf_iterator.h>", "private", "", "public" ] }, + { include: [ "<__iterator/iter_move.h>", "private", "", "public" ] }, + { include: [ "<__iterator/iter_swap.h>", "private", "", "public" ] }, + { include: [ "<__iterator/iterator.h>", "private", "", "public" ] }, + { include: [ "<__iterator/iterator_traits.h>", "private", "", "public" ] }, + { include: [ "<__iterator/iterator_with_data.h>", "private", "", "public" ] }, + { include: [ "<__iterator/mergeable.h>", "private", "", "public" ] }, + { include: [ "<__iterator/move_iterator.h>", "private", "", "public" ] }, + { include: [ "<__iterator/move_sentinel.h>", "private", "", "public" ] }, + { include: [ "<__iterator/next.h>", "private", "", "public" ] }, + { include: [ "<__iterator/ostream_iterator.h>", "private", "", "public" ] }, + { include: [ "<__iterator/ostreambuf_iterator.h>", "private", "", "public" ] }, + { include: [ "<__iterator/permutable.h>", "private", "", "public" ] }, + { include: [ "<__iterator/prev.h>", "private", "", "public" ] }, + { include: [ "<__iterator/projected.h>", "private", "", "public" ] }, + { include: [ "<__iterator/ranges_iterator_traits.h>", "private", "", "public" ] }, + { include: [ "<__iterator/readable_traits.h>", "private", "", "public" ] }, + { include: [ "<__iterator/reverse_access.h>", "private", "", "public" ] }, + { include: [ "<__iterator/reverse_iterator.h>", "private", "", "public" ] }, + { include: [ "<__iterator/segmented_iterator.h>", "private", "", "public" ] }, + { include: [ "<__iterator/size.h>", "private", "", "public" ] }, + { include: [ "<__iterator/sortable.h>", "private", "", "public" ] }, + { include: [ "<__iterator/unreachable_sentinel.h>", "private", "", "public" ] }, + { include: [ "<__iterator/wrap_iter.h>", "private", "", "public" ] }, + { include: [ "<__locale_dir/locale_base_api.h>", "private", "", "public" ] }, + { include: [ "<__locale_dir/locale_base_api/android.h>", "private", "", "public" ] }, + { include: [ "<__locale_dir/locale_base_api/bsd_locale_defaults.h>", "private", "", "public" ] }, + { include: [ "<__locale_dir/locale_base_api/bsd_locale_fallbacks.h>", "private", "", "public" ] }, + { include: [ "<__locale_dir/locale_base_api/fuchsia.h>", "private", "", "public" ] }, + { include: [ "<__locale_dir/locale_base_api/ibm.h>", "private", "", "public" ] }, + { include: [ "<__locale_dir/locale_base_api/locale_guard.h>", "private", "", "public" ] }, + { include: [ "<__locale_dir/locale_base_api/musl.h>", "private", "", "public" ] }, + { include: [ "<__locale_dir/locale_base_api/newlib.h>", "private", "", "public" ] }, + { include: [ "<__locale_dir/locale_base_api/openbsd.h>", "private", "", "public" ] }, + { include: [ "<__locale_dir/locale_base_api/win32.h>", "private", "", "public" ] }, + { include: [ "<__math/abs.h>", "private", "", "public" ] }, + { include: [ "<__math/copysign.h>", "private", "", "public" ] }, + { include: [ "<__math/error_functions.h>", "private", "", "public" ] }, + { include: [ "<__math/exponential_functions.h>", "private", "", "public" ] }, + { include: [ "<__math/fdim.h>", "private", "", "public" ] }, + { include: [ "<__math/fma.h>", "private", "", "public" ] }, + { include: [ "<__math/gamma.h>", "private", "", "public" ] }, + { include: [ "<__math/hyperbolic_functions.h>", "private", "", "public" ] }, + { include: [ "<__math/hypot.h>", "private", "", "public" ] }, + { include: [ "<__math/inverse_hyperbolic_functions.h>", "private", "", "public" ] }, + { include: [ "<__math/inverse_trigonometric_functions.h>", "private", "", "public" ] }, + { include: [ "<__math/logarithms.h>", "private", "", "public" ] }, + { include: [ "<__math/min_max.h>", "private", "", "public" ] }, + { include: [ "<__math/modulo.h>", "private", "", "public" ] }, + { include: [ "<__math/remainder.h>", "private", "", "public" ] }, + { include: [ "<__math/roots.h>", "private", "", "public" ] }, + { include: [ "<__math/rounding_functions.h>", "private", "", "public" ] }, + { include: [ "<__math/traits.h>", "private", "", "public" ] }, + { include: [ "<__math/trigonometric_functions.h>", "private", "", "public" ] }, + { include: [ "<__mdspan/default_accessor.h>", "private", "", "public" ] }, + { include: [ "<__mdspan/extents.h>", "private", "", "public" ] }, + { include: [ "<__mdspan/layout_left.h>", "private", "", "public" ] }, + { include: [ "<__mdspan/layout_right.h>", "private", "", "public" ] }, + { include: [ "<__mdspan/layout_stride.h>", "private", "", "public" ] }, + { include: [ "<__mdspan/mdspan.h>", "private", "", "public" ] }, + { include: [ "<__memory/addressof.h>", "private", "", "public" ] }, + { include: [ "<__memory/align.h>", "private", "", "public" ] }, + { include: [ "<__memory/aligned_alloc.h>", "private", "", "public" ] }, + { include: [ "<__memory/allocate_at_least.h>", "private", "", "public" ] }, + { include: [ "<__memory/allocation_guard.h>", "private", "", "public" ] }, + { include: [ "<__memory/allocator.h>", "private", "", "public" ] }, + { include: [ "<__memory/allocator_arg_t.h>", "private", "", "public" ] }, + { include: [ "<__memory/allocator_destructor.h>", "private", "", "public" ] }, + { include: [ "<__memory/allocator_traits.h>", "private", "", "public" ] }, + { include: [ "<__memory/assume_aligned.h>", "private", "", "public" ] }, + { include: [ "<__memory/auto_ptr.h>", "private", "", "public" ] }, + { include: [ "<__memory/builtin_new_allocator.h>", "private", "", "public" ] }, + { include: [ "<__memory/compressed_pair.h>", "private", "", "public" ] }, + { include: [ "<__memory/concepts.h>", "private", "", "public" ] }, + { include: [ "<__memory/construct_at.h>", "private", "", "public" ] }, + { include: [ "<__memory/destruct_n.h>", "private", "", "public" ] }, + { include: [ "<__memory/pointer_traits.h>", "private", "", "public" ] }, + { include: [ "<__memory/ranges_construct_at.h>", "private", "", "public" ] }, + { include: [ "<__memory/ranges_uninitialized_algorithms.h>", "private", "", "public" ] }, + { include: [ "<__memory/raw_storage_iterator.h>", "private", "", "public" ] }, + { include: [ "<__memory/shared_ptr.h>", "private", "", "public" ] }, + { include: [ "<__memory/swap_allocator.h>", "private", "", "public" ] }, + { include: [ "<__memory/temp_value.h>", "private", "", "public" ] }, + { include: [ "<__memory/temporary_buffer.h>", "private", "", "public" ] }, + { include: [ "<__memory/uninitialized_algorithms.h>", "private", "", "public" ] }, + { include: [ "<__memory/unique_ptr.h>", "private", "", "public" ] }, + { include: [ "<__memory/uses_allocator.h>", "private", "", "public" ] }, + { include: [ "<__memory/uses_allocator_construction.h>", "private", "", "public" ] }, + { include: [ "<__memory/voidify.h>", "private", "", "public" ] }, + { include: [ "<__memory_resource/memory_resource.h>", "private", "", "public" ] }, + { include: [ "<__memory_resource/monotonic_buffer_resource.h>", "private", "", "public" ] }, + { include: [ "<__memory_resource/polymorphic_allocator.h>", "private", "", "public" ] }, + { include: [ "<__memory_resource/pool_options.h>", "private", "", "public" ] }, + { include: [ "<__memory_resource/synchronized_pool_resource.h>", "private", "", "public" ] }, + { include: [ "<__memory_resource/unsynchronized_pool_resource.h>", "private", "", "public" ] }, + { include: [ "<__mutex/lock_guard.h>", "private", "", "public" ] }, + { include: [ "<__mutex/mutex.h>", "private", "", "public" ] }, + { include: [ "<__mutex/once_flag.h>", "private", "", "public" ] }, + { include: [ "<__mutex/tag_types.h>", "private", "", "public" ] }, + { include: [ "<__mutex/unique_lock.h>", "private", "", "public" ] }, + { include: [ "<__numeric/accumulate.h>", "private", "", "public" ] }, + { include: [ "<__numeric/adjacent_difference.h>", "private", "", "public" ] }, + { include: [ "<__numeric/exclusive_scan.h>", "private", "", "public" ] }, + { include: [ "<__numeric/gcd_lcm.h>", "private", "", "public" ] }, + { include: [ "<__numeric/inclusive_scan.h>", "private", "", "public" ] }, + { include: [ "<__numeric/inner_product.h>", "private", "", "public" ] }, + { include: [ "<__numeric/iota.h>", "private", "", "public" ] }, + { include: [ "<__numeric/midpoint.h>", "private", "", "public" ] }, + { include: [ "<__numeric/partial_sum.h>", "private", "", "public" ] }, + { include: [ "<__numeric/pstl_reduce.h>", "private", "", "public" ] }, + { include: [ "<__numeric/pstl_transform_reduce.h>", "private", "", "public" ] }, + { include: [ "<__numeric/reduce.h>", "private", "", "public" ] }, + { include: [ "<__numeric/saturation_arithmetic.h>", "private", "", "public" ] }, + { include: [ "<__numeric/transform_exclusive_scan.h>", "private", "", "public" ] }, + { include: [ "<__numeric/transform_inclusive_scan.h>", "private", "", "public" ] }, + { include: [ "<__numeric/transform_reduce.h>", "private", "", "public" ] }, + { include: [ "<__random/bernoulli_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/binomial_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/cauchy_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/chi_squared_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/clamp_to_integral.h>", "private", "", "public" ] }, + { include: [ "<__random/default_random_engine.h>", "private", "", "public" ] }, + { include: [ "<__random/discard_block_engine.h>", "private", "", "public" ] }, + { include: [ "<__random/discrete_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/exponential_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/extreme_value_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/fisher_f_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/gamma_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/generate_canonical.h>", "private", "", "public" ] }, + { include: [ "<__random/geometric_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/independent_bits_engine.h>", "private", "", "public" ] }, + { include: [ "<__random/is_seed_sequence.h>", "private", "", "public" ] }, + { include: [ "<__random/is_valid.h>", "private", "", "public" ] }, + { include: [ "<__random/knuth_b.h>", "private", "", "public" ] }, + { include: [ "<__random/linear_congruential_engine.h>", "private", "", "public" ] }, + { include: [ "<__random/log2.h>", "private", "", "public" ] }, + { include: [ "<__random/lognormal_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/mersenne_twister_engine.h>", "private", "", "public" ] }, + { include: [ "<__random/negative_binomial_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/normal_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/piecewise_constant_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/piecewise_linear_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/poisson_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/random_device.h>", "private", "", "public" ] }, + { include: [ "<__random/ranlux.h>", "private", "", "public" ] }, + { include: [ "<__random/seed_seq.h>", "private", "", "public" ] }, + { include: [ "<__random/shuffle_order_engine.h>", "private", "", "public" ] }, + { include: [ "<__random/student_t_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/subtract_with_carry_engine.h>", "private", "", "public" ] }, + { include: [ "<__random/uniform_int_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/uniform_random_bit_generator.h>", "private", "", "public" ] }, + { include: [ "<__random/uniform_real_distribution.h>", "private", "", "public" ] }, + { include: [ "<__random/weibull_distribution.h>", "private", "", "public" ] }, + { include: [ "<__ranges/access.h>", "private", "", "public" ] }, + { include: [ "<__ranges/all.h>", "private", "", "public" ] }, + { include: [ "<__ranges/as_rvalue_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/chunk_by_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/common_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/concepts.h>", "private", "", "public" ] }, + { include: [ "<__ranges/container_compatible_range.h>", "private", "", "public" ] }, + { include: [ "<__ranges/counted.h>", "private", "", "public" ] }, + { include: [ "<__ranges/dangling.h>", "private", "", "public" ] }, + { include: [ "<__ranges/data.h>", "private", "", "public" ] }, + { include: [ "<__ranges/drop_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/drop_while_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/elements_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/empty.h>", "private", "", "public" ] }, + { include: [ "<__ranges/empty_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/enable_borrowed_range.h>", "private", "", "public" ] }, + { include: [ "<__ranges/enable_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/filter_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/from_range.h>", "private", "", "public" ] }, + { include: [ "<__ranges/iota_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/istream_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/join_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/lazy_split_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/movable_box.h>", "private", "", "public" ] }, + { include: [ "<__ranges/non_propagating_cache.h>", "private", "", "public" ] }, + { include: [ "<__ranges/owning_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/range_adaptor.h>", "private", "", "public" ] }, + { include: [ "<__ranges/rbegin.h>", "private", "", "public" ] }, + { include: [ "<__ranges/ref_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/rend.h>", "private", "", "public" ] }, + { include: [ "<__ranges/repeat_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/reverse_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/single_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/size.h>", "private", "", "public" ] }, + { include: [ "<__ranges/split_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/stride_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/subrange.h>", "private", "", "public" ] }, + { include: [ "<__ranges/take_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/take_while_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/to.h>", "private", "", "public" ] }, + { include: [ "<__ranges/transform_view.h>", "private", "", "public" ] }, + { include: [ "<__ranges/view_interface.h>", "private", "", "public" ] }, + { include: [ "<__ranges/views.h>", "private", "", "public" ] }, + { include: [ "<__ranges/zip_view.h>", "private", "", "public" ] }, + { include: [ "<__stop_token/atomic_unique_lock.h>", "private", "", "public" ] }, + { include: [ "<__stop_token/intrusive_list_view.h>", "private", "", "public" ] }, + { include: [ "<__stop_token/intrusive_shared_ptr.h>", "private", "", "public" ] }, + { include: [ "<__stop_token/stop_callback.h>", "private", "", "public" ] }, + { include: [ "<__stop_token/stop_source.h>", "private", "", "public" ] }, + { include: [ "<__stop_token/stop_state.h>", "private", "", "public" ] }, + { include: [ "<__stop_token/stop_token.h>", "private", "", "public" ] }, + { include: [ "<__string/char_traits.h>", "private", "", "public" ] }, + { include: [ "<__string/constexpr_c_functions.h>", "private", "", "public" ] }, + { include: [ "<__string/extern_template_lists.h>", "private", "", "public" ] }, + { include: [ "<__system_error/errc.h>", "private", "", "public" ] }, + { include: [ "<__system_error/error_category.h>", "private", "", "public" ] }, + { include: [ "<__system_error/error_code.h>", "private", "", "public" ] }, + { include: [ "<__system_error/error_condition.h>", "private", "", "public" ] }, + { include: [ "<__system_error/system_error.h>", "private", "", "public" ] }, + { include: [ "<__thread/formatter.h>", "private", "", "public" ] }, + { include: [ "<__thread/id.h>", "private", "", "public" ] }, + { include: [ "<__thread/jthread.h>", "private", "", "public" ] }, + { include: [ "<__thread/poll_with_backoff.h>", "private", "", "public" ] }, + { include: [ "<__thread/support.h>", "private", "", "public" ] }, + { include: [ "<__thread/support.h>", "private", "", "public" ] }, + { include: [ "<__thread/support.h>", "private", "", "public" ] }, + { include: [ "<__thread/support.h>", "private", "", "public" ] }, + { include: [ "<__thread/support/c11.h>", "private", "", "public" ] }, + { include: [ "<__thread/support/c11.h>", "private", "", "public" ] }, + { include: [ "<__thread/support/c11.h>", "private", "", "public" ] }, + { include: [ "<__thread/support/c11.h>", "private", "", "public" ] }, + { include: [ "<__thread/support/external.h>", "private", "", "public" ] }, + { include: [ "<__thread/support/external.h>", "private", "", "public" ] }, + { include: [ "<__thread/support/external.h>", "private", "", "public" ] }, + { include: [ "<__thread/support/external.h>", "private", "", "public" ] }, + { include: [ "<__thread/support/pthread.h>", "private", "", "public" ] }, + { include: [ "<__thread/support/pthread.h>", "private", "", "public" ] }, + { include: [ "<__thread/support/pthread.h>", "private", "", "public" ] }, + { include: [ "<__thread/support/pthread.h>", "private", "", "public" ] }, + { include: [ "<__thread/support/windows.h>", "private", "", "public" ] }, + { include: [ "<__thread/support/windows.h>", "private", "", "public" ] }, + { include: [ "<__thread/support/windows.h>", "private", "", "public" ] }, + { include: [ "<__thread/support/windows.h>", "private", "", "public" ] }, + { include: [ "<__thread/this_thread.h>", "private", "", "public" ] }, + { include: [ "<__thread/thread.h>", "private", "", "public" ] }, + { include: [ "<__thread/timed_backoff_policy.h>", "private", "", "public" ] }, + { include: [ "<__tuple/make_tuple_types.h>", "private", "", "public" ] }, + { include: [ "<__tuple/pair_like.h>", "private", "", "public" ] }, + { include: [ "<__tuple/sfinae_helpers.h>", "private", "", "public" ] }, + { include: [ "<__tuple/tuple_element.h>", "private", "", "public" ] }, + { include: [ "<__tuple/tuple_indices.h>", "private", "", "public" ] }, + { include: [ "<__tuple/tuple_like.h>", "private", "", "public" ] }, + { include: [ "<__tuple/tuple_like_ext.h>", "private", "", "public" ] }, + { include: [ "<__tuple/tuple_size.h>", "private", "", "public" ] }, + { include: [ "<__tuple/tuple_types.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/add_const.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/add_cv.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/add_lvalue_reference.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/add_pointer.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/add_rvalue_reference.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/add_volatile.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/aligned_storage.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/aligned_union.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/alignment_of.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/apply_cv.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/can_extract_key.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/common_reference.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/common_type.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/conditional.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/conjunction.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/copy_cv.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/copy_cvref.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/datasizeof.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/decay.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/dependent_type.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/disjunction.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/enable_if.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/extent.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/has_unique_object_representation.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/has_virtual_destructor.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/integral_constant.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/invoke.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_abstract.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_aggregate.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_allocator.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_always_bitcastable.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_arithmetic.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_array.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_assignable.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_base_of.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_bounded_array.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_callable.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_char_like_type.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_class.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_compound.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_const.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_constant_evaluated.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_constructible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_convertible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_copy_assignable.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_copy_constructible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_core_convertible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_default_constructible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_destructible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_empty.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_enum.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_equality_comparable.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_execution_policy.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_final.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_floating_point.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_function.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_fundamental.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_implicitly_default_constructible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_integral.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_literal_type.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_member_function_pointer.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_member_object_pointer.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_member_pointer.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_move_assignable.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_move_constructible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_nothrow_assignable.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_nothrow_constructible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_nothrow_convertible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_nothrow_copy_assignable.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_nothrow_copy_constructible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_nothrow_default_constructible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_nothrow_destructible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_nothrow_move_assignable.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_nothrow_move_constructible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_null_pointer.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_object.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_pod.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_pointer.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_polymorphic.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_primary_template.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_reference.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_reference_wrapper.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_referenceable.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_same.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_scalar.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_scoped_enum.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_signed.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_signed_integer.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_specialization.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_standard_layout.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_swappable.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_trivial.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_trivially_assignable.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_trivially_constructible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_trivially_copy_assignable.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_trivially_copy_constructible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_trivially_copyable.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_trivially_default_constructible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_trivially_destructible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_trivially_lexicographically_comparable.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_trivially_move_assignable.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_trivially_move_constructible.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_trivially_relocatable.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_unbounded_array.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_union.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_unsigned.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_unsigned_integer.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_valid_expansion.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_void.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/is_volatile.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/lazy.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/make_32_64_or_128_bit.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/make_const_lvalue_ref.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/make_signed.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/make_unsigned.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/maybe_const.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/nat.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/negation.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/noexcept_move_assign_container.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/operation_traits.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/promote.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/rank.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/remove_all_extents.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/remove_const.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/remove_const_ref.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/remove_cv.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/remove_cvref.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/remove_extent.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/remove_pointer.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/remove_reference.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/remove_volatile.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/result_of.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/strip_signature.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/type_identity.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/type_list.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/underlying_type.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/unwrap_ref.h>", "private", "", "public" ] }, + { include: [ "<__type_traits/void_t.h>", "private", "", "public" ] }, + { include: [ "<__utility/as_const.h>", "private", "", "public" ] }, + { include: [ "<__utility/as_lvalue.h>", "private", "", "public" ] }, + { include: [ "<__utility/auto_cast.h>", "private", "", "public" ] }, + { include: [ "<__utility/cmp.h>", "private", "", "public" ] }, + { include: [ "<__utility/convert_to_integral.h>", "private", "", "public" ] }, + { include: [ "<__utility/declval.h>", "private", "", "public" ] }, + { include: [ "<__utility/empty.h>", "private", "", "public" ] }, + { include: [ "<__utility/exception_guard.h>", "private", "", "public" ] }, + { include: [ "<__utility/exchange.h>", "private", "", "public" ] }, + { include: [ "<__utility/forward.h>", "private", "", "public" ] }, + { include: [ "<__utility/forward_like.h>", "private", "", "public" ] }, + { include: [ "<__utility/in_place.h>", "private", "", "public" ] }, + { include: [ "<__utility/integer_sequence.h>", "private", "", "public" ] }, + { include: [ "<__utility/is_pointer_in_range.h>", "private", "", "public" ] }, + { include: [ "<__utility/move.h>", "private", "", "public" ] }, + { include: [ "<__utility/no_destroy.h>", "private", "", "public" ] }, + { include: [ "<__utility/pair.h>", "private", "", "public" ] }, + { include: [ "<__utility/piecewise_construct.h>", "private", "", "public" ] }, + { include: [ "<__utility/priority_tag.h>", "private", "", "public" ] }, + { include: [ "<__utility/rel_ops.h>", "private", "", "public" ] }, + { include: [ "<__utility/small_buffer.h>", "private", "", "public" ] }, + { include: [ "<__utility/swap.h>", "private", "", "public" ] }, + { include: [ "<__utility/to_underlying.h>", "private", "", "public" ] }, + { include: [ "<__utility/unreachable.h>", "private", "", "public" ] }, + { include: [ "<__variant/monostate.h>", "private", "", "public" ] }, +] From 1654837d386b0b086330bae7cf35df7abaa2abf1 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 31 Jan 2024 17:39:58 -0500 Subject: [PATCH 108/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Simplify BasicTestView and BasicTestRange and add additional adaptor tests. --- .../range.stride.view/adaptor.pass.cpp | 36 +++++++++++++----- .../range.adaptors/range.stride.view/types.h | 38 +++++++++---------- 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index 352dfcc995eec..cef16b263c5e2 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -51,6 +51,7 @@ constexpr bool test() { // Check various forms of // view | stride + // two tests: first with stride of 1; second with stride of 2. { using View = BasicTestView>; auto view = make_input_view(arr, arr + N); @@ -71,10 +72,12 @@ constexpr bool test() { auto strided_iter = strided.begin(); assert(*strided_iter == arr[0]); + std::ranges::advance(strided_iter, 1); + assert(*strided_iter == arr[2]); } // adaptor | stride - // Parallels the two tests from above. + // two tests: first with stride of 1; second with stride of 2. const auto i2 = [](int i) { return i * 2; }; { auto view = make_input_view(arr, arr + N); @@ -82,6 +85,7 @@ constexpr bool test() { auto transform_stride_applied = transform_stride_partial(view); auto transform_stride_applied_iter = transform_stride_applied.begin(); + assert(*transform_stride_applied_iter == i2(arr[0])); std::ranges::advance(transform_stride_applied_iter, 2); assert(*transform_stride_applied_iter == i2(arr[2])); @@ -93,21 +97,33 @@ constexpr bool test() { const auto transform_stride_applied = transform_stride_partial(view); auto transform_stride_applied_iter = transform_stride_applied.begin(); + assert(*transform_stride_applied_iter == i2(arr[0])); + std::ranges::advance(transform_stride_applied_iter, 1); + assert(*transform_stride_applied_iter == i2(arr[2])); } + // stride | adaptor + // two tests: first with stride of 1; second with stride of 2. { - using View = BasicTestView; - auto view = View(arr, arr + N); - std::same_as> decltype(auto) strided = view | std::views::stride(1); - auto strided_iter = strided.begin(); - auto strided_iter_next = strided_iter; + auto view = make_input_view(arr, arr + N); + const auto stride_transform = std::views::stride(view, 1) | std::views::transform(i2); - (void)strided_iter_next++; + auto stride_transform_iter = stride_transform.begin(); - assert(*strided_iter == arr[0]); - assert(*strided_iter_next == arr[1]); - assert(strided_iter_next - strided_iter == 1); + assert(*stride_transform_iter == i2(arr[0])); + std::ranges::advance(stride_transform_iter, 2); + assert(*stride_transform_iter == i2(arr[2])); + } + { + auto view = make_input_view(arr, arr + N); + const auto stride_transform = std::views::stride(view, 2) | std::views::transform(i2); + + auto stride_transform_iter = stride_transform.begin(); + + assert(*stride_transform_iter == i2(arr[0])); + std::ranges::advance(stride_transform_iter, 1); + assert(*stride_transform_iter == i2(arr[2])); } // Check SFINAE friendliness diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index 83dac4ab1ba7c..70d0a4d1b300a 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -129,13 +129,22 @@ struct IterMoveIterSwapTestRange : std::ranges::view_base { // Views -template Sent = sentinel_wrapper, bool IsSized = false> +template +struct ViewOrRange {}; + +template <> +struct ViewOrRange : std::ranges::view_base {}; + +template Sent = sentinel_wrapper, + bool IsSized = false, + bool IsView = false> requires((!IsSized) || (IsSized && IterDifferable)) -struct BasicTestView : std::ranges::view_base { +struct BasicTestViewOrRange : ViewOrRange { Iter begin_{}; Iter end_{}; - constexpr BasicTestView(Iter b, Iter e) : begin_(b), end_(e) {} + constexpr BasicTestViewOrRange(Iter b, Iter e) : begin_(b), end_(e) {} constexpr Iter begin() { return begin_; } constexpr Iter begin() const { return begin_; } @@ -149,6 +158,10 @@ struct BasicTestView : std::ranges::view_base { } }; +template Sent = sentinel_wrapper, bool IsSized = false> + requires((!IsSized) || (IsSized && IterDifferable)) +using BasicTestView = BasicTestViewOrRange; + template Sent = sentinel_wrapper, bool IsCopyable = true> struct MaybeCopyableAlwaysMoveableView : std::ranges::view_base { Iter begin_; @@ -210,24 +223,9 @@ struct ViewOverNonCopyableIterator : std::ranges::view_base { }; // Ranges + template Sent = sentinel_wrapper, bool IsSized = false> requires((!IsSized) || (IsSized && IterDifferable)) -struct BasicTestRange { - Iter begin_{}; - Iter end_{}; - - constexpr BasicTestRange(Iter b, Iter e) : begin_(b), end_(e) {} - - constexpr Iter begin() { return begin_; } - constexpr Iter begin() const { return begin_; } - constexpr Sent end() { return Sent{end_}; } - constexpr Sent end() const { return Sent{end_}; } - - constexpr auto size() const - requires IsSized - { - return begin_ - end_; - } -}; +using BasicTestRange = BasicTestViewOrRange; #endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H From e2af841d041c43d6598b260d9157161276e6315b Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 31 Jan 2024 17:53:52 -0500 Subject: [PATCH 109/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. use ASSERT_SAME_TYPE where possible. --- .../range.adaptors/range.stride.view/end.pass.cpp | 4 ++-- .../range.stride.view/iterator/ctor.copy.pass.cpp | 12 ++++++------ .../range.stride.view/iterator/iter_move.pass.cpp | 5 +++-- .../range.adaptors/range.stride.view/stride.pass.cpp | 2 +- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp index fc25dfa1488ae..4ceeda39b6cc2 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp @@ -101,7 +101,7 @@ constexpr bool test_default_sentinel() { auto v = UnsimpleUnCommonView{}; auto sv = std::ranges::stride_view(v, 1); - static_assert(std::is_same_v); + ASSERT_SAME_TYPE(std::default_sentinel_t, decltype(sv.end())); } { @@ -111,7 +111,7 @@ constexpr bool test_default_sentinel() { auto v = SimpleUnCommonView{}; auto sv = std::ranges::stride_view(v, 1); - static_assert(std::is_same_v); + ASSERT_SAME_TYPE(std::default_sentinel_t, decltype(sv.end())); } return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp index ad5489a526f84..30bf5b750368c 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp @@ -17,6 +17,7 @@ #include "../types.h" #include "test_iterators.h" +#include "test_macros.h" struct NotSimpleViewIterEnd; template @@ -260,7 +261,7 @@ constexpr bool non_const_iterator_copy_ctor() { StrideView str{NotSimpleViewBeingStrided{}, 5}; // Confirm (5) - static_assert(std::is_same_v); + ASSERT_SAME_TYPE(StrideViewIter, decltype(str.begin())); // Now, do what we wanted the whole time: make sure that we can copy construct a // stride_view::iterator from a stride_view::iterator. The copy @@ -345,18 +346,17 @@ constexpr bool non_const_iterator_copy_ctor() { using StrideViewConstSentinel = std::ranges::sentinel_t; // Confirm (1) and (2) - static_assert(std::is_same_v().base())>); - static_assert( - std::is_same_v().base())>); + ASSERT_SAME_TYPE(NotSimpleViewBeingStridedIterator, decltype(std::declval().base())); + ASSERT_SAME_TYPE(NotSimpleViewBeingStridedConstIterator, decltype(std::declval().base())); // Confirm (3) static_assert(std::convertible_to); static_assert(std::convertible_to); // Confirm (4) - static_assert(std::is_same_v); + ASSERT_SAME_TYPE(StrideViewSentinel, StrideViewConstSentinel); StrideView str{NotSimpleViewBeingStrided{}, 5}; // Confirm (5) - static_assert(std::is_same_v); + ASSERT_SAME_TYPE(StrideViewIter, decltype(str.begin())); // Now, do what we wanted the whole time: make sure that we can copy construct a // stride_view::iterator from a stride_view::iterator. The copy diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp index 3dd4bb90d35f0..25ccf30abe0c5 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp @@ -16,6 +16,7 @@ #include "../types.h" #include "__ranges/access.h" +#include "test_macros.h" template concept iter_moveable = requires(T&& t) { std::ranges::iter_move(t); }; @@ -30,7 +31,7 @@ constexpr bool test() { auto svb = StrideView(View(a, a + 4, &iter_move_counter), 1).begin(); static_assert(iter_moveable>); - static_assert(std::is_same_v); + ASSERT_SAME_TYPE(int, decltype(std::ranges::iter_move(svb))); static_assert(noexcept(std::ranges::iter_move(svb))); auto&& result = std::ranges::iter_move(svb); @@ -52,7 +53,7 @@ constexpr bool test() { auto svb = StrideView(View(a, a + 4, &iter_move_counter), 1).begin(); static_assert(iter_moveable>); - static_assert(std::is_same_v); + ASSERT_SAME_TYPE(int, decltype(std::ranges::iter_move(svb))); static_assert(!noexcept(std::ranges::iter_move(svb))); auto&& result = std::ranges::iter_move(svb); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp index 037b02938b89d..856e08c4649f7 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp @@ -27,7 +27,7 @@ constexpr bool test() { // Make sure that stride member function is noexcept. static_assert(noexcept(str.stride())); // Make sure that the type returned by stride matches what is expected. - static_assert(std::is_same_v, decltype(str.stride())>); + ASSERT_SAME_TYPE(std::ranges::range_difference_t, decltype(str.stride())); // Make sure that we get back a stride equal to the one that we gave in the ctor. assert(str.stride() == 1); From c2345985bfbaad82196b1457bb9ebd8c2ca50a69 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 31 Jan 2024 22:27:13 -0500 Subject: [PATCH 110/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. --- .../range.stride.view/base.pass.cpp | 14 +++-- .../range.stride.view/begin.pass.cpp | 14 +---- .../range.stride.view/end.pass.cpp | 62 ++++++------------- .../range.adaptors/range.stride.view/types.h | 62 ++++++++++++++----- 4 files changed, 72 insertions(+), 80 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp index bfd4ed4940c4e..04af877bf1f1e 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp @@ -18,31 +18,33 @@ #include "types.h" template -concept hasLValueQualifiedBase = requires(T&& t) { t.base(); }; +constexpr bool hasLValueQualifiedBase(T&& t) { + return requires { t.base(); }; +} constexpr bool test() { int buff[] = {1, 2, 3, 4, 5, 6, 7, 8}; - + constexpr int N = 8; { using CopyableInputView = CopyableView>; auto str(std::ranges::stride_view( - CopyableInputView(cpp17_input_iterator(buff), cpp17_input_iterator(buff + 8)), 1)); + CopyableInputView(cpp17_input_iterator(buff), cpp17_input_iterator(buff + N)), 1)); assert(*str.base().begin() == *buff); assert(*(std::move(str)).base().begin() == *buff); ASSERT_SAME_TYPE(decltype(str.base()), CopyableInputView); ASSERT_SAME_TYPE(decltype(std::move(str).base()), CopyableInputView); - static_assert(hasLValueQualifiedBase); + static_assert(hasLValueQualifiedBase(str)); } { using MoveOnlyInputView = MoveOnlyView>; auto str(std::ranges::stride_view( - MoveOnlyInputView(cpp17_input_iterator(buff), cpp17_input_iterator(buff + 8)), 1)); + MoveOnlyInputView(cpp17_input_iterator(buff), cpp17_input_iterator(buff + N)), 1)); assert(*(std::move(str)).base().begin() == *buff); ASSERT_SAME_TYPE(decltype(std::move(str).base()), MoveOnlyInputView); - static_assert(!hasLValueQualifiedBase); + static_assert(!hasLValueQualifiedBase(str)); } return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp index e0dcef0490b94..b2c73db27905c 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp @@ -35,19 +35,7 @@ concept HasOnlyNonConstBegin = HasBegin && !HasConstBegin; template concept HasOnlyConstBegin = HasConstBegin && !HasConstAndNonConstBegin; -struct NoConstView : std::ranges::view_base { - int* begin(); - int* end(); -}; - -struct UnsimpleConstView : std::ranges::view_base { - double* begin(); - int* begin() const; - - double* end(); - int* end() const; -}; -static_assert(HasOnlyNonConstBegin>); +static_assert(HasOnlyNonConstBegin>); static_assert(HasOnlyConstBegin>>); static_assert(HasConstAndNonConstBegin>); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp index 4ceeda39b6cc2..06405a9fc5994 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp @@ -34,39 +34,13 @@ concept HasOnlyNonConstEnd = HasEnd && !HasConstEnd; template concept HasOnlyConstEnd = HasConstEnd && !HasConstAndNonConstEnd; -struct NoConstView : std::ranges::view_base { - int* begin(); - int* end(); -}; - -struct UnsimpleConstView : std::ranges::view_base { - double* begin(); - int* begin() const; - - double* end(); - int* end() const; -}; - -struct UnsimpleUnCommonView : std::ranges::view_base { - double* begin(); - char* begin() const; - - void* end(); - void* end() const; -}; - -struct SimpleUnCommonView : std::ranges::view_base { - int* begin(); - int* begin() const; - - void* end(); - void* end() const; -}; - -static_assert(HasOnlyNonConstEnd>); +static_assert(HasOnlyNonConstEnd>); static_assert(HasOnlyConstEnd>>); static_assert(HasConstAndNonConstEnd>); +static_assert(simple_view); +static_assert(!std::ranges::common_range); + constexpr bool test_non_default_sentinel() { { static_assert(simple_view>); @@ -80,13 +54,13 @@ constexpr bool test_non_default_sentinel() { } { - static_assert(!simple_view); - static_assert(std::ranges::common_range); - static_assert(std::ranges::sized_range); - static_assert(std::ranges::forward_range); + static_assert(!simple_view); + static_assert(std::ranges::common_range); + static_assert(std::ranges::sized_range); + static_assert(std::ranges::forward_range); - auto v = NoConstView{}; - auto sv = std::ranges::stride_view(v, 1); + auto v = UnSimpleNoConstCommonView{}; + auto sv = std::ranges::stride_view(v, 1); static_assert(!std::is_same_v); } return true; @@ -94,22 +68,22 @@ constexpr bool test_non_default_sentinel() { constexpr bool test_default_sentinel() { { - static_assert(!simple_view); - static_assert(!std::ranges::common_range); + static_assert(!simple_view); + static_assert(!std::ranges::common_range); static_assert(std::ranges::sized_range); static_assert(std::ranges::forward_range); - auto v = UnsimpleUnCommonView{}; - auto sv = std::ranges::stride_view(v, 1); + auto v = UnsimpleUnCommonConstView{}; + auto sv = std::ranges::stride_view(v, 1); ASSERT_SAME_TYPE(std::default_sentinel_t, decltype(sv.end())); } { - static_assert(simple_view); - static_assert(!std::ranges::common_range); + static_assert(simple_view); + static_assert(!std::ranges::common_range); - auto v = SimpleUnCommonView{}; - auto sv = std::ranges::stride_view(v, 1); + auto v = SimpleUnCommonConstView{}; + auto sv = std::ranges::stride_view(v, 1); ASSERT_SAME_TYPE(std::default_sentinel_t, decltype(sv.end())); } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index 70d0a4d1b300a..de329bfa77aee 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -14,6 +14,7 @@ #include #include "__iterator/concepts.h" +#include "__ranges/common_view.h" #include "test_iterators.h" #include "test_range.h" @@ -69,6 +70,25 @@ struct SizedInputIterator : InputIterBase { static_assert(std::input_iterator); static_assert(std::sized_sentinel_for); +// Don't move/hold the iterator itself, copy/hold the base +// of that iterator and reconstruct the iterator on demand. +// May result in aliasing (if, e.g., Iterator is an iterator +// over int *). +template Sent = sentinel_wrapper> +struct ViewOverNonCopyableIterator : std::ranges::view_base { + constexpr explicit ViewOverNonCopyableIterator(Iter it, Sent sent) : it_(base(it)), sent_(base(sent)) {} + + ViewOverNonCopyableIterator(ViewOverNonCopyableIterator&&) = default; + ViewOverNonCopyableIterator& operator=(ViewOverNonCopyableIterator&&) = default; + + constexpr Iter begin() const { return Iter(it_); } + constexpr Sent end() const { return Sent(sent_); } + +private: + decltype(base(std::declval())) it_; + decltype(base(std::declval())) sent_; +}; + // Put IterMoveIterSwapTestRangeIterator in a namespace to test ADL of CPOs iter_swap and iter_move // (see iter_swap.pass.cpp and iter_move.pass.cpp). namespace adl { @@ -203,25 +223,33 @@ template Sent = sentinel_wrap using MoveOnlyView = MaybeCopyableAlwaysMoveableView; static_assert(!std::copyable>>); -// Don't move/hold the iterator itself, copy/hold the base -// of that iterator and reconstruct the iterator on demand. -// May result in aliasing (if, e.g., Iterator is an iterator -// over int *). -template Sent = sentinel_wrapper> -struct ViewOverNonCopyableIterator : std::ranges::view_base { - constexpr explicit ViewOverNonCopyableIterator(Iter it, Sent sent) : it_(base(it)), sent_(base(sent)) {} - - ViewOverNonCopyableIterator(ViewOverNonCopyableIterator&&) = default; - ViewOverNonCopyableIterator& operator=(ViewOverNonCopyableIterator&&) = default; - - constexpr Iter begin() const { return Iter(it_); } - constexpr Sent end() const { return Sent(sent_); } - -private: - decltype(base(std::declval())) it_; - decltype(base(std::declval())) sent_; +template +struct MaybeConstCommonSimpleView : std::ranges::view_base { + int* begin(); + int* begin() const + requires(IsConst && IsSimple); + double* begin() const + requires(IsConst && !IsSimple); + + int* end() + requires(IsCommon); + void* end() + requires(!IsCommon); + + int* end() const + requires(IsConst && IsCommon && IsSimple); + double* end() const + requires(IsConst && IsCommon && !IsSimple); + + void* end() const + requires(IsConst && !IsCommon); }; +using UnSimpleNoConstCommonView = MaybeConstCommonSimpleView; +using UnsimpleConstView = MaybeConstCommonSimpleView; +using UnsimpleUnCommonConstView = MaybeConstCommonSimpleView; +using SimpleUnCommonConstView = MaybeConstCommonSimpleView; + // Ranges template Sent = sentinel_wrapper, bool IsSized = false> From 6013c9c9bb76c7de004df24062d0d21206569157 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 31 Jan 2024 23:23:10 -0500 Subject: [PATCH 111/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Make clang-format happy. --- .../std/ranges/range.adaptors/range.stride.view/base.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp index 04af877bf1f1e..c335c038eea4c 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp @@ -23,7 +23,7 @@ constexpr bool hasLValueQualifiedBase(T&& t) { } constexpr bool test() { - int buff[] = {1, 2, 3, 4, 5, 6, 7, 8}; + int buff[] = {1, 2, 3, 4, 5, 6, 7, 8}; constexpr int N = 8; { using CopyableInputView = CopyableView>; From 759f67c82abb989e9eedff82096be1e470b3e5c4 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 2 Feb 2024 18:26:44 -0500 Subject: [PATCH 112/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Relocate stride view in ranges.inc; update and test enable borrowed range. --- libcxx/include/__ranges/stride_view.h | 4 ++++ libcxx/modules/std/ranges.inc | 18 +++++++++--------- ...e.verify.cpp => borrowing.compile.pass.cpp} | 17 ++++++----------- 3 files changed, 19 insertions(+), 20 deletions(-) rename libcxx/test/std/ranges/range.adaptors/range.stride.view/{enable_borrowed_range.verify.cpp => borrowing.compile.pass.cpp} (53%) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 561e2914c1642..8b6deee6bfcca 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -13,6 +13,7 @@ #include "__concepts/relation.h" #include "__functional/ranges_operations.h" #include "__iterator/indirectly_comparable.h" +#include "__ranges/enable_borrowed_range.h" #include <__config> #include <__compare/three_way_comparable.h> @@ -379,6 +380,9 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> } }; // class stride_view::__iterator +template +inline constexpr bool enable_borrowed_range> = enable_borrowed_range; + namespace views { namespace __stride { struct __fn { diff --git a/libcxx/modules/std/ranges.inc b/libcxx/modules/std/ranges.inc index 020f2a1de21f4..f93baa66e3af1 100644 --- a/libcxx/modules/std/ranges.inc +++ b/libcxx/modules/std/ranges.inc @@ -293,15 +293,6 @@ export namespace std { using std::ranges::views::zip; } // namespace views -#if _LIBCPP_STD_VER >= 23 - // [range.stride], stride view - using std::ranges::stride_view; - - namespace views { - using std::ranges::views::stride; - } // namespace views -#endif // _LIBCPP_STD_VER >= 23 - #if 0 // [range.zip.transform], zip transform view using std::ranges::zip_transform_view; @@ -350,6 +341,15 @@ export namespace std { } #endif // _LIBCPP_STD_VER >= 23 +#if _LIBCPP_STD_VER >= 23 + // [range.stride], stride view + using std::ranges::stride_view; + + namespace views { + using std::ranges::views::stride; + } // namespace views +#endif // _LIBCPP_STD_VER >= 23 + #if 0 using std::ranges::cartesian_product_view; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/borrowing.compile.pass.cpp similarity index 53% rename from libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.verify.cpp rename to libcxx/test/std/ranges/range.adaptors/range.stride.view/borrowing.compile.pass.cpp index 142c4d126fa6d..c1f214e208fa0 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/enable_borrowed_range.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/borrowing.compile.pass.cpp @@ -9,19 +9,14 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 // expected-no-diagnostics -// template -// inline constexpr bool enable_borrowed_range> = false; +// template +// inline constexpr bool enable_borrowed_range> = ranges::enable_borrowed_range; #include #include -// The stride_view is not one of those range adaptors that (under any circumstances) -// is enabled as a borrowable range by default. In other words, we will have to make -// a positive test case explicit. +#include "types.h" +#include "test_range.h" -template <> -inline constexpr bool - std::ranges::enable_borrowed_range>>> = true; - -static_assert(!std::ranges::enable_borrowed_range< std::ranges::stride_view>>); -static_assert(std::ranges::enable_borrowed_range< std::ranges::stride_view>>>); +static_assert(std::ranges::enable_borrowed_range< std::ranges::stride_view>); +static_assert(!std::ranges::enable_borrowed_range< std::ranges::stride_view>); From 89892e98a89ce360cc0edc2f137f06019d7a311b Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 9 Feb 2024 21:04:19 -0500 Subject: [PATCH 113/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix misnamed template parameter. Signed-off-by: Will Hawkins --- libcxx/include/__ranges/stride_view.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 8b6deee6bfcca..a76b4d4d794c3 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -380,8 +380,8 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> } }; // class stride_view::__iterator -template -inline constexpr bool enable_borrowed_range> = enable_borrowed_range; +template +inline constexpr bool enable_borrowed_range> = enable_borrowed_range<_V>; namespace views { namespace __stride { From 35dba876ff1fc7a34223c53e0d6ba1fbf4cd1c49 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 9 Feb 2024 22:20:16 -0500 Subject: [PATCH 114/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add macro push/pop to stride_view.h. Signed-off-by: Will Hawkins --- libcxx/include/__ranges/stride_view.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index a76b4d4d794c3..d18b236e83ef2 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -39,6 +39,9 @@ # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER >= 23 @@ -410,4 +413,6 @@ inline constexpr auto stride = __stride::__fn{}; _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #endif // _LIBCPP___RANGES_STRIDE_VIEW_H From f0e07d6a91241ef89cbc5721ff9cd300e52046b3 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 9 Feb 2024 23:02:12 -0500 Subject: [PATCH 115/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Make sure not to use reserved names for templates in stride_view.h. Signed-off-by: Will Hawkins --- libcxx/include/__ranges/stride_view.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index d18b236e83ef2..b9c2a2d8c842f 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -383,8 +383,8 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> } }; // class stride_view::__iterator -template -inline constexpr bool enable_borrowed_range> = enable_borrowed_range<_V>; +template +inline constexpr bool enable_borrowed_range> = enable_borrowed_range<_Tp>; namespace views { namespace __stride { From ce6c3ce19982a9b4c790c4b49dba57012401e1a7 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 9 Feb 2024 23:25:36 -0500 Subject: [PATCH 116/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Explicitly include vector. Signed-off-by: Will Hawkins --- .../range.adaptors/range.stride.view/iterator/operator.pass.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index 44dd560a38d1a..dd8b9e9127e76 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "../types.h" #include "__compare/three_way_comparable.h" From c12b89bee677ba4f4db2bac2bc9e979f863c963c Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 3 May 2024 23:13:02 -0400 Subject: [PATCH 117/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Rebase. --- .../ranges/range.adaptors/range.stride.view/adaptor.pass.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index cef16b263c5e2..9d0349831175a 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -17,11 +17,6 @@ #include "test_iterators.h" #include "types.h" -template -concept CanBePiped = requires(View&& view, T&& t) { - { std::forward(view) | std::forward(t) }; -}; - constexpr BasicTestView> make_input_view(int* begin, int* end) { return BasicTestView>(cpp17_input_iterator(begin), cpp17_input_iterator(end)); } From 9571092b7ae1b826d26f2388b26eceb6b093b7f4 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 3 May 2024 23:24:24 -0400 Subject: [PATCH 118/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix formatting. --- libcxx/include/__ranges/stride_view.h | 4 ++-- libcxx/modules/std/ranges.inc | 2 +- .../range.adaptors/range.stride.view/concept.verify.cpp | 4 +--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index b9c2a2d8c842f..f8c175b534024 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -391,8 +391,8 @@ namespace __stride { struct __fn { template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) const - noexcept(noexcept(/**/ stride_view{std::forward<_Range>(__range), __n})) - -> decltype(/*--*/ stride_view{std::forward<_Range>(__range), __n}) { + noexcept(noexcept(/**/ stride_view{ + std::forward<_Range>(__range), __n})) -> decltype(/*--*/ stride_view{std::forward<_Range>(__range), __n}) { return /*-------------*/ stride_view(std::forward<_Range>(__range), __n); } diff --git a/libcxx/modules/std/ranges.inc b/libcxx/modules/std/ranges.inc index f93baa66e3af1..ba9f09d9ab63e 100644 --- a/libcxx/modules/std/ranges.inc +++ b/libcxx/modules/std/ranges.inc @@ -347,7 +347,7 @@ export namespace std { namespace views { using std::ranges::views::stride; - } // namespace views + } // namespace views #endif // _LIBCPP_STD_VER >= 23 #if 0 diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp index 527651b66fb64..a17960017ce1c 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp @@ -18,9 +18,7 @@ #include "types.h" template D> -concept CanStrideView = requires { - std::ranges::stride_view{I{}, D}; -}; +concept CanStrideView = requires { std::ranges::stride_view{I{}, D}; }; // Ensure that the InputRangeNotIndirectlyReadable is a valid range. static_assert(std::ranges::range); From 3f4512c17ae2db60ac3539355954447a415a9304 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 3 May 2024 23:37:23 -0400 Subject: [PATCH 119/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix feature table. --- libcxx/docs/FeatureTestMacroTable.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst index 77f183237dab5..192549b048a1d 100644 --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -386,10 +386,10 @@ Status ---------------------------------------------------------- ----------------- ``__cpp_lib_ranges_slide`` *unimplemented* ---------------------------------------------------------- ----------------- - ``__cpp_lib_ranges_stride`` ``202207L`` - ---------------------------------------------------------- ----------------- ``__cpp_lib_ranges_starts_ends_with`` ``202106L`` ---------------------------------------------------------- ----------------- + ``__cpp_lib_ranges_stride`` ``202207L`` + ---------------------------------------------------------- ----------------- ``__cpp_lib_ranges_to_container`` ``202202L`` ---------------------------------------------------------- ----------------- ``__cpp_lib_ranges_zip`` *unimplemented* From a1d979c58ac6cadd5d77b2feb5065301555c83a4 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sat, 4 May 2024 00:57:38 -0400 Subject: [PATCH 120/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix unused variables and (hopefully) missing __assert include. --- libcxx/include/__ranges/stride_view.h | 12 ++--- .../iterator/ctor.copy.pass.cpp | 54 +++++++++---------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index f8c175b534024..25db3b2b03fcf 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -10,28 +10,28 @@ #ifndef _LIBCPP___RANGES_STRIDE_VIEW_H #define _LIBCPP___RANGES_STRIDE_VIEW_H -#include "__concepts/relation.h" -#include "__functional/ranges_operations.h" -#include "__iterator/indirectly_comparable.h" -#include "__ranges/enable_borrowed_range.h" -#include <__config> - +#include <__assert> #include <__compare/three_way_comparable.h> #include <__concepts/convertible_to.h> #include <__concepts/derived_from.h> #include <__concepts/equality_comparable.h> +#include <__concepts/relation.h> +#include <__config> #include <__functional/bind_back.h> #include <__functional/operations.h> +#include <__functional/ranges_operations.h> #include <__iterator/advance.h> #include <__iterator/concepts.h> #include <__iterator/default_sentinel.h> #include <__iterator/distance.h> +#include <__iterator/indirectly_comparable.h> #include <__iterator/iter_move.h> #include <__iterator/iter_swap.h> #include <__iterator/iterator_traits.h> #include <__ranges/access.h> #include <__ranges/all.h> #include <__ranges/concepts.h> +#include <__ranges/enable_borrowed_range.h> #include <__ranges/range_adaptor.h> #include <__ranges/view_interface.h> diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp index 30bf5b750368c..d505458e5ea46 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp @@ -187,16 +187,16 @@ constexpr bool non_const_iterator_copy_ctor() { // like it is possible copy construct the stride view's iterator (the move-only requirement comes from // a move of the current between the copied-from iterator to the copied-to iterator). using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; - using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; - using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; using StrideView = std::ranges::stride_view; using StrideViewIter = std::ranges::iterator_t; using StrideViewConstIter = std::ranges::iterator_t; - using StrideViewSentinel = std::ranges::sentinel_t; - using StrideViewConstSentinel = std::ranges::sentinel_t; + //using StrideViewSentinel = std::ranges::sentinel_t; + //using StrideViewConstSentinel = std::ranges::sentinel_t; static_assert(std::convertible_to); static_assert(std::constructible_from); @@ -207,16 +207,16 @@ constexpr bool non_const_iterator_copy_ctor() { // like it is possible copy construct the stride view's iterator (the move-only requirement comes from // a move of the current between the copied-from iterator to the copied-to iterator). using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; - using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; - using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; using StrideView = std::ranges::stride_view; using StrideViewIter = std::ranges::iterator_t; using StrideViewConstIter = std::ranges::iterator_t; - using StrideViewSentinel = std::ranges::sentinel_t; - using StrideViewConstSentinel = std::ranges::sentinel_t; + //using StrideViewSentinel = std::ranges::sentinel_t; + //using StrideViewConstSentinel = std::ranges::sentinel_t; static_assert(std::convertible_to); static_assert(std::constructible_from); @@ -226,16 +226,16 @@ constexpr bool non_const_iterator_copy_ctor() { // Stride over non-simple view over whose iterators are not convertible -- should not be able // to copy construct the stride view's iterator. using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; - using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; - using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; using StrideView = std::ranges::stride_view; using StrideViewIter = std::ranges::iterator_t; using StrideViewConstIter = std::ranges::iterator_t; - using StrideViewSentinel = std::ranges::sentinel_t; - using StrideViewConstSentinel = std::ranges::sentinel_t; + //using StrideViewSentinel = std::ranges::sentinel_t; + //using StrideViewConstSentinel = std::ranges::sentinel_t; static_assert(!std::convertible_to); static_assert(!std::constructible_from); @@ -246,15 +246,15 @@ constexpr bool non_const_iterator_copy_ctor() { // to copy construct the stride view's iterator. using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; - using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; using StrideView = std::ranges::stride_view; using StrideViewIter = std::ranges::iterator_t; using StrideViewConstIter = std::ranges::iterator_t; - using StrideViewSentinel = std::ranges::sentinel_t; - using StrideViewConstSentinel = std::ranges::sentinel_t; + //using StrideViewSentinel = std::ranges::sentinel_t; + //using StrideViewConstSentinel = std::ranges::sentinel_t; static_assert(std::convertible_to); static_assert(std::convertible_to); @@ -276,16 +276,16 @@ constexpr bool non_const_iterator_copy_ctor() { // like it is possible copy construct the stride view's iterator (the move-only requirement comes from // a move of the current between the copied-from iterator to the copied-to iterator). using NotSimpleViewBeingStrided = NotSimpleViewDifferentBegin; - using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; - using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; using StrideView = std::ranges::stride_view; using StrideViewIter = std::ranges::iterator_t; using StrideViewConstIter = std::ranges::iterator_t; - using StrideViewSentinel = std::ranges::sentinel_t; - using StrideViewConstSentinel = std::ranges::sentinel_t; + //using StrideViewSentinel = std::ranges::sentinel_t; + //using StrideViewConstSentinel = std::ranges::sentinel_t; static_assert(std::convertible_to); static_assert(std::constructible_from); @@ -296,16 +296,16 @@ constexpr bool non_const_iterator_copy_ctor() { // like it is possible copy construct the stride view's iterator (the move-only requirement comes from // a move of the current between the copied-from iterator to the copied-to iterator). using NotSimpleViewBeingStrided = NotSimpleViewDifferentBegin; - using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; - using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; using StrideView = std::ranges::stride_view; using StrideViewIter = std::ranges::iterator_t; using StrideViewConstIter = std::ranges::iterator_t; - using StrideViewSentinel = std::ranges::sentinel_t; - using StrideViewConstSentinel = std::ranges::sentinel_t; + //using StrideViewSentinel = std::ranges::sentinel_t; + //using StrideViewConstSentinel = std::ranges::sentinel_t; static_assert(std::convertible_to); static_assert(std::constructible_from); @@ -315,16 +315,16 @@ constexpr bool non_const_iterator_copy_ctor() { // Stride over non-simple view over whose iterators are not convertible -- should not be able // to copy construct the stride view's iterator. using NotSimpleViewBeingStrided = NotSimpleViewDifferentBegin; - using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; - using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; using StrideView = std::ranges::stride_view; using StrideViewIter = std::ranges::iterator_t; using StrideViewConstIter = std::ranges::iterator_t; - using StrideViewSentinel = std::ranges::sentinel_t; - using StrideViewConstSentinel = std::ranges::sentinel_t; + //using StrideViewSentinel = std::ranges::sentinel_t; + //using StrideViewConstSentinel = std::ranges::sentinel_t; static_assert(!std::convertible_to); static_assert(!std::constructible_from); From 266713c63828aca86e19e4581afdc834a30f278b Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sat, 4 May 2024 01:02:19 -0400 Subject: [PATCH 121/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix formatting. --- .../iterator/ctor.copy.pass.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp index d505458e5ea46..cea97fe49ecef 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp @@ -186,7 +186,7 @@ constexpr bool non_const_iterator_copy_ctor() { // Stride over non-simple view over whose iterators are copy convertible -- should look (statically) // like it is possible copy construct the stride view's iterator (the move-only requirement comes from // a move of the current between the copied-from iterator to the copied-to iterator). - using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; + using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; @@ -206,7 +206,7 @@ constexpr bool non_const_iterator_copy_ctor() { // Stride over non-simple view over whose iterators are move convertible -- should look (statically) // like it is possible copy construct the stride view's iterator (the move-only requirement comes from // a move of the current between the copied-from iterator to the copied-to iterator). - using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; + using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; @@ -225,7 +225,7 @@ constexpr bool non_const_iterator_copy_ctor() { { // Stride over non-simple view over whose iterators are not convertible -- should not be able // to copy construct the stride view's iterator. - using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; + using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; @@ -244,8 +244,8 @@ constexpr bool non_const_iterator_copy_ctor() { { // Stride over non-simple view over whose iterators are not convertible -- should not be able // to copy construct the stride view's iterator. - using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; - using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; + using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; using StrideView = std::ranges::stride_view; @@ -275,7 +275,7 @@ constexpr bool non_const_iterator_copy_ctor() { // Stride over non-simple view over whose iterators are copy convertible -- should look (statically) // like it is possible copy construct the stride view's iterator (the move-only requirement comes from // a move of the current between the copied-from iterator to the copied-to iterator). - using NotSimpleViewBeingStrided = NotSimpleViewDifferentBegin; + using NotSimpleViewBeingStrided = NotSimpleViewDifferentBegin; //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; @@ -295,7 +295,7 @@ constexpr bool non_const_iterator_copy_ctor() { // Stride over non-simple view over whose iterators are move convertible -- should look (statically) // like it is possible copy construct the stride view's iterator (the move-only requirement comes from // a move of the current between the copied-from iterator to the copied-to iterator). - using NotSimpleViewBeingStrided = NotSimpleViewDifferentBegin; + using NotSimpleViewBeingStrided = NotSimpleViewDifferentBegin; //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; @@ -314,7 +314,7 @@ constexpr bool non_const_iterator_copy_ctor() { { // Stride over non-simple view over whose iterators are not convertible -- should not be able // to copy construct the stride view's iterator. - using NotSimpleViewBeingStrided = NotSimpleViewDifferentBegin; + using NotSimpleViewBeingStrided = NotSimpleViewDifferentBegin; //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; From 8c6f3c0e04547b17782b72e81cafc3e12d665ee5 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Tue, 7 May 2024 01:49:51 -0400 Subject: [PATCH 122/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix dereference test unsupported tag. --- .../range.stride.view/iterator/dereference.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp index 40400cc91137c..1c44078e52403 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// UNSUPPORTED: libcpp-hardening-mode=none +// UNSUPPORTED: !libcpp-hardening-mode=debug // XFAIL: availability-verbose_abort-missing // constexpr decltype(auto) operator*() const From 314dc741fa935fa468316f0cc62060aae10f55fc Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Thu, 9 May 2024 22:30:21 -0400 Subject: [PATCH 123/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Address feedback from @EricWF. --- .../ranges/range.adaptors/range.stride.view/adaptor.pass.cpp | 2 -- .../range.adaptors/range.stride.view/borrowing.compile.pass.cpp | 1 - 2 files changed, 3 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index 9d0349831175a..ea7fd588fd81f 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -12,8 +12,6 @@ #include -#include "__iterator/concepts.h" -#include "__ranges/concepts.h" #include "test_iterators.h" #include "types.h" diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/borrowing.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/borrowing.compile.pass.cpp index c1f214e208fa0..4c2d0efb774b2 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/borrowing.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/borrowing.compile.pass.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// expected-no-diagnostics // template // inline constexpr bool enable_borrowed_range> = ranges::enable_borrowed_range; From 822030df8c4293fae91545ac89e041dffdafb11a Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sat, 18 May 2024 00:55:41 -0400 Subject: [PATCH 124/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix issue with version file. --- libcxx/include/version | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libcxx/include/version b/libcxx/include/version index 5e3e5b98e3bd6..d6cebfe182c4b 100644 --- a/libcxx/include/version +++ b/libcxx/include/version @@ -212,10 +212,7 @@ __cpp_lib_ranges_repeat 202207L __cpp_lib_ranges_slide 202202L __cpp_lib_ranges_starts_ends_with 202106L __cpp_lib_ranges_stride 202207L -__cpp_lib_ranges_to_container 202202L - - - +__cpp_lib_ranges_to_container 202202L __cpp_lib_ranges_zip 202110L __cpp_lib_ratio 202306L __cpp_lib_raw_memory_algorithms 201606L From 30466349ac5650692cf24cc06f8a403f2774f55d Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 24 Jun 2024 23:31:33 -0400 Subject: [PATCH 125/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Updating tests based on feedback. Signed-off-by: Will Hawkins --- libcxx/include/__ranges/stride_view.h | 6 +-- .../base.nodiscard.verify.cpp | 45 +++++++++++++++++++ .../range.stride.view/iterator/base.pass.cpp | 12 ++++- .../iterator/operator.pass.cpp | 1 + .../range.adaptors/range.stride.view/types.h | 28 +++++++++--- 5 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 25db3b2b03fcf..8403797a1d481 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -84,7 +84,7 @@ class stride_view : public view_interface> { return __stride_; } - _LIBCPP_NODISCARD _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr auto begin() + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr auto begin() requires(!__simple_view<_View>) { return __iterator(this, ranges::begin(__base_), 0); @@ -391,8 +391,8 @@ namespace __stride { struct __fn { template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) const - noexcept(noexcept(/**/ stride_view{ - std::forward<_Range>(__range), __n})) -> decltype(/*--*/ stride_view{std::forward<_Range>(__range), __n}) { + noexcept(noexcept(/**/ stride_view{std::forward<_Range>(__range), __n})) + -> decltype(/*--*/ stride_view{std::forward<_Range>(__range), __n}) { return /*-------------*/ stride_view(std::forward<_Range>(__range), __n); } diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp new file mode 100644 index 0000000000000..bf6527d99f022 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// Test that appropriate (member) functions are properly marked no_discard + +#include + +#include "../../../../std/ranges/range.adaptors/range.stride.view/types.h" + +void test() { + const int range[] = {1, 2, 3}; + + std::views::stride( // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + range, 2); + range | std::views::stride( // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + 2); + std::views::all | // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::views::stride( + 1); + + auto sv = std::views::stride(range, 2); + const auto const_sv = std::views::stride(range, 2); + auto unsimple_sv = std::views::stride(UnsimpleConstView{}, 2); + + const_sv.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::move(sv).base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + const_sv.stride(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + const_sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + unsimple_sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + const_sv.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + unsimple_sv.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + + sv.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + const_sv.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp index f007ffcf84d6e..1c199eb990803 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp @@ -46,11 +46,21 @@ constexpr bool base_const() { return true; } + +bool base_move() { + auto view = BasicTestView{SizedInputIterator(), SizedInputIterator()}; + auto sv = std::ranges::stride_view>(view, 1); + [[maybe_unused]] auto result = sv.begin().base(); + assert(result.move_counter==1); + assert(result.copy_counter==0); + return true; +} + int main(int, char**) { base_noexcept(); static_assert(base_noexcept()); base_const(); static_assert(base_const()); - + base_move(); return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index dd8b9e9127e76..ec9b6dba82c32 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -33,6 +33,7 @@ #include "../types.h" #include "__compare/three_way_comparable.h" #include "__concepts/equality_comparable.h" +#include "__concepts/same_as.h" #include "__iterator/concepts.h" #include "__iterator/default_sentinel.h" #include "__iterator/distance.h" diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index de329bfa77aee..ac0f65f4c02fc 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -9,10 +9,12 @@ #ifndef TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H #define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H +#include #include #include #include +#include "__concepts/constructible.h" #include "__iterator/concepts.h" #include "__ranges/common_view.h" #include "test_iterators.h" @@ -21,7 +23,7 @@ // Concepts template -concept IterDifferable = requires(Iter& t) { t - t; }; +concept IterDifferable = std::invocable,Iter, Iter>; // Iterators @@ -33,15 +35,26 @@ struct InputIterBase { using value_type = typename std::iterator_traits::value_type; using difference_type = typename std::iterator_traits::difference_type; + int copy_counter = 0; + int move_counter = 0; + Iter value_{}; - constexpr InputIterBase() = default; - constexpr InputIterBase(const InputIterBase&) = default; - constexpr InputIterBase(InputIterBase&&) = default; - constexpr InputIterBase& operator=(const InputIterBase& other) = default; - constexpr InputIterBase& operator=(InputIterBase&& other) = default; + constexpr InputIterBase() = default; constexpr explicit InputIterBase(Iter value) : value_(value) {} + constexpr InputIterBase(const InputIterBase& other) noexcept { + copy_counter++; + value_ = other.value_; + } + + constexpr InputIterBase(InputIterBase&& other) noexcept { + move_counter++; + value_ = std::move(other.value_); + } + constexpr InputIterBase& operator=(const InputIterBase& other) = default; + constexpr InputIterBase& operator=(InputIterBase&& other) = default; + constexpr value_type operator*() const { return *value_; } constexpr Derived& operator++() { value_++; @@ -60,7 +73,7 @@ struct InputIterBase { } }; -struct UnsizedInputIterator : InputIterBase {}; +struct UnsizedInputIterator : InputIterBase {}; static_assert(std::input_iterator); static_assert(!std::sized_sentinel_for); @@ -249,6 +262,7 @@ using UnSimpleNoConstCommonView = MaybeConstCommonSimpleView using UnsimpleConstView = MaybeConstCommonSimpleView; using UnsimpleUnCommonConstView = MaybeConstCommonSimpleView; using SimpleUnCommonConstView = MaybeConstCommonSimpleView; +using SimpleCommonConstView = MaybeConstCommonSimpleView; // Ranges From 4bb05d9c0738ab98d36fdb9ebc67701e9ad87d6a Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Tue, 25 Jun 2024 23:11:02 -0400 Subject: [PATCH 126/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add check for whether iterator::base is move/copy Signed-off-by: Will Hawkins --- .../range.stride.view/iterator/base.pass.cpp | 56 ++++++++++++++-- .../range.adaptors/range.stride.view/types.h | 67 +++++++++++-------- 2 files changed, 89 insertions(+), 34 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp index 1c199eb990803..c4fc1db4da581 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp @@ -48,19 +48,65 @@ constexpr bool base_const() { } bool base_move() { - auto view = BasicTestView{SizedInputIterator(), SizedInputIterator()}; - auto sv = std::ranges::stride_view>(view, 1); - [[maybe_unused]] auto result = sv.begin().base(); - assert(result.move_counter==1); - assert(result.copy_counter==0); + // Keep track of how many times the original iterator is moved + // and/or copied during the test. + int move_counter = 0; + int copy_counter = 0; + + auto start = SizedInputIterator(); + start.move_counter = &move_counter; + start.copy_counter = ©_counter; + auto stop = SizedInputIterator(); + + auto view = BasicTestView{start, stop}; + auto sv = std::ranges::stride_view>(view, 1); + auto svi = sv.begin(); + + // Reset the move/copy counters so that they reflect *only* whether the + // base() member function moved or copied the iterator. + move_counter = 0; + copy_counter = 0; + [[maybe_unused]] auto result = std::move(svi).base(); + + // Ensure that base std::move'd the iterator. + assert(*result.move_counter == 1); + assert(*result.copy_counter == 0); + return true; +} + +bool base_copy() { + // See above. + int move_counter = 0; + int copy_counter = 0; + auto start = SizedInputIterator(); + + start.move_counter = &move_counter; + start.copy_counter = ©_counter; + auto stop = SizedInputIterator(); + + auto view = BasicTestView{start, stop}; + auto sv = std::ranges::stride_view>(view, 1); + [[maybe_unused]] auto svi = sv.begin(); + + // See above. + move_counter = 0; + copy_counter = 0; + [[maybe_unused]] const SizedInputIterator& result = svi.base(); + + // Ensure that base did _not_ std::move'd the iterator. + assert(*result.move_counter == 0); + assert(*result.copy_counter == 0); return true; } int main(int, char**) { + /* base_noexcept(); static_assert(base_noexcept()); base_const(); static_assert(base_const()); + */ base_move(); + base_copy(); return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index ac0f65f4c02fc..6f73722ee54de 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -23,10 +23,12 @@ // Concepts template -concept IterDifferable = std::invocable,Iter, Iter>; +concept IterDifferable = std::invocable, Iter, Iter>; // Iterators +// The base for an input iterator that keeps a count of the times that it is +// moved and copied. template requires((!IsSized) || (IsSized && IterDifferable)) struct InputIterBase { @@ -35,25 +37,33 @@ struct InputIterBase { using value_type = typename std::iterator_traits::value_type; using difference_type = typename std::iterator_traits::difference_type; - int copy_counter = 0; - int move_counter = 0; + int* move_counter = nullptr; + int* copy_counter = nullptr; Iter value_{}; - constexpr InputIterBase() = default; + constexpr InputIterBase() = default; constexpr explicit InputIterBase(Iter value) : value_(value) {} constexpr InputIterBase(const InputIterBase& other) noexcept { - copy_counter++; + copy_counter = other.copy_counter; + move_counter = other.move_counter; + if (copy_counter != nullptr) { + (*copy_counter)++; + } value_ = other.value_; } constexpr InputIterBase(InputIterBase&& other) noexcept { - move_counter++; + copy_counter = other.copy_counter; + move_counter = other.move_counter; + if (move_counter != nullptr) { + (*move_counter)++; + } value_ = std::move(other.value_); } constexpr InputIterBase& operator=(const InputIterBase& other) = default; - constexpr InputIterBase& operator=(InputIterBase&& other) = default; + constexpr InputIterBase& operator=(InputIterBase&& other) = default; constexpr value_type operator*() const { return *value_; } constexpr Derived& operator++() { @@ -73,34 +83,14 @@ struct InputIterBase { } }; -struct UnsizedInputIterator : InputIterBase {}; -static_assert(std::input_iterator); -static_assert(!std::sized_sentinel_for); - +// In input iterator that is sized. struct SizedInputIterator : InputIterBase { using InputIterBase::InputIterBase; }; static_assert(std::input_iterator); static_assert(std::sized_sentinel_for); -// Don't move/hold the iterator itself, copy/hold the base -// of that iterator and reconstruct the iterator on demand. -// May result in aliasing (if, e.g., Iterator is an iterator -// over int *). -template Sent = sentinel_wrapper> -struct ViewOverNonCopyableIterator : std::ranges::view_base { - constexpr explicit ViewOverNonCopyableIterator(Iter it, Sent sent) : it_(base(it)), sent_(base(sent)) {} - - ViewOverNonCopyableIterator(ViewOverNonCopyableIterator&&) = default; - ViewOverNonCopyableIterator& operator=(ViewOverNonCopyableIterator&&) = default; - - constexpr Iter begin() const { return Iter(it_); } - constexpr Sent end() const { return Sent(sent_); } - -private: - decltype(base(std::declval())) it_; - decltype(base(std::declval())) sent_; -}; +// Views // Put IterMoveIterSwapTestRangeIterator in a namespace to test ADL of CPOs iter_swap and iter_move // (see iter_swap.pass.cpp and iter_move.pass.cpp). @@ -264,6 +254,25 @@ using UnsimpleUnCommonConstView = MaybeConstCommonSimpleView using SimpleUnCommonConstView = MaybeConstCommonSimpleView; using SimpleCommonConstView = MaybeConstCommonSimpleView; +// Don't move/hold the iterator itself, copy/hold the base +// of that iterator and reconstruct the iterator on demand. +// May result in aliasing (if, e.g., Iterator is an iterator +// over int *). +template Sent = sentinel_wrapper> +struct ViewOverNonCopyableIterator : std::ranges::view_base { + constexpr explicit ViewOverNonCopyableIterator(Iter it, Sent sent) : it_(base(it)), sent_(base(sent)) {} + + ViewOverNonCopyableIterator(ViewOverNonCopyableIterator&&) = default; + ViewOverNonCopyableIterator& operator=(ViewOverNonCopyableIterator&&) = default; + + constexpr Iter begin() const { return Iter(it_); } + constexpr Sent end() const { return Sent(sent_); } + +private: + decltype(base(std::declval())) it_; + decltype(base(std::declval())) sent_; +}; + // Ranges template Sent = sentinel_wrapper, bool IsSized = false> From 774bb13d67643cd8f1e839eb851169ca3d298894 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Tue, 25 Jun 2024 23:20:17 -0400 Subject: [PATCH 127/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. clang-format Signed-off-by: Will Hawkins --- .../range.stride.view/base.nodiscard.verify.cpp | 15 ++++++++------- .../range.stride.view/concept.verify.cpp | 4 +++- .../range.stride.view/iterator/base.pass.cpp | 6 +++--- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp index bf6527d99f022..6599a750e44fc 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp @@ -18,12 +18,13 @@ void test() { const int range[] = {1, 2, 3}; std::views::stride( // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - range, 2); - range | std::views::stride( // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - 2); + range, + 2); + range | + std::views::stride( // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + 2); std::views::all | // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::views::stride( - 1); + std::views::stride(1); auto sv = std::views::stride(range, 2); const auto const_sv = std::views::stride(range, 2); @@ -34,10 +35,10 @@ void test() { const_sv.stride(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - const_sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + const_sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} unsimple_sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - const_sv.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + const_sv.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} unsimple_sv.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sv.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp index a17960017ce1c..527651b66fb64 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp @@ -18,7 +18,9 @@ #include "types.h" template D> -concept CanStrideView = requires { std::ranges::stride_view{I{}, D}; }; +concept CanStrideView = requires { + std::ranges::stride_view{I{}, D}; +}; // Ensure that the InputRangeNotIndirectlyReadable is a valid range. static_assert(std::ranges::range); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp index c4fc1db4da581..e292d56d548ec 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp @@ -53,10 +53,10 @@ bool base_move() { int move_counter = 0; int copy_counter = 0; - auto start = SizedInputIterator(); + auto start = SizedInputIterator(); start.move_counter = &move_counter; start.copy_counter = ©_counter; - auto stop = SizedInputIterator(); + auto stop = SizedInputIterator(); auto view = BasicTestView{start, stop}; auto sv = std::ranges::stride_view>(view, 1); @@ -82,7 +82,7 @@ bool base_copy() { start.move_counter = &move_counter; start.copy_counter = ©_counter; - auto stop = SizedInputIterator(); + auto stop = SizedInputIterator(); auto view = BasicTestView{start, stop}; auto sv = std::ranges::stride_view>(view, 1); From f4c37a3010e72aa4dd0ccda7a4a545b758eeb311 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Thu, 18 Jul 2024 01:37:34 -0400 Subject: [PATCH 128/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add additional testing for sentinel mathematics. Signed-off-by: Will Hawkins --- .../range.stride.view/iterator/base.pass.cpp | 2 - .../iterator/operator.pass.cpp | 52 ++++++++++++------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp index e292d56d548ec..5aadbef16331b 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp @@ -100,12 +100,10 @@ bool base_copy() { } int main(int, char**) { - /* base_noexcept(); static_assert(base_noexcept()); base_const(); static_assert(base_const()); - */ base_move(); base_copy(); return 0; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index ec9b6dba82c32..2a4e2f1647169 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -59,13 +59,16 @@ concept CanSentinelMinus = // Note: Do *not* use std::iterator_traits here because T may not have // all the required pieces when it is not a forward_range. std::is_same_v() - std::default_sentinel)> && - std::is_same_v())> && requires(T& t) { + std::is_same_v())> && + requires(T& t) { t - std::default_sentinel; std::default_sentinel - t; }; template -concept CanDifferencePlus = std::is_same_v() + 1)> && requires(T& t) { t + 1; }; +concept CanDifferencePlus = + std::is_same_v() + 1)> && requires(T& t) { t + 1; } && + std::is_same_v())> && requires(T& t) { 1 + t; }; template concept CanDifferenceMinus = std::is_same_v() - 1)> && requires(T& t) { t - 1; }; @@ -235,12 +238,14 @@ template requires std::sized_sentinel_for && (!std::forward_iterator) constexpr bool test_non_forward_operator_minus(Iter zero_begin, Iter one_begin, Iter end) { using Base = BasicTestView; - // Test the non-forward-range operator- between two iterators (i.e., ceil). - // First, what operators are valid for an iterator derived from a stride view - // over a sized input view. + // Test the non-forward-range operator- between two iterators (i.e., ceil) and an + // iterator and a default sentinel. using StrideViewIterator = std::ranges::iterator_t>; - static_assert(std::weakly_incrementable); + static_assert(!std::ranges::forward_range); + + // First, what operators are valid for an iterator derived from a stride view + // over a sized input view. static_assert(!CanPostDecrement); static_assert(!CanPreDecrement); @@ -268,11 +273,11 @@ constexpr bool test_non_forward_operator_minus(Iter zero_begin, Iter one_begin, auto sv_one_offset_begin = stride_view_over_base_one_offset.begin(); auto sv_zero_offset_zeroth_index = sv_zero_offset_begin; - auto sv_zero_offset_third_index = ++sv_zero_offset_begin; - auto sv_zero_offset_sixth_index = ++sv_zero_offset_begin; + auto sv_zero_offset_third_index = ++sv_zero_offset_begin; // With a stride of 3, so ++ moves 3 indexes. + auto sv_zero_offset_sixth_index = ++sv_zero_offset_begin; // With a stride of 3, so ++ moves 3 indexes. auto sv_one_offset_oneth_index = sv_one_offset_begin; - auto sv_one_offset_fourth_index = ++sv_one_offset_begin; + auto sv_one_offset_fourth_index = ++sv_one_offset_begin; // With a stride of 3, so ++ moves 3 indexes. static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); static_assert(CanMinus); @@ -294,7 +299,10 @@ constexpr bool test_non_forward_operator_minus(Iter zero_begin, Iter one_begin, assert(stride_view_over_base_zero_offset.end() == std::default_sentinel); assert(std::default_sentinel == stride_view_over_base_zero_offset.end()); + assert(std::default_sentinel - stride_view_over_base_zero_offset.end() == 0); assert(stride_view_over_base_zero_offset.end() - std::default_sentinel == 0); + //assert((std::default_sentinel - )== 0); + assert(std::default_sentinel - stride_view_over_base_zero_offset.begin() == std::ranges::distance(stride_view_over_base_zero_offset)); assert(stride_view_over_base_zero_offset.begin() - std::default_sentinel == @@ -303,17 +311,19 @@ constexpr bool test_non_forward_operator_minus(Iter zero_begin, Iter one_begin, return true; } -template -constexpr bool test_forward_operator_minus(Iter begin, Iter end) { - // Test the forward-range operator- between two iterators (i.e., no ceil). +template +constexpr bool test_forward_operator_minus(Iter begin, Iter end, difference_type distance) { + // Test the forward-range operator- between two iterators (i.e., no ceil) and + // an iterator and a default sentinel. using Base = BasicTestView; - //int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + + using StrideViewIterator = std::ranges::iterator_t>; + static_assert(std::ranges::forward_range); + static_assert(std::weakly_incrementable); // First, what operators are valid for an iterator derived from a stride view // over a sized forward view (even though it is actually much more than that!). - using StrideViewIterator = std::ranges::iterator_t>; - static_assert(std::weakly_incrementable); static_assert(CanMinus); static_assert(CanSentinelMinus); @@ -361,6 +371,8 @@ constexpr bool test_forward_operator_minus(Iter begin, Iter end) { std::ranges::distance(stride_view_over_base_zero_offset)); assert(stride_view_over_base_zero_offset.begin() - std::default_sentinel == -std::ranges::distance(stride_view_over_base_zero_offset)); + assert(stride_view_over_base_zero_offset.begin() - std::default_sentinel == -distance); + assert(std::default_sentinel - stride_view_over_base_zero_offset.begin() == distance); return true; } @@ -398,7 +410,7 @@ constexpr bool test_properly_handling_missing() { assert(std::default_sentinel - strider.end() == 0); assert(std::default_sentinel - strider_iter == 0); - // Let's make sure that the newly regenerated __missing_ gets used. + // Let's make sure that the newly regenerated __missing__ gets used. strider_iter += -2; assert(*strider_iter == 1); @@ -407,10 +419,10 @@ constexpr bool test_properly_handling_missing() { int main(int, char**) { { - constexpr int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - std::vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - test_forward_operator_minus(arr, arr + 10); - test_forward_operator_minus(vec.begin(), vec.end()); + constexpr int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + std::vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + test_forward_operator_minus(arr, arr + 11, 4); + test_forward_operator_minus(vec.begin(), vec.end(), 4); } { From 56927a000b93596820984883a652e3988000ae43 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 2 Aug 2024 23:58:47 -0400 Subject: [PATCH 129/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Make sure that all nodiscard-marked member functions are checked. Signed-off-by: Will Hawkins --- libcxx/include/__ranges/stride_view.h | 4 +-- .../base.nodiscard.verify.cpp | 32 ++++--------------- .../begin.nodiscard.verify.cpp | 25 +++++++++++++++ .../ctor.nodiscard.verify.cpp | 23 +++++++++++++ .../end.nodiscard.verify.cpp | 25 +++++++++++++++ .../iterator/base.nodiscard.verify.cpp | 25 +++++++++++++++ .../iterator/dereference.nodiscard.verify.cpp | 2 +- .../iterator/operator.nodiscard.verify.cpp | 12 +++++-- .../size.nodiscard.verify.cpp | 23 +++++++++++++ .../stride.nodiscard.verify.cpp | 22 +++++++++++++ .../range.adaptors/range.stride.view/types.h | 6 +++- 11 files changed, 167 insertions(+), 32 deletions(-) create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/begin.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/end.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/base.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/size.nodiscard.verify.cpp create mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/stride.nodiscard.verify.cpp diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 8403797a1d481..188deac1a201c 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -201,8 +201,8 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> __stride_(__i.__stride_), __missing_(__i.__missing_) {} - _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> const& base() const& noexcept { return __current_; } - _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); } + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> const& base() const& noexcept { return __current_; } + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); } _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__current_ != __end_, "Cannot dereference an iterator at the end."); diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp index 6599a750e44fc..7215052434eaf 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp @@ -8,39 +8,21 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// Test that appropriate (member) functions are properly marked no_discard +// Test that std::ranges::stride_view::base() is marked nodiscard. #include #include "../../../../std/ranges/range.adaptors/range.stride.view/types.h" void test() { - const int range[] = {1, 2, 3}; - - std::views::stride( // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - range, - 2); - range | - std::views::stride( // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - 2); - std::views::all | // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::views::stride(1); - - auto sv = std::views::stride(range, 2); - const auto const_sv = std::views::stride(range, 2); - auto unsimple_sv = std::views::stride(UnsimpleConstView{}, 2); - - const_sv.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::move(sv).base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + const std::vector intv = {1, 2, 3}; + auto copyable_view = CopyableView::const_iterator>(intv.begin(), intv.end()); - const_sv.stride(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + static_assert(std::copy_constructible); - const_sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - unsimple_sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + const auto sv = std::ranges::stride_view(copyable_view, 2); - const_sv.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - unsimple_sv.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - sv.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - const_sv.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::move(sv).base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/begin.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/begin.nodiscard.verify.cpp new file mode 100644 index 0000000000000..7cb13f75969fd --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/begin.nodiscard.verify.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// Test that appropriate (member) functions are properly marked no_discard + +#include + +#include "../../../../std/ranges/range.adaptors/range.stride.view/types.h" + +void test() { + const int range[] = {1, 2, 3}; + + const auto const_sv = std::views::stride(range, 2); + auto unsimple_sv = std::views::stride(UnsimpleConstView{}, 2); + + const_sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + unsimple_sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.nodiscard.verify.cpp new file mode 100644 index 0000000000000..d27b1b6c8f41a --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.nodiscard.verify.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// Test that appropriate (member) functions are properly marked no_discard + +#include + +#include "../../../../std/ranges/range.adaptors/range.stride.view/types.h" + +void test() { + const int range[] = {1, 2, 3}; + + std::views::stride( // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + range, + 2); +} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/end.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/end.nodiscard.verify.cpp new file mode 100644 index 0000000000000..50bed53075566 --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/end.nodiscard.verify.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// Test that appropriate (member) functions are properly marked no_discard + +#include + +#include "../../../../std/ranges/range.adaptors/range.stride.view/types.h" + +void test() { + const int range[] = {1, 2, 3}; + + const auto const_sv = std::views::stride(range, 2); + auto unsimple_sv = std::views::stride(UnsimpleConstView{}, 2); + + const_sv.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + unsimple_sv.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/base.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/base.nodiscard.verify.cpp new file mode 100644 index 0000000000000..0f64846bbff2f --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/base.nodiscard.verify.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// Test that std::ranges::stride_view::iterator::base() is marked nodiscard. + +#include +#include + +void test() { + { + int range[] = {1, 2, 3}; + auto view = std::ranges::views::stride(range, 3); + auto it = view.begin(); + + it.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::move(it).base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + } +} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.nodiscard.verify.cpp index d10a1aa2066a0..366bcebd52d87 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.nodiscard.verify.cpp @@ -8,7 +8,7 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// constexpr decltype(auto) operator*() const { +// Test that std::ranges::stride_view::iterator::operator*() is marked nodiscard. #include #include diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp index 18304d72e5965..5aa5c75a13937 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp @@ -8,7 +8,7 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// constexpr decltype(auto) operator[](difference_type __n) const +// Test that std::ranges::stride_view::iterator::operator- is marked nodiscard. #include @@ -33,10 +33,10 @@ constexpr bool test_non_forward_operator_minus() { } constexpr bool test_forward_operator_minus() { - // Test the forward-range operator- between two iterators (i.e., no ceil). - using Base = BasicTestView; int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + using Base = BasicTestView; + auto base_view_offset_zero = Base(arr, arr + 10); auto base_view_offset_one = Base(arr + 1, arr + 10); auto stride_view_over_base_zero_offset = std::ranges::stride_view(base_view_offset_zero, 3); @@ -54,5 +54,11 @@ constexpr bool test_forward_operator_minus() { sv_one_offset_begin - // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sv_zero_offset_begin; + std::default_sentinel_t() - // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv_zero_offset_begin; + + sv_zero_offset_begin - // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::default_sentinel_t(); + return true; } diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/size.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/size.nodiscard.verify.cpp new file mode 100644 index 0000000000000..b851dd04bd5fe --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/size.nodiscard.verify.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// Test that appropriate (member) functions are properly marked no_discard + +#include + +#include "../../../../std/ranges/range.adaptors/range.stride.view/types.h" + +void test() { + auto sv = std::views::stride(SimpleNoConstSizedCommonView(), 2); + const auto const_sv = std::views::stride(SimpleCommonConstView(), 2); + + sv.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + const_sv.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/stride.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/stride.nodiscard.verify.cpp new file mode 100644 index 0000000000000..22528d77047de --- /dev/null +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/stride.nodiscard.verify.cpp @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// Test that appropriate (member) functions are properly marked no_discard + +#include + +#include "../../../../std/ranges/range.adaptors/range.stride.view/types.h" + +void test() { + const int range[] = {1, 2, 3}; + + const auto const_sv = std::views::stride(range, 2); + const_sv.stride(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index 6f73722ee54de..9b8bf37f41859 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -226,7 +226,7 @@ template Sent = sentinel_wrap using MoveOnlyView = MaybeCopyableAlwaysMoveableView; static_assert(!std::copyable>>); -template +template struct MaybeConstCommonSimpleView : std::ranges::view_base { int* begin(); int* begin() const @@ -246,6 +246,9 @@ struct MaybeConstCommonSimpleView : std::ranges::view_base { void* end() const requires(IsConst && !IsCommon); + + size_t size() const + requires(IsSized); }; using UnSimpleNoConstCommonView = MaybeConstCommonSimpleView; @@ -253,6 +256,7 @@ using UnsimpleConstView = MaybeConstCommonSimpleView; using UnsimpleUnCommonConstView = MaybeConstCommonSimpleView; using SimpleUnCommonConstView = MaybeConstCommonSimpleView; using SimpleCommonConstView = MaybeConstCommonSimpleView; +using SimpleNoConstSizedCommonView = MaybeConstCommonSimpleView; // Don't move/hold the iterator itself, copy/hold the base // of that iterator and reconstruct the iterator on demand. From bec871fccb9b0fd7b0eb6f7ba9ba664b4eea25cf Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sat, 3 Aug 2024 01:15:18 -0400 Subject: [PATCH 130/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Finish fixing bad rebase. Signed-off-by: Will Hawkins --- libcxx/include/ranges | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/libcxx/include/ranges b/libcxx/include/ranges index 5f656d523ded9..ae62354f9d48a 100644 --- a/libcxx/include/ranges +++ b/libcxx/include/ranges @@ -367,6 +367,17 @@ namespace std::ranges { class chunk_by_view; // C++23 namespace views { inline constexpr unspecified chunk_by = unspecified; } // C++23 + + // [range.stride.view] + template + requires view + class stride_view; // C++23 + + template + constexpr bool enable_borrowed_range> = + enable_borrowed_range; // C++23 + + namespace views { inline constexpr unspecified stride = unspecified; } // C++23 } namespace std { @@ -435,7 +446,6 @@ namespace std { # include <__ranges/single_view.h> # include <__ranges/size.h> # include <__ranges/split_view.h> -# include <__ranges/stride_view.h> # include <__ranges/subrange.h> # include <__ranges/take_view.h> # include <__ranges/take_while_view.h> @@ -454,6 +464,7 @@ namespace std { # include <__ranges/from_range.h> # include <__ranges/join_with_view.h> # include <__ranges/repeat_view.h> +# include <__ranges/stride_view.h> # include <__ranges/to.h> # include <__ranges/zip_transform_view.h> # include <__ranges/zip_view.h> From 63ebdd70b54e87c9730eafa3ba7b004b86580477 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sat, 3 Aug 2024 01:31:00 -0400 Subject: [PATCH 131/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Format. Signed-off-by: Will Hawkins --- libcxx/include/__ranges/stride_view.h | 4 +- .../base.nodiscard.verify.cpp | 2 +- .../borrowing.compile.pass.cpp | 2 +- .../range.stride.view/concept.verify.cpp | 3 +- .../iterator/ctor.copy.pass.cpp | 54 +++++++++---------- .../range.stride.view/iterator/equal.pass.cpp | 2 +- .../iterator/operator.pass.cpp | 11 ++-- .../range.adaptors/range.stride.view/types.h | 12 ++--- 8 files changed, 46 insertions(+), 44 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 188deac1a201c..7b9f122ee259d 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -201,7 +201,9 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> __stride_(__i.__stride_), __missing_(__i.__missing_) {} - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> const& base() const& noexcept { return __current_; } + _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> const& base() const& noexcept { + return __current_; + } _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); } _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp index 7215052434eaf..1690e97b917d2 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp @@ -16,7 +16,7 @@ void test() { const std::vector intv = {1, 2, 3}; - auto copyable_view = CopyableView::const_iterator>(intv.begin(), intv.end()); + auto copyable_view = CopyableView::const_iterator>(intv.begin(), intv.end()); static_assert(std::copy_constructible); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/borrowing.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/borrowing.compile.pass.cpp index 4c2d0efb774b2..add0018d455aa 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/borrowing.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/borrowing.compile.pass.cpp @@ -14,8 +14,8 @@ #include #include -#include "types.h" #include "test_range.h" +#include "types.h" static_assert(std::ranges::enable_borrowed_range< std::ranges::stride_view>); static_assert(!std::ranges::enable_borrowed_range< std::ranges::stride_view>); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp index 527651b66fb64..8ec314bd3a114 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp @@ -38,7 +38,8 @@ static_assert(std::movable>); static_assert(!std::ranges::view>); static_assert(!CanStrideView, 1>); -// And now, let's satisfy all the prerequisites and make sure that we can stride over a range (that is an input range and is a view!) +// And now, let's satisfy all the prerequisites and make sure that we can stride over a range (that is an input range +// and is a view!) static_assert(std::ranges::range>); static_assert(std::ranges::input_range>); static_assert(std::ranges::view>); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp index cea97fe49ecef..2c52a39940465 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp @@ -187,16 +187,16 @@ constexpr bool non_const_iterator_copy_ctor() { // like it is possible copy construct the stride view's iterator (the move-only requirement comes from // a move of the current between the copied-from iterator to the copied-to iterator). using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; - //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; - //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + // using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + // using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; using StrideView = std::ranges::stride_view; using StrideViewIter = std::ranges::iterator_t; using StrideViewConstIter = std::ranges::iterator_t; - //using StrideViewSentinel = std::ranges::sentinel_t; - //using StrideViewConstSentinel = std::ranges::sentinel_t; + // using StrideViewSentinel = std::ranges::sentinel_t; + // using StrideViewConstSentinel = std::ranges::sentinel_t; static_assert(std::convertible_to); static_assert(std::constructible_from); @@ -207,16 +207,16 @@ constexpr bool non_const_iterator_copy_ctor() { // like it is possible copy construct the stride view's iterator (the move-only requirement comes from // a move of the current between the copied-from iterator to the copied-to iterator). using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; - //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; - //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + // using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + // using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; using StrideView = std::ranges::stride_view; using StrideViewIter = std::ranges::iterator_t; using StrideViewConstIter = std::ranges::iterator_t; - //using StrideViewSentinel = std::ranges::sentinel_t; - //using StrideViewConstSentinel = std::ranges::sentinel_t; + // using StrideViewSentinel = std::ranges::sentinel_t; + // using StrideViewConstSentinel = std::ranges::sentinel_t; static_assert(std::convertible_to); static_assert(std::constructible_from); @@ -226,16 +226,16 @@ constexpr bool non_const_iterator_copy_ctor() { // Stride over non-simple view over whose iterators are not convertible -- should not be able // to copy construct the stride view's iterator. using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; - //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; - //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + // using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + // using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; using StrideView = std::ranges::stride_view; using StrideViewIter = std::ranges::iterator_t; using StrideViewConstIter = std::ranges::iterator_t; - //using StrideViewSentinel = std::ranges::sentinel_t; - //using StrideViewConstSentinel = std::ranges::sentinel_t; + // using StrideViewSentinel = std::ranges::sentinel_t; + // using StrideViewConstSentinel = std::ranges::sentinel_t; static_assert(!std::convertible_to); static_assert(!std::constructible_from); @@ -246,15 +246,15 @@ constexpr bool non_const_iterator_copy_ctor() { // to copy construct the stride view's iterator. using NotSimpleViewBeingStrided = NotSimpleViewDifferentEnd; using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; - //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + // using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; using StrideView = std::ranges::stride_view; using StrideViewIter = std::ranges::iterator_t; using StrideViewConstIter = std::ranges::iterator_t; - //using StrideViewSentinel = std::ranges::sentinel_t; - //using StrideViewConstSentinel = std::ranges::sentinel_t; + // using StrideViewSentinel = std::ranges::sentinel_t; + // using StrideViewConstSentinel = std::ranges::sentinel_t; static_assert(std::convertible_to); static_assert(std::convertible_to); @@ -276,16 +276,16 @@ constexpr bool non_const_iterator_copy_ctor() { // like it is possible copy construct the stride view's iterator (the move-only requirement comes from // a move of the current between the copied-from iterator to the copied-to iterator). using NotSimpleViewBeingStrided = NotSimpleViewDifferentBegin; - //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; - //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + // using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + // using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; using StrideView = std::ranges::stride_view; using StrideViewIter = std::ranges::iterator_t; using StrideViewConstIter = std::ranges::iterator_t; - //using StrideViewSentinel = std::ranges::sentinel_t; - //using StrideViewConstSentinel = std::ranges::sentinel_t; + // using StrideViewSentinel = std::ranges::sentinel_t; + // using StrideViewConstSentinel = std::ranges::sentinel_t; static_assert(std::convertible_to); static_assert(std::constructible_from); @@ -296,16 +296,16 @@ constexpr bool non_const_iterator_copy_ctor() { // like it is possible copy construct the stride view's iterator (the move-only requirement comes from // a move of the current between the copied-from iterator to the copied-to iterator). using NotSimpleViewBeingStrided = NotSimpleViewDifferentBegin; - //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; - //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + // using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + // using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; using StrideView = std::ranges::stride_view; using StrideViewIter = std::ranges::iterator_t; using StrideViewConstIter = std::ranges::iterator_t; - //using StrideViewSentinel = std::ranges::sentinel_t; - //using StrideViewConstSentinel = std::ranges::sentinel_t; + // using StrideViewSentinel = std::ranges::sentinel_t; + // using StrideViewConstSentinel = std::ranges::sentinel_t; static_assert(std::convertible_to); static_assert(std::constructible_from); @@ -315,16 +315,16 @@ constexpr bool non_const_iterator_copy_ctor() { // Stride over non-simple view over whose iterators are not convertible -- should not be able // to copy construct the stride view's iterator. using NotSimpleViewBeingStrided = NotSimpleViewDifferentBegin; - //using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; - //using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; + // using NotSimpleViewBeingStridedIterator = std::ranges::iterator_t; + // using NotSimpleViewBeingStridedConstIterator = std::ranges::iterator_t; using StrideView = std::ranges::stride_view; using StrideViewIter = std::ranges::iterator_t; using StrideViewConstIter = std::ranges::iterator_t; - //using StrideViewSentinel = std::ranges::sentinel_t; - //using StrideViewConstSentinel = std::ranges::sentinel_t; + // using StrideViewSentinel = std::ranges::sentinel_t; + // using StrideViewConstSentinel = std::ranges::sentinel_t; static_assert(!std::convertible_to); static_assert(!std::constructible_from); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp index 29156e0fe0db6..c1d2c3b6d7cd9 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/equal.pass.cpp @@ -14,8 +14,8 @@ #include #include -#include "test_iterators.h" #include "../types.h" +#include "test_iterators.h" template constexpr void testOne() { diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index 2a4e2f1647169..93029f290d73b 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -59,16 +59,15 @@ concept CanSentinelMinus = // Note: Do *not* use std::iterator_traits here because T may not have // all the required pieces when it is not a forward_range. std::is_same_v() - std::default_sentinel)> && - std::is_same_v())> && - requires(T& t) { + std::is_same_v())> && requires(T& t) { t - std::default_sentinel; std::default_sentinel - t; }; template -concept CanDifferencePlus = - std::is_same_v() + 1)> && requires(T& t) { t + 1; } && - std::is_same_v())> && requires(T& t) { 1 + t; }; +concept CanDifferencePlus = std::is_same_v() + 1)> && requires(T& t) { + t + 1; +} && std::is_same_v())> && requires(T& t) { 1 + t; }; template concept CanDifferenceMinus = std::is_same_v() - 1)> && requires(T& t) { t - 1; }; @@ -301,7 +300,7 @@ constexpr bool test_non_forward_operator_minus(Iter zero_begin, Iter one_begin, assert(std::default_sentinel - stride_view_over_base_zero_offset.end() == 0); assert(stride_view_over_base_zero_offset.end() - std::default_sentinel == 0); - //assert((std::default_sentinel - )== 0); + // assert((std::default_sentinel - )== 0); assert(std::default_sentinel - stride_view_over_base_zero_offset.begin() == std::ranges::distance(stride_view_over_base_zero_offset)); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index 9b8bf37f41859..12fab146c0b6d 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -251,12 +251,12 @@ struct MaybeConstCommonSimpleView : std::ranges::view_base { requires(IsSized); }; -using UnSimpleNoConstCommonView = MaybeConstCommonSimpleView; -using UnsimpleConstView = MaybeConstCommonSimpleView; -using UnsimpleUnCommonConstView = MaybeConstCommonSimpleView; -using SimpleUnCommonConstView = MaybeConstCommonSimpleView; -using SimpleCommonConstView = MaybeConstCommonSimpleView; -using SimpleNoConstSizedCommonView = MaybeConstCommonSimpleView; +using UnSimpleNoConstCommonView = MaybeConstCommonSimpleView; +using UnsimpleConstView = MaybeConstCommonSimpleView; +using UnsimpleUnCommonConstView = MaybeConstCommonSimpleView; +using SimpleUnCommonConstView = MaybeConstCommonSimpleView; +using SimpleCommonConstView = MaybeConstCommonSimpleView; +using SimpleNoConstSizedCommonView = MaybeConstCommonSimpleView; // Don't move/hold the iterator itself, copy/hold the base // of that iterator and reconstruct the iterator on demand. From cb1e39e2d5d56a9677318ccec2806ce0a95bd280 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sat, 3 Aug 2024 01:47:13 -0400 Subject: [PATCH 132/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Format. Signed-off-by: Will Hawkins --- libcxx/include/__ranges/stride_view.h | 19 +++++++++++-------- .../iterator/iter_move.nodiscard.verify.cpp | 3 ++- .../size.nodiscard.verify.cpp | 4 ++-- .../range.stride.view/adaptor.pass.cpp | 4 +++- .../range.stride.view/concept.verify.cpp | 4 +--- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 7b9f122ee259d..fb7cfc3e343d5 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -389,26 +389,29 @@ template inline constexpr bool enable_borrowed_range> = enable_borrowed_range<_Tp>; namespace views { -namespace __stride { +namespace __stride_view { struct __fn { + // clang-format off template - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) const - noexcept(noexcept(/**/ stride_view{std::forward<_Range>(__range), __n})) - -> decltype(/*--*/ stride_view{std::forward<_Range>(__range), __n}) { - return /*-------------*/ stride_view(std::forward<_Range>(__range), __n); - } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Range&& __range, range_difference_t<_Range> __n) const + noexcept(noexcept(stride_view{std::forward<_Range>(__range), __n})) + -> decltype( stride_view{std::forward<_Range>(__range), __n}) + { return stride_view(std::forward<_Range>(__range), __n); } + // clang-format on template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Np&& __n) const { return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Np>(__n))); } }; -} // namespace __stride +} // namespace __stride_view inline namespace __cpo { -inline constexpr auto stride = __stride::__fn{}; +inline constexpr auto stride = __stride_view::__fn{}; } // namespace __cpo } // namespace views + } // namespace ranges #endif // _LIBCPP_STD_VER >= 23 diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/iter_move.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/iter_move.nodiscard.verify.cpp index 9b2108a3361dd..a560bcc899841 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/iter_move.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/iter_move.nodiscard.verify.cpp @@ -8,7 +8,8 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// friend constexpr range_rvalue_reference_t<_Base> iter_move(__iterator const& __it) noexcept(noexcept(ranges::iter_move(__it.__current_))) +// friend constexpr range_rvalue_reference_t<_Base> iter_move(__iterator const& __it) +// noexcept(noexcept(ranges::iter_move(__it.__current_))) #include diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/size.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/size.nodiscard.verify.cpp index b851dd04bd5fe..73fe77df16d14 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/size.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/size.nodiscard.verify.cpp @@ -15,9 +15,9 @@ #include "../../../../std/ranges/range.adaptors/range.stride.view/types.h" void test() { - auto sv = std::views::stride(SimpleNoConstSizedCommonView(), 2); + auto sv = std::views::stride(SimpleNoConstSizedCommonView(), 2); const auto const_sv = std::views::stride(SimpleCommonConstView(), 2); - sv.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} const_sv.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index ea7fd588fd81f..c60c8cc5805ae 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -134,7 +134,9 @@ constexpr bool test() { } // A final sanity check. - { static_assert(std::same_as); } + { + static_assert(std::same_as); + } return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp index 8ec314bd3a114..8f43b63e9de87 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp @@ -18,9 +18,7 @@ #include "types.h" template D> -concept CanStrideView = requires { - std::ranges::stride_view{I{}, D}; -}; +concept CanStrideView = requires { std::ranges::stride_view{I{}, D}; }; // Ensure that the InputRangeNotIndirectlyReadable is a valid range. static_assert(std::ranges::range); From 121986b1674ccedc221885f0f241111a0d04506b Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sat, 3 Aug 2024 01:58:22 -0400 Subject: [PATCH 133/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Format. Signed-off-by: Will Hawkins --- .../ranges/range.adaptors/range.stride.view/adaptor.pass.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index c60c8cc5805ae..ea7fd588fd81f 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -134,9 +134,7 @@ constexpr bool test() { } // A final sanity check. - { - static_assert(std::same_as); - } + { static_assert(std::same_as); } return true; } From 7385dd0a7ea4a3a3e34f01d12e5f87a259fc2f5f Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Tue, 6 Aug 2024 02:31:53 -0400 Subject: [PATCH 134/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Begin splitting iterator tests into different files. Signed-off-by: Will Hawkins --- .../iterator/increment.pass.cpp | 210 ++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp new file mode 100644 index 0000000000000..7b55328cfe851 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp @@ -0,0 +1,210 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// constexpr __iterator& operator++() +// constexpr void operator++(int) +// constexpr __iterator operator++(int) + +#include +#include + +#include "../types.h" +#include "test_iterators.h" + +template +concept CanPostIncrementVoid = std::is_same_v()++)> && requires(T& t) { t++; }; +template +concept CanPostIncrementIterator = std::is_same_v()++)> && requires(T& t) { t = t++; }; +template +concept CanPreIncrementIterator = std::is_same_v()))> && requires(T& t) { t = ++t; }; + +// A stride view with a base that is a non forward range returns void from operator++ +using InputView = BasicTestView, sized_sentinel>>; +using StrideViewOverInputViewIterator = std::ranges::iterator_t>; +static_assert(CanPostIncrementVoid); +static_assert(!CanPostIncrementIterator); +static_assert(CanPreIncrementIterator); + +// A stride view with a base that is a forward range returns void from operator++ +using ForwardView = BasicTestView, sized_sentinel>>; +using StrideViewOverForwardViewIterator = std::ranges::iterator_t>; +static_assert(!CanPostIncrementVoid); +static_assert(CanPostIncrementIterator); +static_assert(CanPreIncrementIterator); + +template + requires std::sized_sentinel_for && (!std::forward_iterator) +constexpr bool test_non_forward_operator_increment(Iter zero_begin, Iter three_begin, Iter end) { + using Base = BasicTestView; + using StrideViewIterator = std::ranges::iterator_t>; + static_assert(std::weakly_incrementable); + static_assert(!std::ranges::forward_range); + + auto base_view_offset_zero = Base(zero_begin, end); + auto base_view_offset_three = Base(three_begin, end); + auto stride_view_over_base_zero_offset = std::ranges::stride_view(base_view_offset_zero, 3); + auto stride_view_over_base_three_offset = std::ranges::stride_view(base_view_offset_three, 3); + + auto sv_zero_offset_begin = stride_view_over_base_zero_offset.begin(); + auto sv_three_offset_begin = stride_view_over_base_three_offset.begin(); + + auto sv_zero_offset_third_index = sv_zero_offset_begin; // With a stride of 3, so ++ moves 3 indexes. + ++sv_zero_offset_third_index; + assert(*sv_three_offset_begin == *sv_zero_offset_third_index); + + sv_zero_offset_third_index = sv_zero_offset_begin; + sv_zero_offset_third_index++; + assert(*sv_three_offset_begin == *sv_zero_offset_third_index); + + // See if both get to the end (with pre-increment). + auto sv_zero_offset_incremented_to_end = sv_zero_offset_begin; + ++sv_zero_offset_incremented_to_end; // 3 + ++sv_zero_offset_incremented_to_end; // 6 + ++sv_zero_offset_incremented_to_end; // 9 + ++sv_zero_offset_incremented_to_end; // End + + auto sv_three_offset_incremented_to_end = sv_three_offset_begin; // With a stride of 3, so ++ moves 3 indexes. + ++sv_three_offset_incremented_to_end; // 6 + ++sv_three_offset_incremented_to_end; // 9 + ++sv_three_offset_incremented_to_end; // End + + assert(sv_three_offset_incremented_to_end == sv_zero_offset_incremented_to_end); + assert(sv_three_offset_incremented_to_end == stride_view_over_base_three_offset.end()); + assert(sv_zero_offset_incremented_to_end == stride_view_over_base_zero_offset.end()); + + // See if both get to the end (with post-increment). + sv_zero_offset_incremented_to_end = sv_zero_offset_begin; + sv_zero_offset_incremented_to_end++; // 3 + sv_zero_offset_incremented_to_end++; // 6 + sv_zero_offset_incremented_to_end++; // 9 + sv_zero_offset_incremented_to_end++; // End + + sv_three_offset_incremented_to_end = sv_three_offset_begin; // With a stride of 3, so ++ moves 3 indexes. + sv_three_offset_incremented_to_end++; // 6 + sv_three_offset_incremented_to_end++; // 9 + sv_three_offset_incremented_to_end++; // End + + assert(sv_three_offset_incremented_to_end == sv_zero_offset_incremented_to_end); + assert(sv_three_offset_incremented_to_end == stride_view_over_base_three_offset.end()); + assert(sv_zero_offset_incremented_to_end == stride_view_over_base_zero_offset.end()); + + return true; +} + +template +constexpr bool test_forward_operator_increment(Iter begin, Iter end) { + using Base = BasicTestView; + + using StrideViewIterator = std::ranges::iterator_t>; + static_assert(std::ranges::forward_range); + static_assert(std::weakly_incrementable); + + auto base_view_offset_zero = Base(begin, end); + auto stride_view_over_base_zero_offset = std::ranges::stride_view(base_view_offset_zero, 3); + auto sv_zero_offset_begin = stride_view_over_base_zero_offset.begin(); + + // Create a ground truth for comparison. + auto sv_zero_offset_third_index_key = stride_view_over_base_zero_offset.begin(); + sv_zero_offset_third_index_key++; + + auto sv_zero_offset_third_index = ++sv_zero_offset_begin; + assert(*sv_zero_offset_third_index == *sv_zero_offset_begin); + assert(*sv_zero_offset_third_index == *sv_zero_offset_third_index_key); + + sv_zero_offset_begin = stride_view_over_base_zero_offset.begin(); + sv_zero_offset_third_index = sv_zero_offset_begin; + sv_zero_offset_third_index++; + assert(*sv_zero_offset_third_index == *sv_zero_offset_third_index_key); + + sv_zero_offset_begin = stride_view_over_base_zero_offset.begin(); + auto sv_zero_offset_incremented_to_end = sv_zero_offset_begin; + ++sv_zero_offset_incremented_to_end; // 3 + ++sv_zero_offset_incremented_to_end; // 6 + ++sv_zero_offset_incremented_to_end; // 9 + ++sv_zero_offset_incremented_to_end; // End + + auto sv_zero_offset_incremented_to_end_reset = sv_zero_offset_begin; // With a stride of 3, so ++ moves 3 indexes. + sv_zero_offset_incremented_to_end_reset = ++sv_zero_offset_incremented_to_end_reset; // 3 + sv_zero_offset_incremented_to_end_reset = ++sv_zero_offset_incremented_to_end_reset; // 6 + sv_zero_offset_incremented_to_end_reset = ++sv_zero_offset_incremented_to_end_reset; // 9 + sv_zero_offset_incremented_to_end_reset = ++sv_zero_offset_incremented_to_end_reset; // End + + assert(sv_zero_offset_incremented_to_end == sv_zero_offset_incremented_to_end_reset); + assert(sv_zero_offset_incremented_to_end == stride_view_over_base_zero_offset.end()); + + sv_zero_offset_incremented_to_end = sv_zero_offset_begin; + sv_zero_offset_incremented_to_end++; // 3 + sv_zero_offset_incremented_to_end++; // 6 + sv_zero_offset_incremented_to_end++; // 9 + sv_zero_offset_incremented_to_end++; // End + assert(sv_zero_offset_incremented_to_end == stride_view_over_base_zero_offset.end()); + + return true; +} + +constexpr bool test_properly_handling_missing() { + // Check whether __missing_ gets handled properly. + using Base = BasicTestView; + int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + auto base = Base(arr, arr + 10); + auto strider = std::ranges::stride_view(base, 7); + + auto strider_iter = strider.end(); + + strider_iter--; + assert(*strider_iter == 8); + + // Now that we are back among the valid, we should + // have a normal stride length back (i.e., __missing_ + // should be equal to 0). + strider_iter--; + assert(*strider_iter == 1); + + strider_iter++; + assert(*strider_iter == 8); + + // By striding past the end, we are going to generate + // another __missing_ != 0 value. + strider_iter++; + assert(strider_iter == strider.end()); + + // Make sure that all sentinel operations work! + assert(strider.end() == std::default_sentinel); + assert(std::default_sentinel == strider.end()); + + assert(strider_iter - std::default_sentinel == 0); + assert(std::default_sentinel - strider.end() == 0); + assert(std::default_sentinel - strider_iter == 0); + + // Let's make sure that the newly regenerated __missing__ gets used. + strider_iter += -2; + assert(*strider_iter == 1); + + return true; +} + +int main(int, char**) { + { + constexpr int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + std::vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + test_forward_operator_increment(arr, arr + 11); + test_forward_operator_increment(vec.begin(), vec.end()); + } + + { + int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + test_non_forward_operator_increment( + SizedInputIterator(arr), SizedInputIterator(arr + 3), SizedInputIterator(arr + 10)); + } + + test_properly_handling_missing(); + static_assert(test_properly_handling_missing()); + return 0; +} From bbfae5adbb849ffbc55a9e2e114b3c81d2e4311f Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 16 Aug 2024 23:59:04 -0400 Subject: [PATCH 135/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Clean up the iterator increment tests. Signed-off-by: Will Hawkins --- .../iterator/decrement.pass.cpp | 93 +++++++++++++++++++ .../iterator/increment.pass.cpp | 4 - .../iterator/operator.pass.cpp | 10 +- 3 files changed, 98 insertions(+), 9 deletions(-) create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/decrement.pass.cpp diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/decrement.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/decrement.pass.cpp new file mode 100644 index 0000000000000..4c51c4b03965b --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/decrement.pass.cpp @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// constexpr __iterator& operator--() +// constexpr __iterator operator--(int) + +#include +#include + +#include "../types.h" + +template +concept CanPostDecrement = std::is_same_v()--)> && requires(T& t) { t--; }; +template +concept CanPreDecrement = std::is_same_v()))> && requires(T& t) { --t; }; + +// What operators are valid for an iterator derived from a stride view +// over an input view. +using InputView = BasicTestView, sized_sentinel>>; +using StrideViewOverInputViewIterator = std::ranges::iterator_t>; + +static_assert(!std::ranges::bidirectional_range); +static_assert(!CanPostDecrement); +static_assert(!CanPreDecrement); + +// What operators are valid for an iterator derived from a stride view +// over a forward view. +using ForwardView = BasicTestView, sized_sentinel>>; +using StrideViewOverForwardViewIterator = std::ranges::iterator_t>; + +static_assert(!std::ranges::bidirectional_range); +static_assert(!CanPostDecrement); +static_assert(!CanPostDecrement); + +// What operators are valid for an iterator derived from a stride view +// over a bidirectional view. +using BidirectionalView = BasicTestView, sized_sentinel>>; +using StrideViewOverBidirectionalViewIterator = std::ranges::iterator_t>; + +static_assert(std::ranges::bidirectional_range); +static_assert(CanPostDecrement); +static_assert(CanPostDecrement); + +// What operators are valid for an iterator derived from a stride view +// over a random access view. +using RandomAccessView = BasicTestView>; +using StrideViewOverRandomAccessViewIterator = std::ranges::iterator_t>; + +static_assert(std::ranges::bidirectional_range); +static_assert(CanPostDecrement); +static_assert(CanPostDecrement); + +template + requires(std::bidirectional_iterator) +constexpr bool test_operator_decrement(Iter begin, Iter end, Difference delta) { + using Base = BasicTestView; + + auto base_view_offset_zero = Base(begin, end); + // Because of the requires on the Iter template type, we are sure + // that the type of sv_incr_one is a bidirectional range. + auto sv_incr_diff = std::ranges::stride_view(base_view_offset_zero, delta); + auto sv_incr_end = sv_incr_diff.end(); + + // Recreate the "missing" calculation here -- to make sure that it matches. + auto missing = delta - (std::ranges::distance(base_view_offset_zero) % delta) % delta; + + auto sought = end + (missing - delta); + + assert(*sought == *(--sv_incr_end)); + assert(*sought == *(sv_incr_end)); + + sv_incr_end = sv_incr_diff.end(); + sv_incr_end--; + assert(*(end + (missing - delta)) == *(sv_incr_end)); + + return true; +} + +int main(int, char**) { + constexpr int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + std::vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + test_operator_decrement(vec.begin(), vec.end(), 3); + test_operator_decrement(arr, arr + 11, 3); + + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp index 7b55328cfe851..976876f08555f 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp @@ -16,7 +16,6 @@ #include #include "../types.h" -#include "test_iterators.h" template concept CanPostIncrementVoid = std::is_same_v()++)> && requires(T& t) { t++; }; @@ -43,9 +42,6 @@ template requires std::sized_sentinel_for && (!std::forward_iterator) constexpr bool test_non_forward_operator_increment(Iter zero_begin, Iter three_begin, Iter end) { using Base = BasicTestView; - using StrideViewIterator = std::ranges::iterator_t>; - static_assert(std::weakly_incrementable); - static_assert(!std::ranges::forward_range); auto base_view_offset_zero = Base(zero_begin, end); auto base_view_offset_three = Base(three_begin, end); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index 93029f290d73b..f68350c50382e 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -235,7 +235,7 @@ static_assert(!std::three_way_comparable); template requires std::sized_sentinel_for && (!std::forward_iterator) -constexpr bool test_non_forward_operator_minus(Iter zero_begin, Iter one_begin, Iter end) { +constexpr bool test_non_forward_operator_plus(Iter zero_begin, Iter one_begin, Iter end) { using Base = BasicTestView; // Test the non-forward-range operator- between two iterators (i.e., ceil) and an // iterator and a default sentinel. @@ -311,7 +311,7 @@ constexpr bool test_non_forward_operator_minus(Iter zero_begin, Iter one_begin, } template -constexpr bool test_forward_operator_minus(Iter begin, Iter end, difference_type distance) { +constexpr bool test_forward_operator_plus(Iter begin, Iter end, difference_type distance) { // Test the forward-range operator- between two iterators (i.e., no ceil) and // an iterator and a default sentinel. using Base = BasicTestView; @@ -420,13 +420,13 @@ int main(int, char**) { { constexpr int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; std::vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - test_forward_operator_minus(arr, arr + 11, 4); - test_forward_operator_minus(vec.begin(), vec.end(), 4); + test_forward_operator_plus(arr, arr + 11, 4); + test_forward_operator_plus(vec.begin(), vec.end(), 4); } { int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - test_non_forward_operator_minus(SizedInputIterator(arr), SizedInputIterator(arr + 1), SizedInputIterator(arr + 10)); + test_non_forward_operator_plus(SizedInputIterator(arr), SizedInputIterator(arr + 1), SizedInputIterator(arr + 10)); } test_properly_handling_missing(); From 87f6972601330d63b5d4f9b64e9bc5ee49a70343 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sat, 17 Aug 2024 00:23:25 -0400 Subject: [PATCH 136/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix minor format error. Signed-off-by: Will Hawkins --- .../range.stride.view/iterator/increment.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp index 976876f08555f..ff5e3894c5d2c 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp @@ -41,7 +41,7 @@ static_assert(CanPreIncrementIterator); template requires std::sized_sentinel_for && (!std::forward_iterator) constexpr bool test_non_forward_operator_increment(Iter zero_begin, Iter three_begin, Iter end) { - using Base = BasicTestView; + using Base = BasicTestView; auto base_view_offset_zero = Base(zero_begin, end); auto base_view_offset_three = Base(three_begin, end); From 3b48b6e9d6e1949f149a073b29f58222716c03b3 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Tue, 10 Sep 2024 00:43:04 -0400 Subject: [PATCH 137/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Refactor and add additional tests. Signed-off-by: Will Hawkins --- .../iterator/operator.nodiscard.verify.cpp | 6 +- .../range.stride.view/adaptor.pass.cpp | 2 +- .../range.stride.view/iterator/base.pass.cpp | 18 +- .../iterator/ctor.copy.pass.cpp | 8 +- .../iterator/ctor.default.verify.cpp | 2 +- .../iterator/greater_than.pass.cpp | 435 ++++++++++++++++++ .../iterator/increment.pass.cpp | 2 +- .../iterator/less_than.pass.cpp | 435 ++++++++++++++++++ .../iterator/operator.pass.cpp | 2 +- .../iterator/plus_equal.pass.cpp | 106 +++++ .../range.adaptors/range.stride.view/types.h | 120 ++--- 11 files changed, 1063 insertions(+), 73 deletions(-) create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/greater_than.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/less_than.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus_equal.pass.cpp diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp index 5aa5c75a13937..e1121b7efc2bf 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp @@ -17,10 +17,10 @@ constexpr bool test_non_forward_operator_minus() { int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - using Base = BasicTestView; + using Base = BasicTestView; - auto base_view_offset_zero = Base(SizedInputIterator(arr), SizedInputIterator(arr + 10)); - auto base_view_offset_one = Base(SizedInputIterator(arr + 1), SizedInputIterator(arr + 10)); + auto base_view_offset_zero = Base(SizedInputIter(arr), SizedInputIter(arr + 10)); + auto base_view_offset_one = Base(SizedInputIter(arr + 1), SizedInputIter(arr + 10)); auto stride_view_over_base_zero_offset = std::ranges::stride_view(base_view_offset_zero, 3); auto stride_view_over_base_one_offset = std::ranges::stride_view(base_view_offset_one, 3); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index ea7fd588fd81f..71e27f7ffc7e8 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -25,7 +25,7 @@ using RandomAccessStrideView = std::ranges::stride_view, random_access_iterator>>; -using SizedInputStrideView = std::ranges::stride_view>; +using SizedInputStrideView = std::ranges::stride_view>; static_assert(std::ranges::forward_range); static_assert(std::ranges::bidirectional_range); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp index 5aadbef16331b..df30e0a10fa7b 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp @@ -53,13 +53,13 @@ bool base_move() { int move_counter = 0; int copy_counter = 0; - auto start = SizedInputIterator(); + auto start = SizedInputIter(); start.move_counter = &move_counter; start.copy_counter = ©_counter; - auto stop = SizedInputIterator(); + auto stop = SizedInputIter(); - auto view = BasicTestView{start, stop}; - auto sv = std::ranges::stride_view>(view, 1); + auto view = BasicTestView{start, stop}; + auto sv = std::ranges::stride_view>(view, 1); auto svi = sv.begin(); // Reset the move/copy counters so that they reflect *only* whether the @@ -78,20 +78,20 @@ bool base_copy() { // See above. int move_counter = 0; int copy_counter = 0; - auto start = SizedInputIterator(); + auto start = SizedInputIter(); start.move_counter = &move_counter; start.copy_counter = ©_counter; - auto stop = SizedInputIterator(); + auto stop = SizedInputIter(); - auto view = BasicTestView{start, stop}; - auto sv = std::ranges::stride_view>(view, 1); + auto view = BasicTestView{start, stop}; + auto sv = std::ranges::stride_view>(view, 1); [[maybe_unused]] auto svi = sv.begin(); // See above. move_counter = 0; copy_counter = 0; - [[maybe_unused]] const SizedInputIterator& result = svi.base(); + [[maybe_unused]] const SizedInputIter& result = svi.base(); // Ensure that base did _not_ std::move'd the iterator. assert(*result.move_counter == 0); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp index 2c52a39940465..1fbc46eccc9fc 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp @@ -25,7 +25,7 @@ struct NotSimpleViewConstIterEnd; template struct NotSimpleViewConstIterBegin; -struct NotSimpleViewIterBegin : InputIterBase { +struct NotSimpleViewIterBegin : InputIter { template friend constexpr bool operator==(const NotSimpleViewIterBegin&, const NotSimpleViewConstIterEnd&) { @@ -39,7 +39,7 @@ struct NotSimpleViewIterBegin : InputIterBase { }; template -struct NotSimpleViewConstIterBegin : InputIterBase> { +struct NotSimpleViewConstIterBegin : InputIter> { constexpr NotSimpleViewConstIterBegin() = default; constexpr NotSimpleViewConstIterBegin(NotSimpleViewConstIterBegin&&) = default; constexpr NotSimpleViewConstIterBegin& operator=(const NotSimpleViewConstIterBegin&) = default; @@ -63,7 +63,7 @@ struct NotSimpleViewConstIterBegin : InputIterBase { +struct NotSimpleViewIterEnd : InputIter { template friend constexpr bool operator==(const NotSimpleViewIterEnd&, const NotSimpleViewConstIterBegin&) { @@ -79,7 +79,7 @@ struct NotSimpleViewIterEnd : InputIterBase { }; template -struct NotSimpleViewConstIterEnd : InputIterBase> { +struct NotSimpleViewConstIterEnd : InputIter> { constexpr NotSimpleViewConstIterEnd() = default; constexpr NotSimpleViewConstIterEnd(NotSimpleViewConstIterEnd&&) = default; constexpr NotSimpleViewConstIterEnd& operator=(const NotSimpleViewConstIterEnd&) = default; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp index 4fbe9c0d2498e..4cb75667cf5de 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp @@ -16,7 +16,7 @@ #include "../types.h" #include "test_iterators.h" -struct NonDefaultConstructibleIterator : InputIterBase { +struct NonDefaultConstructibleIterator : InputIter { NonDefaultConstructibleIterator() = delete; constexpr NonDefaultConstructibleIterator(int) {} }; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/greater_than.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/greater_than.pass.cpp new file mode 100644 index 0000000000000..8d4c2643a5ce9 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/greater_than.pass.cpp @@ -0,0 +1,435 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// constexpr __iterator& operator++() +// constexpr void operator++(int) +// constexpr __iterator operator++(int) +// constexpr __iterator& operator--() +// constexpr __iterator operator--(int) +// constexpr __iterator& operator+=(difference_type __n) +// constexpr __iterator& operator-=(difference_type __n) +// friend constexpr bool operator==(__iterator const& __x, default_sentinel_t) +// friend constexpr bool operator==(__iterator const& __x, __iterator const& __y) +// friend constexpr bool operator<(__iterator const& __x, __iterator const& __y) +// friend constexpr bool operator>(__iterator const& __x, __iterator const& __y) +// friend constexpr bool operator<=(__iterator const& __x, __iterator const& __y) +// friend constexpr bool operator>=(__iterator const& __x, __iterator const& __y) +// friend constexpr bool operator<=>(__iterator const& __x, __iterator const& __y) + +#include +#include +#include +#include +#include +#include + +#include "../types.h" +#include "__compare/three_way_comparable.h" +#include "__concepts/equality_comparable.h" +#include "__concepts/same_as.h" +#include "__iterator/concepts.h" +#include "__iterator/default_sentinel.h" +#include "__iterator/distance.h" +#include "__ranges/access.h" +#include "__ranges/concepts.h" +#include "__ranges/stride_view.h" +#include "test_iterators.h" + +template +concept CanPlusEqual = std::is_same_v() += 1)> && requires(T& t) { t += 1; }; +template +concept CanMinusEqual = std::is_same_v() -= 1)> && requires(T& t) { t -= 1; }; + +template +concept CanMinus = + // Note: Do *not* use std::iterator_traits here because T may not have + // all the required pieces when it is not a forward_range. + std::is_same_v() - std::declval())> && + requires(T& t) { t - t; }; + +template +concept CanSentinelMinus = + // Note: Do *not* use std::iterator_traits here because T may not have + // all the required pieces when it is not a forward_range. + std::is_same_v() - std::default_sentinel)> && + std::is_same_v())> && requires(T& t) { + t - std::default_sentinel; + std::default_sentinel - t; + }; + +template +concept CanDifferencePlus = std::is_same_v() + 1)> && requires(T& t) { + t + 1; +} && std::is_same_v())> && requires(T& t) { 1 + t; }; +template +concept CanDifferenceMinus = std::is_same_v() - 1)> && requires(T& t) { t - 1; }; + +template +concept CanPostDecrement = std::is_same_v()--)> && requires(T& t) { t--; }; +template +concept CanPreDecrement = std::is_same_v())> && requires(T& t) { --t; }; + +template +concept CanSubscript = requires(T& t) { t[5]; }; + +// What operators are valid for an iterator derived from a stride view +// over an input view.(sized sentinel) +using InputView = BasicTestView, sized_sentinel>>; +using StrideViewOverInputViewIterator = std::ranges::iterator_t>; + +static_assert(std::weakly_incrementable); + +static_assert(!CanPostDecrement); +static_assert(!CanPreDecrement); +static_assert(!CanPlusEqual); +static_assert(!CanMinusEqual); +static_assert(!CanMinus); +static_assert(!CanDifferencePlus); +static_assert(!CanDifferenceMinus); +static_assert(CanSentinelMinus); +static_assert(std::invocable, StrideViewOverInputViewIterator, StrideViewOverInputViewIterator>); +static_assert(std::invocable, StrideViewOverInputViewIterator, std::default_sentinel_t>); +static_assert(std::invocable, std::default_sentinel_t, StrideViewOverInputViewIterator>); + +static_assert(!std::is_invocable_v, StrideViewOverInputViewIterator, StrideViewOverInputViewIterator>); +static_assert( + !std::is_invocable_v, StrideViewOverInputViewIterator, StrideViewOverInputViewIterator>); +static_assert(!std::is_invocable_v, StrideViewOverInputViewIterator, StrideViewOverInputViewIterator>); +static_assert( + !std::is_invocable_v, StrideViewOverInputViewIterator, StrideViewOverInputViewIterator>); + +static_assert(!CanSubscript); + +// What operators are valid for an iterator derived from a stride view +// over a forward view.(sized sentinel) +using ForwardView = BasicTestView, sized_sentinel>>; +using StrideViewOverForwardViewIterator = std::ranges::iterator_t>; + +static_assert(std::weakly_incrementable); + +static_assert(!CanPostDecrement); +static_assert(!CanPreDecrement); +static_assert(!CanPlusEqual); +static_assert(!CanMinusEqual); +static_assert(!CanMinus); +static_assert(!CanDifferencePlus); +static_assert(!CanDifferenceMinus); +static_assert(CanSentinelMinus); +static_assert(std::invocable, StrideViewOverForwardViewIterator, StrideViewOverForwardViewIterator>); +static_assert(std::invocable, StrideViewOverForwardViewIterator, std::default_sentinel_t>); +static_assert(std::invocable, std::default_sentinel_t, StrideViewOverForwardViewIterator>); + +static_assert(!std::is_invocable_v, StrideViewOverForwardViewIterator, StrideViewOverForwardViewIterator>); +static_assert( + !std::is_invocable_v, StrideViewOverForwardViewIterator, StrideViewOverForwardViewIterator>); +static_assert( + !std::is_invocable_v, StrideViewOverForwardViewIterator, StrideViewOverForwardViewIterator>); +static_assert( + !std::is_invocable_v, StrideViewOverForwardViewIterator, StrideViewOverForwardViewIterator>); + +static_assert(!CanSubscript); + +// What operators are valid for an iterator derived from a stride view +// over a bidirectional view. (sized sentinel) +using BidirectionalView = BasicTestView, sized_sentinel>>; +using StrideViewOverBidirectionalViewIterator = std::ranges::iterator_t>; + +static_assert(CanPostDecrement); +static_assert(CanPreDecrement); +static_assert(!CanPlusEqual); +static_assert(!CanMinusEqual); +static_assert(!CanMinus); +static_assert(!CanDifferencePlus); +static_assert(!CanDifferenceMinus); +static_assert(CanSentinelMinus); +static_assert( + std::invocable, StrideViewOverBidirectionalViewIterator, StrideViewOverBidirectionalViewIterator>); +static_assert(std::invocable, StrideViewOverBidirectionalViewIterator, std::default_sentinel_t>); +static_assert(std::invocable, std::default_sentinel_t, StrideViewOverBidirectionalViewIterator>); + +static_assert(!std::is_invocable_v, + StrideViewOverBidirectionalViewIterator, + StrideViewOverBidirectionalViewIterator>); +static_assert(!std::is_invocable_v, + StrideViewOverBidirectionalViewIterator, + StrideViewOverBidirectionalViewIterator>); +static_assert(!std::is_invocable_v, + StrideViewOverBidirectionalViewIterator, + StrideViewOverBidirectionalViewIterator>); +static_assert(!std::is_invocable_v, + StrideViewOverBidirectionalViewIterator, + StrideViewOverBidirectionalViewIterator>); + +static_assert(!CanSubscript); + +// What operators are valid for an iterator derived from a stride view +// over a random access view. (non sized sentinel) +using RandomAccessView = BasicTestView>; +using StrideViewOverRandomAccessViewIterator = std::ranges::iterator_t>; + +static_assert(std::weakly_incrementable); + +static_assert(CanPostDecrement); +static_assert(CanPreDecrement); +static_assert(CanPlusEqual); +static_assert(CanMinusEqual); +static_assert(CanMinus); +static_assert(CanDifferencePlus); +static_assert(CanDifferenceMinus); +static_assert(!CanSentinelMinus); +static_assert( + std::invocable, StrideViewOverRandomAccessViewIterator, StrideViewOverRandomAccessViewIterator>); +static_assert(std::invocable, StrideViewOverRandomAccessViewIterator, std::default_sentinel_t>); +static_assert(std::invocable, std::default_sentinel_t, StrideViewOverRandomAccessViewIterator>); + +static_assert( + std::is_invocable_v, StrideViewOverRandomAccessViewIterator, StrideViewOverRandomAccessViewIterator>); +static_assert(std::is_invocable_v, + StrideViewOverRandomAccessViewIterator, + StrideViewOverRandomAccessViewIterator>); +static_assert(std::is_invocable_v, + StrideViewOverRandomAccessViewIterator, + StrideViewOverRandomAccessViewIterator>); +static_assert(std::is_invocable_v, + StrideViewOverRandomAccessViewIterator, + StrideViewOverRandomAccessViewIterator>); + +static_assert(CanSubscript); + +using EqualableView = BasicTestView>; +using EqualableViewStrideView = std::ranges::stride_view; +using EqualableViewStrideViewIter = std::ranges::iterator_t; + +static_assert(std::equality_comparable>); +static_assert(std::equality_comparable); + +static_assert(!std::three_way_comparable>); +static_assert(!std::ranges::random_access_range); +static_assert(!std::three_way_comparable); + +using ThreeWayComparableView = BasicTestView>; +using ThreeWayComparableViewStrideView = std::ranges::stride_view; +using ThreeWayComparableStrideViewIter = std::ranges::iterator_t; + +static_assert(std::three_way_comparable>); +static_assert(std::ranges::random_access_range); +static_assert(std::three_way_comparable); + +using UnEqualableView = ViewOverNonCopyableIterator>; +using UnEqualableViewStrideView = std::ranges::stride_view; +using UnEqualableViewStrideViewIter = std::ranges::iterator_t; + +static_assert(!std::equality_comparable>); +static_assert(!std::equality_comparable); + +static_assert(!std::three_way_comparable>); +static_assert(!std::ranges::random_access_range); +static_assert(!std::three_way_comparable); + +template + requires std::sized_sentinel_for && (!std::forward_iterator) +constexpr bool test_non_forward_operator_minus(Iter zero_begin, Iter one_begin, Iter end) { + using Base = BasicTestView; + // Test the non-forward-range operator- between two iterators (i.e., ceil) and an + // iterator and a default sentinel. + using StrideViewIterator = std::ranges::iterator_t>; + static_assert(std::weakly_incrementable); + static_assert(!std::ranges::forward_range); + + // First, what operators are valid for an iterator derived from a stride view + // over a sized input view. + + static_assert(!CanPostDecrement); + static_assert(!CanPreDecrement); + static_assert(!CanPlusEqual); + static_assert(!CanMinusEqual); + static_assert(!CanDifferencePlus); + static_assert(!CanDifferenceMinus); + static_assert(CanSentinelMinus); + + static_assert(!std::is_invocable_v, StrideViewIterator, StrideViewIterator>); + static_assert(!std::is_invocable_v, StrideViewIterator, StrideViewIterator>); + static_assert(!std::is_invocable_v, StrideViewIterator, StrideViewIterator>); + static_assert(!std::is_invocable_v, StrideViewIterator, StrideViewIterator>); + static_assert(std::is_invocable_v, StrideViewIterator, StrideViewIterator>); + static_assert(std::is_invocable_v, std::default_sentinel_t, StrideViewIterator>); + static_assert(std::is_invocable_v, StrideViewIterator, std::default_sentinel_t>); + static_assert(!CanSubscript); + + auto base_view_offset_zero = Base(zero_begin, end); + auto base_view_offset_one = Base(one_begin, end); + auto stride_view_over_base_zero_offset = std::ranges::stride_view(base_view_offset_zero, 3); + auto stride_view_over_base_one_offset = std::ranges::stride_view(base_view_offset_one, 3); + + auto sv_zero_offset_begin = stride_view_over_base_zero_offset.begin(); + auto sv_one_offset_begin = stride_view_over_base_one_offset.begin(); + + auto sv_zero_offset_zeroth_index = sv_zero_offset_begin; + auto sv_zero_offset_third_index = ++sv_zero_offset_begin; // With a stride of 3, so ++ moves 3 indexes. + auto sv_zero_offset_sixth_index = ++sv_zero_offset_begin; // With a stride of 3, so ++ moves 3 indexes. + + auto sv_one_offset_oneth_index = sv_one_offset_begin; + auto sv_one_offset_fourth_index = ++sv_one_offset_begin; // With a stride of 3, so ++ moves 3 indexes. + + static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); + static_assert(CanMinus); + + // Check positive __n with exact multiple of left's stride. + assert(sv_zero_offset_third_index - sv_zero_offset_zeroth_index == 1); + assert(sv_zero_offset_sixth_index - sv_zero_offset_zeroth_index == 2); + // Check positive __n with non-exact multiple of left's stride (will do ceil here). + assert(sv_one_offset_oneth_index - sv_zero_offset_zeroth_index == 1); + assert(sv_one_offset_fourth_index - sv_zero_offset_zeroth_index == 2); + + // Check negative __n with exact multiple of left's stride. + assert(sv_zero_offset_zeroth_index - sv_zero_offset_third_index == -1); + assert(sv_zero_offset_zeroth_index - sv_zero_offset_sixth_index == -2); + // Check negative __n with non-exact multiple of left's stride (will do ceil here). + assert(sv_zero_offset_zeroth_index - sv_one_offset_oneth_index == -1); + assert(sv_zero_offset_zeroth_index - sv_one_offset_fourth_index == -2); + + assert(stride_view_over_base_zero_offset.end() == std::default_sentinel); + assert(std::default_sentinel == stride_view_over_base_zero_offset.end()); + + assert(std::default_sentinel - stride_view_over_base_zero_offset.end() == 0); + assert(stride_view_over_base_zero_offset.end() - std::default_sentinel == 0); + // assert((std::default_sentinel - )== 0); + + assert(std::default_sentinel - stride_view_over_base_zero_offset.begin() == + std::ranges::distance(stride_view_over_base_zero_offset)); + assert(stride_view_over_base_zero_offset.begin() - std::default_sentinel == + -std::ranges::distance(stride_view_over_base_zero_offset)); + + return true; +} + +template +constexpr bool test_forward_operator_minus(Iter begin, Iter end, difference_type distance) { + // Test the forward-range operator- between two iterators (i.e., no ceil) and + // an iterator and a default sentinel. + using Base = BasicTestView; + + using StrideViewIterator = std::ranges::iterator_t>; + static_assert(std::ranges::forward_range); + static_assert(std::weakly_incrementable); + + // First, what operators are valid for an iterator derived from a stride view + // over a sized forward view (even though it is actually much more than that!). + + static_assert(CanMinus); + static_assert(CanSentinelMinus); + + auto base_view_offset_zero = Base(begin, end); + auto base_view_offset_one = Base(begin + 1, end); + auto stride_view_over_base_zero_offset = std::ranges::stride_view(base_view_offset_zero, 3); + auto stride_view_over_base_one_offset = std::ranges::stride_view(base_view_offset_one, 3); + + auto sv_zero_offset_begin = stride_view_over_base_zero_offset.begin(); + auto sv_one_offset_begin = stride_view_over_base_one_offset.begin(); + + auto sv_zero_offset_should_be_one = sv_zero_offset_begin; + auto sv_zero_offset_should_be_four = ++sv_zero_offset_begin; + auto sv_zero_offset_should_be_seven = ++sv_zero_offset_begin; + + auto sv_one_offset_should_be_two = sv_one_offset_begin; + auto sv_one_offset_should_be_five = ++sv_one_offset_begin; + + static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); + static_assert(CanMinus); + static_assert(std::forward_iterator>); + + // Check positive __n with exact multiple of left's stride. + assert(sv_zero_offset_should_be_four - sv_zero_offset_should_be_one == 1); + assert(sv_zero_offset_should_be_seven - sv_zero_offset_should_be_one == 2); + + // Check positive __n with non-exact multiple of left's stride. + assert(sv_one_offset_should_be_two - sv_zero_offset_should_be_one == 0); + assert(sv_one_offset_should_be_five - sv_zero_offset_should_be_one == 1); + + // Check negative __n with exact multiple of left's stride. + assert(sv_zero_offset_should_be_one - sv_zero_offset_should_be_four == -1); + assert(sv_zero_offset_should_be_one - sv_zero_offset_should_be_seven == -2); + + // Check negative __n with non-exact multiple of left's stride. + assert(sv_zero_offset_should_be_one - sv_one_offset_should_be_two == 0); + assert(sv_zero_offset_should_be_one - sv_one_offset_should_be_five == -1); + + // Make sure that all sentinel operations work! + assert(stride_view_over_base_zero_offset.end() == std::default_sentinel); + assert(std::default_sentinel == stride_view_over_base_zero_offset.end()); + + assert(stride_view_over_base_zero_offset.end() - std::default_sentinel == 0); + assert(std::default_sentinel - stride_view_over_base_zero_offset.begin() == + std::ranges::distance(stride_view_over_base_zero_offset)); + assert(stride_view_over_base_zero_offset.begin() - std::default_sentinel == + -std::ranges::distance(stride_view_over_base_zero_offset)); + assert(stride_view_over_base_zero_offset.begin() - std::default_sentinel == -distance); + assert(std::default_sentinel - stride_view_over_base_zero_offset.begin() == distance); + return true; +} + +constexpr bool test_properly_handling_missing() { + // Check whether __missing_ gets handled properly. + using Base = BasicTestView; + int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + auto base = Base(arr, arr + 10); + auto strider = std::ranges::stride_view(base, 7); + + auto strider_iter = strider.end(); + + strider_iter--; + assert(*strider_iter == 8); + + // Now that we are back among the valid, we should + // have a normal stride length back (i.e., __missing_ + // should be equal to 0). + strider_iter--; + assert(*strider_iter == 1); + + strider_iter++; + assert(*strider_iter == 8); + + // By striding past the end, we are going to generate + // another __missing_ != 0 value. + strider_iter++; + assert(strider_iter == strider.end()); + + // Make sure that all sentinel operations work! + assert(strider.end() == std::default_sentinel); + assert(std::default_sentinel == strider.end()); + + assert(strider_iter - std::default_sentinel == 0); + assert(std::default_sentinel - strider.end() == 0); + assert(std::default_sentinel - strider_iter == 0); + + // Let's make sure that the newly regenerated __missing__ gets used. + strider_iter += -2; + assert(*strider_iter == 1); + + return true; +} + +int main(int, char**) { + { + constexpr int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + std::vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + test_forward_operator_minus(arr, arr + 11, 4); + test_forward_operator_minus(vec.begin(), vec.end(), 4); + } + + { + int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + test_non_forward_operator_minus(SizedInputIter(arr), SizedInputIter(arr + 1), SizedInputIter(arr + 10)); + } + + test_properly_handling_missing(); + static_assert(test_properly_handling_missing()); + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp index ff5e3894c5d2c..5b41bde52146a 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp @@ -197,7 +197,7 @@ int main(int, char**) { { int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; test_non_forward_operator_increment( - SizedInputIterator(arr), SizedInputIterator(arr + 3), SizedInputIterator(arr + 10)); + SizedInputIter(arr), SizedInputIter(arr + 3), SizedInputIter(arr + 10)); } test_properly_handling_missing(); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/less_than.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/less_than.pass.cpp new file mode 100644 index 0000000000000..8d4c2643a5ce9 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/less_than.pass.cpp @@ -0,0 +1,435 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// constexpr __iterator& operator++() +// constexpr void operator++(int) +// constexpr __iterator operator++(int) +// constexpr __iterator& operator--() +// constexpr __iterator operator--(int) +// constexpr __iterator& operator+=(difference_type __n) +// constexpr __iterator& operator-=(difference_type __n) +// friend constexpr bool operator==(__iterator const& __x, default_sentinel_t) +// friend constexpr bool operator==(__iterator const& __x, __iterator const& __y) +// friend constexpr bool operator<(__iterator const& __x, __iterator const& __y) +// friend constexpr bool operator>(__iterator const& __x, __iterator const& __y) +// friend constexpr bool operator<=(__iterator const& __x, __iterator const& __y) +// friend constexpr bool operator>=(__iterator const& __x, __iterator const& __y) +// friend constexpr bool operator<=>(__iterator const& __x, __iterator const& __y) + +#include +#include +#include +#include +#include +#include + +#include "../types.h" +#include "__compare/three_way_comparable.h" +#include "__concepts/equality_comparable.h" +#include "__concepts/same_as.h" +#include "__iterator/concepts.h" +#include "__iterator/default_sentinel.h" +#include "__iterator/distance.h" +#include "__ranges/access.h" +#include "__ranges/concepts.h" +#include "__ranges/stride_view.h" +#include "test_iterators.h" + +template +concept CanPlusEqual = std::is_same_v() += 1)> && requires(T& t) { t += 1; }; +template +concept CanMinusEqual = std::is_same_v() -= 1)> && requires(T& t) { t -= 1; }; + +template +concept CanMinus = + // Note: Do *not* use std::iterator_traits here because T may not have + // all the required pieces when it is not a forward_range. + std::is_same_v() - std::declval())> && + requires(T& t) { t - t; }; + +template +concept CanSentinelMinus = + // Note: Do *not* use std::iterator_traits here because T may not have + // all the required pieces when it is not a forward_range. + std::is_same_v() - std::default_sentinel)> && + std::is_same_v())> && requires(T& t) { + t - std::default_sentinel; + std::default_sentinel - t; + }; + +template +concept CanDifferencePlus = std::is_same_v() + 1)> && requires(T& t) { + t + 1; +} && std::is_same_v())> && requires(T& t) { 1 + t; }; +template +concept CanDifferenceMinus = std::is_same_v() - 1)> && requires(T& t) { t - 1; }; + +template +concept CanPostDecrement = std::is_same_v()--)> && requires(T& t) { t--; }; +template +concept CanPreDecrement = std::is_same_v())> && requires(T& t) { --t; }; + +template +concept CanSubscript = requires(T& t) { t[5]; }; + +// What operators are valid for an iterator derived from a stride view +// over an input view.(sized sentinel) +using InputView = BasicTestView, sized_sentinel>>; +using StrideViewOverInputViewIterator = std::ranges::iterator_t>; + +static_assert(std::weakly_incrementable); + +static_assert(!CanPostDecrement); +static_assert(!CanPreDecrement); +static_assert(!CanPlusEqual); +static_assert(!CanMinusEqual); +static_assert(!CanMinus); +static_assert(!CanDifferencePlus); +static_assert(!CanDifferenceMinus); +static_assert(CanSentinelMinus); +static_assert(std::invocable, StrideViewOverInputViewIterator, StrideViewOverInputViewIterator>); +static_assert(std::invocable, StrideViewOverInputViewIterator, std::default_sentinel_t>); +static_assert(std::invocable, std::default_sentinel_t, StrideViewOverInputViewIterator>); + +static_assert(!std::is_invocable_v, StrideViewOverInputViewIterator, StrideViewOverInputViewIterator>); +static_assert( + !std::is_invocable_v, StrideViewOverInputViewIterator, StrideViewOverInputViewIterator>); +static_assert(!std::is_invocable_v, StrideViewOverInputViewIterator, StrideViewOverInputViewIterator>); +static_assert( + !std::is_invocable_v, StrideViewOverInputViewIterator, StrideViewOverInputViewIterator>); + +static_assert(!CanSubscript); + +// What operators are valid for an iterator derived from a stride view +// over a forward view.(sized sentinel) +using ForwardView = BasicTestView, sized_sentinel>>; +using StrideViewOverForwardViewIterator = std::ranges::iterator_t>; + +static_assert(std::weakly_incrementable); + +static_assert(!CanPostDecrement); +static_assert(!CanPreDecrement); +static_assert(!CanPlusEqual); +static_assert(!CanMinusEqual); +static_assert(!CanMinus); +static_assert(!CanDifferencePlus); +static_assert(!CanDifferenceMinus); +static_assert(CanSentinelMinus); +static_assert(std::invocable, StrideViewOverForwardViewIterator, StrideViewOverForwardViewIterator>); +static_assert(std::invocable, StrideViewOverForwardViewIterator, std::default_sentinel_t>); +static_assert(std::invocable, std::default_sentinel_t, StrideViewOverForwardViewIterator>); + +static_assert(!std::is_invocable_v, StrideViewOverForwardViewIterator, StrideViewOverForwardViewIterator>); +static_assert( + !std::is_invocable_v, StrideViewOverForwardViewIterator, StrideViewOverForwardViewIterator>); +static_assert( + !std::is_invocable_v, StrideViewOverForwardViewIterator, StrideViewOverForwardViewIterator>); +static_assert( + !std::is_invocable_v, StrideViewOverForwardViewIterator, StrideViewOverForwardViewIterator>); + +static_assert(!CanSubscript); + +// What operators are valid for an iterator derived from a stride view +// over a bidirectional view. (sized sentinel) +using BidirectionalView = BasicTestView, sized_sentinel>>; +using StrideViewOverBidirectionalViewIterator = std::ranges::iterator_t>; + +static_assert(CanPostDecrement); +static_assert(CanPreDecrement); +static_assert(!CanPlusEqual); +static_assert(!CanMinusEqual); +static_assert(!CanMinus); +static_assert(!CanDifferencePlus); +static_assert(!CanDifferenceMinus); +static_assert(CanSentinelMinus); +static_assert( + std::invocable, StrideViewOverBidirectionalViewIterator, StrideViewOverBidirectionalViewIterator>); +static_assert(std::invocable, StrideViewOverBidirectionalViewIterator, std::default_sentinel_t>); +static_assert(std::invocable, std::default_sentinel_t, StrideViewOverBidirectionalViewIterator>); + +static_assert(!std::is_invocable_v, + StrideViewOverBidirectionalViewIterator, + StrideViewOverBidirectionalViewIterator>); +static_assert(!std::is_invocable_v, + StrideViewOverBidirectionalViewIterator, + StrideViewOverBidirectionalViewIterator>); +static_assert(!std::is_invocable_v, + StrideViewOverBidirectionalViewIterator, + StrideViewOverBidirectionalViewIterator>); +static_assert(!std::is_invocable_v, + StrideViewOverBidirectionalViewIterator, + StrideViewOverBidirectionalViewIterator>); + +static_assert(!CanSubscript); + +// What operators are valid for an iterator derived from a stride view +// over a random access view. (non sized sentinel) +using RandomAccessView = BasicTestView>; +using StrideViewOverRandomAccessViewIterator = std::ranges::iterator_t>; + +static_assert(std::weakly_incrementable); + +static_assert(CanPostDecrement); +static_assert(CanPreDecrement); +static_assert(CanPlusEqual); +static_assert(CanMinusEqual); +static_assert(CanMinus); +static_assert(CanDifferencePlus); +static_assert(CanDifferenceMinus); +static_assert(!CanSentinelMinus); +static_assert( + std::invocable, StrideViewOverRandomAccessViewIterator, StrideViewOverRandomAccessViewIterator>); +static_assert(std::invocable, StrideViewOverRandomAccessViewIterator, std::default_sentinel_t>); +static_assert(std::invocable, std::default_sentinel_t, StrideViewOverRandomAccessViewIterator>); + +static_assert( + std::is_invocable_v, StrideViewOverRandomAccessViewIterator, StrideViewOverRandomAccessViewIterator>); +static_assert(std::is_invocable_v, + StrideViewOverRandomAccessViewIterator, + StrideViewOverRandomAccessViewIterator>); +static_assert(std::is_invocable_v, + StrideViewOverRandomAccessViewIterator, + StrideViewOverRandomAccessViewIterator>); +static_assert(std::is_invocable_v, + StrideViewOverRandomAccessViewIterator, + StrideViewOverRandomAccessViewIterator>); + +static_assert(CanSubscript); + +using EqualableView = BasicTestView>; +using EqualableViewStrideView = std::ranges::stride_view; +using EqualableViewStrideViewIter = std::ranges::iterator_t; + +static_assert(std::equality_comparable>); +static_assert(std::equality_comparable); + +static_assert(!std::three_way_comparable>); +static_assert(!std::ranges::random_access_range); +static_assert(!std::three_way_comparable); + +using ThreeWayComparableView = BasicTestView>; +using ThreeWayComparableViewStrideView = std::ranges::stride_view; +using ThreeWayComparableStrideViewIter = std::ranges::iterator_t; + +static_assert(std::three_way_comparable>); +static_assert(std::ranges::random_access_range); +static_assert(std::three_way_comparable); + +using UnEqualableView = ViewOverNonCopyableIterator>; +using UnEqualableViewStrideView = std::ranges::stride_view; +using UnEqualableViewStrideViewIter = std::ranges::iterator_t; + +static_assert(!std::equality_comparable>); +static_assert(!std::equality_comparable); + +static_assert(!std::three_way_comparable>); +static_assert(!std::ranges::random_access_range); +static_assert(!std::three_way_comparable); + +template + requires std::sized_sentinel_for && (!std::forward_iterator) +constexpr bool test_non_forward_operator_minus(Iter zero_begin, Iter one_begin, Iter end) { + using Base = BasicTestView; + // Test the non-forward-range operator- between two iterators (i.e., ceil) and an + // iterator and a default sentinel. + using StrideViewIterator = std::ranges::iterator_t>; + static_assert(std::weakly_incrementable); + static_assert(!std::ranges::forward_range); + + // First, what operators are valid for an iterator derived from a stride view + // over a sized input view. + + static_assert(!CanPostDecrement); + static_assert(!CanPreDecrement); + static_assert(!CanPlusEqual); + static_assert(!CanMinusEqual); + static_assert(!CanDifferencePlus); + static_assert(!CanDifferenceMinus); + static_assert(CanSentinelMinus); + + static_assert(!std::is_invocable_v, StrideViewIterator, StrideViewIterator>); + static_assert(!std::is_invocable_v, StrideViewIterator, StrideViewIterator>); + static_assert(!std::is_invocable_v, StrideViewIterator, StrideViewIterator>); + static_assert(!std::is_invocable_v, StrideViewIterator, StrideViewIterator>); + static_assert(std::is_invocable_v, StrideViewIterator, StrideViewIterator>); + static_assert(std::is_invocable_v, std::default_sentinel_t, StrideViewIterator>); + static_assert(std::is_invocable_v, StrideViewIterator, std::default_sentinel_t>); + static_assert(!CanSubscript); + + auto base_view_offset_zero = Base(zero_begin, end); + auto base_view_offset_one = Base(one_begin, end); + auto stride_view_over_base_zero_offset = std::ranges::stride_view(base_view_offset_zero, 3); + auto stride_view_over_base_one_offset = std::ranges::stride_view(base_view_offset_one, 3); + + auto sv_zero_offset_begin = stride_view_over_base_zero_offset.begin(); + auto sv_one_offset_begin = stride_view_over_base_one_offset.begin(); + + auto sv_zero_offset_zeroth_index = sv_zero_offset_begin; + auto sv_zero_offset_third_index = ++sv_zero_offset_begin; // With a stride of 3, so ++ moves 3 indexes. + auto sv_zero_offset_sixth_index = ++sv_zero_offset_begin; // With a stride of 3, so ++ moves 3 indexes. + + auto sv_one_offset_oneth_index = sv_one_offset_begin; + auto sv_one_offset_fourth_index = ++sv_one_offset_begin; // With a stride of 3, so ++ moves 3 indexes. + + static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); + static_assert(CanMinus); + + // Check positive __n with exact multiple of left's stride. + assert(sv_zero_offset_third_index - sv_zero_offset_zeroth_index == 1); + assert(sv_zero_offset_sixth_index - sv_zero_offset_zeroth_index == 2); + // Check positive __n with non-exact multiple of left's stride (will do ceil here). + assert(sv_one_offset_oneth_index - sv_zero_offset_zeroth_index == 1); + assert(sv_one_offset_fourth_index - sv_zero_offset_zeroth_index == 2); + + // Check negative __n with exact multiple of left's stride. + assert(sv_zero_offset_zeroth_index - sv_zero_offset_third_index == -1); + assert(sv_zero_offset_zeroth_index - sv_zero_offset_sixth_index == -2); + // Check negative __n with non-exact multiple of left's stride (will do ceil here). + assert(sv_zero_offset_zeroth_index - sv_one_offset_oneth_index == -1); + assert(sv_zero_offset_zeroth_index - sv_one_offset_fourth_index == -2); + + assert(stride_view_over_base_zero_offset.end() == std::default_sentinel); + assert(std::default_sentinel == stride_view_over_base_zero_offset.end()); + + assert(std::default_sentinel - stride_view_over_base_zero_offset.end() == 0); + assert(stride_view_over_base_zero_offset.end() - std::default_sentinel == 0); + // assert((std::default_sentinel - )== 0); + + assert(std::default_sentinel - stride_view_over_base_zero_offset.begin() == + std::ranges::distance(stride_view_over_base_zero_offset)); + assert(stride_view_over_base_zero_offset.begin() - std::default_sentinel == + -std::ranges::distance(stride_view_over_base_zero_offset)); + + return true; +} + +template +constexpr bool test_forward_operator_minus(Iter begin, Iter end, difference_type distance) { + // Test the forward-range operator- between two iterators (i.e., no ceil) and + // an iterator and a default sentinel. + using Base = BasicTestView; + + using StrideViewIterator = std::ranges::iterator_t>; + static_assert(std::ranges::forward_range); + static_assert(std::weakly_incrementable); + + // First, what operators are valid for an iterator derived from a stride view + // over a sized forward view (even though it is actually much more than that!). + + static_assert(CanMinus); + static_assert(CanSentinelMinus); + + auto base_view_offset_zero = Base(begin, end); + auto base_view_offset_one = Base(begin + 1, end); + auto stride_view_over_base_zero_offset = std::ranges::stride_view(base_view_offset_zero, 3); + auto stride_view_over_base_one_offset = std::ranges::stride_view(base_view_offset_one, 3); + + auto sv_zero_offset_begin = stride_view_over_base_zero_offset.begin(); + auto sv_one_offset_begin = stride_view_over_base_one_offset.begin(); + + auto sv_zero_offset_should_be_one = sv_zero_offset_begin; + auto sv_zero_offset_should_be_four = ++sv_zero_offset_begin; + auto sv_zero_offset_should_be_seven = ++sv_zero_offset_begin; + + auto sv_one_offset_should_be_two = sv_one_offset_begin; + auto sv_one_offset_should_be_five = ++sv_one_offset_begin; + + static_assert(std::sized_sentinel_for, std::ranges::iterator_t>); + static_assert(CanMinus); + static_assert(std::forward_iterator>); + + // Check positive __n with exact multiple of left's stride. + assert(sv_zero_offset_should_be_four - sv_zero_offset_should_be_one == 1); + assert(sv_zero_offset_should_be_seven - sv_zero_offset_should_be_one == 2); + + // Check positive __n with non-exact multiple of left's stride. + assert(sv_one_offset_should_be_two - sv_zero_offset_should_be_one == 0); + assert(sv_one_offset_should_be_five - sv_zero_offset_should_be_one == 1); + + // Check negative __n with exact multiple of left's stride. + assert(sv_zero_offset_should_be_one - sv_zero_offset_should_be_four == -1); + assert(sv_zero_offset_should_be_one - sv_zero_offset_should_be_seven == -2); + + // Check negative __n with non-exact multiple of left's stride. + assert(sv_zero_offset_should_be_one - sv_one_offset_should_be_two == 0); + assert(sv_zero_offset_should_be_one - sv_one_offset_should_be_five == -1); + + // Make sure that all sentinel operations work! + assert(stride_view_over_base_zero_offset.end() == std::default_sentinel); + assert(std::default_sentinel == stride_view_over_base_zero_offset.end()); + + assert(stride_view_over_base_zero_offset.end() - std::default_sentinel == 0); + assert(std::default_sentinel - stride_view_over_base_zero_offset.begin() == + std::ranges::distance(stride_view_over_base_zero_offset)); + assert(stride_view_over_base_zero_offset.begin() - std::default_sentinel == + -std::ranges::distance(stride_view_over_base_zero_offset)); + assert(stride_view_over_base_zero_offset.begin() - std::default_sentinel == -distance); + assert(std::default_sentinel - stride_view_over_base_zero_offset.begin() == distance); + return true; +} + +constexpr bool test_properly_handling_missing() { + // Check whether __missing_ gets handled properly. + using Base = BasicTestView; + int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + auto base = Base(arr, arr + 10); + auto strider = std::ranges::stride_view(base, 7); + + auto strider_iter = strider.end(); + + strider_iter--; + assert(*strider_iter == 8); + + // Now that we are back among the valid, we should + // have a normal stride length back (i.e., __missing_ + // should be equal to 0). + strider_iter--; + assert(*strider_iter == 1); + + strider_iter++; + assert(*strider_iter == 8); + + // By striding past the end, we are going to generate + // another __missing_ != 0 value. + strider_iter++; + assert(strider_iter == strider.end()); + + // Make sure that all sentinel operations work! + assert(strider.end() == std::default_sentinel); + assert(std::default_sentinel == strider.end()); + + assert(strider_iter - std::default_sentinel == 0); + assert(std::default_sentinel - strider.end() == 0); + assert(std::default_sentinel - strider_iter == 0); + + // Let's make sure that the newly regenerated __missing__ gets used. + strider_iter += -2; + assert(*strider_iter == 1); + + return true; +} + +int main(int, char**) { + { + constexpr int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + std::vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + test_forward_operator_minus(arr, arr + 11, 4); + test_forward_operator_minus(vec.begin(), vec.end(), 4); + } + + { + int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + test_non_forward_operator_minus(SizedInputIter(arr), SizedInputIter(arr + 1), SizedInputIter(arr + 10)); + } + + test_properly_handling_missing(); + static_assert(test_properly_handling_missing()); + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index f68350c50382e..87a6090d552eb 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -426,7 +426,7 @@ int main(int, char**) { { int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - test_non_forward_operator_plus(SizedInputIterator(arr), SizedInputIterator(arr + 1), SizedInputIterator(arr + 10)); + test_non_forward_operator_plus(SizedInputIter(arr), SizedInputIter(arr + 1), SizedInputIter(arr + 10)); } test_properly_handling_missing(); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus_equal.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus_equal.pass.cpp new file mode 100644 index 0000000000000..6d8ae7dec2f73 --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus_equal.pass.cpp @@ -0,0 +1,106 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// constexpr __iterator& operator+=(difference_type __n) + +#include +#include + +#include "../types.h" +#include "__iterator/concepts.h" +#include "__ranges/concepts.h" +#include "test_iterators.h" + +template +concept CanPlusEqual = std::is_same_v() += 1)> && requires(T& t) { t += 1; }; + +// Make sure that we cannot use += on a stride view iterator +// over an input view.(sized sentinel) +using InputView = BasicTestView, sized_sentinel>>; +using StrideViewOverInputViewIterator = std::ranges::iterator_t>; + +static_assert(std::ranges::input_range); +static_assert(!CanPlusEqual); + +// Make sure that we cannot use += on a stride view iterator +// over a forward view.(sized sentinel) +using ForwardView = BasicTestView, sized_sentinel>>; +using StrideViewOverForwardViewIterator = std::ranges::iterator_t>; + +static_assert(std::ranges::forward_range); +static_assert(!CanPlusEqual); + +// Make sure that we cannot use += on a stride view iterator +// over a bidirectional view. (sized sentinel) +using BidirectionalView = BasicTestView, sized_sentinel>>; +using StrideViewOverBidirectionalViewIterator = std::ranges::iterator_t>; + +static_assert(std::ranges::bidirectional_range); +static_assert(!CanPlusEqual); + +// Make sure that we can use += on a stride view iterator +// over a random access view. (non sized sentinel) +template > +using RandomAccessView = BasicTestView; +using StrideViewOverRandomAccessViewIterator = std::ranges::iterator_t>>; + +static_assert(std::ranges::random_access_range>); +static_assert(CanPlusEqual); + +template +constexpr bool test_random_access_operator_plus_equal(Iter begin, Iter end, Difference distance) { + // Test the forward-range operator+= between an iterator and its distance type. + // Do not use the RandomAccessView defined in types.h to give the test user more power + // to customize an iterator and a default sentinel. + using Base = RandomAccessView; + static_assert(std::ranges::random_access_range); + + auto base_view = Base(begin, end); + auto stride_view_over_base_view = std::ranges::stride_view(base_view, 1); + + auto base_view_offset = Base(begin + distance, end); + auto stride_view_over_base_view_offset = std::ranges::stride_view(base_view_offset, 1); + + auto sv_bv_begin = stride_view_over_base_view.begin(); + auto sv_bv_offset_begin = stride_view_over_base_view_offset.begin(); + + auto sv_bv_begin_after_distance = sv_bv_begin += distance; + assert(*sv_bv_begin == *sv_bv_offset_begin); + assert(*sv_bv_begin_after_distance == *sv_bv_offset_begin); + + auto big_step = (end - 1) - begin; + auto stride_view_over_base_view_big_step = std::ranges::stride_view(base_view, big_step); + sv_bv_begin = stride_view_over_base_view_big_step.begin(); + + // This += should move us into a position where the __missing_ will come into play. + // Do a -= 1 here to confirm that the __missing_ is taken into account. + sv_bv_begin += 2; + sv_bv_begin -= 1; + assert(*sv_bv_begin == *(stride_view_over_base_view.begin() + big_step)); + return true; +} + +consteval bool do_static_tests() { + std::vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + assert(test_random_access_operator_plus_equal(vec.begin(), vec.end(), 4)); + return true; +} + +int main(int, char**) { + constexpr int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + static_assert(test_random_access_operator_plus_equal(arr, arr + 11, 4)); + test_random_access_operator_plus_equal(arr, arr + 11, 4); + + static_assert(do_static_tests()); + + std::vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + assert(test_random_access_operator_plus_equal(vec.begin(), vec.end(), 4)); + return 0; +} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index 12fab146c0b6d..abacd97f238b3 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -9,6 +9,7 @@ #ifndef TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H #define TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_STRIDE_TYPES_H +#include #include #include #include @@ -27,25 +28,22 @@ concept IterDifferable = std::invocable, Iter, Iter>; // Iterators -// The base for an input iterator that keeps a count of the times that it is +// The base for an iterator that keeps a count of the times that it is // moved and copied. -template - requires((!IsSized) || (IsSized && IterDifferable)) -struct InputIterBase { - using iterator_concept = std::input_iterator_tag; - using iterator_category = std::input_iterator_tag; - using value_type = typename std::iterator_traits::value_type; - using difference_type = typename std::iterator_traits::difference_type; +template +struct IterBase { + using value_type = typename std::iterator_traits::value_type; + using difference_type = typename std::iterator_traits::difference_type; int* move_counter = nullptr; int* copy_counter = nullptr; Iter value_{}; - constexpr InputIterBase() = default; - constexpr explicit InputIterBase(Iter value) : value_(value) {} + constexpr IterBase() = default; + constexpr explicit IterBase(Iter value) : value_(value) {} - constexpr InputIterBase(const InputIterBase& other) noexcept { + constexpr IterBase(const IterBase& other) noexcept { copy_counter = other.copy_counter; move_counter = other.move_counter; if (copy_counter != nullptr) { @@ -54,7 +52,7 @@ struct InputIterBase { value_ = other.value_; } - constexpr InputIterBase(InputIterBase&& other) noexcept { + constexpr IterBase(IterBase&& other) noexcept { copy_counter = other.copy_counter; move_counter = other.move_counter; if (move_counter != nullptr) { @@ -62,17 +60,33 @@ struct InputIterBase { } value_ = std::move(other.value_); } - constexpr InputIterBase& operator=(const InputIterBase& other) = default; - constexpr InputIterBase& operator=(InputIterBase&& other) = default; + constexpr IterBase& operator=(const IterBase& other) = default; + constexpr IterBase& operator=(IterBase&& other) = default; +}; + +// The base for an input iterator that keeps a count of the times that it is +// moved and copied. +template + requires((!IsSized) || (IsSized && IterDifferable)) +struct InputIter : IterBase { + using Base = IterBase; + + using typename Base::difference_type; + using typename Base::value_type; - constexpr value_type operator*() const { return *value_; } + using iterator_concept = std::input_iterator_tag; + using iterator_category = std::input_iterator_tag; + + using Base::Base; + + constexpr value_type operator*() const { return *Base::value_; } constexpr Derived& operator++() { - value_++; + Base::value_++; return static_cast(*this); } constexpr Derived operator++(int) { auto nv = *this; - value_++; + Base::value_++; return nv; } friend constexpr bool operator==(const Derived& left, const Derived& right) { return left.value_ == right.value_; } @@ -83,12 +97,19 @@ struct InputIterBase { } }; +// In input iterator that is unsized. +struct UnsizedInputIter : InputIter { + using InputIter::InputIter; +}; +static_assert(std::input_iterator); +static_assert(!std::sized_sentinel_for); + // In input iterator that is sized. -struct SizedInputIterator : InputIterBase { - using InputIterBase::InputIterBase; +struct SizedInputIter : InputIter { + using InputIter::InputIter; }; -static_assert(std::input_iterator); -static_assert(std::sized_sentinel_for); +static_assert(std::input_iterator); +static_assert(std::sized_sentinel_for); // Views @@ -97,15 +118,14 @@ static_assert(std::sized_sentinel_for); namespace adl { template struct IterMoveIterSwapTestRangeIterator - : InputIterBase, Iter, false> { + : InputIter, Iter, false> { int* counter_{nullptr}; - using InputIterBase, Iter, false>:: - InputIterBase; + using InputIter, Iter, false>:: + InputIter; constexpr IterMoveIterSwapTestRangeIterator(Iter value, int* counter) - : InputIterBase, Iter, false>( - value), + : InputIter, Iter, false>(value), counter_(counter) {} friend constexpr void iter_swap(IterMoveIterSwapTestRangeIterator t, IterMoveIterSwapTestRangeIterator u) noexcept @@ -152,18 +172,19 @@ struct IterMoveIterSwapTestRange : std::ranges::view_base { // Views -template -struct ViewOrRange {}; - +// Depending upon configuration, ViewOrRange is either a View or not. +template +struct MaybeView {}; template <> -struct ViewOrRange : std::ranges::view_base {}; +struct MaybeView : std::ranges::view_base {}; template Sent = sentinel_wrapper, bool IsSized = false, - bool IsView = false> + bool IsView = false, + bool IsCopyable = false > requires((!IsSized) || (IsSized && IterDifferable)) -struct BasicTestViewOrRange : ViewOrRange { +struct BasicTestViewOrRange : MaybeView { Iter begin_{}; Iter end_{}; @@ -179,39 +200,32 @@ struct BasicTestViewOrRange : ViewOrRange { { return begin_ - end_; } -}; -template Sent = sentinel_wrapper, bool IsSized = false> - requires((!IsSized) || (IsSized && IterDifferable)) -using BasicTestView = BasicTestViewOrRange; + constexpr BasicTestViewOrRange(BasicTestViewOrRange&& other) = default; + constexpr BasicTestViewOrRange& operator=(BasicTestViewOrRange&&) = default; -template Sent = sentinel_wrapper, bool IsCopyable = true> -struct MaybeCopyableAlwaysMoveableView : std::ranges::view_base { - Iter begin_; - Iter end_; - - constexpr explicit MaybeCopyableAlwaysMoveableView(Iter b, Iter e) : begin_(b), end_(e) {} - - constexpr MaybeCopyableAlwaysMoveableView(MaybeCopyableAlwaysMoveableView&& other) = default; - constexpr MaybeCopyableAlwaysMoveableView& operator=(MaybeCopyableAlwaysMoveableView&&) = default; - - constexpr MaybeCopyableAlwaysMoveableView(const MaybeCopyableAlwaysMoveableView&) + constexpr BasicTestViewOrRange(const BasicTestViewOrRange&) requires(!IsCopyable) = delete; - constexpr MaybeCopyableAlwaysMoveableView(const MaybeCopyableAlwaysMoveableView&) + constexpr BasicTestViewOrRange(const BasicTestViewOrRange&) requires IsCopyable = default; - constexpr MaybeCopyableAlwaysMoveableView& operator=(const MaybeCopyableAlwaysMoveableView&) + constexpr BasicTestViewOrRange& operator=(const BasicTestViewOrRange&) requires(!IsCopyable) = delete; - constexpr MaybeCopyableAlwaysMoveableView& operator=(const MaybeCopyableAlwaysMoveableView&) + constexpr BasicTestViewOrRange& operator=(const BasicTestViewOrRange&) requires IsCopyable = default; - - constexpr Iter begin() const { return begin_; } - constexpr Sent end() const { return Sent{end_}; } }; + +template Sent = sentinel_wrapper, bool IsSized = false> + requires((!IsSized) || (IsSized && IterDifferable)) +using BasicTestView = BasicTestViewOrRange; + +template Sent = sentinel_wrapper, bool IsCopyable = true> +using MaybeCopyableAlwaysMoveableView = BasicTestViewOrRange; + static_assert(std::ranges::view>>); static_assert(std::ranges::view, sentinel_wrapper>, From 0d28a671f2b080c8cedcc04772d323a9d1936b74 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 2 Oct 2024 19:15:25 -0400 Subject: [PATCH 138/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Bring into line with updates to features like [[nodiscard]] vs _LIBCPP_NODISCARD --- libcxx/include/__ranges/stride_view.h | 49 ++++++-------- .../iterator/operator.nodiscard.verify.cpp | 6 +- .../range.stride.view/adaptor.pass.cpp | 4 +- .../range.stride.view/ctad.pass.cpp | 11 ++-- .../range.stride.view/iterator/base.pass.cpp | 66 ++++++++++++------- .../iterator/increment.pass.cpp | 3 +- .../iterator/plus_equal.pass.cpp | 4 +- .../range.adaptors/range.stride.view/types.h | 2 +- 8 files changed, 83 insertions(+), 62 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index fb7cfc3e343d5..e5b2e9935748a 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -72,31 +72,29 @@ class stride_view : public view_interface> { _LIBCPP_ASSERT_UNCATEGORIZED(__stride > 0, "The value of stride must be greater than 0"); } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& requires copy_constructible<_View> { return __base_; } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_View> stride() const noexcept { - return __stride_; - } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr range_difference_t<_View> stride() const noexcept { return __stride_; } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr auto begin() + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() requires(!__simple_view<_View>) { return __iterator(this, ranges::begin(__base_), 0); } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const requires range { return __iterator(this, ranges::begin(__base_), 0); } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr auto end() + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() requires(!__simple_view<_View>) { if constexpr (common_range<_View> && sized_range<_View> && forward_range<_View>) { @@ -109,7 +107,7 @@ class stride_view : public view_interface> { } } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr auto end() const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() const requires(range) { if constexpr (common_range && sized_range && forward_range) { @@ -122,13 +120,13 @@ class stride_view : public view_interface> { } } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr auto size() + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() requires sized_range<_View> { return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __stride_)); } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr auto size() const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto size() const requires sized_range { return std::__to_unsigned_like(ranges::__div_ceil(ranges::distance(__base_), __stride_)); @@ -201,12 +199,10 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> __stride_(__i.__stride_), __missing_(__i.__missing_) {} - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> const& base() const& noexcept { - return __current_; - } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> const& base() const& noexcept { return __current_; } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__current_ != __end_, "Cannot dereference an iterator at the end."); return *__current_; } @@ -267,7 +263,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> return *this += -__n; } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const requires random_access_range<_Base> { return *(*this + __n); @@ -313,16 +309,14 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> return __x.__current_ <=> __y.__current_; } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator - operator+(__iterator const& __i, difference_type __s) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator const& __i, difference_type __s) requires random_access_range<_Base> { auto __r = __i; __r += __s; return __r; } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator - operator+(difference_type __s, __iterator const& __i) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __s, __iterator const& __i) requires random_access_range<_Base> { auto __r = __i; @@ -330,8 +324,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> return __r; } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator - operator-(__iterator const& __i, difference_type __s) + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator const& __i, difference_type __s) requires random_access_range<_Base> { auto __r = __i; @@ -339,7 +332,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> return __r; } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(__iterator const& __x, __iterator const& __y) requires sized_sentinel_for, iterator_t<_Base>> && forward_range<_Base> { @@ -347,7 +340,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> return (__n + __x.__missing_ - __y.__missing_) / __x.__stride_; } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(__iterator const& __x, __iterator const& __y) requires sized_sentinel_for, iterator_t<_Base>> { @@ -358,20 +351,20 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> return ranges::__div_ceil(__n, __x.__stride_); } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(default_sentinel_t, __iterator const& __x) requires sized_sentinel_for, iterator_t<_Base>> { return ranges::__div_ceil(__x.__end_ - __x.__current_, __x.__stride_); } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(__iterator const& __x, default_sentinel_t __y) requires sized_sentinel_for, iterator_t<_Base>> { return -(__y - __x); } - _LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI friend constexpr range_rvalue_reference_t<_Base> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr range_rvalue_reference_t<_Base> iter_move(__iterator const& __it) noexcept(noexcept(ranges::iter_move(__it.__current_))) { return ranges::iter_move(__it.__current_); } diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp index e1121b7efc2bf..8415345c444d2 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp @@ -47,14 +47,16 @@ constexpr bool test_forward_operator_minus() { sv_zero_offset_begin + // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} 1; - 1 + sv_zero_offset_begin; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + 1 + sv_zero_offset_begin; // expected-warning {{ignoring return value of function declared with 'nodiscard' + // attribute}} sv_one_offset_begin - 1; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sv_one_offset_begin - // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sv_zero_offset_begin; - std::default_sentinel_t() - // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::default_sentinel_t() - // expected-warning {{ignoring return value of function declared with 'nodiscard' + // attribute}} sv_zero_offset_begin; sv_zero_offset_begin - // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index 71e27f7ffc7e8..37c4a20e6a196 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -134,7 +134,9 @@ constexpr bool test() { } // A final sanity check. - { static_assert(std::same_as); } + { + static_assert(std::same_as); + } return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.pass.cpp index d8f19116810c8..df83e25d7fe6f 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctad.pass.cpp @@ -31,14 +31,17 @@ constexpr bool testCTAD() { using BaseRange = BasicTestRange>; using BaseView = BasicTestView; - auto base_view = BaseView(a, a + 5); - auto base_range = BaseRange(cpp17_input_iterator(a), cpp17_input_iterator(a + 5)); + auto base_view = BaseView(a, a + 5); + auto base_view_for_move = BaseView(a, a + 5); + + auto base_range = BaseRange(cpp17_input_iterator(a), cpp17_input_iterator(a + 5)); + auto base_range_for_move = BaseRange(cpp17_input_iterator(a), cpp17_input_iterator(a + 5)); auto copied_stride_base_view = std::ranges::stride_view(base_view, 2); - auto moved_stride_base_view = std::ranges::stride_view(std::move(base_view), 2); + auto moved_stride_base_view = std::ranges::stride_view(std::move(base_view_for_move), 2); auto copied_stride_base_range = std::ranges::stride_view(base_range, 2); - auto moved_stride_base_range = std::ranges::stride_view(std::move(base_range), 2); + auto moved_stride_base_range = std::ranges::stride_view(std::move(base_range_for_move), 2); static_assert(std::same_as< decltype(copied_stride_base_view), std::ranges::stride_view>); static_assert(std::same_as< decltype(moved_stride_base_view), std::ranges::stride_view>); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp index df30e0a10fa7b..7d32432725388 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/base.pass.cpp @@ -47,7 +47,7 @@ constexpr bool base_const() { return true; } -bool base_move() { +constexpr bool base_move() { // Keep track of how many times the original iterator is moved // and/or copied during the test. int move_counter = 0; @@ -59,23 +59,35 @@ bool base_move() { auto stop = SizedInputIter(); auto view = BasicTestView{start, stop}; - auto sv = std::ranges::stride_view>(view, 1); - auto svi = sv.begin(); + assert(move_counter == 0); + // One copies of _start_ occurs when it is copied to the basic test view's member variable. + assert(copy_counter == 1); + + auto sv = std::ranges::stride_view>(view, 1); + // There is a copy of _view_ made when it is passed by value. + // There is a move done of _view_ when it is used as the initial value of __base. + assert(move_counter == 1); + assert(copy_counter == 2); + + auto svi = sv.begin(); + // Another copy of _start_ when begin uses the iterator to the first element + // of the view underlying sv as the by-value parameter to the stride view iterator's + // constructor. + assert(copy_counter == 3); + // Another move of __start_ happens right after that when it is std::move'd to + // become the first __current of the iterator. + assert(move_counter == 2); - // Reset the move/copy counters so that they reflect *only* whether the - // base() member function moved or copied the iterator. - move_counter = 0; - copy_counter = 0; [[maybe_unused]] auto result = std::move(svi).base(); - - // Ensure that base std::move'd the iterator. - assert(*result.move_counter == 1); - assert(*result.copy_counter == 0); + // Ensure that base std::move'd the iterator and did not copy it. + assert(move_counter == 3); + assert(copy_counter == 3); return true; } -bool base_copy() { - // See above. +constexpr bool base_copy() { + // See base_move() for complete description of when/why + // moves/copies take place.. int move_counter = 0; int copy_counter = 0; auto start = SizedInputIter(); @@ -84,27 +96,37 @@ bool base_copy() { start.copy_counter = ©_counter; auto stop = SizedInputIter(); - auto view = BasicTestView{start, stop}; - auto sv = std::ranges::stride_view>(view, 1); - [[maybe_unused]] auto svi = sv.begin(); + auto view = BasicTestView{start, stop}; + assert(move_counter == 0); + assert(copy_counter == 1); - // See above. - move_counter = 0; - copy_counter = 0; - [[maybe_unused]] const SizedInputIter& result = svi.base(); + auto sv = std::ranges::stride_view>(view, 1); + assert(move_counter == 1); + assert(copy_counter == 2); + + [[maybe_unused]] auto svi = sv.begin(); + assert(copy_counter == 3); + assert(move_counter == 2); + [[maybe_unused]] const SizedInputIter result = svi.base(); // Ensure that base did _not_ std::move'd the iterator. - assert(*result.move_counter == 0); - assert(*result.copy_counter == 0); + assert(move_counter == 2); + assert(copy_counter == 4); + return true; } int main(int, char**) { base_noexcept(); static_assert(base_noexcept()); + base_const(); static_assert(base_const()); + base_move(); + static_assert(base_move()); + base_copy(); + static_assert(base_copy()); return 0; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp index 5b41bde52146a..036605d065fd3 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp @@ -196,8 +196,7 @@ int main(int, char**) { { int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - test_non_forward_operator_increment( - SizedInputIter(arr), SizedInputIter(arr + 3), SizedInputIter(arr + 10)); + test_non_forward_operator_increment(SizedInputIter(arr), SizedInputIter(arr + 3), SizedInputIter(arr + 10)); } test_properly_handling_missing(); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus_equal.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus_equal.pass.cpp index 6d8ae7dec2f73..41f2c217b4c38 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus_equal.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus_equal.pass.cpp @@ -75,9 +75,9 @@ constexpr bool test_random_access_operator_plus_equal(Iter begin, Iter end, Diff assert(*sv_bv_begin == *sv_bv_offset_begin); assert(*sv_bv_begin_after_distance == *sv_bv_offset_begin); - auto big_step = (end - 1) - begin; + auto big_step = (end - 1) - begin; auto stride_view_over_base_view_big_step = std::ranges::stride_view(base_view, big_step); - sv_bv_begin = stride_view_over_base_view_big_step.begin(); + sv_bv_begin = stride_view_over_base_view_big_step.begin(); // This += should move us into a position where the __missing_ will come into play. // Do a -= 1 here to confirm that the __missing_ is taken into account. diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index abacd97f238b3..5f8f4ae01d8d2 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -188,7 +188,7 @@ struct BasicTestViewOrRange : MaybeView { Iter begin_{}; Iter end_{}; - constexpr BasicTestViewOrRange(Iter b, Iter e) : begin_(b), end_(e) {} + constexpr BasicTestViewOrRange(const Iter& b, const Iter& e) : begin_(b), end_(e) {} constexpr Iter begin() { return begin_; } constexpr Iter begin() const { return begin_; } From 7c5389dd1263e78addeef3bce0ed482c722bddfd Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 2 Oct 2024 19:24:26 -0400 Subject: [PATCH 139/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Discard accidental change to another range adaptor. --- .../range.as.rvalue/enable_borrowed_range.compile.pass.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/enable_borrowed_range.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/enable_borrowed_range.compile.pass.cpp index 3859f5ad3dee8..48d1d96b02482 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/enable_borrowed_range.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.as.rvalue/enable_borrowed_range.compile.pass.cpp @@ -11,11 +11,6 @@ #include #include -static_assert(std::ranges::enable_borrowed_range>); static_assert(std::ranges::enable_borrowed_range>>); - -static_assert(std::ranges::enable_borrowed_range&>>); static_assert(std::ranges::enable_borrowed_range&>>>); - -static_assert(!std::ranges::enable_borrowed_range>>); static_assert(!std::ranges::enable_borrowed_range>>>); From feb311720961547e95c539d27bc5273146640de3 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 2 Oct 2024 19:31:17 -0400 Subject: [PATCH 140/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Make formatting happy. --- .../ranges/range.adaptors/range.stride.view/adaptor.pass.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index 37c4a20e6a196..71e27f7ffc7e8 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -134,9 +134,7 @@ constexpr bool test() { } // A final sanity check. - { - static_assert(std::same_as); - } + { static_assert(std::same_as); } return true; } From 7b8e5107b651fdaf48255a8ff2415a4c13c6382c Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 2 Oct 2024 22:09:16 -0400 Subject: [PATCH 141/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add stride view into the module map. Signed-off-by: Will Hawkins --- libcxx/include/module.modulemap.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index 894093b409e11..c17f9dc9f7137 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -1921,6 +1921,10 @@ module std [system] { module subrange_fwd { header "__fwd/subrange.h" } + module stride_view { + header "__ranges/stride_view.h" + export std.functional.bind_back + } module take_view { header "__ranges/take_view.h" export std.functional.bind_back From c4a966f08b8b744758e43173d9a9a6435c254bee Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 1 Nov 2024 22:25:00 -0400 Subject: [PATCH 142/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Rebase to main. --- libcxx/include/__ranges/stride_view.h | 5 ++++- .../range.adaptors/range.stride.view/concept.verify.cpp | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index e5b2e9935748a..b213981dbb6d5 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -12,6 +12,7 @@ #include <__assert> #include <__compare/three_way_comparable.h> +#include <__concepts/constructible.h> #include <__concepts/convertible_to.h> #include <__concepts/derived_from.h> #include <__concepts/equality_comparable.h> @@ -35,6 +36,8 @@ #include <__ranges/range_adaptor.h> #include <__ranges/view_interface.h> +#include <__type_traits/make_unsigned.h> + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif @@ -395,7 +398,7 @@ struct __fn { template [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Np&& __n) const { - return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Np>(__n))); + return __pipeable(std::__bind_back(*this, std::forward<_Np>(__n))); } }; } // namespace __stride_view diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp index 8f43b63e9de87..8ec314bd3a114 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp @@ -18,7 +18,9 @@ #include "types.h" template D> -concept CanStrideView = requires { std::ranges::stride_view{I{}, D}; }; +concept CanStrideView = requires { + std::ranges::stride_view{I{}, D}; +}; // Ensure that the InputRangeNotIndirectlyReadable is a valid range. static_assert(std::ranges::range); From e9e18c90824a1287d839ab344e936a11329e160c Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 1 Nov 2024 23:01:06 -0400 Subject: [PATCH 143/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Clang format changes. --- .../ranges/range.adaptors/range.stride.view/adaptor.pass.cpp | 4 +++- .../range.adaptors/range.stride.view/concept.verify.cpp | 4 +--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index 71e27f7ffc7e8..37c4a20e6a196 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -134,7 +134,9 @@ constexpr bool test() { } // A final sanity check. - { static_assert(std::same_as); } + { + static_assert(std::same_as); + } return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp index 8ec314bd3a114..8f43b63e9de87 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp @@ -18,9 +18,7 @@ #include "types.h" template D> -concept CanStrideView = requires { - std::ranges::stride_view{I{}, D}; -}; +concept CanStrideView = requires { std::ranges::stride_view{I{}, D}; }; // Ensure that the InputRangeNotIndirectlyReadable is a valid range. static_assert(std::ranges::range); From c47fc63a59fe8fbf53056247bd3f623e54778d9a Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 1 Nov 2024 23:05:46 -0400 Subject: [PATCH 144/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Clang format changes. --- .../ranges/range.adaptors/range.stride.view/adaptor.pass.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index 37c4a20e6a196..71e27f7ffc7e8 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -134,9 +134,7 @@ constexpr bool test() { } // A final sanity check. - { - static_assert(std::same_as); - } + { static_assert(std::same_as); } return true; } From e2b95336125f6b2e82a318f832874b4069784d78 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 1 Nov 2024 23:59:13 -0400 Subject: [PATCH 145/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add another operator (+) test. --- .../range.stride.view/iterator/plus.pass.cpp | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus.pass.cpp diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus.pass.cpp new file mode 100644 index 0000000000000..d76bee9b0bb7e --- /dev/null +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus.pass.cpp @@ -0,0 +1,102 @@ +//===----------------------------------------------------------------------===// +// +// 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, c++20 + +// constexpr __iterator operator+(difference_type __n, const __iterator &__i) +// constexpr __iterator operator+(const __iterator &__i, difference_type __n) + +#include + +#include "../types.h" +#include "test_iterators.h" + +template +concept CanPlus = + std::is_same_v() + std::declval())> && + std::is_same_v() + std::declval())> && + requires(T& t, T::__iterator::difference_type& u) { t = t + u; } && + requires(T& t, T::__iterator::difference_type& u) { t = u + t; }; + +// Make sure that we cannot use + on a stride view iterator and difference_type +// over an input view.(sized sentinel) +using InputView = BasicTestView, sized_sentinel>>; +using StrideViewOverInputViewIterator = std::ranges::iterator_t>; + +static_assert(std::ranges::input_range); +static_assert(!CanPlus); + +// Make sure that we cannot use + on a stride view iterator and difference_type +// over a forward view.(sized sentinel) +using ForwardView = BasicTestView, sized_sentinel>>; +using StrideViewOverForwardViewIterator = std::ranges::iterator_t>; + +static_assert(std::ranges::forward_range); +static_assert(!CanPlus); + +// Make sure that we cannot use + on a stride view iterator and difference_type +// over a bidirectional view. (sized sentinel) +using BidirectionalView = BasicTestView, sized_sentinel>>; +using StrideViewOverBidirectionalViewIterator = std::ranges::iterator_t>; + +static_assert(std::ranges::bidirectional_range); +static_assert(!CanPlus); + +// Make sure that we can use += on a stride view iterator and difference_type +// over a random access view. (non sized sentinel) +template > +using RandomAccessView = BasicTestView; +using StrideViewOverRandomAccessViewIterator = std::ranges::iterator_t>>; + +static_assert(std::ranges::random_access_range>); +static_assert(CanPlus); + +constexpr bool test_random_access_operator_plus_equal() { + using Iter = std::vector::iterator; + using Diff = Iter::difference_type; + std::vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + // Test the operator+ between an iterator and its difference type. Pay attention solely to + // stride views over random-access ranges because operator+ is not applicable to others. + + auto begin = vec.begin(); + auto end = vec.end(); + Diff distance = 4; + + // Do not use the RandomAccessView defined in types.h to give the test user more power + // to customize an iterator and a default sentinel. + using Base = RandomAccessView; + static_assert(std::ranges::random_access_range); + + auto base_view = Base(begin, end); + auto stride_view_over_base_view = std::ranges::stride_view(base_view, 1); + + auto base_view_offset = Base(begin + distance, end); + auto stride_view_over_base_view_offset = std::ranges::stride_view(base_view_offset, 1); + + assert(*(stride_view_over_base_view.begin() + distance) == *(stride_view_over_base_view_offset.begin())); + + auto distance_to_last = (end - 1) - begin; + auto stride_view_over_base_view_big_step = std::ranges::stride_view(base_view, distance_to_last); + + assert(*(stride_view_over_base_view_big_step.begin() + 1) == + *(stride_view_over_base_view.begin() + distance_to_last)); + assert((stride_view_over_base_view_big_step.begin() + 2) == (stride_view_over_base_view.end())); + + return true; +} + +consteval bool do_static_tests() { + assert(test_random_access_operator_plus_equal()); + return true; +} + +int main(int, char**) { + static_assert(do_static_tests()); + assert(do_static_tests()); + return 0; +} From e944d254b98b992bcf9fe2864651381c35331427 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sat, 2 Nov 2024 02:23:47 -0400 Subject: [PATCH 146/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix verifier error triggered by bad auto format. --- .../iterator/operator.nodiscard.verify.cpp | 6 +-- .../iterator/greater_than.pass.cpp | 12 +++--- .../iterator/operator.pass.cpp | 21 +++------- .../iterator/plus_equal.pass.cpp | 42 ++++++++++--------- 4 files changed, 36 insertions(+), 45 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp index 8415345c444d2..e1121b7efc2bf 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator.nodiscard.verify.cpp @@ -47,16 +47,14 @@ constexpr bool test_forward_operator_minus() { sv_zero_offset_begin + // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} 1; - 1 + sv_zero_offset_begin; // expected-warning {{ignoring return value of function declared with 'nodiscard' - // attribute}} + 1 + sv_zero_offset_begin; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sv_one_offset_begin - 1; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sv_one_offset_begin - // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sv_zero_offset_begin; - std::default_sentinel_t() - // expected-warning {{ignoring return value of function declared with 'nodiscard' - // attribute}} + std::default_sentinel_t() - // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} sv_zero_offset_begin; sv_zero_offset_begin - // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/greater_than.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/greater_than.pass.cpp index 8d4c2643a5ce9..801447a9fad60 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/greater_than.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/greater_than.pass.cpp @@ -43,7 +43,7 @@ #include "test_iterators.h" template -concept CanPlusEqual = std::is_same_v() += 1)> && requires(T& t) { t += 1; }; +concept CanPlus = std::is_same_v() += 1)> && requires(T& t) { t += 1; }; template concept CanMinusEqual = std::is_same_v() -= 1)> && requires(T& t) { t -= 1; }; @@ -88,7 +88,7 @@ static_assert(std::weakly_incrementable); static_assert(!CanPostDecrement); static_assert(!CanPreDecrement); -static_assert(!CanPlusEqual); +static_assert(!CanPlus); static_assert(!CanMinusEqual); static_assert(!CanMinus); static_assert(!CanDifferencePlus); @@ -116,7 +116,7 @@ static_assert(std::weakly_incrementable); static_assert(!CanPostDecrement); static_assert(!CanPreDecrement); -static_assert(!CanPlusEqual); +static_assert(!CanPlus); static_assert(!CanMinusEqual); static_assert(!CanMinus); static_assert(!CanDifferencePlus); @@ -143,7 +143,7 @@ using StrideViewOverBidirectionalViewIterator = std::ranges::iterator_t); static_assert(CanPreDecrement); -static_assert(!CanPlusEqual); +static_assert(!CanPlus); static_assert(!CanMinusEqual); static_assert(!CanMinus); static_assert(!CanDifferencePlus); @@ -178,7 +178,7 @@ static_assert(std::weakly_incrementable) static_assert(CanPostDecrement); static_assert(CanPreDecrement); -static_assert(CanPlusEqual); +static_assert(CanPlus); static_assert(CanMinusEqual); static_assert(CanMinus); static_assert(CanDifferencePlus); @@ -248,7 +248,7 @@ constexpr bool test_non_forward_operator_minus(Iter zero_begin, Iter one_begin, static_assert(!CanPostDecrement); static_assert(!CanPreDecrement); - static_assert(!CanPlusEqual); + static_assert(!CanPlus); static_assert(!CanMinusEqual); static_assert(!CanDifferencePlus); static_assert(!CanDifferenceMinus); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp index 87a6090d552eb..c3d71b7387ea7 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/operator.pass.cpp @@ -31,19 +31,10 @@ #include #include "../types.h" -#include "__compare/three_way_comparable.h" -#include "__concepts/equality_comparable.h" -#include "__concepts/same_as.h" -#include "__iterator/concepts.h" -#include "__iterator/default_sentinel.h" -#include "__iterator/distance.h" -#include "__ranges/access.h" -#include "__ranges/concepts.h" -#include "__ranges/stride_view.h" #include "test_iterators.h" template -concept CanPlusEqual = std::is_same_v() += 1)> && requires(T& t) { t += 1; }; +concept CanPlus = std::is_same_v() += 1)> && requires(T& t) { t += 1; }; template concept CanMinusEqual = std::is_same_v() -= 1)> && requires(T& t) { t -= 1; }; @@ -88,7 +79,7 @@ static_assert(std::weakly_incrementable); static_assert(!CanPostDecrement); static_assert(!CanPreDecrement); -static_assert(!CanPlusEqual); +static_assert(!CanPlus); static_assert(!CanMinusEqual); static_assert(!CanMinus); static_assert(!CanDifferencePlus); @@ -116,7 +107,7 @@ static_assert(std::weakly_incrementable); static_assert(!CanPostDecrement); static_assert(!CanPreDecrement); -static_assert(!CanPlusEqual); +static_assert(!CanPlus); static_assert(!CanMinusEqual); static_assert(!CanMinus); static_assert(!CanDifferencePlus); @@ -143,7 +134,7 @@ using StrideViewOverBidirectionalViewIterator = std::ranges::iterator_t); static_assert(CanPreDecrement); -static_assert(!CanPlusEqual); +static_assert(!CanPlus); static_assert(!CanMinusEqual); static_assert(!CanMinus); static_assert(!CanDifferencePlus); @@ -178,7 +169,7 @@ static_assert(std::weakly_incrementable) static_assert(CanPostDecrement); static_assert(CanPreDecrement); -static_assert(CanPlusEqual); +static_assert(CanPlus); static_assert(CanMinusEqual); static_assert(CanMinus); static_assert(CanDifferencePlus); @@ -248,7 +239,7 @@ constexpr bool test_non_forward_operator_plus(Iter zero_begin, Iter one_begin, I static_assert(!CanPostDecrement); static_assert(!CanPreDecrement); - static_assert(!CanPlusEqual); + static_assert(!CanPlus); static_assert(!CanMinusEqual); static_assert(!CanDifferencePlus); static_assert(!CanDifferenceMinus); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus_equal.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus_equal.pass.cpp index 41f2c217b4c38..886bb3939bb17 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus_equal.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus_equal.pass.cpp @@ -10,16 +10,16 @@ // constexpr __iterator& operator+=(difference_type __n) -#include #include +#include #include "../types.h" -#include "__iterator/concepts.h" -#include "__ranges/concepts.h" #include "test_iterators.h" template -concept CanPlusEqual = std::is_same_v() += 1)> && requires(T& t) { t += 1; }; +concept CanPlus = + std::is_same_v() += std::declval())> && + requires(T& t, T::__iterator::difference_type& u) { t += u; }; // Make sure that we cannot use += on a stride view iterator // over an input view.(sized sentinel) @@ -27,7 +27,7 @@ using InputView = BasicTestView, sized_sentinel>; static_assert(std::ranges::input_range); -static_assert(!CanPlusEqual); +static_assert(!CanPlus); // Make sure that we cannot use += on a stride view iterator // over a forward view.(sized sentinel) @@ -35,7 +35,7 @@ using ForwardView = BasicTestView, using StrideViewOverForwardViewIterator = std::ranges::iterator_t>; static_assert(std::ranges::forward_range); -static_assert(!CanPlusEqual); +static_assert(!CanPlus); // Make sure that we cannot use += on a stride view iterator // over a bidirectional view. (sized sentinel) @@ -43,7 +43,7 @@ using BidirectionalView = BasicTestView, sized_sent using StrideViewOverBidirectionalViewIterator = std::ranges::iterator_t>; static_assert(std::ranges::bidirectional_range); -static_assert(!CanPlusEqual); +static_assert(!CanPlus); // Make sure that we can use += on a stride view iterator // over a random access view. (non sized sentinel) @@ -52,11 +52,20 @@ using RandomAccessView = BasicTestView>>; static_assert(std::ranges::random_access_range>); -static_assert(CanPlusEqual); +static_assert(CanPlus); -template -constexpr bool test_random_access_operator_plus_equal(Iter begin, Iter end, Difference distance) { - // Test the forward-range operator+= between an iterator and its distance type. +constexpr bool test_random_access_operator_plus_equal() { + using Iter = std::vector::iterator; + using Diff = Iter::difference_type; + std::vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + // Test the operator+ between an iterator and its difference type. Pay attention solely to + // stride views over random-access ranges because operator+ is not applicable to others. + + auto begin = vec.begin(); + auto end = vec.end(); + Diff distance = 4; + + // Test the forward-range operator+= between an iterator and its difference type. // Do not use the RandomAccessView defined in types.h to give the test user more power // to customize an iterator and a default sentinel. using Base = RandomAccessView; @@ -88,19 +97,12 @@ constexpr bool test_random_access_operator_plus_equal(Iter begin, Iter end, Diff } consteval bool do_static_tests() { - std::vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - assert(test_random_access_operator_plus_equal(vec.begin(), vec.end(), 4)); + assert(test_random_access_operator_plus_equal()); return true; } int main(int, char**) { - constexpr int arr[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - static_assert(test_random_access_operator_plus_equal(arr, arr + 11, 4)); - test_random_access_operator_plus_equal(arr, arr + 11, 4); - static_assert(do_static_tests()); - - std::vector vec{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; - assert(test_random_access_operator_plus_equal(vec.begin(), vec.end(), 4)); + assert(do_static_tests()); return 0; } From 843efe07e46565a74cdc83a70bc64301a98bf8ab Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sat, 2 Nov 2024 02:29:48 -0400 Subject: [PATCH 147/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Explicitly import vector where needed (for modules). --- .../range.adaptors/range.stride.view/iterator/plus.pass.cpp | 1 + .../range.stride.view/iterator/plus_equal.pass.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus.pass.cpp index d76bee9b0bb7e..d18dc0b0d1b2f 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus.pass.cpp @@ -12,6 +12,7 @@ // constexpr __iterator operator+(const __iterator &__i, difference_type __n) #include +#include #include "../types.h" #include "test_iterators.h" diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus_equal.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus_equal.pass.cpp index 886bb3939bb17..17cb295a48e6b 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus_equal.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/plus_equal.pass.cpp @@ -12,6 +12,7 @@ #include #include +#include #include "../types.h" #include "test_iterators.h" From 6341e4685fa4abf3ca97704fce6fa4166e7d09d4 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 11 Nov 2024 10:46:31 -0500 Subject: [PATCH 148/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Improve base nodiscard test (and fix CI). --- .../range.stride.view/base.nodiscard.verify.cpp | 9 +++++---- .../range.stride.view/begin.nodiscard.verify.cpp | 4 +--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp index 1690e97b917d2..684000cbe807f 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp @@ -11,18 +11,19 @@ // Test that std::ranges::stride_view::base() is marked nodiscard. #include +#include #include "../../../../std/ranges/range.adaptors/range.stride.view/types.h" void test() { const std::vector intv = {1, 2, 3}; auto copyable_view = CopyableView::const_iterator>(intv.begin(), intv.end()); - static_assert(std::copy_constructible); - const auto sv = std::ranges::stride_view(copyable_view, 2); + const auto svc = std::ranges::stride_view(copyable_view, 2); + auto svm= std::ranges::stride_view(copyable_view, 2); - sv.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + svc.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - std::move(sv).base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::move(svm).base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/begin.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/begin.nodiscard.verify.cpp index 7cb13f75969fd..3ffe7787c927a 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/begin.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/begin.nodiscard.verify.cpp @@ -15,9 +15,7 @@ #include "../../../../std/ranges/range.adaptors/range.stride.view/types.h" void test() { - const int range[] = {1, 2, 3}; - - const auto const_sv = std::views::stride(range, 2); + const auto const_sv = std::views::stride(SimpleCommonConstView{}, 2); auto unsimple_sv = std::views::stride(UnsimpleConstView{}, 2); const_sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} From b5f57206b788ba5b05ac36891f6d7be469538cb5 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 11 Nov 2024 10:51:32 -0500 Subject: [PATCH 149/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Make format happy. --- .../range.adaptors/range.stride.view/base.nodiscard.verify.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp index 684000cbe807f..8da7c384b2ed1 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp @@ -21,7 +21,7 @@ void test() { static_assert(std::copy_constructible); const auto svc = std::ranges::stride_view(copyable_view, 2); - auto svm= std::ranges::stride_view(copyable_view, 2); + auto svm = std::ranges::stride_view(copyable_view, 2); svc.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} From 8908a3af6b5e5311afa55b954bc394a78769bc9d Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 18 Nov 2024 10:28:57 -0500 Subject: [PATCH 150/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Remove libcxx/include/libcxx.imp from git. --- libcxx/include/libcxx.imp | 869 -------------------------------------- 1 file changed, 869 deletions(-) delete mode 100644 libcxx/include/libcxx.imp diff --git a/libcxx/include/libcxx.imp b/libcxx/include/libcxx.imp deleted file mode 100644 index 26397c1216a76..0000000000000 --- a/libcxx/include/libcxx.imp +++ /dev/null @@ -1,869 +0,0 @@ -[ - { include: [ "<__algorithm/adjacent_find.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/all_of.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/any_of.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/binary_search.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/clamp.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/comp.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/comp_ref_type.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/copy_backward.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/copy_if.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/copy_move_common.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/copy_n.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/count.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/count_if.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/equal.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/equal_range.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/fill.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/fill_n.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/find.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/find_end.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/find_first_of.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/find_if.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/find_if_not.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/find_segment_if.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/fold.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/for_each.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/for_each_n.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/for_each_segment.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/generate.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/generate_n.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/half_positive.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/in_found_result.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/in_fun_result.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/in_in_out_result.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/in_in_result.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/in_out_out_result.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/in_out_result.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/includes.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/inplace_merge.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/is_heap.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/is_heap_until.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/is_partitioned.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/is_permutation.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/is_sorted.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/is_sorted_until.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/iter_swap.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/iterator_operations.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/lexicographical_compare.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/lexicographical_compare_three_way.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/lower_bound.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/make_heap.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/make_projected.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/max.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/max_element.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/merge.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/min.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/min_element.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/min_max_result.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/minmax.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/minmax_element.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/mismatch.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/move.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/move_backward.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/next_permutation.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/none_of.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/nth_element.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/partial_sort.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/partial_sort_copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/partition.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/partition_copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/partition_point.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pop_heap.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/prev_permutation.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_any_all_none_of.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_backend.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_backends/cpu_backend.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_backends/cpu_backends/any_of.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_backends/cpu_backends/backend.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_backends/cpu_backends/fill.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_backends/cpu_backends/find_if.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_backends/cpu_backends/for_each.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_backends/cpu_backends/libdispatch.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_backends/cpu_backends/merge.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_backends/cpu_backends/serial.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_backends/cpu_backends/stable_sort.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_backends/cpu_backends/thread.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_backends/cpu_backends/transform.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_backends/cpu_backends/transform_reduce.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_count.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_equal.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_fill.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_find.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_for_each.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_frontend_dispatch.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_generate.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_is_partitioned.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_merge.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_move.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_replace.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_rotate_copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_sort.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_stable_sort.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/pstl_transform.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/push_heap.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_adjacent_find.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_all_of.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_any_of.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_binary_search.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_clamp.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_contains.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_copy_backward.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_copy_if.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_copy_n.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_count.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_count_if.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_ends_with.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_equal.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_equal_range.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_fill.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_fill_n.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_find.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_find_end.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_find_first_of.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_find_if.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_find_if_not.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_for_each.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_for_each_n.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_generate.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_generate_n.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_includes.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_inplace_merge.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_is_heap.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_is_heap_until.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_is_partitioned.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_is_permutation.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_is_sorted.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_is_sorted_until.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_iterator_concept.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_lexicographical_compare.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_lower_bound.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_make_heap.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_max.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_max_element.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_merge.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_min.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_min_element.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_minmax.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_minmax_element.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_mismatch.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_move.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_move_backward.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_next_permutation.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_none_of.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_nth_element.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_partial_sort.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_partial_sort_copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_partition.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_partition_copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_partition_point.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_pop_heap.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_prev_permutation.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_push_heap.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_remove.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_remove_copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_remove_copy_if.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_remove_if.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_replace.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_replace_copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_replace_copy_if.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_replace_if.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_reverse.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_reverse_copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_rotate.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_rotate_copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_sample.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_search.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_search_n.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_set_difference.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_set_intersection.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_set_symmetric_difference.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_set_union.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_shuffle.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_sort.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_sort_heap.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_stable_partition.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_stable_sort.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_starts_with.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_swap_ranges.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_transform.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_unique.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_unique_copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/ranges_upper_bound.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/remove.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/remove_copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/remove_copy_if.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/remove_if.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/replace.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/replace_copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/replace_copy_if.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/replace_if.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/reverse.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/reverse_copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/rotate.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/rotate_copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/sample.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/search.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/search_n.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/set_difference.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/set_intersection.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/set_symmetric_difference.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/set_union.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/shift_left.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/shift_right.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/shuffle.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/sift_down.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/sort.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/sort_heap.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/stable_partition.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/stable_sort.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/swap_ranges.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/three_way_comp_ref_type.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/transform.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/uniform_random_bit_generator_adaptor.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/unique.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/unique_copy.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/unwrap_iter.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/unwrap_range.h>", "private", "", "public" ] }, - { include: [ "<__algorithm/upper_bound.h>", "private", "", "public" ] }, - { include: [ "<__atomic/aliases.h>", "private", "", "public" ] }, - { include: [ "<__atomic/atomic.h>", "private", "", "public" ] }, - { include: [ "<__atomic/atomic_base.h>", "private", "", "public" ] }, - { include: [ "<__atomic/atomic_flag.h>", "private", "", "public" ] }, - { include: [ "<__atomic/atomic_init.h>", "private", "", "public" ] }, - { include: [ "<__atomic/atomic_lock_free.h>", "private", "", "public" ] }, - { include: [ "<__atomic/atomic_sync.h>", "private", "", "public" ] }, - { include: [ "<__atomic/check_memory_order.h>", "private", "", "public" ] }, - { include: [ "<__atomic/contention_t.h>", "private", "", "public" ] }, - { include: [ "<__atomic/cxx_atomic_impl.h>", "private", "", "public" ] }, - { include: [ "<__atomic/fence.h>", "private", "", "public" ] }, - { include: [ "<__atomic/is_always_lock_free.h>", "private", "", "public" ] }, - { include: [ "<__atomic/kill_dependency.h>", "private", "", "public" ] }, - { include: [ "<__atomic/memory_order.h>", "private", "", "public" ] }, - { include: [ "<__bit/bit_cast.h>", "private", "", "public" ] }, - { include: [ "<__bit/bit_ceil.h>", "private", "", "public" ] }, - { include: [ "<__bit/bit_floor.h>", "private", "", "public" ] }, - { include: [ "<__bit/bit_log2.h>", "private", "", "public" ] }, - { include: [ "<__bit/bit_width.h>", "private", "", "public" ] }, - { include: [ "<__bit/blsr.h>", "private", "", "public" ] }, - { include: [ "<__bit/byteswap.h>", "private", "", "public" ] }, - { include: [ "<__bit/countl.h>", "private", "", "public" ] }, - { include: [ "<__bit/countr.h>", "private", "", "public" ] }, - { include: [ "<__bit/endian.h>", "private", "", "public" ] }, - { include: [ "<__bit/has_single_bit.h>", "private", "", "public" ] }, - { include: [ "<__bit/invert_if.h>", "private", "", "public" ] }, - { include: [ "<__bit/popcount.h>", "private", "", "public" ] }, - { include: [ "<__bit/rotate.h>", "private", "", "public" ] }, - { include: [ "<__charconv/chars_format.h>", "private", "", "public" ] }, - { include: [ "<__charconv/from_chars_integral.h>", "private", "", "public" ] }, - { include: [ "<__charconv/from_chars_result.h>", "private", "", "public" ] }, - { include: [ "<__charconv/tables.h>", "private", "", "public" ] }, - { include: [ "<__charconv/to_chars.h>", "private", "", "public" ] }, - { include: [ "<__charconv/to_chars_base_10.h>", "private", "", "public" ] }, - { include: [ "<__charconv/to_chars_floating_point.h>", "private", "", "public" ] }, - { include: [ "<__charconv/to_chars_integral.h>", "private", "", "public" ] }, - { include: [ "<__charconv/to_chars_result.h>", "private", "", "public" ] }, - { include: [ "<__charconv/traits.h>", "private", "", "public" ] }, - { include: [ "<__chrono/calendar.h>", "private", "", "public" ] }, - { include: [ "<__chrono/concepts.h>", "private", "", "public" ] }, - { include: [ "<__chrono/convert_to_timespec.h>", "private", "", "public" ] }, - { include: [ "<__chrono/convert_to_tm.h>", "private", "", "public" ] }, - { include: [ "<__chrono/day.h>", "private", "", "public" ] }, - { include: [ "<__chrono/duration.h>", "private", "", "public" ] }, - { include: [ "<__chrono/file_clock.h>", "private", "", "public" ] }, - { include: [ "<__chrono/formatter.h>", "private", "", "public" ] }, - { include: [ "<__chrono/hh_mm_ss.h>", "private", "", "public" ] }, - { include: [ "<__chrono/high_resolution_clock.h>", "private", "", "public" ] }, - { include: [ "<__chrono/literals.h>", "private", "", "public" ] }, - { include: [ "<__chrono/month.h>", "private", "", "public" ] }, - { include: [ "<__chrono/month_weekday.h>", "private", "", "public" ] }, - { include: [ "<__chrono/monthday.h>", "private", "", "public" ] }, - { include: [ "<__chrono/ostream.h>", "private", "", "public" ] }, - { include: [ "<__chrono/parser_std_format_spec.h>", "private", "", "public" ] }, - { include: [ "<__chrono/statically_widen.h>", "private", "", "public" ] }, - { include: [ "<__chrono/steady_clock.h>", "private", "", "public" ] }, - { include: [ "<__chrono/system_clock.h>", "private", "", "public" ] }, - { include: [ "<__chrono/time_point.h>", "private", "", "public" ] }, - { include: [ "<__chrono/tzdb.h>", "private", "", "public" ] }, - { include: [ "<__chrono/tzdb_list.h>", "private", "", "public" ] }, - { include: [ "<__chrono/weekday.h>", "private", "", "public" ] }, - { include: [ "<__chrono/year.h>", "private", "", "public" ] }, - { include: [ "<__chrono/year_month.h>", "private", "", "public" ] }, - { include: [ "<__chrono/year_month_day.h>", "private", "", "public" ] }, - { include: [ "<__chrono/year_month_weekday.h>", "private", "", "public" ] }, - { include: [ "<__compare/common_comparison_category.h>", "private", "", "public" ] }, - { include: [ "<__compare/compare_partial_order_fallback.h>", "private", "", "public" ] }, - { include: [ "<__compare/compare_strong_order_fallback.h>", "private", "", "public" ] }, - { include: [ "<__compare/compare_three_way.h>", "private", "", "public" ] }, - { include: [ "<__compare/compare_three_way_result.h>", "private", "", "public" ] }, - { include: [ "<__compare/compare_weak_order_fallback.h>", "private", "", "public" ] }, - { include: [ "<__compare/is_eq.h>", "private", "", "public" ] }, - { include: [ "<__compare/ordering.h>", "private", "", "public" ] }, - { include: [ "<__compare/partial_order.h>", "private", "", "public" ] }, - { include: [ "<__compare/strong_order.h>", "private", "", "public" ] }, - { include: [ "<__compare/synth_three_way.h>", "private", "", "public" ] }, - { include: [ "<__compare/three_way_comparable.h>", "private", "", "public" ] }, - { include: [ "<__compare/weak_order.h>", "private", "", "public" ] }, - { include: [ "<__concepts/arithmetic.h>", "private", "", "public" ] }, - { include: [ "<__concepts/assignable.h>", "private", "", "public" ] }, - { include: [ "<__concepts/boolean_testable.h>", "private", "", "public" ] }, - { include: [ "<__concepts/class_or_enum.h>", "private", "", "public" ] }, - { include: [ "<__concepts/common_reference_with.h>", "private", "", "public" ] }, - { include: [ "<__concepts/common_with.h>", "private", "", "public" ] }, - { include: [ "<__concepts/constructible.h>", "private", "", "public" ] }, - { include: [ "<__concepts/convertible_to.h>", "private", "", "public" ] }, - { include: [ "<__concepts/copyable.h>", "private", "", "public" ] }, - { include: [ "<__concepts/derived_from.h>", "private", "", "public" ] }, - { include: [ "<__concepts/destructible.h>", "private", "", "public" ] }, - { include: [ "<__concepts/different_from.h>", "private", "", "public" ] }, - { include: [ "<__concepts/equality_comparable.h>", "private", "", "public" ] }, - { include: [ "<__concepts/invocable.h>", "private", "", "public" ] }, - { include: [ "<__concepts/movable.h>", "private", "", "public" ] }, - { include: [ "<__concepts/predicate.h>", "private", "", "public" ] }, - { include: [ "<__concepts/regular.h>", "private", "", "public" ] }, - { include: [ "<__concepts/relation.h>", "private", "", "public" ] }, - { include: [ "<__concepts/same_as.h>", "private", "", "public" ] }, - { include: [ "<__concepts/semiregular.h>", "private", "", "public" ] }, - { include: [ "<__concepts/swappable.h>", "private", "", "public" ] }, - { include: [ "<__concepts/totally_ordered.h>", "private", "", "public" ] }, - { include: [ "<__condition_variable/condition_variable.h>", "private", "", "public" ] }, - { include: [ "<__coroutine/coroutine_handle.h>", "private", "", "public" ] }, - { include: [ "<__coroutine/coroutine_traits.h>", "private", "", "public" ] }, - { include: [ "<__coroutine/noop_coroutine_handle.h>", "private", "", "public" ] }, - { include: [ "<__coroutine/trivial_awaitables.h>", "private", "", "public" ] }, - { include: [ "<__exception/exception.h>", "private", "", "public" ] }, - { include: [ "<__exception/exception_ptr.h>", "private", "", "public" ] }, - { include: [ "<__exception/nested_exception.h>", "private", "", "public" ] }, - { include: [ "<__exception/operations.h>", "private", "", "public" ] }, - { include: [ "<__exception/terminate.h>", "private", "", "public" ] }, - { include: [ "<__expected/bad_expected_access.h>", "private", "", "public" ] }, - { include: [ "<__expected/expected.h>", "private", "", "public" ] }, - { include: [ "<__expected/unexpect.h>", "private", "", "public" ] }, - { include: [ "<__expected/unexpected.h>", "private", "", "public" ] }, - { include: [ "<__filesystem/copy_options.h>", "private", "", "public" ] }, - { include: [ "<__filesystem/directory_entry.h>", "private", "", "public" ] }, - { include: [ "<__filesystem/directory_iterator.h>", "private", "", "public" ] }, - { include: [ "<__filesystem/directory_options.h>", "private", "", "public" ] }, - { include: [ "<__filesystem/file_status.h>", "private", "", "public" ] }, - { include: [ "<__filesystem/file_time_type.h>", "private", "", "public" ] }, - { include: [ "<__filesystem/file_type.h>", "private", "", "public" ] }, - { include: [ "<__filesystem/filesystem_error.h>", "private", "", "public" ] }, - { include: [ "<__filesystem/operations.h>", "private", "", "public" ] }, - { include: [ "<__filesystem/path.h>", "private", "", "public" ] }, - { include: [ "<__filesystem/path_iterator.h>", "private", "", "public" ] }, - { include: [ "<__filesystem/perm_options.h>", "private", "", "public" ] }, - { include: [ "<__filesystem/perms.h>", "private", "", "public" ] }, - { include: [ "<__filesystem/recursive_directory_iterator.h>", "private", "", "public" ] }, - { include: [ "<__filesystem/space_info.h>", "private", "", "public" ] }, - { include: [ "<__filesystem/u8path.h>", "private", "", "public" ] }, - { include: [ "<__format/buffer.h>", "private", "", "public" ] }, - { include: [ "<__format/concepts.h>", "private", "", "public" ] }, - { include: [ "<__format/container_adaptor.h>", "private", "", "public" ] }, - { include: [ "<__format/enable_insertable.h>", "private", "", "public" ] }, - { include: [ "<__format/escaped_output_table.h>", "private", "", "public" ] }, - { include: [ "<__format/extended_grapheme_cluster_table.h>", "private", "", "public" ] }, - { include: [ "<__format/format_arg.h>", "private", "", "public" ] }, - { include: [ "<__format/format_arg_store.h>", "private", "", "public" ] }, - { include: [ "<__format/format_args.h>", "private", "", "public" ] }, - { include: [ "<__format/format_context.h>", "private", "", "public" ] }, - { include: [ "<__format/format_error.h>", "private", "", "public" ] }, - { include: [ "<__format/format_functions.h>", "private", "", "public" ] }, - { include: [ "<__format/format_fwd.h>", "private", "", "public" ] }, - { include: [ "<__format/format_parse_context.h>", "private", "", "public" ] }, - { include: [ "<__format/format_string.h>", "private", "", "public" ] }, - { include: [ "<__format/format_to_n_result.h>", "private", "", "public" ] }, - { include: [ "<__format/formatter.h>", "private", "", "public" ] }, - { include: [ "<__format/formatter_bool.h>", "private", "", "public" ] }, - { include: [ "<__format/formatter_char.h>", "private", "", "public" ] }, - { include: [ "<__format/formatter_floating_point.h>", "private", "", "public" ] }, - { include: [ "<__format/formatter_integer.h>", "private", "", "public" ] }, - { include: [ "<__format/formatter_integral.h>", "private", "", "public" ] }, - { include: [ "<__format/formatter_output.h>", "private", "", "public" ] }, - { include: [ "<__format/formatter_pointer.h>", "private", "", "public" ] }, - { include: [ "<__format/formatter_string.h>", "private", "", "public" ] }, - { include: [ "<__format/formatter_tuple.h>", "private", "", "public" ] }, - { include: [ "<__format/parser_std_format_spec.h>", "private", "", "public" ] }, - { include: [ "<__format/range_default_formatter.h>", "private", "", "public" ] }, - { include: [ "<__format/range_formatter.h>", "private", "", "public" ] }, - { include: [ "<__format/unicode.h>", "private", "", "public" ] }, - { include: [ "<__format/width_estimation_table.h>", "private", "", "public" ] }, - { include: [ "<__format/write_escaped.h>", "private", "", "public" ] }, - { include: [ "<__functional/binary_function.h>", "private", "", "public" ] }, - { include: [ "<__functional/binary_negate.h>", "private", "", "public" ] }, - { include: [ "<__functional/bind.h>", "private", "", "public" ] }, - { include: [ "<__functional/bind_back.h>", "private", "", "public" ] }, - { include: [ "<__functional/bind_front.h>", "private", "", "public" ] }, - { include: [ "<__functional/binder1st.h>", "private", "", "public" ] }, - { include: [ "<__functional/binder2nd.h>", "private", "", "public" ] }, - { include: [ "<__functional/boyer_moore_searcher.h>", "private", "", "public" ] }, - { include: [ "<__functional/compose.h>", "private", "", "public" ] }, - { include: [ "<__functional/default_searcher.h>", "private", "", "public" ] }, - { include: [ "<__functional/function.h>", "private", "", "public" ] }, - { include: [ "<__functional/hash.h>", "private", "", "public" ] }, - { include: [ "<__functional/identity.h>", "private", "", "public" ] }, - { include: [ "<__functional/invoke.h>", "private", "", "public" ] }, - { include: [ "<__functional/is_transparent.h>", "private", "", "public" ] }, - { include: [ "<__functional/mem_fn.h>", "private", "", "public" ] }, - { include: [ "<__functional/mem_fun_ref.h>", "private", "", "public" ] }, - { include: [ "<__functional/not_fn.h>", "private", "", "public" ] }, - { include: [ "<__functional/operations.h>", "private", "", "public" ] }, - { include: [ "<__functional/perfect_forward.h>", "private", "", "public" ] }, - { include: [ "<__functional/pointer_to_binary_function.h>", "private", "", "public" ] }, - { include: [ "<__functional/pointer_to_unary_function.h>", "private", "", "public" ] }, - { include: [ "<__functional/ranges_operations.h>", "private", "", "public" ] }, - { include: [ "<__functional/reference_wrapper.h>", "private", "", "public" ] }, - { include: [ "<__functional/unary_function.h>", "private", "", "public" ] }, - { include: [ "<__functional/unary_negate.h>", "private", "", "public" ] }, - { include: [ "<__functional/weak_result_type.h>", "private", "", "public" ] }, - { include: [ "<__fwd/array.h>", "private", "", "public" ] }, - { include: [ "<__fwd/bit_reference.h>", "private", "", "public" ] }, - { include: [ "<__fwd/bit_reference.h>", "private", "", "public" ] }, - { include: [ "<__fwd/fstream.h>", "private", "", "public" ] }, - { include: [ "<__fwd/hash.h>", "private", "", "public" ] }, - { include: [ "<__fwd/ios.h>", "private", "", "public" ] }, - { include: [ "<__fwd/istream.h>", "private", "", "public" ] }, - { include: [ "<__fwd/mdspan.h>", "private", "", "public" ] }, - { include: [ "<__fwd/memory_resource.h>", "private", "", "public" ] }, - { include: [ "<__fwd/ostream.h>", "private", "", "public" ] }, - { include: [ "<__fwd/pair.h>", "private", "", "public" ] }, - { include: [ "<__fwd/span.h>", "private", "", "public" ] }, - { include: [ "<__fwd/sstream.h>", "private", "", "public" ] }, - { include: [ "<__fwd/streambuf.h>", "private", "", "public" ] }, - { include: [ "<__fwd/string.h>", "private", "", "public" ] }, - { include: [ "<__fwd/string_view.h>", "private", "", "public" ] }, - { include: [ "<__fwd/subrange.h>", "private", "", "public" ] }, - { include: [ "<__fwd/tuple.h>", "private", "", "public" ] }, - { include: [ "<__ios/fpos.h>", "private", "", "public" ] }, - { include: [ "<__iterator/access.h>", "private", "", "public" ] }, - { include: [ "<__iterator/advance.h>", "private", "", "public" ] }, - { include: [ "<__iterator/back_insert_iterator.h>", "private", "", "public" ] }, - { include: [ "<__iterator/bounded_iter.h>", "private", "", "public" ] }, - { include: [ "<__iterator/common_iterator.h>", "private", "", "public" ] }, - { include: [ "<__iterator/concepts.h>", "private", "", "public" ] }, - { include: [ "<__iterator/counted_iterator.h>", "private", "", "public" ] }, - { include: [ "<__iterator/cpp17_iterator_concepts.h>", "private", "", "public" ] }, - { include: [ "<__iterator/data.h>", "private", "", "public" ] }, - { include: [ "<__iterator/default_sentinel.h>", "private", "", "public" ] }, - { include: [ "<__iterator/distance.h>", "private", "", "public" ] }, - { include: [ "<__iterator/empty.h>", "private", "", "public" ] }, - { include: [ "<__iterator/erase_if_container.h>", "private", "", "public" ] }, - { include: [ "<__iterator/front_insert_iterator.h>", "private", "", "public" ] }, - { include: [ "<__iterator/incrementable_traits.h>", "private", "", "public" ] }, - { include: [ "<__iterator/indirectly_comparable.h>", "private", "", "public" ] }, - { include: [ "<__iterator/insert_iterator.h>", "private", "", "public" ] }, - { include: [ "<__iterator/istream_iterator.h>", "private", "", "public" ] }, - { include: [ "<__iterator/istreambuf_iterator.h>", "private", "", "public" ] }, - { include: [ "<__iterator/iter_move.h>", "private", "", "public" ] }, - { include: [ "<__iterator/iter_swap.h>", "private", "", "public" ] }, - { include: [ "<__iterator/iterator.h>", "private", "", "public" ] }, - { include: [ "<__iterator/iterator_traits.h>", "private", "", "public" ] }, - { include: [ "<__iterator/iterator_with_data.h>", "private", "", "public" ] }, - { include: [ "<__iterator/mergeable.h>", "private", "", "public" ] }, - { include: [ "<__iterator/move_iterator.h>", "private", "", "public" ] }, - { include: [ "<__iterator/move_sentinel.h>", "private", "", "public" ] }, - { include: [ "<__iterator/next.h>", "private", "", "public" ] }, - { include: [ "<__iterator/ostream_iterator.h>", "private", "", "public" ] }, - { include: [ "<__iterator/ostreambuf_iterator.h>", "private", "", "public" ] }, - { include: [ "<__iterator/permutable.h>", "private", "", "public" ] }, - { include: [ "<__iterator/prev.h>", "private", "", "public" ] }, - { include: [ "<__iterator/projected.h>", "private", "", "public" ] }, - { include: [ "<__iterator/ranges_iterator_traits.h>", "private", "", "public" ] }, - { include: [ "<__iterator/readable_traits.h>", "private", "", "public" ] }, - { include: [ "<__iterator/reverse_access.h>", "private", "", "public" ] }, - { include: [ "<__iterator/reverse_iterator.h>", "private", "", "public" ] }, - { include: [ "<__iterator/segmented_iterator.h>", "private", "", "public" ] }, - { include: [ "<__iterator/size.h>", "private", "", "public" ] }, - { include: [ "<__iterator/sortable.h>", "private", "", "public" ] }, - { include: [ "<__iterator/unreachable_sentinel.h>", "private", "", "public" ] }, - { include: [ "<__iterator/wrap_iter.h>", "private", "", "public" ] }, - { include: [ "<__locale_dir/locale_base_api.h>", "private", "", "public" ] }, - { include: [ "<__locale_dir/locale_base_api/android.h>", "private", "", "public" ] }, - { include: [ "<__locale_dir/locale_base_api/bsd_locale_defaults.h>", "private", "", "public" ] }, - { include: [ "<__locale_dir/locale_base_api/bsd_locale_fallbacks.h>", "private", "", "public" ] }, - { include: [ "<__locale_dir/locale_base_api/fuchsia.h>", "private", "", "public" ] }, - { include: [ "<__locale_dir/locale_base_api/ibm.h>", "private", "", "public" ] }, - { include: [ "<__locale_dir/locale_base_api/locale_guard.h>", "private", "", "public" ] }, - { include: [ "<__locale_dir/locale_base_api/musl.h>", "private", "", "public" ] }, - { include: [ "<__locale_dir/locale_base_api/newlib.h>", "private", "", "public" ] }, - { include: [ "<__locale_dir/locale_base_api/openbsd.h>", "private", "", "public" ] }, - { include: [ "<__locale_dir/locale_base_api/win32.h>", "private", "", "public" ] }, - { include: [ "<__math/abs.h>", "private", "", "public" ] }, - { include: [ "<__math/copysign.h>", "private", "", "public" ] }, - { include: [ "<__math/error_functions.h>", "private", "", "public" ] }, - { include: [ "<__math/exponential_functions.h>", "private", "", "public" ] }, - { include: [ "<__math/fdim.h>", "private", "", "public" ] }, - { include: [ "<__math/fma.h>", "private", "", "public" ] }, - { include: [ "<__math/gamma.h>", "private", "", "public" ] }, - { include: [ "<__math/hyperbolic_functions.h>", "private", "", "public" ] }, - { include: [ "<__math/hypot.h>", "private", "", "public" ] }, - { include: [ "<__math/inverse_hyperbolic_functions.h>", "private", "", "public" ] }, - { include: [ "<__math/inverse_trigonometric_functions.h>", "private", "", "public" ] }, - { include: [ "<__math/logarithms.h>", "private", "", "public" ] }, - { include: [ "<__math/min_max.h>", "private", "", "public" ] }, - { include: [ "<__math/modulo.h>", "private", "", "public" ] }, - { include: [ "<__math/remainder.h>", "private", "", "public" ] }, - { include: [ "<__math/roots.h>", "private", "", "public" ] }, - { include: [ "<__math/rounding_functions.h>", "private", "", "public" ] }, - { include: [ "<__math/traits.h>", "private", "", "public" ] }, - { include: [ "<__math/trigonometric_functions.h>", "private", "", "public" ] }, - { include: [ "<__mdspan/default_accessor.h>", "private", "", "public" ] }, - { include: [ "<__mdspan/extents.h>", "private", "", "public" ] }, - { include: [ "<__mdspan/layout_left.h>", "private", "", "public" ] }, - { include: [ "<__mdspan/layout_right.h>", "private", "", "public" ] }, - { include: [ "<__mdspan/layout_stride.h>", "private", "", "public" ] }, - { include: [ "<__mdspan/mdspan.h>", "private", "", "public" ] }, - { include: [ "<__memory/addressof.h>", "private", "", "public" ] }, - { include: [ "<__memory/align.h>", "private", "", "public" ] }, - { include: [ "<__memory/aligned_alloc.h>", "private", "", "public" ] }, - { include: [ "<__memory/allocate_at_least.h>", "private", "", "public" ] }, - { include: [ "<__memory/allocation_guard.h>", "private", "", "public" ] }, - { include: [ "<__memory/allocator.h>", "private", "", "public" ] }, - { include: [ "<__memory/allocator_arg_t.h>", "private", "", "public" ] }, - { include: [ "<__memory/allocator_destructor.h>", "private", "", "public" ] }, - { include: [ "<__memory/allocator_traits.h>", "private", "", "public" ] }, - { include: [ "<__memory/assume_aligned.h>", "private", "", "public" ] }, - { include: [ "<__memory/auto_ptr.h>", "private", "", "public" ] }, - { include: [ "<__memory/builtin_new_allocator.h>", "private", "", "public" ] }, - { include: [ "<__memory/compressed_pair.h>", "private", "", "public" ] }, - { include: [ "<__memory/concepts.h>", "private", "", "public" ] }, - { include: [ "<__memory/construct_at.h>", "private", "", "public" ] }, - { include: [ "<__memory/destruct_n.h>", "private", "", "public" ] }, - { include: [ "<__memory/pointer_traits.h>", "private", "", "public" ] }, - { include: [ "<__memory/ranges_construct_at.h>", "private", "", "public" ] }, - { include: [ "<__memory/ranges_uninitialized_algorithms.h>", "private", "", "public" ] }, - { include: [ "<__memory/raw_storage_iterator.h>", "private", "", "public" ] }, - { include: [ "<__memory/shared_ptr.h>", "private", "", "public" ] }, - { include: [ "<__memory/swap_allocator.h>", "private", "", "public" ] }, - { include: [ "<__memory/temp_value.h>", "private", "", "public" ] }, - { include: [ "<__memory/temporary_buffer.h>", "private", "", "public" ] }, - { include: [ "<__memory/uninitialized_algorithms.h>", "private", "", "public" ] }, - { include: [ "<__memory/unique_ptr.h>", "private", "", "public" ] }, - { include: [ "<__memory/uses_allocator.h>", "private", "", "public" ] }, - { include: [ "<__memory/uses_allocator_construction.h>", "private", "", "public" ] }, - { include: [ "<__memory/voidify.h>", "private", "", "public" ] }, - { include: [ "<__memory_resource/memory_resource.h>", "private", "", "public" ] }, - { include: [ "<__memory_resource/monotonic_buffer_resource.h>", "private", "", "public" ] }, - { include: [ "<__memory_resource/polymorphic_allocator.h>", "private", "", "public" ] }, - { include: [ "<__memory_resource/pool_options.h>", "private", "", "public" ] }, - { include: [ "<__memory_resource/synchronized_pool_resource.h>", "private", "", "public" ] }, - { include: [ "<__memory_resource/unsynchronized_pool_resource.h>", "private", "", "public" ] }, - { include: [ "<__mutex/lock_guard.h>", "private", "", "public" ] }, - { include: [ "<__mutex/mutex.h>", "private", "", "public" ] }, - { include: [ "<__mutex/once_flag.h>", "private", "", "public" ] }, - { include: [ "<__mutex/tag_types.h>", "private", "", "public" ] }, - { include: [ "<__mutex/unique_lock.h>", "private", "", "public" ] }, - { include: [ "<__numeric/accumulate.h>", "private", "", "public" ] }, - { include: [ "<__numeric/adjacent_difference.h>", "private", "", "public" ] }, - { include: [ "<__numeric/exclusive_scan.h>", "private", "", "public" ] }, - { include: [ "<__numeric/gcd_lcm.h>", "private", "", "public" ] }, - { include: [ "<__numeric/inclusive_scan.h>", "private", "", "public" ] }, - { include: [ "<__numeric/inner_product.h>", "private", "", "public" ] }, - { include: [ "<__numeric/iota.h>", "private", "", "public" ] }, - { include: [ "<__numeric/midpoint.h>", "private", "", "public" ] }, - { include: [ "<__numeric/partial_sum.h>", "private", "", "public" ] }, - { include: [ "<__numeric/pstl_reduce.h>", "private", "", "public" ] }, - { include: [ "<__numeric/pstl_transform_reduce.h>", "private", "", "public" ] }, - { include: [ "<__numeric/reduce.h>", "private", "", "public" ] }, - { include: [ "<__numeric/saturation_arithmetic.h>", "private", "", "public" ] }, - { include: [ "<__numeric/transform_exclusive_scan.h>", "private", "", "public" ] }, - { include: [ "<__numeric/transform_inclusive_scan.h>", "private", "", "public" ] }, - { include: [ "<__numeric/transform_reduce.h>", "private", "", "public" ] }, - { include: [ "<__random/bernoulli_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/binomial_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/cauchy_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/chi_squared_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/clamp_to_integral.h>", "private", "", "public" ] }, - { include: [ "<__random/default_random_engine.h>", "private", "", "public" ] }, - { include: [ "<__random/discard_block_engine.h>", "private", "", "public" ] }, - { include: [ "<__random/discrete_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/exponential_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/extreme_value_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/fisher_f_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/gamma_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/generate_canonical.h>", "private", "", "public" ] }, - { include: [ "<__random/geometric_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/independent_bits_engine.h>", "private", "", "public" ] }, - { include: [ "<__random/is_seed_sequence.h>", "private", "", "public" ] }, - { include: [ "<__random/is_valid.h>", "private", "", "public" ] }, - { include: [ "<__random/knuth_b.h>", "private", "", "public" ] }, - { include: [ "<__random/linear_congruential_engine.h>", "private", "", "public" ] }, - { include: [ "<__random/log2.h>", "private", "", "public" ] }, - { include: [ "<__random/lognormal_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/mersenne_twister_engine.h>", "private", "", "public" ] }, - { include: [ "<__random/negative_binomial_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/normal_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/piecewise_constant_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/piecewise_linear_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/poisson_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/random_device.h>", "private", "", "public" ] }, - { include: [ "<__random/ranlux.h>", "private", "", "public" ] }, - { include: [ "<__random/seed_seq.h>", "private", "", "public" ] }, - { include: [ "<__random/shuffle_order_engine.h>", "private", "", "public" ] }, - { include: [ "<__random/student_t_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/subtract_with_carry_engine.h>", "private", "", "public" ] }, - { include: [ "<__random/uniform_int_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/uniform_random_bit_generator.h>", "private", "", "public" ] }, - { include: [ "<__random/uniform_real_distribution.h>", "private", "", "public" ] }, - { include: [ "<__random/weibull_distribution.h>", "private", "", "public" ] }, - { include: [ "<__ranges/access.h>", "private", "", "public" ] }, - { include: [ "<__ranges/all.h>", "private", "", "public" ] }, - { include: [ "<__ranges/as_rvalue_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/chunk_by_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/common_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/concepts.h>", "private", "", "public" ] }, - { include: [ "<__ranges/container_compatible_range.h>", "private", "", "public" ] }, - { include: [ "<__ranges/counted.h>", "private", "", "public" ] }, - { include: [ "<__ranges/dangling.h>", "private", "", "public" ] }, - { include: [ "<__ranges/data.h>", "private", "", "public" ] }, - { include: [ "<__ranges/drop_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/drop_while_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/elements_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/empty.h>", "private", "", "public" ] }, - { include: [ "<__ranges/empty_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/enable_borrowed_range.h>", "private", "", "public" ] }, - { include: [ "<__ranges/enable_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/filter_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/from_range.h>", "private", "", "public" ] }, - { include: [ "<__ranges/iota_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/istream_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/join_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/lazy_split_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/movable_box.h>", "private", "", "public" ] }, - { include: [ "<__ranges/non_propagating_cache.h>", "private", "", "public" ] }, - { include: [ "<__ranges/owning_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/range_adaptor.h>", "private", "", "public" ] }, - { include: [ "<__ranges/rbegin.h>", "private", "", "public" ] }, - { include: [ "<__ranges/ref_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/rend.h>", "private", "", "public" ] }, - { include: [ "<__ranges/repeat_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/reverse_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/single_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/size.h>", "private", "", "public" ] }, - { include: [ "<__ranges/split_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/stride_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/subrange.h>", "private", "", "public" ] }, - { include: [ "<__ranges/take_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/take_while_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/to.h>", "private", "", "public" ] }, - { include: [ "<__ranges/transform_view.h>", "private", "", "public" ] }, - { include: [ "<__ranges/view_interface.h>", "private", "", "public" ] }, - { include: [ "<__ranges/views.h>", "private", "", "public" ] }, - { include: [ "<__ranges/zip_view.h>", "private", "", "public" ] }, - { include: [ "<__stop_token/atomic_unique_lock.h>", "private", "", "public" ] }, - { include: [ "<__stop_token/intrusive_list_view.h>", "private", "", "public" ] }, - { include: [ "<__stop_token/intrusive_shared_ptr.h>", "private", "", "public" ] }, - { include: [ "<__stop_token/stop_callback.h>", "private", "", "public" ] }, - { include: [ "<__stop_token/stop_source.h>", "private", "", "public" ] }, - { include: [ "<__stop_token/stop_state.h>", "private", "", "public" ] }, - { include: [ "<__stop_token/stop_token.h>", "private", "", "public" ] }, - { include: [ "<__string/char_traits.h>", "private", "", "public" ] }, - { include: [ "<__string/constexpr_c_functions.h>", "private", "", "public" ] }, - { include: [ "<__string/extern_template_lists.h>", "private", "", "public" ] }, - { include: [ "<__system_error/errc.h>", "private", "", "public" ] }, - { include: [ "<__system_error/error_category.h>", "private", "", "public" ] }, - { include: [ "<__system_error/error_code.h>", "private", "", "public" ] }, - { include: [ "<__system_error/error_condition.h>", "private", "", "public" ] }, - { include: [ "<__system_error/system_error.h>", "private", "", "public" ] }, - { include: [ "<__thread/formatter.h>", "private", "", "public" ] }, - { include: [ "<__thread/id.h>", "private", "", "public" ] }, - { include: [ "<__thread/jthread.h>", "private", "", "public" ] }, - { include: [ "<__thread/poll_with_backoff.h>", "private", "", "public" ] }, - { include: [ "<__thread/support.h>", "private", "", "public" ] }, - { include: [ "<__thread/support.h>", "private", "", "public" ] }, - { include: [ "<__thread/support.h>", "private", "", "public" ] }, - { include: [ "<__thread/support.h>", "private", "", "public" ] }, - { include: [ "<__thread/support/c11.h>", "private", "", "public" ] }, - { include: [ "<__thread/support/c11.h>", "private", "", "public" ] }, - { include: [ "<__thread/support/c11.h>", "private", "", "public" ] }, - { include: [ "<__thread/support/c11.h>", "private", "", "public" ] }, - { include: [ "<__thread/support/external.h>", "private", "", "public" ] }, - { include: [ "<__thread/support/external.h>", "private", "", "public" ] }, - { include: [ "<__thread/support/external.h>", "private", "", "public" ] }, - { include: [ "<__thread/support/external.h>", "private", "", "public" ] }, - { include: [ "<__thread/support/pthread.h>", "private", "", "public" ] }, - { include: [ "<__thread/support/pthread.h>", "private", "", "public" ] }, - { include: [ "<__thread/support/pthread.h>", "private", "", "public" ] }, - { include: [ "<__thread/support/pthread.h>", "private", "", "public" ] }, - { include: [ "<__thread/support/windows.h>", "private", "", "public" ] }, - { include: [ "<__thread/support/windows.h>", "private", "", "public" ] }, - { include: [ "<__thread/support/windows.h>", "private", "", "public" ] }, - { include: [ "<__thread/support/windows.h>", "private", "", "public" ] }, - { include: [ "<__thread/this_thread.h>", "private", "", "public" ] }, - { include: [ "<__thread/thread.h>", "private", "", "public" ] }, - { include: [ "<__thread/timed_backoff_policy.h>", "private", "", "public" ] }, - { include: [ "<__tuple/make_tuple_types.h>", "private", "", "public" ] }, - { include: [ "<__tuple/pair_like.h>", "private", "", "public" ] }, - { include: [ "<__tuple/sfinae_helpers.h>", "private", "", "public" ] }, - { include: [ "<__tuple/tuple_element.h>", "private", "", "public" ] }, - { include: [ "<__tuple/tuple_indices.h>", "private", "", "public" ] }, - { include: [ "<__tuple/tuple_like.h>", "private", "", "public" ] }, - { include: [ "<__tuple/tuple_like_ext.h>", "private", "", "public" ] }, - { include: [ "<__tuple/tuple_size.h>", "private", "", "public" ] }, - { include: [ "<__tuple/tuple_types.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/add_const.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/add_cv.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/add_lvalue_reference.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/add_pointer.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/add_rvalue_reference.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/add_volatile.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/aligned_storage.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/aligned_union.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/alignment_of.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/apply_cv.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/can_extract_key.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/common_reference.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/common_type.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/conditional.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/conjunction.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/copy_cv.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/copy_cvref.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/datasizeof.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/decay.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/dependent_type.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/disjunction.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/enable_if.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/extent.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/has_unique_object_representation.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/has_virtual_destructor.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/integral_constant.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/invoke.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_abstract.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_aggregate.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_allocator.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_always_bitcastable.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_arithmetic.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_array.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_assignable.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_base_of.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_bounded_array.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_callable.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_char_like_type.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_class.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_compound.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_const.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_constant_evaluated.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_constructible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_convertible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_copy_assignable.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_copy_constructible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_core_convertible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_default_constructible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_destructible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_empty.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_enum.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_equality_comparable.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_execution_policy.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_final.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_floating_point.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_function.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_fundamental.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_implicitly_default_constructible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_integral.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_literal_type.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_member_function_pointer.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_member_object_pointer.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_member_pointer.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_move_assignable.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_move_constructible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_nothrow_assignable.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_nothrow_constructible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_nothrow_convertible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_nothrow_copy_assignable.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_nothrow_copy_constructible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_nothrow_default_constructible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_nothrow_destructible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_nothrow_move_assignable.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_nothrow_move_constructible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_null_pointer.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_object.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_pod.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_pointer.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_polymorphic.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_primary_template.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_reference.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_reference_wrapper.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_referenceable.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_same.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_scalar.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_scoped_enum.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_signed.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_signed_integer.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_specialization.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_standard_layout.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_swappable.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_trivial.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_trivially_assignable.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_trivially_constructible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_trivially_copy_assignable.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_trivially_copy_constructible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_trivially_copyable.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_trivially_default_constructible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_trivially_destructible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_trivially_lexicographically_comparable.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_trivially_move_assignable.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_trivially_move_constructible.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_trivially_relocatable.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_unbounded_array.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_union.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_unsigned.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_unsigned_integer.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_valid_expansion.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_void.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/is_volatile.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/lazy.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/make_32_64_or_128_bit.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/make_const_lvalue_ref.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/make_signed.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/make_unsigned.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/maybe_const.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/nat.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/negation.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/noexcept_move_assign_container.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/operation_traits.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/promote.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/rank.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/remove_all_extents.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/remove_const.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/remove_const_ref.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/remove_cv.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/remove_cvref.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/remove_extent.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/remove_pointer.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/remove_reference.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/remove_volatile.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/result_of.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/strip_signature.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/type_identity.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/type_list.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/underlying_type.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/unwrap_ref.h>", "private", "", "public" ] }, - { include: [ "<__type_traits/void_t.h>", "private", "", "public" ] }, - { include: [ "<__utility/as_const.h>", "private", "", "public" ] }, - { include: [ "<__utility/as_lvalue.h>", "private", "", "public" ] }, - { include: [ "<__utility/auto_cast.h>", "private", "", "public" ] }, - { include: [ "<__utility/cmp.h>", "private", "", "public" ] }, - { include: [ "<__utility/convert_to_integral.h>", "private", "", "public" ] }, - { include: [ "<__utility/declval.h>", "private", "", "public" ] }, - { include: [ "<__utility/empty.h>", "private", "", "public" ] }, - { include: [ "<__utility/exception_guard.h>", "private", "", "public" ] }, - { include: [ "<__utility/exchange.h>", "private", "", "public" ] }, - { include: [ "<__utility/forward.h>", "private", "", "public" ] }, - { include: [ "<__utility/forward_like.h>", "private", "", "public" ] }, - { include: [ "<__utility/in_place.h>", "private", "", "public" ] }, - { include: [ "<__utility/integer_sequence.h>", "private", "", "public" ] }, - { include: [ "<__utility/is_pointer_in_range.h>", "private", "", "public" ] }, - { include: [ "<__utility/move.h>", "private", "", "public" ] }, - { include: [ "<__utility/no_destroy.h>", "private", "", "public" ] }, - { include: [ "<__utility/pair.h>", "private", "", "public" ] }, - { include: [ "<__utility/piecewise_construct.h>", "private", "", "public" ] }, - { include: [ "<__utility/priority_tag.h>", "private", "", "public" ] }, - { include: [ "<__utility/rel_ops.h>", "private", "", "public" ] }, - { include: [ "<__utility/small_buffer.h>", "private", "", "public" ] }, - { include: [ "<__utility/swap.h>", "private", "", "public" ] }, - { include: [ "<__utility/to_underlying.h>", "private", "", "public" ] }, - { include: [ "<__utility/unreachable.h>", "private", "", "public" ] }, - { include: [ "<__variant/monostate.h>", "private", "", "public" ] }, -] From ea4d3a99fa4401c73eb6554886ab9875e837511f Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 18 Nov 2024 10:39:22 -0500 Subject: [PATCH 151/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Update status and release documentation. --- libcxx/docs/ReleaseNotes/20.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst index 572d4321dc46f..ab6e25cf0854e 100644 --- a/libcxx/docs/ReleaseNotes/20.rst +++ b/libcxx/docs/ReleaseNotes/20.rst @@ -47,6 +47,7 @@ Implemented Papers - ``std::jthread`` and ```` are not guarded behind ``-fexperimental-library`` anymore - P2674R1: A trait for implicit lifetime types (`Github `__) - P0429R9: A Standard ``flat_map`` (`Github `__) +- P1899: ``stride_view`` (`Github ` __) Improvements and New Features ----------------------------- From d2aac40dc5d95221ce226cd2e6baec03516d67b0 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 18 Nov 2024 10:56:14 -0500 Subject: [PATCH 152/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Use constexpr if for operator- overload. --- libcxx/include/__ranges/stride_view.h | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index b213981dbb6d5..4b3d4754385ac 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -35,7 +35,6 @@ #include <__ranges/enable_borrowed_range.h> #include <__ranges/range_adaptor.h> #include <__ranges/view_interface.h> - #include <__type_traits/make_unsigned.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -335,18 +334,14 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> return __r; } - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type - operator-(__iterator const& __x, __iterator const& __y) - requires sized_sentinel_for, iterator_t<_Base>> && forward_range<_Base> - { - auto __n = __x.__current_ - __y.__current_; - return (__n + __x.__missing_ - __y.__missing_) / __x.__stride_; - } - [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(__iterator const& __x, __iterator const& __y) requires sized_sentinel_for, iterator_t<_Base>> { + if constexpr (forward_range<_Base>) { + auto __n = __x.__current_ - __y.__current_; + return (__n + __x.__missing_ - __y.__missing_) / __x.__stride_; + } auto __n = __x.__current_ - __y.__current_; if (__n < 0) { return -ranges::__div_ceil(-__n, __x.__stride_); From 86291d98c0dcffd97bfcefbeb0e61b97e6fe0199 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 18 Nov 2024 16:43:16 -0500 Subject: [PATCH 153/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Classify assertions. --- libcxx/include/__ranges/stride_view.h | 10 +++++----- .../range.stride.view/ctor.assert.pass.cpp | 4 ++-- .../range.stride.view/iterator/dereference.pass.cpp | 4 ++-- .../range.stride.view/iterator/increment.pass.cpp | 4 ++-- .../iterator/operator_plus_equal.pass.cpp | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 4b3d4754385ac..c8bc5f9381512 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -71,7 +71,7 @@ class stride_view : public view_interface> { public: _LIBCPP_HIDE_FROM_ABI constexpr explicit stride_view(_View __base, range_difference_t<_View> __stride) : __base_(std::move(__base)), __stride_(__stride) { - _LIBCPP_ASSERT_UNCATEGORIZED(__stride > 0, "The value of stride must be greater than 0"); + _LIBCPP_ASSERT_ARGUMENT_WITHIN_DOMAIN(__stride > 0, "The value of stride must be greater than 0"); } [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& @@ -210,19 +210,19 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> } _LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() { - _LIBCPP_ASSERT_UNCATEGORIZED(__current_ != __end_, "Cannot increment an iterator already at the end."); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__current_ != __end_, "Cannot increment an iterator already at the end."); __missing_ = ranges::advance(__current_, __stride_, __end_); return *this; } _LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { - _LIBCPP_ASSERT_UNCATEGORIZED(__current_ != __end_, "Cannot increment an iterator already at the end."); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__current_ != __end_, "Cannot increment an iterator already at the end."); ++*this; } _LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) requires forward_range<_Base> { - _LIBCPP_ASSERT_UNCATEGORIZED(__current_ != __end_, "Cannot increment an iterator already at the end."); + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__current_ != __end_, "Cannot increment an iterator already at the end."); auto __tmp = *this; ++*this; return __tmp; @@ -247,7 +247,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> requires random_access_range<_Base> { if (__n > 0) { - _LIBCPP_ASSERT_UNCATEGORIZED(ranges::distance(__current_, __end_) > __stride_ * (__n - 1), + _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(ranges::distance(__current_, __end_) > __stride_ * (__n - 1), "Advancing the iterator beyond the end is not allowed."); ranges::advance(__current_, __stride_ * (__n - 1)); __missing_ = ranges::advance(__current_, __stride_, __end_); diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp index b62ce15d7c93b..e564891b15a15 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.assert.pass.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// UNSUPPORTED: !libcpp-hardening-mode=debug -// XFAIL: availability-verbose_abort-missing +// REQUIRES: libcpp-hardening-mode={{extensive|debug}} +// XFAIL:libcpp-hardening-mode=debug && availability-verbose_abort-missing // constexpr explicit stride_view(_View, range_difference_t<_View>) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp index 1c44078e52403..5094c0bf532d9 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/dereference.pass.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// UNSUPPORTED: !libcpp-hardening-mode=debug -// XFAIL: availability-verbose_abort-missing +// REQUIRES: libcpp-hardening-mode={{fast|extensive|debug}} +// XFAIL:libcpp-hardening-mode=debug && availability-verbose_abort-missing // constexpr decltype(auto) operator*() const diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp index bd818ecc48b8e..6cd3b11fd7e89 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/increment.pass.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// UNSUPPORTED: !libcpp-hardening-mode=debug -// XFAIL: availability-verbose_abort-missing +// REQUIRES: libcpp-hardening-mode={{fast|extensive|debug}} +// XFAIL:libcpp-hardening-mode=debug && availability-verbose_abort-missing // constexpr stride_view::& operator++() // constexpr __iterator& operator++() diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp index 766d99223dc8d..0a84436444cd5 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/iterator/operator_plus_equal.pass.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// UNSUPPORTED: !libcpp-hardening-mode=debug -// XFAIL: availability-verbose_abort-missing +// REQUIRES: libcpp-hardening-mode={{fast|extensive|debug}} +// XFAIL:libcpp-hardening-mode=debug && availability-verbose_abort-missing // constexpr __iterator& operator+=(difference_type __n) From a48334208f65b46216088148e11f84068d89a57c Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 18 Nov 2024 20:02:04 -0500 Subject: [PATCH 154/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Cleanup formatting. --- libcxx/include/__ranges/stride_view.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index c8bc5f9381512..6e179b11ccbb4 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -248,7 +248,7 @@ class stride_view<_View>::__iterator : public __stride_iterator_category<_View> { if (__n > 0) { _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(ranges::distance(__current_, __end_) > __stride_ * (__n - 1), - "Advancing the iterator beyond the end is not allowed."); + "Advancing the iterator beyond the end is not allowed."); ranges::advance(__current_, __stride_ * (__n - 1)); __missing_ = ranges::advance(__current_, __stride_, __end_); From 62b00c40d2ef2c7fbfb7128a3616a91198e1f545 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Tue, 26 Nov 2024 10:01:57 -0500 Subject: [PATCH 155/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Simplify ctor tests. --- .../range.adaptors/range.stride.view/ctor.pass.cpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp index 3207565e4c5bf..ef360c8d17eba 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/ctor.pass.cpp @@ -35,20 +35,8 @@ constexpr bool test() { // from when the stride view is constructed. std::ranges::stride_view>> mosv(std::move(mov), 1); - // While we are here, make sure that the ctor captured the proper things + // While we are here, make sure that the ctor captured the stride. assert(mosv.stride() == 1); - - auto mosv_i = mosv.begin(); - assert(*mosv_i == 1); - - mosv_i++; - assert(*mosv_i == 2); - - mosv_i++; - assert(*mosv_i == 3); - - mosv_i++; - assert(mosv_i == mosv.end()); } return true; } From 775dbc7d2ebd69caa586a5b7cb8b4dc9d99d25c2 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 6 Dec 2024 22:47:34 -0500 Subject: [PATCH 156/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Consolidate class nodiscard verify tests. --- .../begin.nodiscard.verify.cpp | 23 ----------------- .../ctor.nodiscard.verify.cpp | 23 ----------------- .../end.nodiscard.verify.cpp | 25 ------------------- ...iscard.verify.cpp => nodiscard.verify.cpp} | 0 .../size.nodiscard.verify.cpp | 23 ----------------- .../stride.nodiscard.verify.cpp | 22 ---------------- 6 files changed, 116 deletions(-) delete mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/begin.nodiscard.verify.cpp delete mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.nodiscard.verify.cpp delete mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/end.nodiscard.verify.cpp rename libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/{base.nodiscard.verify.cpp => nodiscard.verify.cpp} (100%) delete mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/size.nodiscard.verify.cpp delete mode 100644 libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/stride.nodiscard.verify.cpp diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/begin.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/begin.nodiscard.verify.cpp deleted file mode 100644 index 3ffe7787c927a..0000000000000 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/begin.nodiscard.verify.cpp +++ /dev/null @@ -1,23 +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, c++20 - -// Test that appropriate (member) functions are properly marked no_discard - -#include - -#include "../../../../std/ranges/range.adaptors/range.stride.view/types.h" - -void test() { - const auto const_sv = std::views::stride(SimpleCommonConstView{}, 2); - auto unsimple_sv = std::views::stride(UnsimpleConstView{}, 2); - - const_sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - unsimple_sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} -} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.nodiscard.verify.cpp deleted file mode 100644 index d27b1b6c8f41a..0000000000000 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/ctor.nodiscard.verify.cpp +++ /dev/null @@ -1,23 +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, c++20 - -// Test that appropriate (member) functions are properly marked no_discard - -#include - -#include "../../../../std/ranges/range.adaptors/range.stride.view/types.h" - -void test() { - const int range[] = {1, 2, 3}; - - std::views::stride( // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - range, - 2); -} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/end.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/end.nodiscard.verify.cpp deleted file mode 100644 index 50bed53075566..0000000000000 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/end.nodiscard.verify.cpp +++ /dev/null @@ -1,25 +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, c++20 - -// Test that appropriate (member) functions are properly marked no_discard - -#include - -#include "../../../../std/ranges/range.adaptors/range.stride.view/types.h" - -void test() { - const int range[] = {1, 2, 3}; - - const auto const_sv = std::views::stride(range, 2); - auto unsimple_sv = std::views::stride(UnsimpleConstView{}, 2); - - const_sv.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - unsimple_sv.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} -} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp similarity index 100% rename from libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/base.nodiscard.verify.cpp rename to libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/size.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/size.nodiscard.verify.cpp deleted file mode 100644 index 73fe77df16d14..0000000000000 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/size.nodiscard.verify.cpp +++ /dev/null @@ -1,23 +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, c++20 - -// Test that appropriate (member) functions are properly marked no_discard - -#include - -#include "../../../../std/ranges/range.adaptors/range.stride.view/types.h" - -void test() { - auto sv = std::views::stride(SimpleNoConstSizedCommonView(), 2); - const auto const_sv = std::views::stride(SimpleCommonConstView(), 2); - - sv.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} - const_sv.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} -} diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/stride.nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/stride.nodiscard.verify.cpp deleted file mode 100644 index 22528d77047de..0000000000000 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/stride.nodiscard.verify.cpp +++ /dev/null @@ -1,22 +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, c++20 - -// Test that appropriate (member) functions are properly marked no_discard - -#include - -#include "../../../../std/ranges/range.adaptors/range.stride.view/types.h" - -void test() { - const int range[] = {1, 2, 3}; - - const auto const_sv = std::views::stride(range, 2); - const_sv.stride(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} -} From e651f2f2051bde50c0570e6330f341a07c7b69ed Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 6 Dec 2024 22:51:40 -0500 Subject: [PATCH 157/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Consolidate class nodiscard verify tests. --- .../range.stride.view/nodiscard.verify.cpp | 60 ++++++++++++++++--- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp index 8da7c384b2ed1..07e3045239455 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp @@ -8,22 +8,64 @@ // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 -// Test that std::ranges::stride_view::base() is marked nodiscard. +// Test that +// std::view::stride() +// std::ranges::stride_view::base() +// std::ranges::stride_view::begin() +// std::ranges::stride_view::end() +// std::ranges::stride_view::size() +// std::ranges::stride_view::stride() +// are all marked nodiscard. #include -#include #include "../../../../std/ranges/range.adaptors/range.stride.view/types.h" -void test() { +void test_base_nodiscard() { const std::vector intv = {1, 2, 3}; - auto copyable_view = CopyableView::const_iterator>(intv.begin(), intv.end()); - static_assert(std::copy_constructible); + auto sv = std::ranges::stride_view(intv, 3); - const auto svc = std::ranges::stride_view(copyable_view, 2); - auto svm = std::ranges::stride_view(copyable_view, 2); + sv.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + std::move(sv).base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +} + +void test_begin_nodiscard() { + const auto const_sv = std::views::stride(SimpleCommonConstView{}, 2); + auto unsimple_sv = std::views::stride(UnsimpleConstView{}, 2); + + const_sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + unsimple_sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +} + + +void test_views_stride_nodiscard() { + const int range[] = {1, 2, 3}; + + std::views::stride( // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + range, + 2); +} + +void test_end_nodiscard() { + const int range[] = {1, 2, 3}; - svc.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + const auto const_sv = std::views::stride(range, 2); + auto unsimple_sv = std::views::stride(UnsimpleConstView{}, 2); + + const_sv.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + unsimple_sv.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +} + +void test_size_nodiscard() { + auto sv = std::views::stride(SimpleNoConstSizedCommonView(), 2); + const auto const_sv = std::views::stride(SimpleCommonConstView(), 2); + + sv.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + const_sv.size(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +} - std::move(svm).base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} +void test_stride_nodiscard() { + const int range[] = {1, 2, 3}; + auto const_sv = std::views::stride(range, 2); + const_sv.stride(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } From 8f6a7138aaf47008fa4c086aad7e863dfd84b84a Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 6 Dec 2024 22:52:08 -0500 Subject: [PATCH 158/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Remove constraint on MoveOnlyView. --- libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index 5f8f4ae01d8d2..a49986af827d0 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -236,7 +236,7 @@ template Sent = sentinel_wrap using CopyableView = MaybeCopyableAlwaysMoveableView; static_assert(std::copyable>>); -template Sent = sentinel_wrapper> +template Sent = sentinel_wrapper> using MoveOnlyView = MaybeCopyableAlwaysMoveableView; static_assert(!std::copyable>>); From 59b07b97b36e9a64119b9c4b60b55877967fbdae Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 9 Dec 2024 16:44:04 -0500 Subject: [PATCH 159/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Fix formatting. --- .../range.adaptors/range.stride.view/nodiscard.verify.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp index 07e3045239455..4d6647f019792 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp @@ -23,9 +23,9 @@ void test_base_nodiscard() { const std::vector intv = {1, 2, 3}; - auto sv = std::ranges::stride_view(intv, 3); + auto sv = std::ranges::stride_view(intv, 3); - sv.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} + sv.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} std::move(sv).base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } @@ -37,7 +37,6 @@ void test_begin_nodiscard() { unsimple_sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } - void test_views_stride_nodiscard() { const int range[] = {1, 2, 3}; @@ -66,6 +65,6 @@ void test_size_nodiscard() { void test_stride_nodiscard() { const int range[] = {1, 2, 3}; - auto const_sv = std::views::stride(range, 2); + auto const_sv = std::views::stride(range, 2); const_sv.stride(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } From 25a0d96581f805369e1b26a4c71dfdbe0d8225f0 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 30 May 2025 08:30:48 -0400 Subject: [PATCH 160/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Signed-off-by: Will Hawkins --- .../ranges.version.compile.pass.cpp | 96 +- .../version.version.compile.pass.cpp | 13957 ++++++++-------- 2 files changed, 6919 insertions(+), 7134 deletions(-) diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp index 7a548c1bf2635..8d69867feba8f 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp @@ -64,13 +64,13 @@ # error "__cpp_lib_ranges_slide should not be defined before c++23" # endif -# ifdef __cpp_lib_ranges_stride -# error "__cpp_lib_ranges_stride should not be defined before c++23" -# endif +# ifdef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should not be defined before c++23" +# endif -# ifdef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should not be defined before c++23" -# endif +# ifdef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should not be defined before c++23" +# endif # ifdef __cpp_lib_ranges_zip # error "__cpp_lib_ranges_zip should not be defined before c++23" @@ -122,13 +122,13 @@ # error "__cpp_lib_ranges_slide should not be defined before c++23" # endif -# ifdef __cpp_lib_ranges_stride -# error "__cpp_lib_ranges_stride should not be defined before c++23" -# endif +# ifdef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should not be defined before c++23" +# endif -# ifdef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should not be defined before c++23" -# endif +# ifdef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should not be defined before c++23" +# endif # ifdef __cpp_lib_ranges_zip # error "__cpp_lib_ranges_zip should not be defined before c++23" @@ -180,13 +180,13 @@ # error "__cpp_lib_ranges_slide should not be defined before c++23" # endif -# ifdef __cpp_lib_ranges_stride -# error "__cpp_lib_ranges_stride should not be defined before c++23" -# endif +# ifdef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should not be defined before c++23" +# endif -# ifdef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should not be defined before c++23" -# endif +# ifdef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should not be defined before c++23" +# endif # ifdef __cpp_lib_ranges_zip # error "__cpp_lib_ranges_zip should not be defined before c++23" @@ -241,13 +241,13 @@ # error "__cpp_lib_ranges_slide should not be defined before c++23" # endif -# ifdef __cpp_lib_ranges_stride -# error "__cpp_lib_ranges_stride should not be defined before c++23" -# endif +# ifdef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should not be defined before c++23" +# endif -# ifdef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should not be defined before c++23" -# endif +# ifdef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should not be defined before c++23" +# endif # ifdef __cpp_lib_ranges_zip # error "__cpp_lib_ranges_zip should not be defined before c++23" @@ -341,19 +341,19 @@ # endif # endif -# ifndef __cpp_lib_ranges_stride -# error "__cpp_lib_ranges_stride should be defined in c++23" -# endif -# if __cpp_lib_ranges_stride != 202207L -# error "__cpp_lib_ranges_stride should have the value 202207L in c++23" -# endif +# ifndef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should be defined in c++23" +# endif +# if __cpp_lib_ranges_stride != 202207L +# error "__cpp_lib_ranges_stride should have the value 202207L in c++23" +# endif -# ifndef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should be defined in c++23" -# endif -# if __cpp_lib_ranges_to_container != 202202L -# error "__cpp_lib_ranges_to_container should have the value 202202L in c++23" -# endif +# ifndef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should be defined in c++23" +# endif +# if __cpp_lib_ranges_to_container != 202202L +# error "__cpp_lib_ranges_to_container should have the value 202202L in c++23" +# endif # if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_ranges_zip @@ -477,19 +477,19 @@ # endif # endif -# ifndef __cpp_lib_ranges_stride -# error "__cpp_lib_ranges_stride should be defined in c++26" -# endif -# if __cpp_lib_ranges_stride != 202207L -# error "__cpp_lib_ranges_stride should have the value 202207L in c++26" -# endif +# ifndef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should be defined in c++26" +# endif +# if __cpp_lib_ranges_stride != 202207L +# error "__cpp_lib_ranges_stride should have the value 202207L in c++26" +# endif -# ifndef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should be defined in c++26" -# endif -# if __cpp_lib_ranges_to_container != 202202L -# error "__cpp_lib_ranges_to_container should have the value 202202L in c++26" -# endif +# ifndef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should be defined in c++26" +# endif +# if __cpp_lib_ranges_to_container != 202202L +# error "__cpp_lib_ranges_to_container should have the value 202202L in c++26" +# endif # if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_ranges_zip diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp index 955229761437a..17294d94d8603 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp @@ -13,244 +13,7 @@ // Test the feature test macros defined by -/* Constant Value - __cpp_lib_adaptor_iterator_pair_constructor 202106L [C++23] - __cpp_lib_addressof_constexpr 201603L [C++17] - __cpp_lib_allocate_at_least 202302L [C++23] - __cpp_lib_allocator_traits_is_always_equal 201411L [C++17] - __cpp_lib_any 201606L [C++17] - __cpp_lib_apply 201603L [C++17] - __cpp_lib_array_constexpr 201603L [C++17] - 201811L [C++20] - __cpp_lib_as_const 201510L [C++17] - __cpp_lib_associative_heterogeneous_erasure 202110L [C++23] - __cpp_lib_associative_heterogeneous_insertion 202306L [C++26] - __cpp_lib_assume_aligned 201811L [C++20] - __cpp_lib_atomic_flag_test 201907L [C++20] - __cpp_lib_atomic_float 201711L [C++20] - __cpp_lib_atomic_is_always_lock_free 201603L [C++17] - __cpp_lib_atomic_lock_free_type_aliases 201907L [C++20] - __cpp_lib_atomic_min_max 202403L [C++26] - __cpp_lib_atomic_ref 201806L [C++20] - __cpp_lib_atomic_shared_ptr 201711L [C++20] - __cpp_lib_atomic_value_initialization 201911L [C++20] - __cpp_lib_atomic_wait 201907L [C++20] - __cpp_lib_barrier 201907L [C++20] - __cpp_lib_bind_back 202202L [C++23] - __cpp_lib_bind_front 201907L [C++20] - 202306L [C++26] - __cpp_lib_bit_cast 201806L [C++20] - __cpp_lib_bitops 201907L [C++20] - __cpp_lib_bitset 202306L [C++26] - __cpp_lib_bool_constant 201505L [C++17] - __cpp_lib_bounded_array_traits 201902L [C++20] - __cpp_lib_boyer_moore_searcher 201603L [C++17] - __cpp_lib_byte 201603L [C++17] - __cpp_lib_byteswap 202110L [C++23] - __cpp_lib_char8_t 201907L [C++20] - __cpp_lib_chrono 201611L [C++17] - __cpp_lib_chrono_udls 201304L [C++14] - __cpp_lib_clamp 201603L [C++17] - __cpp_lib_complex_udls 201309L [C++14] - __cpp_lib_concepts 202002L [C++20] - __cpp_lib_constexpr_algorithms 201806L [C++20] - __cpp_lib_constexpr_bitset 202207L [C++23] - __cpp_lib_constexpr_charconv 202207L [C++23] - __cpp_lib_constexpr_cmath 202202L [C++23] - __cpp_lib_constexpr_complex 201711L [C++20] - __cpp_lib_constexpr_dynamic_alloc 201907L [C++20] - __cpp_lib_constexpr_functional 201907L [C++20] - __cpp_lib_constexpr_iterator 201811L [C++20] - __cpp_lib_constexpr_memory 201811L [C++20] - 202202L [C++23] - __cpp_lib_constexpr_new 202406L [C++26] - __cpp_lib_constexpr_numeric 201911L [C++20] - __cpp_lib_constexpr_string 201907L [C++20] - __cpp_lib_constexpr_string_view 201811L [C++20] - __cpp_lib_constexpr_tuple 201811L [C++20] - __cpp_lib_constexpr_typeinfo 202106L [C++23] - __cpp_lib_constexpr_utility 201811L [C++20] - __cpp_lib_constexpr_vector 201907L [C++20] - __cpp_lib_constrained_equality 202403L [C++26] - __cpp_lib_containers_ranges 202202L [C++23] - __cpp_lib_copyable_function 202306L [C++26] - __cpp_lib_coroutine 201902L [C++20] - __cpp_lib_debugging 202311L [C++26] - __cpp_lib_default_template_type_for_algorithm_values 202403L [C++26] - __cpp_lib_destroying_delete 201806L [C++20] - __cpp_lib_enable_shared_from_this 201603L [C++17] - __cpp_lib_endian 201907L [C++20] - __cpp_lib_erase_if 202002L [C++20] - __cpp_lib_exchange_function 201304L [C++14] - __cpp_lib_execution 201603L [C++17] - 201902L [C++20] - __cpp_lib_expected 202211L [C++23] - __cpp_lib_filesystem 201703L [C++17] - __cpp_lib_flat_map 202207L [C++23] - __cpp_lib_flat_set 202207L [C++23] - __cpp_lib_format 202110L [C++20] - __cpp_lib_format_path 202403L [C++26] - __cpp_lib_format_ranges 202207L [C++23] - __cpp_lib_format_uchar 202311L [C++20] - __cpp_lib_formatters 202302L [C++23] - __cpp_lib_forward_like 202207L [C++23] - __cpp_lib_freestanding_algorithm 202311L [C++26] - __cpp_lib_freestanding_array 202311L [C++26] - __cpp_lib_freestanding_cstring 202306L [C++26] - __cpp_lib_freestanding_expected 202311L [C++26] - __cpp_lib_freestanding_mdspan 202311L [C++26] - __cpp_lib_freestanding_optional 202311L [C++26] - __cpp_lib_freestanding_string_view 202311L [C++26] - __cpp_lib_freestanding_variant 202311L [C++26] - __cpp_lib_fstream_native_handle 202306L [C++26] - __cpp_lib_function_ref 202306L [C++26] - __cpp_lib_gcd_lcm 201606L [C++17] - __cpp_lib_generate_random 202403L [C++26] - __cpp_lib_generic_associative_lookup 201304L [C++14] - __cpp_lib_generic_unordered_lookup 201811L [C++20] - __cpp_lib_hardware_interference_size 201703L [C++17] - __cpp_lib_has_unique_object_representations 201606L [C++17] - __cpp_lib_hazard_pointer 202306L [C++26] - __cpp_lib_hypot 201603L [C++17] - __cpp_lib_incomplete_container_elements 201505L [C++17] - __cpp_lib_inplace_vector 202406L [C++26] - __cpp_lib_int_pow2 202002L [C++20] - __cpp_lib_integer_comparison_functions 202002L [C++20] - __cpp_lib_integer_sequence 201304L [C++14] - __cpp_lib_integral_constant_callable 201304L [C++14] - __cpp_lib_interpolate 201902L [C++20] - __cpp_lib_invoke 201411L [C++17] - __cpp_lib_invoke_r 202106L [C++23] - __cpp_lib_ios_noreplace 202207L [C++23] - __cpp_lib_is_aggregate 201703L [C++17] - __cpp_lib_is_constant_evaluated 201811L [C++20] - __cpp_lib_is_final 201402L [C++14] - __cpp_lib_is_implicit_lifetime 202302L [C++23] - __cpp_lib_is_invocable 201703L [C++17] - __cpp_lib_is_layout_compatible 201907L [C++20] - __cpp_lib_is_nothrow_convertible 201806L [C++20] - __cpp_lib_is_null_pointer 201309L [C++14] - __cpp_lib_is_pointer_interconvertible 201907L [C++20] - __cpp_lib_is_scoped_enum 202011L [C++23] - __cpp_lib_is_swappable 201603L [C++17] - __cpp_lib_is_virtual_base_of 202406L [C++26] - __cpp_lib_is_within_lifetime 202306L [C++26] - __cpp_lib_jthread 201911L [C++20] - __cpp_lib_latch 201907L [C++20] - __cpp_lib_launder 201606L [C++17] - __cpp_lib_linalg 202311L [C++26] - __cpp_lib_list_remove_return_type 201806L [C++20] - __cpp_lib_logical_traits 201510L [C++17] - __cpp_lib_make_from_tuple 201606L [C++17] - __cpp_lib_make_reverse_iterator 201402L [C++14] - __cpp_lib_make_unique 201304L [C++14] - __cpp_lib_map_try_emplace 201411L [C++17] - __cpp_lib_math_constants 201907L [C++20] - __cpp_lib_math_special_functions 201603L [C++17] - __cpp_lib_mdspan 202207L [C++23] - 202406L [C++26] - __cpp_lib_memory_resource 201603L [C++17] - __cpp_lib_modules 202207L [C++23] - __cpp_lib_move_iterator_concept 202207L [C++20] - __cpp_lib_move_only_function 202110L [C++23] - __cpp_lib_node_extract 201606L [C++17] - __cpp_lib_nonmember_container_access 201411L [C++17] - __cpp_lib_not_fn 201603L [C++17] - 202306L [C++26] - __cpp_lib_null_iterators 201304L [C++14] - __cpp_lib_optional 201606L [C++17] - 202106L [C++20] - 202110L [C++23] - __cpp_lib_optional_range_support 202406L [C++26] - __cpp_lib_out_ptr 202106L [C++23] - 202311L [C++26] - __cpp_lib_parallel_algorithm 201603L [C++17] - __cpp_lib_philox_engine 202406L [C++26] - __cpp_lib_polymorphic_allocator 201902L [C++20] - __cpp_lib_print 202207L [C++23] - __cpp_lib_quoted_string_io 201304L [C++14] - __cpp_lib_ranges 202110L [C++20] - 202406L [C++23] - __cpp_lib_ranges_as_const 202207L [C++23] - __cpp_lib_ranges_as_rvalue 202207L [C++23] - __cpp_lib_ranges_chunk 202202L [C++23] - __cpp_lib_ranges_chunk_by 202202L [C++23] - __cpp_lib_ranges_concat 202403L [C++26] - __cpp_lib_ranges_contains 202207L [C++23] - __cpp_lib_ranges_find_last 202207L [C++23] - __cpp_lib_ranges_iota 202202L [C++23] - __cpp_lib_ranges_join_with 202202L [C++23] - __cpp_lib_ranges_repeat 202207L [C++23] - __cpp_lib_ranges_slide 202202L [C++23] - __cpp_lib_ranges_starts_ends_with 202106L [C++23] - __cpp_lib_ranges_stride 202207L [C++23] - __cpp_lib_ranges_to_container 202202L [C++23] - __cpp_lib_ranges_zip 202110L [C++23] - __cpp_lib_ratio 202306L [C++26] - __cpp_lib_raw_memory_algorithms 201606L [C++17] - __cpp_lib_rcu 202306L [C++26] - __cpp_lib_reference_from_temporary 202202L [C++23] - __cpp_lib_reference_wrapper 202403L [C++26] - __cpp_lib_remove_cvref 201711L [C++20] - __cpp_lib_result_of_sfinae 201210L [C++14] - __cpp_lib_robust_nonmodifying_seq_ops 201304L [C++14] - __cpp_lib_sample 201603L [C++17] - __cpp_lib_saturation_arithmetic 202311L [C++26] - __cpp_lib_scoped_lock 201703L [C++17] - __cpp_lib_semaphore 201907L [C++20] - __cpp_lib_senders 202406L [C++26] - __cpp_lib_shared_mutex 201505L [C++17] - __cpp_lib_shared_ptr_arrays 201611L [C++17] - 201707L [C++20] - __cpp_lib_shared_ptr_weak_type 201606L [C++17] - __cpp_lib_shared_timed_mutex 201402L [C++14] - __cpp_lib_shift 201806L [C++20] - __cpp_lib_smart_ptr_for_overwrite 202002L [C++20] - __cpp_lib_smart_ptr_owner_equality 202306L [C++26] - __cpp_lib_source_location 201907L [C++20] - __cpp_lib_span 202002L [C++20] - __cpp_lib_span_at 202311L [C++26] - __cpp_lib_span_initializer_list 202311L [C++26] - __cpp_lib_spanstream 202106L [C++23] - __cpp_lib_ssize 201902L [C++20] - __cpp_lib_sstream_from_string_view 202306L [C++26] - __cpp_lib_stacktrace 202011L [C++23] - __cpp_lib_starts_ends_with 201711L [C++20] - __cpp_lib_stdatomic_h 202011L [C++23] - __cpp_lib_string_contains 202011L [C++23] - __cpp_lib_string_resize_and_overwrite 202110L [C++23] - __cpp_lib_string_udls 201304L [C++14] - __cpp_lib_string_view 201606L [C++17] - 201803L [C++20] - 202403L [C++26] - __cpp_lib_submdspan 202306L [C++26] - __cpp_lib_syncbuf 201803L [C++20] - __cpp_lib_text_encoding 202306L [C++26] - __cpp_lib_three_way_comparison 201907L [C++20] - __cpp_lib_to_address 201711L [C++20] - __cpp_lib_to_array 201907L [C++20] - __cpp_lib_to_chars 201611L [C++17] - 202306L [C++26] - __cpp_lib_to_string 202306L [C++26] - __cpp_lib_to_underlying 202102L [C++23] - __cpp_lib_transformation_trait_aliases 201304L [C++14] - __cpp_lib_transparent_operators 201210L [C++14] - 201510L [C++17] - __cpp_lib_tuple_element_t 201402L [C++14] - __cpp_lib_tuple_like 202207L [C++23] - 202311L [C++26] - __cpp_lib_tuples_by_type 201304L [C++14] - __cpp_lib_type_identity 201806L [C++20] - __cpp_lib_type_trait_variable_templates 201510L [C++17] - __cpp_lib_uncaught_exceptions 201411L [C++17] - __cpp_lib_unordered_map_try_emplace 201411L [C++17] - __cpp_lib_unreachable 202202L [C++23] - __cpp_lib_unwrap_ref 201811L [C++20] - __cpp_lib_variant 202102L [C++17] - 202106L [C++20] - 202306L [C++26] - __cpp_lib_void_t 201411L [C++17] -*/ +// clang-format off #include #include "test_macros.h" @@ -917,18 +680,18 @@ # error "__cpp_lib_ranges_repeat should not be defined before c++23" # endif -# ifdef __cpp_lib_ranges_stride -# error "__cpp_lib_ranges_stride should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should not be defined before c++23" -# endif +# ifdef __cpp_lib_ranges_slide +# error "__cpp_lib_ranges_slide should not be defined before c++23" +# endif # ifdef __cpp_lib_ranges_starts_ends_with # error "__cpp_lib_ranges_starts_ends_with should not be defined before c++23" # endif +# ifdef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should not be defined before c++23" +# endif + # ifdef __cpp_lib_ranges_to_container # error "__cpp_lib_ranges_to_container should not be defined before c++23" # endif @@ -1449,6865 +1212,6887 @@ # error "__cpp_lib_endian should not be defined before c++20" # endif -# ifndef __cpp_lib_exchange_function -# error "__cpp_lib_exchange_function should be defined in c++14" -# endif -# if __cpp_lib_exchange_function != 201304L -# error "__cpp_lib_exchange_function should have the value 201304L in c++14" -# endif +# ifdef __cpp_lib_erase_if +# error "__cpp_lib_erase_if should not be defined before c++20" +# endif + +# ifndef __cpp_lib_exchange_function +# error "__cpp_lib_exchange_function should be defined in c++14" +# endif +# if __cpp_lib_exchange_function != 201304L +# error "__cpp_lib_exchange_function should have the value 201304L in c++14" +# endif -# ifdef __cpp_lib_execution -# error "__cpp_lib_execution should not be defined before c++17" -# endif +# ifdef __cpp_lib_execution +# error "__cpp_lib_execution should not be defined before c++17" +# endif -# ifdef __cpp_lib_expected -# error "__cpp_lib_expected should not be defined before c++23" -# endif +# ifdef __cpp_lib_expected +# error "__cpp_lib_expected should not be defined before c++23" +# endif -# ifdef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should not be defined before c++17" -# endif +# ifdef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should not be defined before c++17" +# endif -# ifdef __cpp_lib_flat_map -# error "__cpp_lib_flat_map should not be defined before c++23" -# endif +# ifdef __cpp_lib_flat_map +# error "__cpp_lib_flat_map should not be defined before c++23" +# endif -# ifdef __cpp_lib_flat_set -# error "__cpp_lib_flat_set should not be defined before c++23" -# endif +# ifdef __cpp_lib_flat_set +# error "__cpp_lib_flat_set should not be defined before c++23" +# endif -# ifdef __cpp_lib_format -# error "__cpp_lib_format should not be defined before c++20" -# endif +# ifdef __cpp_lib_format +# error "__cpp_lib_format should not be defined before c++20" +# endif -# ifdef __cpp_lib_format_path -# error "__cpp_lib_format_path should not be defined before c++26" -# endif +# ifdef __cpp_lib_format_path +# error "__cpp_lib_format_path should not be defined before c++26" +# endif -# ifdef __cpp_lib_format_ranges -# error "__cpp_lib_format_ranges should not be defined before c++23" -# endif +# ifdef __cpp_lib_format_ranges +# error "__cpp_lib_format_ranges should not be defined before c++23" +# endif -# ifdef __cpp_lib_format_uchar -# error "__cpp_lib_format_uchar should not be defined before c++20" -# endif +# ifdef __cpp_lib_format_uchar +# error "__cpp_lib_format_uchar should not be defined before c++20" +# endif -# ifdef __cpp_lib_formatters -# error "__cpp_lib_formatters should not be defined before c++23" -# endif - -# ifdef __cpp_lib_forward_like -# error "__cpp_lib_forward_like should not be defined before c++23" -# endif - -# ifdef __cpp_lib_freestanding_algorithm -# error "__cpp_lib_freestanding_algorithm should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_array -# error "__cpp_lib_freestanding_array should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_cstring -# error "__cpp_lib_freestanding_cstring should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_expected -# error "__cpp_lib_freestanding_expected should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_mdspan -# error "__cpp_lib_freestanding_mdspan should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_optional -# error "__cpp_lib_freestanding_optional should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_string_view -# error "__cpp_lib_freestanding_string_view should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_variant -# error "__cpp_lib_freestanding_variant should not be defined before c++26" -# endif - -# ifdef __cpp_lib_fstream_native_handle -# error "__cpp_lib_fstream_native_handle should not be defined before c++26" -# endif - -# ifdef __cpp_lib_function_ref -# error "__cpp_lib_function_ref should not be defined before c++26" -# endif - -# ifdef __cpp_lib_gcd_lcm -# error "__cpp_lib_gcd_lcm should not be defined before c++17" -# endif - -# ifdef __cpp_lib_generate_random -# error "__cpp_lib_generate_random should not be defined before c++26" -# endif - -# ifndef __cpp_lib_generic_associative_lookup -# error "__cpp_lib_generic_associative_lookup should be defined in c++14" -# endif -# if __cpp_lib_generic_associative_lookup != 201304L -# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++14" -# endif - -# ifdef __cpp_lib_generic_unordered_lookup -# error "__cpp_lib_generic_unordered_lookup should not be defined before c++20" -# endif - -# ifdef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should not be defined before c++17" -# endif - -# ifdef __cpp_lib_has_unique_object_representations -# error "__cpp_lib_has_unique_object_representations should not be defined before c++17" -# endif - -# ifdef __cpp_lib_hazard_pointer -# error "__cpp_lib_hazard_pointer should not be defined before c++26" -# endif - -# ifdef __cpp_lib_hypot -# error "__cpp_lib_hypot should not be defined before c++17" -# endif - -# ifdef __cpp_lib_incomplete_container_elements -# error "__cpp_lib_incomplete_container_elements should not be defined before c++17" -# endif - -# ifdef __cpp_lib_inplace_vector -# error "__cpp_lib_inplace_vector should not be defined before c++26" -# endif - -# ifdef __cpp_lib_int_pow2 -# error "__cpp_lib_int_pow2 should not be defined before c++20" -# endif - -# ifdef __cpp_lib_integer_comparison_functions -# error "__cpp_lib_integer_comparison_functions should not be defined before c++20" -# endif - -# ifndef __cpp_lib_integer_sequence -# error "__cpp_lib_integer_sequence should be defined in c++14" -# endif -# if __cpp_lib_integer_sequence != 201304L -# error "__cpp_lib_integer_sequence should have the value 201304L in c++14" -# endif - -# ifndef __cpp_lib_integral_constant_callable -# error "__cpp_lib_integral_constant_callable should be defined in c++14" -# endif -# if __cpp_lib_integral_constant_callable != 201304L -# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++14" -# endif - -# ifdef __cpp_lib_interpolate -# error "__cpp_lib_interpolate should not be defined before c++20" -# endif - -# ifdef __cpp_lib_invoke -# error "__cpp_lib_invoke should not be defined before c++17" -# endif - -# ifdef __cpp_lib_invoke_r -# error "__cpp_lib_invoke_r should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ios_noreplace -# error "__cpp_lib_ios_noreplace should not be defined before c++23" -# endif - -# ifdef __cpp_lib_is_aggregate -# error "__cpp_lib_is_aggregate should not be defined before c++17" -# endif - -# ifdef __cpp_lib_is_constant_evaluated -# error "__cpp_lib_is_constant_evaluated should not be defined before c++20" -# endif - -# ifndef __cpp_lib_is_final -# error "__cpp_lib_is_final should be defined in c++14" -# endif -# if __cpp_lib_is_final != 201402L -# error "__cpp_lib_is_final should have the value 201402L in c++14" -# endif - -# ifdef __cpp_lib_is_implicit_lifetime -# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" -# endif - -# ifdef __cpp_lib_is_invocable -# error "__cpp_lib_is_invocable should not be defined before c++17" -# endif - -# ifdef __cpp_lib_is_layout_compatible -# error "__cpp_lib_is_layout_compatible should not be defined before c++20" -# endif - -# ifdef __cpp_lib_is_nothrow_convertible -# error "__cpp_lib_is_nothrow_convertible should not be defined before c++20" -# endif - -# ifndef __cpp_lib_is_null_pointer -# error "__cpp_lib_is_null_pointer should be defined in c++14" -# endif -# if __cpp_lib_is_null_pointer != 201309L -# error "__cpp_lib_is_null_pointer should have the value 201309L in c++14" -# endif - -# ifdef __cpp_lib_is_pointer_interconvertible -# error "__cpp_lib_is_pointer_interconvertible should not be defined before c++20" -# endif - -# ifdef __cpp_lib_is_scoped_enum -# error "__cpp_lib_is_scoped_enum should not be defined before c++23" -# endif - -# ifdef __cpp_lib_is_swappable -# error "__cpp_lib_is_swappable should not be defined before c++17" -# endif - -# ifdef __cpp_lib_is_virtual_base_of -# error "__cpp_lib_is_virtual_base_of should not be defined before c++26" -# endif - -# ifdef __cpp_lib_is_within_lifetime -# error "__cpp_lib_is_within_lifetime should not be defined before c++26" -# endif - -# ifdef __cpp_lib_jthread -# error "__cpp_lib_jthread should not be defined before c++20" -# endif - -# ifdef __cpp_lib_latch -# error "__cpp_lib_latch should not be defined before c++20" -# endif - -# ifdef __cpp_lib_launder -# error "__cpp_lib_launder should not be defined before c++17" -# endif - -# ifdef __cpp_lib_linalg -# error "__cpp_lib_linalg should not be defined before c++26" -# endif - -# ifdef __cpp_lib_list_remove_return_type -# error "__cpp_lib_list_remove_return_type should not be defined before c++20" -# endif - -# ifdef __cpp_lib_logical_traits -# error "__cpp_lib_logical_traits should not be defined before c++17" -# endif - -# ifdef __cpp_lib_make_from_tuple -# error "__cpp_lib_make_from_tuple should not be defined before c++17" -# endif - -# ifndef __cpp_lib_make_reverse_iterator -# error "__cpp_lib_make_reverse_iterator should be defined in c++14" -# endif -# if __cpp_lib_make_reverse_iterator != 201402L -# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++14" -# endif - -# ifndef __cpp_lib_make_unique -# error "__cpp_lib_make_unique should be defined in c++14" -# endif -# if __cpp_lib_make_unique != 201304L -# error "__cpp_lib_make_unique should have the value 201304L in c++14" -# endif - -# ifdef __cpp_lib_map_try_emplace -# error "__cpp_lib_map_try_emplace should not be defined before c++17" -# endif - -# ifdef __cpp_lib_math_constants -# error "__cpp_lib_math_constants should not be defined before c++20" -# endif - -# ifdef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should not be defined before c++17" -# endif - -# ifdef __cpp_lib_mdspan -# error "__cpp_lib_mdspan should not be defined before c++23" -# endif - -# ifdef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should not be defined before c++17" -# endif - -# ifdef __cpp_lib_modules -# error "__cpp_lib_modules should not be defined before c++23" -# endif - -# ifdef __cpp_lib_move_iterator_concept -# error "__cpp_lib_move_iterator_concept should not be defined before c++20" -# endif - -# ifdef __cpp_lib_move_only_function -# error "__cpp_lib_move_only_function should not be defined before c++23" -# endif - -# ifdef __cpp_lib_node_extract -# error "__cpp_lib_node_extract should not be defined before c++17" -# endif - -# ifdef __cpp_lib_nonmember_container_access -# error "__cpp_lib_nonmember_container_access should not be defined before c++17" -# endif - -# ifdef __cpp_lib_not_fn -# error "__cpp_lib_not_fn should not be defined before c++17" -# endif - -# ifndef __cpp_lib_null_iterators -# error "__cpp_lib_null_iterators should be defined in c++14" -# endif -# if __cpp_lib_null_iterators != 201304L -# error "__cpp_lib_null_iterators should have the value 201304L in c++14" -# endif - -# ifdef __cpp_lib_optional -# error "__cpp_lib_optional should not be defined before c++17" -# endif - -# ifdef __cpp_lib_optional_range_support -# error "__cpp_lib_optional_range_support should not be defined before c++26" -# endif - -# ifdef __cpp_lib_out_ptr -# error "__cpp_lib_out_ptr should not be defined before c++23" -# endif - -# ifdef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should not be defined before c++17" -# endif - -# ifdef __cpp_lib_philox_engine -# error "__cpp_lib_philox_engine should not be defined before c++26" -# endif - -# ifdef __cpp_lib_polymorphic_allocator -# error "__cpp_lib_polymorphic_allocator should not be defined before c++20" -# endif - -# ifdef __cpp_lib_print -# error "__cpp_lib_print should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION -# ifndef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should be defined in c++14" -# endif -# if __cpp_lib_quoted_string_io != 201304L -# error "__cpp_lib_quoted_string_io should have the value 201304L in c++14" -# endif -# else -# ifdef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" -# endif -# endif - -# ifdef __cpp_lib_ranges -# error "__cpp_lib_ranges should not be defined before c++20" -# endif - -# ifdef __cpp_lib_ranges_as_const -# error "__cpp_lib_ranges_as_const should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_as_rvalue -# error "__cpp_lib_ranges_as_rvalue should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_chunk_by -# error "__cpp_lib_ranges_chunk_by should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_concat -# error "__cpp_lib_ranges_concat should not be defined before c++26" -# endif - -# ifdef __cpp_lib_ranges_contains -# error "__cpp_lib_ranges_contains should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_find_last -# error "__cpp_lib_ranges_find_last should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_iota -# error "__cpp_lib_ranges_iota should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_join_with -# error "__cpp_lib_ranges_join_with should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_repeat -# error "__cpp_lib_ranges_repeat should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_slide -# error "__cpp_lib_ranges_slide should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_starts_ends_with -# error "__cpp_lib_ranges_starts_ends_with should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_stride -# error "__cpp_lib_ranges_stride should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_zip -# error "__cpp_lib_ranges_zip should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ratio -# error "__cpp_lib_ratio should not be defined before c++26" -# endif - -# ifdef __cpp_lib_raw_memory_algorithms -# error "__cpp_lib_raw_memory_algorithms should not be defined before c++17" -# endif - -# ifdef __cpp_lib_rcu -# error "__cpp_lib_rcu should not be defined before c++26" -# endif - -# ifdef __cpp_lib_reference_from_temporary -# error "__cpp_lib_reference_from_temporary should not be defined before c++23" -# endif - -# ifdef __cpp_lib_reference_wrapper -# error "__cpp_lib_reference_wrapper should not be defined before c++26" -# endif - -# ifdef __cpp_lib_remove_cvref -# error "__cpp_lib_remove_cvref should not be defined before c++20" -# endif - -# ifndef __cpp_lib_result_of_sfinae -# error "__cpp_lib_result_of_sfinae should be defined in c++14" -# endif -# if __cpp_lib_result_of_sfinae != 201210L -# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++14" -# endif - -# ifndef __cpp_lib_robust_nonmodifying_seq_ops -# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++14" -# endif -# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L -# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++14" -# endif - -# ifdef __cpp_lib_sample -# error "__cpp_lib_sample should not be defined before c++17" -# endif - -# ifdef __cpp_lib_saturation_arithmetic -# error "__cpp_lib_saturation_arithmetic should not be defined before c++26" -# endif - -# ifdef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should not be defined before c++17" -# endif - -# ifdef __cpp_lib_semaphore -# error "__cpp_lib_semaphore should not be defined before c++20" -# endif - -# ifdef __cpp_lib_senders -# error "__cpp_lib_senders should not be defined before c++26" -# endif - -# ifdef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should not be defined before c++17" -# endif - -# ifdef __cpp_lib_shared_ptr_arrays -# error "__cpp_lib_shared_ptr_arrays should not be defined before c++17" -# endif - -# ifdef __cpp_lib_shared_ptr_weak_type -# error "__cpp_lib_shared_ptr_weak_type should not be defined before c++17" -# endif - -# if _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should be defined in c++14" -# endif -# if __cpp_lib_shared_timed_mutex != 201402L -# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++14" -# endif -# else -# ifdef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifdef __cpp_lib_shift -# error "__cpp_lib_shift should not be defined before c++20" -# endif - -# ifdef __cpp_lib_smart_ptr_for_overwrite -# error "__cpp_lib_smart_ptr_for_overwrite should not be defined before c++20" -# endif - -# ifdef __cpp_lib_smart_ptr_owner_equality -# error "__cpp_lib_smart_ptr_owner_equality should not be defined before c++26" -# endif - -# ifdef __cpp_lib_source_location -# error "__cpp_lib_source_location should not be defined before c++20" -# endif - -# ifdef __cpp_lib_span -# error "__cpp_lib_span should not be defined before c++20" -# endif - -# ifdef __cpp_lib_span_at -# error "__cpp_lib_span_at should not be defined before c++26" -# endif - -# ifdef __cpp_lib_span_initializer_list -# error "__cpp_lib_span_initializer_list should not be defined before c++26" -# endif - -# ifdef __cpp_lib_spanstream -# error "__cpp_lib_spanstream should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ssize -# error "__cpp_lib_ssize should not be defined before c++20" -# endif - -# ifdef __cpp_lib_sstream_from_string_view -# error "__cpp_lib_sstream_from_string_view should not be defined before c++26" -# endif - -# ifdef __cpp_lib_stacktrace -# error "__cpp_lib_stacktrace should not be defined before c++23" -# endif - -# ifdef __cpp_lib_starts_ends_with -# error "__cpp_lib_starts_ends_with should not be defined before c++20" -# endif - -# ifdef __cpp_lib_stdatomic_h -# error "__cpp_lib_stdatomic_h should not be defined before c++23" -# endif - -# ifdef __cpp_lib_string_contains -# error "__cpp_lib_string_contains should not be defined before c++23" -# endif - -# ifdef __cpp_lib_string_resize_and_overwrite -# error "__cpp_lib_string_resize_and_overwrite should not be defined before c++23" -# endif - -# ifndef __cpp_lib_string_udls -# error "__cpp_lib_string_udls should be defined in c++14" -# endif -# if __cpp_lib_string_udls != 201304L -# error "__cpp_lib_string_udls should have the value 201304L in c++14" -# endif - -# ifdef __cpp_lib_string_view -# error "__cpp_lib_string_view should not be defined before c++17" -# endif - -# ifdef __cpp_lib_submdspan -# error "__cpp_lib_submdspan should not be defined before c++26" -# endif - -# ifdef __cpp_lib_syncbuf -# error "__cpp_lib_syncbuf should not be defined before c++20" -# endif - -# ifdef __cpp_lib_text_encoding -# error "__cpp_lib_text_encoding should not be defined before c++26" -# endif - -# ifdef __cpp_lib_three_way_comparison -# error "__cpp_lib_three_way_comparison should not be defined before c++20" -# endif - -# ifdef __cpp_lib_to_address -# error "__cpp_lib_to_address should not be defined before c++20" -# endif - -# ifdef __cpp_lib_to_array -# error "__cpp_lib_to_array should not be defined before c++20" -# endif - -# ifdef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should not be defined before c++17" -# endif - -# ifdef __cpp_lib_to_string -# error "__cpp_lib_to_string should not be defined before c++26" -# endif - -# ifdef __cpp_lib_to_underlying -# error "__cpp_lib_to_underlying should not be defined before c++23" -# endif - -# ifndef __cpp_lib_transformation_trait_aliases -# error "__cpp_lib_transformation_trait_aliases should be defined in c++14" -# endif -# if __cpp_lib_transformation_trait_aliases != 201304L -# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++14" -# endif - -# ifndef __cpp_lib_transparent_operators -# error "__cpp_lib_transparent_operators should be defined in c++14" -# endif -# if __cpp_lib_transparent_operators != 201210L -# error "__cpp_lib_transparent_operators should have the value 201210L in c++14" -# endif - -# ifndef __cpp_lib_tuple_element_t -# error "__cpp_lib_tuple_element_t should be defined in c++14" -# endif -# if __cpp_lib_tuple_element_t != 201402L -# error "__cpp_lib_tuple_element_t should have the value 201402L in c++14" -# endif - -# ifdef __cpp_lib_tuple_like -# error "__cpp_lib_tuple_like should not be defined before c++23" -# endif - -# ifndef __cpp_lib_tuples_by_type -# error "__cpp_lib_tuples_by_type should be defined in c++14" -# endif -# if __cpp_lib_tuples_by_type != 201304L -# error "__cpp_lib_tuples_by_type should have the value 201304L in c++14" -# endif - -# ifdef __cpp_lib_type_identity -# error "__cpp_lib_type_identity should not be defined before c++20" -# endif - -# ifdef __cpp_lib_type_trait_variable_templates -# error "__cpp_lib_type_trait_variable_templates should not be defined before c++17" -# endif - -# ifdef __cpp_lib_uncaught_exceptions -# error "__cpp_lib_uncaught_exceptions should not be defined before c++17" -# endif - -# ifdef __cpp_lib_unordered_map_try_emplace -# error "__cpp_lib_unordered_map_try_emplace should not be defined before c++17" -# endif - -# ifdef __cpp_lib_unreachable -# error "__cpp_lib_unreachable should not be defined before c++23" -# endif - -# ifdef __cpp_lib_unwrap_ref -# error "__cpp_lib_unwrap_ref should not be defined before c++20" -# endif - -# ifdef __cpp_lib_variant -# error "__cpp_lib_variant should not be defined before c++17" -# endif - -# ifdef __cpp_lib_void_t -# error "__cpp_lib_void_t should not be defined before c++17" -# endif +# ifdef __cpp_lib_formatters +# error "__cpp_lib_formatters should not be defined before c++23" +# endif -#elif TEST_STD_VER == 17 +# ifdef __cpp_lib_forward_like +# error "__cpp_lib_forward_like should not be defined before c++23" +# endif -# ifdef __cpp_lib_adaptor_iterator_pair_constructor -# error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++23" -# endif - -# ifndef __cpp_lib_addressof_constexpr -# error "__cpp_lib_addressof_constexpr should be defined in c++17" -# endif -# if __cpp_lib_addressof_constexpr != 201603L -# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++17" -# endif - -# ifdef __cpp_lib_allocate_at_least -# error "__cpp_lib_allocate_at_least should not be defined before c++23" -# endif - -# ifndef __cpp_lib_allocator_traits_is_always_equal -# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++17" -# endif -# if __cpp_lib_allocator_traits_is_always_equal != 201411L -# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17" -# endif - -# ifndef __cpp_lib_any -# error "__cpp_lib_any should be defined in c++17" -# endif -# if __cpp_lib_any != 201606L -# error "__cpp_lib_any should have the value 201606L in c++17" -# endif - -# ifndef __cpp_lib_apply -# error "__cpp_lib_apply should be defined in c++17" -# endif -# if __cpp_lib_apply != 201603L -# error "__cpp_lib_apply should have the value 201603L in c++17" -# endif - -# ifndef __cpp_lib_array_constexpr -# error "__cpp_lib_array_constexpr should be defined in c++17" -# endif -# if __cpp_lib_array_constexpr != 201603L -# error "__cpp_lib_array_constexpr should have the value 201603L in c++17" -# endif - -# ifndef __cpp_lib_as_const -# error "__cpp_lib_as_const should be defined in c++17" -# endif -# if __cpp_lib_as_const != 201510L -# error "__cpp_lib_as_const should have the value 201510L in c++17" -# endif - -# ifdef __cpp_lib_associative_heterogeneous_erasure -# error "__cpp_lib_associative_heterogeneous_erasure should not be defined before c++23" -# endif - -# ifdef __cpp_lib_associative_heterogeneous_insertion -# error "__cpp_lib_associative_heterogeneous_insertion should not be defined before c++26" -# endif - -# ifdef __cpp_lib_assume_aligned -# error "__cpp_lib_assume_aligned should not be defined before c++20" -# endif - -# ifdef __cpp_lib_atomic_flag_test -# error "__cpp_lib_atomic_flag_test should not be defined before c++20" -# endif - -# ifdef __cpp_lib_atomic_float -# error "__cpp_lib_atomic_float should not be defined before c++20" -# endif - -# ifndef __cpp_lib_atomic_is_always_lock_free -# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++17" -# endif -# if __cpp_lib_atomic_is_always_lock_free != 201603L -# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++17" -# endif - -# ifdef __cpp_lib_atomic_lock_free_type_aliases -# error "__cpp_lib_atomic_lock_free_type_aliases should not be defined before c++20" -# endif - -# ifdef __cpp_lib_atomic_min_max -# error "__cpp_lib_atomic_min_max should not be defined before c++26" -# endif - -# ifdef __cpp_lib_atomic_ref -# error "__cpp_lib_atomic_ref should not be defined before c++20" -# endif - -# ifdef __cpp_lib_atomic_shared_ptr -# error "__cpp_lib_atomic_shared_ptr should not be defined before c++20" -# endif - -# ifdef __cpp_lib_atomic_value_initialization -# error "__cpp_lib_atomic_value_initialization should not be defined before c++20" -# endif - -# ifdef __cpp_lib_atomic_wait -# error "__cpp_lib_atomic_wait should not be defined before c++20" -# endif - -# ifdef __cpp_lib_barrier -# error "__cpp_lib_barrier should not be defined before c++20" -# endif - -# ifdef __cpp_lib_bind_back -# error "__cpp_lib_bind_back should not be defined before c++23" -# endif - -# ifdef __cpp_lib_bind_front -# error "__cpp_lib_bind_front should not be defined before c++20" -# endif - -# ifdef __cpp_lib_bit_cast -# error "__cpp_lib_bit_cast should not be defined before c++20" -# endif - -# ifdef __cpp_lib_bitops -# error "__cpp_lib_bitops should not be defined before c++20" -# endif - -# ifdef __cpp_lib_bitset -# error "__cpp_lib_bitset should not be defined before c++26" -# endif - -# ifndef __cpp_lib_bool_constant -# error "__cpp_lib_bool_constant should be defined in c++17" -# endif -# if __cpp_lib_bool_constant != 201505L -# error "__cpp_lib_bool_constant should have the value 201505L in c++17" -# endif - -# ifdef __cpp_lib_bounded_array_traits -# error "__cpp_lib_bounded_array_traits should not be defined before c++20" -# endif - -# ifndef __cpp_lib_boyer_moore_searcher -# error "__cpp_lib_boyer_moore_searcher should be defined in c++17" -# endif -# if __cpp_lib_boyer_moore_searcher != 201603L -# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++17" -# endif - -# ifndef __cpp_lib_byte -# error "__cpp_lib_byte should be defined in c++17" -# endif -# if __cpp_lib_byte != 201603L -# error "__cpp_lib_byte should have the value 201603L in c++17" -# endif - -# ifdef __cpp_lib_byteswap -# error "__cpp_lib_byteswap should not be defined before c++23" -# endif - -# ifdef __cpp_lib_char8_t -# error "__cpp_lib_char8_t should not be defined before c++20" -# endif - -# ifndef __cpp_lib_chrono -# error "__cpp_lib_chrono should be defined in c++17" -# endif -# if __cpp_lib_chrono != 201611L -# error "__cpp_lib_chrono should have the value 201611L in c++17" -# endif - -# ifndef __cpp_lib_chrono_udls -# error "__cpp_lib_chrono_udls should be defined in c++17" -# endif -# if __cpp_lib_chrono_udls != 201304L -# error "__cpp_lib_chrono_udls should have the value 201304L in c++17" -# endif - -# ifndef __cpp_lib_clamp -# error "__cpp_lib_clamp should be defined in c++17" -# endif -# if __cpp_lib_clamp != 201603L -# error "__cpp_lib_clamp should have the value 201603L in c++17" -# endif - -# ifndef __cpp_lib_complex_udls -# error "__cpp_lib_complex_udls should be defined in c++17" -# endif -# if __cpp_lib_complex_udls != 201309L -# error "__cpp_lib_complex_udls should have the value 201309L in c++17" -# endif - -# ifdef __cpp_lib_concepts -# error "__cpp_lib_concepts should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_algorithms -# error "__cpp_lib_constexpr_algorithms should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_bitset -# error "__cpp_lib_constexpr_bitset should not be defined before c++23" -# endif - -# ifdef __cpp_lib_constexpr_charconv -# error "__cpp_lib_constexpr_charconv should not be defined before c++23" -# endif - -# ifdef __cpp_lib_constexpr_cmath -# error "__cpp_lib_constexpr_cmath should not be defined before c++23" -# endif - -# ifdef __cpp_lib_constexpr_complex -# error "__cpp_lib_constexpr_complex should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_dynamic_alloc -# error "__cpp_lib_constexpr_dynamic_alloc should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_functional -# error "__cpp_lib_constexpr_functional should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_iterator -# error "__cpp_lib_constexpr_iterator should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_memory -# error "__cpp_lib_constexpr_memory should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_new -# error "__cpp_lib_constexpr_new should not be defined before c++26" -# endif - -# ifdef __cpp_lib_constexpr_numeric -# error "__cpp_lib_constexpr_numeric should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_string -# error "__cpp_lib_constexpr_string should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_string_view -# error "__cpp_lib_constexpr_string_view should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_tuple -# error "__cpp_lib_constexpr_tuple should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_typeinfo -# error "__cpp_lib_constexpr_typeinfo should not be defined before c++23" -# endif - -# ifdef __cpp_lib_constexpr_utility -# error "__cpp_lib_constexpr_utility should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constexpr_vector -# error "__cpp_lib_constexpr_vector should not be defined before c++20" -# endif - -# ifdef __cpp_lib_constrained_equality -# error "__cpp_lib_constrained_equality should not be defined before c++26" -# endif - -# ifdef __cpp_lib_containers_ranges -# error "__cpp_lib_containers_ranges should not be defined before c++23" -# endif - -# ifdef __cpp_lib_copyable_function -# error "__cpp_lib_copyable_function should not be defined before c++26" -# endif - -# ifdef __cpp_lib_coroutine -# error "__cpp_lib_coroutine should not be defined before c++20" -# endif - -# ifdef __cpp_lib_debugging -# error "__cpp_lib_debugging should not be defined before c++26" -# endif - -# ifdef __cpp_lib_default_template_type_for_algorithm_values -# error "__cpp_lib_default_template_type_for_algorithm_values should not be defined before c++26" -# endif - -# ifdef __cpp_lib_destroying_delete -# error "__cpp_lib_destroying_delete should not be defined before c++20" -# endif - -# ifndef __cpp_lib_enable_shared_from_this -# error "__cpp_lib_enable_shared_from_this should be defined in c++17" -# endif -# if __cpp_lib_enable_shared_from_this != 201603L -# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++17" -# endif - -# ifdef __cpp_lib_endian -# error "__cpp_lib_endian should not be defined before c++20" -# endif - -# ifdef __cpp_lib_erase_if -# error "__cpp_lib_erase_if should not be defined before c++20" -# endif - -# ifndef __cpp_lib_exchange_function -# error "__cpp_lib_exchange_function should be defined in c++17" -# endif -# if __cpp_lib_exchange_function != 201304L -# error "__cpp_lib_exchange_function should have the value 201304L in c++17" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_execution -# error "__cpp_lib_execution should be defined in c++17" -# endif -# if __cpp_lib_execution != 201603L -# error "__cpp_lib_execution should have the value 201603L in c++17" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_execution -# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_expected -# error "__cpp_lib_expected should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY) -# ifndef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should be defined in c++17" -# endif -# if __cpp_lib_filesystem != 201703L -# error "__cpp_lib_filesystem should have the value 201703L in c++17" -# endif -# else -# ifdef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)' is not met!" -# endif -# endif - -# ifdef __cpp_lib_flat_map -# error "__cpp_lib_flat_map should not be defined before c++23" -# endif - -# ifdef __cpp_lib_flat_set -# error "__cpp_lib_flat_set should not be defined before c++23" -# endif - -# ifdef __cpp_lib_format -# error "__cpp_lib_format should not be defined before c++20" -# endif - -# ifdef __cpp_lib_format_path -# error "__cpp_lib_format_path should not be defined before c++26" -# endif - -# ifdef __cpp_lib_format_ranges -# error "__cpp_lib_format_ranges should not be defined before c++23" -# endif - -# ifdef __cpp_lib_format_uchar -# error "__cpp_lib_format_uchar should not be defined before c++20" -# endif - -# ifdef __cpp_lib_formatters -# error "__cpp_lib_formatters should not be defined before c++23" -# endif - -# ifdef __cpp_lib_forward_like -# error "__cpp_lib_forward_like should not be defined before c++23" -# endif - -# ifdef __cpp_lib_freestanding_algorithm -# error "__cpp_lib_freestanding_algorithm should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_array -# error "__cpp_lib_freestanding_array should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_cstring -# error "__cpp_lib_freestanding_cstring should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_expected -# error "__cpp_lib_freestanding_expected should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_mdspan -# error "__cpp_lib_freestanding_mdspan should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_optional -# error "__cpp_lib_freestanding_optional should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_string_view -# error "__cpp_lib_freestanding_string_view should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_variant -# error "__cpp_lib_freestanding_variant should not be defined before c++26" -# endif - -# ifdef __cpp_lib_fstream_native_handle -# error "__cpp_lib_fstream_native_handle should not be defined before c++26" -# endif - -# ifdef __cpp_lib_function_ref -# error "__cpp_lib_function_ref should not be defined before c++26" -# endif - -# ifndef __cpp_lib_gcd_lcm -# error "__cpp_lib_gcd_lcm should be defined in c++17" -# endif -# if __cpp_lib_gcd_lcm != 201606L -# error "__cpp_lib_gcd_lcm should have the value 201606L in c++17" -# endif - -# ifdef __cpp_lib_generate_random -# error "__cpp_lib_generate_random should not be defined before c++26" -# endif - -# ifndef __cpp_lib_generic_associative_lookup -# error "__cpp_lib_generic_associative_lookup should be defined in c++17" -# endif -# if __cpp_lib_generic_associative_lookup != 201304L -# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++17" -# endif - -# ifdef __cpp_lib_generic_unordered_lookup -# error "__cpp_lib_generic_unordered_lookup should not be defined before c++20" -# endif - -# if !defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)) -# ifndef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should be defined in c++17" -# endif -# if __cpp_lib_hardware_interference_size != 201703L -# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++17" -# endif -# else -# ifdef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))' is not met!" -# endif -# endif - -# ifndef __cpp_lib_has_unique_object_representations -# error "__cpp_lib_has_unique_object_representations should be defined in c++17" -# endif -# if __cpp_lib_has_unique_object_representations != 201606L -# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++17" -# endif - -# ifdef __cpp_lib_hazard_pointer -# error "__cpp_lib_hazard_pointer should not be defined before c++26" -# endif - -# ifndef __cpp_lib_hypot -# error "__cpp_lib_hypot should be defined in c++17" -# endif -# if __cpp_lib_hypot != 201603L -# error "__cpp_lib_hypot should have the value 201603L in c++17" -# endif - -# ifndef __cpp_lib_incomplete_container_elements -# error "__cpp_lib_incomplete_container_elements should be defined in c++17" -# endif -# if __cpp_lib_incomplete_container_elements != 201505L -# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++17" -# endif - -# ifdef __cpp_lib_inplace_vector -# error "__cpp_lib_inplace_vector should not be defined before c++26" -# endif - -# ifdef __cpp_lib_int_pow2 -# error "__cpp_lib_int_pow2 should not be defined before c++20" -# endif - -# ifdef __cpp_lib_integer_comparison_functions -# error "__cpp_lib_integer_comparison_functions should not be defined before c++20" -# endif - -# ifndef __cpp_lib_integer_sequence -# error "__cpp_lib_integer_sequence should be defined in c++17" -# endif -# if __cpp_lib_integer_sequence != 201304L -# error "__cpp_lib_integer_sequence should have the value 201304L in c++17" -# endif - -# ifndef __cpp_lib_integral_constant_callable -# error "__cpp_lib_integral_constant_callable should be defined in c++17" -# endif -# if __cpp_lib_integral_constant_callable != 201304L -# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++17" -# endif - -# ifdef __cpp_lib_interpolate -# error "__cpp_lib_interpolate should not be defined before c++20" -# endif - -# ifndef __cpp_lib_invoke -# error "__cpp_lib_invoke should be defined in c++17" -# endif -# if __cpp_lib_invoke != 201411L -# error "__cpp_lib_invoke should have the value 201411L in c++17" -# endif - -# ifdef __cpp_lib_invoke_r -# error "__cpp_lib_invoke_r should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ios_noreplace -# error "__cpp_lib_ios_noreplace should not be defined before c++23" -# endif - -# ifndef __cpp_lib_is_aggregate -# error "__cpp_lib_is_aggregate should be defined in c++17" -# endif -# if __cpp_lib_is_aggregate != 201703L -# error "__cpp_lib_is_aggregate should have the value 201703L in c++17" -# endif - -# ifdef __cpp_lib_is_constant_evaluated -# error "__cpp_lib_is_constant_evaluated should not be defined before c++20" -# endif - -# ifndef __cpp_lib_is_final -# error "__cpp_lib_is_final should be defined in c++17" -# endif -# if __cpp_lib_is_final != 201402L -# error "__cpp_lib_is_final should have the value 201402L in c++17" -# endif - -# ifdef __cpp_lib_is_implicit_lifetime -# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" -# endif - -# ifndef __cpp_lib_is_invocable -# error "__cpp_lib_is_invocable should be defined in c++17" -# endif -# if __cpp_lib_is_invocable != 201703L -# error "__cpp_lib_is_invocable should have the value 201703L in c++17" -# endif - -# ifdef __cpp_lib_is_layout_compatible -# error "__cpp_lib_is_layout_compatible should not be defined before c++20" -# endif - -# ifdef __cpp_lib_is_nothrow_convertible -# error "__cpp_lib_is_nothrow_convertible should not be defined before c++20" -# endif - -# ifndef __cpp_lib_is_null_pointer -# error "__cpp_lib_is_null_pointer should be defined in c++17" -# endif -# if __cpp_lib_is_null_pointer != 201309L -# error "__cpp_lib_is_null_pointer should have the value 201309L in c++17" -# endif - -# ifdef __cpp_lib_is_pointer_interconvertible -# error "__cpp_lib_is_pointer_interconvertible should not be defined before c++20" -# endif - -# ifdef __cpp_lib_is_scoped_enum -# error "__cpp_lib_is_scoped_enum should not be defined before c++23" -# endif - -# ifndef __cpp_lib_is_swappable -# error "__cpp_lib_is_swappable should be defined in c++17" -# endif -# if __cpp_lib_is_swappable != 201603L -# error "__cpp_lib_is_swappable should have the value 201603L in c++17" -# endif - -# ifdef __cpp_lib_is_virtual_base_of -# error "__cpp_lib_is_virtual_base_of should not be defined before c++26" -# endif - -# ifdef __cpp_lib_is_within_lifetime -# error "__cpp_lib_is_within_lifetime should not be defined before c++26" -# endif - -# ifdef __cpp_lib_jthread -# error "__cpp_lib_jthread should not be defined before c++20" -# endif - -# ifdef __cpp_lib_latch -# error "__cpp_lib_latch should not be defined before c++20" -# endif - -# ifndef __cpp_lib_launder -# error "__cpp_lib_launder should be defined in c++17" -# endif -# if __cpp_lib_launder != 201606L -# error "__cpp_lib_launder should have the value 201606L in c++17" -# endif - -# ifdef __cpp_lib_linalg -# error "__cpp_lib_linalg should not be defined before c++26" -# endif - -# ifdef __cpp_lib_list_remove_return_type -# error "__cpp_lib_list_remove_return_type should not be defined before c++20" -# endif - -# ifndef __cpp_lib_logical_traits -# error "__cpp_lib_logical_traits should be defined in c++17" -# endif -# if __cpp_lib_logical_traits != 201510L -# error "__cpp_lib_logical_traits should have the value 201510L in c++17" -# endif - -# ifndef __cpp_lib_make_from_tuple -# error "__cpp_lib_make_from_tuple should be defined in c++17" -# endif -# if __cpp_lib_make_from_tuple != 201606L -# error "__cpp_lib_make_from_tuple should have the value 201606L in c++17" -# endif - -# ifndef __cpp_lib_make_reverse_iterator -# error "__cpp_lib_make_reverse_iterator should be defined in c++17" -# endif -# if __cpp_lib_make_reverse_iterator != 201402L -# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++17" -# endif - -# ifndef __cpp_lib_make_unique -# error "__cpp_lib_make_unique should be defined in c++17" -# endif -# if __cpp_lib_make_unique != 201304L -# error "__cpp_lib_make_unique should have the value 201304L in c++17" -# endif - -# ifndef __cpp_lib_map_try_emplace -# error "__cpp_lib_map_try_emplace should be defined in c++17" -# endif -# if __cpp_lib_map_try_emplace != 201411L -# error "__cpp_lib_map_try_emplace should have the value 201411L in c++17" -# endif - -# ifdef __cpp_lib_math_constants -# error "__cpp_lib_math_constants should not be defined before c++20" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should be defined in c++17" -# endif -# if __cpp_lib_math_special_functions != 201603L -# error "__cpp_lib_math_special_functions should have the value 201603L in c++17" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_mdspan -# error "__cpp_lib_mdspan should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR -# ifndef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should be defined in c++17" -# endif -# if __cpp_lib_memory_resource != 201603L -# error "__cpp_lib_memory_resource should have the value 201603L in c++17" -# endif -# else -# ifdef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" -# endif -# endif - -# ifdef __cpp_lib_modules -# error "__cpp_lib_modules should not be defined before c++23" -# endif - -# ifdef __cpp_lib_move_iterator_concept -# error "__cpp_lib_move_iterator_concept should not be defined before c++20" -# endif - -# ifdef __cpp_lib_move_only_function -# error "__cpp_lib_move_only_function should not be defined before c++23" -# endif - -# ifndef __cpp_lib_node_extract -# error "__cpp_lib_node_extract should be defined in c++17" -# endif -# if __cpp_lib_node_extract != 201606L -# error "__cpp_lib_node_extract should have the value 201606L in c++17" -# endif - -# ifndef __cpp_lib_nonmember_container_access -# error "__cpp_lib_nonmember_container_access should be defined in c++17" -# endif -# if __cpp_lib_nonmember_container_access != 201411L -# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++17" -# endif - -# ifndef __cpp_lib_not_fn -# error "__cpp_lib_not_fn should be defined in c++17" -# endif -# if __cpp_lib_not_fn != 201603L -# error "__cpp_lib_not_fn should have the value 201603L in c++17" -# endif - -# ifndef __cpp_lib_null_iterators -# error "__cpp_lib_null_iterators should be defined in c++17" -# endif -# if __cpp_lib_null_iterators != 201304L -# error "__cpp_lib_null_iterators should have the value 201304L in c++17" -# endif - -# ifndef __cpp_lib_optional -# error "__cpp_lib_optional should be defined in c++17" -# endif -# if __cpp_lib_optional != 201606L -# error "__cpp_lib_optional should have the value 201606L in c++17" -# endif - -# ifdef __cpp_lib_optional_range_support -# error "__cpp_lib_optional_range_support should not be defined before c++26" -# endif - -# ifdef __cpp_lib_out_ptr -# error "__cpp_lib_out_ptr should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should be defined in c++17" -# endif -# if __cpp_lib_parallel_algorithm != 201603L -# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++17" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_philox_engine -# error "__cpp_lib_philox_engine should not be defined before c++26" -# endif - -# ifdef __cpp_lib_polymorphic_allocator -# error "__cpp_lib_polymorphic_allocator should not be defined before c++20" -# endif - -# ifdef __cpp_lib_print -# error "__cpp_lib_print should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION -# ifndef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should be defined in c++17" -# endif -# if __cpp_lib_quoted_string_io != 201304L -# error "__cpp_lib_quoted_string_io should have the value 201304L in c++17" -# endif -# else -# ifdef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" -# endif -# endif - -# ifdef __cpp_lib_ranges -# error "__cpp_lib_ranges should not be defined before c++20" -# endif - -# ifdef __cpp_lib_ranges_as_const -# error "__cpp_lib_ranges_as_const should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_as_rvalue -# error "__cpp_lib_ranges_as_rvalue should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_chunk_by -# error "__cpp_lib_ranges_chunk_by should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_concat -# error "__cpp_lib_ranges_concat should not be defined before c++26" -# endif - -# ifdef __cpp_lib_ranges_contains -# error "__cpp_lib_ranges_contains should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_find_last -# error "__cpp_lib_ranges_find_last should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_iota -# error "__cpp_lib_ranges_iota should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_join_with -# error "__cpp_lib_ranges_join_with should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_repeat -# error "__cpp_lib_ranges_repeat should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_slide -# error "__cpp_lib_ranges_slide should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_starts_ends_with -# error "__cpp_lib_ranges_starts_ends_with should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_stride -# error "__cpp_lib_ranges_stride should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_zip -# error "__cpp_lib_ranges_zip should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ratio -# error "__cpp_lib_ratio should not be defined before c++26" -# endif - -# ifndef __cpp_lib_raw_memory_algorithms -# error "__cpp_lib_raw_memory_algorithms should be defined in c++17" -# endif -# if __cpp_lib_raw_memory_algorithms != 201606L -# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++17" -# endif - -# ifdef __cpp_lib_rcu -# error "__cpp_lib_rcu should not be defined before c++26" -# endif - -# ifdef __cpp_lib_reference_from_temporary -# error "__cpp_lib_reference_from_temporary should not be defined before c++23" -# endif - -# ifdef __cpp_lib_reference_wrapper -# error "__cpp_lib_reference_wrapper should not be defined before c++26" -# endif - -# ifdef __cpp_lib_remove_cvref -# error "__cpp_lib_remove_cvref should not be defined before c++20" -# endif - -# ifndef __cpp_lib_result_of_sfinae -# error "__cpp_lib_result_of_sfinae should be defined in c++17" -# endif -# if __cpp_lib_result_of_sfinae != 201210L -# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++17" -# endif - -# ifndef __cpp_lib_robust_nonmodifying_seq_ops -# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++17" -# endif -# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L -# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++17" -# endif - -# ifndef __cpp_lib_sample -# error "__cpp_lib_sample should be defined in c++17" -# endif -# if __cpp_lib_sample != 201603L -# error "__cpp_lib_sample should have the value 201603L in c++17" -# endif - -# ifdef __cpp_lib_saturation_arithmetic -# error "__cpp_lib_saturation_arithmetic should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should be defined in c++17" -# endif -# if __cpp_lib_scoped_lock != 201703L -# error "__cpp_lib_scoped_lock should have the value 201703L in c++17" -# endif -# else -# ifdef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifdef __cpp_lib_semaphore -# error "__cpp_lib_semaphore should not be defined before c++20" -# endif - -# ifdef __cpp_lib_senders -# error "__cpp_lib_senders should not be defined before c++26" -# endif - -# if _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should be defined in c++17" -# endif -# if __cpp_lib_shared_mutex != 201505L -# error "__cpp_lib_shared_mutex should have the value 201505L in c++17" -# endif -# else -# ifdef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifndef __cpp_lib_shared_ptr_arrays -# error "__cpp_lib_shared_ptr_arrays should be defined in c++17" -# endif -# if __cpp_lib_shared_ptr_arrays != 201611L -# error "__cpp_lib_shared_ptr_arrays should have the value 201611L in c++17" -# endif - -# ifndef __cpp_lib_shared_ptr_weak_type -# error "__cpp_lib_shared_ptr_weak_type should be defined in c++17" -# endif -# if __cpp_lib_shared_ptr_weak_type != 201606L -# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++17" -# endif - -# if _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should be defined in c++17" -# endif -# if __cpp_lib_shared_timed_mutex != 201402L -# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++17" -# endif -# else -# ifdef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifdef __cpp_lib_shift -# error "__cpp_lib_shift should not be defined before c++20" -# endif - -# ifdef __cpp_lib_smart_ptr_for_overwrite -# error "__cpp_lib_smart_ptr_for_overwrite should not be defined before c++20" -# endif - -# ifdef __cpp_lib_smart_ptr_owner_equality -# error "__cpp_lib_smart_ptr_owner_equality should not be defined before c++26" -# endif - -# ifdef __cpp_lib_source_location -# error "__cpp_lib_source_location should not be defined before c++20" -# endif - -# ifdef __cpp_lib_span -# error "__cpp_lib_span should not be defined before c++20" -# endif - -# ifdef __cpp_lib_span_at -# error "__cpp_lib_span_at should not be defined before c++26" -# endif - -# ifdef __cpp_lib_span_initializer_list -# error "__cpp_lib_span_initializer_list should not be defined before c++26" -# endif - -# ifdef __cpp_lib_spanstream -# error "__cpp_lib_spanstream should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ssize -# error "__cpp_lib_ssize should not be defined before c++20" -# endif - -# ifdef __cpp_lib_sstream_from_string_view -# error "__cpp_lib_sstream_from_string_view should not be defined before c++26" -# endif - -# ifdef __cpp_lib_stacktrace -# error "__cpp_lib_stacktrace should not be defined before c++23" -# endif - -# ifdef __cpp_lib_starts_ends_with -# error "__cpp_lib_starts_ends_with should not be defined before c++20" -# endif - -# ifdef __cpp_lib_stdatomic_h -# error "__cpp_lib_stdatomic_h should not be defined before c++23" -# endif - -# ifdef __cpp_lib_string_contains -# error "__cpp_lib_string_contains should not be defined before c++23" -# endif - -# ifdef __cpp_lib_string_resize_and_overwrite -# error "__cpp_lib_string_resize_and_overwrite should not be defined before c++23" -# endif - -# ifndef __cpp_lib_string_udls -# error "__cpp_lib_string_udls should be defined in c++17" -# endif -# if __cpp_lib_string_udls != 201304L -# error "__cpp_lib_string_udls should have the value 201304L in c++17" -# endif - -# ifndef __cpp_lib_string_view -# error "__cpp_lib_string_view should be defined in c++17" -# endif -# if __cpp_lib_string_view != 201606L -# error "__cpp_lib_string_view should have the value 201606L in c++17" -# endif - -# ifdef __cpp_lib_submdspan -# error "__cpp_lib_submdspan should not be defined before c++26" -# endif - -# ifdef __cpp_lib_syncbuf -# error "__cpp_lib_syncbuf should not be defined before c++20" -# endif - -# ifdef __cpp_lib_text_encoding -# error "__cpp_lib_text_encoding should not be defined before c++26" -# endif - -# ifdef __cpp_lib_three_way_comparison -# error "__cpp_lib_three_way_comparison should not be defined before c++20" -# endif - -# ifdef __cpp_lib_to_address -# error "__cpp_lib_to_address should not be defined before c++20" -# endif - -# ifdef __cpp_lib_to_array -# error "__cpp_lib_to_array should not be defined before c++20" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should be defined in c++17" -# endif -# if __cpp_lib_to_chars != 201611L -# error "__cpp_lib_to_chars should have the value 201611L in c++17" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_to_string -# error "__cpp_lib_to_string should not be defined before c++26" -# endif - -# ifdef __cpp_lib_to_underlying -# error "__cpp_lib_to_underlying should not be defined before c++23" -# endif - -# ifndef __cpp_lib_transformation_trait_aliases -# error "__cpp_lib_transformation_trait_aliases should be defined in c++17" -# endif -# if __cpp_lib_transformation_trait_aliases != 201304L -# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++17" -# endif - -# ifndef __cpp_lib_transparent_operators -# error "__cpp_lib_transparent_operators should be defined in c++17" -# endif -# if __cpp_lib_transparent_operators != 201510L -# error "__cpp_lib_transparent_operators should have the value 201510L in c++17" -# endif - -# ifndef __cpp_lib_tuple_element_t -# error "__cpp_lib_tuple_element_t should be defined in c++17" -# endif -# if __cpp_lib_tuple_element_t != 201402L -# error "__cpp_lib_tuple_element_t should have the value 201402L in c++17" -# endif - -# ifdef __cpp_lib_tuple_like -# error "__cpp_lib_tuple_like should not be defined before c++23" -# endif - -# ifndef __cpp_lib_tuples_by_type -# error "__cpp_lib_tuples_by_type should be defined in c++17" -# endif -# if __cpp_lib_tuples_by_type != 201304L -# error "__cpp_lib_tuples_by_type should have the value 201304L in c++17" -# endif - -# ifdef __cpp_lib_type_identity -# error "__cpp_lib_type_identity should not be defined before c++20" -# endif - -# ifndef __cpp_lib_type_trait_variable_templates -# error "__cpp_lib_type_trait_variable_templates should be defined in c++17" -# endif -# if __cpp_lib_type_trait_variable_templates != 201510L -# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++17" -# endif - -# ifndef __cpp_lib_uncaught_exceptions -# error "__cpp_lib_uncaught_exceptions should be defined in c++17" -# endif -# if __cpp_lib_uncaught_exceptions != 201411L -# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++17" -# endif - -# ifndef __cpp_lib_unordered_map_try_emplace -# error "__cpp_lib_unordered_map_try_emplace should be defined in c++17" -# endif -# if __cpp_lib_unordered_map_try_emplace != 201411L -# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++17" -# endif - -# ifdef __cpp_lib_unreachable -# error "__cpp_lib_unreachable should not be defined before c++23" -# endif - -# ifdef __cpp_lib_unwrap_ref -# error "__cpp_lib_unwrap_ref should not be defined before c++20" -# endif - -# ifndef __cpp_lib_variant -# error "__cpp_lib_variant should be defined in c++17" -# endif -# if __cpp_lib_variant != 202102L -# error "__cpp_lib_variant should have the value 202102L in c++17" -# endif - -# ifndef __cpp_lib_void_t -# error "__cpp_lib_void_t should be defined in c++17" -# endif -# if __cpp_lib_void_t != 201411L -# error "__cpp_lib_void_t should have the value 201411L in c++17" -# endif +# ifdef __cpp_lib_freestanding_algorithm +# error "__cpp_lib_freestanding_algorithm should not be defined before c++26" +# endif -#elif TEST_STD_VER == 20 +# ifdef __cpp_lib_freestanding_array +# error "__cpp_lib_freestanding_array should not be defined before c++26" +# endif -# ifdef __cpp_lib_adaptor_iterator_pair_constructor -# error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++23" -# endif - -# ifndef __cpp_lib_addressof_constexpr -# error "__cpp_lib_addressof_constexpr should be defined in c++20" -# endif -# if __cpp_lib_addressof_constexpr != 201603L -# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++20" -# endif - -# ifdef __cpp_lib_allocate_at_least -# error "__cpp_lib_allocate_at_least should not be defined before c++23" -# endif - -# ifndef __cpp_lib_allocator_traits_is_always_equal -# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++20" -# endif -# if __cpp_lib_allocator_traits_is_always_equal != 201411L -# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++20" -# endif - -# ifndef __cpp_lib_any -# error "__cpp_lib_any should be defined in c++20" -# endif -# if __cpp_lib_any != 201606L -# error "__cpp_lib_any should have the value 201606L in c++20" -# endif - -# ifndef __cpp_lib_apply -# error "__cpp_lib_apply should be defined in c++20" -# endif -# if __cpp_lib_apply != 201603L -# error "__cpp_lib_apply should have the value 201603L in c++20" -# endif - -# ifndef __cpp_lib_array_constexpr -# error "__cpp_lib_array_constexpr should be defined in c++20" -# endif -# if __cpp_lib_array_constexpr != 201811L -# error "__cpp_lib_array_constexpr should have the value 201811L in c++20" -# endif - -# ifndef __cpp_lib_as_const -# error "__cpp_lib_as_const should be defined in c++20" -# endif -# if __cpp_lib_as_const != 201510L -# error "__cpp_lib_as_const should have the value 201510L in c++20" -# endif - -# ifdef __cpp_lib_associative_heterogeneous_erasure -# error "__cpp_lib_associative_heterogeneous_erasure should not be defined before c++23" -# endif - -# ifdef __cpp_lib_associative_heterogeneous_insertion -# error "__cpp_lib_associative_heterogeneous_insertion should not be defined before c++26" -# endif - -# ifndef __cpp_lib_assume_aligned -# error "__cpp_lib_assume_aligned should be defined in c++20" -# endif -# if __cpp_lib_assume_aligned != 201811L -# error "__cpp_lib_assume_aligned should have the value 201811L in c++20" -# endif - -# ifndef __cpp_lib_atomic_flag_test -# error "__cpp_lib_atomic_flag_test should be defined in c++20" -# endif -# if __cpp_lib_atomic_flag_test != 201907L -# error "__cpp_lib_atomic_flag_test should have the value 201907L in c++20" -# endif - -# ifndef __cpp_lib_atomic_float -# error "__cpp_lib_atomic_float should be defined in c++20" -# endif -# if __cpp_lib_atomic_float != 201711L -# error "__cpp_lib_atomic_float should have the value 201711L in c++20" -# endif - -# ifndef __cpp_lib_atomic_is_always_lock_free -# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++20" -# endif -# if __cpp_lib_atomic_is_always_lock_free != 201603L -# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++20" -# endif - -# ifndef __cpp_lib_atomic_lock_free_type_aliases -# error "__cpp_lib_atomic_lock_free_type_aliases should be defined in c++20" -# endif -# if __cpp_lib_atomic_lock_free_type_aliases != 201907L -# error "__cpp_lib_atomic_lock_free_type_aliases should have the value 201907L in c++20" -# endif - -# ifdef __cpp_lib_atomic_min_max -# error "__cpp_lib_atomic_min_max should not be defined before c++26" -# endif - -# ifndef __cpp_lib_atomic_ref -# error "__cpp_lib_atomic_ref should be defined in c++20" -# endif -# if __cpp_lib_atomic_ref != 201806L -# error "__cpp_lib_atomic_ref should have the value 201806L in c++20" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_atomic_shared_ptr -# error "__cpp_lib_atomic_shared_ptr should be defined in c++20" -# endif -# if __cpp_lib_atomic_shared_ptr != 201711L -# error "__cpp_lib_atomic_shared_ptr should have the value 201711L in c++20" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_atomic_shared_ptr -# error "__cpp_lib_atomic_shared_ptr should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_atomic_value_initialization -# error "__cpp_lib_atomic_value_initialization should be defined in c++20" -# endif -# if __cpp_lib_atomic_value_initialization != 201911L -# error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++20" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC -# ifndef __cpp_lib_atomic_wait -# error "__cpp_lib_atomic_wait should be defined in c++20" -# endif -# if __cpp_lib_atomic_wait != 201907L -# error "__cpp_lib_atomic_wait should have the value 201907L in c++20" -# endif -# else -# ifdef __cpp_lib_atomic_wait -# error "__cpp_lib_atomic_wait should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_barrier -# error "__cpp_lib_barrier should be defined in c++20" -# endif -# if __cpp_lib_barrier != 201907L -# error "__cpp_lib_barrier should have the value 201907L in c++20" -# endif -# else -# ifdef __cpp_lib_barrier -# error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# ifdef __cpp_lib_bind_back -# error "__cpp_lib_bind_back should not be defined before c++23" -# endif - -# ifndef __cpp_lib_bind_front -# error "__cpp_lib_bind_front should be defined in c++20" -# endif -# if __cpp_lib_bind_front != 201907L -# error "__cpp_lib_bind_front should have the value 201907L in c++20" -# endif - -# ifndef __cpp_lib_bit_cast -# error "__cpp_lib_bit_cast should be defined in c++20" -# endif -# if __cpp_lib_bit_cast != 201806L -# error "__cpp_lib_bit_cast should have the value 201806L in c++20" -# endif - -# ifndef __cpp_lib_bitops -# error "__cpp_lib_bitops should be defined in c++20" -# endif -# if __cpp_lib_bitops != 201907L -# error "__cpp_lib_bitops should have the value 201907L in c++20" -# endif - -# ifdef __cpp_lib_bitset -# error "__cpp_lib_bitset should not be defined before c++26" -# endif - -# ifndef __cpp_lib_bool_constant -# error "__cpp_lib_bool_constant should be defined in c++20" -# endif -# if __cpp_lib_bool_constant != 201505L -# error "__cpp_lib_bool_constant should have the value 201505L in c++20" -# endif - -# ifndef __cpp_lib_bounded_array_traits -# error "__cpp_lib_bounded_array_traits should be defined in c++20" -# endif -# if __cpp_lib_bounded_array_traits != 201902L -# error "__cpp_lib_bounded_array_traits should have the value 201902L in c++20" -# endif - -# ifndef __cpp_lib_boyer_moore_searcher -# error "__cpp_lib_boyer_moore_searcher should be defined in c++20" -# endif -# if __cpp_lib_boyer_moore_searcher != 201603L -# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++20" -# endif - -# ifndef __cpp_lib_byte -# error "__cpp_lib_byte should be defined in c++20" -# endif -# if __cpp_lib_byte != 201603L -# error "__cpp_lib_byte should have the value 201603L in c++20" -# endif - -# ifdef __cpp_lib_byteswap -# error "__cpp_lib_byteswap should not be defined before c++23" -# endif - -# if defined(__cpp_char8_t) -# ifndef __cpp_lib_char8_t -# error "__cpp_lib_char8_t should be defined in c++20" -# endif -# if __cpp_lib_char8_t != 201907L -# error "__cpp_lib_char8_t should have the value 201907L in c++20" -# endif -# else -# ifdef __cpp_lib_char8_t -# error "__cpp_lib_char8_t should not be defined when the requirement 'defined(__cpp_char8_t)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_chrono -# error "__cpp_lib_chrono should be defined in c++20" -# endif -# if __cpp_lib_chrono != 201611L -# error "__cpp_lib_chrono should have the value 201611L in c++20" -# endif - -# ifndef __cpp_lib_chrono_udls -# error "__cpp_lib_chrono_udls should be defined in c++20" -# endif -# if __cpp_lib_chrono_udls != 201304L -# error "__cpp_lib_chrono_udls should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_clamp -# error "__cpp_lib_clamp should be defined in c++20" -# endif -# if __cpp_lib_clamp != 201603L -# error "__cpp_lib_clamp should have the value 201603L in c++20" -# endif - -# ifndef __cpp_lib_complex_udls -# error "__cpp_lib_complex_udls should be defined in c++20" -# endif -# if __cpp_lib_complex_udls != 201309L -# error "__cpp_lib_complex_udls should have the value 201309L in c++20" -# endif - -# ifndef __cpp_lib_concepts -# error "__cpp_lib_concepts should be defined in c++20" -# endif -# if __cpp_lib_concepts != 202002L -# error "__cpp_lib_concepts should have the value 202002L in c++20" -# endif - -# ifndef __cpp_lib_constexpr_algorithms -# error "__cpp_lib_constexpr_algorithms should be defined in c++20" -# endif -# if __cpp_lib_constexpr_algorithms != 201806L -# error "__cpp_lib_constexpr_algorithms should have the value 201806L in c++20" -# endif - -# ifdef __cpp_lib_constexpr_bitset -# error "__cpp_lib_constexpr_bitset should not be defined before c++23" -# endif - -# ifdef __cpp_lib_constexpr_charconv -# error "__cpp_lib_constexpr_charconv should not be defined before c++23" -# endif - -# ifdef __cpp_lib_constexpr_cmath -# error "__cpp_lib_constexpr_cmath should not be defined before c++23" -# endif - -# ifndef __cpp_lib_constexpr_complex -# error "__cpp_lib_constexpr_complex should be defined in c++20" -# endif -# if __cpp_lib_constexpr_complex != 201711L -# error "__cpp_lib_constexpr_complex should have the value 201711L in c++20" -# endif - -# ifndef __cpp_lib_constexpr_dynamic_alloc -# error "__cpp_lib_constexpr_dynamic_alloc should be defined in c++20" -# endif -# if __cpp_lib_constexpr_dynamic_alloc != 201907L -# error "__cpp_lib_constexpr_dynamic_alloc should have the value 201907L in c++20" -# endif - -# ifndef __cpp_lib_constexpr_functional -# error "__cpp_lib_constexpr_functional should be defined in c++20" -# endif -# if __cpp_lib_constexpr_functional != 201907L -# error "__cpp_lib_constexpr_functional should have the value 201907L in c++20" -# endif - -# ifndef __cpp_lib_constexpr_iterator -# error "__cpp_lib_constexpr_iterator should be defined in c++20" -# endif -# if __cpp_lib_constexpr_iterator != 201811L -# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++20" -# endif - -# ifndef __cpp_lib_constexpr_memory -# error "__cpp_lib_constexpr_memory should be defined in c++20" -# endif -# if __cpp_lib_constexpr_memory != 201811L -# error "__cpp_lib_constexpr_memory should have the value 201811L in c++20" -# endif - -# ifdef __cpp_lib_constexpr_new -# error "__cpp_lib_constexpr_new should not be defined before c++26" -# endif - -# ifndef __cpp_lib_constexpr_numeric -# error "__cpp_lib_constexpr_numeric should be defined in c++20" -# endif -# if __cpp_lib_constexpr_numeric != 201911L -# error "__cpp_lib_constexpr_numeric should have the value 201911L in c++20" -# endif - -# ifndef __cpp_lib_constexpr_string -# error "__cpp_lib_constexpr_string should be defined in c++20" -# endif -# if __cpp_lib_constexpr_string != 201907L -# error "__cpp_lib_constexpr_string should have the value 201907L in c++20" -# endif - -# ifndef __cpp_lib_constexpr_string_view -# error "__cpp_lib_constexpr_string_view should be defined in c++20" -# endif -# if __cpp_lib_constexpr_string_view != 201811L -# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++20" -# endif - -# ifndef __cpp_lib_constexpr_tuple -# error "__cpp_lib_constexpr_tuple should be defined in c++20" -# endif -# if __cpp_lib_constexpr_tuple != 201811L -# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++20" -# endif - -# ifdef __cpp_lib_constexpr_typeinfo -# error "__cpp_lib_constexpr_typeinfo should not be defined before c++23" -# endif - -# ifndef __cpp_lib_constexpr_utility -# error "__cpp_lib_constexpr_utility should be defined in c++20" -# endif -# if __cpp_lib_constexpr_utility != 201811L -# error "__cpp_lib_constexpr_utility should have the value 201811L in c++20" -# endif - -# ifndef __cpp_lib_constexpr_vector -# error "__cpp_lib_constexpr_vector should be defined in c++20" -# endif -# if __cpp_lib_constexpr_vector != 201907L -# error "__cpp_lib_constexpr_vector should have the value 201907L in c++20" -# endif - -# ifdef __cpp_lib_constrained_equality -# error "__cpp_lib_constrained_equality should not be defined before c++26" -# endif - -# ifdef __cpp_lib_containers_ranges -# error "__cpp_lib_containers_ranges should not be defined before c++23" -# endif - -# ifdef __cpp_lib_copyable_function -# error "__cpp_lib_copyable_function should not be defined before c++26" -# endif - -# ifndef __cpp_lib_coroutine -# error "__cpp_lib_coroutine should be defined in c++20" -# endif -# if __cpp_lib_coroutine != 201902L -# error "__cpp_lib_coroutine should have the value 201902L in c++20" -# endif - -# ifdef __cpp_lib_debugging -# error "__cpp_lib_debugging should not be defined before c++26" -# endif - -# ifdef __cpp_lib_default_template_type_for_algorithm_values -# error "__cpp_lib_default_template_type_for_algorithm_values should not be defined before c++26" -# endif - -# if TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L -# ifndef __cpp_lib_destroying_delete -# error "__cpp_lib_destroying_delete should be defined in c++20" -# endif -# if __cpp_lib_destroying_delete != 201806L -# error "__cpp_lib_destroying_delete should have the value 201806L in c++20" -# endif -# else -# ifdef __cpp_lib_destroying_delete -# error "__cpp_lib_destroying_delete should not be defined when the requirement 'TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L' is not met!" -# endif -# endif - -# ifndef __cpp_lib_enable_shared_from_this -# error "__cpp_lib_enable_shared_from_this should be defined in c++20" -# endif -# if __cpp_lib_enable_shared_from_this != 201603L -# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++20" -# endif - -# ifndef __cpp_lib_endian -# error "__cpp_lib_endian should be defined in c++20" -# endif -# if __cpp_lib_endian != 201907L -# error "__cpp_lib_endian should have the value 201907L in c++20" -# endif - -# ifndef __cpp_lib_erase_if -# error "__cpp_lib_erase_if should be defined in c++20" -# endif -# if __cpp_lib_erase_if != 202002L -# error "__cpp_lib_erase_if should have the value 202002L in c++20" -# endif - -# ifndef __cpp_lib_exchange_function -# error "__cpp_lib_exchange_function should be defined in c++20" -# endif -# if __cpp_lib_exchange_function != 201304L -# error "__cpp_lib_exchange_function should have the value 201304L in c++20" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_execution -# error "__cpp_lib_execution should be defined in c++20" -# endif -# if __cpp_lib_execution != 201902L -# error "__cpp_lib_execution should have the value 201902L in c++20" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_execution -# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_expected -# error "__cpp_lib_expected should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY) -# ifndef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should be defined in c++20" -# endif -# if __cpp_lib_filesystem != 201703L -# error "__cpp_lib_filesystem should have the value 201703L in c++20" -# endif -# else -# ifdef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)' is not met!" -# endif -# endif - -# ifdef __cpp_lib_flat_map -# error "__cpp_lib_flat_map should not be defined before c++23" -# endif - -# ifdef __cpp_lib_flat_set -# error "__cpp_lib_flat_set should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT -# ifndef __cpp_lib_format -# error "__cpp_lib_format should be defined in c++20" -# endif -# if __cpp_lib_format != 202110L -# error "__cpp_lib_format should have the value 202110L in c++20" -# endif -# else -# ifdef __cpp_lib_format -# error "__cpp_lib_format should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" -# endif -# endif - -# ifdef __cpp_lib_format_path -# error "__cpp_lib_format_path should not be defined before c++26" -# endif - -# ifdef __cpp_lib_format_ranges -# error "__cpp_lib_format_ranges should not be defined before c++23" -# endif - -# ifndef __cpp_lib_format_uchar -# error "__cpp_lib_format_uchar should be defined in c++20" -# endif -# if __cpp_lib_format_uchar != 202311L -# error "__cpp_lib_format_uchar should have the value 202311L in c++20" -# endif - -# ifdef __cpp_lib_formatters -# error "__cpp_lib_formatters should not be defined before c++23" -# endif - -# ifdef __cpp_lib_forward_like -# error "__cpp_lib_forward_like should not be defined before c++23" -# endif - -# ifdef __cpp_lib_freestanding_algorithm -# error "__cpp_lib_freestanding_algorithm should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_array -# error "__cpp_lib_freestanding_array should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_cstring -# error "__cpp_lib_freestanding_cstring should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_expected -# error "__cpp_lib_freestanding_expected should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_mdspan -# error "__cpp_lib_freestanding_mdspan should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_optional -# error "__cpp_lib_freestanding_optional should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_string_view -# error "__cpp_lib_freestanding_string_view should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_variant -# error "__cpp_lib_freestanding_variant should not be defined before c++26" -# endif - -# ifdef __cpp_lib_fstream_native_handle -# error "__cpp_lib_fstream_native_handle should not be defined before c++26" -# endif - -# ifdef __cpp_lib_function_ref -# error "__cpp_lib_function_ref should not be defined before c++26" -# endif - -# ifndef __cpp_lib_gcd_lcm -# error "__cpp_lib_gcd_lcm should be defined in c++20" -# endif -# if __cpp_lib_gcd_lcm != 201606L -# error "__cpp_lib_gcd_lcm should have the value 201606L in c++20" -# endif - -# ifdef __cpp_lib_generate_random -# error "__cpp_lib_generate_random should not be defined before c++26" -# endif - -# ifndef __cpp_lib_generic_associative_lookup -# error "__cpp_lib_generic_associative_lookup should be defined in c++20" -# endif -# if __cpp_lib_generic_associative_lookup != 201304L -# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_generic_unordered_lookup -# error "__cpp_lib_generic_unordered_lookup should be defined in c++20" -# endif -# if __cpp_lib_generic_unordered_lookup != 201811L -# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++20" -# endif - -# if !defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)) -# ifndef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should be defined in c++20" -# endif -# if __cpp_lib_hardware_interference_size != 201703L -# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++20" -# endif -# else -# ifdef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))' is not met!" -# endif -# endif - -# ifndef __cpp_lib_has_unique_object_representations -# error "__cpp_lib_has_unique_object_representations should be defined in c++20" -# endif -# if __cpp_lib_has_unique_object_representations != 201606L -# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++20" -# endif - -# ifdef __cpp_lib_hazard_pointer -# error "__cpp_lib_hazard_pointer should not be defined before c++26" -# endif - -# ifndef __cpp_lib_hypot -# error "__cpp_lib_hypot should be defined in c++20" -# endif -# if __cpp_lib_hypot != 201603L -# error "__cpp_lib_hypot should have the value 201603L in c++20" -# endif - -# ifndef __cpp_lib_incomplete_container_elements -# error "__cpp_lib_incomplete_container_elements should be defined in c++20" -# endif -# if __cpp_lib_incomplete_container_elements != 201505L -# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++20" -# endif - -# ifdef __cpp_lib_inplace_vector -# error "__cpp_lib_inplace_vector should not be defined before c++26" -# endif - -# ifndef __cpp_lib_int_pow2 -# error "__cpp_lib_int_pow2 should be defined in c++20" -# endif -# if __cpp_lib_int_pow2 != 202002L -# error "__cpp_lib_int_pow2 should have the value 202002L in c++20" -# endif - -# ifndef __cpp_lib_integer_comparison_functions -# error "__cpp_lib_integer_comparison_functions should be defined in c++20" -# endif -# if __cpp_lib_integer_comparison_functions != 202002L -# error "__cpp_lib_integer_comparison_functions should have the value 202002L in c++20" -# endif - -# ifndef __cpp_lib_integer_sequence -# error "__cpp_lib_integer_sequence should be defined in c++20" -# endif -# if __cpp_lib_integer_sequence != 201304L -# error "__cpp_lib_integer_sequence should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_integral_constant_callable -# error "__cpp_lib_integral_constant_callable should be defined in c++20" -# endif -# if __cpp_lib_integral_constant_callable != 201304L -# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_interpolate -# error "__cpp_lib_interpolate should be defined in c++20" -# endif -# if __cpp_lib_interpolate != 201902L -# error "__cpp_lib_interpolate should have the value 201902L in c++20" -# endif - -# ifndef __cpp_lib_invoke -# error "__cpp_lib_invoke should be defined in c++20" -# endif -# if __cpp_lib_invoke != 201411L -# error "__cpp_lib_invoke should have the value 201411L in c++20" -# endif - -# ifdef __cpp_lib_invoke_r -# error "__cpp_lib_invoke_r should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ios_noreplace -# error "__cpp_lib_ios_noreplace should not be defined before c++23" -# endif - -# ifndef __cpp_lib_is_aggregate -# error "__cpp_lib_is_aggregate should be defined in c++20" -# endif -# if __cpp_lib_is_aggregate != 201703L -# error "__cpp_lib_is_aggregate should have the value 201703L in c++20" -# endif - -# ifndef __cpp_lib_is_constant_evaluated -# error "__cpp_lib_is_constant_evaluated should be defined in c++20" -# endif -# if __cpp_lib_is_constant_evaluated != 201811L -# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++20" -# endif - -# ifndef __cpp_lib_is_final -# error "__cpp_lib_is_final should be defined in c++20" -# endif -# if __cpp_lib_is_final != 201402L -# error "__cpp_lib_is_final should have the value 201402L in c++20" -# endif - -# ifdef __cpp_lib_is_implicit_lifetime -# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" -# endif - -# ifndef __cpp_lib_is_invocable -# error "__cpp_lib_is_invocable should be defined in c++20" -# endif -# if __cpp_lib_is_invocable != 201703L -# error "__cpp_lib_is_invocable should have the value 201703L in c++20" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_is_layout_compatible -# error "__cpp_lib_is_layout_compatible should be defined in c++20" -# endif -# if __cpp_lib_is_layout_compatible != 201907L -# error "__cpp_lib_is_layout_compatible should have the value 201907L in c++20" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_is_layout_compatible -# error "__cpp_lib_is_layout_compatible should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_is_nothrow_convertible -# error "__cpp_lib_is_nothrow_convertible should be defined in c++20" -# endif -# if __cpp_lib_is_nothrow_convertible != 201806L -# error "__cpp_lib_is_nothrow_convertible should have the value 201806L in c++20" -# endif - -# ifndef __cpp_lib_is_null_pointer -# error "__cpp_lib_is_null_pointer should be defined in c++20" -# endif -# if __cpp_lib_is_null_pointer != 201309L -# error "__cpp_lib_is_null_pointer should have the value 201309L in c++20" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_is_pointer_interconvertible -# error "__cpp_lib_is_pointer_interconvertible should be defined in c++20" -# endif -# if __cpp_lib_is_pointer_interconvertible != 201907L -# error "__cpp_lib_is_pointer_interconvertible should have the value 201907L in c++20" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_is_pointer_interconvertible -# error "__cpp_lib_is_pointer_interconvertible should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_is_scoped_enum -# error "__cpp_lib_is_scoped_enum should not be defined before c++23" -# endif - -# ifndef __cpp_lib_is_swappable -# error "__cpp_lib_is_swappable should be defined in c++20" -# endif -# if __cpp_lib_is_swappable != 201603L -# error "__cpp_lib_is_swappable should have the value 201603L in c++20" -# endif - -# ifdef __cpp_lib_is_virtual_base_of -# error "__cpp_lib_is_virtual_base_of should not be defined before c++26" -# endif - -# ifdef __cpp_lib_is_within_lifetime -# error "__cpp_lib_is_within_lifetime should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_jthread -# error "__cpp_lib_jthread should be defined in c++20" -# endif -# if __cpp_lib_jthread != 201911L -# error "__cpp_lib_jthread should have the value 201911L in c++20" -# endif -# else -# ifdef __cpp_lib_jthread -# error "__cpp_lib_jthread should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_latch -# error "__cpp_lib_latch should be defined in c++20" -# endif -# if __cpp_lib_latch != 201907L -# error "__cpp_lib_latch should have the value 201907L in c++20" -# endif -# else -# ifdef __cpp_lib_latch -# error "__cpp_lib_latch should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_launder -# error "__cpp_lib_launder should be defined in c++20" -# endif -# if __cpp_lib_launder != 201606L -# error "__cpp_lib_launder should have the value 201606L in c++20" -# endif - -# ifdef __cpp_lib_linalg -# error "__cpp_lib_linalg should not be defined before c++26" -# endif - -# ifndef __cpp_lib_list_remove_return_type -# error "__cpp_lib_list_remove_return_type should be defined in c++20" -# endif -# if __cpp_lib_list_remove_return_type != 201806L -# error "__cpp_lib_list_remove_return_type should have the value 201806L in c++20" -# endif - -# ifndef __cpp_lib_logical_traits -# error "__cpp_lib_logical_traits should be defined in c++20" -# endif -# if __cpp_lib_logical_traits != 201510L -# error "__cpp_lib_logical_traits should have the value 201510L in c++20" -# endif - -# ifndef __cpp_lib_make_from_tuple -# error "__cpp_lib_make_from_tuple should be defined in c++20" -# endif -# if __cpp_lib_make_from_tuple != 201606L -# error "__cpp_lib_make_from_tuple should have the value 201606L in c++20" -# endif - -# ifndef __cpp_lib_make_reverse_iterator -# error "__cpp_lib_make_reverse_iterator should be defined in c++20" -# endif -# if __cpp_lib_make_reverse_iterator != 201402L -# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++20" -# endif - -# ifndef __cpp_lib_make_unique -# error "__cpp_lib_make_unique should be defined in c++20" -# endif -# if __cpp_lib_make_unique != 201304L -# error "__cpp_lib_make_unique should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_map_try_emplace -# error "__cpp_lib_map_try_emplace should be defined in c++20" -# endif -# if __cpp_lib_map_try_emplace != 201411L -# error "__cpp_lib_map_try_emplace should have the value 201411L in c++20" -# endif - -# ifndef __cpp_lib_math_constants -# error "__cpp_lib_math_constants should be defined in c++20" -# endif -# if __cpp_lib_math_constants != 201907L -# error "__cpp_lib_math_constants should have the value 201907L in c++20" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should be defined in c++20" -# endif -# if __cpp_lib_math_special_functions != 201603L -# error "__cpp_lib_math_special_functions should have the value 201603L in c++20" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_mdspan -# error "__cpp_lib_mdspan should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR -# ifndef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should be defined in c++20" -# endif -# if __cpp_lib_memory_resource != 201603L -# error "__cpp_lib_memory_resource should have the value 201603L in c++20" -# endif -# else -# ifdef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" -# endif -# endif - -# ifdef __cpp_lib_modules -# error "__cpp_lib_modules should not be defined before c++23" -# endif - -# ifndef __cpp_lib_move_iterator_concept -# error "__cpp_lib_move_iterator_concept should be defined in c++20" -# endif -# if __cpp_lib_move_iterator_concept != 202207L -# error "__cpp_lib_move_iterator_concept should have the value 202207L in c++20" -# endif - -# ifdef __cpp_lib_move_only_function -# error "__cpp_lib_move_only_function should not be defined before c++23" -# endif - -# ifndef __cpp_lib_node_extract -# error "__cpp_lib_node_extract should be defined in c++20" -# endif -# if __cpp_lib_node_extract != 201606L -# error "__cpp_lib_node_extract should have the value 201606L in c++20" -# endif - -# ifndef __cpp_lib_nonmember_container_access -# error "__cpp_lib_nonmember_container_access should be defined in c++20" -# endif -# if __cpp_lib_nonmember_container_access != 201411L -# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++20" -# endif - -# ifndef __cpp_lib_not_fn -# error "__cpp_lib_not_fn should be defined in c++20" -# endif -# if __cpp_lib_not_fn != 201603L -# error "__cpp_lib_not_fn should have the value 201603L in c++20" -# endif - -# ifndef __cpp_lib_null_iterators -# error "__cpp_lib_null_iterators should be defined in c++20" -# endif -# if __cpp_lib_null_iterators != 201304L -# error "__cpp_lib_null_iterators should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_optional -# error "__cpp_lib_optional should be defined in c++20" -# endif -# if __cpp_lib_optional != 202106L -# error "__cpp_lib_optional should have the value 202106L in c++20" -# endif - -# ifdef __cpp_lib_optional_range_support -# error "__cpp_lib_optional_range_support should not be defined before c++26" -# endif - -# ifdef __cpp_lib_out_ptr -# error "__cpp_lib_out_ptr should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should be defined in c++20" -# endif -# if __cpp_lib_parallel_algorithm != 201603L -# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++20" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_philox_engine -# error "__cpp_lib_philox_engine should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR -# ifndef __cpp_lib_polymorphic_allocator -# error "__cpp_lib_polymorphic_allocator should be defined in c++20" -# endif -# if __cpp_lib_polymorphic_allocator != 201902L -# error "__cpp_lib_polymorphic_allocator should have the value 201902L in c++20" -# endif -# else -# ifdef __cpp_lib_polymorphic_allocator -# error "__cpp_lib_polymorphic_allocator should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" -# endif -# endif - -# ifdef __cpp_lib_print -# error "__cpp_lib_print should not be defined before c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION -# ifndef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should be defined in c++20" -# endif -# if __cpp_lib_quoted_string_io != 201304L -# error "__cpp_lib_quoted_string_io should have the value 201304L in c++20" -# endif -# else -# ifdef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" -# endif -# endif - -# ifndef __cpp_lib_ranges -# error "__cpp_lib_ranges should be defined in c++20" -# endif -# if __cpp_lib_ranges != 202110L -# error "__cpp_lib_ranges should have the value 202110L in c++20" -# endif - -# ifdef __cpp_lib_ranges_as_const -# error "__cpp_lib_ranges_as_const should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_as_rvalue -# error "__cpp_lib_ranges_as_rvalue should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_chunk_by -# error "__cpp_lib_ranges_chunk_by should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_concat -# error "__cpp_lib_ranges_concat should not be defined before c++26" -# endif - -# ifdef __cpp_lib_ranges_contains -# error "__cpp_lib_ranges_contains should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_find_last -# error "__cpp_lib_ranges_find_last should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_iota -# error "__cpp_lib_ranges_iota should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_join_with -# error "__cpp_lib_ranges_join_with should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_repeat -# error "__cpp_lib_ranges_repeat should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_slide -# error "__cpp_lib_ranges_slide should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_starts_ends_with -# error "__cpp_lib_ranges_starts_ends_with should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_stride -# error "__cpp_lib_ranges_stride should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ranges_zip -# error "__cpp_lib_ranges_zip should not be defined before c++23" -# endif - -# ifdef __cpp_lib_ratio -# error "__cpp_lib_ratio should not be defined before c++26" -# endif - -# ifndef __cpp_lib_raw_memory_algorithms -# error "__cpp_lib_raw_memory_algorithms should be defined in c++20" -# endif -# if __cpp_lib_raw_memory_algorithms != 201606L -# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++20" -# endif - -# ifdef __cpp_lib_rcu -# error "__cpp_lib_rcu should not be defined before c++26" -# endif - -# ifdef __cpp_lib_reference_from_temporary -# error "__cpp_lib_reference_from_temporary should not be defined before c++23" -# endif - -# ifdef __cpp_lib_reference_wrapper -# error "__cpp_lib_reference_wrapper should not be defined before c++26" -# endif - -# ifndef __cpp_lib_remove_cvref -# error "__cpp_lib_remove_cvref should be defined in c++20" -# endif -# if __cpp_lib_remove_cvref != 201711L -# error "__cpp_lib_remove_cvref should have the value 201711L in c++20" -# endif - -# ifndef __cpp_lib_result_of_sfinae -# error "__cpp_lib_result_of_sfinae should be defined in c++20" -# endif -# if __cpp_lib_result_of_sfinae != 201210L -# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++20" -# endif - -# ifndef __cpp_lib_robust_nonmodifying_seq_ops -# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++20" -# endif -# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L -# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_sample -# error "__cpp_lib_sample should be defined in c++20" -# endif -# if __cpp_lib_sample != 201603L -# error "__cpp_lib_sample should have the value 201603L in c++20" -# endif - -# ifdef __cpp_lib_saturation_arithmetic -# error "__cpp_lib_saturation_arithmetic should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should be defined in c++20" -# endif -# if __cpp_lib_scoped_lock != 201703L -# error "__cpp_lib_scoped_lock should have the value 201703L in c++20" -# endif -# else -# ifdef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_semaphore -# error "__cpp_lib_semaphore should be defined in c++20" -# endif -# if __cpp_lib_semaphore != 201907L -# error "__cpp_lib_semaphore should have the value 201907L in c++20" -# endif -# else -# ifdef __cpp_lib_semaphore -# error "__cpp_lib_semaphore should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# ifdef __cpp_lib_senders -# error "__cpp_lib_senders should not be defined before c++26" -# endif - -# if _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should be defined in c++20" -# endif -# if __cpp_lib_shared_mutex != 201505L -# error "__cpp_lib_shared_mutex should have the value 201505L in c++20" -# endif -# else -# ifdef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifndef __cpp_lib_shared_ptr_arrays -# error "__cpp_lib_shared_ptr_arrays should be defined in c++20" -# endif -# if __cpp_lib_shared_ptr_arrays != 201707L -# error "__cpp_lib_shared_ptr_arrays should have the value 201707L in c++20" -# endif - -# ifndef __cpp_lib_shared_ptr_weak_type -# error "__cpp_lib_shared_ptr_weak_type should be defined in c++20" -# endif -# if __cpp_lib_shared_ptr_weak_type != 201606L -# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++20" -# endif - -# if _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should be defined in c++20" -# endif -# if __cpp_lib_shared_timed_mutex != 201402L -# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++20" -# endif -# else -# ifdef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifndef __cpp_lib_shift -# error "__cpp_lib_shift should be defined in c++20" -# endif -# if __cpp_lib_shift != 201806L -# error "__cpp_lib_shift should have the value 201806L in c++20" -# endif - -# ifndef __cpp_lib_smart_ptr_for_overwrite -# error "__cpp_lib_smart_ptr_for_overwrite should be defined in c++20" -# endif -# if __cpp_lib_smart_ptr_for_overwrite != 202002L -# error "__cpp_lib_smart_ptr_for_overwrite should have the value 202002L in c++20" -# endif - -# ifdef __cpp_lib_smart_ptr_owner_equality -# error "__cpp_lib_smart_ptr_owner_equality should not be defined before c++26" -# endif - -# ifndef __cpp_lib_source_location -# error "__cpp_lib_source_location should be defined in c++20" -# endif -# if __cpp_lib_source_location != 201907L -# error "__cpp_lib_source_location should have the value 201907L in c++20" -# endif - -# ifndef __cpp_lib_span -# error "__cpp_lib_span should be defined in c++20" -# endif -# if __cpp_lib_span != 202002L -# error "__cpp_lib_span should have the value 202002L in c++20" -# endif - -# ifdef __cpp_lib_span_at -# error "__cpp_lib_span_at should not be defined before c++26" -# endif - -# ifdef __cpp_lib_span_initializer_list -# error "__cpp_lib_span_initializer_list should not be defined before c++26" -# endif - -# ifdef __cpp_lib_spanstream -# error "__cpp_lib_spanstream should not be defined before c++23" -# endif - -# ifndef __cpp_lib_ssize -# error "__cpp_lib_ssize should be defined in c++20" -# endif -# if __cpp_lib_ssize != 201902L -# error "__cpp_lib_ssize should have the value 201902L in c++20" -# endif - -# ifdef __cpp_lib_sstream_from_string_view -# error "__cpp_lib_sstream_from_string_view should not be defined before c++26" -# endif - -# ifdef __cpp_lib_stacktrace -# error "__cpp_lib_stacktrace should not be defined before c++23" -# endif - -# ifndef __cpp_lib_starts_ends_with -# error "__cpp_lib_starts_ends_with should be defined in c++20" -# endif -# if __cpp_lib_starts_ends_with != 201711L -# error "__cpp_lib_starts_ends_with should have the value 201711L in c++20" -# endif - -# ifdef __cpp_lib_stdatomic_h -# error "__cpp_lib_stdatomic_h should not be defined before c++23" -# endif - -# ifdef __cpp_lib_string_contains -# error "__cpp_lib_string_contains should not be defined before c++23" -# endif - -# ifdef __cpp_lib_string_resize_and_overwrite -# error "__cpp_lib_string_resize_and_overwrite should not be defined before c++23" -# endif - -# ifndef __cpp_lib_string_udls -# error "__cpp_lib_string_udls should be defined in c++20" -# endif -# if __cpp_lib_string_udls != 201304L -# error "__cpp_lib_string_udls should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_string_view -# error "__cpp_lib_string_view should be defined in c++20" -# endif -# if __cpp_lib_string_view != 201803L -# error "__cpp_lib_string_view should have the value 201803L in c++20" -# endif - -# ifdef __cpp_lib_submdspan -# error "__cpp_lib_submdspan should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM -# ifndef __cpp_lib_syncbuf -# error "__cpp_lib_syncbuf should be defined in c++20" -# endif -# if __cpp_lib_syncbuf != 201803L -# error "__cpp_lib_syncbuf should have the value 201803L in c++20" -# endif -# else -# ifdef __cpp_lib_syncbuf -# error "__cpp_lib_syncbuf should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM' is not met!" -# endif -# endif - -# ifdef __cpp_lib_text_encoding -# error "__cpp_lib_text_encoding should not be defined before c++26" -# endif - -# ifndef __cpp_lib_three_way_comparison -# error "__cpp_lib_three_way_comparison should be defined in c++20" -# endif -# if __cpp_lib_three_way_comparison != 201907L -# error "__cpp_lib_three_way_comparison should have the value 201907L in c++20" -# endif - -# ifndef __cpp_lib_to_address -# error "__cpp_lib_to_address should be defined in c++20" -# endif -# if __cpp_lib_to_address != 201711L -# error "__cpp_lib_to_address should have the value 201711L in c++20" -# endif - -# ifndef __cpp_lib_to_array -# error "__cpp_lib_to_array should be defined in c++20" -# endif -# if __cpp_lib_to_array != 201907L -# error "__cpp_lib_to_array should have the value 201907L in c++20" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should be defined in c++20" -# endif -# if __cpp_lib_to_chars != 201611L -# error "__cpp_lib_to_chars should have the value 201611L in c++20" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_to_string -# error "__cpp_lib_to_string should not be defined before c++26" -# endif - -# ifdef __cpp_lib_to_underlying -# error "__cpp_lib_to_underlying should not be defined before c++23" -# endif - -# ifndef __cpp_lib_transformation_trait_aliases -# error "__cpp_lib_transformation_trait_aliases should be defined in c++20" -# endif -# if __cpp_lib_transformation_trait_aliases != 201304L -# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_transparent_operators -# error "__cpp_lib_transparent_operators should be defined in c++20" -# endif -# if __cpp_lib_transparent_operators != 201510L -# error "__cpp_lib_transparent_operators should have the value 201510L in c++20" -# endif - -# ifndef __cpp_lib_tuple_element_t -# error "__cpp_lib_tuple_element_t should be defined in c++20" -# endif -# if __cpp_lib_tuple_element_t != 201402L -# error "__cpp_lib_tuple_element_t should have the value 201402L in c++20" -# endif - -# ifdef __cpp_lib_tuple_like -# error "__cpp_lib_tuple_like should not be defined before c++23" -# endif - -# ifndef __cpp_lib_tuples_by_type -# error "__cpp_lib_tuples_by_type should be defined in c++20" -# endif -# if __cpp_lib_tuples_by_type != 201304L -# error "__cpp_lib_tuples_by_type should have the value 201304L in c++20" -# endif - -# ifndef __cpp_lib_type_identity -# error "__cpp_lib_type_identity should be defined in c++20" -# endif -# if __cpp_lib_type_identity != 201806L -# error "__cpp_lib_type_identity should have the value 201806L in c++20" -# endif - -# ifndef __cpp_lib_type_trait_variable_templates -# error "__cpp_lib_type_trait_variable_templates should be defined in c++20" -# endif -# if __cpp_lib_type_trait_variable_templates != 201510L -# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++20" -# endif - -# ifndef __cpp_lib_uncaught_exceptions -# error "__cpp_lib_uncaught_exceptions should be defined in c++20" -# endif -# if __cpp_lib_uncaught_exceptions != 201411L -# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++20" -# endif - -# ifndef __cpp_lib_unordered_map_try_emplace -# error "__cpp_lib_unordered_map_try_emplace should be defined in c++20" -# endif -# if __cpp_lib_unordered_map_try_emplace != 201411L -# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++20" -# endif - -# ifdef __cpp_lib_unreachable -# error "__cpp_lib_unreachable should not be defined before c++23" -# endif - -# ifndef __cpp_lib_unwrap_ref -# error "__cpp_lib_unwrap_ref should be defined in c++20" -# endif -# if __cpp_lib_unwrap_ref != 201811L -# error "__cpp_lib_unwrap_ref should have the value 201811L in c++20" -# endif - -# ifndef __cpp_lib_variant -# error "__cpp_lib_variant should be defined in c++20" -# endif -# if __cpp_lib_variant != 202106L -# error "__cpp_lib_variant should have the value 202106L in c++20" -# endif - -# ifndef __cpp_lib_void_t -# error "__cpp_lib_void_t should be defined in c++20" -# endif -# if __cpp_lib_void_t != 201411L -# error "__cpp_lib_void_t should have the value 201411L in c++20" -# endif +# ifdef __cpp_lib_freestanding_cstring +# error "__cpp_lib_freestanding_cstring should not be defined before c++26" +# endif -#elif TEST_STD_VER == 23 +# ifdef __cpp_lib_freestanding_expected +# error "__cpp_lib_freestanding_expected should not be defined before c++26" +# endif -# ifndef __cpp_lib_adaptor_iterator_pair_constructor -# error "__cpp_lib_adaptor_iterator_pair_constructor should be defined in c++23" -# endif -# if __cpp_lib_adaptor_iterator_pair_constructor != 202106L -# error "__cpp_lib_adaptor_iterator_pair_constructor should have the value 202106L in c++23" -# endif - -# ifndef __cpp_lib_addressof_constexpr -# error "__cpp_lib_addressof_constexpr should be defined in c++23" -# endif -# if __cpp_lib_addressof_constexpr != 201603L -# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++23" -# endif - -# ifndef __cpp_lib_allocate_at_least -# error "__cpp_lib_allocate_at_least should be defined in c++23" -# endif -# if __cpp_lib_allocate_at_least != 202302L -# error "__cpp_lib_allocate_at_least should have the value 202302L in c++23" -# endif - -# ifndef __cpp_lib_allocator_traits_is_always_equal -# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++23" -# endif -# if __cpp_lib_allocator_traits_is_always_equal != 201411L -# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++23" -# endif - -# ifndef __cpp_lib_any -# error "__cpp_lib_any should be defined in c++23" -# endif -# if __cpp_lib_any != 201606L -# error "__cpp_lib_any should have the value 201606L in c++23" -# endif - -# ifndef __cpp_lib_apply -# error "__cpp_lib_apply should be defined in c++23" -# endif -# if __cpp_lib_apply != 201603L -# error "__cpp_lib_apply should have the value 201603L in c++23" -# endif - -# ifndef __cpp_lib_array_constexpr -# error "__cpp_lib_array_constexpr should be defined in c++23" -# endif -# if __cpp_lib_array_constexpr != 201811L -# error "__cpp_lib_array_constexpr should have the value 201811L in c++23" -# endif - -# ifndef __cpp_lib_as_const -# error "__cpp_lib_as_const should be defined in c++23" -# endif -# if __cpp_lib_as_const != 201510L -# error "__cpp_lib_as_const should have the value 201510L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_associative_heterogeneous_erasure -# error "__cpp_lib_associative_heterogeneous_erasure should be defined in c++23" -# endif -# if __cpp_lib_associative_heterogeneous_erasure != 202110L -# error "__cpp_lib_associative_heterogeneous_erasure should have the value 202110L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_associative_heterogeneous_erasure -# error "__cpp_lib_associative_heterogeneous_erasure should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_associative_heterogeneous_insertion -# error "__cpp_lib_associative_heterogeneous_insertion should not be defined before c++26" -# endif - -# ifndef __cpp_lib_assume_aligned -# error "__cpp_lib_assume_aligned should be defined in c++23" -# endif -# if __cpp_lib_assume_aligned != 201811L -# error "__cpp_lib_assume_aligned should have the value 201811L in c++23" -# endif - -# ifndef __cpp_lib_atomic_flag_test -# error "__cpp_lib_atomic_flag_test should be defined in c++23" -# endif -# if __cpp_lib_atomic_flag_test != 201907L -# error "__cpp_lib_atomic_flag_test should have the value 201907L in c++23" -# endif - -# ifndef __cpp_lib_atomic_float -# error "__cpp_lib_atomic_float should be defined in c++23" -# endif -# if __cpp_lib_atomic_float != 201711L -# error "__cpp_lib_atomic_float should have the value 201711L in c++23" -# endif - -# ifndef __cpp_lib_atomic_is_always_lock_free -# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++23" -# endif -# if __cpp_lib_atomic_is_always_lock_free != 201603L -# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++23" -# endif - -# ifndef __cpp_lib_atomic_lock_free_type_aliases -# error "__cpp_lib_atomic_lock_free_type_aliases should be defined in c++23" -# endif -# if __cpp_lib_atomic_lock_free_type_aliases != 201907L -# error "__cpp_lib_atomic_lock_free_type_aliases should have the value 201907L in c++23" -# endif - -# ifdef __cpp_lib_atomic_min_max -# error "__cpp_lib_atomic_min_max should not be defined before c++26" -# endif - -# ifndef __cpp_lib_atomic_ref -# error "__cpp_lib_atomic_ref should be defined in c++23" -# endif -# if __cpp_lib_atomic_ref != 201806L -# error "__cpp_lib_atomic_ref should have the value 201806L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_atomic_shared_ptr -# error "__cpp_lib_atomic_shared_ptr should be defined in c++23" -# endif -# if __cpp_lib_atomic_shared_ptr != 201711L -# error "__cpp_lib_atomic_shared_ptr should have the value 201711L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_atomic_shared_ptr -# error "__cpp_lib_atomic_shared_ptr should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_atomic_value_initialization -# error "__cpp_lib_atomic_value_initialization should be defined in c++23" -# endif -# if __cpp_lib_atomic_value_initialization != 201911L -# error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC -# ifndef __cpp_lib_atomic_wait -# error "__cpp_lib_atomic_wait should be defined in c++23" -# endif -# if __cpp_lib_atomic_wait != 201907L -# error "__cpp_lib_atomic_wait should have the value 201907L in c++23" -# endif -# else -# ifdef __cpp_lib_atomic_wait -# error "__cpp_lib_atomic_wait should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_barrier -# error "__cpp_lib_barrier should be defined in c++23" -# endif -# if __cpp_lib_barrier != 201907L -# error "__cpp_lib_barrier should have the value 201907L in c++23" -# endif -# else -# ifdef __cpp_lib_barrier -# error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_bind_back -# error "__cpp_lib_bind_back should be defined in c++23" -# endif -# if __cpp_lib_bind_back != 202202L -# error "__cpp_lib_bind_back should have the value 202202L in c++23" -# endif - -# ifndef __cpp_lib_bind_front -# error "__cpp_lib_bind_front should be defined in c++23" -# endif -# if __cpp_lib_bind_front != 201907L -# error "__cpp_lib_bind_front should have the value 201907L in c++23" -# endif - -# ifndef __cpp_lib_bit_cast -# error "__cpp_lib_bit_cast should be defined in c++23" -# endif -# if __cpp_lib_bit_cast != 201806L -# error "__cpp_lib_bit_cast should have the value 201806L in c++23" -# endif - -# ifndef __cpp_lib_bitops -# error "__cpp_lib_bitops should be defined in c++23" -# endif -# if __cpp_lib_bitops != 201907L -# error "__cpp_lib_bitops should have the value 201907L in c++23" -# endif - -# ifdef __cpp_lib_bitset -# error "__cpp_lib_bitset should not be defined before c++26" -# endif - -# ifndef __cpp_lib_bool_constant -# error "__cpp_lib_bool_constant should be defined in c++23" -# endif -# if __cpp_lib_bool_constant != 201505L -# error "__cpp_lib_bool_constant should have the value 201505L in c++23" -# endif - -# ifndef __cpp_lib_bounded_array_traits -# error "__cpp_lib_bounded_array_traits should be defined in c++23" -# endif -# if __cpp_lib_bounded_array_traits != 201902L -# error "__cpp_lib_bounded_array_traits should have the value 201902L in c++23" -# endif - -# ifndef __cpp_lib_boyer_moore_searcher -# error "__cpp_lib_boyer_moore_searcher should be defined in c++23" -# endif -# if __cpp_lib_boyer_moore_searcher != 201603L -# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++23" -# endif - -# ifndef __cpp_lib_byte -# error "__cpp_lib_byte should be defined in c++23" -# endif -# if __cpp_lib_byte != 201603L -# error "__cpp_lib_byte should have the value 201603L in c++23" -# endif - -# ifndef __cpp_lib_byteswap -# error "__cpp_lib_byteswap should be defined in c++23" -# endif -# if __cpp_lib_byteswap != 202110L -# error "__cpp_lib_byteswap should have the value 202110L in c++23" -# endif - -# if defined(__cpp_char8_t) -# ifndef __cpp_lib_char8_t -# error "__cpp_lib_char8_t should be defined in c++23" -# endif -# if __cpp_lib_char8_t != 201907L -# error "__cpp_lib_char8_t should have the value 201907L in c++23" -# endif -# else -# ifdef __cpp_lib_char8_t -# error "__cpp_lib_char8_t should not be defined when the requirement 'defined(__cpp_char8_t)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_chrono -# error "__cpp_lib_chrono should be defined in c++23" -# endif -# if __cpp_lib_chrono != 201611L -# error "__cpp_lib_chrono should have the value 201611L in c++23" -# endif - -# ifndef __cpp_lib_chrono_udls -# error "__cpp_lib_chrono_udls should be defined in c++23" -# endif -# if __cpp_lib_chrono_udls != 201304L -# error "__cpp_lib_chrono_udls should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_clamp -# error "__cpp_lib_clamp should be defined in c++23" -# endif -# if __cpp_lib_clamp != 201603L -# error "__cpp_lib_clamp should have the value 201603L in c++23" -# endif - -# ifndef __cpp_lib_complex_udls -# error "__cpp_lib_complex_udls should be defined in c++23" -# endif -# if __cpp_lib_complex_udls != 201309L -# error "__cpp_lib_complex_udls should have the value 201309L in c++23" -# endif - -# ifndef __cpp_lib_concepts -# error "__cpp_lib_concepts should be defined in c++23" -# endif -# if __cpp_lib_concepts != 202002L -# error "__cpp_lib_concepts should have the value 202002L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_algorithms -# error "__cpp_lib_constexpr_algorithms should be defined in c++23" -# endif -# if __cpp_lib_constexpr_algorithms != 201806L -# error "__cpp_lib_constexpr_algorithms should have the value 201806L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_bitset -# error "__cpp_lib_constexpr_bitset should be defined in c++23" -# endif -# if __cpp_lib_constexpr_bitset != 202207L -# error "__cpp_lib_constexpr_bitset should have the value 202207L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_charconv -# error "__cpp_lib_constexpr_charconv should be defined in c++23" -# endif -# if __cpp_lib_constexpr_charconv != 202207L -# error "__cpp_lib_constexpr_charconv should have the value 202207L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_constexpr_cmath -# error "__cpp_lib_constexpr_cmath should be defined in c++23" -# endif -# if __cpp_lib_constexpr_cmath != 202202L -# error "__cpp_lib_constexpr_cmath should have the value 202202L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_constexpr_cmath -# error "__cpp_lib_constexpr_cmath should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_constexpr_complex -# error "__cpp_lib_constexpr_complex should be defined in c++23" -# endif -# if __cpp_lib_constexpr_complex != 201711L -# error "__cpp_lib_constexpr_complex should have the value 201711L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_dynamic_alloc -# error "__cpp_lib_constexpr_dynamic_alloc should be defined in c++23" -# endif -# if __cpp_lib_constexpr_dynamic_alloc != 201907L -# error "__cpp_lib_constexpr_dynamic_alloc should have the value 201907L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_functional -# error "__cpp_lib_constexpr_functional should be defined in c++23" -# endif -# if __cpp_lib_constexpr_functional != 201907L -# error "__cpp_lib_constexpr_functional should have the value 201907L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_iterator -# error "__cpp_lib_constexpr_iterator should be defined in c++23" -# endif -# if __cpp_lib_constexpr_iterator != 201811L -# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_memory -# error "__cpp_lib_constexpr_memory should be defined in c++23" -# endif -# if __cpp_lib_constexpr_memory != 202202L -# error "__cpp_lib_constexpr_memory should have the value 202202L in c++23" -# endif - -# ifdef __cpp_lib_constexpr_new -# error "__cpp_lib_constexpr_new should not be defined before c++26" -# endif - -# ifndef __cpp_lib_constexpr_numeric -# error "__cpp_lib_constexpr_numeric should be defined in c++23" -# endif -# if __cpp_lib_constexpr_numeric != 201911L -# error "__cpp_lib_constexpr_numeric should have the value 201911L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_string -# error "__cpp_lib_constexpr_string should be defined in c++23" -# endif -# if __cpp_lib_constexpr_string != 201907L -# error "__cpp_lib_constexpr_string should have the value 201907L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_string_view -# error "__cpp_lib_constexpr_string_view should be defined in c++23" -# endif -# if __cpp_lib_constexpr_string_view != 201811L -# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_tuple -# error "__cpp_lib_constexpr_tuple should be defined in c++23" -# endif -# if __cpp_lib_constexpr_tuple != 201811L -# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_typeinfo -# error "__cpp_lib_constexpr_typeinfo should be defined in c++23" -# endif -# if __cpp_lib_constexpr_typeinfo != 202106L -# error "__cpp_lib_constexpr_typeinfo should have the value 202106L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_utility -# error "__cpp_lib_constexpr_utility should be defined in c++23" -# endif -# if __cpp_lib_constexpr_utility != 201811L -# error "__cpp_lib_constexpr_utility should have the value 201811L in c++23" -# endif - -# ifndef __cpp_lib_constexpr_vector -# error "__cpp_lib_constexpr_vector should be defined in c++23" -# endif -# if __cpp_lib_constexpr_vector != 201907L -# error "__cpp_lib_constexpr_vector should have the value 201907L in c++23" -# endif - -# ifdef __cpp_lib_constrained_equality -# error "__cpp_lib_constrained_equality should not be defined before c++26" -# endif - -# ifndef __cpp_lib_containers_ranges -# error "__cpp_lib_containers_ranges should be defined in c++23" -# endif -# if __cpp_lib_containers_ranges != 202202L -# error "__cpp_lib_containers_ranges should have the value 202202L in c++23" -# endif - -# ifdef __cpp_lib_copyable_function -# error "__cpp_lib_copyable_function should not be defined before c++26" -# endif - -# ifndef __cpp_lib_coroutine -# error "__cpp_lib_coroutine should be defined in c++23" -# endif -# if __cpp_lib_coroutine != 201902L -# error "__cpp_lib_coroutine should have the value 201902L in c++23" -# endif - -# ifdef __cpp_lib_debugging -# error "__cpp_lib_debugging should not be defined before c++26" -# endif - -# ifdef __cpp_lib_default_template_type_for_algorithm_values -# error "__cpp_lib_default_template_type_for_algorithm_values should not be defined before c++26" -# endif - -# if TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L -# ifndef __cpp_lib_destroying_delete -# error "__cpp_lib_destroying_delete should be defined in c++23" -# endif -# if __cpp_lib_destroying_delete != 201806L -# error "__cpp_lib_destroying_delete should have the value 201806L in c++23" -# endif -# else -# ifdef __cpp_lib_destroying_delete -# error "__cpp_lib_destroying_delete should not be defined when the requirement 'TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L' is not met!" -# endif -# endif - -# ifndef __cpp_lib_enable_shared_from_this -# error "__cpp_lib_enable_shared_from_this should be defined in c++23" -# endif -# if __cpp_lib_enable_shared_from_this != 201603L -# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++23" -# endif - -# ifndef __cpp_lib_endian -# error "__cpp_lib_endian should be defined in c++23" -# endif -# if __cpp_lib_endian != 201907L -# error "__cpp_lib_endian should have the value 201907L in c++23" -# endif - -# ifndef __cpp_lib_erase_if -# error "__cpp_lib_erase_if should be defined in c++23" -# endif -# if __cpp_lib_erase_if != 202002L -# error "__cpp_lib_erase_if should have the value 202002L in c++23" -# endif - -# ifndef __cpp_lib_exchange_function -# error "__cpp_lib_exchange_function should be defined in c++23" -# endif -# if __cpp_lib_exchange_function != 201304L -# error "__cpp_lib_exchange_function should have the value 201304L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_execution -# error "__cpp_lib_execution should be defined in c++23" -# endif -# if __cpp_lib_execution != 201902L -# error "__cpp_lib_execution should have the value 201902L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_execution -# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_expected -# error "__cpp_lib_expected should be defined in c++23" -# endif -# if __cpp_lib_expected != 202211L -# error "__cpp_lib_expected should have the value 202211L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY) -# ifndef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should be defined in c++23" -# endif -# if __cpp_lib_filesystem != 201703L -# error "__cpp_lib_filesystem should have the value 201703L in c++23" -# endif -# else -# ifdef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_flat_map -# error "__cpp_lib_flat_map should be defined in c++23" -# endif -# if __cpp_lib_flat_map != 202207L -# error "__cpp_lib_flat_map should have the value 202207L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_flat_set -# error "__cpp_lib_flat_set should be defined in c++23" -# endif -# if __cpp_lib_flat_set != 202207L -# error "__cpp_lib_flat_set should have the value 202207L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_flat_set -# error "__cpp_lib_flat_set should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT -# ifndef __cpp_lib_format -# error "__cpp_lib_format should be defined in c++23" -# endif -# if __cpp_lib_format != 202110L -# error "__cpp_lib_format should have the value 202110L in c++23" -# endif -# else -# ifdef __cpp_lib_format -# error "__cpp_lib_format should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" -# endif -# endif - -# ifdef __cpp_lib_format_path -# error "__cpp_lib_format_path should not be defined before c++26" -# endif - -# ifndef __cpp_lib_format_ranges -# error "__cpp_lib_format_ranges should be defined in c++23" -# endif -# if __cpp_lib_format_ranges != 202207L -# error "__cpp_lib_format_ranges should have the value 202207L in c++23" -# endif - -# ifndef __cpp_lib_format_uchar -# error "__cpp_lib_format_uchar should be defined in c++23" -# endif -# if __cpp_lib_format_uchar != 202311L -# error "__cpp_lib_format_uchar should have the value 202311L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_formatters -# error "__cpp_lib_formatters should be defined in c++23" -# endif -# if __cpp_lib_formatters != 202302L -# error "__cpp_lib_formatters should have the value 202302L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_formatters -# error "__cpp_lib_formatters should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_forward_like -# error "__cpp_lib_forward_like should be defined in c++23" -# endif -# if __cpp_lib_forward_like != 202207L -# error "__cpp_lib_forward_like should have the value 202207L in c++23" -# endif - -# ifdef __cpp_lib_freestanding_algorithm -# error "__cpp_lib_freestanding_algorithm should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_array -# error "__cpp_lib_freestanding_array should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_cstring -# error "__cpp_lib_freestanding_cstring should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_expected -# error "__cpp_lib_freestanding_expected should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_mdspan -# error "__cpp_lib_freestanding_mdspan should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_optional -# error "__cpp_lib_freestanding_optional should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_string_view -# error "__cpp_lib_freestanding_string_view should not be defined before c++26" -# endif - -# ifdef __cpp_lib_freestanding_variant -# error "__cpp_lib_freestanding_variant should not be defined before c++26" -# endif - -# ifdef __cpp_lib_fstream_native_handle -# error "__cpp_lib_fstream_native_handle should not be defined before c++26" -# endif - -# ifdef __cpp_lib_function_ref -# error "__cpp_lib_function_ref should not be defined before c++26" -# endif - -# ifndef __cpp_lib_gcd_lcm -# error "__cpp_lib_gcd_lcm should be defined in c++23" -# endif -# if __cpp_lib_gcd_lcm != 201606L -# error "__cpp_lib_gcd_lcm should have the value 201606L in c++23" -# endif - -# ifdef __cpp_lib_generate_random -# error "__cpp_lib_generate_random should not be defined before c++26" -# endif - -# ifndef __cpp_lib_generic_associative_lookup -# error "__cpp_lib_generic_associative_lookup should be defined in c++23" -# endif -# if __cpp_lib_generic_associative_lookup != 201304L -# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_generic_unordered_lookup -# error "__cpp_lib_generic_unordered_lookup should be defined in c++23" -# endif -# if __cpp_lib_generic_unordered_lookup != 201811L -# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)) -# ifndef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should be defined in c++23" -# endif -# if __cpp_lib_hardware_interference_size != 201703L -# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++23" -# endif -# else -# ifdef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))' is not met!" -# endif -# endif - -# ifndef __cpp_lib_has_unique_object_representations -# error "__cpp_lib_has_unique_object_representations should be defined in c++23" -# endif -# if __cpp_lib_has_unique_object_representations != 201606L -# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++23" -# endif - -# ifdef __cpp_lib_hazard_pointer -# error "__cpp_lib_hazard_pointer should not be defined before c++26" -# endif - -# ifndef __cpp_lib_hypot -# error "__cpp_lib_hypot should be defined in c++23" -# endif -# if __cpp_lib_hypot != 201603L -# error "__cpp_lib_hypot should have the value 201603L in c++23" -# endif - -# ifndef __cpp_lib_incomplete_container_elements -# error "__cpp_lib_incomplete_container_elements should be defined in c++23" -# endif -# if __cpp_lib_incomplete_container_elements != 201505L -# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++23" -# endif - -# ifdef __cpp_lib_inplace_vector -# error "__cpp_lib_inplace_vector should not be defined before c++26" -# endif - -# ifndef __cpp_lib_int_pow2 -# error "__cpp_lib_int_pow2 should be defined in c++23" -# endif -# if __cpp_lib_int_pow2 != 202002L -# error "__cpp_lib_int_pow2 should have the value 202002L in c++23" -# endif - -# ifndef __cpp_lib_integer_comparison_functions -# error "__cpp_lib_integer_comparison_functions should be defined in c++23" -# endif -# if __cpp_lib_integer_comparison_functions != 202002L -# error "__cpp_lib_integer_comparison_functions should have the value 202002L in c++23" -# endif - -# ifndef __cpp_lib_integer_sequence -# error "__cpp_lib_integer_sequence should be defined in c++23" -# endif -# if __cpp_lib_integer_sequence != 201304L -# error "__cpp_lib_integer_sequence should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_integral_constant_callable -# error "__cpp_lib_integral_constant_callable should be defined in c++23" -# endif -# if __cpp_lib_integral_constant_callable != 201304L -# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_interpolate -# error "__cpp_lib_interpolate should be defined in c++23" -# endif -# if __cpp_lib_interpolate != 201902L -# error "__cpp_lib_interpolate should have the value 201902L in c++23" -# endif - -# ifndef __cpp_lib_invoke -# error "__cpp_lib_invoke should be defined in c++23" -# endif -# if __cpp_lib_invoke != 201411L -# error "__cpp_lib_invoke should have the value 201411L in c++23" -# endif - -# ifndef __cpp_lib_invoke_r -# error "__cpp_lib_invoke_r should be defined in c++23" -# endif -# if __cpp_lib_invoke_r != 202106L -# error "__cpp_lib_invoke_r should have the value 202106L in c++23" -# endif - -# ifndef __cpp_lib_ios_noreplace -# error "__cpp_lib_ios_noreplace should be defined in c++23" -# endif -# if __cpp_lib_ios_noreplace != 202207L -# error "__cpp_lib_ios_noreplace should have the value 202207L in c++23" -# endif - -# ifndef __cpp_lib_is_aggregate -# error "__cpp_lib_is_aggregate should be defined in c++23" -# endif -# if __cpp_lib_is_aggregate != 201703L -# error "__cpp_lib_is_aggregate should have the value 201703L in c++23" -# endif - -# ifndef __cpp_lib_is_constant_evaluated -# error "__cpp_lib_is_constant_evaluated should be defined in c++23" -# endif -# if __cpp_lib_is_constant_evaluated != 201811L -# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++23" -# endif - -# ifndef __cpp_lib_is_final -# error "__cpp_lib_is_final should be defined in c++23" -# endif -# if __cpp_lib_is_final != 201402L -# error "__cpp_lib_is_final should have the value 201402L in c++23" -# endif - -# if __has_builtin(__builtin_is_implicit_lifetime) -# ifndef __cpp_lib_is_implicit_lifetime -# error "__cpp_lib_is_implicit_lifetime should be defined in c++23" -# endif -# if __cpp_lib_is_implicit_lifetime != 202302L -# error "__cpp_lib_is_implicit_lifetime should have the value 202302L in c++23" -# endif -# else -# ifdef __cpp_lib_is_implicit_lifetime -# error "__cpp_lib_is_implicit_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_implicit_lifetime)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_is_invocable -# error "__cpp_lib_is_invocable should be defined in c++23" -# endif -# if __cpp_lib_is_invocable != 201703L -# error "__cpp_lib_is_invocable should have the value 201703L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_is_layout_compatible -# error "__cpp_lib_is_layout_compatible should be defined in c++23" -# endif -# if __cpp_lib_is_layout_compatible != 201907L -# error "__cpp_lib_is_layout_compatible should have the value 201907L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_is_layout_compatible -# error "__cpp_lib_is_layout_compatible should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_is_nothrow_convertible -# error "__cpp_lib_is_nothrow_convertible should be defined in c++23" -# endif -# if __cpp_lib_is_nothrow_convertible != 201806L -# error "__cpp_lib_is_nothrow_convertible should have the value 201806L in c++23" -# endif - -# ifndef __cpp_lib_is_null_pointer -# error "__cpp_lib_is_null_pointer should be defined in c++23" -# endif -# if __cpp_lib_is_null_pointer != 201309L -# error "__cpp_lib_is_null_pointer should have the value 201309L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_is_pointer_interconvertible -# error "__cpp_lib_is_pointer_interconvertible should be defined in c++23" -# endif -# if __cpp_lib_is_pointer_interconvertible != 201907L -# error "__cpp_lib_is_pointer_interconvertible should have the value 201907L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_is_pointer_interconvertible -# error "__cpp_lib_is_pointer_interconvertible should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_is_scoped_enum -# error "__cpp_lib_is_scoped_enum should be defined in c++23" -# endif -# if __cpp_lib_is_scoped_enum != 202011L -# error "__cpp_lib_is_scoped_enum should have the value 202011L in c++23" -# endif - -# ifndef __cpp_lib_is_swappable -# error "__cpp_lib_is_swappable should be defined in c++23" -# endif -# if __cpp_lib_is_swappable != 201603L -# error "__cpp_lib_is_swappable should have the value 201603L in c++23" -# endif - -# ifdef __cpp_lib_is_virtual_base_of -# error "__cpp_lib_is_virtual_base_of should not be defined before c++26" -# endif - -# ifdef __cpp_lib_is_within_lifetime -# error "__cpp_lib_is_within_lifetime should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_jthread -# error "__cpp_lib_jthread should be defined in c++23" -# endif -# if __cpp_lib_jthread != 201911L -# error "__cpp_lib_jthread should have the value 201911L in c++23" -# endif -# else -# ifdef __cpp_lib_jthread -# error "__cpp_lib_jthread should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_latch -# error "__cpp_lib_latch should be defined in c++23" -# endif -# if __cpp_lib_latch != 201907L -# error "__cpp_lib_latch should have the value 201907L in c++23" -# endif -# else -# ifdef __cpp_lib_latch -# error "__cpp_lib_latch should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_launder -# error "__cpp_lib_launder should be defined in c++23" -# endif -# if __cpp_lib_launder != 201606L -# error "__cpp_lib_launder should have the value 201606L in c++23" -# endif - -# ifdef __cpp_lib_linalg -# error "__cpp_lib_linalg should not be defined before c++26" -# endif - -# ifndef __cpp_lib_list_remove_return_type -# error "__cpp_lib_list_remove_return_type should be defined in c++23" -# endif -# if __cpp_lib_list_remove_return_type != 201806L -# error "__cpp_lib_list_remove_return_type should have the value 201806L in c++23" -# endif - -# ifndef __cpp_lib_logical_traits -# error "__cpp_lib_logical_traits should be defined in c++23" -# endif -# if __cpp_lib_logical_traits != 201510L -# error "__cpp_lib_logical_traits should have the value 201510L in c++23" -# endif - -# ifndef __cpp_lib_make_from_tuple -# error "__cpp_lib_make_from_tuple should be defined in c++23" -# endif -# if __cpp_lib_make_from_tuple != 201606L -# error "__cpp_lib_make_from_tuple should have the value 201606L in c++23" -# endif - -# ifndef __cpp_lib_make_reverse_iterator -# error "__cpp_lib_make_reverse_iterator should be defined in c++23" -# endif -# if __cpp_lib_make_reverse_iterator != 201402L -# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++23" -# endif - -# ifndef __cpp_lib_make_unique -# error "__cpp_lib_make_unique should be defined in c++23" -# endif -# if __cpp_lib_make_unique != 201304L -# error "__cpp_lib_make_unique should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_map_try_emplace -# error "__cpp_lib_map_try_emplace should be defined in c++23" -# endif -# if __cpp_lib_map_try_emplace != 201411L -# error "__cpp_lib_map_try_emplace should have the value 201411L in c++23" -# endif - -# ifndef __cpp_lib_math_constants -# error "__cpp_lib_math_constants should be defined in c++23" -# endif -# if __cpp_lib_math_constants != 201907L -# error "__cpp_lib_math_constants should have the value 201907L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should be defined in c++23" -# endif -# if __cpp_lib_math_special_functions != 201603L -# error "__cpp_lib_math_special_functions should have the value 201603L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_mdspan -# error "__cpp_lib_mdspan should be defined in c++23" -# endif -# if __cpp_lib_mdspan != 202207L -# error "__cpp_lib_mdspan should have the value 202207L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR -# ifndef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should be defined in c++23" -# endif -# if __cpp_lib_memory_resource != 201603L -# error "__cpp_lib_memory_resource should have the value 201603L in c++23" -# endif -# else -# ifdef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" -# endif -# endif - -# ifndef __cpp_lib_modules -# error "__cpp_lib_modules should be defined in c++23" -# endif -# if __cpp_lib_modules != 202207L -# error "__cpp_lib_modules should have the value 202207L in c++23" -# endif - -# ifndef __cpp_lib_move_iterator_concept -# error "__cpp_lib_move_iterator_concept should be defined in c++23" -# endif -# if __cpp_lib_move_iterator_concept != 202207L -# error "__cpp_lib_move_iterator_concept should have the value 202207L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_move_only_function -# error "__cpp_lib_move_only_function should be defined in c++23" -# endif -# if __cpp_lib_move_only_function != 202110L -# error "__cpp_lib_move_only_function should have the value 202110L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_move_only_function -# error "__cpp_lib_move_only_function should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_node_extract -# error "__cpp_lib_node_extract should be defined in c++23" -# endif -# if __cpp_lib_node_extract != 201606L -# error "__cpp_lib_node_extract should have the value 201606L in c++23" -# endif - -# ifndef __cpp_lib_nonmember_container_access -# error "__cpp_lib_nonmember_container_access should be defined in c++23" -# endif -# if __cpp_lib_nonmember_container_access != 201411L -# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++23" -# endif - -# ifndef __cpp_lib_not_fn -# error "__cpp_lib_not_fn should be defined in c++23" -# endif -# if __cpp_lib_not_fn != 201603L -# error "__cpp_lib_not_fn should have the value 201603L in c++23" -# endif - -# ifndef __cpp_lib_null_iterators -# error "__cpp_lib_null_iterators should be defined in c++23" -# endif -# if __cpp_lib_null_iterators != 201304L -# error "__cpp_lib_null_iterators should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_optional -# error "__cpp_lib_optional should be defined in c++23" -# endif -# if __cpp_lib_optional != 202110L -# error "__cpp_lib_optional should have the value 202110L in c++23" -# endif - -# ifdef __cpp_lib_optional_range_support -# error "__cpp_lib_optional_range_support should not be defined before c++26" -# endif - -# ifndef __cpp_lib_out_ptr -# error "__cpp_lib_out_ptr should be defined in c++23" -# endif -# if __cpp_lib_out_ptr != 202106L -# error "__cpp_lib_out_ptr should have the value 202106L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should be defined in c++23" -# endif -# if __cpp_lib_parallel_algorithm != 201603L -# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_philox_engine -# error "__cpp_lib_philox_engine should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR -# ifndef __cpp_lib_polymorphic_allocator -# error "__cpp_lib_polymorphic_allocator should be defined in c++23" -# endif -# if __cpp_lib_polymorphic_allocator != 201902L -# error "__cpp_lib_polymorphic_allocator should have the value 201902L in c++23" -# endif -# else -# ifdef __cpp_lib_polymorphic_allocator -# error "__cpp_lib_polymorphic_allocator should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT -# ifndef __cpp_lib_print -# error "__cpp_lib_print should be defined in c++23" -# endif -# if __cpp_lib_print != 202207L -# error "__cpp_lib_print should have the value 202207L in c++23" -# endif -# else -# ifdef __cpp_lib_print -# error "__cpp_lib_print should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION -# ifndef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should be defined in c++23" -# endif -# if __cpp_lib_quoted_string_io != 201304L -# error "__cpp_lib_quoted_string_io should have the value 201304L in c++23" -# endif -# else -# ifdef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" -# endif -# endif - -# ifndef __cpp_lib_ranges -# error "__cpp_lib_ranges should be defined in c++23" -# endif -# if __cpp_lib_ranges != 202406L -# error "__cpp_lib_ranges should have the value 202406L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_as_const -# error "__cpp_lib_ranges_as_const should be defined in c++23" -# endif -# if __cpp_lib_ranges_as_const != 202207L -# error "__cpp_lib_ranges_as_const should have the value 202207L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_ranges_as_const -# error "__cpp_lib_ranges_as_const should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ranges_as_rvalue -# error "__cpp_lib_ranges_as_rvalue should be defined in c++23" -# endif -# if __cpp_lib_ranges_as_rvalue != 202207L -# error "__cpp_lib_ranges_as_rvalue should have the value 202207L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should be defined in c++23" -# endif -# if __cpp_lib_ranges_chunk != 202202L -# error "__cpp_lib_ranges_chunk should have the value 202202L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ranges_chunk_by -# error "__cpp_lib_ranges_chunk_by should be defined in c++23" -# endif -# if __cpp_lib_ranges_chunk_by != 202202L -# error "__cpp_lib_ranges_chunk_by should have the value 202202L in c++23" -# endif - -# ifdef __cpp_lib_ranges_concat -# error "__cpp_lib_ranges_concat should not be defined before c++26" -# endif - -# ifndef __cpp_lib_ranges_contains -# error "__cpp_lib_ranges_contains should be defined in c++23" -# endif -# if __cpp_lib_ranges_contains != 202207L -# error "__cpp_lib_ranges_contains should have the value 202207L in c++23" -# endif - -# ifndef __cpp_lib_ranges_find_last -# error "__cpp_lib_ranges_find_last should be defined in c++23" -# endif -# if __cpp_lib_ranges_find_last != 202207L -# error "__cpp_lib_ranges_find_last should have the value 202207L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_iota -# error "__cpp_lib_ranges_iota should be defined in c++23" -# endif -# if __cpp_lib_ranges_iota != 202202L -# error "__cpp_lib_ranges_iota should have the value 202202L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_ranges_iota -# error "__cpp_lib_ranges_iota should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_join_with -# error "__cpp_lib_ranges_join_with should be defined in c++23" -# endif -# if __cpp_lib_ranges_join_with != 202202L -# error "__cpp_lib_ranges_join_with should have the value 202202L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_ranges_join_with -# error "__cpp_lib_ranges_join_with should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ranges_repeat -# error "__cpp_lib_ranges_repeat should be defined in c++23" -# endif -# if __cpp_lib_ranges_repeat != 202207L -# error "__cpp_lib_ranges_repeat should have the value 202207L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_slide -# error "__cpp_lib_ranges_slide should be defined in c++23" -# endif -# if __cpp_lib_ranges_slide != 202202L -# error "__cpp_lib_ranges_slide should have the value 202202L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_ranges_slide -# error "__cpp_lib_ranges_slide should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ranges_starts_ends_with -# error "__cpp_lib_ranges_starts_ends_with should be defined in c++23" -# endif -# if __cpp_lib_ranges_starts_ends_with != 202106L -# error "__cpp_lib_ranges_starts_ends_with should have the value 202106L in c++23" -# endif - -# ifndef __cpp_lib_ranges_stride -# error "__cpp_lib_ranges_stride should be defined in c++23" -# endif -# if __cpp_lib_ranges_stride != 202207L -# error "__cpp_lib_ranges_stride should have the value 202207L in c++23" -# endif - -# ifndef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should be defined in c++23" -# endif -# if __cpp_lib_ranges_to_container != 202202L -# error "__cpp_lib_ranges_to_container should have the value 202202L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_zip -# error "__cpp_lib_ranges_zip should be defined in c++23" -# endif -# if __cpp_lib_ranges_zip != 202110L -# error "__cpp_lib_ranges_zip should have the value 202110L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_ranges_zip -# error "__cpp_lib_ranges_zip should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_ratio -# error "__cpp_lib_ratio should not be defined before c++26" -# endif - -# ifndef __cpp_lib_raw_memory_algorithms -# error "__cpp_lib_raw_memory_algorithms should be defined in c++23" -# endif -# if __cpp_lib_raw_memory_algorithms != 201606L -# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++23" -# endif - -# ifdef __cpp_lib_rcu -# error "__cpp_lib_rcu should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_reference_from_temporary -# error "__cpp_lib_reference_from_temporary should be defined in c++23" -# endif -# if __cpp_lib_reference_from_temporary != 202202L -# error "__cpp_lib_reference_from_temporary should have the value 202202L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_reference_from_temporary -# error "__cpp_lib_reference_from_temporary should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_reference_wrapper -# error "__cpp_lib_reference_wrapper should not be defined before c++26" -# endif - -# ifndef __cpp_lib_remove_cvref -# error "__cpp_lib_remove_cvref should be defined in c++23" -# endif -# if __cpp_lib_remove_cvref != 201711L -# error "__cpp_lib_remove_cvref should have the value 201711L in c++23" -# endif - -# ifndef __cpp_lib_result_of_sfinae -# error "__cpp_lib_result_of_sfinae should be defined in c++23" -# endif -# if __cpp_lib_result_of_sfinae != 201210L -# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++23" -# endif - -# ifndef __cpp_lib_robust_nonmodifying_seq_ops -# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++23" -# endif -# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L -# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_sample -# error "__cpp_lib_sample should be defined in c++23" -# endif -# if __cpp_lib_sample != 201603L -# error "__cpp_lib_sample should have the value 201603L in c++23" -# endif - -# ifdef __cpp_lib_saturation_arithmetic -# error "__cpp_lib_saturation_arithmetic should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should be defined in c++23" -# endif -# if __cpp_lib_scoped_lock != 201703L -# error "__cpp_lib_scoped_lock should have the value 201703L in c++23" -# endif -# else -# ifdef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_semaphore -# error "__cpp_lib_semaphore should be defined in c++23" -# endif -# if __cpp_lib_semaphore != 201907L -# error "__cpp_lib_semaphore should have the value 201907L in c++23" -# endif -# else -# ifdef __cpp_lib_semaphore -# error "__cpp_lib_semaphore should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# ifdef __cpp_lib_senders -# error "__cpp_lib_senders should not be defined before c++26" -# endif - -# if _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should be defined in c++23" -# endif -# if __cpp_lib_shared_mutex != 201505L -# error "__cpp_lib_shared_mutex should have the value 201505L in c++23" -# endif -# else -# ifdef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifndef __cpp_lib_shared_ptr_arrays -# error "__cpp_lib_shared_ptr_arrays should be defined in c++23" -# endif -# if __cpp_lib_shared_ptr_arrays != 201707L -# error "__cpp_lib_shared_ptr_arrays should have the value 201707L in c++23" -# endif - -# ifndef __cpp_lib_shared_ptr_weak_type -# error "__cpp_lib_shared_ptr_weak_type should be defined in c++23" -# endif -# if __cpp_lib_shared_ptr_weak_type != 201606L -# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++23" -# endif - -# if _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should be defined in c++23" -# endif -# if __cpp_lib_shared_timed_mutex != 201402L -# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++23" -# endif -# else -# ifdef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifndef __cpp_lib_shift -# error "__cpp_lib_shift should be defined in c++23" -# endif -# if __cpp_lib_shift != 201806L -# error "__cpp_lib_shift should have the value 201806L in c++23" -# endif - -# ifndef __cpp_lib_smart_ptr_for_overwrite -# error "__cpp_lib_smart_ptr_for_overwrite should be defined in c++23" -# endif -# if __cpp_lib_smart_ptr_for_overwrite != 202002L -# error "__cpp_lib_smart_ptr_for_overwrite should have the value 202002L in c++23" -# endif - -# ifdef __cpp_lib_smart_ptr_owner_equality -# error "__cpp_lib_smart_ptr_owner_equality should not be defined before c++26" -# endif - -# ifndef __cpp_lib_source_location -# error "__cpp_lib_source_location should be defined in c++23" -# endif -# if __cpp_lib_source_location != 201907L -# error "__cpp_lib_source_location should have the value 201907L in c++23" -# endif - -# ifndef __cpp_lib_span -# error "__cpp_lib_span should be defined in c++23" -# endif -# if __cpp_lib_span != 202002L -# error "__cpp_lib_span should have the value 202002L in c++23" -# endif - -# ifdef __cpp_lib_span_at -# error "__cpp_lib_span_at should not be defined before c++26" -# endif - -# ifdef __cpp_lib_span_initializer_list -# error "__cpp_lib_span_initializer_list should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_spanstream -# error "__cpp_lib_spanstream should be defined in c++23" -# endif -# if __cpp_lib_spanstream != 202106L -# error "__cpp_lib_spanstream should have the value 202106L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_spanstream -# error "__cpp_lib_spanstream should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ssize -# error "__cpp_lib_ssize should be defined in c++23" -# endif -# if __cpp_lib_ssize != 201902L -# error "__cpp_lib_ssize should have the value 201902L in c++23" -# endif - -# ifdef __cpp_lib_sstream_from_string_view -# error "__cpp_lib_sstream_from_string_view should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_stacktrace -# error "__cpp_lib_stacktrace should be defined in c++23" -# endif -# if __cpp_lib_stacktrace != 202011L -# error "__cpp_lib_stacktrace should have the value 202011L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_stacktrace -# error "__cpp_lib_stacktrace should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_starts_ends_with -# error "__cpp_lib_starts_ends_with should be defined in c++23" -# endif -# if __cpp_lib_starts_ends_with != 201711L -# error "__cpp_lib_starts_ends_with should have the value 201711L in c++23" -# endif - -# ifndef __cpp_lib_stdatomic_h -# error "__cpp_lib_stdatomic_h should be defined in c++23" -# endif -# if __cpp_lib_stdatomic_h != 202011L -# error "__cpp_lib_stdatomic_h should have the value 202011L in c++23" -# endif - -# ifndef __cpp_lib_string_contains -# error "__cpp_lib_string_contains should be defined in c++23" -# endif -# if __cpp_lib_string_contains != 202011L -# error "__cpp_lib_string_contains should have the value 202011L in c++23" -# endif - -# ifndef __cpp_lib_string_resize_and_overwrite -# error "__cpp_lib_string_resize_and_overwrite should be defined in c++23" -# endif -# if __cpp_lib_string_resize_and_overwrite != 202110L -# error "__cpp_lib_string_resize_and_overwrite should have the value 202110L in c++23" -# endif - -# ifndef __cpp_lib_string_udls -# error "__cpp_lib_string_udls should be defined in c++23" -# endif -# if __cpp_lib_string_udls != 201304L -# error "__cpp_lib_string_udls should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_string_view -# error "__cpp_lib_string_view should be defined in c++23" -# endif -# if __cpp_lib_string_view != 201803L -# error "__cpp_lib_string_view should have the value 201803L in c++23" -# endif - -# ifdef __cpp_lib_submdspan -# error "__cpp_lib_submdspan should not be defined before c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM -# ifndef __cpp_lib_syncbuf -# error "__cpp_lib_syncbuf should be defined in c++23" -# endif -# if __cpp_lib_syncbuf != 201803L -# error "__cpp_lib_syncbuf should have the value 201803L in c++23" -# endif -# else -# ifdef __cpp_lib_syncbuf -# error "__cpp_lib_syncbuf should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM' is not met!" -# endif -# endif - -# ifdef __cpp_lib_text_encoding -# error "__cpp_lib_text_encoding should not be defined before c++26" -# endif - -# ifndef __cpp_lib_three_way_comparison -# error "__cpp_lib_three_way_comparison should be defined in c++23" -# endif -# if __cpp_lib_three_way_comparison != 201907L -# error "__cpp_lib_three_way_comparison should have the value 201907L in c++23" -# endif - -# ifndef __cpp_lib_to_address -# error "__cpp_lib_to_address should be defined in c++23" -# endif -# if __cpp_lib_to_address != 201711L -# error "__cpp_lib_to_address should have the value 201711L in c++23" -# endif - -# ifndef __cpp_lib_to_array -# error "__cpp_lib_to_array should be defined in c++23" -# endif -# if __cpp_lib_to_array != 201907L -# error "__cpp_lib_to_array should have the value 201907L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should be defined in c++23" -# endif -# if __cpp_lib_to_chars != 201611L -# error "__cpp_lib_to_chars should have the value 201611L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifdef __cpp_lib_to_string -# error "__cpp_lib_to_string should not be defined before c++26" -# endif - -# ifndef __cpp_lib_to_underlying -# error "__cpp_lib_to_underlying should be defined in c++23" -# endif -# if __cpp_lib_to_underlying != 202102L -# error "__cpp_lib_to_underlying should have the value 202102L in c++23" -# endif - -# ifndef __cpp_lib_transformation_trait_aliases -# error "__cpp_lib_transformation_trait_aliases should be defined in c++23" -# endif -# if __cpp_lib_transformation_trait_aliases != 201304L -# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_transparent_operators -# error "__cpp_lib_transparent_operators should be defined in c++23" -# endif -# if __cpp_lib_transparent_operators != 201510L -# error "__cpp_lib_transparent_operators should have the value 201510L in c++23" -# endif - -# ifndef __cpp_lib_tuple_element_t -# error "__cpp_lib_tuple_element_t should be defined in c++23" -# endif -# if __cpp_lib_tuple_element_t != 201402L -# error "__cpp_lib_tuple_element_t should have the value 201402L in c++23" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_tuple_like -# error "__cpp_lib_tuple_like should be defined in c++23" -# endif -# if __cpp_lib_tuple_like != 202207L -# error "__cpp_lib_tuple_like should have the value 202207L in c++23" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_tuple_like -# error "__cpp_lib_tuple_like should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_tuples_by_type -# error "__cpp_lib_tuples_by_type should be defined in c++23" -# endif -# if __cpp_lib_tuples_by_type != 201304L -# error "__cpp_lib_tuples_by_type should have the value 201304L in c++23" -# endif - -# ifndef __cpp_lib_type_identity -# error "__cpp_lib_type_identity should be defined in c++23" -# endif -# if __cpp_lib_type_identity != 201806L -# error "__cpp_lib_type_identity should have the value 201806L in c++23" -# endif - -# ifndef __cpp_lib_type_trait_variable_templates -# error "__cpp_lib_type_trait_variable_templates should be defined in c++23" -# endif -# if __cpp_lib_type_trait_variable_templates != 201510L -# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++23" -# endif - -# ifndef __cpp_lib_uncaught_exceptions -# error "__cpp_lib_uncaught_exceptions should be defined in c++23" -# endif -# if __cpp_lib_uncaught_exceptions != 201411L -# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++23" -# endif - -# ifndef __cpp_lib_unordered_map_try_emplace -# error "__cpp_lib_unordered_map_try_emplace should be defined in c++23" -# endif -# if __cpp_lib_unordered_map_try_emplace != 201411L -# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++23" -# endif - -# ifndef __cpp_lib_unreachable -# error "__cpp_lib_unreachable should be defined in c++23" -# endif -# if __cpp_lib_unreachable != 202202L -# error "__cpp_lib_unreachable should have the value 202202L in c++23" -# endif - -# ifndef __cpp_lib_unwrap_ref -# error "__cpp_lib_unwrap_ref should be defined in c++23" -# endif -# if __cpp_lib_unwrap_ref != 201811L -# error "__cpp_lib_unwrap_ref should have the value 201811L in c++23" -# endif - -# ifndef __cpp_lib_variant -# error "__cpp_lib_variant should be defined in c++23" -# endif -# if __cpp_lib_variant != 202106L -# error "__cpp_lib_variant should have the value 202106L in c++23" -# endif - -# ifndef __cpp_lib_void_t -# error "__cpp_lib_void_t should be defined in c++23" -# endif -# if __cpp_lib_void_t != 201411L -# error "__cpp_lib_void_t should have the value 201411L in c++23" -# endif +# ifdef __cpp_lib_freestanding_mdspan +# error "__cpp_lib_freestanding_mdspan should not be defined before c++26" +# endif -#elif TEST_STD_VER > 23 +# ifdef __cpp_lib_freestanding_optional +# error "__cpp_lib_freestanding_optional should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_string_view +# error "__cpp_lib_freestanding_string_view should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_variant +# error "__cpp_lib_freestanding_variant should not be defined before c++26" +# endif + +# ifdef __cpp_lib_fstream_native_handle +# error "__cpp_lib_fstream_native_handle should not be defined before c++26" +# endif + +# ifdef __cpp_lib_function_ref +# error "__cpp_lib_function_ref should not be defined before c++26" +# endif + +# ifdef __cpp_lib_gcd_lcm +# error "__cpp_lib_gcd_lcm should not be defined before c++17" +# endif + +# ifdef __cpp_lib_generate_random +# error "__cpp_lib_generate_random should not be defined before c++26" +# endif + +# ifndef __cpp_lib_generic_associative_lookup +# error "__cpp_lib_generic_associative_lookup should be defined in c++14" +# endif +# if __cpp_lib_generic_associative_lookup != 201304L +# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++14" +# endif + +# ifdef __cpp_lib_generic_unordered_lookup +# error "__cpp_lib_generic_unordered_lookup should not be defined before c++20" +# endif + +# ifdef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should not be defined before c++17" +# endif + +# ifdef __cpp_lib_has_unique_object_representations +# error "__cpp_lib_has_unique_object_representations should not be defined before c++17" +# endif + +# ifdef __cpp_lib_hazard_pointer +# error "__cpp_lib_hazard_pointer should not be defined before c++26" +# endif + +# ifdef __cpp_lib_hypot +# error "__cpp_lib_hypot should not be defined before c++17" +# endif + +# ifdef __cpp_lib_incomplete_container_elements +# error "__cpp_lib_incomplete_container_elements should not be defined before c++17" +# endif + +# ifdef __cpp_lib_inplace_vector +# error "__cpp_lib_inplace_vector should not be defined before c++26" +# endif + +# ifdef __cpp_lib_int_pow2 +# error "__cpp_lib_int_pow2 should not be defined before c++20" +# endif + +# ifdef __cpp_lib_integer_comparison_functions +# error "__cpp_lib_integer_comparison_functions should not be defined before c++20" +# endif -# ifndef __cpp_lib_adaptor_iterator_pair_constructor -# error "__cpp_lib_adaptor_iterator_pair_constructor should be defined in c++26" -# endif -# if __cpp_lib_adaptor_iterator_pair_constructor != 202106L -# error "__cpp_lib_adaptor_iterator_pair_constructor should have the value 202106L in c++26" -# endif - -# ifndef __cpp_lib_addressof_constexpr -# error "__cpp_lib_addressof_constexpr should be defined in c++26" -# endif -# if __cpp_lib_addressof_constexpr != 201603L -# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_allocate_at_least -# error "__cpp_lib_allocate_at_least should be defined in c++26" -# endif -# if __cpp_lib_allocate_at_least != 202302L -# error "__cpp_lib_allocate_at_least should have the value 202302L in c++26" -# endif - -# ifndef __cpp_lib_allocator_traits_is_always_equal -# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++26" -# endif -# if __cpp_lib_allocator_traits_is_always_equal != 201411L -# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++26" -# endif - -# ifndef __cpp_lib_any -# error "__cpp_lib_any should be defined in c++26" -# endif -# if __cpp_lib_any != 201606L -# error "__cpp_lib_any should have the value 201606L in c++26" -# endif - -# ifndef __cpp_lib_apply -# error "__cpp_lib_apply should be defined in c++26" -# endif -# if __cpp_lib_apply != 201603L -# error "__cpp_lib_apply should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_array_constexpr -# error "__cpp_lib_array_constexpr should be defined in c++26" -# endif -# if __cpp_lib_array_constexpr != 201811L -# error "__cpp_lib_array_constexpr should have the value 201811L in c++26" -# endif - -# ifndef __cpp_lib_as_const -# error "__cpp_lib_as_const should be defined in c++26" -# endif -# if __cpp_lib_as_const != 201510L -# error "__cpp_lib_as_const should have the value 201510L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_associative_heterogeneous_erasure -# error "__cpp_lib_associative_heterogeneous_erasure should be defined in c++26" -# endif -# if __cpp_lib_associative_heterogeneous_erasure != 202110L -# error "__cpp_lib_associative_heterogeneous_erasure should have the value 202110L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_associative_heterogeneous_erasure -# error "__cpp_lib_associative_heterogeneous_erasure should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_associative_heterogeneous_insertion -# error "__cpp_lib_associative_heterogeneous_insertion should be defined in c++26" -# endif -# if __cpp_lib_associative_heterogeneous_insertion != 202306L -# error "__cpp_lib_associative_heterogeneous_insertion should have the value 202306L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_associative_heterogeneous_insertion -# error "__cpp_lib_associative_heterogeneous_insertion should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_assume_aligned -# error "__cpp_lib_assume_aligned should be defined in c++26" -# endif -# if __cpp_lib_assume_aligned != 201811L -# error "__cpp_lib_assume_aligned should have the value 201811L in c++26" -# endif - -# ifndef __cpp_lib_atomic_flag_test -# error "__cpp_lib_atomic_flag_test should be defined in c++26" -# endif -# if __cpp_lib_atomic_flag_test != 201907L -# error "__cpp_lib_atomic_flag_test should have the value 201907L in c++26" -# endif - -# ifndef __cpp_lib_atomic_float -# error "__cpp_lib_atomic_float should be defined in c++26" -# endif -# if __cpp_lib_atomic_float != 201711L -# error "__cpp_lib_atomic_float should have the value 201711L in c++26" -# endif - -# ifndef __cpp_lib_atomic_is_always_lock_free -# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++26" -# endif -# if __cpp_lib_atomic_is_always_lock_free != 201603L -# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_atomic_lock_free_type_aliases -# error "__cpp_lib_atomic_lock_free_type_aliases should be defined in c++26" -# endif -# if __cpp_lib_atomic_lock_free_type_aliases != 201907L -# error "__cpp_lib_atomic_lock_free_type_aliases should have the value 201907L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_atomic_min_max -# error "__cpp_lib_atomic_min_max should be defined in c++26" -# endif -# if __cpp_lib_atomic_min_max != 202403L -# error "__cpp_lib_atomic_min_max should have the value 202403L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_atomic_min_max -# error "__cpp_lib_atomic_min_max should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_atomic_ref -# error "__cpp_lib_atomic_ref should be defined in c++26" -# endif -# if __cpp_lib_atomic_ref != 201806L -# error "__cpp_lib_atomic_ref should have the value 201806L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_atomic_shared_ptr -# error "__cpp_lib_atomic_shared_ptr should be defined in c++26" -# endif -# if __cpp_lib_atomic_shared_ptr != 201711L -# error "__cpp_lib_atomic_shared_ptr should have the value 201711L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_atomic_shared_ptr -# error "__cpp_lib_atomic_shared_ptr should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_atomic_value_initialization -# error "__cpp_lib_atomic_value_initialization should be defined in c++26" -# endif -# if __cpp_lib_atomic_value_initialization != 201911L -# error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC -# ifndef __cpp_lib_atomic_wait -# error "__cpp_lib_atomic_wait should be defined in c++26" -# endif -# if __cpp_lib_atomic_wait != 201907L -# error "__cpp_lib_atomic_wait should have the value 201907L in c++26" -# endif -# else -# ifdef __cpp_lib_atomic_wait -# error "__cpp_lib_atomic_wait should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_barrier -# error "__cpp_lib_barrier should be defined in c++26" -# endif -# if __cpp_lib_barrier != 201907L -# error "__cpp_lib_barrier should have the value 201907L in c++26" -# endif -# else -# ifdef __cpp_lib_barrier -# error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_bind_back -# error "__cpp_lib_bind_back should be defined in c++26" -# endif -# if __cpp_lib_bind_back != 202202L -# error "__cpp_lib_bind_back should have the value 202202L in c++26" -# endif - -# ifndef __cpp_lib_bind_front -# error "__cpp_lib_bind_front should be defined in c++26" -# endif -# if __cpp_lib_bind_front != 202306L -# error "__cpp_lib_bind_front should have the value 202306L in c++26" -# endif - -# ifndef __cpp_lib_bit_cast -# error "__cpp_lib_bit_cast should be defined in c++26" -# endif -# if __cpp_lib_bit_cast != 201806L -# error "__cpp_lib_bit_cast should have the value 201806L in c++26" -# endif - -# ifndef __cpp_lib_bitops -# error "__cpp_lib_bitops should be defined in c++26" -# endif -# if __cpp_lib_bitops != 201907L -# error "__cpp_lib_bitops should have the value 201907L in c++26" -# endif - -# ifndef __cpp_lib_bitset -# error "__cpp_lib_bitset should be defined in c++26" -# endif -# if __cpp_lib_bitset != 202306L -# error "__cpp_lib_bitset should have the value 202306L in c++26" -# endif - -# ifndef __cpp_lib_bool_constant -# error "__cpp_lib_bool_constant should be defined in c++26" -# endif -# if __cpp_lib_bool_constant != 201505L -# error "__cpp_lib_bool_constant should have the value 201505L in c++26" -# endif - -# ifndef __cpp_lib_bounded_array_traits -# error "__cpp_lib_bounded_array_traits should be defined in c++26" -# endif -# if __cpp_lib_bounded_array_traits != 201902L -# error "__cpp_lib_bounded_array_traits should have the value 201902L in c++26" -# endif - -# ifndef __cpp_lib_boyer_moore_searcher -# error "__cpp_lib_boyer_moore_searcher should be defined in c++26" -# endif -# if __cpp_lib_boyer_moore_searcher != 201603L -# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_byte -# error "__cpp_lib_byte should be defined in c++26" -# endif -# if __cpp_lib_byte != 201603L -# error "__cpp_lib_byte should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_byteswap -# error "__cpp_lib_byteswap should be defined in c++26" -# endif -# if __cpp_lib_byteswap != 202110L -# error "__cpp_lib_byteswap should have the value 202110L in c++26" -# endif - -# if defined(__cpp_char8_t) -# ifndef __cpp_lib_char8_t -# error "__cpp_lib_char8_t should be defined in c++26" -# endif -# if __cpp_lib_char8_t != 201907L -# error "__cpp_lib_char8_t should have the value 201907L in c++26" -# endif -# else -# ifdef __cpp_lib_char8_t -# error "__cpp_lib_char8_t should not be defined when the requirement 'defined(__cpp_char8_t)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_chrono -# error "__cpp_lib_chrono should be defined in c++26" -# endif -# if __cpp_lib_chrono != 201611L -# error "__cpp_lib_chrono should have the value 201611L in c++26" -# endif - -# ifndef __cpp_lib_chrono_udls -# error "__cpp_lib_chrono_udls should be defined in c++26" -# endif -# if __cpp_lib_chrono_udls != 201304L -# error "__cpp_lib_chrono_udls should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_clamp -# error "__cpp_lib_clamp should be defined in c++26" -# endif -# if __cpp_lib_clamp != 201603L -# error "__cpp_lib_clamp should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_complex_udls -# error "__cpp_lib_complex_udls should be defined in c++26" -# endif -# if __cpp_lib_complex_udls != 201309L -# error "__cpp_lib_complex_udls should have the value 201309L in c++26" -# endif - -# ifndef __cpp_lib_concepts -# error "__cpp_lib_concepts should be defined in c++26" -# endif -# if __cpp_lib_concepts != 202002L -# error "__cpp_lib_concepts should have the value 202002L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_algorithms -# error "__cpp_lib_constexpr_algorithms should be defined in c++26" -# endif -# if __cpp_lib_constexpr_algorithms != 201806L -# error "__cpp_lib_constexpr_algorithms should have the value 201806L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_bitset -# error "__cpp_lib_constexpr_bitset should be defined in c++26" -# endif -# if __cpp_lib_constexpr_bitset != 202207L -# error "__cpp_lib_constexpr_bitset should have the value 202207L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_charconv -# error "__cpp_lib_constexpr_charconv should be defined in c++26" -# endif -# if __cpp_lib_constexpr_charconv != 202207L -# error "__cpp_lib_constexpr_charconv should have the value 202207L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_constexpr_cmath -# error "__cpp_lib_constexpr_cmath should be defined in c++26" -# endif -# if __cpp_lib_constexpr_cmath != 202202L -# error "__cpp_lib_constexpr_cmath should have the value 202202L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_constexpr_cmath -# error "__cpp_lib_constexpr_cmath should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_constexpr_complex -# error "__cpp_lib_constexpr_complex should be defined in c++26" -# endif -# if __cpp_lib_constexpr_complex != 201711L -# error "__cpp_lib_constexpr_complex should have the value 201711L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_dynamic_alloc -# error "__cpp_lib_constexpr_dynamic_alloc should be defined in c++26" -# endif -# if __cpp_lib_constexpr_dynamic_alloc != 201907L -# error "__cpp_lib_constexpr_dynamic_alloc should have the value 201907L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_functional -# error "__cpp_lib_constexpr_functional should be defined in c++26" -# endif -# if __cpp_lib_constexpr_functional != 201907L -# error "__cpp_lib_constexpr_functional should have the value 201907L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_iterator -# error "__cpp_lib_constexpr_iterator should be defined in c++26" -# endif -# if __cpp_lib_constexpr_iterator != 201811L -# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_memory -# error "__cpp_lib_constexpr_memory should be defined in c++26" -# endif -# if __cpp_lib_constexpr_memory != 202202L -# error "__cpp_lib_constexpr_memory should have the value 202202L in c++26" -# endif - -# if !defined(_LIBCPP_ABI_VCRUNTIME) -# ifndef __cpp_lib_constexpr_new -# error "__cpp_lib_constexpr_new should be defined in c++26" -# endif -# if __cpp_lib_constexpr_new != 202406L -# error "__cpp_lib_constexpr_new should have the value 202406L in c++26" -# endif -# else -# ifdef __cpp_lib_constexpr_new -# error "__cpp_lib_constexpr_new should not be defined when the requirement '!defined(_LIBCPP_ABI_VCRUNTIME)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_constexpr_numeric -# error "__cpp_lib_constexpr_numeric should be defined in c++26" -# endif -# if __cpp_lib_constexpr_numeric != 201911L -# error "__cpp_lib_constexpr_numeric should have the value 201911L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_string -# error "__cpp_lib_constexpr_string should be defined in c++26" -# endif -# if __cpp_lib_constexpr_string != 201907L -# error "__cpp_lib_constexpr_string should have the value 201907L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_string_view -# error "__cpp_lib_constexpr_string_view should be defined in c++26" -# endif -# if __cpp_lib_constexpr_string_view != 201811L -# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_tuple -# error "__cpp_lib_constexpr_tuple should be defined in c++26" -# endif -# if __cpp_lib_constexpr_tuple != 201811L -# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_typeinfo -# error "__cpp_lib_constexpr_typeinfo should be defined in c++26" -# endif -# if __cpp_lib_constexpr_typeinfo != 202106L -# error "__cpp_lib_constexpr_typeinfo should have the value 202106L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_utility -# error "__cpp_lib_constexpr_utility should be defined in c++26" -# endif -# if __cpp_lib_constexpr_utility != 201811L -# error "__cpp_lib_constexpr_utility should have the value 201811L in c++26" -# endif - -# ifndef __cpp_lib_constexpr_vector -# error "__cpp_lib_constexpr_vector should be defined in c++26" -# endif -# if __cpp_lib_constexpr_vector != 201907L -# error "__cpp_lib_constexpr_vector should have the value 201907L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_constrained_equality -# error "__cpp_lib_constrained_equality should be defined in c++26" -# endif -# if __cpp_lib_constrained_equality != 202403L -# error "__cpp_lib_constrained_equality should have the value 202403L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_constrained_equality -# error "__cpp_lib_constrained_equality should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_containers_ranges -# error "__cpp_lib_containers_ranges should be defined in c++26" -# endif -# if __cpp_lib_containers_ranges != 202202L -# error "__cpp_lib_containers_ranges should have the value 202202L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_copyable_function -# error "__cpp_lib_copyable_function should be defined in c++26" -# endif -# if __cpp_lib_copyable_function != 202306L -# error "__cpp_lib_copyable_function should have the value 202306L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_copyable_function -# error "__cpp_lib_copyable_function should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_coroutine -# error "__cpp_lib_coroutine should be defined in c++26" -# endif -# if __cpp_lib_coroutine != 201902L -# error "__cpp_lib_coroutine should have the value 201902L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_debugging -# error "__cpp_lib_debugging should be defined in c++26" -# endif -# if __cpp_lib_debugging != 202311L -# error "__cpp_lib_debugging should have the value 202311L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_debugging -# error "__cpp_lib_debugging should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_default_template_type_for_algorithm_values -# error "__cpp_lib_default_template_type_for_algorithm_values should be defined in c++26" -# endif -# if __cpp_lib_default_template_type_for_algorithm_values != 202403L -# error "__cpp_lib_default_template_type_for_algorithm_values should have the value 202403L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_default_template_type_for_algorithm_values -# error "__cpp_lib_default_template_type_for_algorithm_values should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L -# ifndef __cpp_lib_destroying_delete -# error "__cpp_lib_destroying_delete should be defined in c++26" -# endif -# if __cpp_lib_destroying_delete != 201806L -# error "__cpp_lib_destroying_delete should have the value 201806L in c++26" -# endif -# else -# ifdef __cpp_lib_destroying_delete -# error "__cpp_lib_destroying_delete should not be defined when the requirement 'TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L' is not met!" -# endif -# endif - -# ifndef __cpp_lib_enable_shared_from_this -# error "__cpp_lib_enable_shared_from_this should be defined in c++26" -# endif -# if __cpp_lib_enable_shared_from_this != 201603L -# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_endian -# error "__cpp_lib_endian should be defined in c++26" -# endif -# if __cpp_lib_endian != 201907L -# error "__cpp_lib_endian should have the value 201907L in c++26" -# endif - -# ifndef __cpp_lib_erase_if -# error "__cpp_lib_erase_if should be defined in c++26" -# endif -# if __cpp_lib_erase_if != 202002L -# error "__cpp_lib_erase_if should have the value 202002L in c++26" -# endif - -# ifndef __cpp_lib_exchange_function -# error "__cpp_lib_exchange_function should be defined in c++26" -# endif -# if __cpp_lib_exchange_function != 201304L -# error "__cpp_lib_exchange_function should have the value 201304L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_execution -# error "__cpp_lib_execution should be defined in c++26" -# endif -# if __cpp_lib_execution != 201902L -# error "__cpp_lib_execution should have the value 201902L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_execution -# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_expected -# error "__cpp_lib_expected should be defined in c++26" -# endif -# if __cpp_lib_expected != 202211L -# error "__cpp_lib_expected should have the value 202211L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY) -# ifndef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should be defined in c++26" -# endif -# if __cpp_lib_filesystem != 201703L -# error "__cpp_lib_filesystem should have the value 201703L in c++26" -# endif -# else -# ifdef __cpp_lib_filesystem -# error "__cpp_lib_filesystem should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_flat_map -# error "__cpp_lib_flat_map should be defined in c++26" -# endif -# if __cpp_lib_flat_map != 202207L -# error "__cpp_lib_flat_map should have the value 202207L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_flat_set -# error "__cpp_lib_flat_set should be defined in c++26" -# endif -# if __cpp_lib_flat_set != 202207L -# error "__cpp_lib_flat_set should have the value 202207L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_flat_set -# error "__cpp_lib_flat_set should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT -# ifndef __cpp_lib_format -# error "__cpp_lib_format should be defined in c++26" -# endif -# if __cpp_lib_format != 202110L -# error "__cpp_lib_format should have the value 202110L in c++26" -# endif -# else -# ifdef __cpp_lib_format -# error "__cpp_lib_format should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_format_path -# error "__cpp_lib_format_path should be defined in c++26" -# endif -# if __cpp_lib_format_path != 202403L -# error "__cpp_lib_format_path should have the value 202403L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_format_path -# error "__cpp_lib_format_path should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_format_ranges -# error "__cpp_lib_format_ranges should be defined in c++26" -# endif -# if __cpp_lib_format_ranges != 202207L -# error "__cpp_lib_format_ranges should have the value 202207L in c++26" -# endif - -# ifndef __cpp_lib_format_uchar -# error "__cpp_lib_format_uchar should be defined in c++26" -# endif -# if __cpp_lib_format_uchar != 202311L -# error "__cpp_lib_format_uchar should have the value 202311L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_formatters -# error "__cpp_lib_formatters should be defined in c++26" -# endif -# if __cpp_lib_formatters != 202302L -# error "__cpp_lib_formatters should have the value 202302L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_formatters -# error "__cpp_lib_formatters should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_forward_like -# error "__cpp_lib_forward_like should be defined in c++26" -# endif -# if __cpp_lib_forward_like != 202207L -# error "__cpp_lib_forward_like should have the value 202207L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_freestanding_algorithm -# error "__cpp_lib_freestanding_algorithm should be defined in c++26" -# endif -# if __cpp_lib_freestanding_algorithm != 202311L -# error "__cpp_lib_freestanding_algorithm should have the value 202311L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_freestanding_algorithm -# error "__cpp_lib_freestanding_algorithm should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_freestanding_array -# error "__cpp_lib_freestanding_array should be defined in c++26" -# endif -# if __cpp_lib_freestanding_array != 202311L -# error "__cpp_lib_freestanding_array should have the value 202311L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_freestanding_array -# error "__cpp_lib_freestanding_array should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_freestanding_cstring -# error "__cpp_lib_freestanding_cstring should be defined in c++26" -# endif -# if __cpp_lib_freestanding_cstring != 202306L -# error "__cpp_lib_freestanding_cstring should have the value 202306L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_freestanding_cstring -# error "__cpp_lib_freestanding_cstring should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_freestanding_expected -# error "__cpp_lib_freestanding_expected should be defined in c++26" -# endif -# if __cpp_lib_freestanding_expected != 202311L -# error "__cpp_lib_freestanding_expected should have the value 202311L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_freestanding_expected -# error "__cpp_lib_freestanding_expected should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_freestanding_mdspan -# error "__cpp_lib_freestanding_mdspan should be defined in c++26" -# endif -# if __cpp_lib_freestanding_mdspan != 202311L -# error "__cpp_lib_freestanding_mdspan should have the value 202311L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_freestanding_mdspan -# error "__cpp_lib_freestanding_mdspan should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_freestanding_optional -# error "__cpp_lib_freestanding_optional should be defined in c++26" -# endif -# if __cpp_lib_freestanding_optional != 202311L -# error "__cpp_lib_freestanding_optional should have the value 202311L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_freestanding_optional -# error "__cpp_lib_freestanding_optional should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_freestanding_string_view -# error "__cpp_lib_freestanding_string_view should be defined in c++26" -# endif -# if __cpp_lib_freestanding_string_view != 202311L -# error "__cpp_lib_freestanding_string_view should have the value 202311L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_freestanding_string_view -# error "__cpp_lib_freestanding_string_view should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_freestanding_variant -# error "__cpp_lib_freestanding_variant should be defined in c++26" -# endif -# if __cpp_lib_freestanding_variant != 202311L -# error "__cpp_lib_freestanding_variant should have the value 202311L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_freestanding_variant -# error "__cpp_lib_freestanding_variant should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION) -# ifndef __cpp_lib_fstream_native_handle -# error "__cpp_lib_fstream_native_handle should be defined in c++26" -# endif -# if __cpp_lib_fstream_native_handle != 202306L -# error "__cpp_lib_fstream_native_handle should have the value 202306L in c++26" -# endif -# else -# ifdef __cpp_lib_fstream_native_handle -# error "__cpp_lib_fstream_native_handle should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION)' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_function_ref -# error "__cpp_lib_function_ref should be defined in c++26" -# endif -# if __cpp_lib_function_ref != 202306L -# error "__cpp_lib_function_ref should have the value 202306L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_function_ref -# error "__cpp_lib_function_ref should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_gcd_lcm -# error "__cpp_lib_gcd_lcm should be defined in c++26" -# endif -# if __cpp_lib_gcd_lcm != 201606L -# error "__cpp_lib_gcd_lcm should have the value 201606L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_generate_random -# error "__cpp_lib_generate_random should be defined in c++26" -# endif -# if __cpp_lib_generate_random != 202403L -# error "__cpp_lib_generate_random should have the value 202403L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_generate_random -# error "__cpp_lib_generate_random should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_generic_associative_lookup -# error "__cpp_lib_generic_associative_lookup should be defined in c++26" -# endif -# if __cpp_lib_generic_associative_lookup != 201304L -# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_generic_unordered_lookup -# error "__cpp_lib_generic_unordered_lookup should be defined in c++26" -# endif -# if __cpp_lib_generic_unordered_lookup != 201811L -# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)) -# ifndef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should be defined in c++26" -# endif -# if __cpp_lib_hardware_interference_size != 201703L -# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++26" -# endif -# else -# ifdef __cpp_lib_hardware_interference_size -# error "__cpp_lib_hardware_interference_size should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))' is not met!" -# endif -# endif - -# ifndef __cpp_lib_has_unique_object_representations -# error "__cpp_lib_has_unique_object_representations should be defined in c++26" -# endif -# if __cpp_lib_has_unique_object_representations != 201606L -# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_hazard_pointer -# error "__cpp_lib_hazard_pointer should be defined in c++26" -# endif -# if __cpp_lib_hazard_pointer != 202306L -# error "__cpp_lib_hazard_pointer should have the value 202306L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_hazard_pointer -# error "__cpp_lib_hazard_pointer should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_hypot -# error "__cpp_lib_hypot should be defined in c++26" -# endif -# if __cpp_lib_hypot != 201603L -# error "__cpp_lib_hypot should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_incomplete_container_elements -# error "__cpp_lib_incomplete_container_elements should be defined in c++26" -# endif -# if __cpp_lib_incomplete_container_elements != 201505L -# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_inplace_vector -# error "__cpp_lib_inplace_vector should be defined in c++26" -# endif -# if __cpp_lib_inplace_vector != 202406L -# error "__cpp_lib_inplace_vector should have the value 202406L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_inplace_vector -# error "__cpp_lib_inplace_vector should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_int_pow2 -# error "__cpp_lib_int_pow2 should be defined in c++26" -# endif -# if __cpp_lib_int_pow2 != 202002L -# error "__cpp_lib_int_pow2 should have the value 202002L in c++26" -# endif - -# ifndef __cpp_lib_integer_comparison_functions -# error "__cpp_lib_integer_comparison_functions should be defined in c++26" -# endif -# if __cpp_lib_integer_comparison_functions != 202002L -# error "__cpp_lib_integer_comparison_functions should have the value 202002L in c++26" -# endif - -# ifndef __cpp_lib_integer_sequence -# error "__cpp_lib_integer_sequence should be defined in c++26" -# endif -# if __cpp_lib_integer_sequence != 201304L -# error "__cpp_lib_integer_sequence should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_integral_constant_callable -# error "__cpp_lib_integral_constant_callable should be defined in c++26" -# endif -# if __cpp_lib_integral_constant_callable != 201304L -# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_interpolate -# error "__cpp_lib_interpolate should be defined in c++26" -# endif -# if __cpp_lib_interpolate != 201902L -# error "__cpp_lib_interpolate should have the value 201902L in c++26" -# endif - -# ifndef __cpp_lib_invoke -# error "__cpp_lib_invoke should be defined in c++26" -# endif -# if __cpp_lib_invoke != 201411L -# error "__cpp_lib_invoke should have the value 201411L in c++26" -# endif - -# ifndef __cpp_lib_invoke_r -# error "__cpp_lib_invoke_r should be defined in c++26" -# endif -# if __cpp_lib_invoke_r != 202106L -# error "__cpp_lib_invoke_r should have the value 202106L in c++26" -# endif - -# ifndef __cpp_lib_ios_noreplace -# error "__cpp_lib_ios_noreplace should be defined in c++26" -# endif -# if __cpp_lib_ios_noreplace != 202207L -# error "__cpp_lib_ios_noreplace should have the value 202207L in c++26" -# endif - -# ifndef __cpp_lib_is_aggregate -# error "__cpp_lib_is_aggregate should be defined in c++26" -# endif -# if __cpp_lib_is_aggregate != 201703L -# error "__cpp_lib_is_aggregate should have the value 201703L in c++26" -# endif - -# ifndef __cpp_lib_is_constant_evaluated -# error "__cpp_lib_is_constant_evaluated should be defined in c++26" -# endif -# if __cpp_lib_is_constant_evaluated != 201811L -# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++26" -# endif - -# ifndef __cpp_lib_is_final -# error "__cpp_lib_is_final should be defined in c++26" -# endif -# if __cpp_lib_is_final != 201402L -# error "__cpp_lib_is_final should have the value 201402L in c++26" -# endif - -# if __has_builtin(__builtin_is_implicit_lifetime) -# ifndef __cpp_lib_is_implicit_lifetime -# error "__cpp_lib_is_implicit_lifetime should be defined in c++26" -# endif -# if __cpp_lib_is_implicit_lifetime != 202302L -# error "__cpp_lib_is_implicit_lifetime should have the value 202302L in c++26" -# endif -# else -# ifdef __cpp_lib_is_implicit_lifetime -# error "__cpp_lib_is_implicit_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_implicit_lifetime)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_is_invocable -# error "__cpp_lib_is_invocable should be defined in c++26" -# endif -# if __cpp_lib_is_invocable != 201703L -# error "__cpp_lib_is_invocable should have the value 201703L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_is_layout_compatible -# error "__cpp_lib_is_layout_compatible should be defined in c++26" -# endif -# if __cpp_lib_is_layout_compatible != 201907L -# error "__cpp_lib_is_layout_compatible should have the value 201907L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_is_layout_compatible -# error "__cpp_lib_is_layout_compatible should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_is_nothrow_convertible -# error "__cpp_lib_is_nothrow_convertible should be defined in c++26" -# endif -# if __cpp_lib_is_nothrow_convertible != 201806L -# error "__cpp_lib_is_nothrow_convertible should have the value 201806L in c++26" -# endif - -# ifndef __cpp_lib_is_null_pointer -# error "__cpp_lib_is_null_pointer should be defined in c++26" -# endif -# if __cpp_lib_is_null_pointer != 201309L -# error "__cpp_lib_is_null_pointer should have the value 201309L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_is_pointer_interconvertible -# error "__cpp_lib_is_pointer_interconvertible should be defined in c++26" -# endif -# if __cpp_lib_is_pointer_interconvertible != 201907L -# error "__cpp_lib_is_pointer_interconvertible should have the value 201907L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_is_pointer_interconvertible -# error "__cpp_lib_is_pointer_interconvertible should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_is_scoped_enum -# error "__cpp_lib_is_scoped_enum should be defined in c++26" -# endif -# if __cpp_lib_is_scoped_enum != 202011L -# error "__cpp_lib_is_scoped_enum should have the value 202011L in c++26" -# endif - -# ifndef __cpp_lib_is_swappable -# error "__cpp_lib_is_swappable should be defined in c++26" -# endif -# if __cpp_lib_is_swappable != 201603L -# error "__cpp_lib_is_swappable should have the value 201603L in c++26" -# endif - -# if __has_builtin(__builtin_is_virtual_base_of) -# ifndef __cpp_lib_is_virtual_base_of -# error "__cpp_lib_is_virtual_base_of should be defined in c++26" -# endif -# if __cpp_lib_is_virtual_base_of != 202406L -# error "__cpp_lib_is_virtual_base_of should have the value 202406L in c++26" -# endif -# else -# ifdef __cpp_lib_is_virtual_base_of -# error "__cpp_lib_is_virtual_base_of should not be defined when the requirement '__has_builtin(__builtin_is_virtual_base_of)' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_is_within_lifetime -# error "__cpp_lib_is_within_lifetime should be defined in c++26" -# endif -# if __cpp_lib_is_within_lifetime != 202306L -# error "__cpp_lib_is_within_lifetime should have the value 202306L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_is_within_lifetime -# error "__cpp_lib_is_within_lifetime should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_jthread -# error "__cpp_lib_jthread should be defined in c++26" -# endif -# if __cpp_lib_jthread != 201911L -# error "__cpp_lib_jthread should have the value 201911L in c++26" -# endif -# else -# ifdef __cpp_lib_jthread -# error "__cpp_lib_jthread should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_latch -# error "__cpp_lib_latch should be defined in c++26" -# endif -# if __cpp_lib_latch != 201907L -# error "__cpp_lib_latch should have the value 201907L in c++26" -# endif -# else -# ifdef __cpp_lib_latch -# error "__cpp_lib_latch should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# ifndef __cpp_lib_launder -# error "__cpp_lib_launder should be defined in c++26" -# endif -# if __cpp_lib_launder != 201606L -# error "__cpp_lib_launder should have the value 201606L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_linalg -# error "__cpp_lib_linalg should be defined in c++26" -# endif -# if __cpp_lib_linalg != 202311L -# error "__cpp_lib_linalg should have the value 202311L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_linalg -# error "__cpp_lib_linalg should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_list_remove_return_type -# error "__cpp_lib_list_remove_return_type should be defined in c++26" -# endif -# if __cpp_lib_list_remove_return_type != 201806L -# error "__cpp_lib_list_remove_return_type should have the value 201806L in c++26" -# endif - -# ifndef __cpp_lib_logical_traits -# error "__cpp_lib_logical_traits should be defined in c++26" -# endif -# if __cpp_lib_logical_traits != 201510L -# error "__cpp_lib_logical_traits should have the value 201510L in c++26" -# endif - -# ifndef __cpp_lib_make_from_tuple -# error "__cpp_lib_make_from_tuple should be defined in c++26" -# endif -# if __cpp_lib_make_from_tuple != 201606L -# error "__cpp_lib_make_from_tuple should have the value 201606L in c++26" -# endif - -# ifndef __cpp_lib_make_reverse_iterator -# error "__cpp_lib_make_reverse_iterator should be defined in c++26" -# endif -# if __cpp_lib_make_reverse_iterator != 201402L -# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++26" -# endif - -# ifndef __cpp_lib_make_unique -# error "__cpp_lib_make_unique should be defined in c++26" -# endif -# if __cpp_lib_make_unique != 201304L -# error "__cpp_lib_make_unique should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_map_try_emplace -# error "__cpp_lib_map_try_emplace should be defined in c++26" -# endif -# if __cpp_lib_map_try_emplace != 201411L -# error "__cpp_lib_map_try_emplace should have the value 201411L in c++26" -# endif - -# ifndef __cpp_lib_math_constants -# error "__cpp_lib_math_constants should be defined in c++26" -# endif -# if __cpp_lib_math_constants != 201907L -# error "__cpp_lib_math_constants should have the value 201907L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should be defined in c++26" -# endif -# if __cpp_lib_math_special_functions != 201603L -# error "__cpp_lib_math_special_functions should have the value 201603L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_math_special_functions -# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_mdspan -# error "__cpp_lib_mdspan should be defined in c++26" -# endif -# if __cpp_lib_mdspan != 202406L -# error "__cpp_lib_mdspan should have the value 202406L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR -# ifndef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should be defined in c++26" -# endif -# if __cpp_lib_memory_resource != 201603L -# error "__cpp_lib_memory_resource should have the value 201603L in c++26" -# endif -# else -# ifdef __cpp_lib_memory_resource -# error "__cpp_lib_memory_resource should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" -# endif -# endif - -# ifndef __cpp_lib_modules -# error "__cpp_lib_modules should be defined in c++26" -# endif -# if __cpp_lib_modules != 202207L -# error "__cpp_lib_modules should have the value 202207L in c++26" -# endif - -# ifndef __cpp_lib_move_iterator_concept -# error "__cpp_lib_move_iterator_concept should be defined in c++26" -# endif -# if __cpp_lib_move_iterator_concept != 202207L -# error "__cpp_lib_move_iterator_concept should have the value 202207L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_move_only_function -# error "__cpp_lib_move_only_function should be defined in c++26" -# endif -# if __cpp_lib_move_only_function != 202110L -# error "__cpp_lib_move_only_function should have the value 202110L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_move_only_function -# error "__cpp_lib_move_only_function should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_node_extract -# error "__cpp_lib_node_extract should be defined in c++26" -# endif -# if __cpp_lib_node_extract != 201606L -# error "__cpp_lib_node_extract should have the value 201606L in c++26" -# endif - -# ifndef __cpp_lib_nonmember_container_access -# error "__cpp_lib_nonmember_container_access should be defined in c++26" -# endif -# if __cpp_lib_nonmember_container_access != 201411L -# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++26" -# endif - -# ifndef __cpp_lib_not_fn -# error "__cpp_lib_not_fn should be defined in c++26" -# endif -# if __cpp_lib_not_fn != 202306L -# error "__cpp_lib_not_fn should have the value 202306L in c++26" -# endif - -# ifndef __cpp_lib_null_iterators -# error "__cpp_lib_null_iterators should be defined in c++26" -# endif -# if __cpp_lib_null_iterators != 201304L -# error "__cpp_lib_null_iterators should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_optional -# error "__cpp_lib_optional should be defined in c++26" -# endif -# if __cpp_lib_optional != 202110L -# error "__cpp_lib_optional should have the value 202110L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_optional_range_support -# error "__cpp_lib_optional_range_support should be defined in c++26" -# endif -# if __cpp_lib_optional_range_support != 202406L -# error "__cpp_lib_optional_range_support should have the value 202406L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_optional_range_support -# error "__cpp_lib_optional_range_support should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_out_ptr -# error "__cpp_lib_out_ptr should be defined in c++26" -# endif -# if __cpp_lib_out_ptr != 202311L -# error "__cpp_lib_out_ptr should have the value 202311L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should be defined in c++26" -# endif -# if __cpp_lib_parallel_algorithm != 201603L -# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_parallel_algorithm -# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_philox_engine -# error "__cpp_lib_philox_engine should be defined in c++26" -# endif -# if __cpp_lib_philox_engine != 202406L -# error "__cpp_lib_philox_engine should have the value 202406L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_philox_engine -# error "__cpp_lib_philox_engine should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR -# ifndef __cpp_lib_polymorphic_allocator -# error "__cpp_lib_polymorphic_allocator should be defined in c++26" -# endif -# if __cpp_lib_polymorphic_allocator != 201902L -# error "__cpp_lib_polymorphic_allocator should have the value 201902L in c++26" -# endif -# else -# ifdef __cpp_lib_polymorphic_allocator -# error "__cpp_lib_polymorphic_allocator should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT -# ifndef __cpp_lib_print -# error "__cpp_lib_print should be defined in c++26" -# endif -# if __cpp_lib_print != 202207L -# error "__cpp_lib_print should have the value 202207L in c++26" -# endif -# else -# ifdef __cpp_lib_print -# error "__cpp_lib_print should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION -# ifndef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should be defined in c++26" -# endif -# if __cpp_lib_quoted_string_io != 201304L -# error "__cpp_lib_quoted_string_io should have the value 201304L in c++26" -# endif -# else -# ifdef __cpp_lib_quoted_string_io -# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" -# endif -# endif - -# ifndef __cpp_lib_ranges -# error "__cpp_lib_ranges should be defined in c++26" -# endif -# if __cpp_lib_ranges != 202406L -# error "__cpp_lib_ranges should have the value 202406L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_as_const -# error "__cpp_lib_ranges_as_const should be defined in c++26" -# endif -# if __cpp_lib_ranges_as_const != 202207L -# error "__cpp_lib_ranges_as_const should have the value 202207L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_ranges_as_const -# error "__cpp_lib_ranges_as_const should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ranges_as_rvalue -# error "__cpp_lib_ranges_as_rvalue should be defined in c++26" -# endif -# if __cpp_lib_ranges_as_rvalue != 202207L -# error "__cpp_lib_ranges_as_rvalue should have the value 202207L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should be defined in c++26" -# endif -# if __cpp_lib_ranges_chunk != 202202L -# error "__cpp_lib_ranges_chunk should have the value 202202L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_ranges_chunk -# error "__cpp_lib_ranges_chunk should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ranges_chunk_by -# error "__cpp_lib_ranges_chunk_by should be defined in c++26" -# endif -# if __cpp_lib_ranges_chunk_by != 202202L -# error "__cpp_lib_ranges_chunk_by should have the value 202202L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_concat -# error "__cpp_lib_ranges_concat should be defined in c++26" -# endif -# if __cpp_lib_ranges_concat != 202403L -# error "__cpp_lib_ranges_concat should have the value 202403L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_ranges_concat -# error "__cpp_lib_ranges_concat should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ranges_contains -# error "__cpp_lib_ranges_contains should be defined in c++26" -# endif -# if __cpp_lib_ranges_contains != 202207L -# error "__cpp_lib_ranges_contains should have the value 202207L in c++26" -# endif - -# ifndef __cpp_lib_ranges_find_last -# error "__cpp_lib_ranges_find_last should be defined in c++26" -# endif -# if __cpp_lib_ranges_find_last != 202207L -# error "__cpp_lib_ranges_find_last should have the value 202207L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_iota -# error "__cpp_lib_ranges_iota should be defined in c++26" -# endif -# if __cpp_lib_ranges_iota != 202202L -# error "__cpp_lib_ranges_iota should have the value 202202L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_ranges_iota -# error "__cpp_lib_ranges_iota should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_join_with -# error "__cpp_lib_ranges_join_with should be defined in c++26" -# endif -# if __cpp_lib_ranges_join_with != 202202L -# error "__cpp_lib_ranges_join_with should have the value 202202L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_ranges_join_with -# error "__cpp_lib_ranges_join_with should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ranges_repeat -# error "__cpp_lib_ranges_repeat should be defined in c++26" -# endif -# if __cpp_lib_ranges_repeat != 202207L -# error "__cpp_lib_ranges_repeat should have the value 202207L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_slide -# error "__cpp_lib_ranges_slide should be defined in c++26" -# endif -# if __cpp_lib_ranges_slide != 202202L -# error "__cpp_lib_ranges_slide should have the value 202202L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_ranges_slide -# error "__cpp_lib_ranges_slide should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ranges_starts_ends_with -# error "__cpp_lib_ranges_starts_ends_with should be defined in c++26" -# endif -# if __cpp_lib_ranges_starts_ends_with != 202106L -# error "__cpp_lib_ranges_starts_ends_with should have the value 202106L in c++26" -# endif - -# ifndef __cpp_lib_ranges_stride -# error "__cpp_lib_ranges_stride should be defined in c++26" -# endif -# if __cpp_lib_ranges_stride != 202207L -# error "__cpp_lib_ranges_stride should have the value 202207L in c++26" -# endif - -# ifndef __cpp_lib_ranges_to_container -# error "__cpp_lib_ranges_to_container should be defined in c++26" -# endif -# if __cpp_lib_ranges_to_container != 202202L -# error "__cpp_lib_ranges_to_container should have the value 202202L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_zip -# error "__cpp_lib_ranges_zip should be defined in c++26" -# endif -# if __cpp_lib_ranges_zip != 202110L -# error "__cpp_lib_ranges_zip should have the value 202110L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_ranges_zip -# error "__cpp_lib_ranges_zip should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ratio -# error "__cpp_lib_ratio should be defined in c++26" -# endif -# if __cpp_lib_ratio != 202306L -# error "__cpp_lib_ratio should have the value 202306L in c++26" -# endif - -# ifndef __cpp_lib_raw_memory_algorithms -# error "__cpp_lib_raw_memory_algorithms should be defined in c++26" -# endif -# if __cpp_lib_raw_memory_algorithms != 201606L -# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_rcu -# error "__cpp_lib_rcu should be defined in c++26" -# endif -# if __cpp_lib_rcu != 202306L -# error "__cpp_lib_rcu should have the value 202306L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_rcu -# error "__cpp_lib_rcu should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_reference_from_temporary -# error "__cpp_lib_reference_from_temporary should be defined in c++26" -# endif -# if __cpp_lib_reference_from_temporary != 202202L -# error "__cpp_lib_reference_from_temporary should have the value 202202L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_reference_from_temporary -# error "__cpp_lib_reference_from_temporary should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_reference_wrapper -# error "__cpp_lib_reference_wrapper should be defined in c++26" -# endif -# if __cpp_lib_reference_wrapper != 202403L -# error "__cpp_lib_reference_wrapper should have the value 202403L in c++26" -# endif - -# ifndef __cpp_lib_remove_cvref -# error "__cpp_lib_remove_cvref should be defined in c++26" -# endif -# if __cpp_lib_remove_cvref != 201711L -# error "__cpp_lib_remove_cvref should have the value 201711L in c++26" -# endif - -# ifndef __cpp_lib_result_of_sfinae -# error "__cpp_lib_result_of_sfinae should be defined in c++26" -# endif -# if __cpp_lib_result_of_sfinae != 201210L -# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++26" -# endif - -# ifndef __cpp_lib_robust_nonmodifying_seq_ops -# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++26" -# endif -# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L -# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_sample -# error "__cpp_lib_sample should be defined in c++26" -# endif -# if __cpp_lib_sample != 201603L -# error "__cpp_lib_sample should have the value 201603L in c++26" -# endif - -# ifndef __cpp_lib_saturation_arithmetic -# error "__cpp_lib_saturation_arithmetic should be defined in c++26" -# endif -# if __cpp_lib_saturation_arithmetic != 202311L -# error "__cpp_lib_saturation_arithmetic should have the value 202311L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should be defined in c++26" -# endif -# if __cpp_lib_scoped_lock != 201703L -# error "__cpp_lib_scoped_lock should have the value 201703L in c++26" -# endif -# else -# ifdef __cpp_lib_scoped_lock -# error "__cpp_lib_scoped_lock should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) -# ifndef __cpp_lib_semaphore -# error "__cpp_lib_semaphore should be defined in c++26" -# endif -# if __cpp_lib_semaphore != 201907L -# error "__cpp_lib_semaphore should have the value 201907L in c++26" -# endif -# else -# ifdef __cpp_lib_semaphore -# error "__cpp_lib_semaphore should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_senders -# error "__cpp_lib_senders should be defined in c++26" -# endif -# if __cpp_lib_senders != 202406L -# error "__cpp_lib_senders should have the value 202406L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_senders -# error "__cpp_lib_senders should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should be defined in c++26" -# endif -# if __cpp_lib_shared_mutex != 201505L -# error "__cpp_lib_shared_mutex should have the value 201505L in c++26" -# endif -# else -# ifdef __cpp_lib_shared_mutex -# error "__cpp_lib_shared_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifndef __cpp_lib_shared_ptr_arrays -# error "__cpp_lib_shared_ptr_arrays should be defined in c++26" -# endif -# if __cpp_lib_shared_ptr_arrays != 201707L -# error "__cpp_lib_shared_ptr_arrays should have the value 201707L in c++26" -# endif - -# ifndef __cpp_lib_shared_ptr_weak_type -# error "__cpp_lib_shared_ptr_weak_type should be defined in c++26" -# endif -# if __cpp_lib_shared_ptr_weak_type != 201606L -# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++26" -# endif - -# if _LIBCPP_HAS_THREADS -# ifndef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should be defined in c++26" -# endif -# if __cpp_lib_shared_timed_mutex != 201402L -# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++26" -# endif -# else -# ifdef __cpp_lib_shared_timed_mutex -# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '_LIBCPP_HAS_THREADS' is not met!" -# endif -# endif - -# ifndef __cpp_lib_shift -# error "__cpp_lib_shift should be defined in c++26" -# endif -# if __cpp_lib_shift != 201806L -# error "__cpp_lib_shift should have the value 201806L in c++26" -# endif - -# ifndef __cpp_lib_smart_ptr_for_overwrite -# error "__cpp_lib_smart_ptr_for_overwrite should be defined in c++26" -# endif -# if __cpp_lib_smart_ptr_for_overwrite != 202002L -# error "__cpp_lib_smart_ptr_for_overwrite should have the value 202002L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_smart_ptr_owner_equality -# error "__cpp_lib_smart_ptr_owner_equality should be defined in c++26" -# endif -# if __cpp_lib_smart_ptr_owner_equality != 202306L -# error "__cpp_lib_smart_ptr_owner_equality should have the value 202306L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_smart_ptr_owner_equality -# error "__cpp_lib_smart_ptr_owner_equality should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_source_location -# error "__cpp_lib_source_location should be defined in c++26" -# endif -# if __cpp_lib_source_location != 201907L -# error "__cpp_lib_source_location should have the value 201907L in c++26" -# endif - -# ifndef __cpp_lib_span -# error "__cpp_lib_span should be defined in c++26" -# endif -# if __cpp_lib_span != 202002L -# error "__cpp_lib_span should have the value 202002L in c++26" -# endif - -# ifndef __cpp_lib_span_at -# error "__cpp_lib_span_at should be defined in c++26" -# endif -# if __cpp_lib_span_at != 202311L -# error "__cpp_lib_span_at should have the value 202311L in c++26" -# endif - -# ifndef __cpp_lib_span_initializer_list -# error "__cpp_lib_span_initializer_list should be defined in c++26" -# endif -# if __cpp_lib_span_initializer_list != 202311L -# error "__cpp_lib_span_initializer_list should have the value 202311L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_spanstream -# error "__cpp_lib_spanstream should be defined in c++26" -# endif -# if __cpp_lib_spanstream != 202106L -# error "__cpp_lib_spanstream should have the value 202106L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_spanstream -# error "__cpp_lib_spanstream should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_ssize -# error "__cpp_lib_ssize should be defined in c++26" -# endif -# if __cpp_lib_ssize != 201902L -# error "__cpp_lib_ssize should have the value 201902L in c++26" -# endif - -# ifndef __cpp_lib_sstream_from_string_view -# error "__cpp_lib_sstream_from_string_view should be defined in c++26" -# endif -# if __cpp_lib_sstream_from_string_view != 202306L -# error "__cpp_lib_sstream_from_string_view should have the value 202306L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_stacktrace -# error "__cpp_lib_stacktrace should be defined in c++26" -# endif -# if __cpp_lib_stacktrace != 202011L -# error "__cpp_lib_stacktrace should have the value 202011L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_stacktrace -# error "__cpp_lib_stacktrace should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_starts_ends_with -# error "__cpp_lib_starts_ends_with should be defined in c++26" -# endif -# if __cpp_lib_starts_ends_with != 201711L -# error "__cpp_lib_starts_ends_with should have the value 201711L in c++26" -# endif - -# ifndef __cpp_lib_stdatomic_h -# error "__cpp_lib_stdatomic_h should be defined in c++26" -# endif -# if __cpp_lib_stdatomic_h != 202011L -# error "__cpp_lib_stdatomic_h should have the value 202011L in c++26" -# endif - -# ifndef __cpp_lib_string_contains -# error "__cpp_lib_string_contains should be defined in c++26" -# endif -# if __cpp_lib_string_contains != 202011L -# error "__cpp_lib_string_contains should have the value 202011L in c++26" -# endif - -# ifndef __cpp_lib_string_resize_and_overwrite -# error "__cpp_lib_string_resize_and_overwrite should be defined in c++26" -# endif -# if __cpp_lib_string_resize_and_overwrite != 202110L -# error "__cpp_lib_string_resize_and_overwrite should have the value 202110L in c++26" -# endif - -# ifndef __cpp_lib_string_udls -# error "__cpp_lib_string_udls should be defined in c++26" -# endif -# if __cpp_lib_string_udls != 201304L -# error "__cpp_lib_string_udls should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_string_view -# error "__cpp_lib_string_view should be defined in c++26" -# endif -# if __cpp_lib_string_view != 202403L -# error "__cpp_lib_string_view should have the value 202403L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_submdspan -# error "__cpp_lib_submdspan should be defined in c++26" -# endif -# if __cpp_lib_submdspan != 202306L -# error "__cpp_lib_submdspan should have the value 202306L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_submdspan -# error "__cpp_lib_submdspan should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM -# ifndef __cpp_lib_syncbuf -# error "__cpp_lib_syncbuf should be defined in c++26" -# endif -# if __cpp_lib_syncbuf != 201803L -# error "__cpp_lib_syncbuf should have the value 201803L in c++26" -# endif -# else -# ifdef __cpp_lib_syncbuf -# error "__cpp_lib_syncbuf should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM' is not met!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_text_encoding -# error "__cpp_lib_text_encoding should be defined in c++26" -# endif -# if __cpp_lib_text_encoding != 202306L -# error "__cpp_lib_text_encoding should have the value 202306L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_text_encoding -# error "__cpp_lib_text_encoding should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_three_way_comparison -# error "__cpp_lib_three_way_comparison should be defined in c++26" -# endif -# if __cpp_lib_three_way_comparison != 201907L -# error "__cpp_lib_three_way_comparison should have the value 201907L in c++26" -# endif - -# ifndef __cpp_lib_to_address -# error "__cpp_lib_to_address should be defined in c++26" -# endif -# if __cpp_lib_to_address != 201711L -# error "__cpp_lib_to_address should have the value 201711L in c++26" -# endif - -# ifndef __cpp_lib_to_array -# error "__cpp_lib_to_array should be defined in c++26" -# endif -# if __cpp_lib_to_array != 201907L -# error "__cpp_lib_to_array should have the value 201907L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should be defined in c++26" -# endif -# if __cpp_lib_to_chars != 202306L -# error "__cpp_lib_to_chars should have the value 202306L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_to_chars -# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_to_string -# error "__cpp_lib_to_string should be defined in c++26" -# endif -# if __cpp_lib_to_string != 202306L -# error "__cpp_lib_to_string should have the value 202306L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_to_string -# error "__cpp_lib_to_string should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_to_underlying -# error "__cpp_lib_to_underlying should be defined in c++26" -# endif -# if __cpp_lib_to_underlying != 202102L -# error "__cpp_lib_to_underlying should have the value 202102L in c++26" -# endif - -# ifndef __cpp_lib_transformation_trait_aliases -# error "__cpp_lib_transformation_trait_aliases should be defined in c++26" -# endif -# if __cpp_lib_transformation_trait_aliases != 201304L -# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_transparent_operators -# error "__cpp_lib_transparent_operators should be defined in c++26" -# endif -# if __cpp_lib_transparent_operators != 201510L -# error "__cpp_lib_transparent_operators should have the value 201510L in c++26" -# endif - -# ifndef __cpp_lib_tuple_element_t -# error "__cpp_lib_tuple_element_t should be defined in c++26" -# endif -# if __cpp_lib_tuple_element_t != 201402L -# error "__cpp_lib_tuple_element_t should have the value 201402L in c++26" -# endif - -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_tuple_like -# error "__cpp_lib_tuple_like should be defined in c++26" -# endif -# if __cpp_lib_tuple_like != 202311L -# error "__cpp_lib_tuple_like should have the value 202311L in c++26" -# endif -# else // _LIBCPP_VERSION -# ifdef __cpp_lib_tuple_like -# error "__cpp_lib_tuple_like should not be defined because it is unimplemented in libc++!" -# endif -# endif - -# ifndef __cpp_lib_tuples_by_type -# error "__cpp_lib_tuples_by_type should be defined in c++26" -# endif -# if __cpp_lib_tuples_by_type != 201304L -# error "__cpp_lib_tuples_by_type should have the value 201304L in c++26" -# endif - -# ifndef __cpp_lib_type_identity -# error "__cpp_lib_type_identity should be defined in c++26" -# endif -# if __cpp_lib_type_identity != 201806L -# error "__cpp_lib_type_identity should have the value 201806L in c++26" -# endif - -# ifndef __cpp_lib_type_trait_variable_templates -# error "__cpp_lib_type_trait_variable_templates should be defined in c++26" -# endif -# if __cpp_lib_type_trait_variable_templates != 201510L -# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++26" -# endif - -# ifndef __cpp_lib_uncaught_exceptions -# error "__cpp_lib_uncaught_exceptions should be defined in c++26" -# endif -# if __cpp_lib_uncaught_exceptions != 201411L -# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++26" -# endif - -# ifndef __cpp_lib_unordered_map_try_emplace -# error "__cpp_lib_unordered_map_try_emplace should be defined in c++26" -# endif -# if __cpp_lib_unordered_map_try_emplace != 201411L -# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++26" -# endif - -# ifndef __cpp_lib_unreachable -# error "__cpp_lib_unreachable should be defined in c++26" -# endif -# if __cpp_lib_unreachable != 202202L -# error "__cpp_lib_unreachable should have the value 202202L in c++26" -# endif - -# ifndef __cpp_lib_unwrap_ref -# error "__cpp_lib_unwrap_ref should be defined in c++26" -# endif -# if __cpp_lib_unwrap_ref != 201811L -# error "__cpp_lib_unwrap_ref should have the value 201811L in c++26" -# endif - -# ifndef __cpp_lib_variant -# error "__cpp_lib_variant should be defined in c++26" -# endif -# if __cpp_lib_variant != 202306L -# error "__cpp_lib_variant should have the value 202306L in c++26" -# endif - -# ifndef __cpp_lib_void_t -# error "__cpp_lib_void_t should be defined in c++26" -# endif -# if __cpp_lib_void_t != 201411L -# error "__cpp_lib_void_t should have the value 201411L in c++26" -# endif +# ifndef __cpp_lib_integer_sequence +# error "__cpp_lib_integer_sequence should be defined in c++14" +# endif +# if __cpp_lib_integer_sequence != 201304L +# error "__cpp_lib_integer_sequence should have the value 201304L in c++14" +# endif + +# ifndef __cpp_lib_integral_constant_callable +# error "__cpp_lib_integral_constant_callable should be defined in c++14" +# endif +# if __cpp_lib_integral_constant_callable != 201304L +# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++14" +# endif + +# ifdef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should not be defined before c++20" +# endif + +# ifdef __cpp_lib_invoke +# error "__cpp_lib_invoke should not be defined before c++17" +# endif + +# ifdef __cpp_lib_invoke_r +# error "__cpp_lib_invoke_r should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ios_noreplace +# error "__cpp_lib_ios_noreplace should not be defined before c++23" +# endif + +# ifdef __cpp_lib_is_aggregate +# error "__cpp_lib_is_aggregate should not be defined before c++17" +# endif + +# ifdef __cpp_lib_is_constant_evaluated +# error "__cpp_lib_is_constant_evaluated should not be defined before c++20" +# endif + +# ifndef __cpp_lib_is_final +# error "__cpp_lib_is_final should be defined in c++14" +# endif +# if __cpp_lib_is_final != 201402L +# error "__cpp_lib_is_final should have the value 201402L in c++14" +# endif + +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" +# endif + +# ifdef __cpp_lib_is_invocable +# error "__cpp_lib_is_invocable should not be defined before c++17" +# endif + +# ifdef __cpp_lib_is_layout_compatible +# error "__cpp_lib_is_layout_compatible should not be defined before c++20" +# endif + +# ifdef __cpp_lib_is_nothrow_convertible +# error "__cpp_lib_is_nothrow_convertible should not be defined before c++20" +# endif + +# ifndef __cpp_lib_is_null_pointer +# error "__cpp_lib_is_null_pointer should be defined in c++14" +# endif +# if __cpp_lib_is_null_pointer != 201309L +# error "__cpp_lib_is_null_pointer should have the value 201309L in c++14" +# endif + +# ifdef __cpp_lib_is_pointer_interconvertible +# error "__cpp_lib_is_pointer_interconvertible should not be defined before c++20" +# endif + +# ifdef __cpp_lib_is_scoped_enum +# error "__cpp_lib_is_scoped_enum should not be defined before c++23" +# endif + +# ifdef __cpp_lib_is_sufficiently_aligned +# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" +# endif + +# ifdef __cpp_lib_is_swappable +# error "__cpp_lib_is_swappable should not be defined before c++17" +# endif + +# ifdef __cpp_lib_is_virtual_base_of +# error "__cpp_lib_is_virtual_base_of should not be defined before c++26" +# endif + +# ifdef __cpp_lib_is_within_lifetime +# error "__cpp_lib_is_within_lifetime should not be defined before c++26" +# endif + +# ifdef __cpp_lib_jthread +# error "__cpp_lib_jthread should not be defined before c++20" +# endif + +# ifdef __cpp_lib_latch +# error "__cpp_lib_latch should not be defined before c++20" +# endif + +# ifdef __cpp_lib_launder +# error "__cpp_lib_launder should not be defined before c++17" +# endif + +# ifdef __cpp_lib_linalg +# error "__cpp_lib_linalg should not be defined before c++26" +# endif + +# ifdef __cpp_lib_list_remove_return_type +# error "__cpp_lib_list_remove_return_type should not be defined before c++20" +# endif + +# ifdef __cpp_lib_logical_traits +# error "__cpp_lib_logical_traits should not be defined before c++17" +# endif + +# ifdef __cpp_lib_make_from_tuple +# error "__cpp_lib_make_from_tuple should not be defined before c++17" +# endif + +# ifndef __cpp_lib_make_reverse_iterator +# error "__cpp_lib_make_reverse_iterator should be defined in c++14" +# endif +# if __cpp_lib_make_reverse_iterator != 201402L +# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++14" +# endif + +# ifndef __cpp_lib_make_unique +# error "__cpp_lib_make_unique should be defined in c++14" +# endif +# if __cpp_lib_make_unique != 201304L +# error "__cpp_lib_make_unique should have the value 201304L in c++14" +# endif + +# ifdef __cpp_lib_map_try_emplace +# error "__cpp_lib_map_try_emplace should not be defined before c++17" +# endif + +# ifdef __cpp_lib_math_constants +# error "__cpp_lib_math_constants should not be defined before c++20" +# endif + +# ifdef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should not be defined before c++17" +# endif + +# ifdef __cpp_lib_mdspan +# error "__cpp_lib_mdspan should not be defined before c++23" +# endif + +# ifdef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should not be defined before c++17" +# endif + +# ifdef __cpp_lib_modules +# error "__cpp_lib_modules should not be defined before c++23" +# endif + +# ifdef __cpp_lib_move_iterator_concept +# error "__cpp_lib_move_iterator_concept should not be defined before c++20" +# endif + +# ifdef __cpp_lib_move_only_function +# error "__cpp_lib_move_only_function should not be defined before c++23" +# endif + +# ifdef __cpp_lib_node_extract +# error "__cpp_lib_node_extract should not be defined before c++17" +# endif + +# ifdef __cpp_lib_nonmember_container_access +# error "__cpp_lib_nonmember_container_access should not be defined before c++17" +# endif + +# ifdef __cpp_lib_not_fn +# error "__cpp_lib_not_fn should not be defined before c++17" +# endif + +# ifndef __cpp_lib_null_iterators +# error "__cpp_lib_null_iterators should be defined in c++14" +# endif +# if __cpp_lib_null_iterators != 201304L +# error "__cpp_lib_null_iterators should have the value 201304L in c++14" +# endif + +# ifdef __cpp_lib_optional +# error "__cpp_lib_optional should not be defined before c++17" +# endif + +# ifdef __cpp_lib_optional_range_support +# error "__cpp_lib_optional_range_support should not be defined before c++26" +# endif + +# ifdef __cpp_lib_out_ptr +# error "__cpp_lib_out_ptr should not be defined before c++23" +# endif + +# ifdef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should not be defined before c++17" +# endif + +# ifdef __cpp_lib_philox_engine +# error "__cpp_lib_philox_engine should not be defined before c++26" +# endif + +# ifdef __cpp_lib_polymorphic_allocator +# error "__cpp_lib_polymorphic_allocator should not be defined before c++20" +# endif + +# ifdef __cpp_lib_print +# error "__cpp_lib_print should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION +# ifndef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should be defined in c++14" +# endif +# if __cpp_lib_quoted_string_io != 201304L +# error "__cpp_lib_quoted_string_io should have the value 201304L in c++14" +# endif +# else +# ifdef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" +# endif +# endif + +# ifdef __cpp_lib_ranges +# error "__cpp_lib_ranges should not be defined before c++20" +# endif + +# ifdef __cpp_lib_ranges_as_const +# error "__cpp_lib_ranges_as_const should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_as_rvalue +# error "__cpp_lib_ranges_as_rvalue should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_chunk_by +# error "__cpp_lib_ranges_chunk_by should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_concat +# error "__cpp_lib_ranges_concat should not be defined before c++26" +# endif + +# ifdef __cpp_lib_ranges_contains +# error "__cpp_lib_ranges_contains should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_find_last +# error "__cpp_lib_ranges_find_last should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_iota +# error "__cpp_lib_ranges_iota should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_join_with +# error "__cpp_lib_ranges_join_with should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_repeat +# error "__cpp_lib_ranges_repeat should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_slide +# error "__cpp_lib_ranges_slide should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_starts_ends_with +# error "__cpp_lib_ranges_starts_ends_with should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_zip +# error "__cpp_lib_ranges_zip should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ratio +# error "__cpp_lib_ratio should not be defined before c++26" +# endif + +# ifdef __cpp_lib_raw_memory_algorithms +# error "__cpp_lib_raw_memory_algorithms should not be defined before c++17" +# endif + +# ifdef __cpp_lib_rcu +# error "__cpp_lib_rcu should not be defined before c++26" +# endif + +# ifdef __cpp_lib_reference_from_temporary +# error "__cpp_lib_reference_from_temporary should not be defined before c++23" +# endif + +# ifdef __cpp_lib_reference_wrapper +# error "__cpp_lib_reference_wrapper should not be defined before c++26" +# endif + +# ifdef __cpp_lib_remove_cvref +# error "__cpp_lib_remove_cvref should not be defined before c++20" +# endif + +# ifndef __cpp_lib_result_of_sfinae +# error "__cpp_lib_result_of_sfinae should be defined in c++14" +# endif +# if __cpp_lib_result_of_sfinae != 201210L +# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++14" +# endif + +# ifndef __cpp_lib_robust_nonmodifying_seq_ops +# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++14" +# endif +# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L +# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++14" +# endif + +# ifdef __cpp_lib_sample +# error "__cpp_lib_sample should not be defined before c++17" +# endif + +# ifdef __cpp_lib_saturation_arithmetic +# error "__cpp_lib_saturation_arithmetic should not be defined before c++26" +# endif + +# ifdef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should not be defined before c++17" +# endif + +# ifdef __cpp_lib_semaphore +# error "__cpp_lib_semaphore should not be defined before c++20" +# endif + +# ifdef __cpp_lib_senders +# error "__cpp_lib_senders should not be defined before c++26" +# endif + +# ifdef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should not be defined before c++17" +# endif + +# ifdef __cpp_lib_shared_ptr_arrays +# error "__cpp_lib_shared_ptr_arrays should not be defined before c++17" +# endif + +# ifdef __cpp_lib_shared_ptr_weak_type +# error "__cpp_lib_shared_ptr_weak_type should not be defined before c++17" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should be defined in c++14" +# endif +# if __cpp_lib_shared_timed_mutex != 201402L +# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++14" +# endif +# else +# ifdef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifdef __cpp_lib_shift +# error "__cpp_lib_shift should not be defined before c++20" +# endif + +# ifdef __cpp_lib_smart_ptr_for_overwrite +# error "__cpp_lib_smart_ptr_for_overwrite should not be defined before c++20" +# endif + +# ifdef __cpp_lib_smart_ptr_owner_equality +# error "__cpp_lib_smart_ptr_owner_equality should not be defined before c++26" +# endif + +# ifdef __cpp_lib_source_location +# error "__cpp_lib_source_location should not be defined before c++20" +# endif + +# ifdef __cpp_lib_span +# error "__cpp_lib_span should not be defined before c++20" +# endif + +# ifdef __cpp_lib_span_at +# error "__cpp_lib_span_at should not be defined before c++26" +# endif + +# ifdef __cpp_lib_span_initializer_list +# error "__cpp_lib_span_initializer_list should not be defined before c++26" +# endif + +# ifdef __cpp_lib_spanstream +# error "__cpp_lib_spanstream should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ssize +# error "__cpp_lib_ssize should not be defined before c++20" +# endif + +# ifdef __cpp_lib_sstream_from_string_view +# error "__cpp_lib_sstream_from_string_view should not be defined before c++26" +# endif + +# ifdef __cpp_lib_stacktrace +# error "__cpp_lib_stacktrace should not be defined before c++23" +# endif + +# ifdef __cpp_lib_starts_ends_with +# error "__cpp_lib_starts_ends_with should not be defined before c++20" +# endif + +# ifdef __cpp_lib_stdatomic_h +# error "__cpp_lib_stdatomic_h should not be defined before c++23" +# endif + +# ifdef __cpp_lib_string_contains +# error "__cpp_lib_string_contains should not be defined before c++23" +# endif + +# ifdef __cpp_lib_string_resize_and_overwrite +# error "__cpp_lib_string_resize_and_overwrite should not be defined before c++23" +# endif + +# ifndef __cpp_lib_string_udls +# error "__cpp_lib_string_udls should be defined in c++14" +# endif +# if __cpp_lib_string_udls != 201304L +# error "__cpp_lib_string_udls should have the value 201304L in c++14" +# endif + +# ifdef __cpp_lib_string_view +# error "__cpp_lib_string_view should not be defined before c++17" +# endif + +# ifdef __cpp_lib_submdspan +# error "__cpp_lib_submdspan should not be defined before c++26" +# endif + +# ifdef __cpp_lib_syncbuf +# error "__cpp_lib_syncbuf should not be defined before c++20" +# endif + +# ifdef __cpp_lib_text_encoding +# error "__cpp_lib_text_encoding should not be defined before c++26" +# endif + +# ifdef __cpp_lib_three_way_comparison +# error "__cpp_lib_three_way_comparison should not be defined before c++20" +# endif + +# ifdef __cpp_lib_to_address +# error "__cpp_lib_to_address should not be defined before c++20" +# endif + +# ifdef __cpp_lib_to_array +# error "__cpp_lib_to_array should not be defined before c++20" +# endif + +# ifdef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should not be defined before c++17" +# endif + +# ifdef __cpp_lib_to_string +# error "__cpp_lib_to_string should not be defined before c++26" +# endif + +# ifdef __cpp_lib_to_underlying +# error "__cpp_lib_to_underlying should not be defined before c++23" +# endif + +# ifndef __cpp_lib_transformation_trait_aliases +# error "__cpp_lib_transformation_trait_aliases should be defined in c++14" +# endif +# if __cpp_lib_transformation_trait_aliases != 201304L +# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++14" +# endif + +# ifndef __cpp_lib_transparent_operators +# error "__cpp_lib_transparent_operators should be defined in c++14" +# endif +# if __cpp_lib_transparent_operators != 201210L +# error "__cpp_lib_transparent_operators should have the value 201210L in c++14" +# endif + +# ifndef __cpp_lib_tuple_element_t +# error "__cpp_lib_tuple_element_t should be defined in c++14" +# endif +# if __cpp_lib_tuple_element_t != 201402L +# error "__cpp_lib_tuple_element_t should have the value 201402L in c++14" +# endif + +# ifdef __cpp_lib_tuple_like +# error "__cpp_lib_tuple_like should not be defined before c++23" +# endif + +# ifndef __cpp_lib_tuples_by_type +# error "__cpp_lib_tuples_by_type should be defined in c++14" +# endif +# if __cpp_lib_tuples_by_type != 201304L +# error "__cpp_lib_tuples_by_type should have the value 201304L in c++14" +# endif + +# ifdef __cpp_lib_type_identity +# error "__cpp_lib_type_identity should not be defined before c++20" +# endif + +# ifdef __cpp_lib_type_trait_variable_templates +# error "__cpp_lib_type_trait_variable_templates should not be defined before c++17" +# endif + +# ifdef __cpp_lib_uncaught_exceptions +# error "__cpp_lib_uncaught_exceptions should not be defined before c++17" +# endif + +# ifdef __cpp_lib_unordered_map_try_emplace +# error "__cpp_lib_unordered_map_try_emplace should not be defined before c++17" +# endif + +# ifdef __cpp_lib_unreachable +# error "__cpp_lib_unreachable should not be defined before c++23" +# endif + +# ifdef __cpp_lib_unwrap_ref +# error "__cpp_lib_unwrap_ref should not be defined before c++20" +# endif + +# ifdef __cpp_lib_variant +# error "__cpp_lib_variant should not be defined before c++17" +# endif + +# ifdef __cpp_lib_void_t +# error "__cpp_lib_void_t should not be defined before c++17" +# endif + +#elif TEST_STD_VER == 17 + +# ifdef __cpp_lib_adaptor_iterator_pair_constructor +# error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++23" +# endif + +# ifndef __cpp_lib_addressof_constexpr +# error "__cpp_lib_addressof_constexpr should be defined in c++17" +# endif +# if __cpp_lib_addressof_constexpr != 201603L +# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++17" +# endif + +# ifdef __cpp_lib_aligned_accessor +# error "__cpp_lib_aligned_accessor should not be defined before c++26" +# endif + +# ifdef __cpp_lib_allocate_at_least +# error "__cpp_lib_allocate_at_least should not be defined before c++23" +# endif + +# ifndef __cpp_lib_allocator_traits_is_always_equal +# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++17" +# endif +# if __cpp_lib_allocator_traits_is_always_equal != 201411L +# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17" +# endif + +# ifndef __cpp_lib_any +# error "__cpp_lib_any should be defined in c++17" +# endif +# if __cpp_lib_any != 201606L +# error "__cpp_lib_any should have the value 201606L in c++17" +# endif + +# ifndef __cpp_lib_apply +# error "__cpp_lib_apply should be defined in c++17" +# endif +# if __cpp_lib_apply != 201603L +# error "__cpp_lib_apply should have the value 201603L in c++17" +# endif + +# ifndef __cpp_lib_array_constexpr +# error "__cpp_lib_array_constexpr should be defined in c++17" +# endif +# if __cpp_lib_array_constexpr != 201603L +# error "__cpp_lib_array_constexpr should have the value 201603L in c++17" +# endif + +# ifndef __cpp_lib_as_const +# error "__cpp_lib_as_const should be defined in c++17" +# endif +# if __cpp_lib_as_const != 201510L +# error "__cpp_lib_as_const should have the value 201510L in c++17" +# endif + +# ifdef __cpp_lib_associative_heterogeneous_erasure +# error "__cpp_lib_associative_heterogeneous_erasure should not be defined before c++23" +# endif + +# ifdef __cpp_lib_associative_heterogeneous_insertion +# error "__cpp_lib_associative_heterogeneous_insertion should not be defined before c++26" +# endif + +# ifdef __cpp_lib_assume_aligned +# error "__cpp_lib_assume_aligned should not be defined before c++20" +# endif + +# ifdef __cpp_lib_atomic_flag_test +# error "__cpp_lib_atomic_flag_test should not be defined before c++20" +# endif + +# ifdef __cpp_lib_atomic_float +# error "__cpp_lib_atomic_float should not be defined before c++20" +# endif + +# ifndef __cpp_lib_atomic_is_always_lock_free +# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++17" +# endif +# if __cpp_lib_atomic_is_always_lock_free != 201603L +# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++17" +# endif + +# ifdef __cpp_lib_atomic_lock_free_type_aliases +# error "__cpp_lib_atomic_lock_free_type_aliases should not be defined before c++20" +# endif + +# ifdef __cpp_lib_atomic_min_max +# error "__cpp_lib_atomic_min_max should not be defined before c++26" +# endif + +# ifdef __cpp_lib_atomic_ref +# error "__cpp_lib_atomic_ref should not be defined before c++20" +# endif + +# ifdef __cpp_lib_atomic_shared_ptr +# error "__cpp_lib_atomic_shared_ptr should not be defined before c++20" +# endif + +# ifdef __cpp_lib_atomic_value_initialization +# error "__cpp_lib_atomic_value_initialization should not be defined before c++20" +# endif + +# ifdef __cpp_lib_atomic_wait +# error "__cpp_lib_atomic_wait should not be defined before c++20" +# endif + +# ifdef __cpp_lib_barrier +# error "__cpp_lib_barrier should not be defined before c++20" +# endif + +# ifdef __cpp_lib_bind_back +# error "__cpp_lib_bind_back should not be defined before c++23" +# endif + +# ifdef __cpp_lib_bind_front +# error "__cpp_lib_bind_front should not be defined before c++20" +# endif + +# ifdef __cpp_lib_bit_cast +# error "__cpp_lib_bit_cast should not be defined before c++20" +# endif + +# ifdef __cpp_lib_bitops +# error "__cpp_lib_bitops should not be defined before c++20" +# endif + +# ifdef __cpp_lib_bitset +# error "__cpp_lib_bitset should not be defined before c++26" +# endif + +# ifndef __cpp_lib_bool_constant +# error "__cpp_lib_bool_constant should be defined in c++17" +# endif +# if __cpp_lib_bool_constant != 201505L +# error "__cpp_lib_bool_constant should have the value 201505L in c++17" +# endif + +# ifdef __cpp_lib_bounded_array_traits +# error "__cpp_lib_bounded_array_traits should not be defined before c++20" +# endif + +# ifndef __cpp_lib_boyer_moore_searcher +# error "__cpp_lib_boyer_moore_searcher should be defined in c++17" +# endif +# if __cpp_lib_boyer_moore_searcher != 201603L +# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++17" +# endif + +# ifndef __cpp_lib_byte +# error "__cpp_lib_byte should be defined in c++17" +# endif +# if __cpp_lib_byte != 201603L +# error "__cpp_lib_byte should have the value 201603L in c++17" +# endif + +# ifdef __cpp_lib_byteswap +# error "__cpp_lib_byteswap should not be defined before c++23" +# endif + +# ifdef __cpp_lib_char8_t +# error "__cpp_lib_char8_t should not be defined before c++20" +# endif + +# ifndef __cpp_lib_chrono +# error "__cpp_lib_chrono should be defined in c++17" +# endif +# if __cpp_lib_chrono != 201611L +# error "__cpp_lib_chrono should have the value 201611L in c++17" +# endif + +# ifndef __cpp_lib_chrono_udls +# error "__cpp_lib_chrono_udls should be defined in c++17" +# endif +# if __cpp_lib_chrono_udls != 201304L +# error "__cpp_lib_chrono_udls should have the value 201304L in c++17" +# endif + +# ifndef __cpp_lib_clamp +# error "__cpp_lib_clamp should be defined in c++17" +# endif +# if __cpp_lib_clamp != 201603L +# error "__cpp_lib_clamp should have the value 201603L in c++17" +# endif + +# ifndef __cpp_lib_complex_udls +# error "__cpp_lib_complex_udls should be defined in c++17" +# endif +# if __cpp_lib_complex_udls != 201309L +# error "__cpp_lib_complex_udls should have the value 201309L in c++17" +# endif + +# ifdef __cpp_lib_concepts +# error "__cpp_lib_concepts should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_algorithms +# error "__cpp_lib_constexpr_algorithms should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_bitset +# error "__cpp_lib_constexpr_bitset should not be defined before c++23" +# endif + +# ifdef __cpp_lib_constexpr_charconv +# error "__cpp_lib_constexpr_charconv should not be defined before c++23" +# endif + +# ifdef __cpp_lib_constexpr_cmath +# error "__cpp_lib_constexpr_cmath should not be defined before c++23" +# endif + +# ifdef __cpp_lib_constexpr_complex +# error "__cpp_lib_constexpr_complex should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_dynamic_alloc +# error "__cpp_lib_constexpr_dynamic_alloc should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_functional +# error "__cpp_lib_constexpr_functional should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_iterator +# error "__cpp_lib_constexpr_iterator should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_memory +# error "__cpp_lib_constexpr_memory should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_new +# error "__cpp_lib_constexpr_new should not be defined before c++26" +# endif + +# ifdef __cpp_lib_constexpr_numeric +# error "__cpp_lib_constexpr_numeric should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_string +# error "__cpp_lib_constexpr_string should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_string_view +# error "__cpp_lib_constexpr_string_view should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_tuple +# error "__cpp_lib_constexpr_tuple should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_typeinfo +# error "__cpp_lib_constexpr_typeinfo should not be defined before c++23" +# endif + +# ifdef __cpp_lib_constexpr_utility +# error "__cpp_lib_constexpr_utility should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constexpr_vector +# error "__cpp_lib_constexpr_vector should not be defined before c++20" +# endif + +# ifdef __cpp_lib_constrained_equality +# error "__cpp_lib_constrained_equality should not be defined before c++26" +# endif + +# ifdef __cpp_lib_containers_ranges +# error "__cpp_lib_containers_ranges should not be defined before c++23" +# endif + +# ifdef __cpp_lib_copyable_function +# error "__cpp_lib_copyable_function should not be defined before c++26" +# endif + +# ifdef __cpp_lib_coroutine +# error "__cpp_lib_coroutine should not be defined before c++20" +# endif + +# ifdef __cpp_lib_debugging +# error "__cpp_lib_debugging should not be defined before c++26" +# endif + +# ifdef __cpp_lib_default_template_type_for_algorithm_values +# error "__cpp_lib_default_template_type_for_algorithm_values should not be defined before c++26" +# endif + +# ifdef __cpp_lib_destroying_delete +# error "__cpp_lib_destroying_delete should not be defined before c++20" +# endif + +# ifndef __cpp_lib_enable_shared_from_this +# error "__cpp_lib_enable_shared_from_this should be defined in c++17" +# endif +# if __cpp_lib_enable_shared_from_this != 201603L +# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++17" +# endif + +# ifdef __cpp_lib_endian +# error "__cpp_lib_endian should not be defined before c++20" +# endif + +# ifdef __cpp_lib_erase_if +# error "__cpp_lib_erase_if should not be defined before c++20" +# endif + +# ifndef __cpp_lib_exchange_function +# error "__cpp_lib_exchange_function should be defined in c++17" +# endif +# if __cpp_lib_exchange_function != 201304L +# error "__cpp_lib_exchange_function should have the value 201304L in c++17" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_execution +# error "__cpp_lib_execution should be defined in c++17" +# endif +# if __cpp_lib_execution != 201603L +# error "__cpp_lib_execution should have the value 201603L in c++17" +# endif +# else +# ifdef __cpp_lib_execution +# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_expected +# error "__cpp_lib_expected should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY) +# ifndef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should be defined in c++17" +# endif +# if __cpp_lib_filesystem != 201703L +# error "__cpp_lib_filesystem should have the value 201703L in c++17" +# endif +# else +# ifdef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)' is not met!" +# endif +# endif + +# ifdef __cpp_lib_flat_map +# error "__cpp_lib_flat_map should not be defined before c++23" +# endif + +# ifdef __cpp_lib_flat_set +# error "__cpp_lib_flat_set should not be defined before c++23" +# endif + +# ifdef __cpp_lib_format +# error "__cpp_lib_format should not be defined before c++20" +# endif + +# ifdef __cpp_lib_format_path +# error "__cpp_lib_format_path should not be defined before c++26" +# endif + +# ifdef __cpp_lib_format_ranges +# error "__cpp_lib_format_ranges should not be defined before c++23" +# endif + +# ifdef __cpp_lib_format_uchar +# error "__cpp_lib_format_uchar should not be defined before c++20" +# endif + +# ifdef __cpp_lib_formatters +# error "__cpp_lib_formatters should not be defined before c++23" +# endif + +# ifdef __cpp_lib_forward_like +# error "__cpp_lib_forward_like should not be defined before c++23" +# endif + +# ifdef __cpp_lib_freestanding_algorithm +# error "__cpp_lib_freestanding_algorithm should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_array +# error "__cpp_lib_freestanding_array should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_cstring +# error "__cpp_lib_freestanding_cstring should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_expected +# error "__cpp_lib_freestanding_expected should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_mdspan +# error "__cpp_lib_freestanding_mdspan should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_optional +# error "__cpp_lib_freestanding_optional should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_string_view +# error "__cpp_lib_freestanding_string_view should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_variant +# error "__cpp_lib_freestanding_variant should not be defined before c++26" +# endif + +# ifdef __cpp_lib_fstream_native_handle +# error "__cpp_lib_fstream_native_handle should not be defined before c++26" +# endif + +# ifdef __cpp_lib_function_ref +# error "__cpp_lib_function_ref should not be defined before c++26" +# endif + +# ifndef __cpp_lib_gcd_lcm +# error "__cpp_lib_gcd_lcm should be defined in c++17" +# endif +# if __cpp_lib_gcd_lcm != 201606L +# error "__cpp_lib_gcd_lcm should have the value 201606L in c++17" +# endif + +# ifdef __cpp_lib_generate_random +# error "__cpp_lib_generate_random should not be defined before c++26" +# endif + +# ifndef __cpp_lib_generic_associative_lookup +# error "__cpp_lib_generic_associative_lookup should be defined in c++17" +# endif +# if __cpp_lib_generic_associative_lookup != 201304L +# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++17" +# endif + +# ifdef __cpp_lib_generic_unordered_lookup +# error "__cpp_lib_generic_unordered_lookup should not be defined before c++20" +# endif + +# if !defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)) +# ifndef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should be defined in c++17" +# endif +# if __cpp_lib_hardware_interference_size != 201703L +# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++17" +# endif +# else +# ifdef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))' is not met!" +# endif +# endif + +# ifndef __cpp_lib_has_unique_object_representations +# error "__cpp_lib_has_unique_object_representations should be defined in c++17" +# endif +# if __cpp_lib_has_unique_object_representations != 201606L +# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++17" +# endif + +# ifdef __cpp_lib_hazard_pointer +# error "__cpp_lib_hazard_pointer should not be defined before c++26" +# endif + +# ifndef __cpp_lib_hypot +# error "__cpp_lib_hypot should be defined in c++17" +# endif +# if __cpp_lib_hypot != 201603L +# error "__cpp_lib_hypot should have the value 201603L in c++17" +# endif + +# ifndef __cpp_lib_incomplete_container_elements +# error "__cpp_lib_incomplete_container_elements should be defined in c++17" +# endif +# if __cpp_lib_incomplete_container_elements != 201505L +# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++17" +# endif + +# ifdef __cpp_lib_inplace_vector +# error "__cpp_lib_inplace_vector should not be defined before c++26" +# endif + +# ifdef __cpp_lib_int_pow2 +# error "__cpp_lib_int_pow2 should not be defined before c++20" +# endif + +# ifdef __cpp_lib_integer_comparison_functions +# error "__cpp_lib_integer_comparison_functions should not be defined before c++20" +# endif + +# ifndef __cpp_lib_integer_sequence +# error "__cpp_lib_integer_sequence should be defined in c++17" +# endif +# if __cpp_lib_integer_sequence != 201304L +# error "__cpp_lib_integer_sequence should have the value 201304L in c++17" +# endif + +# ifndef __cpp_lib_integral_constant_callable +# error "__cpp_lib_integral_constant_callable should be defined in c++17" +# endif +# if __cpp_lib_integral_constant_callable != 201304L +# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++17" +# endif + +# ifdef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should not be defined before c++20" +# endif + +# ifndef __cpp_lib_invoke +# error "__cpp_lib_invoke should be defined in c++17" +# endif +# if __cpp_lib_invoke != 201411L +# error "__cpp_lib_invoke should have the value 201411L in c++17" +# endif + +# ifdef __cpp_lib_invoke_r +# error "__cpp_lib_invoke_r should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ios_noreplace +# error "__cpp_lib_ios_noreplace should not be defined before c++23" +# endif + +# ifndef __cpp_lib_is_aggregate +# error "__cpp_lib_is_aggregate should be defined in c++17" +# endif +# if __cpp_lib_is_aggregate != 201703L +# error "__cpp_lib_is_aggregate should have the value 201703L in c++17" +# endif + +# ifdef __cpp_lib_is_constant_evaluated +# error "__cpp_lib_is_constant_evaluated should not be defined before c++20" +# endif + +# ifndef __cpp_lib_is_final +# error "__cpp_lib_is_final should be defined in c++17" +# endif +# if __cpp_lib_is_final != 201402L +# error "__cpp_lib_is_final should have the value 201402L in c++17" +# endif + +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" +# endif + +# ifndef __cpp_lib_is_invocable +# error "__cpp_lib_is_invocable should be defined in c++17" +# endif +# if __cpp_lib_is_invocable != 201703L +# error "__cpp_lib_is_invocable should have the value 201703L in c++17" +# endif + +# ifdef __cpp_lib_is_layout_compatible +# error "__cpp_lib_is_layout_compatible should not be defined before c++20" +# endif + +# ifdef __cpp_lib_is_nothrow_convertible +# error "__cpp_lib_is_nothrow_convertible should not be defined before c++20" +# endif + +# ifndef __cpp_lib_is_null_pointer +# error "__cpp_lib_is_null_pointer should be defined in c++17" +# endif +# if __cpp_lib_is_null_pointer != 201309L +# error "__cpp_lib_is_null_pointer should have the value 201309L in c++17" +# endif + +# ifdef __cpp_lib_is_pointer_interconvertible +# error "__cpp_lib_is_pointer_interconvertible should not be defined before c++20" +# endif + +# ifdef __cpp_lib_is_scoped_enum +# error "__cpp_lib_is_scoped_enum should not be defined before c++23" +# endif + +# ifdef __cpp_lib_is_sufficiently_aligned +# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" +# endif + +# ifndef __cpp_lib_is_swappable +# error "__cpp_lib_is_swappable should be defined in c++17" +# endif +# if __cpp_lib_is_swappable != 201603L +# error "__cpp_lib_is_swappable should have the value 201603L in c++17" +# endif + +# ifdef __cpp_lib_is_virtual_base_of +# error "__cpp_lib_is_virtual_base_of should not be defined before c++26" +# endif + +# ifdef __cpp_lib_is_within_lifetime +# error "__cpp_lib_is_within_lifetime should not be defined before c++26" +# endif + +# ifdef __cpp_lib_jthread +# error "__cpp_lib_jthread should not be defined before c++20" +# endif + +# ifdef __cpp_lib_latch +# error "__cpp_lib_latch should not be defined before c++20" +# endif + +# ifndef __cpp_lib_launder +# error "__cpp_lib_launder should be defined in c++17" +# endif +# if __cpp_lib_launder != 201606L +# error "__cpp_lib_launder should have the value 201606L in c++17" +# endif + +# ifdef __cpp_lib_linalg +# error "__cpp_lib_linalg should not be defined before c++26" +# endif + +# ifdef __cpp_lib_list_remove_return_type +# error "__cpp_lib_list_remove_return_type should not be defined before c++20" +# endif + +# ifndef __cpp_lib_logical_traits +# error "__cpp_lib_logical_traits should be defined in c++17" +# endif +# if __cpp_lib_logical_traits != 201510L +# error "__cpp_lib_logical_traits should have the value 201510L in c++17" +# endif + +# ifndef __cpp_lib_make_from_tuple +# error "__cpp_lib_make_from_tuple should be defined in c++17" +# endif +# if __cpp_lib_make_from_tuple != 201606L +# error "__cpp_lib_make_from_tuple should have the value 201606L in c++17" +# endif + +# ifndef __cpp_lib_make_reverse_iterator +# error "__cpp_lib_make_reverse_iterator should be defined in c++17" +# endif +# if __cpp_lib_make_reverse_iterator != 201402L +# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++17" +# endif + +# ifndef __cpp_lib_make_unique +# error "__cpp_lib_make_unique should be defined in c++17" +# endif +# if __cpp_lib_make_unique != 201304L +# error "__cpp_lib_make_unique should have the value 201304L in c++17" +# endif + +# ifndef __cpp_lib_map_try_emplace +# error "__cpp_lib_map_try_emplace should be defined in c++17" +# endif +# if __cpp_lib_map_try_emplace != 201411L +# error "__cpp_lib_map_try_emplace should have the value 201411L in c++17" +# endif + +# ifdef __cpp_lib_math_constants +# error "__cpp_lib_math_constants should not be defined before c++20" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should be defined in c++17" +# endif +# if __cpp_lib_math_special_functions != 201603L +# error "__cpp_lib_math_special_functions should have the value 201603L in c++17" +# endif +# else +# ifdef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_mdspan +# error "__cpp_lib_mdspan should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR +# ifndef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should be defined in c++17" +# endif +# if __cpp_lib_memory_resource != 201603L +# error "__cpp_lib_memory_resource should have the value 201603L in c++17" +# endif +# else +# ifdef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" +# endif +# endif + +# ifdef __cpp_lib_modules +# error "__cpp_lib_modules should not be defined before c++23" +# endif + +# ifdef __cpp_lib_move_iterator_concept +# error "__cpp_lib_move_iterator_concept should not be defined before c++20" +# endif + +# ifdef __cpp_lib_move_only_function +# error "__cpp_lib_move_only_function should not be defined before c++23" +# endif + +# ifndef __cpp_lib_node_extract +# error "__cpp_lib_node_extract should be defined in c++17" +# endif +# if __cpp_lib_node_extract != 201606L +# error "__cpp_lib_node_extract should have the value 201606L in c++17" +# endif + +# ifndef __cpp_lib_nonmember_container_access +# error "__cpp_lib_nonmember_container_access should be defined in c++17" +# endif +# if __cpp_lib_nonmember_container_access != 201411L +# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++17" +# endif + +# ifndef __cpp_lib_not_fn +# error "__cpp_lib_not_fn should be defined in c++17" +# endif +# if __cpp_lib_not_fn != 201603L +# error "__cpp_lib_not_fn should have the value 201603L in c++17" +# endif + +# ifndef __cpp_lib_null_iterators +# error "__cpp_lib_null_iterators should be defined in c++17" +# endif +# if __cpp_lib_null_iterators != 201304L +# error "__cpp_lib_null_iterators should have the value 201304L in c++17" +# endif + +# ifndef __cpp_lib_optional +# error "__cpp_lib_optional should be defined in c++17" +# endif +# if __cpp_lib_optional != 201606L +# error "__cpp_lib_optional should have the value 201606L in c++17" +# endif + +# ifdef __cpp_lib_optional_range_support +# error "__cpp_lib_optional_range_support should not be defined before c++26" +# endif + +# ifdef __cpp_lib_out_ptr +# error "__cpp_lib_out_ptr should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should be defined in c++17" +# endif +# if __cpp_lib_parallel_algorithm != 201603L +# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++17" +# endif +# else +# ifdef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_philox_engine +# error "__cpp_lib_philox_engine should not be defined before c++26" +# endif + +# ifdef __cpp_lib_polymorphic_allocator +# error "__cpp_lib_polymorphic_allocator should not be defined before c++20" +# endif + +# ifdef __cpp_lib_print +# error "__cpp_lib_print should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION +# ifndef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should be defined in c++17" +# endif +# if __cpp_lib_quoted_string_io != 201304L +# error "__cpp_lib_quoted_string_io should have the value 201304L in c++17" +# endif +# else +# ifdef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" +# endif +# endif + +# ifdef __cpp_lib_ranges +# error "__cpp_lib_ranges should not be defined before c++20" +# endif + +# ifdef __cpp_lib_ranges_as_const +# error "__cpp_lib_ranges_as_const should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_as_rvalue +# error "__cpp_lib_ranges_as_rvalue should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_chunk_by +# error "__cpp_lib_ranges_chunk_by should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_concat +# error "__cpp_lib_ranges_concat should not be defined before c++26" +# endif + +# ifdef __cpp_lib_ranges_contains +# error "__cpp_lib_ranges_contains should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_find_last +# error "__cpp_lib_ranges_find_last should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_iota +# error "__cpp_lib_ranges_iota should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_join_with +# error "__cpp_lib_ranges_join_with should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_repeat +# error "__cpp_lib_ranges_repeat should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_slide +# error "__cpp_lib_ranges_slide should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_starts_ends_with +# error "__cpp_lib_ranges_starts_ends_with should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_zip +# error "__cpp_lib_ranges_zip should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ratio +# error "__cpp_lib_ratio should not be defined before c++26" +# endif + +# ifndef __cpp_lib_raw_memory_algorithms +# error "__cpp_lib_raw_memory_algorithms should be defined in c++17" +# endif +# if __cpp_lib_raw_memory_algorithms != 201606L +# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++17" +# endif + +# ifdef __cpp_lib_rcu +# error "__cpp_lib_rcu should not be defined before c++26" +# endif + +# ifdef __cpp_lib_reference_from_temporary +# error "__cpp_lib_reference_from_temporary should not be defined before c++23" +# endif + +# ifdef __cpp_lib_reference_wrapper +# error "__cpp_lib_reference_wrapper should not be defined before c++26" +# endif + +# ifdef __cpp_lib_remove_cvref +# error "__cpp_lib_remove_cvref should not be defined before c++20" +# endif + +# ifndef __cpp_lib_result_of_sfinae +# error "__cpp_lib_result_of_sfinae should be defined in c++17" +# endif +# if __cpp_lib_result_of_sfinae != 201210L +# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++17" +# endif + +# ifndef __cpp_lib_robust_nonmodifying_seq_ops +# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++17" +# endif +# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L +# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++17" +# endif + +# ifndef __cpp_lib_sample +# error "__cpp_lib_sample should be defined in c++17" +# endif +# if __cpp_lib_sample != 201603L +# error "__cpp_lib_sample should have the value 201603L in c++17" +# endif + +# ifdef __cpp_lib_saturation_arithmetic +# error "__cpp_lib_saturation_arithmetic should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should be defined in c++17" +# endif +# if __cpp_lib_scoped_lock != 201703L +# error "__cpp_lib_scoped_lock should have the value 201703L in c++17" +# endif +# else +# ifdef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifdef __cpp_lib_semaphore +# error "__cpp_lib_semaphore should not be defined before c++20" +# endif + +# ifdef __cpp_lib_senders +# error "__cpp_lib_senders should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should be defined in c++17" +# endif +# if __cpp_lib_shared_mutex != 201505L +# error "__cpp_lib_shared_mutex should have the value 201505L in c++17" +# endif +# else +# ifdef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifndef __cpp_lib_shared_ptr_arrays +# error "__cpp_lib_shared_ptr_arrays should be defined in c++17" +# endif +# if __cpp_lib_shared_ptr_arrays != 201611L +# error "__cpp_lib_shared_ptr_arrays should have the value 201611L in c++17" +# endif + +# ifndef __cpp_lib_shared_ptr_weak_type +# error "__cpp_lib_shared_ptr_weak_type should be defined in c++17" +# endif +# if __cpp_lib_shared_ptr_weak_type != 201606L +# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++17" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should be defined in c++17" +# endif +# if __cpp_lib_shared_timed_mutex != 201402L +# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++17" +# endif +# else +# ifdef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifdef __cpp_lib_shift +# error "__cpp_lib_shift should not be defined before c++20" +# endif + +# ifdef __cpp_lib_smart_ptr_for_overwrite +# error "__cpp_lib_smart_ptr_for_overwrite should not be defined before c++20" +# endif + +# ifdef __cpp_lib_smart_ptr_owner_equality +# error "__cpp_lib_smart_ptr_owner_equality should not be defined before c++26" +# endif + +# ifdef __cpp_lib_source_location +# error "__cpp_lib_source_location should not be defined before c++20" +# endif + +# ifdef __cpp_lib_span +# error "__cpp_lib_span should not be defined before c++20" +# endif + +# ifdef __cpp_lib_span_at +# error "__cpp_lib_span_at should not be defined before c++26" +# endif + +# ifdef __cpp_lib_span_initializer_list +# error "__cpp_lib_span_initializer_list should not be defined before c++26" +# endif + +# ifdef __cpp_lib_spanstream +# error "__cpp_lib_spanstream should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ssize +# error "__cpp_lib_ssize should not be defined before c++20" +# endif + +# ifdef __cpp_lib_sstream_from_string_view +# error "__cpp_lib_sstream_from_string_view should not be defined before c++26" +# endif + +# ifdef __cpp_lib_stacktrace +# error "__cpp_lib_stacktrace should not be defined before c++23" +# endif + +# ifdef __cpp_lib_starts_ends_with +# error "__cpp_lib_starts_ends_with should not be defined before c++20" +# endif + +# ifdef __cpp_lib_stdatomic_h +# error "__cpp_lib_stdatomic_h should not be defined before c++23" +# endif + +# ifdef __cpp_lib_string_contains +# error "__cpp_lib_string_contains should not be defined before c++23" +# endif + +# ifdef __cpp_lib_string_resize_and_overwrite +# error "__cpp_lib_string_resize_and_overwrite should not be defined before c++23" +# endif + +# ifndef __cpp_lib_string_udls +# error "__cpp_lib_string_udls should be defined in c++17" +# endif +# if __cpp_lib_string_udls != 201304L +# error "__cpp_lib_string_udls should have the value 201304L in c++17" +# endif + +# ifndef __cpp_lib_string_view +# error "__cpp_lib_string_view should be defined in c++17" +# endif +# if __cpp_lib_string_view != 201606L +# error "__cpp_lib_string_view should have the value 201606L in c++17" +# endif + +# ifdef __cpp_lib_submdspan +# error "__cpp_lib_submdspan should not be defined before c++26" +# endif + +# ifdef __cpp_lib_syncbuf +# error "__cpp_lib_syncbuf should not be defined before c++20" +# endif + +# ifdef __cpp_lib_text_encoding +# error "__cpp_lib_text_encoding should not be defined before c++26" +# endif + +# ifdef __cpp_lib_three_way_comparison +# error "__cpp_lib_three_way_comparison should not be defined before c++20" +# endif + +# ifdef __cpp_lib_to_address +# error "__cpp_lib_to_address should not be defined before c++20" +# endif + +# ifdef __cpp_lib_to_array +# error "__cpp_lib_to_array should not be defined before c++20" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should be defined in c++17" +# endif +# if __cpp_lib_to_chars != 201611L +# error "__cpp_lib_to_chars should have the value 201611L in c++17" +# endif +# else +# ifdef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_to_string +# error "__cpp_lib_to_string should not be defined before c++26" +# endif + +# ifdef __cpp_lib_to_underlying +# error "__cpp_lib_to_underlying should not be defined before c++23" +# endif + +# ifndef __cpp_lib_transformation_trait_aliases +# error "__cpp_lib_transformation_trait_aliases should be defined in c++17" +# endif +# if __cpp_lib_transformation_trait_aliases != 201304L +# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++17" +# endif + +# ifndef __cpp_lib_transparent_operators +# error "__cpp_lib_transparent_operators should be defined in c++17" +# endif +# if __cpp_lib_transparent_operators != 201510L +# error "__cpp_lib_transparent_operators should have the value 201510L in c++17" +# endif + +# ifndef __cpp_lib_tuple_element_t +# error "__cpp_lib_tuple_element_t should be defined in c++17" +# endif +# if __cpp_lib_tuple_element_t != 201402L +# error "__cpp_lib_tuple_element_t should have the value 201402L in c++17" +# endif + +# ifdef __cpp_lib_tuple_like +# error "__cpp_lib_tuple_like should not be defined before c++23" +# endif + +# ifndef __cpp_lib_tuples_by_type +# error "__cpp_lib_tuples_by_type should be defined in c++17" +# endif +# if __cpp_lib_tuples_by_type != 201304L +# error "__cpp_lib_tuples_by_type should have the value 201304L in c++17" +# endif + +# ifdef __cpp_lib_type_identity +# error "__cpp_lib_type_identity should not be defined before c++20" +# endif + +# ifndef __cpp_lib_type_trait_variable_templates +# error "__cpp_lib_type_trait_variable_templates should be defined in c++17" +# endif +# if __cpp_lib_type_trait_variable_templates != 201510L +# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++17" +# endif + +# ifndef __cpp_lib_uncaught_exceptions +# error "__cpp_lib_uncaught_exceptions should be defined in c++17" +# endif +# if __cpp_lib_uncaught_exceptions != 201411L +# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++17" +# endif + +# ifndef __cpp_lib_unordered_map_try_emplace +# error "__cpp_lib_unordered_map_try_emplace should be defined in c++17" +# endif +# if __cpp_lib_unordered_map_try_emplace != 201411L +# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++17" +# endif + +# ifdef __cpp_lib_unreachable +# error "__cpp_lib_unreachable should not be defined before c++23" +# endif + +# ifdef __cpp_lib_unwrap_ref +# error "__cpp_lib_unwrap_ref should not be defined before c++20" +# endif + +# ifndef __cpp_lib_variant +# error "__cpp_lib_variant should be defined in c++17" +# endif +# if __cpp_lib_variant != 202102L +# error "__cpp_lib_variant should have the value 202102L in c++17" +# endif + +# ifndef __cpp_lib_void_t +# error "__cpp_lib_void_t should be defined in c++17" +# endif +# if __cpp_lib_void_t != 201411L +# error "__cpp_lib_void_t should have the value 201411L in c++17" +# endif + +#elif TEST_STD_VER == 20 + +# ifdef __cpp_lib_adaptor_iterator_pair_constructor +# error "__cpp_lib_adaptor_iterator_pair_constructor should not be defined before c++23" +# endif + +# ifndef __cpp_lib_addressof_constexpr +# error "__cpp_lib_addressof_constexpr should be defined in c++20" +# endif +# if __cpp_lib_addressof_constexpr != 201603L +# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++20" +# endif + +# ifdef __cpp_lib_aligned_accessor +# error "__cpp_lib_aligned_accessor should not be defined before c++26" +# endif + +# ifdef __cpp_lib_allocate_at_least +# error "__cpp_lib_allocate_at_least should not be defined before c++23" +# endif + +# ifndef __cpp_lib_allocator_traits_is_always_equal +# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++20" +# endif +# if __cpp_lib_allocator_traits_is_always_equal != 201411L +# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++20" +# endif + +# ifndef __cpp_lib_any +# error "__cpp_lib_any should be defined in c++20" +# endif +# if __cpp_lib_any != 201606L +# error "__cpp_lib_any should have the value 201606L in c++20" +# endif + +# ifndef __cpp_lib_apply +# error "__cpp_lib_apply should be defined in c++20" +# endif +# if __cpp_lib_apply != 201603L +# error "__cpp_lib_apply should have the value 201603L in c++20" +# endif + +# ifndef __cpp_lib_array_constexpr +# error "__cpp_lib_array_constexpr should be defined in c++20" +# endif +# if __cpp_lib_array_constexpr != 201811L +# error "__cpp_lib_array_constexpr should have the value 201811L in c++20" +# endif + +# ifndef __cpp_lib_as_const +# error "__cpp_lib_as_const should be defined in c++20" +# endif +# if __cpp_lib_as_const != 201510L +# error "__cpp_lib_as_const should have the value 201510L in c++20" +# endif + +# ifdef __cpp_lib_associative_heterogeneous_erasure +# error "__cpp_lib_associative_heterogeneous_erasure should not be defined before c++23" +# endif + +# ifdef __cpp_lib_associative_heterogeneous_insertion +# error "__cpp_lib_associative_heterogeneous_insertion should not be defined before c++26" +# endif + +# ifndef __cpp_lib_assume_aligned +# error "__cpp_lib_assume_aligned should be defined in c++20" +# endif +# if __cpp_lib_assume_aligned != 201811L +# error "__cpp_lib_assume_aligned should have the value 201811L in c++20" +# endif + +# ifndef __cpp_lib_atomic_flag_test +# error "__cpp_lib_atomic_flag_test should be defined in c++20" +# endif +# if __cpp_lib_atomic_flag_test != 201907L +# error "__cpp_lib_atomic_flag_test should have the value 201907L in c++20" +# endif + +# ifndef __cpp_lib_atomic_float +# error "__cpp_lib_atomic_float should be defined in c++20" +# endif +# if __cpp_lib_atomic_float != 201711L +# error "__cpp_lib_atomic_float should have the value 201711L in c++20" +# endif + +# ifndef __cpp_lib_atomic_is_always_lock_free +# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++20" +# endif +# if __cpp_lib_atomic_is_always_lock_free != 201603L +# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++20" +# endif + +# ifndef __cpp_lib_atomic_lock_free_type_aliases +# error "__cpp_lib_atomic_lock_free_type_aliases should be defined in c++20" +# endif +# if __cpp_lib_atomic_lock_free_type_aliases != 201907L +# error "__cpp_lib_atomic_lock_free_type_aliases should have the value 201907L in c++20" +# endif + +# ifdef __cpp_lib_atomic_min_max +# error "__cpp_lib_atomic_min_max should not be defined before c++26" +# endif + +# ifndef __cpp_lib_atomic_ref +# error "__cpp_lib_atomic_ref should be defined in c++20" +# endif +# if __cpp_lib_atomic_ref != 201806L +# error "__cpp_lib_atomic_ref should have the value 201806L in c++20" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_atomic_shared_ptr +# error "__cpp_lib_atomic_shared_ptr should be defined in c++20" +# endif +# if __cpp_lib_atomic_shared_ptr != 201711L +# error "__cpp_lib_atomic_shared_ptr should have the value 201711L in c++20" +# endif +# else +# ifdef __cpp_lib_atomic_shared_ptr +# error "__cpp_lib_atomic_shared_ptr should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_atomic_value_initialization +# error "__cpp_lib_atomic_value_initialization should be defined in c++20" +# endif +# if __cpp_lib_atomic_value_initialization != 201911L +# error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++20" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC +# ifndef __cpp_lib_atomic_wait +# error "__cpp_lib_atomic_wait should be defined in c++20" +# endif +# if __cpp_lib_atomic_wait != 201907L +# error "__cpp_lib_atomic_wait should have the value 201907L in c++20" +# endif +# else +# ifdef __cpp_lib_atomic_wait +# error "__cpp_lib_atomic_wait should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_barrier +# error "__cpp_lib_barrier should be defined in c++20" +# endif +# if __cpp_lib_barrier != 201907L +# error "__cpp_lib_barrier should have the value 201907L in c++20" +# endif +# else +# ifdef __cpp_lib_barrier +# error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# ifdef __cpp_lib_bind_back +# error "__cpp_lib_bind_back should not be defined before c++23" +# endif + +# ifndef __cpp_lib_bind_front +# error "__cpp_lib_bind_front should be defined in c++20" +# endif +# if __cpp_lib_bind_front != 201907L +# error "__cpp_lib_bind_front should have the value 201907L in c++20" +# endif + +# ifndef __cpp_lib_bit_cast +# error "__cpp_lib_bit_cast should be defined in c++20" +# endif +# if __cpp_lib_bit_cast != 201806L +# error "__cpp_lib_bit_cast should have the value 201806L in c++20" +# endif + +# ifndef __cpp_lib_bitops +# error "__cpp_lib_bitops should be defined in c++20" +# endif +# if __cpp_lib_bitops != 201907L +# error "__cpp_lib_bitops should have the value 201907L in c++20" +# endif + +# ifdef __cpp_lib_bitset +# error "__cpp_lib_bitset should not be defined before c++26" +# endif + +# ifndef __cpp_lib_bool_constant +# error "__cpp_lib_bool_constant should be defined in c++20" +# endif +# if __cpp_lib_bool_constant != 201505L +# error "__cpp_lib_bool_constant should have the value 201505L in c++20" +# endif + +# ifndef __cpp_lib_bounded_array_traits +# error "__cpp_lib_bounded_array_traits should be defined in c++20" +# endif +# if __cpp_lib_bounded_array_traits != 201902L +# error "__cpp_lib_bounded_array_traits should have the value 201902L in c++20" +# endif + +# ifndef __cpp_lib_boyer_moore_searcher +# error "__cpp_lib_boyer_moore_searcher should be defined in c++20" +# endif +# if __cpp_lib_boyer_moore_searcher != 201603L +# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++20" +# endif + +# ifndef __cpp_lib_byte +# error "__cpp_lib_byte should be defined in c++20" +# endif +# if __cpp_lib_byte != 201603L +# error "__cpp_lib_byte should have the value 201603L in c++20" +# endif + +# ifdef __cpp_lib_byteswap +# error "__cpp_lib_byteswap should not be defined before c++23" +# endif + +# if defined(__cpp_char8_t) +# ifndef __cpp_lib_char8_t +# error "__cpp_lib_char8_t should be defined in c++20" +# endif +# if __cpp_lib_char8_t != 201907L +# error "__cpp_lib_char8_t should have the value 201907L in c++20" +# endif +# else +# ifdef __cpp_lib_char8_t +# error "__cpp_lib_char8_t should not be defined when the requirement 'defined(__cpp_char8_t)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_chrono +# error "__cpp_lib_chrono should be defined in c++20" +# endif +# if __cpp_lib_chrono != 201611L +# error "__cpp_lib_chrono should have the value 201611L in c++20" +# endif + +# ifndef __cpp_lib_chrono_udls +# error "__cpp_lib_chrono_udls should be defined in c++20" +# endif +# if __cpp_lib_chrono_udls != 201304L +# error "__cpp_lib_chrono_udls should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_clamp +# error "__cpp_lib_clamp should be defined in c++20" +# endif +# if __cpp_lib_clamp != 201603L +# error "__cpp_lib_clamp should have the value 201603L in c++20" +# endif + +# ifndef __cpp_lib_complex_udls +# error "__cpp_lib_complex_udls should be defined in c++20" +# endif +# if __cpp_lib_complex_udls != 201309L +# error "__cpp_lib_complex_udls should have the value 201309L in c++20" +# endif + +# ifndef __cpp_lib_concepts +# error "__cpp_lib_concepts should be defined in c++20" +# endif +# if __cpp_lib_concepts != 202002L +# error "__cpp_lib_concepts should have the value 202002L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_algorithms +# error "__cpp_lib_constexpr_algorithms should be defined in c++20" +# endif +# if __cpp_lib_constexpr_algorithms != 201806L +# error "__cpp_lib_constexpr_algorithms should have the value 201806L in c++20" +# endif + +# ifdef __cpp_lib_constexpr_bitset +# error "__cpp_lib_constexpr_bitset should not be defined before c++23" +# endif + +# ifdef __cpp_lib_constexpr_charconv +# error "__cpp_lib_constexpr_charconv should not be defined before c++23" +# endif + +# ifdef __cpp_lib_constexpr_cmath +# error "__cpp_lib_constexpr_cmath should not be defined before c++23" +# endif + +# ifndef __cpp_lib_constexpr_complex +# error "__cpp_lib_constexpr_complex should be defined in c++20" +# endif +# if __cpp_lib_constexpr_complex != 201711L +# error "__cpp_lib_constexpr_complex should have the value 201711L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_dynamic_alloc +# error "__cpp_lib_constexpr_dynamic_alloc should be defined in c++20" +# endif +# if __cpp_lib_constexpr_dynamic_alloc != 201907L +# error "__cpp_lib_constexpr_dynamic_alloc should have the value 201907L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_functional +# error "__cpp_lib_constexpr_functional should be defined in c++20" +# endif +# if __cpp_lib_constexpr_functional != 201907L +# error "__cpp_lib_constexpr_functional should have the value 201907L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_iterator +# error "__cpp_lib_constexpr_iterator should be defined in c++20" +# endif +# if __cpp_lib_constexpr_iterator != 201811L +# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_memory +# error "__cpp_lib_constexpr_memory should be defined in c++20" +# endif +# if __cpp_lib_constexpr_memory != 201811L +# error "__cpp_lib_constexpr_memory should have the value 201811L in c++20" +# endif + +# ifdef __cpp_lib_constexpr_new +# error "__cpp_lib_constexpr_new should not be defined before c++26" +# endif + +# ifndef __cpp_lib_constexpr_numeric +# error "__cpp_lib_constexpr_numeric should be defined in c++20" +# endif +# if __cpp_lib_constexpr_numeric != 201911L +# error "__cpp_lib_constexpr_numeric should have the value 201911L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_string +# error "__cpp_lib_constexpr_string should be defined in c++20" +# endif +# if __cpp_lib_constexpr_string != 201907L +# error "__cpp_lib_constexpr_string should have the value 201907L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_string_view +# error "__cpp_lib_constexpr_string_view should be defined in c++20" +# endif +# if __cpp_lib_constexpr_string_view != 201811L +# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_tuple +# error "__cpp_lib_constexpr_tuple should be defined in c++20" +# endif +# if __cpp_lib_constexpr_tuple != 201811L +# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++20" +# endif + +# ifdef __cpp_lib_constexpr_typeinfo +# error "__cpp_lib_constexpr_typeinfo should not be defined before c++23" +# endif + +# ifndef __cpp_lib_constexpr_utility +# error "__cpp_lib_constexpr_utility should be defined in c++20" +# endif +# if __cpp_lib_constexpr_utility != 201811L +# error "__cpp_lib_constexpr_utility should have the value 201811L in c++20" +# endif + +# ifndef __cpp_lib_constexpr_vector +# error "__cpp_lib_constexpr_vector should be defined in c++20" +# endif +# if __cpp_lib_constexpr_vector != 201907L +# error "__cpp_lib_constexpr_vector should have the value 201907L in c++20" +# endif + +# ifdef __cpp_lib_constrained_equality +# error "__cpp_lib_constrained_equality should not be defined before c++26" +# endif + +# ifdef __cpp_lib_containers_ranges +# error "__cpp_lib_containers_ranges should not be defined before c++23" +# endif + +# ifdef __cpp_lib_copyable_function +# error "__cpp_lib_copyable_function should not be defined before c++26" +# endif + +# ifndef __cpp_lib_coroutine +# error "__cpp_lib_coroutine should be defined in c++20" +# endif +# if __cpp_lib_coroutine != 201902L +# error "__cpp_lib_coroutine should have the value 201902L in c++20" +# endif + +# ifdef __cpp_lib_debugging +# error "__cpp_lib_debugging should not be defined before c++26" +# endif + +# ifdef __cpp_lib_default_template_type_for_algorithm_values +# error "__cpp_lib_default_template_type_for_algorithm_values should not be defined before c++26" +# endif + +# if TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L +# ifndef __cpp_lib_destroying_delete +# error "__cpp_lib_destroying_delete should be defined in c++20" +# endif +# if __cpp_lib_destroying_delete != 201806L +# error "__cpp_lib_destroying_delete should have the value 201806L in c++20" +# endif +# else +# ifdef __cpp_lib_destroying_delete +# error "__cpp_lib_destroying_delete should not be defined when the requirement 'TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L' is not met!" +# endif +# endif + +# ifndef __cpp_lib_enable_shared_from_this +# error "__cpp_lib_enable_shared_from_this should be defined in c++20" +# endif +# if __cpp_lib_enable_shared_from_this != 201603L +# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++20" +# endif + +# ifndef __cpp_lib_endian +# error "__cpp_lib_endian should be defined in c++20" +# endif +# if __cpp_lib_endian != 201907L +# error "__cpp_lib_endian should have the value 201907L in c++20" +# endif + +# ifndef __cpp_lib_erase_if +# error "__cpp_lib_erase_if should be defined in c++20" +# endif +# if __cpp_lib_erase_if != 202002L +# error "__cpp_lib_erase_if should have the value 202002L in c++20" +# endif + +# ifndef __cpp_lib_exchange_function +# error "__cpp_lib_exchange_function should be defined in c++20" +# endif +# if __cpp_lib_exchange_function != 201304L +# error "__cpp_lib_exchange_function should have the value 201304L in c++20" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_execution +# error "__cpp_lib_execution should be defined in c++20" +# endif +# if __cpp_lib_execution != 201902L +# error "__cpp_lib_execution should have the value 201902L in c++20" +# endif +# else +# ifdef __cpp_lib_execution +# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_expected +# error "__cpp_lib_expected should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY) +# ifndef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should be defined in c++20" +# endif +# if __cpp_lib_filesystem != 201703L +# error "__cpp_lib_filesystem should have the value 201703L in c++20" +# endif +# else +# ifdef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)' is not met!" +# endif +# endif + +# ifdef __cpp_lib_flat_map +# error "__cpp_lib_flat_map should not be defined before c++23" +# endif + +# ifdef __cpp_lib_flat_set +# error "__cpp_lib_flat_set should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT +# ifndef __cpp_lib_format +# error "__cpp_lib_format should be defined in c++20" +# endif +# if __cpp_lib_format != 202110L +# error "__cpp_lib_format should have the value 202110L in c++20" +# endif +# else +# ifdef __cpp_lib_format +# error "__cpp_lib_format should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" +# endif +# endif + +# ifdef __cpp_lib_format_path +# error "__cpp_lib_format_path should not be defined before c++26" +# endif + +# ifdef __cpp_lib_format_ranges +# error "__cpp_lib_format_ranges should not be defined before c++23" +# endif + +# ifndef __cpp_lib_format_uchar +# error "__cpp_lib_format_uchar should be defined in c++20" +# endif +# if __cpp_lib_format_uchar != 202311L +# error "__cpp_lib_format_uchar should have the value 202311L in c++20" +# endif + +# ifdef __cpp_lib_formatters +# error "__cpp_lib_formatters should not be defined before c++23" +# endif + +# ifdef __cpp_lib_forward_like +# error "__cpp_lib_forward_like should not be defined before c++23" +# endif + +# ifdef __cpp_lib_freestanding_algorithm +# error "__cpp_lib_freestanding_algorithm should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_array +# error "__cpp_lib_freestanding_array should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_cstring +# error "__cpp_lib_freestanding_cstring should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_expected +# error "__cpp_lib_freestanding_expected should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_mdspan +# error "__cpp_lib_freestanding_mdspan should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_optional +# error "__cpp_lib_freestanding_optional should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_string_view +# error "__cpp_lib_freestanding_string_view should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_variant +# error "__cpp_lib_freestanding_variant should not be defined before c++26" +# endif + +# ifdef __cpp_lib_fstream_native_handle +# error "__cpp_lib_fstream_native_handle should not be defined before c++26" +# endif + +# ifdef __cpp_lib_function_ref +# error "__cpp_lib_function_ref should not be defined before c++26" +# endif + +# ifndef __cpp_lib_gcd_lcm +# error "__cpp_lib_gcd_lcm should be defined in c++20" +# endif +# if __cpp_lib_gcd_lcm != 201606L +# error "__cpp_lib_gcd_lcm should have the value 201606L in c++20" +# endif + +# ifdef __cpp_lib_generate_random +# error "__cpp_lib_generate_random should not be defined before c++26" +# endif + +# ifndef __cpp_lib_generic_associative_lookup +# error "__cpp_lib_generic_associative_lookup should be defined in c++20" +# endif +# if __cpp_lib_generic_associative_lookup != 201304L +# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_generic_unordered_lookup +# error "__cpp_lib_generic_unordered_lookup should be defined in c++20" +# endif +# if __cpp_lib_generic_unordered_lookup != 201811L +# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++20" +# endif + +# if !defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)) +# ifndef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should be defined in c++20" +# endif +# if __cpp_lib_hardware_interference_size != 201703L +# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++20" +# endif +# else +# ifdef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))' is not met!" +# endif +# endif + +# ifndef __cpp_lib_has_unique_object_representations +# error "__cpp_lib_has_unique_object_representations should be defined in c++20" +# endif +# if __cpp_lib_has_unique_object_representations != 201606L +# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++20" +# endif + +# ifdef __cpp_lib_hazard_pointer +# error "__cpp_lib_hazard_pointer should not be defined before c++26" +# endif + +# ifndef __cpp_lib_hypot +# error "__cpp_lib_hypot should be defined in c++20" +# endif +# if __cpp_lib_hypot != 201603L +# error "__cpp_lib_hypot should have the value 201603L in c++20" +# endif + +# ifndef __cpp_lib_incomplete_container_elements +# error "__cpp_lib_incomplete_container_elements should be defined in c++20" +# endif +# if __cpp_lib_incomplete_container_elements != 201505L +# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++20" +# endif + +# ifdef __cpp_lib_inplace_vector +# error "__cpp_lib_inplace_vector should not be defined before c++26" +# endif + +# ifndef __cpp_lib_int_pow2 +# error "__cpp_lib_int_pow2 should be defined in c++20" +# endif +# if __cpp_lib_int_pow2 != 202002L +# error "__cpp_lib_int_pow2 should have the value 202002L in c++20" +# endif + +# ifndef __cpp_lib_integer_comparison_functions +# error "__cpp_lib_integer_comparison_functions should be defined in c++20" +# endif +# if __cpp_lib_integer_comparison_functions != 202002L +# error "__cpp_lib_integer_comparison_functions should have the value 202002L in c++20" +# endif + +# ifndef __cpp_lib_integer_sequence +# error "__cpp_lib_integer_sequence should be defined in c++20" +# endif +# if __cpp_lib_integer_sequence != 201304L +# error "__cpp_lib_integer_sequence should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_integral_constant_callable +# error "__cpp_lib_integral_constant_callable should be defined in c++20" +# endif +# if __cpp_lib_integral_constant_callable != 201304L +# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should be defined in c++20" +# endif +# if __cpp_lib_interpolate != 201902L +# error "__cpp_lib_interpolate should have the value 201902L in c++20" +# endif + +# ifndef __cpp_lib_invoke +# error "__cpp_lib_invoke should be defined in c++20" +# endif +# if __cpp_lib_invoke != 201411L +# error "__cpp_lib_invoke should have the value 201411L in c++20" +# endif + +# ifdef __cpp_lib_invoke_r +# error "__cpp_lib_invoke_r should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ios_noreplace +# error "__cpp_lib_ios_noreplace should not be defined before c++23" +# endif + +# ifndef __cpp_lib_is_aggregate +# error "__cpp_lib_is_aggregate should be defined in c++20" +# endif +# if __cpp_lib_is_aggregate != 201703L +# error "__cpp_lib_is_aggregate should have the value 201703L in c++20" +# endif + +# ifndef __cpp_lib_is_constant_evaluated +# error "__cpp_lib_is_constant_evaluated should be defined in c++20" +# endif +# if __cpp_lib_is_constant_evaluated != 201811L +# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++20" +# endif + +# ifndef __cpp_lib_is_final +# error "__cpp_lib_is_final should be defined in c++20" +# endif +# if __cpp_lib_is_final != 201402L +# error "__cpp_lib_is_final should have the value 201402L in c++20" +# endif + +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined before c++23" +# endif + +# ifndef __cpp_lib_is_invocable +# error "__cpp_lib_is_invocable should be defined in c++20" +# endif +# if __cpp_lib_is_invocable != 201703L +# error "__cpp_lib_is_invocable should have the value 201703L in c++20" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_is_layout_compatible +# error "__cpp_lib_is_layout_compatible should be defined in c++20" +# endif +# if __cpp_lib_is_layout_compatible != 201907L +# error "__cpp_lib_is_layout_compatible should have the value 201907L in c++20" +# endif +# else +# ifdef __cpp_lib_is_layout_compatible +# error "__cpp_lib_is_layout_compatible should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_is_nothrow_convertible +# error "__cpp_lib_is_nothrow_convertible should be defined in c++20" +# endif +# if __cpp_lib_is_nothrow_convertible != 201806L +# error "__cpp_lib_is_nothrow_convertible should have the value 201806L in c++20" +# endif + +# ifndef __cpp_lib_is_null_pointer +# error "__cpp_lib_is_null_pointer should be defined in c++20" +# endif +# if __cpp_lib_is_null_pointer != 201309L +# error "__cpp_lib_is_null_pointer should have the value 201309L in c++20" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_is_pointer_interconvertible +# error "__cpp_lib_is_pointer_interconvertible should be defined in c++20" +# endif +# if __cpp_lib_is_pointer_interconvertible != 201907L +# error "__cpp_lib_is_pointer_interconvertible should have the value 201907L in c++20" +# endif +# else +# ifdef __cpp_lib_is_pointer_interconvertible +# error "__cpp_lib_is_pointer_interconvertible should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_is_scoped_enum +# error "__cpp_lib_is_scoped_enum should not be defined before c++23" +# endif + +# ifdef __cpp_lib_is_sufficiently_aligned +# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" +# endif + +# ifndef __cpp_lib_is_swappable +# error "__cpp_lib_is_swappable should be defined in c++20" +# endif +# if __cpp_lib_is_swappable != 201603L +# error "__cpp_lib_is_swappable should have the value 201603L in c++20" +# endif + +# ifdef __cpp_lib_is_virtual_base_of +# error "__cpp_lib_is_virtual_base_of should not be defined before c++26" +# endif + +# ifdef __cpp_lib_is_within_lifetime +# error "__cpp_lib_is_within_lifetime should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_jthread +# error "__cpp_lib_jthread should be defined in c++20" +# endif +# if __cpp_lib_jthread != 201911L +# error "__cpp_lib_jthread should have the value 201911L in c++20" +# endif +# else +# ifdef __cpp_lib_jthread +# error "__cpp_lib_jthread should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_latch +# error "__cpp_lib_latch should be defined in c++20" +# endif +# if __cpp_lib_latch != 201907L +# error "__cpp_lib_latch should have the value 201907L in c++20" +# endif +# else +# ifdef __cpp_lib_latch +# error "__cpp_lib_latch should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_launder +# error "__cpp_lib_launder should be defined in c++20" +# endif +# if __cpp_lib_launder != 201606L +# error "__cpp_lib_launder should have the value 201606L in c++20" +# endif + +# ifdef __cpp_lib_linalg +# error "__cpp_lib_linalg should not be defined before c++26" +# endif + +# ifndef __cpp_lib_list_remove_return_type +# error "__cpp_lib_list_remove_return_type should be defined in c++20" +# endif +# if __cpp_lib_list_remove_return_type != 201806L +# error "__cpp_lib_list_remove_return_type should have the value 201806L in c++20" +# endif + +# ifndef __cpp_lib_logical_traits +# error "__cpp_lib_logical_traits should be defined in c++20" +# endif +# if __cpp_lib_logical_traits != 201510L +# error "__cpp_lib_logical_traits should have the value 201510L in c++20" +# endif + +# ifndef __cpp_lib_make_from_tuple +# error "__cpp_lib_make_from_tuple should be defined in c++20" +# endif +# if __cpp_lib_make_from_tuple != 201606L +# error "__cpp_lib_make_from_tuple should have the value 201606L in c++20" +# endif + +# ifndef __cpp_lib_make_reverse_iterator +# error "__cpp_lib_make_reverse_iterator should be defined in c++20" +# endif +# if __cpp_lib_make_reverse_iterator != 201402L +# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++20" +# endif + +# ifndef __cpp_lib_make_unique +# error "__cpp_lib_make_unique should be defined in c++20" +# endif +# if __cpp_lib_make_unique != 201304L +# error "__cpp_lib_make_unique should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_map_try_emplace +# error "__cpp_lib_map_try_emplace should be defined in c++20" +# endif +# if __cpp_lib_map_try_emplace != 201411L +# error "__cpp_lib_map_try_emplace should have the value 201411L in c++20" +# endif + +# ifndef __cpp_lib_math_constants +# error "__cpp_lib_math_constants should be defined in c++20" +# endif +# if __cpp_lib_math_constants != 201907L +# error "__cpp_lib_math_constants should have the value 201907L in c++20" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should be defined in c++20" +# endif +# if __cpp_lib_math_special_functions != 201603L +# error "__cpp_lib_math_special_functions should have the value 201603L in c++20" +# endif +# else +# ifdef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_mdspan +# error "__cpp_lib_mdspan should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR +# ifndef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should be defined in c++20" +# endif +# if __cpp_lib_memory_resource != 201603L +# error "__cpp_lib_memory_resource should have the value 201603L in c++20" +# endif +# else +# ifdef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" +# endif +# endif + +# ifdef __cpp_lib_modules +# error "__cpp_lib_modules should not be defined before c++23" +# endif + +# ifndef __cpp_lib_move_iterator_concept +# error "__cpp_lib_move_iterator_concept should be defined in c++20" +# endif +# if __cpp_lib_move_iterator_concept != 202207L +# error "__cpp_lib_move_iterator_concept should have the value 202207L in c++20" +# endif + +# ifdef __cpp_lib_move_only_function +# error "__cpp_lib_move_only_function should not be defined before c++23" +# endif + +# ifndef __cpp_lib_node_extract +# error "__cpp_lib_node_extract should be defined in c++20" +# endif +# if __cpp_lib_node_extract != 201606L +# error "__cpp_lib_node_extract should have the value 201606L in c++20" +# endif + +# ifndef __cpp_lib_nonmember_container_access +# error "__cpp_lib_nonmember_container_access should be defined in c++20" +# endif +# if __cpp_lib_nonmember_container_access != 201411L +# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++20" +# endif + +# ifndef __cpp_lib_not_fn +# error "__cpp_lib_not_fn should be defined in c++20" +# endif +# if __cpp_lib_not_fn != 201603L +# error "__cpp_lib_not_fn should have the value 201603L in c++20" +# endif + +# ifndef __cpp_lib_null_iterators +# error "__cpp_lib_null_iterators should be defined in c++20" +# endif +# if __cpp_lib_null_iterators != 201304L +# error "__cpp_lib_null_iterators should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_optional +# error "__cpp_lib_optional should be defined in c++20" +# endif +# if __cpp_lib_optional != 202106L +# error "__cpp_lib_optional should have the value 202106L in c++20" +# endif + +# ifdef __cpp_lib_optional_range_support +# error "__cpp_lib_optional_range_support should not be defined before c++26" +# endif + +# ifdef __cpp_lib_out_ptr +# error "__cpp_lib_out_ptr should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should be defined in c++20" +# endif +# if __cpp_lib_parallel_algorithm != 201603L +# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++20" +# endif +# else +# ifdef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_philox_engine +# error "__cpp_lib_philox_engine should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR +# ifndef __cpp_lib_polymorphic_allocator +# error "__cpp_lib_polymorphic_allocator should be defined in c++20" +# endif +# if __cpp_lib_polymorphic_allocator != 201902L +# error "__cpp_lib_polymorphic_allocator should have the value 201902L in c++20" +# endif +# else +# ifdef __cpp_lib_polymorphic_allocator +# error "__cpp_lib_polymorphic_allocator should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" +# endif +# endif + +# ifdef __cpp_lib_print +# error "__cpp_lib_print should not be defined before c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION +# ifndef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should be defined in c++20" +# endif +# if __cpp_lib_quoted_string_io != 201304L +# error "__cpp_lib_quoted_string_io should have the value 201304L in c++20" +# endif +# else +# ifdef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" +# endif +# endif + +# ifndef __cpp_lib_ranges +# error "__cpp_lib_ranges should be defined in c++20" +# endif +# if __cpp_lib_ranges != 202110L +# error "__cpp_lib_ranges should have the value 202110L in c++20" +# endif + +# ifdef __cpp_lib_ranges_as_const +# error "__cpp_lib_ranges_as_const should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_as_rvalue +# error "__cpp_lib_ranges_as_rvalue should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_chunk_by +# error "__cpp_lib_ranges_chunk_by should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_concat +# error "__cpp_lib_ranges_concat should not be defined before c++26" +# endif + +# ifdef __cpp_lib_ranges_contains +# error "__cpp_lib_ranges_contains should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_find_last +# error "__cpp_lib_ranges_find_last should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_iota +# error "__cpp_lib_ranges_iota should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_join_with +# error "__cpp_lib_ranges_join_with should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_repeat +# error "__cpp_lib_ranges_repeat should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_slide +# error "__cpp_lib_ranges_slide should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_starts_ends_with +# error "__cpp_lib_ranges_starts_ends_with should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ranges_zip +# error "__cpp_lib_ranges_zip should not be defined before c++23" +# endif + +# ifdef __cpp_lib_ratio +# error "__cpp_lib_ratio should not be defined before c++26" +# endif + +# ifndef __cpp_lib_raw_memory_algorithms +# error "__cpp_lib_raw_memory_algorithms should be defined in c++20" +# endif +# if __cpp_lib_raw_memory_algorithms != 201606L +# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++20" +# endif + +# ifdef __cpp_lib_rcu +# error "__cpp_lib_rcu should not be defined before c++26" +# endif + +# ifdef __cpp_lib_reference_from_temporary +# error "__cpp_lib_reference_from_temporary should not be defined before c++23" +# endif + +# ifdef __cpp_lib_reference_wrapper +# error "__cpp_lib_reference_wrapper should not be defined before c++26" +# endif + +# ifndef __cpp_lib_remove_cvref +# error "__cpp_lib_remove_cvref should be defined in c++20" +# endif +# if __cpp_lib_remove_cvref != 201711L +# error "__cpp_lib_remove_cvref should have the value 201711L in c++20" +# endif + +# ifndef __cpp_lib_result_of_sfinae +# error "__cpp_lib_result_of_sfinae should be defined in c++20" +# endif +# if __cpp_lib_result_of_sfinae != 201210L +# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++20" +# endif + +# ifndef __cpp_lib_robust_nonmodifying_seq_ops +# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++20" +# endif +# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L +# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_sample +# error "__cpp_lib_sample should be defined in c++20" +# endif +# if __cpp_lib_sample != 201603L +# error "__cpp_lib_sample should have the value 201603L in c++20" +# endif + +# ifdef __cpp_lib_saturation_arithmetic +# error "__cpp_lib_saturation_arithmetic should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should be defined in c++20" +# endif +# if __cpp_lib_scoped_lock != 201703L +# error "__cpp_lib_scoped_lock should have the value 201703L in c++20" +# endif +# else +# ifdef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_semaphore +# error "__cpp_lib_semaphore should be defined in c++20" +# endif +# if __cpp_lib_semaphore != 201907L +# error "__cpp_lib_semaphore should have the value 201907L in c++20" +# endif +# else +# ifdef __cpp_lib_semaphore +# error "__cpp_lib_semaphore should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# ifdef __cpp_lib_senders +# error "__cpp_lib_senders should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should be defined in c++20" +# endif +# if __cpp_lib_shared_mutex != 201505L +# error "__cpp_lib_shared_mutex should have the value 201505L in c++20" +# endif +# else +# ifdef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifndef __cpp_lib_shared_ptr_arrays +# error "__cpp_lib_shared_ptr_arrays should be defined in c++20" +# endif +# if __cpp_lib_shared_ptr_arrays != 201707L +# error "__cpp_lib_shared_ptr_arrays should have the value 201707L in c++20" +# endif + +# ifndef __cpp_lib_shared_ptr_weak_type +# error "__cpp_lib_shared_ptr_weak_type should be defined in c++20" +# endif +# if __cpp_lib_shared_ptr_weak_type != 201606L +# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++20" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should be defined in c++20" +# endif +# if __cpp_lib_shared_timed_mutex != 201402L +# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++20" +# endif +# else +# ifdef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifndef __cpp_lib_shift +# error "__cpp_lib_shift should be defined in c++20" +# endif +# if __cpp_lib_shift != 201806L +# error "__cpp_lib_shift should have the value 201806L in c++20" +# endif + +# ifndef __cpp_lib_smart_ptr_for_overwrite +# error "__cpp_lib_smart_ptr_for_overwrite should be defined in c++20" +# endif +# if __cpp_lib_smart_ptr_for_overwrite != 202002L +# error "__cpp_lib_smart_ptr_for_overwrite should have the value 202002L in c++20" +# endif + +# ifdef __cpp_lib_smart_ptr_owner_equality +# error "__cpp_lib_smart_ptr_owner_equality should not be defined before c++26" +# endif + +# ifndef __cpp_lib_source_location +# error "__cpp_lib_source_location should be defined in c++20" +# endif +# if __cpp_lib_source_location != 201907L +# error "__cpp_lib_source_location should have the value 201907L in c++20" +# endif + +# ifndef __cpp_lib_span +# error "__cpp_lib_span should be defined in c++20" +# endif +# if __cpp_lib_span != 202002L +# error "__cpp_lib_span should have the value 202002L in c++20" +# endif + +# ifdef __cpp_lib_span_at +# error "__cpp_lib_span_at should not be defined before c++26" +# endif + +# ifdef __cpp_lib_span_initializer_list +# error "__cpp_lib_span_initializer_list should not be defined before c++26" +# endif + +# ifdef __cpp_lib_spanstream +# error "__cpp_lib_spanstream should not be defined before c++23" +# endif + +# ifndef __cpp_lib_ssize +# error "__cpp_lib_ssize should be defined in c++20" +# endif +# if __cpp_lib_ssize != 201902L +# error "__cpp_lib_ssize should have the value 201902L in c++20" +# endif + +# ifdef __cpp_lib_sstream_from_string_view +# error "__cpp_lib_sstream_from_string_view should not be defined before c++26" +# endif + +# ifdef __cpp_lib_stacktrace +# error "__cpp_lib_stacktrace should not be defined before c++23" +# endif + +# ifndef __cpp_lib_starts_ends_with +# error "__cpp_lib_starts_ends_with should be defined in c++20" +# endif +# if __cpp_lib_starts_ends_with != 201711L +# error "__cpp_lib_starts_ends_with should have the value 201711L in c++20" +# endif + +# ifdef __cpp_lib_stdatomic_h +# error "__cpp_lib_stdatomic_h should not be defined before c++23" +# endif + +# ifdef __cpp_lib_string_contains +# error "__cpp_lib_string_contains should not be defined before c++23" +# endif + +# ifdef __cpp_lib_string_resize_and_overwrite +# error "__cpp_lib_string_resize_and_overwrite should not be defined before c++23" +# endif + +# ifndef __cpp_lib_string_udls +# error "__cpp_lib_string_udls should be defined in c++20" +# endif +# if __cpp_lib_string_udls != 201304L +# error "__cpp_lib_string_udls should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_string_view +# error "__cpp_lib_string_view should be defined in c++20" +# endif +# if __cpp_lib_string_view != 201803L +# error "__cpp_lib_string_view should have the value 201803L in c++20" +# endif + +# ifdef __cpp_lib_submdspan +# error "__cpp_lib_submdspan should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM +# ifndef __cpp_lib_syncbuf +# error "__cpp_lib_syncbuf should be defined in c++20" +# endif +# if __cpp_lib_syncbuf != 201803L +# error "__cpp_lib_syncbuf should have the value 201803L in c++20" +# endif +# else +# ifdef __cpp_lib_syncbuf +# error "__cpp_lib_syncbuf should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM' is not met!" +# endif +# endif + +# ifdef __cpp_lib_text_encoding +# error "__cpp_lib_text_encoding should not be defined before c++26" +# endif + +# ifndef __cpp_lib_three_way_comparison +# error "__cpp_lib_three_way_comparison should be defined in c++20" +# endif +# if __cpp_lib_three_way_comparison != 201907L +# error "__cpp_lib_three_way_comparison should have the value 201907L in c++20" +# endif + +# ifndef __cpp_lib_to_address +# error "__cpp_lib_to_address should be defined in c++20" +# endif +# if __cpp_lib_to_address != 201711L +# error "__cpp_lib_to_address should have the value 201711L in c++20" +# endif + +# ifndef __cpp_lib_to_array +# error "__cpp_lib_to_array should be defined in c++20" +# endif +# if __cpp_lib_to_array != 201907L +# error "__cpp_lib_to_array should have the value 201907L in c++20" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should be defined in c++20" +# endif +# if __cpp_lib_to_chars != 201611L +# error "__cpp_lib_to_chars should have the value 201611L in c++20" +# endif +# else +# ifdef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_to_string +# error "__cpp_lib_to_string should not be defined before c++26" +# endif + +# ifdef __cpp_lib_to_underlying +# error "__cpp_lib_to_underlying should not be defined before c++23" +# endif + +# ifndef __cpp_lib_transformation_trait_aliases +# error "__cpp_lib_transformation_trait_aliases should be defined in c++20" +# endif +# if __cpp_lib_transformation_trait_aliases != 201304L +# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_transparent_operators +# error "__cpp_lib_transparent_operators should be defined in c++20" +# endif +# if __cpp_lib_transparent_operators != 201510L +# error "__cpp_lib_transparent_operators should have the value 201510L in c++20" +# endif + +# ifndef __cpp_lib_tuple_element_t +# error "__cpp_lib_tuple_element_t should be defined in c++20" +# endif +# if __cpp_lib_tuple_element_t != 201402L +# error "__cpp_lib_tuple_element_t should have the value 201402L in c++20" +# endif + +# ifdef __cpp_lib_tuple_like +# error "__cpp_lib_tuple_like should not be defined before c++23" +# endif + +# ifndef __cpp_lib_tuples_by_type +# error "__cpp_lib_tuples_by_type should be defined in c++20" +# endif +# if __cpp_lib_tuples_by_type != 201304L +# error "__cpp_lib_tuples_by_type should have the value 201304L in c++20" +# endif + +# ifndef __cpp_lib_type_identity +# error "__cpp_lib_type_identity should be defined in c++20" +# endif +# if __cpp_lib_type_identity != 201806L +# error "__cpp_lib_type_identity should have the value 201806L in c++20" +# endif + +# ifndef __cpp_lib_type_trait_variable_templates +# error "__cpp_lib_type_trait_variable_templates should be defined in c++20" +# endif +# if __cpp_lib_type_trait_variable_templates != 201510L +# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++20" +# endif + +# ifndef __cpp_lib_uncaught_exceptions +# error "__cpp_lib_uncaught_exceptions should be defined in c++20" +# endif +# if __cpp_lib_uncaught_exceptions != 201411L +# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++20" +# endif + +# ifndef __cpp_lib_unordered_map_try_emplace +# error "__cpp_lib_unordered_map_try_emplace should be defined in c++20" +# endif +# if __cpp_lib_unordered_map_try_emplace != 201411L +# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++20" +# endif + +# ifdef __cpp_lib_unreachable +# error "__cpp_lib_unreachable should not be defined before c++23" +# endif + +# ifndef __cpp_lib_unwrap_ref +# error "__cpp_lib_unwrap_ref should be defined in c++20" +# endif +# if __cpp_lib_unwrap_ref != 201811L +# error "__cpp_lib_unwrap_ref should have the value 201811L in c++20" +# endif + +# ifndef __cpp_lib_variant +# error "__cpp_lib_variant should be defined in c++20" +# endif +# if __cpp_lib_variant != 202106L +# error "__cpp_lib_variant should have the value 202106L in c++20" +# endif + +# ifndef __cpp_lib_void_t +# error "__cpp_lib_void_t should be defined in c++20" +# endif +# if __cpp_lib_void_t != 201411L +# error "__cpp_lib_void_t should have the value 201411L in c++20" +# endif + +#elif TEST_STD_VER == 23 + +# ifndef __cpp_lib_adaptor_iterator_pair_constructor +# error "__cpp_lib_adaptor_iterator_pair_constructor should be defined in c++23" +# endif +# if __cpp_lib_adaptor_iterator_pair_constructor != 202106L +# error "__cpp_lib_adaptor_iterator_pair_constructor should have the value 202106L in c++23" +# endif + +# ifndef __cpp_lib_addressof_constexpr +# error "__cpp_lib_addressof_constexpr should be defined in c++23" +# endif +# if __cpp_lib_addressof_constexpr != 201603L +# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++23" +# endif + +# ifdef __cpp_lib_aligned_accessor +# error "__cpp_lib_aligned_accessor should not be defined before c++26" +# endif + +# ifndef __cpp_lib_allocate_at_least +# error "__cpp_lib_allocate_at_least should be defined in c++23" +# endif +# if __cpp_lib_allocate_at_least != 202302L +# error "__cpp_lib_allocate_at_least should have the value 202302L in c++23" +# endif + +# ifndef __cpp_lib_allocator_traits_is_always_equal +# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++23" +# endif +# if __cpp_lib_allocator_traits_is_always_equal != 201411L +# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++23" +# endif + +# ifndef __cpp_lib_any +# error "__cpp_lib_any should be defined in c++23" +# endif +# if __cpp_lib_any != 201606L +# error "__cpp_lib_any should have the value 201606L in c++23" +# endif + +# ifndef __cpp_lib_apply +# error "__cpp_lib_apply should be defined in c++23" +# endif +# if __cpp_lib_apply != 201603L +# error "__cpp_lib_apply should have the value 201603L in c++23" +# endif + +# ifndef __cpp_lib_array_constexpr +# error "__cpp_lib_array_constexpr should be defined in c++23" +# endif +# if __cpp_lib_array_constexpr != 201811L +# error "__cpp_lib_array_constexpr should have the value 201811L in c++23" +# endif + +# ifndef __cpp_lib_as_const +# error "__cpp_lib_as_const should be defined in c++23" +# endif +# if __cpp_lib_as_const != 201510L +# error "__cpp_lib_as_const should have the value 201510L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_associative_heterogeneous_erasure +# error "__cpp_lib_associative_heterogeneous_erasure should be defined in c++23" +# endif +# if __cpp_lib_associative_heterogeneous_erasure != 202110L +# error "__cpp_lib_associative_heterogeneous_erasure should have the value 202110L in c++23" +# endif +# else +# ifdef __cpp_lib_associative_heterogeneous_erasure +# error "__cpp_lib_associative_heterogeneous_erasure should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_associative_heterogeneous_insertion +# error "__cpp_lib_associative_heterogeneous_insertion should not be defined before c++26" +# endif + +# ifndef __cpp_lib_assume_aligned +# error "__cpp_lib_assume_aligned should be defined in c++23" +# endif +# if __cpp_lib_assume_aligned != 201811L +# error "__cpp_lib_assume_aligned should have the value 201811L in c++23" +# endif + +# ifndef __cpp_lib_atomic_flag_test +# error "__cpp_lib_atomic_flag_test should be defined in c++23" +# endif +# if __cpp_lib_atomic_flag_test != 201907L +# error "__cpp_lib_atomic_flag_test should have the value 201907L in c++23" +# endif + +# ifndef __cpp_lib_atomic_float +# error "__cpp_lib_atomic_float should be defined in c++23" +# endif +# if __cpp_lib_atomic_float != 201711L +# error "__cpp_lib_atomic_float should have the value 201711L in c++23" +# endif + +# ifndef __cpp_lib_atomic_is_always_lock_free +# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++23" +# endif +# if __cpp_lib_atomic_is_always_lock_free != 201603L +# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++23" +# endif + +# ifndef __cpp_lib_atomic_lock_free_type_aliases +# error "__cpp_lib_atomic_lock_free_type_aliases should be defined in c++23" +# endif +# if __cpp_lib_atomic_lock_free_type_aliases != 201907L +# error "__cpp_lib_atomic_lock_free_type_aliases should have the value 201907L in c++23" +# endif + +# ifdef __cpp_lib_atomic_min_max +# error "__cpp_lib_atomic_min_max should not be defined before c++26" +# endif + +# ifndef __cpp_lib_atomic_ref +# error "__cpp_lib_atomic_ref should be defined in c++23" +# endif +# if __cpp_lib_atomic_ref != 201806L +# error "__cpp_lib_atomic_ref should have the value 201806L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_atomic_shared_ptr +# error "__cpp_lib_atomic_shared_ptr should be defined in c++23" +# endif +# if __cpp_lib_atomic_shared_ptr != 201711L +# error "__cpp_lib_atomic_shared_ptr should have the value 201711L in c++23" +# endif +# else +# ifdef __cpp_lib_atomic_shared_ptr +# error "__cpp_lib_atomic_shared_ptr should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_atomic_value_initialization +# error "__cpp_lib_atomic_value_initialization should be defined in c++23" +# endif +# if __cpp_lib_atomic_value_initialization != 201911L +# error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC +# ifndef __cpp_lib_atomic_wait +# error "__cpp_lib_atomic_wait should be defined in c++23" +# endif +# if __cpp_lib_atomic_wait != 201907L +# error "__cpp_lib_atomic_wait should have the value 201907L in c++23" +# endif +# else +# ifdef __cpp_lib_atomic_wait +# error "__cpp_lib_atomic_wait should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_barrier +# error "__cpp_lib_barrier should be defined in c++23" +# endif +# if __cpp_lib_barrier != 201907L +# error "__cpp_lib_barrier should have the value 201907L in c++23" +# endif +# else +# ifdef __cpp_lib_barrier +# error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_bind_back +# error "__cpp_lib_bind_back should be defined in c++23" +# endif +# if __cpp_lib_bind_back != 202202L +# error "__cpp_lib_bind_back should have the value 202202L in c++23" +# endif + +# ifndef __cpp_lib_bind_front +# error "__cpp_lib_bind_front should be defined in c++23" +# endif +# if __cpp_lib_bind_front != 201907L +# error "__cpp_lib_bind_front should have the value 201907L in c++23" +# endif + +# ifndef __cpp_lib_bit_cast +# error "__cpp_lib_bit_cast should be defined in c++23" +# endif +# if __cpp_lib_bit_cast != 201806L +# error "__cpp_lib_bit_cast should have the value 201806L in c++23" +# endif + +# ifndef __cpp_lib_bitops +# error "__cpp_lib_bitops should be defined in c++23" +# endif +# if __cpp_lib_bitops != 201907L +# error "__cpp_lib_bitops should have the value 201907L in c++23" +# endif + +# ifdef __cpp_lib_bitset +# error "__cpp_lib_bitset should not be defined before c++26" +# endif + +# ifndef __cpp_lib_bool_constant +# error "__cpp_lib_bool_constant should be defined in c++23" +# endif +# if __cpp_lib_bool_constant != 201505L +# error "__cpp_lib_bool_constant should have the value 201505L in c++23" +# endif + +# ifndef __cpp_lib_bounded_array_traits +# error "__cpp_lib_bounded_array_traits should be defined in c++23" +# endif +# if __cpp_lib_bounded_array_traits != 201902L +# error "__cpp_lib_bounded_array_traits should have the value 201902L in c++23" +# endif + +# ifndef __cpp_lib_boyer_moore_searcher +# error "__cpp_lib_boyer_moore_searcher should be defined in c++23" +# endif +# if __cpp_lib_boyer_moore_searcher != 201603L +# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++23" +# endif + +# ifndef __cpp_lib_byte +# error "__cpp_lib_byte should be defined in c++23" +# endif +# if __cpp_lib_byte != 201603L +# error "__cpp_lib_byte should have the value 201603L in c++23" +# endif + +# ifndef __cpp_lib_byteswap +# error "__cpp_lib_byteswap should be defined in c++23" +# endif +# if __cpp_lib_byteswap != 202110L +# error "__cpp_lib_byteswap should have the value 202110L in c++23" +# endif + +# if defined(__cpp_char8_t) +# ifndef __cpp_lib_char8_t +# error "__cpp_lib_char8_t should be defined in c++23" +# endif +# if __cpp_lib_char8_t != 201907L +# error "__cpp_lib_char8_t should have the value 201907L in c++23" +# endif +# else +# ifdef __cpp_lib_char8_t +# error "__cpp_lib_char8_t should not be defined when the requirement 'defined(__cpp_char8_t)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_chrono +# error "__cpp_lib_chrono should be defined in c++23" +# endif +# if __cpp_lib_chrono != 201611L +# error "__cpp_lib_chrono should have the value 201611L in c++23" +# endif + +# ifndef __cpp_lib_chrono_udls +# error "__cpp_lib_chrono_udls should be defined in c++23" +# endif +# if __cpp_lib_chrono_udls != 201304L +# error "__cpp_lib_chrono_udls should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_clamp +# error "__cpp_lib_clamp should be defined in c++23" +# endif +# if __cpp_lib_clamp != 201603L +# error "__cpp_lib_clamp should have the value 201603L in c++23" +# endif + +# ifndef __cpp_lib_complex_udls +# error "__cpp_lib_complex_udls should be defined in c++23" +# endif +# if __cpp_lib_complex_udls != 201309L +# error "__cpp_lib_complex_udls should have the value 201309L in c++23" +# endif + +# ifndef __cpp_lib_concepts +# error "__cpp_lib_concepts should be defined in c++23" +# endif +# if __cpp_lib_concepts != 202002L +# error "__cpp_lib_concepts should have the value 202002L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_algorithms +# error "__cpp_lib_constexpr_algorithms should be defined in c++23" +# endif +# if __cpp_lib_constexpr_algorithms != 201806L +# error "__cpp_lib_constexpr_algorithms should have the value 201806L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_bitset +# error "__cpp_lib_constexpr_bitset should be defined in c++23" +# endif +# if __cpp_lib_constexpr_bitset != 202207L +# error "__cpp_lib_constexpr_bitset should have the value 202207L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_charconv +# error "__cpp_lib_constexpr_charconv should be defined in c++23" +# endif +# if __cpp_lib_constexpr_charconv != 202207L +# error "__cpp_lib_constexpr_charconv should have the value 202207L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_constexpr_cmath +# error "__cpp_lib_constexpr_cmath should be defined in c++23" +# endif +# if __cpp_lib_constexpr_cmath != 202202L +# error "__cpp_lib_constexpr_cmath should have the value 202202L in c++23" +# endif +# else +# ifdef __cpp_lib_constexpr_cmath +# error "__cpp_lib_constexpr_cmath should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_constexpr_complex +# error "__cpp_lib_constexpr_complex should be defined in c++23" +# endif +# if __cpp_lib_constexpr_complex != 201711L +# error "__cpp_lib_constexpr_complex should have the value 201711L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_dynamic_alloc +# error "__cpp_lib_constexpr_dynamic_alloc should be defined in c++23" +# endif +# if __cpp_lib_constexpr_dynamic_alloc != 201907L +# error "__cpp_lib_constexpr_dynamic_alloc should have the value 201907L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_functional +# error "__cpp_lib_constexpr_functional should be defined in c++23" +# endif +# if __cpp_lib_constexpr_functional != 201907L +# error "__cpp_lib_constexpr_functional should have the value 201907L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_iterator +# error "__cpp_lib_constexpr_iterator should be defined in c++23" +# endif +# if __cpp_lib_constexpr_iterator != 201811L +# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_memory +# error "__cpp_lib_constexpr_memory should be defined in c++23" +# endif +# if __cpp_lib_constexpr_memory != 202202L +# error "__cpp_lib_constexpr_memory should have the value 202202L in c++23" +# endif + +# ifdef __cpp_lib_constexpr_new +# error "__cpp_lib_constexpr_new should not be defined before c++26" +# endif + +# ifndef __cpp_lib_constexpr_numeric +# error "__cpp_lib_constexpr_numeric should be defined in c++23" +# endif +# if __cpp_lib_constexpr_numeric != 201911L +# error "__cpp_lib_constexpr_numeric should have the value 201911L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_string +# error "__cpp_lib_constexpr_string should be defined in c++23" +# endif +# if __cpp_lib_constexpr_string != 201907L +# error "__cpp_lib_constexpr_string should have the value 201907L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_string_view +# error "__cpp_lib_constexpr_string_view should be defined in c++23" +# endif +# if __cpp_lib_constexpr_string_view != 201811L +# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_tuple +# error "__cpp_lib_constexpr_tuple should be defined in c++23" +# endif +# if __cpp_lib_constexpr_tuple != 201811L +# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_typeinfo +# error "__cpp_lib_constexpr_typeinfo should be defined in c++23" +# endif +# if __cpp_lib_constexpr_typeinfo != 202106L +# error "__cpp_lib_constexpr_typeinfo should have the value 202106L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_utility +# error "__cpp_lib_constexpr_utility should be defined in c++23" +# endif +# if __cpp_lib_constexpr_utility != 201811L +# error "__cpp_lib_constexpr_utility should have the value 201811L in c++23" +# endif + +# ifndef __cpp_lib_constexpr_vector +# error "__cpp_lib_constexpr_vector should be defined in c++23" +# endif +# if __cpp_lib_constexpr_vector != 201907L +# error "__cpp_lib_constexpr_vector should have the value 201907L in c++23" +# endif + +# ifdef __cpp_lib_constrained_equality +# error "__cpp_lib_constrained_equality should not be defined before c++26" +# endif + +# ifndef __cpp_lib_containers_ranges +# error "__cpp_lib_containers_ranges should be defined in c++23" +# endif +# if __cpp_lib_containers_ranges != 202202L +# error "__cpp_lib_containers_ranges should have the value 202202L in c++23" +# endif + +# ifdef __cpp_lib_copyable_function +# error "__cpp_lib_copyable_function should not be defined before c++26" +# endif + +# ifndef __cpp_lib_coroutine +# error "__cpp_lib_coroutine should be defined in c++23" +# endif +# if __cpp_lib_coroutine != 201902L +# error "__cpp_lib_coroutine should have the value 201902L in c++23" +# endif + +# ifdef __cpp_lib_debugging +# error "__cpp_lib_debugging should not be defined before c++26" +# endif + +# ifdef __cpp_lib_default_template_type_for_algorithm_values +# error "__cpp_lib_default_template_type_for_algorithm_values should not be defined before c++26" +# endif + +# if TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L +# ifndef __cpp_lib_destroying_delete +# error "__cpp_lib_destroying_delete should be defined in c++23" +# endif +# if __cpp_lib_destroying_delete != 201806L +# error "__cpp_lib_destroying_delete should have the value 201806L in c++23" +# endif +# else +# ifdef __cpp_lib_destroying_delete +# error "__cpp_lib_destroying_delete should not be defined when the requirement 'TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L' is not met!" +# endif +# endif + +# ifndef __cpp_lib_enable_shared_from_this +# error "__cpp_lib_enable_shared_from_this should be defined in c++23" +# endif +# if __cpp_lib_enable_shared_from_this != 201603L +# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++23" +# endif + +# ifndef __cpp_lib_endian +# error "__cpp_lib_endian should be defined in c++23" +# endif +# if __cpp_lib_endian != 201907L +# error "__cpp_lib_endian should have the value 201907L in c++23" +# endif + +# ifndef __cpp_lib_erase_if +# error "__cpp_lib_erase_if should be defined in c++23" +# endif +# if __cpp_lib_erase_if != 202002L +# error "__cpp_lib_erase_if should have the value 202002L in c++23" +# endif + +# ifndef __cpp_lib_exchange_function +# error "__cpp_lib_exchange_function should be defined in c++23" +# endif +# if __cpp_lib_exchange_function != 201304L +# error "__cpp_lib_exchange_function should have the value 201304L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_execution +# error "__cpp_lib_execution should be defined in c++23" +# endif +# if __cpp_lib_execution != 201902L +# error "__cpp_lib_execution should have the value 201902L in c++23" +# endif +# else +# ifdef __cpp_lib_execution +# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_expected +# error "__cpp_lib_expected should be defined in c++23" +# endif +# if __cpp_lib_expected != 202211L +# error "__cpp_lib_expected should have the value 202211L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY) +# ifndef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should be defined in c++23" +# endif +# if __cpp_lib_filesystem != 201703L +# error "__cpp_lib_filesystem should have the value 201703L in c++23" +# endif +# else +# ifdef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_flat_map +# error "__cpp_lib_flat_map should be defined in c++23" +# endif +# if __cpp_lib_flat_map != 202207L +# error "__cpp_lib_flat_map should have the value 202207L in c++23" +# endif + +# ifndef __cpp_lib_flat_set +# error "__cpp_lib_flat_set should be defined in c++23" +# endif +# if __cpp_lib_flat_set != 202207L +# error "__cpp_lib_flat_set should have the value 202207L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT +# ifndef __cpp_lib_format +# error "__cpp_lib_format should be defined in c++23" +# endif +# if __cpp_lib_format != 202110L +# error "__cpp_lib_format should have the value 202110L in c++23" +# endif +# else +# ifdef __cpp_lib_format +# error "__cpp_lib_format should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" +# endif +# endif + +# ifdef __cpp_lib_format_path +# error "__cpp_lib_format_path should not be defined before c++26" +# endif + +# ifndef __cpp_lib_format_ranges +# error "__cpp_lib_format_ranges should be defined in c++23" +# endif +# if __cpp_lib_format_ranges != 202207L +# error "__cpp_lib_format_ranges should have the value 202207L in c++23" +# endif + +# ifndef __cpp_lib_format_uchar +# error "__cpp_lib_format_uchar should be defined in c++23" +# endif +# if __cpp_lib_format_uchar != 202311L +# error "__cpp_lib_format_uchar should have the value 202311L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_formatters +# error "__cpp_lib_formatters should be defined in c++23" +# endif +# if __cpp_lib_formatters != 202302L +# error "__cpp_lib_formatters should have the value 202302L in c++23" +# endif +# else +# ifdef __cpp_lib_formatters +# error "__cpp_lib_formatters should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_forward_like +# error "__cpp_lib_forward_like should be defined in c++23" +# endif +# if __cpp_lib_forward_like != 202207L +# error "__cpp_lib_forward_like should have the value 202207L in c++23" +# endif + +# ifdef __cpp_lib_freestanding_algorithm +# error "__cpp_lib_freestanding_algorithm should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_array +# error "__cpp_lib_freestanding_array should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_cstring +# error "__cpp_lib_freestanding_cstring should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_expected +# error "__cpp_lib_freestanding_expected should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_mdspan +# error "__cpp_lib_freestanding_mdspan should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_optional +# error "__cpp_lib_freestanding_optional should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_string_view +# error "__cpp_lib_freestanding_string_view should not be defined before c++26" +# endif + +# ifdef __cpp_lib_freestanding_variant +# error "__cpp_lib_freestanding_variant should not be defined before c++26" +# endif + +# ifdef __cpp_lib_fstream_native_handle +# error "__cpp_lib_fstream_native_handle should not be defined before c++26" +# endif + +# ifdef __cpp_lib_function_ref +# error "__cpp_lib_function_ref should not be defined before c++26" +# endif + +# ifndef __cpp_lib_gcd_lcm +# error "__cpp_lib_gcd_lcm should be defined in c++23" +# endif +# if __cpp_lib_gcd_lcm != 201606L +# error "__cpp_lib_gcd_lcm should have the value 201606L in c++23" +# endif + +# ifdef __cpp_lib_generate_random +# error "__cpp_lib_generate_random should not be defined before c++26" +# endif + +# ifndef __cpp_lib_generic_associative_lookup +# error "__cpp_lib_generic_associative_lookup should be defined in c++23" +# endif +# if __cpp_lib_generic_associative_lookup != 201304L +# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_generic_unordered_lookup +# error "__cpp_lib_generic_unordered_lookup should be defined in c++23" +# endif +# if __cpp_lib_generic_unordered_lookup != 201811L +# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)) +# ifndef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should be defined in c++23" +# endif +# if __cpp_lib_hardware_interference_size != 201703L +# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++23" +# endif +# else +# ifdef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))' is not met!" +# endif +# endif + +# ifndef __cpp_lib_has_unique_object_representations +# error "__cpp_lib_has_unique_object_representations should be defined in c++23" +# endif +# if __cpp_lib_has_unique_object_representations != 201606L +# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++23" +# endif + +# ifdef __cpp_lib_hazard_pointer +# error "__cpp_lib_hazard_pointer should not be defined before c++26" +# endif + +# ifndef __cpp_lib_hypot +# error "__cpp_lib_hypot should be defined in c++23" +# endif +# if __cpp_lib_hypot != 201603L +# error "__cpp_lib_hypot should have the value 201603L in c++23" +# endif + +# ifndef __cpp_lib_incomplete_container_elements +# error "__cpp_lib_incomplete_container_elements should be defined in c++23" +# endif +# if __cpp_lib_incomplete_container_elements != 201505L +# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++23" +# endif + +# ifdef __cpp_lib_inplace_vector +# error "__cpp_lib_inplace_vector should not be defined before c++26" +# endif + +# ifndef __cpp_lib_int_pow2 +# error "__cpp_lib_int_pow2 should be defined in c++23" +# endif +# if __cpp_lib_int_pow2 != 202002L +# error "__cpp_lib_int_pow2 should have the value 202002L in c++23" +# endif + +# ifndef __cpp_lib_integer_comparison_functions +# error "__cpp_lib_integer_comparison_functions should be defined in c++23" +# endif +# if __cpp_lib_integer_comparison_functions != 202002L +# error "__cpp_lib_integer_comparison_functions should have the value 202002L in c++23" +# endif + +# ifndef __cpp_lib_integer_sequence +# error "__cpp_lib_integer_sequence should be defined in c++23" +# endif +# if __cpp_lib_integer_sequence != 201304L +# error "__cpp_lib_integer_sequence should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_integral_constant_callable +# error "__cpp_lib_integral_constant_callable should be defined in c++23" +# endif +# if __cpp_lib_integral_constant_callable != 201304L +# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should be defined in c++23" +# endif +# if __cpp_lib_interpolate != 201902L +# error "__cpp_lib_interpolate should have the value 201902L in c++23" +# endif + +# ifndef __cpp_lib_invoke +# error "__cpp_lib_invoke should be defined in c++23" +# endif +# if __cpp_lib_invoke != 201411L +# error "__cpp_lib_invoke should have the value 201411L in c++23" +# endif + +# ifndef __cpp_lib_invoke_r +# error "__cpp_lib_invoke_r should be defined in c++23" +# endif +# if __cpp_lib_invoke_r != 202106L +# error "__cpp_lib_invoke_r should have the value 202106L in c++23" +# endif + +# ifndef __cpp_lib_ios_noreplace +# error "__cpp_lib_ios_noreplace should be defined in c++23" +# endif +# if __cpp_lib_ios_noreplace != 202207L +# error "__cpp_lib_ios_noreplace should have the value 202207L in c++23" +# endif + +# ifndef __cpp_lib_is_aggregate +# error "__cpp_lib_is_aggregate should be defined in c++23" +# endif +# if __cpp_lib_is_aggregate != 201703L +# error "__cpp_lib_is_aggregate should have the value 201703L in c++23" +# endif + +# ifndef __cpp_lib_is_constant_evaluated +# error "__cpp_lib_is_constant_evaluated should be defined in c++23" +# endif +# if __cpp_lib_is_constant_evaluated != 201811L +# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++23" +# endif + +# ifndef __cpp_lib_is_final +# error "__cpp_lib_is_final should be defined in c++23" +# endif +# if __cpp_lib_is_final != 201402L +# error "__cpp_lib_is_final should have the value 201402L in c++23" +# endif + +# if __has_builtin(__builtin_is_implicit_lifetime) +# ifndef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should be defined in c++23" +# endif +# if __cpp_lib_is_implicit_lifetime != 202302L +# error "__cpp_lib_is_implicit_lifetime should have the value 202302L in c++23" +# endif +# else +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_implicit_lifetime)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_is_invocable +# error "__cpp_lib_is_invocable should be defined in c++23" +# endif +# if __cpp_lib_is_invocable != 201703L +# error "__cpp_lib_is_invocable should have the value 201703L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_is_layout_compatible +# error "__cpp_lib_is_layout_compatible should be defined in c++23" +# endif +# if __cpp_lib_is_layout_compatible != 201907L +# error "__cpp_lib_is_layout_compatible should have the value 201907L in c++23" +# endif +# else +# ifdef __cpp_lib_is_layout_compatible +# error "__cpp_lib_is_layout_compatible should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_is_nothrow_convertible +# error "__cpp_lib_is_nothrow_convertible should be defined in c++23" +# endif +# if __cpp_lib_is_nothrow_convertible != 201806L +# error "__cpp_lib_is_nothrow_convertible should have the value 201806L in c++23" +# endif + +# ifndef __cpp_lib_is_null_pointer +# error "__cpp_lib_is_null_pointer should be defined in c++23" +# endif +# if __cpp_lib_is_null_pointer != 201309L +# error "__cpp_lib_is_null_pointer should have the value 201309L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_is_pointer_interconvertible +# error "__cpp_lib_is_pointer_interconvertible should be defined in c++23" +# endif +# if __cpp_lib_is_pointer_interconvertible != 201907L +# error "__cpp_lib_is_pointer_interconvertible should have the value 201907L in c++23" +# endif +# else +# ifdef __cpp_lib_is_pointer_interconvertible +# error "__cpp_lib_is_pointer_interconvertible should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_is_scoped_enum +# error "__cpp_lib_is_scoped_enum should be defined in c++23" +# endif +# if __cpp_lib_is_scoped_enum != 202011L +# error "__cpp_lib_is_scoped_enum should have the value 202011L in c++23" +# endif + +# ifdef __cpp_lib_is_sufficiently_aligned +# error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26" +# endif + +# ifndef __cpp_lib_is_swappable +# error "__cpp_lib_is_swappable should be defined in c++23" +# endif +# if __cpp_lib_is_swappable != 201603L +# error "__cpp_lib_is_swappable should have the value 201603L in c++23" +# endif + +# ifdef __cpp_lib_is_virtual_base_of +# error "__cpp_lib_is_virtual_base_of should not be defined before c++26" +# endif + +# ifdef __cpp_lib_is_within_lifetime +# error "__cpp_lib_is_within_lifetime should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_jthread +# error "__cpp_lib_jthread should be defined in c++23" +# endif +# if __cpp_lib_jthread != 201911L +# error "__cpp_lib_jthread should have the value 201911L in c++23" +# endif +# else +# ifdef __cpp_lib_jthread +# error "__cpp_lib_jthread should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_latch +# error "__cpp_lib_latch should be defined in c++23" +# endif +# if __cpp_lib_latch != 201907L +# error "__cpp_lib_latch should have the value 201907L in c++23" +# endif +# else +# ifdef __cpp_lib_latch +# error "__cpp_lib_latch should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_launder +# error "__cpp_lib_launder should be defined in c++23" +# endif +# if __cpp_lib_launder != 201606L +# error "__cpp_lib_launder should have the value 201606L in c++23" +# endif + +# ifdef __cpp_lib_linalg +# error "__cpp_lib_linalg should not be defined before c++26" +# endif + +# ifndef __cpp_lib_list_remove_return_type +# error "__cpp_lib_list_remove_return_type should be defined in c++23" +# endif +# if __cpp_lib_list_remove_return_type != 201806L +# error "__cpp_lib_list_remove_return_type should have the value 201806L in c++23" +# endif + +# ifndef __cpp_lib_logical_traits +# error "__cpp_lib_logical_traits should be defined in c++23" +# endif +# if __cpp_lib_logical_traits != 201510L +# error "__cpp_lib_logical_traits should have the value 201510L in c++23" +# endif + +# ifndef __cpp_lib_make_from_tuple +# error "__cpp_lib_make_from_tuple should be defined in c++23" +# endif +# if __cpp_lib_make_from_tuple != 201606L +# error "__cpp_lib_make_from_tuple should have the value 201606L in c++23" +# endif + +# ifndef __cpp_lib_make_reverse_iterator +# error "__cpp_lib_make_reverse_iterator should be defined in c++23" +# endif +# if __cpp_lib_make_reverse_iterator != 201402L +# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++23" +# endif + +# ifndef __cpp_lib_make_unique +# error "__cpp_lib_make_unique should be defined in c++23" +# endif +# if __cpp_lib_make_unique != 201304L +# error "__cpp_lib_make_unique should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_map_try_emplace +# error "__cpp_lib_map_try_emplace should be defined in c++23" +# endif +# if __cpp_lib_map_try_emplace != 201411L +# error "__cpp_lib_map_try_emplace should have the value 201411L in c++23" +# endif + +# ifndef __cpp_lib_math_constants +# error "__cpp_lib_math_constants should be defined in c++23" +# endif +# if __cpp_lib_math_constants != 201907L +# error "__cpp_lib_math_constants should have the value 201907L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should be defined in c++23" +# endif +# if __cpp_lib_math_special_functions != 201603L +# error "__cpp_lib_math_special_functions should have the value 201603L in c++23" +# endif +# else +# ifdef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_mdspan +# error "__cpp_lib_mdspan should be defined in c++23" +# endif +# if __cpp_lib_mdspan != 202207L +# error "__cpp_lib_mdspan should have the value 202207L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR +# ifndef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should be defined in c++23" +# endif +# if __cpp_lib_memory_resource != 201603L +# error "__cpp_lib_memory_resource should have the value 201603L in c++23" +# endif +# else +# ifdef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" +# endif +# endif + +# ifndef __cpp_lib_modules +# error "__cpp_lib_modules should be defined in c++23" +# endif +# if __cpp_lib_modules != 202207L +# error "__cpp_lib_modules should have the value 202207L in c++23" +# endif + +# ifndef __cpp_lib_move_iterator_concept +# error "__cpp_lib_move_iterator_concept should be defined in c++23" +# endif +# if __cpp_lib_move_iterator_concept != 202207L +# error "__cpp_lib_move_iterator_concept should have the value 202207L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_move_only_function +# error "__cpp_lib_move_only_function should be defined in c++23" +# endif +# if __cpp_lib_move_only_function != 202110L +# error "__cpp_lib_move_only_function should have the value 202110L in c++23" +# endif +# else +# ifdef __cpp_lib_move_only_function +# error "__cpp_lib_move_only_function should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_node_extract +# error "__cpp_lib_node_extract should be defined in c++23" +# endif +# if __cpp_lib_node_extract != 201606L +# error "__cpp_lib_node_extract should have the value 201606L in c++23" +# endif + +# ifndef __cpp_lib_nonmember_container_access +# error "__cpp_lib_nonmember_container_access should be defined in c++23" +# endif +# if __cpp_lib_nonmember_container_access != 201411L +# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++23" +# endif + +# ifndef __cpp_lib_not_fn +# error "__cpp_lib_not_fn should be defined in c++23" +# endif +# if __cpp_lib_not_fn != 201603L +# error "__cpp_lib_not_fn should have the value 201603L in c++23" +# endif + +# ifndef __cpp_lib_null_iterators +# error "__cpp_lib_null_iterators should be defined in c++23" +# endif +# if __cpp_lib_null_iterators != 201304L +# error "__cpp_lib_null_iterators should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_optional +# error "__cpp_lib_optional should be defined in c++23" +# endif +# if __cpp_lib_optional != 202110L +# error "__cpp_lib_optional should have the value 202110L in c++23" +# endif + +# ifdef __cpp_lib_optional_range_support +# error "__cpp_lib_optional_range_support should not be defined before c++26" +# endif + +# ifndef __cpp_lib_out_ptr +# error "__cpp_lib_out_ptr should be defined in c++23" +# endif +# if __cpp_lib_out_ptr != 202106L +# error "__cpp_lib_out_ptr should have the value 202106L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should be defined in c++23" +# endif +# if __cpp_lib_parallel_algorithm != 201603L +# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++23" +# endif +# else +# ifdef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_philox_engine +# error "__cpp_lib_philox_engine should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR +# ifndef __cpp_lib_polymorphic_allocator +# error "__cpp_lib_polymorphic_allocator should be defined in c++23" +# endif +# if __cpp_lib_polymorphic_allocator != 201902L +# error "__cpp_lib_polymorphic_allocator should have the value 201902L in c++23" +# endif +# else +# ifdef __cpp_lib_polymorphic_allocator +# error "__cpp_lib_polymorphic_allocator should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT +# ifndef __cpp_lib_print +# error "__cpp_lib_print should be defined in c++23" +# endif +# if __cpp_lib_print != 202207L +# error "__cpp_lib_print should have the value 202207L in c++23" +# endif +# else +# ifdef __cpp_lib_print +# error "__cpp_lib_print should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION +# ifndef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should be defined in c++23" +# endif +# if __cpp_lib_quoted_string_io != 201304L +# error "__cpp_lib_quoted_string_io should have the value 201304L in c++23" +# endif +# else +# ifdef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" +# endif +# endif + +# ifndef __cpp_lib_ranges +# error "__cpp_lib_ranges should be defined in c++23" +# endif +# if __cpp_lib_ranges != 202406L +# error "__cpp_lib_ranges should have the value 202406L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_as_const +# error "__cpp_lib_ranges_as_const should be defined in c++23" +# endif +# if __cpp_lib_ranges_as_const != 202207L +# error "__cpp_lib_ranges_as_const should have the value 202207L in c++23" +# endif +# else +# ifdef __cpp_lib_ranges_as_const +# error "__cpp_lib_ranges_as_const should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_as_rvalue +# error "__cpp_lib_ranges_as_rvalue should be defined in c++23" +# endif +# if __cpp_lib_ranges_as_rvalue != 202207L +# error "__cpp_lib_ranges_as_rvalue should have the value 202207L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should be defined in c++23" +# endif +# if __cpp_lib_ranges_chunk != 202202L +# error "__cpp_lib_ranges_chunk should have the value 202202L in c++23" +# endif +# else +# ifdef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_chunk_by +# error "__cpp_lib_ranges_chunk_by should be defined in c++23" +# endif +# if __cpp_lib_ranges_chunk_by != 202202L +# error "__cpp_lib_ranges_chunk_by should have the value 202202L in c++23" +# endif + +# ifdef __cpp_lib_ranges_concat +# error "__cpp_lib_ranges_concat should not be defined before c++26" +# endif + +# ifndef __cpp_lib_ranges_contains +# error "__cpp_lib_ranges_contains should be defined in c++23" +# endif +# if __cpp_lib_ranges_contains != 202207L +# error "__cpp_lib_ranges_contains should have the value 202207L in c++23" +# endif + +# ifndef __cpp_lib_ranges_find_last +# error "__cpp_lib_ranges_find_last should be defined in c++23" +# endif +# if __cpp_lib_ranges_find_last != 202207L +# error "__cpp_lib_ranges_find_last should have the value 202207L in c++23" +# endif + +# ifndef __cpp_lib_ranges_iota +# error "__cpp_lib_ranges_iota should be defined in c++23" +# endif +# if __cpp_lib_ranges_iota != 202202L +# error "__cpp_lib_ranges_iota should have the value 202202L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_join_with +# error "__cpp_lib_ranges_join_with should be defined in c++23" +# endif +# if __cpp_lib_ranges_join_with != 202202L +# error "__cpp_lib_ranges_join_with should have the value 202202L in c++23" +# endif +# else +# ifdef __cpp_lib_ranges_join_with +# error "__cpp_lib_ranges_join_with should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_repeat +# error "__cpp_lib_ranges_repeat should be defined in c++23" +# endif +# if __cpp_lib_ranges_repeat != 202207L +# error "__cpp_lib_ranges_repeat should have the value 202207L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_slide +# error "__cpp_lib_ranges_slide should be defined in c++23" +# endif +# if __cpp_lib_ranges_slide != 202202L +# error "__cpp_lib_ranges_slide should have the value 202202L in c++23" +# endif +# else +# ifdef __cpp_lib_ranges_slide +# error "__cpp_lib_ranges_slide should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_starts_ends_with +# error "__cpp_lib_ranges_starts_ends_with should be defined in c++23" +# endif +# if __cpp_lib_ranges_starts_ends_with != 202106L +# error "__cpp_lib_ranges_starts_ends_with should have the value 202106L in c++23" +# endif + +# ifndef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should be defined in c++23" +# endif +# if __cpp_lib_ranges_stride != 202207L +# error "__cpp_lib_ranges_stride should have the value 202207L in c++23" +# endif + +# ifndef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should be defined in c++23" +# endif +# if __cpp_lib_ranges_to_container != 202202L +# error "__cpp_lib_ranges_to_container should have the value 202202L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_zip +# error "__cpp_lib_ranges_zip should be defined in c++23" +# endif +# if __cpp_lib_ranges_zip != 202110L +# error "__cpp_lib_ranges_zip should have the value 202110L in c++23" +# endif +# else +# ifdef __cpp_lib_ranges_zip +# error "__cpp_lib_ranges_zip should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_ratio +# error "__cpp_lib_ratio should not be defined before c++26" +# endif + +# ifndef __cpp_lib_raw_memory_algorithms +# error "__cpp_lib_raw_memory_algorithms should be defined in c++23" +# endif +# if __cpp_lib_raw_memory_algorithms != 201606L +# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++23" +# endif + +# ifdef __cpp_lib_rcu +# error "__cpp_lib_rcu should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_reference_from_temporary +# error "__cpp_lib_reference_from_temporary should be defined in c++23" +# endif +# if __cpp_lib_reference_from_temporary != 202202L +# error "__cpp_lib_reference_from_temporary should have the value 202202L in c++23" +# endif +# else +# ifdef __cpp_lib_reference_from_temporary +# error "__cpp_lib_reference_from_temporary should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_reference_wrapper +# error "__cpp_lib_reference_wrapper should not be defined before c++26" +# endif + +# ifndef __cpp_lib_remove_cvref +# error "__cpp_lib_remove_cvref should be defined in c++23" +# endif +# if __cpp_lib_remove_cvref != 201711L +# error "__cpp_lib_remove_cvref should have the value 201711L in c++23" +# endif + +# ifndef __cpp_lib_result_of_sfinae +# error "__cpp_lib_result_of_sfinae should be defined in c++23" +# endif +# if __cpp_lib_result_of_sfinae != 201210L +# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++23" +# endif + +# ifndef __cpp_lib_robust_nonmodifying_seq_ops +# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++23" +# endif +# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L +# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_sample +# error "__cpp_lib_sample should be defined in c++23" +# endif +# if __cpp_lib_sample != 201603L +# error "__cpp_lib_sample should have the value 201603L in c++23" +# endif + +# ifdef __cpp_lib_saturation_arithmetic +# error "__cpp_lib_saturation_arithmetic should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should be defined in c++23" +# endif +# if __cpp_lib_scoped_lock != 201703L +# error "__cpp_lib_scoped_lock should have the value 201703L in c++23" +# endif +# else +# ifdef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_semaphore +# error "__cpp_lib_semaphore should be defined in c++23" +# endif +# if __cpp_lib_semaphore != 201907L +# error "__cpp_lib_semaphore should have the value 201907L in c++23" +# endif +# else +# ifdef __cpp_lib_semaphore +# error "__cpp_lib_semaphore should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# ifdef __cpp_lib_senders +# error "__cpp_lib_senders should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should be defined in c++23" +# endif +# if __cpp_lib_shared_mutex != 201505L +# error "__cpp_lib_shared_mutex should have the value 201505L in c++23" +# endif +# else +# ifdef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifndef __cpp_lib_shared_ptr_arrays +# error "__cpp_lib_shared_ptr_arrays should be defined in c++23" +# endif +# if __cpp_lib_shared_ptr_arrays != 201707L +# error "__cpp_lib_shared_ptr_arrays should have the value 201707L in c++23" +# endif + +# ifndef __cpp_lib_shared_ptr_weak_type +# error "__cpp_lib_shared_ptr_weak_type should be defined in c++23" +# endif +# if __cpp_lib_shared_ptr_weak_type != 201606L +# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should be defined in c++23" +# endif +# if __cpp_lib_shared_timed_mutex != 201402L +# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++23" +# endif +# else +# ifdef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifndef __cpp_lib_shift +# error "__cpp_lib_shift should be defined in c++23" +# endif +# if __cpp_lib_shift != 201806L +# error "__cpp_lib_shift should have the value 201806L in c++23" +# endif + +# ifndef __cpp_lib_smart_ptr_for_overwrite +# error "__cpp_lib_smart_ptr_for_overwrite should be defined in c++23" +# endif +# if __cpp_lib_smart_ptr_for_overwrite != 202002L +# error "__cpp_lib_smart_ptr_for_overwrite should have the value 202002L in c++23" +# endif + +# ifdef __cpp_lib_smart_ptr_owner_equality +# error "__cpp_lib_smart_ptr_owner_equality should not be defined before c++26" +# endif + +# ifndef __cpp_lib_source_location +# error "__cpp_lib_source_location should be defined in c++23" +# endif +# if __cpp_lib_source_location != 201907L +# error "__cpp_lib_source_location should have the value 201907L in c++23" +# endif + +# ifndef __cpp_lib_span +# error "__cpp_lib_span should be defined in c++23" +# endif +# if __cpp_lib_span != 202002L +# error "__cpp_lib_span should have the value 202002L in c++23" +# endif + +# ifdef __cpp_lib_span_at +# error "__cpp_lib_span_at should not be defined before c++26" +# endif + +# ifdef __cpp_lib_span_initializer_list +# error "__cpp_lib_span_initializer_list should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_spanstream +# error "__cpp_lib_spanstream should be defined in c++23" +# endif +# if __cpp_lib_spanstream != 202106L +# error "__cpp_lib_spanstream should have the value 202106L in c++23" +# endif +# else +# ifdef __cpp_lib_spanstream +# error "__cpp_lib_spanstream should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ssize +# error "__cpp_lib_ssize should be defined in c++23" +# endif +# if __cpp_lib_ssize != 201902L +# error "__cpp_lib_ssize should have the value 201902L in c++23" +# endif + +# ifdef __cpp_lib_sstream_from_string_view +# error "__cpp_lib_sstream_from_string_view should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_stacktrace +# error "__cpp_lib_stacktrace should be defined in c++23" +# endif +# if __cpp_lib_stacktrace != 202011L +# error "__cpp_lib_stacktrace should have the value 202011L in c++23" +# endif +# else +# ifdef __cpp_lib_stacktrace +# error "__cpp_lib_stacktrace should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_starts_ends_with +# error "__cpp_lib_starts_ends_with should be defined in c++23" +# endif +# if __cpp_lib_starts_ends_with != 201711L +# error "__cpp_lib_starts_ends_with should have the value 201711L in c++23" +# endif + +# ifndef __cpp_lib_stdatomic_h +# error "__cpp_lib_stdatomic_h should be defined in c++23" +# endif +# if __cpp_lib_stdatomic_h != 202011L +# error "__cpp_lib_stdatomic_h should have the value 202011L in c++23" +# endif + +# ifndef __cpp_lib_string_contains +# error "__cpp_lib_string_contains should be defined in c++23" +# endif +# if __cpp_lib_string_contains != 202011L +# error "__cpp_lib_string_contains should have the value 202011L in c++23" +# endif + +# ifndef __cpp_lib_string_resize_and_overwrite +# error "__cpp_lib_string_resize_and_overwrite should be defined in c++23" +# endif +# if __cpp_lib_string_resize_and_overwrite != 202110L +# error "__cpp_lib_string_resize_and_overwrite should have the value 202110L in c++23" +# endif + +# ifndef __cpp_lib_string_udls +# error "__cpp_lib_string_udls should be defined in c++23" +# endif +# if __cpp_lib_string_udls != 201304L +# error "__cpp_lib_string_udls should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_string_view +# error "__cpp_lib_string_view should be defined in c++23" +# endif +# if __cpp_lib_string_view != 201803L +# error "__cpp_lib_string_view should have the value 201803L in c++23" +# endif + +# ifdef __cpp_lib_submdspan +# error "__cpp_lib_submdspan should not be defined before c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM +# ifndef __cpp_lib_syncbuf +# error "__cpp_lib_syncbuf should be defined in c++23" +# endif +# if __cpp_lib_syncbuf != 201803L +# error "__cpp_lib_syncbuf should have the value 201803L in c++23" +# endif +# else +# ifdef __cpp_lib_syncbuf +# error "__cpp_lib_syncbuf should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM' is not met!" +# endif +# endif + +# ifdef __cpp_lib_text_encoding +# error "__cpp_lib_text_encoding should not be defined before c++26" +# endif + +# ifndef __cpp_lib_three_way_comparison +# error "__cpp_lib_three_way_comparison should be defined in c++23" +# endif +# if __cpp_lib_three_way_comparison != 201907L +# error "__cpp_lib_three_way_comparison should have the value 201907L in c++23" +# endif + +# ifndef __cpp_lib_to_address +# error "__cpp_lib_to_address should be defined in c++23" +# endif +# if __cpp_lib_to_address != 201711L +# error "__cpp_lib_to_address should have the value 201711L in c++23" +# endif + +# ifndef __cpp_lib_to_array +# error "__cpp_lib_to_array should be defined in c++23" +# endif +# if __cpp_lib_to_array != 201907L +# error "__cpp_lib_to_array should have the value 201907L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should be defined in c++23" +# endif +# if __cpp_lib_to_chars != 201611L +# error "__cpp_lib_to_chars should have the value 201611L in c++23" +# endif +# else +# ifdef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifdef __cpp_lib_to_string +# error "__cpp_lib_to_string should not be defined before c++26" +# endif + +# ifndef __cpp_lib_to_underlying +# error "__cpp_lib_to_underlying should be defined in c++23" +# endif +# if __cpp_lib_to_underlying != 202102L +# error "__cpp_lib_to_underlying should have the value 202102L in c++23" +# endif + +# ifndef __cpp_lib_transformation_trait_aliases +# error "__cpp_lib_transformation_trait_aliases should be defined in c++23" +# endif +# if __cpp_lib_transformation_trait_aliases != 201304L +# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_transparent_operators +# error "__cpp_lib_transparent_operators should be defined in c++23" +# endif +# if __cpp_lib_transparent_operators != 201510L +# error "__cpp_lib_transparent_operators should have the value 201510L in c++23" +# endif + +# ifndef __cpp_lib_tuple_element_t +# error "__cpp_lib_tuple_element_t should be defined in c++23" +# endif +# if __cpp_lib_tuple_element_t != 201402L +# error "__cpp_lib_tuple_element_t should have the value 201402L in c++23" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_tuple_like +# error "__cpp_lib_tuple_like should be defined in c++23" +# endif +# if __cpp_lib_tuple_like != 202207L +# error "__cpp_lib_tuple_like should have the value 202207L in c++23" +# endif +# else +# ifdef __cpp_lib_tuple_like +# error "__cpp_lib_tuple_like should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_tuples_by_type +# error "__cpp_lib_tuples_by_type should be defined in c++23" +# endif +# if __cpp_lib_tuples_by_type != 201304L +# error "__cpp_lib_tuples_by_type should have the value 201304L in c++23" +# endif + +# ifndef __cpp_lib_type_identity +# error "__cpp_lib_type_identity should be defined in c++23" +# endif +# if __cpp_lib_type_identity != 201806L +# error "__cpp_lib_type_identity should have the value 201806L in c++23" +# endif + +# ifndef __cpp_lib_type_trait_variable_templates +# error "__cpp_lib_type_trait_variable_templates should be defined in c++23" +# endif +# if __cpp_lib_type_trait_variable_templates != 201510L +# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++23" +# endif + +# ifndef __cpp_lib_uncaught_exceptions +# error "__cpp_lib_uncaught_exceptions should be defined in c++23" +# endif +# if __cpp_lib_uncaught_exceptions != 201411L +# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++23" +# endif + +# ifndef __cpp_lib_unordered_map_try_emplace +# error "__cpp_lib_unordered_map_try_emplace should be defined in c++23" +# endif +# if __cpp_lib_unordered_map_try_emplace != 201411L +# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++23" +# endif + +# ifndef __cpp_lib_unreachable +# error "__cpp_lib_unreachable should be defined in c++23" +# endif +# if __cpp_lib_unreachable != 202202L +# error "__cpp_lib_unreachable should have the value 202202L in c++23" +# endif + +# ifndef __cpp_lib_unwrap_ref +# error "__cpp_lib_unwrap_ref should be defined in c++23" +# endif +# if __cpp_lib_unwrap_ref != 201811L +# error "__cpp_lib_unwrap_ref should have the value 201811L in c++23" +# endif + +# ifndef __cpp_lib_variant +# error "__cpp_lib_variant should be defined in c++23" +# endif +# if __cpp_lib_variant != 202106L +# error "__cpp_lib_variant should have the value 202106L in c++23" +# endif + +# ifndef __cpp_lib_void_t +# error "__cpp_lib_void_t should be defined in c++23" +# endif +# if __cpp_lib_void_t != 201411L +# error "__cpp_lib_void_t should have the value 201411L in c++23" +# endif + +#elif TEST_STD_VER > 23 + +# ifndef __cpp_lib_adaptor_iterator_pair_constructor +# error "__cpp_lib_adaptor_iterator_pair_constructor should be defined in c++26" +# endif +# if __cpp_lib_adaptor_iterator_pair_constructor != 202106L +# error "__cpp_lib_adaptor_iterator_pair_constructor should have the value 202106L in c++26" +# endif + +# ifndef __cpp_lib_addressof_constexpr +# error "__cpp_lib_addressof_constexpr should be defined in c++26" +# endif +# if __cpp_lib_addressof_constexpr != 201603L +# error "__cpp_lib_addressof_constexpr should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_aligned_accessor +# error "__cpp_lib_aligned_accessor should be defined in c++26" +# endif +# if __cpp_lib_aligned_accessor != 202411L +# error "__cpp_lib_aligned_accessor should have the value 202411L in c++26" +# endif + +# ifndef __cpp_lib_allocate_at_least +# error "__cpp_lib_allocate_at_least should be defined in c++26" +# endif +# if __cpp_lib_allocate_at_least != 202302L +# error "__cpp_lib_allocate_at_least should have the value 202302L in c++26" +# endif + +# ifndef __cpp_lib_allocator_traits_is_always_equal +# error "__cpp_lib_allocator_traits_is_always_equal should be defined in c++26" +# endif +# if __cpp_lib_allocator_traits_is_always_equal != 201411L +# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++26" +# endif + +# ifndef __cpp_lib_any +# error "__cpp_lib_any should be defined in c++26" +# endif +# if __cpp_lib_any != 201606L +# error "__cpp_lib_any should have the value 201606L in c++26" +# endif + +# ifndef __cpp_lib_apply +# error "__cpp_lib_apply should be defined in c++26" +# endif +# if __cpp_lib_apply != 201603L +# error "__cpp_lib_apply should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_array_constexpr +# error "__cpp_lib_array_constexpr should be defined in c++26" +# endif +# if __cpp_lib_array_constexpr != 201811L +# error "__cpp_lib_array_constexpr should have the value 201811L in c++26" +# endif + +# ifndef __cpp_lib_as_const +# error "__cpp_lib_as_const should be defined in c++26" +# endif +# if __cpp_lib_as_const != 201510L +# error "__cpp_lib_as_const should have the value 201510L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_associative_heterogeneous_erasure +# error "__cpp_lib_associative_heterogeneous_erasure should be defined in c++26" +# endif +# if __cpp_lib_associative_heterogeneous_erasure != 202110L +# error "__cpp_lib_associative_heterogeneous_erasure should have the value 202110L in c++26" +# endif +# else +# ifdef __cpp_lib_associative_heterogeneous_erasure +# error "__cpp_lib_associative_heterogeneous_erasure should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_associative_heterogeneous_insertion +# error "__cpp_lib_associative_heterogeneous_insertion should be defined in c++26" +# endif +# if __cpp_lib_associative_heterogeneous_insertion != 202306L +# error "__cpp_lib_associative_heterogeneous_insertion should have the value 202306L in c++26" +# endif +# else +# ifdef __cpp_lib_associative_heterogeneous_insertion +# error "__cpp_lib_associative_heterogeneous_insertion should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_assume_aligned +# error "__cpp_lib_assume_aligned should be defined in c++26" +# endif +# if __cpp_lib_assume_aligned != 201811L +# error "__cpp_lib_assume_aligned should have the value 201811L in c++26" +# endif + +# ifndef __cpp_lib_atomic_flag_test +# error "__cpp_lib_atomic_flag_test should be defined in c++26" +# endif +# if __cpp_lib_atomic_flag_test != 201907L +# error "__cpp_lib_atomic_flag_test should have the value 201907L in c++26" +# endif + +# ifndef __cpp_lib_atomic_float +# error "__cpp_lib_atomic_float should be defined in c++26" +# endif +# if __cpp_lib_atomic_float != 201711L +# error "__cpp_lib_atomic_float should have the value 201711L in c++26" +# endif + +# ifndef __cpp_lib_atomic_is_always_lock_free +# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++26" +# endif +# if __cpp_lib_atomic_is_always_lock_free != 201603L +# error "__cpp_lib_atomic_is_always_lock_free should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_atomic_lock_free_type_aliases +# error "__cpp_lib_atomic_lock_free_type_aliases should be defined in c++26" +# endif +# if __cpp_lib_atomic_lock_free_type_aliases != 201907L +# error "__cpp_lib_atomic_lock_free_type_aliases should have the value 201907L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_atomic_min_max +# error "__cpp_lib_atomic_min_max should be defined in c++26" +# endif +# if __cpp_lib_atomic_min_max != 202403L +# error "__cpp_lib_atomic_min_max should have the value 202403L in c++26" +# endif +# else +# ifdef __cpp_lib_atomic_min_max +# error "__cpp_lib_atomic_min_max should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_atomic_ref +# error "__cpp_lib_atomic_ref should be defined in c++26" +# endif +# if __cpp_lib_atomic_ref != 201806L +# error "__cpp_lib_atomic_ref should have the value 201806L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_atomic_shared_ptr +# error "__cpp_lib_atomic_shared_ptr should be defined in c++26" +# endif +# if __cpp_lib_atomic_shared_ptr != 201711L +# error "__cpp_lib_atomic_shared_ptr should have the value 201711L in c++26" +# endif +# else +# ifdef __cpp_lib_atomic_shared_ptr +# error "__cpp_lib_atomic_shared_ptr should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_atomic_value_initialization +# error "__cpp_lib_atomic_value_initialization should be defined in c++26" +# endif +# if __cpp_lib_atomic_value_initialization != 201911L +# error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC +# ifndef __cpp_lib_atomic_wait +# error "__cpp_lib_atomic_wait should be defined in c++26" +# endif +# if __cpp_lib_atomic_wait != 201907L +# error "__cpp_lib_atomic_wait should have the value 201907L in c++26" +# endif +# else +# ifdef __cpp_lib_atomic_wait +# error "__cpp_lib_atomic_wait should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_SYNC' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_barrier +# error "__cpp_lib_barrier should be defined in c++26" +# endif +# if __cpp_lib_barrier != 201907L +# error "__cpp_lib_barrier should have the value 201907L in c++26" +# endif +# else +# ifdef __cpp_lib_barrier +# error "__cpp_lib_barrier should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_bind_back +# error "__cpp_lib_bind_back should be defined in c++26" +# endif +# if __cpp_lib_bind_back != 202202L +# error "__cpp_lib_bind_back should have the value 202202L in c++26" +# endif + +# ifndef __cpp_lib_bind_front +# error "__cpp_lib_bind_front should be defined in c++26" +# endif +# if __cpp_lib_bind_front != 202306L +# error "__cpp_lib_bind_front should have the value 202306L in c++26" +# endif + +# ifndef __cpp_lib_bit_cast +# error "__cpp_lib_bit_cast should be defined in c++26" +# endif +# if __cpp_lib_bit_cast != 201806L +# error "__cpp_lib_bit_cast should have the value 201806L in c++26" +# endif + +# ifndef __cpp_lib_bitops +# error "__cpp_lib_bitops should be defined in c++26" +# endif +# if __cpp_lib_bitops != 201907L +# error "__cpp_lib_bitops should have the value 201907L in c++26" +# endif + +# ifndef __cpp_lib_bitset +# error "__cpp_lib_bitset should be defined in c++26" +# endif +# if __cpp_lib_bitset != 202306L +# error "__cpp_lib_bitset should have the value 202306L in c++26" +# endif + +# ifndef __cpp_lib_bool_constant +# error "__cpp_lib_bool_constant should be defined in c++26" +# endif +# if __cpp_lib_bool_constant != 201505L +# error "__cpp_lib_bool_constant should have the value 201505L in c++26" +# endif + +# ifndef __cpp_lib_bounded_array_traits +# error "__cpp_lib_bounded_array_traits should be defined in c++26" +# endif +# if __cpp_lib_bounded_array_traits != 201902L +# error "__cpp_lib_bounded_array_traits should have the value 201902L in c++26" +# endif + +# ifndef __cpp_lib_boyer_moore_searcher +# error "__cpp_lib_boyer_moore_searcher should be defined in c++26" +# endif +# if __cpp_lib_boyer_moore_searcher != 201603L +# error "__cpp_lib_boyer_moore_searcher should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_byte +# error "__cpp_lib_byte should be defined in c++26" +# endif +# if __cpp_lib_byte != 201603L +# error "__cpp_lib_byte should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_byteswap +# error "__cpp_lib_byteswap should be defined in c++26" +# endif +# if __cpp_lib_byteswap != 202110L +# error "__cpp_lib_byteswap should have the value 202110L in c++26" +# endif + +# if defined(__cpp_char8_t) +# ifndef __cpp_lib_char8_t +# error "__cpp_lib_char8_t should be defined in c++26" +# endif +# if __cpp_lib_char8_t != 201907L +# error "__cpp_lib_char8_t should have the value 201907L in c++26" +# endif +# else +# ifdef __cpp_lib_char8_t +# error "__cpp_lib_char8_t should not be defined when the requirement 'defined(__cpp_char8_t)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_chrono +# error "__cpp_lib_chrono should be defined in c++26" +# endif +# if __cpp_lib_chrono != 201611L +# error "__cpp_lib_chrono should have the value 201611L in c++26" +# endif + +# ifndef __cpp_lib_chrono_udls +# error "__cpp_lib_chrono_udls should be defined in c++26" +# endif +# if __cpp_lib_chrono_udls != 201304L +# error "__cpp_lib_chrono_udls should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_clamp +# error "__cpp_lib_clamp should be defined in c++26" +# endif +# if __cpp_lib_clamp != 201603L +# error "__cpp_lib_clamp should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_complex_udls +# error "__cpp_lib_complex_udls should be defined in c++26" +# endif +# if __cpp_lib_complex_udls != 201309L +# error "__cpp_lib_complex_udls should have the value 201309L in c++26" +# endif + +# ifndef __cpp_lib_concepts +# error "__cpp_lib_concepts should be defined in c++26" +# endif +# if __cpp_lib_concepts != 202002L +# error "__cpp_lib_concepts should have the value 202002L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_algorithms +# error "__cpp_lib_constexpr_algorithms should be defined in c++26" +# endif +# if __cpp_lib_constexpr_algorithms != 202306L +# error "__cpp_lib_constexpr_algorithms should have the value 202306L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_bitset +# error "__cpp_lib_constexpr_bitset should be defined in c++26" +# endif +# if __cpp_lib_constexpr_bitset != 202207L +# error "__cpp_lib_constexpr_bitset should have the value 202207L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_charconv +# error "__cpp_lib_constexpr_charconv should be defined in c++26" +# endif +# if __cpp_lib_constexpr_charconv != 202207L +# error "__cpp_lib_constexpr_charconv should have the value 202207L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_constexpr_cmath +# error "__cpp_lib_constexpr_cmath should be defined in c++26" +# endif +# if __cpp_lib_constexpr_cmath != 202202L +# error "__cpp_lib_constexpr_cmath should have the value 202202L in c++26" +# endif +# else +# ifdef __cpp_lib_constexpr_cmath +# error "__cpp_lib_constexpr_cmath should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_constexpr_complex +# error "__cpp_lib_constexpr_complex should be defined in c++26" +# endif +# if __cpp_lib_constexpr_complex != 201711L +# error "__cpp_lib_constexpr_complex should have the value 201711L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_dynamic_alloc +# error "__cpp_lib_constexpr_dynamic_alloc should be defined in c++26" +# endif +# if __cpp_lib_constexpr_dynamic_alloc != 201907L +# error "__cpp_lib_constexpr_dynamic_alloc should have the value 201907L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_functional +# error "__cpp_lib_constexpr_functional should be defined in c++26" +# endif +# if __cpp_lib_constexpr_functional != 201907L +# error "__cpp_lib_constexpr_functional should have the value 201907L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_iterator +# error "__cpp_lib_constexpr_iterator should be defined in c++26" +# endif +# if __cpp_lib_constexpr_iterator != 201811L +# error "__cpp_lib_constexpr_iterator should have the value 201811L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_memory +# error "__cpp_lib_constexpr_memory should be defined in c++26" +# endif +# if __cpp_lib_constexpr_memory != 202202L +# error "__cpp_lib_constexpr_memory should have the value 202202L in c++26" +# endif + +# if !defined(_LIBCPP_ABI_VCRUNTIME) +# ifndef __cpp_lib_constexpr_new +# error "__cpp_lib_constexpr_new should be defined in c++26" +# endif +# if __cpp_lib_constexpr_new != 202406L +# error "__cpp_lib_constexpr_new should have the value 202406L in c++26" +# endif +# else +# ifdef __cpp_lib_constexpr_new +# error "__cpp_lib_constexpr_new should not be defined when the requirement '!defined(_LIBCPP_ABI_VCRUNTIME)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_constexpr_numeric +# error "__cpp_lib_constexpr_numeric should be defined in c++26" +# endif +# if __cpp_lib_constexpr_numeric != 201911L +# error "__cpp_lib_constexpr_numeric should have the value 201911L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_string +# error "__cpp_lib_constexpr_string should be defined in c++26" +# endif +# if __cpp_lib_constexpr_string != 201907L +# error "__cpp_lib_constexpr_string should have the value 201907L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_string_view +# error "__cpp_lib_constexpr_string_view should be defined in c++26" +# endif +# if __cpp_lib_constexpr_string_view != 201811L +# error "__cpp_lib_constexpr_string_view should have the value 201811L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_tuple +# error "__cpp_lib_constexpr_tuple should be defined in c++26" +# endif +# if __cpp_lib_constexpr_tuple != 201811L +# error "__cpp_lib_constexpr_tuple should have the value 201811L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_typeinfo +# error "__cpp_lib_constexpr_typeinfo should be defined in c++26" +# endif +# if __cpp_lib_constexpr_typeinfo != 202106L +# error "__cpp_lib_constexpr_typeinfo should have the value 202106L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_utility +# error "__cpp_lib_constexpr_utility should be defined in c++26" +# endif +# if __cpp_lib_constexpr_utility != 201811L +# error "__cpp_lib_constexpr_utility should have the value 201811L in c++26" +# endif + +# ifndef __cpp_lib_constexpr_vector +# error "__cpp_lib_constexpr_vector should be defined in c++26" +# endif +# if __cpp_lib_constexpr_vector != 201907L +# error "__cpp_lib_constexpr_vector should have the value 201907L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_constrained_equality +# error "__cpp_lib_constrained_equality should be defined in c++26" +# endif +# if __cpp_lib_constrained_equality != 202403L +# error "__cpp_lib_constrained_equality should have the value 202403L in c++26" +# endif +# else +# ifdef __cpp_lib_constrained_equality +# error "__cpp_lib_constrained_equality should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_containers_ranges +# error "__cpp_lib_containers_ranges should be defined in c++26" +# endif +# if __cpp_lib_containers_ranges != 202202L +# error "__cpp_lib_containers_ranges should have the value 202202L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_copyable_function +# error "__cpp_lib_copyable_function should be defined in c++26" +# endif +# if __cpp_lib_copyable_function != 202306L +# error "__cpp_lib_copyable_function should have the value 202306L in c++26" +# endif +# else +# ifdef __cpp_lib_copyable_function +# error "__cpp_lib_copyable_function should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_coroutine +# error "__cpp_lib_coroutine should be defined in c++26" +# endif +# if __cpp_lib_coroutine != 201902L +# error "__cpp_lib_coroutine should have the value 201902L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_debugging +# error "__cpp_lib_debugging should be defined in c++26" +# endif +# if __cpp_lib_debugging != 202311L +# error "__cpp_lib_debugging should have the value 202311L in c++26" +# endif +# else +# ifdef __cpp_lib_debugging +# error "__cpp_lib_debugging should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_default_template_type_for_algorithm_values +# error "__cpp_lib_default_template_type_for_algorithm_values should be defined in c++26" +# endif +# if __cpp_lib_default_template_type_for_algorithm_values != 202403L +# error "__cpp_lib_default_template_type_for_algorithm_values should have the value 202403L in c++26" +# endif +# else +# ifdef __cpp_lib_default_template_type_for_algorithm_values +# error "__cpp_lib_default_template_type_for_algorithm_values should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L +# ifndef __cpp_lib_destroying_delete +# error "__cpp_lib_destroying_delete should be defined in c++26" +# endif +# if __cpp_lib_destroying_delete != 201806L +# error "__cpp_lib_destroying_delete should have the value 201806L in c++26" +# endif +# else +# ifdef __cpp_lib_destroying_delete +# error "__cpp_lib_destroying_delete should not be defined when the requirement 'TEST_STD_VER > 17 && defined(__cpp_impl_destroying_delete) && __cpp_impl_destroying_delete >= 201806L' is not met!" +# endif +# endif + +# ifndef __cpp_lib_enable_shared_from_this +# error "__cpp_lib_enable_shared_from_this should be defined in c++26" +# endif +# if __cpp_lib_enable_shared_from_this != 201603L +# error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_endian +# error "__cpp_lib_endian should be defined in c++26" +# endif +# if __cpp_lib_endian != 201907L +# error "__cpp_lib_endian should have the value 201907L in c++26" +# endif + +# ifndef __cpp_lib_erase_if +# error "__cpp_lib_erase_if should be defined in c++26" +# endif +# if __cpp_lib_erase_if != 202002L +# error "__cpp_lib_erase_if should have the value 202002L in c++26" +# endif + +# ifndef __cpp_lib_exchange_function +# error "__cpp_lib_exchange_function should be defined in c++26" +# endif +# if __cpp_lib_exchange_function != 201304L +# error "__cpp_lib_exchange_function should have the value 201304L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_execution +# error "__cpp_lib_execution should be defined in c++26" +# endif +# if __cpp_lib_execution != 201902L +# error "__cpp_lib_execution should have the value 201902L in c++26" +# endif +# else +# ifdef __cpp_lib_execution +# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_expected +# error "__cpp_lib_expected should be defined in c++26" +# endif +# if __cpp_lib_expected != 202211L +# error "__cpp_lib_expected should have the value 202211L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY) +# ifndef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should be defined in c++26" +# endif +# if __cpp_lib_filesystem != 201703L +# error "__cpp_lib_filesystem should have the value 201703L in c++26" +# endif +# else +# ifdef __cpp_lib_filesystem +# error "__cpp_lib_filesystem should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_AVAILABILITY_HAS_FILESYSTEM_LIBRARY)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_flat_map +# error "__cpp_lib_flat_map should be defined in c++26" +# endif +# if __cpp_lib_flat_map != 202207L +# error "__cpp_lib_flat_map should have the value 202207L in c++26" +# endif + +# ifndef __cpp_lib_flat_set +# error "__cpp_lib_flat_set should be defined in c++26" +# endif +# if __cpp_lib_flat_set != 202207L +# error "__cpp_lib_flat_set should have the value 202207L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT +# ifndef __cpp_lib_format +# error "__cpp_lib_format should be defined in c++26" +# endif +# if __cpp_lib_format != 202110L +# error "__cpp_lib_format should have the value 202110L in c++26" +# endif +# else +# ifdef __cpp_lib_format +# error "__cpp_lib_format should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_format_path +# error "__cpp_lib_format_path should be defined in c++26" +# endif +# if __cpp_lib_format_path != 202403L +# error "__cpp_lib_format_path should have the value 202403L in c++26" +# endif +# else +# ifdef __cpp_lib_format_path +# error "__cpp_lib_format_path should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_format_ranges +# error "__cpp_lib_format_ranges should be defined in c++26" +# endif +# if __cpp_lib_format_ranges != 202207L +# error "__cpp_lib_format_ranges should have the value 202207L in c++26" +# endif + +# ifndef __cpp_lib_format_uchar +# error "__cpp_lib_format_uchar should be defined in c++26" +# endif +# if __cpp_lib_format_uchar != 202311L +# error "__cpp_lib_format_uchar should have the value 202311L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_formatters +# error "__cpp_lib_formatters should be defined in c++26" +# endif +# if __cpp_lib_formatters != 202302L +# error "__cpp_lib_formatters should have the value 202302L in c++26" +# endif +# else +# ifdef __cpp_lib_formatters +# error "__cpp_lib_formatters should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_forward_like +# error "__cpp_lib_forward_like should be defined in c++26" +# endif +# if __cpp_lib_forward_like != 202207L +# error "__cpp_lib_forward_like should have the value 202207L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_freestanding_algorithm +# error "__cpp_lib_freestanding_algorithm should be defined in c++26" +# endif +# if __cpp_lib_freestanding_algorithm != 202311L +# error "__cpp_lib_freestanding_algorithm should have the value 202311L in c++26" +# endif +# else +# ifdef __cpp_lib_freestanding_algorithm +# error "__cpp_lib_freestanding_algorithm should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_freestanding_array +# error "__cpp_lib_freestanding_array should be defined in c++26" +# endif +# if __cpp_lib_freestanding_array != 202311L +# error "__cpp_lib_freestanding_array should have the value 202311L in c++26" +# endif +# else +# ifdef __cpp_lib_freestanding_array +# error "__cpp_lib_freestanding_array should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_freestanding_cstring +# error "__cpp_lib_freestanding_cstring should be defined in c++26" +# endif +# if __cpp_lib_freestanding_cstring != 202306L +# error "__cpp_lib_freestanding_cstring should have the value 202306L in c++26" +# endif +# else +# ifdef __cpp_lib_freestanding_cstring +# error "__cpp_lib_freestanding_cstring should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_freestanding_expected +# error "__cpp_lib_freestanding_expected should be defined in c++26" +# endif +# if __cpp_lib_freestanding_expected != 202311L +# error "__cpp_lib_freestanding_expected should have the value 202311L in c++26" +# endif +# else +# ifdef __cpp_lib_freestanding_expected +# error "__cpp_lib_freestanding_expected should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_freestanding_mdspan +# error "__cpp_lib_freestanding_mdspan should be defined in c++26" +# endif +# if __cpp_lib_freestanding_mdspan != 202311L +# error "__cpp_lib_freestanding_mdspan should have the value 202311L in c++26" +# endif +# else +# ifdef __cpp_lib_freestanding_mdspan +# error "__cpp_lib_freestanding_mdspan should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_freestanding_optional +# error "__cpp_lib_freestanding_optional should be defined in c++26" +# endif +# if __cpp_lib_freestanding_optional != 202311L +# error "__cpp_lib_freestanding_optional should have the value 202311L in c++26" +# endif +# else +# ifdef __cpp_lib_freestanding_optional +# error "__cpp_lib_freestanding_optional should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_freestanding_string_view +# error "__cpp_lib_freestanding_string_view should be defined in c++26" +# endif +# if __cpp_lib_freestanding_string_view != 202311L +# error "__cpp_lib_freestanding_string_view should have the value 202311L in c++26" +# endif +# else +# ifdef __cpp_lib_freestanding_string_view +# error "__cpp_lib_freestanding_string_view should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_freestanding_variant +# error "__cpp_lib_freestanding_variant should be defined in c++26" +# endif +# if __cpp_lib_freestanding_variant != 202311L +# error "__cpp_lib_freestanding_variant should have the value 202311L in c++26" +# endif +# else +# ifdef __cpp_lib_freestanding_variant +# error "__cpp_lib_freestanding_variant should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION) +# ifndef __cpp_lib_fstream_native_handle +# error "__cpp_lib_fstream_native_handle should be defined in c++26" +# endif +# if __cpp_lib_fstream_native_handle != 202306L +# error "__cpp_lib_fstream_native_handle should have the value 202306L in c++26" +# endif +# else +# ifdef __cpp_lib_fstream_native_handle +# error "__cpp_lib_fstream_native_handle should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_FILESYSTEM && _LIBCPP_HAS_LOCALIZATION)' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_function_ref +# error "__cpp_lib_function_ref should be defined in c++26" +# endif +# if __cpp_lib_function_ref != 202306L +# error "__cpp_lib_function_ref should have the value 202306L in c++26" +# endif +# else +# ifdef __cpp_lib_function_ref +# error "__cpp_lib_function_ref should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_gcd_lcm +# error "__cpp_lib_gcd_lcm should be defined in c++26" +# endif +# if __cpp_lib_gcd_lcm != 201606L +# error "__cpp_lib_gcd_lcm should have the value 201606L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_generate_random +# error "__cpp_lib_generate_random should be defined in c++26" +# endif +# if __cpp_lib_generate_random != 202403L +# error "__cpp_lib_generate_random should have the value 202403L in c++26" +# endif +# else +# ifdef __cpp_lib_generate_random +# error "__cpp_lib_generate_random should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_generic_associative_lookup +# error "__cpp_lib_generic_associative_lookup should be defined in c++26" +# endif +# if __cpp_lib_generic_associative_lookup != 201304L +# error "__cpp_lib_generic_associative_lookup should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_generic_unordered_lookup +# error "__cpp_lib_generic_unordered_lookup should be defined in c++26" +# endif +# if __cpp_lib_generic_unordered_lookup != 201811L +# error "__cpp_lib_generic_unordered_lookup should have the value 201811L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE)) +# ifndef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should be defined in c++26" +# endif +# if __cpp_lib_hardware_interference_size != 201703L +# error "__cpp_lib_hardware_interference_size should have the value 201703L in c++26" +# endif +# else +# ifdef __cpp_lib_hardware_interference_size +# error "__cpp_lib_hardware_interference_size should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (defined(__GCC_DESTRUCTIVE_SIZE) && defined(__GCC_CONSTRUCTIVE_SIZE))' is not met!" +# endif +# endif + +# ifndef __cpp_lib_has_unique_object_representations +# error "__cpp_lib_has_unique_object_representations should be defined in c++26" +# endif +# if __cpp_lib_has_unique_object_representations != 201606L +# error "__cpp_lib_has_unique_object_representations should have the value 201606L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_hazard_pointer +# error "__cpp_lib_hazard_pointer should be defined in c++26" +# endif +# if __cpp_lib_hazard_pointer != 202306L +# error "__cpp_lib_hazard_pointer should have the value 202306L in c++26" +# endif +# else +# ifdef __cpp_lib_hazard_pointer +# error "__cpp_lib_hazard_pointer should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_hypot +# error "__cpp_lib_hypot should be defined in c++26" +# endif +# if __cpp_lib_hypot != 201603L +# error "__cpp_lib_hypot should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_incomplete_container_elements +# error "__cpp_lib_incomplete_container_elements should be defined in c++26" +# endif +# if __cpp_lib_incomplete_container_elements != 201505L +# error "__cpp_lib_incomplete_container_elements should have the value 201505L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_inplace_vector +# error "__cpp_lib_inplace_vector should be defined in c++26" +# endif +# if __cpp_lib_inplace_vector != 202406L +# error "__cpp_lib_inplace_vector should have the value 202406L in c++26" +# endif +# else +# ifdef __cpp_lib_inplace_vector +# error "__cpp_lib_inplace_vector should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_int_pow2 +# error "__cpp_lib_int_pow2 should be defined in c++26" +# endif +# if __cpp_lib_int_pow2 != 202002L +# error "__cpp_lib_int_pow2 should have the value 202002L in c++26" +# endif + +# ifndef __cpp_lib_integer_comparison_functions +# error "__cpp_lib_integer_comparison_functions should be defined in c++26" +# endif +# if __cpp_lib_integer_comparison_functions != 202002L +# error "__cpp_lib_integer_comparison_functions should have the value 202002L in c++26" +# endif + +# ifndef __cpp_lib_integer_sequence +# error "__cpp_lib_integer_sequence should be defined in c++26" +# endif +# if __cpp_lib_integer_sequence != 201304L +# error "__cpp_lib_integer_sequence should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_integral_constant_callable +# error "__cpp_lib_integral_constant_callable should be defined in c++26" +# endif +# if __cpp_lib_integral_constant_callable != 201304L +# error "__cpp_lib_integral_constant_callable should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should be defined in c++26" +# endif +# if __cpp_lib_interpolate != 201902L +# error "__cpp_lib_interpolate should have the value 201902L in c++26" +# endif + +# ifndef __cpp_lib_invoke +# error "__cpp_lib_invoke should be defined in c++26" +# endif +# if __cpp_lib_invoke != 201411L +# error "__cpp_lib_invoke should have the value 201411L in c++26" +# endif + +# ifndef __cpp_lib_invoke_r +# error "__cpp_lib_invoke_r should be defined in c++26" +# endif +# if __cpp_lib_invoke_r != 202106L +# error "__cpp_lib_invoke_r should have the value 202106L in c++26" +# endif + +# ifndef __cpp_lib_ios_noreplace +# error "__cpp_lib_ios_noreplace should be defined in c++26" +# endif +# if __cpp_lib_ios_noreplace != 202207L +# error "__cpp_lib_ios_noreplace should have the value 202207L in c++26" +# endif + +# ifndef __cpp_lib_is_aggregate +# error "__cpp_lib_is_aggregate should be defined in c++26" +# endif +# if __cpp_lib_is_aggregate != 201703L +# error "__cpp_lib_is_aggregate should have the value 201703L in c++26" +# endif + +# ifndef __cpp_lib_is_constant_evaluated +# error "__cpp_lib_is_constant_evaluated should be defined in c++26" +# endif +# if __cpp_lib_is_constant_evaluated != 201811L +# error "__cpp_lib_is_constant_evaluated should have the value 201811L in c++26" +# endif + +# ifndef __cpp_lib_is_final +# error "__cpp_lib_is_final should be defined in c++26" +# endif +# if __cpp_lib_is_final != 201402L +# error "__cpp_lib_is_final should have the value 201402L in c++26" +# endif + +# if __has_builtin(__builtin_is_implicit_lifetime) +# ifndef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should be defined in c++26" +# endif +# if __cpp_lib_is_implicit_lifetime != 202302L +# error "__cpp_lib_is_implicit_lifetime should have the value 202302L in c++26" +# endif +# else +# ifdef __cpp_lib_is_implicit_lifetime +# error "__cpp_lib_is_implicit_lifetime should not be defined when the requirement '__has_builtin(__builtin_is_implicit_lifetime)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_is_invocable +# error "__cpp_lib_is_invocable should be defined in c++26" +# endif +# if __cpp_lib_is_invocable != 201703L +# error "__cpp_lib_is_invocable should have the value 201703L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_is_layout_compatible +# error "__cpp_lib_is_layout_compatible should be defined in c++26" +# endif +# if __cpp_lib_is_layout_compatible != 201907L +# error "__cpp_lib_is_layout_compatible should have the value 201907L in c++26" +# endif +# else +# ifdef __cpp_lib_is_layout_compatible +# error "__cpp_lib_is_layout_compatible should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_is_nothrow_convertible +# error "__cpp_lib_is_nothrow_convertible should be defined in c++26" +# endif +# if __cpp_lib_is_nothrow_convertible != 201806L +# error "__cpp_lib_is_nothrow_convertible should have the value 201806L in c++26" +# endif + +# ifndef __cpp_lib_is_null_pointer +# error "__cpp_lib_is_null_pointer should be defined in c++26" +# endif +# if __cpp_lib_is_null_pointer != 201309L +# error "__cpp_lib_is_null_pointer should have the value 201309L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_is_pointer_interconvertible +# error "__cpp_lib_is_pointer_interconvertible should be defined in c++26" +# endif +# if __cpp_lib_is_pointer_interconvertible != 201907L +# error "__cpp_lib_is_pointer_interconvertible should have the value 201907L in c++26" +# endif +# else +# ifdef __cpp_lib_is_pointer_interconvertible +# error "__cpp_lib_is_pointer_interconvertible should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_is_scoped_enum +# error "__cpp_lib_is_scoped_enum should be defined in c++26" +# endif +# if __cpp_lib_is_scoped_enum != 202011L +# error "__cpp_lib_is_scoped_enum should have the value 202011L in c++26" +# endif + +# ifndef __cpp_lib_is_sufficiently_aligned +# error "__cpp_lib_is_sufficiently_aligned should be defined in c++26" +# endif +# if __cpp_lib_is_sufficiently_aligned != 202411L +# error "__cpp_lib_is_sufficiently_aligned should have the value 202411L in c++26" +# endif + +# ifndef __cpp_lib_is_swappable +# error "__cpp_lib_is_swappable should be defined in c++26" +# endif +# if __cpp_lib_is_swappable != 201603L +# error "__cpp_lib_is_swappable should have the value 201603L in c++26" +# endif + +# if __has_builtin(__builtin_is_virtual_base_of) +# ifndef __cpp_lib_is_virtual_base_of +# error "__cpp_lib_is_virtual_base_of should be defined in c++26" +# endif +# if __cpp_lib_is_virtual_base_of != 202406L +# error "__cpp_lib_is_virtual_base_of should have the value 202406L in c++26" +# endif +# else +# ifdef __cpp_lib_is_virtual_base_of +# error "__cpp_lib_is_virtual_base_of should not be defined when the requirement '__has_builtin(__builtin_is_virtual_base_of)' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_is_within_lifetime +# error "__cpp_lib_is_within_lifetime should be defined in c++26" +# endif +# if __cpp_lib_is_within_lifetime != 202306L +# error "__cpp_lib_is_within_lifetime should have the value 202306L in c++26" +# endif +# else +# ifdef __cpp_lib_is_within_lifetime +# error "__cpp_lib_is_within_lifetime should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_jthread +# error "__cpp_lib_jthread should be defined in c++26" +# endif +# if __cpp_lib_jthread != 201911L +# error "__cpp_lib_jthread should have the value 201911L in c++26" +# endif +# else +# ifdef __cpp_lib_jthread +# error "__cpp_lib_jthread should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_latch +# error "__cpp_lib_latch should be defined in c++26" +# endif +# if __cpp_lib_latch != 201907L +# error "__cpp_lib_latch should have the value 201907L in c++26" +# endif +# else +# ifdef __cpp_lib_latch +# error "__cpp_lib_latch should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# ifndef __cpp_lib_launder +# error "__cpp_lib_launder should be defined in c++26" +# endif +# if __cpp_lib_launder != 201606L +# error "__cpp_lib_launder should have the value 201606L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_linalg +# error "__cpp_lib_linalg should be defined in c++26" +# endif +# if __cpp_lib_linalg != 202311L +# error "__cpp_lib_linalg should have the value 202311L in c++26" +# endif +# else +# ifdef __cpp_lib_linalg +# error "__cpp_lib_linalg should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_list_remove_return_type +# error "__cpp_lib_list_remove_return_type should be defined in c++26" +# endif +# if __cpp_lib_list_remove_return_type != 201806L +# error "__cpp_lib_list_remove_return_type should have the value 201806L in c++26" +# endif + +# ifndef __cpp_lib_logical_traits +# error "__cpp_lib_logical_traits should be defined in c++26" +# endif +# if __cpp_lib_logical_traits != 201510L +# error "__cpp_lib_logical_traits should have the value 201510L in c++26" +# endif + +# ifndef __cpp_lib_make_from_tuple +# error "__cpp_lib_make_from_tuple should be defined in c++26" +# endif +# if __cpp_lib_make_from_tuple != 201606L +# error "__cpp_lib_make_from_tuple should have the value 201606L in c++26" +# endif + +# ifndef __cpp_lib_make_reverse_iterator +# error "__cpp_lib_make_reverse_iterator should be defined in c++26" +# endif +# if __cpp_lib_make_reverse_iterator != 201402L +# error "__cpp_lib_make_reverse_iterator should have the value 201402L in c++26" +# endif + +# ifndef __cpp_lib_make_unique +# error "__cpp_lib_make_unique should be defined in c++26" +# endif +# if __cpp_lib_make_unique != 201304L +# error "__cpp_lib_make_unique should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_map_try_emplace +# error "__cpp_lib_map_try_emplace should be defined in c++26" +# endif +# if __cpp_lib_map_try_emplace != 201411L +# error "__cpp_lib_map_try_emplace should have the value 201411L in c++26" +# endif + +# ifndef __cpp_lib_math_constants +# error "__cpp_lib_math_constants should be defined in c++26" +# endif +# if __cpp_lib_math_constants != 201907L +# error "__cpp_lib_math_constants should have the value 201907L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should be defined in c++26" +# endif +# if __cpp_lib_math_special_functions != 201603L +# error "__cpp_lib_math_special_functions should have the value 201603L in c++26" +# endif +# else +# ifdef __cpp_lib_math_special_functions +# error "__cpp_lib_math_special_functions should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_mdspan +# error "__cpp_lib_mdspan should be defined in c++26" +# endif +# if __cpp_lib_mdspan != 202406L +# error "__cpp_lib_mdspan should have the value 202406L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR +# ifndef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should be defined in c++26" +# endif +# if __cpp_lib_memory_resource != 201603L +# error "__cpp_lib_memory_resource should have the value 201603L in c++26" +# endif +# else +# ifdef __cpp_lib_memory_resource +# error "__cpp_lib_memory_resource should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" +# endif +# endif + +# ifndef __cpp_lib_modules +# error "__cpp_lib_modules should be defined in c++26" +# endif +# if __cpp_lib_modules != 202207L +# error "__cpp_lib_modules should have the value 202207L in c++26" +# endif + +# ifndef __cpp_lib_move_iterator_concept +# error "__cpp_lib_move_iterator_concept should be defined in c++26" +# endif +# if __cpp_lib_move_iterator_concept != 202207L +# error "__cpp_lib_move_iterator_concept should have the value 202207L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_move_only_function +# error "__cpp_lib_move_only_function should be defined in c++26" +# endif +# if __cpp_lib_move_only_function != 202110L +# error "__cpp_lib_move_only_function should have the value 202110L in c++26" +# endif +# else +# ifdef __cpp_lib_move_only_function +# error "__cpp_lib_move_only_function should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_node_extract +# error "__cpp_lib_node_extract should be defined in c++26" +# endif +# if __cpp_lib_node_extract != 201606L +# error "__cpp_lib_node_extract should have the value 201606L in c++26" +# endif + +# ifndef __cpp_lib_nonmember_container_access +# error "__cpp_lib_nonmember_container_access should be defined in c++26" +# endif +# if __cpp_lib_nonmember_container_access != 201411L +# error "__cpp_lib_nonmember_container_access should have the value 201411L in c++26" +# endif + +# ifndef __cpp_lib_not_fn +# error "__cpp_lib_not_fn should be defined in c++26" +# endif +# if __cpp_lib_not_fn != 202306L +# error "__cpp_lib_not_fn should have the value 202306L in c++26" +# endif + +# ifndef __cpp_lib_null_iterators +# error "__cpp_lib_null_iterators should be defined in c++26" +# endif +# if __cpp_lib_null_iterators != 201304L +# error "__cpp_lib_null_iterators should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_optional +# error "__cpp_lib_optional should be defined in c++26" +# endif +# if __cpp_lib_optional != 202110L +# error "__cpp_lib_optional should have the value 202110L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_optional_range_support +# error "__cpp_lib_optional_range_support should be defined in c++26" +# endif +# if __cpp_lib_optional_range_support != 202406L +# error "__cpp_lib_optional_range_support should have the value 202406L in c++26" +# endif +# else +# ifdef __cpp_lib_optional_range_support +# error "__cpp_lib_optional_range_support should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_out_ptr +# error "__cpp_lib_out_ptr should be defined in c++26" +# endif +# if __cpp_lib_out_ptr != 202311L +# error "__cpp_lib_out_ptr should have the value 202311L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should be defined in c++26" +# endif +# if __cpp_lib_parallel_algorithm != 201603L +# error "__cpp_lib_parallel_algorithm should have the value 201603L in c++26" +# endif +# else +# ifdef __cpp_lib_parallel_algorithm +# error "__cpp_lib_parallel_algorithm should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_philox_engine +# error "__cpp_lib_philox_engine should be defined in c++26" +# endif +# if __cpp_lib_philox_engine != 202406L +# error "__cpp_lib_philox_engine should have the value 202406L in c++26" +# endif +# else +# ifdef __cpp_lib_philox_engine +# error "__cpp_lib_philox_engine should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR +# ifndef __cpp_lib_polymorphic_allocator +# error "__cpp_lib_polymorphic_allocator should be defined in c++26" +# endif +# if __cpp_lib_polymorphic_allocator != 201902L +# error "__cpp_lib_polymorphic_allocator should have the value 201902L in c++26" +# endif +# else +# ifdef __cpp_lib_polymorphic_allocator +# error "__cpp_lib_polymorphic_allocator should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_PMR' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT +# ifndef __cpp_lib_print +# error "__cpp_lib_print should be defined in c++26" +# endif +# if __cpp_lib_print != 202207L +# error "__cpp_lib_print should have the value 202207L in c++26" +# endif +# else +# ifdef __cpp_lib_print +# error "__cpp_lib_print should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_AVAILABILITY_HAS_TO_CHARS_FLOATING_POINT' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION +# ifndef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should be defined in c++26" +# endif +# if __cpp_lib_quoted_string_io != 201304L +# error "__cpp_lib_quoted_string_io should have the value 201304L in c++26" +# endif +# else +# ifdef __cpp_lib_quoted_string_io +# error "__cpp_lib_quoted_string_io should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_LOCALIZATION' is not met!" +# endif +# endif + +# ifndef __cpp_lib_ranges +# error "__cpp_lib_ranges should be defined in c++26" +# endif +# if __cpp_lib_ranges != 202406L +# error "__cpp_lib_ranges should have the value 202406L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_as_const +# error "__cpp_lib_ranges_as_const should be defined in c++26" +# endif +# if __cpp_lib_ranges_as_const != 202207L +# error "__cpp_lib_ranges_as_const should have the value 202207L in c++26" +# endif +# else +# ifdef __cpp_lib_ranges_as_const +# error "__cpp_lib_ranges_as_const should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_as_rvalue +# error "__cpp_lib_ranges_as_rvalue should be defined in c++26" +# endif +# if __cpp_lib_ranges_as_rvalue != 202207L +# error "__cpp_lib_ranges_as_rvalue should have the value 202207L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should be defined in c++26" +# endif +# if __cpp_lib_ranges_chunk != 202202L +# error "__cpp_lib_ranges_chunk should have the value 202202L in c++26" +# endif +# else +# ifdef __cpp_lib_ranges_chunk +# error "__cpp_lib_ranges_chunk should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_chunk_by +# error "__cpp_lib_ranges_chunk_by should be defined in c++26" +# endif +# if __cpp_lib_ranges_chunk_by != 202202L +# error "__cpp_lib_ranges_chunk_by should have the value 202202L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_concat +# error "__cpp_lib_ranges_concat should be defined in c++26" +# endif +# if __cpp_lib_ranges_concat != 202403L +# error "__cpp_lib_ranges_concat should have the value 202403L in c++26" +# endif +# else +# ifdef __cpp_lib_ranges_concat +# error "__cpp_lib_ranges_concat should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_contains +# error "__cpp_lib_ranges_contains should be defined in c++26" +# endif +# if __cpp_lib_ranges_contains != 202207L +# error "__cpp_lib_ranges_contains should have the value 202207L in c++26" +# endif + +# ifndef __cpp_lib_ranges_find_last +# error "__cpp_lib_ranges_find_last should be defined in c++26" +# endif +# if __cpp_lib_ranges_find_last != 202207L +# error "__cpp_lib_ranges_find_last should have the value 202207L in c++26" +# endif + +# ifndef __cpp_lib_ranges_iota +# error "__cpp_lib_ranges_iota should be defined in c++26" +# endif +# if __cpp_lib_ranges_iota != 202202L +# error "__cpp_lib_ranges_iota should have the value 202202L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_join_with +# error "__cpp_lib_ranges_join_with should be defined in c++26" +# endif +# if __cpp_lib_ranges_join_with != 202202L +# error "__cpp_lib_ranges_join_with should have the value 202202L in c++26" +# endif +# else +# ifdef __cpp_lib_ranges_join_with +# error "__cpp_lib_ranges_join_with should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_repeat +# error "__cpp_lib_ranges_repeat should be defined in c++26" +# endif +# if __cpp_lib_ranges_repeat != 202207L +# error "__cpp_lib_ranges_repeat should have the value 202207L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_slide +# error "__cpp_lib_ranges_slide should be defined in c++26" +# endif +# if __cpp_lib_ranges_slide != 202202L +# error "__cpp_lib_ranges_slide should have the value 202202L in c++26" +# endif +# else +# ifdef __cpp_lib_ranges_slide +# error "__cpp_lib_ranges_slide should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ranges_starts_ends_with +# error "__cpp_lib_ranges_starts_ends_with should be defined in c++26" +# endif +# if __cpp_lib_ranges_starts_ends_with != 202106L +# error "__cpp_lib_ranges_starts_ends_with should have the value 202106L in c++26" +# endif + +# ifndef __cpp_lib_ranges_stride +# error "__cpp_lib_ranges_stride should be defined in c++26" +# endif +# if __cpp_lib_ranges_stride != 202207L +# error "__cpp_lib_ranges_stride should have the value 202207L in c++26" +# endif + +# ifndef __cpp_lib_ranges_to_container +# error "__cpp_lib_ranges_to_container should be defined in c++26" +# endif +# if __cpp_lib_ranges_to_container != 202202L +# error "__cpp_lib_ranges_to_container should have the value 202202L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_ranges_zip +# error "__cpp_lib_ranges_zip should be defined in c++26" +# endif +# if __cpp_lib_ranges_zip != 202110L +# error "__cpp_lib_ranges_zip should have the value 202110L in c++26" +# endif +# else +# ifdef __cpp_lib_ranges_zip +# error "__cpp_lib_ranges_zip should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ratio +# error "__cpp_lib_ratio should be defined in c++26" +# endif +# if __cpp_lib_ratio != 202306L +# error "__cpp_lib_ratio should have the value 202306L in c++26" +# endif + +# ifndef __cpp_lib_raw_memory_algorithms +# error "__cpp_lib_raw_memory_algorithms should be defined in c++26" +# endif +# if __cpp_lib_raw_memory_algorithms != 201606L +# error "__cpp_lib_raw_memory_algorithms should have the value 201606L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_rcu +# error "__cpp_lib_rcu should be defined in c++26" +# endif +# if __cpp_lib_rcu != 202306L +# error "__cpp_lib_rcu should have the value 202306L in c++26" +# endif +# else +# ifdef __cpp_lib_rcu +# error "__cpp_lib_rcu should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_reference_from_temporary +# error "__cpp_lib_reference_from_temporary should be defined in c++26" +# endif +# if __cpp_lib_reference_from_temporary != 202202L +# error "__cpp_lib_reference_from_temporary should have the value 202202L in c++26" +# endif +# else +# ifdef __cpp_lib_reference_from_temporary +# error "__cpp_lib_reference_from_temporary should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_reference_wrapper +# error "__cpp_lib_reference_wrapper should be defined in c++26" +# endif +# if __cpp_lib_reference_wrapper != 202403L +# error "__cpp_lib_reference_wrapper should have the value 202403L in c++26" +# endif + +# ifndef __cpp_lib_remove_cvref +# error "__cpp_lib_remove_cvref should be defined in c++26" +# endif +# if __cpp_lib_remove_cvref != 201711L +# error "__cpp_lib_remove_cvref should have the value 201711L in c++26" +# endif + +# ifndef __cpp_lib_result_of_sfinae +# error "__cpp_lib_result_of_sfinae should be defined in c++26" +# endif +# if __cpp_lib_result_of_sfinae != 201210L +# error "__cpp_lib_result_of_sfinae should have the value 201210L in c++26" +# endif + +# ifndef __cpp_lib_robust_nonmodifying_seq_ops +# error "__cpp_lib_robust_nonmodifying_seq_ops should be defined in c++26" +# endif +# if __cpp_lib_robust_nonmodifying_seq_ops != 201304L +# error "__cpp_lib_robust_nonmodifying_seq_ops should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_sample +# error "__cpp_lib_sample should be defined in c++26" +# endif +# if __cpp_lib_sample != 201603L +# error "__cpp_lib_sample should have the value 201603L in c++26" +# endif + +# ifndef __cpp_lib_saturation_arithmetic +# error "__cpp_lib_saturation_arithmetic should be defined in c++26" +# endif +# if __cpp_lib_saturation_arithmetic != 202311L +# error "__cpp_lib_saturation_arithmetic should have the value 202311L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should be defined in c++26" +# endif +# if __cpp_lib_scoped_lock != 201703L +# error "__cpp_lib_scoped_lock should have the value 201703L in c++26" +# endif +# else +# ifdef __cpp_lib_scoped_lock +# error "__cpp_lib_scoped_lock should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC) +# ifndef __cpp_lib_semaphore +# error "__cpp_lib_semaphore should be defined in c++26" +# endif +# if __cpp_lib_semaphore != 201907L +# error "__cpp_lib_semaphore should have the value 201907L in c++26" +# endif +# else +# ifdef __cpp_lib_semaphore +# error "__cpp_lib_semaphore should not be defined when the requirement '!defined(_LIBCPP_VERSION) || (_LIBCPP_HAS_THREADS && _LIBCPP_AVAILABILITY_HAS_SYNC)' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_senders +# error "__cpp_lib_senders should be defined in c++26" +# endif +# if __cpp_lib_senders != 202406L +# error "__cpp_lib_senders should have the value 202406L in c++26" +# endif +# else +# ifdef __cpp_lib_senders +# error "__cpp_lib_senders should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should be defined in c++26" +# endif +# if __cpp_lib_shared_mutex != 201505L +# error "__cpp_lib_shared_mutex should have the value 201505L in c++26" +# endif +# else +# ifdef __cpp_lib_shared_mutex +# error "__cpp_lib_shared_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifndef __cpp_lib_shared_ptr_arrays +# error "__cpp_lib_shared_ptr_arrays should be defined in c++26" +# endif +# if __cpp_lib_shared_ptr_arrays != 201707L +# error "__cpp_lib_shared_ptr_arrays should have the value 201707L in c++26" +# endif + +# ifndef __cpp_lib_shared_ptr_weak_type +# error "__cpp_lib_shared_ptr_weak_type should be defined in c++26" +# endif +# if __cpp_lib_shared_ptr_weak_type != 201606L +# error "__cpp_lib_shared_ptr_weak_type should have the value 201606L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS +# ifndef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should be defined in c++26" +# endif +# if __cpp_lib_shared_timed_mutex != 201402L +# error "__cpp_lib_shared_timed_mutex should have the value 201402L in c++26" +# endif +# else +# ifdef __cpp_lib_shared_timed_mutex +# error "__cpp_lib_shared_timed_mutex should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_THREADS' is not met!" +# endif +# endif + +# ifndef __cpp_lib_shift +# error "__cpp_lib_shift should be defined in c++26" +# endif +# if __cpp_lib_shift != 201806L +# error "__cpp_lib_shift should have the value 201806L in c++26" +# endif + +# ifndef __cpp_lib_smart_ptr_for_overwrite +# error "__cpp_lib_smart_ptr_for_overwrite should be defined in c++26" +# endif +# if __cpp_lib_smart_ptr_for_overwrite != 202002L +# error "__cpp_lib_smart_ptr_for_overwrite should have the value 202002L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_smart_ptr_owner_equality +# error "__cpp_lib_smart_ptr_owner_equality should be defined in c++26" +# endif +# if __cpp_lib_smart_ptr_owner_equality != 202306L +# error "__cpp_lib_smart_ptr_owner_equality should have the value 202306L in c++26" +# endif +# else +# ifdef __cpp_lib_smart_ptr_owner_equality +# error "__cpp_lib_smart_ptr_owner_equality should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_source_location +# error "__cpp_lib_source_location should be defined in c++26" +# endif +# if __cpp_lib_source_location != 201907L +# error "__cpp_lib_source_location should have the value 201907L in c++26" +# endif + +# ifndef __cpp_lib_span +# error "__cpp_lib_span should be defined in c++26" +# endif +# if __cpp_lib_span != 202002L +# error "__cpp_lib_span should have the value 202002L in c++26" +# endif + +# ifndef __cpp_lib_span_at +# error "__cpp_lib_span_at should be defined in c++26" +# endif +# if __cpp_lib_span_at != 202311L +# error "__cpp_lib_span_at should have the value 202311L in c++26" +# endif + +# ifndef __cpp_lib_span_initializer_list +# error "__cpp_lib_span_initializer_list should be defined in c++26" +# endif +# if __cpp_lib_span_initializer_list != 202311L +# error "__cpp_lib_span_initializer_list should have the value 202311L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_spanstream +# error "__cpp_lib_spanstream should be defined in c++26" +# endif +# if __cpp_lib_spanstream != 202106L +# error "__cpp_lib_spanstream should have the value 202106L in c++26" +# endif +# else +# ifdef __cpp_lib_spanstream +# error "__cpp_lib_spanstream should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_ssize +# error "__cpp_lib_ssize should be defined in c++26" +# endif +# if __cpp_lib_ssize != 201902L +# error "__cpp_lib_ssize should have the value 201902L in c++26" +# endif + +# ifndef __cpp_lib_sstream_from_string_view +# error "__cpp_lib_sstream_from_string_view should be defined in c++26" +# endif +# if __cpp_lib_sstream_from_string_view != 202306L +# error "__cpp_lib_sstream_from_string_view should have the value 202306L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_stacktrace +# error "__cpp_lib_stacktrace should be defined in c++26" +# endif +# if __cpp_lib_stacktrace != 202011L +# error "__cpp_lib_stacktrace should have the value 202011L in c++26" +# endif +# else +# ifdef __cpp_lib_stacktrace +# error "__cpp_lib_stacktrace should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_starts_ends_with +# error "__cpp_lib_starts_ends_with should be defined in c++26" +# endif +# if __cpp_lib_starts_ends_with != 201711L +# error "__cpp_lib_starts_ends_with should have the value 201711L in c++26" +# endif + +# ifndef __cpp_lib_stdatomic_h +# error "__cpp_lib_stdatomic_h should be defined in c++26" +# endif +# if __cpp_lib_stdatomic_h != 202011L +# error "__cpp_lib_stdatomic_h should have the value 202011L in c++26" +# endif + +# ifndef __cpp_lib_string_contains +# error "__cpp_lib_string_contains should be defined in c++26" +# endif +# if __cpp_lib_string_contains != 202011L +# error "__cpp_lib_string_contains should have the value 202011L in c++26" +# endif + +# ifndef __cpp_lib_string_resize_and_overwrite +# error "__cpp_lib_string_resize_and_overwrite should be defined in c++26" +# endif +# if __cpp_lib_string_resize_and_overwrite != 202110L +# error "__cpp_lib_string_resize_and_overwrite should have the value 202110L in c++26" +# endif + +# ifndef __cpp_lib_string_udls +# error "__cpp_lib_string_udls should be defined in c++26" +# endif +# if __cpp_lib_string_udls != 201304L +# error "__cpp_lib_string_udls should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_string_view +# error "__cpp_lib_string_view should be defined in c++26" +# endif +# if __cpp_lib_string_view != 202403L +# error "__cpp_lib_string_view should have the value 202403L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_submdspan +# error "__cpp_lib_submdspan should be defined in c++26" +# endif +# if __cpp_lib_submdspan != 202306L +# error "__cpp_lib_submdspan should have the value 202306L in c++26" +# endif +# else +# ifdef __cpp_lib_submdspan +# error "__cpp_lib_submdspan should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM +# ifndef __cpp_lib_syncbuf +# error "__cpp_lib_syncbuf should be defined in c++26" +# endif +# if __cpp_lib_syncbuf != 201803L +# error "__cpp_lib_syncbuf should have the value 201803L in c++26" +# endif +# else +# ifdef __cpp_lib_syncbuf +# error "__cpp_lib_syncbuf should not be defined when the requirement '!defined(_LIBCPP_VERSION) || _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM' is not met!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_text_encoding +# error "__cpp_lib_text_encoding should be defined in c++26" +# endif +# if __cpp_lib_text_encoding != 202306L +# error "__cpp_lib_text_encoding should have the value 202306L in c++26" +# endif +# else +# ifdef __cpp_lib_text_encoding +# error "__cpp_lib_text_encoding should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_three_way_comparison +# error "__cpp_lib_three_way_comparison should be defined in c++26" +# endif +# if __cpp_lib_three_way_comparison != 201907L +# error "__cpp_lib_three_way_comparison should have the value 201907L in c++26" +# endif + +# ifndef __cpp_lib_to_address +# error "__cpp_lib_to_address should be defined in c++26" +# endif +# if __cpp_lib_to_address != 201711L +# error "__cpp_lib_to_address should have the value 201711L in c++26" +# endif + +# ifndef __cpp_lib_to_array +# error "__cpp_lib_to_array should be defined in c++26" +# endif +# if __cpp_lib_to_array != 201907L +# error "__cpp_lib_to_array should have the value 201907L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should be defined in c++26" +# endif +# if __cpp_lib_to_chars != 202306L +# error "__cpp_lib_to_chars should have the value 202306L in c++26" +# endif +# else +# ifdef __cpp_lib_to_chars +# error "__cpp_lib_to_chars should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_to_string +# error "__cpp_lib_to_string should be defined in c++26" +# endif +# if __cpp_lib_to_string != 202306L +# error "__cpp_lib_to_string should have the value 202306L in c++26" +# endif +# else +# ifdef __cpp_lib_to_string +# error "__cpp_lib_to_string should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_to_underlying +# error "__cpp_lib_to_underlying should be defined in c++26" +# endif +# if __cpp_lib_to_underlying != 202102L +# error "__cpp_lib_to_underlying should have the value 202102L in c++26" +# endif + +# ifndef __cpp_lib_transformation_trait_aliases +# error "__cpp_lib_transformation_trait_aliases should be defined in c++26" +# endif +# if __cpp_lib_transformation_trait_aliases != 201304L +# error "__cpp_lib_transformation_trait_aliases should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_transparent_operators +# error "__cpp_lib_transparent_operators should be defined in c++26" +# endif +# if __cpp_lib_transparent_operators != 201510L +# error "__cpp_lib_transparent_operators should have the value 201510L in c++26" +# endif + +# ifndef __cpp_lib_tuple_element_t +# error "__cpp_lib_tuple_element_t should be defined in c++26" +# endif +# if __cpp_lib_tuple_element_t != 201402L +# error "__cpp_lib_tuple_element_t should have the value 201402L in c++26" +# endif + +# if !defined(_LIBCPP_VERSION) +# ifndef __cpp_lib_tuple_like +# error "__cpp_lib_tuple_like should be defined in c++26" +# endif +# if __cpp_lib_tuple_like != 202311L +# error "__cpp_lib_tuple_like should have the value 202311L in c++26" +# endif +# else +# ifdef __cpp_lib_tuple_like +# error "__cpp_lib_tuple_like should not be defined because it is unimplemented in libc++!" +# endif +# endif + +# ifndef __cpp_lib_tuples_by_type +# error "__cpp_lib_tuples_by_type should be defined in c++26" +# endif +# if __cpp_lib_tuples_by_type != 201304L +# error "__cpp_lib_tuples_by_type should have the value 201304L in c++26" +# endif + +# ifndef __cpp_lib_type_identity +# error "__cpp_lib_type_identity should be defined in c++26" +# endif +# if __cpp_lib_type_identity != 201806L +# error "__cpp_lib_type_identity should have the value 201806L in c++26" +# endif + +# ifndef __cpp_lib_type_trait_variable_templates +# error "__cpp_lib_type_trait_variable_templates should be defined in c++26" +# endif +# if __cpp_lib_type_trait_variable_templates != 201510L +# error "__cpp_lib_type_trait_variable_templates should have the value 201510L in c++26" +# endif + +# ifndef __cpp_lib_uncaught_exceptions +# error "__cpp_lib_uncaught_exceptions should be defined in c++26" +# endif +# if __cpp_lib_uncaught_exceptions != 201411L +# error "__cpp_lib_uncaught_exceptions should have the value 201411L in c++26" +# endif + +# ifndef __cpp_lib_unordered_map_try_emplace +# error "__cpp_lib_unordered_map_try_emplace should be defined in c++26" +# endif +# if __cpp_lib_unordered_map_try_emplace != 201411L +# error "__cpp_lib_unordered_map_try_emplace should have the value 201411L in c++26" +# endif + +# ifndef __cpp_lib_unreachable +# error "__cpp_lib_unreachable should be defined in c++26" +# endif +# if __cpp_lib_unreachable != 202202L +# error "__cpp_lib_unreachable should have the value 202202L in c++26" +# endif + +# ifndef __cpp_lib_unwrap_ref +# error "__cpp_lib_unwrap_ref should be defined in c++26" +# endif +# if __cpp_lib_unwrap_ref != 201811L +# error "__cpp_lib_unwrap_ref should have the value 201811L in c++26" +# endif + +# ifndef __cpp_lib_variant +# error "__cpp_lib_variant should be defined in c++26" +# endif +# if __cpp_lib_variant != 202306L +# error "__cpp_lib_variant should have the value 202306L in c++26" +# endif + +# ifndef __cpp_lib_void_t +# error "__cpp_lib_void_t should be defined in c++26" +# endif +# if __cpp_lib_void_t != 201411L +# error "__cpp_lib_void_t should have the value 201411L in c++26" +# endif #endif // TEST_STD_VER > 23 From b8ac01dab77530942030a4e4ee300c8ab6dd157d Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 30 May 2025 08:41:17 -0400 Subject: [PATCH 161/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Update includes. Signed-off-by: Will Hawkins --- .../range.stride.view/borrowing.compile.pass.cpp | 2 -- .../range.adaptors/range.stride.view/concept.verify.cpp | 2 -- .../range.stride.view/iterator/ctor.copy.pass.cpp | 2 -- .../range.stride.view/iterator/ctor.default.verify.cpp | 1 - .../range.stride.view/iterator/greater_than.pass.cpp | 9 --------- .../range.stride.view/iterator/iter_move.pass.cpp | 1 - .../range.stride.view/iterator/less_than.pass.cpp | 9 --------- .../range.adaptors/range.stride.view/size.verify.cpp | 1 - .../range.adaptors/range.stride.view/stride.pass.cpp | 2 -- 9 files changed, 29 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/borrowing.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/borrowing.compile.pass.cpp index add0018d455aa..cfadffbda28de 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/borrowing.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/borrowing.compile.pass.cpp @@ -12,10 +12,8 @@ // inline constexpr bool enable_borrowed_range> = ranges::enable_borrowed_range; #include -#include #include "test_range.h" -#include "types.h" static_assert(std::ranges::enable_borrowed_range< std::ranges::stride_view>); static_assert(!std::ranges::enable_borrowed_range< std::ranges::stride_view>); diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp index 8f43b63e9de87..d580d240f7a3b 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/concept.verify.cpp @@ -11,11 +11,9 @@ // template requires view<_View> -#include "__ranges/stride_view.h" #include "almost_satisfies_types.h" #include "test_iterators.h" #include "test_range.h" -#include "types.h" template D> concept CanStrideView = requires { std::ranges::stride_view{I{}, D}; }; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp index 1fbc46eccc9fc..eb0998cb0c8bb 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.copy.pass.cpp @@ -12,11 +12,9 @@ // requires _Const && convertible_to, iterator_t<_Base>> && // convertible_to, sentinel_t<_Base>> -#include #include #include "../types.h" -#include "test_iterators.h" #include "test_macros.h" struct NotSimpleViewIterEnd; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp index 4cb75667cf5de..eb90fa2e674e2 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/ctor.default.verify.cpp @@ -14,7 +14,6 @@ #include #include "../types.h" -#include "test_iterators.h" struct NonDefaultConstructibleIterator : InputIter { NonDefaultConstructibleIterator() = delete; diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/greater_than.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/greater_than.pass.cpp index 801447a9fad60..08845f59d58ed 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/greater_than.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/greater_than.pass.cpp @@ -31,15 +31,6 @@ #include #include "../types.h" -#include "__compare/three_way_comparable.h" -#include "__concepts/equality_comparable.h" -#include "__concepts/same_as.h" -#include "__iterator/concepts.h" -#include "__iterator/default_sentinel.h" -#include "__iterator/distance.h" -#include "__ranges/access.h" -#include "__ranges/concepts.h" -#include "__ranges/stride_view.h" #include "test_iterators.h" template diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp index 25ccf30abe0c5..5275115437bcc 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/iter_move.pass.cpp @@ -15,7 +15,6 @@ #include #include "../types.h" -#include "__ranges/access.h" #include "test_macros.h" template diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/less_than.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/less_than.pass.cpp index 8d4c2643a5ce9..13eecf9283dee 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/less_than.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/iterator/less_than.pass.cpp @@ -31,15 +31,6 @@ #include #include "../types.h" -#include "__compare/three_way_comparable.h" -#include "__concepts/equality_comparable.h" -#include "__concepts/same_as.h" -#include "__iterator/concepts.h" -#include "__iterator/default_sentinel.h" -#include "__iterator/distance.h" -#include "__ranges/access.h" -#include "__ranges/concepts.h" -#include "__ranges/stride_view.h" #include "test_iterators.h" template diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp index 0accfc43258c4..64dec9460323f 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/size.verify.cpp @@ -13,7 +13,6 @@ #include -#include "__ranges/stride_view.h" #include "test_iterators.h" #include "types.h" diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp index 856e08c4649f7..b9879c1c473f8 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/stride.pass.cpp @@ -11,8 +11,6 @@ // constexpr range_difference_t<_View> stride() const noexcept; #include -#include -#include #include "test_iterators.h" #include "types.h" From d09aea4fcc856ef5a03ebb47ab1d9742c6aadded Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 30 May 2025 09:24:45 -0400 Subject: [PATCH 162/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Mark internal typedef-like name as _LIBCPP_NODEBUG. Signed-off-by: Will Hawkins --- libcxx/include/__ranges/stride_view.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index 6e179b11ccbb4..a9e9d186743cb 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -143,7 +143,7 @@ struct __stride_iterator_category {}; template struct __stride_iterator_category<_View> { - using _Cat = typename iterator_traits>::iterator_category; + using _Cat _LIBCPP_NODEBUG = typename iterator_traits>::iterator_category; using iterator_category = _If, /* then */ random_access_iterator_tag, @@ -154,8 +154,8 @@ template requires view<_View> template class stride_view<_View>::__iterator : public __stride_iterator_category<_View> { - using _Parent = __maybe_const<_Const, stride_view<_View>>; - using _Base = __maybe_const<_Const, _View>; + using _Parent _LIBCPP_NODEBUG = __maybe_const<_Const, stride_view<_View>>; + using _Base _LIBCPP_NODEBUG = __maybe_const<_Const, _View>; _LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_Base> __current_ = iterator_t<_Base>(); _LIBCPP_NO_UNIQUE_ADDRESS ranges::sentinel_t<_Base> __end_ = ranges::sentinel_t<_Base>(); From f51546b72dbcf5109ef9a76eff1d7588ca4e4a49 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 30 May 2025 10:05:47 -0400 Subject: [PATCH 163/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Make clang-format happy. Signed-off-by: Will Hawkins --- .../ranges/range.adaptors/range.stride.view/adaptor.pass.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp index 71e27f7ffc7e8..37c4a20e6a196 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/adaptor.pass.cpp @@ -134,7 +134,9 @@ constexpr bool test() { } // A final sanity check. - { static_assert(std::same_as); } + { + static_assert(std::same_as); + } return true; } From 3f32a80b8766070f7bd48b8fb6822568e7f0ee4d Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 30 May 2025 16:30:38 -0400 Subject: [PATCH 164/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Base nodiscard test cleanup. Signed-off-by: Will Hawkins --- .../range.adaptors/range.stride.view/nodiscard.verify.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp index 4d6647f019792..eb3aa9a6ebfcb 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp @@ -22,8 +22,8 @@ #include "../../../../std/ranges/range.adaptors/range.stride.view/types.h" void test_base_nodiscard() { - const std::vector intv = {1, 2, 3}; - auto sv = std::ranges::stride_view(intv, 3); + const int range[] = {1, 2, 3}; + auto sv = std::ranges::stride_view(range, 3); sv.base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} std::move(sv).base(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} From 1eace39c37bb78769edc2db1893484f4e5d135e8 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 30 May 2025 17:54:57 -0400 Subject: [PATCH 165/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. base test cleanups. Signed-off-by: Will Hawkins --- .../range.stride.view/base.pass.cpp | 65 ++++++++++++++++--- 1 file changed, 57 insertions(+), 8 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp index c335c038eea4c..e8a7aab215bd1 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp @@ -19,32 +19,81 @@ template constexpr bool hasLValueQualifiedBase(T&& t) { + // Thanks to forwarding references, t's type is + // preserved from the caller. No matter the type of + // the argument, when it is used here, t is an l value + // (after all, it has a name). Therefore, this code + // will test whether the l value const-ref-qualified + // version of base is callable. return requires { t.base(); }; } +using CopyableInputView = CopyableView>; +using MoveOnlyInputView = MoveOnlyView>; + constexpr bool test() { int buff[] = {1, 2, 3, 4, 5, 6, 7, 8}; constexpr int N = 8; + + // l-value ref qualified + // const & + { + const auto str(std::ranges::stride_view( + CopyableInputView(cpp17_input_iterator(buff), cpp17_input_iterator(buff + N)), 1)); + + static_assert(hasLValueQualifiedBase(str)); + + std::same_as decltype(auto) s = str.base(); + assert(*s.begin() == *buff); + } + + // & + { + auto str(std::ranges::stride_view( + CopyableInputView(cpp17_input_iterator(buff), cpp17_input_iterator(buff + N)), 1)); + + std::same_as decltype(auto) s = str.base(); + assert(*s.begin() == *buff); + + static_assert(hasLValueQualifiedBase(str)); + } + + // r-value ref qualified + // && { - using CopyableInputView = CopyableView>; auto str(std::ranges::stride_view( CopyableInputView(cpp17_input_iterator(buff), cpp17_input_iterator(buff + N)), 1)); - assert(*str.base().begin() == *buff); - assert(*(std::move(str)).base().begin() == *buff); - ASSERT_SAME_TYPE(decltype(str.base()), CopyableInputView); - ASSERT_SAME_TYPE(decltype(std::move(str).base()), CopyableInputView); static_assert(hasLValueQualifiedBase(str)); + + std::same_as decltype(auto) s = std::move(str).base(); + assert(*s.begin() == *buff); + } + // const && + { + const auto str_a(std::ranges::stride_view( + CopyableInputView(cpp17_input_iterator(buff), cpp17_input_iterator(buff + N)), 1)); + + static_assert(hasLValueQualifiedBase(str_a)); + + std::same_as decltype(auto) s = std::move(str_a).base(); + assert(*s.begin() == *buff); + } + + // && { - using MoveOnlyInputView = MoveOnlyView>; auto str(std::ranges::stride_view( MoveOnlyInputView(cpp17_input_iterator(buff), cpp17_input_iterator(buff + N)), 1)); - assert(*(std::move(str)).base().begin() == *buff); - ASSERT_SAME_TYPE(decltype(std::move(str).base()), MoveOnlyInputView); + // Because the base of the stride view is move only, + // the const & version is not applicable and, therefore, + // there is no l-value qualified base method. static_assert(!hasLValueQualifiedBase(str)); + + std::same_as decltype(auto) s = std::move(str).base(); + assert(*s.begin() == *buff); } return true; } From 16479bbd121bb8f4ccaff752c99b177129c2de9c Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 30 May 2025 20:42:07 -0400 Subject: [PATCH 166/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Make clang-format happy. Signed-off-by: Will Hawkins --- .../std/ranges/range.adaptors/range.stride.view/base.pass.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp index e8a7aab215bd1..17b5afb070b8b 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/base.pass.cpp @@ -68,7 +68,6 @@ constexpr bool test() { std::same_as decltype(auto) s = std::move(str).base(); assert(*s.begin() == *buff); - } // const && From f7c366f54cd6bd2dccd893d5bafaf1e170954cae Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 30 May 2025 22:50:53 -0400 Subject: [PATCH 167/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Update begin tests. Signed-off-by: Will Hawkins --- .../range.stride.view/begin.pass.cpp | 36 +++++++++++++++---- .../range.adaptors/range.stride.view/types.h | 2 +- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp index b2c73db27905c..0fb8d2c1939fd 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp @@ -14,6 +14,7 @@ // Note: Checks here are augmented by checks in // iterator/ctor.copy.pass.cpp. +#include #include #include "types.h" @@ -24,25 +25,46 @@ concept HasConstBegin = requires(const T& ct) { ct.begin(); }; template concept HasBegin = requires(T& t) { t.begin(); }; +// _View has const-qualified begin and end methods and +// is _not_ a simple view. template -concept HasConstAndNonConstBegin = HasConstBegin && requires(T& t, const T& ct) { +concept HasConstAndNonConstBegin = requires(T& t, const T& ct) { + // The return types for begin are different when this is const or not: + // the iterator's _Const non-type-template parameter is true in the former + // and false in the latter. requires !std::same_as; }; +// _View does not have const-qualified begin and end methods and +// is _not_ a simple view. template +// There is a begin but it's not const qualified => Only non-const qualified begin. concept HasOnlyNonConstBegin = HasBegin && !HasConstBegin; +// _View does have const-qualified begin and end methods and +// is a simple view. template +// There is a const-qualified begin and there are not both const- and non-const qualified begin => Only const-qualified begin. concept HasOnlyConstBegin = HasConstBegin && !HasConstAndNonConstBegin; static_assert(HasOnlyNonConstBegin>); static_assert(HasOnlyConstBegin>>); -static_assert(HasConstAndNonConstBegin>); +static_assert(HasConstAndNonConstBegin>); -int main(int, char**) { - int buffer[] = {1, 2, 3}; - auto sv = std::ranges::stride_view(BasicTestView(buffer, buffer + 3), 1); - assert(1 == *(sv.begin())); +constexpr bool test() { + const auto const_basic = UnSimpleConstView(); + const auto sv_const_basic = std::ranges::stride_view(const_basic, 1); + static_assert(std::same_as); - return 0; + auto non_const_basic = SimpleCommonConstView(); + auto sv_non_const_basic = std::ranges::stride_view(non_const_basic, 1); + static_assert(std::same_as); + + return true; } + +int main(int, char**) { + test(); + static_assert(test()); + return 0; +} \ No newline at end of file diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index a49986af827d0..82d4e0c59b5a1 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -266,7 +266,7 @@ struct MaybeConstCommonSimpleView : std::ranges::view_base { }; using UnSimpleNoConstCommonView = MaybeConstCommonSimpleView; -using UnsimpleConstView = MaybeConstCommonSimpleView; +using UnSimpleConstView = MaybeConstCommonSimpleView; using UnsimpleUnCommonConstView = MaybeConstCommonSimpleView; using SimpleUnCommonConstView = MaybeConstCommonSimpleView; using SimpleCommonConstView = MaybeConstCommonSimpleView; From 0600fda65c7e6f46ea525f815faa3349a20b97f6 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Sat, 31 May 2025 02:43:18 -0400 Subject: [PATCH 168/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Finish renaming UnsimpleConstView to UnSimpleConstView. Signed-off-by: Will Hawkins --- .../range.adaptors/range.stride.view/nodiscard.verify.cpp | 4 ++-- .../ranges/range.adaptors/range.stride.view/end.pass.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp index eb3aa9a6ebfcb..280d9b822f4a7 100644 --- a/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp +++ b/libcxx/test/libcxx/ranges/range.adaptors/range.stride.view/nodiscard.verify.cpp @@ -31,7 +31,7 @@ void test_base_nodiscard() { void test_begin_nodiscard() { const auto const_sv = std::views::stride(SimpleCommonConstView{}, 2); - auto unsimple_sv = std::views::stride(UnsimpleConstView{}, 2); + auto unsimple_sv = std::views::stride(UnSimpleConstView{}, 2); const_sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} unsimple_sv.begin(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} @@ -49,7 +49,7 @@ void test_end_nodiscard() { const int range[] = {1, 2, 3}; const auto const_sv = std::views::stride(range, 2); - auto unsimple_sv = std::views::stride(UnsimpleConstView{}, 2); + auto unsimple_sv = std::views::stride(UnSimpleConstView{}, 2); const_sv.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} unsimple_sv.end(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp index 06405a9fc5994..0374b479b1025 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp @@ -36,7 +36,7 @@ concept HasOnlyConstEnd = HasConstEnd && !HasConstAndNonConstEnd; static_assert(HasOnlyNonConstEnd>); static_assert(HasOnlyConstEnd>>); -static_assert(HasConstAndNonConstEnd>); +static_assert(HasConstAndNonConstEnd>); static_assert(simple_view); static_assert(!std::ranges::common_range); @@ -70,8 +70,8 @@ constexpr bool test_default_sentinel() { { static_assert(!simple_view); static_assert(!std::ranges::common_range); - static_assert(std::ranges::sized_range); - static_assert(std::ranges::forward_range); + static_assert(std::ranges::sized_range); + static_assert(std::ranges::forward_range); auto v = UnsimpleUnCommonConstView{}; auto sv = std::ranges::stride_view(v, 1); From cdb52b468037ddb67adcdf183c3ebe0bd754da28 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 2 Jun 2025 07:58:37 -0400 Subject: [PATCH 169/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Final cleanup of begin tests. Signed-off-by: Will Hawkins --- .../range.stride.view/begin.pass.cpp | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp index 0fb8d2c1939fd..71d2325c84805 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp @@ -25,8 +25,6 @@ concept HasConstBegin = requires(const T& ct) { ct.begin(); }; template concept HasBegin = requires(T& t) { t.begin(); }; -// _View has const-qualified begin and end methods and -// is _not_ a simple view. template concept HasConstAndNonConstBegin = requires(T& t, const T& ct) { // The return types for begin are different when this is const or not: @@ -35,30 +33,26 @@ concept HasConstAndNonConstBegin = requires(T& t, const T& ct) { requires !std::same_as; }; -// _View does not have const-qualified begin and end methods and -// is _not_ a simple view. template // There is a begin but it's not const qualified => Only non-const qualified begin. concept HasOnlyNonConstBegin = HasBegin && !HasConstBegin; -// _View does have const-qualified begin and end methods and -// is a simple view. template // There is a const-qualified begin and there are not both const- and non-const qualified begin => Only const-qualified begin. concept HasOnlyConstBegin = HasConstBegin && !HasConstAndNonConstBegin; static_assert(HasOnlyNonConstBegin>); -static_assert(HasOnlyConstBegin>>); +static_assert(HasOnlyConstBegin>); static_assert(HasConstAndNonConstBegin>); constexpr bool test() { - const auto const_basic = UnSimpleConstView(); - const auto sv_const_basic = std::ranges::stride_view(const_basic, 1); - static_assert(std::same_as); + const auto unsimple_const_view = UnSimpleConstView(); + const auto sv_unsimple_const = std::ranges::stride_view(unsimple_const_view, 1); + static_assert(std::same_as); - auto non_const_basic = SimpleCommonConstView(); - auto sv_non_const_basic = std::ranges::stride_view(non_const_basic, 1); - static_assert(std::same_as); + auto simple_const_view = SimpleCommonConstView(); + auto sv_simple_const = std::ranges::stride_view(simple_const_view, 1); + static_assert(std::same_as); return true; } From d63d9d11b5ace097b037ec507b20062e9efa050c Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 2 Jun 2025 09:15:05 -0400 Subject: [PATCH 170/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Begin cleanup of end tests. Signed-off-by: Will Hawkins --- .../range.stride.view/end.pass.cpp | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp index 0374b479b1025..55db970ca6d13 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp @@ -16,6 +16,7 @@ #include +#include "test_iterators.h" #include "types.h" template @@ -35,21 +36,34 @@ template concept HasOnlyConstEnd = HasConstEnd && !HasConstAndNonConstEnd; static_assert(HasOnlyNonConstEnd>); -static_assert(HasOnlyConstEnd>>); +static_assert(HasOnlyConstEnd>); static_assert(HasConstAndNonConstEnd>); -static_assert(simple_view); -static_assert(!std::ranges::common_range); - constexpr bool test_non_default_sentinel() { { + const int data[3] = {1, 2, 3}; static_assert(simple_view>); static_assert(std::ranges::common_range>); static_assert(std::ranges::sized_range>); static_assert(std::ranges::forward_range>); - auto v = BasicTestView{nullptr, nullptr}; - auto sv = std::ranges::stride_view>(v, 1); + // A const, simple, common-, sized- and forward-range + auto v = BasicTestView{data, data + 3}; + auto sv = std::ranges::stride_view>(v, 1); + static_assert(!std::is_same_v); + } + + { + int data[3] = {1, 2, 3}; + // TODO: start here. + using x = BasicTestView, forward_iterator, false>; + static_assert(simple_view>>); + static_assert(std::ranges::common_range); + static_assert(!std::ranges::sized_range); + static_assert(!std::ranges::bidirectional_range); + + auto v = x{forward_iterator(data), forward_iterator(data + 3)}; + auto sv = std::ranges::stride_view(v, 1); static_assert(!std::is_same_v); } @@ -59,6 +73,7 @@ constexpr bool test_non_default_sentinel() { static_assert(std::ranges::sized_range); static_assert(std::ranges::forward_range); + // An unconst, unsimple, common-, sized- and forward-range auto v = UnSimpleNoConstCommonView{}; auto sv = std::ranges::stride_view(v, 1); static_assert(!std::is_same_v); From acff18b9ffea47b0bc985411430fda995e11d121 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Mon, 2 Jun 2025 09:15:46 -0400 Subject: [PATCH 171/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Cleanup unneeded includes in types.h. Signed-off-by: Will Hawkins --- .../test/std/ranges/range.adaptors/range.stride.view/types.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h index 82d4e0c59b5a1..5879c5022006e 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/types.h @@ -13,11 +13,7 @@ #include #include #include -#include -#include "__concepts/constructible.h" -#include "__iterator/concepts.h" -#include "__ranges/common_view.h" #include "test_iterators.h" #include "test_range.h" From 0cfc9e23053549715bdb6c1934bd4e2cc668b2c4 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 13 Jun 2025 08:49:46 -0400 Subject: [PATCH 172/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Cleanup another stride_view::end test. Signed-off-by: Will Hawkins --- .../range.stride.view/end.pass.cpp | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp index 55db970ca6d13..a33349d554761 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/end.pass.cpp @@ -42,12 +42,9 @@ static_assert(HasConstAndNonConstEnd constexpr bool test_non_default_sentinel() { { const int data[3] = {1, 2, 3}; - static_assert(simple_view>); - static_assert(std::ranges::common_range>); - static_assert(std::ranges::sized_range>); - static_assert(std::ranges::forward_range>); - // A const, simple, common-, sized- and forward-range + // Note: sized because it is possible to get a difference between its + // beginning and its end. auto v = BasicTestView{data, data + 3}; auto sv = std::ranges::stride_view>(v, 1); static_assert(!std::is_same_v); @@ -55,19 +52,18 @@ constexpr bool test_non_default_sentinel() { { int data[3] = {1, 2, 3}; - // TODO: start here. - using x = BasicTestView, forward_iterator, false>; - static_assert(simple_view>>); - static_assert(std::ranges::common_range); - static_assert(!std::ranges::sized_range); - static_assert(!std::ranges::bidirectional_range); - - auto v = x{forward_iterator(data), forward_iterator(data + 3)}; - auto sv = std::ranges::stride_view(v, 1); + // ForwardTestView is not sized and not bidirectional, but it is common. + // Note: It is not sized because BasicTestView has no member function named size (by default) + // and nor is it possible to get a difference between its beginning and its end. + using ForwardTestView = BasicTestView, forward_iterator>; + + auto v = ForwardTestView{forward_iterator(data), forward_iterator(data + 3)}; + auto sv = std::ranges::stride_view(v, 1); static_assert(!std::is_same_v); } { + // TODO: Start here. static_assert(!simple_view); static_assert(std::ranges::common_range); static_assert(std::ranges::sized_range); From 22bc443f7d9c02c79b66571399c72012409c5e03 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 5 Sep 2025 06:56:45 -0400 Subject: [PATCH 173/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Update module map. Signed-off-by: Will Hawkins --- libcxx/include/__cxx03/module.modulemap | 1 + .../range.adaptors/range.stride.view/begin.pass.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libcxx/include/__cxx03/module.modulemap b/libcxx/include/__cxx03/module.modulemap index 34a2d0f25fc45..45e90c9b23830 100644 --- a/libcxx/include/__cxx03/module.modulemap +++ b/libcxx/include/__cxx03/module.modulemap @@ -1753,6 +1753,7 @@ module cxx03_std_private_ranges_size [system] { export std_private_type_traits_make_unsigned } module cxx03_std_private_ranges_split_view [system] { header "__ranges/split_view.h" } +module cxx03_std_private_ranges_stride_view [system] { header "__ranges/stride_view.h" } module cxx03_std_private_ranges_subrange [system] { header "__ranges/subrange.h" export std_private_ranges_subrange_fwd diff --git a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp index 71d2325c84805..c032e1e940311 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.stride.view/begin.pass.cpp @@ -46,12 +46,12 @@ static_assert(HasOnlyConstBegin> static_assert(HasConstAndNonConstBegin>); constexpr bool test() { - const auto unsimple_const_view = UnSimpleConstView(); - const auto sv_unsimple_const = std::ranges::stride_view(unsimple_const_view, 1); + const auto unsimple_const_view = UnSimpleConstView(); + const auto sv_unsimple_const = std::ranges::stride_view(unsimple_const_view, 1); static_assert(std::same_as); - auto simple_const_view = SimpleCommonConstView(); - auto sv_simple_const = std::ranges::stride_view(simple_const_view, 1); + auto simple_const_view = SimpleCommonConstView(); + auto sv_simple_const = std::ranges::stride_view(simple_const_view, 1); static_assert(std::same_as); return true; From 51c37d6107f0af048324cef08064e39c4af7d7ae Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 5 Sep 2025 06:57:05 -0400 Subject: [PATCH 174/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Update ranges include to match style. Signed-off-by: Will Hawkins --- libcxx/include/ranges | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/include/ranges b/libcxx/include/ranges index ae62354f9d48a..2d7171c6b438f 100644 --- a/libcxx/include/ranges +++ b/libcxx/include/ranges @@ -368,7 +368,7 @@ namespace std::ranges { namespace views { inline constexpr unspecified chunk_by = unspecified; } // C++23 - // [range.stride.view] + // [range.stride.view], stride view template requires view class stride_view; // C++23 From 5df9d0c93515c3cdf53c492a84885c7155a2b0c1 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 5 Sep 2025 06:57:59 -0400 Subject: [PATCH 175/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Add template argument comment. Signed-off-by: Will Hawkins --- libcxx/include/__ranges/stride_view.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libcxx/include/__ranges/stride_view.h b/libcxx/include/__ranges/stride_view.h index a9e9d186743cb..5ca398382948b 100644 --- a/libcxx/include/__ranges/stride_view.h +++ b/libcxx/include/__ranges/stride_view.h @@ -87,13 +87,13 @@ class stride_view : public view_interface> { [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() requires(!__simple_view<_View>) { - return __iterator(this, ranges::begin(__base_), 0); + return __iterator(this, ranges::begin(__base_), 0); } [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const requires range { - return __iterator(this, ranges::begin(__base_), 0); + return __iterator(this, ranges::begin(__base_), 0); } [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto end() @@ -101,9 +101,9 @@ class stride_view : public view_interface> { { if constexpr (common_range<_View> && sized_range<_View> && forward_range<_View>) { auto __missing = (__stride_ - ranges::distance(__base_) % __stride_) % __stride_; - return __iterator(this, ranges::end(__base_), __missing); + return __iterator(this, ranges::end(__base_), __missing); } else if constexpr (common_range<_View> && !bidirectional_range<_View>) { - return __iterator(this, ranges::end(__base_), 0); + return __iterator(this, ranges::end(__base_), 0); } else { return default_sentinel; } @@ -114,9 +114,9 @@ class stride_view : public view_interface> { { if constexpr (common_range && sized_range && forward_range) { auto __missing = (__stride_ - ranges::distance(__base_) % __stride_) % __stride_; - return __iterator(this, ranges::end(__base_), __missing); + return __iterator(this, ranges::end(__base_), __missing); } else if constexpr (common_range<_View> && !bidirectional_range<_View>) { - return __iterator(this, ranges::end(__base_), 0); + return __iterator(this, ranges::end(__base_), 0); } else { return default_sentinel; } From 922c14e59513d682b4b3fb5d6f1cbac75d1dd7f0 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 5 Sep 2025 07:10:50 -0400 Subject: [PATCH 176/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Make clang-format happy. Signed-off-by: Will Hawkins --- libcxx/modules/std/ranges.inc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/libcxx/modules/std/ranges.inc b/libcxx/modules/std/ranges.inc index ba9f09d9ab63e..abfeae5e65ca9 100644 --- a/libcxx/modules/std/ranges.inc +++ b/libcxx/modules/std/ranges.inc @@ -293,16 +293,16 @@ export namespace std { using std::ranges::views::zip; } // namespace views -#if 0 +# if 0 // [range.zip.transform], zip transform view using std::ranges::zip_transform_view; namespace views { using std::ranges::views::zip_transform; } -#endif // _LIBCPP_STD_VER >= 23 +# endif // _LIBCPP_STD_VER >= 23 -#if 0 +# if 0 using std::ranges::adjacent_view; namespace views { @@ -330,33 +330,33 @@ export namespace std { namespace views { using std::ranges::views::slide; } -#endif +# endif -#if _LIBCPP_STD_VER >= 23 +# if _LIBCPP_STD_VER >= 23 // [range.chunk.by], chunk by view using std::ranges::chunk_by_view; namespace views { using std::ranges::views::chunk_by; } -#endif // _LIBCPP_STD_VER >= 23 +# endif // _LIBCPP_STD_VER >= 23 -#if _LIBCPP_STD_VER >= 23 +# if _LIBCPP_STD_VER >= 23 // [range.stride], stride view using std::ranges::stride_view; namespace views { using std::ranges::views::stride; } // namespace views -#endif // _LIBCPP_STD_VER >= 23 +# endif // _LIBCPP_STD_VER >= 23 -#if 0 +# if 0 using std::ranges::cartesian_product_view; namespace views { using std::ranges::views::cartesian_product; } -#endif +# endif } // namespace ranges namespace views = ranges::views; @@ -364,8 +364,8 @@ export namespace std { using std::tuple_element; using std::tuple_size; -#if _LIBCPP_STD_VER >= 23 +# if _LIBCPP_STD_VER >= 23 using std::from_range; using std::from_range_t; -#endif // _LIBCPP_STD_VER >= 23 +# endif // _LIBCPP_STD_VER >= 23 } // namespace std From 8d8a6dcac1713a8899b91dedfb3f3eecfac9c91b Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 12 Sep 2025 07:44:56 -0400 Subject: [PATCH 177/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Update Generated Files --- .../version.version.compile.pass.cpp | 171 +++++++++++++----- 1 file changed, 127 insertions(+), 44 deletions(-) diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp index 17294d94d8603..471e47b69b7bd 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp @@ -2087,6 +2087,14 @@ # error "__cpp_lib_clamp should have the value 201603L in c++17" # endif +# ifdef __cpp_lib_common_reference +# error "__cpp_lib_common_reference should not be defined before c++20" +# endif + +# ifdef __cpp_lib_common_reference_wrapper +# error "__cpp_lib_common_reference_wrapper should not be defined before c++20" +# endif + # ifndef __cpp_lib_complex_udls # error "__cpp_lib_complex_udls should be defined in c++17" # endif @@ -2122,6 +2130,10 @@ # error "__cpp_lib_constexpr_dynamic_alloc should not be defined before c++20" # endif +# ifdef __cpp_lib_constexpr_forward_list +# error "__cpp_lib_constexpr_forward_list should not be defined before c++26" +# endif + # ifdef __cpp_lib_constexpr_functional # error "__cpp_lib_constexpr_functional should not be defined before c++20" # endif @@ -2130,6 +2142,10 @@ # error "__cpp_lib_constexpr_iterator should not be defined before c++20" # endif +# ifdef __cpp_lib_constexpr_list +# error "__cpp_lib_constexpr_list should not be defined before c++26" +# endif + # ifdef __cpp_lib_constexpr_memory # error "__cpp_lib_constexpr_memory should not be defined before c++20" # endif @@ -2142,6 +2158,10 @@ # error "__cpp_lib_constexpr_numeric should not be defined before c++20" # endif +# ifdef __cpp_lib_constexpr_queue +# error "__cpp_lib_constexpr_queue should not be defined before c++26" +# endif + # ifdef __cpp_lib_constexpr_string # error "__cpp_lib_constexpr_string should not be defined before c++20" # endif @@ -3305,6 +3325,20 @@ # error "__cpp_lib_clamp should have the value 201603L in c++20" # endif +# ifndef __cpp_lib_common_reference +# error "__cpp_lib_common_reference should be defined in c++20" +# endif +# if __cpp_lib_common_reference != 202302L +# error "__cpp_lib_common_reference should have the value 202302L in c++20" +# endif + +# ifndef __cpp_lib_common_reference_wrapper +# error "__cpp_lib_common_reference_wrapper should be defined in c++20" +# endif +# if __cpp_lib_common_reference_wrapper != 202302L +# error "__cpp_lib_common_reference_wrapper should have the value 202302L in c++20" +# endif + # ifndef __cpp_lib_complex_udls # error "__cpp_lib_complex_udls should be defined in c++20" # endif @@ -3352,6 +3386,10 @@ # error "__cpp_lib_constexpr_dynamic_alloc should have the value 201907L in c++20" # endif +# ifdef __cpp_lib_constexpr_forward_list +# error "__cpp_lib_constexpr_forward_list should not be defined before c++26" +# endif + # ifndef __cpp_lib_constexpr_functional # error "__cpp_lib_constexpr_functional should be defined in c++20" # endif @@ -3366,6 +3404,10 @@ # error "__cpp_lib_constexpr_iterator should have the value 201811L in c++20" # endif +# ifdef __cpp_lib_constexpr_list +# error "__cpp_lib_constexpr_list should not be defined before c++26" +# endif + # ifndef __cpp_lib_constexpr_memory # error "__cpp_lib_constexpr_memory should be defined in c++20" # endif @@ -3384,6 +3426,10 @@ # error "__cpp_lib_constexpr_numeric should have the value 201911L in c++20" # endif +# ifdef __cpp_lib_constexpr_queue +# error "__cpp_lib_constexpr_queue should not be defined before c++26" +# endif + # ifndef __cpp_lib_constexpr_string # error "__cpp_lib_constexpr_string should be defined in c++20" # endif @@ -4742,6 +4788,20 @@ # error "__cpp_lib_clamp should have the value 201603L in c++23" # endif +# ifndef __cpp_lib_common_reference +# error "__cpp_lib_common_reference should be defined in c++23" +# endif +# if __cpp_lib_common_reference != 202302L +# error "__cpp_lib_common_reference should have the value 202302L in c++23" +# endif + +# ifndef __cpp_lib_common_reference_wrapper +# error "__cpp_lib_common_reference_wrapper should be defined in c++23" +# endif +# if __cpp_lib_common_reference_wrapper != 202302L +# error "__cpp_lib_common_reference_wrapper should have the value 202302L in c++23" +# endif + # ifndef __cpp_lib_complex_udls # error "__cpp_lib_complex_udls should be defined in c++23" # endif @@ -4804,6 +4864,10 @@ # error "__cpp_lib_constexpr_dynamic_alloc should have the value 201907L in c++23" # endif +# ifdef __cpp_lib_constexpr_forward_list +# error "__cpp_lib_constexpr_forward_list should not be defined before c++26" +# endif + # ifndef __cpp_lib_constexpr_functional # error "__cpp_lib_constexpr_functional should be defined in c++23" # endif @@ -4818,6 +4882,10 @@ # error "__cpp_lib_constexpr_iterator should have the value 201811L in c++23" # endif +# ifdef __cpp_lib_constexpr_list +# error "__cpp_lib_constexpr_list should not be defined before c++26" +# endif + # ifndef __cpp_lib_constexpr_memory # error "__cpp_lib_constexpr_memory should be defined in c++23" # endif @@ -4836,6 +4904,10 @@ # error "__cpp_lib_constexpr_numeric should have the value 201911L in c++23" # endif +# ifdef __cpp_lib_constexpr_queue +# error "__cpp_lib_constexpr_queue should not be defined before c++26" +# endif + # ifndef __cpp_lib_constexpr_string # error "__cpp_lib_constexpr_string should be defined in c++23" # endif @@ -5637,17 +5709,11 @@ # error "__cpp_lib_ranges_iota should have the value 202202L in c++23" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_join_with -# error "__cpp_lib_ranges_join_with should be defined in c++23" -# endif -# if __cpp_lib_ranges_join_with != 202202L -# error "__cpp_lib_ranges_join_with should have the value 202202L in c++23" -# endif -# else -# ifdef __cpp_lib_ranges_join_with -# error "__cpp_lib_ranges_join_with should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_ranges_join_with +# error "__cpp_lib_ranges_join_with should be defined in c++23" +# endif +# if __cpp_lib_ranges_join_with != 202202L +# error "__cpp_lib_ranges_join_with should have the value 202202L in c++23" # endif # ifndef __cpp_lib_ranges_repeat @@ -6416,6 +6482,20 @@ # error "__cpp_lib_clamp should have the value 201603L in c++26" # endif +# ifndef __cpp_lib_common_reference +# error "__cpp_lib_common_reference should be defined in c++26" +# endif +# if __cpp_lib_common_reference != 202302L +# error "__cpp_lib_common_reference should have the value 202302L in c++26" +# endif + +# ifndef __cpp_lib_common_reference_wrapper +# error "__cpp_lib_common_reference_wrapper should be defined in c++26" +# endif +# if __cpp_lib_common_reference_wrapper != 202302L +# error "__cpp_lib_common_reference_wrapper should have the value 202302L in c++26" +# endif + # ifndef __cpp_lib_complex_udls # error "__cpp_lib_complex_udls should be defined in c++26" # endif @@ -6478,6 +6558,13 @@ # error "__cpp_lib_constexpr_dynamic_alloc should have the value 201907L in c++26" # endif +# ifndef __cpp_lib_constexpr_forward_list +# error "__cpp_lib_constexpr_forward_list should be defined in c++26" +# endif +# if __cpp_lib_constexpr_forward_list != 202502L +# error "__cpp_lib_constexpr_forward_list should have the value 202502L in c++26" +# endif + # ifndef __cpp_lib_constexpr_functional # error "__cpp_lib_constexpr_functional should be defined in c++26" # endif @@ -6492,6 +6579,13 @@ # error "__cpp_lib_constexpr_iterator should have the value 201811L in c++26" # endif +# ifndef __cpp_lib_constexpr_list +# error "__cpp_lib_constexpr_list should be defined in c++26" +# endif +# if __cpp_lib_constexpr_list != 202502L +# error "__cpp_lib_constexpr_list should have the value 202502L in c++26" +# endif + # ifndef __cpp_lib_constexpr_memory # error "__cpp_lib_constexpr_memory should be defined in c++26" # endif @@ -6519,6 +6613,13 @@ # error "__cpp_lib_constexpr_numeric should have the value 201911L in c++26" # endif +# ifndef __cpp_lib_constexpr_queue +# error "__cpp_lib_constexpr_queue should be defined in c++26" +# endif +# if __cpp_lib_constexpr_queue != 202502L +# error "__cpp_lib_constexpr_queue should have the value 202502L in c++26" +# endif + # ifndef __cpp_lib_constexpr_string # error "__cpp_lib_constexpr_string should be defined in c++26" # endif @@ -6561,17 +6662,11 @@ # error "__cpp_lib_constexpr_vector should have the value 201907L in c++26" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_constrained_equality -# error "__cpp_lib_constrained_equality should be defined in c++26" -# endif -# if __cpp_lib_constrained_equality != 202403L -# error "__cpp_lib_constrained_equality should have the value 202403L in c++26" -# endif -# else -# ifdef __cpp_lib_constrained_equality -# error "__cpp_lib_constrained_equality should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_constrained_equality +# error "__cpp_lib_constrained_equality should be defined in c++26" +# endif +# if __cpp_lib_constrained_equality != 202411L +# error "__cpp_lib_constrained_equality should have the value 202411L in c++26" # endif # ifndef __cpp_lib_containers_ranges @@ -7373,17 +7468,11 @@ # error "__cpp_lib_optional should have the value 202110L in c++26" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_optional_range_support -# error "__cpp_lib_optional_range_support should be defined in c++26" -# endif -# if __cpp_lib_optional_range_support != 202406L -# error "__cpp_lib_optional_range_support should have the value 202406L in c++26" -# endif -# else -# ifdef __cpp_lib_optional_range_support -# error "__cpp_lib_optional_range_support should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_optional_range_support +# error "__cpp_lib_optional_range_support should be defined in c++26" +# endif +# if __cpp_lib_optional_range_support != 202406L +# error "__cpp_lib_optional_range_support should have the value 202406L in c++26" # endif # ifndef __cpp_lib_out_ptr @@ -7539,17 +7628,11 @@ # error "__cpp_lib_ranges_iota should have the value 202202L in c++26" # endif -# if !defined(_LIBCPP_VERSION) -# ifndef __cpp_lib_ranges_join_with -# error "__cpp_lib_ranges_join_with should be defined in c++26" -# endif -# if __cpp_lib_ranges_join_with != 202202L -# error "__cpp_lib_ranges_join_with should have the value 202202L in c++26" -# endif -# else -# ifdef __cpp_lib_ranges_join_with -# error "__cpp_lib_ranges_join_with should not be defined because it is unimplemented in libc++!" -# endif +# ifndef __cpp_lib_ranges_join_with +# error "__cpp_lib_ranges_join_with should be defined in c++26" +# endif +# if __cpp_lib_ranges_join_with != 202202L +# error "__cpp_lib_ranges_join_with should have the value 202202L in c++26" # endif # ifndef __cpp_lib_ranges_repeat From 782c9980102e122583db10741ed244266ed0bbf0 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Fri, 12 Sep 2025 18:13:45 -0400 Subject: [PATCH 178/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Update ranges.inc. --- libcxx/modules/std/ranges.inc | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/libcxx/modules/std/ranges.inc b/libcxx/modules/std/ranges.inc index abfeae5e65ca9..f9f24cc23b5b4 100644 --- a/libcxx/modules/std/ranges.inc +++ b/libcxx/modules/std/ranges.inc @@ -293,16 +293,15 @@ export namespace std { using std::ranges::views::zip; } // namespace views -# if 0 // [range.zip.transform], zip transform view using std::ranges::zip_transform_view; namespace views { using std::ranges::views::zip_transform; } -# endif // _LIBCPP_STD_VER >= 23 +#endif // _LIBCPP_STD_VER >= 23 -# if 0 +#if 0 using std::ranges::adjacent_view; namespace views { @@ -330,33 +329,31 @@ export namespace std { namespace views { using std::ranges::views::slide; } -# endif +#endif -# if _LIBCPP_STD_VER >= 23 +#if _LIBCPP_STD_VER >= 23 // [range.chunk.by], chunk by view using std::ranges::chunk_by_view; namespace views { using std::ranges::views::chunk_by; } -# endif // _LIBCPP_STD_VER >= 23 -# if _LIBCPP_STD_VER >= 23 // [range.stride], stride view using std::ranges::stride_view; namespace views { using std::ranges::views::stride; - } // namespace views -# endif // _LIBCPP_STD_VER >= 23 + } +#endif // _LIBCPP_STD_VER >= 23 -# if 0 +#if 0 using std::ranges::cartesian_product_view; namespace views { using std::ranges::views::cartesian_product; } -# endif +#endif } // namespace ranges namespace views = ranges::views; @@ -364,8 +361,8 @@ export namespace std { using std::tuple_element; using std::tuple_size; -# if _LIBCPP_STD_VER >= 23 +#if _LIBCPP_STD_VER >= 23 using std::from_range; using std::from_range_t; -# endif // _LIBCPP_STD_VER >= 23 +#endif // _LIBCPP_STD_VER >= 23 } // namespace std From fd697096d8872aba6dfda963226e885d797dde43 Mon Sep 17 00:00:00 2001 From: Will Hawkins Date: Wed, 8 Oct 2025 07:59:01 -0400 Subject: [PATCH 179/179] fixup! WIP: [libc++][ranges] Implement `ranges::stride_view`. Regenerate files. --- .../version.version.compile.pass.cpp | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp index 471e47b69b7bd..d78b1a26087ea 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp @@ -1616,6 +1616,10 @@ # error "__cpp_lib_ranges_find_last should not be defined before c++23" # endif +# ifdef __cpp_lib_ranges_indices +# error "__cpp_lib_ranges_indices should not be defined before c++26" +# endif + # ifdef __cpp_lib_ranges_iota # error "__cpp_lib_ranges_iota should not be defined before c++23" # endif @@ -1791,6 +1795,10 @@ # error "__cpp_lib_string_resize_and_overwrite should not be defined before c++23" # endif +# ifdef __cpp_lib_string_subview +# error "__cpp_lib_string_subview should not be defined before c++26" +# endif + # ifndef __cpp_lib_string_udls # error "__cpp_lib_string_udls should be defined in c++14" # endif @@ -2731,6 +2739,10 @@ # error "__cpp_lib_ranges_find_last should not be defined before c++23" # endif +# ifdef __cpp_lib_ranges_indices +# error "__cpp_lib_ranges_indices should not be defined before c++26" +# endif + # ifdef __cpp_lib_ranges_iota # error "__cpp_lib_ranges_iota should not be defined before c++23" # endif @@ -2936,6 +2948,10 @@ # error "__cpp_lib_string_resize_and_overwrite should not be defined before c++23" # endif +# ifdef __cpp_lib_string_subview +# error "__cpp_lib_string_subview should not be defined before c++26" +# endif + # ifndef __cpp_lib_string_udls # error "__cpp_lib_string_udls should be defined in c++17" # endif @@ -4119,6 +4135,10 @@ # error "__cpp_lib_ranges_find_last should not be defined before c++23" # endif +# ifdef __cpp_lib_ranges_indices +# error "__cpp_lib_ranges_indices should not be defined before c++26" +# endif + # ifdef __cpp_lib_ranges_iota # error "__cpp_lib_ranges_iota should not be defined before c++23" # endif @@ -4354,6 +4374,10 @@ # error "__cpp_lib_string_resize_and_overwrite should not be defined before c++23" # endif +# ifdef __cpp_lib_string_subview +# error "__cpp_lib_string_subview should not be defined before c++26" +# endif + # ifndef __cpp_lib_string_udls # error "__cpp_lib_string_udls should be defined in c++20" # endif @@ -5702,6 +5726,10 @@ # error "__cpp_lib_ranges_find_last should have the value 202207L in c++23" # endif +# ifdef __cpp_lib_ranges_indices +# error "__cpp_lib_ranges_indices should not be defined before c++26" +# endif + # ifndef __cpp_lib_ranges_iota # error "__cpp_lib_ranges_iota should be defined in c++23" # endif @@ -6009,6 +6037,10 @@ # error "__cpp_lib_string_resize_and_overwrite should have the value 202110L in c++23" # endif +# ifdef __cpp_lib_string_subview +# error "__cpp_lib_string_subview should not be defined before c++26" +# endif + # ifndef __cpp_lib_string_udls # error "__cpp_lib_string_udls should be defined in c++23" # endif @@ -7621,6 +7653,13 @@ # error "__cpp_lib_ranges_find_last should have the value 202207L in c++26" # endif +# ifndef __cpp_lib_ranges_indices +# error "__cpp_lib_ranges_indices should be defined in c++26" +# endif +# if __cpp_lib_ranges_indices != 202506L +# error "__cpp_lib_ranges_indices should have the value 202506L in c++26" +# endif + # ifndef __cpp_lib_ranges_iota # error "__cpp_lib_ranges_iota should be defined in c++26" # endif @@ -7973,6 +8012,13 @@ # error "__cpp_lib_string_resize_and_overwrite should have the value 202110L in c++26" # endif +# ifndef __cpp_lib_string_subview +# error "__cpp_lib_string_subview should be defined in c++26" +# endif +# if __cpp_lib_string_subview != 202506L +# error "__cpp_lib_string_subview should have the value 202506L in c++26" +# endif + # ifndef __cpp_lib_string_udls # error "__cpp_lib_string_udls should be defined in c++26" # endif