ostream.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // Formatting library for C++ - std::ostream support
  2. //
  3. // Copyright (c) 2012 - present, Victor Zverovich
  4. // All rights reserved.
  5. //
  6. // For the license information refer to format.h.
  7. #ifndef FMT_OSTREAM_H_
  8. #define FMT_OSTREAM_H_
  9. #include <ostream>
  10. #include "format.h"
  11. FMT_BEGIN_NAMESPACE
  12. template <typename OutputIt, typename Char> class basic_printf_context;
  13. namespace detail {
  14. // Checks if T has a user-defined operator<<.
  15. template <typename T, typename Char, typename Enable = void>
  16. class is_streamable {
  17. private:
  18. template <typename U>
  19. static auto test(int)
  20. -> bool_constant<sizeof(std::declval<std::basic_ostream<Char>&>()
  21. << std::declval<U>()) != 0>;
  22. template <typename> static auto test(...) -> std::false_type;
  23. using result = decltype(test<T>(0));
  24. public:
  25. is_streamable() = default;
  26. static const bool value = result::value;
  27. };
  28. // Formatting of built-in types and arrays is intentionally disabled because
  29. // it's handled by standard (non-ostream) formatters.
  30. template <typename T, typename Char>
  31. struct is_streamable<
  32. T, Char,
  33. enable_if_t<
  34. std::is_arithmetic<T>::value || std::is_array<T>::value ||
  35. std::is_pointer<T>::value || std::is_same<T, char8_type>::value ||
  36. std::is_same<T, std::basic_string<Char>>::value ||
  37. std::is_same<T, std_string_view<Char>>::value ||
  38. (std::is_convertible<T, int>::value && !std::is_enum<T>::value)>>
  39. : std::false_type {};
  40. // Write the content of buf to os.
  41. // It is a separate function rather than a part of vprint to simplify testing.
  42. template <typename Char>
  43. void write_buffer(std::basic_ostream<Char>& os, buffer<Char>& buf) {
  44. const Char* buf_data = buf.data();
  45. using unsigned_streamsize = std::make_unsigned<std::streamsize>::type;
  46. unsigned_streamsize size = buf.size();
  47. unsigned_streamsize max_size = to_unsigned(max_value<std::streamsize>());
  48. do {
  49. unsigned_streamsize n = size <= max_size ? size : max_size;
  50. os.write(buf_data, static_cast<std::streamsize>(n));
  51. buf_data += n;
  52. size -= n;
  53. } while (size != 0);
  54. }
  55. template <typename Char, typename T>
  56. void format_value(buffer<Char>& buf, const T& value,
  57. locale_ref loc = locale_ref()) {
  58. auto&& format_buf = formatbuf<std::basic_streambuf<Char>>(buf);
  59. auto&& output = std::basic_ostream<Char>(&format_buf);
  60. #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
  61. if (loc) output.imbue(loc.get<std::locale>());
  62. #endif
  63. output << value;
  64. output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
  65. buf.try_resize(buf.size());
  66. }
  67. // Formats an object of type T that has an overloaded ostream operator<<.
  68. template <typename T, typename Char>
  69. struct fallback_formatter<T, Char, enable_if_t<is_streamable<T, Char>::value>>
  70. : private formatter<basic_string_view<Char>, Char> {
  71. using formatter<basic_string_view<Char>, Char>::parse;
  72. template <typename OutputIt>
  73. auto format(const T& value, basic_format_context<OutputIt, Char>& ctx)
  74. -> OutputIt {
  75. auto buffer = basic_memory_buffer<Char>();
  76. format_value(buffer, value, ctx.locale());
  77. return formatter<basic_string_view<Char>, Char>::format(
  78. {buffer.data(), buffer.size()}, ctx);
  79. }
  80. // DEPRECATED!
  81. template <typename OutputIt>
  82. auto format(const T& value, basic_printf_context<OutputIt, Char>& ctx)
  83. -> OutputIt {
  84. auto buffer = basic_memory_buffer<Char>();
  85. format_value(buffer, value, ctx.locale());
  86. return std::copy(buffer.begin(), buffer.end(), ctx.out());
  87. }
  88. };
  89. } // namespace detail
  90. FMT_MODULE_EXPORT
  91. template <typename Char>
  92. void vprint(std::basic_ostream<Char>& os, basic_string_view<Char> format_str,
  93. basic_format_args<buffer_context<type_identity_t<Char>>> args) {
  94. auto buffer = basic_memory_buffer<Char>();
  95. detail::vformat_to(buffer, format_str, args);
  96. detail::write_buffer(os, buffer);
  97. }
  98. /**
  99. \rst
  100. Prints formatted data to the stream *os*.
  101. **Example**::
  102. fmt::print(cerr, "Don't {}!", "panic");
  103. \endrst
  104. */
  105. FMT_MODULE_EXPORT
  106. template <typename S, typename... Args,
  107. typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
  108. void print(std::basic_ostream<Char>& os, const S& format_str, Args&&... args) {
  109. vprint(os, to_string_view(format_str),
  110. fmt::make_args_checked<Args...>(format_str, args...));
  111. }
  112. FMT_END_NAMESPACE
  113. #endif // FMT_OSTREAM_H_