From Jason Turner

[stream.iterators]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpq1wj1vm9/{from.md → to.md} +127 -159
tmp/tmpq1wj1vm9/{from.md → to.md} RENAMED
@@ -17,31 +17,13 @@ the partial sums onto `cout`.
17
 
18
  — *end example*]
19
 
20
  ### Class template `istream_iterator` <a id="istream.iterator">[[istream.iterator]]</a>
21
 
22
- The class template `istream_iterator` is an input iterator (
23
- [[input.iterators]]) that reads (using `operator>>`) successive elements
24
- from the input stream for which it was constructed. After it is
25
- constructed, and every time `++` is used, the iterator reads and stores
26
- a value of `T`. If the iterator fails to read and store a value of `T`
27
- (`fail()` on the stream returns `true`), the iterator becomes equal to
28
- the *end-of-stream* iterator value. The constructor with no arguments
29
- `istream_iterator()` always constructs an end-of-stream input iterator
30
- object, which is the only legitimate iterator to be used for the end
31
- condition. The result of `operator*` on an end-of-stream iterator is not
32
- defined. For any other iterator value a `const T&` is returned. The
33
- result of `operator->` on an end-of-stream iterator is not defined. For
34
- any other iterator value a `const T*` is returned. The behavior of a
35
- program that applies `operator++()` to an end-of-stream iterator is
36
- undefined. It is impossible to store things into istream iterators. The
37
- type `T` shall meet the `DefaultConstructible`, `CopyConstructible`, and
38
- `CopyAssignable` requirements.
39
-
40
- Two end-of-stream iterators are always equal. An end-of-stream iterator
41
- is not equal to a non-end-of-stream iterator. Two non-end-of-stream
42
- iterators are equal when they are constructed from the same stream.
43
 
44
  ``` cpp
45
  namespace std {
46
  template<class T, class charT = char, class traits = char_traits<charT>,
47
  class Distance = ptrdiff_t>
@@ -55,107 +37,117 @@ namespace std {
55
  using char_type = charT;
56
  using traits_type = traits;
57
  using istream_type = basic_istream<charT,traits>;
58
 
59
  constexpr istream_iterator();
 
60
  istream_iterator(istream_type& s);
61
  istream_iterator(const istream_iterator& x) = default;
62
  ~istream_iterator() = default;
 
63
 
64
  const T& operator*() const;
65
  const T* operator->() const;
66
  istream_iterator& operator++();
67
  istream_iterator operator++(int);
 
 
 
68
  private:
69
  basic_istream<charT,traits>* in_stream; // exposition only
70
  T value; // exposition only
71
  };
72
-
73
- template <class T, class charT, class traits, class Distance>
74
- bool operator==(const istream_iterator<T,charT,traits,Distance>& x,
75
- const istream_iterator<T,charT,traits,Distance>& y);
76
- template <class T, class charT, class traits, class Distance>
77
- bool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
78
- const istream_iterator<T,charT,traits,Distance>& y);
79
  }
80
  ```
81
 
82
- #### `istream_iterator` constructors and destructor <a id="istream.iterator.cons">[[istream.iterator.cons]]</a>
 
 
 
83
 
84
  ``` cpp
85
  constexpr istream_iterator();
 
86
  ```
87
 
88
- *Effects:* Constructs the end-of-stream iterator. If
89
- `is_trivially_default_constructible_v<T>` is `true`, then this
90
- constructor is a constexpr constructor.
91
 
92
- *Postconditions:* `in_stream == 0`.
 
 
 
 
93
 
94
  ``` cpp
95
  istream_iterator(istream_type& s);
96
  ```
97
 
98
- *Effects:* Initializes `in_stream` with `addressof(s)`. `value` may be
99
- initialized during construction or the first time it is referenced.
100
-
101
- *Postconditions:* `in_stream == addressof(s)`.
102
 
103
  ``` cpp
104
  istream_iterator(const istream_iterator& x) = default;
105
  ```
106
 
107
- *Effects:* Constructs a copy of `x`. If
108
- `is_trivially_copy_constructible_v<T>` is `true`, then this constructor
109
- is a trivial copy constructor.
110
 
