Horizon
tail.hpp
Go to the documentation of this file.
1 // 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 
20 #include <range/v3/range_fwd.hpp>
21 
27 #include <range/v3/utility/static_const.hpp>
28 #include <range/v3/view/all.hpp>
30 #include <range/v3/view/view.hpp>
31 
32 #include <range/v3/detail/prologue.hpp>
33 
34 namespace 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)(
125  requires viewable_range<Rng> AND input_range<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 
138  } // namespace views
140 } // namespace ranges
141 
142 #include <range/v3/detail/epilogue.hpp>
143 #include <range/v3/detail/satisfy_boost_range.hpp>
144 RANGES_SATISFY_BOOST_RANGE(::ranges::tail_view)
145 
146 #endif
CPP_concept range
\concept range
Definition: concepts.hpp:69
decltype(begin(declval(Rng &))) iterator_t
Definition: access.hpp:698
RANGES_INLINE_VARIABLE(detail::to_container_fn< detail::from_range< std::vector >>, to_vector) template< template< typename... > class ContT > auto to(RANGES_HIDDEN_DETAIL(detail
For initializing a container of the specified type with the elements of an Range.
Definition: conversion.hpp:399
meta::size_t< L::size()> size
An integral constant wrapper that is the size of the meta::list L.
Definition: meta.hpp:1696
Definition: traits.hpp:128
Definition: tail.hpp:53
Definition: interface.hpp:129
Definition: tail.hpp:123
Definition: view.hpp:178