1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef _LIBCPP___RANGES_VIEW_INTERFACE_H
#define _LIBCPP___RANGES_VIEW_INTERFACE_H
#include <__assert>
#include <__concepts/derived_from.h>
#include <__concepts/same_as.h>
#include <__config>
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
#include <__iterator/prev.h>
#include <__memory/pointer_traits.h>
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/empty.h>
#include <type_traits>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
namespace ranges {
template<class _Derived>
requires is_class_v<_Derived> && same_as<_Derived, remove_cv_t<_Derived>>
class view_interface {
_LIBCPP_HIDE_FROM_ABI
constexpr _Derived& __derived() noexcept {
static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>);
return static_cast<_Derived&>(*this);
}
_LIBCPP_HIDE_FROM_ABI
constexpr _Derived const& __derived() const noexcept {
static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>);
return static_cast<_Derived const&>(*this);
}
public:
template<class _D2 = _Derived>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty()
requires forward_range<_D2>
{
return ranges::begin(__derived()) == ranges::end(__derived());
}
template<class _D2 = _Derived>
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const
requires forward_range<const _D2>
{
return ranges::begin(__derived()) == ranges::end(__derived());
}
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr explicit operator bool()
requires requires (_D2& __t) { ranges::empty(__t); }
{
return !ranges::empty(__derived());
}
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr explicit operator bool() const
requires requires (const _D2& __t) { ranges::empty(__t); }
{
return !ranges::empty(__derived());
}
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr auto data()
requires contiguous_iterator<iterator_t<_D2>>
{
return std::to_address(ranges::begin(__derived()));
}
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr auto data() const
requires range<const _D2> && contiguous_iterator<iterator_t<const _D2>>
{
return std::to_address(ranges::begin(__derived()));
}
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr auto size()
requires forward_range<_D2> && sized_sentinel_for<sentinel_t<_D2>, iterator_t<_D2>>
{
return ranges::end(__derived()) - ranges::begin(__derived());
}
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr auto size() const
requires forward_range<const _D2> && sized_sentinel_for<sentinel_t<const _D2>, iterator_t<const _D2>>
{
return ranges::end(__derived()) - ranges::begin(__derived());
}
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) front()
requires forward_range<_D2>
{
_LIBCPP_ASSERT(!empty(),
"Precondition `!empty()` not satisfied. `.front()` called on an empty view.");
return *ranges::begin(__derived());
}
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) front() const
requires forward_range<const _D2>
{
_LIBCPP_ASSERT(!empty(),
"Precondition `!empty()` not satisfied. `.front()` called on an empty view.");
return *ranges::begin(__derived());
}
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) back()
requires bidirectional_range<_D2> && common_range<_D2>
{
_LIBCPP_ASSERT(!empty(),
"Precondition `!empty()` not satisfied. `.back()` called on an empty view.");
return *ranges::prev(ranges::end(__derived()));
}
template<class _D2 = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) back() const
requires bidirectional_range<const _D2> && common_range<const _D2>
{
_LIBCPP_ASSERT(!empty(),
"Precondition `!empty()` not satisfied. `.back()` called on an empty view.");
return *ranges::prev(ranges::end(__derived()));
}
template<random_access_range _RARange = _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) operator[](range_difference_t<_RARange> __index)
{
return ranges::begin(__derived())[__index];
}
template<random_access_range _RARange = const _Derived>
_LIBCPP_HIDE_FROM_ABI
constexpr decltype(auto) operator[](range_difference_t<_RARange> __index) const
{
return ranges::begin(__derived())[__index];
}
};
} // namespace ranges
#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP___RANGES_VIEW_INTERFACE_H
|