https://gcc.gnu.org/g:36058be77f4c684350047adfe7c82aec91f3b72e

commit r16-4073-g36058be77f4c684350047adfe7c82aec91f3b72e
Author: Tomasz Kamiński <tkami...@redhat.com>
Date:   Tue Sep 23 11:09:08 2025 +0200

    libstdc++: Use basic_format_parse_context<_CharT> in internal chrono 
formatters.
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/chrono_io.h (__formatter_chrono::_M_parse):
            Replace _ParseContext with basic_format_parse_context<_CharT> and
            make it non-template.
            (__formatter_duration::_M_parse): Replace _ParseContext with
            basic_format_parse_context<_CharT> and remove unused default
            argument.
    
    Reviewed-by: Jonathan Wakely <jwak...@redhat.com>
    Signed-off-by: Tomasz Kamiński <tkami...@redhat.com>

Diff:
---
 libstdc++-v3/include/bits/chrono_io.h | 520 +++++++++++++++++-----------------
 1 file changed, 259 insertions(+), 261 deletions(-)

diff --git a/libstdc++-v3/include/bits/chrono_io.h 
b/libstdc++-v3/include/bits/chrono_io.h
index 85b2013cf704..0a6a3a5ce5a2 100644
--- a/libstdc++-v3/include/bits/chrono_io.h
+++ b/libstdc++-v3/include/bits/chrono_io.h
@@ -559,282 +559,281 @@ namespace __format
       __formatter_chrono(_ChronoSpec<_CharT> __spec) noexcept
       : _M_spec(__spec)
       { }
