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_PARSER_STD_FORMAT_SPEC_H
11 #define _LIBCPP___FORMAT_PARSER_STD_FORMAT_SPEC_H
12 
13 #include <__algorithm/find_if.h>
14 #include <__algorithm/min.h>
15 #include <__assert>
16 #include <__config>
17 #include <__format/format_arg.h>
18 #include <__format/format_error.h>
19 #include <__format/format_string.h>
20 #include <__variant/monostate.h>
21 #include <bit>
22 #include <concepts>
23 #include <cstdint>
24 #include <type_traits>
25 
26 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
27 #  pragma GCC system_header
28 #endif
29 
30 _LIBCPP_PUSH_MACROS
31 #include <__undef_macros>
32 
33 _LIBCPP_BEGIN_NAMESPACE_STD
34 
35 #if _LIBCPP_STD_VER > 17
36 
37 // TODO FMT Remove this once we require compilers with proper C++20 support.
38 // If the compiler has no concepts support, the format header will be disabled.
39 // Without concepts support enable_if needs to be used and that too much effort
40 // to support compilers with partial C++20 support.
41 # if !defined(_LIBCPP_HAS_NO_CONCEPTS)
42 
43 namespace __format_spec {
44 
45 /**
46  * Contains the flags for the std-format-spec.
47  *
48  * Some format-options can only be used for specific C++ types and may depend on
49  * the selected format-type.
50  * * The C++type filtering can be done using the proper policies for
51  *   @ref __parser_std.
52  * * The format-type filtering needs to be done post parsing in the parser
53  *   derived from @ref __parser_std.
54  */
55 _LIBCPP_PACKED_BYTE_FOR_AIX
56 class _LIBCPP_TYPE_VIS _Flags {
57 public:
58   enum class _LIBCPP_ENUM_VIS _Alignment : uint8_t {
59     /**
60      * No alignment is set in the format string.
61      *
62      * Zero-padding is ignored when an alignment is selected.
63      * The default alignment depends on the selected format-type.
64      */
65     __default,
66     __left,
67     __center,
68     __right
69   };
70   enum class _LIBCPP_ENUM_VIS _Sign : uint8_t {
71     /**
72      * No sign is set in the format string.
73      *
74      * The sign isn't allowed for certain format-types. By using this value
75      * it's possible to detect whether or not the user explicitly set the sign
76      * flag. For formatting purposes it behaves the same as @ref __minus.
77      */
78     __default,
79     __minus,
80     __plus,
81     __space
82   };
83 
84   _Alignment __alignment : 2 {_Alignment::__default};
85   _Sign __sign : 2 {_Sign::__default};
86   uint8_t __alternate_form : 1 {false};
87   uint8_t __zero_padding : 1 {false};
88   uint8_t __locale_specific_form : 1 {false};
89 
90   enum class _LIBCPP_ENUM_VIS _Type : uint8_t {
91     __default,
92     __string,
93     __binary_lower_case,
94     __binary_upper_case,
95     __octal,
96     __decimal,
97     __hexadecimal_lower_case,
98     __hexadecimal_upper_case,
99     __pointer,
100     __char,
101     __float_hexadecimal_lower_case,
102     __float_hexadecimal_upper_case,
103     __scientific_lower_case,
104     __scientific_upper_case,
105     __fixed_lower_case,
106     __fixed_upper_case,
107     __general_lower_case,
108     __general_upper_case
109   };
110 
111   _Type __type{_Type::__default};
112 };
113 _LIBCPP_PACKED_BYTE_FOR_AIX_END
114 
115 namespace __detail {
116 template <class _CharT>
117 _LIBCPP_HIDE_FROM_ABI constexpr bool
118 __parse_alignment(_CharT __c, _Flags& __flags) noexcept {
119   switch (__c) {
120   case _CharT('<'):
121     __flags.__alignment = _Flags::_Alignment::__left;
122     return true;
123 
124   case _CharT('^'):
125     __flags.__alignment = _Flags::_Alignment::__center;
126     return true;
127 
128   case _CharT('>'):
129     __flags.__alignment = _Flags::_Alignment::__right;
130     return true;
131   }
132   return false;
133 }
134 } // namespace __detail
135 
136 template <class _CharT>
137 class _LIBCPP_TEMPLATE_VIS __parser_fill_align {
138 public:
139   // TODO FMT The standard doesn't specify this character is a Unicode
140   // character. Validate what fmt and MSVC have implemented.
141   _CharT __fill{_CharT(' ')};
142 
143 protected:
144   _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
145   __parse(const _CharT* __begin, const _CharT* __end, _Flags& __flags) {
146     _LIBCPP_ASSERT(__begin != __end,
147                    "When called with an empty input the function will cause "
148                    "undefined behavior by evaluating data not in the input");
149     if (__begin + 1 != __end) {
150       if (__detail::__parse_alignment(*(__begin + 1), __flags)) {
151         if (*__begin == _CharT('{') || *__begin == _CharT('}'))
152           __throw_format_error(
153               "The format-spec fill field contains an invalid character");
154         __fill = *__begin;
155         return __begin + 2;
156       }
157     }
158 
159     if (__detail::__parse_alignment(*__begin, __flags))
160       return __begin + 1;
161 
162     return __begin;
163   }
164 };
165 
166 template <class _CharT>
167 _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
168 __parse_sign(const _CharT* __begin, _Flags& __flags) noexcept {
169   switch (*__begin) {
170   case _CharT('-'):
171     __flags.__sign = _Flags::_Sign::__minus;
172     break;
173   case _CharT('+'):
174     __flags.__sign = _Flags::_Sign::__plus;
175     break;
176   case _CharT(' '):
177     __flags.__sign = _Flags::_Sign::__space;
178     break;
179   default:
180     return __begin;
181   }
182   return __begin + 1;
183 }
184 
185 template <class _CharT>
186 _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
187 __parse_alternate_form(const _CharT* __begin, _Flags& __flags) noexcept {
188   if (*__begin == _CharT('#')) {
189     __flags.__alternate_form = true;
190     ++__begin;
191   }
192 
193   return __begin;
194 }
195 
196 template <class _CharT>
197 _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
198 __parse_zero_padding(const _CharT* __begin, _Flags& __flags) noexcept {
199   if (*__begin == _CharT('0')) {
200     __flags.__zero_padding = true;
201     ++__begin;
202   }
203 
204   return __begin;
205 }
206 
207 template <class _CharT>
208 _LIBCPP_HIDE_FROM_ABI constexpr __format::__parse_number_result< _CharT>
209 __parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
210   // This function is a wrapper to call the real parser. But it does the
211   // validation for the pre-conditions and post-conditions.
212   if (__begin == __end)
213     __throw_format_error("End of input while parsing format-spec arg-id");
214 
215   __format::__parse_number_result __r =
216       __format::__parse_arg_id(__begin, __end, __parse_ctx);
217 
218   if (__r.__ptr == __end || *__r.__ptr != _CharT('}'))
219     __throw_format_error("Invalid arg-id");
220 
221   ++__r.__ptr;
222   return __r;
223 }
224 
225 template <class _Context>
226 _LIBCPP_HIDE_FROM_ABI constexpr uint32_t
227 __substitute_arg_id(basic_format_arg<_Context> __arg) {
228   return visit_format_arg(
229       [](auto __arg) -> uint32_t {
230         using _Type = decltype(__arg);
231         if constexpr (integral<_Type>) {
232           if constexpr (signed_integral<_Type>) {
233             if (__arg < 0)
234               __throw_format_error("A format-spec arg-id replacement shouldn't "
235                                    "have a negative value");
236           }
237 
238           using _CT = common_type_t<_Type, decltype(__format::__number_max)>;
239           if (static_cast<_CT>(__arg) >
240               static_cast<_CT>(__format::__number_max))
241             __throw_format_error("A format-spec arg-id replacement exceeds "
242                                  "the maximum supported value");
243 
244           return __arg;
245         } else if constexpr (same_as<_Type, monostate>)
246           __throw_format_error("Argument index out of bounds");
247         else
248           __throw_format_error("A format-spec arg-id replacement argument "
249                                "isn't an integral type");
250       },
251       __arg);
252 }
253 
254 class _LIBCPP_TYPE_VIS __parser_width {
255 public:
256   /** Contains a width or an arg-id. */
257   uint32_t __width : 31 {0};
258   /** Determines whether the value stored is a width or an arg-id. */
259   uint32_t __width_as_arg : 1 {0};
260 
261 protected:
262   /**
263    * Does the supplied std-format-spec contain a width field?
264    *
265    * When the field isn't present there's no padding required. This can be used
266    * to optimize the formatting.
267    */
268   constexpr bool __has_width_field() const noexcept {
269     return __width_as_arg || __width;
270   }
271 
272   /**
273    * Does the supplied width field contain an arg-id?
274    *
275    * If @c true the formatter needs to call @ref __substitute_width_arg_id.
276    */
277   constexpr bool __width_needs_substitution() const noexcept {
278     return __width_as_arg;
279   }
280 
281   template <class _CharT>
282   _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
283   __parse(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
284     if (*__begin == _CharT('0'))
285       __throw_format_error(
286           "A format-spec width field shouldn't have a leading zero");
287 
288     if (*__begin == _CharT('{')) {
289       __format::__parse_number_result __r =
290           __parse_arg_id(++__begin, __end, __parse_ctx);
291       __width = __r.__value;
292       __width_as_arg = 1;
293       return __r.__ptr;
294     }
295 
296     if (*__begin < _CharT('0') || *__begin > _CharT('9'))
297       return __begin;
298 
299     __format::__parse_number_result __r =
300         __format::__parse_number(__begin, __end);
301     __width = __r.__value;
302     _LIBCPP_ASSERT(__width != 0,
303                    "A zero value isn't allowed and should be impossible, "
304                    "due to validations in this function");
305     return __r.__ptr;
306   }
307 
308   _LIBCPP_HIDE_FROM_ABI constexpr void __substitute_width_arg_id(auto __arg) {
309     _LIBCPP_ASSERT(__width_as_arg == 1,
310                    "Substitute width called when no substitution is required");
311 
312     // The clearing of the flag isn't required but looks better when debugging
313     // the code.
314     __width_as_arg = 0;
315     __width = __substitute_arg_id(__arg);
316     if (__width == 0)
317       __throw_format_error(
318           "A format-spec width field replacement should have a positive value");
319   }
320 };
321 
322 class _LIBCPP_TYPE_VIS __parser_precision {
323 public:
324   /** Contains a precision or an arg-id. */
325   uint32_t __precision : 31 {__format::__number_max};
326   /**
327    * Determines whether the value stored is a precision or an arg-id.
328    *
329    * @note Since @ref __precision == @ref __format::__number_max is a valid
330    * value, the default value contains an arg-id of INT32_MAX. (This number of
331    * arguments isn't supported by compilers.)  This is used to detect whether
332    * the std-format-spec contains a precision field.
333    */
334   uint32_t __precision_as_arg : 1 {1};
335 
336 protected:
337   /**
338    * Does the supplied std-format-spec contain a precision field?
339    *
340    * When the field isn't present there's no truncating required. This can be
341    * used to optimize the formatting.
342    */
343   constexpr bool __has_precision_field() const noexcept {
344 
345     return __precision_as_arg == 0 ||             // Contains a value?
346            __precision != __format::__number_max; // The arg-id is valid?
347   }
348 
349   /**
350    * Does the supplied precision field contain an arg-id?
351    *
352    * If @c true the formatter needs to call @ref __substitute_precision_arg_id.
353    */
354   constexpr bool __precision_needs_substitution() const noexcept {
355     return __precision_as_arg && __precision != __format::__number_max;
356   }
357 
358   template <class _CharT>
359   _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
360   __parse(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
361     if (*__begin != _CharT('.'))
362       return __begin;
363 
364     ++__begin;
365     if (__begin == __end)
366       __throw_format_error("End of input while parsing format-spec precision");
367 
368     if (*__begin == _CharT('{')) {
369       __format::__parse_number_result __arg_id =
370           __parse_arg_id(++__begin, __end, __parse_ctx);
371       _LIBCPP_ASSERT(__arg_id.__value != __format::__number_max,
372                      "Unsupported number of arguments, since this number of "
373                      "arguments is used a special value");
374       __precision = __arg_id.__value;
375       return __arg_id.__ptr;
376     }
377 
378     if (*__begin < _CharT('0') || *__begin > _CharT('9'))
379       __throw_format_error(
380           "The format-spec precision field doesn't contain a value or arg-id");
381 
382     __format::__parse_number_result __r =
383         __format::__parse_number(__begin, __end);
384     __precision = __r.__value;
385     __precision_as_arg = 0;
386     return __r.__ptr;
387   }
388 
389   _LIBCPP_HIDE_FROM_ABI constexpr void __substitute_precision_arg_id(
390       auto __arg) {
391     _LIBCPP_ASSERT(
392         __precision_as_arg == 1 && __precision != __format::__number_max,
393         "Substitute precision called when no substitution is required");
394 
395     // The clearing of the flag isn't required but looks better when debugging
396     // the code.
397     __precision_as_arg = 0;
398     __precision = __substitute_arg_id(__arg);
399   }
400 };
401 
402 template <class _CharT>
403 _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
404 __parse_locale_specific_form(const _CharT* __begin, _Flags& __flags) noexcept {
405   if (*__begin == _CharT('L')) {
406     __flags.__locale_specific_form = true;
407     ++__begin;
408   }
409 
410   return __begin;
411 }
412 
413 template <class _CharT>
414 _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
415 __parse_type(const _CharT* __begin, _Flags& __flags) {
416 
417   // Determines the type. It does not validate whether the selected type is
418   // valid. Most formatters have optional fields that are only allowed for
419   // certain types. These parsers need to do validation after the type has
420   // been parsed. So its easier to implement the validation for all types in
421   // the specific parse function.
422   switch (*__begin) {
423   case 'A':
424     __flags.__type = _Flags::_Type::__float_hexadecimal_upper_case;
425     break;
426   case 'B':
427     __flags.__type = _Flags::_Type::__binary_upper_case;
428     break;
429   case 'E':
430     __flags.__type = _Flags::_Type::__scientific_upper_case;
431     break;
432   case 'F':
433     __flags.__type = _Flags::_Type::__fixed_upper_case;
434     break;
435   case 'G':
436     __flags.__type = _Flags::_Type::__general_upper_case;
437     break;
438   case 'X':
439     __flags.__type = _Flags::_Type::__hexadecimal_upper_case;
440     break;
441   case 'a':
442     __flags.__type = _Flags::_Type::__float_hexadecimal_lower_case;
443     break;
444   case 'b':
445     __flags.__type = _Flags::_Type::__binary_lower_case;
446     break;
447   case 'c':
448     __flags.__type = _Flags::_Type::__char;
449     break;
450   case 'd':
451     __flags.__type = _Flags::_Type::__decimal;
452     break;
453   case 'e':
454     __flags.__type = _Flags::_Type::__scientific_lower_case;
455     break;
456   case 'f':
457     __flags.__type = _Flags::_Type::__fixed_lower_case;
458     break;
459   case 'g':
460     __flags.__type = _Flags::_Type::__general_lower_case;
461     break;
462   case 'o':
463     __flags.__type = _Flags::_Type::__octal;
464     break;
465   case 'p':
466     __flags.__type = _Flags::_Type::__pointer;
467     break;
468   case 's':
469     __flags.__type = _Flags::_Type::__string;
470     break;
471   case 'x':
472     __flags.__type = _Flags::_Type::__hexadecimal_lower_case;
473     break;
474   default:
475     return __begin;
476   }
477   return ++__begin;
478 }
479 
480 /**
481  * Process the parsed alignment and zero-padding state of arithmetic types.
482  *
483  * [format.string.std]/13
484  *   If the 0 character and an align option both appear, the 0 character is
485  *   ignored.
486  *
487  * For the formatter a @ref __default alignment means zero-padding.
488  */
489 _LIBCPP_HIDE_FROM_ABI constexpr void __process_arithmetic_alignment(_Flags& __flags) {
490   __flags.__zero_padding &= __flags.__alignment == _Flags::_Alignment::__default;
491   if (!__flags.__zero_padding && __flags.__alignment == _Flags::_Alignment::__default)
492     __flags.__alignment = _Flags::_Alignment::__right;
493 }
494 
495 /**
496  * The parser for the std-format-spec.
497  *
498  * [format.string.std]/1 specifies the std-format-spec:
499  *   fill-and-align sign # 0 width precision L type
500  *
501  * All these fields are optional. Whether these fields can be used depend on:
502  * - The type supplied to the format string.
503  *   E.g. A string never uses the sign field so the field may not be set.
504  *   This constrain is validated by the parsers in this file.
505  * - The supplied value for the optional type field.
506  *   E.g. A int formatted as decimal uses the sign field.
507  *   When formatted as a char the sign field may no longer be set.
508  *   This constrain isn't validated by the parsers in this file.
509  *
510  * The base classes are ordered to minimize the amount of padding.
511  *
512  * This implements the parser for the string types.
513  */
514 template <class _CharT>
515 class _LIBCPP_TEMPLATE_VIS __parser_string
516     : public __parser_width,              // provides __width(|as_arg)
517       public __parser_precision,          // provides __precision(|as_arg)
518       public __parser_fill_align<_CharT>, // provides __fill and uses __flags
519       public _Flags                       // provides __flags
520 {
521 public:
522   using char_type = _CharT;
523 
524   _LIBCPP_HIDE_FROM_ABI constexpr __parser_string() {
525     this->__alignment = _Flags::_Alignment::__left;
526   }
527 
528   /**
529    * The low-level std-format-spec parse function.
530    *
531    * @pre __begin points at the beginning of the std-format-spec. This means
532    * directly after the ':'.
533    * @pre The std-format-spec parses the entire input, or the first unmatched
534    * character is a '}'.
535    *
536    * @returns The iterator pointing at the last parsed character.
537    */
538   _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx)
539       -> decltype(__parse_ctx.begin()) {
540     auto __it = __parse(__parse_ctx);
541     __process_display_type();
542     return __it;
543   }
544 
545 private:
546   /**
547    * Parses the std-format-spec.
548    *
549    * @throws __throw_format_error When @a __parse_ctx contains an ill-formed
550    *                               std-format-spec.
551    *
552    * @returns An iterator to the end of input or point at the closing '}'.
553    */
554   _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx)
555       -> decltype(__parse_ctx.begin()) {
556 
557     auto __begin = __parse_ctx.begin();
558     auto __end = __parse_ctx.end();
559     if (__begin == __end)
560       return __begin;
561 
562     __begin = __parser_fill_align<_CharT>::__parse(__begin, __end,
563                                                    static_cast<_Flags&>(*this));
564     if (__begin == __end)
565       return __begin;
566 
567     __begin = __parser_width::__parse(__begin, __end, __parse_ctx);
568     if (__begin == __end)
569       return __begin;
570 
571     __begin = __parser_precision::__parse(__begin, __end, __parse_ctx);
572     if (__begin == __end)
573       return __begin;
574 
575     __begin = __parse_type(__begin, static_cast<_Flags&>(*this));
576 
577     if (__begin != __end && *__begin != _CharT('}'))
578       __throw_format_error(
579           "The format-spec should consume the input or end with a '}'");
580 
581     return __begin;
582   }
583 
584   /** Processes the parsed std-format-spec based on the parsed display type. */
585   _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type() {
586     switch (this->__type) {
587     case _Flags::_Type::__default:
588     case _Flags::_Type::__string:
589       break;
590 
591     default:
592       __throw_format_error("The format-spec type has a type not supported for "
593                            "a string argument");
594     }
595   }
596 };
597 
598 /**
599  * The parser for the std-format-spec.
600  *
601  * This implements the parser for the integral types. This includes the
602  * character type and boolean type.
603  *
604  * See @ref __parser_string.
605  */
606 template <class _CharT>
607 class _LIBCPP_TEMPLATE_VIS __parser_integral
608     : public __parser_width,              // provides __width(|as_arg)
609       public __parser_fill_align<_CharT>, // provides __fill and uses __flags
610       public _Flags                       // provides __flags
611 {
612 public:
613   using char_type = _CharT;
614 
615 protected:
616   /**
617    * The low-level std-format-spec parse function.
618    *
619    * @pre __begin points at the beginning of the std-format-spec. This means
620    * directly after the ':'.
621    * @pre The std-format-spec parses the entire input, or the first unmatched
622    * character is a '}'.
623    *
624    * @returns The iterator pointing at the last parsed character.
625    */
626   _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx)
627       -> decltype(__parse_ctx.begin()) {
628     auto __begin = __parse_ctx.begin();
629     auto __end = __parse_ctx.end();
630     if (__begin == __end)
631       return __begin;
632 
633     __begin = __parser_fill_align<_CharT>::__parse(__begin, __end,
634                                                    static_cast<_Flags&>(*this));
635     if (__begin == __end)
636       return __begin;
637 
638     __begin = __parse_sign(__begin, static_cast<_Flags&>(*this));
639     if (__begin == __end)
640       return __begin;
641 
642     __begin = __parse_alternate_form(__begin, static_cast<_Flags&>(*this));
643     if (__begin == __end)
644       return __begin;
645 
646     __begin = __parse_zero_padding(__begin, static_cast<_Flags&>(*this));
647     if (__begin == __end)
648       return __begin;
649 
650     __begin = __parser_width::__parse(__begin, __end, __parse_ctx);
651     if (__begin == __end)
652       return __begin;
653 
654     __begin =
655         __parse_locale_specific_form(__begin, static_cast<_Flags&>(*this));
656     if (__begin == __end)
657       return __begin;
658 
659     __begin = __parse_type(__begin, static_cast<_Flags&>(*this));
660 
661     if (__begin != __end && *__begin != _CharT('}'))
662       __throw_format_error(
663           "The format-spec should consume the input or end with a '}'");
664 
665     return __begin;
666   }
667 
668   /** Handles the post-parsing updates for the integer types. */
669   _LIBCPP_HIDE_FROM_ABI constexpr void __handle_integer() noexcept {
670     __process_arithmetic_alignment(static_cast<_Flags&>(*this));
671   }
672 
673   /**
674    * Handles the post-parsing updates for the character types.
675    *
676    * Sets the alignment and validates the format flags set for a character type.
677    *
678    * At the moment the validation for a character and a Boolean behave the
679    * same, but this may change in the future.
680    * Specifically at the moment the locale-specific form is allowed for the
681    * char output type, but it has no effect on the output.
682    */
683   _LIBCPP_HIDE_FROM_ABI constexpr void __handle_char() { __handle_bool(); }
684 
685   /**
686    * Handles the post-parsing updates for the Boolean types.
687    *
688    * Sets the alignment and validates the format flags set for a Boolean type.
689    */
690   _LIBCPP_HIDE_FROM_ABI constexpr void __handle_bool() {
691     if (this->__sign != _Flags::_Sign::__default)
692       __throw_format_error("A sign field isn't allowed in this format-spec");
693 
694     if (this->__alternate_form)
695       __throw_format_error(
696           "An alternate form field isn't allowed in this format-spec");
697 
698     if (this->__zero_padding)
699       __throw_format_error(
700           "A zero-padding field isn't allowed in this format-spec");
701 
702     if (this->__alignment == _Flags::_Alignment::__default)
703       this->__alignment = _Flags::_Alignment::__left;
704   }
705 };
706 
707 /**
708  * The parser for the std-format-spec.
709  *
710  * This implements the parser for the floating-point types.
711  *
712  * See @ref __parser_string.
713  */
714 template <class _CharT>
715 class _LIBCPP_TEMPLATE_VIS __parser_floating_point
716     : public __parser_width,              // provides __width(|as_arg)
717       public __parser_precision,          // provides __precision(|as_arg)
718       public __parser_fill_align<_CharT>, // provides __fill and uses __flags
719       public _Flags                       // provides __flags
720 {
721 public:
722   using char_type = _CharT;
723 
724   /**
725    * The low-level std-format-spec parse function.
726    *
727    * @pre __begin points at the beginning of the std-format-spec. This means
728    * directly after the ':'.
729    * @pre The std-format-spec parses the entire input, or the first unmatched
730    * character is a '}'.
731    *
732    * @returns The iterator pointing at the last parsed character.
733    */
734   _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx)
735       -> decltype(__parse_ctx.begin()) {
736     auto __it = __parse(__parse_ctx);
737     __process_arithmetic_alignment(static_cast<_Flags&>(*this));
738     __process_display_type();
739     return __it;
740   }
741 protected:
742   /**
743    * The low-level std-format-spec parse function.
744    *
745    * @pre __begin points at the beginning of the std-format-spec. This means
746    * directly after the ':'.
747    * @pre The std-format-spec parses the entire input, or the first unmatched
748    * character is a '}'.
749    *
750    * @returns The iterator pointing at the last parsed character.
751    */
752   _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx)
753       -> decltype(__parse_ctx.begin()) {
754     auto __begin = __parse_ctx.begin();
755     auto __end = __parse_ctx.end();
756     if (__begin == __end)
757       return __begin;
758 
759     __begin = __parser_fill_align<_CharT>::__parse(__begin, __end,
760                                                    static_cast<_Flags&>(*this));
761     if (__begin == __end)
762       return __begin;
763 
764     __begin = __parse_sign(__begin, static_cast<_Flags&>(*this));
765     if (__begin == __end)
766       return __begin;
767 
768     __begin = __parse_alternate_form(__begin, static_cast<_Flags&>(*this));
769     if (__begin == __end)
770       return __begin;
771 
772     __begin = __parse_zero_padding(__begin, static_cast<_Flags&>(*this));
773     if (__begin == __end)
774       return __begin;
775 
776     __begin = __parser_width::__parse(__begin, __end, __parse_ctx);
777     if (__begin == __end)
778       return __begin;
779 
780     __begin = __parser_precision::__parse(__begin, __end, __parse_ctx);
781     if (__begin == __end)
782       return __begin;
783 
784     __begin =
785         __parse_locale_specific_form(__begin, static_cast<_Flags&>(*this));
786     if (__begin == __end)
787       return __begin;
788 
789     __begin = __parse_type(__begin, static_cast<_Flags&>(*this));
790 
791     if (__begin != __end && *__begin != _CharT('}'))
792       __throw_format_error(
793           "The format-spec should consume the input or end with a '}'");
794 
795     return __begin;
796   }
797 
798   /** Processes the parsed std-format-spec based on the parsed display type. */
799   _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type() {
800     switch (this->__type) {
801     case _Flags::_Type::__default:
802       // When no precision specified then it keeps default since that
803       // formatting differs from the other types.
804       if (this->__has_precision_field())
805         this->__type = _Flags::_Type::__general_lower_case;
806       break;
807     case _Flags::_Type::__float_hexadecimal_lower_case:
808     case _Flags::_Type::__float_hexadecimal_upper_case:
809       // Precision specific behavior will be handled later.
810       break;
811     case _Flags::_Type::__scientific_lower_case:
812     case _Flags::_Type::__scientific_upper_case:
813     case _Flags::_Type::__fixed_lower_case:
814     case _Flags::_Type::__fixed_upper_case:
815     case _Flags::_Type::__general_lower_case:
816     case _Flags::_Type::__general_upper_case:
817       if (!this->__has_precision_field()) {
818         // Set the default precision for the call to to_chars.
819         this->__precision = 6;
820         this->__precision_as_arg = false;
821       }
822       break;
823 
824     default:
825       __throw_format_error("The format-spec type has a type not supported for "
826                            "a floating-point argument");
827     }
828   }
829 };
830 
831 /**
832  * The parser for the std-format-spec.
833  *
834  * This implements the parser for the pointer types.
835  *
836  * See @ref __parser_string.
837  */
838 template <class _CharT>
839 class _LIBCPP_TEMPLATE_VIS __parser_pointer : public __parser_width,              // provides __width(|as_arg)
840                                               public __parser_fill_align<_CharT>, // provides __fill and uses __flags
841                                               public _Flags                       // provides __flags
842 {
843 public:
844   using char_type = _CharT;
845 
846   _LIBCPP_HIDE_FROM_ABI constexpr __parser_pointer() {
847     // Implements LWG3612 Inconsistent pointer alignment in std::format.
848     // The issue's current status is "Tentatively Ready" and libc++ status is
849     // still experimental.
850     //
851     // TODO FMT Validate this with the final resolution of LWG3612.
852     this->__alignment = _Flags::_Alignment::__right;
853   }
854 
855   /**
856    * The low-level std-format-spec parse function.
857    *
858    * @pre __begin points at the beginning of the std-format-spec. This means
859    * directly after the ':'.
860    * @pre The std-format-spec parses the entire input, or the first unmatched
861    * character is a '}'.
862    *
863    * @returns The iterator pointing at the last parsed character.
864    */
865   _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx) -> decltype(__parse_ctx.begin()) {
866     auto __it = __parse(__parse_ctx);
867     __process_display_type();
868     return __it;
869   }
870 
871 protected:
872   /**
873    * The low-level std-format-spec parse function.
874    *
875    * @pre __begin points at the beginning of the std-format-spec. This means
876    * directly after the ':'.
877    * @pre The std-format-spec parses the entire input, or the first unmatched
878    * character is a '}'.
879    *
880    * @returns The iterator pointing at the last parsed character.
881    */
882   _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx) -> decltype(__parse_ctx.begin()) {
883     auto __begin = __parse_ctx.begin();
884     auto __end = __parse_ctx.end();
885     if (__begin == __end)
886       return __begin;
887 
888     __begin = __parser_fill_align<_CharT>::__parse(__begin, __end, static_cast<_Flags&>(*this));
889     if (__begin == __end)
890       return __begin;
891 
892     // An integer presentation type isn't defined in the Standard.
893     // Since a pointer is formatted as an integer it can be argued it's an
894     // integer presentation type. However there are two LWG-issues asserting it
895     // isn't an integer presentation type:
896     // - LWG3612 Inconsistent pointer alignment in std::format
897     // - LWG3644 std::format does not define "integer presentation type"
898     //
899     // There's a paper to make additional clarifications on the status of
900     // formatting pointers and proposes additional fields to be valid. That
901     // paper hasn't been reviewed by the Committee yet.
902     // - P2510 Formatting pointers
903     //
904     // The current implementation assumes formatting pointers isn't covered by
905     // "integer presentation type".
906     // TODO FMT Apply the LWG-issues/papers after approval/rejection by the Committee.
907 
908     __begin = __parser_width::__parse(__begin, __end, __parse_ctx);
909     if (__begin == __end)
910       return __begin;
911 
912     __begin = __parse_type(__begin, static_cast<_Flags&>(*this));
913 
914     if (__begin != __end && *__begin != _CharT('}'))
915       __throw_format_error("The format-spec should consume the input or end with a '}'");
916 
917     return __begin;
918   }
919 
920   /** Processes the parsed std-format-spec based on the parsed display type. */
921   _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type() {
922     switch (this->__type) {
923     case _Flags::_Type::__default:
924       this->__type = _Flags::_Type::__pointer;
925       break;
926     case _Flags::_Type::__pointer:
927       break;
928     default:
929       __throw_format_error("The format-spec type has a type not supported for a pointer argument");
930     }
931   }
932 };
933 
934 /** Helper struct returned from @ref __get_string_alignment. */
935 template <class _CharT>
936 struct _LIBCPP_TEMPLATE_VIS __string_alignment {
937   /** Points beyond the last character to write to the output. */
938   const _CharT* __last;
939   /**
940    * The estimated number of columns in the output or 0.
941    *
942    * Only when the output needs to be aligned it's required to know the exact
943    * number of columns in the output. So if the formatted output has only a
944    * minimum width the exact size isn't important. It's only important to know
945    * the minimum has been reached. The minimum width is the width specified in
946    * the format-spec.
947    *
948    * For example in this code @code std::format("{:10}", MyString); @endcode
949    * the width estimation can stop once the algorithm has determined the output
950    * width is 10 columns.
951    *
952    * So if:
953    * * @ref __align == @c true the @ref __size is the estimated number of
954    *   columns required.
955    * * @ref __align == @c false the @ref __size is the estimated number of
956    *   columns required or 0 when the estimation algorithm stopped prematurely.
957    */
958   ptrdiff_t __size;
959   /**
960    * Does the output need to be aligned.
961    *
962    * When alignment is needed the output algorithm needs to add the proper
963    * padding. Else the output algorithm just needs to copy the input up to
964    * @ref __last.
965    */
966   bool __align;
967 };
968 
969 #ifndef _LIBCPP_HAS_NO_UNICODE
970 namespace __detail {
971 
972 /**
973  * Unicode column width estimates.
974  *
975  * Unicode can be stored in several formats: UTF-8, UTF-16, and UTF-32.
976  * Depending on format the relation between the number of code units stored and
977  * the number of output columns differs. The first relation is the number of
978  * code units forming a code point. (The text assumes the code units are
979  * unsigned.)
980  * - UTF-8 The number of code units is between one and four. The first 127
981  *   Unicode code points match the ASCII character set. When the highest bit is
982  *   set it means the code point has more than one code unit.
983  * - UTF-16: The number of code units is between 1 and 2. When the first
984  *   code unit is in the range [0xd800,0xdfff) it means the code point uses two
985  *   code units.
986  * - UTF-32: The number of code units is always one.
987  *
988  * The code point to the number of columns isn't well defined. The code uses the
989  * estimations defined in [format.string.std]/11. This list might change in the
990  * future.
991  *
992  * The algorithm of @ref __get_string_alignment uses two different scanners:
993  * - The simple scanner @ref __estimate_column_width_fast. This scanner assumes
994  *   1 code unit is 1 column. This scanner stops when it can't be sure the
995  *   assumption is valid:
996  *   - UTF-8 when the code point is encoded in more than 1 code unit.
997  *   - UTF-16 and UTF-32 when the first multi-column code point is encountered.
998  *     (The code unit's value is lower than 0xd800 so the 2 code unit encoding
999  *     is irrelevant for this scanner.)
1000  *   Due to these assumptions the scanner is faster than the full scanner. It
1001  *   can process all text only containing ASCII. For UTF-16/32 it can process
1002  *   most (all?) European languages. (Note the set it can process might be
1003  *   reduced in the future, due to updates in the scanning rules.)
1004  * - The full scanner @ref __estimate_column_width. This scanner, if needed,
1005  *   converts multiple code units into one code point then converts the code
1006  *   point to a column width.
1007  *
1008  * See also:
1009  * - [format.string.general]/11
1010  * - https://en.wikipedia.org/wiki/UTF-8#Encoding
1011  * - https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF
1012  */
1013 
1014 /**
1015  * The first 2 column code point.
1016  *
1017  * This is the point where the fast UTF-16/32 scanner needs to stop processing.
1018  */
1019 inline constexpr uint32_t __two_column_code_point = 0x1100;
1020 
1021 /** Helper concept for an UTF-8 character type. */
1022 template <class _CharT>
1023 concept __utf8_character = same_as<_CharT, char> || same_as<_CharT, char8_t>;
1024 
1025 /** Helper concept for an UTF-16 character type. */
1026 template <class _CharT>
1027 concept __utf16_character = (same_as<_CharT, wchar_t> && sizeof(wchar_t) == 2) || same_as<_CharT, char16_t>;
1028 
1029 /** Helper concept for an UTF-32 character type. */
1030 template <class _CharT>
1031 concept __utf32_character = (same_as<_CharT, wchar_t> && sizeof(wchar_t) == 4) || same_as<_CharT, char32_t>;
1032 
1033 /** Helper concept for an UTF-16 or UTF-32 character type. */
1034 template <class _CharT>
1035 concept __utf16_or_32_character = __utf16_character<_CharT> || __utf32_character<_CharT>;
1036 
1037 /**
1038  * Converts a code point to the column width.
1039  *
1040  * The estimations are conforming to [format.string.general]/11
1041  *
1042  * This version expects a value less than 0x1'0000, which is a 3-byte UTF-8
1043  * character.
1044  */
1045 _LIBCPP_HIDE_FROM_ABI inline constexpr int __column_width_3(uint32_t __c) noexcept {
1046   _LIBCPP_ASSERT(__c < 0x1'0000,
1047                  "Use __column_width_4 or __column_width for larger values");
1048 
1049   // clang-format off
1050   return 1 + (__c >= 0x1100 && (__c <= 0x115f ||
1051              (__c >= 0x2329 && (__c <= 0x232a ||
1052              (__c >= 0x2e80 && (__c <= 0x303e ||
1053              (__c >= 0x3040 && (__c <= 0xa4cf ||
1054              (__c >= 0xac00 && (__c <= 0xd7a3 ||
1055              (__c >= 0xf900 && (__c <= 0xfaff ||
1056              (__c >= 0xfe10 && (__c <= 0xfe19 ||
1057              (__c >= 0xfe30 && (__c <= 0xfe6f ||
1058              (__c >= 0xff00 && (__c <= 0xff60 ||
1059              (__c >= 0xffe0 && (__c <= 0xffe6
1060              ))))))))))))))))))));
1061   // clang-format on
1062 }
1063 
1064 /**
1065  * @overload
1066  *
1067  * This version expects a value greater than or equal to 0x1'0000, which is a
1068  * 4-byte UTF-8 character.
1069  */
1070 _LIBCPP_HIDE_FROM_ABI inline constexpr int __column_width_4(uint32_t __c) noexcept {
1071   _LIBCPP_ASSERT(__c >= 0x1'0000,
1072                  "Use __column_width_3 or __column_width for smaller values");
1073 
1074   // clang-format off
1075   return 1 + (__c >= 0x1'f300 && (__c <= 0x1'f64f ||
1076              (__c >= 0x1'f900 && (__c <= 0x1'f9ff ||
1077              (__c >= 0x2'0000 && (__c <= 0x2'fffd ||
1078              (__c >= 0x3'0000 && (__c <= 0x3'fffd
1079              ))))))));
1080   // clang-format on
1081 }
1082 
1083 /**
1084  * @overload
1085  *
1086  * The general case, accepting all values.
1087  */
1088 _LIBCPP_HIDE_FROM_ABI inline constexpr int __column_width(uint32_t __c) noexcept {
1089   if (__c < 0x1'0000)
1090     return __column_width_3(__c);
1091 
1092   return __column_width_4(__c);
1093 }
1094 
1095 /**
1096  * Estimate the column width for the UTF-8 sequence using the fast algorithm.
1097  */
1098 template <__utf8_character _CharT>
1099 _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
1100 __estimate_column_width_fast(const _CharT* __first,
1101                              const _CharT* __last) noexcept {
1102   return _VSTD::find_if(__first, __last,
1103                         [](unsigned char __c) { return __c & 0x80; });
1104 }
1105 
1106 /**
1107  * @overload
1108  *
1109  * The implementation for UTF-16/32.
1110  */
1111 template <__utf16_or_32_character _CharT>
1112 _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
1113 __estimate_column_width_fast(const _CharT* __first,
1114                              const _CharT* __last) noexcept {
1115   return _VSTD::find_if(__first, __last,
1116                         [](uint32_t __c) { return __c >= 0x1100; });
1117 }
1118 
1119 template <class _CharT>
1120 struct _LIBCPP_TEMPLATE_VIS __column_width_result {
1121   /** The number of output columns. */
1122   size_t __width;
1123   /**
1124    * The last parsed element.
1125    *
1126    * This limits the original output to fit in the wanted number of columns.
1127    */
1128   const _CharT* __ptr;
1129 };
1130 
1131 /**
1132  * Small helper to determine the width of malformed Unicode.
1133  *
1134  * @note This function's only needed for UTF-8. During scanning UTF-8 there
1135  * are multiple place where it can be detected that the Unicode is malformed.
1136  * UTF-16 only requires 1 test and UTF-32 requires no testing.
1137  */
1138 template <__utf8_character _CharT>
1139 _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT>
1140 __estimate_column_width_malformed(const _CharT* __first, const _CharT* __last,
1141                                   size_t __maximum, size_t __result) noexcept {
1142   size_t __size = __last - __first;
1143   size_t __n = _VSTD::min(__size, __maximum);
1144   return {__result + __n, __first + __n};
1145 }
1146 
1147 /**
1148  * Determines the number of output columns needed to render the input.
1149  *
1150  * @note When the scanner encounters malformed Unicode it acts as-if every code
1151  * unit at the end of the input is one output column. It's expected the output
1152  * terminal will replace these malformed code units with a one column
1153  * replacement characters.
1154  *
1155  * @param __first   Points to the first element of the input range.
1156  * @param __last    Points beyond the last element of the input range.
1157  * @param __maximum The maximum number of output columns. The returned number
1158  *                  of estimated output columns will not exceed this value.
1159  */
1160 template <__utf8_character _CharT>
1161 _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT>
1162 __estimate_column_width(const _CharT* __first, const _CharT* __last,
1163                         size_t __maximum) noexcept {
1164   size_t __result = 0;
1165 
1166   while (__first != __last) {
1167     // Based on the number of leading 1 bits the number of code units in the
1168     // code point can be determined. See
1169     // https://en.wikipedia.org/wiki/UTF-8#Encoding
1170     switch (_VSTD::countl_one(static_cast<unsigned char>(*__first))) {
1171     case 0: // 1-code unit encoding: all 1 column
1172       ++__result;
1173       ++__first;
1174       break;
1175 
1176     case 2: // 2-code unit encoding: all 1 column
1177       // Malformed Unicode.
1178       if (__last - __first < 2) [[unlikely]]
1179         return __estimate_column_width_malformed(__first, __last, __maximum,
1180                                                  __result);
1181       __first += 2;
1182       ++__result;
1183       break;
1184 
1185     case 3: // 3-code unit encoding: either 1 or 2 columns
1186       // Malformed Unicode.
1187       if (__last - __first < 3) [[unlikely]]
1188         return __estimate_column_width_malformed(__first, __last, __maximum,
1189                                                  __result);
1190       {
1191         uint32_t __c = static_cast<unsigned char>(*__first++) & 0x0f;
1192         __c <<= 6;
1193         __c |= static_cast<unsigned char>(*__first++) & 0x3f;
1194         __c <<= 6;
1195         __c |= static_cast<unsigned char>(*__first++) & 0x3f;
1196         __result += __column_width_3(__c);
1197         if (__result > __maximum)
1198           return {__result - 2, __first - 3};
1199       }
1200       break;
1201     case 4: // 4-code unit encoding: either 1 or 2 columns
1202       // Malformed Unicode.
1203       if (__last - __first < 4) [[unlikely]]
1204         return __estimate_column_width_malformed(__first, __last, __maximum,
1205                                                  __result);
1206       {
1207         uint32_t __c = static_cast<unsigned char>(*__first++) & 0x07;
1208         __c <<= 6;
1209         __c |= static_cast<unsigned char>(*__first++) & 0x3f;
1210         __c <<= 6;
1211         __c |= static_cast<unsigned char>(*__first++) & 0x3f;
1212         __c <<= 6;
1213         __c |= static_cast<unsigned char>(*__first++) & 0x3f;
1214         __result += __column_width_4(__c);
1215         if (__result > __maximum)
1216           return {__result - 2, __first - 4};
1217       }
1218       break;
1219     default:
1220       // Malformed Unicode.
1221       return __estimate_column_width_malformed(__first, __last, __maximum,
1222                                                __result);
1223     }
1224 
1225     if (__result >= __maximum)
1226       return {__result, __first};
1227   }
1228   return {__result, __first};
1229 }
1230 
1231 template <__utf16_character _CharT>
1232 _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT>
1233 __estimate_column_width(const _CharT* __first, const _CharT* __last,
1234                         size_t __maximum) noexcept {
1235   size_t __result = 0;
1236 
1237   while (__first != __last) {
1238     uint32_t __c = *__first;
1239     // Is the code unit part of a surrogate pair? See
1240     // https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF
1241     if (__c >= 0xd800 && __c <= 0xDfff) {
1242       // Malformed Unicode.
1243       if (__last - __first < 2) [[unlikely]]
1244         return {__result + 1, __first + 1};
1245 
1246       __c -= 0xd800;
1247       __c <<= 10;
1248       __c += (*(__first + 1) - 0xdc00);
1249       __c += 0x10'000;
1250 
1251       __result += __column_width_4(__c);
1252       if (__result > __maximum)
1253         return {__result - 2, __first};
1254       __first += 2;
1255     } else {
1256       __result += __column_width_3(__c);
1257       if (__result > __maximum)
1258         return {__result - 2, __first};
1259       ++__first;
1260     }
1261 
1262     if (__result >= __maximum)
1263       return {__result, __first};
1264   }
1265 
1266   return {__result, __first};
1267 }
1268 
1269 template <__utf32_character _CharT>
1270 _LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT>
1271 __estimate_column_width(const _CharT* __first, const _CharT* __last,
1272                         size_t __maximum) noexcept {
1273   size_t __result = 0;
1274 
1275   while (__first != __last) {
1276     uint32_t __c = *__first;
1277     __result += __column_width(__c);
1278 
1279     if (__result > __maximum)
1280       return {__result - 2, __first};
1281 
1282     ++__first;
1283     if (__result >= __maximum)
1284       return {__result, __first};
1285   }
1286 
1287   return {__result, __first};
1288 }
1289 
1290 } // namespace __detail
1291 
1292 template <class _CharT>
1293 _LIBCPP_HIDE_FROM_ABI constexpr __string_alignment<_CharT>
1294 __get_string_alignment(const _CharT* __first, const _CharT* __last,
1295                        ptrdiff_t __width, ptrdiff_t __precision) noexcept {
1296   _LIBCPP_ASSERT(__width != 0 || __precision != -1,
1297                  "The function has no effect and shouldn't be used");
1298 
1299   // TODO FMT There might be more optimizations possible:
1300   // If __precision == __format::__number_max and the encoding is:
1301   // * UTF-8  : 4 * (__last - __first) >= __width
1302   // * UTF-16 : 2 * (__last - __first) >= __width
1303   // * UTF-32 : (__last - __first) >= __width
1304   // In these cases it's certain the output is at least the requested width.
1305   // It's unknown how often this happens in practice. For now the improvement
1306   // isn't implemented.
1307 
1308   /*
1309    * First assume there are no special Unicode code units in the input.
1310    * - Apply the precision (this may reduce the size of the input). When
1311    *   __precison == -1 this step is omitted.
1312    * - Scan for special code units in the input.
1313    * If our assumption was correct the __pos will be at the end of the input.
1314    */
1315   const ptrdiff_t __length = __last - __first;
1316   const _CharT* __limit =
1317       __first +
1318       (__precision == -1 ? __length : _VSTD::min(__length, __precision));
1319   ptrdiff_t __size = __limit - __first;
1320   const _CharT* __pos =
1321       __detail::__estimate_column_width_fast(__first, __limit);
1322 
1323   if (__pos == __limit)
1324     return {__limit, __size, __size < __width};
1325 
1326   /*
1327    * Our assumption was wrong, there are special Unicode code units.
1328    * The range [__first, __pos) contains a set of code units with the
1329    * following property:
1330    *      Every _CharT in the range will be rendered in 1 column.
1331    *
1332    * If there's no maximum width and the parsed size already exceeds the
1333    *   minimum required width. The real size isn't important. So bail out.
1334    */
1335   if (__precision == -1 && (__pos - __first) >= __width)
1336     return {__last, 0, false};
1337 
1338   /* If there's a __precision, truncate the output to that width. */
1339   ptrdiff_t __prefix = __pos - __first;
1340   if (__precision != -1) {
1341     _LIBCPP_ASSERT(__precision > __prefix, "Logic error.");
1342     auto __lengh_info = __detail::__estimate_column_width(
1343         __pos, __last, __precision - __prefix);
1344     __size = __lengh_info.__width + __prefix;
1345     return {__lengh_info.__ptr, __size, __size < __width};
1346   }
1347 
1348   /* Else use __width to determine the number of required padding characters. */
1349   _LIBCPP_ASSERT(__width > __prefix, "Logic error.");
1350   /*
1351    * The column width is always one or two columns. For the precision the wanted
1352    * column width is the maximum, for the width it's the minimum. Using the
1353    * width estimation with its truncating behavior will result in the wrong
1354    * result in the following case:
1355    * - The last code unit processed requires two columns and exceeds the
1356    *   maximum column width.
1357    * By increasing the __maximum by one avoids this issue. (It means it may
1358    * pass one code point more than required to determine the proper result;
1359    * that however isn't a problem for the algorithm.)
1360    */
1361   size_t __maximum = 1 + __width - __prefix;
1362   auto __lengh_info =
1363       __detail::__estimate_column_width(__pos, __last, __maximum);
1364   if (__lengh_info.__ptr != __last) {
1365     // Consumed the width number of code units. The exact size of the string
1366     // is unknown. We only know we don't need to align the output.
1367     _LIBCPP_ASSERT(static_cast<ptrdiff_t>(__lengh_info.__width + __prefix) >=
1368                        __width,
1369                    "Logic error");
1370     return {__last, 0, false};
1371   }
1372 
1373   __size = __lengh_info.__width + __prefix;
1374   return {__last, __size, __size < __width};
1375 }
1376 #else  // _LIBCPP_HAS_NO_UNICODE
1377 template <class _CharT>
1378 _LIBCPP_HIDE_FROM_ABI constexpr __string_alignment<_CharT>
1379 __get_string_alignment(const _CharT* __first, const _CharT* __last,
1380                        ptrdiff_t __width, ptrdiff_t __precision) noexcept {
1381   const ptrdiff_t __length = __last - __first;
1382   const _CharT* __limit =
1383       __first +
1384       (__precision == -1 ? __length : _VSTD::min(__length, __precision));
1385   ptrdiff_t __size = __limit - __first;
1386   return {__limit, __size, __size < __width};
1387 }
1388 #endif // _LIBCPP_HAS_NO_UNICODE
1389 
1390 } // namespace __format_spec
1391 
1392 # endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
1393 
1394 #endif //_LIBCPP_STD_VER > 17
1395 
1396 _LIBCPP_END_NAMESPACE_STD
1397 
1398 _LIBCPP_POP_MACROS
1399 
1400 #endif // _LIBCPP___FORMAT_PARSER_STD_FORMAT_SPEC_H
1401