Files
cppdraft_translate/cppdraft/syncstream.md
2025-10-25 03:02:53 +03:00

493 lines
21 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[syncstream]
# 31 Input/output library [[input.output]](./#input.output)
## 31.11 Synchronized output streams [syncstream]
### [31.11.1](#syn) Header <syncstream> synopsis [[syncstream.syn]](syncstream.syn)
[🔗](#header:%3csyncstream%3e)
#include <ostream> // see [[ostream.syn]](ostream.syn "31.7.2Header <ostream> synopsis")namespace std {// [[syncstream.syncbuf]](#syncbuf "31.11.2Class template basic_­syncbuf"), class template basic_syncbuftemplate<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>class basic_syncbuf; // [[syncstream.syncbuf.special]](#syncbuf.special "31.11.2.6Specialized algorithms"), specialized algorithmstemplate<class charT, class traits, class Allocator>void swap(basic_syncbuf<charT, traits, Allocator>&,
basic_syncbuf<charT, traits, Allocator>&); using syncbuf = basic_syncbuf<char>; using wsyncbuf = basic_syncbuf<wchar_t>; // [[syncstream.osyncstream]](#osyncstream "31.11.3Class template basic_­osyncstream"), class template basic_osyncstreamtemplate<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>class basic_osyncstream; using osyncstream = basic_osyncstream<char>; using wosyncstream = basic_osyncstream<wchar_t>;}
[1](#syn-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12596)
The header [<syncstream>](#header:%3csyncstream%3e "31.11.1Header <syncstream> synopsis[syncstream.syn]") provides a mechanism
to synchronize execution agents writing to the same stream[.](#syn-1.sentence-1)
### [31.11.2](#syncbuf) Class template basic_syncbuf [[syncstream.syncbuf]](syncstream.syncbuf)
#### [31.11.2.1](#syncbuf.overview) Overview [[syncstream.syncbuf.overview]](syncstream.syncbuf.overview)
[🔗](#lib:basic_syncbuf)
namespace std {template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>class basic_syncbuf : public basic_streambuf<charT, traits> {public:using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; using allocator_type = Allocator; using streambuf_type = basic_streambuf<charT, traits>; // [[syncstream.syncbuf.cons]](#syncbuf.cons "31.11.2.2Construction and destruction"), construction and destruction basic_syncbuf(): basic_syncbuf(nullptr) {}explicit basic_syncbuf(streambuf_type* obuf): basic_syncbuf(obuf, Allocator()) {} basic_syncbuf(streambuf_type*, const Allocator&);
basic_syncbuf(basic_syncbuf&&); ~basic_syncbuf(); // [[syncstream.syncbuf.assign]](#syncbuf.assign "31.11.2.3Assignment and swap"), assignment and swap basic_syncbuf& operator=(basic_syncbuf&&); void swap(basic_syncbuf&); // [[syncstream.syncbuf.members]](#syncbuf.members "31.11.2.4Member functions"), member functionsbool emit();
streambuf_type* get_wrapped() const noexcept;
allocator_type get_allocator() const noexcept; void set_emit_on_sync(bool) noexcept; protected:// [[syncstream.syncbuf.virtuals]](#syncbuf.virtuals "31.11.2.5Overridden virtual functions"), overridden virtual functionsint sync() override; private: streambuf_type* *wrapped*; // *exposition only*bool *emit-on-sync*{}; // *exposition only*};}
[1](#syncbuf.overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12649)
Class template basic_syncbuf stores character data
written to it, known as the associated output, into internal
buffers allocated using the object's allocator[.](#syncbuf.overview-1.sentence-1)
The associated output is transferred to the
wrapped stream buffer object **wrapped* when emit() is called
or when the basic_syncbuf object is destroyed[.](#syncbuf.overview-1.sentence-2)
Such transfers are atomic with respect to transfers
by other basic_syncbuf objects
with the same wrapped stream buffer object[.](#syncbuf.overview-1.sentence-3)
#### [31.11.2.2](#syncbuf.cons) Construction and destruction [[syncstream.syncbuf.cons]](syncstream.syncbuf.cons)
[🔗](#lib:basic_syncbuf,constructor)
`basic_syncbuf(streambuf_type* obuf, const Allocator& allocator);
`
[1](#syncbuf.cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12669)
*Effects*: Sets *wrapped* to obuf[.](#syncbuf.cons-1.sentence-1)
[2](#syncbuf.cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12673)
*Postconditions*: get_wrapped() == obuf andget_allocator() == allocator are true[.](#syncbuf.cons-2.sentence-1)
[3](#syncbuf.cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12678)
*Throws*: Nothing unless an exception is thrown
by the construction of a mutex or
by memory allocation[.](#syncbuf.cons-3.sentence-1)
[4](#syncbuf.cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12684)
*Remarks*: A copy of allocator is used
to allocate memory for internal buffers
holding the associated output[.](#syncbuf.cons-4.sentence-1)
[🔗](#lib:basic_syncbuf,constructor_)
`basic_syncbuf(basic_syncbuf&& other);
`
[5](#syncbuf.cons-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12697)
*Postconditions*: The value returned by this->get_wrapped() is the value returned by other.get_wrapped() prior to calling this constructor[.](#syncbuf.cons-5.sentence-1)
Output stored in other prior to calling this constructor
will be stored in *this afterwards[.](#syncbuf.cons-5.sentence-2)
other.pbase() == other.pptr() andother.get_wrapped() == nullptr are true[.](#syncbuf.cons-5.sentence-3)
[6](#syncbuf.cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12710)
*Remarks*: This constructor disassociates other from its wrapped stream buffer,
ensuring destruction of other produces no output[.](#syncbuf.cons-6.sentence-1)
[🔗](#lib:basic_syncbuf,destructor)
`~basic_syncbuf();
`
[7](#syncbuf.cons-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12723)
*Effects*: Calls emit()[.](#syncbuf.cons-7.sentence-1)
[8](#syncbuf.cons-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12727)
*Throws*: Nothing[.](#syncbuf.cons-8.sentence-1)
If an exception is thrown from emit(),
the destructor catches and ignores that exception[.](#syncbuf.cons-8.sentence-2)
#### [31.11.2.3](#syncbuf.assign) Assignment and swap [[syncstream.syncbuf.assign]](syncstream.syncbuf.assign)
[🔗](#lib:operator=,basic_syncbuf)
`basic_syncbuf& operator=(basic_syncbuf&& rhs);
`
[1](#syncbuf.assign-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12742)
*Effects*: Calls emit() then
move assigns from rhs[.](#syncbuf.assign-1.sentence-1)
After the move assignment *this has the observable state it would have had if
it had been move constructed from rhs ([[syncstream.syncbuf.cons]](#syncbuf.cons "31.11.2.2Construction and destruction"))[.](#syncbuf.assign-1.sentence-2)
[2](#syncbuf.assign-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12750)
*Postconditions*:
- [(2.1)](#syncbuf.assign-2.1)
rhs.get_wrapped() == nullptr is true.
- [(2.2)](#syncbuf.assign-2.2)
this->get_allocator() == rhs.get_allocator() is true whenallocator_traits<Allocator>::propagate_on_container_move_assignment::value is true; otherwise, the allocator is unchanged.
[3](#syncbuf.assign-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12763)
*Returns*: *this[.](#syncbuf.assign-3.sentence-1)
[4](#syncbuf.assign-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12767)
*Remarks*: This assignment operator disassociates rhs from its wrapped stream buffer,
ensuring destruction of rhs produces no output[.](#syncbuf.assign-4.sentence-1)
[🔗](#lib:swap,basic_syncbuf)
`void swap(basic_syncbuf& other);
`
[5](#syncbuf.assign-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12780)
*Preconditions*: Eitherallocator_traits<Allocator>::propagate_on_container_swap::value is true orthis->get_allocator() == other.get_allocator() is true[.](#syncbuf.assign-5.sentence-1)
[6](#syncbuf.assign-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12789)
*Effects*: Exchanges the state of *this and other[.](#syncbuf.assign-6.sentence-1)
#### [31.11.2.4](#syncbuf.members) Member functions [[syncstream.syncbuf.members]](syncstream.syncbuf.members)
[🔗](#lib:emit,basic_syncbuf)
`bool emit();
`
[1](#syncbuf.members-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12802)
*Effects*: Atomically transfers the associated output of *this to the stream buffer **wrapped*,
so that it appears in the output stream
as a contiguous sequence of characters[.](#syncbuf.members-1.sentence-1)
*wrapped*->pubsync() is called
if and only if a call was made to sync() since the most recent call to emit(), if any[.](#syncbuf.members-1.sentence-2)
[2](#syncbuf.members-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12812)
*Synchronization*: All emit() calls transferring characters
to the same stream buffer object
appear to execute in a total order
consistent with the “happens before” relation ([[intro.races]](intro.races "6.10.2.2Data races")),
where each emit() call
synchronizes with
subsequent emit() calls in that total order[.](#syncbuf.members-2.sentence-1)
[3](#syncbuf.members-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12822)
*Postconditions*: On success, the associated output is empty[.](#syncbuf.members-3.sentence-1)
[4](#syncbuf.members-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12826)
*Returns*: true if all of the following conditions hold;
otherwise false:
- [(4.1)](#syncbuf.members-4.1)
*wrapped* == nullptr is false[.](#syncbuf.members-4.1.sentence-1)
- [(4.2)](#syncbuf.members-4.2)
All of the characters in the associated output were successfully transferred[.](#syncbuf.members-4.2.sentence-1)
- [(4.3)](#syncbuf.members-4.3)
The call to *wrapped*->pubsync() (if any) succeeded[.](#syncbuf.members-4.3.sentence-1)
[5](#syncbuf.members-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12836)
*Remarks*: May call member functions of *wrapped* while holding a lock uniquely associated with *wrapped*[.](#syncbuf.members-5.sentence-1)
[🔗](#lib:get_wrapped,basic_syncbuf)
`streambuf_type* get_wrapped() const noexcept;
`
[6](#syncbuf.members-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12848)
*Returns*: *wrapped*[.](#syncbuf.members-6.sentence-1)
[🔗](#lib:get_allocator,basic_syncbuf)
`allocator_type get_allocator() const noexcept;
`
[7](#syncbuf.members-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12859)
*Returns*: A copy of the allocator that was set in the constructor or assignment operator[.](#syncbuf.members-7.sentence-1)
[🔗](#lib:set_emit_on_sync,basic_syncbuf)
`void set_emit_on_sync(bool b) noexcept;
`
[8](#syncbuf.members-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12870)
*Effects*: *emit-on-sync* = b[.](#syncbuf.members-8.sentence-1)
#### [31.11.2.5](#syncbuf.virtuals) Overridden virtual functions [[syncstream.syncbuf.virtuals]](syncstream.syncbuf.virtuals)
[🔗](#lib:sync,basic_syncbuf)
`int sync() override;
`
[1](#syncbuf.virtuals-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12883)
*Effects*: Records that the wrapped stream buffer is to be flushed[.](#syncbuf.virtuals-1.sentence-1)
Then, if *emit-on-sync* is true, calls emit()[.](#syncbuf.virtuals-1.sentence-2)
[*Note [1](#syncbuf.virtuals-note-1)*:
If *emit-on-sync* is false,
the actual flush is delayed until a call to emit()[.](#syncbuf.virtuals-1.sentence-3)
— *end note*]
[2](#syncbuf.virtuals-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12892)
*Returns*: If emit() was called and returned false,
returns -1; otherwise 0[.](#syncbuf.virtuals-2.sentence-1)
#### [31.11.2.6](#syncbuf.special) Specialized algorithms [[syncstream.syncbuf.special]](syncstream.syncbuf.special)
[🔗](#lib:swap,basic_syncbuf_)
`template<class charT, class traits, class Allocator>
void swap(basic_syncbuf<charT, traits, Allocator>& a,
basic_syncbuf<charT, traits, Allocator>& b);
`
[1](#syncbuf.special-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12908)
*Effects*: Equivalent to a.swap(b)[.](#syncbuf.special-1.sentence-1)
### [31.11.3](#osyncstream) Class template basic_osyncstream [[syncstream.osyncstream]](syncstream.osyncstream)
#### [31.11.3.1](#osyncstream.overview) Overview [[syncstream.osyncstream.overview]](syncstream.osyncstream.overview)
[🔗](#lib:basic_osyncstream)
namespace std {template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>class basic_osyncstream : public basic_ostream<charT, traits> {public:using char_type = charT; using int_type = typename traits::int_type; using pos_type = typename traits::pos_type; using off_type = typename traits::off_type; using traits_type = traits; using allocator_type = Allocator; using streambuf_type = basic_streambuf<charT, traits>; using syncbuf_type = basic_syncbuf<charT, traits, Allocator>; // [[syncstream.osyncstream.cons]](#osyncstream.cons "31.11.3.2Construction and destruction"), construction and destruction basic_osyncstream(streambuf_type*, const Allocator&); explicit basic_osyncstream(streambuf_type* obuf): basic_osyncstream(obuf, Allocator()) {} basic_osyncstream(basic_ostream<charT, traits>& os, const Allocator& allocator): basic_osyncstream(os.rdbuf(), allocator) {}explicit basic_osyncstream(basic_ostream<charT, traits>& os): basic_osyncstream(os, Allocator()) {} basic_osyncstream(basic_osyncstream&&) noexcept; ~basic_osyncstream(); // assignment basic_osyncstream& operator=(basic_osyncstream&&); // [[syncstream.osyncstream.members]](#osyncstream.members "31.11.3.3Member functions"), member functionsvoid emit();
streambuf_type* get_wrapped() const noexcept;
syncbuf_type* rdbuf() const noexcept { return const_cast<syncbuf_type*>(addressof(*sb*)); }private: syncbuf_type *sb*; // *exposition only*};}
[1](#osyncstream.overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12958)
Allocator shall meet
the [*Cpp17Allocator*](allocator.requirements.general#:Cpp17Allocator "16.4.4.6.1General[allocator.requirements.general]") requirements ([[allocator.requirements.general]](allocator.requirements.general "16.4.4.6.1General"))[.](#osyncstream.overview-1.sentence-1)
[2](#osyncstream.overview-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12962)
[*Example [1](#osyncstream.overview-example-1)*:
A named variable can be used within a block statement for streaming[.](#osyncstream.overview-2.sentence-1)
{ osyncstream bout(cout);
bout << "Hello, ";
bout << "World!";
bout << endl; // flush is noted bout << "and more!\n";} // characters are transferred and cout is flushed — *end example*]
[3](#osyncstream.overview-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12976)
[*Example [2](#osyncstream.overview-example-2)*:
A temporary object can be used for streaming within a single statement[.](#osyncstream.overview-3.sentence-1)
osyncstream(cout) << "Hello, " << "World!" << '\n';
In this example, cout is not flushed[.](#osyncstream.overview-3.sentence-2)
— *end example*]
#### [31.11.3.2](#osyncstream.cons) Construction and destruction [[syncstream.osyncstream.cons]](syncstream.osyncstream.cons)
[🔗](#lib:basic_osyncstream,constructor)
`basic_osyncstream(streambuf_type* buf, const Allocator& allocator);
`
[1](#osyncstream.cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12993)
*Effects*: Initializes *sb* from buf and allocator[.](#osyncstream.cons-1.sentence-1)
Initializes the base class with basic_ostream<charT, traits>(addressof(*sb*))[.](#osyncstream.cons-1.sentence-2)
[2](#osyncstream.cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12998)
[*Note [1](#osyncstream.cons-note-1)*:
The member functions of the provided stream buffer
can be called from emit() while a lock is held,
which might result in a deadlock if used incautiously[.](#osyncstream.cons-2.sentence-1)
— *end note*]
[3](#osyncstream.cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13005)
*Postconditions*: get_wrapped() == buf is true[.](#osyncstream.cons-3.sentence-1)
[🔗](#lib:basic_osyncstream,constructor_)
`basic_osyncstream(basic_osyncstream&& other) noexcept;
`
[4](#osyncstream.cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13016)
*Effects*: Move constructs the base class
and *sb* from the corresponding subobjects of other,
and calls basic_ostream<charT, traits>::set_rdbuf(addressof(*sb*))[.](#osyncstream.cons-4.sentence-1)
[5](#osyncstream.cons-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13022)
*Postconditions*: The value returned by get_wrapped() is the value returned by other.get_wrapped() prior to calling this constructor[.](#osyncstream.cons-5.sentence-1)
nullptr == other.get_wrapped() is true[.](#osyncstream.cons-5.sentence-2)
#### [31.11.3.3](#osyncstream.members) Member functions [[syncstream.osyncstream.members]](syncstream.osyncstream.members)
[🔗](#lib:set_emit_on_sync,basic_osyncstream)
`void emit();
`
[1](#osyncstream.members-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13038)
*Effects*: Behaves as an unformatted output function ([[ostream.unformatted]](ostream.unformatted "31.7.6.4Unformatted output functions"))[.](#osyncstream.members-1.sentence-1)
After constructing a sentry object, calls *sb*.emit()[.](#osyncstream.members-1.sentence-2)
If that call returns false,
calls setstate(ios_base::badbit)[.](#osyncstream.members-1.sentence-3)
[2](#osyncstream.members-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13045)
[*Example [1](#osyncstream.members-example-1)*:
A flush on a basic_osyncstream does not flush immediately:{ osyncstream bout(cout);
bout << "Hello," << '\n'; // no flush bout.emit(); // characters transferred; cout not flushed bout << "World!" << endl; // flush noted; cout not flushed bout.emit(); // characters transferred; cout flushed bout << "Greetings." << '\n'; // no flush} // characters transferred; cout not flushed
— *end example*]
[3](#osyncstream.members-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13060)
[*Example [2](#osyncstream.members-example-2)*:
The function emit() can be used to
handle exceptions from operations on the underlying stream[.](#osyncstream.members-3.sentence-1)
{ osyncstream bout(cout);
bout << "Hello, " << "World!" << '\n'; try { bout.emit(); } catch (...) {// handle exception}} — *end example*]
[🔗](#lib:set_emit_on_sync,basic_osyncstream_)
`streambuf_type* get_wrapped() const noexcept;
`
[4](#osyncstream.members-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13084)
*Returns*: *sb*.get_wrapped()[.](#osyncstream.members-4.sentence-1)
[5](#osyncstream.members-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13088)
[*Example [3](#osyncstream.members-example-3)*:
Obtaining the wrapped stream buffer with get_wrapped() allows wrapping it again with an osyncstream[.](#osyncstream.members-5.sentence-1)
For example,{ osyncstream bout1(cout);
bout1 << "Hello, "; { osyncstream(bout1.get_wrapped()) << "Goodbye, " << "Planet!" << '\n'; } bout1 << "World!" << '\n';} produces the *uninterleaved* output
```
Goodbye, Planet!
Hello, World!
```
— *end example*]