Path: blob/main/contrib/llvm-project/libcxx/src/iostream.cpp
35154 views
//===----------------------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "std_stream.h"9#include <__locale>10#include <new>11#include <string>1213#ifdef _LIBCPP_MSVCRT_LIKE14# include <__locale_dir/locale_base_api/locale_guard.h>15#endif1617#define _str(s) #s18#define str(s) _str(s)19#define _LIBCPP_ABI_NAMESPACE_STR str(_LIBCPP_ABI_NAMESPACE)2021_LIBCPP_BEGIN_NAMESPACE_STD2223alignas(istream) _LIBCPP_EXPORTED_FROM_ABI char cin[sizeof(istream)]24#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)25__asm__("?cin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR26"@std@@@12@A")27#endif28;29alignas(__stdinbuf<char>) static char __cin[sizeof(__stdinbuf<char>)];30static mbstate_t mb_cin;3132#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS33alignas(wistream) _LIBCPP_EXPORTED_FROM_ABI char wcin[sizeof(wistream)]34# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)35__asm__("?wcin@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_istream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR36"@std@@@12@A")37# endif38;39alignas(__stdinbuf<wchar_t>) static char __wcin[sizeof(__stdinbuf<wchar_t>)];40static mbstate_t mb_wcin;41#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS4243alignas(ostream) _LIBCPP_EXPORTED_FROM_ABI char cout[sizeof(ostream)]44#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)45__asm__("?cout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR46"@std@@@12@A")47#endif48;49alignas(__stdoutbuf<char>) static char __cout[sizeof(__stdoutbuf<char>)];50static mbstate_t mb_cout;5152#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS53alignas(wostream) _LIBCPP_EXPORTED_FROM_ABI char wcout[sizeof(wostream)]54# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)55__asm__("?wcout@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR56"@std@@@12@A")57# endif58;59alignas(__stdoutbuf<wchar_t>) static char __wcout[sizeof(__stdoutbuf<wchar_t>)];60static mbstate_t mb_wcout;61#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS6263alignas(ostream) _LIBCPP_EXPORTED_FROM_ABI char cerr[sizeof(ostream)]64#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)65__asm__("?cerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR66"@std@@@12@A")67#endif68;69alignas(__stdoutbuf<char>) static char __cerr[sizeof(__stdoutbuf<char>)];70static mbstate_t mb_cerr;7172#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS73alignas(wostream) _LIBCPP_EXPORTED_FROM_ABI char wcerr[sizeof(wostream)]74# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)75__asm__("?wcerr@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR76"@std@@@12@A")77# endif78;79alignas(__stdoutbuf<wchar_t>) static char __wcerr[sizeof(__stdoutbuf<wchar_t>)];80static mbstate_t mb_wcerr;81#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS8283alignas(ostream) _LIBCPP_EXPORTED_FROM_ABI char clog[sizeof(ostream)]84#if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)85__asm__("?clog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@DU?$char_traits@D@" _LIBCPP_ABI_NAMESPACE_STR86"@std@@@12@A")87#endif88;8990#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS91alignas(wostream) _LIBCPP_EXPORTED_FROM_ABI char wclog[sizeof(wostream)]92# if defined(_LIBCPP_ABI_MICROSOFT) && defined(__clang__)93__asm__("?wclog@" _LIBCPP_ABI_NAMESPACE_STR "@std@@3V?$basic_ostream@_WU?$char_traits@_W@" _LIBCPP_ABI_NAMESPACE_STR94"@std@@@12@A")95# endif96;97#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS9899// Pretend we're inside a system header so the compiler doesn't flag the use of the init_priority100// attribute with a value that's reserved for the implementation (we're the implementation).101#include "iostream_init.h"102103// On Windows the TLS storage for locales needs to be initialized before we create104// the standard streams, otherwise it may not be alive during program termination105// when we flush the streams.106static void force_locale_initialization() {107#if defined(_LIBCPP_MSVCRT_LIKE)108static bool once = []() {109auto loc = newlocale(LC_ALL_MASK, "C", 0);110{111__libcpp_locale_guard g(loc); // forces initialization of locale TLS112((void)g);113}114freelocale(loc);115return true;116}();117((void)once);118#endif119}120121class DoIOSInit {122public:123DoIOSInit();124~DoIOSInit();125};126127DoIOSInit::DoIOSInit() {128force_locale_initialization();129130istream* cin_ptr = ::new (cin) istream(::new (__cin) __stdinbuf<char>(stdin, &mb_cin));131ostream* cout_ptr = ::new (cout) ostream(::new (__cout) __stdoutbuf<char>(stdout, &mb_cout));132ostream* cerr_ptr = ::new (cerr) ostream(::new (__cerr) __stdoutbuf<char>(stderr, &mb_cerr));133::new (clog) ostream(cerr_ptr->rdbuf());134cin_ptr->tie(cout_ptr);135std::unitbuf(*cerr_ptr);136cerr_ptr->tie(cout_ptr);137138#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS139wistream* wcin_ptr = ::new (wcin) wistream(::new (__wcin) __stdinbuf<wchar_t>(stdin, &mb_wcin));140wostream* wcout_ptr = ::new (wcout) wostream(::new (__wcout) __stdoutbuf<wchar_t>(stdout, &mb_wcout));141wostream* wcerr_ptr = ::new (wcerr) wostream(::new (__wcerr) __stdoutbuf<wchar_t>(stderr, &mb_wcerr));142::new (wclog) wostream(wcerr_ptr->rdbuf());143144wcin_ptr->tie(wcout_ptr);145std::unitbuf(*wcerr_ptr);146wcerr_ptr->tie(wcout_ptr);147#endif148}149150DoIOSInit::~DoIOSInit() {151ostream* cout_ptr = reinterpret_cast<ostream*>(cout);152cout_ptr->flush();153ostream* clog_ptr = reinterpret_cast<ostream*>(clog);154clog_ptr->flush();155156#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS157wostream* wcout_ptr = reinterpret_cast<wostream*>(wcout);158wcout_ptr->flush();159wostream* wclog_ptr = reinterpret_cast<wostream*>(wclog);160wclog_ptr->flush();161#endif162}163164ios_base::Init::Init() {165static DoIOSInit init_the_streams; // gets initialized once166}167168ios_base::Init::~Init() {}169170_LIBCPP_END_NAMESPACE_STD171172173