111
- *Postconditions:* `in_stream == x.in_stream`.
 
112
 
113
  ``` cpp
114
  ~istream_iterator() = default;
115
  ```
116
 
117
- *Effects:* The iterator is destroyed. If
118
- `is_trivially_destructible_v<T>` is `true`, then this destructor is a
119
- trivial destructor.
120
 
121
- #### `istream_iterator` operations <a id="istream.iterator.ops">[[istream.iterator.ops]]</a>
122
 
123
  ``` cpp
124
  const T& operator*() const;
125
  ```
126
 
 
 
127
  *Returns:* `value`.
128
 
129
  ``` cpp
130
  const T* operator->() const;
131
  ```
132
 
133
- *Returns:* `addressof(operator*())`.
 
 
134
 
135
  ``` cpp
136
  istream_iterator& operator++();
137
  ```
138
 
139
- *Requires:* `in_stream != 0`.
140
 
141
- *Effects:* As if by: `*in_stream >> value;`
 
 
 
 
 
142
 
143
  *Returns:* `*this`.
144
 
145
  ``` cpp
146
  istream_iterator operator++(int);
147
  ```
148
 
149
- *Requires:* `in_stream != 0`.
150
 
151
- *Effects:* As if by:
152
 
153
  ``` cpp
154
  istream_iterator tmp = *this;
155
- *in_stream >> value;
156
- return (tmp);
157
  ```
158
 
159
  ``` cpp
160
  template<class T, class charT, class traits, class Distance>
161
  bool operator==(const istream_iterator<T,charT,traits,Distance>& x,
@@ -163,104 +155,82 @@ template <class T, class charT, class traits, class Distance>
163
  ```
164
 
165
  *Returns:* `x.in_stream == y.in_stream`.
166
 
167
  ``` cpp
168
- template <class T, class charT, class traits, class Distance>
169
- bool operator!=(const istream_iterator<T,charT,traits,Distance>& x,
170
- const istream_iterator<T,charT,traits,Distance>& y);
171
  ```
172
 
173
- *Returns:* `!(x == y)`
174
 
175
  ### Class template `ostream_iterator` <a id="ostream.iterator">[[ostream.iterator]]</a>
176
 
177
  `ostream_iterator` writes (using `operator<<`) successive elements onto
178
  the output stream from which it was constructed. If it was constructed
179
  with `charT*` as a constructor argument, this string, called a
180
  *delimiter string*, is written to the stream after every `T` is written.
181
- It is not possible to get a value out of the output iterator. Its only
182
- use is as an output iterator in situations like
183
-
184
- ``` cpp
185
- while (first != last)
186
- *result++ = *first++;
187
- ```
188
-
189
- `ostream_iterator`
190
-
191
- is defined as:
192
 
193
  ``` cpp
194
  namespace std {
195
  template<class T, class charT = char, class traits = char_traits<charT>>
196
  class ostream_iterator {
197
  public:
198
  using iterator_category = output_iterator_tag;
199
  using value_type = void;
200
- using difference_type = void;
201
  using pointer = void;
202
  using reference = void;
203
  using char_type = charT;
204
  using traits_type = traits;
205
  using ostream_type = basic_ostream<charT,traits>;
206
 
 
207
  ostream_iterator(ostream_type& s);
208
  ostream_iterator(ostream_type& s, const charT* delimiter);
209
  ostream_iterator(const ostream_iterator& x);
210
  ~ostream_iterator();
 
211
  ostream_iterator& operator=(const T& value);
212
 
213
  ostream_iterator& operator*();
214
  ostream_iterator& operator++();
215
  ostream_iterator& operator++(int);
 
216
  private:
217
- basic_ostream<charT,traits>* out_stream; // exposition only
218
- const charT* delim; // exposition only
219
  };
220
  }
221
  ```
222
 
223
- #### `ostream_iterator` constructors and destructor <a id="ostream.iterator.cons.des">[[ostream.iterator.cons.des]]</a>
224
 
225
  ``` cpp
226
  ostream_iterator(ostream_type& s);
227
  ```
228
 
