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