forked from HowardHinnant/date
And yet more fixes to allow duplicate flags on parse
This commit is contained in:
@@ -4664,13 +4664,15 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
if (*fmt == 'c' && !fds.has_tod)
|
||||
os.setstate(std::ios::failbit);
|
||||
#if !ONLY_C_LOCALE
|
||||
if (*fmt == 'c')
|
||||
tm = std::tm{};
|
||||
auto const& ymd = fds.ymd;
|
||||
auto ld = local_days(ymd);
|
||||
if (*fmt == 'c')
|
||||
{
|
||||
tm.tm_sec = static_cast<int>(fds.tod.seconds().count());
|
||||
tm.tm_min = static_cast<int>(fds.tod.minutes().count());
|
||||
tm.tm_hour = static_cast<int>(fds.tod.hours().count());
|
||||
}
|
||||
tm.tm_mday = static_cast<int>(static_cast<unsigned>(ymd.day()));
|
||||
tm.tm_mon = static_cast<int>(extract_month(os, fds) - 1);
|
||||
tm.tm_year = static_cast<int>(ymd.year()) - 1900;
|
||||
@@ -5990,6 +5992,20 @@ read(std::basic_istream<CharT, Traits>& is, rld a0, Args&& ...args)
|
||||
read(is, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class T, class CharT, class Traits>
|
||||
inline
|
||||
void
|
||||
checked_set(T& value, T from, T not_a_value, std::basic_ios<CharT, Traits>& is)
|
||||
{
|
||||
if (!is.fail())
|
||||
{
|
||||
if (value == not_a_value)
|
||||
value = std::move(from);
|
||||
else if (value != from)
|
||||
is.setstate(std::ios::failbit);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail;
|
||||
|
||||
template <class CharT, class Traits, class Duration, class Alloc = std::allocator<CharT>>
|
||||
@@ -6011,71 +6027,133 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
auto& f = use_facet<time_get<CharT>>(is.getloc());
|
||||
std::tm tm{};
|
||||
#endif
|
||||
std::basic_string<CharT, Traits, Alloc> temp_abbrev;
|
||||
minutes temp_offset{};
|
||||
const CharT* command = nullptr;
|
||||
auto modified = CharT{};
|
||||
auto width = -1;
|
||||
CONSTDATA int not_a_year = numeric_limits<short>::min();
|
||||
int Y = not_a_year;
|
||||
CONSTDATA int not_a_century = not_a_year / 100;
|
||||
int C = not_a_century;
|
||||
|
||||
CONSTDATA int not_a_year = numeric_limits<int>::min();
|
||||
CONSTDATA int not_a_2digit_year = 100;
|
||||
int y = not_a_2digit_year;
|
||||
CONSTDATA int not_a_century = not_a_year / 100;
|
||||
CONSTDATA int not_a_month = 0;
|
||||
CONSTDATA int not_a_day = 0;
|
||||
CONSTDATA int not_a_doy = 0;
|
||||
int m = not_a_month;
|
||||
int d = not_a_day;
|
||||
int j = not_a_doy;
|
||||
CONSTDATA int not_a_weekday = 7;
|
||||
int wd = not_a_weekday;
|
||||
CONSTDATA int not_a_hour = numeric_limits<int>::min();
|
||||
CONSTDATA int not_a_hour_12_value = 0;
|
||||
int I = not_a_hour_12_value;
|
||||
hours h{};
|
||||
minutes min{};
|
||||
Duration s{};
|
||||
int g = not_a_2digit_year;
|
||||
int G = not_a_year;
|
||||
CONSTDATA int not_a_minute = not_a_hour;
|
||||
CONSTDATA Duration not_a_second = Duration::min();
|
||||
CONSTDATA int not_a_doy = 0;
|
||||
CONSTDATA int not_a_weekday = 7;
|
||||
CONSTDATA int not_a_week_num = 100;
|
||||
int V = not_a_week_num;
|
||||
int U = not_a_week_num;
|
||||
int W = not_a_week_num;
|
||||
CONSTDATA int not_a_ampm = -1;
|
||||
CONSTDATA minutes not_a_offset = minutes::min();
|
||||
|
||||
int Y = not_a_year; // c, F, Y *
|
||||
int y = not_a_2digit_year; // D, x, y *
|
||||
int g = not_a_2digit_year; // g *
|
||||
int G = not_a_year; // G *
|
||||
int C = not_a_century; // C *
|
||||
int m = not_a_month; // b, B, h, m, c, D, F, x *
|
||||
int d = not_a_day; // c, d, D, e, F, x *
|
||||
int j = not_a_doy; // j *
|
||||
int wd = not_a_weekday; // a, A, u, w *
|
||||
int H = not_a_hour; // c, H, R, T, X *
|
||||
int I = not_a_hour_12_value; // I, r *
|
||||
int p = not_a_ampm; // p, r *
|
||||
int M = not_a_minute; // c, M, r, R, T, X *
|
||||
Duration s = not_a_second; // c, r, S, T, X *
|
||||
int U = not_a_week_num; // U *
|
||||
int V = not_a_week_num; // V *
|
||||
int W = not_a_week_num; // W *
|
||||
std::basic_string<CharT, Traits, Alloc> temp_abbrev; // Z *
|
||||
minutes temp_offset = not_a_offset; // z *
|
||||
|
||||
using detail::read;
|
||||
using detail::rs;
|
||||
using detail::ru;
|
||||
using detail::rld;
|
||||
using detail::checked_set;
|
||||
for (; *fmt && is.rdstate() == std::ios::goodbit; ++fmt)
|
||||
{
|
||||
switch (*fmt)
|
||||
{
|
||||
case 'a':
|
||||
case 'A':
|
||||
case 'u':
|
||||
case 'w': // wd: a, A, u, w
|
||||
if (command)
|
||||
{
|
||||
int trial_wd = not_a_weekday;
|
||||
if (*fmt == 'a' || *fmt == 'A')
|
||||
{
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
if ((err & ios::failbit) == 0)
|
||||
wd = tm.tm_wday;
|
||||
is.setstate(err);
|
||||
if (!is.fail())
|
||||
trial_wd = tm.tm_wday;
|
||||
#else
|
||||
auto nm = detail::weekday_names();
|
||||
auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
|
||||
if (!is.fail())
|
||||
wd = i % 7;
|
||||
trial_wd = i % 7;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
}
|
||||
else // *fmt == 'u' || *fmt == 'w'
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
#else
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
{
|
||||
read(is, ru{trial_wd, 1, width == -1 ? 1u : static_cast<unsigned>(width)});
|
||||
if (!is.fail())
|
||||
{
|
||||
if (*fmt == 'u')
|
||||
{
|
||||
if (!(1 <= trial_wd && trial_wd <= 7))
|
||||
{
|
||||
trial_wd = not_a_weekday;
|
||||
is.setstate(ios_base::failbit);
|
||||
}
|
||||
else if (trial_wd == 7)
|
||||
trial_wd = 0;
|
||||
}
|
||||
else // *fmt == 'w'
|
||||
{
|
||||
if (!(0 <= trial_wd && trial_wd <= 6))
|
||||
{
|
||||
trial_wd = not_a_weekday;
|
||||
is.setstate(ios_base::failbit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
is.setstate(err);
|
||||
if (!is.fail())
|
||||
trial_wd = tm.tm_wday;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
}
|
||||
if (trial_wd != not_a_weekday)
|
||||
checked_set(wd, trial_wd, not_a_weekday, is);
|
||||
}
|
||||
else // !command
|
||||
read(is, *fmt);
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
}
|
||||
else
|
||||
read(is, *fmt);
|
||||
break;
|
||||
case 'b':
|
||||
case 'B':
|
||||
@@ -6084,18 +6162,20 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
{
|
||||
if (modified == CharT{})
|
||||
{
|
||||
int ttm = not_a_month;
|
||||
#if !ONLY_C_LOCALE
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
if ((err & ios::failbit) == 0)
|
||||
m = tm.tm_mon + 1;
|
||||
ttm = tm.tm_mon + 1;
|
||||
is.setstate(err);
|
||||
#else
|
||||
auto nm = detail::month_names();
|
||||
auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
|
||||
if (!is.fail())
|
||||
m = i % 12 + 1;
|
||||
ttm = i % 12 + 1;
|
||||
#endif
|
||||
checked_set(m, ttm, not_a_month, is);
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
@@ -6116,45 +6196,44 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
if ((err & ios::failbit) == 0)
|
||||
{
|
||||
Y = tm.tm_year + 1900;
|
||||
m = tm.tm_mon + 1;
|
||||
d = tm.tm_mday;
|
||||
h = hours{tm.tm_hour};
|
||||
min = minutes{tm.tm_min};
|
||||
s = duration_cast<Duration>(seconds{tm.tm_sec});
|
||||
checked_set(Y, tm.tm_year + 1900, not_a_year, is);
|
||||
checked_set(m, tm.tm_mon + 1, not_a_month, is);
|
||||
checked_set(d, tm.tm_mday, not_a_day, is);
|
||||
checked_set(H, tm.tm_hour, not_a_hour, is);
|
||||
checked_set(M, tm.tm_min, not_a_minute, is);
|
||||
checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}),
|
||||
not_a_second, is);
|
||||
}
|
||||
is.setstate(err);
|
||||
#else
|
||||
// "%a %b %e %T %Y"
|
||||
auto nm = detail::weekday_names();
|
||||
auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
|
||||
if (is.fail())
|
||||
goto broken;
|
||||
wd = i % 7;
|
||||
checked_set(wd, static_cast<int>(i % 7), not_a_weekday, is);
|
||||
ws(is);
|
||||
nm = detail::month_names();
|
||||
i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
|
||||
if (is.fail())
|
||||
goto broken;
|
||||
m = i % 12 + 1;
|
||||
checked_set(m, static_cast<int>(i % 12 + 1), not_a_month, is);
|
||||
ws(is);
|
||||
read(is, rs{d, 1, 2});
|
||||
if (is.fail())
|
||||
goto broken;
|
||||
int td = not_a_day;
|
||||
read(is, rs{td, 1, 2});
|
||||
checked_set(d, td, not_a_day, is);
|
||||
ws(is);
|
||||
using dfs = detail::decimal_format_seconds<Duration>;
|
||||
CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
|
||||
int H;
|
||||
int M;
|
||||
int tH;
|
||||
int tM;
|
||||
long double S;
|
||||
read(is, ru{H, 1, 2}, CharT{':'}, ru{M, 1, 2},
|
||||
read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2},
|
||||
CharT{':'}, rld{S, 1, w});
|
||||
if (is.fail())
|
||||
goto broken;
|
||||
h = hours{H};
|
||||
min = minutes{M};
|
||||
s = round<Duration>(duration<long double>{S});
|
||||
checked_set(H, tH, not_a_hour, is);
|
||||
checked_set(M, tM, not_a_minute, is);
|
||||
checked_set(s, round<Duration>(duration<long double>{S}),
|
||||
not_a_second, is);
|
||||
ws(is);
|
||||
read(is, rs{Y, 1, 4u});
|
||||
int tY = not_a_year;
|
||||
read(is, rs{tY, 1, 4u});
|
||||
checked_set(Y, tY, not_a_year, is);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -6176,14 +6255,21 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
if ((err & ios::failbit) == 0)
|
||||
{
|
||||
Y = tm.tm_year + 1900;
|
||||
m = tm.tm_mon + 1;
|
||||
d = tm.tm_mday;
|
||||
checked_set(Y, tm.tm_year + 1900, not_a_year, is);
|
||||
checked_set(m, tm.tm_mon + 1, not_a_month, is);
|
||||
checked_set(d, tm.tm_mday, not_a_day, is);
|
||||
}
|
||||
is.setstate(err);
|
||||
#else
|
||||
read(is, ru{m, 1, 2}, CharT{'/'}, ru{d, 1, 2}, CharT{'/'},
|
||||
rs{y, 1, 2});
|
||||
// "%m/%d/%y"
|
||||
int ty = not_a_2digit_year;
|
||||
int tm = not_a_month;
|
||||
int td = not_a_day;
|
||||
read(is, ru{tm, 1, 2}, CharT{'/'}, ru{td, 1, 2}, CharT{'/'},
|
||||
rs{ty, 1, 2});
|
||||
checked_set(y, ty, not_a_2digit_year, is);
|
||||
checked_set(m, tm, not_a_month, is);
|
||||
checked_set(d, td, not_a_day, is);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -6205,25 +6291,25 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
if ((err & ios::failbit) == 0)
|
||||
{
|
||||
h = hours{tm.tm_hour};
|
||||
min = minutes{tm.tm_min};
|
||||
s = duration_cast<Duration>(seconds{tm.tm_sec});
|
||||
checked_set(H, tm.tm_hour, not_a_hour, is);
|
||||
checked_set(M, tm.tm_min, not_a_minute, is);
|
||||
checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}),
|
||||
not_a_second, is);
|
||||
}
|
||||
is.setstate(err);
|
||||
#else
|
||||
// "%T"
|
||||
using dfs = detail::decimal_format_seconds<Duration>;
|
||||
CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
|
||||
int H;
|
||||
int M;
|
||||
int tH = not_a_hour;
|
||||
int tM = not_a_minute;
|
||||
long double S;
|
||||
read(is, ru{H, 1, 2}, CharT{':'}, ru{M, 1, 2},
|
||||
read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2},
|
||||
CharT{':'}, rld{S, 1, w});
|
||||
if (!is.fail())
|
||||
{
|
||||
h = hours{H};
|
||||
min = minutes{M};
|
||||
s = round<Duration>(duration<long double>{S});
|
||||
}
|
||||
checked_set(H, tH, not_a_hour, is);
|
||||
checked_set(M, tM, not_a_minute, is);
|
||||
checked_set(s, round<Duration>(duration<long double>{S}),
|
||||
not_a_second, is);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -6238,11 +6324,12 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
case 'C':
|
||||
if (command)
|
||||
{
|
||||
int tC = not_a_century;
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#endif
|
||||
read(is, rs{C, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
read(is, rs{tC, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
#if !ONLY_C_LOCALE
|
||||
}
|
||||
else
|
||||
@@ -6252,11 +6339,12 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
if ((err & ios::failbit) == 0)
|
||||
{
|
||||
auto tY = tm.tm_year + 1900;
|
||||
C = (tY >= 0 ? tY : tY-99) / 100;
|
||||
tC = (tY >= 0 ? tY : tY-99) / 100;
|
||||
}
|
||||
is.setstate(err);
|
||||
}
|
||||
#endif
|
||||
checked_set(C, tC, not_a_century, is);
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
@@ -6268,9 +6356,17 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
if (command)
|
||||
{
|
||||
if (modified == CharT{})
|
||||
read(is, ru{m, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'},
|
||||
ru{d, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'},
|
||||
rs{y, 1, 2});
|
||||
{
|
||||
int tm = not_a_month;
|
||||
int td = not_a_day;
|
||||
int ty = not_a_2digit_year;
|
||||
read(is, ru{tm, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'},
|
||||
ru{td, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'},
|
||||
rs{ty, 1, 2});
|
||||
checked_set(y, ty, not_a_2digit_year, is);
|
||||
checked_set(m, tm, not_a_month, is);
|
||||
checked_set(d, td, not_a_day, is);
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
command = nullptr;
|
||||
@@ -6284,8 +6380,16 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
if (command)
|
||||
{
|
||||
if (modified == CharT{})
|
||||
read(is, rs{Y, 1, width == -1 ? 4u : static_cast<unsigned>(width)},
|
||||
CharT{'-'}, ru{m, 1, 2}, CharT{'-'}, ru{d, 1, 2});
|
||||
{
|
||||
int tY = not_a_year;
|
||||
int tm = not_a_month;
|
||||
int td = not_a_day;
|
||||
read(is, rs{tY, 1, width == -1 ? 4u : static_cast<unsigned>(width)},
|
||||
CharT{'-'}, ru{tm, 1, 2}, CharT{'-'}, ru{td, 1, 2});
|
||||
checked_set(Y, tY, not_a_year, is);
|
||||
checked_set(m, tm, not_a_month, is);
|
||||
checked_set(d, td, not_a_day, is);
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
command = nullptr;
|
||||
@@ -6305,7 +6409,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
{
|
||||
read(is, rs{d, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
int td = not_a_day;
|
||||
read(is, rs{td, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
checked_set(d, td, not_a_day, is);
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
@@ -6316,7 +6422,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
if ((err & ios::failbit) == 0)
|
||||
d = tm.tm_mday;
|
||||
checked_set(d, tm.tm_mday, not_a_day, is);
|
||||
is.setstate(err);
|
||||
}
|
||||
#endif
|
||||
@@ -6338,10 +6444,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
{
|
||||
int H;
|
||||
read(is, ru{H, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
if (!is.fail())
|
||||
h = hours{H};
|
||||
int tH = not_a_hour;
|
||||
read(is, ru{tH, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
checked_set(H, tH, not_a_hour, is);
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
@@ -6349,7 +6454,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
if ((err & ios::failbit) == 0)
|
||||
h = hours{tm.tm_hour};
|
||||
checked_set(H, tm.tm_hour, not_a_hour, is);
|
||||
is.setstate(err);
|
||||
}
|
||||
#endif
|
||||
@@ -6367,16 +6472,12 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
{
|
||||
if (modified == CharT{})
|
||||
{
|
||||
int tI = not_a_hour_12_value;
|
||||
// reads in an hour into I, but most be in [1, 12]
|
||||
read(is, rs{I, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
if (I != not_a_hour_12_value)
|
||||
{
|
||||
if (!(1 <= I && I <= 12))
|
||||
{
|
||||
I = not_a_hour_12_value;
|
||||
goto broken;
|
||||
}
|
||||
}
|
||||
read(is, rs{tI, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
if (!(1 <= tI && tI <= 12))
|
||||
is.setstate(ios::failbit);
|
||||
checked_set(I, tI, not_a_hour_12_value, is);
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
@@ -6391,7 +6492,11 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
if (command)
|
||||
{
|
||||
if (modified == CharT{})
|
||||
read(is, ru{j, 1, width == -1 ? 3u : static_cast<unsigned>(width)});
|
||||
{
|
||||
int tj = not_a_doy;
|
||||
read(is, ru{tj, 1, width == -1 ? 3u : static_cast<unsigned>(width)});
|
||||
checked_set(j, tj, not_a_doy, is);
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
command = nullptr;
|
||||
@@ -6410,10 +6515,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
{
|
||||
int M;
|
||||
read(is, ru{M, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
if (!is.fail())
|
||||
min = minutes{M};
|
||||
int tM = not_a_minute;
|
||||
read(is, ru{tM, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
checked_set(M, tM, not_a_minute, is);
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
@@ -6421,7 +6525,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
if ((err & ios::failbit) == 0)
|
||||
min = minutes{tm.tm_min};
|
||||
checked_set(M, tm.tm_min, not_a_minute, is);
|
||||
is.setstate(err);
|
||||
}
|
||||
#endif
|
||||
@@ -6442,14 +6546,18 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
#else
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
read(is, rs{m, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
{
|
||||
int tm = not_a_month;
|
||||
read(is, rs{tm, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
checked_set(m, tm, not_a_month, is);
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
if ((err & ios::failbit) == 0)
|
||||
m = tm.tm_mon + 1;
|
||||
checked_set(m, tm.tm_mon + 1, not_a_month, is);
|
||||
is.setstate(err);
|
||||
}
|
||||
#endif
|
||||
@@ -6496,39 +6604,29 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
read(is, *fmt);
|
||||
break;
|
||||
case 'p':
|
||||
// Error if haven't yet seen %I
|
||||
if (command)
|
||||
{
|
||||
if (modified == CharT{})
|
||||
{
|
||||
int tp = not_a_ampm;
|
||||
#if !ONLY_C_LOCALE
|
||||
if (I == not_a_hour_12_value)
|
||||
goto broken;
|
||||
tm = std::tm{};
|
||||
tm.tm_hour = I;
|
||||
tm.tm_hour = 1;
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
if (err & ios::failbit)
|
||||
goto broken;
|
||||
h = hours{tm.tm_hour};
|
||||
I = not_a_hour_12_value;
|
||||
is.setstate(err);
|
||||
if (tm.tm_hour == 1)
|
||||
tp = 0;
|
||||
else if (tm.tm_hour == 13)
|
||||
tp = 1;
|
||||
else
|
||||
is.setstate(err);
|
||||
#else
|
||||
if (I == not_a_hour_12_value)
|
||||
goto broken;
|
||||
auto nm = detail::ampm_names();
|
||||
auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
|
||||
if (is.fail())
|
||||
goto broken;
|
||||
h = hours{I};
|
||||
if (i == 1)
|
||||
{
|
||||
if (h != hours{12})
|
||||
h += hours{12};
|
||||
}
|
||||
else if (h == hours{12})
|
||||
h = hours{0};
|
||||
I = not_a_hour_12_value;
|
||||
tp = i;
|
||||
#endif
|
||||
checked_set(p, tp, not_a_ampm, is);
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
@@ -6550,36 +6648,29 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
if ((err & ios::failbit) == 0)
|
||||
{
|
||||
h = hours{tm.tm_hour};
|
||||
min = minutes{tm.tm_min};
|
||||
s = duration_cast<Duration>(seconds{tm.tm_sec});
|
||||
checked_set(H, tm.tm_hour, not_a_hour, is);
|
||||
checked_set(M, tm.tm_min, not_a_hour, is);
|
||||
checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}),
|
||||
not_a_second, is);
|
||||
}
|
||||
is.setstate(err);
|
||||
#else
|
||||
// "%I:%M:%S %p"
|
||||
using dfs = detail::decimal_format_seconds<Duration>;
|
||||
CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
|
||||
int H;
|
||||
int M;
|
||||
long double S;
|
||||
read(is, ru{H, 1, 2}, CharT{':'}, ru{M, 1, 2},
|
||||
int tI = not_a_hour_12_value;
|
||||
int tM = not_a_minute;
|
||||
read(is, ru{tI, 1, 2}, CharT{':'}, ru{tM, 1, 2},
|
||||
CharT{':'}, rld{S, 1, w});
|
||||
if (is.fail() || !(1 <= H && H <= 12))
|
||||
goto broken;
|
||||
checked_set(I, tI, not_a_hour_12_value, is);
|
||||
checked_set(M, tM, not_a_minute, is);
|
||||
checked_set(s, round<Duration>(duration<long double>{S}),
|
||||
not_a_second, is);
|
||||
ws(is);
|
||||
auto nm = detail::ampm_names();
|
||||
auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
|
||||
if (is.fail())
|
||||
goto broken;
|
||||
h = hours{H};
|
||||
if (i == 1)
|
||||
{
|
||||
if (h != hours{12})
|
||||
h += hours{12};
|
||||
}
|
||||
else if (h == hours{12})
|
||||
h = hours{0};
|
||||
min = minutes{M};
|
||||
s = round<Duration>(duration<long double>{S});
|
||||
checked_set(p, static_cast<int>(i), not_a_ampm, is);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -6596,14 +6687,12 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
{
|
||||
if (modified == CharT{})
|
||||
{
|
||||
int H, M;
|
||||
read(is, ru{H, 1, 2}, CharT{'\0'}, CharT{':'}, CharT{'\0'},
|
||||
ru{M, 1, 2}, CharT{'\0'});
|
||||
if (!is.fail())
|
||||
{
|
||||
h = hours{H};
|
||||
min = minutes{M};
|
||||
}
|
||||
int tH = not_a_hour;
|
||||
int tM = not_a_minute;
|
||||
read(is, ru{tH, 1, 2}, CharT{'\0'}, CharT{':'}, CharT{'\0'},
|
||||
ru{tM, 1, 2}, CharT{'\0'});
|
||||
checked_set(H, tH, not_a_hour, is);
|
||||
checked_set(M, tM, not_a_minute, is);
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
@@ -6627,8 +6716,8 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
|
||||
long double S;
|
||||
read(is, rld{S, 1, width == -1 ? w : static_cast<unsigned>(width)});
|
||||
if (!is.fail())
|
||||
s = round<Duration>(duration<long double>{S});
|
||||
checked_set(s, round<Duration>(duration<long double>{S}),
|
||||
not_a_second, is);
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
@@ -6636,7 +6725,8 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
if ((err & ios::failbit) == 0)
|
||||
s = duration_cast<Duration>(seconds{tm.tm_sec});
|
||||
checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}),
|
||||
not_a_second, is);
|
||||
is.setstate(err);
|
||||
}
|
||||
#endif
|
||||
@@ -6656,17 +6746,15 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
{
|
||||
using dfs = detail::decimal_format_seconds<Duration>;
|
||||
CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
|
||||
int H;
|
||||
int M;
|
||||
int tH = not_a_hour;
|
||||
int tM = not_a_minute;
|
||||
long double S;
|
||||
read(is, ru{H, 1, 2}, CharT{':'}, ru{M, 1, 2},
|
||||
read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2},
|
||||
CharT{':'}, rld{S, 1, w});
|
||||
if (!is.fail())
|
||||
{
|
||||
h = hours{H};
|
||||
min = minutes{M};
|
||||
s = round<Duration>(duration<long double>{S});
|
||||
}
|
||||
checked_set(H, tH, not_a_hour, is);
|
||||
checked_set(M, tM, not_a_minute, is);
|
||||
checked_set(s, round<Duration>(duration<long double>{S}),
|
||||
not_a_second, is);
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
@@ -6685,14 +6773,18 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
#else
|
||||
if (modified != CharT{'O'})
|
||||
#endif
|
||||
read(is, rs{Y, 1, width == -1 ? 4u : static_cast<unsigned>(width)});
|
||||
{
|
||||
int tY = not_a_year;
|
||||
read(is, rs{tY, 1, width == -1 ? 4u : static_cast<unsigned>(width)});
|
||||
checked_set(Y, tY, not_a_year, is);
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'E'})
|
||||
{
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
if ((err & ios::failbit) == 0)
|
||||
Y = tm.tm_year + 1900;
|
||||
checked_set(Y, tm.tm_year + 1900, not_a_year, is);
|
||||
is.setstate(err);
|
||||
}
|
||||
#endif
|
||||
@@ -6711,14 +6803,18 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
#endif
|
||||
read(is, ru{y, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
{
|
||||
int ty = not_a_2digit_year;
|
||||
read(is, ru{ty, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
checked_set(y, ty, not_a_2digit_year, is);
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else
|
||||
{
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
if ((err & ios::failbit) == 0)
|
||||
Y = tm.tm_year + 1900;
|
||||
checked_set(Y, tm.tm_year + 1900, not_a_year, is);
|
||||
is.setstate(err);
|
||||
}
|
||||
#endif
|
||||
@@ -6733,7 +6829,11 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
if (command)
|
||||
{
|
||||
if (modified == CharT{})
|
||||
read(is, ru{g, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
{
|
||||
int tg = not_a_2digit_year;
|
||||
read(is, ru{tg, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
checked_set(g, tg, not_a_2digit_year, is);
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
command = nullptr;
|
||||
@@ -6747,7 +6847,11 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
if (command)
|
||||
{
|
||||
if (modified == CharT{})
|
||||
read(is, rs{G, 1, width == -1 ? 4u : static_cast<unsigned>(width)});
|
||||
{
|
||||
int tG = not_a_year;
|
||||
read(is, rs{tG, 1, width == -1 ? 4u : static_cast<unsigned>(width)});
|
||||
checked_set(G, tG, not_a_year, is);
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
command = nullptr;
|
||||
@@ -6761,7 +6865,11 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
if (command)
|
||||
{
|
||||
if (modified == CharT{})
|
||||
read(is, ru{U, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
{
|
||||
int tU = not_a_week_num;
|
||||
read(is, ru{tU, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
checked_set(U, tU, not_a_week_num, is);
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
command = nullptr;
|
||||
@@ -6775,7 +6883,11 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
if (command)
|
||||
{
|
||||
if (modified == CharT{})
|
||||
read(is, ru{V, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
{
|
||||
int tV = not_a_week_num;
|
||||
read(is, ru{tV, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
checked_set(V, tV, not_a_week_num, is);
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
command = nullptr;
|
||||
@@ -6789,59 +6901,11 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
if (command)
|
||||
{
|
||||
if (modified == CharT{})
|
||||
read(is, ru{W, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
}
|
||||
else
|
||||
read(is, *fmt);
|
||||
break;
|
||||
case 'u':
|
||||
case 'w':
|
||||
if (command)
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
#else
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
{
|
||||
read(is, ru{wd, 1, width == -1 ? 1u : static_cast<unsigned>(width)});
|
||||
if (!is.fail())
|
||||
{
|
||||
if (*fmt == 'u')
|
||||
{
|
||||
if (!(1 <= wd && wd <= 7))
|
||||
{
|
||||
wd = not_a_weekday;
|
||||
is.setstate(ios_base::failbit);
|
||||
int tW = not_a_week_num;
|
||||
read(is, ru{tW, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
checked_set(W, tW, not_a_week_num, is);
|
||||
}
|
||||
else if (wd == 7)
|
||||
wd = 0;
|
||||
}
|
||||
else // *fmt == 'w'
|
||||
{
|
||||
if (!(0 <= wd && wd <= 6))
|
||||
{
|
||||
wd = not_a_weekday;
|
||||
is.setstate(ios_base::failbit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
if ((err & ios::failbit) == 0)
|
||||
wd = tm.tm_wday;
|
||||
is.setstate(err);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
command = nullptr;
|
||||
@@ -6887,12 +6951,13 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
case 'z':
|
||||
if (command)
|
||||
{
|
||||
int H, M;
|
||||
int tH, tM;
|
||||
minutes toff = not_a_offset;
|
||||
if (modified == CharT{})
|
||||
{
|
||||
read(is, rs{H, 2, 2});
|
||||
read(is, rs{tH, 2, 2});
|
||||
if (!is.fail())
|
||||
temp_offset = hours{H};
|
||||
toff = hours{tH};
|
||||
if (is.good())
|
||||
{
|
||||
auto ic = is.peek();
|
||||
@@ -6901,18 +6966,18 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
auto c = static_cast<char>(Traits::to_char_type(ic));
|
||||
if ('0' <= c && c <= '9')
|
||||
{
|
||||
read(is, ru{M, 2, 2});
|
||||
read(is, ru{tM, 2, 2});
|
||||
if (!is.fail())
|
||||
temp_offset += minutes{ H < 0 ? -M : M };
|
||||
toff += minutes{ tH < 0 ? -tM : tM };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
read(is, rs{H, 1, 2});
|
||||
read(is, rs{tH, 1, 2});
|
||||
if (!is.fail())
|
||||
temp_offset = hours{H};
|
||||
toff = hours{tH};
|
||||
if (is.good())
|
||||
{
|
||||
auto ic = is.peek();
|
||||
@@ -6922,13 +6987,14 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
if (c == ':')
|
||||
{
|
||||
(void)is.get();
|
||||
read(is, ru{M, 2, 2});
|
||||
read(is, ru{tM, 2, 2});
|
||||
if (!is.fail())
|
||||
temp_offset += minutes{ H < 0 ? -M : M };
|
||||
toff += minutes{ tH < 0 ? -tM : tM };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
checked_set(temp_offset, toff, not_a_offset, is);
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
@@ -6941,10 +7007,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
{
|
||||
if (modified == CharT{})
|
||||
{
|
||||
if (!temp_abbrev.empty())
|
||||
is.setstate(ios::failbit);
|
||||
else
|
||||
{
|
||||
std::basic_string<CharT, Traits, Alloc> buf;
|
||||
while (is.rdstate() == std::ios::goodbit)
|
||||
{
|
||||
auto i = is.rdbuf()->sgetc();
|
||||
@@ -6959,12 +7022,12 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
if (!(CharT{1} < wc && wc < CharT{127}) || !(isalnum(c) ||
|
||||
c == '_' || c == '/' || c == '-' || c == '+'))
|
||||
break;
|
||||
temp_abbrev.push_back(c);
|
||||
buf.push_back(c);
|
||||
is.rdbuf()->sbumpc();
|
||||
}
|
||||
if (temp_abbrev.empty())
|
||||
if (buf.empty())
|
||||
is.setstate(ios::failbit);
|
||||
}
|
||||
checked_set(temp_abbrev, buf, {}, is);
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
@@ -7193,9 +7256,55 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
}
|
||||
}
|
||||
fds.ymd = ymd;
|
||||
fds.tod = time_of_day<Duration>{h};
|
||||
fds.tod.m_ = min;
|
||||
if (I != not_a_hour_12_value)
|
||||
{
|
||||
if (!(1 <= I && I <= 12))
|
||||
goto broken;
|
||||
if (p != not_a_ampm)
|
||||
{
|
||||
// p is in [0, 1] == [AM, PM]
|
||||
// Store trial H in I
|
||||
if (I == 12)
|
||||
--p;
|
||||
I += p*12;
|
||||
// Either set H from I or make sure H and I are consistent
|
||||
if (H == not_a_hour)
|
||||
H = I;
|
||||
else if (I != H)
|
||||
goto broken;
|
||||
}
|
||||
else // p == not_a_ampm
|
||||
{
|
||||
// if H, make sure H and I could be consistent
|
||||
if (H != not_a_hour)
|
||||
{
|
||||
if (I == 12)
|
||||
{
|
||||
if (H != 0 && H != 12)
|
||||
goto broken;
|
||||
}
|
||||
else if (!(I == H || I == H+12))
|
||||
{
|
||||
goto broken;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (H != not_a_hour)
|
||||
{
|
||||
fds.has_tod = true;
|
||||
fds.tod = time_of_day<Duration>{hours{H}};
|
||||
}
|
||||
if (M != not_a_minute)
|
||||
{
|
||||
fds.has_tod = true;
|
||||
fds.tod.m_ = minutes{M};
|
||||
}
|
||||
if (s != not_a_second)
|
||||
{
|
||||
fds.has_tod = true;
|
||||
fds.tod.s_ = detail::decimal_format_seconds<Duration>{s};
|
||||
}
|
||||
if (wd != not_a_weekday)
|
||||
fds.wd = weekday{static_cast<unsigned>(wd)};
|
||||
if (abbrev != nullptr)
|
||||
@@ -7348,6 +7457,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
minutes offset_local{};
|
||||
auto offptr = offset ? offset : &offset_local;
|
||||
fields<CT> fds{};
|
||||
fds.has_tod = true;
|
||||
from_stream(is, fmt, fds, abbrev, offptr);
|
||||
if (!fds.ymd.ok() || !fds.tod.in_conventional_range())
|
||||
is.setstate(ios::failbit);
|
||||
@@ -7366,6 +7476,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
using namespace std::chrono;
|
||||
using CT = typename common_type<Duration, seconds>::type;
|
||||
fields<CT> fds{};
|
||||
fds.has_tod = true;
|
||||
from_stream(is, fmt, fds, abbrev, offset);
|
||||
if (!fds.ymd.ok() || !fds.tod.in_conventional_range())
|
||||
is.setstate(ios::failbit);
|
||||
@@ -7387,6 +7498,8 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
using CT = typename common_type<Duration, seconds>::type;
|
||||
fields<CT> fds{};
|
||||
from_stream(is, fmt, fds, abbrev, offset);
|
||||
if (!fds.has_tod)
|
||||
is.setstate(ios::failbit);
|
||||
if (!is.fail())
|
||||
d = duration_cast<Duration>(fds.tod.to_duration());
|
||||
return is;
|
||||
|
@@ -1951,6 +1951,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
minutes offset_local{};
|
||||
auto offptr = offset ? offset : &offset_local;
|
||||
fields<CT> fds{};
|
||||
fds.has_tod = true;
|
||||
from_stream(is, fmt, fds, abbrev, offptr);
|
||||
if (!fds.ymd.ok())
|
||||
is.setstate(ios::failbit);
|
||||
@@ -2071,6 +2072,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
minutes offset_local{};
|
||||
auto offptr = offset ? offset : &offset_local;
|
||||
fields<CT> fds{};
|
||||
fds.has_tod = true;
|
||||
from_stream(is, fmt, fds, abbrev, offptr);
|
||||
if (!fds.ymd.ok() || !fds.tod.in_conventional_range())
|
||||
is.setstate(ios::failbit);
|
||||
@@ -2182,6 +2184,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
minutes offset_local{};
|
||||
auto offptr = offset ? offset : &offset_local;
|
||||
fields<CT> fds{};
|
||||
fds.has_tod = true;
|
||||
from_stream(is, fmt, fds, abbrev, offptr);
|
||||
if (!fds.ymd.ok() || !fds.tod.in_conventional_range())
|
||||
is.setstate(ios::failbit);
|
||||
|
Reference in New Issue
Block a user