File Coverage

/usr/local/lib/perl5/site_perl/5.26.1/XS/librangeV3.x/i/range/v3/view_interface.hpp
Criterion Covered Total %
statement 3 3 100.0
branch n/a
condition n/a
subroutine n/a
pod n/a
total 3 3 100.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_INTERFACE_HPP
14             #define RANGES_V3_VIEW_INTERFACE_HPP
15              
16             #include
17             #include
18             #include
19             #include
20             #include
21             #include
22             #include
23             #include
24             #include
25             #include
26             #include
27              
28             namespace ranges
29             {
30             inline namespace v3
31             {
32             /// \cond
33             namespace detail
34             {
35             template
36             struct slice_bounds
37             {
38             From from;
39             To to;
40             template
41             CONCEPT_REQUIRES_(ConvertibleTo() && ConvertibleTo())>
42             constexpr slice_bounds(F from, T to)
43             : from(from), to(to)
44             {}
45             };
46              
47             template
48             struct from_end_
49             {
50             Int dist_;
51              
52             template
53             CONCEPT_REQUIRES_(Integral() && ExplicitlyConvertibleTo())>
54             constexpr operator from_end_ () const
55             {
56             return {static_cast(dist_)};
57             }
58             };
59             }
60             /// \endcond
61              
62             /// \addtogroup group-core
63             /// @{
64             template
65             struct view_interface
66             : basic_view
67             {
68             protected:
69 2552           RANGES_CXX14_CONSTEXPR Derived &derived() noexcept
70             {
71             CONCEPT_ASSERT(DerivedFrom());
72 2552           return static_cast(*this);
73             }
74             /// \overload
75             constexpr Derived const &derived() const noexcept
76             {
77             CONCEPT_ASSERT(DerivedFrom());
78             return static_cast(*this);
79             }
80             ~view_interface() = default;
81             public:
82 1914           view_interface() = default;
83             view_interface(view_interface &&) = default;
84             view_interface(view_interface const &) = default;
85             view_interface &operator=(view_interface &&) = default;
86             view_interface &operator=(view_interface const &) = default;
87             // A few ways of testing whether a range can be empty:
88             CONCEPT_REQUIRES(Cardinality >= 0 || Cardinality == infinite)
89             constexpr bool empty() const noexcept
90             {
91             return Cardinality == 0;
92             }
93             template
94             CONCEPT_REQUIRES_(Same() &&
95             Cardinality < 0 && Cardinality != infinite &&
96             ForwardRange())>
97             RANGES_CXX14_CONSTEXPR bool empty()
98             noexcept(noexcept(bool(ranges::begin(std::declval()) ==
99             ranges::end(std::declval()))))
100             {
101             return ranges::begin(derived()) == ranges::end(derived());
102             }
103             template
104             CONCEPT_REQUIRES_(Same() &&
105             Cardinality < 0 && Cardinality != infinite &&
106             ForwardRange())>
107             constexpr bool empty() const
108             noexcept(noexcept(bool(ranges::begin(std::declval()) ==
109             ranges::end(std::declval()))))
110             {
111             return ranges::begin(derived()) == ranges::end(derived());
112             }
113             template())>
114             constexpr auto operator!() const
115             RANGES_DECLTYPE_NOEXCEPT(ranges::empty(std::declval()))
116             {
117             return ranges::empty(derived());
118             }
119             template()),
120             typename = decltype(ranges::empty(std::declval()))>
121             constexpr explicit operator bool() const
122             noexcept(noexcept(ranges::empty(std::declval())))
123             {
124             return !ranges::empty(derived());
125             }
126             /// Access the size of the range, if it can be determined:
127             template
128             CONCEPT_REQUIRES_(Same() && Cardinality >= 0)>
129             constexpr range_size_type_t size() const noexcept
130             {
131             return (range_size_type_t)Cardinality;
132             }
133             template
134             CONCEPT_REQUIRES_(Same() && Cardinality < 0 &&
135             SizedSentinel, iterator_t>() &&
136             ForwardRange())>
137             constexpr range_size_type_t size() const
138             {
139             return iter_size(derived().begin(), derived().end());
140             }
141             template
142             CONCEPT_REQUIRES_(Same() && Cardinality < 0 &&
143             SizedSentinel, iterator_t>() &&
144             ForwardRange())>
145             RANGES_CXX14_CONSTEXPR range_size_type_t size()
146             {
147             return iter_size(derived().begin(), derived().end());
148             }
149             /// Access the first element in a range:
150             template
151             CONCEPT_REQUIRES_(Same() && ForwardRange())>
152             RANGES_CXX14_CONSTEXPR range_reference_t front()
153             {
154             return *derived().begin();
155             }
156             /// \overload
157             template
158             CONCEPT_REQUIRES_(Same() && ForwardRange())>
159             constexpr range_reference_t front() const
160             {
161             return *derived().begin();
162             }
163             /// Access the last element in a range:
164             template
165             CONCEPT_REQUIRES_(Same() && BoundedRange() && BidirectionalRange())>
166             RANGES_CXX14_CONSTEXPR range_reference_t back()
167             {
168             return *prev(derived().end());
169             }
170             /// \overload
171             template
172             CONCEPT_REQUIRES_(Same() && BoundedRange() && BidirectionalRange())>
173             constexpr range_reference_t back() const
174             {
175             return *prev(derived().end());
176             }
177             /// Simple indexing:
178             template
179             CONCEPT_REQUIRES_(Same() && RandomAccessRange())>
180             RANGES_CXX14_CONSTEXPR auto operator[](range_difference_type_t n) ->
181             decltype(std::declval().begin()[n])
182             {
183             return derived().begin()[n];
184             }
185             /// \overload
186             template
187             CONCEPT_REQUIRES_(Same() && RandomAccessRange())>
188             constexpr auto operator[](range_difference_type_t n) const ->
189             decltype(std::declval().begin()[n])
190             {
191             return derived().begin()[n];
192             }
193             /// Python-ic slicing:
194             // rng[{4,6}]
195             template
196             CONCEPT_REQUIRES_(Same())>
197             RANGES_CXX14_CONSTEXPR
198             auto operator[](detail::slice_bounds> offs) & ->
199             decltype(std::declval()(std::declval(), offs.from, offs.to))
200             {
201             return Slice{}(derived(), offs.from, offs.to);
202             }
203             /// \overload
204             template
205             CONCEPT_REQUIRES_(Same())>
206             constexpr
207             auto operator[](detail::slice_bounds> offs) const & ->
208             decltype(std::declval()(std::declval(), offs.from, offs.to))
209             {
210             return Slice{}(derived(), offs.from, offs.to);
211             }
212             /// \overload
213             template
214             CONCEPT_REQUIRES_(Same())>
215             RANGES_CXX14_CONSTEXPR
216             auto operator[](detail::slice_bounds> offs) && ->
217             decltype(std::declval()(std::declval(), offs.from, offs.to))
218             {
219             return Slice{}(detail::move(derived()), offs.from, offs.to);
220             }
221             // rng[{4,end-2}]
222             /// \overload
223             template
224             CONCEPT_REQUIRES_(Same())>
225             RANGES_CXX14_CONSTEXPR
226             auto operator[](detail::slice_bounds,
227             detail::from_end_>> offs) & ->
228             decltype(std::declval()(std::declval(), offs.from, offs.to))
229             {
230             return Slice{}(derived(), offs.from, offs.to);
231             }
232             /// \overload
233             template
234             CONCEPT_REQUIRES_(Same())>
235             constexpr auto operator[](detail::slice_bounds,
236             detail::from_end_>> offs) const & ->
237             decltype(std::declval()(std::declval(), offs.from, offs.to))
238             {
239             return Slice{}(derived(), offs.from, offs.to);
240             }
241             /// \overload
242             template
243             CONCEPT_REQUIRES_(Same())>
244             RANGES_CXX14_CONSTEXPR
245             auto operator[](detail::slice_bounds,
246             detail::from_end_>> offs) && ->
247             decltype(std::declval()(std::declval(), offs.from, offs.to))
248             {
249             return Slice{}(detail::move(derived()), offs.from, offs.to);
250             }
251             // rng[{end-4,end-2}]
252             /// \overload
253             template
254             CONCEPT_REQUIRES_(Same())>
255             RANGES_CXX14_CONSTEXPR
256             auto operator[](detail::slice_bounds>,
257             detail::from_end_>> offs) & ->
258             decltype(std::declval()(std::declval(), offs.from, offs.to))
259             {
260             return Slice{}(derived(), offs.from, offs.to);
261             }
262             /// \overload
263             template
264             CONCEPT_REQUIRES_(Same())>
265             constexpr
266             auto operator[](detail::slice_bounds>,
267             detail::from_end_>> offs) const & ->
268             decltype(std::declval()(std::declval(), offs.from, offs.to))
269             {
270             return Slice{}(derived(), offs.from, offs.to);
271             }
272             /// \overload
273             template
274             CONCEPT_REQUIRES_(Same())>
275             RANGES_CXX14_CONSTEXPR
276             auto operator[](detail::slice_bounds>,
277             detail::from_end_>> offs) && ->
278             decltype(std::declval()(std::declval(), offs.from, offs.to))
279             {
280             return Slice{}(detail::move(derived()), offs.from, offs.to);
281             }
282             // rng[{4,end}]
283             /// \overload
284             template
285             CONCEPT_REQUIRES_(Same())>
286             RANGES_CXX14_CONSTEXPR
287             auto operator[](detail::slice_bounds, end_fn> offs) & ->
288             decltype(std::declval()(std::declval(), offs.from, offs.to))
289             {
290             return Slice{}(derived(), offs.from, offs.to);
291             }
292             /// \overload
293             template
294             CONCEPT_REQUIRES_(Same())>
295             constexpr
296             auto operator[](detail::slice_bounds, end_fn> offs) const & ->
297             decltype(std::declval()(std::declval(), offs.from, offs.to))
298             {
299             return Slice{}(derived(), offs.from, offs.to);
300             }
301             /// \overload
302             template
303             CONCEPT_REQUIRES_(Same())>
304             RANGES_CXX14_CONSTEXPR
305             auto operator[](detail::slice_bounds, end_fn> offs) && ->
306             decltype(std::declval()(std::declval(), offs.from, offs.to))
307             {
308             return Slice{}(detail::move(derived()), offs.from, offs.to);
309             }
310             // rng[{end-4,end}]
311             /// \overload
312             template
313             CONCEPT_REQUIRES_(Same())>
314             RANGES_CXX14_CONSTEXPR
315             auto operator[](detail::slice_bounds>, end_fn> offs) & ->
316             decltype(std::declval()(std::declval(), offs.from, offs.to))
317             {
318             return Slice{}(derived(), offs.from, offs.to);
319             }
320             /// \overload
321             template
322             CONCEPT_REQUIRES_(Same())>
323             constexpr
324             auto operator[](detail::slice_bounds>, end_fn> offs) const & ->
325             decltype(std::declval()(std::declval(), offs.from, offs.to))
326             {
327             return Slice{}(derived(), offs.from, offs.to);
328             }
329             /// \overload
330             template
331             CONCEPT_REQUIRES_(Same())>
332             RANGES_CXX14_CONSTEXPR
333             auto operator[](detail::slice_bounds>, end_fn> offs) && ->
334             decltype(std::declval()(std::declval(), offs.from, offs.to))
335             {
336             return Slice{}(detail::move(derived()), offs.from, offs.to);
337             }
338             /// Returns a reference to the element at specified location pos, with bounds checking.
339             template
340             CONCEPT_REQUIRES_(Same() && RandomAccessRange() && SizedRange())>
341             RANGES_CXX14_CONSTEXPR auto at(range_difference_type_t n) ->
342             decltype(std::declval().begin()[n])
343             {
344             using size_type = range_size_type_t;
345             if (n < 0 || size_type(n) >= ranges::size(derived()))
346             {
347             throw std::out_of_range("view_interface::at");
348             }
349             return derived().begin()[n];
350             }
351             /// \overload
352             template
353             CONCEPT_REQUIRES_(Same() && RandomAccessRange() && SizedRange())>
354             RANGES_CXX14_CONSTEXPR auto at(range_difference_type_t n) const ->
355             decltype(std::declval().begin()[n])
356             {
357             using size_type = range_size_type_t;
358             if (n < 0 || size_type(n) >= ranges::size(derived()))
359             {
360             throw std::out_of_range("view_interface::at");
361             }
362             return derived().begin()[n];
363             }
364             /// Implicit conversion to something that looks like a container.
365             template
366             typename = typename Container::allocator_type, // HACKHACK
367             CONCEPT_REQUIRES_(detail::ConvertibleToContainer())>
368             RANGES_CXX14_CONSTEXPR operator Container ()
369             {
370             return ranges::to_(derived());
371             }
372             /// \overload
373             template
374             typename = typename Container::allocator_type, // HACKHACK
375             CONCEPT_REQUIRES_(detail::ConvertibleToContainer())>
376             constexpr operator Container () const
377             {
378             return ranges::to_(derived());
379             }
380             /// \brief Print a range to an ostream
381             private:
382             template
383             CONCEPT_REQUIRES_(Same>>())>
384             static Stream &print_(Stream &sout, Rng &rng)
385             {
386             sout << '[';
387             auto it = ranges::begin(rng);
388             auto const e = ranges::end(rng);
389             if(it != e)
390             {
391             for(;;)
392             {
393             sout << *it;
394             if(++it == e) break;
395             sout << ',';
396             }
397             }
398             sout << ']';
399             return sout;
400             }
401              
402             template
403             CONCEPT_REQUIRES_(Same() && InputRange())>
404             friend std::ostream &operator<<(std::ostream &sout, Derived const &rng)
405             {
406             return view_interface::print_(sout, rng);
407             }
408             /// \overload
409             template
410             CONCEPT_REQUIRES_(Same() && !Range() && InputRange())>
411             friend std::ostream &operator<<(std::ostream &sout, Derived &rng)
412             {
413             return view_interface::print_(sout, rng);
414             }
415             /// \overload
416             template
417             CONCEPT_REQUIRES_(Same() && !Range() && InputRange())>
418             friend std::ostream &operator<<(std::ostream &sout, Derived &&rng)
419             {
420             return view_interface::print_(sout, rng);
421             }
422             };
423             /// @}
424             }
425             }
426              
427             #endif