Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7571786

Browse files
committed
[ostream.manip] Introduce SYNCBUF to detect basic_syncbuf
This attempts to address the problem of `Allocator` being mentioned in the function descriptions without being defined. We cannot say that > `os.rdbuf()` is a `basic_syncbuf<charT, traits, Allocator>*` because firstly, that type is not defined, and secondly `os.rdbuf()` is a `basic_streambuf<charT, traits>*` and not any other type. By introducing SYNCBUF we can define the manipulators properly, by talking about a base class subobject rather than "is a". This introduces an apparently normative change that the syncbuf type must not use a program-defined specialization. Without that additional restriction the implementation suggested by the note doesn't work, because program-defined specializations cannot derive from the intermediate base class, and therefore cannot be detected by SYNCBUF.
1 parent 36c6132 commit 7571786

1 file changed

Lines changed: 24 additions & 18 deletions

File tree

source/iostreams.tex

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6771,6 +6771,24 @@
67716771
specified in this subclause
67726772
is a designated addressable function\iref{namespace.std}.
67736773

6774+
\pnum
6775+
In this subclause,
6776+
\exposid{SYNCBUF}\tcode{(p)} for a pointer \tcode{p} of type \tcode{B*}
6777+
is determined as follows.
6778+
If \tcode{*p} is a base class subobject of an object of type \tcode{S},
6779+
where \tcode{S} is a specialization generated from
6780+
the \tcode{basic_syncbuf} primary template,
6781+
and \tcode{is_convertible_v<S*, B*>} is \tcode{true},
6782+
then \exposid{SYNCBUF}\tcode{(p)} is \tcode{dynamic_cast<S*>(p)}.
6783+
Otherwise, \exposid{SYNCBUF}\tcode{(p)} is \tcode{static_cast<void*>(nullptr)}.
6784+
6785+
\begin{note}
6786+
To work around the issue that the
6787+
\tcode{Allocator} template argument of \tcode{S} cannot be deduced,
6788+
implementations can introduce an intermediate base class
6789+
to \tcode{basic_syncbuf} that manages its \tcode{emit_on_sync} flag.
6790+
\end{note}
6791+
67746792
\indexlibraryglobal{endl}%
67756793
\begin{itemdecl}
67766794
template<class charT, class traits>
@@ -6834,17 +6852,9 @@
68346852
\begin{itemdescr}
68356853
\pnum
68366854
\effects
6837-
If \tcode{os.rdbuf()} is a
6838-
\tcode{basic_syncbuf<charT, traits, Allocator>*},
6839-
called \tcode{buf} for the purpose of exposition,
6840-
calls \tcode{buf->set_emit_on_sync(true)}.
6855+
If \exposid{SYNCBUF}\tcode{(os.rdbuf())} is not null,
6856+
calls \exposid{SYNCBUF}\tcode{(os.rdbuf())->set_emit_on_sync(true)}.
68416857
Otherwise this manipulator has no effect.
6842-
\begin{note}
6843-
To work around the issue that the
6844-
\tcode{Allocator} template argument cannot be deduced,
6845-
implementations can introduce an intermediate base class
6846-
to \tcode{basic_syncbuf} that manages its \tcode{emit_on_sync} flag.
6847-
\end{note}
68486858

68496859
\pnum
68506860
\returns
@@ -6860,10 +6870,8 @@
68606870
\begin{itemdescr}
68616871
\pnum
68626872
\effects
6863-
If \tcode{os.rdbuf()} is a
6864-
\tcode{basic_syncbuf<charT, traits, Allocator>*},
6865-
called \tcode{buf} for the purpose of exposition,
6866-
calls \tcode{buf->set_emit_on_sync(false)}.
6873+
If \exposid{SYNCBUF}\tcode{(os.rdbuf())} is not null,
6874+
calls \exposid{SYNCBUF}\tcode{(os.rdbuf())->set_emit_on_sync(false)}.
68676875
Otherwise this manipulator has no effect.
68686876

68696877
\pnum
@@ -6881,10 +6889,8 @@
68816889
\pnum
68826890
\effects
68836891
Calls \tcode{os.flush()}.
6884-
Then, if \tcode{os.rdbuf()} is a
6885-
\tcode{basic_syncbuf<charT, traits, Allocator>*},
6886-
called \tcode{buf} for the purpose of exposition,
6887-
calls \tcode{buf->emit()}.
6892+
If \exposid{SYNCBUF}\tcode{(os.rdbuf())} is not null,
6893+
calls \exposid{SYNCBUF}\tcode{(os.rdbuf())->emit()}.
68886894

68896895
\pnum
68906896
\returns

0 commit comments

Comments
 (0)