Path: blob/main/contrib/llvm-project/libcxx/include/__ranges/view_interface.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_VIEW_INTERFACE_H10#define _LIBCPP___RANGES_VIEW_INTERFACE_H1112#include <__assert>13#include <__concepts/derived_from.h>14#include <__concepts/same_as.h>15#include <__config>16#include <__iterator/concepts.h>17#include <__iterator/iterator_traits.h>18#include <__iterator/prev.h>19#include <__memory/pointer_traits.h>20#include <__ranges/access.h>21#include <__ranges/concepts.h>22#include <__ranges/empty.h>23#include <__ranges/size.h>24#include <__type_traits/is_class.h>25#include <__type_traits/make_unsigned.h>26#include <__type_traits/remove_cv.h>2728#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)29# pragma GCC system_header30#endif3132_LIBCPP_BEGIN_NAMESPACE_STD3334#if _LIBCPP_STD_VER >= 203536namespace ranges {3738template <class _Derived>39requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>40class view_interface {41_LIBCPP_HIDE_FROM_ABI constexpr _Derived& __derived() noexcept {42static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>);43return static_cast<_Derived&>(*this);44}4546_LIBCPP_HIDE_FROM_ABI constexpr _Derived const& __derived() const noexcept {47static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>);48return static_cast<_Derived const&>(*this);49}5051public:52template <class _D2 = _Derived>53[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty()54requires sized_range<_D2> || forward_range<_D2>55{56if constexpr (sized_range<_D2>) {57return ranges::size(__derived()) == 0;58} else {59return ranges::begin(__derived()) == ranges::end(__derived());60}61}6263template <class _D2 = _Derived>64[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const65requires sized_range<const _D2> || forward_range<const _D2>66{67if constexpr (sized_range<const _D2>) {68return ranges::size(__derived()) == 0;69} else {70return ranges::begin(__derived()) == ranges::end(__derived());71}72}7374template <class _D2 = _Derived>75_LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool()76requires requires(_D2& __t) { ranges::empty(__t); }77{78return !ranges::empty(__derived());79}8081template <class _D2 = _Derived>82_LIBCPP_HIDE_FROM_ABI constexpr explicit operator bool() const83requires requires(const _D2& __t) { ranges::empty(__t); }84{85return !ranges::empty(__derived());86}8788template <class _D2 = _Derived>89_LIBCPP_HIDE_FROM_ABI constexpr auto data()90requires contiguous_iterator<iterator_t<_D2>>91{92return std::to_address(ranges::begin(__derived()));93}9495template <class _D2 = _Derived>96_LIBCPP_HIDE_FROM_ABI constexpr auto data() const97requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>>98{99return std::to_address(ranges::begin(__derived()));100}101102template <class _D2 = _Derived>103_LIBCPP_HIDE_FROM_ABI constexpr auto size()104requires forward_range<_D2> && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>>105{106return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived()));107}108109template <class _D2 = _Derived>110_LIBCPP_HIDE_FROM_ABI constexpr auto size() const111requires forward_range<const _D2> && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>>112{113return std::__to_unsigned_like(ranges::end(__derived()) - ranges::begin(__derived()));114}115116template <class _D2 = _Derived>117_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front()118requires forward_range<_D2>119{120_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(121!empty(), "Precondition `!empty()` not satisfied. `.front()` called on an empty view.");122return *ranges::begin(__derived());123}124125template <class _D2 = _Derived>126_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) front() const127requires forward_range<const _D2>128{129_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(130!empty(), "Precondition `!empty()` not satisfied. `.front()` called on an empty view.");131return *ranges::begin(__derived());132}133134template <class _D2 = _Derived>135_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back()136requires bidirectional_range<_D2> && common_range<_D2>137{138_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(139!empty(), "Precondition `!empty()` not satisfied. `.back()` called on an empty view.");140return *ranges::prev(ranges::end(__derived()));141}142143template <class _D2 = _Derived>144_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) back() const145requires bidirectional_range<const _D2> && common_range<const _D2>146{147_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(148!empty(), "Precondition `!empty()` not satisfied. `.back()` called on an empty view.");149return *ranges::prev(ranges::end(__derived()));150}151152template <random_access_range _RARange = _Derived>153_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) {154return ranges::begin(__derived())[__index];155}156157template <random_access_range _RARange = const _Derived>158_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const {159return ranges::begin(__derived())[__index];160}161};162163} // namespace ranges164165#endif // _LIBCPP_STD_VER >= 20166167_LIBCPP_END_NAMESPACE_STD168169#endif // _LIBCPP___RANGES_VIEW_INTERFACE_H170171172