1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
19 #include "include/config_elast.h"
22 #include <__undef_macros>
24 _LIBCPP_BEGIN_NAMESPACE_STD
26 class _LIBCPP_HIDDEN __iostream_category
: public __do_message
{
28 virtual const char* name() const noexcept
;
29 virtual string
message(int ev
) const;
32 const char* __iostream_category::name() const noexcept
{ return "iostream"; }
34 string
__iostream_category::message(int ev
) const {
35 if (ev
!= static_cast<int>(io_errc::stream
)
37 && ev
<= _LIBCPP_ELAST
38 #endif // _LIBCPP_ELAST
40 return __do_message::message(ev
);
41 return string("unspecified iostream_category error");
44 const error_category
& iostream_category() noexcept
{
45 union AvoidDestroyingIostreamCategory
{
46 __iostream_category iostream_error_category
;
47 constexpr explicit AvoidDestroyingIostreamCategory() : iostream_error_category() {}
48 ~AvoidDestroyingIostreamCategory() {}
50 constinit
static AvoidDestroyingIostreamCategory helper
;
51 return helper
.iostream_error_category
;
56 ios_base::failure::failure(const string
& msg
, const error_code
& ec
) : system_error(ec
, msg
) {}
58 ios_base::failure::failure(const char* msg
, const error_code
& ec
) : system_error(ec
, msg
) {}
60 ios_base::failure::~failure() throw() {}
64 const ios_base::fmtflags
ios_base::boolalpha
;
65 const ios_base::fmtflags
ios_base::dec
;
66 const ios_base::fmtflags
ios_base::fixed
;
67 const ios_base::fmtflags
ios_base::hex
;
68 const ios_base::fmtflags
ios_base::internal
;
69 const ios_base::fmtflags
ios_base::left
;
70 const ios_base::fmtflags
ios_base::oct
;
71 const ios_base::fmtflags
ios_base::right
;
72 const ios_base::fmtflags
ios_base::scientific
;
73 const ios_base::fmtflags
ios_base::showbase
;
74 const ios_base::fmtflags
ios_base::showpoint
;
75 const ios_base::fmtflags
ios_base::showpos
;
76 const ios_base::fmtflags
ios_base::skipws
;
77 const ios_base::fmtflags
ios_base::unitbuf
;
78 const ios_base::fmtflags
ios_base::uppercase
;
79 const ios_base::fmtflags
ios_base::adjustfield
;
80 const ios_base::fmtflags
ios_base::basefield
;
81 const ios_base::fmtflags
ios_base::floatfield
;
83 const ios_base::iostate
ios_base::badbit
;
84 const ios_base::iostate
ios_base::eofbit
;
85 const ios_base::iostate
ios_base::failbit
;
86 const ios_base::iostate
ios_base::goodbit
;
88 const ios_base::openmode
ios_base::app
;
89 const ios_base::openmode
ios_base::ate
;
90 const ios_base::openmode
ios_base::binary
;
91 const ios_base::openmode
ios_base::in
;
92 const ios_base::openmode
ios_base::out
;
93 const ios_base::openmode
ios_base::trunc
;
95 void ios_base::__call_callbacks(event ev
) {
96 for (size_t i
= __event_size_
; i
;) {
98 __fn_
[i
](ev
, *this, __index_
[i
]);
104 locale
ios_base::imbue(const locale
& newloc
) {
105 static_assert(sizeof(locale
) == sizeof(__loc_
), "");
106 locale
& loc_storage
= *reinterpret_cast<locale
*>(&__loc_
);
107 locale oldloc
= loc_storage
;
108 loc_storage
= newloc
;
109 __call_callbacks(imbue_event
);
113 locale
ios_base::getloc() const {
114 const locale
& loc_storage
= *reinterpret_cast<const locale
*>(&__loc_
);
119 #if _LIBCPP_HAS_C_ATOMIC_IMP && _LIBCPP_HAS_THREADS
120 atomic
<int> ios_base::__xindex_
{0};
122 int ios_base::__xindex_
= 0;
125 template <typename _Tp
>
126 static size_t __ios_new_cap(size_t __req_size
, size_t __current_cap
) { // Precondition: __req_size > __current_cap
127 const size_t mx
= std::numeric_limits
<size_t>::max() / sizeof(_Tp
);
128 if (__req_size
< mx
/ 2)
129 return std::max(2 * __current_cap
, __req_size
);
134 int ios_base::xalloc() { return __xindex_
++; }
136 long& ios_base::iword(int index
) {
137 size_t req_size
= static_cast<size_t>(index
) + 1;
138 if (req_size
> __iarray_cap_
) {
139 size_t newcap
= __ios_new_cap
<long>(req_size
, __iarray_cap_
);
140 long* iarray
= static_cast<long*>(realloc(__iarray_
, newcap
* sizeof(long)));
148 for (long* p
= __iarray_
+ __iarray_size_
; p
< __iarray_
+ newcap
; ++p
)
150 __iarray_cap_
= newcap
;
152 __iarray_size_
= max
<size_t>(__iarray_size_
, req_size
);
153 return __iarray_
[index
];
156 void*& ios_base::pword(int index
) {
157 size_t req_size
= static_cast<size_t>(index
) + 1;
158 if (req_size
> __parray_cap_
) {
159 size_t newcap
= __ios_new_cap
<void*>(req_size
, __iarray_cap_
);
160 void** parray
= static_cast<void**>(realloc(__parray_
, newcap
* sizeof(void*)));
168 for (void** p
= __parray_
+ __parray_size_
; p
< __parray_
+ newcap
; ++p
)
170 __parray_cap_
= newcap
;
172 __parray_size_
= max
<size_t>(__parray_size_
, req_size
);
173 return __parray_
[index
];
178 void ios_base::register_callback(event_callback fn
, int index
) {
179 size_t req_size
= __event_size_
+ 1;
180 if (req_size
> __event_cap_
) {
181 size_t newcap
= __ios_new_cap
<event_callback
>(req_size
, __event_cap_
);
182 event_callback
* fns
= static_cast<event_callback
*>(realloc(__fn_
, newcap
* sizeof(event_callback
)));
186 int* indxs
= static_cast<int*>(realloc(__index_
, newcap
* sizeof(int)));
190 __event_cap_
= newcap
;
192 __fn_
[__event_size_
] = fn
;
193 __index_
[__event_size_
] = index
;
197 ios_base::~ios_base() {
198 // Avoid UB when not properly initialized. See ios_base::ios_base for
202 __call_callbacks(erase_event
);
203 locale
& loc_storage
= *reinterpret_cast<locale
*>(&__loc_
);
204 loc_storage
.~locale();
213 void ios_base::clear(iostate state
) {
217 __rdstate_
= state
| badbit
;
219 if (((state
| (__rdbuf_
? goodbit
: badbit
)) & __exceptions_
) != 0)
220 __throw_failure("ios_base::clear");
225 void ios_base::init(void* sb
) {
227 __rdstate_
= __rdbuf_
? goodbit
: badbit
;
228 __exceptions_
= goodbit
;
229 __fmtflags_
= skipws
| dec
;
242 ::new (&__loc_
) locale
;
245 void ios_base::copyfmt(const ios_base
& rhs
) {
246 // If we can't acquire the needed resources, throw bad_alloc (can't set badbit)
247 // Don't alter *this until all needed resources are acquired
248 unique_ptr
<event_callback
, void (*)(void*)> new_callbacks(0, free
);
249 unique_ptr
<int, void (*)(void*)> new_ints(0, free
);
250 unique_ptr
<long, void (*)(void*)> new_longs(0, free
);
251 unique_ptr
<void*, void (*)(void*)> new_pointers(0, free
);
252 if (__event_cap_
< rhs
.__event_size_
) {
253 size_t newesize
= sizeof(event_callback
) * rhs
.__event_size_
;
254 new_callbacks
.reset(static_cast<event_callback
*>(malloc(newesize
)));
258 size_t newisize
= sizeof(int) * rhs
.__event_size_
;
259 new_ints
.reset(static_cast<int*>(malloc(newisize
)));
263 if (__iarray_cap_
< rhs
.__iarray_size_
) {
264 size_t newsize
= sizeof(long) * rhs
.__iarray_size_
;
265 new_longs
.reset(static_cast<long*>(malloc(newsize
)));
269 if (__parray_cap_
< rhs
.__parray_size_
) {
270 size_t newsize
= sizeof(void*) * rhs
.__parray_size_
;
271 new_pointers
.reset(static_cast<void**>(malloc(newsize
)));
275 // Got everything we need. Copy everything but __rdstate_, __rdbuf_ and __exceptions_
276 __fmtflags_
= rhs
.__fmtflags_
;
277 __precision_
= rhs
.__precision_
;
278 __width_
= rhs
.__width_
;
279 locale
& lhs_loc
= *reinterpret_cast<locale
*>(&__loc_
);
280 const locale
& rhs_loc
= *reinterpret_cast<const locale
*>(&rhs
.__loc_
);
282 if (__event_cap_
< rhs
.__event_size_
) {
284 __fn_
= new_callbacks
.release();
286 __index_
= new_ints
.release();
287 __event_cap_
= rhs
.__event_size_
;
289 for (__event_size_
= 0; __event_size_
< rhs
.__event_size_
; ++__event_size_
) {
290 __fn_
[__event_size_
] = rhs
.__fn_
[__event_size_
];
291 __index_
[__event_size_
] = rhs
.__index_
[__event_size_
];
293 if (__iarray_cap_
< rhs
.__iarray_size_
) {
295 __iarray_
= new_longs
.release();
296 __iarray_cap_
= rhs
.__iarray_size_
;
298 for (__iarray_size_
= 0; __iarray_size_
< rhs
.__iarray_size_
; ++__iarray_size_
)
299 __iarray_
[__iarray_size_
] = rhs
.__iarray_
[__iarray_size_
];
300 if (__parray_cap_
< rhs
.__parray_size_
) {
302 __parray_
= new_pointers
.release();
303 __parray_cap_
= rhs
.__parray_size_
;
305 for (__parray_size_
= 0; __parray_size_
< rhs
.__parray_size_
; ++__parray_size_
)
306 __parray_
[__parray_size_
] = rhs
.__parray_
[__parray_size_
];
309 void ios_base::move(ios_base
& rhs
) {
310 // *this is uninitialized
311 __fmtflags_
= rhs
.__fmtflags_
;
312 __precision_
= rhs
.__precision_
;
313 __width_
= rhs
.__width_
;
314 __rdstate_
= rhs
.__rdstate_
;
315 __exceptions_
= rhs
.__exceptions_
;
317 locale
& rhs_loc
= *reinterpret_cast<locale
*>(&rhs
.__loc_
);
318 ::new (&__loc_
) locale(rhs_loc
);
321 __index_
= rhs
.__index_
;
323 __event_size_
= rhs
.__event_size_
;
324 rhs
.__event_size_
= 0;
325 __event_cap_
= rhs
.__event_cap_
;
326 rhs
.__event_cap_
= 0;
327 __iarray_
= rhs
.__iarray_
;
329 __iarray_size_
= rhs
.__iarray_size_
;
330 rhs
.__iarray_size_
= 0;
331 __iarray_cap_
= rhs
.__iarray_cap_
;
332 rhs
.__iarray_cap_
= 0;
333 __parray_
= rhs
.__parray_
;
335 __parray_size_
= rhs
.__parray_size_
;
336 rhs
.__parray_size_
= 0;
337 __parray_cap_
= rhs
.__parray_cap_
;
338 rhs
.__parray_cap_
= 0;
341 void ios_base::swap(ios_base
& rhs
) noexcept
{
342 std::swap(__fmtflags_
, rhs
.__fmtflags_
);
343 std::swap(__precision_
, rhs
.__precision_
);
344 std::swap(__width_
, rhs
.__width_
);
345 std::swap(__rdstate_
, rhs
.__rdstate_
);
346 std::swap(__exceptions_
, rhs
.__exceptions_
);
347 locale
& lhs_loc
= *reinterpret_cast<locale
*>(&__loc_
);
348 locale
& rhs_loc
= *reinterpret_cast<locale
*>(&rhs
.__loc_
);
349 std::swap(lhs_loc
, rhs_loc
);
350 std::swap(__fn_
, rhs
.__fn_
);
351 std::swap(__index_
, rhs
.__index_
);
352 std::swap(__event_size_
, rhs
.__event_size_
);
353 std::swap(__event_cap_
, rhs
.__event_cap_
);
354 std::swap(__iarray_
, rhs
.__iarray_
);
355 std::swap(__iarray_size_
, rhs
.__iarray_size_
);
356 std::swap(__iarray_cap_
, rhs
.__iarray_cap_
);
357 std::swap(__parray_
, rhs
.__parray_
);
358 std::swap(__parray_size_
, rhs
.__parray_size_
);
359 std::swap(__parray_cap_
, rhs
.__parray_cap_
);
362 void ios_base::__set_badbit_and_consider_rethrow() {
363 __rdstate_
|= badbit
;
364 #if _LIBCPP_HAS_EXCEPTIONS
365 if (__exceptions_
& badbit
)
367 #endif // _LIBCPP_HAS_EXCEPTIONS
370 void ios_base::__set_failbit_and_consider_rethrow() {
371 __rdstate_
|= failbit
;
372 #if _LIBCPP_HAS_EXCEPTIONS
373 if (__exceptions_
& failbit
)
375 #endif // _LIBCPP_HAS_EXCEPTIONS
378 bool ios_base::sync_with_stdio(bool sync
) {
379 static bool previous_state
= true;
380 bool r
= previous_state
;
381 previous_state
= sync
;
385 _LIBCPP_END_NAMESPACE_STD