Horizon
Loading...
Searching...
No Matches
cache1.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#ifndef RANGES_V3_VIEW_CACHE1_HPP
14#define RANGES_V3_VIEW_CACHE1_HPP
15
17
26#include <range/v3/view/all.hpp>
27
28#include <range/v3/detail/prologue.hpp>
29
30namespace ranges
31{
34 template<typename Rng>
35 struct cache1_view : view_facade<cache1_view<Rng>, range_cardinality<Rng>::value>
36 {
37 private:
38 CPP_assert(view_<Rng>);
39 CPP_assert(input_range<Rng>);
40 CPP_assert(constructible_from<range_value_t<Rng>, range_reference_t<Rng>>);
41 friend range_access;
42 Rng rng_;
43 bool dirty_ = true;
44 detail::non_propagating_cache<range_value_t<Rng>> cache_;
45
46 CPP_member
47 auto update_(range_reference_t<Rng> && val) //
48 -> CPP_ret(void)(
49 requires assignable_from<range_value_t<Rng> &, range_reference_t<Rng>>)
50 {
51 if(!cache_)
52 cache_.emplace(static_cast<range_reference_t<Rng> &&>(val));
53 else
54 *cache_ = static_cast<range_reference_t<Rng> &&>(val);
55 }
56 CPP_member
57 auto update_(range_reference_t<Rng> && val) //
58 -> CPP_ret(void)(
59 requires (!assignable_from<range_value_t<Rng> &, range_reference_t<Rng>>))
60 {
61 cache_.emplace(static_cast<range_reference_t<Rng> &&>(val));
62 }
63
64 struct cursor;
65
66 struct sentinel
67 {
68 private:
69 friend cursor;
70 sentinel_t<Rng> last_;
71
72 public:
73 sentinel() = default;
74 constexpr explicit sentinel(sentinel_t<Rng> last)
75 : last_(std::move(last))
76 {}
77 };
78
79 struct cursor
80 {
81 private:
82 cache1_view * parent_;
83 iterator_t<Rng> current_;
84
85 public:
86 using value_type = range_value_t<Rng>;
87 using single_pass = std::true_type;
88 using difference_type = range_difference_t<Rng>;
89
90 cursor() = default;
91
92 constexpr explicit cursor(cache1_view * parent, iterator_t<Rng> current)
93 : parent_(parent)
94 , current_(std::move(current))
95 {}
96 range_value_t<Rng> && read() const
97 {
98 if(parent_->dirty_)
99 {
100 parent_->update_(*current_);
101 parent_->dirty_ = false;
102 }
103 return std::move(*parent_->cache_);
104 }
105 void next()
106 {
107 ++current_;
108 parent_->dirty_ = true;
109 }
110 bool equal(cursor const & that) const
111 {
112 return current_ == that.current_;
113 }
114 bool equal(sentinel const & that) const
115 {
116 return current_ == that.last_;
117 }
118 CPP_member
119 auto distance_to(cursor const & that) const //
120 -> CPP_ret(difference_type)(
122 {
123 return that.current_ - current_;
124 }
125 CPP_member
126 auto distance_to(sentinel const & that) const //
127 -> CPP_ret(difference_type)(
129 {
130 return that.last_ - current_;
131 }
132 };
133
134 cursor begin_cursor()
135 {
136 dirty_ = true;
137 return cursor{this, ranges::begin(rng_)};
138 }
139
140 cursor end_cursor_impl(std::true_type)
141 {
142 return cursor{this, ranges::end(rng_)};
143 }
144 sentinel end_cursor_impl(std::false_type)
145 {
146 return sentinel{ranges::end(rng_)};
147 }
148 auto end_cursor()
149 {
150 return end_cursor_impl(meta::bool_<(bool)common_range<Rng>>{});
151 }
152
153 public:
154 cache1_view() = default;
155 constexpr explicit cache1_view(Rng rng)
156 : rng_{std::move(rng)}
157 {}
158 CPP_auto_member
159 constexpr auto CPP_fun(size)()(
160 requires sized_range<Rng>)
161 {
162 return ranges::size(rng_);
163 }
164 };
165
166#if RANGES_CXX_DEDUCTION_GUIDES >= RANGES_CXX_DEDUCTION_GUIDES_17
167 template<typename Rng>
168 cache1_view(Rng &&) //
170#endif
171
172 namespace views
173 {
175 {
181 template(typename Rng)(
183 constructible_from<range_value_t<Rng>, range_reference_t<Rng>>)
184 constexpr cache1_view<all_t<Rng>> operator()(Rng && rng) const //
185 {
186 return cache1_view<all_t<Rng>>{all(static_cast<Rng &&>(rng))};
187 }
188 };
189
192 RANGES_INLINE_VARIABLE(view_closure<cache1_fn>, cache1)
193 } // namespace views
194
196} // namespace ranges
197
198#include <range/v3/detail/epilogue.hpp>
199#include <range/v3/detail/satisfy_boost_range.hpp>
200RANGES_SATISFY_BOOST_RANGE(::ranges::cache1_view)
201
202#endif
The common_range concept.
The input_range concept.
The sized_range concept.
The sized_sentinel_for concept.
The view_ concept.
The viewable_range concept.
decltype(begin(declval(Rng &))) iterator_t
Definition access.hpp:698
std::integral_constant< bool, B > bool_
An integral constant wrapper for bool.
Definition meta.hpp:168
Definition cache1.hpp:36
A utility for constructing a view from a (derived) type that implements begin and end cursors.
Definition facade.hpp:66
Definition cache1.hpp:175