Horizon
Loading...
Searching...
No Matches
view.hpp
Go to the documentation of this file.
1
2// Range v3 library
3//
4// Copyright Eric Niebler 2014-present
5//
6// Use, modification and distribution is subject to the
7// Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at
9// http://www.boost.org/LICENSE_1_0.txt)
10//
11// Project home: https://github.com/ericniebler/range-v3
12//
13
14#ifndef RANGES_V3_VIEW_VIEW_HPP
15#define RANGES_V3_VIEW_VIEW_HPP
16
17#include <type_traits>
18#include <utility>
19
20#include <meta/meta.hpp>
21
23
30#include <range/v3/utility/static_const.hpp>
31
32#include <range/v3/detail/prologue.hpp>
33
34namespace ranges
35{
38
40 namespace detail
41 {
42 struct dereference_fn
43 {
44 // clang-format off
45 template<typename I>
46 constexpr auto CPP_auto_fun(operator())(I &&i) (const)
47 (
48 return *(I &&) i
49 )
50 // clang-format on
51 };
52
53 struct view_closure_base_
54 {};
55 } // namespace detail
57
58 // clang-format off
61 template(typename Rng)(
62 concept (simple_view_impl_)(Rng),
63 same_as<iterator_t<Rng>, iterator_t<Rng const>> AND
64 same_as<sentinel_t<Rng>, sentinel_t<Rng const>>);
65
68 template<typename Rng>
69 CPP_concept simple_view_ =
70 view_<Rng> &&
71 range<Rng const> &&
72 CPP_concept_ref(ranges::simple_view_impl_, Rng);
73
76 template(typename ViewFn, typename Rng)(
77 concept (invocable_view_closure_)(ViewFn, Rng),
78 !derived_from<invoke_result_t<ViewFn, Rng>, detail::view_closure_base_>);
79
82 template<typename ViewFn, typename Rng>
83 CPP_concept invocable_view_closure =
84 invocable<ViewFn, Rng> &&
85 CPP_concept_ref(ranges::invocable_view_closure_, ViewFn, Rng);
86 // clang-format on
87
88 template<typename Rng>
89 constexpr bool simple_view() noexcept
90 {
91 return (bool)simple_view_<Rng>;
92 }
93
95 {
96 template<typename Fun>
97 constexpr views::view_closure<Fun> operator()(Fun fun) const
98 {
99 return views::view_closure<Fun>{static_cast<Fun &&>(fun)};
100 }
101 };
102
105 RANGES_INLINE_VARIABLE(make_view_closure_fn, make_view_closure)
106
107 namespace views
108 {
109 struct RANGES_STRUCT_WITH_ADL_BARRIER(view_closure_base)
110 : detail::view_closure_base_
111 {
112 // Piping requires viewable_ranges. Pipeing a value into a closure
113 // should not yield another closure.
114 template(typename Rng, typename ViewFn)(
115 requires viewable_range<Rng> AND
117 friend constexpr auto operator|(Rng && rng, view_closure<ViewFn> vw)
118 {
119 return static_cast<ViewFn &&>(vw)(static_cast<Rng &&>(rng));
120 }
121
122#ifndef RANGES_WORKAROUND_CLANG_43400
123 // This overload is deleted because when piping a range into an
124 // view, it must be moved in.
125 template<typename Rng, typename ViewFn> // **************************
126 friend constexpr auto // **************************
127 operator|(Rng &&, view_closure<ViewFn> const &) // ******* READ THIS ********
128 // **** IF YOUR COMPILE *****
129 -> CPP_broken_friend_ret(Rng)( // ****** BREAKS HERE *******
130 requires range<Rng> && // **************************
131 (!viewable_range<Rng>)) = delete; // **************************
132 // **************************************************************************
133 // * When piping a range into an adaptor, the range must satisfy the *
134 // * "viewable_range" concept. A range is viewable when either or both *
135 // * of these things are true: *
136 // * - The range is an lvalue (not a temporary object), OR *
137 // * - The range is a view (not a container). *
138 // **************************************************************************
139#endif
140
141 template<typename ViewFn, typename Pipeable>
142 friend constexpr auto operator|(view_closure<ViewFn> vw, Pipeable pipe)
143 -> CPP_broken_friend_ret(view_closure<composed<Pipeable, ViewFn>>)(
144 requires (is_pipeable_v<Pipeable>))
145 {
146 return make_view_closure(
147 compose(static_cast<Pipeable &&>(pipe), static_cast<ViewFn &&>(vw)));
148 }
149 };
150
151#ifdef RANGES_WORKAROUND_CLANG_43400
152 namespace RANGES_ADL_BARRIER_FOR(view_closure_base)
153 {
154 // This overload is deleted because when piping a range into an
155 // view, it must be moved in.
156 template(typename Rng, typename ViewFn)( // ************************
157 requires range<Rng> AND (!viewable_range<Rng>))// ************************
158 constexpr Rng // ************************
159 operator|(Rng &&, view_closure<ViewFn> const &) // ****** READ THIS *******
160 = delete; // *** IF YOUR COMPILE ****
161 // ***** BREAKS HERE ******
162 // ************************
163 // ************************
164 // ***************************************************************************
165 // * When piping a range into an adaptor, the range must satisfy the *
166 // * "viewable_range" concept. A range is viewable when either or both *
167 // * of these things are true: *
168 // * - The range is an lvalue (not a temporary object), OR *
169 // * - The range is a view (not a container). *
170 // ***************************************************************************
171 } // namespace )
172#endif // RANGES_WORKAROUND_CLANG_43400
173
174 template<typename ViewFn>
175 struct RANGES_EMPTY_BASES view_closure
176 : view_closure_base
177 , ViewFn
178 {
179 view_closure() = default;
180
181 constexpr explicit view_closure(ViewFn fn)
182 : ViewFn(static_cast<ViewFn &&>(fn))
183 {}
184 };
185
188 struct view_access_
189 {
190 template<typename ViewFn>
191 struct impl
192 {
193 // clang-format off
194 template<typename... Ts, typename V = ViewFn>
195 static constexpr auto CPP_auto_fun(bind)(Ts &&... ts)
196 (
197 return V::bind(static_cast<Ts &&>(ts)...)
198 )
199 // clang-format on
200 };
201 };
202
203 using view_access RANGES_DEPRECATED(
204 "view_access and views::view<> are deprecated. Please "
205 "replace view<> with view_closure<> and discontinue use of view_access.") =
206 view_access_;
207
208 template<typename>
209 struct old_view_;
210
211 struct make_view_fn_
212 {
213 template<typename Fun>
214 constexpr old_view_<Fun> operator()(Fun fun) const
215 {
216 return old_view_<Fun>{static_cast<Fun &&>(fun)};
217 }
218 };
219 using make_view_fn RANGES_DEPRECATED(
220 "make_view_fn is deprecated. Please use "
221 "make_view_closure instead.") = make_view_fn_;
222
223 namespace
224 {
225 RANGES_DEPRECATED(
226 "make_view and views::view<> has been deprecated. Please switch to "
227 "make_view_closure and views::view_closure.")
228 RANGES_INLINE_VAR constexpr auto & make_view =
229 static_const<make_view_fn_>::value;
230 } // namespace
231
232 template<typename ViewFn>
233 struct old_view_ : pipeable_base
234 {
235 private:
236 ViewFn vw_;
237 friend pipeable_access;
238
239 // Piping requires range arguments or lvalue containers.
240 template(typename Rng, typename Vw)(
241 requires viewable_range<Rng> AND invocable<ViewFn &, Rng>)
242 static constexpr auto pipe(Rng && rng, Vw && v)
243 {
244 return v.vw_(static_cast<Rng &&>(rng));
245 }
246
247 public:
248 old_view_() = default;
249
250 constexpr explicit old_view_(ViewFn a) noexcept(
251 std::is_nothrow_move_constructible<ViewFn>::value)
252 : vw_(std::move(a))
253 {}
254
255 // Calling directly requires a viewable_range.
256 template(typename Rng, typename... Rest)(
257 requires viewable_range<Rng> AND invocable<ViewFn const &, Rng, Rest...>)
258 constexpr invoke_result_t<ViewFn const &, Rng, Rest...> //
259 operator()(Rng && rng, Rest &&... rest) const
260 {
261 return vw_(static_cast<Rng &&>(rng), static_cast<Rest &&>(rest)...);
262 }
263
264 // Currying overload.
265 // clang-format off
266 template<typename... Ts, typename V = ViewFn>
267 constexpr auto CPP_auto_fun(operator())(Ts &&... ts)(const)
268 (
269 return make_view_fn_{}(
270 view_access_::impl<V>::bind(vw_, static_cast<Ts &&>(ts)...))
271 )
272 // clang-format on
273 };
274
275 template<typename ViewFn>
276 using view RANGES_DEPRECATED(
277 "The views::view<> template is deprecated. Please switch to view_closure") =
278 old_view_<ViewFn>;
280 } // namespace views
281
282 template<typename ViewFn>
283 RANGES_INLINE_VAR constexpr bool is_pipeable_v<views::view_closure<ViewFn>> = true;
285} // namespace ranges
286
287#include <range/v3/detail/epilogue.hpp>
288
289#endif
The invocable_view_closure_ concept.
The invocable_view_closure concept.
The simple_view_impl_ concept.
The viewable_range concept.
Tiny meta-programming library.
Definition view.hpp:95
Definition view.hpp:178