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