From Jason Turner

[syncstream]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp5wn7kccp/{from.md → to.md} +34 -33
tmp/tmp5wn7kccp/{from.md → to.md} RENAMED
@@ -7,10 +7,15 @@
7
 
8
  namespace std {
9
  template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
10
  class basic_syncbuf;
11
 
 
 
 
 
 
12
  using syncbuf = basic_syncbuf<char>;
13
  using wsyncbuf = basic_syncbuf<wchar_t>;
14
 
15
  template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
16
  class basic_osyncstream;
@@ -66,15 +71,10 @@ namespace std {
66
 
67
  private:
68
  streambuf_type* wrapped; // exposition only
69
  bool emit_on_sync{}; // exposition only
70
  };
71
-
72
- // [syncstream.syncbuf.special], specialized algorithms
73
- template<class charT, class traits, class Allocator>
74
- void swap(basic_syncbuf<charT, traits, Allocator>&,
75
- basic_syncbuf<charT, traits, Allocator>&);
76
  }
77
  ```
78
 
79
  Class template `basic_syncbuf` stores character data written to it,
80
  known as the associated output, into internal buffers allocated using
@@ -90,28 +90,27 @@ wrapped stream buffer object.
90
  basic_syncbuf(streambuf_type* obuf, const Allocator& allocator);
91
  ```
92
 
93
  *Effects:* Sets `wrapped` to `obuf`.
94
 
95
- *Remarks:* A copy of `allocator` is used to allocate memory for internal
96
- buffers holding the associated output.
97
-
98
- *Throws:* Nothing unless an exception is thrown by the construction of a
99
- mutex or by memory allocation.
100
-
101
  *Ensures:* `get_wrapped() == obuf` and `get_allocator() == allocator`
102
  are `true`.
103
 
 
 
 
 
 
 
104
  ``` cpp
105
  basic_syncbuf(basic_syncbuf&& other);
106
  ```
107
 
108
  *Ensures:* The value returned by `this->get_wrapped()` is the value
109
  returned by `other.get_wrapped()` prior to calling this constructor.
110
  Output stored in `other` prior to calling this constructor will be
111
- stored in `*this` afterwards.
112
- `other.rdbuf()->pbase() == other.rdbuf()->pptr()` and
113
  `other.get_wrapped() == nullptr` are `true`.
114
 
115
  *Remarks:* This constructor disassociates `other` from its wrapped
116
  stream buffer, ensuring destruction of `other` produces no output.
117
 
@@ -125,34 +124,34 @@ stream buffer, ensuring destruction of `other` produces no output.
125
  destructor catches and ignores that exception.
126
 
127
  #### Assignment and swap <a id="syncstream.syncbuf.assign">[[syncstream.syncbuf.assign]]</a>
128
 
129
  ``` cpp
130
- basic_syncbuf& operator=(basic_syncbuf&& rhs) noexcept;
131
  ```
132
 
133
  *Effects:* Calls `emit()` then move assigns from `rhs`. After the move
134
  assignment `*this` has the observable state it would have had if it had
135
  been move constructed from `rhs` [[syncstream.syncbuf.cons]].
136
 
137
- *Returns:* `*this`.
138
-
139
  *Ensures:*
140
 
141
  - `rhs.get_wrapped() == nullptr` is `true`.
142
  - `this->get_allocator() == rhs.get_allocator()` is `true` when
143
  ``` cpp
144
  allocator_traits<Allocator>::propagate_on_container_move_assignment::value
145
  ```
146
 
147
  is `true`; otherwise, the allocator is unchanged.
148
 
 
 
149
  *Remarks:* This assignment operator disassociates `rhs` from its wrapped
150
  stream buffer, ensuring destruction of `rhs` produces no output.
151
 
152
  ``` cpp
153
- void swap(basic_syncbuf& other) noexcept;
154
  ```
155
 
156
  *Preconditions:* Either
157
  `allocator_traits<Allocator>::propagate_on_container_swap::value` is
158
  `true` or `this->get_allocator() == other.get_allocator()` is `true`.