229
  *Effects:* Initializes `out_stream` with `addressof(s)` and `delim` with
230
- null.
231
 
232
  ``` cpp
233
  ostream_iterator(ostream_type& s, const charT* delimiter);
234
  ```
235
 
236
  *Effects:* Initializes `out_stream` with `addressof(s)` and `delim` with
237
  `delimiter`.
238
 
239
- ``` cpp
240
- ostream_iterator(const ostream_iterator& x);
241
- ```
242
-
243
- *Effects:* Constructs a copy of `x`.
244
-
245
- ``` cpp
246
- ~ostream_iterator();
247
- ```
248
-
249
- *Effects:* The iterator is destroyed.
250
-
251
- #### `ostream_iterator` operations <a id="ostream.iterator.ops">[[ostream.iterator.ops]]</a>
252
 
253
  ``` cpp
254
  ostream_iterator& operator=(const T& value);
255
  ```
256
 
257
  *Effects:* As if by:
258
 
259
  ``` cpp
260
  *out_stream << value;
261
- if (delim != 0)
262
  *out_stream << delim;
263
  return *this;
264
  ```
265
 
266
  ``` cpp
@@ -276,22 +246,23 @@ ostream_iterator& operator++(int);
276
 
277
  *Returns:* `*this`.
278
 
279
  ### Class template `istreambuf_iterator` <a id="istreambuf.iterator">[[istreambuf.iterator]]</a>
280
 
281
- The class template `istreambuf_iterator` defines an input iterator (
282
- [[input.iterators]]) that reads successive *characters* from the
283
  streambuf for which it was constructed. `operator*` provides access to
284
  the current input character, if any. Each time `operator++` is
285
  evaluated, the iterator advances to the next input character. If the end
286
  of stream is reached (`streambuf_type::sgetc()` returns
287
  `traits::eof()`), the iterator becomes equal to the *end-of-stream*
288
  iterator value. The default constructor `istreambuf_iterator()` and the
289
- constructor `istreambuf_iterator(0)` both construct an end-of-stream
290
- iterator object suitable for use as an end-of-range. All specializations
291
- of `istreambuf_iterator` shall have a trivial copy constructor, a
292
- `constexpr` default constructor, and a trivial destructor.
 
293
 
294
  The result of `operator*()` on an end-of-stream iterator is undefined.
295
  For any other iterator value a `char_type` value is returned. It is
296
  impossible to assign a character via an input iterator.
297
 
@@ -312,64 +283,63 @@ namespace std {
312
  using istream_type = basic_istream<charT,traits>;
313
 
314
  class proxy; // exposition only
315
 
316
  constexpr istreambuf_iterator() noexcept;
 
317
  istreambuf_iterator(const istreambuf_iterator&) noexcept = default;
318
  ~istreambuf_iterator() = default;
319
  istreambuf_iterator(istream_type& s) noexcept;
320
  istreambuf_iterator(streambuf_type* s) noexcept;
321
  istreambuf_iterator(const proxy& p) noexcept;
 
322
  charT operator*() const;
323
  istreambuf_iterator& operator++();
324
  proxy operator++(int);
325
  bool equal(const istreambuf_iterator& b) const;
 
 
 
326
  private:
327
  streambuf_type* sbuf_; // exposition only
328
  };
329
-
330
- template <class charT, class traits>
331
- bool operator==(const istreambuf_iterator<charT,traits>& a,
332
- const istreambuf_iterator<charT,traits>& b);
333
- template <class charT, class traits>
334
- bool operator!=(const istreambuf_iterator<charT,traits>& a,
335
- const istreambuf_iterator<charT,traits>& b);
336
  }
337
  ```
338
 
339
- #### Class template `istreambuf_iterator::proxy` <a id="istreambuf.iterator.proxy">[[istreambuf.iterator.proxy]]</a>
340
-
341
- ``` cpp
342
- namespace std {
343
- template <class charT, class traits = char_traits<charT>>
344
- class istreambuf_iterator<charT, traits>::proxy { // exposition only
345
- charT keep_;
346
- basic_streambuf<charT,traits>* sbuf_;
347
- proxy(charT c, basic_streambuf<charT,traits>* sbuf)
348
- : keep_(c), sbuf_(sbuf) { }
349
- public:
350
- charT operator*() { return keep_; }
351
- };
352
- }
353
- ```
354
 
