Path: blob/main/contrib/llvm-project/libcxx/include/__ranges/rend.h
35236 views
// -*- C++ -*-1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//89#ifndef _LIBCPP___RANGES_REND_H10#define _LIBCPP___RANGES_REND_H1112#include <__concepts/class_or_enum.h>13#include <__concepts/same_as.h>14#include <__config>15#include <__iterator/concepts.h>16#include <__iterator/readable_traits.h>17#include <__iterator/reverse_iterator.h>18#include <__ranges/access.h>19#include <__ranges/rbegin.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>2526#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)27# pragma GCC system_header28#endif2930_LIBCPP_BEGIN_NAMESPACE_STD3132#if _LIBCPP_STD_VER >= 203334// [range.access.rend]3536namespace ranges {37namespace __rend {38template <class _Tp>39concept __member_rend = __can_borrow<_Tp> && requires(_Tp&& __t) {40ranges::rbegin(__t);41{ _LIBCPP_AUTO_CAST(__t.rend()) } -> sentinel_for<decltype(ranges::rbegin(__t))>;42};4344void rend() = delete;4546template <class _Tp>47concept __unqualified_rend =48!__member_rend<_Tp> && __can_borrow<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {49ranges::rbegin(__t);50{ _LIBCPP_AUTO_CAST(rend(__t)) } -> sentinel_for<decltype(ranges::rbegin(__t))>;51};5253template <class _Tp>54concept __can_reverse = __can_borrow<_Tp> && !__member_rend<_Tp> && !__unqualified_rend<_Tp> && requires(_Tp&& __t) {55{ ranges::begin(__t) } -> same_as<decltype(ranges::end(__t))>;56{ ranges::begin(__t) } -> bidirectional_iterator;57};5859class __fn {60public:61template <class _Tp>62requires __member_rend<_Tp>63[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const64noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.rend()))) {65return _LIBCPP_AUTO_CAST(__t.rend());66}6768template <class _Tp>69requires __unqualified_rend<_Tp>70[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const71noexcept(noexcept(_LIBCPP_AUTO_CAST(rend(__t)))) {72return _LIBCPP_AUTO_CAST(rend(__t));73}7475template <class _Tp>76requires __can_reverse<_Tp>77[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const78noexcept(noexcept(ranges::begin(__t))) {79return std::make_reverse_iterator(ranges::begin(__t));80}8182void operator()(auto&&) const = delete;83};84} // namespace __rend8586inline namespace __cpo {87inline constexpr auto rend = __rend::__fn{};88} // namespace __cpo89} // namespace ranges9091// [range.access.crend]9293namespace ranges {94namespace __crend {95struct __fn {96template <class _Tp>97requires is_lvalue_reference_v<_Tp&&>98[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const99noexcept(noexcept(ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t))))100-> decltype(ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t))) {101return ranges::rend(static_cast<const remove_reference_t<_Tp>&>(__t));102}103104template <class _Tp>105requires is_rvalue_reference_v<_Tp&&>106[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const noexcept(107noexcept(ranges::rend(static_cast<const _Tp&&>(__t)))) -> decltype(ranges::rend(static_cast<const _Tp&&>(__t))) {108return ranges::rend(static_cast<const _Tp&&>(__t));109}110};111} // namespace __crend112113inline namespace __cpo {114inline constexpr auto crend = __crend::__fn{};115} // namespace __cpo116} // namespace ranges117118#endif // _LIBCPP_STD_VER >= 20119120_LIBCPP_END_NAMESPACE_STD121122#endif // _LIBCPP___RANGES_REND_H123124125