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