[libcxx-commits] [libcxx] 207e7e4 - [libc++[format][NFC] Removes dead code.

Mark de Wever via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jul 6 23:00:48 PDT 2022


Author: Mark de Wever
Date: 2022-07-07T08:00:43+02:00
New Revision: 207e7e4a70f49b4dda8edeb37f87157def0a51ab

URL: https://github.com/llvm/llvm-project/commit/207e7e4a70f49b4dda8edeb37f87157def0a51ab
DIFF: https://github.com/llvm/llvm-project/commit/207e7e4a70f49b4dda8edeb37f87157def0a51ab.diff

LOG: [libc++[format][NFC] Removes dead code.

This removes a part of the now obsolete formater code.
The removal also removes the _v2 suffix where it's no longer needed.

Depends on D128785

Reviewed By: #libc, ldionne

Differential Revision: https://reviews.llvm.org/D128846

Added: 
    

Modified: 
    libcxx/include/__format/formatter.h
    libcxx/include/__format/formatter_floating_point.h
    libcxx/include/__format/formatter_output.h
    libcxx/include/__format/parser_std_format_spec.h

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__format/formatter.h b/libcxx/include/__format/formatter.h
index c39e25b354eb..4816f961c445 100644
--- a/libcxx/include/__format/formatter.h
+++ b/libcxx/include/__format/formatter.h
@@ -10,20 +10,10 @@
 #ifndef _LIBCPP___FORMAT_FORMATTER_H
 #define _LIBCPP___FORMAT_FORMATTER_H
 
-#include <__algorithm/copy.h>
-#include <__algorithm/fill_n.h>
-#include <__algorithm/transform.h>
-#include <__assert>
 #include <__availability>
 #include <__concepts/same_as.h>
 #include <__config>
-#include <__format/format_error.h>
 #include <__format/format_fwd.h>
-#include <__format/format_string.h>
-#include <__format/parser_std_format_spec.h>
-#include <__utility/move.h>
-#include <__utility/unreachable.h>
-#include <string_view>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
@@ -49,229 +39,12 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT formatter {
   formatter& operator=(const formatter&) = delete;
 };
 
-namespace __format_spec {
-
-_LIBCPP_HIDE_FROM_ABI inline char* __insert_sign(char* __buf, bool __negative,
-                                                 _Flags::_Sign __sign) {
-  if (__negative)
-    *__buf++ = '-';
-  else
-    switch (__sign) {
-    case _Flags::_Sign::__default:
-    case _Flags::_Sign::__minus:
-      // No sign added.
-      break;
-    case _Flags::_Sign::__plus:
-      *__buf++ = '+';
-      break;
-    case _Flags::_Sign::__space:
-      *__buf++ = ' ';
-      break;
-    }
-
-  return __buf;
-}
-
-_LIBCPP_HIDE_FROM_ABI constexpr char __hex_to_upper(char c) {
-  switch (c) {
-  case 'a':
-    return 'A';
-  case 'b':
-    return 'B';
-  case 'c':
-    return 'C';
-  case 'd':
-    return 'D';
-  case 'e':
-    return 'E';
-  case 'f':
-    return 'F';
-  }
-  return c;
-}
-
-} // namespace __format_spec
-
 namespace __formatter {
 
 /** The character types that formatters are specialized for. */
 template <class _CharT>
 concept __char_type = same_as<_CharT, char> || same_as<_CharT, wchar_t>;
 
-struct _LIBCPP_TEMPLATE_VIS __padding_size_result {
-  size_t __before;
-  size_t __after;
-};
-
-_LIBCPP_HIDE_FROM_ABI constexpr __padding_size_result
-__padding_size(size_t __size, size_t __width,
-               __format_spec::_Flags::_Alignment __align) {
-  _LIBCPP_ASSERT(__width > __size,
-                 "Don't call this function when no padding is required");
-  _LIBCPP_ASSERT(
-      __align != __format_spec::_Flags::_Alignment::__default,
-      "Caller should adjust the default to the value required by the type");
-
-  size_t __fill = __width - __size;
-  switch (__align) {
-  case __format_spec::_Flags::_Alignment::__default:
-    __libcpp_unreachable();
-
-  case __format_spec::_Flags::_Alignment::__left:
-    return {0, __fill};
-
-  case __format_spec::_Flags::_Alignment::__center: {
-    // The extra padding is divided per [format.string.std]/3
-    // __before = floor(__fill, 2);
-    // __after = ceil(__fill, 2);
-    size_t __before = __fill / 2;
-    size_t __after = __fill - __before;
-    return {__before, __after};
-  }
-  case __format_spec::_Flags::_Alignment::__right:
-    return {__fill, 0};
-  }
-  __libcpp_unreachable();
-}
-
-/**
- * Writes the input to the output with the required padding.
- *
- * Since the output column width is specified the function can be used for
- * ASCII and Unicode input.
- *
- * @pre [@a __first, @a __last) is a valid range.
- * @pre @a __size <= @a __width. Using this function when this pre-condition
- *      doesn't hold incurs an unwanted overhead.
- *
- * @param __out_it    The output iterator to write to.
- * @param __first     Pointer to the first element to write.
- * @param __last      Pointer beyond the last element to write.
- * @param __size      The (estimated) output column width. When the elements
- *                    to be written are ASCII the following condition holds
- *                    @a __size == @a __last - @a __first.
- * @param __width     The number of output columns to write.
- * @param __fill      The character used for the alignment of the output.
- *                    TODO FMT Will probably change to support Unicode grapheme
- *                    cluster.
- * @param __alignment The requested alignment.
- *
- * @returns           An iterator pointing beyond the last element written.
- *
- * @note The type of the elements in range [@a __first, @a __last) can 
diff er
- * from the type of @a __fill. Integer output uses @c std::to_chars for its
- * conversion, which means the [@a __first, @a __last) always contains elements
- * of the type @c char.
- */
-template <class _CharT, class _Fill>
-_LIBCPP_HIDE_FROM_ABI auto
-__write(output_iterator<const _CharT&> auto __out_it, const _CharT* __first,
-        const _CharT* __last, size_t __size, size_t __width, _Fill __fill,
-        __format_spec::_Flags::_Alignment __alignment) -> decltype(__out_it) {
-
-  _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
-  _LIBCPP_ASSERT(__size < __width, "Precondition failure");
-
-  __padding_size_result __padding =
-      __padding_size(__size, __width, __alignment);
-  __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill);
-  __out_it = _VSTD::copy(__first, __last, _VSTD::move(__out_it));
-  return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill);
-}
-
-/**
- * @overload
- *
- * Writes additional zero's for the precision before the exponent.
- * This is used when the precision requested in the format string is larger
- * than the maximum precision of the floating-point type. These precision
- * digits are always 0.
- *
- * @param __exponent           The location of the exponent character.
- * @param __num_trailing_zeros The number of 0's to write before the exponent
- *                             character.
- */
-template <class _CharT, class _Fill>
-_LIBCPP_HIDE_FROM_ABI auto __write(output_iterator<const _CharT&> auto __out_it, const _CharT* __first,
-                                   const _CharT* __last, size_t __size, size_t __width, _Fill __fill,
-                                   __format_spec::_Flags::_Alignment __alignment, const _CharT* __exponent,
-                                   size_t __num_trailing_zeros) -> decltype(__out_it) {
-  _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
-  _LIBCPP_ASSERT(__num_trailing_zeros > 0, "The overload not writing trailing zeros should have been used");
-
-  __padding_size_result __padding = __padding_size(__size + __num_trailing_zeros, __width, __alignment);
-  __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill);
-  __out_it = _VSTD::copy(__first, __exponent, _VSTD::move(__out_it));
-  __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0'));
-  __out_it = _VSTD::copy(__exponent, __last, _VSTD::move(__out_it));
-  return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill);
-}
-
-/**
- * @overload
- *
- * Uses a transformation operation before writing an element.
- *
- * TODO FMT Fill will probably change to support Unicode grapheme cluster.
- */
-template <class _CharT, class _UnaryOperation, class _Fill>
-_LIBCPP_HIDE_FROM_ABI auto
-__write(output_iterator<const _CharT&> auto __out_it, const _CharT* __first,
-        const _CharT* __last, size_t __size, _UnaryOperation __op,
-        size_t __width, _Fill __fill,
-        __format_spec::_Flags::_Alignment __alignment) -> decltype(__out_it) {
-
-  _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
-  _LIBCPP_ASSERT(__size < __width, "Precondition failure");
-
-  __padding_size_result __padding =
-      __padding_size(__size, __width, __alignment);
-  __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before, __fill);
-  __out_it = _VSTD::transform(__first, __last, _VSTD::move(__out_it), __op);
-  return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after, __fill);
-}
-
-/**
- * Writes Unicode input to the output with the required padding.
- *
- * This function does almost the same as the @ref __write function, but handles
- * the width estimation of the Unicode input.
- *
- * @param __str       The range [@a __first, @a __last).
- * @param __precision The width to truncate the input string to, use @c -1 for
- *                     no limit.
- */
-template <class _CharT, class _Fill>
-_LIBCPP_HIDE_FROM_ABI auto
-__write_unicode(output_iterator<const _CharT&> auto __out_it,
-                basic_string_view<_CharT> __str, ptr
diff _t __width,
-                ptr
diff _t __precision, _Fill __fill,
-                __format_spec::_Flags::_Alignment __alignment)
-    -> decltype(__out_it) {
-
-  // This value changes when there Unicode column width limits the output
-  // size.
-  auto __last = __str.end();
-  if (__width != 0 || __precision != -1) {
-    __format_spec::__string_alignment<_CharT> __format_traits =
-        __format_spec::__get_string_alignment(__str.begin(), __str.end(),
-                                              __width, __precision);
-
-    if (__format_traits.__align)
-      return __write(_VSTD::move(__out_it), __str.begin(),
-                     __format_traits.__last, __format_traits.__size, __width,
-                     __fill, __alignment);
-
-    // No alignment required update the output based on the precision.
-    // This might be the same as __str.end().
-    __last = __format_traits.__last;
-  }
-
-  // Copy the input to the output. The output size might be limited by the
-  // precision.
-  return _VSTD::copy(__str.begin(), __last, _VSTD::move(__out_it));
-}
-
 } // namespace __formatter
 
 #endif //_LIBCPP_STD_VER > 17