355
  Class `istreambuf_iterator<charT,traits>::proxy` is for exposition only.
356
  An implementation is permitted to provide equivalent functionality
357
  without providing a class with this name. Class
358
  `istreambuf_iterator<charT, traits>::proxy` provides a temporary
359
  placeholder as the return value of the post-increment operator
360
  (`operator++`). It keeps the character pointed to by the previous value
361
  of the iterator for some possible future access to get the character.
362
 
363
- #### `istreambuf_iterator` constructors <a id="istreambuf.iterator.cons">[[istreambuf.iterator.cons]]</a>
 
 
 
 
 
 
 
 
 
 
 
 
364
 
365
- For each `istreambuf_iterator` constructor in this section, an
 
 
366
  end-of-stream iterator is constructed if and only if the exposition-only
367
  member `sbuf_` is initialized with a null pointer value.
368
 
369
  ``` cpp
370
  constexpr istreambuf_iterator() noexcept;
 
371
  ```
372
 
373
  *Effects:* Initializes `sbuf_` with `nullptr`.
374
 
375
  ``` cpp
@@ -388,14 +358,14 @@ istreambuf_iterator(streambuf_type* s) noexcept;
388
  istreambuf_iterator(const proxy& p) noexcept;
389
  ```
390
 
391
  *Effects:* Initializes `sbuf_` with `p.sbuf_`.
392
 
393
- #### `istreambuf_iterator` operations <a id="istreambuf.iterator.ops">[[istreambuf.iterator.ops]]</a>
394
 
395
  ``` cpp
396
- charT operator*() const
397
  ```
398
 
399
  *Returns:* The character obtained via the `streambuf` member
400
  `sbuf_->sgetc()`.
401
 
@@ -409,11 +379,11 @@ istreambuf_iterator& operator++();
409
 
410
  ``` cpp
411
  proxy operator++(int);
412
  ```
413
 
414
- *Returns:* `proxy(sbuf_->sbumpc(), sbuf_)`.
415
 
416
  ``` cpp
417
  bool equal(const istreambuf_iterator& b) const;
418
  ```
419
 
@@ -428,72 +398,70 @@ template <class charT, class traits>
428
  ```
429
 
430
  *Returns:* `a.equal(b)`.
431
 
432
  ``` cpp
433
- template <class charT, class traits>
434
- bool operator!=(const istreambuf_iterator<charT,traits>& a,
435
- const istreambuf_iterator<charT,traits>& b);
436
  ```
437
 
438
- *Returns:* `!a.equal(b)`.
439
 
440
  ### Class template `ostreambuf_iterator` <a id="ostreambuf.iterator">[[ostreambuf.iterator]]</a>
441
 
442
- ``` cpp
443
- namespace std {
444
- template <class charT, class traits = char_traits<charT>>
445
- class ostreambuf_iterator {
446
- public:
447
- using iterator_category = output_iterator_tag;
448
- using value_type = void;
449
- using difference_type = void;
450
- using pointer = void;
451
- using reference = void;
452
- using char_type = charT;
453
- using traits_type = traits;
454
- using streambuf_type = basic_streambuf<charT,traits>;
455
- using ostream_type = basic_ostream<charT,traits>;
456
-
457
- ostreambuf_iterator(ostream_type& s) noexcept;
458
- ostreambuf_iterator(streambuf_type* s) noexcept;
459
- ostreambuf_iterator& operator=(charT c);
460
-
461
- ostreambuf_iterator& operator*();
462
- ostreambuf_iterator& operator++();
463
- ostreambuf_iterator& operator++(int);
464
- bool failed() const noexcept;
465
-
466
- private:
467
- streambuf_type* sbuf_; // exposition only
468
- };
469
- }
470
- ```
471
-
472
  The class template `ostreambuf_iterator` writes successive *characters*
473
- onto the output stream from which it was constructed. It is not possible
474
- to get a character value out of the output iterator.
475
 
476
- #### `ostreambuf_iterator` constructors <a id="ostreambuf.iter.cons">[[ostreambuf.iter.cons]]</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477
 
478
  ``` cpp
