diff options
Diffstat (limited to 'contrib/llvm-project/libcxx/include/__ranges')
18 files changed, 2409 insertions, 0 deletions
diff --git a/contrib/llvm-project/libcxx/include/__ranges/access.h b/contrib/llvm-project/libcxx/include/__ranges/access.h new file mode 100644 index 000000000000..add848887c11 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/access.h @@ -0,0 +1,222 @@ +// -*- C++ -*- +//===------------------------ __ranges/access.h ---------------------------===// +// +// 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_ACCESS_H +#define _LIBCPP___RANGES_ACCESS_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/readable_traits.h> +#include <__ranges/enable_borrowed_range.h> +#include <__utility/__decay_copy.h> +#include <__utility/forward.h> +#include <concepts> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +// clang-format off + +namespace ranges { + template <class _Tp> + concept __can_borrow = + is_lvalue_reference_v<_Tp> || enable_borrowed_range<remove_cvref_t<_Tp> >; + + template<class _Tp> + concept __is_complete = requires { sizeof(_Tp); }; +} // namespace ranges + +// [range.access.begin] +namespace ranges::__begin { + template <class _Tp> + concept __member_begin = + __can_borrow<_Tp> && + requires(_Tp&& __t) { + { _VSTD::__decay_copy(__t.begin()) } -> input_or_output_iterator; + }; + + void begin(auto&) = delete; + void begin(const auto&) = delete; + + template <class _Tp> + concept __unqualified_begin = + !__member_begin<_Tp> && + __can_borrow<_Tp> && + __class_or_enum<remove_cvref_t<_Tp> > && + requires(_Tp && __t) { + { _VSTD::__decay_copy(begin(__t)) } -> input_or_output_iterator; + }; + + struct __fn { + template <class _Tp> + requires is_array_v<remove_cv_t<_Tp>> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const noexcept { + constexpr bool __complete = __is_complete<iter_value_t<_Tp> >; + if constexpr (__complete) { // used to disable cryptic diagnostic + return __t + 0; + } + else { + static_assert(__complete, "`std::ranges::begin` is SFINAE-unfriendly on arrays of an incomplete type."); + } + } + + template <class _Tp> + requires __member_begin<_Tp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(_VSTD::__decay_copy(__t.begin()))) + { + return __t.begin(); + } + + template <class _Tp> + requires __unqualified_begin<_Tp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(_VSTD::__decay_copy(begin(__t)))) + { + return begin(__t); + } + + void operator()(auto&&) const = delete; + }; +} // namespace ranges::__begin + +namespace ranges { + inline namespace __cpo { + inline constexpr auto begin = __begin::__fn{}; + } // namespace __cpo + + template <class _Tp> + using iterator_t = decltype(ranges::begin(declval<_Tp&>())); +} // namespace ranges + +// [range.access.end] +namespace ranges::__end { + template <class _Tp> + concept __member_end = + __can_borrow<_Tp> && + requires(_Tp&& __t) { + typename iterator_t<_Tp>; + { _VSTD::__decay_copy(_VSTD::forward<_Tp>(__t).end()) } -> sentinel_for<iterator_t<_Tp> >; + }; + + void end(auto&) = delete; + void end(const auto&) = delete; + + template <class _Tp> + concept __unqualified_end = + !__member_end<_Tp> && + __can_borrow<_Tp> && + __class_or_enum<remove_cvref_t<_Tp> > && + requires(_Tp && __t) { + typename iterator_t<_Tp>; + { _VSTD::__decay_copy(end(_VSTD::forward<_Tp>(__t))) } -> sentinel_for<iterator_t<_Tp> >; + }; + + class __fn { + public: + template <class _Tp, size_t _Np> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept { + constexpr bool __complete = __is_complete<remove_cv_t<_Tp> >; + if constexpr (__complete) { // used to disable cryptic diagnostic + return __t + _Np; + } + else { + static_assert(__complete, "`std::ranges::end` is SFINAE-unfriendly on arrays of an incomplete type."); + } + } + + template <class _Tp> + requires __member_end<_Tp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(_VSTD::__decay_copy(__t.end()))) + { + return _VSTD::forward<_Tp>(__t).end(); + } + + template <class _Tp> + requires __unqualified_end<_Tp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(_VSTD::__decay_copy(end(__t)))) + { + return end(__t); + } + + void operator()(auto&&) const = delete; + }; +} // namespace ranges::__end + +namespace ranges::inline __cpo { + inline constexpr auto end = __end::__fn{}; +} // namespace ranges::__cpo + +namespace ranges::__cbegin { + struct __fn { + template <class _Tp> + requires invocable<decltype(ranges::begin), _Tp const&> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const + noexcept(noexcept(ranges::begin(_VSTD::as_const(__t)))) + { + return ranges::begin(_VSTD::as_const(__t)); + } + + template <class _Tp> + requires is_rvalue_reference_v<_Tp> && invocable<decltype(ranges::begin), _Tp const&&> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::begin(static_cast<_Tp const&&>(__t)))) + { + return ranges::begin(static_cast<_Tp const&&>(__t)); + } + }; +} // namespace ranges::__cbegin + +namespace ranges::inline __cpo { + inline constexpr auto cbegin = __cbegin::__fn{}; +} // namespace ranges::__cpo + +namespace ranges::__cend { + struct __fn { + template <class _Tp> + requires invocable<decltype(ranges::end), _Tp const&> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp& __t) const + noexcept(noexcept(ranges::end(_VSTD::as_const(__t)))) + { + return ranges::end(_VSTD::as_const(__t)); + } + + template <class _Tp> + requires is_rvalue_reference_v<_Tp> && invocable<decltype(ranges::end), _Tp const&&> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::end(static_cast<_Tp const&&>(__t)))) + { + return ranges::end(static_cast<_Tp const&&>(__t)); + } + }; +} // namespace ranges::__cend + +namespace ranges::inline __cpo { + inline constexpr auto cend = __cend::__fn{}; +} // namespace ranges::__cpo + +// clang-format off + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_ACCESS_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/all.h b/contrib/llvm-project/libcxx/include/__ranges/all.h new file mode 100644 index 000000000000..d678d3e5d357 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/all.h @@ -0,0 +1,86 @@ +// -*- 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_ALL_H +#define _LIBCPP___RANGES_ALL_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/ref_view.h> +#include <__ranges/subrange.h> +#include <__utility/__decay_copy.h> +#include <__utility/declval.h> +#include <__utility/forward.h> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +namespace views { + +namespace __all { + struct __fn { + template<class _Tp> + requires ranges::view<decay_t<_Tp>> + _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(_VSTD::__decay_copy(_VSTD::forward<_Tp>(__t)))) + { + return _VSTD::forward<_Tp>(__t); + } + + template<class _Tp> + requires (!ranges::view<decay_t<_Tp>>) && + requires (_Tp&& __t) { ranges::ref_view{_VSTD::forward<_Tp>(__t)}; } + _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::ref_view{_VSTD::forward<_Tp>(__t)})) + { + return ranges::ref_view{_VSTD::forward<_Tp>(__t)}; + } + + template<class _Tp> + requires (!ranges::view<decay_t<_Tp>> && + !requires (_Tp&& __t) { ranges::ref_view{_VSTD::forward<_Tp>(__t)}; } && + requires (_Tp&& __t) { ranges::subrange{_VSTD::forward<_Tp>(__t)}; }) + _LIBCPP_HIDE_FROM_ABI + constexpr auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::subrange{_VSTD::forward<_Tp>(__t)})) + { + return ranges::subrange{_VSTD::forward<_Tp>(__t)}; + } + }; +} + +inline namespace __cpo { + inline constexpr auto all = __all::__fn{}; +} // namespace __cpo + +template<ranges::viewable_range _Range> +using all_t = decltype(views::all(declval<_Range>())); + +} // namespace views + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_ALL_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/common_view.h b/contrib/llvm-project/libcxx/include/__ranges/common_view.h new file mode 100644 index 000000000000..dab82602f671 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/common_view.h @@ -0,0 +1,113 @@ +// -*- 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_COMMON_VIEW_H +#define _LIBCPP___RANGES_COMMON_VIEW_H + +#include <__config> +#include <__iterator/common_iterator.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/size.h> +#include <__ranges/view_interface.h> +#include <concepts> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +namespace ranges { + +template<view _View> + requires (!common_range<_View> && copyable<iterator_t<_View>>) +class common_view : public view_interface<common_view<_View>> { + _View __base_ = _View(); + +public: + _LIBCPP_HIDE_FROM_ABI + common_view() requires default_initializable<_View> = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr explicit common_view(_View __v) : __base_(_VSTD::move(__v)) { } + + _LIBCPP_HIDE_FROM_ABI + constexpr _View base() const& requires copy_constructible<_View> { return __base_; } + + _LIBCPP_HIDE_FROM_ABI + constexpr _View base() && { return _VSTD::move(__base_); } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto begin() { + if constexpr (random_access_range<_View> && sized_range<_View>) + return ranges::begin(__base_); + else + return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::begin(__base_)); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto begin() const requires range<const _View> { + if constexpr (random_access_range<const _View> && sized_range<const _View>) + return ranges::begin(__base_); + else + return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::begin(__base_)); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto end() { + if constexpr (random_access_range<_View> && sized_range<_View>) + return ranges::begin(__base_) + ranges::size(__base_); + else + return common_iterator<iterator_t<_View>, sentinel_t<_View>>(ranges::end(__base_)); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto end() const requires range<const _View> { + if constexpr (random_access_range<const _View> && sized_range<const _View>) + return ranges::begin(__base_) + ranges::size(__base_); + else + return common_iterator<iterator_t<const _View>, sentinel_t<const _View>>(ranges::end(__base_)); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto size() requires sized_range<_View> { + return ranges::size(__base_); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto size() const requires sized_range<const _View> { + return ranges::size(__base_); + } +}; + +template<class _Range> +common_view(_Range&&) + -> common_view<views::all_t<_Range>>; + +template<class _View> +inline constexpr bool enable_borrowed_range<common_view<_View>> = enable_borrowed_range<_View>; + +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_COMMON_VIEW_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/concepts.h b/contrib/llvm-project/libcxx/include/__ranges/concepts.h new file mode 100644 index 000000000000..2f912c2841e8 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/concepts.h @@ -0,0 +1,138 @@ +// -*- C++ -*- +//===--------------------- __ranges/concepts.h ----------------------------===// +// +// 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_CONCEPTS_H +#define _LIBCPP___RANGES_CONCEPTS_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iter_move.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/readable_traits.h> +#include <__ranges/access.h> +#include <__ranges/enable_borrowed_range.h> +#include <__ranges/data.h> +#include <__ranges/enable_view.h> +#include <__ranges/size.h> +#include <concepts> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +// clang-format off + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +namespace ranges { + // [range.range] + template <class _Tp> + concept range = requires(_Tp& __t) { + ranges::begin(__t); // sometimes equality-preserving + ranges::end(__t); + }; + + template<class _Range> + concept borrowed_range = range<_Range> && + (is_lvalue_reference_v<_Range> || enable_borrowed_range<remove_cvref_t<_Range>>); + + // `iterator_t` defined in <__ranges/access.h> + + template <range _Rp> + using sentinel_t = decltype(ranges::end(declval<_Rp&>())); + + template <range _Rp> + using range_difference_t = iter_difference_t<iterator_t<_Rp>>; + + template <range _Rp> + using range_value_t = iter_value_t<iterator_t<_Rp>>; + + template <range _Rp> + using range_reference_t = iter_reference_t<iterator_t<_Rp>>; + + template <range _Rp> + using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rp>>; + + // [range.sized] + template <class _Tp> + concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); }; + + template<sized_range _Rp> + using range_size_t = decltype(ranges::size(declval<_Rp&>())); + + // `disable_sized_range` defined in `<__ranges/size.h>` + + // [range.view], views + + // `enable_view` defined in <__ranges/enable_view.h> + // `view_base` defined in <__ranges/enable_view.h> + + template <class _Tp> + concept view = + range<_Tp> && + movable<_Tp> && + enable_view<_Tp>; + + template<class _Range> + concept __simple_view = + view<_Range> && range<const _Range> && + same_as<iterator_t<_Range>, iterator_t<const _Range>> && + same_as<sentinel_t<_Range>, iterator_t<const _Range>>; + + // [range.refinements], other range refinements + template <class _Rp, class _Tp> + concept output_range = range<_Rp> && output_iterator<iterator_t<_Rp>, _Tp>; + + template <class _Tp> + concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>; + + template <class _Tp> + concept forward_range = input_range<_Tp> && forward_iterator<iterator_t<_Tp>>; + + template <class _Tp> + concept bidirectional_range = forward_range<_Tp> && bidirectional_iterator<iterator_t<_Tp>>; + + template <class _Tp> + concept random_access_range = + bidirectional_range<_Tp> && random_access_iterator<iterator_t<_Tp>>; + + template<class _Tp> + concept contiguous_range = + random_access_range<_Tp> && + contiguous_iterator<iterator_t<_Tp>> && + requires(_Tp& __t) { + { ranges::data(__t) } -> same_as<add_pointer_t<range_reference_t<_Tp>>>; + }; + + template <class _Tp> + concept common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>; + + template<class _Tp> + concept viewable_range = + range<_Tp> && ( + (view<remove_cvref_t<_Tp>> && constructible_from<remove_cvref_t<_Tp>, _Tp>) || + (!view<remove_cvref_t<_Tp>> && borrowed_range<_Tp>) + ); +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +// clang-format on + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_CONCEPTS_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/copyable_box.h b/contrib/llvm-project/libcxx/include/__ranges/copyable_box.h new file mode 100644 index 000000000000..f2d3843f79f5 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/copyable_box.h @@ -0,0 +1,175 @@ +// -*- 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_COPYABLE_BOX_H +#define _LIBCPP___RANGES_COPYABLE_BOX_H + +#include <__config> +#include <__memory/addressof.h> +#include <__memory/construct_at.h> +#include <__utility/move.h> +#include <concepts> +#include <optional> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +// __copyable_box allows turning a type that is copy-constructible (but maybe not copy-assignable) into +// a type that is both copy-constructible and copy-assignable. It does that by introducing an empty state +// and basically doing destroy-then-copy-construct in the assignment operator. The empty state is necessary +// to handle the case where the copy construction fails after destroying the object. +// +// In some cases, we can completely avoid the use of an empty state; we provide a specialization of +// __copyable_box that does this, see below for the details. + +template<class _Tp> +concept __copy_constructible_object = copy_constructible<_Tp> && is_object_v<_Tp>; + +namespace ranges { + // Primary template - uses std::optional and introduces an empty state in case assignment fails. + template<__copy_constructible_object _Tp> + class __copyable_box { + [[no_unique_address]] optional<_Tp> __val_; + + public: + template<class ..._Args> + requires is_constructible_v<_Tp, _Args...> + _LIBCPP_HIDE_FROM_ABI + constexpr explicit __copyable_box(in_place_t, _Args&& ...__args) + noexcept(is_nothrow_constructible_v<_Tp, _Args...>) + : __val_(in_place, _VSTD::forward<_Args>(__args)...) + { } + + _LIBCPP_HIDE_FROM_ABI + constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>) + requires default_initializable<_Tp> + : __val_(in_place) + { } + + _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default; + _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr __copyable_box& operator=(__copyable_box const& __other) + noexcept(is_nothrow_copy_constructible_v<_Tp>) + { + if (this != _VSTD::addressof(__other)) { + if (__other.__has_value()) __val_.emplace(*__other); + else __val_.reset(); + } + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr __copyable_box& operator=(__copyable_box&& __other) + noexcept(is_nothrow_move_constructible_v<_Tp>) + { + if (this != _VSTD::addressof(__other)) { + if (__other.__has_value()) __val_.emplace(_VSTD::move(*__other)); + else __val_.reset(); + } + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return *__val_; } + _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return *__val_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return __val_.has_value(); } + }; + + // This partial specialization implements an optimization for when we know we don't need to store + // an empty state to represent failure to perform an assignment. For copy-assignment, this happens: + // + // 1. If the type is copyable (which includes copy-assignment), we can use the type's own assignment operator + // directly and avoid using std::optional. + // 2. If the type is not copyable, but it is nothrow-copy-constructible, then we can implement assignment as + // destroy-and-then-construct and we know it will never fail, so we don't need an empty state. + // + // The exact same reasoning can be applied for move-assignment, with copyable replaced by movable and + // nothrow-copy-constructible replaced by nothrow-move-constructible. This specialization is enabled + // whenever we can apply any of these optimizations for both the copy assignment and the move assignment + // operator. + template<class _Tp> + concept __doesnt_need_empty_state_for_copy = copyable<_Tp> || is_nothrow_copy_constructible_v<_Tp>; + + template<class _Tp> + concept __doesnt_need_empty_state_for_move = movable<_Tp> || is_nothrow_move_constructible_v<_Tp>; + + template<__copy_constructible_object _Tp> + requires __doesnt_need_empty_state_for_copy<_Tp> && __doesnt_need_empty_state_for_move<_Tp> + class __copyable_box<_Tp> { + [[no_unique_address]] _Tp __val_; + + public: + template<class ..._Args> + requires is_constructible_v<_Tp, _Args...> + _LIBCPP_HIDE_FROM_ABI + constexpr explicit __copyable_box(in_place_t, _Args&& ...__args) + noexcept(is_nothrow_constructible_v<_Tp, _Args...>) + : __val_(_VSTD::forward<_Args>(__args)...) + { } + + _LIBCPP_HIDE_FROM_ABI + constexpr __copyable_box() noexcept(is_nothrow_default_constructible_v<_Tp>) + requires default_initializable<_Tp> + : __val_() + { } + + _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box const&) = default; + _LIBCPP_HIDE_FROM_ABI __copyable_box(__copyable_box&&) = default; + + // Implementation of assignment operators in case we perform optimization (1) + _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box const&) requires copyable<_Tp> = default; + _LIBCPP_HIDE_FROM_ABI __copyable_box& operator=(__copyable_box&&) requires movable<_Tp> = default; + + // Implementation of assignment operators in case we perform optimization (2) + _LIBCPP_HIDE_FROM_ABI + constexpr __copyable_box& operator=(__copyable_box const& __other) noexcept { + static_assert(is_nothrow_copy_constructible_v<_Tp>); + if (this != _VSTD::addressof(__other)) { + _VSTD::destroy_at(_VSTD::addressof(__val_)); + _VSTD::construct_at(_VSTD::addressof(__val_), __other.__val_); + } + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __copyable_box& operator=(__copyable_box&& __other) noexcept { + static_assert(is_nothrow_move_constructible_v<_Tp>); + if (this != _VSTD::addressof(__other)) { + _VSTD::destroy_at(_VSTD::addressof(__val_)); + _VSTD::construct_at(_VSTD::addressof(__val_), _VSTD::move(__other.__val_)); + } + return *this; + } + + _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return __val_; } + _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return __val_; } + _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; } + }; +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_COPYABLE_BOX_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/dangling.h b/contrib/llvm-project/libcxx/include/__ranges/dangling.h new file mode 100644 index 000000000000..deb02a1a448d --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/dangling.h @@ -0,0 +1,47 @@ +// -*- 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_DANGLING_H +#define _LIBCPP___RANGES_DANGLING_H + +#include <__config> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +namespace ranges { +struct dangling { + dangling() = default; + _LIBCPP_HIDE_FROM_ABI constexpr dangling(auto&&...) noexcept {} +}; + +template <range _Rp> +using borrowed_iterator_t = _If<borrowed_range<_Rp>, iterator_t<_Rp>, dangling>; + +// borrowed_subrange_t defined in <__ranges/subrange.h> +} // namespace ranges + +#endif // !_LIBCPP_HAS_NO_RANGES + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_DANGLING_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/data.h b/contrib/llvm-project/libcxx/include/__ranges/data.h new file mode 100644 index 000000000000..dae30984d3f9 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/data.h @@ -0,0 +1,86 @@ +// -*- C++ -*- +//===------------------------ __ranges/data.h ------------------------------===// +// +// 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_DATA_H +#define _LIBCPP___RANGES_DATA_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__memory/pointer_traits.h> +#include <__ranges/access.h> +#include <__utility/forward.h> +#include <concepts> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +// clang-format off +namespace ranges { +// [range.prim.data] +namespace __data { + template <class _Tp> + concept __ptr_to_object = is_pointer_v<_Tp> && is_object_v<remove_pointer_t<_Tp>>; + + template <class _Tp> + concept __member_data = + requires(_Tp&& __t) { + { _VSTD::forward<_Tp>(__t) } -> __can_borrow; + { __t.data() } -> __ptr_to_object; + }; + + template <class _Tp> + concept __ranges_begin_invocable = + !__member_data<_Tp> && + requires(_Tp&& __t) { + { _VSTD::forward<_Tp>(__t) } -> __can_borrow; + { ranges::begin(_VSTD::forward<_Tp>(__t)) } -> contiguous_iterator; + }; + + struct __fn { + template <__member_data _Tp> + requires __can_borrow<_Tp> + _LIBCPP_HIDE_FROM_ABI + constexpr __ptr_to_object auto operator()(_Tp&& __t) const + noexcept(noexcept(__t.data())) { + return __t.data(); + } + + template<__ranges_begin_invocable _Tp> + requires __can_borrow<_Tp> + _LIBCPP_HIDE_FROM_ABI + constexpr __ptr_to_object auto operator()(_Tp&& __t) const + noexcept(noexcept(_VSTD::to_address(ranges::begin(_VSTD::forward<_Tp>(__t))))) { + return _VSTD::to_address(ranges::begin(_VSTD::forward<_Tp>(__t))); + } + }; +} // end namespace __data + +inline namespace __cpo { + inline constexpr const auto data = __data::__fn{}; +} // namespace __cpo +} // namespace ranges + +// clang-format off + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_DATA_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/drop_view.h b/contrib/llvm-project/libcxx/include/__ranges/drop_view.h new file mode 100644 index 000000000000..099fd227111d --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/drop_view.h @@ -0,0 +1,131 @@ +// -*- 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_DROP_VIEW_H +#define _LIBCPP___RANGES_DROP_VIEW_H + +#include <__config> +#include <__iterator/concepts.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/size.h> +#include <__ranges/view_interface.h> +#include <__utility/move.h> +#include <concepts> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +namespace ranges { + template<view _View> + class drop_view + : public view_interface<drop_view<_View>> + { + // We cache begin() whenever ranges::next is not guaranteed O(1) to provide an + // amortized O(1) begin() method. If this is an input_range, then we cannot cache + // begin because begin is not equality preserving. + // Note: drop_view<input-range>::begin() is still trivially amortized O(1) because + // one can't call begin() on it more than once. + static constexpr bool _UseCache = forward_range<_View> && !(random_access_range<_View> && sized_range<_View>); + using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>; + [[no_unique_address]] _Cache __cached_begin_ = _Cache(); + range_difference_t<_View> __count_ = 0; + _View __base_ = _View(); + +public: + drop_view() requires default_initializable<_View> = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr drop_view(_View __base, range_difference_t<_View> __count) + : __count_(__count) + , __base_(_VSTD::move(__base)) + { + _LIBCPP_ASSERT(__count_ >= 0, "count must be greater than or equal to zero."); + } + + _LIBCPP_HIDE_FROM_ABI constexpr _View base() const& requires copy_constructible<_View> { return __base_; } + _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return _VSTD::move(__base_); } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto begin() + requires (!(__simple_view<_View> && + random_access_range<const _View> && sized_range<const _View>)) + { + if constexpr (_UseCache) + if (__cached_begin_.__has_value()) + return *__cached_begin_; + + auto __tmp = ranges::next(ranges::begin(__base_), __count_, ranges::end(__base_)); + if constexpr (_UseCache) + __cached_begin_.__set(__tmp); + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto begin() const + requires random_access_range<const _View> && sized_range<const _View> + { + return ranges::next(ranges::begin(__base_), __count_, ranges::end(__base_)); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto end() + requires (!__simple_view<_View>) + { return ranges::end(__base_); } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto end() const + requires range<const _View> + { return ranges::end(__base_); } + + _LIBCPP_HIDE_FROM_ABI + static constexpr auto __size(auto& __self) { + const auto __s = ranges::size(__self.__base_); + const auto __c = static_cast<decltype(__s)>(__self.__count_); + return __s < __c ? 0 : __s - __c; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto size() + requires sized_range<_View> + { return __size(*this); } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto size() const + requires sized_range<const _View> + { return __size(*this); } + }; + + template<class _Range> + drop_view(_Range&&, range_difference_t<_Range>) -> drop_view<views::all_t<_Range>>; + + template<class _Tp> + inline constexpr bool enable_borrowed_range<drop_view<_Tp>> = enable_borrowed_range<_Tp>; +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_DROP_VIEW_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/empty.h b/contrib/llvm-project/libcxx/include/__ranges/empty.h new file mode 100644 index 000000000000..73892a8c1035 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/empty.h @@ -0,0 +1,86 @@ +// -*- 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_EMPTY_H +#define _LIBCPP___RANGES_EMPTY_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__ranges/access.h> +#include <__ranges/size.h> +#include <__utility/forward.h> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +// clang-format off +namespace ranges { +// [range.prim.empty] +namespace __empty { + template <class _Tp> + concept __member_empty = requires(_Tp&& __t) { + bool(_VSTD::forward<_Tp>(__t).empty()); + }; + + template<class _Tp> + concept __can_invoke_size = + !__member_empty<_Tp> && + requires(_Tp&& __t) { ranges::size(_VSTD::forward<_Tp>(__t)); }; + + template <class _Tp> + concept __can_compare_begin_end = + !__member_empty<_Tp> && + !__can_invoke_size<_Tp> && + requires(_Tp&& __t) { + bool(ranges::begin(__t) == ranges::end(__t)); + { ranges::begin(__t) } -> forward_iterator; + }; + + struct __fn { + template <__member_empty _Tp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const + noexcept(noexcept(bool(__t.empty()))) { + return __t.empty(); + } + + template <__can_invoke_size _Tp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const + noexcept(noexcept(ranges::size(_VSTD::forward<_Tp>(__t)))) { + return ranges::size(_VSTD::forward<_Tp>(__t)) == 0; + } + + template<__can_compare_begin_end _Tp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const + noexcept(noexcept(bool(ranges::begin(__t) == ranges::end(__t)))) { + return ranges::begin(__t) == ranges::end(__t); + } + }; +} + +inline namespace __cpo { + inline constexpr auto empty = __empty::__fn{}; +} // namespace __cpo +} // namespace ranges +// clang-format off + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_EMPTY_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/empty_view.h b/contrib/llvm-project/libcxx/include/__ranges/empty_view.h new file mode 100644 index 000000000000..7c0f307c8243 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/empty_view.h @@ -0,0 +1,46 @@ +// -*- 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_EMPTY_VIEW_H +#define _LIBCPP___RANGES_EMPTY_VIEW_H + +#include <__config> +#include <__ranges/view_interface.h> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +namespace ranges { + template<class _Tp> + requires is_object_v<_Tp> + class empty_view : public view_interface<empty_view<_Tp>> { + public: + _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* begin() noexcept { return nullptr; } + _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* end() noexcept { return nullptr; } + _LIBCPP_HIDE_FROM_ABI static constexpr _Tp* data() noexcept { return nullptr; } + _LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 0; } + _LIBCPP_HIDE_FROM_ABI static constexpr bool empty() noexcept { return true; } + }; +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_EMPTY_VIEW_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/enable_borrowed_range.h b/contrib/llvm-project/libcxx/include/__ranges/enable_borrowed_range.h new file mode 100644 index 000000000000..618b2223c716 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/enable_borrowed_range.h @@ -0,0 +1,46 @@ +// -*- C++ -*- +//===------------------ __ranges/enable_borrowed_range.h ------------------===// +// +// 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_ENABLE_BORROWED_RANGE_H +#define _LIBCPP___RANGES_ENABLE_BORROWED_RANGE_H + +// These customization variables are used in <span> and <string_view>. The +// separate header is used to avoid including the entire <ranges> header in +// <span> and <string_view>. + +#include <__config> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES) + +namespace ranges +{ + +// [range.range], ranges + +template <class> +inline constexpr bool enable_borrowed_range = false; + +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_ENABLE_BORROWED_RANGE_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/enable_view.h b/contrib/llvm-project/libcxx/include/__ranges/enable_view.h new file mode 100644 index 000000000000..2628d51ced49 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/enable_view.h @@ -0,0 +1,42 @@ +// -*- 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_ENABLE_VIEW_H +#define _LIBCPP___RANGES_ENABLE_VIEW_H + +#include <__config> +#include <concepts> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +namespace ranges { + +struct view_base { }; + +template <class _Tp> +inline constexpr bool enable_view = derived_from<_Tp, view_base>; + +} // end namespace ranges + +#endif // !_LIBCPP_HAS_NO_RANGES + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_ENABLE_VIEW_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/non_propagating_cache.h b/contrib/llvm-project/libcxx/include/__ranges/non_propagating_cache.h new file mode 100644 index 000000000000..878f7070a07f --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/non_propagating_cache.h @@ -0,0 +1,99 @@ +// -*- 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_NON_PROPAGATING_CACHE_H +#define _LIBCPP___RANGES_NON_PROPAGATING_CACHE_H + +#include <__config> +#include <__iterator/concepts.h> // indirectly_readable +#include <__iterator/iterator_traits.h> // iter_reference_t +#include <__memory/addressof.h> +#include <concepts> // constructible_from +#include <optional> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +// clang-format off + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +namespace ranges { + // __non_propagating_cache is a helper type that allows storing an optional value in it, + // but which does not copy the source's value when it is copy constructed/assigned to, + // and which resets the source's value when it is moved-from. + // + // This type is used as an implementation detail of some views that need to cache the + // result of `begin()` in order to provide an amortized O(1) begin() method. Typically, + // we don't want to propagate the value of the cache upon copy because the cached iterator + // may refer to internal details of the source view. + template<class _Tp> + requires is_object_v<_Tp> + class _LIBCPP_TEMPLATE_VIS __non_propagating_cache { + optional<_Tp> __value_ = nullopt; + + public: + _LIBCPP_HIDE_FROM_ABI __non_propagating_cache() = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr __non_propagating_cache(__non_propagating_cache const&) noexcept + : __value_(nullopt) + { } + + _LIBCPP_HIDE_FROM_ABI + constexpr __non_propagating_cache(__non_propagating_cache&& __other) noexcept + : __value_(nullopt) + { + __other.__value_.reset(); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __non_propagating_cache& operator=(__non_propagating_cache const& __other) noexcept { + if (this != _VSTD::addressof(__other)) { + __value_.reset(); + } + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __non_propagating_cache& operator=(__non_propagating_cache&& __other) noexcept { + __value_.reset(); + __other.__value_.reset(); + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr _Tp& operator*() { return *__value_; } + _LIBCPP_HIDE_FROM_ABI + constexpr _Tp const& operator*() const { return *__value_; } + + _LIBCPP_HIDE_FROM_ABI + constexpr bool __has_value() const { return __value_.has_value(); } + _LIBCPP_HIDE_FROM_ABI + constexpr void __set(_Tp const& __value) { __value_.emplace(__value); } + _LIBCPP_HIDE_FROM_ABI + constexpr void __set(_Tp&& __value) { __value_.emplace(_VSTD::move(__value)); } + }; + + struct __empty_cache { }; +} // namespace ranges + +#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_NON_PROPAGATING_CACHE_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/ref_view.h b/contrib/llvm-project/libcxx/include/__ranges/ref_view.h new file mode 100644 index 000000000000..fb45a359863b --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/ref_view.h @@ -0,0 +1,87 @@ +// -*- 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_REF_VIEW_H +#define _LIBCPP___RANGES_REF_VIEW_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__memory/addressof.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/data.h> +#include <__ranges/empty.h> +#include <__ranges/size.h> +#include <__ranges/view_interface.h> +#include <concepts> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +namespace ranges { + template<range _Range> + requires is_object_v<_Range> + class ref_view : public view_interface<ref_view<_Range>> { + _Range *__range_; + + static void __fun(_Range&); + static void __fun(_Range&&) = delete; + +public: + template<class _Tp> + requires __different_from<_Tp, ref_view> && + convertible_to<_Tp, _Range&> && requires { __fun(declval<_Tp>()); } + _LIBCPP_HIDE_FROM_ABI + constexpr ref_view(_Tp&& __t) + : __range_(_VSTD::addressof(static_cast<_Range&>(_VSTD::forward<_Tp>(__t)))) + {} + + _LIBCPP_HIDE_FROM_ABI constexpr _Range& base() const { return *__range_; } + + _LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Range> begin() const { return ranges::begin(*__range_); } + _LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Range> end() const { return ranges::end(*__range_); } + + _LIBCPP_HIDE_FROM_ABI + constexpr bool empty() const + requires requires { ranges::empty(*__range_); } + { return ranges::empty(*__range_); } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto size() const + requires sized_range<_Range> + { return ranges::size(*__range_); } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto data() const + requires contiguous_range<_Range> + { return ranges::data(*__range_); } + }; + + template<class _Range> + ref_view(_Range&) -> ref_view<_Range>; + +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_REF_VIEW_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/size.h b/contrib/llvm-project/libcxx/include/__ranges/size.h new file mode 100644 index 000000000000..ce7183e15447 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/size.h @@ -0,0 +1,132 @@ +// -*- 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_SIZE_H +#define _LIBCPP___RANGES_SIZE_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__ranges/access.h> +#include <__utility/__decay_copy.h> +#include <__utility/forward.h> +#include <concepts> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +// clang-format off +namespace ranges { +template<class> +inline constexpr bool disable_sized_range = false; + +// [range.prim.size] +namespace __size { + void size(auto&) = delete; + void size(const auto&) = delete; + + template <class _Tp> + concept __size_enabled = !disable_sized_range<remove_cvref_t<_Tp>>; + + template <class _Tp> + concept __member_size = __size_enabled<_Tp> && requires(_Tp&& __t) { + { _VSTD::__decay_copy(_VSTD::forward<_Tp>(__t).size()) } -> __integer_like; + }; + + template <class _Tp> + concept __unqualified_size = + __size_enabled<_Tp> && + !__member_size<_Tp> && + __class_or_enum<remove_cvref_t<_Tp>> && + requires(_Tp&& __t) { + { _VSTD::__decay_copy(size(_VSTD::forward<_Tp>(__t))) } -> __integer_like; + }; + + template <class _Tp> + concept __difference = + !__member_size<_Tp> && + !__unqualified_size<_Tp> && + __class_or_enum<remove_cvref_t<_Tp>> && + requires(_Tp&& __t) { + { ranges::begin(__t) } -> forward_iterator; + { ranges::end(__t) } -> sized_sentinel_for<decltype(ranges::begin(declval<_Tp>()))>; + }; + + struct __fn { + template <class _Tp, size_t _Sz> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&&)[_Sz]) const noexcept { + return _Sz; + } + + template <class _Tp, size_t _Sz> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&)[_Sz]) const noexcept { + return _Sz; + } + + template <__member_size _Tp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const + noexcept(noexcept(_VSTD::forward<_Tp>(__t).size())) { + return _VSTD::forward<_Tp>(__t).size(); + } + + template <__unqualified_size _Tp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const + noexcept(noexcept(size(_VSTD::forward<_Tp>(__t)))) { + return size(_VSTD::forward<_Tp>(__t)); + } + + template<__difference _Tp> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::end(__t) - ranges::begin(__t))) { + return _VSTD::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t)); + } + }; +} // end namespace __size + +inline namespace __cpo { + inline constexpr auto size = __size::__fn{}; +} // namespace __cpo + +namespace __ssize { + struct __fn { + template<class _Tp> + requires requires (_Tp&& __t) { ranges::size(__t); } + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr integral auto operator()(_Tp&& __t) const + noexcept(noexcept(ranges::size(__t))) { + using _Signed = make_signed_t<decltype(ranges::size(__t))>; + if constexpr (sizeof(ptrdiff_t) > sizeof(_Signed)) + return static_cast<ptrdiff_t>(ranges::size(__t)); + else + return static_cast<_Signed>(ranges::size(__t)); + } + }; +} + +inline namespace __cpo { + inline constexpr const auto ssize = __ssize::__fn{}; +} // namespace __cpo +} // namespace ranges + +// clang-format off + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_SIZE_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/subrange.h b/contrib/llvm-project/libcxx/include/__ranges/subrange.h new file mode 100644 index 000000000000..25d333db02de --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/subrange.h @@ -0,0 +1,267 @@ +// -*- 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_SUBRANGE_H +#define _LIBCPP___RANGES_SUBRANGE_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/incrementable_traits.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/advance.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/dangling.h> +#include <__ranges/enable_borrowed_range.h> +#include <__ranges/size.h> +#include <__ranges/view_interface.h> +#include <concepts> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +// clang-format off +namespace ranges { + template<class _From, class _To> + concept __convertible_to_non_slicing = + convertible_to<_From, _To> && + // If they're both pointers, they must have the same element type. + !(is_pointer_v<decay_t<_From>> && + is_pointer_v<decay_t<_To>> && + __different_from<remove_pointer_t<decay_t<_From>>, remove_pointer_t<decay_t<_To>>>); + + template<class _Tp> + concept __pair_like = + !is_reference_v<_Tp> && requires(_Tp __t) { + typename tuple_size<_Tp>::type; // Ensures `tuple_size<T>` is complete. + requires derived_from<tuple_size<_Tp>, integral_constant<size_t, 2>>; + typename tuple_element_t<0, remove_const_t<_Tp>>; + typename tuple_element_t<1, remove_const_t<_Tp>>; + { _VSTD::get<0>(__t) } -> convertible_to<const tuple_element_t<0, _Tp>&>; + { _VSTD::get<1>(__t) } -> convertible_to<const tuple_element_t<1, _Tp>&>; + }; + + template<class _Pair, class _Iter, class _Sent> + concept __pair_like_convertible_from = + !range<_Pair> && __pair_like<_Pair> && + constructible_from<_Pair, _Iter, _Sent> && + __convertible_to_non_slicing<_Iter, tuple_element_t<0, _Pair>> && + convertible_to<_Sent, tuple_element_t<1, _Pair>>; + + enum class _LIBCPP_ENUM_VIS subrange_kind : bool { unsized, sized }; + + template<class _Iter, class _Sent, bool> + struct __subrange_base { + static constexpr bool __store_size = false; + _Iter __begin_ = _Iter(); + _Sent __end_ = _Sent(); + + _LIBCPP_HIDE_FROM_ABI + constexpr __subrange_base() = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr __subrange_base(_Iter __iter, _Sent __sent, make_unsigned_t<iter_difference_t<_Iter>> = 0) + : __begin_(_VSTD::move(__iter)), __end_(__sent) { } + }; + + template<class _Iter, class _Sent> + struct __subrange_base<_Iter, _Sent, true> { + static constexpr bool __store_size = true; + _Iter __begin_ = _Iter(); + _Sent __end_ = _Sent(); + make_unsigned_t<iter_difference_t<_Iter>> __size_ = 0; + + _LIBCPP_HIDE_FROM_ABI + constexpr __subrange_base() = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr __subrange_base(_Iter __iter, _Sent __sent, decltype(__size_) __size) + : __begin_(_VSTD::move(__iter)), __end_(__sent), __size_(__size) { } + }; + + template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent = _Iter, + subrange_kind _Kind = sized_sentinel_for<_Sent, _Iter> + ? subrange_kind::sized + : subrange_kind::unsized> + requires (_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _Iter>) + struct _LIBCPP_TEMPLATE_VIS subrange + : public view_interface<subrange<_Iter, _Sent, _Kind>>, + private __subrange_base<_Iter, _Sent, _Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _Iter>> { + + using _Base = __subrange_base<_Iter, _Sent, _Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _Iter>>; + + _LIBCPP_HIDE_FROM_ABI + subrange() requires default_initializable<_Iter> = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr subrange(__convertible_to_non_slicing<_Iter> auto __iter, _Sent __sent) + requires (!_Base::__store_size) + : _Base(_VSTD::move(__iter), __sent) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr subrange(__convertible_to_non_slicing<_Iter> auto __iter, _Sent __sent, + make_unsigned_t<iter_difference_t<_Iter>> __n) + requires (_Kind == subrange_kind::sized) + : _Base(_VSTD::move(__iter), __sent, __n) { } + + template<__different_from<subrange> _Range> + requires borrowed_range<_Range> && + __convertible_to_non_slicing<iterator_t<_Range>, _Iter> && + convertible_to<sentinel_t<_Range>, _Sent> + _LIBCPP_HIDE_FROM_ABI + constexpr subrange(_Range&& __range) + requires (!_Base::__store_size) + : subrange(ranges::begin(__range), ranges::end(__range)) { } + + template<__different_from<subrange> _Range> + requires borrowed_range<_Range> && + __convertible_to_non_slicing<iterator_t<_Range>, _Iter> && + convertible_to<sentinel_t<_Range>, _Sent> + _LIBCPP_HIDE_FROM_ABI + constexpr subrange(_Range&& __range) + requires _Base::__store_size && sized_range<_Range> + : subrange(__range, ranges::size(__range)) { } + + + template<borrowed_range _Range> + requires __convertible_to_non_slicing<iterator_t<_Range>, _Iter> && + convertible_to<sentinel_t<_Range>, _Sent> + _LIBCPP_HIDE_FROM_ABI + constexpr subrange(_Range&& __range, make_unsigned_t<iter_difference_t<_Iter>> __n) + requires (_Kind == subrange_kind::sized) + : subrange(ranges::begin(__range), ranges::end(__range), __n) { } + + template<__different_from<subrange> _Pair> + requires __pair_like_convertible_from<_Pair, const _Iter&, const _Sent&> + _LIBCPP_HIDE_FROM_ABI + constexpr operator _Pair() const { return _Pair(this->__begin_, this->__end_); } + + _LIBCPP_HIDE_FROM_ABI + constexpr _Iter begin() const requires copyable<_Iter> { + return this->__begin_; + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter begin() requires (!copyable<_Iter>) { + return _VSTD::move(this->__begin_); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr _Sent end() const { return this->__end_; } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const { return this->__begin_ == this->__end_; } + + _LIBCPP_HIDE_FROM_ABI + constexpr make_unsigned_t<iter_difference_t<_Iter>> size() const + requires (_Kind == subrange_kind::sized) + { + if constexpr (_Base::__store_size) + return this->__size_; + else + return __to_unsigned_like(this->__end_ - this->__begin_); + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange next(iter_difference_t<_Iter> __n = 1) const& + requires forward_iterator<_Iter> { + auto __tmp = *this; + __tmp.advance(__n); + return __tmp; + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange next(iter_difference_t<_Iter> __n = 1) && { + advance(__n); + return _VSTD::move(*this); + } + + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr subrange prev(iter_difference_t<_Iter> __n = 1) const + requires bidirectional_iterator<_Iter> { + auto __tmp = *this; + __tmp.advance(-__n); + return __tmp; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr subrange& advance(iter_difference_t<_Iter> __n) { + if constexpr (bidirectional_iterator<_Iter>) { + if (__n < 0) { + ranges::advance(this->__begin_, __n); + if constexpr (_Base::__store_size) + this->__size_ += _VSTD::__to_unsigned_like(-__n); + return *this; + } + } + + auto __d = __n - ranges::advance(this->__begin_, __n, this->__end_); + if constexpr (_Base::__store_size) + this->__size_ -= _VSTD::__to_unsigned_like(__d); + return *this; + } + }; + + template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent> + subrange(_Iter, _Sent) -> subrange<_Iter, _Sent>; + + template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent> + subrange(_Iter, _Sent, make_unsigned_t<iter_difference_t<_Iter>>) + -> subrange<_Iter, _Sent, subrange_kind::sized>; + + template<borrowed_range _Range> + subrange(_Range&&) -> subrange<iterator_t<_Range>, sentinel_t<_Range>, + (sized_range<_Range> || sized_sentinel_for<sentinel_t<_Range>, iterator_t<_Range>>) + ? subrange_kind::sized : subrange_kind::unsized>; + + template<borrowed_range _Range> + subrange(_Range&&, make_unsigned_t<range_difference_t<_Range>>) + -> subrange<iterator_t<_Range>, sentinel_t<_Range>, subrange_kind::sized>; + + template<size_t _Index, class _Iter, class _Sent, subrange_kind _Kind> + requires (_Index < 2) + _LIBCPP_HIDE_FROM_ABI + constexpr auto get(const subrange<_Iter, _Sent, _Kind>& __subrange) { + if constexpr (_Index == 0) + return __subrange.begin(); + else + return __subrange.end(); + } + + template<size_t _Index, class _Iter, class _Sent, subrange_kind _Kind> + requires (_Index < 2) + _LIBCPP_HIDE_FROM_ABI + constexpr auto get(subrange<_Iter, _Sent, _Kind>&& __subrange) { + if constexpr (_Index == 0) + return __subrange.begin(); + else + return __subrange.end(); + } + + template<class _Ip, class _Sp, subrange_kind _Kp> + inline constexpr bool enable_borrowed_range<subrange<_Ip, _Sp, _Kp>> = true; + + template<range _Rp> + using borrowed_subrange_t = _If<borrowed_range<_Rp>, subrange<iterator_t<_Rp> >, dangling>; +} // namespace ranges + +using ranges::get; + +// clang-format off + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_SUBRANGE_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/transform_view.h b/contrib/llvm-project/libcxx/include/__ranges/transform_view.h new file mode 100644 index 000000000000..4243dc0366e9 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/transform_view.h @@ -0,0 +1,408 @@ +// -*- 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_TRANSFORM_VIEW_H +#define _LIBCPP___RANGES_TRANSFORM_VIEW_H + +#include <__config> +#include <__iterator/concepts.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/copyable_box.h> +#include <__ranges/empty.h> +#include <__ranges/size.h> +#include <__ranges/view_interface.h> +#include <concepts> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +namespace ranges { + +template<class _View, class _Fn> +concept __transform_view_constraints = + view<_View> && is_object_v<_Fn> && + regular_invocable<_Fn&, range_reference_t<_View>> && + __referenceable<invoke_result_t<_Fn&, range_reference_t<_View>>>; + +template<input_range _View, copy_constructible _Fn> + requires __transform_view_constraints<_View, _Fn> +class transform_view : public view_interface<transform_view<_View, _Fn>> { + template<bool> class __iterator; + template<bool> class __sentinel; + + [[no_unique_address]] __copyable_box<_Fn> __func_; + [[no_unique_address]] _View __base_ = _View(); + +public: + _LIBCPP_HIDE_FROM_ABI + transform_view() + requires default_initializable<_View> && default_initializable<_Fn> = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr transform_view(_View __base, _Fn __func) + : __func_(_VSTD::in_place, _VSTD::move(__func)), __base_(_VSTD::move(__base)) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr _View base() const& requires copy_constructible<_View> { return __base_; } + _LIBCPP_HIDE_FROM_ABI + constexpr _View base() && { return _VSTD::move(__base_); } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator<false> begin() { + return __iterator<false>{*this, ranges::begin(__base_)}; + } + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator<true> begin() const + requires range<const _View> && + regular_invocable<const _Fn&, range_reference_t<const _View>> + { + return __iterator<true>(*this, ranges::begin(__base_)); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __sentinel<false> end() { + return __sentinel<false>(ranges::end(__base_)); + } + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator<false> end() + requires common_range<_View> + { + return __iterator<false>(*this, ranges::end(__base_)); + } + _LIBCPP_HIDE_FROM_ABI + constexpr __sentinel<true> end() const + requires range<const _View> && + regular_invocable<const _Fn&, range_reference_t<const _View>> + { + return __sentinel<true>(ranges::end(__base_)); + } + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator<true> end() const + requires common_range<const _View> && + regular_invocable<const _Fn&, range_reference_t<const _View>> + { + return __iterator<true>(*this, ranges::end(__base_)); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr auto size() requires sized_range<_View> { return ranges::size(__base_); } + _LIBCPP_HIDE_FROM_ABI + constexpr auto size() const requires sized_range<const _View> { return ranges::size(__base_); } +}; + +template<class _Range, class _Fn> +transform_view(_Range&&, _Fn) -> transform_view<views::all_t<_Range>, _Fn>; + +template<class _View> +struct __transform_view_iterator_concept { using type = input_iterator_tag; }; + +template<random_access_range _View> +struct __transform_view_iterator_concept<_View> { using type = random_access_iterator_tag; }; + +template<bidirectional_range _View> +struct __transform_view_iterator_concept<_View> { using type = bidirectional_iterator_tag; }; + +template<forward_range _View> +struct __transform_view_iterator_concept<_View> { using type = forward_iterator_tag; }; + +template<class, class> +struct __transform_view_iterator_category_base {}; + +template<forward_range _View, class _Fn> +struct __transform_view_iterator_category_base<_View, _Fn> { + using _Cat = typename iterator_traits<iterator_t<_View>>::iterator_category; + + using iterator_category = conditional_t< + is_lvalue_reference_v<invoke_result_t<_Fn&, range_reference_t<_View>>>, + conditional_t< + derived_from<_Cat, contiguous_iterator_tag>, + random_access_iterator_tag, + _Cat + >, + input_iterator_tag + >; +}; + +template<input_range _View, copy_constructible _Fn> + requires __transform_view_constraints<_View, _Fn> +template<bool _Const> +class transform_view<_View, _Fn>::__iterator + : public __transform_view_iterator_category_base<_View, _Fn> { + + using _Parent = __maybe_const<_Const, transform_view>; + using _Base = __maybe_const<_Const, _View>; + + _Parent *__parent_ = nullptr; + + template<bool> + friend class transform_view<_View, _Fn>::__iterator; + + template<bool> + friend class transform_view<_View, _Fn>::__sentinel; + +public: + iterator_t<_Base> __current_ = iterator_t<_Base>(); + + using iterator_concept = typename __transform_view_iterator_concept<_View>::type; + using value_type = remove_cvref_t<invoke_result_t<_Fn&, range_reference_t<_Base>>>; + using difference_type = range_difference_t<_Base>; + + _LIBCPP_HIDE_FROM_ABI + __iterator() requires default_initializable<iterator_t<_Base>> = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator(_Parent& __parent, iterator_t<_Base> __current) + : __parent_(_VSTD::addressof(__parent)), __current_(_VSTD::move(__current)) {} + + // Note: `__i` should always be `__iterator<false>`, but directly using + // `__iterator<false>` is ill-formed when `_Const` is false + // (see http://wg21.link/class.copy.ctor#5). + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator(__iterator<!_Const> __i) + requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>> + : __parent_(__i.__parent_), __current_(_VSTD::move(__i.__current_)) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr iterator_t<_Base> base() const& + requires copyable<iterator_t<_Base>> + { + return __current_; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr iterator_t<_Base> base() && { + return _VSTD::move(__current_); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr decltype(auto) operator*() const + noexcept(noexcept(_VSTD::invoke(*__parent_->__func_, *__current_))) + { + return _VSTD::invoke(*__parent_->__func_, *__current_); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator& operator++() { + ++__current_; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr void operator++(int) { ++__current_; } + + _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> + { + --__current_; + 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 __n) + requires random_access_range<_Base> + { + __current_ += __n; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr __iterator& operator-=(difference_type __n) + requires random_access_range<_Base> + { + __current_ -= __n; + return *this; + } + + _LIBCPP_HIDE_FROM_ABI + constexpr decltype(auto) operator[](difference_type __n) const + noexcept(noexcept(_VSTD::invoke(*__parent_->__func_, __current_[__n]))) + requires random_access_range<_Base> + { + return _VSTD::invoke(*__parent_->__func_, __current_[__n]); + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) + requires equality_comparable<iterator_t<_Base>> + { + return __x.__current_ == __y.__current_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<(const __iterator& __x, const __iterator& __y) + requires random_access_range<_Base> + { + return __x.__current_ < __y.__current_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>(const __iterator& __x, const __iterator& __y) + requires random_access_range<_Base> + { + return __x.__current_ > __y.__current_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y) + requires random_access_range<_Base> + { + return __x.__current_ <= __y.__current_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y) + requires random_access_range<_Base> + { + return __x.__current_ >= __y.__current_; + } + +// TODO: Fix this as soon as soon as three_way_comparable is implemented. +// _LIBCPP_HIDE_FROM_ABI +// friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) +// requires random_access_range<_Base> && three_way_comparable<iterator_t<_Base>> +// { +// return __x.__current_ <=> __y.__current_; +// } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr __iterator operator+(__iterator __i, difference_type __n) + requires random_access_range<_Base> + { + return __iterator{*__i.__parent_, __i.__current_ + __n}; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr __iterator operator+(difference_type __n, __iterator __i) + requires random_access_range<_Base> + { + return __iterator{*__i.__parent_, __i.__current_ + __n}; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr __iterator operator-(__iterator __i, difference_type __n) + requires random_access_range<_Base> + { + return __iterator{*__i.__parent_, __i.__current_ - __n}; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) + requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>> + { + return __x.__current_ - __y.__current_; + } + + _LIBCPP_HIDE_FROM_ABI + friend constexpr decltype(auto) iter_move(const __iterator& __i) + noexcept(noexcept(*__i)) + { + if constexpr (is_lvalue_reference_v<decltype(*__i)>) + return _VSTD::move(*__i); + else + return *__i; + } +}; + +template<input_range _View, copy_constructible _Fn> + requires __transform_view_constraints<_View, _Fn> +template<bool _Const> +class transform_view<_View, _Fn>::__sentinel { + using _Parent = __maybe_const<_Const, transform_view>; + using _Base = __maybe_const<_Const, _View>; + + sentinel_t<_Base> __end_ = sentinel_t<_Base>(); + + template<bool> + friend class transform_view<_View, _Fn>::__iterator; + + template<bool> + friend class transform_view<_View, _Fn>::__sentinel; + +public: + _LIBCPP_HIDE_FROM_ABI + __sentinel() = default; + + _LIBCPP_HIDE_FROM_ABI + constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(__end) {} + + // Note: `__i` should always be `__sentinel<false>`, but directly using + // `__sentinel<false>` is ill-formed when `_Const` is false + // (see http://wg21.link/class.copy.ctor#5). + _LIBCPP_HIDE_FROM_ABI + constexpr __sentinel(__sentinel<!_Const> __i) + requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>> + : __end_(_VSTD::move(__i.__end_)) {} + + _LIBCPP_HIDE_FROM_ABI + constexpr sentinel_t<_Base> base() const { return __end_; } + + template<bool _OtherConst> + requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> + _LIBCPP_HIDE_FROM_ABI + friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) { + return __x.__current_ == __y.__end_; + } + + template<bool _OtherConst> + requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> + _LIBCPP_HIDE_FROM_ABI + friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>> + operator-(const __iterator<_OtherConst>& __x, const __sentinel& __y) { + return __x.__current_ - __y.__end_; + } + + template<bool _OtherConst> + requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>> + _LIBCPP_HIDE_FROM_ABI + friend constexpr range_difference_t<__maybe_const<_OtherConst, _View>> + operator-(const __sentinel& __x, const __iterator<_OtherConst>& __y) { + return __x.__end_ - __y.__current_; + } +}; + +} // namespace ranges + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_TRANSFORM_VIEW_H diff --git a/contrib/llvm-project/libcxx/include/__ranges/view_interface.h b/contrib/llvm-project/libcxx/include/__ranges/view_interface.h new file mode 100644 index 000000000000..62cc5fd24362 --- /dev/null +++ b/contrib/llvm-project/libcxx/include/__ranges/view_interface.h @@ -0,0 +1,198 @@ +// -*- 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_VIEW_INTERFACE_H +#define _LIBCPP___RANGES_VIEW_INTERFACE_H + +#include <__config> +#include <__iterator/concepts.h> +#include <__iterator/iterator_traits.h> +#include <__iterator/prev.h> +#include <__memory/pointer_traits.h> +#include <__ranges/access.h> +#include <__ranges/concepts.h> +#include <__ranges/empty.h> +#include <__ranges/enable_view.h> +#include <concepts> +#include <type_traits> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +#pragma GCC system_header +#endif + +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + +_LIBCPP_BEGIN_NAMESPACE_STD + +#if !defined(_LIBCPP_HAS_NO_RANGES) + +namespace ranges { + +template<class _Tp> +concept __can_empty = requires(_Tp __t) { ranges::empty(__t); }; + +template<class _Tp> +void __implicitly_convert_to(type_identity_t<_Tp>) noexcept; + +template<class _Derived> + requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>> +class view_interface : public view_base { + _LIBCPP_HIDE_FROM_ABI + constexpr _Derived& __derived() noexcept { + return static_cast<_Derived&>(*this); + } + + _LIBCPP_HIDE_FROM_ABI + constexpr _Derived const& __derived() const noexcept { + return static_cast<_Derived const&>(*this); + } + +public: + template<class _D2 = _Derived> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() + noexcept(noexcept(__implicitly_convert_to<bool>(ranges::begin(__derived()) == ranges::end(__derived())))) + requires forward_range<_D2> + { + return ranges::begin(__derived()) == ranges::end(__derived()); + } + + template<class _D2 = _Derived> + [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const + noexcept(noexcept(__implicitly_convert_to<bool>(ranges::begin(__derived()) == ranges::end(__derived())))) + requires forward_range<const _D2> + { + return ranges::begin(__derived()) == ranges::end(__derived()); + } + + template<class _D2 = _Derived> + _LIBCPP_HIDE_FROM_ABI + constexpr explicit operator bool() + noexcept(noexcept(ranges::empty(declval<_D2>()))) + requires __can_empty<_D2> + { + return !ranges::empty(__derived()); + } + + template<class _D2 = _Derived> + _LIBCPP_HIDE_FROM_ABI + constexpr explicit operator bool() const + noexcept(noexcept(ranges::empty(declval<const _D2>()))) + requires __can_empty<const _D2> + { + return !ranges::empty(__derived()); + } + + template<class _D2 = _Derived> + _LIBCPP_HIDE_FROM_ABI + constexpr auto data() + noexcept(noexcept(_VSTD::to_address(ranges::begin(__derived())))) + requires contiguous_iterator<iterator_t<_D2>> + { + return _VSTD::to_address(ranges::begin(__derived())); + } + + template<class _D2 = _Derived> + _LIBCPP_HIDE_FROM_ABI + constexpr auto data() const + noexcept(noexcept(_VSTD::to_address(ranges::begin(__derived())))) + requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>> + { + return _VSTD::to_address(ranges::begin(__derived())); + } + + template<class _D2 = _Derived> + _LIBCPP_HIDE_FROM_ABI + constexpr auto size() + noexcept(noexcept(ranges::end(__derived()) - ranges::begin(__derived()))) + requires forward_range<_D2> + && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>> + { + return ranges::end(__derived()) - ranges::begin(__derived()); + } + + template<class _D2 = _Derived> + _LIBCPP_HIDE_FROM_ABI + constexpr auto size() const + noexcept(noexcept(ranges::end(__derived()) - ranges::begin(__derived()))) + requires forward_range<const _D2> + && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>> + { + return ranges::end(__derived()) - ranges::begin(__derived()); + } + + template<class _D2 = _Derived> + _LIBCPP_HIDE_FROM_ABI + constexpr decltype(auto) front() + noexcept(noexcept(*ranges::begin(__derived()))) + requires forward_range<_D2> + { + _LIBCPP_ASSERT(!empty(), + "Precondition `!empty()` not satisfied. `.front()` called on an empty view."); + return *ranges::begin(__derived()); + } + + template<class _D2 = _Derived> + _LIBCPP_HIDE_FROM_ABI + constexpr decltype(auto) front() const + noexcept(noexcept(*ranges::begin(__derived()))) + requires forward_range<const _D2> + { + _LIBCPP_ASSERT(!empty(), + "Precondition `!empty()` not satisfied. `.front()` called on an empty view."); + return *ranges::begin(__derived()); + } + + template<class _D2 = _Derived> + _LIBCPP_HIDE_FROM_ABI + constexpr decltype(auto) back() + noexcept(noexcept(*ranges::prev(ranges::end(__derived())))) + requires bidirectional_range<_D2> && common_range<_D2> + { + _LIBCPP_ASSERT(!empty(), + "Precondition `!empty()` not satisfied. `.back()` called on an empty view."); + return *ranges::prev(ranges::end(__derived())); + } + + template<class _D2 = _Derived> + _LIBCPP_HIDE_FROM_ABI + constexpr decltype(auto) back() const + noexcept(noexcept(*ranges::prev(ranges::end(__derived())))) + requires bidirectional_range<const _D2> && common_range<const _D2> + { + _LIBCPP_ASSERT(!empty(), + "Precondition `!empty()` not satisfied. `.back()` called on an empty view."); + return *ranges::prev(ranges::end(__derived())); + } + + template<random_access_range _RARange = _Derived> + _LIBCPP_HIDE_FROM_ABI + constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) + noexcept(noexcept(ranges::begin(__derived())[__index])) + { + return ranges::begin(__derived())[__index]; + } + + template<random_access_range _RARange = const _Derived> + _LIBCPP_HIDE_FROM_ABI + constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const + noexcept(noexcept(ranges::begin(__derived())[__index])) + { + return ranges::begin(__derived())[__index]; + } +}; + +} + +#endif // !defined(_LIBCPP_HAS_NO_RANGES) + +_LIBCPP_END_NAMESPACE_STD + +_LIBCPP_POP_MACROS + +#endif // _LIBCPP___RANGES_VIEW_INTERFACE_H |