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