master
  1// -*- C++ -*-
  2//===----------------------------------------------------------------------===//
  3//
  4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5// See https://llvm.org/LICENSE.txt for license information.
  6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7//
  8//===----------------------------------------------------------------------===//
  9
 10#ifndef _LIBCPP___RANGES_RBEGIN_H
 11#define _LIBCPP___RANGES_RBEGIN_H
 12
 13#include <__concepts/class_or_enum.h>
 14#include <__concepts/same_as.h>
 15#include <__config>
 16#include <__iterator/concepts.h>
 17#include <__iterator/readable_traits.h>
 18#include <__iterator/reverse_iterator.h>
 19#include <__ranges/access.h>
 20#include <__type_traits/decay.h>
 21#include <__type_traits/is_reference.h>
 22#include <__type_traits/remove_cvref.h>
 23#include <__type_traits/remove_reference.h>
 24#include <__utility/auto_cast.h>
 25
 26#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 27#  pragma GCC system_header
 28#endif
 29
 30_LIBCPP_BEGIN_NAMESPACE_STD
 31
 32#if _LIBCPP_STD_VER >= 20
 33
 34// [ranges.access.rbegin]
 35
 36namespace ranges {
 37namespace __rbegin {
 38template <class _Tp>
 39concept __member_rbegin = __can_borrow<_Tp> && requires(_Tp&& __t) {
 40  { _LIBCPP_AUTO_CAST(__t.rbegin()) } -> input_or_output_iterator;
 41};
 42
 43void rbegin() = delete;
 44
 45template <class _Tp>
 46concept __unqualified_rbegin =
 47    !__member_rbegin<_Tp> && __can_borrow<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {
 48      { _LIBCPP_AUTO_CAST(rbegin(__t)) } -> input_or_output_iterator;
 49    };
 50
 51template <class _Tp>
 52concept __can_reverse =
 53    __can_borrow<_Tp> && !__member_rbegin<_Tp> && !__unqualified_rbegin<_Tp> && requires(_Tp&& __t) {
 54      { ranges::begin(__t) } -> same_as<decltype(ranges::end(__t))>;
 55      { ranges::begin(__t) } -> bidirectional_iterator;
 56    };
 57
 58struct __fn {
 59  template <class _Tp>
 60    requires __member_rbegin<_Tp>
 61  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
 62      noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.rbegin()))) {
 63    return _LIBCPP_AUTO_CAST(__t.rbegin());
 64  }
 65
 66  template <class _Tp>
 67    requires __unqualified_rbegin<_Tp>
 68  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
 69      noexcept(noexcept(_LIBCPP_AUTO_CAST(rbegin(__t)))) {
 70    return _LIBCPP_AUTO_CAST(rbegin(__t));
 71  }
 72
 73  template <class _Tp>
 74    requires __can_reverse<_Tp>
 75  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const noexcept(noexcept(ranges::end(__t))) {
 76    return std::make_reverse_iterator(ranges::end(__t));
 77  }
 78
 79  void operator()(auto&&) const = delete;
 80};
 81} // namespace __rbegin
 82
 83inline namespace __cpo {
 84inline constexpr auto rbegin = __rbegin::__fn{};
 85} // namespace __cpo
 86} // namespace ranges
 87
 88// [range.access.crbegin]
 89
 90namespace ranges {
 91namespace __crbegin {
 92struct __fn {
 93  template <class _Tp>
 94    requires is_lvalue_reference_v<_Tp&&>
 95  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
 96      noexcept(noexcept(ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t))))
 97          -> decltype(ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t))) {
 98    return ranges::rbegin(static_cast<const remove_reference_t<_Tp>&>(__t));
 99  }
100
101  template <class _Tp>
102    requires is_rvalue_reference_v<_Tp&&>
103  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
104      noexcept(noexcept(ranges::rbegin(static_cast<const _Tp&&>(__t))))
105          -> decltype(ranges::rbegin(static_cast<const _Tp&&>(__t))) {
106    return ranges::rbegin(static_cast<const _Tp&&>(__t));
107  }
108};
109} // namespace __crbegin
110
111inline namespace __cpo {
112inline constexpr auto crbegin = __crbegin::__fn{};
113} // namespace __cpo
114} // namespace ranges
115
116#endif // _LIBCPP_STD_VER >= 20
117
118_LIBCPP_END_NAMESPACE_STD
119
120#endif // _LIBCPP___RANGES_RBEGIN_H