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