Horizon
Loading...
Searching...
No Matches
reverse.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_REVERSE_HPP
15#define RANGES_V3_VIEW_REVERSE_HPP
16
17#include <iterator>
18#include <utility>
19
20#include <meta/meta.hpp>
21
23
32#include <range/v3/utility/static_const.hpp>
34#include <range/v3/view/all.hpp>
36
37#include <range/v3/detail/prologue.hpp>
38
39namespace ranges
40{
43 template<typename Rng>
44 struct RANGES_EMPTY_BASES reverse_view
45 : view_interface<reverse_view<Rng>, range_cardinality<Rng>::value>
46 , private detail::non_propagating_cache<iterator_t<Rng>, reverse_view<Rng>,
47 !common_range<Rng>>
48 {
49 private:
50 CPP_assert(bidirectional_range<Rng>);
51 Rng rng_;
52 constexpr reverse_iterator<iterator_t<Rng>> begin_(std::true_type)
53 {
54 return make_reverse_iterator(ranges::end(rng_));
55 }
56 constexpr reverse_iterator<iterator_t<Rng>> begin_(std::false_type)
57 {
58 using cache_t =
59 detail::non_propagating_cache<iterator_t<Rng>, reverse_view<Rng>>;
60 auto & end_ = static_cast<cache_t &>(*this);
61 if(!end_)
62 {
63#if defined(_MSC_VER)
64 auto tmp = ranges::begin(rng_);
65 auto e = ranges::end(rng_);
66 while(tmp != e)
67 ++tmp;
68#else
69 auto tmp = ranges::next(ranges::begin(rng_), ranges::end(rng_));
70#endif
71 end_ = std::move(tmp);
72 }
73 return make_reverse_iterator(*end_);
74 }
75
76 public:
77 reverse_view() = default;
78 constexpr explicit reverse_view(Rng rng)
79 : rng_(detail::move(rng))
80 {}
81 Rng base() const
82 {
83 return rng_;
84 }
85 constexpr reverse_iterator<iterator_t<Rng>> begin()
86 {
87 return begin_(meta::bool_<(bool)common_range<Rng>>{});
88 }
89 template(bool Const = true)(
90 requires Const AND common_range<meta::const_if_c<Const, Rng>>)
92 {
93 return make_reverse_iterator(ranges::end(rng_));
94 }
96 {
97 return make_reverse_iterator(ranges::begin(rng_));
98 }
99 template(bool Const = true)(
100 requires Const AND common_range<meta::const_if_c<Const, Rng>>)
102 {
103 return make_reverse_iterator(ranges::begin(rng_));
104 }
105 CPP_auto_member
106 constexpr auto CPP_fun(size)()(
107 requires sized_range<Rng>)
108 {
109 return ranges::size(rng_);
110 }
111 CPP_auto_member
112 constexpr auto CPP_fun(size)()(const //
113 requires sized_range<Rng const>)
114 {
115 return ranges::size(rng_);
116 }
117 };
118
119 template<typename Rng>
120 struct reverse_view<reverse_view<Rng>> : Rng
121 {
122 CPP_assert(bidirectional_range<Rng>);
123 CPP_assert(
124 same_as<detail::decay_t<decltype(std::declval<reverse_view<Rng>>().base())>,
125 Rng>);
126
127 reverse_view() = default;
128 constexpr explicit reverse_view(reverse_view<Rng> rng)
129 : Rng(rng.base())
130 {}
131
132 constexpr reverse_view<Rng> base() const
133 {
134 return reverse_view<Rng>{*this};
135 }
136 };
137
138 template<typename Rng>
139 RANGES_INLINE_VAR constexpr bool enable_borrowed_range<reverse_view<Rng>> =
140 enable_borrowed_range<Rng>;
141
142#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
143 template<typename Rng>
144 reverse_view(Rng &&) //
146
147 template<typename Rng>
150#endif
151
152 namespace views
153 {
155 {
156 template(typename Rng)(
158 constexpr reverse_view<all_t<Rng>> operator()(Rng && rng) const
159 {
160 return reverse_view<all_t<Rng>>{all(static_cast<Rng &&>(rng))};
161 }
162 };
163
166 RANGES_INLINE_VARIABLE(view_closure<reverse_fn>, reverse)
167 } // namespace views
168
169 namespace cpp20
170 {
171 namespace views
172 {
173 using ranges::views::reverse;
174 }
175 template(typename Rng)(
176 requires view_<Rng> AND bidirectional_range<Rng>)
177 using reverse_view = ranges::reverse_view<Rng>;
178 } // namespace cpp20
180} // namespace ranges
181
182#include <range/v3/detail/epilogue.hpp>
183#include <range/v3/detail/satisfy_boost_range.hpp>
184RANGES_SATISFY_BOOST_RANGE(::ranges::reverse_view)
185
186#endif
The bidirectional_range concept.
The common_range concept.
The sized_range concept.
The viewable_range concept.
std::integral_constant< bool, B > bool_
An integral constant wrapper for bool.
Definition meta.hpp:168
Tiny meta-programming library.
Definition basic_iterator.hpp:532
Definition reverse.hpp:48
Definition interface.hpp:129
Definition reverse.hpp:155
Definition view.hpp:178