Files
2025-10-25 03:02:53 +03:00

175 lines
7.3 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.osyncstream]
# 31 Input/output library [[input.output]](./#input.output)
## 31.11 Synchronized output streams [[syncstream]](syncstream#osyncstream)
### 31.11.3 Class template basic_osyncstream [syncstream.osyncstream]
#### [31.11.3.1](#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]](#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]](#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](#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"))[.](#overview-1.sentence-1)
[2](#overview-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12962)
[*Example [1](#overview-example-1)*:
A named variable can be used within a block statement for streaming[.](#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](#overview-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12976)
[*Example [2](#overview-example-2)*:
A temporary object can be used for streaming within a single statement[.](#overview-3.sentence-1)
osyncstream(cout) << "Hello, " << "World!" << '\n';
In this example, cout is not flushed[.](#overview-3.sentence-2)
— *end example*]
#### [31.11.3.2](#cons) Construction and destruction [[syncstream.osyncstream.cons]](syncstream.osyncstream.cons)
[🔗](#lib:basic_osyncstream,constructor)
`basic_osyncstream(streambuf_type* buf, const Allocator& allocator);
`
[1](#cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12993)
*Effects*: Initializes *sb* from buf and allocator[.](#cons-1.sentence-1)
Initializes the base class with basic_ostream<charT, traits>(addressof(*sb*))[.](#cons-1.sentence-2)
[2](#cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L12998)
[*Note [1](#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[.](#cons-2.sentence-1)
— *end note*]
[3](#cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13005)
*Postconditions*: get_wrapped() == buf is true[.](#cons-3.sentence-1)
[🔗](#lib:basic_osyncstream,constructor_)
`basic_osyncstream(basic_osyncstream&& other) noexcept;
`
[4](#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*))[.](#cons-4.sentence-1)
[5](#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[.](#cons-5.sentence-1)
nullptr == other.get_wrapped() is true[.](#cons-5.sentence-2)
#### [31.11.3.3](#members) Member functions [[syncstream.osyncstream.members]](syncstream.osyncstream.members)
[🔗](#lib:set_emit_on_sync,basic_osyncstream)
`void emit();
`
[1](#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"))[.](#members-1.sentence-1)
After constructing a sentry object, calls *sb*.emit()[.](#members-1.sentence-2)
If that call returns false,
calls setstate(ios_base::badbit)[.](#members-1.sentence-3)
[2](#members-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13045)
[*Example [1](#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](#members-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13060)
[*Example [2](#members-example-2)*:
The function emit() can be used to
handle exceptions from operations on the underlying stream[.](#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](#members-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13084)
*Returns*: *sb*.get_wrapped()[.](#members-4.sentence-1)
[5](#members-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/iostreams.tex#L13088)
[*Example [3](#members-example-3)*:
Obtaining the wrapped stream buffer with get_wrapped() allows wrapping it again with an 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*]