1 //===-------------------------- ios.cpp -----------------------------------===//
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 //===----------------------------------------------------------------------===//
17 #include "include/config_elast.h"
22 #include "__undef_macros"
24 _LIBCPP_BEGIN_NAMESPACE_STD
26 class _LIBCPP_HIDDEN __iostream_category
30 virtual const char* name() const _NOEXCEPT
;
31 virtual string
message(int ev
) const;
35 __iostream_category::name() const _NOEXCEPT
41 __iostream_category::message(int ev
) const
43 if (ev
!= static_cast<int>(io_errc::stream
)
45 && ev
<= _LIBCPP_ELAST
46 #endif // _LIBCPP_ELAST
48 return __do_message::message(ev
);
49 return string("unspecified iostream_category error");
53 iostream_category() _NOEXCEPT
55 static __iostream_category s
;
61 ios_base::failure::failure(const string
& msg
, const error_code
& ec
)
62 : system_error(ec
, msg
)
66 ios_base::failure::failure(const char* msg
, const error_code
& ec
)
67 : system_error(ec
, msg
)
71 ios_base::failure::~failure() throw()
77 const ios_base::fmtflags
ios_base::boolalpha
;
78 const ios_base::fmtflags
ios_base::dec
;
79 const ios_base::fmtflags
ios_base::fixed
;
80 const ios_base::fmtflags
ios_base::hex
;
81 const ios_base::fmtflags
ios_base::internal
;
82 const ios_base::fmtflags
ios_base::left
;
83 const ios_base::fmtflags
ios_base::oct
;
84 const ios_base::fmtflags
ios_base::right
;
85 const ios_base::fmtflags
ios_base::scientific
;
86 const ios_base::fmtflags
ios_base::showbase
;
87 const ios_base::fmtflags
ios_base::showpoint
;
88 const ios_base::fmtflags
ios_base::showpos
;
89 const ios_base::fmtflags
ios_base::skipws
;
90 const ios_base::fmtflags
ios_base::unitbuf
;
91 const ios_base::fmtflags
ios_base::uppercase
;
92 const ios_base::fmtflags
ios_base::adjustfield
;
93 const ios_base::fmtflags
ios_base::basefield
;
94 const ios_base::fmtflags
ios_base::floatfield
;
96 const ios_base::iostate
ios_base::badbit
;
97 const ios_base::iostate
ios_base::eofbit
;
98 const ios_base::iostate
ios_base::failbit
;
99 const ios_base::iostate
ios_base::goodbit
;
101 const ios_base::openmode
ios_base::app
;
102 const ios_base::openmode
ios_base::ate
;
103 const ios_base::openmode
ios_base::binary
;
104 const ios_base::openmode
ios_base::in
;
105 const ios_base::openmode
ios_base::out
;
106 const ios_base::openmode
ios_base::trunc
;
109 ios_base::__call_callbacks(event ev
)
111 for (size_t i
= __event_size_
; i
;)
114 __fn_
[i
](ev
, *this, __index_
[i
]);
121 ios_base::imbue(const locale
& newloc
)
123 static_assert(sizeof(locale
) == sizeof(__loc_
), "");
124 locale
& loc_storage
= *reinterpret_cast<locale
*>(&__loc_
);
125 locale oldloc
= loc_storage
;
126 loc_storage
= newloc
;
127 __call_callbacks(imbue_event
);
132 ios_base::getloc() const
134 const locale
& loc_storage
= *reinterpret_cast<const locale
*>(&__loc_
);
139 #if defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_NO_THREADS)
140 atomic
<int> ios_base::__xindex_
= ATOMIC_VAR_INIT(0);
142 int ios_base::__xindex_
= 0;
145 template <typename _Tp
>
146 static size_t __ios_new_cap(size_t __req_size
, size_t __current_cap
)
147 { // Precondition: __req_size > __current_cap
148 const size_t mx
= std::numeric_limits
<size_t>::max() / sizeof(_Tp
);
149 if (__req_size
< mx
/2)
150 return _VSTD::max(2 * __current_cap
, __req_size
);
162 ios_base::iword(int index
)
164 size_t req_size
= static_cast<size_t>(index
)+1;
165 if (req_size
> __iarray_cap_
)
167 size_t newcap
= __ios_new_cap
<long>(req_size
, __iarray_cap_
);
168 long* iarray
= static_cast<long*>(realloc(__iarray_
, newcap
* sizeof(long)));
177 for (long* p
= __iarray_
+ __iarray_size_
; p
< __iarray_
+ newcap
; ++p
)
179 __iarray_cap_
= newcap
;
181 __iarray_size_
= max
<size_t>(__iarray_size_
, req_size
);
182 return __iarray_
[index
];
186 ios_base::pword(int index
)
188 size_t req_size
= static_cast<size_t>(index
)+1;
189 if (req_size
> __parray_cap_
)
191 size_t newcap
= __ios_new_cap
<void *>(req_size
, __iarray_cap_
);
192 void** parray
= static_cast<void**>(realloc(__parray_
, newcap
* sizeof(void *)));
201 for (void** p
= __parray_
+ __parray_size_
; p
< __parray_
+ newcap
; ++p
)
203 __parray_cap_
= newcap
;
205 __parray_size_
= max
<size_t>(__parray_size_
, req_size
);
206 return __parray_
[index
];
212 ios_base::register_callback(event_callback fn
, int index
)
214 size_t req_size
= __event_size_
+ 1;
215 if (req_size
> __event_cap_
)
217 size_t newcap
= __ios_new_cap
<event_callback
>(req_size
, __event_cap_
);
218 event_callback
* fns
= static_cast<event_callback
*>(realloc(__fn_
, newcap
* sizeof(event_callback
)));
222 int* indxs
= static_cast<int *>(realloc(__index_
, newcap
* sizeof(int)));
226 __event_cap_
= newcap
;
228 __fn_
[__event_size_
] = fn
;
229 __index_
[__event_size_
] = index
;
233 ios_base::~ios_base()
235 __call_callbacks(erase_event
);
236 locale
& loc_storage
= *reinterpret_cast<locale
*>(&__loc_
);
237 loc_storage
.~locale();
247 ios_base::clear(iostate state
)
252 __rdstate_
= state
| badbit
;
254 if (((state
| (__rdbuf_
? goodbit
: badbit
)) & __exceptions_
) != 0)
255 __throw_failure("ios_base::clear");
261 ios_base::init(void* sb
)
264 __rdstate_
= __rdbuf_
? goodbit
: badbit
;
265 __exceptions_
= goodbit
;
266 __fmtflags_
= skipws
| dec
;
279 ::new(&__loc_
) locale
;
283 ios_base::copyfmt(const ios_base
& rhs
)
285 // If we can't acquire the needed resources, throw bad_alloc (can't set badbit)
286 // Don't alter *this until all needed resources are acquired
287 unique_ptr
<event_callback
, void (*)(void*)> new_callbacks(0, free
);
288 unique_ptr
<int, void (*)(void*)> new_ints(0, free
);
289 unique_ptr
<long, void (*)(void*)> new_longs(0, free
);
290 unique_ptr
<void*, void (*)(void*)> new_pointers(0, free
);
291 if (__event_cap_
< rhs
.__event_size_
)
293 size_t newesize
= sizeof(event_callback
) * rhs
.__event_size_
;
294 new_callbacks
.reset(static_cast<event_callback
*>(malloc(newesize
)));
298 size_t newisize
= sizeof(int) * rhs
.__event_size_
;
299 new_ints
.reset(static_cast<int *>(malloc(newisize
)));
303 if (__iarray_cap_
< rhs
.__iarray_size_
)
305 size_t newsize
= sizeof(long) * rhs
.__iarray_size_
;
306 new_longs
.reset(static_cast<long*>(malloc(newsize
)));
310 if (__parray_cap_
< rhs
.__parray_size_
)
312 size_t newsize
= sizeof(void*) * rhs
.__parray_size_
;
313 new_pointers
.reset(static_cast<void**>(malloc(newsize
)));
317 // Got everything we need. Copy everything but __rdstate_, __rdbuf_ and __exceptions_
318 __fmtflags_
= rhs
.__fmtflags_
;
319 __precision_
= rhs
.__precision_
;
320 __width_
= rhs
.__width_
;
321 locale
& lhs_loc
= *reinterpret_cast<locale
*>(&__loc_
);
322 const locale
& rhs_loc
= *reinterpret_cast<const locale
*>(&rhs
.__loc_
);
324 if (__event_cap_
< rhs
.__event_size_
)
327 __fn_
= new_callbacks
.release();
329 __index_
= new_ints
.release();
330 __event_cap_
= rhs
.__event_size_
;
332 for (__event_size_
= 0; __event_size_
< rhs
.__event_size_
; ++__event_size_
)
334 __fn_
[__event_size_
] = rhs
.__fn_
[__event_size_
];
335 __index_
[__event_size_
] = rhs
.__index_
[__event_size_
];
337 if (__iarray_cap_
< rhs
.__iarray_size_
)
340 __iarray_
= new_longs
.release();
341 __iarray_cap_
= rhs
.__iarray_size_
;
343 for (__iarray_size_
= 0; __iarray_size_
< rhs
.__iarray_size_
; ++__iarray_size_
)
344 __iarray_
[__iarray_size_
] = rhs
.__iarray_
[__iarray_size_
];
345 if (__parray_cap_
< rhs
.__parray_size_
)
348 __parray_
= new_pointers
.release();
349 __parray_cap_
= rhs
.__parray_size_
;
351 for (__parray_size_
= 0; __parray_size_
< rhs
.__parray_size_
; ++__parray_size_
)
352 __parray_
[__parray_size_
] = rhs
.__parray_
[__parray_size_
];
356 ios_base::move(ios_base
& rhs
)
358 // *this is uninitialized
359 __fmtflags_
= rhs
.__fmtflags_
;
360 __precision_
= rhs
.__precision_
;
361 __width_
= rhs
.__width_
;
362 __rdstate_
= rhs
.__rdstate_
;
363 __exceptions_
= rhs
.__exceptions_
;
365 locale
& rhs_loc
= *reinterpret_cast<locale
*>(&rhs
.__loc_
);
366 ::new(&__loc_
) locale(rhs_loc
);
369 __index_
= rhs
.__index_
;
371 __event_size_
= rhs
.__event_size_
;
372 rhs
.__event_size_
= 0;
373 __event_cap_
= rhs
.__event_cap_
;
374 rhs
.__event_cap_
= 0;
375 __iarray_
= rhs
.__iarray_
;
377 __iarray_size_
= rhs
.__iarray_size_
;
378 rhs
.__iarray_size_
= 0;
379 __iarray_cap_
= rhs
.__iarray_cap_
;
380 rhs
.__iarray_cap_
= 0;
381 __parray_
= rhs
.__parray_
;
383 __parray_size_
= rhs
.__parray_size_
;
384 rhs
.__parray_size_
= 0;
385 __parray_cap_
= rhs
.__parray_cap_
;
386 rhs
.__parray_cap_
= 0;
390 ios_base::swap(ios_base
& rhs
) _NOEXCEPT
392 _VSTD::swap(__fmtflags_
, rhs
.__fmtflags_
);
393 _VSTD::swap(__precision_
, rhs
.__precision_
);
394 _VSTD::swap(__width_
, rhs
.__width_
);
395 _VSTD::swap(__rdstate_
, rhs
.__rdstate_
);
396 _VSTD::swap(__exceptions_
, rhs
.__exceptions_
);
397 locale
& lhs_loc
= *reinterpret_cast<locale
*>(&__loc_
);
398 locale
& rhs_loc
= *reinterpret_cast<locale
*>(&rhs
.__loc_
);
399 _VSTD::swap(lhs_loc
, rhs_loc
);
400 _VSTD::swap(__fn_
, rhs
.__fn_
);
401 _VSTD::swap(__index_
, rhs
.__index_
);
402 _VSTD::swap(__event_size_
, rhs
.__event_size_
);
403 _VSTD::swap(__event_cap_
, rhs
.__event_cap_
);
404 _VSTD::swap(__iarray_
, rhs
.__iarray_
);
405 _VSTD::swap(__iarray_size_
, rhs
.__iarray_size_
);
406 _VSTD::swap(__iarray_cap_
, rhs
.__iarray_cap_
);
407 _VSTD::swap(__parray_
, rhs
.__parray_
);
408 _VSTD::swap(__parray_size_
, rhs
.__parray_size_
);
409 _VSTD::swap(__parray_cap_
, rhs
.__parray_cap_
);
413 ios_base::__set_badbit_and_consider_rethrow()
415 __rdstate_
|= badbit
;
416 #ifndef _LIBCPP_NO_EXCEPTIONS
417 if (__exceptions_
& badbit
)
419 #endif // _LIBCPP_NO_EXCEPTIONS
423 ios_base::__set_failbit_and_consider_rethrow()
425 __rdstate_
|= failbit
;
426 #ifndef _LIBCPP_NO_EXCEPTIONS
427 if (__exceptions_
& failbit
)
429 #endif // _LIBCPP_NO_EXCEPTIONS
433 ios_base::sync_with_stdio(bool sync
)
435 static bool previous_state
= true;
436 bool r
= previous_state
;
437 previous_state
= sync
;
441 _LIBCPP_END_NAMESPACE_STD