@@ -169,25 +168,25 @@ bool emit();
169
  stream buffer `*wrapped`, so that it appears in the output stream as a
170
  contiguous sequence of characters. `wrapped->pubsync()` is called if and
171
  only if a call was made to `sync()` since the most recent call to
172
  `emit()`, if any.
173
 
 
 
 
 
 
 
 
174
  *Returns:* `true` if all of the following conditions hold; otherwise
175
  `false`:
176
 
177
  - `wrapped == nullptr` is `false`.
178
  - All of the characters in the associated output were successfully
179
  transferred.
180
  - The call to `wrapped->pubsync()` (if any) succeeded.
181
 
182
- *Ensures:* On success, the associated output is empty.
183
-
184
- *Synchronization:* All `emit()` calls transferring characters to the
185
- same stream buffer object appear to execute in a total order consistent
186
- with the “happens before” relation [[intro.races]], where each `emit()`
187
- call synchronizes with subsequent `emit()` calls in that total order.
188
-
189
  *Remarks:* May call member functions of `wrapped` while holding a lock
190
  uniquely associated with `wrapped`.
191
 
192
  ``` cpp
193
  streambuf_type* get_wrapped() const noexcept;
@@ -226,11 +225,11 @@ otherwise `0`.
226
  #### Specialized algorithms <a id="syncstream.syncbuf.special">[[syncstream.syncbuf.special]]</a>
227
 
228
  ``` cpp
229
  template<class charT, class traits, class Allocator>
230
  void swap(basic_syncbuf<charT, traits, Allocator>& a,
231
- basic_syncbuf<charT, traits, Allocator>& b) noexcept;
232
  ```
233
 
234
  *Effects:* Equivalent to `a.swap(b)`.
235
 
236
  ### Class template `basic_osyncstream` <a id="syncstream.osyncstream">[[syncstream.osyncstream]]</a>
@@ -262,11 +261,11 @@ namespace std {
262
  : basic_osyncstream(os, Allocator()) {}
263
  basic_osyncstream(basic_osyncstream&&) noexcept;
264
  ~basic_osyncstream();
265
 
266
  // assignment
267
- basic_osyncstream& operator=(basic_osyncstream&&) noexcept;
268
 
269
  // [syncstream.osyncstream.members], member functions
270
  void emit();
271
  streambuf_type* get_wrapped() const noexcept;
272
  syncbuf_type* rdbuf() const noexcept { return const_cast<syncbuf_type*>(addressof(sb)); }
@@ -275,12 +274,12 @@ namespace std {
275
  syncbuf_type sb; // exposition only
276
  };
277
  }
278
  ```
279
 
280
- `Allocator` shall meet the *Cpp17Allocator* requirements (
281
- [[cpp17.allocator]]).
282
 
