formatter.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. // -*- C++ -*-
  2. //===----------------------------------------------------------------------===//
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef _LIBCPP___FORMAT_FORMATTER_H
  10. #define _LIBCPP___FORMAT_FORMATTER_H
  11. #include <__algorithm/copy.h>
  12. #include <__algorithm/fill_n.h>
  13. #include <__algorithm/transform.h>
  14. #include <__assert>
  15. #include <__availability>
  16. #include <__config>
  17. #include <__format/format_error.h>
  18. #include <__format/format_fwd.h>
  19. #include <__format/format_string.h>
  20. #include <__format/parser_std_format_spec.h>
  21. #include <__utility/unreachable.h>
  22. #include <string_view>
  23. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  24. # pragma GCC system_header
  25. #endif
  26. _LIBCPP_BEGIN_NAMESPACE_STD
  27. #if _LIBCPP_STD_VER > 17
  28. // TODO FMT Remove this once we require compilers with proper C++20 support.
  29. // If the compiler has no concepts support, the format header will be disabled.
  30. // Without concepts support enable_if needs to be used and that too much effort
  31. // to support compilers with partial C++20 support.
  32. #if !defined(_LIBCPP_HAS_NO_CONCEPTS)
  33. /// The default formatter template.
  34. ///
  35. /// [format.formatter.spec]/5
  36. /// If F is a disabled specialization of formatter, these values are false:
  37. /// - is_default_constructible_v<F>,
  38. /// - is_copy_constructible_v<F>,
  39. /// - is_move_constructible_v<F>,
  40. /// - is_copy_assignable<F>, and
  41. /// - is_move_assignable<F>.
  42. template <class _Tp, class _CharT>
  43. struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter {
  44. formatter() = delete;
  45. formatter(const formatter&) = delete;
  46. formatter& operator=(const formatter&) = delete;
  47. };
  48. namespace __format_spec {
  49. _LIBCPP_HIDE_FROM_ABI inline char* __insert_sign(char* __buf, bool __negative,
  50. _Flags::_Sign __sign) {
  51. if (__negative)
  52. *__buf++ = '-';
  53. else
  54. switch (__sign) {
  55. case _Flags::_Sign::__default:
  56. case _Flags::_Sign::__minus:
  57. // No sign added.
  58. break;
  59. case _Flags::_Sign::__plus:
  60. *__buf++ = '+';
  61. break;
  62. case _Flags::_Sign::__space:
  63. *__buf++ = ' ';
  64. break;
  65. }
  66. return __buf;
  67. }
  68. _LIBCPP_HIDE_FROM_ABI constexpr char __hex_to_upper(char c) {
  69. switch (c) {
  70. case 'a':
  71. return 'A';
  72. case 'b':
  73. return 'B';
  74. case 'c':
  75. return 'C';
  76. case 'd':
  77. return 'D';
  78. case 'e':
  79. return 'E';
  80. case 'f':
  81. return 'F';
  82. }
  83. return c;
  84. }
  85. } // namespace __format_spec
  86. namespace __formatter {
  87. /** The character types that formatters are specialized for. */
  88. template <class _CharT>
  89. concept __char_type = same_as<_CharT, char> || same_as<_CharT, wchar_t>;
  90. struct _LIBCPP_TEMPLATE_VIS __padding_size_result {
  91. size_t __before;
  92. size_t __after;
  93. };
  94. _LIBCPP_HIDE_FROM_ABI constexpr __padding_size_result
  95. __padding_size(size_t __size, size_t __width,
  96. __format_spec::_Flags::_Alignment __align) {
  97. _LIBCPP_ASSERT(__width > __size,
  98. "Don't call this function when no padding is required");
  99. _LIBCPP_ASSERT(
  100. __align != __format_spec::_Flags::_Alignment::__default,
  101. "Caller should adjust the default to the value required by the type");
  102. size_t __fill = __width - __size;
  103. switch (__align) {
  104. case __format_spec::_Flags::_Alignment::__default:
  105. __libcpp_unreachable();
  106. case __format_spec::_Flags::_Alignment::__left:
  107. return {0, __fill};
  108. case __format_spec::_Flags::_Alignment::__center: {
  109. // The extra padding is divided per [format.string.std]/3
  110. // __before = floor(__fill, 2);
  111. // __after = ceil(__fill, 2);
  112. size_t __before = __fill / 2;
  113. size_t __after = __fill - __before;
  114. return {__before, __after};
  115. }
  116. case __format_spec::_Flags::_Alignment::__right:
  117. return {__fill, 0};
  118. }
  119. __libcpp_unreachable();
  120. }
  121. /**
  122. * Writes the input to the output with the required padding.
  123. *
  124. * Since the output column width is specified the function can be used for
  125. * ASCII and Unicode input.
  126. *
  127. * @pre [@a __first, @a __last) is a valid range.
  128. * @pre @a __size <= @a __width. Using this function when this pre-condition
  129. * doesn't hold incurs an unwanted overhead.
  130. *
  131. * @param __out_it The output iterator to write to.
  132. * @param __first Pointer to the first element to write.
  133. * @param __last Pointer beyond the last element to write.
  134. * @param __size The (estimated) output column width. When the elements
  135. * to be written are ASCII the following condition holds
  136. * @a __size == @a __last - @a __first.
  137. * @param __width The number of output columns to write.
  138. * @param __fill The character used for the alignment of the output.
  139. * TODO FMT Will probably change to support Unicode grapheme
  140. * cluster.
  141. * @param __alignment The requested alignment.
  142. *
  143. * @returns An iterator pointing beyond the last element written.
  144. *
  145. * @note The type of the elements in range [@a __first, @a __last) can differ
  146. * from the type of @a __fill. Integer output uses @c std::to_chars for its
  147. * conversion, which means the [@a __first, @a __last) always contains elements
  148. * of the type @c char.
  149. */
  150. template <class _CharT, class _Fill>
  151. _LIBCPP_HIDE_FROM_ABI auto
  152. __write(output_iterator<const _CharT&> auto __out_it, const _CharT* __first,
  153. const _CharT* __last, size_t __size, size_t __width, _Fill __fill,
  154. __format_spec::_Flags::_Alignment __alignment) -> decltype(__out_it) {
  155. _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
  156. _LIBCPP_ASSERT(__size < __width, "Precondition failure");
  157. __padding_size_result __padding =
  158. __padding_size(__size, __width, __alignment);
  159. __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill);
  160. __out_it = _VSTD::copy(__first, __last, _VSTD::move(__out_it));
  161. return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill);
  162. }
  163. /**
  164. * @overload
  165. *
  166. * Writes additional zero's for the precision before the exponent.
  167. * This is used when the precision requested in the format string is larger
  168. * than the maximum precision of the floating-point type. These precision
  169. * digits are always 0.
  170. *
  171. * @param __exponent The location of the exponent character.
  172. * @param __num_trailing_zeros The number of 0's to write before the exponent
  173. * character.
  174. */
  175. template <class _CharT, class _Fill>
  176. _LIBCPP_HIDE_FROM_ABI auto __write(output_iterator<const _CharT&> auto __out_it, const _CharT* __first,
  177. const _CharT* __last, size_t __size, size_t __width, _Fill __fill,
  178. __format_spec::_Flags::_Alignment __alignment, const _CharT* __exponent,
  179. size_t __num_trailing_zeros) -> decltype(__out_it) {
  180. _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
  181. _LIBCPP_ASSERT(__num_trailing_zeros > 0, "The overload not writing trailing zeros should have been used");
  182. __padding_size_result __padding = __padding_size(__size + __num_trailing_zeros, __width, __alignment);
  183. __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill);
  184. __out_it = _VSTD::copy(__first, __exponent, _VSTD::move(__out_it));
  185. __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0'));
  186. __out_it = _VSTD::copy(__exponent, __last, _VSTD::move(__out_it));
  187. return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill);
  188. }
  189. /**
  190. * @overload
  191. *
  192. * Uses a transformation operation before writing an element.
  193. *
  194. * TODO FMT Fill will probably change to support Unicode grapheme cluster.
  195. */
  196. template <class _CharT, class _UnaryOperation, class _Fill>
  197. _LIBCPP_HIDE_FROM_ABI auto
  198. __write(output_iterator<const _CharT&> auto __out_it, const _CharT* __first,
  199. const _CharT* __last, size_t __size, _UnaryOperation __op,
  200. size_t __width, _Fill __fill,
  201. __format_spec::_Flags::_Alignment __alignment) -> decltype(__out_it) {
  202. _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
  203. _LIBCPP_ASSERT(__size < __width, "Precondition failure");
  204. __padding_size_result __padding =
  205. __padding_size(__size, __width, __alignment);
  206. __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill);
  207. __out_it = _VSTD::transform(__first, __last, _VSTD::move(__out_it), __op);
  208. return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill);
  209. }
  210. /**
  211. * Writes Unicode input to the output with the required padding.
  212. *
  213. * This function does almost the same as the @ref __write function, but handles
  214. * the width estimation of the Unicode input.
  215. *
  216. * @param __str The range [@a __first, @a __last).
  217. * @param __precision The width to truncate the input string to, use @c -1 for
  218. * no limit.
  219. */
  220. template <class _CharT, class _Fill>
  221. _LIBCPP_HIDE_FROM_ABI auto
  222. __write_unicode(output_iterator<const _CharT&> auto __out_it,
  223. basic_string_view<_CharT> __str, ptrdiff_t __width,
  224. ptrdiff_t __precision, _Fill __fill,
  225. __format_spec::_Flags::_Alignment __alignment)
  226. -> decltype(__out_it) {
  227. // This value changes when there Unicode column width limits the output
  228. // size.
  229. auto __last = __str.end();
  230. if (__width != 0 || __precision != -1) {
  231. __format_spec::__string_alignment<_CharT> __format_traits =
  232. __format_spec::__get_string_alignment(__str.begin(), __str.end(),
  233. __width, __precision);
  234. if (__format_traits.__align)
  235. return __write(_VSTD::move(__out_it), __str.begin(),
  236. __format_traits.__last, __format_traits.__size, __width,
  237. __fill, __alignment);
  238. // No alignment required update the output based on the precision.
  239. // This might be the same as __str.end().
  240. __last = __format_traits.__last;
  241. }
  242. // Copy the input to the output. The output size might be limited by the
  243. // precision.
  244. return _VSTD::copy(__str.begin(), __last, _VSTD::move(__out_it));
  245. }
  246. } // namespace __formatter
  247. #endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
  248. #endif //_LIBCPP_STD_VER > 17
  249. _LIBCPP_END_NAMESPACE_STD
  250. #endif // _LIBCPP___FORMAT_FORMATTER_H