Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:13:41

0001 // -*- C++ -*-
0002 //===----------------------------------------------------------------------===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009 
0010 #ifndef _LIBCPP___CXX03___RANGES_REVERSE_VIEW_H
0011 #define _LIBCPP___CXX03___RANGES_REVERSE_VIEW_H
0012 
0013 #include <__cxx03/__concepts/constructible.h>
0014 #include <__cxx03/__config>
0015 #include <__cxx03/__iterator/concepts.h>
0016 #include <__cxx03/__iterator/next.h>
0017 #include <__cxx03/__iterator/reverse_iterator.h>
0018 #include <__cxx03/__ranges/access.h>
0019 #include <__cxx03/__ranges/all.h>
0020 #include <__cxx03/__ranges/concepts.h>
0021 #include <__cxx03/__ranges/enable_borrowed_range.h>
0022 #include <__cxx03/__ranges/non_propagating_cache.h>
0023 #include <__cxx03/__ranges/range_adaptor.h>
0024 #include <__cxx03/__ranges/size.h>
0025 #include <__cxx03/__ranges/subrange.h>
0026 #include <__cxx03/__ranges/view_interface.h>
0027 #include <__cxx03/__type_traits/conditional.h>
0028 #include <__cxx03/__type_traits/remove_cvref.h>
0029 #include <__cxx03/__utility/forward.h>
0030 #include <__cxx03/__utility/move.h>
0031 
0032 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0033 #  pragma GCC system_header
0034 #endif
0035 
0036 _LIBCPP_PUSH_MACROS
0037 #include <__cxx03/__undef_macros>
0038 
0039 _LIBCPP_BEGIN_NAMESPACE_STD
0040 
0041 #if _LIBCPP_STD_VER >= 20
0042 
0043 namespace ranges {
0044 template <view _View>
0045   requires bidirectional_range<_View>
0046 class reverse_view : public view_interface<reverse_view<_View>> {
0047   // We cache begin() whenever ranges::next is not guaranteed O(1) to provide an
0048   // amortized O(1) begin() method.
0049   static constexpr bool _UseCache = !random_access_range<_View> && !common_range<_View>;
0050   using _Cache = _If<_UseCache, __non_propagating_cache<reverse_iterator<iterator_t<_View>>>, __empty_cache>;
0051   _LIBCPP_NO_UNIQUE_ADDRESS _Cache __cached_begin_ = _Cache();
0052   _LIBCPP_NO_UNIQUE_ADDRESS _View __base_          = _View();
0053 
0054 public:
0055   _LIBCPP_HIDE_FROM_ABI reverse_view()
0056     requires default_initializable<_View>
0057   = default;
0058 
0059   _LIBCPP_HIDE_FROM_ABI constexpr explicit reverse_view(_View __view) : __base_(std::move(__view)) {}
0060 
0061   _LIBCPP_HIDE_FROM_ABI constexpr _View base() const&
0062     requires copy_constructible<_View>
0063   {
0064     return __base_;
0065   }
0066 
0067   _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); }
0068 
0069   _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator<iterator_t<_View>> begin() {
0070     if constexpr (_UseCache)
0071       if (__cached_begin_.__has_value())
0072         return *__cached_begin_;
0073 
0074     auto __tmp = std::make_reverse_iterator(ranges::next(ranges::begin(__base_), ranges::end(__base_)));
0075     if constexpr (_UseCache)
0076       __cached_begin_.__emplace(__tmp);
0077     return __tmp;
0078   }
0079 
0080   _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator<iterator_t<_View>> begin()
0081     requires common_range<_View>
0082   {
0083     return std::make_reverse_iterator(ranges::end(__base_));
0084   }
0085 
0086   _LIBCPP_HIDE_FROM_ABI constexpr auto begin() const
0087     requires common_range<const _View>
0088   {
0089     return std::make_reverse_iterator(ranges::end(__base_));
0090   }
0091 
0092   _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator<iterator_t<_View>> end() {
0093     return std::make_reverse_iterator(ranges::begin(__base_));
0094   }
0095 
0096   _LIBCPP_HIDE_FROM_ABI constexpr auto end() const
0097     requires common_range<const _View>
0098   {
0099     return std::make_reverse_iterator(ranges::begin(__base_));
0100   }
0101 
0102   _LIBCPP_HIDE_FROM_ABI constexpr auto size()
0103     requires sized_range<_View>
0104   {
0105     return ranges::size(__base_);
0106   }
0107 
0108   _LIBCPP_HIDE_FROM_ABI constexpr auto size() const
0109     requires sized_range<const _View>
0110   {
0111     return ranges::size(__base_);
0112   }
0113 };
0114 
0115 template <class _Range>
0116 reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;
0117 
0118 template <class _Tp>
0119 inline constexpr bool enable_borrowed_range<reverse_view<_Tp>> = enable_borrowed_range<_Tp>;
0120 
0121 namespace views {
0122 namespace __reverse {
0123 template <class _Tp>
0124 inline constexpr bool __is_reverse_view = false;
0125 
0126 template <class _Tp>
0127 inline constexpr bool __is_reverse_view<reverse_view<_Tp>> = true;
0128 
0129 template <class _Tp>
0130 inline constexpr bool __is_sized_reverse_subrange = false;
0131 
0132 template <class _Iter>
0133 inline constexpr bool
0134     __is_sized_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, subrange_kind::sized>> =
0135         true;
0136 
0137 template <class _Tp>
0138 inline constexpr bool __is_unsized_reverse_subrange = false;
0139 
0140 template <class _Iter, subrange_kind _Kind>
0141 inline constexpr bool __is_unsized_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, _Kind>> =
0142     _Kind == subrange_kind::unsized;
0143 
0144 template <class _Tp>
0145 struct __unwrapped_reverse_subrange {
0146   using type =
0147       void; // avoid SFINAE-ing out the overload below -- let the concept requirements do it for better diagnostics
0148 };
0149 
0150 template <class _Iter, subrange_kind _Kind>
0151 struct __unwrapped_reverse_subrange<subrange<reverse_iterator<_Iter>, reverse_iterator<_Iter>, _Kind>> {
0152   using type = subrange<_Iter, _Iter, _Kind>;
0153 };
0154 
0155 struct __fn : __range_adaptor_closure<__fn> {
0156   template <class _Range>
0157     requires __is_reverse_view<remove_cvref_t<_Range>>
0158   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
0159       noexcept(noexcept(std::forward<_Range>(__range).base())) -> decltype(std::forward<_Range>(__range).base()) {
0160     return std::forward<_Range>(__range).base();
0161   }
0162 
0163   template <class _Range,
0164             class _UnwrappedSubrange = typename __unwrapped_reverse_subrange<remove_cvref_t<_Range>>::type>
0165     requires __is_sized_reverse_subrange<remove_cvref_t<_Range>>
0166   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
0167       noexcept(noexcept(_UnwrappedSubrange(__range.end().base(), __range.begin().base(), __range.size())))
0168           -> decltype(_UnwrappedSubrange(__range.end().base(), __range.begin().base(), __range.size())) {
0169     return _UnwrappedSubrange(__range.end().base(), __range.begin().base(), __range.size());
0170   }
0171 
0172   template <class _Range,
0173             class _UnwrappedSubrange = typename __unwrapped_reverse_subrange<remove_cvref_t<_Range>>::type>
0174     requires __is_unsized_reverse_subrange<remove_cvref_t<_Range>>
0175   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const
0176       noexcept(noexcept(_UnwrappedSubrange(__range.end().base(), __range.begin().base())))
0177           -> decltype(_UnwrappedSubrange(__range.end().base(), __range.begin().base())) {
0178     return _UnwrappedSubrange(__range.end().base(), __range.begin().base());
0179   }
0180 
0181   template <class _Range>
0182     requires(!__is_reverse_view<remove_cvref_t<_Range>> && !__is_sized_reverse_subrange<remove_cvref_t<_Range>> &&
0183              !__is_unsized_reverse_subrange<remove_cvref_t<_Range>>)
0184   [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __range) const noexcept(noexcept(reverse_view{
0185       std::forward<_Range>(__range)})) -> decltype(reverse_view{std::forward<_Range>(__range)}) {
0186     return reverse_view{std::forward<_Range>(__range)};
0187   }
0188 };
0189 } // namespace __reverse
0190 
0191 inline namespace __cpo {
0192 inline constexpr auto reverse = __reverse::__fn{};
0193 } // namespace __cpo
0194 } // namespace views
0195 } // namespace ranges
0196 
0197 #endif // _LIBCPP_STD_VER >= 20
0198 
0199 _LIBCPP_END_NAMESPACE_STD
0200 
0201 _LIBCPP_POP_MACROS
0202 
0203 #endif // _LIBCPP___CXX03___RANGES_REVERSE_VIEW_H