283
  [*Example 1*:
284
 
285
  A named variable can be used within a block statement for streaming.
286
 
@@ -315,13 +314,13 @@ basic_osyncstream(streambuf_type* buf, const Allocator& allocator);
315
  ```
316
 
317
  *Effects:* Initializes `sb` from `buf` and `allocator`. Initializes the
318
  base class with `basic_ostream<charT, traits>(addressof(sb))`.
319
 
320
- [*Note 1*: The member functions of the provided stream buffer might be
321
- called from `emit()` while a lock is held. Care should be taken to
322
- ensure that this does not result in deadlock. — *end note*]
323
 
324
  *Ensures:* `get_wrapped() == buf` is `true`.
325
 
326
  ``` cpp
327
  basic_osyncstream(basic_osyncstream&& other) noexcept;
@@ -330,20 +329,22 @@ basic_osyncstream(basic_osyncstream&& other) noexcept;
330
  *Effects:* Move constructs the base class and `sb` from the
331
  corresponding subobjects of `other`, and calls
332
  `basic_ostream<charT, traits>::set_rdbuf(addressof(sb))`.
333
 
334
  *Ensures:* The value returned by `get_wrapped()` is the value returned
335
- by `os.get_wrapped()` prior to calling this constructor.
336
  `nullptr == other.get_wrapped()` is `true`.
337
 
338
  #### Member functions <a id="syncstream.osyncstream.members">[[syncstream.osyncstream.members]]</a>
339
 
340
  ``` cpp
341
  void emit();
342
  ```
343
 
344
- *Effects:* Calls `sb.emit()`. If that call returns `false`, calls
 
 
345
  `setstate(ios_base::badbit)`.
346
 
347
  [*Example 1*:
348
 
349
  A flush on a `basic_osyncstream` does not flush immediately:
 
7
 
8
  namespace std {
9
  template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
10
  class basic_syncbuf;
11
 
12
+ // [syncstream.syncbuf.special], specialized algorithms
13
+ template<class charT, class traits, class Allocator>
14
+ void swap(basic_syncbuf<charT, traits, Allocator>&,
15
+ basic_syncbuf<charT, traits, Allocator>&);
16
+
17
  using syncbuf = basic_syncbuf<char>;
18
  using wsyncbuf = basic_syncbuf<wchar_t>;
19
 
20
  template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
21
  class basic_osyncstream;
 
71
 
72
  private:
73
  streambuf_type* wrapped; // exposition only
74
  bool emit_on_sync{}; // exposition only
75
  };
 
 
 
 
 
76
  }
77
  ```
78
 
79
  Class template `basic_syncbuf` stores character data written to it,
80
  known as the associated output, into internal buffers allocated using
 
90
  basic_syncbuf(streambuf_type* obuf, const Allocator& allocator);
91
  ```
92
 
93
  *Effects:* Sets `wrapped` to `obuf`.
94
 
 
 
 
 
 
 
95
  *Ensures:* `get_wrapped() == obuf` and `get_allocator() == allocator`
96
  are `true`.
97
 
98
+ *Throws:* Nothing unless an exception is thrown by the construction of a
99
+ mutex or by memory allocation.
100
+
101
+ *Remarks:* A copy of `allocator` is used to allocate memory for internal
102
+ buffers holding the associated output.
103
+
104
  ``` cpp
105
  basic_syncbuf(basic_syncbuf&& other);
106
  ```
107
 
108
  *Ensures:* The value returned by `this->get_wrapped()` is the value
109
  returned by `other.get_wrapped()` prior to calling this constructor.
110
  Output stored in `other` prior to calling this constructor will be
111
+ stored in `*this` afterwards. `other.pbase() == other.pptr()` and
 
112
  `other.get_wrapped() == nullptr` are `true`.
113
 
114
  *Remarks:* This constructor disassociates `other` from its wrapped
115
  stream buffer, ensuring destruction of `other` produces no output.
116
 
 
124
  destructor catches and ignores that exception.
125
 
126
  #### Assignment and swap <a id="syncstream.syncbuf.assign">[[syncstream.syncbuf.assign]]</a>
127
 
128
  ``` cpp
129
+ basic_syncbuf& operator=(basic_syncbuf&& rhs);
130
  ```
131
 
132
  *Effects:* Calls `emit()` then move assigns from `rhs`. After the move
133
  assignment `*this` has the observable state it would have had if it had
134
  been move constructed from `rhs` [[syncstream.syncbuf.cons]].
135
 
 
 
136
  *Ensures:*
137
 
138
  - `rhs.get_wrapped() == nullptr` is `true`.
139
  - `this->get_allocator() == rhs.get_allocator()` is `true` when
140
  ``` cpp
141
  allocator_traits<Allocator>::propagate_on_container_move_assignment::value
142
  ```
143
 
144
  is `true`; otherwise, the allocator is unchanged.
145
 
146
+ *Returns:* `*this`.
147
+
148
  *Remarks:* This assignment operator disassociates `rhs` from its wrapped
149
  stream buffer, ensuring destruction of `rhs` produces no output.
150
 
151
  ``` cpp
152
+ void swap(basic_syncbuf& other);
153
  ```
154
 
155
  *Preconditions:* Either
156
  `allocator_traits<Allocator>::propagate_on_container_swap::value` is
157
  `true` or `this->get_allocator() == other.get_allocator()` is `true`.
 
168
  stream buffer `*wrapped`, so that it appears in the output stream as a
169
  contiguous sequence of characters. `wrapped->pubsync()` is called if and
170
  only if a call was made to `sync()` since the most recent call to
171
  `emit()`, if any.
172
 
173
+ *Synchronization:* All `emit()` calls transferring characters to the
174
+ same stream buffer object appear to execute in a total order consistent
175
+ with the “happens before” relation [[intro.races]], where each `emit()`
176
+ call synchronizes with subsequent `emit()` calls in that total order.
177
+
178
+ *Ensures:* On success, the associated output is empty.
179
+
180
  *Returns:* `true` if all of the following conditions hold; otherwise
181
  `false`:
182
 
183
  - `wrapped == nullptr` is `false`.
184
  - All of the characters in the associated output were successfully
185
  transferred.
186
  - The call to `wrapped->pubsync()` (if any) succeeded.
187
 
 
 
 
 
 
 
 
188
  *Remarks:* May call member functions of `wrapped` while holding a lock
189
  uniquely associated with `wrapped`.
190
 
191
  ``` cpp
192
  streambuf_type* get_wrapped() const noexcept;
 
225
  #### Specialized algorithms <a id="syncstream.syncbuf.special">[[syncstream.syncbuf.special]]</a>
226
 
227
  ``` cpp
228
  template<class charT, class traits, class Allocator>
229
  void swap(basic_syncbuf<charT, traits, Allocator>& a,
230
+ basic_syncbuf<charT, traits, Allocator>& b);
231
  ```
232
 
233
  *Effects:* Equivalent to `a.swap(b)`.
234
 
235
  ### Class template `basic_osyncstream` <a id="syncstream.osyncstream">[[syncstream.osyncstream]]</a>
 
261
  : basic_osyncstream(os, Allocator()) {}
262
  basic_osyncstream(basic_osyncstream&&) noexcept;
263
  ~basic_osyncstream();
264
 
265
  // assignment
266
+ basic_osyncstream& operator=(basic_osyncstream&&);
267
 
268
  // [syncstream.osyncstream.members], member functions
269
  void emit();
270
  streambuf_type* get_wrapped() const noexcept;
271
  syncbuf_type* rdbuf() const noexcept { return const_cast<syncbuf_type*>(addressof(sb)); }
 
274
  syncbuf_type sb; // exposition only
275
  };
276
  }
277
  ```
278
 
279
+ `Allocator` shall meet the *Cpp17Allocator* requirements
280
+ [[allocator.requirements.general]].
281
 
282
  [*Example 1*:
283
 
284
  A named variable can be used within a block statement for streaming.
285
 
 
314
  ```
315
 
316
  *Effects:* Initializes `sb` from `buf` and `allocator`. Initializes the
317
  base class with `basic_ostream<charT, traits>(addressof(sb))`.
318
 
319
+ [*Note 1*: The member functions of the provided stream buffer can be
320
+ called from `emit()` while a lock is held, which might result in a
321
+ deadlock if used incautiously. — *end note*]
322
 
323
  *Ensures:* `get_wrapped() == buf` is `true`.
324
 
325
  ``` cpp
326
  basic_osyncstream(basic_osyncstream&& other) noexcept;
 
329
  *Effects:* Move constructs the base class and `sb` from the
330
  corresponding subobjects of `other`, and calls
331
  `basic_ostream<charT, traits>::set_rdbuf(addressof(sb))`.
332
 
333
  *Ensures:* The value returned by `get_wrapped()` is the value returned
334
+ by `other.get_wrapped()` prior to calling this constructor.
335
  `nullptr == other.get_wrapped()` is `true`.
336
 
337
  #### Member functions <a id="syncstream.osyncstream.members">[[syncstream.osyncstream.members]]</a>
338
 
339
  ``` cpp
340
  void emit();
341
  ```
342
 
343
+ *Effects:* Behaves as an unformatted output
344
+ function [[ostream.unformatted]]. After constructing a `sentry` object,
345
+ calls `sb.emit()`. If that call returns `false`, calls
346
  `setstate(ios_base::badbit)`.
347
 
348
  [*Example 1*:
349
 
350
  A flush on a `basic_osyncstream` does not flush immediately: