[PATCH] libstdc++: Use on_month_day istream operator in ZoneInfo parsing. [PR124852]
Tomasz Kaminski
tkaminsk@redhat.com
Wed Jul 22 15:10:27 GMT 2026
On Fri, May 15, 2026 at 9:37 PM Jonathan Wakely <jwakely@redhat.com> 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?
>
>
> > 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
> >
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20260722/a0246fe5/attachment.htm>
More information about the Libstdc++
mailing list