479
  ostreambuf_iterator(ostream_type& s) noexcept;
480
  ```
481
 
482
- *Requires:* `s.rdbuf()` shall not be a null pointer.
483
 
484
  *Effects:* Initializes `sbuf_` with `s.rdbuf()`.
485
 
486
  ``` cpp
487
  ostreambuf_iterator(streambuf_type* s) noexcept;
488
  ```
489
 
490
- *Requires:* `s` shall not be a null pointer.
491
 
492
  *Effects:* Initializes `sbuf_` with `s`.
493
 
494
- #### `ostreambuf_iterator` operations <a id="ostreambuf.iter.ops">[[ostreambuf.iter.ops]]</a>
495
 
496
  ``` cpp
497
  ostreambuf_iterator& operator=(charT c);
498
  ```
499
 
 
17
 
18
  — *end example*]
19
 
20
  ### Class template `istream_iterator` <a id="istream.iterator">[[istream.iterator]]</a>
21
 
22
+ The class template `istream_iterator` is an input iterator
23
+ [[input.iterators]] that reads successive elements from the input stream
24
+ for which it was constructed.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
  ``` cpp
27
  namespace std {
28
  template<class T, class charT = char, class traits = char_traits<charT>,
29
  class Distance = ptrdiff_t>
 
37
  using char_type = charT;
38
  using traits_type = traits;
39
  using istream_type = basic_istream<charT,traits>;
40
 
41
  constexpr istream_iterator();
42
+ constexpr istream_iterator(default_sentinel_t);
43
  istream_iterator(istream_type& s);
44
  istream_iterator(const istream_iterator& x) = default;
45
  ~istream_iterator() = default;
46
+ istream_iterator& operator=(const istream_iterator&) = default;
47
 
48
  const T& operator*() const;
49
  const T* operator->() const;
50
  istream_iterator& operator++();
51
  istream_iterator operator++(int);
52
+
53
+ friend bool operator==(const istream_iterator& i, default_sentinel_t);
54
+
55
  private:
56
  basic_istream<charT,traits>* in_stream; // exposition only
57
  T value; // exposition only
58
  };
 
 
 
 
 
 
 
59
  }
60
  ```
61
 
62
+ The type `T` shall meet the *Cpp17DefaultConstructible*,
63
+ *Cpp17CopyConstructible*, and *Cpp17CopyAssignable* requirements.
64
+
65
+ #### Constructors and destructor <a id="istream.iterator.cons">[[istream.iterator.cons]]</a>
66
 
67
  ``` cpp
68
  constexpr istream_iterator();
69
+ constexpr istream_iterator(default_sentinel_t);
70
  ```
71
 
72
+ *Effects:* Constructs the end-of-stream iterator, value-initializing
73
+ `value`.
 
74
 
75
+ *Ensures:* `in_stream == nullptr` is `true`.
76
+
77
+ *Remarks:* If the initializer `T()` in the declaration `auto x = T();`
78
+ is a constant initializer [[expr.const]], then these constructors are
79
+ `constexpr` constructors.
80
 
81
  ``` cpp
82
  istream_iterator(istream_type& s);
83
  ```
84
 
85
+ *Effects:* Initializes `in_stream` with `addressof(s)`,
86
+ value-initializes `value`, and then calls `operator++()`.
 
 
87
 
88
  ``` cpp
89
  istream_iterator(const istream_iterator& x) = default;
90
  ```
91
 
92
+ *Ensures:* `in_stream == x.in_stream` is `true`.
 
 
93
 
94
+ *Remarks:* If `is_trivially_copy_constructible_v<T>` is `true`, then
95
+ this constructor is trivial.
96
 
97
  ``` cpp
98
  ~istream_iterator() = default;
99
  ```
100
 
101
+ *Remarks:* If `is_trivially_destructible_v<T>` is `true`, then this
102
+ destructor is trivial.
 
103
 
104
+ #### Operations <a id="istream.iterator.ops">[[istream.iterator.ops]]</a>
105
 
106
  ``` cpp
