File Coverage

/usr/local/lib/perl5/site_perl/5.26.1/XS/librangeV3.x/i/range/v3/view_adaptor.hpp
Criterion Covered Total %
statement 43 43 100.0
branch 6 12 50.0
condition n/a
subroutine n/a
pod n/a
total 49 55 89.0


line stmt bran cond sub pod time code
1             /// \file
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             #ifndef RANGES_V3_VIEW_ADAPTOR_HPP
14             #define RANGES_V3_VIEW_ADAPTOR_HPP
15              
16             #include
17             #include
18             #include
19             #include
20             #include
21             #include
22             #include
23             #include
24             #include
25             #include
26              
27             namespace ranges
28             {
29             inline namespace v3
30             {
31             /// \cond
32             namespace detail
33             {
34             template
35             using begin_adaptor_t =
36             detail::decay_t()))>;
37              
38             template
39             using end_adaptor_t =
40             detail::decay_t()))>;
41              
42             template
43             using adapted_iterator_t =
44             detail::decay_t>().begin(std::declval()))>;
45              
46             template
47             using adapted_sentinel_t =
48             detail::decay_t>().end(std::declval()))>;
49              
50             struct adaptor_base_current_mem_fn
51             {};
52              
53             template
54             struct adaptor_value_type_2_
55             : compressed_pair
56             {
57             using compressed_pair::compressed_pair;
58             };
59              
60             template
61             struct adaptor_value_type_2_<
62             BaseIter,
63             Adapt,
64             meta::void_(), adaptor_base_current_mem_fn{}))>>
65             : compressed_pair
66             {
67 1276           using compressed_pair::compressed_pair;
68             using value_type = value_type_t;
69             };
70              
71             template
72             struct adaptor_value_type_
73             : adaptor_value_type_2_
74             {
75 1276           using adaptor_value_type_2_::adaptor_value_type_2_;
76             };
77              
78             template
79             struct adaptor_value_type_>
80             : compressed_pair
81             {
82 1276           using compressed_pair::compressed_pair;
83             #ifdef RANGES_WORKAROUND_MSVC_688606
84             using value_type = value_type_t;
85             #else // ^^^ workaround ^^^ / vvv no workaround vvv
86             using value_type = typename Adapt::value_type;
87             #endif // RANGES_WORKAROUND_MSVC_688606
88             };
89             }
90             /// \endcond
91              
92             /// \addtogroup group-core
93             /// @{
94             template
95             struct adaptor_cursor;
96              
97             template
98             struct adaptor_sentinel;
99              
100             struct adaptor_base
101             {
102 1276           adaptor_base() = default;
103             adaptor_base(adaptor_base &&) = default;
104             adaptor_base(adaptor_base const &) = default;
105             adaptor_base &operator=(adaptor_base &&) = default;
106             adaptor_base &operator=(adaptor_base const &) = default;
107              
108             adaptor_base(detail::any, detail::any = {}, detail::any = {})
109             {}
110             template
111 319           static constexpr auto begin(Rng &rng)
112 319           RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT
113             (
114             ranges::begin(rng.base())
115             )
116             template
117 638           static constexpr auto end(Rng &rng)
118 638           RANGES_DECLTYPE_AUTO_RETURN_NOEXCEPT
119             (
120             ranges::end(rng.base())
121             )
122             template())>
123 946           static bool equal(I const &it0, I const &it1)
124             {
125 946           return it0 == it1;
126             }
127             template())>
128 154           static reference_t read(I const &it,
129             detail::adaptor_base_current_mem_fn = {})
130             noexcept(noexcept(reference_t(*it)))
131             {
132 154           return *it;
133             }
134             template())>
135 154           static void next(I &it)
136             {
137 154           ++it;
138 154           }
139             template())>
140             static void prev(I &it)
141             {
142             --it;
143             }
144             template())>
145             static void advance(I &it, difference_type_t n)
146             {
147             it += n;
148             }
149             template())>
150             static difference_type_t distance_to(I const &it0, I const &it1)
151             {
152             return it1 - it0;
153             }
154             template())>
155             static constexpr bool empty(I const &it, S const &end)
156             {
157             return it == end;
158             }
159             };
160              
161             // Build a sentinel out of a sentinel into the adapted range, and an
162             // adaptor that customizes behavior.
163             template
164             struct adaptor_sentinel
165             : private compressed_pair
166             {
167             private:
168             template
169             friend struct adaptor_cursor;
170              
171             using compressed_pair::first;
172             using compressed_pair::second;
173             public:
174             using compressed_pair::compressed_pair;
175              
176             // All sentinels into adapted ranges have a base() member for fetching
177             // the underlying sentinel.
178             BaseSent base() const
179             {
180             return first();
181             }
182             };
183              
184             // Build a cursor out of an iterator into the adapted range, and an
185             // adaptor that customizes behavior.
186             template
187             struct adaptor_cursor
188             : private detail::adaptor_value_type_
189             {
190             private:
191             friend range_access;
192             using base_t = detail::adaptor_value_type_;
193             using single_pass = meta::or_<
194             range_access::single_pass_t,
195             SinglePass>;
196             struct mixin
197             : basic_mixin
198             {
199             mixin() = default;
200 2552           using basic_mixin::basic_mixin;
201             // All iterators into adapted ranges have a base() member for fetching
202             // the underlying iterator.
203             BaseIter base() const
204             {
205             return this->get().first();
206             }
207             };
208              
209             using base_t::first;
210             using base_t::second;
211              
212             template
213             std::declval().read(std::declval()))>
214 308           R read() const
215             noexcept(noexcept(
216             std::declval().read(std::declval())))
217             {
218             using V = range_access::cursor_value_t;
219             static_assert(
220             CommonReference(),
221             "In your adaptor, you've specified a value type that does not "
222             "share a common reference type with the return type of read.");
223 308           return second().read(first());
224             }
225             template
226             typename = decltype(std::declval().next(std::declval()))>
227 308           void next()
228             {
229 308           second().next(first());
230 308           }
231             template
232             std::declval().equal(
233             std::declval(),
234             std::declval(),
235             std::declval()))>
236             bool equal_(adaptor_cursor const &that, int) const
237             {
238             return second().equal(first(), that.first(), that.second());
239             }
240             template
241             std::declval().equal(
242             std::declval(),
243             std::declval()))>
244 946           bool equal_(adaptor_cursor const &that, long) const
245             {
246 946           return second().equal(first(), that.first());
247             }
248             template
249 946           auto equal(adaptor_cursor const &that) const ->
250             decltype(std::declval().equal_(that, 42))
251             {
252 946           return this->equal_(that, 42);
253             }
254             template
255             std::declval().empty(
256             std::declval(),
257             std::declval(),
258             std::declval()))>
259             constexpr bool equal_(adaptor_sentinel const &that, int) const
260             {
261             return that.second().empty(first(), second(), that.first());
262             }
263             template
264             std::declval().empty(
265             std::declval(),
266             std::declval()))>
267             constexpr bool equal_(adaptor_sentinel const &that, long) const
268             {
269             return that.second().empty(first(), that.first());
270             }
271             template
272             constexpr auto equal(adaptor_sentinel const &that) const ->
273             decltype(std::declval().equal_(that, 42))
274             {
275             return this->equal_(that, 42);
276             }
277             template
278             std::declval().prev(std::declval()))>
279             void prev()
280             {
281             second().prev(first());
282             }
283             template
284             std::declval().advance(std::declval(), 0))>
285             void advance(difference_type_t n)
286             {
287             second().advance(first(), n);
288             }
289             template
290             std::declval().distance_to(
291             std::declval(),
292             std::declval(),
293             std::declval()))>
294             R distance_to_(adaptor_cursor const &that, int) const
295             {
296             return second().distance_to(first(), that.first(), that.second());
297             }
298             template
299             std::declval().distance_to(
300             std::declval(),
301             std::declval()))>
302             R distance_to_(adaptor_cursor const &that, long) const
303             {
304             return second().distance_to(first(), that.first());
305             }
306             template
307             auto distance_to(adaptor_cursor const &that) const ->
308             decltype(std::declval().distance_to_(that, 42))
309             {
310             return this->distance_to_(that, 42);
311             }
312             // If the adaptor has an iter_move function, use it.
313             template
314             std::declval().iter_move(
315             std::declval()))>
316             X iter_move_(int) const
317             noexcept(noexcept(std::declval().iter_move(
318             std::declval())))
319             {
320             using V = range_access::cursor_value_t;
321             using R = decltype(second().read(first()));
322             static_assert(
323             CommonReference(),
324             "In your adaptor, the result of your iter_move member function does "
325             "not share a common reference with your value type.");
326             static_assert(
327             CommonReference(),
328             "In your adaptor, the result of your iter_move member function does "
329             "not share a common reference with the result of your read member "
330             "function.");
331             return second().iter_move(first());
332             }
333             // If there is no iter_move member and the adaptor has not overridden the read
334             // member function, then dispatch to the base iterator's iter_move function.
335             template
336             typename R = decltype(std::declval().read(
337             std::declval(), detail::adaptor_base_current_mem_fn{})),
338             typename X = rvalue_reference_t>
339             X iter_move_(long) const
340             noexcept(noexcept(X(ranges::iter_move(std::declval()))))
341             {
342             return ranges::iter_move(first());
343             }
344             // If the adaptor does not have an iter_move function but overrides the read
345             // member function, apply std::move to the result of calling read.
346             template
347             typename R = decltype(std::declval().read(std::declval())),
348             typename X = aux::move_t>
349             X iter_move_(detail::any) const
350             noexcept(noexcept(X(static_cast(
351             std::declval().read(std::declval())))))
352             {
353             using V = range_access::cursor_value_t;
354             static_assert(
355             CommonReference(),
356             "In your adaptor, you've specified a value type that does not share a common "
357             "reference type with the result of moving the result of the read member "
358             "function. Consider defining an iter_move function in your adaptor.");
359             return static_cast(second().read(first()));
360             }
361             // Gives users a way to override the default iter_move function in their adaptors.
362             auto move() const
363             noexcept(noexcept(std::declval().iter_move_(42))) ->
364             decltype(std::declval().iter_move_(42))
365             {
366             return iter_move_(42);
367             }
368             public:
369 2552           using base_t::base_t;
370             };
371              
372             template
373             using adaptor_cursor_t =
374             adaptor_cursor, detail::begin_adaptor_t>;
375              
376             template
377             using adaptor_sentinel_t =
378             meta::if_<
379             meta::and_<
380             Same, detail::adapted_sentinel_t>,
381             Same, detail::end_adaptor_t>>,
382             adaptor_cursor_t,
383             adaptor_sentinel, detail::end_adaptor_t>>;
384              
385             template
386             cardinality Cardinality /*= range_cardinality::value*/>
387             struct view_adaptor
388             : view_facade
389             {
390             private:
391             friend Derived;
392             friend range_access;
393             friend adaptor_base;
394             using base_range_t = view::all_t;
395             using view_facade::derived;
396              
397             base_range_t rng_;
398              
399             constexpr adaptor_base begin_adaptor() const noexcept
400             {
401             return {};
402             }
403             constexpr adaptor_base end_adaptor() const noexcept
404             {
405             return {};
406             }
407              
408             template
409 638           static RANGES_CXX14_CONSTEXPR adaptor_cursor_t begin_cursor_(D &d)
410             noexcept(noexcept(adaptor_cursor_t{
411             std::declval &>().begin(d),
412             range_access::begin_adaptor(d)}))
413             {
414 638 50         auto adapt = range_access::begin_adaptor(d);
    50          
415 638 50         auto pos = adapt.begin(d);
416 638           return {std::move(pos), std::move(adapt)};
417             }
418             template())>
419 638           RANGES_CXX14_CONSTEXPR auto begin_cursor()
420             RANGES_DECLTYPE_NOEXCEPT(view_adaptor::begin_cursor_(std::declval()))
421             {
422 638           return view_adaptor::begin_cursor_(derived());
423             }
424             template
425             CONCEPT_REQUIRES_(Same() && Range())>
426             RANGES_CXX14_CONSTEXPR auto begin_cursor() const
427             RANGES_DECLTYPE_NOEXCEPT(view_adaptor::begin_cursor_(std::declval()))
428             {
429             return view_adaptor::begin_cursor_(derived());
430             }
431              
432             template
433 638           static RANGES_CXX14_CONSTEXPR adaptor_sentinel_t end_cursor_(D &d)
434             noexcept(noexcept(adaptor_sentinel_t{
435             std::declval &>().end(d),
436             range_access::end_adaptor(d)}))
437             {
438 638 50         auto adapt = range_access::end_adaptor(d);
    50          
439 638 50         auto pos = adapt.end(d);
440 638           return {std::move(pos), std::move(adapt)};
441             }
442             template())>
443 638           RANGES_CXX14_CONSTEXPR auto end_cursor()
444             RANGES_DECLTYPE_NOEXCEPT(view_adaptor::end_cursor_(std::declval()))
445             {
446 638           return view_adaptor::end_cursor_(derived());
447             }
448             template
449             CONCEPT_REQUIRES_(Same() && Range())>
450             RANGES_CXX14_CONSTEXPR auto end_cursor() const
451             RANGES_DECLTYPE_NOEXCEPT(view_adaptor::end_cursor_(std::declval()))
452             {
453             return view_adaptor::end_cursor_(derived());
454             }
455             protected:
456             ~view_adaptor() = default;
457             public:
458             view_adaptor() = default;
459             view_adaptor(view_adaptor &&) = default;
460             view_adaptor(view_adaptor const &) = default;
461             view_adaptor &operator=(view_adaptor &&) = default;
462             view_adaptor &operator=(view_adaptor const &) = default;
463 638           explicit constexpr view_adaptor(BaseRng &&rng)
464 638           : rng_(view::all(static_cast(rng)))
465 638           {}
466 1903           RANGES_CXX14_CONSTEXPR base_range_t &base() noexcept
467             {
468 1903           return rng_;
469             }
470             /// \overload
471             constexpr base_range_t const &base() const noexcept
472             {
473             return rng_;
474             }
475             };
476              
477             /// @}
478             }
479             }
480              
481             #endif