diff  --git a/libcxx/include/__format/formatter_floating_point.h b/libcxx/include/__format/formatter_floating_point.h
index 9d8de95a7005..90a76193196e 100644
--- a/libcxx/include/__format/formatter_floating_point.h
+++ b/libcxx/include/__format/formatter_floating_point.h
@@ -514,7 +514,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form(
       __grouping.size() -                  // Grouping contains one
       !__grouping.empty();                 // additional character
 
-  __formatter::__padding_size_result_v2 __padding = {0, 0};
+  __formatter::__padding_size_result __padding    = {0, 0};
   bool __zero_padding                             = __specs.__alignment_ == __format_spec::__alignment::__zero_padding;
   if (__size < __specs.__width_) {
     if (__zero_padding) {
@@ -522,7 +522,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __format_locale_specific_form(
       __specs.__fill_      = _CharT('0');
     }
 
-    __padding = __formatter::__padding_size_v2(__size, __specs.__width_, __specs.__alignment_);
+    __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__alignment_);
   }
 
   // sign and (zero padding or alignment)

diff  --git a/libcxx/include/__format/formatter_output.h b/libcxx/include/__format/formatter_output.h
index f9f18a01c5bb..fc2cc2fb28a0 100644
--- a/libcxx/include/__format/formatter_output.h
+++ b/libcxx/include/__format/formatter_output.h
@@ -51,15 +51,13 @@ _LIBCPP_HIDE_FROM_ABI constexpr char __hex_to_upper(char c) {
   return c;
 }
 
-// TODO FMT remove _v2 suffix.
-struct _LIBCPP_TYPE_VIS __padding_size_result_v2 {
+struct _LIBCPP_TYPE_VIS __padding_size_result {
   size_t __before_;
   size_t __after_;
 };
 
-// TODO FMT remove _v2 suffix.
-_LIBCPP_HIDE_FROM_ABI constexpr __padding_size_result_v2 __padding_size_v2(size_t __size, size_t __width,
-                                                                           __format_spec::__alignment __align) {
+_LIBCPP_HIDE_FROM_ABI constexpr __padding_size_result
+__padding_size(size_t __size, size_t __width, __format_spec::__alignment __align) {
   _LIBCPP_ASSERT(__width > __size, "don't call this function when no padding is required");
   _LIBCPP_ASSERT(__align != __format_spec::__alignment::__default,
                  "the caller should adjust the default to the value required by the type");
@@ -100,7 +98,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, c
                (__last - __first) +     // data
                (__grouping.size() - 1); // number of separator characters
 
-  __padding_size_result_v2 __padding = {0, 0};
+  __padding_size_result __padding = {0, 0};
   if (__specs.__alignment_ == __format_spec::__alignment::__zero_padding) {
     // Write [sign][prefix].
     __out_it = _VSTD::copy(__begin, __first, _VSTD::move(__out_it));
@@ -113,7 +111,7 @@ _LIBCPP_HIDE_FROM_ABI _OutIt __write_using_decimal_separators(_OutIt __out_it, c
   } else {
     if (__specs.__width_ > __size) {
       // Determine padding and write padding.
-      __padding = __padding_size_v2(__size, __specs.__width_, __specs.__alignment_);
+      __padding = __padding_size(__size, __specs.__width_, __specs.__alignment_);
 
       __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
     }
@@ -189,8 +187,7 @@ _LIBCPP_HIDE_FROM_ABI auto __write(const _CharT* __first, const _CharT* __last,
   if (__size >= __specs.__width_)
     return _VSTD::copy(__first, __last, _VSTD::move(__out_it));
 
-  __padding_size_result_v2 __padding =
-      __formatter::__padding_size_v2(__size, __specs.__width_, __specs.__std_.__alignment_);
+  __padding_size_result __padding = __formatter::__padding_size(__size, __specs.__width_, __specs.__std_.__alignment_);
   __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
   __out_it = _VSTD::copy(__first, __last, _VSTD::move(__out_it));
   return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
@@ -216,7 +213,7 @@ _LIBCPP_HIDE_FROM_ABI auto __write_transformed(const _CharT* __first, const _Cha
   if (__size >= __specs.__width_)
     return _VSTD::transform(__first, __last, _VSTD::move(__out_it), __op);
 
-  __padding_size_result_v2 __padding = __padding_size_v2(__size, __specs.__width_, __specs.__alignment_);
+  __padding_size_result __padding = __padding_size(__size, __specs.__width_, __specs.__alignment_);
   __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
   __out_it = _VSTD::transform(__first, __last, _VSTD::move(__out_it), __op);
   return _VSTD::fill_n(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
@@ -242,8 +239,8 @@ _LIBCPP_HIDE_FROM_ABI auto __write_using_trailing_zeros(
   _LIBCPP_ASSERT(__first <= __last, "Not a valid range");
   _LIBCPP_ASSERT(__num_trailing_zeros > 0, "The overload not writing trailing zeros should have been used");
 
-  __padding_size_result_v2 __padding =
-      __padding_size_v2(__size + __num_trailing_zeros, __specs.__width_, __specs.__alignment_);
+  __padding_size_result __padding =
+      __padding_size(__size + __num_trailing_zeros, __specs.__width_, __specs.__alignment_);
   __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __padding.__before_, __specs.__fill_);
   __out_it = _VSTD::copy(__first, __exponent, _VSTD::move(__out_it));
   __out_it = _VSTD::fill_n(_VSTD::move(__out_it), __num_trailing_zeros, _CharT('0'));

diff  --git a/libcxx/include/__format/parser_std_format_spec.h b/libcxx/include/__format/parser_std_format_spec.h
index de513b051a04..630f6fde24a8 100644
--- a/libcxx/include/__format/parser_std_format_spec.h
+++ b/libcxx/include/__format/parser_std_format_spec.h
@@ -44,168 +44,6 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 namespace __format_spec {
 
-/**
- * Contains the flags for the std-format-spec.
- *
- * Some format-options can only be used for specific C++ types and may depend on
- * the selected format-type.
- * * The C++type filtering can be done using the proper policies for
- *   @ref __parser_std.
- * * The format-type filtering needs to be done post parsing in the parser
- *   derived from @ref __parser_std.
- */
-_LIBCPP_PACKED_BYTE_FOR_AIX
-class _LIBCPP_TYPE_VIS _Flags {
-public:
-  enum class _LIBCPP_ENUM_VIS _Alignment : uint8_t {
-    /**
-     * No alignment is set in the format string.
-     *
-     * Zero-padding is ignored when an alignment is selected.
-     * The default alignment depends on the selected format-type.
-     */
-    __default,
-    __left,
-    __center,
-    __right
-  };
-  enum class _LIBCPP_ENUM_VIS _Sign : uint8_t {
-    /**
-     * No sign is set in the format string.
-     *
-     * The sign isn't allowed for certain format-types. By using this value
-     * it's possible to detect whether or not the user explicitly set the sign
-     * flag. For formatting purposes it behaves the same as @ref __minus.
-     */
-    __default,
-    __minus,
-    __plus,
-    __space
-  };
-
-  _Alignment __alignment : 2 {_Alignment::__default};
-  _Sign __sign : 2 {_Sign::__default};
-  uint8_t __alternate_form : 1 {false};
-  uint8_t __zero_padding : 1 {false};
-  uint8_t __locale_specific_form : 1 {false};
-
-  enum class _LIBCPP_ENUM_VIS _Type : uint8_t {
-    __default,
-    __string,
-    __binary_lower_case,
-    __binary_upper_case,
-    __octal,
-    __decimal,
-    __hexadecimal_lower_case,
-    __hexadecimal_upper_case,
-    __pointer,
-    __char,
-    __float_hexadecimal_lower_case,
-    __float_hexadecimal_upper_case,
-    __scientific_lower_case,
-    __scientific_upper_case,
-    __fixed_lower_case,
-    __fixed_upper_case,
-    __general_lower_case,
-    __general_upper_case
-  };
-
-  _Type __type{_Type::__default};
-};
-_LIBCPP_PACKED_BYTE_FOR_AIX_END
-
-namespace __detail {
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr bool
-__parse_alignment(_CharT __c, _Flags& __flags) noexcept {
-  switch (__c) {
-  case _CharT('<'):
-    __flags.__alignment = _Flags::_Alignment::__left;
-    return true;
-
-  case _CharT('^'):
-    __flags.__alignment = _Flags::_Alignment::__center;
-    return true;
-
-  case _CharT('>'):
-    __flags.__alignment = _Flags::_Alignment::__right;
-    return true;
-  }
-  return false;
-}
-} // namespace __detail
-
-template <class _CharT>
-class _LIBCPP_TEMPLATE_VIS __parser_fill_align {
-public:
-  // TODO FMT The standard doesn't specify this character is a Unicode
-  // character. Validate what fmt and MSVC have implemented.
-  _CharT __fill{_CharT(' ')};
-
-protected:
-  _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
-  __parse(const _CharT* __begin, const _CharT* __end, _Flags& __flags) {
-    _LIBCPP_ASSERT(__begin != __end,
-                   "When called with an empty input the function will cause "
-                   "undefined behavior by evaluating data not in the input");
-    if (__begin + 1 != __end) {
-      if (__detail::__parse_alignment(*(__begin + 1), __flags)) {
-        if (*__begin == _CharT('{') || *__begin == _CharT('}'))
-          __throw_format_error(
-              "The format-spec fill field contains an invalid character");
-        __fill = *__begin;
-        return __begin + 2;
-      }
-    }
-
-    if (__detail::__parse_alignment(*__begin, __flags))
-      return __begin + 1;
-
-    return __begin;
-  }
-};
-
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
-__parse_sign(const _CharT* __begin, _Flags& __flags) noexcept {
-  switch (*__begin) {
-  case _CharT('-'):
-    __flags.__sign = _Flags::_Sign::__minus;
-    break;
-  case _CharT('+'):
-    __flags.__sign = _Flags::_Sign::__plus;
-    break;
-  case _CharT(' '):
-    __flags.__sign = _Flags::_Sign::__space;
-    break;
-  default:
-    return __begin;
-  }
-  return __begin + 1;
-}
-
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
-__parse_alternate_form(const _CharT* __begin, _Flags& __flags) noexcept {
-  if (*__begin == _CharT('#')) {
-    __flags.__alternate_form = true;
-    ++__begin;
-  }
-
-  return __begin;
-}
-
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
-__parse_zero_padding(const _CharT* __begin, _Flags& __flags) noexcept {
-  if (*__begin == _CharT('0')) {
-    __flags.__zero_padding = true;
-    ++__begin;
-  }
-
-  return __begin;
-}
-
 template <class _CharT>
 _LIBCPP_HIDE_FROM_ABI constexpr __format::__parse_number_result< _CharT>
 __parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
@@ -253,682 +91,6 @@ __substitute_arg_id(basic_format_arg<_Context> _Arg) {
       _Arg);
 }
 
-class _LIBCPP_TYPE_VIS __parser_width {
-public:
-  /** Contains a width or an arg-id. */
-  uint32_t __width : 31 {0};
-  /** Determines whether the value stored is a width or an arg-id. */
-  uint32_t __width_as_arg : 1 {0};
-
-  /**
-   * Does the supplied width field contain an arg-id?
-   *
-   * If @c true the formatter needs to call @ref __substitute_width_arg_id.
-   */
-  constexpr bool __width_needs_substitution() const noexcept { return __width_as_arg; }
-
-protected:
-  /**
-   * Does the supplied std-format-spec contain a width field?
-   *
-   * When the field isn't present there's no padding required. This can be used
-   * to optimize the formatting.
-   */
-  constexpr bool __has_width_field() const noexcept { return __width_as_arg || __width; }
-
-  template <class _CharT>
-  _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
-  __parse(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
-    if (*__begin == _CharT('0'))
-      __throw_format_error(
-          "A format-spec width field shouldn't have a leading zero");
-
-    if (*__begin == _CharT('{')) {
-      __format::__parse_number_result __r =
-          __parse_arg_id(++__begin, __end, __parse_ctx);
-      __width = __r.__value;
-      __width_as_arg = 1;
-      return __r.__ptr;
-    }
-
-    if (*__begin < _CharT('0') || *__begin > _CharT('9'))
-      return __begin;
-
-    __format::__parse_number_result __r =
-        __format::__parse_number(__begin, __end);
-    __width = __r.__value;
-    _LIBCPP_ASSERT(__width != 0,
-                   "A zero value isn't allowed and should be impossible, "
-                   "due to validations in this function");
-    return __r.__ptr;
-  }
-
-  _LIBCPP_HIDE_FROM_ABI constexpr void __substitute_width_arg_id(auto __arg) {
-    _LIBCPP_ASSERT(__width_as_arg == 1,
-                   "Substitute width called when no substitution is required");
-
-    // The clearing of the flag isn't required but looks better when debugging
-    // the code.
-    __width_as_arg = 0;
-    __width = __substitute_arg_id(__arg);
-    if (__width == 0)
-      __throw_format_error(
-          "A format-spec width field replacement should have a positive value");
-  }
-};
-
-class _LIBCPP_TYPE_VIS __parser_precision {
-public:
-  /** Contains a precision or an arg-id. */
-  uint32_t __precision : 31 {__format::__number_max};
-  /**
-   * Determines whether the value stored is a precision or an arg-id.
-   *
-   * @note Since @ref __precision == @ref __format::__number_max is a valid
-   * value, the default value contains an arg-id of INT32_MAX. (This number of
-   * arguments isn't supported by compilers.)  This is used to detect whether
-   * the std-format-spec contains a precision field.
-   */
-  uint32_t __precision_as_arg : 1 {1};
-
-  /**
-   * Does the supplied precision field contain an arg-id?
-   *
-   * If @c true the formatter needs to call @ref __substitute_precision_arg_id.
-   */
-  constexpr bool __precision_needs_substitution() const noexcept {
-    return __precision_as_arg && __precision != __format::__number_max;
-  }
-
-protected:
-  /**
-   * Does the supplied std-format-spec contain a precision field?
-   *
-   * When the field isn't present there's no truncating required. This can be
-   * used to optimize the formatting.
-   */
-  constexpr bool __has_precision_field() const noexcept {
-
-    return __precision_as_arg == 0 ||             // Contains a value?
-           __precision != __format::__number_max; // The arg-id is valid?
-  }
-
-  template <class _CharT>
-  _LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
-  __parse(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
-    if (*__begin != _CharT('.'))
-      return __begin;
-
-    ++__begin;
-    if (__begin == __end)
-      __throw_format_error("End of input while parsing format-spec precision");
-
-    if (*__begin == _CharT('{')) {
-      __format::__parse_number_result __arg_id =
-          __parse_arg_id(++__begin, __end, __parse_ctx);
-      _LIBCPP_ASSERT(__arg_id.__value != __format::__number_max,
-                     "Unsupported number of arguments, since this number of "
-                     "arguments is used a special value");
-      __precision = __arg_id.__value;
-      return __arg_id.__ptr;
-    }
-
-    if (*__begin < _CharT('0') || *__begin > _CharT('9'))
-      __throw_format_error(
-          "The format-spec precision field doesn't contain a value or arg-id");
-
-    __format::__parse_number_result __r =
-        __format::__parse_number(__begin, __end);
-    __precision = __r.__value;
-    __precision_as_arg = 0;
-    return __r.__ptr;
-  }
-
-  _LIBCPP_HIDE_FROM_ABI constexpr void __substitute_precision_arg_id(
-      auto __arg) {
-    _LIBCPP_ASSERT(
-        __precision_as_arg == 1 && __precision != __format::__number_max,
-        "Substitute precision called when no substitution is required");
-
-    // The clearing of the flag isn't required but looks better when debugging
-    // the code.
-    __precision_as_arg = 0;
-    __precision = __substitute_arg_id(__arg);
-  }
-};
-
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
-__parse_locale_specific_form(const _CharT* __begin, _Flags& __flags) noexcept {
-  if (*__begin == _CharT('L')) {
-    __flags.__locale_specific_form = true;
-    ++__begin;
-  }
-
-  return __begin;
-}
-
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
-__parse_type(const _CharT* __begin, _Flags& __flags) {
-
-  // Determines the type. It does not validate whether the selected type is
-  // valid. Most formatters have optional fields that are only allowed for
-  // certain types. These parsers need to do validation after the type has
-  // been parsed. So its easier to implement the validation for all types in
-  // the specific parse function.
-  switch (*__begin) {
-  case 'A':
-    __flags.__type = _Flags::_Type::__float_hexadecimal_upper_case;
-    break;
-  case 'B':
-    __flags.__type = _Flags::_Type::__binary_upper_case;
-    break;
-  case 'E':
-    __flags.__type = _Flags::_Type::__scientific_upper_case;
-    break;
-  case 'F':
-    __flags.__type = _Flags::_Type::__fixed_upper_case;
-    break;
-  case 'G':
-    __flags.__type = _Flags::_Type::__general_upper_case;
-    break;
-  case 'X':
-    __flags.__type = _Flags::_Type::__hexadecimal_upper_case;
-    break;
-  case 'a':
-    __flags.__type = _Flags::_Type::__float_hexadecimal_lower_case;
-    break;
-  case 'b':
-    __flags.__type = _Flags::_Type::__binary_lower_case;
-    break;
-  case 'c':
-    __flags.__type = _Flags::_Type::__char;
-    break;
-  case 'd':
-    __flags.__type = _Flags::_Type::__decimal;
-    break;
-  case 'e':
-    __flags.__type = _Flags::_Type::__scientific_lower_case;
-    break;
-  case 'f':
-    __flags.__type = _Flags::_Type::__fixed_lower_case;
-    break;
-  case 'g':
-    __flags.__type = _Flags::_Type::__general_lower_case;
-    break;
-  case 'o':
-    __flags.__type = _Flags::_Type::__octal;
-    break;
-  case 'p':
-    __flags.__type = _Flags::_Type::__pointer;
-    break;
-  case 's':
-    __flags.__type = _Flags::_Type::__string;
-    break;
-  case 'x':
-    __flags.__type = _Flags::_Type::__hexadecimal_lower_case;
-    break;
-  default:
-    return __begin;
-  }
-  return ++__begin;
-}
-
-/**
- * Process the parsed alignment and zero-padding state of arithmetic types.
- *
- * [format.string.std]/13
- *   If the 0 character and an align option both appear, the 0 character is
- *   ignored.
- *
- * For the formatter a @ref __default alignment means zero-padding.
- */
-_LIBCPP_HIDE_FROM_ABI constexpr void __process_arithmetic_alignment(_Flags& __flags) {
-  __flags.__zero_padding &= __flags.__alignment == _Flags::_Alignment::__default;
-  if (!__flags.__zero_padding && __flags.__alignment == _Flags::_Alignment::__default)
-    __flags.__alignment = _Flags::_Alignment::__right;
-}
-
-/**
- * The parser for the std-format-spec.
- *
- * [format.string.std]/1 specifies the std-format-spec:
- *   fill-and-align sign # 0 width precision L type
- *
- * All these fields are optional. Whether these fields can be used depend on:
- * - The type supplied to the format string.
- *   E.g. A string never uses the sign field so the field may not be set.
- *   This constrain is validated by the parsers in this file.
- * - The supplied value for the optional type field.
- *   E.g. A int formatted as decimal uses the sign field.
- *   When formatted as a char the sign field may no longer be set.
- *   This constrain isn't validated by the parsers in this file.
- *
- * The base classes are ordered to minimize the amount of padding.
- *
- * This implements the parser for the string types.
- */
-template <class _CharT>
-class _LIBCPP_TEMPLATE_VIS __parser_string
-    : public __parser_width,              // provides __width(|as_arg)
-      public __parser_precision,          // provides __precision(|as_arg)
-      public __parser_fill_align<_CharT>, // provides __fill and uses __flags
-      public _Flags                       // provides __flags
-{
-public:
-  using char_type = _CharT;
-
-  _LIBCPP_HIDE_FROM_ABI constexpr __parser_string() {
-    this->__alignment = _Flags::_Alignment::__left;
-  }
-
-  /**
-   * The low-level std-format-spec parse function.
-   *
-   * @pre __begin points at the beginning of the std-format-spec. This means
-   * directly after the ':'.
-   * @pre The std-format-spec parses the entire input, or the first unmatched
-   * character is a '}'.
-   *
-   * @returns The iterator pointing at the last parsed character.
-   */
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    auto __it = __parse(__parse_ctx);
-    __process_display_type();
-    return __it;
-  }
-
-private:
-  /**
-   * Parses the std-format-spec.
-   *
-   * @throws __throw_format_error When @a __parse_ctx contains an ill-formed
-   *                               std-format-spec.
-   *
-   * @returns An iterator to the end of input or point at the closing '}'.
-   */
-  _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-
-    auto __begin = __parse_ctx.begin();
-    auto __end = __parse_ctx.end();
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parser_fill_align<_CharT>::__parse(__begin, __end,
-                                                   static_cast<_Flags&>(*this));
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parser_width::__parse(__begin, __end, __parse_ctx);
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parser_precision::__parse(__begin, __end, __parse_ctx);
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parse_type(__begin, static_cast<_Flags&>(*this));
-
-    if (__begin != __end && *__begin != _CharT('}'))
-      __throw_format_error(
-          "The format-spec should consume the input or end with a '}'");
-
-    return __begin;
-  }
-
-  /** Processes the parsed std-format-spec based on the parsed display type. */
-  _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type() {
-    switch (this->__type) {
-    case _Flags::_Type::__default:
-    case _Flags::_Type::__string:
-      break;
-
-    default:
-      __throw_format_error("The format-spec type has a type not supported for "
-                           "a string argument");
-    }
-  }
-};
-
-/**
- * The parser for the std-format-spec.
- *
- * This implements the parser for the integral types. This includes the
- * character type and boolean type.
- *
- * See @ref __parser_string.
- */
-template <class _CharT>
-class _LIBCPP_TEMPLATE_VIS __parser_integral
-    : public __parser_width,              // provides __width(|as_arg)
-      public __parser_fill_align<_CharT>, // provides __fill and uses __flags
-      public _Flags                       // provides __flags
-{
-public:
-  using char_type = _CharT;
-
-protected:
-  /**
-   * The low-level std-format-spec parse function.
-   *
-   * @pre __begin points at the beginning of the std-format-spec. This means
-   * directly after the ':'.
-   * @pre The std-format-spec parses the entire input, or the first unmatched
-   * character is a '}'.
-   *
-   * @returns The iterator pointing at the last parsed character.
-   */
-  _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    auto __begin = __parse_ctx.begin();
-    auto __end = __parse_ctx.end();
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parser_fill_align<_CharT>::__parse(__begin, __end,
-                                                   static_cast<_Flags&>(*this));
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parse_sign(__begin, static_cast<_Flags&>(*this));
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parse_alternate_form(__begin, static_cast<_Flags&>(*this));
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parse_zero_padding(__begin, static_cast<_Flags&>(*this));
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parser_width::__parse(__begin, __end, __parse_ctx);
-    if (__begin == __end)
-      return __begin;
-
-    __begin =
-        __parse_locale_specific_form(__begin, static_cast<_Flags&>(*this));
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parse_type(__begin, static_cast<_Flags&>(*this));
-
-    if (__begin != __end && *__begin != _CharT('}'))
-      __throw_format_error(
-          "The format-spec should consume the input or end with a '}'");
-
-    return __begin;
-  }
-
-  /** Handles the post-parsing updates for the integer types. */
-  _LIBCPP_HIDE_FROM_ABI constexpr void __handle_integer() noexcept {
-    __process_arithmetic_alignment(static_cast<_Flags&>(*this));
-  }
-
-  /**
-   * Handles the post-parsing updates for the character types.
-   *
-   * Sets the alignment and validates the format flags set for a character type.
-   *
-   * At the moment the validation for a character and a Boolean behave the
-   * same, but this may change in the future.
-   * Specifically at the moment the locale-specific form is allowed for the
-   * char output type, but it has no effect on the output.
-   */
-  _LIBCPP_HIDE_FROM_ABI constexpr void __handle_char() { __handle_bool(); }
-
-  /**
-   * Handles the post-parsing updates for the Boolean types.
-   *
-   * Sets the alignment and validates the format flags set for a Boolean type.
-   */
-  _LIBCPP_HIDE_FROM_ABI constexpr void __handle_bool() {
-    if (this->__sign != _Flags::_Sign::__default)
-      __throw_format_error("A sign field isn't allowed in this format-spec");
-
-    if (this->__alternate_form)
-      __throw_format_error(
-          "An alternate form field isn't allowed in this format-spec");
-
-    if (this->__zero_padding)
-      __throw_format_error(
-          "A zero-padding field isn't allowed in this format-spec");
-
-    if (this->__alignment == _Flags::_Alignment::__default)
-      this->__alignment = _Flags::_Alignment::__left;
-  }
-};
-
-/**
- * The parser for the std-format-spec.
- *
- * This implements the parser for the floating-point types.
- *
- * See @ref __parser_string.
- */
-template <class _CharT>
-class _LIBCPP_TEMPLATE_VIS __parser_floating_point
-    : public __parser_width,              // provides __width(|as_arg)
-      public __parser_precision,          // provides __precision(|as_arg)
-      public __parser_fill_align<_CharT>, // provides __fill and uses __flags
-      public _Flags                       // provides __flags
-{
-public:
-  using char_type = _CharT;
-
-  /**
-   * The low-level std-format-spec parse function.
-   *
-   * @pre __begin points at the beginning of the std-format-spec. This means
-   * directly after the ':'.
-   * @pre The std-format-spec parses the entire input, or the first unmatched
-   * character is a '}'.
-   *
-   * @returns The iterator pointing at the last parsed character.
-   */
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    auto __it = __parse(__parse_ctx);
-    __process_arithmetic_alignment(static_cast<_Flags&>(*this));
-    __process_display_type();
-    return __it;
-  }
-protected:
-  /**
-   * The low-level std-format-spec parse function.
-   *
-   * @pre __begin points at the beginning of the std-format-spec. This means
-   * directly after the ':'.
-   * @pre The std-format-spec parses the entire input, or the first unmatched
-   * character is a '}'.
-   *
-   * @returns The iterator pointing at the last parsed character.
-   */
-  _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx)
-      -> decltype(__parse_ctx.begin()) {
-    auto __begin = __parse_ctx.begin();
-    auto __end = __parse_ctx.end();
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parser_fill_align<_CharT>::__parse(__begin, __end,
-                                                   static_cast<_Flags&>(*this));
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parse_sign(__begin, static_cast<_Flags&>(*this));
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parse_alternate_form(__begin, static_cast<_Flags&>(*this));
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parse_zero_padding(__begin, static_cast<_Flags&>(*this));
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parser_width::__parse(__begin, __end, __parse_ctx);
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parser_precision::__parse(__begin, __end, __parse_ctx);
-    if (__begin == __end)
-      return __begin;
-
-    __begin =
-        __parse_locale_specific_form(__begin, static_cast<_Flags&>(*this));
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parse_type(__begin, static_cast<_Flags&>(*this));
-
-    if (__begin != __end && *__begin != _CharT('}'))
-      __throw_format_error(
-          "The format-spec should consume the input or end with a '}'");
-
-    return __begin;
-  }
-
-  /** Processes the parsed std-format-spec based on the parsed display type. */
-  _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type() {
-    switch (this->__type) {
-    case _Flags::_Type::__default:
-      // When no precision specified then it keeps default since that
-      // formatting 
diff ers from the other types.
-      if (this->__has_precision_field())
-        this->__type = _Flags::_Type::__general_lower_case;
-      break;
-    case _Flags::_Type::__float_hexadecimal_lower_case:
-    case _Flags::_Type::__float_hexadecimal_upper_case:
-      // Precision specific behavior will be handled later.
-      break;
-    case _Flags::_Type::__scientific_lower_case:
-    case _Flags::_Type::__scientific_upper_case:
-    case _Flags::_Type::__fixed_lower_case:
-    case _Flags::_Type::__fixed_upper_case:
-    case _Flags::_Type::__general_lower_case:
-    case _Flags::_Type::__general_upper_case:
-      if (!this->__has_precision_field()) {
-        // Set the default precision for the call to to_chars.
-        this->__precision = 6;
-        this->__precision_as_arg = false;
-      }
-      break;
-
-    default:
-      __throw_format_error("The format-spec type has a type not supported for "
-                           "a floating-point argument");
-    }
-  }
-};
-
-/**
- * The parser for the std-format-spec.
- *
- * This implements the parser for the pointer types.
- *
- * See @ref __parser_string.
- */
-template <class _CharT>
-class _LIBCPP_TEMPLATE_VIS __parser_pointer : public __parser_width,              // provides __width(|as_arg)
-                                              public __parser_fill_align<_CharT>, // provides __fill and uses __flags
-                                              public _Flags                       // provides __flags
-{
-public:
-  using char_type = _CharT;
-
-  _LIBCPP_HIDE_FROM_ABI constexpr __parser_pointer() {
-    // Implements LWG3612 Inconsistent pointer alignment in std::format.
-    // The issue's current status is "Tentatively Ready" and libc++ status is
-    // still experimental.
-    //
-    // TODO FMT Validate this with the final resolution of LWG3612.
-    this->__alignment = _Flags::_Alignment::__right;
-  }
-
-  /**
-   * The low-level std-format-spec parse function.
-   *
-   * @pre __begin points at the beginning of the std-format-spec. This means
-   * directly after the ':'.
-   * @pre The std-format-spec parses the entire input, or the first unmatched
-   * character is a '}'.
-   *
-   * @returns The iterator pointing at the last parsed character.
-   */
-  _LIBCPP_HIDE_FROM_ABI constexpr auto parse(auto& __parse_ctx) -> decltype(__parse_ctx.begin()) {
-    auto __it = __parse(__parse_ctx);
-    __process_display_type();
-    return __it;
-  }
-
-protected:
-  /**
-   * The low-level std-format-spec parse function.
-   *
-   * @pre __begin points at the beginning of the std-format-spec. This means
-   * directly after the ':'.
-   * @pre The std-format-spec parses the entire input, or the first unmatched
-   * character is a '}'.
-   *
-   * @returns The iterator pointing at the last parsed character.
-   */
-  _LIBCPP_HIDE_FROM_ABI constexpr auto __parse(auto& __parse_ctx) -> decltype(__parse_ctx.begin()) {
-    auto __begin = __parse_ctx.begin();
-    auto __end = __parse_ctx.end();
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parser_fill_align<_CharT>::__parse(__begin, __end, static_cast<_Flags&>(*this));
-    if (__begin == __end)
-      return __begin;
-
-    // An integer presentation type isn't defined in the Standard.
-    // Since a pointer is formatted as an integer it can be argued it's an
-    // integer presentation type. However there are two LWG-issues asserting it
-    // isn't an integer presentation type:
-    // - LWG3612 Inconsistent pointer alignment in std::format
-    // - LWG3644 std::format does not define "integer presentation type"
-    //
-    // There's a paper to make additional clarifications on the status of
-    // formatting pointers and proposes additional fields to be valid. That
-    // paper hasn't been reviewed by the Committee yet.
-    // - P2510 Formatting pointers
-    //
-    // The current implementation assumes formatting pointers isn't covered by
-    // "integer presentation type".
-    // TODO FMT Apply the LWG-issues/papers after approval/rejection by the Committee.
-
-    __begin = __parser_width::__parse(__begin, __end, __parse_ctx);
-    if (__begin == __end)
-      return __begin;
-
-    __begin = __parse_type(__begin, static_cast<_Flags&>(*this));
-
-    if (__begin != __end && *__begin != _CharT('}'))
-      __throw_format_error("The format-spec should consume the input or end with a '}'");
-
-    return __begin;
-  }
-
-  /** Processes the parsed std-format-spec based on the parsed display type. */
-  _LIBCPP_HIDE_FROM_ABI constexpr void __process_display_type() {
-    switch (this->__type) {
-    case _Flags::_Type::__default:
-      this->__type = _Flags::_Type::__pointer;
-      break;
-    case _Flags::_Type::__pointer:
-      break;
-    default:
-      __throw_format_error("The format-spec type has a type not supported for a pointer argument");
-    }
-  }
-};
-
 /** Helper struct returned from @ref __get_string_alignment. */
 template <class _CharT>
 struct _LIBCPP_TEMPLATE_VIS __string_alignment {


        


More information about the libcxx-commits mailing list