106c3fb27SDimitry Andric// -*- C++ -*- 206c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 306c3fb27SDimitry Andric// 406c3fb27SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 506c3fb27SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 606c3fb27SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 706c3fb27SDimitry Andric// 806c3fb27SDimitry Andric//===----------------------------------------------------------------------===// 906c3fb27SDimitry Andric 1006c3fb27SDimitry Andric#ifndef _LIBCPP_PRINT 1106c3fb27SDimitry Andric#define _LIBCPP_PRINT 1206c3fb27SDimitry Andric 1306c3fb27SDimitry Andric/* 1406c3fb27SDimitry Andricnamespace std { 1506c3fb27SDimitry Andric // [print.fun], print functions 1606c3fb27SDimitry Andric template<class... Args> 1706c3fb27SDimitry Andric void print(format_string<Args...> fmt, Args&&... args); 1806c3fb27SDimitry Andric template<class... Args> 1906c3fb27SDimitry Andric void print(FILE* stream, format_string<Args...> fmt, Args&&... args); 2006c3fb27SDimitry Andric 2106c3fb27SDimitry Andric template<class... Args> 2206c3fb27SDimitry Andric void println(format_string<Args...> fmt, Args&&... args); 2306c3fb27SDimitry Andric template<class... Args> 2406c3fb27SDimitry Andric void println(FILE* stream, format_string<Args...> fmt, Args&&... args); 2506c3fb27SDimitry Andric 2606c3fb27SDimitry Andric void vprint_unicode(string_view fmt, format_args args); 2706c3fb27SDimitry Andric void vprint_unicode(FILE* stream, string_view fmt, format_args args); 2806c3fb27SDimitry Andric 2906c3fb27SDimitry Andric void vprint_nonunicode(string_view fmt, format_args args); 3006c3fb27SDimitry Andric void vprint_nonunicode(FILE* stream, string_view fmt, format_args args); 3106c3fb27SDimitry Andric} 3206c3fb27SDimitry Andric*/ 3306c3fb27SDimitry Andric 3406c3fb27SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler 3506c3fb27SDimitry Andric#include <__concepts/same_as.h> 3606c3fb27SDimitry Andric#include <__config> 3706c3fb27SDimitry Andric#include <__format/buffer.h> 3806c3fb27SDimitry Andric#include <__format/format_arg_store.h> 3906c3fb27SDimitry Andric#include <__format/format_args.h> 4006c3fb27SDimitry Andric#include <__format/format_context.h> 4106c3fb27SDimitry Andric#include <__format/format_error.h> 4206c3fb27SDimitry Andric#include <__format/format_functions.h> 4306c3fb27SDimitry Andric#include <__format/unicode.h> 4406c3fb27SDimitry Andric#include <__system_error/system_error.h> 4506c3fb27SDimitry Andric#include <__utility/forward.h> 4606c3fb27SDimitry Andric#include <cerrno> 4706c3fb27SDimitry Andric#include <cstdio> 4806c3fb27SDimitry Andric#include <string> 4906c3fb27SDimitry Andric#include <string_view> 5006c3fb27SDimitry Andric#include <version> 5106c3fb27SDimitry Andric 5206c3fb27SDimitry Andric#if __has_include(<unistd.h>) 5306c3fb27SDimitry Andric# include <unistd.h> 5406c3fb27SDimitry Andric#endif 5506c3fb27SDimitry Andric 5606c3fb27SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 5706c3fb27SDimitry Andric# pragma GCC system_header 5806c3fb27SDimitry Andric#endif 5906c3fb27SDimitry Andric 6006c3fb27SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 6106c3fb27SDimitry Andric 62cb14a3feSDimitry Andric#ifdef _LIBCPP_WIN32API 6306c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI bool __is_windows_terminal(FILE* __stream); 6406c3fb27SDimitry Andric 6506c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 6606c3fb27SDimitry Andric// A wrapper for WriteConsoleW which is used to write to the Windows 6706c3fb27SDimitry Andric// console. This function is in the dylib to avoid pulling in windows.h 6806c3fb27SDimitry Andric// in the library headers. The function itself uses some private parts 6906c3fb27SDimitry Andric// of the dylib too. 7006c3fb27SDimitry Andric// 7106c3fb27SDimitry Andric// The function does not depend on the language standard used. Guarding 7206c3fb27SDimitry Andric// it with C++23 would fail since the dylib is currently built using C++20. 7306c3fb27SDimitry Andric// 7406c3fb27SDimitry Andric// Note the function is only implemented on the Windows platform. 7506c3fb27SDimitry Andric_LIBCPP_EXPORTED_FROM_ABI void __write_to_windows_console(FILE* __stream, wstring_view __view); 7606c3fb27SDimitry Andric# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 7706c3fb27SDimitry Andric 78cb14a3feSDimitry Andric#endif // _LIBCPP_WIN32API 7906c3fb27SDimitry Andric 8006c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 23 8106c3fb27SDimitry Andric 8206c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_UNICODE 8306c3fb27SDimitry Andric// This is the code to transcode UTF-8 to UTF-16. This is used on 8406c3fb27SDimitry Andric// Windows for the native Unicode API. The code is modeled to make it 8506c3fb27SDimitry Andric// easier to extend to 8606c3fb27SDimitry Andric// 8706c3fb27SDimitry Andric// P2728R0 Unicode in the Library, Part 1: UTF Transcoding 8806c3fb27SDimitry Andric// 8906c3fb27SDimitry Andric// This paper is still under heavy development so it makes no sense yet 9006c3fb27SDimitry Andric// to strictly follow the paper. 9106c3fb27SDimitry Andricnamespace __unicode { 9206c3fb27SDimitry Andric 9306c3fb27SDimitry Andric// The names of these concepts are modelled after P2728R0, but the 9406c3fb27SDimitry Andric// implementation is not. char16_t may contain 32-bits so depending on the 9506c3fb27SDimitry Andric// number of bits is an issue. 9606c3fb27SDimitry Andric# ifdef _LIBCPP_SHORT_WCHAR 9706c3fb27SDimitry Andrictemplate <class _Tp> 9806c3fb27SDimitry Andricconcept __utf16_code_unit = 9906c3fb27SDimitry Andric same_as<_Tp, char16_t> 10006c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 10106c3fb27SDimitry Andric || same_as<_Tp, wchar_t> 10206c3fb27SDimitry Andric# endif 10306c3fb27SDimitry Andric ; 10406c3fb27SDimitry Andrictemplate <class _Tp> 10506c3fb27SDimitry Andricconcept __utf32_code_unit = same_as<_Tp, char32_t>; 10606c3fb27SDimitry Andric# else // _LIBCPP_SHORT_WCHAR 10706c3fb27SDimitry Andrictemplate <class _Tp> 10806c3fb27SDimitry Andricconcept __utf16_code_unit = same_as<_Tp, char16_t>; 10906c3fb27SDimitry Andrictemplate <class _Tp> 11006c3fb27SDimitry Andricconcept __utf32_code_unit = 11106c3fb27SDimitry Andric same_as<_Tp, char32_t> 11206c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 11306c3fb27SDimitry Andric || same_as<_Tp, wchar_t> 11406c3fb27SDimitry Andric# endif 11506c3fb27SDimitry Andric ; 11606c3fb27SDimitry Andric# endif // _LIBCPP_SHORT_WCHAR 11706c3fb27SDimitry Andric 11806c3fb27SDimitry Andric// Pass by reference since an output_iterator may not be copyable. 11906c3fb27SDimitry Andrictemplate <class _OutIt> 12006c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt&, char32_t) = delete; 12106c3fb27SDimitry Andric 12206c3fb27SDimitry Andrictemplate <class _OutIt> 12306c3fb27SDimitry Andric requires __utf16_code_unit<iter_value_t<_OutIt>> 12406c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt& __out_it, char32_t __value) { 125*1db9f3b2SDimitry Andric // [print.fun]/7 : "if `out` contains invalid code units, the behavior is undefined and implementations are encouraged 126*1db9f3b2SDimitry Andric // to diagnose it". 12706c3fb27SDimitry Andric _LIBCPP_ASSERT_UNCATEGORIZED(__is_scalar_value(__value), "an invalid unicode scalar value results in invalid UTF-16"); 12806c3fb27SDimitry Andric 12906c3fb27SDimitry Andric if (__value < 0x10000) { 13006c3fb27SDimitry Andric *__out_it++ = __value; 13106c3fb27SDimitry Andric return; 13206c3fb27SDimitry Andric } 13306c3fb27SDimitry Andric 13406c3fb27SDimitry Andric __value -= 0x10000; 13506c3fb27SDimitry Andric *__out_it++ = 0xd800 + (__value >> 10); 13606c3fb27SDimitry Andric *__out_it++ = 0xdc00 + (__value & 0x3FF); 13706c3fb27SDimitry Andric} 13806c3fb27SDimitry Andric 13906c3fb27SDimitry Andrictemplate <class _OutIt> 14006c3fb27SDimitry Andric requires __utf32_code_unit<iter_value_t<_OutIt>> 14106c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt& __out_it, char32_t __value) { 142*1db9f3b2SDimitry Andric // [print.fun]/7 : "if `out` contains invalid code units, the behavior is undefined and implementations are encouraged 143*1db9f3b2SDimitry Andric // to diagnose it". 14406c3fb27SDimitry Andric _LIBCPP_ASSERT_UNCATEGORIZED(__is_scalar_value(__value), "an invalid unicode scalar value results in invalid UTF-32"); 14506c3fb27SDimitry Andric *__out_it++ = __value; 14606c3fb27SDimitry Andric} 14706c3fb27SDimitry Andric 14806c3fb27SDimitry Andrictemplate <class _OutIt, input_iterator _InIt> 14906c3fb27SDimitry Andric requires output_iterator<_OutIt, const iter_value_t<_OutIt>&> && (!same_as<iter_value_t<_OutIt>, iter_value_t<_InIt>>) 15006c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI constexpr _OutIt __transcode(_InIt __first, _InIt __last, _OutIt __out_it) { 15106c3fb27SDimitry Andric // The __code_point_view has a basic_string_view interface. 15206c3fb27SDimitry Andric // When transcoding becomes part of the standard we probably want to 15306c3fb27SDimitry Andric // look at smarter algorithms. 15406c3fb27SDimitry Andric // For example, when processing a code point that is encoded in 15506c3fb27SDimitry Andric // 1 to 3 code units in UTF-8, the result will always be encoded 15606c3fb27SDimitry Andric // in 1 code unit in UTF-16 (code points that require 4 code 15706c3fb27SDimitry Andric // units in UTF-8 will require 2 code units in UTF-16). 15806c3fb27SDimitry Andric // 15906c3fb27SDimitry Andric // Note if P2728 is accepted types like int may become valid. In that case 16006c3fb27SDimitry Andric // the __code_point_view should use a span. Libc++ will remove support for 16106c3fb27SDimitry Andric // char_traits<int>. 16206c3fb27SDimitry Andric 16306c3fb27SDimitry Andric // TODO PRINT Validate with clang-tidy 16406c3fb27SDimitry Andric // NOLINTNEXTLINE(bugprone-dangling-handle) 16506c3fb27SDimitry Andric basic_string_view<iter_value_t<_InIt>> __data{__first, __last}; 16606c3fb27SDimitry Andric __code_point_view<iter_value_t<_InIt>> __view{__data.begin(), __data.end()}; 16706c3fb27SDimitry Andric while (!__view.__at_end()) 16806c3fb27SDimitry Andric __unicode::__encode(__out_it, __view.__consume().__code_point); 16906c3fb27SDimitry Andric return __out_it; 17006c3fb27SDimitry Andric} 17106c3fb27SDimitry Andric 17206c3fb27SDimitry Andric} // namespace __unicode 17306c3fb27SDimitry Andric 17406c3fb27SDimitry Andric# endif // _LIBCPP_HAS_NO_UNICODE 17506c3fb27SDimitry Andric 17606c3fb27SDimitry Andricnamespace __print { 17706c3fb27SDimitry Andric 17806c3fb27SDimitry Andric// [print.fun]/2 17906c3fb27SDimitry Andric// Effects: If the ordinary literal encoding ([lex.charset]) is UTF-8, equivalent to: 18006c3fb27SDimitry Andric// vprint_unicode(stream, fmt.str, make_format_args(args...)); 18106c3fb27SDimitry Andric// Otherwise, equivalent to: 18206c3fb27SDimitry Andric// vprint_nonunicode(stream, fmt.str, make_format_args(args...)); 18306c3fb27SDimitry Andric// 18406c3fb27SDimitry Andric// Based on the compiler and its compilation flags this value is or is 18506c3fb27SDimitry Andric// not true. As mentioned in P2093R14 this only affects Windows. The 18606c3fb27SDimitry Andric// test below could also be done for 18706c3fb27SDimitry Andric// - GCC using __GNUC_EXECUTION_CHARSET_NAME 18806c3fb27SDimitry Andric// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html 18906c3fb27SDimitry Andric// - Clang using __clang_literal_encoding__ 19006c3fb27SDimitry Andric// https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros 19106c3fb27SDimitry Andric// (note at the time of writing Clang is hard-coded to UTF-8.) 19206c3fb27SDimitry Andric// 19306c3fb27SDimitry Andric 19406c3fb27SDimitry Andric# ifdef _LIBCPP_HAS_NO_UNICODE 19506c3fb27SDimitry Andricinline constexpr bool __use_unicode = false; 19606c3fb27SDimitry Andric# elif defined(_MSVC_EXECUTION_CHARACTER_SET) 19706c3fb27SDimitry Andric// This is the same test MSVC STL uses in their implementation of <print> 19806c3fb27SDimitry Andric// See: https://learn.microsoft.com/en-us/windows/win32/intl/code-page-identifiers 19906c3fb27SDimitry Andricinline constexpr bool __use_unicode = _MSVC_EXECUTION_CHARACTER_SET == 65001; 20006c3fb27SDimitry Andric# else 20106c3fb27SDimitry Andricinline constexpr bool __use_unicode = true; 20206c3fb27SDimitry Andric# endif 20306c3fb27SDimitry Andric 20406c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline bool __is_terminal(FILE* __stream) { 205cb14a3feSDimitry Andric // The macro _LIBCPP_TESTING_PRINT_IS_TERMINAL is used to change 206cb14a3feSDimitry Andric // the behavior in the test. This is not part of the public API. 207cb14a3feSDimitry Andric# ifdef _LIBCPP_TESTING_PRINT_IS_TERMINAL 208cb14a3feSDimitry Andric return _LIBCPP_TESTING_PRINT_IS_TERMINAL(__stream); 209cb14a3feSDimitry Andric# elif defined(_LIBCPP_WIN32API) 21006c3fb27SDimitry Andric return std::__is_windows_terminal(__stream); 21106c3fb27SDimitry Andric# elif __has_include(<unistd.h>) 21206c3fb27SDimitry Andric return isatty(fileno(__stream)); 21306c3fb27SDimitry Andric# else 21406c3fb27SDimitry Andric# error "Provide a way to determine whether a FILE* is a terminal" 21506c3fb27SDimitry Andric# endif 21606c3fb27SDimitry Andric} 21706c3fb27SDimitry Andric 21806c3fb27SDimitry Andrictemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). 21906c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline void 22006c3fb27SDimitry Andric__vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl) { 221*1db9f3b2SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__stream, "__stream must be a valid pointer to an output C stream"); 22206c3fb27SDimitry Andric string __str = std::vformat(__fmt, __args); 22306c3fb27SDimitry Andric if (__write_nl) 22406c3fb27SDimitry Andric __str.push_back('\n'); 22506c3fb27SDimitry Andric 22606c3fb27SDimitry Andric size_t __size = fwrite(__str.data(), 1, __str.size(), __stream); 22706c3fb27SDimitry Andric if (__size < __str.size()) { 22806c3fb27SDimitry Andric if (std::feof(__stream)) 22906c3fb27SDimitry Andric std::__throw_system_error(EIO, "EOF while writing the formatted output"); 23006c3fb27SDimitry Andric std::__throw_system_error(std::ferror(__stream), "failed to write formatted output"); 23106c3fb27SDimitry Andric } 23206c3fb27SDimitry Andric} 23306c3fb27SDimitry Andric 23406c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_UNICODE 23506c3fb27SDimitry Andric 23606c3fb27SDimitry Andric// Note these helper functions are mainly used to aid testing. 23706c3fb27SDimitry Andric// On POSIX systems and Windows the output is no longer considered a 23806c3fb27SDimitry Andric// terminal when the output is redirected. Typically during testing the 23906c3fb27SDimitry Andric// output is redirected to be able to capture it. This makes it hard to 24006c3fb27SDimitry Andric// test this code path. 24106c3fb27SDimitry Andrictemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). 24206c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline void 24306c3fb27SDimitry Andric__vprint_unicode_posix(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl, bool __is_terminal) { 24406c3fb27SDimitry Andric // TODO PRINT Should flush errors throw too? 24506c3fb27SDimitry Andric if (__is_terminal) 24606c3fb27SDimitry Andric std::fflush(__stream); 24706c3fb27SDimitry Andric 24806c3fb27SDimitry Andric __print::__vprint_nonunicode(__stream, __fmt, __args, __write_nl); 24906c3fb27SDimitry Andric} 25006c3fb27SDimitry Andric 25106c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 25206c3fb27SDimitry Andrictemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). 25306c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline void 25406c3fb27SDimitry Andric__vprint_unicode_windows(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl, bool __is_terminal) { 25506c3fb27SDimitry Andric if (!__is_terminal) 25606c3fb27SDimitry Andric return __print::__vprint_nonunicode(__stream, __fmt, __args, __write_nl); 25706c3fb27SDimitry Andric 25806c3fb27SDimitry Andric // TODO PRINT Should flush errors throw too? 25906c3fb27SDimitry Andric std::fflush(__stream); 26006c3fb27SDimitry Andric 26106c3fb27SDimitry Andric string __str = std::vformat(__fmt, __args); 26206c3fb27SDimitry Andric // UTF-16 uses the same number or less code units than UTF-8. 26306c3fb27SDimitry Andric // However the size of the code unit is 16 bits instead of 8 bits. 26406c3fb27SDimitry Andric // 26506c3fb27SDimitry Andric // The buffer uses the worst-case estimate and should never resize. 26606c3fb27SDimitry Andric // However when the string is large this could lead to OOM. Using a 26706c3fb27SDimitry Andric // smaller size might work, but since the buffer uses a grow factor 26806c3fb27SDimitry Andric // the final size might be larger when the estimate is wrong. 26906c3fb27SDimitry Andric // 27006c3fb27SDimitry Andric // TODO PRINT profile and improve the speed of this code. 27106c3fb27SDimitry Andric __format::__retarget_buffer<wchar_t> __buffer{__str.size()}; 27206c3fb27SDimitry Andric __unicode::__transcode(__str.begin(), __str.end(), __buffer.__make_output_iterator()); 27306c3fb27SDimitry Andric if (__write_nl) 27406c3fb27SDimitry Andric __buffer.push_back(L'\n'); 27506c3fb27SDimitry Andric 27606c3fb27SDimitry Andric [[maybe_unused]] wstring_view __view = __buffer.__view(); 27706c3fb27SDimitry Andric 27806c3fb27SDimitry Andric // The macro _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION is used to change 27906c3fb27SDimitry Andric // the behavior in the test. This is not part of the public API. 28006c3fb27SDimitry Andric# ifdef _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION 28106c3fb27SDimitry Andric _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION(__stream, __view); 282cb14a3feSDimitry Andric# elif defined(_LIBCPP_WIN32API) 28306c3fb27SDimitry Andric std::__write_to_windows_console(__stream, __view); 28406c3fb27SDimitry Andric# else 28506c3fb27SDimitry Andric std::__throw_runtime_error("No defintion of _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION and " 28606c3fb27SDimitry Andric "__write_to_windows_console is not available."); 28706c3fb27SDimitry Andric# endif 28806c3fb27SDimitry Andric} 28906c3fb27SDimitry Andric# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 29006c3fb27SDimitry Andric 29106c3fb27SDimitry Andrictemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). 29206c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline void 29306c3fb27SDimitry Andric__vprint_unicode([[maybe_unused]] FILE* __stream, 29406c3fb27SDimitry Andric [[maybe_unused]] string_view __fmt, 29506c3fb27SDimitry Andric [[maybe_unused]] format_args __args, 29606c3fb27SDimitry Andric [[maybe_unused]] bool __write_nl) { 297*1db9f3b2SDimitry Andric _LIBCPP_ASSERT_NON_NULL(__stream, "__stream must be a valid pointer to an output C stream"); 29806c3fb27SDimitry Andric 29906c3fb27SDimitry Andric // [print.fun] 30006c3fb27SDimitry Andric // 7 - Effects: If stream refers to a terminal capable of displaying 30106c3fb27SDimitry Andric // Unicode, writes out to the terminal using the native Unicode 30206c3fb27SDimitry Andric // API; if out contains invalid code units, the behavior is 30306c3fb27SDimitry Andric // undefined and implementations are encouraged to diagnose it. 30406c3fb27SDimitry Andric // Otherwise writes out to stream unchanged. If the native 30506c3fb27SDimitry Andric // Unicode API is used, the function flushes stream before 30606c3fb27SDimitry Andric // writing out. 30706c3fb27SDimitry Andric // 8 - Throws: Any exception thrown by the call to vformat 30806c3fb27SDimitry Andric // ([format.err.report]). system_error if writing to the terminal 30906c3fb27SDimitry Andric // or stream fails. May throw bad_alloc. 31006c3fb27SDimitry Andric // 9 - Recommended practice: If invoking the native Unicode API 31106c3fb27SDimitry Andric // requires transcoding, implementations should substitute 31206c3fb27SDimitry Andric // invalid code units with U+FFFD replacement character per the 31306c3fb27SDimitry Andric // Unicode Standard, Chapter 3.9 U+FFFD Substitution in 31406c3fb27SDimitry Andric // Conversion. 31506c3fb27SDimitry Andric 31606c3fb27SDimitry Andric // On non-Windows platforms the Unicode API is the normal file I/O API 31706c3fb27SDimitry Andric // so there the call can be forwarded to the non_unicode API. On 31806c3fb27SDimitry Andric // Windows there is a different API. This API requires transcoding. 31906c3fb27SDimitry Andric 320cb14a3feSDimitry Andric# ifndef _LIBCPP_WIN32API 32106c3fb27SDimitry Andric __print::__vprint_unicode_posix(__stream, __fmt, __args, __write_nl, __print::__is_terminal(__stream)); 32206c3fb27SDimitry Andric# elif !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS) 32306c3fb27SDimitry Andric __print::__vprint_unicode_windows(__stream, __fmt, __args, __write_nl, __print::__is_terminal(__stream)); 32406c3fb27SDimitry Andric# else 32506c3fb27SDimitry Andric# error "Windows builds with wchar_t disabled are not supported." 32606c3fb27SDimitry Andric# endif 32706c3fb27SDimitry Andric} 32806c3fb27SDimitry Andric 32906c3fb27SDimitry Andric# endif // _LIBCPP_HAS_NO_UNICODE 33006c3fb27SDimitry Andric 33106c3fb27SDimitry Andric} // namespace __print 33206c3fb27SDimitry Andric 33306c3fb27SDimitry Andrictemplate <class... _Args> 33406c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI void print(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) { 33506c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_UNICODE 33606c3fb27SDimitry Andric if constexpr (__print::__use_unicode) 33706c3fb27SDimitry Andric __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), false); 33806c3fb27SDimitry Andric else 33906c3fb27SDimitry Andric __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), false); 34006c3fb27SDimitry Andric# else // _LIBCPP_HAS_NO_UNICODE 34106c3fb27SDimitry Andric __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), false); 34206c3fb27SDimitry Andric# endif // _LIBCPP_HAS_NO_UNICODE 34306c3fb27SDimitry Andric} 34406c3fb27SDimitry Andric 34506c3fb27SDimitry Andrictemplate <class... _Args> 34606c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI void print(format_string<_Args...> __fmt, _Args&&... __args) { 34706c3fb27SDimitry Andric std::print(stdout, __fmt, std::forward<_Args>(__args)...); 34806c3fb27SDimitry Andric} 34906c3fb27SDimitry Andric 35006c3fb27SDimitry Andrictemplate <class... _Args> 35106c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) { 35206c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_UNICODE 35306c3fb27SDimitry Andric // Note the wording in the Standard is inefficient. The output of 35406c3fb27SDimitry Andric // std::format is a std::string which is then copied. This solution 35506c3fb27SDimitry Andric // just appends a newline at the end of the output. 35606c3fb27SDimitry Andric if constexpr (__print::__use_unicode) 35706c3fb27SDimitry Andric __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), true); 35806c3fb27SDimitry Andric else 35906c3fb27SDimitry Andric __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), true); 36006c3fb27SDimitry Andric# else // _LIBCPP_HAS_NO_UNICODE 36106c3fb27SDimitry Andric __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), true); 36206c3fb27SDimitry Andric# endif // _LIBCPP_HAS_NO_UNICODE 36306c3fb27SDimitry Andric} 36406c3fb27SDimitry Andric 36506c3fb27SDimitry Andrictemplate <class... _Args> 36606c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI void println(format_string<_Args...> __fmt, _Args&&... __args) { 36706c3fb27SDimitry Andric std::println(stdout, __fmt, std::forward<_Args>(__args)...); 36806c3fb27SDimitry Andric} 36906c3fb27SDimitry Andric 37006c3fb27SDimitry Andric# ifndef _LIBCPP_HAS_NO_UNICODE 37106c3fb27SDimitry Andrictemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). 37206c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(FILE* __stream, string_view __fmt, format_args __args) { 37306c3fb27SDimitry Andric __print::__vprint_unicode(__stream, __fmt, __args, false); 37406c3fb27SDimitry Andric} 37506c3fb27SDimitry Andric 37606c3fb27SDimitry Andrictemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). 37706c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(string_view __fmt, format_args __args) { 37806c3fb27SDimitry Andric std::vprint_unicode(stdout, __fmt, __args); 37906c3fb27SDimitry Andric} 38006c3fb27SDimitry Andric 38106c3fb27SDimitry Andric# endif // _LIBCPP_HAS_NO_UNICODE 38206c3fb27SDimitry Andric 38306c3fb27SDimitry Andrictemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). 38406c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args) { 38506c3fb27SDimitry Andric __print::__vprint_nonunicode(__stream, __fmt, __args, false); 38606c3fb27SDimitry Andric} 38706c3fb27SDimitry Andric 38806c3fb27SDimitry Andrictemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563). 38906c3fb27SDimitry Andric_LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(string_view __fmt, format_args __args) { 39006c3fb27SDimitry Andric std::vprint_nonunicode(stdout, __fmt, __args); 39106c3fb27SDimitry Andric} 39206c3fb27SDimitry Andric 39306c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 23 39406c3fb27SDimitry Andric 39506c3fb27SDimitry Andric_LIBCPP_END_NAMESPACE_STD 39606c3fb27SDimitry Andric 39706c3fb27SDimitry Andric#endif // _LIBCPP_PRINT 398