107
  const T& operator*() const;
108
  ```
109
 
110
+ *Preconditions:* `in_stream != nullptr` is `true`.
111
+
112
  *Returns:* `value`.
113
 
114
  ``` cpp
115
  const T* operator->() const;
116
  ```
117
 
118
+ *Preconditions:* `in_stream != nullptr` is `true`.
119
+
120
+ *Returns:* `addressof(value)`.
121
 
122
  ``` cpp
123
  istream_iterator& operator++();
124
  ```
125
 
126
+ *Preconditions:* `in_stream != nullptr` is `true`.
127
 
128
+ *Effects:* Equivalent to:
129
+
130
+ ``` cpp
131
+ if (!(*in_stream >> value))
132
+ in_stream = nullptr;
133
+ ```
134
 
135
  *Returns:* `*this`.
136
 
137
  ``` cpp
138
  istream_iterator operator++(int);
139
  ```
140
 
141
+ *Preconditions:* `in_stream != nullptr` is `true`.
142
 
143
+ *Effects:* Equivalent to:
144
 
145
  ``` cpp
146
  istream_iterator tmp = *this;
147
+ ++*this;
148
+ return tmp;
149
  ```
150
 
151
  ``` cpp
152
  template<class T, class charT, class traits, class Distance>
153
  bool operator==(const istream_iterator<T,charT,traits,Distance>& x,
 
155
  ```
156
 
157
  *Returns:* `x.in_stream == y.in_stream`.
158
 
159
  ``` cpp
160
+ friend bool operator==(const istream_iterator& i, default_sentinel_t);
 
 
161
  ```
162
 
163
+ *Returns:* `!i.in_stream`.
164
 
165
  ### Class template `ostream_iterator` <a id="ostream.iterator">[[ostream.iterator]]</a>
166
 
167
  `ostream_iterator` writes (using `operator<<`) successive elements onto
168
  the output stream from which it was constructed. If it was constructed
169
  with `charT*` as a constructor argument, this string, called a
170
  *delimiter string*, is written to the stream after every `T` is written.
 
 
 
 
 
 
 
 
 
 
 
171
 
172
  ``` cpp
173
  namespace std {
174
  template<class T, class charT = char, class traits = char_traits<charT>>
175
  class ostream_iterator {
176
  public:
177
  using iterator_category = output_iterator_tag;
178
  using value_type = void;
179
+ using difference_type = ptrdiff_t;
180
  using pointer = void;
181
  using reference = void;
182
  using char_type = charT;
183
  using traits_type = traits;
184
  using ostream_type = basic_ostream<charT,traits>;
185
 
186
+ constexpr ostream_iterator() noexcept = default;
187
  ostream_iterator(ostream_type& s);
188
  ostream_iterator(ostream_type& s, const charT* delimiter);
189
  ostream_iterator(const ostream_iterator& x);
190
  ~ostream_iterator();
191
+ ostream_iterator& operator=(const ostream_iterator&) = default;
192
  ostream_iterator& operator=(const T& value);
193
 
194
  ostream_iterator& operator*();
195
  ostream_iterator& operator++();
196
  ostream_iterator& operator++(int);
197
+
198
  private:
199
+ basic_ostream<charT,traits>* out_stream = nullptr; // exposition only
200
+ const charT* delim = nullptr; // exposition only
201
  };
202
  }
203
  ```
204
 
205
+ #### Constructors and destructor <a id="ostream.iterator.cons.des">[[ostream.iterator.cons.des]]</a>
206
 
207
  ``` cpp
208
  ostream_iterator(ostream_type& s);
209
  ```
210
 
211
  *Effects:* Initializes `out_stream` with `addressof(s)` and `delim` with
212
+ `nullptr`.
213
 
214
  ``` cpp
215
  ostream_iterator(ostream_type& s, const charT* delimiter);
216
  ```
217
 
218
  *Effects:* Initializes `out_stream` with `addressof(s)` and `delim` with
219
  `delimiter`.
220
 
221
+ #### Operations <a id="ostream.iterator.ops">[[ostream.iterator.ops]]</a>
 
 
 
 
 
 
 
 
 
 
 
 
222
 
223
  ``` cpp
224
  ostream_iterator& operator=(const T& value);
225
  ```
226
 
227
  *Effects:* As if by:
228
 
229
  ``` cpp
230
  *out_stream << value;
231
+ if (delim)
232
  *out_stream << delim;
233
  return *this;
234
  ```
235
 
236
  ``` cpp
 
246
 
247
  *Returns:* `*this`.
248
 
249
  ### Class template `istreambuf_iterator` <a id="istreambuf.iterator">[[istreambuf.iterator]]</a>
250
 
251
+ The class template `istreambuf_iterator` defines an input iterator
252
+ [[input.iterators]] that reads successive *characters* from the
253
  streambuf for which it was constructed. `operator*` provides access to
254
  the current input character, if any. Each time `operator++` is
255
  evaluated, the iterator advances to the next input character. If the end
256
  of stream is reached (`streambuf_type::sgetc()` returns
257
  `traits::eof()`), the iterator becomes equal to the *end-of-stream*
258
  iterator value. The default constructor `istreambuf_iterator()` and the
259
+ constructor `istreambuf_iterator(nullptr)` both construct an
260
+ end-of-stream iterator object suitable for use as an end-of-range. All
261
+ specializations of `istreambuf_iterator` shall have a trivial copy
262
+ constructor, a `constexpr` default constructor, and a trivial
263
+ destructor.
264
 
265
  The result of `operator*()` on an end-of-stream iterator is undefined.
266
  For any other iterator value a `char_type` value is returned. It is
267
  impossible to assign a character via an input iterator.
268
 
 
283
  using istream_type = basic_istream<charT,traits>;
284
 
285
  class proxy; // exposition only
286
 
287
  constexpr istreambuf_iterator() noexcept;
288
+ constexpr istreambuf_iterator(default_sentinel_t) noexcept;
289
  istreambuf_iterator(const istreambuf_iterator&) noexcept = default;
290
  ~istreambuf_iterator() = default;
291
  istreambuf_iterator(istream_type& s) noexcept;
292
  istreambuf_iterator(streambuf_type* s) noexcept;
293
  istreambuf_iterator(const proxy& p) noexcept;
294
+ istreambuf_iterator& operator=(const istreambuf_iterator&) noexcept = default;
295
  charT operator*() const;
296
  istreambuf_iterator& operator++();
297
  proxy operator++(int);
298
  bool equal(const istreambuf_iterator& b) const;
299
+
300
+ friend bool operator==(const istreambuf_iterator& i, default_sentinel_t s);
301
+
302
  private:
303
  streambuf_type* sbuf_; // exposition only
304
  };
 
 
 
 
 
 
 
