1*06c3fb27SDimitry Andric// -*- C++ -*- 2*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 3*06c3fb27SDimitry Andric// 4*06c3fb27SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*06c3fb27SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 6*06c3fb27SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*06c3fb27SDimitry Andric// 8*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 9*06c3fb27SDimitry Andric 10*06c3fb27SDimitry Andric#ifndef _LIBCPP_PRINT 11*06c3fb27SDimitry Andric#define _LIBCPP_PRINT 12*06c3fb27SDimitry Andric 13*06c3fb27SDimitry Andric/* 14*06c3fb27SDimitry Andricnamespace std { 15*06c3fb27SDimitry Andric // [print.fun], print functions 16*06c3fb27SDimitry Andric template<class... Args> 17*06c3fb27SDimitry Andric void print(format_string<Args...> fmt, Args&&... args); 18*06c3fb27SDimitry Andric template<class... Args> 19*06c3fb27SDimitry Andric void print(FILE* stream, format_string<Args...> fmt, Args&&... args); 20*06c3fb27SDimitry Andric 21*06c3fb27SDimitry Andric template<class... Args> 22*06c3fb27SDimitry Andric void println(format_string<Args...> fmt, Args&&... args); 23*06c3fb27SDimitry Andric template<class... Args> 24*06c3fb27SDimitry Andric void println(FILE* stream, format_string<Args...> fmt, Args&&... args); 25*06c3fb27SDimitry Andric 26*06c3fb27SDimitry Andric void vprint_unicode(string_view fmt, format_args args); 27*06c3fb27SDimitry Andric void vprint_unicode(FILE* stream, string_view fmt, format_args args); 28*06c3fb27SDimitry Andric 29*06c3fb27SDimitry Andric void vprint_nonunicode(string_view fmt, format_args args); 30*06c3fb27SDimitry Andric void vprint_nonunicode(FILE* stream, string_view fmt, format_args args); 31*06c3fb27SDimitry Andric} 32*06c3fb27SDimitry Andric*/ 33*06c3fb27SDimitry Andric 34*06c3fb27SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler 35*06c3fb27SDimitry Andric#include <__concepts/same_as.h> 36*06c3fb27SDimitry Andric#include <__config> 37*06c3fb27SDimitry Andric#include <__format/buffer.h> 38*06c3fb27SDimitry Andric#include <__format/format_arg_store.h> 39*06c3fb27SDimitry Andric#include <__format/format_args.h> 40*06c3fb27SDimitry Andric#include <__format/format_context.h> 41*06c3fb27SDimitry Andric#include <__format/format_error.h> 42*06c3fb27SDimitry Andric#include <__format/format_functions.h> 43*06c3fb27SDimitry Andric#include <__format/unicode.h> 44*06c3fb27SDimitry Andric#include <__system_error/system_error.h> 45*06c3fb27SDimitry Andric#include <__utility/forward.h> 46*06c3fb27SDimitry Andric#include <cerrno> 47*06c3fb27SDimitry Andric#include <cstdio> 48*06c3fb27SDimitry Andric#include <string> 49*06c3fb27SDimitry Andric#include <string_view> 50*06c3fb27SDimitry Andric#include <version> 51*06c3fb27SDimitry Andric 52*06c3fb27SDimitry Andric#if __has_include(<unistd.h>) 53*06c3fb27SDimitry Andric# include <unistd.h> 54*06c3fb27SDimitry Andric#endif 55*06c3fb27SDimitry Andric 56*06c3fb27SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 57*06c3fb27SDimitry Andric# pragma GCC system_header 58*06c3fb27SDimitry Andric#endif 59*06c3fb27SDimitry Andric 60*06c3fb27SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 61*06c3fb27SDimitry Andric 62*06c3fb27SDimitry Andric#ifdef _WIN32 63*06c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI bool __is_windows_terminal(FILE* __stream); 64*06c3fb27SDimitry Andric 65*06c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 66*06c3fb27SDimitry Andric// A wrapper for WriteConsoleW which is used to write to the Windows 67*06c3fb27SDimitry Andric// console. This function is in the dylib to avoid pulling in windows.h 68*06c3fb27SDimitry Andric// in the library headers. The function itself uses some private parts 69*06c3fb27SDimitry Andric// of the dylib too. 70*06c3fb27SDimitry Andric// 71*06c3fb27SDimitry Andric// The function does not depend on the language standard used. Guarding 72*06c3fb27SDimitry Andric// it with C++23 would fail since the dylib is currently built using C++20. 73*06c3fb27SDimitry Andric// 74*06c3fb27SDimitry Andric// Note the function is only implemented on the Windows platform. 75*06c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI void __write_to_windows_console(FILE* __stream, wstring_view __view); 76*06c3fb27SDimitry Andric# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 77*06c3fb27SDimitry Andric 78*06c3fb27SDimitry Andric#endif // _WIN32 79*06c3fb27SDimitry Andric 80*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 81*06c3fb27SDimitry Andric 82*06c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_UNICODE 83*06c3fb27SDimitry Andric// This is the code to transcode UTF-8 to UTF-16. This is used on 84*06c3fb27SDimitry Andric// Windows for the native Unicode API. The code is modeled to make it 85*06c3fb27SDimitry Andric// easier to extend to 86*06c3fb27SDimitry Andric// 87*06c3fb27SDimitry Andric// P2728R0 Unicode in the Library, Part 1: UTF Transcoding 88*06c3fb27SDimitry Andric// 89*06c3fb27SDimitry Andric// This paper is still under heavy development so it makes no sense yet 90*06c3fb27SDimitry Andric// to strictly follow the paper. 91*06c3fb27SDimitry Andricnamespace __unicode { 92*06c3fb27SDimitry Andric 93*06c3fb27SDimitry Andric// The names of these concepts are modelled after P2728R0, but the 94*06c3fb27SDimitry Andric// implementation is not. char16_t may contain 32-bits so depending on the 95*06c3fb27SDimitry Andric// number of bits is an issue. 96*06c3fb27SDimitry Andric# ifdef _LIBCPP_SHORT_WCHAR 97*06c3fb27SDimitry Andrictemplate <class _Tp> 98*06c3fb27SDimitry Andricconcept __utf16_code_unit = 99*06c3fb27SDimitry Andric same_as<_Tp, char16_t> 100*06c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 101*06c3fb27SDimitry Andric || same_as<_Tp, wchar_t> 102*06c3fb27SDimitry Andric# endif 103*06c3fb27SDimitry Andric ; 104*06c3fb27SDimitry Andrictemplate <class _Tp> 105*06c3fb27SDimitry Andricconcept __utf32_code_unit = same_as<_Tp, char32_t>; 106*06c3fb27SDimitry Andric# else // _LIBCPP_SHORT_WCHAR 107*06c3fb27SDimitry Andrictemplate <class _Tp> 108*06c3fb27SDimitry Andricconcept __utf16_code_unit = same_as<_Tp, char16_t>; 109*06c3fb27SDimitry Andrictemplate <class _Tp> 110*06c3fb27SDimitry Andricconcept __utf32_code_unit = 111*06c3fb27SDimitry Andric same_as<_Tp, char32_t> 112*06c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 113*06c3fb27SDimitry Andric || same_as<_Tp, wchar_t> 114*06c3fb27SDimitry Andric# endif 115*06c3fb27SDimitry Andric ; 116*06c3fb27SDimitry Andric# endif // _LIBCPP_SHORT_WCHAR 117*06c3fb27SDimitry Andric 118*06c3fb27SDimitry Andric// Pass by reference since an output_iterator may not be copyable. 119*06c3fb27SDimitry Andrictemplate <class _OutIt> 120*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt&, char32_t) = delete; 121*06c3fb27SDimitry Andric 122*06c3fb27SDimitry Andrictemplate <class _OutIt> 123*06c3fb27SDimitry Andric requires __utf16_code_unit<iter_value_t<_OutIt>> 124*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt& __out_it, char32_t __value) { 125*06c3fb27SDimitry Andric _LIBCPP_ASSERT_UNCATEGORIZED(__is_scalar_value(__value), "an invalid unicode scalar value results in invalid UTF-16"); 126*06c3fb27SDimitry Andric 127*06c3fb27SDimitry Andric if (__value < 0x10000) { 128*06c3fb27SDimitry Andric *__out_it++ = __value; 129*06c3fb27SDimitry Andric return; 130*06c3fb27SDimitry Andric } 131*06c3fb27SDimitry Andric 132*06c3fb27SDimitry Andric __value -= 0x10000; 133*06c3fb27SDimitry Andric *__out_it++ = 0xd800 + (__value >> 10); 134*06c3fb27SDimitry Andric *__out_it++ = 0xdc00 + (__value & 0x3FF); 135*06c3fb27SDimitry Andric} 136*06c3fb27SDimitry Andric 137*06c3fb27SDimitry Andrictemplate <class _OutIt> 138*06c3fb27SDimitry Andric requires __utf32_code_unit<iter_value_t<_OutIt>> 139*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt& __out_it, char32_t __value) { 140*06c3fb27SDimitry Andric _LIBCPP_ASSERT_UNCATEGORIZED(__is_scalar_value(__value), "an invalid unicode scalar value results in invalid UTF-32"); 141*06c3fb27SDimitry Andric *__out_it++ = __value; 142*06c3fb27SDimitry Andric} 143*06c3fb27SDimitry Andric 144*06c3fb27SDimitry Andrictemplate <class _OutIt, input_iterator _InIt> 145*06c3fb27SDimitry Andric requires output_iterator<_OutIt, const iter_value_t<_OutIt>&> && (!same_as<iter_value_t<_OutIt>, iter_value_t<_InIt>>) 146*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr _OutIt __transcode(_InIt __first, _InIt __last, _OutIt __out_it) { 147*06c3fb27SDimitry Andric // The __code_point_view has a basic_string_view interface. 148*06c3fb27SDimitry Andric // When transcoding becomes part of the standard we probably want to 149*06c3fb27SDimitry Andric // look at smarter algorithms. 150*06c3fb27SDimitry Andric // For example, when processing a code point that is encoded in 151*06c3fb27SDimitry Andric // 1 to 3 code units in UTF-8, the result will always be encoded 152*06c3fb27SDimitry Andric // in 1 code unit in UTF-16 (code points that require 4 code 153*06c3fb27SDimitry Andric // units in UTF-8 will require 2 code units in UTF-16). 154*06c3fb27SDimitry Andric // 155*06c3fb27SDimitry Andric // Note if P2728 is accepted types like int may become valid. In that case 156*06c3fb27SDimitry Andric // the __code_point_view should use a span. Libc++ will remove support for 157*06c3fb27SDimitry Andric // char_traits<int>. 158*06c3fb27SDimitry Andric 159*06c3fb27SDimitry Andric // TODO PRINT Validate with clang-tidy 160*06c3fb27SDimitry Andric // NOLINTNEXTLINE(bugprone-dangling-handle) 161*06c3fb27SDimitry Andric basic_string_view<iter_value_t<_InIt>> __data{__first, __last}; 162*06c3fb27SDimitry Andric __code_point_view<iter_value_t<_InIt>> __view{__data.begin(), __data.end()}; 163*06c3fb27SDimitry Andric while (!__view.__at_end()) 164*06c3fb27SDimitry Andric __unicode::__encode(__out_it, __view.__consume().__code_point); 165*06c3fb27SDimitry Andric return __out_it; 166*06c3fb27SDimitry Andric} 167*06c3fb27SDimitry Andric 168*06c3fb27SDimitry Andric} // namespace __unicode 169*06c3fb27SDimitry Andric 170*06c3fb27SDimitry Andric# endif // _LIBCPP_HAS_NO_UNICODE 171*06c3fb27SDimitry Andric 172*06c3fb27SDimitry Andricnamespace __print { 173*06c3fb27SDimitry Andric 174*06c3fb27SDimitry Andric// [print.fun]/2 175*06c3fb27SDimitry Andric// Effects: If the ordinary literal encoding ([lex.charset]) is UTF-8, equivalent to: 176*06c3fb27SDimitry Andric// vprint_unicode(stream, fmt.str, make_format_args(args...)); 177*06c3fb27SDimitry Andric// Otherwise, equivalent to: 178*06c3fb27SDimitry Andric// vprint_nonunicode(stream, fmt.str, make_format_args(args...)); 179*06c3fb27SDimitry Andric// 180*06c3fb27SDimitry Andric// Based on the compiler and its compilation flags this value is or is 181*06c3fb27SDimitry Andric// not true. As mentioned in P2093R14 this only affects Windows. The 182*06c3fb27SDimitry Andric// test below could also be done for 183*06c3fb27SDimitry Andric// - GCC using __GNUC_EXECUTION_CHARSET_NAME 184*06c3fb27SDimitry Andric// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html 185*06c3fb27SDimitry Andric// - Clang using __clang_literal_encoding__ 186*06c3fb27SDimitry Andric// https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros 187*06c3fb27SDimitry Andric// (note at the time of writing Clang is hard-coded to UTF-8.) 188*06c3fb27SDimitry Andric// 189*06c3fb27SDimitry Andric 190*06c3fb27SDimitry Andric# ifdef _LIBCPP_HAS_NO_UNICODE 191*06c3fb27SDimitry Andricinline constexpr bool __use_unicode = false; 192*06c3fb27SDimitry Andric# elif defined(_MSVC_EXECUTION_CHARACTER_SET) 193*06c3fb27SDimitry Andric// This is the same test MSVC STL uses in their implementation of <print> 194*06c3fb27SDimitry Andric// See: https://learn.microsoft.com/en-us/windows/win32/intl/code-page-identifiers 195*06c3fb27SDimitry Andricinline constexpr bool __use_unicode = _MSVC_EXECUTION_CHARACTER_SET == 65001; 196*06c3fb27SDimitry Andric# else 197*06c3fb27SDimitry Andricinline constexpr bool __use_unicode = true; 198*06c3fb27SDimitry Andric# endif 199*06c3fb27SDimitry Andric 200*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline bool __is_terminal(FILE* __stream) { 201*06c3fb27SDimitry Andric# ifdef _WIN32 202*06c3fb27SDimitry Andric return std::__is_windows_terminal(__stream); 203*06c3fb27SDimitry Andric# elif __has_include(<unistd.h>) 204*06c3fb27SDimitry Andric return isatty(fileno(__stream)); 205*06c3fb27SDimitry Andric# else 206*06c3fb27SDimitry Andric# error "Provide a way to determine whether a FILE* is a terminal" 207*06c3fb27SDimitry Andric# endif 208*06c3fb27SDimitry Andric} 209*06c3fb27SDimitry Andric 210*06c3fb27SDimitry Andrictemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). 211*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline void 212*06c3fb27SDimitry Andric__vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl) { 213*06c3fb27SDimitry Andric _LIBCPP_ASSERT_UNCATEGORIZED(__stream, "__stream is a valid pointer to an output C stream"); 214*06c3fb27SDimitry Andric string __str = std::vformat(__fmt, __args); 215*06c3fb27SDimitry Andric if (__write_nl) 216*06c3fb27SDimitry Andric __str.push_back('\n'); 217*06c3fb27SDimitry Andric 218*06c3fb27SDimitry Andric size_t __size = fwrite(__str.data(), 1, __str.size(), __stream); 219*06c3fb27SDimitry Andric if (__size < __str.size()) { 220*06c3fb27SDimitry Andric if (std::feof(__stream)) 221*06c3fb27SDimitry Andric std::__throw_system_error(EIO, "EOF while writing the formatted output"); 222*06c3fb27SDimitry Andric std::__throw_system_error(std::ferror(__stream), "failed to write formatted output"); 223*06c3fb27SDimitry Andric } 224*06c3fb27SDimitry Andric} 225*06c3fb27SDimitry Andric 226*06c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_UNICODE 227*06c3fb27SDimitry Andric 228*06c3fb27SDimitry Andric// Note these helper functions are mainly used to aid testing. 229*06c3fb27SDimitry Andric// On POSIX systems and Windows the output is no longer considered a 230*06c3fb27SDimitry Andric// terminal when the output is redirected. Typically during testing the 231*06c3fb27SDimitry Andric// output is redirected to be able to capture it. This makes it hard to 232*06c3fb27SDimitry Andric// test this code path. 233*06c3fb27SDimitry Andrictemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). 234*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline void 235*06c3fb27SDimitry Andric__vprint_unicode_posix(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl, bool __is_terminal) { 236*06c3fb27SDimitry Andric // TODO PRINT Should flush errors throw too? 237*06c3fb27SDimitry Andric if (__is_terminal) 238*06c3fb27SDimitry Andric std::fflush(__stream); 239*06c3fb27SDimitry Andric 240*06c3fb27SDimitry Andric __print::__vprint_nonunicode(__stream, __fmt, __args, __write_nl); 241*06c3fb27SDimitry Andric} 242*06c3fb27SDimitry Andric 243*06c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 244*06c3fb27SDimitry Andrictemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). 245*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline void 246*06c3fb27SDimitry Andric__vprint_unicode_windows(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl, bool __is_terminal) { 247*06c3fb27SDimitry Andric if (!__is_terminal) 248*06c3fb27SDimitry Andric return __print::__vprint_nonunicode(__stream, __fmt, __args, __write_nl); 249*06c3fb27SDimitry Andric 250*06c3fb27SDimitry Andric // TODO PRINT Should flush errors throw too? 251*06c3fb27SDimitry Andric std::fflush(__stream); 252*06c3fb27SDimitry Andric 253*06c3fb27SDimitry Andric string __str = std::vformat(__fmt, __args); 254*06c3fb27SDimitry Andric // UTF-16 uses the same number or less code units than UTF-8. 255*06c3fb27SDimitry Andric // However the size of the code unit is 16 bits instead of 8 bits. 256*06c3fb27SDimitry Andric // 257*06c3fb27SDimitry Andric // The buffer uses the worst-case estimate and should never resize. 258*06c3fb27SDimitry Andric // However when the string is large this could lead to OOM. Using a 259*06c3fb27SDimitry Andric // smaller size might work, but since the buffer uses a grow factor 260*06c3fb27SDimitry Andric // the final size might be larger when the estimate is wrong. 261*06c3fb27SDimitry Andric // 262*06c3fb27SDimitry Andric // TODO PRINT profile and improve the speed of this code. 263*06c3fb27SDimitry Andric __format::__retarget_buffer<wchar_t> __buffer{__str.size()}; 264*06c3fb27SDimitry Andric __unicode::__transcode(__str.begin(), __str.end(), __buffer.__make_output_iterator()); 265*06c3fb27SDimitry Andric if (__write_nl) 266*06c3fb27SDimitry Andric __buffer.push_back(L'\n'); 267*06c3fb27SDimitry Andric 268*06c3fb27SDimitry Andric [[maybe_unused]] wstring_view __view = __buffer.__view(); 269*06c3fb27SDimitry Andric 270*06c3fb27SDimitry Andric // The macro _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION is used to change 271*06c3fb27SDimitry Andric // the behavior in the test. This is not part of the public API. 272*06c3fb27SDimitry Andric# ifdef _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION 273*06c3fb27SDimitry Andric _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION(__stream, __view); 274*06c3fb27SDimitry Andric# elif defined(_WIN32) 275*06c3fb27SDimitry Andric std::__write_to_windows_console(__stream, __view); 276*06c3fb27SDimitry Andric# else 277*06c3fb27SDimitry Andric std::__throw_runtime_error("No defintion of _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION and " 278*06c3fb27SDimitry Andric "__write_to_windows_console is not available."); 279*06c3fb27SDimitry Andric# endif 280*06c3fb27SDimitry Andric} 281*06c3fb27SDimitry Andric# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 282*06c3fb27SDimitry Andric 283*06c3fb27SDimitry Andrictemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). 284*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline void 285*06c3fb27SDimitry Andric__vprint_unicode([[maybe_unused]] FILE* __stream, 286*06c3fb27SDimitry Andric [[maybe_unused]] string_view __fmt, 287*06c3fb27SDimitry Andric [[maybe_unused]] format_args __args, 288*06c3fb27SDimitry Andric [[maybe_unused]] bool __write_nl) { 289*06c3fb27SDimitry Andric _LIBCPP_ASSERT_UNCATEGORIZED(__stream, "__stream is a valid pointer to an output C stream"); 290*06c3fb27SDimitry Andric 291*06c3fb27SDimitry Andric // [print.fun] 292*06c3fb27SDimitry Andric // 7 - Effects: If stream refers to a terminal capable of displaying 293*06c3fb27SDimitry Andric // Unicode, writes out to the terminal using the native Unicode 294*06c3fb27SDimitry Andric // API; if out contains invalid code units, the behavior is 295*06c3fb27SDimitry Andric // undefined and implementations are encouraged to diagnose it. 296*06c3fb27SDimitry Andric // Otherwise writes out to stream unchanged. If the native 297*06c3fb27SDimitry Andric // Unicode API is used, the function flushes stream before 298*06c3fb27SDimitry Andric // writing out. 299*06c3fb27SDimitry Andric // 8 - Throws: Any exception thrown by the call to vformat 300*06c3fb27SDimitry Andric // ([format.err.report]). system_error if writing to the terminal 301*06c3fb27SDimitry Andric // or stream fails. May throw bad_alloc. 302*06c3fb27SDimitry Andric // 9 - Recommended practice: If invoking the native Unicode API 303*06c3fb27SDimitry Andric // requires transcoding, implementations should substitute 304*06c3fb27SDimitry Andric // invalid code units with U+FFFD replacement character per the 305*06c3fb27SDimitry Andric // Unicode Standard, Chapter 3.9 U+FFFD Substitution in 306*06c3fb27SDimitry Andric // Conversion. 307*06c3fb27SDimitry Andric 308*06c3fb27SDimitry Andric // On non-Windows platforms the Unicode API is the normal file I/O API 309*06c3fb27SDimitry Andric // so there the call can be forwarded to the non_unicode API. On 310*06c3fb27SDimitry Andric // Windows there is a different API. This API requires transcoding. 311*06c3fb27SDimitry Andric 312*06c3fb27SDimitry Andric# ifndef _WIN32 313*06c3fb27SDimitry Andric __print::__vprint_unicode_posix(__stream, __fmt, __args, __write_nl, __print::__is_terminal(__stream)); 314*06c3fb27SDimitry Andric# elif !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) 315*06c3fb27SDimitry Andric __print::__vprint_unicode_windows(__stream, __fmt, __args, __write_nl, __print::__is_terminal(__stream)); 316*06c3fb27SDimitry Andric# else 317*06c3fb27SDimitry Andric# error "Windows builds with wchar_t disabled are not supported." 318*06c3fb27SDimitry Andric# endif 319*06c3fb27SDimitry Andric} 320*06c3fb27SDimitry Andric 321*06c3fb27SDimitry Andric# endif // _LIBCPP_HAS_NO_UNICODE 322*06c3fb27SDimitry Andric 323*06c3fb27SDimitry Andric} // namespace __print 324*06c3fb27SDimitry Andric 325*06c3fb27SDimitry Andrictemplate <class... _Args> 326*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI void print(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) { 327*06c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_UNICODE 328*06c3fb27SDimitry Andric if constexpr (__print::__use_unicode) 329*06c3fb27SDimitry Andric __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), false); 330*06c3fb27SDimitry Andric else 331*06c3fb27SDimitry Andric __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), false); 332*06c3fb27SDimitry Andric# else // _LIBCPP_HAS_NO_UNICODE 333*06c3fb27SDimitry Andric __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), false); 334*06c3fb27SDimitry Andric# endif // _LIBCPP_HAS_NO_UNICODE 335*06c3fb27SDimitry Andric} 336*06c3fb27SDimitry Andric 337*06c3fb27SDimitry Andrictemplate <class... _Args> 338*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI void print(format_string<_Args...> __fmt, _Args&&... __args) { 339*06c3fb27SDimitry Andric std::print(stdout, __fmt, std::forward<_Args>(__args)...); 340*06c3fb27SDimitry Andric} 341*06c3fb27SDimitry Andric 342*06c3fb27SDimitry Andrictemplate <class... _Args> 343*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) { 344*06c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_UNICODE 345*06c3fb27SDimitry Andric // Note the wording in the Standard is inefficient. The output of 346*06c3fb27SDimitry Andric // std::format is a std::string which is then copied. This solution 347*06c3fb27SDimitry Andric // just appends a newline at the end of the output. 348*06c3fb27SDimitry Andric if constexpr (__print::__use_unicode) 349*06c3fb27SDimitry Andric __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), true); 350*06c3fb27SDimitry Andric else 351*06c3fb27SDimitry Andric __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), true); 352*06c3fb27SDimitry Andric# else // _LIBCPP_HAS_NO_UNICODE 353*06c3fb27SDimitry Andric __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), true); 354*06c3fb27SDimitry Andric# endif // _LIBCPP_HAS_NO_UNICODE 355*06c3fb27SDimitry Andric} 356*06c3fb27SDimitry Andric 357*06c3fb27SDimitry Andrictemplate <class... _Args> 358*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI void println(format_string<_Args...> __fmt, _Args&&... __args) { 359*06c3fb27SDimitry Andric std::println(stdout, __fmt, std::forward<_Args>(__args)...); 360*06c3fb27SDimitry Andric} 361*06c3fb27SDimitry Andric 362*06c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_UNICODE 363*06c3fb27SDimitry Andrictemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). 364*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(FILE* __stream, string_view __fmt, format_args __args) { 365*06c3fb27SDimitry Andric __print::__vprint_unicode(__stream, __fmt, __args, false); 366*06c3fb27SDimitry Andric} 367*06c3fb27SDimitry Andric 368*06c3fb27SDimitry Andrictemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). 369*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(string_view __fmt, format_args __args) { 370*06c3fb27SDimitry Andric std::vprint_unicode(stdout, __fmt, __args); 371*06c3fb27SDimitry Andric} 372*06c3fb27SDimitry Andric 373*06c3fb27SDimitry Andric# endif // _LIBCPP_HAS_NO_UNICODE 374*06c3fb27SDimitry Andric 375*06c3fb27SDimitry Andrictemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). 376*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args) { 377*06c3fb27SDimitry Andric __print::__vprint_nonunicode(__stream, __fmt, __args, false); 378*06c3fb27SDimitry Andric} 379*06c3fb27SDimitry Andric 380*06c3fb27SDimitry Andrictemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). 381*06c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(string_view __fmt, format_args __args) { 382*06c3fb27SDimitry Andric std::vprint_nonunicode(stdout, __fmt, __args); 383*06c3fb27SDimitry Andric} 384*06c3fb27SDimitry Andric 385*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 23 386*06c3fb27SDimitry Andric 387*06c3fb27SDimitry Andric_LIBCPP_END_NAMESPACE_STD 388*06c3fb27SDimitry Andric 389*06c3fb27SDimitry Andric#endif // _LIBCPP_PRINT 390