On Wed, 22 Jul 2026 at 16:10, Tomasz Kaminski <[email protected]> wrote:
>
>
>
> On Fri, May 15, 2026 at 9:37 PM Jonathan Wakely <[email protected]> wrote:
>>
>> On Wed, 13 May 2026 at 10:22 +0200, Tomasz Kamiński wrote:
>> >This patch changes ZoneInfo parsing, to use operator>> for on_month_day
>> >direclty, and removes on_day tag. The operator>>(istream&, on_month_day)
>>
>> "directly"
>>
>> >is updated to not override on.month if the MONTH component is not present,
>> >and set failbit instead. This allows to use in >> on >> time, to parse
>> >MONT DAY TIME.
>>
>> "MONTH"
>>
>> >
>> >We also handle failure to parse day number N for Www>=N or Www<=N
>> >productions, by leaving the day part of input unchanged and setting
>> >failbit.
>> >
>> >       PR libsdc++/124852
>> >
>> >libstdc++-v3/ChangeLog:
>> >
>> >       * src/c++20/tzdb.cc (on_month_day::on_day_t, on_month_day::on_day):
>> >       Remove.
>> >       (operator>>(istream&, on_month_day::day_t&)): Inlined in...
>> >       (operator>>(istream&, on_month_day): Inlined on_month_day::on_day.
>> >       Avoid modifying on.month if MONTH is not present. Report failure
>> >       on failure to parse day for LessEq / GreaterEq.
>> >---
>> >Realized this yesterday, but decied that doing this as separate patch as 
>> >this
>> >is reverting direction. If this causes some failure, I want git blame to
>> >show only me for it.
>> >
>> >Tested on x86_64-linux locally. OK for trunk?
>>
>> OK for trunk with a few typos fixed (two above, two below).
>
> OK for GCC 16,a As we are backporting a previous patch, this is what we
> have on trunk?


OK for gcc-16


>>
>>
>>
>> > libstdc++-v3/src/c++20/tzdb.cc | 89 ++++++++++++----------------------
>> > 1 file changed, 30 insertions(+), 59 deletions(-)
>> >
>> >diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc
>> >index f9238542274..8db86a8d4b0 100644
>> >--- a/libstdc++-v3/src/c++20/tzdb.cc
>> >+++ b/libstdc++-v3/src/c++20/tzdb.cc
>> >@@ -371,13 +371,6 @@ namespace std::chrono
>> >       return ymd;
>> >       }
>> >
>> >-      struct on_day_t // tag type for reading ON and DAY fields only
>> >-      {
>> >-      on_month_day& parent;
>> >-      friend istream& operator>>(istream&, on_day_t&&);
>> >-      };
>> >-
>> >-      on_day_t on_day() { return on_day_t{*this}; }
>> >
>> >       friend istream& operator>>(istream&, on_month_day&);
>> >     };
>> >@@ -2334,73 +2327,55 @@ namespace
>> >       }
>> >     };
>> >
>> >-    // Read the day-component of an on_month_day expression (everything 
>> >after
>> >-    // the month).  Three forms are accepted: a plain day-of-month number,
>> >-    // "lastXxx" where Xxx is a weekday name (LastWeekday), or "Xxx<=N" or
>> >-    // "Xxx>=N" (LessEq / GreaterEq).  On failure the function sets failbit
>> >-    // and leaves `to.parent` unchanged.
>> >-    istream& operator>>(istream& in, on_month_day::on_day_t&& to)
>> >+    // Read the MONTH DAY. Three forms are accepted for DAY:
>> >+    // * a plain day-of-month number (DayOfMonth),
>> >+    // * "lastWww" where Www is a weekday name (LastWeekday),
>> >+    // * "Www<=N" or "Www>=N" (LessEq / GreaterEq).
>> >+    // On failure to read either MONTH or DAY this function set
>>
>> "sets"
>>
>> >+    // failbit. If DAY is not pared, only `on.month` is modified,
>>
>> "parsed"
>>
>> >+    // otherwise `on` is left unchanged.
>> >+    istream& operator>>(istream& in, on_month_day& on)
>> >     {
>> >       using enum on_month_day::Kind;
>> >-
>> >-      on_month_day& on = to.parent;
>> >-      int c = ws(in).peek();
>> >-      if ('0' <= c && c <= '9')
>> >+      if (abbrev_month m{}; in >> m)
>> >       {
>> >-        unsigned d;
>> >-        in >> d;
>> >-        if (d <= 31) [[likely]]
>> >+        on.month = static_cast<unsigned>(m.m);
>> >+        if (int c = ws(in).peek(); '0' <= c && c <= '9')
>> >           {
>> >-            on.kind = DayOfMonth;
>> >-            on.day_of_month = d;
>> >-            return in;
>> >+            if (unsigned d; (in >> d) && (d <= 31)) [[likely]]
>> >+              {
>> >+                on.kind = DayOfMonth;
>> >+                on.day_of_month = d;
>> >+                return in;
>> >+              }
>> >           }
>> >-      }
>> >-      else if (c == 'l') // lastSunday, lastWed, ...
>> >-      {
>> >-        in.ignore(4);
>> >-        if (abbrev_weekday w{}; in >> w) [[likely]]
>> >+        else if (c == 'l') // lastSunday, lastWed, ...
>> >           {
>> >-            on.kind = LastWeekday;
>> >-            on.day_of_week = w.wd.c_encoding();
>> >-            return in;
>> >+            in.ignore(4);
>> >+            if (abbrev_weekday w{}; in >> w) [[likely]]
>> >+              {
>> >+                on.kind = LastWeekday;
>> >+                on.day_of_week = w.wd.c_encoding();
>> >+                return in;
>> >+              }
>> >           }
>> >-      }
>> >-      else
>> >-      {
>> >-        abbrev_weekday w;
>> >-        in >> w;
>> >-        if (auto c = in.get(); c == '<' || c == '>')
>> >+        else if (abbrev_weekday w; in >> w) [[likely]]
>> >           {
>> >-            if (in.get() == '=')
>> >-              {
>> >-                unsigned d;
>> >-                in >> d;
>> >-                if (d <= 31) [[likely]]
>> >+            if (c = in.get(); c == '<' || c == '>')
>> >+              if (in.get() == '=')
>> >+                if (unsigned d; (in >> d) && (d <= 31)) [[likely]]
>> >                   {
>> >                     on.kind = c == '<' ? LessEq : GreaterEq;
>> >                     on.day_of_week = w.wd.c_encoding();
>> >                     on.day_of_month = d;
>> >                     return in;
>> >                   }
>> >-              }
>> >           }
>> >       }
>> >       in.setstate(ios::failbit);
>> >       return in;
>> >     }
>> >
>> >-    istream& operator>>(istream& in, on_month_day& to)
>> >-    {
>> >-      on_month_day md{};
>> >-      abbrev_month m{};
>> >-      in >> m;
>> >-      md.month = static_cast<unsigned>(m.m);
>> >-      if (in >> md.on_day())
>> >-      to = md;
>> >-      return in;
>> >-    }
>> >-
>> >     istream& operator>>(istream& in, at_time& at)
>> >     {
>> >       int sign = 1;
>> >@@ -2506,11 +2481,7 @@ namespace
>> >         on_month_day on{ .kind = on_month_day::DayOfMonth,
>> >                          .month = 1, .day_of_month = 1 };
>> >         at_time t{};
>> >-        if (abbrev_month m{January}; in >> m)
>> >-          {
>> >-            on.month = static_cast<unsigned>(m.m);
>> >-            in >> on.on_day() >> t;
>> >-          }
>> >+        in >> on >> t;
>> >         year_month_day ymd = on.pin(year(y));
>> >         inf.m_until = sys_days(ymd) + seconds(t.time);
>> >         if (t.indicator != at_time::Universal)
>> >--
>> >2.54.0
>> >
>> >
>>

Reply via email to