libstdc++
syncstream
Go to the documentation of this file.
1
/
/
<
syncstream
>
-
*
-
C
+
+
-
*
-
2
3
/
/
Copyright
(
C
)
2020-2025
Free
Software
Foundation
,
Inc
.
4
/
/
5
/
/
This
file
is
part
of
the
GNU
ISO
C
+
+
Library
.
This
library
is
free
6
/
/
software
;
you
can
redistribute
it
and
/
or
modify
it
under
the
7
/
/
terms
of
the
GNU
General
Public
License
as
published
by
the
8
/
/
Free
Software
Foundation
;
either
version
3
,
or
(
at
your
option
)
9
/
/
any
later
version
.
10
11
/
/
This
library
is
distributed
in
the
hope
that
it
will
be
useful
,
12
/
/
but
WITHOUT
ANY
WARRANTY
;
without
even
the
implied
warranty
of
13
/
/
MERCHANTABILITY
or
FITNESS
FOR
A
PARTICULAR
PURPOSE
.
See
the
14
/
/
GNU
General
Public
License
for
more
details
.
15
16
/
/
Under
Section
7
of
GPL
version
3
,
you
are
granted
additional
17
/
/
permissions
described
in
the
GCC
Runtime
Library
Exception
,
version
18
/
/
3
.
1
,
as
published
by
the
Free
Software
Foundation
.
19
20
/
/
You
should
have
received
a
copy
of
the
GNU
General
Public
License
and
21
/
/
a
copy
of
the
GCC
Runtime
Library
Exception
along
with
this
program
;
22
/
/
see
the
files
COPYING3
and
COPYING
.
RUNTIME
respectively
.
If
not
,
see
23
/
/
<
http
:
/
/
www
.
gnu
.
org
/
licenses
/
>
.
24
25
/
*
*
@
file
include
/
syncstream
26
*
This
is
a
Standard
C
+
+
Library
header
.
27
*
/
28
29
#ifndef _GLIBCXX_SYNCSTREAM
30
#define _GLIBCXX_SYNCSTREAM 1
31
32
#ifdef _GLIBCXX_SYSHDR
33
#pragma GCC system_header
34
#endif
35
36
#include <bits/requires_hosted.h> // iostreams
37
38
#include <bits/c++config.h>
39
40
#define __glibcxx_want_syncbuf
41
#include <bits/version.h>
42
43
#ifdef __cpp_lib_syncbuf // C++ >= 20 && HOSTED && CXX11ABI
44
#include <sstream>
45
46
#include <bits/alloc_traits.h>
47
#include <bits/allocator.h>
48
#include <bits/functexcept.h>
49
#include <bits/std_mutex.h>
50
51
namespace
std
_GLIBCXX_VISIBILITY
(
default
)
52
{
53
_GLIBCXX_BEGIN_NAMESPACE_VERSION
54
55
template
<
typename
_CharT
,
typename
_Traits
,
typename
_Alloc
>
56
class
basic_syncbuf
:
public
__syncbuf_base
<
_CharT
,
_Traits
>
57
{
58
public
:
59
using
char_type
=
_CharT
;
60
using
int_type
=
typename
_Traits
:
:
int_type
;
61
using
pos_type
=
typename
_Traits
:
:
pos_type
;
62
using
off_type
=
typename
_Traits
:
:
off_type
;
63
using
traits_type
=
_Traits
;
64
using
allocator_type
=
_Alloc
;
65
using
streambuf_type
=
basic_streambuf
<
_CharT
,
_Traits
>
;
66
67
basic_syncbuf
(
)
68
:
basic_syncbuf
(
nullptr
,
allocator_type
{}
)
69
{ }
70
71
explicit
72
basic_syncbuf
(
streambuf_type
*
__obuf
)
73
:
basic_syncbuf
(
__obuf
,
allocator_type
{}
)
74
{ }
75
76
basic_syncbuf
(
streambuf_type
*
__obuf
,
const
allocator_type
&
__alloc
)
77
:
__syncbuf_base
<
_CharT
,
_Traits
>
(
__obuf
)
78
,
_M_impl
(
__alloc
)
79
,
_M_mtx
(
__obuf
)
80
{ }
81
82
basic_syncbuf
(
basic_syncbuf
&&
__other
)
83
:
__syncbuf_base
<
_CharT
,
_Traits
>
(
__other
.
_M_wrapped
)
84
,
_M_impl
(
std
:
:
move
(
__other
.
_M_impl
)
)
85
,
_M_mtx
(
std
:
:
move
(
__other
.
_M_mtx
)
)
86
{
87
this
-
>
_M_emit_on_sync
=
__other
.
_M_emit_on_sync
;
88
this
-
>
_M_needs_sync
=
__other
.
_M_needs_sync
;
89
__other
.
_M_wrapped
=
nullptr
;
90
}
91
92
~
basic_syncbuf
(
)
93
{
94
__try
95
{
96
emit
(
)
;
97
}
98
__catch
(
.
.
.
)
99
{ }
100
}
101
102
basic_syncbuf
&
103
operator
=
(
basic_syncbuf
&&
__other
)
104
{
105
emit
(
)
;
106
107
_M_impl
=
std
:
:
move
(
__other
.
_M_impl
)
;
108
this
-
>
_M_emit_on_sync
=
__other
.
_M_emit_on_sync
;
109
this
-
>
_M_needs_sync
=
__other
.
_M_needs_sync
;
110
this
-
>
_M_wrapped
=
__other
.
_M_wrapped
;
111
__other
.
_M_wrapped
=
nullptr
;
112
_M_mtx
=
std
:
:
move
(
__other
.
_M_mtx
)
;
113
114
return
*
this
;
115
}
116
117
void
118
swap
(
basic_syncbuf
&
__other
)
119
{
120
using
_ATr
=
allocator_traits
<
_Alloc
>
;
121
if
constexpr
(
!
_ATr
:
:
propagate_on_container_swap
:
:
value
)
122
__glibcxx_assert
(
get_allocator
(
)
==
__other
.
get_allocator
(
)
)
;
123
124
std
:
:
swap
(
_M_impl
,
__other
.
_M_impl
)
;
125
std
:
:
swap
(
this
-
>
_M_emit_on_sync
,
__other
.
_M_emit_on_sync
)
;
126
std
:
:
swap
(
this
-
>
_M_needs_sync
,
__other
.
_M_needs_sync
)
;
127
std
:
:
swap
(
this
-
>
_M_wrapped
,
__other
.
_M_wrapped
)
;
128
std
:
:
swap
(
_M_mtx
,
__other
.
_M_mtx
)
;
129
}
130
131
bool
132
emit
(
)
133
{
134
if
(
!
this
-
>
_M_wrapped
)
135
return
false
;
136
137
auto
__s
=
std
:
:
move
(
_M_impl
)
.
str
(
)
;
138
139
const
lock_guard
<
__mutex
>
__l
(
_M_mtx
)
;
140
if
(
auto
__size
=
__s
.
size
(
)
)
141
{
142
auto
__n
=
this
-
>
_M_wrapped
-
>
sputn
(
__s
.
data
(
)
,
__size
)
;
143
if
(
__n
!=
__size
)
144
{
145
__s
.
erase
(
0
,
__n
)
;
146
_M_impl
.
str
(
std
:
:
move
(
__s
)
)
;
147
return
false
;
148
}
149
}
150
151
if
(
this
-
>
_M_needs_sync
)
152
{
153
this
-
>
_M_needs_sync
=
false
;
154
if
(
this
-
>
_M_wrapped
-
>
pubsync
(
)
!=
0
)
155
return
false
;
156
}
157
return
true
;
158
}
159
160
streambuf_type
*
161
get_wrapped
(
)
const
noexcept
162
{
return
this
-
>
_M_wrapped
; }
163
164
allocator_type
165
get_allocator
(
)
const
noexcept
166
{
return
_M_impl
.
get_allocator
(
)
; }
167
168
void
169
set_emit_on_sync(bool __b) noexcept
170
{
this
-
>
_M_emit_on_sync
=
__b
; }
171
172
protected
:
173
int
174
sync
(
)
override
175
{
176
this
-
>
_M_needs_sync
=
true
;
177
if
(
this
-
>
_M_emit_on_sync
&&
!
emit
(
)
)
178
return
-
1
;
179
return
0
;
180
}
181
182
int_type
183
overflow
(
int_type
__c
)
override
184
{
185
int_type
__eof
=
traits_type
:
:
eof
(
)
;
186
if
(
__builtin_expect
(
!
traits_type
:
:
eq_int_type
(
__c
,
__eof
)
,
true
)
)
187
return
_M_impl
.
sputc
(
__c
)
;
188
return
__eof
;
189
}
190
191
streamsize
192
xsputn
(
const
char_type
*
__s
,
streamsize
__n
)
override
193
{
return
_M_impl
.
sputn
(
__s
,
__n
)
; }
194
195
private
:
196
basic_stringbuf
<
char_type
,
traits_type
,
allocator_type
>
_M_impl
;
197
198
struct
__mutex
199
{
200
#if _GLIBCXX_HAS_GTHREADS
201
mutex
*
_M_mtx
=
nullptr
;
202
203
__mutex
(
void
*
__t
)
/
/
__t
is
the
underlying
sbuf
,
as
hash
seed
.
204
{
205
extern
mutex
&
__syncbuf_get_mutex
(
void
*
)
;
/
/
in
src
/
c
+
+
20
/
syncbuf
.
cc
206
if
(
__t
)
_M_mtx
=
&
__syncbuf_get_mutex
(
__t
)
;
207
}
208
209
void
210
swap
(
__mutex
&
__other
)
noexcept
211
{
std
:
:
swap
(
_M_mtx
,
__other
.
_M_mtx
)
; }
212
213
void
214
lock
(
)
215
{
216
_M_mtx
-
>
lock
(
)
;
217
}
218
219
void
220
unlock
(
)
221
{
222
_M_mtx
-
>
unlock
(
)
;
223
}
224
#else
225
__mutex
(
void
*
)
{ }
226
void
swap
(
__mutex
&&
)
noexcept
{ }
227
void
lock
(
)
{ }
228
void
unlock
(
)
{ }
229
#endif
230
__mutex
(
__mutex
&&
)
=
default
;
231
__mutex
&
operator
=
(
__mutex
&&
)
=
default
;
232
};
233
__mutex
_M_mtx
;
234
};
235
236
template
<
typename
_CharT
,
typename
_Traits
,
typename
_Alloc
>
237
class
basic_osyncstream
:
public
basic_ostream
<
_CharT
,
_Traits
>
238
{
239
using
__ostream_type
=
basic_ostream
<
_CharT
,
_Traits
>
;
240
241
public
:
242
/
/
Types
:
243
using
char_type
=
_CharT
;
244
using
traits_type
=
_Traits
;
245
using
allocator_type
=
_Alloc
;
246
using
int_type
=
typename
traits_type
:
:
int_type
;
247
using
pos_type
=
typename
traits_type
:
:
pos_type
;
248
using
off_type
=
typename
traits_type
:
:
off_type
;
249
using
syncbuf_type
=
basic_syncbuf
<
_CharT
,
_Traits
,
_Alloc
>
;
250
using
streambuf_type
=
typename
syncbuf_type
:
:
streambuf_type
;
251
252
private
:
253
syncbuf_type
_M_syncbuf
;
254
255
public
:
256
basic_osyncstream
(
streambuf_type
*
__buf
,
const
allocator_type
&
__a
)
257
:
_M_syncbuf
(
__buf
,
__a
)
258
{
this
-
>
init
(
std
:
:
__addressof
(
_M_syncbuf
)
)
; }
259
260
explicit
basic_osyncstream
(
streambuf_type
*
__buf
)
261
:
_M_syncbuf
(
__buf
)
262
{
this
-
>
init
(
std
:
:
__addressof
(
_M_syncbuf
)
)
; }
263
264
basic_osyncstream
(
basic_ostream
<
char_type
,
traits_type
>
&
__os
,
265
const
allocator_type
&
__a
)
266
:
basic_osyncstream
(
__os
.
rdbuf
(
)
,
__a
)
267
{
this
-
>
init
(
std
:
:
__addressof
(
_M_syncbuf
)
)
; }
268
269
explicit
basic_osyncstream
(
basic_ostream
<
char_type
,
traits_type
>
&
__os
)
270
:
basic_osyncstream
(
__os
.
rdbuf
(
)
)
271
{
this
-
>
init
(
std
:
:
__addressof
(
_M_syncbuf
)
)
; }
272
273
basic_osyncstream
(
basic_osyncstream
&&
__rhs
)
noexcept
274
:
__ostream_type
(
std
:
:
move
(
__rhs
)
)
,
275
_M_syncbuf
(
std
:
:
move
(
__rhs
.
_M_syncbuf
)
)
276
{
__ostream_type
:
:
set_rdbuf
(
std
:
:
__addressof
(
_M_syncbuf
)
)
; }
277
278
~
basic_osyncstream
(
)
=
default
;
279
280
basic_osyncstream
&
operator
=
(
basic_osyncstream
&&
)
=
default
;
281
282
syncbuf_type
*
rdbuf
(
)
const
noexcept
283
{
return
const_cast
<
syncbuf_type
*
>
(
&
_M_syncbuf
)
; }
284
285
streambuf_type
*
get_wrapped
(
)
const
noexcept
286
{
return
_M_syncbuf
.
get_wrapped
(
)
; }
287
288
void
emit
(
)
289
{
290
if
(
!
_M_syncbuf
.
emit
(
)
)
291
this
-
>
setstate
(
ios_base
:
:
failbit
)
;
292
}
293
};
294
295
template
<
class
_CharT
,
class
_Traits
,
class
_Allocator
>
296
inline
void
297
swap
(
basic_syncbuf
<
_CharT
,
_Traits
,
_Allocator
>
&
__x
,
298
basic_syncbuf
<
_CharT
,
_Traits
,
_Allocator
>
&
__y
)
noexcept
299
{
__x
.
swap
(
__y
)
; }
300
301
using
syncbuf
=
basic_syncbuf
<
char
>
;
302
using
wsyncbuf
=
basic_syncbuf
<
wchar_t
>
;
303
304
using
osyncstream
=
basic_osyncstream
<
char
>
;
305
using
wosyncstream
=
basic_osyncstream
<
wchar_t
>
;
306
_GLIBCXX_END_NAMESPACE_VERSION
307
}
/
/
namespace
std
308
#endif // __cpp_lib_syncbuf
309
310
#endif /* _GLIBCXX_SYNCSTREAM */
syncstream
Generated by
1.13.2