305
  }
306
  ```
307
 
308
+ #### Class `istreambuf_iterator::proxy` <a id="istreambuf.iterator.proxy">[[istreambuf.iterator.proxy]]</a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
309
 
310
  Class `istreambuf_iterator<charT,traits>::proxy` is for exposition only.
311
  An implementation is permitted to provide equivalent functionality
312
  without providing a class with this name. Class
313
  `istreambuf_iterator<charT, traits>::proxy` provides a temporary
314
  placeholder as the return value of the post-increment operator
315
  (`operator++`). It keeps the character pointed to by the previous value
316
  of the iterator for some possible future access to get the character.
317
 
318
+ ``` cpp
319
+ namespace std {
320
+ template<class charT, class traits>
321
+ class istreambuf_iterator<charT, traits>::proxy { // exposition only
322
+ charT keep_;
323
+ basic_streambuf<charT,traits>* sbuf_;
324
+ proxy(charT c, basic_streambuf<charT,traits>* sbuf)
325
+ : keep_(c), sbuf_(sbuf) { }
326
+ public:
327
+ charT operator*() { return keep_; }
328
+ };
329
+ }
330
+ ```
331
 
332
+ #### Constructors <a id="istreambuf.iterator.cons">[[istreambuf.iterator.cons]]</a>
333
+
334
+ For each `istreambuf_iterator` constructor in this subclause, an
335
  end-of-stream iterator is constructed if and only if the exposition-only
336
  member `sbuf_` is initialized with a null pointer value.
337
 
338
  ``` cpp
