Path: blob/main/contrib/llvm-project/libcxx/include/__ranges/access.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_ACCESS_H10#define _LIBCPP___RANGES_ACCESS_H1112#include <__concepts/class_or_enum.h>13#include <__config>14#include <__iterator/concepts.h>15#include <__iterator/readable_traits.h>16#include <__ranges/enable_borrowed_range.h>17#include <__type_traits/decay.h>18#include <__type_traits/is_reference.h>19#include <__type_traits/remove_cvref.h>20#include <__type_traits/remove_reference.h>21#include <__utility/auto_cast.h>22#include <__utility/declval.h>23#include <cstddef>2425#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)26# pragma GCC system_header27#endif2829_LIBCPP_BEGIN_NAMESPACE_STD3031#if _LIBCPP_STD_VER >= 203233namespace ranges {34template <class _Tp>35concept __can_borrow = is_lvalue_reference_v<_Tp> || enable_borrowed_range<remove_cvref_t<_Tp>>;36} // namespace ranges3738// [range.access.begin]3940namespace ranges {41namespace __begin {42template <class _Tp>43concept __member_begin = __can_borrow<_Tp> && requires(_Tp&& __t) {44{ _LIBCPP_AUTO_CAST(__t.begin()) } -> input_or_output_iterator;45};4647void begin() = delete;4849template <class _Tp>50concept __unqualified_begin =51!__member_begin<_Tp> && __can_borrow<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {52{ _LIBCPP_AUTO_CAST(begin(__t)) } -> input_or_output_iterator;53};5455struct __fn {56template <class _Tp>57[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[]) const noexcept58requires(sizeof(_Tp) >= 0) // Disallow incomplete element types.59{60return __t + 0;61}6263template <class _Tp, size_t _Np>64[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept65requires(sizeof(_Tp) >= 0) // Disallow incomplete element types.66{67return __t + 0;68}6970template <class _Tp>71requires __member_begin<_Tp>72[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const73noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.begin()))) {74return _LIBCPP_AUTO_CAST(__t.begin());75}7677template <class _Tp>78requires __unqualified_begin<_Tp>79[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const80noexcept(noexcept(_LIBCPP_AUTO_CAST(begin(__t)))) {81return _LIBCPP_AUTO_CAST(begin(__t));82}8384void operator()(auto&&) const = delete;85};86} // namespace __begin8788inline namespace __cpo {89inline constexpr auto begin = __begin::__fn{};90} // namespace __cpo91} // namespace ranges9293// [range.range]9495namespace ranges {96template <class _Tp>97using iterator_t = decltype(ranges::begin(std::declval<_Tp&>()));98} // namespace ranges99100// [range.access.end]101102namespace ranges {103namespace __end {104template <class _Tp>105concept __member_end = __can_borrow<_Tp> && requires(_Tp&& __t) {106typename iterator_t<_Tp>;107{ _LIBCPP_AUTO_CAST(__t.end()) } -> sentinel_for<iterator_t<_Tp>>;108};109110void end() = delete;111112template <class _Tp>113concept __unqualified_end =114!__member_end<_Tp> && __can_borrow<_Tp> && __class_or_enum<remove_cvref_t<_Tp>> && requires(_Tp&& __t) {115typename iterator_t<_Tp>;116{ _LIBCPP_AUTO_CAST(end(__t)) } -> sentinel_for<iterator_t<_Tp>>;117};118119struct __fn {120template <class _Tp, size_t _Np>121[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp (&__t)[_Np]) const noexcept122requires(sizeof(_Tp) >= 0) // Disallow incomplete element types.123{124return __t + _Np;125}126127template <class _Tp>128requires __member_end<_Tp>129[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const130noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.end()))) {131return _LIBCPP_AUTO_CAST(__t.end());132}133134template <class _Tp>135requires __unqualified_end<_Tp>136[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const137noexcept(noexcept(_LIBCPP_AUTO_CAST(end(__t)))) {138return _LIBCPP_AUTO_CAST(end(__t));139}140141void operator()(auto&&) const = delete;142};143} // namespace __end144145inline namespace __cpo {146inline constexpr auto end = __end::__fn{};147} // namespace __cpo148} // namespace ranges149150// [range.access.cbegin]151152namespace ranges {153namespace __cbegin {154struct __fn {155template <class _Tp>156requires is_lvalue_reference_v<_Tp&&>157[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const158noexcept(noexcept(ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t))))159-> decltype(ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t))) {160return ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t));161}162163template <class _Tp>164requires is_rvalue_reference_v<_Tp&&>165[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const166noexcept(noexcept(ranges::begin(static_cast<const _Tp&&>(__t))))167-> decltype(ranges::begin(static_cast<const _Tp&&>(__t))) {168return ranges::begin(static_cast<const _Tp&&>(__t));169}170};171} // namespace __cbegin172173inline namespace __cpo {174inline constexpr auto cbegin = __cbegin::__fn{};175} // namespace __cpo176} // namespace ranges177178// [range.access.cend]179180namespace ranges {181namespace __cend {182struct __fn {183template <class _Tp>184requires is_lvalue_reference_v<_Tp&&>185[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const186noexcept(noexcept(ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t))))187-> decltype(ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t))) {188return ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t));189}190191template <class _Tp>192requires is_rvalue_reference_v<_Tp&&>193[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const noexcept(194noexcept(ranges::end(static_cast<const _Tp&&>(__t)))) -> decltype(ranges::end(static_cast<const _Tp&&>(__t))) {195return ranges::end(static_cast<const _Tp&&>(__t));196}197};198} // namespace __cend199200inline namespace __cpo {201inline constexpr auto cend = __cend::__fn{};202} // namespace __cpo203} // namespace ranges204205#endif // _LIBCPP_STD_VER >= 20206207_LIBCPP_END_NAMESPACE_STD208209#endif // _LIBCPP___RANGES_ACCESS_H210211212