Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/c++/v1/print is written in an unsupported language. File is not indexed.

0001 // -*- C++ -*-
0002 //===----------------------------------------------------------------------===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009 
0010 #ifndef _LIBCPP_PRINT
0011 #define _LIBCPP_PRINT
0012 
0013 /*
0014 namespace std {
0015   // [print.fun], print functions
0016   template<class... Args>
0017     void print(format_string<Args...> fmt, Args&&... args);
0018   void println();                                                          // Since C++26
0019   template<class... Args>
0020     void print(FILE* stream, format_string<Args...> fmt, Args&&... args);
0021   void println(FILE* stream);                                              // Since C++26
0022 
0023   template<class... Args>
0024     void println(format_string<Args...> fmt, Args&&... args);
0025   template<class... Args>
0026     void println(FILE* stream, format_string<Args...> fmt, Args&&... args);
0027 
0028   void vprint_unicode(string_view fmt, format_args args);
0029   void vprint_unicode(FILE* stream, string_view fmt, format_args args);
0030 
0031   void vprint_nonunicode(string_view fmt, format_args args);
0032   void vprint_nonunicode(FILE* stream, string_view fmt, format_args args);
0033 }
0034 */
0035 
0036 #if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
0037 #  include <__cxx03/print>
0038 #else
0039 #  include <__assert>
0040 #  include <__concepts/same_as.h>
0041 #  include <__config>
0042 #  include <__system_error/throw_system_error.h>
0043 #  include <__utility/forward.h>
0044 #  include <cerrno>
0045 #  include <cstdio>
0046 #  include <format>
0047 #  include <string>
0048 #  include <string_view>
0049 #  include <version>
0050 
0051 #  if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0052 #    pragma GCC system_header
0053 #  endif
0054 
0055 _LIBCPP_BEGIN_NAMESPACE_STD
0056 
0057 #  ifdef _LIBCPP_WIN32API
0058 _LIBCPP_EXPORTED_FROM_ABI bool __is_windows_terminal(FILE* __stream);
0059 
0060 #    if _LIBCPP_HAS_WIDE_CHARACTERS
0061 // A wrapper for WriteConsoleW which is used to write to the Windows
0062 // console. This function is in the dylib to avoid pulling in windows.h
0063 // in the library headers. The function itself uses some private parts
0064 // of the dylib too.
0065 //
0066 // The function does not depend on the language standard used. Guarding
0067 // it with C++23 would fail since the dylib is currently built using C++20.
0068 //
0069 // Note the function is only implemented on the Windows platform.
0070 _LIBCPP_EXPORTED_FROM_ABI void __write_to_windows_console(FILE* __stream, wstring_view __view);
0071 #    endif // _LIBCPP_HAS_WIDE_CHARACTERS
0072 #  elif __has_include(<unistd.h>)
0073 _LIBCPP_EXPORTED_FROM_ABI bool __is_posix_terminal(FILE* __stream);
0074 #  endif // _LIBCPP_WIN32API
0075 
0076 #  if _LIBCPP_STD_VER >= 23
0077 
0078 #    if _LIBCPP_HAS_UNICODE
0079 // This is the code to transcode UTF-8 to UTF-16. This is used on
0080 // Windows for the native Unicode API. The code is modeled to make it
0081 // easier to extend to
0082 //
0083 //  P2728R0 Unicode in the Library, Part 1: UTF Transcoding
0084 //
0085 // This paper is still under heavy development so it makes no sense yet
0086 // to strictly follow the paper.
0087 namespace __unicode {
0088 
0089 // The names of these concepts are modelled after P2728R0, but the
0090 // implementation is not. char16_t may contain 32-bits so depending on the
0091 // number of bits is an issue.
0092 #      ifdef _LIBCPP_SHORT_WCHAR
0093 template <class _Tp>
0094 concept __utf16_code_unit =
0095     same_as<_Tp, char16_t>
0096 #        if _LIBCPP_HAS_WIDE_CHARACTERS
0097     || same_as<_Tp, wchar_t>
0098 #        endif
0099     ;
0100 template <class _Tp>
0101 concept __utf32_code_unit = same_as<_Tp, char32_t>;
0102 #      else // _LIBCPP_SHORT_WCHAR
0103 template <class _Tp>
0104 concept __utf16_code_unit = same_as<_Tp, char16_t>;
0105 template <class _Tp>
0106 concept __utf32_code_unit =
0107     same_as<_Tp, char32_t>
0108 #        if _LIBCPP_HAS_WIDE_CHARACTERS
0109     || same_as<_Tp, wchar_t>
0110 #        endif
0111     ;
0112 #      endif // _LIBCPP_SHORT_WCHAR
0113 
0114 // Pass by reference since an output_iterator may not be copyable.
0115 template <class _OutIt>
0116 _LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt&, char32_t) = delete;
0117 
0118 template <class _OutIt>
0119   requires __utf16_code_unit<iter_value_t<_OutIt>>
0120 _LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt& __out_it, char32_t __value) {
0121   // [print.fun]/7 : "if `out` contains invalid code units, the behavior is undefined and implementations are encouraged
0122   // to diagnose it".
0123   _LIBCPP_ASSERT_UNCATEGORIZED(__is_scalar_value(__value), "an invalid unicode scalar value results in invalid UTF-16");
0124 
0125   if (__value < 0x10000) {
0126     *__out_it++ = __value;
0127     return;
0128   }
0129 
0130   __value -= 0x10000;
0131   *__out_it++ = 0xd800 + (__value >> 10);
0132   *__out_it++ = 0xdc00 + (__value & 0x3FF);
0133 }
0134 
0135 template <class _OutIt>
0136   requires __utf32_code_unit<iter_value_t<_OutIt>>
0137 _LIBCPP_HIDE_FROM_ABI constexpr void __encode(_OutIt& __out_it, char32_t __value) {
0138   // [print.fun]/7 : "if `out` contains invalid code units, the behavior is undefined and implementations are encouraged
0139   // to diagnose it".
0140   _LIBCPP_ASSERT_UNCATEGORIZED(__is_scalar_value(__value), "an invalid unicode scalar value results in invalid UTF-32");
0141   *__out_it++ = __value;
0142 }
0143 
0144 template <class _OutIt, input_iterator _InIt>
0145   requires output_iterator<_OutIt, const iter_value_t<_OutIt>&> && (!same_as<iter_value_t<_OutIt>, iter_value_t<_InIt>>)
0146 _LIBCPP_HIDE_FROM_ABI constexpr _OutIt __transcode(_InIt __first, _InIt __last, _OutIt __out_it) {
0147   // The __code_point_view has a basic_string_view interface.
0148   // When transcoding becomes part of the standard we probably want to
0149   // look at smarter algorithms.
0150   // For example, when processing a code point that is encoded in
0151   // 1 to 3 code units in UTF-8, the result will always be encoded
0152   // in 1 code unit in UTF-16 (code points that require 4 code
0153   // units in UTF-8 will require 2 code units in UTF-16).
0154   //
0155   // Note if P2728 is accepted types like int may become valid. In that case
0156   // the __code_point_view should use a span. Libc++ will remove support for
0157   // char_traits<int>.
0158 
0159   // TODO PRINT Validate with clang-tidy
0160   // NOLINTNEXTLINE(bugprone-dangling-handle)
0161   basic_string_view<iter_value_t<_InIt>> __data{__first, __last};
0162   __code_point_view<iter_value_t<_InIt>> __view{__data.begin(), __data.end()};
0163   while (!__view.__at_end())
0164     __unicode::__encode(__out_it, __view.__consume().__code_point);
0165   return __out_it;
0166 }
0167 
0168 } // namespace __unicode
0169 
0170 #    endif //  _LIBCPP_HAS_UNICODE
0171 
0172 namespace __print {
0173 
0174 // [print.fun]/2
0175 //   Effects: If the ordinary literal encoding ([lex.charset]) is UTF-8, equivalent to:
0176 //     vprint_unicode(stream, fmt.str, make_format_args(args...));
0177 //   Otherwise, equivalent to:
0178 //     vprint_nonunicode(stream, fmt.str, make_format_args(args...));
0179 //
0180 // Based on the compiler and its compilation flags this value is or is
0181 // not true. As mentioned in P2093R14 this only affects Windows. The
0182 // test below could also be done for
0183 // - GCC using __GNUC_EXECUTION_CHARSET_NAME
0184 //   https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
0185 // - Clang using __clang_literal_encoding__
0186 //   https://clang.llvm.org/docs/LanguageExtensions.html#builtin-macros
0187 //   (note at the time of writing Clang is hard-coded to UTF-8.)
0188 //
0189 
0190 #    if !_LIBCPP_HAS_UNICODE
0191 inline constexpr bool __use_unicode_execution_charset = false;
0192 #    elif defined(_MSVC_EXECUTION_CHARACTER_SET)
0193 // This is the same test MSVC STL uses in their implementation of <print>
0194 // See: https://learn.microsoft.com/en-us/windows/win32/intl/code-page-identifiers
0195 inline constexpr bool __use_unicode_execution_charset = _MSVC_EXECUTION_CHARACTER_SET == 65001;
0196 #    else
0197 inline constexpr bool __use_unicode_execution_charset = true;
0198 #    endif
0199 
0200 _LIBCPP_HIDE_FROM_ABI inline bool __is_terminal([[maybe_unused]] FILE* __stream) {
0201   // The macro _LIBCPP_TESTING_PRINT_IS_TERMINAL is used to change
0202   // the behavior in the test. This is not part of the public API.
0203 #    ifdef _LIBCPP_TESTING_PRINT_IS_TERMINAL
0204   return _LIBCPP_TESTING_PRINT_IS_TERMINAL(__stream);
0205 #    elif _LIBCPP_AVAILABILITY_HAS_PRINT == 0 || !_LIBCPP_HAS_TERMINAL
0206   return false;
0207 #    elif defined(_LIBCPP_WIN32API)
0208   return std::__is_windows_terminal(__stream);
0209 #    elif __has_include(<unistd.h>)
0210   return std::__is_posix_terminal(__stream);
0211 #    else
0212 #      error "Provide a way to determine whether a FILE* is a terminal"
0213 #    endif
0214 }
0215 
0216 template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
0217 _LIBCPP_HIDE_FROM_ABI inline void
0218 __vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl) {
0219   _LIBCPP_ASSERT_NON_NULL(__stream, "__stream must be a valid pointer to an output C stream");
0220   string __str = std::vformat(__fmt, __args);
0221   if (__write_nl)
0222     __str.push_back('\n');
0223 
0224   size_t __size = fwrite(__str.data(), 1, __str.size(), __stream);
0225   if (__size < __str.size()) {
0226     if (std::feof(__stream))
0227       std::__throw_system_error(EIO, "EOF while writing the formatted output");
0228     std::__throw_system_error(std::ferror(__stream), "failed to write formatted output");
0229   }
0230 }
0231 
0232 #    if _LIBCPP_HAS_UNICODE
0233 
0234 // Note these helper functions are mainly used to aid testing.
0235 // On POSIX systems and Windows the output is no longer considered a
0236 // terminal when the output is redirected. Typically during testing the
0237 // output is redirected to be able to capture it. This makes it hard to
0238 // test this code path.
0239 template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
0240 _LIBCPP_HIDE_FROM_ABI inline void
0241 __vprint_unicode_posix(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl, bool __is_terminal) {
0242   // TODO PRINT Should flush errors throw too?
0243   if (__is_terminal)
0244     std::fflush(__stream);
0245 
0246   __print::__vprint_nonunicode(__stream, __fmt, __args, __write_nl);
0247 }
0248 
0249 #      if _LIBCPP_HAS_WIDE_CHARACTERS
0250 template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
0251 _LIBCPP_HIDE_FROM_ABI inline void
0252 __vprint_unicode_windows(FILE* __stream, string_view __fmt, format_args __args, bool __write_nl, bool __is_terminal) {
0253   if (!__is_terminal)
0254     return __print::__vprint_nonunicode(__stream, __fmt, __args, __write_nl);
0255 
0256   // TODO PRINT Should flush errors throw too?
0257   std::fflush(__stream);
0258 
0259   string __str = std::vformat(__fmt, __args);
0260   // UTF-16 uses the same number or less code units than UTF-8.
0261   // However the size of the code unit is 16 bits instead of 8 bits.
0262   //
0263   // The buffer uses the worst-case estimate and should never resize.
0264   // However when the string is large this could lead to OOM. Using a
0265   // smaller size might work, but since the buffer uses a grow factor
0266   // the final size might be larger when the estimate is wrong.
0267   //
0268   // TODO PRINT profile and improve the speed of this code.
0269   __format::__retarget_buffer<wchar_t> __buffer{__str.size()};
0270   __unicode::__transcode(__str.begin(), __str.end(), __buffer.__make_output_iterator());
0271   if (__write_nl)
0272     __buffer.push_back(L'\n');
0273 
0274   [[maybe_unused]] wstring_view __view = __buffer.__view();
0275 
0276   // The macro _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION is used to change
0277   // the behavior in the test. This is not part of the public API.
0278 #        ifdef _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION
0279   _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION(__stream, __view);
0280 #        elif defined(_LIBCPP_WIN32API)
0281   std::__write_to_windows_console(__stream, __view);
0282 #        else
0283   std::__throw_runtime_error("No defintion of _LIBCPP_TESTING_PRINT_WRITE_TO_WINDOWS_CONSOLE_FUNCTION and "
0284                              "__write_to_windows_console is not available.");
0285 #        endif
0286 }
0287 #      endif // _LIBCPP_HAS_WIDE_CHARACTERS
0288 
0289 template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
0290 _LIBCPP_HIDE_FROM_ABI inline void
0291 __vprint_unicode([[maybe_unused]] FILE* __stream,
0292                  [[maybe_unused]] string_view __fmt,
0293                  [[maybe_unused]] format_args __args,
0294                  [[maybe_unused]] bool __write_nl) {
0295   _LIBCPP_ASSERT_NON_NULL(__stream, "__stream must be a valid pointer to an output C stream");
0296 
0297   // [print.fun]
0298   //   7 - Effects: If stream refers to a terminal capable of displaying
0299   //       Unicode, writes out to the terminal using the native Unicode
0300   //       API; if out contains invalid code units, the behavior is
0301   //       undefined and implementations are encouraged to diagnose it.
0302   //       Otherwise writes out to stream unchanged. If the native
0303   //       Unicode API is used, the function flushes stream before
0304   //       writing out.
0305   //   8 - Throws: Any exception thrown by the call to vformat
0306   //       ([format.err.report]). system_error if writing to the terminal
0307   //       or stream fails. May throw bad_alloc.
0308   //   9 - Recommended practice: If invoking the native Unicode API
0309   //       requires transcoding, implementations should substitute
0310   //       invalid code units with U+FFFD replacement character per the
0311   //       Unicode Standard, Chapter 3.9 U+FFFD Substitution in
0312   //       Conversion.
0313 
0314   // On non-Windows platforms the Unicode API is the normal file I/O API
0315   // so there the call can be forwarded to the non_unicode API. On
0316   // Windows there is a different API. This API requires transcoding.
0317 
0318 #      ifndef _LIBCPP_WIN32API
0319   __print::__vprint_unicode_posix(__stream, __fmt, __args, __write_nl, __print::__is_terminal(__stream));
0320 #      elif _LIBCPP_HAS_WIDE_CHARACTERS
0321   __print::__vprint_unicode_windows(__stream, __fmt, __args, __write_nl, __print::__is_terminal(__stream));
0322 #      else
0323 #        error "Windows builds with wchar_t disabled are not supported."
0324 #      endif
0325 }
0326 
0327 #    endif // _LIBCPP_HAS_UNICODE
0328 
0329 } // namespace __print
0330 
0331 template <class... _Args>
0332 _LIBCPP_HIDE_FROM_ABI void print(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) {
0333 #    if _LIBCPP_HAS_UNICODE
0334   if constexpr (__print::__use_unicode_execution_charset)
0335     __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
0336   else
0337     __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
0338 #    else  // _LIBCPP_HAS_UNICODE
0339   __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), false);
0340 #    endif // _LIBCPP_HAS_UNICODE
0341 }
0342 
0343 template <class... _Args>
0344 _LIBCPP_HIDE_FROM_ABI void print(format_string<_Args...> __fmt, _Args&&... __args) {
0345   std::print(stdout, __fmt, std::forward<_Args>(__args)...);
0346 }
0347 
0348 template <class... _Args>
0349 _LIBCPP_HIDE_FROM_ABI void println(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) {
0350 #    if _LIBCPP_HAS_UNICODE
0351   // Note the wording in the Standard is inefficient. The output of
0352   // std::format is a std::string which is then copied. This solution
0353   // just appends a newline at the end of the output.
0354   if constexpr (__print::__use_unicode_execution_charset)
0355     __print::__vprint_unicode(__stream, __fmt.get(), std::make_format_args(__args...), true);
0356   else
0357     __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), true);
0358 #    else  // _LIBCPP_HAS_UNICODE
0359   __print::__vprint_nonunicode(__stream, __fmt.get(), std::make_format_args(__args...), true);
0360 #    endif // _LIBCPP_HAS_UNICODE
0361 }
0362 
0363 template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
0364 _LIBCPP_HIDE_FROM_ABI inline void println(FILE* __stream) {
0365   std::print(__stream, "\n");
0366 }
0367 
0368 template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
0369 _LIBCPP_HIDE_FROM_ABI inline void println() {
0370   println(stdout);
0371 }
0372 
0373 template <class... _Args>
0374 _LIBCPP_HIDE_FROM_ABI void println(format_string<_Args...> __fmt, _Args&&... __args) {
0375   std::println(stdout, __fmt, std::forward<_Args>(__args)...);
0376 }
0377 
0378 #    if _LIBCPP_HAS_UNICODE
0379 template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
0380 _LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(FILE* __stream, string_view __fmt, format_args __args) {
0381   __print::__vprint_unicode(__stream, __fmt, __args, false);
0382 }
0383 
0384 template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
0385 _LIBCPP_HIDE_FROM_ABI inline void vprint_unicode(string_view __fmt, format_args __args) {
0386   std::vprint_unicode(stdout, __fmt, __args);
0387 }
0388 
0389 #    endif // _LIBCPP_HAS_UNICODE
0390 
0391 template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
0392 _LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(FILE* __stream, string_view __fmt, format_args __args) {
0393   __print::__vprint_nonunicode(__stream, __fmt, __args, false);
0394 }
0395 
0396 template <class = void> // TODO PRINT template or availability markup fires too eagerly (http://llvm.org/PR61563).
0397 _LIBCPP_HIDE_FROM_ABI inline void vprint_nonunicode(string_view __fmt, format_args __args) {
0398   std::vprint_nonunicode(stdout, __fmt, __args);
0399 }
0400 
0401 #  endif // _LIBCPP_STD_VER >= 23
0402 
0403 _LIBCPP_END_NAMESPACE_STD
0404 
0405 #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)
0406 
0407 #endif // _LIBCPP_PRINT