339
  constexpr istreambuf_iterator() noexcept;
340
+ constexpr istreambuf_iterator(default_sentinel_t) noexcept;
341
  ```
342
 
343
  *Effects:* Initializes `sbuf_` with `nullptr`.
344
 
345
  ``` cpp
 
358
  istreambuf_iterator(const proxy& p) noexcept;
359
  ```
360
 
361
  *Effects:* Initializes `sbuf_` with `p.sbuf_`.
362
 
363
+ #### Operations <a id="istreambuf.iterator.ops">[[istreambuf.iterator.ops]]</a>
364
 
365
  ``` cpp
366
+ charT operator*() const;
367
  ```
368
 
369
  *Returns:* The character obtained via the `streambuf` member
370
  `sbuf_->sgetc()`.
371
 
 
379
 
380
  ``` cpp
381
  proxy operator++(int);
382
  ```
383
 
384
+ *Returns:* *`proxy`*`(sbuf_->sbumpc(), sbuf_)`.
385
 
386
  ``` cpp
387
  bool equal(const istreambuf_iterator& b) const;
388
  ```
389
 
 
398
  ```
399
 
400
  *Returns:* `a.equal(b)`.
401
 
402
  ``` cpp
403
+ friend bool operator==(const istreambuf_iterator& i, default_sentinel_t s);
 
 
404
  ```
405
 
406
+ *Returns:* `i.equal(s)`.
407
 
408
  ### Class template `ostreambuf_iterator` <a id="ostreambuf.iterator">[[ostreambuf.iterator]]</a>
409
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
  The class template `ostreambuf_iterator` writes successive *characters*
411
+ onto the output stream from which it was constructed.
 
412
 
413
+ ``` cpp
414
+ namespace std {
415
+ template<class charT, class traits = char_traits<charT>>
416
+ class ostreambuf_iterator {
417
+ public:
418
+ using iterator_category = output_iterator_tag;
419
+ using value_type = void;
420
+ using difference_type = ptrdiff_t;
421
+ using pointer = void;
422
+ using reference = void;
423
+ using char_type = charT;
424
+ using traits_type = traits;
425
+ using streambuf_type = basic_streambuf<charT,traits>;
426
+ using ostream_type = basic_ostream<charT,traits>;
427
+
428
+ constexpr ostreambuf_iterator() noexcept = default;
429
+ ostreambuf_iterator(ostream_type& s) noexcept;
430
+ ostreambuf_iterator(streambuf_type* s) noexcept;
431
+ ostreambuf_iterator& operator=(charT c);
432
+
433
+ ostreambuf_iterator& operator*();
434
+ ostreambuf_iterator& operator++();
435
+ ostreambuf_iterator& operator++(int);
436
+ bool failed() const noexcept;
437
+
438
+ private:
439
+ streambuf_type* sbuf_ = nullptr; // exposition only
440
+ };
441
+ }
442
+ ```
443
+
444
+ #### Constructors <a id="ostreambuf.iter.cons">[[ostreambuf.iter.cons]]</a>
445
 
446
  ``` cpp
447
  ostreambuf_iterator(ostream_type& s) noexcept;
448
  ```
449
 
450
+ *Preconditions:* `s.rdbuf()` is not a null pointer.
451
 
452
  *Effects:* Initializes `sbuf_` with `s.rdbuf()`.
453
 
454
  ``` cpp
455
  ostreambuf_iterator(streambuf_type* s) noexcept;
456
  ```
457
 
458
+ *Preconditions:* `s` is not a null pointer.
459
 
460
  *Effects:* Initializes `sbuf_` with `s`.
461
 
462
+ #### Operations <a id="ostreambuf.iter.ops">[[ostreambuf.iter.ops]]</a>
463
 
464
  ``` cpp
465
  ostreambuf_iterator& operator=(charT c);
466
  ```
467