mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 23:08:31 +00:00
Release Cosmopolitan v3.6.0
This release is an atomic upgrade to GCC 14.1.0 with C23 and C++23
This commit is contained in:
parent
62ace3623a
commit
5660ec4741
1585 changed files with 117353 additions and 271644 deletions
222
third_party/libcxx/__ranges/access.h
vendored
222
third_party/libcxx/__ranges/access.h
vendored
|
@ -32,138 +32,119 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
template <class _Tp>
|
||||
concept __can_borrow =
|
||||
is_lvalue_reference_v<_Tp> || enable_borrowed_range<remove_cvref_t<_Tp>>;
|
||||
template <class _Tp>
|
||||
concept __can_borrow = is_lvalue_reference_v<_Tp> || enable_borrowed_range<remove_cvref_t<_Tp>>;
|
||||
} // namespace ranges
|
||||
|
||||
// [range.access.begin]
|
||||
|
||||
namespace ranges {
|
||||
namespace __begin {
|
||||
template <class _Tp>
|
||||
concept __member_begin =
|
||||
__can_borrow<_Tp> &&
|
||||
__workaround_52970<_Tp> &&
|
||||
requires(_Tp&& __t) {
|
||||
{ _LIBCPP_AUTO_CAST(__t.begin()) } -> input_or_output_iterator;
|
||||
};
|
||||
template <class _Tp>
|
||||
concept __member_begin = __can_borrow<_Tp> && requires(_Tp&& __t) {
|
||||
{ _LIBCPP_AUTO_CAST(__t.begin()) } -> input_or_output_iterator;
|
||||
};
|
||||
|
||||
void begin(auto&) = delete;
|
||||
void begin(const auto&) = delete;
|
||||
void begin() = delete;
|
||||
|
||||
template <class _Tp>
|
||||
concept __unqualified_begin =
|
||||
!__member_begin<_Tp> &&
|
||||
__can_borrow<_Tp> &&
|
||||
__class_or_enum<remove_cvref_t<_Tp>> &&
|
||||
requires(_Tp && __t) {
|
||||
template <class _Tp>
|
||||
concept __unqualified_begin =
|
||||
!__member_begin<_Tp> && __can_borrow<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {
|
||||
{ _LIBCPP_AUTO_CAST(begin(__t)) } -> input_or_output_iterator;
|
||||
};
|
||||
|
||||
struct __fn {
|
||||
template <class _Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[]) const noexcept
|
||||
requires (sizeof(_Tp) >= 0) // Disallow incomplete element types.
|
||||
{
|
||||
return __t + 0;
|
||||
}
|
||||
struct __fn {
|
||||
template <class _Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[]) const noexcept
|
||||
requires(sizeof(_Tp) >= 0) // Disallow incomplete element types.
|
||||
{
|
||||
return __t + 0;
|
||||
}
|
||||
|
||||
template <class _Tp, size_t _Np>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept
|
||||
requires (sizeof(_Tp) >= 0) // Disallow incomplete element types.
|
||||
{
|
||||
return __t + 0;
|
||||
}
|
||||
template <class _Tp, size_t _Np>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept
|
||||
requires(sizeof(_Tp) >= 0) // Disallow incomplete element types.
|
||||
{
|
||||
return __t + 0;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
requires __member_begin<_Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.begin())))
|
||||
{
|
||||
return _LIBCPP_AUTO_CAST(__t.begin());
|
||||
}
|
||||
template <class _Tp>
|
||||
requires __member_begin<_Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.begin()))) {
|
||||
return _LIBCPP_AUTO_CAST(__t.begin());
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
requires __unqualified_begin<_Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(begin(__t))))
|
||||
{
|
||||
return _LIBCPP_AUTO_CAST(begin(__t));
|
||||
}
|
||||
template <class _Tp>
|
||||
requires __unqualified_begin<_Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(begin(__t)))) {
|
||||
return _LIBCPP_AUTO_CAST(begin(__t));
|
||||
}
|
||||
|
||||
void operator()(auto&&) const = delete;
|
||||
};
|
||||
void operator()(auto&&) const = delete;
|
||||
};
|
||||
} // namespace __begin
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto begin = __begin::__fn{};
|
||||
inline constexpr auto begin = __begin::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
// [range.range]
|
||||
|
||||
namespace ranges {
|
||||
template <class _Tp>
|
||||
using iterator_t = decltype(ranges::begin(std::declval<_Tp&>()));
|
||||
template <class _Tp>
|
||||
using iterator_t = decltype(ranges::begin(std::declval<_Tp&>()));
|
||||
} // namespace ranges
|
||||
|
||||
// [range.access.end]
|
||||
|
||||
namespace ranges {
|
||||
namespace __end {
|
||||
template <class _Tp>
|
||||
concept __member_end =
|
||||
__can_borrow<_Tp> &&
|
||||
__workaround_52970<_Tp> &&
|
||||
requires(_Tp&& __t) {
|
||||
typename iterator_t<_Tp>;
|
||||
{ _LIBCPP_AUTO_CAST(__t.end()) } -> sentinel_for<iterator_t<_Tp>>;
|
||||
};
|
||||
template <class _Tp>
|
||||
concept __member_end = __can_borrow<_Tp> && requires(_Tp&& __t) {
|
||||
typename iterator_t<_Tp>;
|
||||
{ _LIBCPP_AUTO_CAST(__t.end()) } -> sentinel_for<iterator_t<_Tp>>;
|
||||
};
|
||||
|
||||
void end(auto&) = delete;
|
||||
void end(const auto&) = delete;
|
||||
void end() = delete;
|
||||
|
||||
template <class _Tp>
|
||||
concept __unqualified_end =
|
||||
!__member_end<_Tp> &&
|
||||
__can_borrow<_Tp> &&
|
||||
__class_or_enum<remove_cvref_t<_Tp>> &&
|
||||
requires(_Tp && __t) {
|
||||
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>;
|
||||
{ _LIBCPP_AUTO_CAST(end(__t)) } -> sentinel_for<iterator_t<_Tp>>;
|
||||
};
|
||||
|
||||
struct __fn {
|
||||
template <class _Tp, size_t _Np>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept
|
||||
requires (sizeof(_Tp) >= 0) // Disallow incomplete element types.
|
||||
{
|
||||
return __t + _Np;
|
||||
}
|
||||
struct __fn {
|
||||
template <class _Tp, size_t _Np>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept
|
||||
requires(sizeof(_Tp) >= 0) // Disallow incomplete element types.
|
||||
{
|
||||
return __t + _Np;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
requires __member_end<_Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.end())))
|
||||
{
|
||||
return _LIBCPP_AUTO_CAST(__t.end());
|
||||
}
|
||||
template <class _Tp>
|
||||
requires __member_end<_Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.end()))) {
|
||||
return _LIBCPP_AUTO_CAST(__t.end());
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
requires __unqualified_end<_Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(end(__t))))
|
||||
{
|
||||
return _LIBCPP_AUTO_CAST(end(__t));
|
||||
}
|
||||
template <class _Tp>
|
||||
requires __unqualified_end<_Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(end(__t)))) {
|
||||
return _LIBCPP_AUTO_CAST(end(__t));
|
||||
}
|
||||
|
||||
void operator()(auto&&) const = delete;
|
||||
};
|
||||
void operator()(auto&&) const = delete;
|
||||
};
|
||||
} // namespace __end
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto end = __end::__fn{};
|
||||
inline constexpr auto end = __end::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
|
@ -171,27 +152,27 @@ inline namespace __cpo {
|
|||
|
||||
namespace ranges {
|
||||
namespace __cbegin {
|
||||
struct __fn {
|
||||
template <class _Tp>
|
||||
requires is_lvalue_reference_v<_Tp&&>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Tp&& __t) const
|
||||
struct __fn {
|
||||
template <class _Tp>
|
||||
requires is_lvalue_reference_v<_Tp&&>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t))))
|
||||
-> decltype( ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t)))
|
||||
{ return ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t)); }
|
||||
-> decltype(ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t))) {
|
||||
return ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t));
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
requires is_rvalue_reference_v<_Tp&&>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Tp&& __t) const
|
||||
template <class _Tp>
|
||||
requires is_rvalue_reference_v<_Tp&&>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::begin(static_cast<const _Tp&&>(__t))))
|
||||
-> decltype( ranges::begin(static_cast<const _Tp&&>(__t)))
|
||||
{ return ranges::begin(static_cast<const _Tp&&>(__t)); }
|
||||
};
|
||||
-> decltype(ranges::begin(static_cast<const _Tp&&>(__t))) {
|
||||
return ranges::begin(static_cast<const _Tp&&>(__t));
|
||||
}
|
||||
};
|
||||
} // namespace __cbegin
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto cbegin = __cbegin::__fn{};
|
||||
inline constexpr auto cbegin = __cbegin::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
|
@ -199,27 +180,26 @@ inline namespace __cpo {
|
|||
|
||||
namespace ranges {
|
||||
namespace __cend {
|
||||
struct __fn {
|
||||
template <class _Tp>
|
||||
requires is_lvalue_reference_v<_Tp&&>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Tp&& __t) const
|
||||
struct __fn {
|
||||
template <class _Tp>
|
||||
requires is_lvalue_reference_v<_Tp&&>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t))))
|
||||
-> decltype( ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t)))
|
||||
{ return ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t)); }
|
||||
-> decltype(ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t))) {
|
||||
return ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t));
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
requires is_rvalue_reference_v<_Tp&&>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::end(static_cast<const _Tp&&>(__t))))
|
||||
-> decltype( ranges::end(static_cast<const _Tp&&>(__t)))
|
||||
{ return ranges::end(static_cast<const _Tp&&>(__t)); }
|
||||
};
|
||||
template <class _Tp>
|
||||
requires is_rvalue_reference_v<_Tp&&>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const noexcept(
|
||||
noexcept(ranges::end(static_cast<const _Tp&&>(__t)))) -> decltype(ranges::end(static_cast<const _Tp&&>(__t))) {
|
||||
return ranges::end(static_cast<const _Tp&&>(__t));
|
||||
}
|
||||
};
|
||||
} // namespace __cend
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto cend = __cend::__fn{};
|
||||
inline constexpr auto cend = __cend::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
|
|
58
third_party/libcxx/__ranges/all.h
vendored
58
third_party/libcxx/__ranges/all.h
vendored
|
@ -11,6 +11,8 @@
|
|||
#define _LIBCPP___RANGES_ALL_H
|
||||
|
||||
#include <__config>
|
||||
#include <__functional/compose.h> // TODO(modules): Those should not be required
|
||||
#include <__functional/perfect_forward.h> //
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__ranges/access.h>
|
||||
|
@ -34,45 +36,37 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
namespace ranges::views {
|
||||
|
||||
namespace __all {
|
||||
struct __fn : __range_adaptor_closure<__fn> {
|
||||
template<class _Tp>
|
||||
requires ranges::view<decay_t<_Tp>>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Tp>(__t))))
|
||||
-> decltype(_LIBCPP_AUTO_CAST(std::forward<_Tp>(__t)))
|
||||
{
|
||||
return _LIBCPP_AUTO_CAST(std::forward<_Tp>(__t));
|
||||
}
|
||||
struct __fn : __range_adaptor_closure<__fn> {
|
||||
template <class _Tp>
|
||||
requires ranges::view<decay_t<_Tp>>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const noexcept(
|
||||
noexcept(_LIBCPP_AUTO_CAST(std::forward<_Tp>(__t)))) -> decltype(_LIBCPP_AUTO_CAST(std::forward<_Tp>(__t))) {
|
||||
return _LIBCPP_AUTO_CAST(std::forward<_Tp>(__t));
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
requires (!ranges::view<decay_t<_Tp>>) &&
|
||||
requires (_Tp&& __t) { ranges::ref_view{std::forward<_Tp>(__t)}; }
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::ref_view{std::forward<_Tp>(__t)}))
|
||||
{
|
||||
return ranges::ref_view{std::forward<_Tp>(__t)};
|
||||
}
|
||||
template <class _Tp>
|
||||
requires(!ranges::view<decay_t<_Tp>>) && requires(_Tp&& __t) { ranges::ref_view{std::forward<_Tp>(__t)}; }
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::ref_view{std::forward<_Tp>(__t)})) {
|
||||
return ranges::ref_view{std::forward<_Tp>(__t)};
|
||||
}
|
||||
|
||||
template<class _Tp>
|
||||
requires (!ranges::view<decay_t<_Tp>> &&
|
||||
!requires (_Tp&& __t) { ranges::ref_view{std::forward<_Tp>(__t)}; } &&
|
||||
requires (_Tp&& __t) { ranges::owning_view{std::forward<_Tp>(__t)}; })
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::owning_view{std::forward<_Tp>(__t)}))
|
||||
{
|
||||
return ranges::owning_view{std::forward<_Tp>(__t)};
|
||||
}
|
||||
};
|
||||
template <class _Tp>
|
||||
requires(
|
||||
!ranges::view<decay_t<_Tp>> && !requires(_Tp&& __t) { ranges::ref_view{std::forward<_Tp>(__t)}; } &&
|
||||
requires(_Tp&& __t) { ranges::owning_view{std::forward<_Tp>(__t)}; })
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::owning_view{std::forward<_Tp>(__t)})) {
|
||||
return ranges::owning_view{std::forward<_Tp>(__t)};
|
||||
}
|
||||
};
|
||||
} // namespace __all
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto all = __all::__fn{};
|
||||
inline constexpr auto all = __all::__fn{};
|
||||
} // namespace __cpo
|
||||
|
||||
template<ranges::viewable_range _Range>
|
||||
template <ranges::viewable_range _Range>
|
||||
using all_t = decltype(views::all(std::declval<_Range>()));
|
||||
|
||||
} // namespace ranges::views
|
||||
|
|
21
third_party/libcxx/__ranges/as_rvalue_view.h
vendored
21
third_party/libcxx/__ranges/as_rvalue_view.h
vendored
|
@ -28,6 +28,9 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
#if _LIBCPP_STD_VER >= 23
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
@ -108,18 +111,18 @@ namespace views {
|
|||
namespace __as_rvalue {
|
||||
struct __fn : __range_adaptor_closure<__fn> {
|
||||
template <class _Range>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
|
||||
noexcept(noexcept(/**/ as_rvalue_view(std::forward<_Range>(__range))))
|
||||
-> decltype(/*--*/ as_rvalue_view(std::forward<_Range>(__range))) {
|
||||
return /*-------------*/ as_rvalue_view(std::forward<_Range>(__range));
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto
|
||||
operator()(_Range&& __range) noexcept(noexcept(as_rvalue_view(std::forward<_Range>(__range))))
|
||||
-> decltype(/*--------------------------*/ as_rvalue_view(std::forward<_Range>(__range))) {
|
||||
return /*---------------------------------*/ as_rvalue_view(std::forward<_Range>(__range));
|
||||
}
|
||||
|
||||
template <class _Range>
|
||||
requires same_as<range_rvalue_reference_t<_Range>, range_reference_t<_Range>>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
|
||||
noexcept(noexcept(/**/ views::all(std::forward<_Range>(__range))))
|
||||
-> decltype(/*--*/ views::all(std::forward<_Range>(__range))) {
|
||||
return /*-------------*/ views::all(std::forward<_Range>(__range));
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto
|
||||
operator()(_Range&& __range) noexcept(noexcept(views::all(std::forward<_Range>(__range))))
|
||||
-> decltype(/*--------------------------*/ views::all(std::forward<_Range>(__range))) {
|
||||
return /*---------------------------------*/ views::all(std::forward<_Range>(__range));
|
||||
}
|
||||
};
|
||||
} // namespace __as_rvalue
|
||||
|
@ -134,4 +137,6 @@ _LIBCPP_END_NAMESPACE_STD
|
|||
|
||||
#endif // _LIBCPP_STD_VER >= 23
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_AS_RVALUE_H
|
||||
|
|
235
third_party/libcxx/__ranges/chunk_by_view.h
vendored
Normal file
235
third_party/libcxx/__ranges/chunk_by_view.h
vendored
Normal file
|
@ -0,0 +1,235 @@
|
|||
// -*- 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_CHUNK_BY_VIEW_H
|
||||
#define _LIBCPP___RANGES_CHUNK_BY_VIEW_H
|
||||
|
||||
#include <__algorithm/ranges_adjacent_find.h>
|
||||
#include <__assert>
|
||||
#include <__concepts/constructible.h>
|
||||
#include <__config>
|
||||
#include <__functional/bind_back.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/default_sentinel.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/next.h>
|
||||
#include <__iterator/prev.h>
|
||||
#include <__memory/addressof.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/all.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/movable_box.h>
|
||||
#include <__ranges/non_propagating_cache.h>
|
||||
#include <__ranges/range_adaptor.h>
|
||||
#include <__ranges/reverse_view.h>
|
||||
#include <__ranges/subrange.h>
|
||||
#include <__ranges/view_interface.h>
|
||||
#include <__type_traits/conditional.h>
|
||||
#include <__type_traits/decay.h>
|
||||
#include <__type_traits/is_nothrow_constructible.h>
|
||||
#include <__type_traits/is_object.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <__utility/in_place.h>
|
||||
#include <__utility/move.h>
|
||||
|
||||
#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 >= 23
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <forward_range _View, indirect_binary_predicate<iterator_t<_View>, iterator_t<_View>> _Pred>
|
||||
requires view<_View> && is_object_v<_Pred>
|
||||
class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS chunk_by_view : public view_interface<chunk_by_view<_View, _Pred>> {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_;
|
||||
|
||||
// We cache the result of begin() to allow providing an amortized O(1).
|
||||
using _Cache = __non_propagating_cache<iterator_t<_View>>;
|
||||
_Cache __cached_begin_;
|
||||
|
||||
class __iterator;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> __find_next(iterator_t<_View> __current) {
|
||||
// Note: this duplicates a check in `optional` but provides a better error message.
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
|
||||
__pred_.__has_value(), "Trying to call __find_next() on a chunk_by_view that does not have a valid predicate.");
|
||||
auto __reversed_pred = [this]<class _Tp, class _Up>(_Tp&& __x, _Up&& __y) -> bool {
|
||||
return !std::invoke(*__pred_, std::forward<_Tp>(__x), std::forward<_Up>(__y));
|
||||
};
|
||||
return ranges::next(
|
||||
ranges::adjacent_find(__current, ranges::end(__base_), __reversed_pred), 1, ranges::end(__base_));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> __find_prev(iterator_t<_View> __current)
|
||||
requires bidirectional_range<_View>
|
||||
{
|
||||
// Attempting to decrement a begin iterator is a no-op (`__find_prev` would return the same argument given to it).
|
||||
_LIBCPP_ASSERT_PEDANTIC(__current != ranges::begin(__base_), "Trying to call __find_prev() on a begin iterator.");
|
||||
// Note: this duplicates a check in `optional` but provides a better error message.
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
|
||||
__pred_.__has_value(), "Trying to call __find_prev() on a chunk_by_view that does not have a valid predicate.");
|
||||
|
||||
auto __first = ranges::begin(__base_);
|
||||
reverse_view __reversed{subrange{__first, __current}};
|
||||
auto __reversed_pred = [this]<class _Tp, class _Up>(_Tp&& __x, _Up&& __y) -> bool {
|
||||
return !std::invoke(*__pred_, std::forward<_Up>(__y), std::forward<_Tp>(__x));
|
||||
};
|
||||
return ranges::prev(ranges::adjacent_find(__reversed, __reversed_pred).base(), 1, std::move(__first));
|
||||
}
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI chunk_by_view()
|
||||
requires default_initializable<_View> && default_initializable<_Pred>
|
||||
= default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit chunk_by_view(_View __base, _Pred __pred)
|
||||
: __base_(std::move(__base)), __pred_(in_place, std::move(__pred)) {}
|
||||
|
||||
_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 const _Pred& pred() const { return *__pred_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() {
|
||||
// Note: this duplicates a check in `optional` but provides a better error message.
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
|
||||
__pred_.__has_value(), "Trying to call begin() on a chunk_by_view that does not have a valid predicate.");
|
||||
|
||||
auto __first = ranges::begin(__base_);
|
||||
if (!__cached_begin_.__has_value()) {
|
||||
__cached_begin_.__emplace(__find_next(__first));
|
||||
}
|
||||
return {*this, std::move(__first), *__cached_begin_};
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto end() {
|
||||
if constexpr (common_range<_View>) {
|
||||
return __iterator{*this, ranges::end(__base_), ranges::end(__base_)};
|
||||
} else {
|
||||
return default_sentinel;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Range, class _Pred>
|
||||
chunk_by_view(_Range&&, _Pred) -> chunk_by_view<views::all_t<_Range>, _Pred>;
|
||||
|
||||
template <forward_range _View, indirect_binary_predicate<iterator_t<_View>, iterator_t<_View>> _Pred>
|
||||
requires view<_View> && is_object_v<_Pred>
|
||||
class chunk_by_view<_View, _Pred>::__iterator {
|
||||
friend chunk_by_view;
|
||||
|
||||
chunk_by_view* __parent_ = nullptr;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __current_ = iterator_t<_View>();
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __next_ = iterator_t<_View>();
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator(
|
||||
chunk_by_view& __parent, iterator_t<_View> __current, iterator_t<_View> __next)
|
||||
: __parent_(std::addressof(__parent)), __current_(__current), __next_(__next) {}
|
||||
|
||||
public:
|
||||
using value_type = subrange<iterator_t<_View>>;
|
||||
using difference_type = range_difference_t<_View>;
|
||||
using iterator_category = input_iterator_tag;
|
||||
using iterator_concept = conditional_t<bidirectional_range<_View>, bidirectional_iterator_tag, forward_iterator_tag>;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI __iterator() = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const {
|
||||
// If the iterator is at end, this would return an empty range which can be checked by the calling code and doesn't
|
||||
// necessarily lead to a bad access.
|
||||
_LIBCPP_ASSERT_PEDANTIC(__current_ != __next_, "Trying to dereference past-the-end chunk_by_view iterator.");
|
||||
return {__current_, __next_};
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
|
||||
// Attempting to increment an end iterator is a no-op (`__find_next` would return the same argument given to it).
|
||||
_LIBCPP_ASSERT_PEDANTIC(__current_ != __next_, "Trying to increment past end chunk_by_view iterator.");
|
||||
__current_ = __next_;
|
||||
__next_ = __parent_->__find_next(__current_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) {
|
||||
auto __tmp = *this;
|
||||
++*this;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
|
||||
requires bidirectional_range<_View>
|
||||
{
|
||||
__next_ = __current_;
|
||||
__current_ = __parent_->__find_prev(__next_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
|
||||
requires bidirectional_range<_View>
|
||||
{
|
||||
auto __tmp = *this;
|
||||
--*this;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) {
|
||||
return __x.__current_ == __y.__current_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, default_sentinel_t) {
|
||||
return __x.__current_ == __x.__next_;
|
||||
}
|
||||
};
|
||||
|
||||
namespace views {
|
||||
namespace __chunk_by {
|
||||
struct __fn {
|
||||
template <class _Range, class _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Pred&& __pred) const
|
||||
noexcept(noexcept(/**/ chunk_by_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred))))
|
||||
-> decltype(/*--*/ chunk_by_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred))) {
|
||||
return /*-------------*/ chunk_by_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred));
|
||||
}
|
||||
|
||||
template <class _Pred>
|
||||
requires constructible_from<decay_t<_Pred>, _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pred&& __pred) const
|
||||
noexcept(is_nothrow_constructible_v<decay_t<_Pred>, _Pred>) {
|
||||
return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pred>(__pred)));
|
||||
}
|
||||
};
|
||||
} // namespace __chunk_by
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto chunk_by = __chunk_by::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace views
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 23
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_CHUNK_BY_VIEW_H
|
90
third_party/libcxx/__ranges/common_view.h
vendored
90
third_party/libcxx/__ranges/common_view.h
vendored
|
@ -29,102 +29,106 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template<view _View>
|
||||
requires (!common_range<_View> && copyable<iterator_t<_View>>)
|
||||
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 common_view()
|
||||
requires default_initializable<_View>
|
||||
= default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit common_view(_View __v) : __base_(std::move(__v)) { }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit common_view(_View __v) : __base_(std::move(__v)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
|
||||
_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 _View base() && { return std::move(__base_); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto begin() {
|
||||
_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> {
|
||||
_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() {
|
||||
_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> {
|
||||
_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> {
|
||||
_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> {
|
||||
_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 _Range>
|
||||
common_view(_Range&&) -> common_view<views::all_t<_Range>>;
|
||||
|
||||
template<class _View>
|
||||
template <class _View>
|
||||
inline constexpr bool enable_borrowed_range<common_view<_View>> = enable_borrowed_range<_View>;
|
||||
|
||||
namespace views {
|
||||
namespace __common {
|
||||
struct __fn : __range_adaptor_closure<__fn> {
|
||||
template<class _Range>
|
||||
requires common_range<_Range>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __range) const
|
||||
noexcept(noexcept(views::all(std::forward<_Range>(__range))))
|
||||
-> decltype( views::all(std::forward<_Range>(__range)))
|
||||
{ return views::all(std::forward<_Range>(__range)); }
|
||||
struct __fn : __range_adaptor_closure<__fn> {
|
||||
template <class _Range>
|
||||
requires common_range<_Range>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const noexcept(
|
||||
noexcept(views::all(std::forward<_Range>(__range)))) -> decltype(views::all(std::forward<_Range>(__range))) {
|
||||
return views::all(std::forward<_Range>(__range));
|
||||
}
|
||||
|
||||
template<class _Range>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __range) const
|
||||
noexcept(noexcept(common_view{std::forward<_Range>(__range)}))
|
||||
-> decltype( common_view{std::forward<_Range>(__range)})
|
||||
{ return common_view{std::forward<_Range>(__range)}; }
|
||||
};
|
||||
template <class _Range>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const noexcept(noexcept(common_view{
|
||||
std::forward<_Range>(__range)})) -> decltype(common_view{std::forward<_Range>(__range)}) {
|
||||
return common_view{std::forward<_Range>(__range)};
|
||||
}
|
||||
};
|
||||
} // namespace __common
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto common = __common::__fn{};
|
||||
inline constexpr auto common = __common::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace views
|
||||
} // namespace ranges
|
||||
|
@ -133,4 +137,6 @@ inline namespace __cpo {
|
|||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_COMMON_VIEW_H
|
||||
|
|
126
third_party/libcxx/__ranges/concepts.h
vendored
126
third_party/libcxx/__ranges/concepts.h
vendored
|
@ -41,100 +41,92 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
|
||||
namespace ranges {
|
||||
|
||||
// [range.range]
|
||||
// [range.range]
|
||||
|
||||
template <class _Tp>
|
||||
concept range = requires(_Tp& __t) {
|
||||
ranges::begin(__t); // sometimes equality-preserving
|
||||
ranges::end(__t);
|
||||
};
|
||||
template <class _Tp>
|
||||
concept range = requires(_Tp& __t) {
|
||||
ranges::begin(__t); // sometimes equality-preserving
|
||||
ranges::end(__t);
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
|
||||
template <class _Tp>
|
||||
concept input_range = range<_Tp> && input_iterator<iterator_t<_Tp>>;
|
||||
|
||||
template<class _Range>
|
||||
concept borrowed_range = range<_Range> &&
|
||||
(is_lvalue_reference_v<_Range> || enable_borrowed_range<remove_cvref_t<_Range>>);
|
||||
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>
|
||||
// `iterator_t` defined in <__ranges/access.h>
|
||||
|
||||
template <range _Rp>
|
||||
using sentinel_t = decltype(ranges::end(std::declval<_Rp&>()));
|
||||
template <range _Rp>
|
||||
using sentinel_t = decltype(ranges::end(std::declval<_Rp&>()));
|
||||
|
||||
template <range _Rp>
|
||||
using range_difference_t = iter_difference_t<iterator_t<_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_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_reference_t = iter_reference_t<iterator_t<_Rp>>;
|
||||
|
||||
template <range _Rp>
|
||||
using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rp>>;
|
||||
template <range _Rp>
|
||||
using range_rvalue_reference_t = iter_rvalue_reference_t<iterator_t<_Rp>>;
|
||||
|
||||
template <range _Rp>
|
||||
using range_common_reference_t = iter_common_reference_t<iterator_t<_Rp>>;
|
||||
template <range _Rp>
|
||||
using range_common_reference_t = iter_common_reference_t<iterator_t<_Rp>>;
|
||||
|
||||
// [range.sized]
|
||||
template <class _Tp>
|
||||
concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); };
|
||||
// [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(std::declval<_Rp&>()));
|
||||
template <sized_range _Rp>
|
||||
using range_size_t = decltype(ranges::size(std::declval<_Rp&>()));
|
||||
|
||||
// `disable_sized_range` defined in `<__ranges/size.h>`
|
||||
// `disable_sized_range` defined in `<__ranges/size.h>`
|
||||
|
||||
// [range.view], views
|
||||
// [range.view], views
|
||||
|
||||
// `enable_view` defined in <__ranges/enable_view.h>
|
||||
// `view_base` defined in <__ranges/enable_view.h>
|
||||
// `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 _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>> &&
|
||||
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>, sentinel_t<const _Range>>;
|
||||
|
||||
// [range.refinements], other range refinements
|
||||
template <class _Rp, class _Tp>
|
||||
concept output_range = range<_Rp> && output_iterator<iterator_t<_Rp>, _Tp>;
|
||||
// [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 forward_range = input_range<_Tp> && forward_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 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 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 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 common_range = range<_Tp> && same_as<iterator_t<_Tp>, sentinel_t<_Tp>>;
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr bool __is_std_initializer_list = false;
|
||||
template <class _Tp>
|
||||
inline constexpr bool __is_std_initializer_list = false;
|
||||
|
||||
template <class _Ep>
|
||||
inline constexpr bool __is_std_initializer_list<initializer_list<_Ep>> = true;
|
||||
template <class _Ep>
|
||||
inline constexpr bool __is_std_initializer_list<initializer_list<_Ep>> = true;
|
||||
|
||||
template <class _Tp>
|
||||
concept viewable_range =
|
||||
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>> &&
|
||||
|
|
182
third_party/libcxx/__ranges/copyable_box.h
vendored
182
third_party/libcxx/__ranges/copyable_box.h
vendored
|
@ -1,182 +0,0 @@
|
|||
// -*- 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 <__concepts/constructible.h>
|
||||
#include <__concepts/copyable.h>
|
||||
#include <__concepts/movable.h>
|
||||
#include <__config>
|
||||
#include <__memory/addressof.h>
|
||||
#include <__memory/construct_at.h>
|
||||
#include <__type_traits/is_nothrow_constructible.h>
|
||||
#include <__type_traits/is_nothrow_copy_constructible.h>
|
||||
#include <__type_traits/is_nothrow_default_constructible.h>
|
||||
#include <__utility/move.h>
|
||||
#include <optional>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
// __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 {
|
||||
_LIBCPP_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, std::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 != std::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 != std::addressof(__other)) {
|
||||
if (__other.__has_value()) __val_.emplace(std::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 const _Tp *operator->() const noexcept { return __val_.operator->(); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Tp *operator->() noexcept { return __val_.operator->(); }
|
||||
|
||||
_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> {
|
||||
_LIBCPP_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_(std::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 != std::addressof(__other)) {
|
||||
std::destroy_at(std::addressof(__val_));
|
||||
std::construct_at(std::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 != std::addressof(__other)) {
|
||||
std::destroy_at(std::addressof(__val_));
|
||||
std::construct_at(std::addressof(__val_), std::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 const _Tp *operator->() const noexcept { return std::addressof(__val_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Tp *operator->() noexcept { return std::addressof(__val_); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; }
|
||||
};
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___RANGES_COPYABLE_BOX_H
|
60
third_party/libcxx/__ranges/counted.h
vendored
60
third_party/libcxx/__ranges/counted.h
vendored
|
@ -29,6 +29,9 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
@ -37,41 +40,42 @@ namespace ranges::views {
|
|||
|
||||
namespace __counted {
|
||||
|
||||
struct __fn {
|
||||
template<contiguous_iterator _It>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
static constexpr auto __go(_It __it, iter_difference_t<_It> __count)
|
||||
noexcept(noexcept(span(std::to_address(__it), static_cast<size_t>(__count))))
|
||||
// Deliberately omit return-type SFINAE, because to_address is not SFINAE-friendly
|
||||
{ return span(std::to_address(__it), static_cast<size_t>(__count)); }
|
||||
struct __fn {
|
||||
template <contiguous_iterator _It>
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr auto
|
||||
__go(_It __it,
|
||||
iter_difference_t<_It> __count) noexcept(noexcept(span(std::to_address(__it), static_cast<size_t>(__count))))
|
||||
// Deliberately omit return-type SFINAE, because to_address is not SFINAE-friendly
|
||||
{
|
||||
return span(std::to_address(__it), static_cast<size_t>(__count));
|
||||
}
|
||||
|
||||
template<random_access_iterator _It>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
static constexpr auto __go(_It __it, iter_difference_t<_It> __count)
|
||||
noexcept(noexcept(subrange(__it, __it + __count)))
|
||||
-> decltype( subrange(__it, __it + __count))
|
||||
{ return subrange(__it, __it + __count); }
|
||||
template <random_access_iterator _It>
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_It __it, iter_difference_t<_It> __count) noexcept(
|
||||
noexcept(subrange(__it, __it + __count))) -> decltype(subrange(__it, __it + __count)) {
|
||||
return subrange(__it, __it + __count);
|
||||
}
|
||||
|
||||
template<class _It>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
static constexpr auto __go(_It __it, iter_difference_t<_It> __count)
|
||||
noexcept(noexcept(subrange(counted_iterator(std::move(__it), __count), default_sentinel)))
|
||||
-> decltype( subrange(counted_iterator(std::move(__it), __count), default_sentinel))
|
||||
{ return subrange(counted_iterator(std::move(__it), __count), default_sentinel); }
|
||||
template <class _It>
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr auto __go(_It __it, iter_difference_t<_It> __count) noexcept(
|
||||
noexcept(subrange(counted_iterator(std::move(__it), __count), default_sentinel)))
|
||||
-> decltype(subrange(counted_iterator(std::move(__it), __count), default_sentinel)) {
|
||||
return subrange(counted_iterator(std::move(__it), __count), default_sentinel);
|
||||
}
|
||||
|
||||
template<class _It, convertible_to<iter_difference_t<_It>> _Diff>
|
||||
requires input_or_output_iterator<decay_t<_It>>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_It&& __it, _Diff&& __count) const
|
||||
template <class _It, convertible_to<iter_difference_t<_It>> _Diff>
|
||||
requires input_or_output_iterator<decay_t<_It>>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_It&& __it, _Diff&& __count) const
|
||||
noexcept(noexcept(__go(std::forward<_It>(__it), std::forward<_Diff>(__count))))
|
||||
-> decltype( __go(std::forward<_It>(__it), std::forward<_Diff>(__count)))
|
||||
{ return __go(std::forward<_It>(__it), std::forward<_Diff>(__count)); }
|
||||
};
|
||||
-> decltype(__go(std::forward<_It>(__it), std::forward<_Diff>(__count))) {
|
||||
return __go(std::forward<_It>(__it), std::forward<_Diff>(__count));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __counted
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto counted = __counted::__fn{};
|
||||
inline constexpr auto counted = __counted::__fn{};
|
||||
} // namespace __cpo
|
||||
|
||||
} // namespace ranges::views
|
||||
|
@ -80,4 +84,6 @@ inline namespace __cpo {
|
|||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_COUNTED_H
|
||||
|
|
84
third_party/libcxx/__ranges/data.h
vendored
84
third_party/libcxx/__ranges/data.h
vendored
|
@ -36,44 +36,35 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
|
||||
namespace ranges {
|
||||
namespace __data {
|
||||
template <class _Tp>
|
||||
concept __ptr_to_object = is_pointer_v<_Tp> && is_object_v<remove_pointer_t<_Tp>>;
|
||||
template <class _Tp>
|
||||
concept __ptr_to_object = is_pointer_v<_Tp> && is_object_v<remove_pointer_t<_Tp>>;
|
||||
|
||||
template <class _Tp>
|
||||
concept __member_data =
|
||||
__can_borrow<_Tp> &&
|
||||
__workaround_52970<_Tp> &&
|
||||
requires(_Tp&& __t) {
|
||||
{ _LIBCPP_AUTO_CAST(__t.data()) } -> __ptr_to_object;
|
||||
};
|
||||
template <class _Tp>
|
||||
concept __member_data = __can_borrow<_Tp> && requires(_Tp&& __t) {
|
||||
{ _LIBCPP_AUTO_CAST(__t.data()) } -> __ptr_to_object;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
concept __ranges_begin_invocable =
|
||||
!__member_data<_Tp> &&
|
||||
__can_borrow<_Tp> &&
|
||||
requires(_Tp&& __t) {
|
||||
{ ranges::begin(__t) } -> contiguous_iterator;
|
||||
};
|
||||
template <class _Tp>
|
||||
concept __ranges_begin_invocable = !__member_data<_Tp> && __can_borrow<_Tp> && requires(_Tp&& __t) {
|
||||
{ ranges::begin(__t) } -> contiguous_iterator;
|
||||
};
|
||||
|
||||
struct __fn {
|
||||
template <__member_data _Tp>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(__t.data())) {
|
||||
return __t.data();
|
||||
}
|
||||
struct __fn {
|
||||
template <__member_data _Tp>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const noexcept(noexcept(__t.data())) {
|
||||
return __t.data();
|
||||
}
|
||||
|
||||
template<__ranges_begin_invocable _Tp>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(std::to_address(ranges::begin(__t)))) {
|
||||
return std::to_address(ranges::begin(__t));
|
||||
}
|
||||
};
|
||||
template <__ranges_begin_invocable _Tp>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(std::to_address(ranges::begin(__t)))) {
|
||||
return std::to_address(ranges::begin(__t));
|
||||
}
|
||||
};
|
||||
} // namespace __data
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto data = __data::__fn{};
|
||||
inline constexpr auto data = __data::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
|
@ -81,27 +72,26 @@ inline namespace __cpo {
|
|||
|
||||
namespace ranges {
|
||||
namespace __cdata {
|
||||
struct __fn {
|
||||
template <class _Tp>
|
||||
requires is_lvalue_reference_v<_Tp&&>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Tp&& __t) const
|
||||
struct __fn {
|
||||
template <class _Tp>
|
||||
requires is_lvalue_reference_v<_Tp&&>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t))))
|
||||
-> decltype( ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t)))
|
||||
{ return ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t)); }
|
||||
-> decltype(ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t))) {
|
||||
return ranges::data(static_cast<const remove_reference_t<_Tp>&>(__t));
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
requires is_rvalue_reference_v<_Tp&&>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::data(static_cast<const _Tp&&>(__t))))
|
||||
-> decltype( ranges::data(static_cast<const _Tp&&>(__t)))
|
||||
{ return ranges::data(static_cast<const _Tp&&>(__t)); }
|
||||
};
|
||||
template <class _Tp>
|
||||
requires is_rvalue_reference_v<_Tp&&>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const noexcept(
|
||||
noexcept(ranges::data(static_cast<const _Tp&&>(__t)))) -> decltype(ranges::data(static_cast<const _Tp&&>(__t))) {
|
||||
return ranges::data(static_cast<const _Tp&&>(__t));
|
||||
}
|
||||
};
|
||||
} // namespace __cdata
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto cdata = __cdata::__fn{};
|
||||
inline constexpr auto cdata = __cdata::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
|
|
304
third_party/libcxx/__ranges/drop_view.h
vendored
304
third_party/libcxx/__ranges/drop_view.h
vendored
|
@ -30,6 +30,7 @@
|
|||
#include <__ranges/iota_view.h>
|
||||
#include <__ranges/non_propagating_cache.h>
|
||||
#include <__ranges/range_adaptor.h>
|
||||
#include <__ranges/repeat_view.h>
|
||||
#include <__ranges/size.h>
|
||||
#include <__ranges/subrange.h>
|
||||
#include <__ranges/view_interface.h>
|
||||
|
@ -55,89 +56,96 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
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>;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache();
|
||||
range_difference_t<_View> __count_ = 0;
|
||||
_View __base_ = _View();
|
||||
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>;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache();
|
||||
range_difference_t<_View> __count_ = 0;
|
||||
_View __base_ = _View();
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI drop_view() requires default_initializable<_View> = default;
|
||||
_LIBCPP_HIDE_FROM_ABI drop_view()
|
||||
requires default_initializable<_View>
|
||||
= default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 drop_view(_View __base, range_difference_t<_View> __count)
|
||||
: __count_(__count)
|
||||
, __base_(std::move(__base))
|
||||
{
|
||||
_LIBCPP_ASSERT(__count_ >= 0, "count must be greater than or equal to zero.");
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23
|
||||
drop_view(_View __base, range_difference_t<_View> __count)
|
||||
: __count_(__count), __base_(std::move(__base)) {
|
||||
_LIBCPP_ASSERT_UNCATEGORIZED(__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 std::move(__base_); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto begin()
|
||||
requires(!(__simple_view<_View> && random_access_range<const _View> && sized_range<const _View>))
|
||||
{
|
||||
if constexpr (random_access_range<_View> && sized_range<_View>) {
|
||||
const auto __dist = std::min(ranges::distance(__base_), __count_);
|
||||
return ranges::begin(__base_) + __dist;
|
||||
}
|
||||
if constexpr (_UseCache)
|
||||
if (__cached_begin_.__has_value())
|
||||
return *__cached_begin_;
|
||||
|
||||
_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_); }
|
||||
auto __tmp = ranges::next(ranges::begin(__base_), __count_, ranges::end(__base_));
|
||||
if constexpr (_UseCache)
|
||||
__cached_begin_.__emplace(__tmp);
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_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_;
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
|
||||
requires random_access_range<const _View> && sized_range<const _View>
|
||||
{
|
||||
const auto __dist = std::min(ranges::distance(__base_), __count_);
|
||||
return ranges::begin(__base_) + __dist;
|
||||
}
|
||||
|
||||
auto __tmp = ranges::next(ranges::begin(__base_), __count_, ranges::end(__base_));
|
||||
if constexpr (_UseCache)
|
||||
__cached_begin_.__emplace(__tmp);
|
||||
return __tmp;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto end()
|
||||
requires(!__simple_view<_View>)
|
||||
{
|
||||
return ranges::end(__base_);
|
||||
}
|
||||
|
||||
_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() const
|
||||
requires range<const _View>
|
||||
{
|
||||
return ranges::end(__base_);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto end()
|
||||
requires (!__simple_view<_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 end() const
|
||||
requires range<const _View>
|
||||
{ return ranges::end(__base_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto size()
|
||||
requires sized_range<_View>
|
||||
{
|
||||
return __size(*this);
|
||||
}
|
||||
|
||||
_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() const
|
||||
requires sized_range<const _View>
|
||||
{
|
||||
return __size(*this);
|
||||
}
|
||||
};
|
||||
|
||||
_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>
|
||||
template <class _Range>
|
||||
drop_view(_Range&&, range_difference_t<_Range>) -> drop_view<views::all_t<_Range>>;
|
||||
|
||||
template<class _Tp>
|
||||
template <class _Tp>
|
||||
inline constexpr bool enable_borrowed_range<drop_view<_Tp>> = enable_borrowed_range<_Tp>;
|
||||
|
||||
namespace views {
|
||||
|
@ -202,103 +210,111 @@ struct __fn {
|
|||
// [range.drop.overview]: the `empty_view` case.
|
||||
template <class _Range, convertible_to<range_difference_t<_Range>> _Np>
|
||||
requires __is_empty_view<remove_cvref_t<_Range>>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __range, _Np&&) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range))))
|
||||
-> decltype( _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)))
|
||||
{ return _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)); }
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&&) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range))))
|
||||
-> decltype(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range))) {
|
||||
return _LIBCPP_AUTO_CAST(std::forward<_Range>(__range));
|
||||
}
|
||||
|
||||
// [range.drop.overview]: the `span | basic_string_view | iota_view | subrange (StoreSize == false)` case.
|
||||
template <class _Range,
|
||||
convertible_to<range_difference_t<_Range>> _Np,
|
||||
class _RawRange = remove_cvref_t<_Range>,
|
||||
class _Dist = range_difference_t<_Range>>
|
||||
requires (!__is_empty_view<_RawRange> &&
|
||||
random_access_range<_RawRange> &&
|
||||
sized_range<_RawRange> &&
|
||||
__is_passthrough_specialization<_RawRange>)
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __rng, _Np&& __n) const
|
||||
noexcept(noexcept(__passthrough_type_t<_RawRange>(
|
||||
ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)),
|
||||
ranges::end(__rng)
|
||||
)))
|
||||
-> decltype( __passthrough_type_t<_RawRange>(
|
||||
// Note: deliberately not forwarding `__rng` to guard against double moves.
|
||||
ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)),
|
||||
ranges::end(__rng)
|
||||
))
|
||||
{ return __passthrough_type_t<_RawRange>(
|
||||
ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)),
|
||||
ranges::end(__rng)
|
||||
); }
|
||||
class _Dist = range_difference_t<_Range>>
|
||||
requires(!__is_empty_view<_RawRange> && random_access_range<_RawRange> && sized_range<_RawRange> &&
|
||||
__is_passthrough_specialization<_RawRange>)
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __rng, _Np&& __n) const
|
||||
noexcept(noexcept(__passthrough_type_t<_RawRange>(
|
||||
ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)), ranges::end(__rng))))
|
||||
-> decltype(__passthrough_type_t<_RawRange>(
|
||||
// Note: deliberately not forwarding `__rng` to guard against double moves.
|
||||
ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)),
|
||||
ranges::end(__rng))) {
|
||||
return __passthrough_type_t<_RawRange>(
|
||||
ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)), ranges::end(__rng));
|
||||
}
|
||||
|
||||
// [range.drop.overview]: the `subrange (StoreSize == true)` case.
|
||||
template <class _Range,
|
||||
convertible_to<range_difference_t<_Range>> _Np,
|
||||
class _RawRange = remove_cvref_t<_Range>,
|
||||
class _Dist = range_difference_t<_Range>>
|
||||
requires (!__is_empty_view<_RawRange> &&
|
||||
random_access_range<_RawRange> &&
|
||||
sized_range<_RawRange> &&
|
||||
__is_subrange_specialization_with_store_size<_RawRange>)
|
||||
class _Dist = range_difference_t<_Range>>
|
||||
requires(!__is_empty_view<_RawRange> && random_access_range<_RawRange> && sized_range<_RawRange> &&
|
||||
__is_subrange_specialization_with_store_size<_RawRange>)
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __rng, _Np&& __n) const noexcept(noexcept(
|
||||
_RawRange(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)),
|
||||
ranges::end(__rng),
|
||||
std::__to_unsigned_like(ranges::distance(__rng) -
|
||||
std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))))))
|
||||
-> decltype(_RawRange(
|
||||
// Note: deliberately not forwarding `__rng` to guard against double moves.
|
||||
ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)),
|
||||
ranges::end(__rng),
|
||||
std::__to_unsigned_like(ranges::distance(__rng) -
|
||||
std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))))) {
|
||||
// Introducing local variables avoids calculating `min` and `distance` twice (at the cost of diverging from the
|
||||
// expression used in the `noexcept` clause and the return statement).
|
||||
auto __dist = ranges::distance(__rng);
|
||||
auto __clamped = std::min<_Dist>(__dist, std::forward<_Np>(__n));
|
||||
return _RawRange(ranges::begin(__rng) + __clamped, ranges::end(__rng), std::__to_unsigned_like(__dist - __clamped));
|
||||
}
|
||||
// clang-format off
|
||||
#if _LIBCPP_STD_VER >= 23
|
||||
// [range.drop.overview]: the `repeat_view` "_RawRange models sized_range" case.
|
||||
template <class _Range,
|
||||
convertible_to<range_difference_t<_Range>> _Np,
|
||||
class _RawRange = remove_cvref_t<_Range>,
|
||||
class _Dist = range_difference_t<_Range>>
|
||||
requires (__is_repeat_specialization<_RawRange> && sized_range<_RawRange>)
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const
|
||||
noexcept(noexcept(views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n)))))
|
||||
-> decltype( views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))))
|
||||
{ return views::repeat(*__range.__value_, ranges::distance(__range) - std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))); }
|
||||
|
||||
// [range.drop.overview]: the `repeat_view` "otherwise" case.
|
||||
template <class _Range,
|
||||
convertible_to<range_difference_t<_Range>> _Np,
|
||||
class _RawRange = remove_cvref_t<_Range>,
|
||||
class _Dist = range_difference_t<_Range>>
|
||||
requires (__is_repeat_specialization<_RawRange> && !sized_range<_RawRange>)
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __rng, _Np&& __n) const
|
||||
noexcept(noexcept(_RawRange(
|
||||
ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)),
|
||||
ranges::end(__rng),
|
||||
std::__to_unsigned_like(ranges::distance(__rng) -
|
||||
std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))
|
||||
)))
|
||||
-> decltype( _RawRange(
|
||||
// Note: deliberately not forwarding `__rng` to guard against double moves.
|
||||
ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)),
|
||||
ranges::end(__rng),
|
||||
std::__to_unsigned_like(ranges::distance(__rng) -
|
||||
std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))
|
||||
))
|
||||
{
|
||||
// Introducing local variables avoids calculating `min` and `distance` twice (at the cost of diverging from the
|
||||
// expression used in the `noexcept` clause and the return statement).
|
||||
auto __dist = ranges::distance(__rng);
|
||||
auto __clamped = std::min<_Dist>(__dist, std::forward<_Np>(__n));
|
||||
return _RawRange(
|
||||
ranges::begin(__rng) + __clamped,
|
||||
ranges::end(__rng),
|
||||
std::__to_unsigned_like(__dist - __clamped)
|
||||
);}
|
||||
constexpr auto operator()(_Range&& __range, _Np&&) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range))))
|
||||
-> decltype( _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)))
|
||||
{ return _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)); }
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
// [range.drop.overview]: the "otherwise" case.
|
||||
template <class _Range, convertible_to<range_difference_t<_Range>> _Np,
|
||||
class _RawRange = remove_cvref_t<_Range>>
|
||||
// Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other
|
||||
// overloads.
|
||||
requires (!(__is_empty_view<_RawRange> ||
|
||||
(__is_subrange_specialization_with_store_size<_RawRange> &&
|
||||
sized_range<_RawRange> &&
|
||||
template <class _Range, convertible_to<range_difference_t<_Range>> _Np, class _RawRange = remove_cvref_t<_Range>>
|
||||
// Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other
|
||||
// overloads.
|
||||
requires(!(__is_empty_view<_RawRange> ||
|
||||
# if _LIBCPP_STD_VER >= 23
|
||||
__is_repeat_specialization<_RawRange> ||
|
||||
# endif
|
||||
(__is_subrange_specialization_with_store_size<_RawRange> && sized_range<_RawRange> &&
|
||||
random_access_range<_RawRange>) ||
|
||||
(__is_passthrough_specialization<_RawRange> &&
|
||||
sized_range<_RawRange> &&
|
||||
random_access_range<_RawRange>)
|
||||
))
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __range, _Np&& __n) const
|
||||
noexcept(noexcept(drop_view(std::forward<_Range>(__range), std::forward<_Np>(__n))))
|
||||
-> decltype( drop_view(std::forward<_Range>(__range), std::forward<_Np>(__n)))
|
||||
{ return drop_view(std::forward<_Range>(__range), std::forward<_Np>(__n)); }
|
||||
(__is_passthrough_specialization<_RawRange> && sized_range<_RawRange> &&
|
||||
random_access_range<_RawRange>)))
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const
|
||||
noexcept(noexcept(drop_view(std::forward<_Range>(__range), std::forward<_Np>(__n))))
|
||||
-> decltype(drop_view(std::forward<_Range>(__range), std::forward<_Np>(__n))) {
|
||||
return drop_view(std::forward<_Range>(__range), std::forward<_Np>(__n));
|
||||
}
|
||||
|
||||
template <class _Np>
|
||||
requires constructible_from<decay_t<_Np>, _Np>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Np&& __n) const
|
||||
noexcept(is_nothrow_constructible_v<decay_t<_Np>, _Np>)
|
||||
{ return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Np>(__n))); }
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Np&& __n) const
|
||||
noexcept(is_nothrow_constructible_v<decay_t<_Np>, _Np>) {
|
||||
return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Np>(__n)));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __drop
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto drop = __drop::__fn{};
|
||||
inline constexpr auto drop = __drop::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace views
|
||||
|
||||
|
|
19
third_party/libcxx/__ranges/drop_while_view.h
vendored
19
third_party/libcxx/__ranges/drop_while_view.h
vendored
|
@ -20,8 +20,8 @@
|
|||
#include <__ranges/access.h>
|
||||
#include <__ranges/all.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/copyable_box.h>
|
||||
#include <__ranges/enable_borrowed_range.h>
|
||||
#include <__ranges/movable_box.h>
|
||||
#include <__ranges/non_propagating_cache.h>
|
||||
#include <__ranges/range_adaptor.h>
|
||||
#include <__ranges/view_interface.h>
|
||||
|
@ -37,6 +37,9 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
@ -45,7 +48,7 @@ namespace ranges {
|
|||
|
||||
template <view _View, class _Pred>
|
||||
requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate<const _Pred, iterator_t<_View>>
|
||||
class drop_while_view : public view_interface<drop_while_view<_View, _Pred>> {
|
||||
class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS drop_while_view : public view_interface<drop_while_view<_View, _Pred>> {
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI drop_while_view()
|
||||
requires default_initializable<_View> && default_initializable<_Pred>
|
||||
|
@ -65,9 +68,11 @@ public:
|
|||
_LIBCPP_HIDE_FROM_ABI constexpr const _Pred& pred() const { return *__pred_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto begin() {
|
||||
_LIBCPP_ASSERT(__pred_.__has_value(),
|
||||
"drop_while_view needs to have a non-empty predicate before calling begin() -- did a previous "
|
||||
"assignment to this drop_while_view fail?");
|
||||
// Note: this duplicates a check in `optional` but provides a better error message.
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
|
||||
__pred_.__has_value(),
|
||||
"drop_while_view needs to have a non-empty predicate before calling begin() -- did a previous "
|
||||
"assignment to this drop_while_view fail?");
|
||||
if constexpr (_UseCache) {
|
||||
if (!__cached_begin_.__has_value()) {
|
||||
__cached_begin_.__emplace(ranges::find_if_not(__base_, std::cref(*__pred_)));
|
||||
|
@ -82,7 +87,7 @@ public:
|
|||
|
||||
private:
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_;
|
||||
|
||||
static constexpr bool _UseCache = forward_range<_View>;
|
||||
using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
|
||||
|
@ -126,4 +131,6 @@ inline constexpr auto drop_while = __drop_while::__fn{};
|
|||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_DROP_WHILE_VIEW_H
|
||||
|
|
7
third_party/libcxx/__ranges/elements_view.h
vendored
7
third_party/libcxx/__ranges/elements_view.h
vendored
|
@ -16,7 +16,7 @@
|
|||
#include <__concepts/derived_from.h>
|
||||
#include <__concepts/equality_comparable.h>
|
||||
#include <__config>
|
||||
#include <__fwd/get.h>
|
||||
#include <__fwd/complex.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__ranges/access.h>
|
||||
|
@ -43,6 +43,9 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
@ -410,4 +413,6 @@ inline constexpr auto values = elements<1>;
|
|||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_ELEMENTS_VIEW_H
|
||||
|
|
61
third_party/libcxx/__ranges/empty.h
vendored
61
third_party/libcxx/__ranges/empty.h
vendored
|
@ -28,50 +28,39 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
|
||||
namespace ranges {
|
||||
namespace __empty {
|
||||
template <class _Tp>
|
||||
concept __member_empty =
|
||||
__workaround_52970<_Tp> &&
|
||||
requires(_Tp&& __t) {
|
||||
bool(__t.empty());
|
||||
};
|
||||
template <class _Tp>
|
||||
concept __member_empty = requires(_Tp&& __t) { bool(__t.empty()); };
|
||||
|
||||
template<class _Tp>
|
||||
concept __can_invoke_size =
|
||||
!__member_empty<_Tp> &&
|
||||
requires(_Tp&& __t) { ranges::size(__t); };
|
||||
template <class _Tp>
|
||||
concept __can_invoke_size = !__member_empty<_Tp> && requires(_Tp&& __t) { ranges::size(__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;
|
||||
};
|
||||
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 bool(__t.empty());
|
||||
}
|
||||
struct __fn {
|
||||
template <__member_empty _Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const noexcept(noexcept(bool(__t.empty()))) {
|
||||
return bool(__t.empty());
|
||||
}
|
||||
|
||||
template <__can_invoke_size _Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::size(__t))) {
|
||||
return ranges::size(__t) == 0;
|
||||
}
|
||||
template <__can_invoke_size _Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool operator()(_Tp&& __t) const noexcept(noexcept(ranges::size(__t))) {
|
||||
return ranges::size(__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);
|
||||
}
|
||||
};
|
||||
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);
|
||||
}
|
||||
};
|
||||
} // namespace __empty
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto empty = __empty::__fn{};
|
||||
inline constexpr auto empty = __empty::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
|
|
32
third_party/libcxx/__ranges/empty_view.h
vendored
32
third_party/libcxx/__ranges/empty_view.h
vendored
|
@ -25,26 +25,26 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
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; }
|
||||
};
|
||||
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; }
|
||||
};
|
||||
|
||||
template<class _Tp>
|
||||
inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
|
||||
template <class _Tp>
|
||||
inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;
|
||||
|
||||
namespace views {
|
||||
namespace views {
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr empty_view<_Tp> empty{};
|
||||
template <class _Tp>
|
||||
inline constexpr empty_view<_Tp> empty{};
|
||||
|
||||
} // namespace views
|
||||
} // namespace views
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
|
11
third_party/libcxx/__ranges/enable_view.h
vendored
11
third_party/libcxx/__ranges/enable_view.h
vendored
|
@ -27,19 +27,20 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
|
||||
namespace ranges {
|
||||
|
||||
struct view_base { };
|
||||
struct view_base {};
|
||||
|
||||
template<class _Derived>
|
||||
template <class _Derived>
|
||||
requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
|
||||
class view_interface;
|
||||
|
||||
template<class _Op, class _Yp>
|
||||
template <class _Op, class _Yp>
|
||||
requires is_convertible_v<_Op*, view_interface<_Yp>*>
|
||||
void __is_derived_from_view_interface(const _Op*, const view_interface<_Yp>*);
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr bool enable_view = derived_from<_Tp, view_base> ||
|
||||
requires { ranges::__is_derived_from_view_interface((_Tp*)nullptr, (_Tp*)nullptr); };
|
||||
inline constexpr bool enable_view = derived_from<_Tp, view_base> || requires {
|
||||
ranges::__is_derived_from_view_interface((_Tp*)nullptr, (_Tp*)nullptr);
|
||||
};
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
|
|
333
third_party/libcxx/__ranges/filter_view.h
vendored
333
third_party/libcxx/__ranges/filter_view.h
vendored
|
@ -11,12 +11,12 @@
|
|||
#define _LIBCPP___RANGES_FILTER_VIEW_H
|
||||
|
||||
#include <__algorithm/ranges_find_if.h>
|
||||
#include <__assert>
|
||||
#include <__concepts/constructible.h>
|
||||
#include <__concepts/copyable.h>
|
||||
#include <__concepts/derived_from.h>
|
||||
#include <__concepts/equality_comparable.h>
|
||||
#include <__config>
|
||||
#include <__debug>
|
||||
#include <__functional/bind_back.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__functional/reference_wrapper.h>
|
||||
|
@ -28,7 +28,7 @@
|
|||
#include <__ranges/access.h>
|
||||
#include <__ranges/all.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/copyable_box.h>
|
||||
#include <__ranges/movable_box.h>
|
||||
#include <__ranges/non_propagating_cache.h>
|
||||
#include <__ranges/range_adaptor.h>
|
||||
#include <__ranges/view_interface.h>
|
||||
|
@ -44,215 +44,208 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
|
||||
requires view<_View> && is_object_v<_Pred>
|
||||
class filter_view : public view_interface<filter_view<_View, _Pred>> {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
|
||||
template <input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
|
||||
requires view<_View> && is_object_v<_Pred>
|
||||
class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS filter_view : public view_interface<filter_view<_View, _Pred>> {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_;
|
||||
|
||||
// We cache the result of begin() to allow providing an amortized O(1) begin() whenever
|
||||
// the underlying range is at least a forward_range.
|
||||
static constexpr bool _UseCache = forward_range<_View>;
|
||||
using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache();
|
||||
// We cache the result of begin() to allow providing an amortized O(1) begin() whenever
|
||||
// the underlying range is at least a forward_range.
|
||||
static constexpr bool _UseCache = forward_range<_View>;
|
||||
using _Cache = _If<_UseCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache();
|
||||
|
||||
class __iterator;
|
||||
class __sentinel;
|
||||
class __iterator;
|
||||
class __sentinel;
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
filter_view() requires default_initializable<_View> && default_initializable<_Pred> = default;
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI filter_view()
|
||||
requires default_initializable<_View> && default_initializable<_Pred>
|
||||
= default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 filter_view(_View __base, _Pred __pred)
|
||||
: __base_(std::move(__base)), __pred_(in_place, std::move(__pred)) {}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 filter_view(_View __base, _Pred __pred)
|
||||
: __base_(std::move(__base)), __pred_(in_place, std::move(__pred)) {}
|
||||
|
||||
template<class _Vp = _View>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _View base() const& requires copy_constructible<_Vp> { return __base_; }
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _View base() && { return std::move(__base_); }
|
||||
template <class _Vp = _View>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
|
||||
requires copy_constructible<_Vp>
|
||||
{
|
||||
return __base_;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _Pred const& pred() const { return *__pred_; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Pred const& pred() const { return *__pred_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator begin() {
|
||||
_LIBCPP_ASSERT(__pred_.__has_value(), "Trying to call begin() on a filter_view that does not have a valid predicate.");
|
||||
if constexpr (_UseCache) {
|
||||
if (!__cached_begin_.__has_value()) {
|
||||
__cached_begin_.__emplace(ranges::find_if(__base_, std::ref(*__pred_)));
|
||||
}
|
||||
return {*this, *__cached_begin_};
|
||||
} else {
|
||||
return {*this, ranges::find_if(__base_, std::ref(*__pred_))};
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() {
|
||||
// Note: this duplicates a check in `optional` but provides a better error message.
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
|
||||
__pred_.__has_value(), "Trying to call begin() on a filter_view that does not have a valid predicate.");
|
||||
if constexpr (_UseCache) {
|
||||
if (!__cached_begin_.__has_value()) {
|
||||
__cached_begin_.__emplace(ranges::find_if(__base_, std::ref(*__pred_)));
|
||||
}
|
||||
return {*this, *__cached_begin_};
|
||||
} else {
|
||||
return {*this, ranges::find_if(__base_, std::ref(*__pred_))};
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto end() {
|
||||
if constexpr (common_range<_View>)
|
||||
return __iterator{*this, ranges::end(__base_)};
|
||||
else
|
||||
return __sentinel{*this};
|
||||
}
|
||||
};
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto end() {
|
||||
if constexpr (common_range<_View>)
|
||||
return __iterator{*this, ranges::end(__base_)};
|
||||
else
|
||||
return __sentinel{*this};
|
||||
}
|
||||
};
|
||||
|
||||
template<class _Range, class _Pred>
|
||||
filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
|
||||
template <class _Range, class _Pred>
|
||||
filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;
|
||||
|
||||
template<class _View>
|
||||
struct __filter_iterator_category { };
|
||||
template <class _View>
|
||||
struct __filter_iterator_category {};
|
||||
|
||||
template<forward_range _View>
|
||||
struct __filter_iterator_category<_View> {
|
||||
using _Cat = typename iterator_traits<iterator_t<_View>>::iterator_category;
|
||||
using iterator_category =
|
||||
_If<derived_from<_Cat, bidirectional_iterator_tag>, bidirectional_iterator_tag,
|
||||
_If<derived_from<_Cat, forward_iterator_tag>, forward_iterator_tag,
|
||||
/* else */ _Cat
|
||||
>>;
|
||||
};
|
||||
template <forward_range _View>
|
||||
struct __filter_iterator_category<_View> {
|
||||
using _Cat = typename iterator_traits<iterator_t<_View>>::iterator_category;
|
||||
using iterator_category =
|
||||
_If<derived_from<_Cat, bidirectional_iterator_tag>,
|
||||
bidirectional_iterator_tag,
|
||||
_If<derived_from<_Cat, forward_iterator_tag>,
|
||||
forward_iterator_tag,
|
||||
/* else */ _Cat >>;
|
||||
};
|
||||
|
||||
template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
|
||||
requires view<_View> && is_object_v<_Pred>
|
||||
class filter_view<_View, _Pred>::__iterator : public __filter_iterator_category<_View> {
|
||||
template <input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
|
||||
requires view<_View> && is_object_v<_Pred>
|
||||
class filter_view<_View, _Pred>::__iterator : public __filter_iterator_category<_View> {
|
||||
public:
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __current_ = iterator_t<_View>();
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS filter_view* __parent_ = nullptr;
|
||||
|
||||
public:
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS iterator_t<_View> __current_ = iterator_t<_View>();
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS filter_view* __parent_ = nullptr;
|
||||
using iterator_concept =
|
||||
_If<bidirectional_range<_View>,
|
||||
bidirectional_iterator_tag,
|
||||
_If<forward_range<_View>,
|
||||
forward_iterator_tag,
|
||||
/* else */ input_iterator_tag >>;
|
||||
// using iterator_category = inherited;
|
||||
using value_type = range_value_t<_View>;
|
||||
using difference_type = range_difference_t<_View>;
|
||||
|
||||
using iterator_concept =
|
||||
_If<bidirectional_range<_View>, bidirectional_iterator_tag,
|
||||
_If<forward_range<_View>, forward_iterator_tag,
|
||||
/* else */ input_iterator_tag
|
||||
>>;
|
||||
// using iterator_category = inherited;
|
||||
using value_type = range_value_t<_View>;
|
||||
using difference_type = range_difference_t<_View>;
|
||||
_LIBCPP_HIDE_FROM_ABI __iterator()
|
||||
requires default_initializable<iterator_t<_View>>
|
||||
= default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
__iterator() requires default_initializable<iterator_t<_View>> = default;
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator(filter_view& __parent, iterator_t<_View> __current)
|
||||
: __current_(std::move(__current)), __parent_(std::addressof(__parent)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator(filter_view& __parent, iterator_t<_View> __current)
|
||||
: __current_(std::move(__current)), __parent_(std::addressof(__parent))
|
||||
{ }
|
||||
_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<_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 range_reference_t<_View> operator*() const { return *__current_; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_View> operator->() const
|
||||
requires __has_arrow<iterator_t<_View>> && copyable<iterator_t<_View>>
|
||||
{
|
||||
return __current_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr range_reference_t<_View> operator*() const { return *__current_; }
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr iterator_t<_View> operator->() const
|
||||
requires __has_arrow<iterator_t<_View>> && copyable<iterator_t<_View>>
|
||||
{
|
||||
return __current_;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
|
||||
__current_ =
|
||||
ranges::find_if(std::move(++__current_), ranges::end(__parent_->__base_), std::ref(*__parent_->__pred_));
|
||||
return *this;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int)
|
||||
requires forward_range<_View>
|
||||
{
|
||||
auto __tmp = *this;
|
||||
++*this;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator& operator++() {
|
||||
__current_ = ranges::find_if(std::move(++__current_), ranges::end(__parent_->__base_),
|
||||
std::ref(*__parent_->__pred_));
|
||||
return *this;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr void operator++(int) { ++*this; }
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator operator++(int) requires forward_range<_View> {
|
||||
auto __tmp = *this;
|
||||
++*this;
|
||||
return __tmp;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
|
||||
requires bidirectional_range<_View>
|
||||
{
|
||||
do {
|
||||
--__current_;
|
||||
} while (!std::invoke(*__parent_->__pred_, *__current_));
|
||||
return *this;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
|
||||
requires bidirectional_range<_View>
|
||||
{
|
||||
auto __tmp = *this;
|
||||
--*this;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator& operator--() requires bidirectional_range<_View> {
|
||||
do {
|
||||
--__current_;
|
||||
} while (!std::invoke(*__parent_->__pred_, *__current_));
|
||||
return *this;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator operator--(int) requires bidirectional_range<_View> {
|
||||
auto __tmp = *this;
|
||||
--*this;
|
||||
return __tmp;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(__iterator const& __x, __iterator const& __y)
|
||||
requires equality_comparable<iterator_t<_View>>
|
||||
{
|
||||
return __x.__current_ == __y.__current_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator==(__iterator const& __x, __iterator const& __y)
|
||||
requires equality_comparable<iterator_t<_View>>
|
||||
{
|
||||
return __x.__current_ == __y.__current_;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr range_rvalue_reference_t<_View>
|
||||
iter_move(__iterator const& __it) noexcept(noexcept(ranges::iter_move(__it.__current_))) {
|
||||
return ranges::iter_move(__it.__current_);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr range_rvalue_reference_t<_View> 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<iterator_t<_View>>
|
||||
{
|
||||
return ranges::iter_swap(__x.__current_, __y.__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<iterator_t<_View>>
|
||||
{
|
||||
return ranges::iter_swap(__x.__current_, __y.__current_);
|
||||
}
|
||||
};
|
||||
template <input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
|
||||
requires view<_View> && is_object_v<_Pred>
|
||||
class filter_view<_View, _Pred>::__sentinel {
|
||||
public:
|
||||
sentinel_t<_View> __end_ = sentinel_t<_View>();
|
||||
|
||||
template<input_range _View, indirect_unary_predicate<iterator_t<_View>> _Pred>
|
||||
requires view<_View> && is_object_v<_Pred>
|
||||
class filter_view<_View, _Pred>::__sentinel {
|
||||
public:
|
||||
sentinel_t<_View> __end_ = sentinel_t<_View>();
|
||||
_LIBCPP_HIDE_FROM_ABI __sentinel() = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
__sentinel() = default;
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(filter_view& __parent) : __end_(ranges::end(__parent.__base_)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit __sentinel(filter_view& __parent)
|
||||
: __end_(ranges::end(__parent.__base_))
|
||||
{ }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_View> base() const { return __end_; }
|
||||
|
||||
_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_;
|
||||
}
|
||||
};
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(__iterator const& __x, __sentinel const& __y) {
|
||||
return __x.__current_ == __y.__end_;
|
||||
}
|
||||
};
|
||||
|
||||
namespace views {
|
||||
namespace __filter {
|
||||
struct __fn {
|
||||
template<class _Range, class _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __range, _Pred&& __pred) const
|
||||
struct __fn {
|
||||
template <class _Range, class _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Pred&& __pred) const
|
||||
noexcept(noexcept(filter_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred))))
|
||||
-> decltype( filter_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred)))
|
||||
{ return filter_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred)); }
|
||||
-> decltype(filter_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred))) {
|
||||
return filter_view(std::forward<_Range>(__range), std::forward<_Pred>(__pred));
|
||||
}
|
||||
|
||||
template<class _Pred>
|
||||
requires constructible_from<decay_t<_Pred>, _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Pred&& __pred) const
|
||||
noexcept(is_nothrow_constructible_v<decay_t<_Pred>, _Pred>)
|
||||
{ return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pred>(__pred))); }
|
||||
};
|
||||
template <class _Pred>
|
||||
requires constructible_from<decay_t<_Pred>, _Pred>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pred&& __pred) const
|
||||
noexcept(is_nothrow_constructible_v<decay_t<_Pred>, _Pred>) {
|
||||
return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pred>(__pred)));
|
||||
}
|
||||
};
|
||||
} // namespace __filter
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto filter = __filter::__fn{};
|
||||
inline constexpr auto filter = __filter::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace views
|
||||
|
||||
|
@ -262,4 +255,6 @@ inline namespace __cpo {
|
|||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_FILTER_VIEW_H
|
||||
|
|
628
third_party/libcxx/__ranges/iota_view.h
vendored
628
third_party/libcxx/__ranges/iota_view.h
vendored
|
@ -22,16 +22,15 @@
|
|||
#include <__concepts/semiregular.h>
|
||||
#include <__concepts/totally_ordered.h>
|
||||
#include <__config>
|
||||
#include <__functional/ranges_operations.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/incrementable_traits.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/unreachable_sentinel.h>
|
||||
#include <__ranges/copyable_box.h>
|
||||
#include <__ranges/enable_borrowed_range.h>
|
||||
#include <__ranges/movable_box.h>
|
||||
#include <__ranges/view_interface.h>
|
||||
#include <__type_traits/conditional.h>
|
||||
#include <__type_traits/is_nothrow_copy_constructible.h>
|
||||
#include <__type_traits/is_nothrow_constructible.h>
|
||||
#include <__type_traits/make_unsigned.h>
|
||||
#include <__type_traits/type_identity.h>
|
||||
#include <__utility/forward.h>
|
||||
|
@ -41,41 +40,47 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
template<class _Int>
|
||||
struct __get_wider_signed {
|
||||
consteval static auto __call() {
|
||||
if constexpr (sizeof(_Int) < sizeof(short)) return type_identity<short>{};
|
||||
else if constexpr (sizeof(_Int) < sizeof(int)) return type_identity<int>{};
|
||||
else if constexpr (sizeof(_Int) < sizeof(long)) return type_identity<long>{};
|
||||
else return type_identity<long long>{};
|
||||
template <class _Int>
|
||||
struct __get_wider_signed {
|
||||
consteval static auto __call() {
|
||||
if constexpr (sizeof(_Int) < sizeof(short))
|
||||
return type_identity<short>{};
|
||||
else if constexpr (sizeof(_Int) < sizeof(int))
|
||||
return type_identity<int>{};
|
||||
else if constexpr (sizeof(_Int) < sizeof(long))
|
||||
return type_identity<long>{};
|
||||
else
|
||||
return type_identity<long long>{};
|
||||
|
||||
static_assert(sizeof(_Int) <= sizeof(long long),
|
||||
"Found integer-like type that is bigger than largest integer like type.");
|
||||
}
|
||||
static_assert(
|
||||
sizeof(_Int) <= sizeof(long long), "Found integer-like type that is bigger than largest integer like type.");
|
||||
}
|
||||
|
||||
using type = typename decltype(__call())::type;
|
||||
};
|
||||
using type = typename decltype(__call())::type;
|
||||
};
|
||||
|
||||
template<class _Start>
|
||||
using _IotaDiffT = typename _If<
|
||||
(!integral<_Start> || sizeof(iter_difference_t<_Start>) > sizeof(_Start)),
|
||||
type_identity<iter_difference_t<_Start>>,
|
||||
__get_wider_signed<_Start>
|
||||
>::type;
|
||||
template <class _Start>
|
||||
using _IotaDiffT =
|
||||
typename _If< (!integral<_Start> || sizeof(iter_difference_t<_Start>) > sizeof(_Start)),
|
||||
type_identity<iter_difference_t<_Start>>,
|
||||
__get_wider_signed<_Start> >::type;
|
||||
|
||||
template<class _Iter>
|
||||
concept __decrementable = incrementable<_Iter> && requires(_Iter __i) {
|
||||
{ --__i } -> same_as<_Iter&>;
|
||||
{ __i-- } -> same_as<_Iter>;
|
||||
};
|
||||
template <class _Iter>
|
||||
concept __decrementable = incrementable<_Iter> && requires(_Iter __i) {
|
||||
{ --__i } -> same_as<_Iter&>;
|
||||
{ __i-- } -> same_as<_Iter>;
|
||||
};
|
||||
|
||||
template<class _Iter>
|
||||
concept __advanceable =
|
||||
template <class _Iter>
|
||||
concept __advanceable =
|
||||
__decrementable<_Iter> && totally_ordered<_Iter> &&
|
||||
requires(_Iter __i, const _Iter __j, const _IotaDiffT<_Iter> __n) {
|
||||
{ __i += __n } -> same_as<_Iter&>;
|
||||
|
@ -86,323 +91,306 @@ namespace ranges {
|
|||
{ __j - __j } -> convertible_to<_IotaDiffT<_Iter>>;
|
||||
};
|
||||
|
||||
template<class>
|
||||
struct __iota_iterator_category {};
|
||||
template <class>
|
||||
struct __iota_iterator_category {};
|
||||
|
||||
template<incrementable _Tp>
|
||||
struct __iota_iterator_category<_Tp> {
|
||||
using iterator_category = input_iterator_tag;
|
||||
};
|
||||
template <incrementable _Tp>
|
||||
struct __iota_iterator_category<_Tp> {
|
||||
using iterator_category = input_iterator_tag;
|
||||
};
|
||||
|
||||
template <weakly_incrementable _Start, semiregular _BoundSentinel = unreachable_sentinel_t>
|
||||
requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start>
|
||||
class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
|
||||
struct __iterator : public __iota_iterator_category<_Start> {
|
||||
friend class iota_view;
|
||||
template <weakly_incrementable _Start, semiregular _BoundSentinel = unreachable_sentinel_t>
|
||||
requires __weakly_equality_comparable_with<_Start, _BoundSentinel> && copyable<_Start>
|
||||
class iota_view : public view_interface<iota_view<_Start, _BoundSentinel>> {
|
||||
struct __iterator : public __iota_iterator_category<_Start> {
|
||||
friend class iota_view;
|
||||
|
||||
using iterator_concept =
|
||||
_If<__advanceable<_Start>, random_access_iterator_tag,
|
||||
_If<__decrementable<_Start>, bidirectional_iterator_tag,
|
||||
_If<incrementable<_Start>, forward_iterator_tag,
|
||||
/*Else*/ input_iterator_tag>>>;
|
||||
using iterator_concept =
|
||||
_If<__advanceable<_Start>,
|
||||
random_access_iterator_tag,
|
||||
_If<__decrementable<_Start>,
|
||||
bidirectional_iterator_tag,
|
||||
_If<incrementable<_Start>,
|
||||
forward_iterator_tag,
|
||||
/*Else*/ input_iterator_tag>>>;
|
||||
|
||||
using value_type = _Start;
|
||||
using difference_type = _IotaDiffT<_Start>;
|
||||
|
||||
_Start __value_ = _Start();
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
__iterator() requires default_initializable<_Start> = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit __iterator(_Start __value) : __value_(std::move(__value)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) {
|
||||
return __value_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator& operator++() {
|
||||
++__value_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr void operator++(int) { ++*this; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator operator++(int) requires incrementable<_Start> {
|
||||
auto __tmp = *this;
|
||||
++*this;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator& operator--() requires __decrementable<_Start> {
|
||||
--__value_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator operator--(int) requires __decrementable<_Start> {
|
||||
auto __tmp = *this;
|
||||
--*this;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator& operator+=(difference_type __n)
|
||||
requires __advanceable<_Start>
|
||||
{
|
||||
if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
|
||||
if (__n >= difference_type(0)) {
|
||||
__value_ += static_cast<_Start>(__n);
|
||||
} else {
|
||||
__value_ -= static_cast<_Start>(-__n);
|
||||
}
|
||||
} else {
|
||||
__value_ += __n;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator& operator-=(difference_type __n)
|
||||
requires __advanceable<_Start>
|
||||
{
|
||||
if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
|
||||
if (__n >= difference_type(0)) {
|
||||
__value_ -= static_cast<_Start>(__n);
|
||||
} else {
|
||||
__value_ += static_cast<_Start>(-__n);
|
||||
}
|
||||
} else {
|
||||
__value_ -= __n;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _Start operator[](difference_type __n) const
|
||||
requires __advanceable<_Start>
|
||||
{
|
||||
return _Start(__value_ + __n);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
|
||||
requires equality_comparable<_Start>
|
||||
{
|
||||
return __x.__value_ == __y.__value_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
|
||||
requires totally_ordered<_Start>
|
||||
{
|
||||
return __x.__value_ < __y.__value_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
|
||||
requires totally_ordered<_Start>
|
||||
{
|
||||
return __y < __x;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
|
||||
requires totally_ordered<_Start>
|
||||
{
|
||||
return !(__y < __x);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
|
||||
requires totally_ordered<_Start>
|
||||
{
|
||||
return !(__x < __y);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
|
||||
requires totally_ordered<_Start> && three_way_comparable<_Start>
|
||||
{
|
||||
return __x.__value_ <=> __y.__value_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr __iterator operator+(__iterator __i, difference_type __n)
|
||||
requires __advanceable<_Start>
|
||||
{
|
||||
__i += __n;
|
||||
return __i;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr __iterator operator+(difference_type __n, __iterator __i)
|
||||
requires __advanceable<_Start>
|
||||
{
|
||||
return __i + __n;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr __iterator operator-(__iterator __i, difference_type __n)
|
||||
requires __advanceable<_Start>
|
||||
{
|
||||
__i -= __n;
|
||||
return __i;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
|
||||
requires __advanceable<_Start>
|
||||
{
|
||||
if constexpr (__integer_like<_Start>) {
|
||||
if constexpr (__signed_integer_like<_Start>) {
|
||||
return difference_type(difference_type(__x.__value_) - difference_type(__y.__value_));
|
||||
}
|
||||
if (__y.__value_ > __x.__value_) {
|
||||
return difference_type(-difference_type(__y.__value_ - __x.__value_));
|
||||
}
|
||||
return difference_type(__x.__value_ - __y.__value_);
|
||||
}
|
||||
return __x.__value_ - __y.__value_;
|
||||
}
|
||||
};
|
||||
|
||||
struct __sentinel {
|
||||
friend class iota_view;
|
||||
|
||||
private:
|
||||
_BoundSentinel __bound_sentinel_ = _BoundSentinel();
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
__sentinel() = default;
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(_BoundSentinel __bound_sentinel)
|
||||
: __bound_sentinel_(std::move(__bound_sentinel)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) {
|
||||
return __x.__value_ == __y.__bound_sentinel_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr iter_difference_t<_Start> operator-(const __iterator& __x, const __sentinel& __y)
|
||||
requires sized_sentinel_for<_BoundSentinel, _Start>
|
||||
{
|
||||
return __x.__value_ - __y.__bound_sentinel_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr iter_difference_t<_Start> operator-(const __sentinel& __x, const __iterator& __y)
|
||||
requires sized_sentinel_for<_BoundSentinel, _Start>
|
||||
{
|
||||
return -(__y - __x);
|
||||
}
|
||||
};
|
||||
using value_type = _Start;
|
||||
using difference_type = _IotaDiffT<_Start>;
|
||||
|
||||
_Start __value_ = _Start();
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI __iterator()
|
||||
requires default_initializable<_Start>
|
||||
= default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(_Start __value) : __value_(std::move(__value)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Start operator*() const noexcept(is_nothrow_copy_constructible_v<_Start>) {
|
||||
return __value_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
|
||||
++__value_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int)
|
||||
requires incrementable<_Start>
|
||||
{
|
||||
auto __tmp = *this;
|
||||
++*this;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
|
||||
requires __decrementable<_Start>
|
||||
{
|
||||
--__value_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
|
||||
requires __decrementable<_Start>
|
||||
{
|
||||
auto __tmp = *this;
|
||||
--*this;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n)
|
||||
requires __advanceable<_Start>
|
||||
{
|
||||
if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
|
||||
if (__n >= difference_type(0)) {
|
||||
__value_ += static_cast<_Start>(__n);
|
||||
} else {
|
||||
__value_ -= static_cast<_Start>(-__n);
|
||||
}
|
||||
} else {
|
||||
__value_ += __n;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n)
|
||||
requires __advanceable<_Start>
|
||||
{
|
||||
if constexpr (__integer_like<_Start> && !__signed_integer_like<_Start>) {
|
||||
if (__n >= difference_type(0)) {
|
||||
__value_ -= static_cast<_Start>(__n);
|
||||
} else {
|
||||
__value_ += static_cast<_Start>(-__n);
|
||||
}
|
||||
} else {
|
||||
__value_ -= __n;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Start operator[](difference_type __n) const
|
||||
requires __advanceable<_Start>
|
||||
{
|
||||
return _Start(__value_ + __n);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
|
||||
requires equality_comparable<_Start>
|
||||
{
|
||||
return __x.__value_ == __y.__value_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
|
||||
requires totally_ordered<_Start>
|
||||
{
|
||||
return __x.__value_ < __y.__value_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
|
||||
requires totally_ordered<_Start>
|
||||
{
|
||||
return __y < __x;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
|
||||
requires totally_ordered<_Start>
|
||||
{
|
||||
return !(__y < __x);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
|
||||
requires totally_ordered<_Start>
|
||||
{
|
||||
return !(__x < __y);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
|
||||
requires totally_ordered<_Start> && three_way_comparable<_Start>
|
||||
{
|
||||
return __x.__value_ <=> __y.__value_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator __i, difference_type __n)
|
||||
requires __advanceable<_Start>
|
||||
{
|
||||
__i += __n;
|
||||
return __i;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, __iterator __i)
|
||||
requires __advanceable<_Start>
|
||||
{
|
||||
return __i + __n;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator __i, difference_type __n)
|
||||
requires __advanceable<_Start>
|
||||
{
|
||||
__i -= __n;
|
||||
return __i;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
|
||||
requires __advanceable<_Start>
|
||||
{
|
||||
if constexpr (__integer_like<_Start>) {
|
||||
if constexpr (__signed_integer_like<_Start>) {
|
||||
return difference_type(difference_type(__x.__value_) - difference_type(__y.__value_));
|
||||
}
|
||||
if (__y.__value_ > __x.__value_) {
|
||||
return difference_type(-difference_type(__y.__value_ - __x.__value_));
|
||||
}
|
||||
return difference_type(__x.__value_ - __y.__value_);
|
||||
}
|
||||
return __x.__value_ - __y.__value_;
|
||||
}
|
||||
};
|
||||
|
||||
struct __sentinel {
|
||||
friend class iota_view;
|
||||
|
||||
private:
|
||||
_BoundSentinel __bound_sentinel_ = _BoundSentinel();
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
iota_view() requires default_initializable<_Start> = default;
|
||||
_LIBCPP_HIDE_FROM_ABI __sentinel() = default;
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(_BoundSentinel __bound_sentinel)
|
||||
: __bound_sentinel_(std::move(__bound_sentinel)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit iota_view(_Start __value) : __value_(std::move(__value)) { }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(type_identity_t<_Start> __value, type_identity_t<_BoundSentinel> __bound_sentinel)
|
||||
: __value_(std::move(__value)), __bound_sentinel_(std::move(__bound_sentinel)) {
|
||||
// Validate the precondition if possible.
|
||||
if constexpr (totally_ordered_with<_Start, _BoundSentinel>) {
|
||||
_LIBCPP_ASSERT(ranges::less_equal()(__value_, __bound_sentinel_),
|
||||
"Precondition violated: value is greater than bound.");
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __sentinel& __y) {
|
||||
return __x.__value_ == __y.__bound_sentinel_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, __iterator __last)
|
||||
requires same_as<_Start, _BoundSentinel>
|
||||
: iota_view(std::move(__first.__value_), std::move(__last.__value_)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, _BoundSentinel __last)
|
||||
requires same_as<_BoundSentinel, unreachable_sentinel_t>
|
||||
: iota_view(std::move(__first.__value_), std::move(__last)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, __sentinel __last)
|
||||
requires(!same_as<_Start, _BoundSentinel> && !same_as<_BoundSentinel, unreachable_sentinel_t>)
|
||||
: iota_view(std::move(__first.__value_), std::move(__last.__bound_sentinel_)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator begin() const { return __iterator{__value_}; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto end() const {
|
||||
if constexpr (same_as<_BoundSentinel, unreachable_sentinel_t>)
|
||||
return unreachable_sentinel;
|
||||
else
|
||||
return __sentinel{__bound_sentinel_};
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator end() const
|
||||
requires same_as<_Start, _BoundSentinel>
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_Start>
|
||||
operator-(const __iterator& __x, const __sentinel& __y)
|
||||
requires sized_sentinel_for<_BoundSentinel, _Start>
|
||||
{
|
||||
return __iterator{__bound_sentinel_};
|
||||
return __x.__value_ - __y.__bound_sentinel_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto size() const
|
||||
requires(same_as<_Start, _BoundSentinel> && __advanceable<_Start>) ||
|
||||
(integral<_Start> && integral<_BoundSentinel>) || sized_sentinel_for<_BoundSentinel, _Start>
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr iter_difference_t<_Start>
|
||||
operator-(const __sentinel& __x, const __iterator& __y)
|
||||
requires sized_sentinel_for<_BoundSentinel, _Start>
|
||||
{
|
||||
if constexpr (__integer_like<_Start> && __integer_like<_BoundSentinel>) {
|
||||
if (__value_ < 0) {
|
||||
if (__bound_sentinel_ < 0) {
|
||||
return std::__to_unsigned_like(-__value_) - std::__to_unsigned_like(-__bound_sentinel_);
|
||||
}
|
||||
return std::__to_unsigned_like(__bound_sentinel_) + std::__to_unsigned_like(-__value_);
|
||||
}
|
||||
return std::__to_unsigned_like(__bound_sentinel_) - std::__to_unsigned_like(__value_);
|
||||
}
|
||||
return -(__y - __x);
|
||||
}
|
||||
};
|
||||
|
||||
_Start __value_ = _Start();
|
||||
_BoundSentinel __bound_sentinel_ = _BoundSentinel();
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI iota_view()
|
||||
requires default_initializable<_Start>
|
||||
= default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit iota_view(_Start __value) : __value_(std::move(__value)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23
|
||||
iota_view(type_identity_t<_Start> __value, type_identity_t<_BoundSentinel> __bound_sentinel)
|
||||
: __value_(std::move(__value)), __bound_sentinel_(std::move(__bound_sentinel)) {
|
||||
// Validate the precondition if possible.
|
||||
if constexpr (totally_ordered_with<_Start, _BoundSentinel>) {
|
||||
_LIBCPP_ASSERT_VALID_INPUT_RANGE(
|
||||
bool(__value_ <= __bound_sentinel_), "iota_view: bound must be reachable from value");
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, __iterator __last)
|
||||
requires same_as<_Start, _BoundSentinel>
|
||||
: iota_view(std::move(__first.__value_), std::move(__last.__value_)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, _BoundSentinel __last)
|
||||
requires same_as<_BoundSentinel, unreachable_sentinel_t>
|
||||
: iota_view(std::move(__first.__value_), std::move(__last)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 iota_view(__iterator __first, __sentinel __last)
|
||||
requires(!same_as<_Start, _BoundSentinel> && !same_as<_BoundSentinel, unreachable_sentinel_t>)
|
||||
: iota_view(std::move(__first.__value_), std::move(__last.__bound_sentinel_)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() const { return __iterator{__value_}; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto end() const {
|
||||
if constexpr (same_as<_BoundSentinel, unreachable_sentinel_t>)
|
||||
return unreachable_sentinel;
|
||||
else
|
||||
return __sentinel{__bound_sentinel_};
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator end() const
|
||||
requires same_as<_Start, _BoundSentinel>
|
||||
{
|
||||
return __iterator{__bound_sentinel_};
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr bool empty() const { return __value_ == __bound_sentinel_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto size() const
|
||||
requires(same_as<_Start, _BoundSentinel> && __advanceable<_Start>) ||
|
||||
(integral<_Start> && integral<_BoundSentinel>) || sized_sentinel_for<_BoundSentinel, _Start>
|
||||
{
|
||||
if constexpr (__integer_like<_Start> && __integer_like<_BoundSentinel>) {
|
||||
return (__value_ < 0)
|
||||
? ((__bound_sentinel_ < 0)
|
||||
? std::__to_unsigned_like(-__value_) - std::__to_unsigned_like(-__bound_sentinel_)
|
||||
: std::__to_unsigned_like(__bound_sentinel_) + std::__to_unsigned_like(-__value_))
|
||||
: std::__to_unsigned_like(__bound_sentinel_) - std::__to_unsigned_like(__value_);
|
||||
} else {
|
||||
return std::__to_unsigned_like(__bound_sentinel_ - __value_);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Start, class _BoundSentinel>
|
||||
requires(!__integer_like<_Start> || !__integer_like<_BoundSentinel> ||
|
||||
(__signed_integer_like<_Start> == __signed_integer_like<_BoundSentinel>))
|
||||
iota_view(_Start, _BoundSentinel) -> iota_view<_Start, _BoundSentinel>;
|
||||
template <class _Start, class _BoundSentinel>
|
||||
requires(!__integer_like<_Start> || !__integer_like<_BoundSentinel> ||
|
||||
(__signed_integer_like<_Start> == __signed_integer_like<_BoundSentinel>))
|
||||
iota_view(_Start, _BoundSentinel) -> iota_view<_Start, _BoundSentinel>;
|
||||
|
||||
template <class _Start, class _BoundSentinel>
|
||||
inline constexpr bool enable_borrowed_range<iota_view<_Start, _BoundSentinel>> = true;
|
||||
template <class _Start, class _BoundSentinel>
|
||||
inline constexpr bool enable_borrowed_range<iota_view<_Start, _BoundSentinel>> = true;
|
||||
|
||||
namespace views {
|
||||
namespace __iota {
|
||||
struct __fn {
|
||||
template<class _Start>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Start&& __start) const
|
||||
namespace views {
|
||||
namespace __iota {
|
||||
struct __fn {
|
||||
template <class _Start>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Start&& __start) const
|
||||
noexcept(noexcept(ranges::iota_view(std::forward<_Start>(__start))))
|
||||
-> decltype( ranges::iota_view(std::forward<_Start>(__start)))
|
||||
{ return ranges::iota_view(std::forward<_Start>(__start)); }
|
||||
-> decltype(ranges::iota_view(std::forward<_Start>(__start))) {
|
||||
return ranges::iota_view(std::forward<_Start>(__start));
|
||||
}
|
||||
|
||||
template <class _Start, class _BoundSentinel>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Start&& __start, _BoundSentinel&& __bound_sentinel) const
|
||||
noexcept(noexcept(ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel))))
|
||||
-> decltype( ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel)))
|
||||
{ return ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel)); }
|
||||
};
|
||||
template <class _Start, class _BoundSentinel>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Start&& __start, _BoundSentinel&& __bound_sentinel) const noexcept(
|
||||
noexcept(ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel))))
|
||||
-> decltype(ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel))) {
|
||||
return ranges::iota_view(std::forward<_Start>(__start), std::forward<_BoundSentinel>(__bound_sentinel));
|
||||
}
|
||||
};
|
||||
} // namespace __iota
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto iota = __iota::__fn{};
|
||||
inline constexpr auto iota = __iota::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace views
|
||||
} // namespace ranges
|
||||
|
@ -411,4 +399,6 @@ inline namespace __cpo {
|
|||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_IOTA_VIEW_H
|
||||
|
|
6
third_party/libcxx/__ranges/istream_view.h
vendored
6
third_party/libcxx/__ranges/istream_view.h
vendored
|
@ -14,6 +14,8 @@
|
|||
#include <__concepts/derived_from.h>
|
||||
#include <__concepts/movable.h>
|
||||
#include <__config>
|
||||
#include <__fwd/istream.h>
|
||||
#include <__fwd/string.h>
|
||||
#include <__iterator/default_sentinel.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__memory/addressof.h>
|
||||
|
@ -21,7 +23,6 @@
|
|||
#include <__type_traits/remove_cvref.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <cstddef>
|
||||
#include <iosfwd>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
# pragma GCC system_header
|
||||
|
@ -65,8 +66,7 @@ public:
|
|||
using difference_type = ptrdiff_t;
|
||||
using value_type = _Val;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(
|
||||
basic_istream_view<_Val, _CharT, _Traits>& __parent) noexcept
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(basic_istream_view<_Val, _CharT, _Traits>& __parent) noexcept
|
||||
: __parent_(std::addressof(__parent)) {}
|
||||
|
||||
__iterator(const __iterator&) = delete;
|
||||
|
|
590
third_party/libcxx/__ranges/join_view.h
vendored
590
third_party/libcxx/__ranges/join_view.h
vendored
|
@ -32,6 +32,8 @@
|
|||
#include <__ranges/view_interface.h>
|
||||
#include <__type_traits/common_type.h>
|
||||
#include <__type_traits/maybe_const.h>
|
||||
#include <__utility/as_lvalue.h>
|
||||
#include <__utility/empty.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <optional>
|
||||
|
||||
|
@ -39,366 +41,342 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
// Note: `join_view` is still marked experimental because there is an ABI-breaking change that affects `join_view` in
|
||||
// the pipeline (https://isocpp.org/files/papers/D2770R0.html).
|
||||
// TODO: make `join_view` non-experimental once D2770 is implemented.
|
||||
#if _LIBCPP_STD_VER >= 20 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
template<class>
|
||||
struct __join_view_iterator_category {};
|
||||
template <class>
|
||||
struct __join_view_iterator_category {};
|
||||
|
||||
template<class _View>
|
||||
requires is_reference_v<range_reference_t<_View>> &&
|
||||
forward_range<_View> &&
|
||||
forward_range<range_reference_t<_View>>
|
||||
struct __join_view_iterator_category<_View> {
|
||||
using _OuterC = typename iterator_traits<iterator_t<_View>>::iterator_category;
|
||||
using _InnerC = typename iterator_traits<iterator_t<range_reference_t<_View>>>::iterator_category;
|
||||
template <class _View>
|
||||
requires is_reference_v<range_reference_t<_View>> && forward_range<_View> && forward_range<range_reference_t<_View>>
|
||||
struct __join_view_iterator_category<_View> {
|
||||
using _OuterC = typename iterator_traits<iterator_t<_View>>::iterator_category;
|
||||
using _InnerC = typename iterator_traits<iterator_t<range_reference_t<_View>>>::iterator_category;
|
||||
|
||||
using iterator_category = _If<
|
||||
derived_from<_OuterC, bidirectional_iterator_tag> && derived_from<_InnerC, bidirectional_iterator_tag> &&
|
||||
common_range<range_reference_t<_View>>,
|
||||
bidirectional_iterator_tag,
|
||||
_If<
|
||||
derived_from<_OuterC, forward_iterator_tag> && derived_from<_InnerC, forward_iterator_tag>,
|
||||
forward_iterator_tag,
|
||||
input_iterator_tag
|
||||
>
|
||||
>;
|
||||
};
|
||||
using iterator_category =
|
||||
_If< derived_from<_OuterC, bidirectional_iterator_tag> && derived_from<_InnerC, bidirectional_iterator_tag> &&
|
||||
common_range<range_reference_t<_View>>,
|
||||
bidirectional_iterator_tag,
|
||||
_If< derived_from<_OuterC, forward_iterator_tag> && derived_from<_InnerC, forward_iterator_tag>,
|
||||
forward_iterator_tag,
|
||||
input_iterator_tag > >;
|
||||
};
|
||||
|
||||
template<input_range _View>
|
||||
requires view<_View> && input_range<range_reference_t<_View>>
|
||||
class join_view
|
||||
: public view_interface<join_view<_View>> {
|
||||
private:
|
||||
using _InnerRange = range_reference_t<_View>;
|
||||
template <input_range _View>
|
||||
requires view<_View> && input_range<range_reference_t<_View>>
|
||||
class join_view : public view_interface<join_view<_View>> {
|
||||
private:
|
||||
using _InnerRange = range_reference_t<_View>;
|
||||
|
||||
template<bool> struct __iterator;
|
||||
template <bool>
|
||||
struct __iterator;
|
||||
|
||||
template<bool> struct __sentinel;
|
||||
template <bool>
|
||||
struct __sentinel;
|
||||
|
||||
template <class>
|
||||
friend struct std::__segmented_iterator_traits;
|
||||
template <class>
|
||||
friend struct std::__segmented_iterator_traits;
|
||||
|
||||
static constexpr bool _UseCache = !is_reference_v<_InnerRange>;
|
||||
using _Cache = _If<_UseCache, __non_propagating_cache<remove_cvref_t<_InnerRange>>, __empty_cache>;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Cache __cache_;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
join_view() requires default_initializable<_View> = default;
|
||||
static constexpr bool _UseOuterCache = !forward_range<_View>;
|
||||
using _OuterCache = _If<_UseOuterCache, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _OuterCache __outer_;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit join_view(_View __base)
|
||||
: __base_(std::move(__base)) {}
|
||||
static constexpr bool _UseInnerCache = !is_reference_v<_InnerRange>;
|
||||
using _InnerCache = _If<_UseInnerCache, __non_propagating_cache<remove_cvref_t<_InnerRange>>, __empty_cache>;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _InnerCache __inner_;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI join_view()
|
||||
requires default_initializable<_View>
|
||||
= default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _View base() && { return std::move(__base_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit join_view(_View __base) : __base_(std::move(__base)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto begin() {
|
||||
constexpr bool __use_const = __simple_view<_View> &&
|
||||
is_reference_v<range_reference_t<_View>>;
|
||||
_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 begin() {
|
||||
if constexpr (forward_range<_View>) {
|
||||
constexpr bool __use_const = __simple_view<_View> && is_reference_v<range_reference_t<_View>>;
|
||||
return __iterator<__use_const>{*this, ranges::begin(__base_)};
|
||||
} else {
|
||||
__outer_.__emplace(ranges::begin(__base_));
|
||||
return __iterator<false>{*this};
|
||||
}
|
||||
}
|
||||
|
||||
template<class _V2 = _View>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto begin() const
|
||||
requires input_range<const _V2> &&
|
||||
is_reference_v<range_reference_t<const _V2>>
|
||||
{
|
||||
return __iterator<true>{*this, ranges::begin(__base_)};
|
||||
template <class _V2 = _View>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
|
||||
requires forward_range<const _V2> && is_reference_v<range_reference_t<const _V2>> &&
|
||||
input_range<range_reference_t<const _V2>>
|
||||
{
|
||||
return __iterator<true>{*this, ranges::begin(__base_)};
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto end() {
|
||||
if constexpr (forward_range<_View> && is_reference_v<_InnerRange> && forward_range<_InnerRange> &&
|
||||
common_range<_View> && common_range<_InnerRange>)
|
||||
return __iterator<__simple_view<_View>>{*this, ranges::end(__base_)};
|
||||
else
|
||||
return __sentinel<__simple_view<_View>>{*this};
|
||||
}
|
||||
|
||||
template <class _V2 = _View>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto end() const
|
||||
requires forward_range<const _V2> && is_reference_v<range_reference_t<const _V2>> &&
|
||||
input_range<range_reference_t<const _V2>>
|
||||
{
|
||||
using _ConstInnerRange = range_reference_t<const _View>;
|
||||
if constexpr (forward_range<_ConstInnerRange> && common_range<const _View> && common_range<_ConstInnerRange>) {
|
||||
return __iterator<true>{*this, ranges::end(__base_)};
|
||||
} else {
|
||||
return __sentinel<true>{*this};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto end() {
|
||||
if constexpr (forward_range<_View> &&
|
||||
is_reference_v<_InnerRange> &&
|
||||
forward_range<_InnerRange> &&
|
||||
common_range<_View> &&
|
||||
common_range<_InnerRange>)
|
||||
return __iterator<__simple_view<_View>>{*this, ranges::end(__base_)};
|
||||
else
|
||||
return __sentinel<__simple_view<_View>>{*this};
|
||||
}
|
||||
template <input_range _View>
|
||||
requires view<_View> && input_range<range_reference_t<_View>>
|
||||
template <bool _Const>
|
||||
struct join_view<_View>::__sentinel {
|
||||
private:
|
||||
template <bool>
|
||||
friend struct __sentinel;
|
||||
|
||||
template<class _V2 = _View>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto end() const
|
||||
requires input_range<const _V2> &&
|
||||
is_reference_v<range_reference_t<const _V2>>
|
||||
{
|
||||
using _ConstInnerRange = range_reference_t<const _View>;
|
||||
if constexpr (forward_range<const _View> &&
|
||||
is_reference_v<_ConstInnerRange> &&
|
||||
forward_range<_ConstInnerRange> &&
|
||||
common_range<const _View> &&
|
||||
common_range<_ConstInnerRange>) {
|
||||
return __iterator<true>{*this, ranges::end(__base_)};
|
||||
} else {
|
||||
return __sentinel<true>{*this};
|
||||
}
|
||||
}
|
||||
};
|
||||
using _Parent = __maybe_const<_Const, join_view>;
|
||||
using _Base = __maybe_const<_Const, _View>;
|
||||
sentinel_t<_Base> __end_ = sentinel_t<_Base>();
|
||||
|
||||
template<input_range _View>
|
||||
requires view<_View> && input_range<range_reference_t<_View>>
|
||||
template<bool _Const>
|
||||
struct join_view<_View>::__sentinel {
|
||||
template<bool>
|
||||
friend struct __sentinel;
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI __sentinel() = default;
|
||||
|
||||
private:
|
||||
using _Parent = __maybe_const<_Const, join_view<_View>>;
|
||||
using _Base = __maybe_const<_Const, _View>;
|
||||
sentinel_t<_Base> __end_ = sentinel_t<_Base>();
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(_Parent& __parent) : __end_(ranges::end(__parent.__base_)) {}
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
__sentinel() = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit __sentinel(_Parent& __parent)
|
||||
: __end_(ranges::end(__parent.__base_)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __sentinel(__sentinel<!_Const> __s)
|
||||
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __s)
|
||||
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
|
||||
: __end_(std::move(__s.__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.__outer_ == __y.__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.__get_outer() == __y.__end_;
|
||||
}
|
||||
};
|
||||
|
||||
// https://reviews.llvm.org/D142811#inline-1383022
|
||||
// To simplify the segmented iterator traits specialization,
|
||||
// make the iterator `final`
|
||||
template<input_range _View>
|
||||
requires view<_View> && input_range<range_reference_t<_View>>
|
||||
template<bool _Const>
|
||||
struct join_view<_View>::__iterator final
|
||||
: public __join_view_iterator_category<__maybe_const<_Const, _View>> {
|
||||
// https://reviews.llvm.org/D142811#inline-1383022
|
||||
// To simplify the segmented iterator traits specialization,
|
||||
// make the iterator `final`
|
||||
template <input_range _View>
|
||||
requires view<_View> && input_range<range_reference_t<_View>>
|
||||
template <bool _Const>
|
||||
struct join_view<_View>::__iterator final : public __join_view_iterator_category<__maybe_const<_Const, _View>> {
|
||||
friend join_view;
|
||||
|
||||
template<bool>
|
||||
friend struct __iterator;
|
||||
template <class>
|
||||
friend struct std::__segmented_iterator_traits;
|
||||
|
||||
template <class>
|
||||
friend struct std::__segmented_iterator_traits;
|
||||
static constexpr bool __is_join_view_iterator = true;
|
||||
|
||||
static constexpr bool __is_join_view_iterator = true;
|
||||
private:
|
||||
using _Parent = __maybe_const<_Const, join_view<_View>>;
|
||||
using _Base = __maybe_const<_Const, _View>;
|
||||
using _Outer = iterator_t<_Base>;
|
||||
using _Inner = iterator_t<range_reference_t<_Base>>;
|
||||
using _InnerRange = range_reference_t<_View>;
|
||||
|
||||
private:
|
||||
using _Parent = __maybe_const<_Const, join_view<_View>>;
|
||||
using _Base = __maybe_const<_Const, _View>;
|
||||
using _Outer = iterator_t<_Base>;
|
||||
using _Inner = iterator_t<range_reference_t<_Base>>;
|
||||
using _InnerRange = range_reference_t<_View>;
|
||||
static_assert(!_Const || forward_range<_Base>, "Const can only be true when Base models forward_range.");
|
||||
|
||||
static constexpr bool __ref_is_glvalue = is_reference_v<range_reference_t<_Base>>;
|
||||
static constexpr bool __ref_is_glvalue = is_reference_v<range_reference_t<_Base>>;
|
||||
|
||||
public:
|
||||
_Outer __outer_ = _Outer();
|
||||
static constexpr bool _OuterPresent = forward_range<_Base>;
|
||||
using _OuterType = _If<_OuterPresent, _Outer, std::__empty>;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _OuterType __outer_ = _OuterType();
|
||||
|
||||
private:
|
||||
optional<_Inner> __inner_;
|
||||
_Parent *__parent_ = nullptr;
|
||||
optional<_Inner> __inner_;
|
||||
_Parent* __parent_ = nullptr;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr void __satisfy() {
|
||||
for (; __outer_ != ranges::end(__parent_->__base_); ++__outer_) {
|
||||
auto&& __inner = [&]() -> auto&& {
|
||||
if constexpr (__ref_is_glvalue)
|
||||
return *__outer_;
|
||||
else
|
||||
return __parent_->__cache_.__emplace_from([&]() -> decltype(auto) { return *__outer_; });
|
||||
}();
|
||||
__inner_ = ranges::begin(__inner);
|
||||
if (*__inner_ != ranges::end(__inner))
|
||||
return;
|
||||
}
|
||||
|
||||
if constexpr (__ref_is_glvalue)
|
||||
__inner_.reset();
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr void __satisfy() {
|
||||
for (; __get_outer() != ranges::end(__parent_->__base_); ++__get_outer()) {
|
||||
auto&& __inner = [this]() -> auto&& {
|
||||
if constexpr (__ref_is_glvalue)
|
||||
return *__get_outer();
|
||||
else
|
||||
return __parent_->__inner_.__emplace_from([&]() -> decltype(auto) { return *__get_outer(); });
|
||||
}();
|
||||
__inner_ = ranges::begin(__inner);
|
||||
if (*__inner_ != ranges::end(__inner))
|
||||
return;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator(_Parent* __parent, _Outer __outer, _Inner __inner)
|
||||
if constexpr (__ref_is_glvalue)
|
||||
__inner_.reset();
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Outer& __get_outer() {
|
||||
if constexpr (forward_range<_Base>) {
|
||||
return __outer_;
|
||||
} else {
|
||||
return *__parent_->__outer_;
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr const _Outer& __get_outer() const {
|
||||
if constexpr (forward_range<_Base>) {
|
||||
return __outer_;
|
||||
} else {
|
||||
return *__parent_->__outer_;
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator(_Parent& __parent, _Outer __outer)
|
||||
requires forward_range<_Base>
|
||||
: __outer_(std::move(__outer)), __parent_(std::addressof(__parent)) {
|
||||
__satisfy();
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(_Parent& __parent)
|
||||
requires(!forward_range<_Base>)
|
||||
: __parent_(std::addressof(__parent)) {
|
||||
__satisfy();
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator(_Parent* __parent, _Outer __outer, _Inner __inner)
|
||||
requires forward_range<_Base>
|
||||
: __outer_(std::move(__outer)), __inner_(std::move(__inner)), __parent_(__parent) {}
|
||||
|
||||
public:
|
||||
using iterator_concept = _If<
|
||||
__ref_is_glvalue && bidirectional_range<_Base> && bidirectional_range<range_reference_t<_Base>> &&
|
||||
common_range<range_reference_t<_Base>>,
|
||||
bidirectional_iterator_tag,
|
||||
_If<
|
||||
__ref_is_glvalue && forward_range<_Base> && forward_range<range_reference_t<_Base>>,
|
||||
forward_iterator_tag,
|
||||
input_iterator_tag
|
||||
>
|
||||
>;
|
||||
public:
|
||||
using iterator_concept =
|
||||
_If< __ref_is_glvalue && bidirectional_range<_Base> && bidirectional_range<range_reference_t<_Base>> &&
|
||||
common_range<range_reference_t<_Base>>,
|
||||
bidirectional_iterator_tag,
|
||||
_If< __ref_is_glvalue && forward_range<_Base> && forward_range<range_reference_t<_Base>>,
|
||||
forward_iterator_tag,
|
||||
input_iterator_tag > >;
|
||||
|
||||
using value_type = range_value_t<range_reference_t<_Base>>;
|
||||
using value_type = range_value_t<range_reference_t<_Base>>;
|
||||
|
||||
using difference_type = common_type_t<
|
||||
range_difference_t<_Base>, range_difference_t<range_reference_t<_Base>>>;
|
||||
using difference_type = common_type_t< range_difference_t<_Base>, range_difference_t<range_reference_t<_Base>>>;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
__iterator() requires default_initializable<_Outer> = default;
|
||||
_LIBCPP_HIDE_FROM_ABI __iterator() = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator(_Parent& __parent, _Outer __outer)
|
||||
: __outer_(std::move(__outer))
|
||||
, __parent_(std::addressof(__parent)) {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i)
|
||||
requires _Const && convertible_to<iterator_t<_View>, _Outer> && convertible_to<iterator_t<_InnerRange>, _Inner>
|
||||
: __outer_(std::move(__i.__outer_)), __inner_(std::move(__i.__inner_)), __parent_(__i.__parent_) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return **__inner_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Inner operator->() const
|
||||
requires __has_arrow<_Inner> && copyable<_Inner>
|
||||
{
|
||||
return *__inner_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
|
||||
auto __get_inner_range = [&]() -> decltype(auto) {
|
||||
if constexpr (__ref_is_glvalue)
|
||||
return *__get_outer();
|
||||
else
|
||||
return *__parent_->__inner_;
|
||||
};
|
||||
if (++*__inner_ == ranges::end(std::__as_lvalue(__get_inner_range()))) {
|
||||
++__get_outer();
|
||||
__satisfy();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator(__iterator<!_Const> __i)
|
||||
requires _Const &&
|
||||
convertible_to<iterator_t<_View>, _Outer> &&
|
||||
convertible_to<iterator_t<_InnerRange>, _Inner>
|
||||
: __outer_(std::move(__i.__outer_))
|
||||
, __inner_(std::move(__i.__inner_))
|
||||
, __parent_(__i.__parent_) {}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr decltype(auto) operator*() const {
|
||||
return **__inner_;
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int)
|
||||
requires __ref_is_glvalue && forward_range<_Base> && forward_range<range_reference_t<_Base>>
|
||||
{
|
||||
auto __tmp = *this;
|
||||
++*this;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
|
||||
requires __ref_is_glvalue && bidirectional_range<_Base> && bidirectional_range<range_reference_t<_Base>> &&
|
||||
common_range<range_reference_t<_Base>>
|
||||
{
|
||||
if (__outer_ == ranges::end(__parent_->__base_))
|
||||
__inner_ = ranges::end(std::__as_lvalue(*--__outer_));
|
||||
|
||||
// Skip empty inner ranges when going backwards.
|
||||
while (*__inner_ == ranges::begin(std::__as_lvalue(*__outer_))) {
|
||||
__inner_ = ranges::end(std::__as_lvalue(*--__outer_));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _Inner operator->() const
|
||||
requires __has_arrow<_Inner> && copyable<_Inner>
|
||||
{
|
||||
return *__inner_;
|
||||
}
|
||||
--*__inner_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator& operator++() {
|
||||
auto&& __inner = [&]() -> auto&& {
|
||||
if constexpr (__ref_is_glvalue)
|
||||
return *__outer_;
|
||||
else
|
||||
return *__parent_->__cache_;
|
||||
}();
|
||||
if (++*__inner_ == ranges::end(__inner)) {
|
||||
++__outer_;
|
||||
__satisfy();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
|
||||
requires __ref_is_glvalue && bidirectional_range<_Base> && bidirectional_range<range_reference_t<_Base>> &&
|
||||
common_range<range_reference_t<_Base>>
|
||||
{
|
||||
auto __tmp = *this;
|
||||
--*this;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr void operator++(int) {
|
||||
++*this;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
|
||||
requires __ref_is_glvalue && forward_range<_Base> && equality_comparable<iterator_t<range_reference_t<_Base>>>
|
||||
{
|
||||
return __x.__outer_ == __y.__outer_ && __x.__inner_ == __y.__inner_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator operator++(int)
|
||||
requires __ref_is_glvalue &&
|
||||
forward_range<_Base> &&
|
||||
forward_range<range_reference_t<_Base>>
|
||||
{
|
||||
auto __tmp = *this;
|
||||
++*this;
|
||||
return __tmp;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr decltype(auto)
|
||||
iter_move(const __iterator& __i) noexcept(noexcept(ranges::iter_move(*__i.__inner_))) {
|
||||
return ranges::iter_move(*__i.__inner_);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator& operator--()
|
||||
requires __ref_is_glvalue &&
|
||||
bidirectional_range<_Base> &&
|
||||
bidirectional_range<range_reference_t<_Base>> &&
|
||||
common_range<range_reference_t<_Base>>
|
||||
{
|
||||
if (__outer_ == ranges::end(__parent_->__base_))
|
||||
__inner_ = ranges::end(*--__outer_);
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr void
|
||||
iter_swap(const __iterator& __x,
|
||||
const __iterator& __y) noexcept(noexcept(ranges::iter_swap(*__x.__inner_, *__y.__inner_)))
|
||||
requires indirectly_swappable<_Inner>
|
||||
{
|
||||
return ranges::iter_swap(*__x.__inner_, *__y.__inner_);
|
||||
}
|
||||
};
|
||||
|
||||
// Skip empty inner ranges when going backwards.
|
||||
while (*__inner_ == ranges::begin(*__outer_)) {
|
||||
__inner_ = ranges::end(*--__outer_);
|
||||
}
|
||||
|
||||
--*__inner_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator operator--(int)
|
||||
requires __ref_is_glvalue &&
|
||||
bidirectional_range<_Base> &&
|
||||
bidirectional_range<range_reference_t<_Base>> &&
|
||||
common_range<range_reference_t<_Base>>
|
||||
{
|
||||
auto __tmp = *this;
|
||||
--*this;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
|
||||
requires __ref_is_glvalue &&
|
||||
equality_comparable<iterator_t<_Base>> &&
|
||||
equality_comparable<iterator_t<range_reference_t<_Base>>>
|
||||
{
|
||||
return __x.__outer_ == __y.__outer_ && __x.__inner_ == __y.__inner_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr decltype(auto) iter_move(const __iterator& __i)
|
||||
noexcept(noexcept(ranges::iter_move(*__i.__inner_)))
|
||||
{
|
||||
return ranges::iter_move(*__i.__inner_);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr void iter_swap(const __iterator& __x, const __iterator& __y)
|
||||
noexcept(noexcept(ranges::iter_swap(*__x.__inner_, *__y.__inner_)))
|
||||
requires indirectly_swappable<_Inner>
|
||||
{
|
||||
return ranges::iter_swap(*__x.__inner_, *__y.__inner_);
|
||||
}
|
||||
};
|
||||
|
||||
template<class _Range>
|
||||
explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
|
||||
template <class _Range>
|
||||
explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;
|
||||
|
||||
namespace views {
|
||||
namespace __join_view {
|
||||
struct __fn : __range_adaptor_closure<__fn> {
|
||||
template<class _Range>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __range) const
|
||||
noexcept(noexcept(join_view<all_t<_Range&&>>(std::forward<_Range>(__range))))
|
||||
-> decltype( join_view<all_t<_Range&&>>(std::forward<_Range>(__range)))
|
||||
{ return join_view<all_t<_Range&&>>(std::forward<_Range>(__range)); }
|
||||
template <class _Range>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
|
||||
noexcept(noexcept(join_view<all_t<_Range&&>>(std::forward<_Range>(__range))))
|
||||
-> decltype(join_view<all_t<_Range&&>>(std::forward<_Range>(__range))) {
|
||||
return join_view<all_t<_Range&&>>(std::forward<_Range>(__range));
|
||||
}
|
||||
};
|
||||
} // namespace __join_view
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto join = __join_view::__fn{};
|
||||
inline constexpr auto join = __join_view::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace views
|
||||
} // namespace ranges
|
||||
|
||||
template <class _JoinViewIterator>
|
||||
requires(_JoinViewIterator::__is_join_view_iterator &&
|
||||
ranges::common_range<typename _JoinViewIterator::_Parent> &&
|
||||
requires(_JoinViewIterator::__is_join_view_iterator && ranges::common_range<typename _JoinViewIterator::_Parent> &&
|
||||
__has_random_access_iterator_category<typename _JoinViewIterator::_Outer>::value &&
|
||||
__has_random_access_iterator_category<typename _JoinViewIterator::_Inner>::value)
|
||||
struct __segmented_iterator_traits<_JoinViewIterator> {
|
||||
|
||||
using __segment_iterator =
|
||||
_LIBCPP_NODEBUG __iterator_with_data<typename _JoinViewIterator::_Outer, typename _JoinViewIterator::_Parent*>;
|
||||
using __local_iterator = typename _JoinViewIterator::_Inner;
|
||||
|
@ -406,38 +384,40 @@ struct __segmented_iterator_traits<_JoinViewIterator> {
|
|||
// TODO: Would it make sense to enable the optimization for other iterator types?
|
||||
|
||||
static constexpr _LIBCPP_HIDE_FROM_ABI __segment_iterator __segment(_JoinViewIterator __iter) {
|
||||
if (ranges::empty(__iter.__parent_->__base_))
|
||||
return {};
|
||||
if (!__iter.__inner_.has_value())
|
||||
return __segment_iterator(--__iter.__outer_, __iter.__parent_);
|
||||
return __segment_iterator(__iter.__outer_, __iter.__parent_);
|
||||
if (ranges::empty(__iter.__parent_->__base_))
|
||||
return {};
|
||||
if (!__iter.__inner_.has_value())
|
||||
return __segment_iterator(--__iter.__outer_, __iter.__parent_);
|
||||
return __segment_iterator(__iter.__outer_, __iter.__parent_);
|
||||
}
|
||||
|
||||
static constexpr _LIBCPP_HIDE_FROM_ABI __local_iterator __local(_JoinViewIterator __iter) {
|
||||
if (ranges::empty(__iter.__parent_->__base_))
|
||||
return {};
|
||||
if (!__iter.__inner_.has_value())
|
||||
return ranges::end(*--__iter.__outer_);
|
||||
return *__iter.__inner_;
|
||||
if (ranges::empty(__iter.__parent_->__base_))
|
||||
return {};
|
||||
if (!__iter.__inner_.has_value())
|
||||
return ranges::end(*--__iter.__outer_);
|
||||
return *__iter.__inner_;
|
||||
}
|
||||
|
||||
static constexpr _LIBCPP_HIDE_FROM_ABI __local_iterator __begin(__segment_iterator __iter) {
|
||||
return ranges::begin(*__iter.__get_iter());
|
||||
return ranges::begin(*__iter.__get_iter());
|
||||
}
|
||||
|
||||
static constexpr _LIBCPP_HIDE_FROM_ABI __local_iterator __end(__segment_iterator __iter) {
|
||||
return ranges::end(*__iter.__get_iter());
|
||||
return ranges::end(*__iter.__get_iter());
|
||||
}
|
||||
|
||||
static constexpr _LIBCPP_HIDE_FROM_ABI _JoinViewIterator
|
||||
__compose(__segment_iterator __seg_iter, __local_iterator __local_iter) {
|
||||
return _JoinViewIterator(
|
||||
std::move(__seg_iter).__get_data(), std::move(__seg_iter).__get_iter(), std::move(__local_iter));
|
||||
return _JoinViewIterator(
|
||||
std::move(__seg_iter).__get_data(), std::move(__seg_iter).__get_iter(), std::move(__local_iter));
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #if _LIBCPP_STD_VER >= 20 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
|
||||
#endif // #if _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_JOIN_VIEW_H
|
||||
|
|
252
third_party/libcxx/__ranges/lazy_split_view.h
vendored
252
third_party/libcxx/__ranges/lazy_split_view.h
vendored
|
@ -47,79 +47,82 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <auto> struct __require_constant;
|
||||
template <auto>
|
||||
struct __require_constant;
|
||||
|
||||
template <class _Range>
|
||||
concept __tiny_range =
|
||||
sized_range<_Range> &&
|
||||
requires { typename __require_constant<remove_reference_t<_Range>::size()>; } &&
|
||||
(remove_reference_t<_Range>::size() <= 1);
|
||||
concept __tiny_range = sized_range<_Range> && requires {
|
||||
typename __require_constant<remove_reference_t<_Range>::size()>;
|
||||
} && (remove_reference_t<_Range>::size() <= 1);
|
||||
|
||||
template <input_range _View, forward_range _Pattern>
|
||||
requires view<_View> && view<_Pattern> &&
|
||||
indirectly_comparable<iterator_t<_View>, iterator_t<_Pattern>, ranges::equal_to> &&
|
||||
(forward_range<_View> || __tiny_range<_Pattern>)
|
||||
class lazy_split_view : public view_interface<lazy_split_view<_View, _Pattern>> {
|
||||
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Pattern __pattern_ = _Pattern();
|
||||
|
||||
using _MaybeCurrent = _If<!forward_range<_View>, __non_propagating_cache<iterator_t<_View>>, __empty_cache>;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _MaybeCurrent __current_ = _MaybeCurrent();
|
||||
|
||||
template <bool> struct __outer_iterator;
|
||||
template <bool> struct __inner_iterator;
|
||||
template <bool>
|
||||
struct __outer_iterator;
|
||||
template <bool>
|
||||
struct __inner_iterator;
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
lazy_split_view()
|
||||
requires default_initializable<_View> && default_initializable<_Pattern> = default;
|
||||
_LIBCPP_HIDE_FROM_ABI lazy_split_view()
|
||||
requires default_initializable<_View> && default_initializable<_Pattern>
|
||||
= default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 lazy_split_view(_View __base, _Pattern __pattern)
|
||||
: __base_(std::move(__base)), __pattern_(std::move(__pattern)) {}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 lazy_split_view(_View __base, _Pattern __pattern)
|
||||
: __base_(std::move(__base)), __pattern_(std::move(__pattern)) {}
|
||||
|
||||
template <input_range _Range>
|
||||
requires constructible_from<_View, views::all_t<_Range>> &&
|
||||
constructible_from<_Pattern, single_view<range_value_t<_Range>>>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
|
||||
: __base_(views::all(std::forward<_Range>(__r)))
|
||||
, __pattern_(views::single(std::move(__e))) {}
|
||||
constructible_from<_Pattern, single_view<range_value_t<_Range>>>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
|
||||
: __base_(views::all(std::forward<_Range>(__r))), __pattern_(views::single(std::move(__e))) {}
|
||||
|
||||
_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 _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 begin() {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto begin() {
|
||||
if constexpr (forward_range<_View>) {
|
||||
return __outer_iterator<__simple_view<_View> && __simple_view<_Pattern>>{*this, ranges::begin(__base_)};
|
||||
return __outer_iterator < __simple_view<_View> && __simple_view < _Pattern >> {*this, ranges::begin(__base_)};
|
||||
} else {
|
||||
__current_.__emplace(ranges::begin(__base_));
|
||||
return __outer_iterator<false>{*this};
|
||||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto begin() const requires forward_range<_View> && forward_range<const _View> {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
|
||||
requires forward_range<_View> && forward_range<const _View>
|
||||
{
|
||||
return __outer_iterator<true>{*this, ranges::begin(__base_)};
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto end() requires forward_range<_View> && common_range<_View> {
|
||||
return __outer_iterator<__simple_view<_View> && __simple_view<_Pattern>>{*this, ranges::end(__base_)};
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto end()
|
||||
requires forward_range<_View> && common_range<_View>
|
||||
{
|
||||
return __outer_iterator < __simple_view<_View> && __simple_view < _Pattern >> {*this, ranges::end(__base_)};
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto end() const {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto end() const {
|
||||
if constexpr (forward_range<_View> && forward_range<const _View> && common_range<const _View>) {
|
||||
return __outer_iterator<true>{*this, ranges::end(__base_)};
|
||||
} else {
|
||||
|
@ -128,7 +131,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
template <class>
|
||||
struct __outer_iterator_category {};
|
||||
|
||||
|
@ -145,15 +147,14 @@ private:
|
|||
friend __outer_iterator<true>;
|
||||
|
||||
using _Parent = __maybe_const<_Const, lazy_split_view>;
|
||||
using _Base = __maybe_const<_Const, _View>;
|
||||
using _Base = __maybe_const<_Const, _View>;
|
||||
|
||||
_Parent* __parent_ = nullptr;
|
||||
using _MaybeCurrent = _If<forward_range<_View>, iterator_t<_Base>, __empty_cache>;
|
||||
_Parent* __parent_ = nullptr;
|
||||
using _MaybeCurrent = _If<forward_range<_View>, iterator_t<_Base>, __empty_cache>;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _MaybeCurrent __current_ = _MaybeCurrent();
|
||||
bool __trailing_empty_ = false;
|
||||
bool __trailing_empty_ = false;
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto& __current() noexcept {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto& __current() noexcept {
|
||||
if constexpr (forward_range<_View>) {
|
||||
return __current_;
|
||||
} else {
|
||||
|
@ -161,8 +162,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr const auto& __current() const noexcept {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const auto& __current() const noexcept {
|
||||
if constexpr (forward_range<_View>) {
|
||||
return __current_;
|
||||
} else {
|
||||
|
@ -172,56 +172,42 @@ private:
|
|||
|
||||
// Workaround for the GCC issue that doesn't allow calling `__parent_->__base_` from friend functions (because
|
||||
// `__base_` is private).
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto& __parent_base() const noexcept {
|
||||
return __parent_->__base_;
|
||||
}
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto& __parent_base() const noexcept { return __parent_->__base_; }
|
||||
|
||||
public:
|
||||
// using iterator_category = inherited;
|
||||
using iterator_concept = conditional_t<forward_range<_Base>, forward_iterator_tag, input_iterator_tag>;
|
||||
using difference_type = range_difference_t<_Base>;
|
||||
using difference_type = range_difference_t<_Base>;
|
||||
|
||||
struct value_type : view_interface<value_type> {
|
||||
private:
|
||||
__outer_iterator __i_ = __outer_iterator();
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
value_type() = default;
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit value_type(__outer_iterator __i)
|
||||
: __i_(std::move(__i)) {}
|
||||
_LIBCPP_HIDE_FROM_ABI value_type() = default;
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit value_type(__outer_iterator __i) : __i_(std::move(__i)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __inner_iterator<_Const> begin() const { return __inner_iterator<_Const>{__i_}; }
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr default_sentinel_t end() const noexcept { return default_sentinel; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __inner_iterator<_Const> begin() const { return __inner_iterator<_Const>{__i_}; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr default_sentinel_t end() const noexcept { return default_sentinel; }
|
||||
};
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
__outer_iterator() = default;
|
||||
_LIBCPP_HIDE_FROM_ABI __outer_iterator() = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit __outer_iterator(_Parent& __parent)
|
||||
requires (!forward_range<_Base>)
|
||||
: __parent_(std::addressof(__parent)) {}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __outer_iterator(_Parent& __parent)
|
||||
requires(!forward_range<_Base>)
|
||||
: __parent_(std::addressof(__parent)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __outer_iterator(_Parent& __parent, iterator_t<_Base> __current)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __outer_iterator(_Parent& __parent, iterator_t<_Base> __current)
|
||||
requires forward_range<_Base>
|
||||
: __parent_(std::addressof(__parent)), __current_(std::move(__current)) {}
|
||||
: __parent_(std::addressof(__parent)), __current_(std::move(__current)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __outer_iterator(__outer_iterator<!_Const> __i)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __outer_iterator(__outer_iterator<!_Const> __i)
|
||||
requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
|
||||
: __parent_(__i.__parent_), __current_(std::move(__i.__current_)) {}
|
||||
: __parent_(__i.__parent_), __current_(std::move(__i.__current_)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr value_type operator*() const { return value_type{*this}; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr value_type operator*() const { return value_type{*this}; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __outer_iterator& operator++() {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __outer_iterator& operator++() {
|
||||
const auto __end = ranges::end(__parent_->__base_);
|
||||
if (__current() == __end) {
|
||||
__trailing_empty_ = false;
|
||||
|
@ -260,8 +246,7 @@ private:
|
|||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr decltype(auto) operator++(int) {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator++(int) {
|
||||
if constexpr (forward_range<_Base>) {
|
||||
auto __tmp = *this;
|
||||
++*this;
|
||||
|
@ -272,15 +257,14 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator==(const __outer_iterator& __x, const __outer_iterator& __y)
|
||||
requires forward_range<_Base> {
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __outer_iterator& __x, const __outer_iterator& __y)
|
||||
requires forward_range<_Base>
|
||||
{
|
||||
return __x.__current_ == __y.__current_ && __x.__trailing_empty_ == __y.__trailing_empty_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator==(const __outer_iterator& __x, default_sentinel_t) {
|
||||
_LIBCPP_ASSERT(__x.__parent_, "Cannot call comparison on a default-constructed iterator.");
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __outer_iterator& __x, default_sentinel_t) {
|
||||
_LIBCPP_ASSERT_NON_NULL(__x.__parent_ != nullptr, "Cannot call comparison on a default-constructed iterator.");
|
||||
return __x.__current() == ranges::end(__x.__parent_base()) && !__x.__trailing_empty_;
|
||||
}
|
||||
};
|
||||
|
@ -290,11 +274,10 @@ private:
|
|||
|
||||
template <forward_range _Tp>
|
||||
struct __inner_iterator_category<_Tp> {
|
||||
using iterator_category = _If<
|
||||
derived_from<typename iterator_traits<iterator_t<_Tp>>::iterator_category, forward_iterator_tag>,
|
||||
forward_iterator_tag,
|
||||
typename iterator_traits<iterator_t<_Tp>>::iterator_category
|
||||
>;
|
||||
using iterator_category =
|
||||
_If< derived_from<typename iterator_traits<iterator_t<_Tp>>::iterator_category, forward_iterator_tag>,
|
||||
forward_iterator_tag,
|
||||
typename iterator_traits<iterator_t<_Tp>>::iterator_category >;
|
||||
};
|
||||
|
||||
template <bool _Const>
|
||||
|
@ -303,18 +286,17 @@ private:
|
|||
using _Base = __maybe_const<_Const, _View>;
|
||||
// Workaround for a GCC issue.
|
||||
static constexpr bool _OuterConst = _Const;
|
||||
__outer_iterator<_Const> __i_ = __outer_iterator<_OuterConst>();
|
||||
bool __incremented_ = false;
|
||||
__outer_iterator<_Const> __i_ = __outer_iterator<_OuterConst>();
|
||||
bool __incremented_ = false;
|
||||
|
||||
// Note: these private functions are necessary because GCC doesn't allow calls to private members of `__i_` from
|
||||
// free functions that are friends of `inner-iterator`.
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr bool __is_done() const {
|
||||
_LIBCPP_ASSERT(__i_.__parent_, "Cannot call comparison on a default-constructed iterator.");
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr bool __is_done() const {
|
||||
_LIBCPP_ASSERT_NON_NULL(__i_.__parent_ != nullptr, "Cannot call comparison on a default-constructed iterator.");
|
||||
|
||||
auto [__pcur, __pend] = ranges::subrange{__i_.__parent_->__pattern_};
|
||||
auto __end = ranges::end(__i_.__parent_->__base_);
|
||||
auto __end = ranges::end(__i_.__parent_->__base_);
|
||||
|
||||
if constexpr (__tiny_range<_Pattern>) {
|
||||
const auto& __cur = __i_.__current();
|
||||
|
@ -343,40 +325,32 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto& __outer_current() noexcept {
|
||||
return __i_.__current();
|
||||
}
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto& __outer_current() noexcept { return __i_.__current(); }
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr const auto& __outer_current() const noexcept {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const auto& __outer_current() const noexcept {
|
||||
return __i_.__current();
|
||||
}
|
||||
|
||||
public:
|
||||
// using iterator_category = inherited;
|
||||
using iterator_concept = typename __outer_iterator<_Const>::iterator_concept;
|
||||
using value_type = range_value_t<_Base>;
|
||||
using difference_type = range_difference_t<_Base>;
|
||||
using value_type = range_value_t<_Base>;
|
||||
using difference_type = range_difference_t<_Base>;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
__inner_iterator() = default;
|
||||
_LIBCPP_HIDE_FROM_ABI __inner_iterator() = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit __inner_iterator(__outer_iterator<_Const> __i)
|
||||
: __i_(std::move(__i)) {}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __inner_iterator(__outer_iterator<_Const> __i) : __i_(std::move(__i)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr const iterator_t<_Base>& base() const& noexcept { return __i_.__current(); }
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr iterator_t<_Base> base() &&
|
||||
requires forward_range<_View> { return std::move(__i_.__current()); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept { return __i_.__current(); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() &&
|
||||
requires forward_range<_View>
|
||||
{
|
||||
return std::move(__i_.__current());
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr decltype(auto) operator*() const { return *__i_.__current(); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const { return *__i_.__current(); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __inner_iterator& operator++() {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __inner_iterator& operator++() {
|
||||
__incremented_ = true;
|
||||
|
||||
if constexpr (!forward_range<_Base>) {
|
||||
|
@ -389,8 +363,7 @@ private:
|
|||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr decltype(auto) operator++(int) {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator++(int) {
|
||||
if constexpr (forward_range<_Base>) {
|
||||
auto __tmp = *this;
|
||||
++*this;
|
||||
|
@ -401,54 +374,51 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator==(const __inner_iterator& __x, const __inner_iterator& __y)
|
||||
requires forward_range<_Base> {
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __inner_iterator& __x, const __inner_iterator& __y)
|
||||
requires forward_range<_Base>
|
||||
{
|
||||
return __x.__outer_current() == __y.__outer_current();
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator==(const __inner_iterator& __x, default_sentinel_t) {
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __inner_iterator& __x, default_sentinel_t) {
|
||||
return __x.__is_done();
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr decltype(auto) iter_move(const __inner_iterator& __i)
|
||||
noexcept(noexcept(ranges::iter_move(__i.__outer_current()))) {
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr decltype(auto)
|
||||
iter_move(const __inner_iterator& __i) noexcept(noexcept(ranges::iter_move(__i.__outer_current()))) {
|
||||
return ranges::iter_move(__i.__outer_current());
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr void iter_swap(const __inner_iterator& __x, const __inner_iterator& __y)
|
||||
noexcept(noexcept(ranges::iter_swap(__x.__outer_current(), __y.__outer_current())))
|
||||
requires indirectly_swappable<iterator_t<_Base>> {
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr void iter_swap(
|
||||
const __inner_iterator& __x,
|
||||
const __inner_iterator& __y) noexcept(noexcept(ranges::iter_swap(__x.__outer_current(), __y.__outer_current())))
|
||||
requires indirectly_swappable<iterator_t<_Base>>
|
||||
{
|
||||
ranges::iter_swap(__x.__outer_current(), __y.__outer_current());
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template <class _Range, class _Pattern>
|
||||
lazy_split_view(_Range&&, _Pattern&&) -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;
|
||||
|
||||
template <input_range _Range>
|
||||
lazy_split_view(_Range&&, range_value_t<_Range>)
|
||||
-> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
|
||||
lazy_split_view(_Range&&,
|
||||
range_value_t<_Range>) -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;
|
||||
|
||||
namespace views {
|
||||
namespace __lazy_split_view {
|
||||
struct __fn : __range_adaptor_closure<__fn> {
|
||||
struct __fn {
|
||||
template <class _Range, class _Pattern>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __range, _Pattern&& __pattern) const
|
||||
noexcept(noexcept(lazy_split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern))))
|
||||
-> decltype( lazy_split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern)))
|
||||
{ return lazy_split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern)); }
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Pattern&& __pattern) const
|
||||
noexcept(noexcept(lazy_split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern))))
|
||||
-> decltype(lazy_split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern))) {
|
||||
return lazy_split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern));
|
||||
}
|
||||
|
||||
template <class _Pattern>
|
||||
requires constructible_from<decay_t<_Pattern>, _Pattern>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Pattern&& __pattern) const
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pattern&& __pattern) const
|
||||
noexcept(is_nothrow_constructible_v<decay_t<_Pattern>, _Pattern>) {
|
||||
return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pattern>(__pattern)));
|
||||
}
|
||||
|
@ -456,7 +426,7 @@ struct __fn : __range_adaptor_closure<__fn> {
|
|||
} // namespace __lazy_split_view
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto lazy_split = __lazy_split_view::__fn{};
|
||||
inline constexpr auto lazy_split = __lazy_split_view::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace views
|
||||
|
||||
|
@ -466,4 +436,6 @@ inline namespace __cpo {
|
|||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_LAZY_SPLIT_VIEW_H
|
||||
|
|
247
third_party/libcxx/__ranges/movable_box.h
vendored
Normal file
247
third_party/libcxx/__ranges/movable_box.h
vendored
Normal file
|
@ -0,0 +1,247 @@
|
|||
// -*- 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_MOVABLE_BOX_H
|
||||
#define _LIBCPP___RANGES_MOVABLE_BOX_H
|
||||
|
||||
#include <__concepts/constructible.h>
|
||||
#include <__concepts/copyable.h>
|
||||
#include <__concepts/movable.h>
|
||||
#include <__config>
|
||||
#include <__memory/addressof.h>
|
||||
#include <__memory/construct_at.h>
|
||||
#include <__type_traits/is_nothrow_constructible.h>
|
||||
#include <__utility/move.h>
|
||||
#include <optional>
|
||||
|
||||
#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 >= 20
|
||||
|
||||
// __movable_box allows turning a type that is move-constructible (but maybe not move-assignable) into
|
||||
// a type that is both move-constructible and move-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
|
||||
// __movable_box that does this, see below for the details.
|
||||
|
||||
// until C++23, `__movable_box` was named `__copyable_box` and required the stored type to be copy-constructible, not
|
||||
// just move-constructible; we preserve the old behavior in pre-C++23 modes.
|
||||
template <class _Tp>
|
||||
concept __movable_box_object =
|
||||
# if _LIBCPP_STD_VER >= 23
|
||||
move_constructible<_Tp>
|
||||
# else
|
||||
copy_constructible<_Tp>
|
||||
# endif
|
||||
&& is_object_v<_Tp>;
|
||||
|
||||
namespace ranges {
|
||||
// Primary template - uses std::optional and introduces an empty state in case assignment fails.
|
||||
template <__movable_box_object _Tp>
|
||||
class __movable_box {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS optional<_Tp> __val_;
|
||||
|
||||
public:
|
||||
template <class... _Args>
|
||||
requires is_constructible_v<_Tp, _Args...>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __movable_box(in_place_t, _Args&&... __args) noexcept(
|
||||
is_nothrow_constructible_v<_Tp, _Args...>)
|
||||
: __val_(in_place, std::forward<_Args>(__args)...) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __movable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
|
||||
requires default_initializable<_Tp>
|
||||
: __val_(in_place) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box const&) = default;
|
||||
_LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box&&) = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __movable_box&
|
||||
operator=(__movable_box const& __other) noexcept(is_nothrow_copy_constructible_v<_Tp>)
|
||||
# if _LIBCPP_STD_VER >= 23
|
||||
requires copy_constructible<_Tp>
|
||||
# endif
|
||||
{
|
||||
if (this != std::addressof(__other)) {
|
||||
if (__other.__has_value())
|
||||
__val_.emplace(*__other);
|
||||
else
|
||||
__val_.reset();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box&&)
|
||||
requires movable<_Tp>
|
||||
= default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __movable_box&
|
||||
operator=(__movable_box&& __other) noexcept(is_nothrow_move_constructible_v<_Tp>) {
|
||||
if (this != std::addressof(__other)) {
|
||||
if (__other.__has_value())
|
||||
__val_.emplace(std::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 const _Tp* operator->() const noexcept { return __val_.operator->(); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { return __val_.operator->(); }
|
||||
|
||||
_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.
|
||||
|
||||
# if _LIBCPP_STD_VER >= 23
|
||||
template <class _Tp>
|
||||
concept __doesnt_need_empty_state =
|
||||
(copy_constructible<_Tp>
|
||||
// 1. If copy_constructible<T> is true, movable-box<T> should store only a T if either T models
|
||||
// copyable, or is_nothrow_move_constructible_v<T> && is_nothrow_copy_constructible_v<T> is true.
|
||||
? copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Tp>)
|
||||
// 2. Otherwise, movable-box<T> should store only a T if either T models movable or
|
||||
// is_nothrow_move_constructible_v<T> is true.
|
||||
: movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);
|
||||
|
||||
// When _Tp doesn't have an assignment operator, we must implement __movable_box's assignment operator
|
||||
// by doing destroy_at followed by construct_at. However, that implementation strategy leads to UB if the nested
|
||||
// _Tp is potentially overlapping, as it is doing a non-transparent replacement of the sub-object, which means that
|
||||
// we're not considered "nested" inside the movable-box anymore, and since we're not nested within it, [basic.life]/1.5
|
||||
// says that we essentially just reused the storage of the movable-box for a completely unrelated object and ended the
|
||||
// movable-box's lifetime.
|
||||
// https://github.com/llvm/llvm-project/issues/70494#issuecomment-1845646490
|
||||
//
|
||||
// Hence, when the _Tp doesn't have an assignment operator, we can't risk making it a potentially-overlapping
|
||||
// subobject because of the above, and we don't use [[no_unique_address]] in that case.
|
||||
template <class _Tp>
|
||||
concept __can_use_no_unique_address = (copy_constructible<_Tp> ? copyable<_Tp> : movable<_Tp>);
|
||||
|
||||
# else
|
||||
|
||||
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 <class _Tp>
|
||||
concept __doesnt_need_empty_state = __doesnt_need_empty_state_for_copy<_Tp> && __doesnt_need_empty_state_for_move<_Tp>;
|
||||
|
||||
template <class _Tp>
|
||||
concept __can_use_no_unique_address = copyable<_Tp>;
|
||||
# endif
|
||||
|
||||
template <class _Tp>
|
||||
struct __movable_box_holder {
|
||||
_Tp __val_;
|
||||
|
||||
template <class... _Args>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __movable_box_holder(in_place_t, _Args&&... __args)
|
||||
: __val_(std::forward<_Args>(__args)...) {}
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
requires __can_use_no_unique_address<_Tp>
|
||||
struct __movable_box_holder<_Tp> {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_;
|
||||
|
||||
template <class... _Args>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __movable_box_holder(in_place_t, _Args&&... __args)
|
||||
: __val_(std::forward<_Args>(__args)...) {}
|
||||
};
|
||||
|
||||
template <__movable_box_object _Tp>
|
||||
requires __doesnt_need_empty_state<_Tp>
|
||||
class __movable_box<_Tp> {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS __movable_box_holder<_Tp> __holder_;
|
||||
|
||||
public:
|
||||
template <class... _Args>
|
||||
requires is_constructible_v<_Tp, _Args...>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __movable_box(in_place_t __inplace, _Args&&... __args) noexcept(
|
||||
is_nothrow_constructible_v<_Tp, _Args...>)
|
||||
: __holder_(__inplace, std::forward<_Args>(__args)...) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __movable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
|
||||
requires default_initializable<_Tp>
|
||||
: __holder_(in_place_t{}) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box const&) = default;
|
||||
_LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box&&) = default;
|
||||
|
||||
// Implementation of assignment operators in case we perform optimization (1)
|
||||
_LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box const&)
|
||||
requires copyable<_Tp>
|
||||
= default;
|
||||
_LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box&&)
|
||||
requires movable<_Tp>
|
||||
= default;
|
||||
|
||||
// Implementation of assignment operators in case we perform optimization (2)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __movable_box& operator=(__movable_box const& __other) noexcept {
|
||||
static_assert(is_nothrow_copy_constructible_v<_Tp>);
|
||||
static_assert(!__can_use_no_unique_address<_Tp>);
|
||||
if (this != std::addressof(__other)) {
|
||||
std::destroy_at(std::addressof(__holder_.__val_));
|
||||
std::construct_at(std::addressof(__holder_.__val_), __other.__holder_.__val_);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __movable_box& operator=(__movable_box&& __other) noexcept {
|
||||
static_assert(is_nothrow_move_constructible_v<_Tp>);
|
||||
static_assert(!__can_use_no_unique_address<_Tp>);
|
||||
if (this != std::addressof(__other)) {
|
||||
std::destroy_at(std::addressof(__holder_.__val_));
|
||||
std::construct_at(std::addressof(__holder_.__val_), std::move(__other.__holder_.__val_));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return __holder_.__val_; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return __holder_.__val_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { return std::addressof(__holder_.__val_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { return std::addressof(__holder_.__val_); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; }
|
||||
};
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_MOVABLE_BOX_H
|
141
third_party/libcxx/__ranges/non_propagating_cache.h
vendored
141
third_party/libcxx/__ranges/non_propagating_cache.h
vendored
|
@ -26,85 +26,74 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
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 {
|
||||
struct __from_tag { };
|
||||
struct __forward_tag { };
|
||||
// __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 {
|
||||
struct __from_tag {};
|
||||
struct __forward_tag {};
|
||||
|
||||
// This helper class is needed to perform copy and move elision when
|
||||
// constructing the contained type from an iterator.
|
||||
struct __wrapper {
|
||||
template <class... _Args>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __wrapper(__forward_tag, _Args&&... __args)
|
||||
: __t_(std::forward<_Args>(__args)...) {}
|
||||
template <class _Fn>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __wrapper(__from_tag, _Fn const& __f) : __t_(__f()) {}
|
||||
_Tp __t_;
|
||||
};
|
||||
|
||||
optional<__wrapper> __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 != std::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_->__t_; }
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _Tp const& operator*() const { return __value_->__t_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr bool __has_value() const { return __value_.has_value(); }
|
||||
|
||||
template<class _Fn>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _Tp& __emplace_from(_Fn const& __f) {
|
||||
return __value_.emplace(__from_tag{}, __f).__t_;
|
||||
}
|
||||
|
||||
template<class ..._Args>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _Tp& __emplace(_Args&& ...__args) {
|
||||
return __value_.emplace(__forward_tag{}, std::forward<_Args>(__args)...).__t_;
|
||||
}
|
||||
// This helper class is needed to perform copy and move elision when
|
||||
// constructing the contained type from an iterator.
|
||||
struct __wrapper {
|
||||
template <class... _Args>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __wrapper(__forward_tag, _Args&&... __args)
|
||||
: __t_(std::forward<_Args>(__args)...) {}
|
||||
template <class _Fn>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __wrapper(__from_tag, _Fn const& __f) : __t_(__f()) {}
|
||||
_Tp __t_;
|
||||
};
|
||||
|
||||
struct __empty_cache { };
|
||||
optional<__wrapper> __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 != std::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_->__t_; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const { return __value_->__t_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const { return __value_.has_value(); }
|
||||
|
||||
template <class _Fn>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Tp& __emplace_from(_Fn const& __f) {
|
||||
return __value_.emplace(__from_tag{}, __f).__t_;
|
||||
}
|
||||
|
||||
template <class... _Args>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Tp& __emplace(_Args&&... __args) {
|
||||
return __value_.emplace(__forward_tag{}, std::forward<_Args>(__args)...).__t_;
|
||||
}
|
||||
};
|
||||
|
||||
struct __empty_cache {};
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
|
97
third_party/libcxx/__ranges/owning_view.h
vendored
97
third_party/libcxx/__ranges/owning_view.h
vendored
|
@ -27,52 +27,83 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
template<range _Rp>
|
||||
requires movable<_Rp> && (!__is_std_initializer_list<remove_cvref_t<_Rp>>)
|
||||
class owning_view : public view_interface<owning_view<_Rp>> {
|
||||
_Rp __r_ = _Rp();
|
||||
template <range _Rp>
|
||||
requires movable<_Rp> && (!__is_std_initializer_list<remove_cvref_t<_Rp>>)
|
||||
class owning_view : public view_interface<owning_view<_Rp>> {
|
||||
_Rp __r_ = _Rp();
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI owning_view() requires default_initializable<_Rp> = default;
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr owning_view(_Rp&& __r) : __r_(std::move(__r)) {}
|
||||
_LIBCPP_HIDE_FROM_ABI owning_view()
|
||||
requires default_initializable<_Rp>
|
||||
= default;
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr owning_view(_Rp&& __r) : __r_(std::move(__r)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI owning_view(owning_view&&) = default;
|
||||
_LIBCPP_HIDE_FROM_ABI owning_view& operator=(owning_view&&) = default;
|
||||
_LIBCPP_HIDE_FROM_ABI owning_view(owning_view&&) = default;
|
||||
_LIBCPP_HIDE_FROM_ABI owning_view& operator=(owning_view&&) = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Rp& base() & noexcept { return __r_; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr const _Rp& base() const& noexcept { return __r_; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Rp&& base() && noexcept { return std::move(__r_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr const _Rp&& base() const&& noexcept { return std::move(__r_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Rp& base() & noexcept { return __r_; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr const _Rp& base() const& noexcept { return __r_; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Rp&& base() && noexcept { return std::move(__r_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr const _Rp&& base() const&& noexcept { return std::move(__r_); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Rp> begin() { return ranges::begin(__r_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Rp> end() { return ranges::end(__r_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto begin() const requires range<const _Rp> { return ranges::begin(__r_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto end() const requires range<const _Rp> { return ranges::end(__r_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Rp> begin() { return ranges::begin(__r_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Rp> end() { return ranges::end(__r_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
|
||||
requires range<const _Rp>
|
||||
{
|
||||
return ranges::begin(__r_);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto end() const
|
||||
requires range<const _Rp>
|
||||
{
|
||||
return ranges::end(__r_);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr bool empty() requires requires { ranges::empty(__r_); }
|
||||
{ return ranges::empty(__r_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr bool empty() const requires requires { ranges::empty(__r_); }
|
||||
{ return ranges::empty(__r_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr bool empty()
|
||||
requires requires { ranges::empty(__r_); }
|
||||
{
|
||||
return ranges::empty(__r_);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
|
||||
requires requires { ranges::empty(__r_); }
|
||||
{
|
||||
return ranges::empty(__r_);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto size() requires sized_range<_Rp>
|
||||
{ return ranges::size(__r_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto size() const requires sized_range<const _Rp>
|
||||
{ return ranges::size(__r_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto size()
|
||||
requires sized_range<_Rp>
|
||||
{
|
||||
return ranges::size(__r_);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto size() const
|
||||
requires sized_range<const _Rp>
|
||||
{
|
||||
return ranges::size(__r_);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto data() requires contiguous_range<_Rp>
|
||||
{ return ranges::data(__r_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto data() const requires contiguous_range<const _Rp>
|
||||
{ return ranges::data(__r_); }
|
||||
};
|
||||
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(owning_view);
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto data()
|
||||
requires contiguous_range<_Rp>
|
||||
{
|
||||
return ranges::data(__r_);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto data() const
|
||||
requires contiguous_range<const _Rp>
|
||||
{
|
||||
return ranges::data(__r_);
|
||||
}
|
||||
};
|
||||
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(owning_view);
|
||||
|
||||
template<class _Tp>
|
||||
inline constexpr bool enable_borrowed_range<owning_view<_Tp>> = enable_borrowed_range<_Tp>;
|
||||
template <class _Tp>
|
||||
inline constexpr bool enable_borrowed_range<owning_view<_Tp>> = enable_borrowed_range<_Tp>;
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
|
@ -80,4 +111,6 @@ public:
|
|||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_OWNING_VIEW_H
|
||||
|
|
62
third_party/libcxx/__ranges/range_adaptor.h
vendored
62
third_party/libcxx/__ranges/range_adaptor.h
vendored
|
@ -19,6 +19,7 @@
|
|||
#include <__functional/invoke.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__type_traits/decay.h>
|
||||
#include <__type_traits/is_class.h>
|
||||
#include <__type_traits/is_nothrow_constructible.h>
|
||||
#include <__type_traits/remove_cvref.h>
|
||||
#include <__utility/forward.h>
|
||||
|
@ -28,52 +29,73 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
|
||||
// CRTP base that one can derive from in order to be considered a range adaptor closure
|
||||
// by the library. When deriving from this class, a pipe operator will be provided to
|
||||
// make the following hold:
|
||||
// - `x | f` is equivalent to `f(x)`
|
||||
// - `f1 | f2` is an adaptor closure `g` such that `g(x)` is equivalent to `f2(f1(x))`
|
||||
template <class _Tp>
|
||||
requires is_class_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
|
||||
struct __range_adaptor_closure;
|
||||
|
||||
// Type that wraps an arbitrary function object and makes it into a range adaptor closure,
|
||||
// i.e. something that can be called via the `x | f` notation.
|
||||
template <class _Fn>
|
||||
struct __range_adaptor_closure_t : _Fn, __range_adaptor_closure<__range_adaptor_closure_t<_Fn>> {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __range_adaptor_closure_t(_Fn&& __f) : _Fn(std::move(__f)) { }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __range_adaptor_closure_t(_Fn&& __f) : _Fn(std::move(__f)) {}
|
||||
};
|
||||
_LIBCPP_CTAD_SUPPORTED_FOR_TYPE(__range_adaptor_closure_t);
|
||||
|
||||
template <class _Tp>
|
||||
concept _RangeAdaptorClosure = derived_from<remove_cvref_t<_Tp>, __range_adaptor_closure<remove_cvref_t<_Tp>>>;
|
||||
_Tp __derived_from_range_adaptor_closure(__range_adaptor_closure<_Tp>*);
|
||||
|
||||
template <class _Tp>
|
||||
struct __range_adaptor_closure {
|
||||
template <ranges::viewable_range _View, _RangeAdaptorClosure _Closure>
|
||||
requires same_as<_Tp, remove_cvref_t<_Closure>> &&
|
||||
invocable<_Closure, _View>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr decltype(auto) operator|(_View&& __view, _Closure&& __closure)
|
||||
noexcept(is_nothrow_invocable_v<_Closure, _View>)
|
||||
{ return std::invoke(std::forward<_Closure>(__closure), std::forward<_View>(__view)); }
|
||||
|
||||
template <_RangeAdaptorClosure _Closure, _RangeAdaptorClosure _OtherClosure>
|
||||
requires same_as<_Tp, remove_cvref_t<_Closure>> &&
|
||||
constructible_from<decay_t<_Closure>, _Closure> &&
|
||||
constructible_from<decay_t<_OtherClosure>, _OtherClosure>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr auto operator|(_Closure&& __c1, _OtherClosure&& __c2)
|
||||
noexcept(is_nothrow_constructible_v<decay_t<_Closure>, _Closure> &&
|
||||
is_nothrow_constructible_v<decay_t<_OtherClosure>, _OtherClosure>)
|
||||
{ return __range_adaptor_closure_t(std::__compose(std::forward<_OtherClosure>(__c2), std::forward<_Closure>(__c1))); }
|
||||
concept _RangeAdaptorClosure = !ranges::range<remove_cvref_t<_Tp>> && requires {
|
||||
// Ensure that `remove_cvref_t<_Tp>` is derived from `__range_adaptor_closure<remove_cvref_t<_Tp>>` and isn't derived
|
||||
// from `__range_adaptor_closure<U>` for any other type `U`.
|
||||
{ ranges::__derived_from_range_adaptor_closure((remove_cvref_t<_Tp>*)nullptr) } -> same_as<remove_cvref_t<_Tp>>;
|
||||
};
|
||||
|
||||
template <ranges::range _Range, _RangeAdaptorClosure _Closure>
|
||||
requires invocable<_Closure, _Range>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto)
|
||||
operator|(_Range&& __range, _Closure&& __closure) noexcept(is_nothrow_invocable_v<_Closure, _Range>) {
|
||||
return std::invoke(std::forward<_Closure>(__closure), std::forward<_Range>(__range));
|
||||
}
|
||||
|
||||
template <_RangeAdaptorClosure _Closure, _RangeAdaptorClosure _OtherClosure>
|
||||
requires constructible_from<decay_t<_Closure>, _Closure> && constructible_from<decay_t<_OtherClosure>, _OtherClosure>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator|(_Closure&& __c1, _OtherClosure&& __c2) noexcept(
|
||||
is_nothrow_constructible_v<decay_t<_Closure>, _Closure> &&
|
||||
is_nothrow_constructible_v<decay_t<_OtherClosure>, _OtherClosure>) {
|
||||
return __range_adaptor_closure_t(std::__compose(std::forward<_OtherClosure>(__c2), std::forward<_Closure>(__c1)));
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
requires is_class_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
|
||||
struct __range_adaptor_closure {};
|
||||
|
||||
# if _LIBCPP_STD_VER >= 23
|
||||
template <class _Tp>
|
||||
requires is_class_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>>
|
||||
class range_adaptor_closure : public __range_adaptor_closure<_Tp> {};
|
||||
# endif // _LIBCPP_STD_VER >= 23
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_RANGE_ADAPTOR_H
|
||||
|
|
66
third_party/libcxx/__ranges/rbegin.h
vendored
66
third_party/libcxx/__ranges/rbegin.h
vendored
|
@ -36,57 +36,43 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
namespace ranges {
|
||||
namespace __rbegin {
|
||||
template <class _Tp>
|
||||
concept __member_rbegin =
|
||||
__can_borrow<_Tp> &&
|
||||
__workaround_52970<_Tp> &&
|
||||
requires(_Tp&& __t) {
|
||||
{ _LIBCPP_AUTO_CAST(__t.rbegin()) } -> input_or_output_iterator;
|
||||
};
|
||||
concept __member_rbegin = __can_borrow<_Tp> && requires(_Tp&& __t) {
|
||||
{ _LIBCPP_AUTO_CAST(__t.rbegin()) } -> input_or_output_iterator;
|
||||
};
|
||||
|
||||
void rbegin(auto&) = delete;
|
||||
void rbegin(const auto&) = delete;
|
||||
void rbegin() = delete;
|
||||
|
||||
template <class _Tp>
|
||||
concept __unqualified_rbegin =
|
||||
!__member_rbegin<_Tp> &&
|
||||
__can_borrow<_Tp> &&
|
||||
__class_or_enum<remove_cvref_t<_Tp>> &&
|
||||
requires(_Tp&& __t) {
|
||||
{ _LIBCPP_AUTO_CAST(rbegin(__t)) } -> input_or_output_iterator;
|
||||
};
|
||||
!__member_rbegin<_Tp> && __can_borrow<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {
|
||||
{ _LIBCPP_AUTO_CAST(rbegin(__t)) } -> input_or_output_iterator;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
concept __can_reverse =
|
||||
__can_borrow<_Tp> &&
|
||||
!__member_rbegin<_Tp> &&
|
||||
!__unqualified_rbegin<_Tp> &&
|
||||
requires(_Tp&& __t) {
|
||||
{ ranges::begin(__t) } -> same_as<decltype(ranges::end(__t))>;
|
||||
{ ranges::begin(__t) } -> bidirectional_iterator;
|
||||
};
|
||||
__can_borrow<_Tp> && !__member_rbegin<_Tp> && !__unqualified_rbegin<_Tp> && requires(_Tp&& __t) {
|
||||
{ ranges::begin(__t) } -> same_as<decltype(ranges::end(__t))>;
|
||||
{ ranges::begin(__t) } -> bidirectional_iterator;
|
||||
};
|
||||
|
||||
struct __fn {
|
||||
template <class _Tp>
|
||||
requires __member_rbegin<_Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.rbegin())))
|
||||
{
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.rbegin()))) {
|
||||
return _LIBCPP_AUTO_CAST(__t.rbegin());
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
requires __unqualified_rbegin<_Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(rbegin(__t))))
|
||||
{
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(rbegin(__t)))) {
|
||||
return _LIBCPP_AUTO_CAST(rbegin(__t));
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
requires __can_reverse<_Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::end(__t)))
|
||||
{
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const noexcept(noexcept(ranges::end(__t))) {
|
||||
return std::make_reverse_iterator(ranges::end(__t));
|
||||
}
|
||||
|
||||
|
@ -95,7 +81,7 @@ struct __fn {
|
|||
} // namespace __rbegin
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto rbegin = __rbegin::__fn{};
|
||||
inline constexpr auto rbegin = __rbegin::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
|
@ -106,24 +92,24 @@ namespace __crbegin {
|
|||
struct __fn {
|
||||
template <class _Tp>
|
||||
requires is_lvalue_reference_v<_Tp&&>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t))))
|
||||
-> decltype( ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t)))
|
||||
{ return ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t)); }
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t))))
|
||||
-> decltype(ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t))) {
|
||||
return ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t));
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
requires is_rvalue_reference_v<_Tp&&>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::rbegin(static_cast<const _Tp&&>(__t))))
|
||||
-> decltype( ranges::rbegin(static_cast<const _Tp&&>(__t)))
|
||||
{ return ranges::rbegin(static_cast<const _Tp&&>(__t)); }
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::rbegin(static_cast<const _Tp&&>(__t))))
|
||||
-> decltype(ranges::rbegin(static_cast<const _Tp&&>(__t))) {
|
||||
return ranges::rbegin(static_cast<const _Tp&&>(__t));
|
||||
}
|
||||
};
|
||||
} // namespace __crbegin
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto crbegin = __crbegin::__fn{};
|
||||
inline constexpr auto crbegin = __crbegin::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
|
|
66
third_party/libcxx/__ranges/ref_view.h
vendored
66
third_party/libcxx/__ranges/ref_view.h
vendored
|
@ -37,49 +37,49 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
template<range _Range>
|
||||
requires is_object_v<_Range>
|
||||
class ref_view : public view_interface<ref_view<_Range>> {
|
||||
_Range *__range_;
|
||||
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;
|
||||
static void __fun(_Range&);
|
||||
static void __fun(_Range&&) = delete; // NOLINT(modernize-use-equals-delete) ; This is llvm.org/PR54276
|
||||
|
||||
public:
|
||||
template<class _Tp>
|
||||
requires __different_from<_Tp, ref_view> &&
|
||||
convertible_to<_Tp, _Range&> && requires { __fun(std::declval<_Tp>()); }
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr ref_view(_Tp&& __t)
|
||||
: __range_(std::addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
|
||||
{}
|
||||
template <class _Tp>
|
||||
requires __different_from<_Tp, ref_view> && convertible_to<_Tp, _Range&> && requires { __fun(std::declval<_Tp>()); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr ref_view(_Tp&& __t)
|
||||
: __range_(std::addressof(static_cast<_Range&>(std::forward<_Tp>(__t)))) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Range& base() const { return *__range_; }
|
||||
_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 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 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 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_); }
|
||||
};
|
||||
_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>;
|
||||
template <class _Range>
|
||||
ref_view(_Range&) -> ref_view<_Range>;
|
||||
|
||||
template<class _Tp>
|
||||
inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
|
||||
template <class _Tp>
|
||||
inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
|
69
third_party/libcxx/__ranges/rend.h
vendored
69
third_party/libcxx/__ranges/rend.h
vendored
|
@ -37,60 +37,46 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
namespace ranges {
|
||||
namespace __rend {
|
||||
template <class _Tp>
|
||||
concept __member_rend =
|
||||
__can_borrow<_Tp> &&
|
||||
__workaround_52970<_Tp> &&
|
||||
requires(_Tp&& __t) {
|
||||
ranges::rbegin(__t);
|
||||
{ _LIBCPP_AUTO_CAST(__t.rend()) } -> sentinel_for<decltype(ranges::rbegin(__t))>;
|
||||
};
|
||||
concept __member_rend = __can_borrow<_Tp> && requires(_Tp&& __t) {
|
||||
ranges::rbegin(__t);
|
||||
{ _LIBCPP_AUTO_CAST(__t.rend()) } -> sentinel_for<decltype(ranges::rbegin(__t))>;
|
||||
};
|
||||
|
||||
void rend(auto&) = delete;
|
||||
void rend(const auto&) = delete;
|
||||
void rend() = delete;
|
||||
|
||||
template <class _Tp>
|
||||
concept __unqualified_rend =
|
||||
!__member_rend<_Tp> &&
|
||||
__can_borrow<_Tp> &&
|
||||
__class_or_enum<remove_cvref_t<_Tp>> &&
|
||||
requires(_Tp&& __t) {
|
||||
ranges::rbegin(__t);
|
||||
{ _LIBCPP_AUTO_CAST(rend(__t)) } -> sentinel_for<decltype(ranges::rbegin(__t))>;
|
||||
};
|
||||
!__member_rend<_Tp> && __can_borrow<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {
|
||||
ranges::rbegin(__t);
|
||||
{ _LIBCPP_AUTO_CAST(rend(__t)) } -> sentinel_for<decltype(ranges::rbegin(__t))>;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
concept __can_reverse =
|
||||
__can_borrow<_Tp> &&
|
||||
!__member_rend<_Tp> &&
|
||||
!__unqualified_rend<_Tp> &&
|
||||
requires(_Tp&& __t) {
|
||||
{ ranges::begin(__t) } -> same_as<decltype(ranges::end(__t))>;
|
||||
{ ranges::begin(__t) } -> bidirectional_iterator;
|
||||
};
|
||||
concept __can_reverse = __can_borrow<_Tp> && !__member_rend<_Tp> && !__unqualified_rend<_Tp> && requires(_Tp&& __t) {
|
||||
{ ranges::begin(__t) } -> same_as<decltype(ranges::end(__t))>;
|
||||
{ ranges::begin(__t) } -> bidirectional_iterator;
|
||||
};
|
||||
|
||||
class __fn {
|
||||
public:
|
||||
template <class _Tp>
|
||||
requires __member_rend<_Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.rend())))
|
||||
{
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.rend()))) {
|
||||
return _LIBCPP_AUTO_CAST(__t.rend());
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
requires __unqualified_rend<_Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(rend(__t))))
|
||||
{
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(rend(__t)))) {
|
||||
return _LIBCPP_AUTO_CAST(rend(__t));
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
requires __can_reverse<_Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::begin(__t)))
|
||||
{
|
||||
noexcept(noexcept(ranges::begin(__t))) {
|
||||
return std::make_reverse_iterator(ranges::begin(__t));
|
||||
}
|
||||
|
||||
|
@ -99,7 +85,7 @@ public:
|
|||
} // namespace __rend
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto rend = __rend::__fn{};
|
||||
inline constexpr auto rend = __rend::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
|
@ -110,24 +96,23 @@ namespace __crend {
|
|||
struct __fn {
|
||||
template <class _Tp>
|
||||
requires is_lvalue_reference_v<_Tp&&>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t))))
|
||||
-> decltype( ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t)))
|
||||
{ return ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t)); }
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t))))
|
||||
-> decltype(ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t))) {
|
||||
return ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t));
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
requires is_rvalue_reference_v<_Tp&&>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(ranges::rend(static_cast<const _Tp&&>(__t))))
|
||||
-> decltype( ranges::rend(static_cast<const _Tp&&>(__t)))
|
||||
{ return ranges::rend(static_cast<const _Tp&&>(__t)); }
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const noexcept(
|
||||
noexcept(ranges::rend(static_cast<const _Tp&&>(__t)))) -> decltype(ranges::rend(static_cast<const _Tp&&>(__t))) {
|
||||
return ranges::rend(static_cast<const _Tp&&>(__t));
|
||||
}
|
||||
};
|
||||
} // namespace __crend
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto crend = __crend::__fn{};
|
||||
inline constexpr auto crend = __crend::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
|
|
266
third_party/libcxx/__ranges/repeat_view.h
vendored
Normal file
266
third_party/libcxx/__ranges/repeat_view.h
vendored
Normal file
|
@ -0,0 +1,266 @@
|
|||
// -*- 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_REPEAT_VIEW_H
|
||||
#define _LIBCPP___RANGES_REPEAT_VIEW_H
|
||||
|
||||
#include <__assert>
|
||||
#include <__concepts/constructible.h>
|
||||
#include <__concepts/same_as.h>
|
||||
#include <__concepts/semiregular.h>
|
||||
#include <__config>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__iterator/unreachable_sentinel.h>
|
||||
#include <__memory/addressof.h>
|
||||
#include <__ranges/iota_view.h>
|
||||
#include <__ranges/movable_box.h>
|
||||
#include <__ranges/view_interface.h>
|
||||
#include <__type_traits/decay.h>
|
||||
#include <__type_traits/is_object.h>
|
||||
#include <__type_traits/make_unsigned.h>
|
||||
#include <__type_traits/remove_cv.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <__utility/in_place.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/piecewise_construct.h>
|
||||
#include <tuple>
|
||||
|
||||
#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 >= 23
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template <class _Tp>
|
||||
concept __integer_like_with_usable_difference_type =
|
||||
__signed_integer_like<_Tp> || (__integer_like<_Tp> && weakly_incrementable<_Tp>);
|
||||
|
||||
template <class _Tp>
|
||||
struct __repeat_view_iterator_difference {
|
||||
using type = _IotaDiffT<_Tp>;
|
||||
};
|
||||
|
||||
template <__signed_integer_like _Tp>
|
||||
struct __repeat_view_iterator_difference<_Tp> {
|
||||
using type = _Tp;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
using __repeat_view_iterator_difference_t = typename __repeat_view_iterator_difference<_Tp>::type;
|
||||
|
||||
namespace views::__drop {
|
||||
struct __fn;
|
||||
} // namespace views::__drop
|
||||
|
||||
namespace views::__take {
|
||||
struct __fn;
|
||||
} // namespace views::__take
|
||||
|
||||
template <move_constructible _Tp, semiregular _Bound = unreachable_sentinel_t>
|
||||
requires(is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>> &&
|
||||
(__integer_like_with_usable_difference_type<_Bound> || same_as<_Bound, unreachable_sentinel_t>))
|
||||
class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS repeat_view : public view_interface<repeat_view<_Tp, _Bound>> {
|
||||
friend struct views::__take::__fn;
|
||||
friend struct views::__drop::__fn;
|
||||
class __iterator;
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI repeat_view()
|
||||
requires default_initializable<_Tp>
|
||||
= default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view(const _Tp& __value, _Bound __bound_sentinel = _Bound())
|
||||
requires copy_constructible<_Tp>
|
||||
: __value_(in_place, __value), __bound_(__bound_sentinel) {
|
||||
if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
|
||||
_LIBCPP_ASSERT_UNCATEGORIZED(__bound_ >= 0, "The value of bound must be greater than or equal to 0");
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view(_Tp&& __value, _Bound __bound_sentinel = _Bound())
|
||||
: __value_(in_place, std::move(__value)), __bound_(__bound_sentinel) {
|
||||
if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
|
||||
_LIBCPP_ASSERT_UNCATEGORIZED(__bound_ >= 0, "The value of bound must be greater than or equal to 0");
|
||||
}
|
||||
|
||||
template <class... _TpArgs, class... _BoundArgs>
|
||||
requires(constructible_from<_Tp, _TpArgs...> && constructible_from<_Bound, _BoundArgs...>)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit repeat_view(
|
||||
piecewise_construct_t, tuple<_TpArgs...> __value_args, tuple<_BoundArgs...> __bound_args = tuple<>{})
|
||||
: __value_(in_place, std::make_from_tuple<_Tp>(std::move(__value_args))),
|
||||
__bound_(std::make_from_tuple<_Bound>(std::move(__bound_args))) {
|
||||
if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
|
||||
_LIBCPP_ASSERT_UNCATEGORIZED(
|
||||
__bound_ >= 0, "The behavior is undefined if Bound is not unreachable_sentinel_t and bound is negative");
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator begin() const { return __iterator(std::addressof(*__value_)); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator end() const
|
||||
requires(!same_as<_Bound, unreachable_sentinel_t>)
|
||||
{
|
||||
return __iterator(std::addressof(*__value_), __bound_);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr unreachable_sentinel_t end() const noexcept { return unreachable_sentinel; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto size() const
|
||||
requires(!same_as<_Bound, unreachable_sentinel_t>)
|
||||
{
|
||||
return std::__to_unsigned_like(__bound_);
|
||||
}
|
||||
|
||||
private:
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Tp> __value_;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Bound __bound_ = _Bound();
|
||||
};
|
||||
|
||||
template <class _Tp, class _Bound = unreachable_sentinel_t>
|
||||
repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>;
|
||||
|
||||
// [range.repeat.iterator]
|
||||
template <move_constructible _Tp, semiregular _Bound>
|
||||
requires(is_object_v<_Tp> && same_as<_Tp, remove_cv_t<_Tp>> &&
|
||||
(__integer_like_with_usable_difference_type<_Bound> || same_as<_Bound, unreachable_sentinel_t>))
|
||||
class repeat_view<_Tp, _Bound>::__iterator {
|
||||
friend class repeat_view;
|
||||
|
||||
using _IndexT = conditional_t<same_as<_Bound, unreachable_sentinel_t>, ptrdiff_t, _Bound>;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(const _Tp* __value, _IndexT __bound_sentinel = _IndexT())
|
||||
: __value_(__value), __current_(__bound_sentinel) {}
|
||||
|
||||
public:
|
||||
using iterator_concept = random_access_iterator_tag;
|
||||
using iterator_category = random_access_iterator_tag;
|
||||
using value_type = _Tp;
|
||||
using difference_type = __repeat_view_iterator_difference_t<_IndexT>;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI __iterator() = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator*() const noexcept { return *__value_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
|
||||
++__current_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int) {
|
||||
auto __tmp = *this;
|
||||
++*this;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--() {
|
||||
if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
|
||||
_LIBCPP_ASSERT_UNCATEGORIZED(__current_ > 0, "The value of bound must be greater than or equal to 0");
|
||||
--__current_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int) {
|
||||
auto __tmp = *this;
|
||||
--*this;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __n) {
|
||||
if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
|
||||
_LIBCPP_ASSERT_UNCATEGORIZED(__current_ + __n >= 0, "The value of bound must be greater than or equal to 0");
|
||||
__current_ += __n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __n) {
|
||||
if constexpr (!same_as<_Bound, unreachable_sentinel_t>)
|
||||
_LIBCPP_ASSERT_UNCATEGORIZED(__current_ - __n >= 0, "The value of bound must be greater than or equal to 0");
|
||||
__current_ -= __n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator[](difference_type __n) const noexcept { return *(*this + __n); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y) {
|
||||
return __x.__current_ == __y.__current_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) {
|
||||
return __x.__current_ <=> __y.__current_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(__iterator __i, difference_type __n) {
|
||||
__i += __n;
|
||||
return __i;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, __iterator __i) {
|
||||
__i += __n;
|
||||
return __i;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(__iterator __i, difference_type __n) {
|
||||
__i -= __n;
|
||||
return __i;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y) {
|
||||
return static_cast<difference_type>(__x.__current_) - static_cast<difference_type>(__y.__current_);
|
||||
}
|
||||
|
||||
private:
|
||||
const _Tp* __value_ = nullptr;
|
||||
_IndexT __current_ = _IndexT();
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
namespace views {
|
||||
namespace __repeat {
|
||||
struct __fn {
|
||||
template <class _Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Tp&& __value)
|
||||
noexcept(noexcept(ranges::repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value))))
|
||||
-> decltype( ranges::repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value)))
|
||||
{ return ranges::repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value)); }
|
||||
|
||||
template <class _Tp, class _Bound>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Tp&& __value, _Bound&& __bound_sentinel)
|
||||
noexcept(noexcept(ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel))))
|
||||
-> decltype( ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel)))
|
||||
{ return ranges::repeat_view(std::forward<_Tp>(__value), std::forward<_Bound>(__bound_sentinel)); }
|
||||
};
|
||||
} // namespace __repeat
|
||||
// clang-format on
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto repeat = __repeat::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace views
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr bool __is_repeat_specialization = false;
|
||||
|
||||
template <class _Tp, class _Bound>
|
||||
inline constexpr bool __is_repeat_specialization<repeat_view<_Tp, _Bound>> = true;
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 23
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_REPEAT_VIEW_H
|
247
third_party/libcxx/__ranges/reverse_view.h
vendored
247
third_party/libcxx/__ranges/reverse_view.h
vendored
|
@ -33,160 +33,171 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
template<view _View>
|
||||
requires bidirectional_range<_View>
|
||||
class reverse_view : public view_interface<reverse_view<_View>> {
|
||||
// We cache begin() whenever ranges::next is not guaranteed O(1) to provide an
|
||||
// amortized O(1) begin() method.
|
||||
static constexpr bool _UseCache = !random_access_range<_View> && !common_range<_View>;
|
||||
using _Cache = _If<_UseCache, __non_propagating_cache<reverse_iterator<iterator_t<_View>>>, __empty_cache>;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache();
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
|
||||
template <view _View>
|
||||
requires bidirectional_range<_View>
|
||||
class reverse_view : public view_interface<reverse_view<_View>> {
|
||||
// We cache begin() whenever ranges::next is not guaranteed O(1) to provide an
|
||||
// amortized O(1) begin() method.
|
||||
static constexpr bool _UseCache = !random_access_range<_View> && !common_range<_View>;
|
||||
using _Cache = _If<_UseCache, __non_propagating_cache<reverse_iterator<iterator_t<_View>>>, __empty_cache>;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache();
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
reverse_view() requires default_initializable<_View> = default;
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI reverse_view()
|
||||
requires default_initializable<_View>
|
||||
= default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit reverse_view(_View __view) : __base_(std::move(__view)) {}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit reverse_view(_View __view) : __base_(std::move(__view)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _View base() const& requires copy_constructible<_View> { return __base_; }
|
||||
_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 _View base() && { return std::move(__base_); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr reverse_iterator<iterator_t<_View>> begin() {
|
||||
if constexpr (_UseCache)
|
||||
if (__cached_begin_.__has_value())
|
||||
return *__cached_begin_;
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator<iterator_t<_View>> begin() {
|
||||
if constexpr (_UseCache)
|
||||
if (__cached_begin_.__has_value())
|
||||
return *__cached_begin_;
|
||||
|
||||
auto __tmp = std::make_reverse_iterator(ranges::next(ranges::begin(__base_), ranges::end(__base_)));
|
||||
if constexpr (_UseCache)
|
||||
__cached_begin_.__emplace(__tmp);
|
||||
return __tmp;
|
||||
}
|
||||
auto __tmp = std::make_reverse_iterator(ranges::next(ranges::begin(__base_), ranges::end(__base_)));
|
||||
if constexpr (_UseCache)
|
||||
__cached_begin_.__emplace(__tmp);
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr reverse_iterator<iterator_t<_View>> begin() requires common_range<_View> {
|
||||
return std::make_reverse_iterator(ranges::end(__base_));
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator<iterator_t<_View>> begin()
|
||||
requires common_range<_View>
|
||||
{
|
||||
return std::make_reverse_iterator(ranges::end(__base_));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto begin() const requires common_range<const _View> {
|
||||
return std::make_reverse_iterator(ranges::end(__base_));
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
|
||||
requires common_range<const _View>
|
||||
{
|
||||
return std::make_reverse_iterator(ranges::end(__base_));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr reverse_iterator<iterator_t<_View>> end() {
|
||||
return std::make_reverse_iterator(ranges::begin(__base_));
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator<iterator_t<_View>> end() {
|
||||
return std::make_reverse_iterator(ranges::begin(__base_));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto end() const requires common_range<const _View> {
|
||||
return std::make_reverse_iterator(ranges::begin(__base_));
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto end() const
|
||||
requires common_range<const _View>
|
||||
{
|
||||
return std::make_reverse_iterator(ranges::begin(__base_));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto size() requires sized_range<_View> {
|
||||
return ranges::size(__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_);
|
||||
}
|
||||
};
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto size() const
|
||||
requires sized_range<const _View>
|
||||
{
|
||||
return ranges::size(__base_);
|
||||
}
|
||||
};
|
||||
|
||||
template<class _Range>
|
||||
reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
|
||||
template <class _Range>
|
||||
reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
|
||||
|
||||
template<class _Tp>
|
||||
inline constexpr bool enable_borrowed_range<reverse_view<_Tp>> = enable_borrowed_range<_Tp>;
|
||||
template <class _Tp>
|
||||
inline constexpr bool enable_borrowed_range<reverse_view<_Tp>> = enable_borrowed_range<_Tp>;
|
||||
|
||||
namespace views {
|
||||
namespace __reverse {
|
||||
template<class _Tp>
|
||||
inline constexpr bool __is_reverse_view = false;
|
||||
namespace views {
|
||||
namespace __reverse {
|
||||
template <class _Tp>
|
||||
inline constexpr bool __is_reverse_view = false;
|
||||
|
||||
template<class _Tp>
|
||||
inline constexpr bool __is_reverse_view<reverse_view<_Tp>> = true;
|
||||
template <class _Tp>
|
||||
inline constexpr bool __is_reverse_view<reverse_view<_Tp>> = true;
|
||||
|
||||
template<class _Tp>
|
||||
inline constexpr bool __is_sized_reverse_subrange = false;
|
||||
template <class _Tp>
|
||||
inline constexpr bool __is_sized_reverse_subrange = false;
|
||||
|
||||
template<class _Iter>
|
||||
inline constexpr bool __is_sized_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, subrange_kind::sized>> = true;
|
||||
template <class _Iter>
|
||||
inline constexpr bool
|
||||
__is_sized_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, subrange_kind::sized>> =
|
||||
true;
|
||||
|
||||
template<class _Tp>
|
||||
inline constexpr bool __is_unsized_reverse_subrange = false;
|
||||
template <class _Tp>
|
||||
inline constexpr bool __is_unsized_reverse_subrange = false;
|
||||
|
||||
template<class _Iter, subrange_kind _Kind>
|
||||
inline constexpr bool __is_unsized_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, _Kind>> = _Kind == subrange_kind::unsized;
|
||||
template <class _Iter, subrange_kind _Kind>
|
||||
inline constexpr bool __is_unsized_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, _Kind>> =
|
||||
_Kind == subrange_kind::unsized;
|
||||
|
||||
template<class _Tp>
|
||||
struct __unwrapped_reverse_subrange {
|
||||
using type = void; // avoid SFINAE-ing out the overload below -- let the concept requirements do it for better diagnostics
|
||||
};
|
||||
template <class _Tp>
|
||||
struct __unwrapped_reverse_subrange {
|
||||
using type =
|
||||
void; // avoid SFINAE-ing out the overload below -- let the concept requirements do it for better diagnostics
|
||||
};
|
||||
|
||||
template<class _Iter, subrange_kind _Kind>
|
||||
struct __unwrapped_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, _Kind>> {
|
||||
using type = subrange<_Iter, _Iter, _Kind>;
|
||||
};
|
||||
template <class _Iter, subrange_kind _Kind>
|
||||
struct __unwrapped_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, _Kind>> {
|
||||
using type = subrange<_Iter, _Iter, _Kind>;
|
||||
};
|
||||
|
||||
struct __fn : __range_adaptor_closure<__fn> {
|
||||
template<class _Range>
|
||||
requires __is_reverse_view<remove_cvref_t<_Range>>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __range) const
|
||||
noexcept(noexcept(std::forward<_Range>(__range).base()))
|
||||
-> decltype( std::forward<_Range>(__range).base())
|
||||
{ return std::forward<_Range>(__range).base(); }
|
||||
struct __fn : __range_adaptor_closure<__fn> {
|
||||
template <class _Range>
|
||||
requires __is_reverse_view<remove_cvref_t<_Range>>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
|
||||
noexcept(noexcept(std::forward<_Range>(__range).base())) -> decltype(std::forward<_Range>(__range).base()) {
|
||||
return std::forward<_Range>(__range).base();
|
||||
}
|
||||
|
||||
template<class _Range,
|
||||
class _UnwrappedSubrange = typename __unwrapped_reverse_subrange<remove_cvref_t<_Range>>::type>
|
||||
requires __is_sized_reverse_subrange<remove_cvref_t<_Range>>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __range) const
|
||||
noexcept(noexcept(_UnwrappedSubrange(__range.end().base(), __range.begin().base(), __range.size())))
|
||||
-> decltype( _UnwrappedSubrange(__range.end().base(), __range.begin().base(), __range.size()))
|
||||
{ return _UnwrappedSubrange(__range.end().base(), __range.begin().base(), __range.size()); }
|
||||
template <class _Range,
|
||||
class _UnwrappedSubrange = typename __unwrapped_reverse_subrange<remove_cvref_t<_Range>>::type>
|
||||
requires __is_sized_reverse_subrange<remove_cvref_t<_Range>>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
|
||||
noexcept(noexcept(_UnwrappedSubrange(__range.end().base(), __range.begin().base(), __range.size())))
|
||||
-> decltype(_UnwrappedSubrange(__range.end().base(), __range.begin().base(), __range.size())) {
|
||||
return _UnwrappedSubrange(__range.end().base(), __range.begin().base(), __range.size());
|
||||
}
|
||||
|
||||
template<class _Range,
|
||||
class _UnwrappedSubrange = typename __unwrapped_reverse_subrange<remove_cvref_t<_Range>>::type>
|
||||
requires __is_unsized_reverse_subrange<remove_cvref_t<_Range>>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __range) const
|
||||
noexcept(noexcept(_UnwrappedSubrange(__range.end().base(), __range.begin().base())))
|
||||
-> decltype( _UnwrappedSubrange(__range.end().base(), __range.begin().base()))
|
||||
{ return _UnwrappedSubrange(__range.end().base(), __range.begin().base()); }
|
||||
template <class _Range,
|
||||
class _UnwrappedSubrange = typename __unwrapped_reverse_subrange<remove_cvref_t<_Range>>::type>
|
||||
requires __is_unsized_reverse_subrange<remove_cvref_t<_Range>>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
|
||||
noexcept(noexcept(_UnwrappedSubrange(__range.end().base(), __range.begin().base())))
|
||||
-> decltype(_UnwrappedSubrange(__range.end().base(), __range.begin().base())) {
|
||||
return _UnwrappedSubrange(__range.end().base(), __range.begin().base());
|
||||
}
|
||||
|
||||
template<class _Range>
|
||||
requires (!__is_reverse_view<remove_cvref_t<_Range>> &&
|
||||
!__is_sized_reverse_subrange<remove_cvref_t<_Range>> &&
|
||||
!__is_unsized_reverse_subrange<remove_cvref_t<_Range>>)
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __range) const
|
||||
noexcept(noexcept(reverse_view{std::forward<_Range>(__range)}))
|
||||
-> decltype( reverse_view{std::forward<_Range>(__range)})
|
||||
{ return reverse_view{std::forward<_Range>(__range)}; }
|
||||
};
|
||||
} // namespace __reverse
|
||||
template <class _Range>
|
||||
requires(!__is_reverse_view<remove_cvref_t<_Range>> && !__is_sized_reverse_subrange<remove_cvref_t<_Range>> &&
|
||||
!__is_unsized_reverse_subrange<remove_cvref_t<_Range>>)
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const noexcept(noexcept(reverse_view{
|
||||
std::forward<_Range>(__range)})) -> decltype(reverse_view{std::forward<_Range>(__range)}) {
|
||||
return reverse_view{std::forward<_Range>(__range)};
|
||||
}
|
||||
};
|
||||
} // namespace __reverse
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto reverse = __reverse::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace views
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto reverse = __reverse::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace views
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 20
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_REVERSE_VIEW_H
|
||||
|
|
85
third_party/libcxx/__ranges/single_view.h
vendored
85
third_party/libcxx/__ranges/single_view.h
vendored
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include <__concepts/constructible.h>
|
||||
#include <__config>
|
||||
#include <__ranges/copyable_box.h>
|
||||
#include <__ranges/movable_box.h>
|
||||
#include <__ranges/range_adaptor.h>
|
||||
#include <__ranges/view_interface.h>
|
||||
#include <__type_traits/decay.h>
|
||||
|
@ -26,72 +26,77 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
template<copy_constructible _Tp>
|
||||
requires is_object_v<_Tp>
|
||||
class single_view : public view_interface<single_view<_Tp>> {
|
||||
__copyable_box<_Tp> __value_;
|
||||
# if _LIBCPP_STD_VER >= 23
|
||||
template <move_constructible _Tp>
|
||||
# else
|
||||
template <copy_constructible _Tp>
|
||||
# endif
|
||||
requires is_object_v<_Tp>
|
||||
class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS single_view : public view_interface<single_view<_Tp>> {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Tp> __value_;
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
single_view() requires default_initializable<_Tp> = default;
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI single_view()
|
||||
requires default_initializable<_Tp>
|
||||
= default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit single_view(const _Tp& __t) : __value_(in_place, __t) {}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(const _Tp& __t)
|
||||
# if _LIBCPP_STD_VER >= 23
|
||||
requires copy_constructible<_Tp>
|
||||
# endif
|
||||
: __value_(in_place, __t) {
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit single_view(_Tp&& __t) : __value_(in_place, std::move(__t)) {}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(_Tp&& __t) : __value_(in_place, std::move(__t)) {}
|
||||
|
||||
template<class... _Args>
|
||||
requires constructible_from<_Tp, _Args...>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit single_view(in_place_t, _Args&&... __args)
|
||||
template <class... _Args>
|
||||
requires constructible_from<_Tp, _Args...>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit single_view(in_place_t, _Args&&... __args)
|
||||
: __value_{in_place, std::forward<_Args>(__args)...} {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _Tp* begin() noexcept { return data(); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Tp* begin() noexcept { return data(); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr const _Tp* begin() const noexcept { return data(); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr const _Tp* begin() const noexcept { return data(); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _Tp* end() noexcept { return data() + 1; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Tp* end() noexcept { return data() + 1; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr const _Tp* end() const noexcept { return data() + 1; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr const _Tp* end() const noexcept { return data() + 1; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
static constexpr size_t size() noexcept { return 1; }
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr bool empty() noexcept { return false; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _Tp* data() noexcept { return __value_.operator->(); }
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr size_t size() noexcept { return 1; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr const _Tp* data() const noexcept { return __value_.operator->(); }
|
||||
};
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Tp* data() noexcept { return __value_.operator->(); }
|
||||
|
||||
template<class _Tp>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr const _Tp* data() const noexcept { return __value_.operator->(); }
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
single_view(_Tp) -> single_view<_Tp>;
|
||||
|
||||
namespace views {
|
||||
namespace __single_view {
|
||||
|
||||
struct __fn : __range_adaptor_closure<__fn> {
|
||||
template<class _Range>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __range) const
|
||||
noexcept(noexcept(single_view<decay_t<_Range&&>>(std::forward<_Range>(__range))))
|
||||
-> decltype( single_view<decay_t<_Range&&>>(std::forward<_Range>(__range)))
|
||||
{ return single_view<decay_t<_Range&&>>(std::forward<_Range>(__range)); }
|
||||
template <class _Range>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
|
||||
noexcept(noexcept(single_view<decay_t<_Range&&>>(std::forward<_Range>(__range))))
|
||||
-> decltype(single_view<decay_t<_Range&&>>(std::forward<_Range>(__range))) {
|
||||
return single_view<decay_t<_Range&&>>(std::forward<_Range>(__range));
|
||||
}
|
||||
};
|
||||
} // namespace __single_view
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto single = __single_view::__fn{};
|
||||
inline constexpr auto single = __single_view::__fn{};
|
||||
} // namespace __cpo
|
||||
|
||||
} // namespace views
|
||||
|
@ -101,4 +106,6 @@ inline namespace __cpo {
|
|||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_SINGLE_VIEW_H
|
||||
|
|
53
third_party/libcxx/__ranges/size.h
vendored
53
third_party/libcxx/__ranges/size.h
vendored
|
@ -33,49 +33,38 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
template<class>
|
||||
inline constexpr bool disable_sized_range = false;
|
||||
template <class>
|
||||
inline constexpr bool disable_sized_range = false;
|
||||
} // namespace ranges
|
||||
|
||||
// [range.prim.size]
|
||||
|
||||
namespace ranges {
|
||||
namespace __size {
|
||||
void size(auto&) = delete;
|
||||
void size(const auto&) = delete;
|
||||
void size() = delete;
|
||||
|
||||
template <class _Tp>
|
||||
concept __size_enabled = !disable_sized_range<remove_cvref_t<_Tp>>;
|
||||
|
||||
template <class _Tp>
|
||||
concept __member_size =
|
||||
__size_enabled<_Tp> &&
|
||||
__workaround_52970<_Tp> &&
|
||||
requires(_Tp&& __t) {
|
||||
{ _LIBCPP_AUTO_CAST(__t.size()) } -> __integer_like;
|
||||
};
|
||||
concept __member_size = __size_enabled<_Tp> && requires(_Tp&& __t) {
|
||||
{ _LIBCPP_AUTO_CAST(__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) {
|
||||
{ _LIBCPP_AUTO_CAST(size(__t)) } -> __integer_like;
|
||||
};
|
||||
__size_enabled<_Tp> && !__member_size<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {
|
||||
{ _LIBCPP_AUTO_CAST(size(__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(std::declval<_Tp>()))>;
|
||||
};
|
||||
!__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(std::declval<_Tp>()))>;
|
||||
};
|
||||
|
||||
struct __fn {
|
||||
|
||||
// `[range.prim.size]`: the array case (for rvalues).
|
||||
template <class _Tp, size_t _Sz>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&&)[_Sz]) const noexcept {
|
||||
|
@ -105,16 +94,16 @@ struct __fn {
|
|||
// [range.prim.size]: the `to-unsigned-like` case.
|
||||
template <__difference _Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
|
||||
noexcept(noexcept(std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t))))
|
||||
-> decltype( std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t)))
|
||||
{ return std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t));
|
||||
noexcept(noexcept(std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t))))
|
||||
-> decltype(std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t))) {
|
||||
return std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __size
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto size = __size::__fn{};
|
||||
inline constexpr auto size = __size::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
|
@ -123,10 +112,10 @@ inline namespace __cpo {
|
|||
namespace ranges {
|
||||
namespace __ssize {
|
||||
struct __fn {
|
||||
template<class _Tp>
|
||||
requires requires (_Tp&& __t) { ranges::size(__t); }
|
||||
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))) {
|
||||
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));
|
||||
|
@ -137,7 +126,7 @@ struct __fn {
|
|||
} // namespace __ssize
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto ssize = __ssize::__fn{};
|
||||
inline constexpr auto ssize = __ssize::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace ranges
|
||||
|
||||
|
|
11
third_party/libcxx/__ranges/split_view.h
vendored
11
third_party/libcxx/__ranges/split_view.h
vendored
|
@ -36,6 +36,9 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
@ -194,10 +197,10 @@ public:
|
|||
|
||||
namespace views {
|
||||
namespace __split_view {
|
||||
struct __fn : __range_adaptor_closure<__fn> {
|
||||
struct __fn {
|
||||
// clang-format off
|
||||
template <class _Range, class _Pattern>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __range, _Pattern&& __pattern) const
|
||||
noexcept(noexcept(split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern))))
|
||||
-> decltype( split_view(std::forward<_Range>(__range), std::forward<_Pattern>(__pattern)))
|
||||
|
@ -206,7 +209,7 @@ struct __fn : __range_adaptor_closure<__fn> {
|
|||
|
||||
template <class _Pattern>
|
||||
requires constructible_from<decay_t<_Pattern>, _Pattern>
|
||||
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pattern&& __pattern) const
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Pattern&& __pattern) const
|
||||
noexcept(is_nothrow_constructible_v<decay_t<_Pattern>, _Pattern>) {
|
||||
return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Pattern>(__pattern)));
|
||||
}
|
||||
|
@ -224,4 +227,6 @@ inline constexpr auto split = __split_view::__fn{};
|
|||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_SPLIT_VIEW_H
|
||||
|
|
370
third_party/libcxx/__ranges/subrange.h
vendored
370
third_party/libcxx/__ranges/subrange.h
vendored
|
@ -17,7 +17,6 @@
|
|||
#include <__concepts/derived_from.h>
|
||||
#include <__concepts/different_from.h>
|
||||
#include <__config>
|
||||
#include <__fwd/get.h>
|
||||
#include <__fwd/subrange.h>
|
||||
#include <__iterator/advance.h>
|
||||
#include <__iterator/concepts.h>
|
||||
|
@ -29,8 +28,8 @@
|
|||
#include <__ranges/enable_borrowed_range.h>
|
||||
#include <__ranges/size.h>
|
||||
#include <__ranges/view_interface.h>
|
||||
#include <__tuple/pair_like.h>
|
||||
#include <__tuple/tuple_element.h>
|
||||
#include <__tuple/tuple_like_no_subrange.h>
|
||||
#include <__tuple/tuple_size.h>
|
||||
#include <__type_traits/conditional.h>
|
||||
#include <__type_traits/decay.h>
|
||||
|
@ -46,213 +45,194 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
template<class _From, class _To>
|
||||
concept __uses_nonqualification_pointer_conversion =
|
||||
template <class _From, class _To>
|
||||
concept __uses_nonqualification_pointer_conversion =
|
||||
is_pointer_v<_From> && is_pointer_v<_To> &&
|
||||
!convertible_to<remove_pointer_t<_From>(*)[], remove_pointer_t<_To>(*)[]>;
|
||||
!convertible_to<remove_pointer_t<_From> (*)[], remove_pointer_t<_To> (*)[]>;
|
||||
|
||||
template<class _From, class _To>
|
||||
concept __convertible_to_non_slicing =
|
||||
convertible_to<_From, _To> &&
|
||||
!__uses_nonqualification_pointer_conversion<decay_t<_From>, decay_t<_To>>;
|
||||
template <class _From, class _To>
|
||||
concept __convertible_to_non_slicing =
|
||||
convertible_to<_From, _To> && !__uses_nonqualification_pointer_conversion<decay_t<_From>, decay_t<_To>>;
|
||||
|
||||
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>>;
|
||||
template <class _Pair, class _Iter, class _Sent>
|
||||
concept __pair_like_convertible_from =
|
||||
!range<_Pair> && __pair_like_no_subrange<_Pair> && constructible_from<_Pair, _Iter, _Sent> &&
|
||||
__convertible_to_non_slicing<_Iter, tuple_element_t<0, _Pair>> && convertible_to<_Sent, tuple_element_t<1, _Pair>>;
|
||||
|
||||
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>)
|
||||
class _LIBCPP_TEMPLATE_VIS subrange
|
||||
: public view_interface<subrange<_Iter, _Sent, _Kind>>
|
||||
{
|
||||
public:
|
||||
// Note: this is an internal implementation detail that is public only for internal usage.
|
||||
static constexpr bool _StoreSize = (_Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _Iter>);
|
||||
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>)
|
||||
class _LIBCPP_TEMPLATE_VIS subrange : public view_interface<subrange<_Iter, _Sent, _Kind>> {
|
||||
public:
|
||||
// Note: this is an internal implementation detail that is public only for internal usage.
|
||||
static constexpr bool _StoreSize = (_Kind == subrange_kind::sized && !sized_sentinel_for<_Sent, _Iter>);
|
||||
|
||||
private:
|
||||
static constexpr bool _MustProvideSizeAtConstruction = !_StoreSize; // just to improve compiler diagnostics
|
||||
struct _Empty { _LIBCPP_HIDE_FROM_ABI constexpr _Empty(auto) noexcept { } };
|
||||
using _Size = conditional_t<_StoreSize, make_unsigned_t<iter_difference_t<_Iter>>, _Empty>;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Iter __begin_ = _Iter();
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Sent __end_ = _Sent();
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Size __size_ = 0;
|
||||
|
||||
public:
|
||||
_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 _MustProvideSizeAtConstruction
|
||||
: __begin_(std::move(__iter)), __end_(std::move(__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)
|
||||
: __begin_(std::move(__iter)), __end_(std::move(__sent)), __size_(__n)
|
||||
{
|
||||
if constexpr (sized_sentinel_for<_Sent, _Iter>)
|
||||
_LIBCPP_ASSERT((__end_ - __begin_) == static_cast<iter_difference_t<_Iter>>(__n),
|
||||
"std::ranges::subrange was passed an invalid size hint");
|
||||
}
|
||||
|
||||
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 (!_StoreSize)
|
||||
: 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 _StoreSize && 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(__begin_, __end_);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _Iter begin() const requires copyable<_Iter> {
|
||||
return __begin_;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter begin() requires (!copyable<_Iter>) {
|
||||
return std::move(__begin_);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _Sent end() const {
|
||||
return __end_;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const {
|
||||
return __begin_ == __end_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr make_unsigned_t<iter_difference_t<_Iter>> size() const
|
||||
requires (_Kind == subrange_kind::sized)
|
||||
{
|
||||
if constexpr (_StoreSize)
|
||||
return __size_;
|
||||
else
|
||||
return std::__to_unsigned_like(__end_ - __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 std::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(__begin_, __n);
|
||||
if constexpr (_StoreSize)
|
||||
__size_ += std::__to_unsigned_like(-__n);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
auto __d = __n - ranges::advance(__begin_, __n, __end_);
|
||||
if constexpr (_StoreSize)
|
||||
__size_ -= std::__to_unsigned_like(__d);
|
||||
return *this;
|
||||
}
|
||||
private:
|
||||
static constexpr bool _MustProvideSizeAtConstruction = !_StoreSize; // just to improve compiler diagnostics
|
||||
struct _Empty {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Empty(auto) noexcept {}
|
||||
};
|
||||
using _Size = conditional_t<_StoreSize, make_unsigned_t<iter_difference_t<_Iter>>, _Empty>;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Iter __begin_ = _Iter();
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Sent __end_ = _Sent();
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _Size __size_ = 0;
|
||||
|
||||
template<input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent>
|
||||
subrange(_Iter, _Sent) -> subrange<_Iter, _Sent>;
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI subrange()
|
||||
requires default_initializable<_Iter>
|
||||
= default;
|
||||
|
||||
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>;
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr subrange(__convertible_to_non_slicing<_Iter> auto __iter, _Sent __sent)
|
||||
requires _MustProvideSizeAtConstruction
|
||||
: __begin_(std::move(__iter)), __end_(std::move(__sent)) {}
|
||||
|
||||
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>;
|
||||
_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)
|
||||
: __begin_(std::move(__iter)), __end_(std::move(__sent)), __size_(__n) {
|
||||
if constexpr (sized_sentinel_for<_Sent, _Iter>)
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS((__end_ - __begin_) == static_cast<iter_difference_t<_Iter>>(__n),
|
||||
"std::ranges::subrange was passed an invalid size hint");
|
||||
}
|
||||
|
||||
template<borrowed_range _Range>
|
||||
subrange(_Range&&, make_unsigned_t<range_difference_t<_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(!_StoreSize)
|
||||
: 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 _StoreSize && 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 <__pair_like_convertible_from<const _Iter&, const _Sent&> _Pair>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr operator _Pair() const {
|
||||
return _Pair(__begin_, __end_);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Iter begin() const
|
||||
requires copyable<_Iter>
|
||||
{
|
||||
return __begin_;
|
||||
}
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Iter begin()
|
||||
requires(!copyable<_Iter>)
|
||||
{
|
||||
return std::move(__begin_);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Sent end() const { return __end_; }
|
||||
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const { return __begin_ == __end_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr make_unsigned_t<iter_difference_t<_Iter>> size() const
|
||||
requires(_Kind == subrange_kind::sized)
|
||||
{
|
||||
if constexpr (_StoreSize)
|
||||
return __size_;
|
||||
else
|
||||
return std::__to_unsigned_like(__end_ - __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 std::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(__begin_, __n);
|
||||
if constexpr (_StoreSize)
|
||||
__size_ += std::__to_unsigned_like(-__n);
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
|
||||
auto __d = __n - ranges::advance(__begin_, __n, __end_);
|
||||
if constexpr (_StoreSize)
|
||||
__size_ -= std::__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 == 0 && copyable<_Iter>) || _Index == 1)
|
||||
_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 == 0 && copyable<_Iter>) || _Index == 1)
|
||||
_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 <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 <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>;
|
||||
template <range _Rp>
|
||||
using borrowed_subrange_t = _If<borrowed_range<_Rp>, subrange<iterator_t<_Rp>>, dangling>;
|
||||
} // namespace ranges
|
||||
|
||||
// [range.subrange.general]
|
||||
|
@ -261,25 +241,25 @@ using ranges::get;
|
|||
|
||||
// [ranges.syn]
|
||||
|
||||
template<class _Ip, class _Sp, ranges::subrange_kind _Kp>
|
||||
template <class _Ip, class _Sp, ranges::subrange_kind _Kp>
|
||||
struct tuple_size<ranges::subrange<_Ip, _Sp, _Kp>> : integral_constant<size_t, 2> {};
|
||||
|
||||
template<class _Ip, class _Sp, ranges::subrange_kind _Kp>
|
||||
template <class _Ip, class _Sp, ranges::subrange_kind _Kp>
|
||||
struct tuple_element<0, ranges::subrange<_Ip, _Sp, _Kp>> {
|
||||
using type = _Ip;
|
||||
};
|
||||
|
||||
template<class _Ip, class _Sp, ranges::subrange_kind _Kp>
|
||||
template <class _Ip, class _Sp, ranges::subrange_kind _Kp>
|
||||
struct tuple_element<1, ranges::subrange<_Ip, _Sp, _Kp>> {
|
||||
using type = _Sp;
|
||||
};
|
||||
|
||||
template<class _Ip, class _Sp, ranges::subrange_kind _Kp>
|
||||
template <class _Ip, class _Sp, ranges::subrange_kind _Kp>
|
||||
struct tuple_element<0, const ranges::subrange<_Ip, _Sp, _Kp>> {
|
||||
using type = _Ip;
|
||||
};
|
||||
|
||||
template<class _Ip, class _Sp, ranges::subrange_kind _Kp>
|
||||
template <class _Ip, class _Sp, ranges::subrange_kind _Kp>
|
||||
struct tuple_element<1, const ranges::subrange<_Ip, _Sp, _Kp>> {
|
||||
using type = _Sp;
|
||||
};
|
||||
|
@ -288,4 +268,6 @@ struct tuple_element<1, const ranges::subrange<_Ip, _Sp, _Kp>> {
|
|||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_SUBRANGE_H
|
||||
|
|
220
third_party/libcxx/__ranges/take_view.h
vendored
220
third_party/libcxx/__ranges/take_view.h
vendored
|
@ -31,6 +31,7 @@
|
|||
#include <__ranges/enable_borrowed_range.h>
|
||||
#include <__ranges/iota_view.h>
|
||||
#include <__ranges/range_adaptor.h>
|
||||
#include <__ranges/repeat_view.h>
|
||||
#include <__ranges/size.h>
|
||||
#include <__ranges/subrange.h>
|
||||
#include <__ranges/view_interface.h>
|
||||
|
@ -56,37 +57,42 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
|
||||
namespace ranges {
|
||||
|
||||
template<view _View>
|
||||
template <view _View>
|
||||
class take_view : public view_interface<take_view<_View>> {
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
|
||||
range_difference_t<_View> __count_ = 0;
|
||||
range_difference_t<_View> __count_ = 0;
|
||||
|
||||
template<bool> class __sentinel;
|
||||
template <bool>
|
||||
class __sentinel;
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
take_view() requires default_initializable<_View> = default;
|
||||
_LIBCPP_HIDE_FROM_ABI take_view()
|
||||
requires default_initializable<_View>
|
||||
= default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 take_view(_View __base, range_difference_t<_View> __count)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23
|
||||
take_view(_View __base, range_difference_t<_View> __count)
|
||||
: __base_(std::move(__base)), __count_(__count) {
|
||||
_LIBCPP_ASSERT(__count >= 0, "count has to be greater than or equal to zero");
|
||||
_LIBCPP_ASSERT_UNCATEGORIZED(__count >= 0, "count has to 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() const&
|
||||
requires copy_constructible<_View>
|
||||
{
|
||||
return __base_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _View base() && { return std::move(__base_); }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto begin() requires (!__simple_view<_View>) {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto begin()
|
||||
requires(!__simple_view<_View>)
|
||||
{
|
||||
if constexpr (sized_range<_View>) {
|
||||
if constexpr (random_access_range<_View>) {
|
||||
return ranges::begin(__base_);
|
||||
} else {
|
||||
using _DifferenceT = range_difference_t<_View>;
|
||||
auto __size = size();
|
||||
auto __size = size();
|
||||
return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size));
|
||||
}
|
||||
} else {
|
||||
|
@ -94,14 +100,15 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto begin() const requires range<const _View> {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
|
||||
requires range<const _View>
|
||||
{
|
||||
if constexpr (sized_range<const _View>) {
|
||||
if constexpr (random_access_range<const _View>) {
|
||||
return ranges::begin(__base_);
|
||||
} else {
|
||||
using _DifferenceT = range_difference_t<const _View>;
|
||||
auto __size = size();
|
||||
auto __size = size();
|
||||
return counted_iterator(ranges::begin(__base_), static_cast<_DifferenceT>(__size));
|
||||
}
|
||||
} else {
|
||||
|
@ -109,8 +116,9 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto end() requires (!__simple_view<_View>) {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto end()
|
||||
requires(!__simple_view<_View>)
|
||||
{
|
||||
if constexpr (sized_range<_View>) {
|
||||
if constexpr (random_access_range<_View>) {
|
||||
return ranges::begin(__base_) + size();
|
||||
|
@ -122,8 +130,9 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto end() const requires range<const _View> {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto end() const
|
||||
requires range<const _View>
|
||||
{
|
||||
if constexpr (sized_range<const _View>) {
|
||||
if constexpr (random_access_range<const _View>) {
|
||||
return ranges::begin(__base_) + size();
|
||||
|
@ -135,62 +144,58 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto size() requires sized_range<_View> {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto size()
|
||||
requires sized_range<_View>
|
||||
{
|
||||
auto __n = ranges::size(__base_);
|
||||
return ranges::min(__n, static_cast<decltype(__n)>(__count_));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto size() const requires sized_range<const _View> {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto size() const
|
||||
requires sized_range<const _View>
|
||||
{
|
||||
auto __n = ranges::size(__base_);
|
||||
return ranges::min(__n, static_cast<decltype(__n)>(__count_));
|
||||
}
|
||||
};
|
||||
|
||||
template<view _View>
|
||||
template<bool _Const>
|
||||
template <view _View>
|
||||
template <bool _Const>
|
||||
class take_view<_View>::__sentinel {
|
||||
using _Base = __maybe_const<_Const, _View>;
|
||||
template<bool _OtherConst>
|
||||
using _Iter = counted_iterator<iterator_t<__maybe_const<_OtherConst, _View>>>;
|
||||
template <bool _OtherConst>
|
||||
using _Iter = counted_iterator<iterator_t<__maybe_const<_OtherConst, _View>>>;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS sentinel_t<_Base> __end_ = sentinel_t<_Base>();
|
||||
|
||||
template<bool>
|
||||
template <bool>
|
||||
friend class take_view<_View>::__sentinel;
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
__sentinel() = default;
|
||||
_LIBCPP_HIDE_FROM_ABI __sentinel() = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(std::move(__end)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __sentinel(__sentinel<!_Const> __s)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __s)
|
||||
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
|
||||
: __end_(std::move(__s.__end_)) {}
|
||||
: __end_(std::move(__s.__end_)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr sentinel_t<_Base> base() const { return __end_; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) {
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) {
|
||||
return __lhs.count() == 0 || __lhs.base() == __rhs.__end_;
|
||||
}
|
||||
|
||||
template<bool _OtherConst = !_Const>
|
||||
template <bool _OtherConst = !_Const>
|
||||
requires sentinel_for<sentinel_t<_Base>, iterator_t<__maybe_const<_OtherConst, _View>>>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator==(const _Iter<_Const>& __lhs, const __sentinel& __rhs) {
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const _Iter<_OtherConst>& __lhs, const __sentinel& __rhs) {
|
||||
return __lhs.count() == 0 || __lhs.base() == __rhs.__end_;
|
||||
}
|
||||
};
|
||||
|
||||
template<class _Range>
|
||||
template <class _Range>
|
||||
take_view(_Range&&, range_difference_t<_Range>) -> take_view<views::all_t<_Range>>;
|
||||
|
||||
template<class _Tp>
|
||||
template <class _Tp>
|
||||
inline constexpr bool enable_borrowed_range<take_view<_Tp>> = enable_borrowed_range<_Tp>;
|
||||
|
||||
namespace views {
|
||||
|
@ -234,7 +239,7 @@ struct __passthrough_type<basic_string_view<_CharT, _Traits>> {
|
|||
};
|
||||
|
||||
template <class _Iter, class _Sent, subrange_kind _Kind>
|
||||
requires requires{typename subrange<_Iter>;}
|
||||
requires requires { typename subrange<_Iter>; }
|
||||
struct __passthrough_type<subrange<_Iter, _Sent, _Kind>> {
|
||||
using type = subrange<_Iter>;
|
||||
};
|
||||
|
@ -246,42 +251,36 @@ struct __fn {
|
|||
// [range.take.overview]: the `empty_view` case.
|
||||
template <class _Range, convertible_to<range_difference_t<_Range>> _Np>
|
||||
requires __is_empty_view<remove_cvref_t<_Range>>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __range, _Np&&) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range))))
|
||||
-> decltype( _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)))
|
||||
{ return _LIBCPP_AUTO_CAST(std::forward<_Range>(__range)); }
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&&) const
|
||||
noexcept(noexcept(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range))))
|
||||
-> decltype(_LIBCPP_AUTO_CAST(std::forward<_Range>(__range))) {
|
||||
return _LIBCPP_AUTO_CAST(std::forward<_Range>(__range));
|
||||
}
|
||||
|
||||
// [range.take.overview]: the `span | basic_string_view | subrange` case.
|
||||
template <class _Range,
|
||||
convertible_to<range_difference_t<_Range>> _Np,
|
||||
class _RawRange = remove_cvref_t<_Range>,
|
||||
class _Dist = range_difference_t<_Range>>
|
||||
requires (!__is_empty_view<_RawRange> &&
|
||||
random_access_range<_RawRange> &&
|
||||
sized_range<_RawRange> &&
|
||||
__is_passthrough_specialization<_RawRange>)
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __rng, _Np&& __n) const
|
||||
noexcept(noexcept(__passthrough_type_t<_RawRange>(
|
||||
ranges::begin(__rng),
|
||||
ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))
|
||||
)))
|
||||
-> decltype( __passthrough_type_t<_RawRange>(
|
||||
// Note: deliberately not forwarding `__rng` to guard against double moves.
|
||||
ranges::begin(__rng),
|
||||
ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))
|
||||
))
|
||||
{ return __passthrough_type_t<_RawRange>(
|
||||
ranges::begin(__rng),
|
||||
ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))
|
||||
); }
|
||||
class _Dist = range_difference_t<_Range>>
|
||||
requires(!__is_empty_view<_RawRange> && random_access_range<_RawRange> && sized_range<_RawRange> &&
|
||||
__is_passthrough_specialization<_RawRange>)
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto
|
||||
operator()(_Range&& __rng, _Np&& __n) const noexcept(noexcept(__passthrough_type_t<_RawRange>(
|
||||
ranges::begin(__rng), ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))))
|
||||
-> decltype(__passthrough_type_t<_RawRange>(
|
||||
// Note: deliberately not forwarding `__rng` to guard against double moves.
|
||||
ranges::begin(__rng),
|
||||
ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))) {
|
||||
return __passthrough_type_t<_RawRange>(
|
||||
ranges::begin(__rng), ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)));
|
||||
}
|
||||
|
||||
// [range.take.overview]: the `iota_view` case.
|
||||
// clang-format off
|
||||
template <class _Range,
|
||||
convertible_to<range_difference_t<_Range>> _Np,
|
||||
class _RawRange = remove_cvref_t<_Range>,
|
||||
class _Dist = range_difference_t<_Range>>
|
||||
class _Dist = range_difference_t<_Range>>
|
||||
requires (!__is_empty_view<_RawRange> &&
|
||||
random_access_range<_RawRange> &&
|
||||
sized_range<_RawRange> &&
|
||||
|
@ -290,49 +289,72 @@ struct __fn {
|
|||
constexpr auto operator()(_Range&& __rng, _Np&& __n) const
|
||||
noexcept(noexcept(ranges::iota_view(
|
||||
*ranges::begin(__rng),
|
||||
*ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))
|
||||
*(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))
|
||||
)))
|
||||
-> decltype( ranges::iota_view(
|
||||
// Note: deliberately not forwarding `__rng` to guard against double moves.
|
||||
*ranges::begin(__rng),
|
||||
*ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))
|
||||
*(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))
|
||||
))
|
||||
{ return ranges::iota_view(
|
||||
*ranges::begin(__rng),
|
||||
*ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))
|
||||
*(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))
|
||||
); }
|
||||
|
||||
#if _LIBCPP_STD_VER >= 23
|
||||
// [range.take.overview]: the `repeat_view` "_RawRange models sized_range" case.
|
||||
template <class _Range,
|
||||
convertible_to<range_difference_t<_Range>> _Np,
|
||||
class _RawRange = remove_cvref_t<_Range>,
|
||||
class _Dist = range_difference_t<_Range>>
|
||||
requires(__is_repeat_specialization<_RawRange> && sized_range<_RawRange>)
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const
|
||||
noexcept(noexcept(views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n)))))
|
||||
-> decltype( views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))))
|
||||
{ return views::repeat(*__range.__value_, std::min<_Dist>(ranges::distance(__range), std::forward<_Np>(__n))); }
|
||||
|
||||
// [range.take.overview]: the `repeat_view` "otherwise" case.
|
||||
template <class _Range,
|
||||
convertible_to<range_difference_t<_Range>> _Np,
|
||||
class _RawRange = remove_cvref_t<_Range>,
|
||||
class _Dist = range_difference_t<_Range>>
|
||||
requires(__is_repeat_specialization<_RawRange> && !sized_range<_RawRange>)
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const
|
||||
noexcept(noexcept(views::repeat(*__range.__value_, static_cast<_Dist>(__n))))
|
||||
-> decltype( views::repeat(*__range.__value_, static_cast<_Dist>(__n)))
|
||||
{ return views::repeat(*__range.__value_, static_cast<_Dist>(__n)); }
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
// [range.take.overview]: the "otherwise" case.
|
||||
template <class _Range, convertible_to<range_difference_t<_Range>> _Np,
|
||||
class _RawRange = remove_cvref_t<_Range>>
|
||||
// Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other
|
||||
// overloads.
|
||||
requires (!(__is_empty_view<_RawRange> ||
|
||||
(__is_iota_specialization<_RawRange> &&
|
||||
sized_range<_RawRange> &&
|
||||
random_access_range<_RawRange>) ||
|
||||
(__is_passthrough_specialization<_RawRange> &&
|
||||
sized_range<_RawRange> &&
|
||||
random_access_range<_RawRange>)
|
||||
))
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __range, _Np&& __n) const
|
||||
noexcept(noexcept(take_view(std::forward<_Range>(__range), std::forward<_Np>(__n))))
|
||||
-> decltype( take_view(std::forward<_Range>(__range), std::forward<_Np>(__n)))
|
||||
{ return take_view(std::forward<_Range>(__range), std::forward<_Np>(__n)); }
|
||||
template <class _Range, convertible_to<range_difference_t<_Range>> _Np, class _RawRange = remove_cvref_t<_Range>>
|
||||
// Note: without specifically excluding the other cases, GCC sees this overload as ambiguous with the other
|
||||
// overloads.
|
||||
requires(!(__is_empty_view<_RawRange> ||
|
||||
# if _LIBCPP_STD_VER >= 23
|
||||
__is_repeat_specialization<_RawRange> ||
|
||||
# endif
|
||||
(__is_iota_specialization<_RawRange> && sized_range<_RawRange> && random_access_range<_RawRange>) ||
|
||||
(__is_passthrough_specialization<_RawRange> && sized_range<_RawRange> &&
|
||||
random_access_range<_RawRange>)))
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Np&& __n) const
|
||||
noexcept(noexcept(take_view(std::forward<_Range>(__range), std::forward<_Np>(__n))))
|
||||
-> decltype(take_view(std::forward<_Range>(__range), std::forward<_Np>(__n))) {
|
||||
return take_view(std::forward<_Range>(__range), std::forward<_Np>(__n));
|
||||
}
|
||||
|
||||
template <class _Np>
|
||||
requires constructible_from<decay_t<_Np>, _Np>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Np&& __n) const
|
||||
noexcept(is_nothrow_constructible_v<decay_t<_Np>, _Np>)
|
||||
{ return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Np>(__n))); }
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Np&& __n) const
|
||||
noexcept(is_nothrow_constructible_v<decay_t<_Np>, _Np>) {
|
||||
return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Np>(__n)));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __take
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto take = __take::__fn{};
|
||||
inline constexpr auto take = __take::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace views
|
||||
|
||||
|
|
27
third_party/libcxx/__ranges/take_while_view.h
vendored
27
third_party/libcxx/__ranges/take_while_view.h
vendored
|
@ -20,7 +20,7 @@
|
|||
#include <__ranges/access.h>
|
||||
#include <__ranges/all.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/copyable_box.h>
|
||||
#include <__ranges/movable_box.h>
|
||||
#include <__ranges/range_adaptor.h>
|
||||
#include <__ranges/view_interface.h>
|
||||
#include <__type_traits/decay.h>
|
||||
|
@ -35,32 +35,23 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
|
||||
// The spec uses the unnamed requirement inside the `begin` and `end` member functions:
|
||||
// constexpr auto begin() const
|
||||
// requires range<const V> && indirect_unary_predicate<const Pred, iterator_t<const V>>
|
||||
// However, due to a clang-14 and clang-15 bug, the above produces a hard error when `const V` is not a range.
|
||||
// The workaround is to create a named concept and use the concept instead.
|
||||
// As of take_while_view is implemented, the clang-trunk has already fixed the bug.
|
||||
// It is OK to remove the workaround once our CI no longer uses clang-14, clang-15 based compilers,
|
||||
// because we don't actually expect a lot of vendors to ship a new libc++ with an old clang.
|
||||
template <class _View, class _Pred>
|
||||
concept __take_while_const_is_range =
|
||||
range<const _View> && indirect_unary_predicate<const _Pred, iterator_t<const _View>>;
|
||||
|
||||
template <view _View, class _Pred>
|
||||
requires input_range<_View> && is_object_v<_Pred> && indirect_unary_predicate<const _Pred, iterator_t<_View>>
|
||||
class take_while_view : public view_interface<take_while_view<_View, _Pred>> {
|
||||
class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS take_while_view : public view_interface<take_while_view<_View, _Pred>> {
|
||||
template <bool>
|
||||
class __sentinel;
|
||||
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS _View __base_ = _View();
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Pred> __pred_;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Pred> __pred_;
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI take_while_view()
|
||||
|
@ -87,7 +78,7 @@ public:
|
|||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
|
||||
requires __take_while_const_is_range<_View, _Pred>
|
||||
requires range<const _View> && indirect_unary_predicate<const _Pred, iterator_t<const _View>>
|
||||
{
|
||||
return ranges::begin(__base_);
|
||||
}
|
||||
|
@ -99,7 +90,7 @@ public:
|
|||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto end() const
|
||||
requires __take_while_const_is_range<_View, _Pred>
|
||||
requires range<const _View> && indirect_unary_predicate<const _Pred, iterator_t<const _View>>
|
||||
{
|
||||
return __sentinel</*_Const=*/true>(ranges::end(__base_), std::addressof(*__pred_));
|
||||
}
|
||||
|
@ -174,4 +165,6 @@ inline constexpr auto take_while = __take_while::__fn{};
|
|||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_TAKE_WHILE_VIEW_H
|
||||
|
|
245
third_party/libcxx/__ranges/to.h
vendored
Normal file
245
third_party/libcxx/__ranges/to.h
vendored
Normal file
|
@ -0,0 +1,245 @@
|
|||
// -*- 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_TO_H
|
||||
#define _LIBCPP___RANGES_TO_H
|
||||
|
||||
#include <__algorithm/ranges_copy.h>
|
||||
#include <__concepts/constructible.h>
|
||||
#include <__concepts/convertible_to.h>
|
||||
#include <__concepts/derived_from.h>
|
||||
#include <__concepts/same_as.h>
|
||||
#include <__config>
|
||||
#include <__functional/bind_back.h>
|
||||
#include <__iterator/back_insert_iterator.h>
|
||||
#include <__iterator/insert_iterator.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/from_range.h>
|
||||
#include <__ranges/range_adaptor.h>
|
||||
#include <__ranges/ref_view.h>
|
||||
#include <__ranges/size.h>
|
||||
#include <__ranges/transform_view.h>
|
||||
#include <__type_traits/add_pointer.h>
|
||||
#include <__type_traits/is_const.h>
|
||||
#include <__type_traits/is_volatile.h>
|
||||
#include <__type_traits/type_identity.h>
|
||||
#include <__utility/declval.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <cstddef>
|
||||
|
||||
#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 <class _Container>
|
||||
constexpr bool __reservable_container =
|
||||
sized_range<_Container> && requires(_Container& __c, range_size_t<_Container> __n) {
|
||||
__c.reserve(__n);
|
||||
{ __c.capacity() } -> same_as<decltype(__n)>;
|
||||
{ __c.max_size() } -> same_as<decltype(__n)>;
|
||||
};
|
||||
|
||||
template <class _Container, class _Ref>
|
||||
constexpr bool __container_insertable = requires(_Container& __c, _Ref&& __ref) {
|
||||
requires(
|
||||
requires { __c.push_back(std::forward<_Ref>(__ref)); } ||
|
||||
requires { __c.insert(__c.end(), std::forward<_Ref>(__ref)); });
|
||||
};
|
||||
|
||||
template <class _Ref, class _Container>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto __container_inserter(_Container& __c) {
|
||||
if constexpr (requires { __c.push_back(std::declval<_Ref>()); }) {
|
||||
return std::back_inserter(__c);
|
||||
} else {
|
||||
return std::inserter(__c, __c.end());
|
||||
}
|
||||
}
|
||||
|
||||
// Note: making this a concept allows short-circuiting the second condition.
|
||||
template <class _Container, class _Range>
|
||||
concept __try_non_recursive_conversion =
|
||||
!input_range<_Container> || convertible_to<range_reference_t<_Range>, range_value_t<_Container>>;
|
||||
|
||||
template <class _Container, class _Range, class... _Args>
|
||||
concept __constructible_from_iter_pair =
|
||||
common_range<_Range> && requires { typename iterator_traits<iterator_t<_Range>>::iterator_category; } &&
|
||||
derived_from<typename iterator_traits<iterator_t<_Range>>::iterator_category, input_iterator_tag> &&
|
||||
constructible_from<_Container, iterator_t<_Range>, sentinel_t<_Range>, _Args...>;
|
||||
|
||||
template <class>
|
||||
concept __always_false = false;
|
||||
|
||||
// `ranges::to` base template -- the `_Container` type is a simple type template parameter.
|
||||
template <class _Container, input_range _Range, class... _Args>
|
||||
requires(!view<_Container>)
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Container to(_Range&& __range, _Args&&... __args) {
|
||||
// Mandates: C is a cv-unqualified class type.
|
||||
static_assert(!is_const_v<_Container>, "The target container cannot be const-qualified, please remove the const");
|
||||
static_assert(
|
||||
!is_volatile_v<_Container>, "The target container cannot be volatile-qualified, please remove the volatile");
|
||||
|
||||
// First see if the non-recursive case applies -- the conversion target is either:
|
||||
// - a range with a convertible value type;
|
||||
// - a non-range type which might support being created from the input argument(s) (e.g. an `optional`).
|
||||
if constexpr (__try_non_recursive_conversion<_Container, _Range>) {
|
||||
// Case 1 -- construct directly from the given range.
|
||||
if constexpr (constructible_from<_Container, _Range, _Args...>) {
|
||||
return _Container(std::forward<_Range>(__range), std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
// Case 2 -- construct using the `from_range_t` tagged constructor.
|
||||
else if constexpr (constructible_from<_Container, from_range_t, _Range, _Args...>) {
|
||||
return _Container(from_range, std::forward<_Range>(__range), std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
// Case 3 -- construct from a begin-end iterator pair.
|
||||
else if constexpr (__constructible_from_iter_pair<_Container, _Range, _Args...>) {
|
||||
return _Container(ranges::begin(__range), ranges::end(__range), std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
// Case 4 -- default-construct (or construct from the extra arguments) and insert, reserving the size if possible.
|
||||
else if constexpr (constructible_from<_Container, _Args...> &&
|
||||
__container_insertable<_Container, range_reference_t<_Range>>) {
|
||||
_Container __result(std::forward<_Args>(__args)...);
|
||||
if constexpr (sized_range<_Range> && __reservable_container<_Container>) {
|
||||
__result.reserve(static_cast<range_size_t<_Container>>(ranges::size(__range)));
|
||||
}
|
||||
|
||||
ranges::copy(__range, ranges::__container_inserter<range_reference_t<_Range>>(__result));
|
||||
|
||||
return __result;
|
||||
|
||||
} else {
|
||||
static_assert(__always_false<_Container>, "ranges::to: unable to convert to the given container type.");
|
||||
}
|
||||
|
||||
// Try the recursive case.
|
||||
} else if constexpr (input_range<range_reference_t<_Range>>) {
|
||||
return ranges::to<_Container>(
|
||||
ref_view(__range) | views::transform([](auto&& __elem) {
|
||||
return ranges::to<range_value_t<_Container>>(std::forward<decltype(__elem)>(__elem));
|
||||
}),
|
||||
std::forward<_Args>(__args)...);
|
||||
|
||||
} else {
|
||||
static_assert(__always_false<_Container>, "ranges::to: unable to convert to the given container type.");
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Range>
|
||||
struct __minimal_input_iterator {
|
||||
using iterator_category = input_iterator_tag;
|
||||
using value_type = range_value_t<_Range>;
|
||||
using difference_type = ptrdiff_t;
|
||||
using pointer = add_pointer_t<range_reference_t<_Range>>;
|
||||
using reference = range_reference_t<_Range>;
|
||||
|
||||
reference operator*() const;
|
||||
pointer operator->() const;
|
||||
__minimal_input_iterator& operator++();
|
||||
__minimal_input_iterator operator++(int);
|
||||
bool operator==(const __minimal_input_iterator&) const;
|
||||
};
|
||||
|
||||
// Deduces the full type of the container from the given template template parameter.
|
||||
template <template <class...> class _Container, input_range _Range, class... _Args>
|
||||
struct _Deducer {
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr auto __deduce_func() {
|
||||
using _InputIter = __minimal_input_iterator<_Range>;
|
||||
|
||||
// Case 1 -- can construct directly from the given range.
|
||||
if constexpr (requires { _Container(std::declval<_Range>(), std::declval<_Args>()...); }) {
|
||||
using _Result = decltype( //
|
||||
_Container(std::declval<_Range>(), std::declval<_Args>()...));
|
||||
return type_identity<_Result>{};
|
||||
|
||||
// Case 2 -- can construct from the given range using the `from_range_t` tagged constructor.
|
||||
} else if constexpr ( //
|
||||
requires { _Container(from_range, std::declval<_Range>(), std::declval<_Args>()...); }) {
|
||||
using _Result = //
|
||||
decltype(_Container(from_range, std::declval<_Range>(), std::declval<_Args>()...));
|
||||
return type_identity<_Result>{};
|
||||
|
||||
// Case 3 -- can construct from a begin-end iterator pair.
|
||||
} else if constexpr ( //
|
||||
requires { _Container(std::declval<_InputIter>(), std::declval<_InputIter>(), std::declval<_Args>()...); }) {
|
||||
using _Result =
|
||||
decltype(_Container(std::declval<_InputIter>(), std::declval<_InputIter>(), std::declval<_Args>()...));
|
||||
return type_identity<_Result>{};
|
||||
|
||||
} else {
|
||||
static_assert(__always_false<_Range>,
|
||||
"ranges::to: unable to deduce the container type from the template template argument.");
|
||||
}
|
||||
}
|
||||
|
||||
using type = typename decltype(__deduce_func())::type;
|
||||
};
|
||||
|
||||
// `ranges::to` specialization -- `_Container` is a template template parameter requiring deduction to figure out the
|
||||
// container element type.
|
||||
template <template <class...> class _Container, input_range _Range, class... _Args>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto to(_Range&& __range, _Args&&... __args) {
|
||||
using _DeduceExpr = typename _Deducer<_Container, _Range, _Args...>::type;
|
||||
return ranges::to<_DeduceExpr>(std::forward<_Range>(__range), std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
// Range adaptor closure object 1 -- wrapping the `ranges::to` version where `_Container` is a simple type template
|
||||
// parameter.
|
||||
template <class _Container, class... _Args>
|
||||
requires(!view<_Container>)
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto to(_Args&&... __args) {
|
||||
// Mandates: C is a cv-unqualified class type.
|
||||
static_assert(!is_const_v<_Container>, "The target container cannot be const-qualified, please remove the const");
|
||||
static_assert(
|
||||
!is_volatile_v<_Container>, "The target container cannot be volatile-qualified, please remove the volatile");
|
||||
|
||||
auto __to_func = []<input_range _Range, class... _Tail>(_Range&& __range, _Tail&&... __tail) static
|
||||
requires requires { //
|
||||
/**/ ranges::to<_Container>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...);
|
||||
}
|
||||
{ return ranges::to<_Container>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...); };
|
||||
|
||||
return __range_adaptor_closure_t(std::__bind_back(__to_func, std::forward<_Args>(__args)...));
|
||||
}
|
||||
|
||||
// Range adaptor closure object 2 -- wrapping the `ranges::to` version where `_Container` is a template template
|
||||
// parameter.
|
||||
template <template <class...> class _Container, class... _Args>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto to(_Args&&... __args) {
|
||||
// clang-format off
|
||||
auto __to_func = []<input_range _Range, class... _Tail,
|
||||
class _DeducedExpr = typename _Deducer<_Container, _Range, _Tail...>::type>
|
||||
(_Range&& __range, _Tail&& ... __tail) static
|
||||
requires requires { //
|
||||
/**/ ranges::to<_DeducedExpr>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...);
|
||||
}
|
||||
{
|
||||
return ranges::to<_DeducedExpr>(std::forward<_Range>(__range), std::forward<_Tail>(__tail)...);
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
return __range_adaptor_closure_t(std::__bind_back(__to_func, std::forward<_Args>(__args)...));
|
||||
}
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
#endif // _LIBCPP_STD_VER >= 23
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
#endif // _LIBCPP___RANGES_TO_H
|
331
third_party/libcxx/__ranges/transform_view.h
vendored
331
third_party/libcxx/__ranges/transform_view.h
vendored
|
@ -20,14 +20,15 @@
|
|||
#include <__config>
|
||||
#include <__functional/bind_back.h>
|
||||
#include <__functional/invoke.h>
|
||||
#include <__functional/perfect_forward.h>
|
||||
#include <__iterator/concepts.h>
|
||||
#include <__iterator/iterator_traits.h>
|
||||
#include <__memory/addressof.h>
|
||||
#include <__ranges/access.h>
|
||||
#include <__ranges/all.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/copyable_box.h>
|
||||
#include <__ranges/empty.h>
|
||||
#include <__ranges/movable_box.h>
|
||||
#include <__ranges/range_adaptor.h>
|
||||
#include <__ranges/size.h>
|
||||
#include <__ranges/view_interface.h>
|
||||
|
@ -46,188 +47,183 @@
|
|||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
_LIBCPP_PUSH_MACROS
|
||||
#include <__undef_macros>
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
namespace ranges {
|
||||
|
||||
template<class _Fn, class _View>
|
||||
concept __regular_invocable_with_range_ref =
|
||||
regular_invocable<_Fn, range_reference_t<_View>>;
|
||||
template <class _Fn, class _View>
|
||||
concept __regular_invocable_with_range_ref = regular_invocable<_Fn, range_reference_t<_View>>;
|
||||
|
||||
template<class _View, class _Fn>
|
||||
template <class _View, class _Fn>
|
||||
concept __transform_view_constraints =
|
||||
view<_View> && is_object_v<_Fn> &&
|
||||
regular_invocable<_Fn&, range_reference_t<_View>> &&
|
||||
__can_reference<invoke_result_t<_Fn&, range_reference_t<_View>>>;
|
||||
view<_View> && is_object_v<_Fn> && regular_invocable<_Fn&, range_reference_t<_View>> &&
|
||||
__can_reference<invoke_result_t<_Fn&, range_reference_t<_View>>>;
|
||||
|
||||
template<input_range _View, copy_constructible _Fn>
|
||||
# if _LIBCPP_STD_VER >= 23
|
||||
template <input_range _View, move_constructible _Fn>
|
||||
# else
|
||||
template <input_range _View, copy_constructible _Fn>
|
||||
# endif
|
||||
requires __transform_view_constraints<_View, _Fn>
|
||||
class transform_view : public view_interface<transform_view<_View, _Fn>> {
|
||||
template<bool> class __iterator;
|
||||
template<bool> class __sentinel;
|
||||
class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS transform_view : public view_interface<transform_view<_View, _Fn>> {
|
||||
template <bool>
|
||||
class __iterator;
|
||||
template <bool>
|
||||
class __sentinel;
|
||||
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS __copyable_box<_Fn> __func_;
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS __movable_box<_Fn> __func_;
|
||||
_LIBCPP_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 transform_view()
|
||||
requires default_initializable<_View> && default_initializable<_Fn>
|
||||
= default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 transform_view(_View __base, _Fn __func)
|
||||
: __func_(std::in_place, std::move(__func)), __base_(std::move(__base)) {}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _LIBCPP_EXPLICIT_SINCE_CXX23 transform_view(_View __base, _Fn __func)
|
||||
: __func_(std::in_place, std::move(__func)), __base_(std::move(__base)) {}
|
||||
|
||||
_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 __iterator<false> begin() {
|
||||
return __iterator<false>{*this, ranges::begin(__base_)};
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
|
||||
requires copy_constructible<_View>
|
||||
{
|
||||
return __base_;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator<true> begin() const
|
||||
requires range<const _View> &&
|
||||
__regular_invocable_with_range_ref<const _Fn&, const _View>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::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_with_range_ref<const _Fn&, 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()
|
||||
_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_with_range_ref<const _Fn&, const _View>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __sentinel<true> end() const
|
||||
requires range<const _View> && __regular_invocable_with_range_ref<const _Fn&, const _View>
|
||||
{
|
||||
return __sentinel<true>(ranges::end(__base_));
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator<true> end() const
|
||||
requires common_range<const _View> &&
|
||||
__regular_invocable_with_range_ref<const _Fn&, const _View>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator<true> end() const
|
||||
requires common_range<const _View> && __regular_invocable_with_range_ref<const _Fn&, 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_); }
|
||||
_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>
|
||||
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 <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 <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 <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 <forward_range _View>
|
||||
struct __transform_view_iterator_concept<_View> {
|
||||
using type = forward_iterator_tag;
|
||||
};
|
||||
|
||||
template<class, class>
|
||||
template <class, class>
|
||||
struct __transform_view_iterator_category_base {};
|
||||
|
||||
template<forward_range _View, class _Fn>
|
||||
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_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
|
||||
>;
|
||||
using iterator_category =
|
||||
conditional_t< is_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>
|
||||
# if _LIBCPP_STD_VER >= 23
|
||||
template <input_range _View, move_constructible _Fn>
|
||||
# else
|
||||
template <input_range _View, copy_constructible _Fn>
|
||||
# endif
|
||||
requires __transform_view_constraints<_View, _Fn>
|
||||
template<bool _Const>
|
||||
class transform_view<_View, _Fn>::__iterator
|
||||
: public __transform_view_iterator_category_base<_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>;
|
||||
using _Base = __maybe_const<_Const, _View>;
|
||||
|
||||
_Parent *__parent_ = nullptr;
|
||||
_Parent* __parent_ = nullptr;
|
||||
|
||||
template<bool>
|
||||
template <bool>
|
||||
friend class transform_view<_View, _Fn>::__iterator;
|
||||
|
||||
template<bool>
|
||||
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>;
|
||||
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 __iterator()
|
||||
requires default_initializable<iterator_t<_Base>>
|
||||
= default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator(_Parent& __parent, iterator_t<_Base> __current)
|
||||
: __parent_(std::addressof(__parent)), __current_(std::move(__current)) {}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator(_Parent& __parent, iterator_t<_Base> __current)
|
||||
: __parent_(std::addressof(__parent)), __current_(std::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)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i)
|
||||
requires _Const && convertible_to<iterator_t<_View>, iterator_t<_Base>>
|
||||
: __parent_(__i.__parent_), __current_(std::move(__i.__current_)) {}
|
||||
: __parent_(__i.__parent_), __current_(std::move(__i.__current_)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr const iterator_t<_Base>& base() const& noexcept {
|
||||
return __current_;
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr const iterator_t<_Base>& base() const& noexcept { return __current_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr iterator_t<_Base> base() && {
|
||||
return std::move(__current_);
|
||||
}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr iterator_t<_Base> base() && { return std::move(__current_); }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr decltype(auto) operator*() const
|
||||
noexcept(noexcept(std::invoke(*__parent_->__func_, *__current_)))
|
||||
{
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator*() const
|
||||
noexcept(noexcept(std::invoke(*__parent_->__func_, *__current_))) {
|
||||
return std::invoke(*__parent_->__func_, *__current_);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator& operator++() {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
|
||||
++__current_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr void operator++(int) { ++__current_; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++__current_; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator operator++(int)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int)
|
||||
requires forward_range<_Base>
|
||||
{
|
||||
auto __tmp = *this;
|
||||
|
@ -235,16 +231,14 @@ public:
|
|||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator& operator--()
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
|
||||
requires bidirectional_range<_Base>
|
||||
{
|
||||
--__current_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator operator--(int)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
|
||||
requires bidirectional_range<_Base>
|
||||
{
|
||||
auto __tmp = *this;
|
||||
|
@ -252,104 +246,88 @@ public:
|
|||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator& operator+=(difference_type __n)
|
||||
_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)
|
||||
_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(std::invoke(*__parent_->__func_, __current_[__n])))
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](difference_type __n) const
|
||||
noexcept(noexcept(std::invoke(*__parent_->__func_, __current_[__n])))
|
||||
requires random_access_range<_Base>
|
||||
{
|
||||
return std::invoke(*__parent_->__func_, __current_[__n]);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
|
||||
_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)
|
||||
_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)
|
||||
_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)
|
||||
_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)
|
||||
_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 auto operator<=>(const __iterator& __x, const __iterator& __y)
|
||||
_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)
|
||||
_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)
|
||||
_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)
|
||||
_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)
|
||||
_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))
|
||||
{
|
||||
_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 std::move(*__i);
|
||||
else
|
||||
|
@ -357,58 +335,55 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
template<input_range _View, copy_constructible _Fn>
|
||||
# if _LIBCPP_STD_VER >= 23
|
||||
template <input_range _View, move_constructible _Fn>
|
||||
# else
|
||||
template <input_range _View, copy_constructible _Fn>
|
||||
# endif
|
||||
requires __transform_view_constraints<_View, _Fn>
|
||||
template<bool _Const>
|
||||
template <bool _Const>
|
||||
class transform_view<_View, _Fn>::__sentinel {
|
||||
using _Parent = __maybe_const<_Const, transform_view>;
|
||||
using _Base = __maybe_const<_Const, _View>;
|
||||
using _Base = __maybe_const<_Const, _View>;
|
||||
|
||||
sentinel_t<_Base> __end_ = sentinel_t<_Base>();
|
||||
|
||||
template<bool>
|
||||
template <bool>
|
||||
friend class transform_view<_View, _Fn>::__iterator;
|
||||
|
||||
template<bool>
|
||||
template <bool>
|
||||
friend class transform_view<_View, _Fn>::__sentinel;
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
__sentinel() = default;
|
||||
_LIBCPP_HIDE_FROM_ABI __sentinel() = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit __sentinel(sentinel_t<_Base> __end) : __end_(__end) {}
|
||||
_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)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __i)
|
||||
requires _Const && convertible_to<sentinel_t<_View>, sentinel_t<_Base>>
|
||||
: __end_(std::move(__i.__end_)) {}
|
||||
: __end_(std::move(__i.__end_)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr sentinel_t<_Base> base() const { return __end_; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr sentinel_t<_Base> base() const { return __end_; }
|
||||
|
||||
template<bool _OtherConst>
|
||||
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) {
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator<_OtherConst>& __x, const __sentinel& __y) {
|
||||
return __x.__current_ == __y.__end_;
|
||||
}
|
||||
|
||||
template<bool _OtherConst>
|
||||
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>>
|
||||
_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>
|
||||
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>>
|
||||
_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_;
|
||||
}
|
||||
|
@ -416,25 +391,25 @@ public:
|
|||
|
||||
namespace views {
|
||||
namespace __transform {
|
||||
struct __fn {
|
||||
template<class _Range, class _Fn>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Range&& __range, _Fn&& __f) const
|
||||
struct __fn {
|
||||
template <class _Range, class _Fn>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range, _Fn&& __f) const
|
||||
noexcept(noexcept(transform_view(std::forward<_Range>(__range), std::forward<_Fn>(__f))))
|
||||
-> decltype( transform_view(std::forward<_Range>(__range), std::forward<_Fn>(__f)))
|
||||
{ return transform_view(std::forward<_Range>(__range), std::forward<_Fn>(__f)); }
|
||||
-> decltype(transform_view(std::forward<_Range>(__range), std::forward<_Fn>(__f))) {
|
||||
return transform_view(std::forward<_Range>(__range), std::forward<_Fn>(__f));
|
||||
}
|
||||
|
||||
template<class _Fn>
|
||||
requires constructible_from<decay_t<_Fn>, _Fn>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator()(_Fn&& __f) const
|
||||
noexcept(is_nothrow_constructible_v<decay_t<_Fn>, _Fn>)
|
||||
{ return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Fn>(__f))); }
|
||||
};
|
||||
template <class _Fn>
|
||||
requires constructible_from<decay_t<_Fn>, _Fn>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Fn&& __f) const
|
||||
noexcept(is_nothrow_constructible_v<decay_t<_Fn>, _Fn>) {
|
||||
return __range_adaptor_closure_t(std::__bind_back(*this, std::forward<_Fn>(__f)));
|
||||
}
|
||||
};
|
||||
} // namespace __transform
|
||||
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto transform = __transform::__fn{};
|
||||
inline constexpr auto transform = __transform::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace views
|
||||
|
||||
|
@ -444,4 +419,6 @@ inline namespace __cpo {
|
|||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
||||
#endif // _LIBCPP___RANGES_TRANSFORM_VIEW_H
|
||||
|
|
111
third_party/libcxx/__ranges/view_interface.h
vendored
111
third_party/libcxx/__ranges/view_interface.h
vendored
|
@ -21,6 +21,7 @@
|
|||
#include <__ranges/access.h>
|
||||
#include <__ranges/concepts.h>
|
||||
#include <__ranges/empty.h>
|
||||
#include <__ranges/size.h>
|
||||
#include <__type_traits/is_class.h>
|
||||
#include <__type_traits/make_unsigned.h>
|
||||
#include <__type_traits/remove_cv.h>
|
||||
|
@ -35,135 +36,127 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
|
||||
namespace ranges {
|
||||
|
||||
template<class _Derived>
|
||||
template <class _Derived>
|
||||
requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
|
||||
class view_interface {
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _Derived& __derived() noexcept {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Derived& __derived() noexcept {
|
||||
static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>);
|
||||
return static_cast<_Derived&>(*this);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr _Derived const& __derived() const noexcept {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr _Derived const& __derived() const noexcept {
|
||||
static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>);
|
||||
return static_cast<_Derived const&>(*this);
|
||||
}
|
||||
|
||||
public:
|
||||
template<class _D2 = _Derived>
|
||||
template <class _D2 = _Derived>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty()
|
||||
requires forward_range<_D2>
|
||||
requires sized_range<_D2> || forward_range<_D2>
|
||||
{
|
||||
return ranges::begin(__derived()) == ranges::end(__derived());
|
||||
if constexpr (sized_range<_D2>) {
|
||||
return ranges::size(__derived()) == 0;
|
||||
} else {
|
||||
return ranges::begin(__derived()) == ranges::end(__derived());
|
||||
}
|
||||
}
|
||||
|
||||
template<class _D2 = _Derived>
|
||||
template <class _D2 = _Derived>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
|
||||
requires forward_range<const _D2>
|
||||
requires sized_range<const _D2> || forward_range<const _D2>
|
||||
{
|
||||
return ranges::begin(__derived()) == ranges::end(__derived());
|
||||
if constexpr (sized_range<const _D2>) {
|
||||
return ranges::size(__derived()) == 0;
|
||||
} else {
|
||||
return ranges::begin(__derived()) == ranges::end(__derived());
|
||||
}
|
||||
}
|
||||
|
||||
template<class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit operator bool()
|
||||
requires requires (_D2& __t) { ranges::empty(__t); }
|
||||
template <class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool()
|
||||
requires requires(_D2& __t) { ranges::empty(__t); }
|
||||
{
|
||||
return !ranges::empty(__derived());
|
||||
}
|
||||
|
||||
template<class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit operator bool() const
|
||||
requires requires (const _D2& __t) { ranges::empty(__t); }
|
||||
template <class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const
|
||||
requires requires(const _D2& __t) { ranges::empty(__t); }
|
||||
{
|
||||
return !ranges::empty(__derived());
|
||||
}
|
||||
|
||||
template<class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto data()
|
||||
template <class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto data()
|
||||
requires contiguous_iterator<iterator_t<_D2>>
|
||||
{
|
||||
return std::to_address(ranges::begin(__derived()));
|
||||
}
|
||||
|
||||
template<class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto data() const
|
||||
template <class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto data() const
|
||||
requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>>
|
||||
{
|
||||
return std::to_address(ranges::begin(__derived()));
|
||||
}
|
||||
|
||||
template<class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto size()
|
||||
template <class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto size()
|
||||
requires forward_range<_D2> && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>>
|
||||
{
|
||||
return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived()));
|
||||
}
|
||||
|
||||
template<class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto size() const
|
||||
template <class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto size() const
|
||||
requires forward_range<const _D2> && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>>
|
||||
{
|
||||
return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived()));
|
||||
}
|
||||
|
||||
template<class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr decltype(auto) front()
|
||||
template <class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front()
|
||||
requires forward_range<_D2>
|
||||
{
|
||||
_LIBCPP_ASSERT(!empty(),
|
||||
"Precondition `!empty()` not satisfied. `.front()` called on an empty view.");
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
|
||||
!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
|
||||
template <class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front() const
|
||||
requires forward_range<const _D2>
|
||||
{
|
||||
_LIBCPP_ASSERT(!empty(),
|
||||
"Precondition `!empty()` not satisfied. `.front()` called on an empty view.");
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
|
||||
!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()
|
||||
template <class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back()
|
||||
requires bidirectional_range<_D2> && common_range<_D2>
|
||||
{
|
||||
_LIBCPP_ASSERT(!empty(),
|
||||
"Precondition `!empty()` not satisfied. `.back()` called on an empty view.");
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
|
||||
!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
|
||||
template <class _D2 = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back() const
|
||||
requires bidirectional_range<const _D2> && common_range<const _D2>
|
||||
{
|
||||
_LIBCPP_ASSERT(!empty(),
|
||||
"Precondition `!empty()` not satisfied. `.back()` called on an empty view.");
|
||||
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
|
||||
!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)
|
||||
{
|
||||
template <random_access_range _RARange = _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __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
|
||||
{
|
||||
template <random_access_range _RARange = const _Derived>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const {
|
||||
return ranges::begin(__derived())[__index];
|
||||
}
|
||||
};
|
||||
|
|
2
third_party/libcxx/__ranges/views.h
vendored
2
third_party/libcxx/__ranges/views.h
vendored
|
@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
|
||||
namespace ranges {
|
||||
|
||||
namespace views { }
|
||||
namespace views {}
|
||||
|
||||
} // namespace ranges
|
||||
|
||||
|
|
246
third_party/libcxx/__ranges/zip_view.h
vendored
246
third_party/libcxx/__ranges/zip_view.h
vendored
|
@ -30,12 +30,13 @@
|
|||
#include <__ranges/enable_borrowed_range.h>
|
||||
#include <__ranges/size.h>
|
||||
#include <__ranges/view_interface.h>
|
||||
#include <__type_traits/is_nothrow_move_constructible.h>
|
||||
#include <__type_traits/is_nothrow_constructible.h>
|
||||
#include <__type_traits/make_unsigned.h>
|
||||
#include <__utility/declval.h>
|
||||
#include <__utility/forward.h>
|
||||
#include <__utility/integer_sequence.h>
|
||||
#include <__utility/move.h>
|
||||
#include <__utility/pair.h>
|
||||
#include <tuple>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
|
@ -52,9 +53,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
|
|||
namespace ranges {
|
||||
|
||||
template <class... _Ranges>
|
||||
concept __zip_is_common = (sizeof...(_Ranges) == 1 && (common_range<_Ranges> && ...)) ||
|
||||
(!(bidirectional_range<_Ranges> && ...) && (common_range<_Ranges> && ...)) ||
|
||||
((random_access_range<_Ranges> && ...) && (sized_range<_Ranges> && ...));
|
||||
concept __zip_is_common =
|
||||
(sizeof...(_Ranges) == 1 && (common_range<_Ranges> && ...)) ||
|
||||
(!(bidirectional_range<_Ranges> && ...) && (common_range<_Ranges> && ...)) ||
|
||||
((random_access_range<_Ranges> && ...) && (sized_range<_Ranges> && ...));
|
||||
|
||||
template <typename _Tp, typename _Up>
|
||||
auto __tuple_or_pair_test() -> pair<_Tp, _Up>;
|
||||
|
@ -87,31 +89,39 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __tuple_for_each(_Fun&& __f, _Tuple&& __tup
|
|||
|
||||
template <class _Fun, class _Tuple1, class _Tuple2, size_t... _Indices>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __tuple_or_pair<
|
||||
invoke_result_t<_Fun&, typename tuple_element<_Indices, remove_cvref_t<_Tuple1>>::type,
|
||||
invoke_result_t<_Fun&,
|
||||
typename tuple_element<_Indices, remove_cvref_t<_Tuple1>>::type,
|
||||
typename tuple_element<_Indices, remove_cvref_t<_Tuple2>>::type>...>
|
||||
__tuple_zip_transform(_Fun&& __f, _Tuple1&& __tuple1, _Tuple2&& __tuple2, index_sequence<_Indices...>) {
|
||||
return {std::invoke(__f, std::get<_Indices>(std::forward<_Tuple1>(__tuple1)),
|
||||
return {std::invoke(__f,
|
||||
std::get<_Indices>(std::forward<_Tuple1>(__tuple1)),
|
||||
std::get<_Indices>(std::forward<_Tuple2>(__tuple2)))...};
|
||||
}
|
||||
|
||||
template <class _Fun, class _Tuple1, class _Tuple2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_zip_transform(_Fun&& __f, _Tuple1&& __tuple1, _Tuple2&& __tuple2) {
|
||||
return ranges::__tuple_zip_transform(__f, std::forward<_Tuple1>(__tuple1), std::forward<_Tuple2>(__tuple2),
|
||||
std::make_index_sequence<tuple_size<remove_cvref_t<_Tuple1>>::value>());
|
||||
return ranges::__tuple_zip_transform(
|
||||
__f,
|
||||
std::forward<_Tuple1>(__tuple1),
|
||||
std::forward<_Tuple2>(__tuple2),
|
||||
std::make_index_sequence<tuple_size<remove_cvref_t<_Tuple1>>::value>());
|
||||
}
|
||||
|
||||
template <class _Fun, class _Tuple1, class _Tuple2, size_t... _Indices>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr void __tuple_zip_for_each(_Fun&& __f, _Tuple1&& __tuple1, _Tuple2&& __tuple2,
|
||||
index_sequence<_Indices...>) {
|
||||
(std::invoke(__f, std::get<_Indices>(std::forward<_Tuple1>(__tuple1)),
|
||||
std::get<_Indices>(std::forward<_Tuple2>(__tuple2))),
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr void
|
||||
__tuple_zip_for_each(_Fun&& __f, _Tuple1&& __tuple1, _Tuple2&& __tuple2, index_sequence<_Indices...>) {
|
||||
(std::invoke(
|
||||
__f, std::get<_Indices>(std::forward<_Tuple1>(__tuple1)), std::get<_Indices>(std::forward<_Tuple2>(__tuple2))),
|
||||
...);
|
||||
}
|
||||
|
||||
template <class _Fun, class _Tuple1, class _Tuple2>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_zip_for_each(_Fun&& __f, _Tuple1&& __tuple1, _Tuple2&& __tuple2) {
|
||||
return ranges::__tuple_zip_for_each(__f, std::forward<_Tuple1>(__tuple1), std::forward<_Tuple2>(__tuple2),
|
||||
std::make_index_sequence<tuple_size<remove_cvref_t<_Tuple1>>::value>());
|
||||
return ranges::__tuple_zip_for_each(
|
||||
__f,
|
||||
std::forward<_Tuple1>(__tuple1),
|
||||
std::forward<_Tuple2>(__tuple2),
|
||||
std::make_index_sequence<tuple_size<remove_cvref_t<_Tuple1>>::value>());
|
||||
}
|
||||
|
||||
template <class _Tuple1, class _Tuple2>
|
||||
|
@ -130,7 +140,6 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp __abs(_Tp __t) {
|
|||
template <input_range... _Views>
|
||||
requires(view<_Views> && ...) && (sizeof...(_Views) > 0)
|
||||
class zip_view : public view_interface<zip_view<_Views...>> {
|
||||
|
||||
_LIBCPP_NO_UNIQUE_ADDRESS tuple<_Views...> __views_;
|
||||
|
||||
template <bool>
|
||||
|
@ -140,27 +149,25 @@ class zip_view : public view_interface<zip_view<_Views...>> {
|
|||
class __sentinel;
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
zip_view() = default;
|
||||
_LIBCPP_HIDE_FROM_ABI zip_view() = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit zip_view(_Views... __views) : __views_(std::move(__views)...) {}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit zip_view(_Views... __views) : __views_(std::move(__views)...) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto begin()
|
||||
requires(!(__simple_view<_Views> && ...)) {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto begin()
|
||||
requires(!(__simple_view<_Views> && ...))
|
||||
{
|
||||
return __iterator<false>(ranges::__tuple_transform(ranges::begin, __views_));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto begin() const
|
||||
requires(range<const _Views> && ...) {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
|
||||
requires(range<const _Views> && ...)
|
||||
{
|
||||
return __iterator<true>(ranges::__tuple_transform(ranges::begin, __views_));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto end()
|
||||
requires(!(__simple_view<_Views> && ...)) {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto end()
|
||||
requires(!(__simple_view<_Views> && ...))
|
||||
{
|
||||
if constexpr (!__zip_is_common<_Views...>) {
|
||||
return __sentinel<false>(ranges::__tuple_transform(ranges::end, __views_));
|
||||
} else if constexpr ((random_access_range<_Views> && ...)) {
|
||||
|
@ -170,9 +177,9 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto end() const
|
||||
requires(range<const _Views> && ...) {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto end() const
|
||||
requires(range<const _Views> && ...)
|
||||
{
|
||||
if constexpr (!__zip_is_common<const _Views...>) {
|
||||
return __sentinel<true>(ranges::__tuple_transform(ranges::end, __views_));
|
||||
} else if constexpr ((random_access_range<const _Views> && ...)) {
|
||||
|
@ -182,9 +189,9 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto size()
|
||||
requires(sized_range<_Views> && ...) {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto size()
|
||||
requires(sized_range<_Views> && ...)
|
||||
{
|
||||
return std::apply(
|
||||
[](auto... __sizes) {
|
||||
using _CT = make_unsigned_t<common_type_t<decltype(__sizes)...>>;
|
||||
|
@ -193,9 +200,9 @@ public:
|
|||
ranges::__tuple_transform(ranges::size, __views_));
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto size() const
|
||||
requires(sized_range<const _Views> && ...) {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto size() const
|
||||
requires(sized_range<const _Views> && ...)
|
||||
{
|
||||
return std::apply(
|
||||
[](auto... __sizes) {
|
||||
using _CT = make_unsigned_t<common_type_t<decltype(__sizes)...>>;
|
||||
|
@ -243,11 +250,10 @@ template <input_range... _Views>
|
|||
requires(view<_Views> && ...) && (sizeof...(_Views) > 0)
|
||||
template <bool _Const>
|
||||
class zip_view<_Views...>::__iterator : public __zip_view_iterator_category_base<_Const, _Views...> {
|
||||
|
||||
__tuple_or_pair<iterator_t<__maybe_const<_Const, _Views>>...> __current_;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit __iterator(__tuple_or_pair<iterator_t<__maybe_const<_Const, _Views>>...> __current)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(
|
||||
__tuple_or_pair<iterator_t<__maybe_const<_Const, _Views>>...> __current)
|
||||
: __current_(std::move(__current)) {}
|
||||
|
||||
template <bool>
|
||||
|
@ -260,78 +266,73 @@ class zip_view<_Views...>::__iterator : public __zip_view_iterator_category_base
|
|||
|
||||
public:
|
||||
using iterator_concept = decltype(__get_zip_view_iterator_tag<_Const, _Views...>());
|
||||
using value_type = __tuple_or_pair<range_value_t<__maybe_const<_Const, _Views>>...>;
|
||||
using difference_type = common_type_t<range_difference_t<__maybe_const<_Const, _Views>>...>;
|
||||
using value_type = __tuple_or_pair<range_value_t<__maybe_const<_Const, _Views>>...>;
|
||||
using difference_type = common_type_t<range_difference_t<__maybe_const<_Const, _Views>>...>;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
__iterator() = default;
|
||||
_LIBCPP_HIDE_FROM_ABI __iterator() = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator(__iterator<!_Const> __i)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator(__iterator<!_Const> __i)
|
||||
requires _Const && (convertible_to<iterator_t<_Views>, iterator_t<__maybe_const<_Const, _Views>>> && ...)
|
||||
: __current_(std::move(__i.__current_)) {}
|
||||
: __current_(std::move(__i.__current_)) {}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator*() const {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto operator*() const {
|
||||
return ranges::__tuple_transform([](auto& __i) -> decltype(auto) { return *__i; }, __current_);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator& operator++() {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator++() {
|
||||
ranges::__tuple_for_each([](auto& __i) { ++__i; }, __current_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr void operator++(int) { ++*this; }
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr void operator++(int) { ++*this; }
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator operator++(int)
|
||||
requires __zip_all_forward<_Const, _Views...> {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator operator++(int)
|
||||
requires __zip_all_forward<_Const, _Views...>
|
||||
{
|
||||
auto __tmp = *this;
|
||||
++*this;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator& operator--()
|
||||
requires __zip_all_bidirectional<_Const, _Views...> {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator--()
|
||||
requires __zip_all_bidirectional<_Const, _Views...>
|
||||
{
|
||||
ranges::__tuple_for_each([](auto& __i) { --__i; }, __current_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator operator--(int)
|
||||
requires __zip_all_bidirectional<_Const, _Views...> {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator operator--(int)
|
||||
requires __zip_all_bidirectional<_Const, _Views...>
|
||||
{
|
||||
auto __tmp = *this;
|
||||
--*this;
|
||||
return __tmp;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator& operator+=(difference_type __x)
|
||||
requires __zip_all_random_access<_Const, _Views...> {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator+=(difference_type __x)
|
||||
requires __zip_all_random_access<_Const, _Views...>
|
||||
{
|
||||
ranges::__tuple_for_each([&]<class _Iter>(_Iter& __i) { __i += iter_difference_t<_Iter>(__x); }, __current_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __iterator& operator-=(difference_type __x)
|
||||
requires __zip_all_random_access<_Const, _Views...> {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __iterator& operator-=(difference_type __x)
|
||||
requires __zip_all_random_access<_Const, _Views...>
|
||||
{
|
||||
ranges::__tuple_for_each([&]<class _Iter>(_Iter& __i) { __i -= iter_difference_t<_Iter>(__x); }, __current_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr auto operator[](difference_type __n) const
|
||||
requires __zip_all_random_access<_Const, _Views...> {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto operator[](difference_type __n) const
|
||||
requires __zip_all_random_access<_Const, _Views...>
|
||||
{
|
||||
return ranges::__tuple_transform(
|
||||
[&]<class _Iter>(_Iter& __i) -> decltype(auto) { return __i[iter_difference_t<_Iter>(__n)]; }, __current_);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
|
||||
requires(equality_comparable<iterator_t<__maybe_const<_Const, _Views>>> && ...) {
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator==(const __iterator& __x, const __iterator& __y)
|
||||
requires(equality_comparable<iterator_t<__maybe_const<_Const, _Views>>> && ...)
|
||||
{
|
||||
if constexpr (__zip_all_bidirectional<_Const, _Views...>) {
|
||||
return __x.__current_ == __y.__current_;
|
||||
} else {
|
||||
|
@ -339,85 +340,85 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
|
||||
requires __zip_all_random_access<_Const, _Views...> {
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y)
|
||||
requires __zip_all_random_access<_Const, _Views...>
|
||||
{
|
||||
return __x.__current_ < __y.__current_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
|
||||
requires __zip_all_random_access<_Const, _Views...> {
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __iterator& __x, const __iterator& __y)
|
||||
requires __zip_all_random_access<_Const, _Views...>
|
||||
{
|
||||
return __y < __x;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
|
||||
requires __zip_all_random_access<_Const, _Views...> {
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y)
|
||||
requires __zip_all_random_access<_Const, _Views...>
|
||||
{
|
||||
return !(__y < __x);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
|
||||
requires __zip_all_random_access<_Const, _Views...> {
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y)
|
||||
requires __zip_all_random_access<_Const, _Views...>
|
||||
{
|
||||
return !(__x < __y);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y)
|
||||
requires __zip_all_random_access<_Const, _Views...> &&
|
||||
(three_way_comparable<iterator_t<__maybe_const<_Const, _Views>>> && ...) {
|
||||
(three_way_comparable<iterator_t<__maybe_const<_Const, _Views>>> && ...)
|
||||
{
|
||||
return __x.__current_ <=> __y.__current_;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr __iterator operator+(const __iterator& __i, difference_type __n)
|
||||
requires __zip_all_random_access<_Const, _Views...> {
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(const __iterator& __i, difference_type __n)
|
||||
requires __zip_all_random_access<_Const, _Views...>
|
||||
{
|
||||
auto __r = __i;
|
||||
__r += __n;
|
||||
return __r;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr __iterator operator+(difference_type __n, const __iterator& __i)
|
||||
requires __zip_all_random_access<_Const, _Views...> {
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator+(difference_type __n, const __iterator& __i)
|
||||
requires __zip_all_random_access<_Const, _Views...>
|
||||
{
|
||||
return __i + __n;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr __iterator operator-(const __iterator& __i, difference_type __n)
|
||||
requires __zip_all_random_access<_Const, _Views...> {
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr __iterator operator-(const __iterator& __i, difference_type __n)
|
||||
requires __zip_all_random_access<_Const, _Views...>
|
||||
{
|
||||
auto __r = __i;
|
||||
__r -= __n;
|
||||
return __r;
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr difference_type operator-(const __iterator& __x, const __iterator& __y)
|
||||
requires(sized_sentinel_for<iterator_t<__maybe_const<_Const, _Views>>, iterator_t<__maybe_const<_Const, _Views>>> &&
|
||||
...) {
|
||||
...)
|
||||
{
|
||||
const auto __diffs = ranges::__tuple_zip_transform(minus<>(), __x.__current_, __y.__current_);
|
||||
return std::apply(
|
||||
[](auto... __ds) {
|
||||
return ranges::min({difference_type(__ds)...},
|
||||
[](auto __a, auto __b) { return ranges::__abs(__a) < ranges::__abs(__b); });
|
||||
return ranges::min({difference_type(__ds)...}, [](auto __a, auto __b) {
|
||||
return ranges::__abs(__a) < ranges::__abs(__b);
|
||||
});
|
||||
},
|
||||
__diffs);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr auto iter_move(const __iterator& __i) noexcept(
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr auto iter_move(const __iterator& __i) noexcept(
|
||||
(noexcept(ranges::iter_move(std::declval<const iterator_t<__maybe_const<_Const, _Views>>&>())) && ...) &&
|
||||
(is_nothrow_move_constructible_v<range_rvalue_reference_t<__maybe_const<_Const, _Views>>> && ...)) {
|
||||
return ranges::__tuple_transform(ranges::iter_move, __i.__current_);
|
||||
}
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
friend constexpr void iter_swap(const __iterator& __l, const __iterator& __r) noexcept(
|
||||
_LIBCPP_HIDE_FROM_ABI friend constexpr void iter_swap(const __iterator& __l, const __iterator& __r) noexcept(
|
||||
(noexcept(ranges::iter_swap(std::declval<const iterator_t<__maybe_const<_Const, _Views>>&>(),
|
||||
std::declval<const iterator_t<__maybe_const<_Const, _Views>>&>())) &&
|
||||
...))
|
||||
requires(indirectly_swappable<iterator_t<__maybe_const<_Const, _Views>>> && ...) {
|
||||
requires(indirectly_swappable<iterator_t<__maybe_const<_Const, _Views>>> && ...)
|
||||
{
|
||||
ranges::__tuple_zip_for_each(ranges::iter_swap, __l.__current_, __r.__current_);
|
||||
}
|
||||
};
|
||||
|
@ -426,11 +427,11 @@ template <input_range... _Views>
|
|||
requires(view<_Views> && ...) && (sizeof...(_Views) > 0)
|
||||
template <bool _Const>
|
||||
class zip_view<_Views...>::__sentinel {
|
||||
|
||||
__tuple_or_pair<sentinel_t<__maybe_const<_Const, _Views>>...> __end_;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr explicit __sentinel(__tuple_or_pair<sentinel_t<__maybe_const<_Const, _Views>>...> __end) : __end_(__end) {}
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(
|
||||
__tuple_or_pair<sentinel_t<__maybe_const<_Const, _Views>>...> __end)
|
||||
: __end_(__end) {}
|
||||
|
||||
friend class zip_view<_Views...>;
|
||||
|
||||
|
@ -442,13 +443,11 @@ class zip_view<_Views...>::__sentinel {
|
|||
}
|
||||
|
||||
public:
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
__sentinel() = default;
|
||||
_LIBCPP_HIDE_FROM_ABI __sentinel() = default;
|
||||
|
||||
_LIBCPP_HIDE_FROM_ABI
|
||||
constexpr __sentinel(__sentinel<!_Const> __i)
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr __sentinel(__sentinel<!_Const> __i)
|
||||
requires _Const && (convertible_to<sentinel_t<_Views>, sentinel_t<__maybe_const<_Const, _Views>>> && ...)
|
||||
: __end_(std::move(__i.__end_)) {}
|
||||
: __end_(std::move(__i.__end_)) {}
|
||||
|
||||
template <bool _OtherConst>
|
||||
requires(sentinel_for<sentinel_t<__maybe_const<_Const, _Views>>, iterator_t<__maybe_const<_OtherConst, _Views>>> &&
|
||||
|
@ -467,8 +466,9 @@ public:
|
|||
return std::apply(
|
||||
[](auto... __ds) {
|
||||
using _Diff = common_type_t<range_difference_t<__maybe_const<_OtherConst, _Views>>...>;
|
||||
return ranges::min({_Diff(__ds)...},
|
||||
[](auto __a, auto __b) { return ranges::__abs(__a) < ranges::__abs(__b); });
|
||||
return ranges::min({_Diff(__ds)...}, [](auto __a, auto __b) {
|
||||
return ranges::__abs(__a) < ranges::__abs(__b);
|
||||
});
|
||||
},
|
||||
__diffs);
|
||||
}
|
||||
|
@ -490,19 +490,19 @@ namespace views {
|
|||
namespace __zip {
|
||||
|
||||
struct __fn {
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto operator()() const noexcept { return empty_view<tuple<>>{}; }
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr auto operator()() noexcept { return empty_view<tuple<>>{}; }
|
||||
|
||||
template <class... _Ranges>
|
||||
_LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ranges&&... __rs) const
|
||||
noexcept(noexcept(zip_view<all_t<_Ranges&&>...>(std::forward<_Ranges>(__rs)...)))
|
||||
-> decltype(zip_view<all_t<_Ranges&&>...>(std::forward<_Ranges>(__rs)...)) {
|
||||
_LIBCPP_HIDE_FROM_ABI static constexpr auto
|
||||
operator()(_Ranges&&... __rs) noexcept(noexcept(zip_view<all_t<_Ranges&&>...>(std::forward<_Ranges>(__rs)...)))
|
||||
-> decltype(zip_view<all_t<_Ranges&&>...>(std::forward<_Ranges>(__rs)...)) {
|
||||
return zip_view<all_t<_Ranges>...>(std::forward<_Ranges>(__rs)...);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __zip
|
||||
inline namespace __cpo {
|
||||
inline constexpr auto zip = __zip::__fn{};
|
||||
inline constexpr auto zip = __zip::__fn{};
|
||||
} // namespace __cpo
|
||||
} // namespace views
|
||||
} // namespace ranges
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue