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