xref: /llvm-project/libcxx/include/print (revision b9a2658a3e8bd13b0f9e7a8a440832a95b377216)
120341c3aSMark de Wever// -*- C++ -*-
220341c3aSMark de Wever//===----------------------------------------------------------------------===//
320341c3aSMark de Wever//
420341c3aSMark de Wever// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
520341c3aSMark de Wever// See https://llvm.org/LICENSE.txt for license information.
620341c3aSMark de Wever// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
720341c3aSMark de Wever//
820341c3aSMark de Wever//===----------------------------------------------------------------------===//
920341c3aSMark de Wever
1020341c3aSMark de Wever#ifndef _LIBCPP_PRINT
1120341c3aSMark de Wever#define _LIBCPP_PRINT
1220341c3aSMark de Wever
133f65f718SMark de Wever/*
143f65f718SMark de Wevernamespace std {
153f65f718SMark de Wever  // [print.fun], print functions
163f65f718SMark de Wever  template<class... Args>
17e2953303SMark de Wever    void print(format_string<Args...> fmt, Args&&... args);
187f9f82e3SHristo Hristov  void println();                                                          // Since C++26
19e2953303SMark de Wever  template<class... Args>
203f65f718SMark de Wever    void print(FILE* stream, format_string<Args...> fmt, Args&&... args);
217f9f82e3SHristo Hristov  void println(FILE* stream);                                              // Since C++26
223f65f718SMark de Wever
233f65f718SMark de Wever  template<class... Args>
24e2953303SMark de Wever    void println(format_string<Args...> fmt, Args&&... args);
25e2953303SMark de Wever  template<class... Args>
263f65f718SMark de Wever    void println(FILE* stream, format_string<Args...> fmt, Args&&... args);
273f65f718SMark de Wever
28e2953303SMark de Wever  void vprint_unicode(string_view fmt, format_args args);
293f65f718SMark de Wever  void vprint_unicode(FILE* stream, string_view fmt, format_args args);
303f65f718SMark de Wever
31e2953303SMark de Wever  void vprint_nonunicode(string_view fmt, format_args args);
323f65f718SMark de Wever  void vprint_nonunicode(FILE* stream, string_view fmt, format_args args);
333f65f718SMark de Wever}
343f65f718SMark de Wever*/
353f65f718SMark de Wever
36*b9a2658aSNikolas Klauser#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
37*b9a2658aSNikolas Klauser#  include <__cxx03/print>
38*b9a2658aSNikolas Klauser#else
3937dca605SLouis Dionne#  include <__assert>
4020341c3aSMark de Wever#  include <__concepts/same_as.h>
4120341c3aSMark de Wever#  include <__config>
42dedc5159SNikolas Klauser#  include <__system_error/throw_system_error.h>
433f65f718SMark de Wever#  include <__utility/forward.h>
443f65f718SMark de Wever#  include <cerrno>
453f65f718SMark de Wever#  include <cstdio>
4682d21814SMark de Wever#  include <format>
473f65f718SMark de Wever#  include <string>
4820341c3aSMark de Wever#  include <string_view>
4920341c3aSMark de Wever#  include <version>
5020341c3aSMark de Wever
5120341c3aSMark de Wever#  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
5220341c3aSMark de Wever#    pragma GCC system_header
5320341c3aSMark de Wever#  endif
5420341c3aSMark de Wever
5520341c3aSMark de Wever_LIBCPP_BEGIN_NAMESPACE_STD
5620341c3aSMark de Wever
572fd4084fSMark de Wever#  ifdef _LIBCPP_WIN32API
583f65f718SMark de Wever_LIBCPP_EXPORTED_FROM_ABI bool __is_windows_terminal(FILE* __stream);
593f65f718SMark de Wever
60c6f3b7bcSNikolas Klauser#    if _LIBCPP_HAS_WIDE_CHARACTERS
613f65f718SMark de Wever// A wrapper for WriteConsoleW which is used to write to the Windows
623f65f718SMark de Wever// console. This function is in the dylib to avoid pulling in windows.h
633f65f718SMark de Wever// in the library headers. The function itself uses some private parts
643f65f718SMark de Wever// of the dylib too.
653f65f718SMark de Wever//
663f65f718SMark de Wever// The function does not depend on the language standard used. Guarding
673f65f718SMark de Wever// it with C++23 would fail since the dylib is currently built using C++20.
683f65f718SMark de Wever//
693f65f718SMark de Wever// Note the function is only implemented on the Windows platform.
703f65f718SMark de Wever_LIBCPP_EXPORTED_FROM_ABI void __write_to_windows_console(FILE* __stream, wstring_view __view);
71c6f3b7bcSNikolas Klauser#    endif // _LIBCPP_HAS_WIDE_CHARACTERS
724fb7b330SMark de Wever#  elif __has_include(<unistd.h>)
734fb7b330SMark de Wever_LIBCPP_EXPORTED_FROM_ABI bool __is_posix_terminal(FILE* __stream);
742fd4084fSMark de Wever#  endif // _LIBCPP_WIN32API
753f65f718SMark de Wever
7620341c3aSMark de Wever#  if _LIBCPP_STD_VER >= 23
7720341c3aSMark de Wever
78c6f3b7bcSNikolas Klauser#    if _LIBCPP_HAS_UNICODE
7920341c3aSMark de Wever// This is the code to transcode UTF-8 to UTF-16. This is used on
8020341c3aSMark de Wever// Windows for the native Unicode API. The code is modeled to make it
8120341c3aSMark de Wever// easier to extend to
8220341c3aSMark de Wever//
8320341c3aSMark de Wever//  P2728R0 Unicode in the Library, Part 1: UTF Transcoding
8420341c3aSMark de Wever//
8520341c3aSMark de Wever// This paper is still under heavy development so it makes no sense yet
8620341c3aSMark de Wever// to strictly follow the paper.
8720341c3aSMark de Wevernamespace __unicode {
8820341c3aSMark de Wever
8920341c3aSMark de Wever// The names of these concepts are modelled after P2728R0, but the
9020341c3aSMark de Wever// implementation is not. char16_t may contain 32-bits so depending on the
9120341c3aSMark de Wever// number of bits is an issue.
9220341c3aSMark de Wever#      ifdef _LIBCPP_SHORT_WCHAR
9320341c3aSMark de Wevertemplate <class _Tp>
9420341c3aSMark de Weverconcept __utf16_code_unit =
9520341c3aSMark de Wever    same_as<_Tp, char16_t>
96c6f3b7bcSNikolas Klauser#        if _LIBCPP_HAS_WIDE_CHARACTERS
9720341c3aSMark de Wever    || same_as<_Tp, wchar_t>
9820341c3aSMark de Wever#        endif
9920341c3aSMark de Wever    ;
10020341c3aSMark de Wevertemplate <class _Tp>
10120341c3aSMark de Weverconcept __utf32_code_unit = same_as<_Tp, char32_t>;
10220341c3aSMark de Wever#      else // _LIBCPP_SHORT_WCHAR
10320341c3aSMark de Wevertemplate <class _Tp>
10420341c3aSMark de Weverconcept __utf16_code_unit = same_as<_Tp, char16_t>;
10520341c3aSMark de Wevertemplate <class _Tp>
10620341c3aSMark de Weverconcept __utf32_code_unit =
10720341c3aSMark de Wever    same_as<_Tp, char32_t>
108c6f3b7bcSNikolas Klauser#        if _LIBCPP_HAS_WIDE_CHARACTERS
10920341c3aSMark de Wever    || same_as<_Tp, wchar_t>
11020341c3aSMark de Wever#        endif
11120341c3aSMark de Wever    ;
11220341c3aSMark de Wever#      endif // _LIBCPP_SHORT_WCHAR
11320341c3aSMark de Wever
11420341c3aSMark de Wever// Pass by reference since an output_iterator may not be copyable.
11520341c3aSMark de Wevertemplate <class _OutIt>
11620341c3aSMark de Wever_LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt&, char32_t) = delete;
11720341c3aSMark de Wever
11820341c3aSMark de Wevertemplate <class _OutIt>
11920341c3aSMark de Wever  requires __utf16_code_unit<iter_value_t<_OutIt>>
12020341c3aSMark de Wever_LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt& __out_it, char32_t __value) {
1214f215fddSKonstantin Varlamov  // [print.fun]/7 : "if `out` contains invalid code units, the behavior is undefined and implementations are encouraged
1224f215fddSKonstantin Varlamov  // to diagnose it".
1233f65f718SMark de Wever  _LIBCPP_ASSERT_UNCATEGORIZED(__is_scalar_value(__value), "an invalid unicode scalar value results in invalid UTF-16");
12420341c3aSMark de Wever
12520341c3aSMark de Wever  if (__value < 0x10000) {
12620341c3aSMark de Wever    *__out_it++ = __value;
12720341c3aSMark de Wever    return;
12820341c3aSMark de Wever  }
12920341c3aSMark de Wever
13020341c3aSMark de Wever  __value -= 0x10000;
13120341c3aSMark de Wever  *__out_it++ = 0xd800 + (__value >> 10);
13220341c3aSMark de Wever  *__out_it++ = 0xdc00 + (__value & 0x3FF);
13320341c3aSMark de Wever}
13420341c3aSMark de Wever
13520341c3aSMark de Wevertemplate <class _OutIt>
13620341c3aSMark de Wever  requires __utf32_code_unit<iter_value_t<_OutIt>>
13720341c3aSMark de Wever_LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt& __out_it, char32_t __value) {
1384f215fddSKonstantin Varlamov  // [print.fun]/7 : "if `out` contains invalid code units, the behavior is undefined and implementations are encouraged
1394f215fddSKonstantin Varlamov  // to diagnose it".
1403f65f718SMark de Wever  _LIBCPP_ASSERT_UNCATEGORIZED(__is_scalar_value(__value), "an invalid unicode scalar value results in invalid UTF-32");
14120341c3aSMark de Wever  *__out_it++ = __value;
14220341c3aSMark de Wever}
14320341c3aSMark de Wever
14420341c3aSMark de Wevertemplate <class _OutIt, input_iterator _InIt>
14520341c3aSMark de Wever  requires output_iterator<_OutIt, const iter_value_t<_OutIt>&> && (!same_as<iter_value_t<_OutIt>, iter_value_t<_InIt>>)
14620341c3aSMark de Wever_LIBCPP_HIDE_FROM_ABI constexpr _OutIt __transcode(_InIt __first, _InIt __last, _OutIt __out_it) {
14720341c3aSMark de Wever  // The __code_point_view has a basic_string_view interface.
14820341c3aSMark de Wever  // When transcoding becomes part of the standard we probably want to
14920341c3aSMark de Wever  // look at smarter algorithms.
15020341c3aSMark de Wever  // For example, when processing a code point that is encoded in
15120341c3aSMark de Wever  // 1 to 3 code units in UTF-8, the result will always be encoded
15220341c3aSMark de Wever  // in 1 code unit in UTF-16 (code points that require 4 code
15320341c3aSMark de Wever  // units in UTF-8 will require 2 code units in UTF-16).
15420341c3aSMark de Wever  //
15520341c3aSMark de Wever  // Note if P2728 is accepted types like int may become valid. In that case
15620341c3aSMark de Wever  // the __code_point_view should use a span. Libc++ will remove support for
15720341c3aSMark de Wever  // char_traits<int>.
1583f65f718SMark de Wever
1593f65f718SMark de Wever  // TODO PRINT Validate with clang-tidy
1603f65f718SMark de Wever  // NOLINTNEXTLINE(bugprone-dangling-handle)
16120341c3aSMark de Wever  basic_string_view<iter_value_t<_InIt>> __data{__first, __last};
16220341c3aSMark de Wever  __code_point_view<iter_value_t<_InIt>> __view{__data.begin(), __data.end()};
16320341c3aSMark de Wever  while (!__view.__at_end())
16420341c3aSMark de Wever    __unicode::__encode(__out_it, __view.__consume().__code_point);
16520341c3aSMark de Wever  return __out_it;
16620341c3aSMark de Wever}
16720341c3aSMark de Wever
16820341c3aSMark de Wever} // namespace __unicode
16920341c3aSMark de Wever
170c6f3b7bcSNikolas Klauser#    endif //  _LIBCPP_HAS_UNICODE
17120341c3aSMark de Wever
1723f65f718SMark de Wevernamespace __print {
1733f65f718SMark de Wever
1743f65f718SMark de Wever// [print.fun]/2
1753f65f718SMark de Wever//   Effects: If the ordinary literal encoding ([lex.charset]) is UTF-8, equivalent to:
1763f65f718SMark de Wever//     vprint_unicode(stream, fmt.str, make_format_args(args...));
1773f65f718SMark de Wever//   Otherwise, equivalent to:
1783f65f718SMark de Wever//     vprint_nonunicode(stream, fmt.str, make_format_args(args...));
1793f65f718SMark de Wever//
1803f65f718SMark de Wever// Based on the compiler and its compilation flags this value is or is
1813f65f718SMark de Wever// not true. As mentioned in P2093R14 this only affects Windows. The
1823f65f718SMark de Wever// test below could also be done for
1833f65f718SMark de Wever// - GCC using __GNUC_EXECUTION_CHARSET_NAME
1843f65f718SMark de Wever//   https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
1853f65f718SMark de Wever// - Clang using __clang_literal_encoding__
1863f65f718SMark de Wever//   https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros
1873f65f718SMark de Wever//   (note at the time of writing Clang is hard-coded to UTF-8.)
1883f65f718SMark de Wever//
1893f65f718SMark de Wever
190c6f3b7bcSNikolas Klauser#    if !_LIBCPP_HAS_UNICODE
191a8b3deb2SMark de Weverinline constexpr bool __use_unicode_execution_charset = false;
1923f65f718SMark de Wever#    elif defined(_MSVC_EXECUTION_CHARACTER_SET)
1933f65f718SMark de Wever// This is the same test MSVC STL uses in their implementation of <print>
1943f65f718SMark de Wever// See: https://learn.microsoft.com/en-us/windows/win32/intl/code-page-identifiers
195a8b3deb2SMark de Weverinline constexpr bool __use_unicode_execution_charset = _MSVC_EXECUTION_CHARACTER_SET == 65001;
1963f65f718SMark de Wever#    else
197a8b3deb2SMark de Weverinline constexpr bool __use_unicode_execution_charset = true;
1983f65f718SMark de Wever#    endif
1993f65f718SMark de Wever
2004fb7b330SMark de Wever_LIBCPP_HIDE_FROM_ABI inline bool __is_terminal([[maybe_unused]] FILE* __stream) {
2012fd4084fSMark de Wever  // The macro _LIBCPP_TESTING_PRINT_IS_TERMINAL is used to change
2022fd4084fSMark de Wever  // the behavior in the test. This is not part of the public API.
2032fd4084fSMark de Wever#    ifdef _LIBCPP_TESTING_PRINT_IS_TERMINAL
2042fd4084fSMark de Wever  return _LIBCPP_TESTING_PRINT_IS_TERMINAL(__stream);
205a9cd941fSJoseph Huber#    elif _LIBCPP_AVAILABILITY_HAS_PRINT == 0 || !_LIBCPP_HAS_TERMINAL
2064fb7b330SMark de Wever  return false;
2072fd4084fSMark de Wever#    elif defined(_LIBCPP_WIN32API)
2083f65f718SMark de Wever  return std::__is_windows_terminal(__stream);
2093f65f718SMark de Wever#    elif __has_include(<unistd.h>)
2104fb7b330SMark de Wever  return std::__is_posix_terminal(__stream);
2113f65f718SMark de Wever#    else
2123f65f718SMark de Wever#      error "Provide a way to determine whether a FILE* is a terminal"
2133f65f718SMark de Wever#    endif
2143f65f718SMark de Wever}
2153f65f718SMark de Wever
2163f65f718SMark de Wevertemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
2173f65f718SMark de Wever_LIBCPP_HIDE_FROM_ABI inline void
2183f65f718SMark de Wever__vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl) {
2194f215fddSKonstantin Varlamov  _LIBCPP_ASSERT_NON_NULL(__stream, "__stream must be a valid pointer to an output C stream");
2203f65f718SMark de Wever  string __str = std::vformat(__fmt, __args);
2213f65f718SMark de Wever  if (__write_nl)
2223f65f718SMark de Wever    __str.push_back('\n');
2233f65f718SMark de Wever
2243f65f718SMark de Wever  size_t __size = fwrite(__str.data(), 1, __str.size(), __stream);
2253f65f718SMark de Wever  if (__size < __str.size()) {
2263f65f718SMark de Wever    if (std::feof(__stream))
2273f65f718SMark de Wever      std::__throw_system_error(EIO, "EOF while writing the formatted output");
2283f65f718SMark de Wever    std::__throw_system_error(std::ferror(__stream), "failed to write formatted output");
2293f65f718SMark de Wever  }
2303f65f718SMark de Wever}
2313f65f718SMark de Wever
232c6f3b7bcSNikolas Klauser#    if _LIBCPP_HAS_UNICODE
2333f65f718SMark de Wever
2343f65f718SMark de Wever// Note these helper functions are mainly used to aid testing.
2353f65f718SMark de Wever// On POSIX systems and Windows the output is no longer considered a
2363f65f718SMark de Wever// terminal when the output is redirected. Typically during testing the
2373f65f718SMark de Wever// output is redirected to be able to capture it. This makes it hard to
2383f65f718SMark de Wever// test this code path.
2393f65f718SMark de Wevertemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
2403f65f718SMark de Wever_LIBCPP_HIDE_FROM_ABI inline void
2413f65f718SMark de Wever__vprint_unicode_posix(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl, bool __is_terminal) {
2423f65f718SMark de Wever  // TODO PRINT Should flush errors throw too?
2433f65f718SMark de Wever  if (__is_terminal)
2443f65f718SMark de Wever    std::fflush(__stream);
2453f65f718SMark de Wever
2463f65f718SMark de Wever  __print::__vprint_nonunicode(__stream, __fmt, __args, __write_nl);
2473f65f718SMark de Wever}
2483f65f718SMark de Wever
249c6f3b7bcSNikolas Klauser#      if _LIBCPP_HAS_WIDE_CHARACTERS
2503f65f718SMark de Wevertemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
2513f65f718SMark de Wever_LIBCPP_HIDE_FROM_ABI inline void
2523f65f718SMark de Wever__vprint_unicode_windows(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl, bool __is_terminal) {
2533f65f718SMark de Wever  if (!__is_terminal)
2543f65f718SMark de Wever    return __print::__vprint_nonunicode(__stream, __fmt, __args, __write_nl);
2553f65f718SMark de Wever
2563f65f718SMark de Wever  // TODO PRINT Should flush errors throw too?
2573f65f718SMark de Wever  std::fflush(__stream);
2583f65f718SMark de Wever
2593f65f718SMark de Wever  string __str = std::vformat(__fmt, __args);
2603f65f718SMark de Wever  // UTF-16 uses the same number or less code units than UTF-8.
2613f65f718SMark de Wever  // However the size of the code unit is 16 bits instead of 8 bits.
2623f65f718SMark de Wever  //
2633f65f718SMark de Wever  // The buffer uses the worst-case estimate and should never resize.
2643f65f718SMark de Wever  // However when the string is large this could lead to OOM. Using a
2653f65f718SMark de Wever  // smaller size might work, but since the buffer uses a grow factor
2663f65f718SMark de Wever  // the final size might be larger when the estimate is wrong.
2673f65f718SMark de Wever  //
2683f65f718SMark de Wever  // TODO PRINT profile and improve the speed of this code.
2693f65f718SMark de Wever  __format::__retarget_buffer<wchar_t> __buffer{__str.size()};
2703f65f718SMark de Wever  __unicode::__transcode(__str.begin(), __str.end(), __buffer.__make_output_iterator());
2713f65f718SMark de Wever  if (__write_nl)
2723f65f718SMark de Wever    __buffer.push_back(L'\n');
2733f65f718SMark de Wever
2743f65f718SMark de Wever  [[maybe_unused]] wstring_view __view = __buffer.__view();
2753f65f718SMark de Wever
2763f65f718SMark de Wever  // The macro _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION is used to change
2773f65f718SMark de Wever  // the behavior in the test. This is not part of the public API.
2783f65f718SMark de Wever#        ifdef _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION
2793f65f718SMark de Wever  _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION(__stream, __view);
2802fd4084fSMark de Wever#        elif defined(_LIBCPP_WIN32API)
2813f65f718SMark de Wever  std::__write_to_windows_console(__stream, __view);
2823f65f718SMark de Wever#        else
2833f65f718SMark de Wever  std::__throw_runtime_error("No defintion of _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION and "
2843f65f718SMark de Wever                             "__write_to_windows_console is not available.");
2853f65f718SMark de Wever#        endif
2863f65f718SMark de Wever}
287c6f3b7bcSNikolas Klauser#      endif // _LIBCPP_HAS_WIDE_CHARACTERS
2883f65f718SMark de Wever
2893f65f718SMark de Wevertemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
2903f65f718SMark de Wever_LIBCPP_HIDE_FROM_ABI inline void
2913f65f718SMark de Wever__vprint_unicode([[maybe_unused]] FILE* __stream,
2923f65f718SMark de Wever                 [[maybe_unused]] string_view __fmt,
2933f65f718SMark de Wever                 [[maybe_unused]] format_args __args,
2943f65f718SMark de Wever                 [[maybe_unused]] bool __write_nl) {
2954f215fddSKonstantin Varlamov  _LIBCPP_ASSERT_NON_NULL(__stream, "__stream must be a valid pointer to an output C stream");
2963f65f718SMark de Wever
2973f65f718SMark de Wever  // [print.fun]
2983f65f718SMark de Wever  //   7 - Effects: If stream refers to a terminal capable of displaying
2993f65f718SMark de Wever  //       Unicode, writes out to the terminal using the native Unicode
3003f65f718SMark de Wever  //       API; if out contains invalid code units, the behavior is
3013f65f718SMark de Wever  //       undefined and implementations are encouraged to diagnose it.
3023f65f718SMark de Wever  //       Otherwise writes out to stream unchanged. If the native
3033f65f718SMark de Wever  //       Unicode API is used, the function flushes stream before
3043f65f718SMark de Wever  //       writing out.
3053f65f718SMark de Wever  //   8 - Throws: Any exception thrown by the call to vformat
3063f65f718SMark de Wever  //       ([format.err.report]). system_error if writing to the terminal
3073f65f718SMark de Wever  //       or stream fails. May throw bad_alloc.
3083f65f718SMark de Wever  //   9 - Recommended practice: If invoking the native Unicode API
3093f65f718SMark de Wever  //       requires transcoding, implementations should substitute
3103f65f718SMark de Wever  //       invalid code units with U+FFFD replacement character per the
3113f65f718SMark de Wever  //       Unicode Standard, Chapter 3.9 U+FFFD Substitution in
3123f65f718SMark de Wever  //       Conversion.
3133f65f718SMark de Wever
3143f65f718SMark de Wever  // On non-Windows platforms the Unicode API is the normal file I/O API
3153f65f718SMark de Wever  // so there the call can be forwarded to the non_unicode API. On
3163f65f718SMark de Wever  // Windows there is a different API. This API requires transcoding.
3173f65f718SMark de Wever
3182fd4084fSMark de Wever#      ifndef _LIBCPP_WIN32API
3193f65f718SMark de Wever  __print::__vprint_unicode_posix(__stream, __fmt, __args, __write_nl, __print::__is_terminal(__stream));
320c6f3b7bcSNikolas Klauser#      elif _LIBCPP_HAS_WIDE_CHARACTERS
3213f65f718SMark de Wever  __print::__vprint_unicode_windows(__stream, __fmt, __args, __write_nl, __print::__is_terminal(__stream));
3223f65f718SMark de Wever#      else
3233f65f718SMark de Wever#        error "Windows builds with wchar_t disabled are not supported."
3243f65f718SMark de Wever#      endif
3253f65f718SMark de Wever}
3263f65f718SMark de Wever
327c6f3b7bcSNikolas Klauser#    endif // _LIBCPP_HAS_UNICODE
3283f65f718SMark de Wever
3293f65f718SMark de Wever} // namespace __print
3303f65f718SMark de Wever
3313f65f718SMark de Wevertemplate <class... _Args>
3323f65f718SMark de Wever_LIBCPP_HIDE_FROM_ABI void print(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) {
333c6f3b7bcSNikolas Klauser#    if _LIBCPP_HAS_UNICODE
334a8b3deb2SMark de Wever  if constexpr (__print::__use_unicode_execution_charset)
3353f65f718SMark de Wever    __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
3363f65f718SMark de Wever  else
3373f65f718SMark de Wever    __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
338c6f3b7bcSNikolas Klauser#    else  // _LIBCPP_HAS_UNICODE
3393f65f718SMark de Wever  __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
340c6f3b7bcSNikolas Klauser#    endif // _LIBCPP_HAS_UNICODE
3413f65f718SMark de Wever}
3423f65f718SMark de Wever
3433f65f718SMark de Wevertemplate <class... _Args>
344e2953303SMark de Wever_LIBCPP_HIDE_FROM_ABI void print(format_string<_Args...> __fmt, _Args&&... __args) {
345e2953303SMark de Wever  std::print(stdout, __fmt, std::forward<_Args>(__args)...);
346e2953303SMark de Wever}
347e2953303SMark de Wever
348e2953303SMark de Wevertemplate <class... _Args>
3493f65f718SMark de Wever_LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) {
350c6f3b7bcSNikolas Klauser#    if _LIBCPP_HAS_UNICODE
3513f65f718SMark de Wever  // Note the wording in the Standard is inefficient. The output of
3523f65f718SMark de Wever  // std::format is a std::string which is then copied. This solution
3533f65f718SMark de Wever  // just appends a newline at the end of the output.
354a8b3deb2SMark de Wever  if constexpr (__print::__use_unicode_execution_charset)
3553f65f718SMark de Wever    __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), true);
3563f65f718SMark de Wever  else
3573f65f718SMark de Wever    __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), true);
358c6f3b7bcSNikolas Klauser#    else  // _LIBCPP_HAS_UNICODE
3593f65f718SMark de Wever  __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), true);
360c6f3b7bcSNikolas Klauser#    endif // _LIBCPP_HAS_UNICODE
3613f65f718SMark de Wever}
3623f65f718SMark de Wever
3637f9f82e3SHristo Hristovtemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
364e2c2ffbeSLouis Dionne_LIBCPP_HIDE_FROM_ABI inline void println(FILE* __stream) {
365e2c2ffbeSLouis Dionne  std::print(__stream, "\n");
366e2c2ffbeSLouis Dionne}
3677f9f82e3SHristo Hristov
3687f9f82e3SHristo Hristovtemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
369e2c2ffbeSLouis Dionne_LIBCPP_HIDE_FROM_ABI inline void println() {
370e2c2ffbeSLouis Dionne  println(stdout);
371e2c2ffbeSLouis Dionne}
3727f9f82e3SHristo Hristov
373e2953303SMark de Wevertemplate <class... _Args>
374e2953303SMark de Wever_LIBCPP_HIDE_FROM_ABI void println(format_string<_Args...> __fmt, _Args&&... __args) {
375e2953303SMark de Wever  std::println(stdout, __fmt, std::forward<_Args>(__args)...);
376e2953303SMark de Wever}
377e2953303SMark de Wever
378c6f3b7bcSNikolas Klauser#    if _LIBCPP_HAS_UNICODE
3793f65f718SMark de Wevertemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
3803f65f718SMark de Wever_LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(FILE* __stream, string_view __fmt, format_args __args) {
3813f65f718SMark de Wever  __print::__vprint_unicode(__stream, __fmt, __args, false);
3823f65f718SMark de Wever}
383e2953303SMark de Wever
384e2953303SMark de Wevertemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
385e2953303SMark de Wever_LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(string_view __fmt, format_args __args) {
386e2953303SMark de Wever  std::vprint_unicode(stdout, __fmt, __args);
387e2953303SMark de Wever}
388e2953303SMark de Wever
389c6f3b7bcSNikolas Klauser#    endif // _LIBCPP_HAS_UNICODE
3903f65f718SMark de Wever
3913f65f718SMark de Wevertemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
3923f65f718SMark de Wever_LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args) {
3933f65f718SMark de Wever  __print::__vprint_nonunicode(__stream, __fmt, __args, false);
3943f65f718SMark de Wever}
3953f65f718SMark de Wever
396e2953303SMark de Wevertemplate <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
397e2953303SMark de Wever_LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(string_view __fmt, format_args __args) {
398e2953303SMark de Wever  std::vprint_nonunicode(stdout, __fmt, __args);
399e2953303SMark de Wever}
400e2953303SMark de Wever
40120341c3aSMark de Wever#  endif // _LIBCPP_STD_VER >= 23
40220341c3aSMark de Wever
40320341c3aSMark de Wever_LIBCPP_END_NAMESPACE_STD
40420341c3aSMark de Wever
405*b9a2658aSNikolas Klauser#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
406c166a9c7SNikolas Klauser
40720341c3aSMark de Wever#endif // _LIBCPP_PRINT
408