Horizon
Loading...
Searching...
No Matches
tail.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_TAIL_HPP
15#define RANGES_V3_VIEW_TAIL_HPP
16
17#include <type_traits>
18#include <utility>
19
21
27#include <range/v3/utility/static_const.hpp>
28#include <range/v3/view/all.hpp>
31
32#include <range/v3/detail/prologue.hpp>
33
34namespace ranges
35{
36 namespace detail
37 {
38 template<typename T>
39 constexpr T prev_or_zero_(T n)
40 {
41 return n == 0 ? T(0) : T(n - 1);
42 }
43 } // namespace detail
44
47 template<typename Rng>
48 struct tail_view
49 : view_interface<tail_view<Rng>,
50 (range_cardinality<Rng>::value >= 0)
51 ? detail::prev_or_zero_(range_cardinality<Rng>::value)
52 : range_cardinality<Rng>::value>
53 {
54 private:
55 Rng rng_;
56
57 public:
58 tail_view() = default;
59 tail_view(Rng rng)
60 : rng_(static_cast<Rng &&>(rng))
61 {
62 CPP_assert(input_range<Rng>);
63 }
64 iterator_t<Rng> begin()
65 {
66 return next(ranges::begin(rng_), 1, ranges::end(rng_));
67 }
68 template(bool Const = true)(
69 requires Const AND range<meta::const_if_c<Const, Rng>>)
71 {
72 return next(ranges::begin(rng_), 1, ranges::end(rng_));
73 }
74 sentinel_t<Rng> end()
75 {
76 return ranges::end(rng_);
77 }
78 template(bool Const = true)(
79 requires Const AND range<meta::const_if_c<Const, Rng>>)
80 sentinel_t<meta::const_if_c<Const, Rng>> end() const
81 {
82 return ranges::end(rng_);
83 }
84 // Strange cast to bool in the requires clause is to work around gcc bug.
85 CPP_auto_member
86 constexpr auto CPP_fun(size)()(
87 requires(bool(sized_range<Rng>)))
88 {
89 using size_type = range_size_t<Rng>;
91 ? detail::prev_or_zero_((size_type)range_cardinality<Rng>::value)
92 : detail::prev_or_zero_(ranges::size(rng_));
93 }
94 CPP_auto_member
95 constexpr auto CPP_fun(size)()(const //
96 requires(bool(sized_range<Rng const>)))
97 {
98 using size_type = range_size_t<Rng>;
100 ? detail::prev_or_zero_((size_type)range_cardinality<Rng>::value)
101 : detail::prev_or_zero_(ranges::size(rng_));
102 }
103 Rng base() const
104 {
105 return rng_;
106 }
107 };
108
109 template<typename Rng>
110 RANGES_INLINE_VAR constexpr bool enable_borrowed_range<tail_view<Rng>> = //
111 enable_borrowed_range<Rng>;
112
113#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
114 template(typename Rng)(
115 requires viewable_range<Rng>)
116 tail_view(Rng &&)
117 ->tail_view<views::all_t<Rng>>;
118#endif
119
120 namespace views
121 {
122 struct tail_fn
123 {
124 template(typename Rng)(
126 meta::if_c<range_cardinality<Rng>::value == 0,
127 all_t<Rng>,
129 operator()(Rng && rng) const
130 {
131 return all(static_cast<Rng &&>(rng));
132 }
133 };
134
137 RANGES_INLINE_VARIABLE(view_closure<tail_fn>, tail)
138 } // namespace views
140} // namespace ranges
141
142#include <range/v3/detail/epilogue.hpp>
143#include <range/v3/detail/satisfy_boost_range.hpp>
144RANGES_SATISFY_BOOST_RANGE(::ranges::tail_view)
145
146#endif
The input_range concept.
The range concept.
The sized_range concept.
The viewable_range concept.
decltype(begin(declval(Rng &))) iterator_t
Definition access.hpp:698
Definition traits.hpp:128
Definition tail.hpp:53
Definition interface.hpp:129
Definition tail.hpp:123
Definition view.hpp:178