]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/stl_interfaces/view_interface.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / stl_interfaces / view_interface.hpp
1 // Copyright (C) 2019 T. Zachary Laine
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See
4 // accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 #ifndef BOOST_STL_INTERFACES_VIEW_INTERFACE_HPP
7 #define BOOST_STL_INTERFACES_VIEW_INTERFACE_HPP
8
9 #include <boost/stl_interfaces/fwd.hpp>
10
11
12 namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V1 {
13
14 /** A CRTP template that one may derive from to make it easier to define
15 `std::ranges::view`-like types with a container-like interface. This
16 is a pre-C++20 version of C++20's `view_interface` (see
17 [view.interface] in the C++ standard).
18
19 The template parameter `D` for `view_interface` may be an incomplete
20 type. Before any member of the resulting specialization of
21 `view_interface` other than special member functions is referenced,
22 `D` shall be complete, and model both
23 `std::derived_from<view_interface<D>>` and `std::view`. */
24 template<
25 typename Derived,
26 element_layout Contiguity = element_layout::discontiguous
27 #ifndef BOOST_STL_INTERFACES_DOXYGEN
28 ,
29 typename E = std::enable_if_t<
30 std::is_class<Derived>::value &&
31 std::is_same<Derived, std::remove_cv_t<Derived>>::value>
32 #endif
33 >
34 struct view_interface;
35
36 namespace v1_dtl {
37 template<typename D, element_layout Contiguity>
38 void derived_view(view_interface<D, Contiguity> const &);
39 }
40
41 template<
42 typename Derived,
43 element_layout Contiguity
44 #ifndef BOOST_STL_INTERFACES_DOXYGEN
45 ,
46 typename E
47 #endif
48 >
49 struct view_interface
50 {
51 #ifndef BOOST_STL_INTERFACES_DOXYGEN
52 private:
53 constexpr Derived & derived() noexcept
54 {
55 return static_cast<Derived &>(*this);
56 }
57 constexpr const Derived & derived() const noexcept
58 {
59 return static_cast<Derived const &>(*this);
60 }
61 #endif
62
63 public:
64 template<typename D = Derived>
65 constexpr auto empty() noexcept(
66 noexcept(std::declval<D &>().begin() == std::declval<D &>().end()))
67 -> decltype(
68 std::declval<D &>().begin() == std::declval<D &>().end())
69 {
70 return derived().begin() == derived().end();
71 }
72 template<typename D = Derived>
73 constexpr auto empty() const noexcept(noexcept(
74 std::declval<D const &>().begin() ==
75 std::declval<D const &>().end()))
76 -> decltype(
77 std::declval<D const &>().begin() ==
78 std::declval<D const &>().end())
79 {
80 return derived().begin() == derived().end();
81 }
82
83 template<
84 typename D = Derived,
85 typename R = decltype(std::declval<D &>().empty())>
86 constexpr explicit
87 operator bool() noexcept(noexcept(std::declval<D &>().empty()))
88 {
89 return !derived().empty();
90 }
91 template<
92 typename D = Derived,
93 typename R = decltype(std::declval<D const &>().empty())>
94 constexpr explicit operator bool() const
95 noexcept(noexcept(std::declval<D const &>().empty()))
96 {
97 return !derived().empty();
98 }
99
100 template<
101 typename D = Derived,
102 element_layout C = Contiguity,
103 typename Enable = std::enable_if_t<C == element_layout::contiguous>>
104 constexpr auto data() noexcept(noexcept(std::declval<D &>().begin()))
105 -> decltype(std::addressof(*std::declval<D &>().begin()))
106 {
107 return std::addressof(*derived().begin());
108 }
109 template<
110 typename D = Derived,
111 element_layout C = Contiguity,
112 typename Enable = std::enable_if_t<C == element_layout::contiguous>>
113 constexpr auto data() const
114 noexcept(noexcept(std::declval<D const &>().begin()))
115 -> decltype(std::addressof(*std::declval<D const &>().begin()))
116 {
117 return std::addressof(*derived().begin());
118 }
119
120 template<typename D = Derived>
121 constexpr auto size() noexcept(
122 noexcept(std::declval<D &>().end() - std::declval<D &>().begin()))
123 -> decltype(std::declval<D &>().end() - std::declval<D &>().begin())
124 {
125 return derived().end() - derived().begin();
126 }
127 template<typename D = Derived>
128 constexpr auto size() const noexcept(noexcept(
129 std::declval<D const &>().end() -
130 std::declval<D const &>().begin()))
131 -> decltype(
132 std::declval<D const &>().end() -
133 std::declval<D const &>().begin())
134 {
135 return derived().end() - derived().begin();
136 }
137
138 template<typename D = Derived>
139 constexpr auto front() noexcept(noexcept(*std::declval<D &>().begin()))
140 -> decltype(*std::declval<D &>().begin())
141 {
142 return *derived().begin();
143 }
144 template<typename D = Derived>
145 constexpr auto front() const
146 noexcept(noexcept(*std::declval<D const &>().begin()))
147 -> decltype(*std::declval<D const &>().begin())
148 {
149 return *derived().begin();
150 }
151
152 template<
153 typename D = Derived,
154 typename Enable = std::enable_if_t<
155 v1_dtl::decrementable_sentinel<D>::value &&
156 v1_dtl::common_range<D>::value>>
157 constexpr auto
158 back() noexcept(noexcept(*std::prev(std::declval<D &>().end())))
159 -> decltype(*std::prev(std::declval<D &>().end()))
160 {
161 return *std::prev(derived().end());
162 }
163 template<
164 typename D = Derived,
165 typename Enable = std::enable_if_t<
166 v1_dtl::decrementable_sentinel<D>::value &&
167 v1_dtl::common_range<D>::value>>
168 constexpr auto back() const
169 noexcept(noexcept(*std::prev(std::declval<D const &>().end())))
170 -> decltype(*std::prev(std::declval<D const &>().end()))
171 {
172 return *std::prev(derived().end());
173 }
174
175 template<typename D = Derived>
176 constexpr auto operator[](v1_dtl::range_difference_t<D> n) noexcept(
177 noexcept(std::declval<D &>().begin()[n]))
178 -> decltype(std::declval<D &>().begin()[n])
179 {
180 return derived().begin()[n];
181 }
182 template<typename D = Derived>
183 constexpr auto operator[](v1_dtl::range_difference_t<D> n) const
184 noexcept(noexcept(std::declval<D const &>().begin()[n]))
185 -> decltype(std::declval<D const &>().begin()[n])
186 {
187 return derived().begin()[n];
188 }
189 };
190
191 /** Implementation of `operator!=()` for all views derived from
192 `view_interface`. */
193 template<typename ViewInterface>
194 constexpr auto operator!=(ViewInterface lhs, ViewInterface rhs) noexcept(
195 noexcept(lhs == rhs))
196 -> decltype(v1_dtl::derived_view(lhs), !(lhs == rhs))
197 {
198 return !(lhs == rhs);
199 }
200
201 }}}
202
203
204 #if defined(BOOST_STL_INTERFACES_DOXYGEN) || BOOST_STL_INTERFACES_USE_CONCEPTS
205
206 namespace boost { namespace stl_interfaces { BOOST_STL_INTERFACES_NAMESPACE_V2 {
207
208 /** A template alias for `std::ranges::view_interface`. This only exists
209 to make migration from Boost.STLInterfaces to C++20 easier; switch to
210 the one in `std` as soon as you can. */
211 template<typename D, element_layout = element_layout::discontiguous>
212 using view_interface = std::ranges::view_interface<D>;
213
214 }}}
215
216 #endif
217
218 #endif