From Jason Turner

[range.cache.latest]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp19a12p38/{from.md → to.md} +262 -0
tmp/tmp19a12p38/{from.md → to.md} RENAMED
@@ -0,0 +1,262 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Cache latest view <a id="range.cache.latest">[[range.cache.latest]]</a>
2
+
3
+ #### Overview <a id="range.cache.latest.overview">[[range.cache.latest.overview]]</a>
4
+
5
+ `cache_latest_view` caches the last-accessed element of its underlying
6
+ sequence so that the element does not have to be recomputed on repeated
7
+ access.
8
+
9
+ [*Note 1*: This is useful if computation of the element to produce is
10
+ expensive. — *end note*]
11
+
12
+ The name `views::cache_latest` denotes a range adaptor object
13
+ [[range.adaptor.object]]. Let `E` be an expression. The expression
14
+ `views::cache_latest(E)` is expression-equivalent to
15
+ `cache_latest_view(E)`.
16
+
17
+ #### Class template `cache_latest_view` <a id="range.cache.latest.view">[[range.cache.latest.view]]</a>
18
+
19
+ ``` cpp
20
+ namespace std::ranges {
21
+ template<input_range V>
22
+ requires view<V>
23
+ class cache_latest_view : public view_interface<cache_latest_view<V>> {
24
+ V base_ = V(); // exposition only
25
+ using cache-t = conditional_t<is_reference_v<range_reference_t<V>>, // exposition only
26
+ add_pointer_t<range_reference_t<V>>,
27
+ range_reference_t<V>>;
28
+
29
+ non-propagating-cache<cache-t> cache_; // exposition only
30
+
31
+ // [range.cache.latest.iterator], class cache_latest_view::iterator
32
+ class iterator; // exposition only
33
+ // [range.cache.latest.sentinel], class cache_latest_view::sentinel
34
+ class sentinel; // exposition only
35
+
36
+ public:
37
+ cache_latest_view() requires default_initializable<V> = default;
38
+ constexpr explicit cache_latest_view(V base);
39
+
40
+ constexpr V base() const & requires copy_constructible<V> { return base_; }
41
+ constexpr V base() && { return std::move(base_); }
42
+
43
+ constexpr auto begin();
44
+ constexpr auto end();
45
+
46
+ constexpr auto size() requires sized_range<V>;
47
+ constexpr auto size() const requires sized_range<const V>;
48
+
49
+ constexpr auto reserve_hint() requires approximately_sized_range<V>;
50
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
51
+ };
52
+
53
+ template<class R>
54
+ cache_latest_view(R&&) -> cache_latest_view<views::all_t<R>>;
55
+ }
56
+ ```
57
+
58
+ ``` cpp
59
+ constexpr explicit cache_latest_view(V base);
60
+ ```
61
+
62
+ *Effects:* Initializes *base\_* with `std::move(base)`.
63
+
64
+ ``` cpp
65
+ constexpr auto begin();
66
+ ```
67
+
68
+ *Effects:* Equivalent to: `return `*`iterator`*`(*this);`
69
+
70
+ ``` cpp
71
+ constexpr auto end();
72
+ ```
73
+
74
+ *Effects:* Equivalent to: `return `*`sentinel`*`(*this);`
75
+
76
+ ``` cpp
77
+ constexpr auto size() requires sized_range<V>;
78
+ constexpr auto size() const requires sized_range<const V>;
79
+ ```
80
+
81
+ *Effects:* Equivalent to: `return ranges::size(`*`base_`*`);`
82
+
83
+ ``` cpp
84
+ constexpr auto reserve_hint() requires approximately_sized_range<V>;
85
+ constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
86
+ ```
87
+
88
+ *Effects:* Equivalent to: `return ranges::reserve_hint(`*`base_`*`);`
89
+
90
+ #### Class `cache_latest_view::iterator` <a id="range.cache.latest.iterator">[[range.cache.latest.iterator]]</a>
91
+
92
+ ``` cpp
93
+ namespace std::ranges {
94
+ template<input_range V>
95
+ requires view<V>
96
+ class cache_latest_view<V>::iterator {
97
+ cache_latest_view* parent_; // exposition only
98
+ iterator_t<V> current_; // exposition only
99
+
100
+ constexpr explicit iterator(cache_latest_view& parent); // exposition only
101
+
102
+ public:
103
+ using difference_type = range_difference_t<V>;
104
+ using value_type = range_value_t<V>;
105
+ using iterator_concept = input_iterator_tag;
106
+
107
+ iterator(iterator&&) = default;
108
+ iterator& operator=(iterator&&) = default;
109
+
110
+ constexpr iterator_t<V> base() &&;
111
+ constexpr const iterator_t<V>& base() const & noexcept;
112
+
113
+ constexpr range_reference_t<V>& operator*() const;
114
+
115
+ constexpr iterator& operator++();
116
+ constexpr void operator++(int);
117
+
118
+ friend constexpr range_rvalue_reference_t<V> iter_move(const iterator& i)
119
+ noexcept(noexcept(ranges::iter_move(i.current_)));
120
+
121
+ friend constexpr void iter_swap(const iterator& x, const iterator& y)
122
+ noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
123
+ requires indirectly_swappable<iterator_t<V>>;
124
+ };
125
+ }
126
+ ```
127
+
128
+ ``` cpp
129
+ constexpr explicit iterator(cache_latest_view& parent);
130
+ ```
131
+
132
+ *Effects:* Initializes *current\_* with
133
+ `ranges::begin(parent.`*`base_`*`)` and *parent\_* with
134
+ `addressof(parent)`.
135
+
136
+ ``` cpp
137
+ constexpr iterator_t<V> base() &&;
138
+ ```
139
+
140
+ *Returns:* `std::move(`*`current_`*`)`.
141
+
142
+ ``` cpp
143
+ constexpr const iterator_t<V>& base() const & noexcept;
144
+ ```
145
+
146
+ *Returns:* *current\_*.
147
+
148
+ ``` cpp
149
+ constexpr iterator& operator++();
150
+ ```
151
+
152
+ *Effects:* Equivalent to:
153
+
154
+ ``` cpp
155
+ parent_->cache_.reset();
156
+ ++current_;
157
+ return *this;
158
+ ```
159
+
160
+ ``` cpp
161
+ constexpr void operator++(int);
162
+ ```
163
+
164
+ *Effects:* Equivalent to: `++*this`.
165
+
166
+ ``` cpp
167
+ constexpr range_reference_t<V>& operator*() const;
168
+ ```
169
+
170
+ *Effects:* Equivalent to:
171
+
172
+ ``` cpp
173
+ if constexpr (is_reference_v<range_reference_t<V>>) {
174
+ if (!parent_->cache_) {
175
+ parent_->cache_ = addressof(as-lvalue(*current_));
176
+ }
177
+ return **parent_->cache_;
178
+ } else {
179
+ if (!parent_->cache_) {
180
+ parent_->cache_.emplace-deref(current_);
181
+ }
182
+ return *parent_->cache_;
183
+ }
184
+ ```
185
+
186
+ [*Note 1*: Evaluations of `operator*` on the same iterator object can
187
+ conflict [[intro.races]]. — *end note*]
188
+
189
+ ``` cpp
190
+ friend constexpr range_rvalue_reference_t<V> iter_move(const iterator& i)
191
+ noexcept(noexcept(ranges::iter_move(i.current_)));
192
+ ```
193
+
194
+ *Effects:* Equivalent to: `return ranges::iter_move(i.`*`current_`*`);`
195
+
196
+ ``` cpp
197
+ friend constexpr void iter_swap(const iterator& x, const iterator& y)
198
+ noexcept(noexcept(ranges::iter_swap(x.current_, y.current_)))
199
+ requires indirectly_swappable<iterator_t<V>>;
200
+ ```
201
+
202
+ *Effects:* Equivalent to
203
+ `ranges::iter_swap(x.`*`current_`*`, y.`*`current_`*`)`.
204
+
205
+ #### Class `cache_latest_view::sentinel` <a id="range.cache.latest.sentinel">[[range.cache.latest.sentinel]]</a>
206
+
207
+ ``` cpp
208
+ namespace std::ranges {
209
+ template<input_range V>
210
+ requires view<V>
211
+ class cache_latest_view<V>::sentinel {
212
+ sentinel_t<V> end_ = sentinel_t<V>(); // exposition only
213
+
214
+ constexpr explicit sentinel(cache_latest_view& parent); // exposition only
215
+
216
+ public:
217
+ sentinel() = default;
218
+
219
+ constexpr sentinel_t<V> base() const;
220
+
221
+ friend constexpr bool operator==(const iterator& x, const sentinel& y);
222
+
223
+ friend constexpr range_difference_t<V> operator-(const iterator& x, const sentinel& y)
224
+ requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
225
+ friend constexpr range_difference_t<V> operator-(const sentinel& x, const iterator& y)
226
+ requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
227
+ };
228
+ }
229
+ ```
230
+
231
+ ``` cpp
232
+ constexpr explicit sentinel(cache_latest_view& parent);
233
+ ```
234
+
235
+ *Effects:* Initializes *end\_* with `ranges::end(parent.`*`base_`*`)`.
236
+
237
+ ``` cpp
238
+ constexpr sentinel_t<V> base() const;
239
+ ```
240
+
241
+ *Returns:* *end\_*.
242
+
243
+ ``` cpp
244
+ friend constexpr bool operator==(const iterator& x, const sentinel& y);
245
+ ```
246
+
247
+ *Returns:* `x.`*`current_`*` == y.`*`end_`*.
248
+
249
+ ``` cpp
250
+ friend constexpr range_difference_t<V> operator-(const iterator& x, const sentinel& y)
251
+ requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
252
+ ```
253
+
254
+ *Returns:* `x.`*`current_`*` - y.`*`end_`*.
255
+
256
+ ``` cpp
257
+ friend constexpr range_difference_t<V> operator-(const sentinel& x, const iterator& y)
258
+ requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>;
259
+ ```
260
+
261
+ *Returns:* `x.`*`end_`*` - y.`*`current_`*.
262
+