+       
+      constexpr typename basic_format_parse_context<_CharT>::iterator
+      _M_parse(basic_format_parse_context<_CharT>& __pc, _ChronoParts __parts,
+              const _ChronoSpec<_CharT>& __def)
+      {
+       auto __first = __pc.begin();
+       auto __last = __pc.end();
 
-      template<typename _ParseContext>
-       constexpr typename _ParseContext::iterator
-       _M_parse(_ParseContext& __pc, _ChronoParts __parts,
-                const _ChronoSpec<_CharT>& __def)
-       {
-         auto __first = __pc.begin();
-         auto __last = __pc.end();
-
-         _ChronoSpec<_CharT> __spec = __def;
-
-         auto __finalize = [this, &__spec, &__def] {
-           using enum _ChronoParts;
-           _ChronoParts __checked
-             = __spec._M_debug ? _YearMonthDay|_IndexedWeekday
-                               : _Month|_Weekday;
-           // n.b. for calendar types __def._M_needed contains only parts
-           // copied from the input, remaining ones are computed, and thus ok
-           __spec._M_needs_ok_check
-             = __spec._M_needs(__def._M_needed & __checked);
-           _M_spec = __spec;
-         };
-
-         auto __finished = [&] {
-           if (__first == __last || *__first == '}')
-             {
-               __finalize();
-               return true;
-             }
-           return false;
-         };
-
-         if (__finished())
-           return __first;
-
-         __first = __spec._M_parse_fill_and_align(__first, __last);
-         if (__finished())
-           return __first;
+       _ChronoSpec<_CharT> __spec = __def;
 
-         __first = __spec._M_parse_width(__first, __last, __pc);
-         if (__finished())
-           return __first;
+       auto __finalize = [this, &__spec, &__def] {
+         using enum _ChronoParts;
+         _ChronoParts __checked
+           = __spec._M_debug ? _YearMonthDay|_IndexedWeekday
+                             : _Month|_Weekday;
+         // n.b. for calendar types __def._M_needed contains only parts
+         // copied from the input, remaining ones are computed, and thus ok
+         __spec._M_needs_ok_check
+            = __spec._M_needs(__def._M_needed & __checked);
+         _M_spec = __spec;
+       };
 
-         if (*__first == '.')
+       auto __finished = [&] {
+         if (__first == __last || *__first == '}')
            {
-             if ((__parts & _ChronoParts::_EpochUnits) == 0
-                 || !__spec._M_floating_point_rep)
-               __throw_format_error("format error: invalid precision for 
duration");
-
-             // Precision is allowed, but value is ignored.
-             __first = _Spec<_CharT>()._M_parse_precision(__first, __last, 
__pc);
-             // Still inditate that there was user supplied precision.
-             __spec._M_prec_kind = _WP_value;
-            if (__finished())
-              return __first;
+             __finalize();
+             return true;
            }
+         return false;
+       };
+
+       if (__finished())
+         return __first;
+
+       __first = __spec._M_parse_fill_and_align(__first, __last);
+       if (__finished())
+         return __first;
 
-         __spec._M_localized = false;
-         __first = __spec._M_parse_locale(__first, __last);
-         if (__finished())
-           return __first;
+       __first = __spec._M_parse_width(__first, __last, __pc);
+       if (__finished())
+         return __first;
 
-         // Everything up to the end of the string or the first '}' is a
-         // chrono-specs string. Check it is valid.
+       if (*__first == '.')
          {
-           __string_view __str(__first, __last - __first);
-           auto __end = __str.find('}');
-           if (__end != __str.npos)
-             {
-               __str.remove_suffix(__str.length() - __end);
-               __last = __first + __end;
-             }
-           if (__str.find('{') != __str.npos)
-             __throw_format_error("chrono format error: '{' in chrono-specs");
+           if ((__parts & _ChronoParts::_EpochUnits) == 0
+                 || !__spec._M_floating_point_rep)
+             __throw_format_error("format error: invalid precision for 
duration");
+
+           // Precision is allowed, but value is ignored.
+           __first = _Spec<_CharT>()._M_parse_precision(__first, __last, __pc);
+           // Still inditate that there was user supplied precision.
+           __spec._M_prec_kind = _WP_value;
+           if (__finished())
+             return __first;
          }
 
-         // Parse chrono-specs in [first,last), checking each conversion-spec
-         // against __parts (so fail for %Y if no year in parts).
-         // Save range in __spec._M_chrono_specs.
-         __spec._M_debug = false;
-         __spec._M_locale_specific = false;
-         __spec._M_needed = _ChronoParts::_None;
-         __spec._M_chrono_specs = __string_view();
-
-         const auto __chrono_specs = __first++; // Skip leading '%'
-         if (*__chrono_specs != '%')
-           __throw_format_error("chrono format error: no '%' at start of "
-                                "chrono-specs");
+       __spec._M_localized = false;
+       __first = __spec._M_parse_locale(__first, __last);
+       if (__finished())
+         return __first;
 
-         _CharT __mod{};
-         bool __conv = true;
-         while (__first != __last)
+       // Everything up to the end of the string or the first '}' is a
+       // chrono-specs string. Check it is valid.
+       {
+         __string_view __str(__first, __last - __first);
+         auto __end = __str.find('}');
+         if (__end != __str.npos)
            {
-             enum _Mods { _Mod_none, _Mod_E, _Mod_O, _Mod_E_O };
-             _Mods __allowed_mods = _Mod_none;
+             __str.remove_suffix(__str.length() - __end);
+             __last = __first + __end;
+           }
+         if (__str.find('{') != __str.npos)
+           __throw_format_error("chrono format error: '{' in chrono-specs");
+       }
 
-             _ChronoParts __needed = _ChronoParts::_None;
-             bool __locale_specific = false;
+       // Parse chrono-specs in [first,last), checking each conversion-spec
+       // against __parts (so fail for %Y if no year in parts).
+       // Save range in __spec._M_chrono_specs.
+       __spec._M_debug = false;
+       __spec._M_locale_specific = false;
+       __spec._M_needed = _ChronoParts::_None;
+       __spec._M_chrono_specs = __string_view();
+
+       const auto __chrono_specs = __first++; // Skip leading '%'
+       if (*__chrono_specs != '%')
+         __throw_format_error("chrono format error: no '%' at start of "
+                              "chrono-specs");
+
+       _CharT __mod{};
+       bool __conv = true;
+       while (__first != __last)
+         {
+           enum _Mods { _Mod_none, _Mod_E, _Mod_O, _Mod_E_O };
+           _Mods __allowed_mods = _Mod_none;
 
-             _CharT __c = *__first++;
-             switch (__c)
-               {
-               using enum _ChronoParts;
-               case 'a':
-               case 'A':
-                 __needed = _Weekday;
-                 __locale_specific = true;
-                 break;
-               case 'b':
-               case 'h':
-               case 'B':
-                 __needed = _Month;
-                 __locale_specific = true;
-                 break;
-               case 'c':
-                 __needed = _Date|_HoursMinutesSeconds;
-                 __allowed_mods = _Mod_E;
-                 __locale_specific = true;
-                 break;
-               case 'C':
-                 __needed = _Year;
-                 __allowed_mods = _Mod_E;
-                 break;
-               case 'd':
-               case 'e':
-                 __needed = _Day;
-                 __allowed_mods = _Mod_O;
-                 break;
-               case 'D':
-               case 'F':
-                 __needed = _YearMonthDay;
-                 break;
-               case 'g':
-               case 'G':
-               case 'V':
-                 __needed = _LocalDays|_Year|_DayOfYear|_Weekday;
-                 break;
-               case 'H':
-               case 'I':
-                 __needed = _HoursMinutesSeconds;
-                 __allowed_mods = _Mod_O;
-                 break;
-               case 'j':
-                 __needed = __parts & _DayOfYear;
-                 // If we do not know day-of-year then we must have a duration,
-                 // which is to be formatted as decimal number of days.
-                 if (__needed == _None)
-                   __needed = _HoursMinutesSeconds;
-                 break;
-               case 'm':
-                 __needed = _Month;
-                 __allowed_mods = _Mod_O;
-                 break;
-               case 'M':
-                 __needed = _HoursMinutesSeconds;
-                 __allowed_mods = _Mod_O;
-                 break;
-               case 'p':
-               case 'r':
-                 __locale_specific = true;
-                 [[fallthrough]];
-               case 'R':
-                 __needed = _HoursMinutesSeconds;
-                 break;
-               case 'T':
-                 __needed = _TimeOfDay;
-                 break;
-               case 'q':
-                 __needed = _UnitSuffix;
-                 break;
-               case 'Q':
-                 __needed = _EpochUnits;
-                 break;
-               case 'S':
-                 __needed = _TimeOfDay;
-                 __allowed_mods = _Mod_O;
-                 break;
-               case 'u':
-               case 'w':
-                 __needed = _Weekday;
-                 __allowed_mods = _Mod_O;
-                 break;
-               case 'U':
-               case 'W':
-                 __needed = _DayOfYear|_Weekday;
-                 __allowed_mods = _Mod_O;
-                 break;
-               case 'x':
-                 __needed = _Date;
-                 __locale_specific = true;
-                 __allowed_mods = _Mod_E;
-                 break;
-               case 'X':
-                 __needed = _HoursMinutesSeconds;
-                 __locale_specific = true;
-                 __allowed_mods = _Mod_E;
-                 break;
-               case 'y':
-                 __needed = _Year;
-                 __allowed_mods = _Mod_E_O;
-                 break;
-               case 'Y':
-                 __needed = _Year;
-                 __allowed_mods = _Mod_E;
-                 break;
-               case 'z':
-                 __needed = _ZoneOffset;
-                 __allowed_mods = _Mod_E_O;
-                 break;
-               case 'Z':
-                 __needed = _ZoneAbbrev;
-                 break;
-               case 'n':
-               case 't':
-               case '%':
-                 break;
-               case 'O':
-               case 'E':
-                 if (__mod) [[unlikely]]
-                   {
-                     __allowed_mods = _Mod_none;
-                     break;
-                   }
-                 __mod = __c;
-                 continue;
-               default:
-                 __throw_format_error("chrono format error: invalid "
-                                      " specifier in chrono-specs");
-               }
+           _ChronoParts __needed = _ChronoParts::_None;
+           bool __locale_specific = false;
 
-             if ((__mod == 'E' && !(__allowed_mods & _Mod_E))
-                   || (__mod == 'O' && !(__allowed_mods & _Mod_O)))
-               __throw_format_error("chrono format error: invalid "
-                                    " modifier in chrono-specs");
-             if (__mod && __c != 'z')
+           _CharT __c = *__first++;
+           switch (__c)
+             {
+             using enum _ChronoParts;
+             case 'a':
+             case 'A':
+               __needed = _Weekday;
                __locale_specific = true;
-             __mod = _CharT();
-
-             // localized formats do not include subseconds
-             if (__locale_specific)
-               __needed -= _ChronoParts::_Subseconds;
-
-             if ((__parts & __needed) != __needed)
-               __throw_format_error("chrono format error: format argument "
-                                    "does not contain the information "
-                                    "required by the chrono-specs");
-             __spec._M_needed |= __needed;
-             __spec._M_locale_specific |= __locale_specific;
-
-             // Scan for next '%', ignoring literal-chars before it.
-             size_t __pos = __string_view(__first, __last - __first).find('%');
-             if (__pos == 0)
-               ++__first;
-             else
-               {
-                 if (__pos == __string_view::npos)
-                   {
-                     __first = __last;
-                     __conv = false;
-                   }
-                 else
-                   __first += __pos + 1;
-               }
+               break;
+             case 'b':
+             case 'h':
+             case 'B':
+               __needed = _Month;
+               __locale_specific = true;
+               break;
+             case 'c':
+               __needed = _Date|_HoursMinutesSeconds;
+               __allowed_mods = _Mod_E;
+               __locale_specific = true;
+               break;
+             case 'C':
+               __needed = _Year;
+               __allowed_mods = _Mod_E;
+               break;
+             case 'd':
+             case 'e':
+               __needed = _Day;
+               __allowed_mods = _Mod_O;
+               break;
+             case 'D':
+             case 'F':
+               __needed = _YearMonthDay;
+               break;
+             case 'g':
+             case 'G':
+             case 'V':
+               __needed = _LocalDays|_Year|_DayOfYear|_Weekday;
+               break;
+             case 'H':
+             case 'I':
+               __needed = _HoursMinutesSeconds;
+               __allowed_mods = _Mod_O;
+               break;
+             case 'j':
+               __needed = __parts & _DayOfYear;
+               // If we do not know day-of-year then we must have a duration,
+               // which is to be formatted as decimal number of days.
+               if (__needed == _None)
+                 __needed = _HoursMinutesSeconds;
+               break;
+             case 'm':
+               __needed = _Month;
+               __allowed_mods = _Mod_O;
+               break;
+             case 'M':
+               __needed = _HoursMinutesSeconds;
+               __allowed_mods = _Mod_O;
+               break;
+             case 'p':
+             case 'r':
+               __locale_specific = true;
+               [[fallthrough]];
+             case 'R':
+               __needed = _HoursMinutesSeconds;
+               break;
+             case 'T':
+               __needed = _TimeOfDay;
+               break;
+             case 'q':
+               __needed = _UnitSuffix;
+               break;
+             case 'Q':
+               __needed = _EpochUnits;
+               break;
+             case 'S':
+               __needed = _TimeOfDay;
+               __allowed_mods = _Mod_O;
+               break;
+             case 'u':
+             case 'w':
+               __needed = _Weekday;
+               __allowed_mods = _Mod_O;
+               break;
+             case 'U':
+             case 'W':
+               __needed = _DayOfYear|_Weekday;
+               __allowed_mods = _Mod_O;
+               break;
+             case 'x':
+               __needed = _Date;
+               __locale_specific = true;
+               __allowed_mods = _Mod_E;
+               break;
+             case 'X':
+               __needed = _HoursMinutesSeconds;
+               __locale_specific = true;
+               __allowed_mods = _Mod_E;
+               break;
+             case 'y':
+               __needed = _Year;
+               __allowed_mods = _Mod_E_O;
+               break;
+             case 'Y':
+               __needed = _Year;
+               __allowed_mods = _Mod_E;
+               break;
+             case 'z':
+               __needed = _ZoneOffset;
+               __allowed_mods = _Mod_E_O;
+               break;
+             case 'Z':
+               __needed = _ZoneAbbrev;
+               break;
+             case 'n':
+             case 't':
+             case '%':
+               break;
+             case 'O':
+             case 'E':
+               if (__mod) [[unlikely]]
+                 {
+                   __allowed_mods = _Mod_none;
+                   break;
+                 }
+               __mod = __c;
+               continue;
+             default:
+               __throw_format_error("chrono format error: invalid specifier "
+                                    "in chrono-specs");
            }
 
-         // Check for a '%' conversion-spec without a type.
-         if (__conv || __mod != _CharT())
-           __throw_format_error("chrono format error: unescaped '%' in "
-                                "chrono-specs");
+           if ((__mod == 'E' && !(__allowed_mods & _Mod_E))
+                  || (__mod == 'O' && !(__allowed_mods & _Mod_O)))
+             __throw_format_error("chrono format error: invalid  modifier "
+                                  "in chrono-specs");
+           if (__mod && __c != 'z')
+             __locale_specific = true;
+           __mod = _CharT();
+
+           // localized formats do not include subseconds
+           if (__locale_specific)
+             __needed -= _ChronoParts::_Subseconds;
+
+           if ((__parts & __needed) != __needed)
+             __throw_format_error("chrono format error: format argument does "
+                                  "not contain the information required by the 
"
+                                  "chrono-specs");
+           __spec._M_needed |= __needed;
+           __spec._M_locale_specific |= __locale_specific;
+
+           // Scan for next '%', ignoring literal-chars before it.
+           size_t __pos = __string_view(__first, __last - __first).find('%');
+           if (__pos == 0)
+             ++__first;
+           else
+             {
+               if (__pos == __string_view::npos)
+                 {
+                   __first = __last;
+                   __conv = false;
+                 }
+               else
+                 __first += __pos + 1;
+             }
+         }
 
-         __spec._M_chrono_specs
-           = __string_view(__chrono_specs, __first - __chrono_specs);
+       // Check for a '%' conversion-spec without a type.
+       if (__conv || __mod != _CharT())
+         __throw_format_error("chrono format error: unescaped '%' in "
+                              "chrono-specs");
 
-         __finalize();
-         return __first;
-       }
+       __spec._M_chrono_specs
+         = __string_view(__chrono_specs, __first - __chrono_specs);
+
+       __finalize();
+       return __first;
+      }
 
       // pre: !_M_spec._M_chrono_specs.empty()
       template<typename _FormatContext>
@@ -869,7 +868,6 @@ namespace __format
          return __sink._M_finish(_M_spec._M_align, _M_spec._M_fill);
        }
 
-
       _ChronoSpec<_CharT> _M_spec;
 
     protected:
@@ -1934,10 +1932,10 @@ namespace __format
       using __formatter_chrono<_CharT>::__formatter_chrono;
       using __formatter_chrono<_CharT>::_M_spec;
 
-      template<typename _Duration, typename _ParseContext>
-       constexpr typename _ParseContext::iterator
-       _M_parse(_ParseContext& __pc, _ChronoParts __parts,
-                const _ChronoSpec<_CharT>& __def = {})
+      template<typename _Duration>
+       constexpr typename basic_format_parse_context<_CharT>::iterator
+       _M_parse(basic_format_parse_context<_CharT>& __pc, _ChronoParts __parts,
+                const _ChronoSpec<_CharT>& __def)
        {
          using _Rep = typename _Duration::rep;
          using enum _ChronoParts;

Reply via email to