mirror of
https://github.com/HowardHinnant/date.git
synced 2025-01-14 09:47:57 +08:00
Correct to_stream/from_stream handling of stream data
* to_stream and from_stream now reset the stream formatting state to default settings on entry, and restore the stream state on exit. * to_stream and from_stream now correctly handle mis-modified flags. * Fix %h to be equivalent to %b instead of %B. * This addresses issues 319, 320 and 321.
This commit is contained in:
parent
e7e1482087
commit
0125d330ab
@ -944,9 +944,10 @@ namespace detail {
|
||||
template<class CharT, class Traits = std::char_traits<CharT>>
|
||||
class save_stream
|
||||
{
|
||||
std::basic_ostream<CharT, Traits>& os_;
|
||||
std::basic_ios<CharT, Traits>& os_;
|
||||
CharT fill_;
|
||||
std::ios::fmtflags flags_;
|
||||
std::streamsize width_;
|
||||
std::locale loc_;
|
||||
|
||||
public:
|
||||
@ -954,16 +955,18 @@ public:
|
||||
{
|
||||
os_.fill(fill_);
|
||||
os_.flags(flags_);
|
||||
os_.width(width_);
|
||||
os_.imbue(loc_);
|
||||
}
|
||||
|
||||
save_stream(const save_stream&) = delete;
|
||||
save_stream& operator=(const save_stream&) = delete;
|
||||
|
||||
explicit save_stream(std::basic_ostream<CharT, Traits>& os)
|
||||
explicit save_stream(std::basic_ios<CharT, Traits>& os)
|
||||
: os_(os)
|
||||
, fill_(os.fill())
|
||||
, flags_(os.flags())
|
||||
, width_(os.width(0))
|
||||
, loc_(os.getloc())
|
||||
{}
|
||||
};
|
||||
@ -3729,7 +3732,7 @@ typename std::enable_if
|
||||
>::type
|
||||
abs(std::chrono::duration<Rep, Period> d)
|
||||
{
|
||||
return d >= d.zero() ? d : -d;
|
||||
return d >= d.zero() ? +d : -d;
|
||||
}
|
||||
|
||||
template <class Rep, class Period>
|
||||
@ -4578,6 +4581,10 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
using namespace std;
|
||||
using namespace std::chrono;
|
||||
using namespace detail;
|
||||
date::detail::save_stream<CharT, Traits> ss(os);
|
||||
os.fill(' ');
|
||||
os.flags(std::ios::skipws | std::ios::dec);
|
||||
os.width(0);
|
||||
tm tm{};
|
||||
#if !ONLY_C_LOCALE
|
||||
auto& facet = use_facet<time_put<CharT>>(os.getloc());
|
||||
@ -4626,7 +4633,7 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
const CharT f[] = {'%', *fmt};
|
||||
facet.put(os, os, os.fill(), &tm, begin(f), end(f));
|
||||
#else // ONLY_C_LOCALE
|
||||
os << month_names().first[tm.tm_mon+12*(*fmt == 'b')];
|
||||
os << month_names().first[tm.tm_mon+12*(*fmt != 'B')];
|
||||
#endif // ONLY_C_LOCALE
|
||||
}
|
||||
else
|
||||
@ -4709,8 +4716,10 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
auto y = static_cast<int>(fds.ymd.year());
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#else
|
||||
if (modified != CharT{'O'})
|
||||
#endif
|
||||
{
|
||||
save_stream<CharT, Traits> _(os);
|
||||
os.fill('0');
|
||||
os.flags(std::ios::dec | std::ios::right);
|
||||
@ -4725,19 +4734,19 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
os.width(2);
|
||||
os << -(y-99)/100;
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'E'})
|
||||
{
|
||||
tm.tm_year = y - 1900;
|
||||
CharT f[3] = {'%', 'E', 'C'};
|
||||
facet.put(os, os, os.fill(), &tm, begin(f), end(f));
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
os << CharT{'%'} << modified << *fmt;
|
||||
}
|
||||
#endif
|
||||
command = nullptr;
|
||||
modified = CharT{};
|
||||
}
|
||||
@ -4751,27 +4760,31 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
auto d = static_cast<int>(static_cast<unsigned>(fds.ymd.day()));
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#else
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
{
|
||||
save_stream<CharT, Traits> _(os);
|
||||
if (*fmt == CharT{'d'})
|
||||
os.fill('0');
|
||||
else
|
||||
os.fill(' ');
|
||||
os.flags(std::ios::dec | std::ios::right);
|
||||
os.width(2);
|
||||
os << d;
|
||||
#if !ONLY_C_LOCALE
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
tm.tm_mday = d;
|
||||
CharT f[3] = {'%', 'O', *fmt};
|
||||
facet.put(os, os, os.fill(), &tm, begin(f), end(f));
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
os << CharT{'%'} << modified << *fmt;
|
||||
}
|
||||
#endif
|
||||
command = nullptr;
|
||||
modified = CharT{};
|
||||
}
|
||||
@ -4869,26 +4882,28 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
auto hms = fds.tod;
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#else
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
{
|
||||
if (*fmt == CharT{'I'})
|
||||
hms.make12();
|
||||
if (hms.hours() < hours{10})
|
||||
os << CharT{'0'};
|
||||
os << hms.hours().count();
|
||||
#if !ONLY_C_LOCALE
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
const CharT f[] = {'%', modified, *fmt};
|
||||
tm.tm_hour = static_cast<int>(hms.hours().count());
|
||||
facet.put(os, os, os.fill(), &tm, begin(f), end(f));
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
os << CharT{'%'} << modified << *fmt;
|
||||
}
|
||||
#endif
|
||||
modified = CharT{};
|
||||
command = nullptr;
|
||||
}
|
||||
@ -4925,24 +4940,26 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
auto m = static_cast<unsigned>(fds.ymd.month());
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#else
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
{
|
||||
if (m < 10)
|
||||
os << CharT{'0'};
|
||||
os << m;
|
||||
#if !ONLY_C_LOCALE
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
const CharT f[] = {'%', modified, *fmt};
|
||||
tm.tm_mon = static_cast<int>(m-1);
|
||||
facet.put(os, os, os.fill(), &tm, begin(f), end(f));
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
os << CharT{'%'} << modified << *fmt;
|
||||
}
|
||||
#endif
|
||||
modified = CharT{};
|
||||
command = nullptr;
|
||||
}
|
||||
@ -4954,24 +4971,26 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#else
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
{
|
||||
if (fds.tod.minutes() < minutes{10})
|
||||
os << CharT{'0'};
|
||||
os << fds.tod.minutes().count();
|
||||
#if !ONLY_C_LOCALE
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
const CharT f[] = {'%', modified, *fmt};
|
||||
tm.tm_min = static_cast<int>(fds.tod.minutes().count());
|
||||
facet.put(os, os, os.fill(), &tm, begin(f), end(f));
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
os << CharT{'%'} << modified << *fmt;
|
||||
}
|
||||
#endif
|
||||
modified = CharT{};
|
||||
command = nullptr;
|
||||
}
|
||||
@ -4996,23 +5015,23 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
case 'p':
|
||||
if (command)
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
const CharT f[] = {'%', *fmt};
|
||||
tm.tm_hour = static_cast<int>(fds.tod.hours().count());
|
||||
facet.put(os, os, os.fill(), &tm, begin(f), end(f));
|
||||
}
|
||||
else
|
||||
{
|
||||
os << CharT{'%'} << modified << *fmt;
|
||||
}
|
||||
#else
|
||||
if (fds.tod.hours() < hours{12})
|
||||
os << ampm_names().first[0];
|
||||
else
|
||||
os << ampm_names().first[1];
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
os << CharT{'%'} << modified << *fmt;
|
||||
}
|
||||
modified = CharT{};
|
||||
command = nullptr;
|
||||
}
|
||||
@ -5022,19 +5041,14 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
case 'r':
|
||||
if (command)
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
const CharT f[] = {'%', *fmt};
|
||||
tm.tm_hour = static_cast<int>(fds.tod.hours().count());
|
||||
tm.tm_min = static_cast<int>(fds.tod.minutes().count());
|
||||
tm.tm_sec = static_cast<int>(fds.tod.seconds().count());
|
||||
facet.put(os, os, os.fill(), &tm, begin(f), end(f));
|
||||
}
|
||||
else
|
||||
{
|
||||
os << CharT{'%'} << modified << *fmt;
|
||||
}
|
||||
#else
|
||||
time_of_day<seconds> tod(duration_cast<seconds>(fds.tod.to_duration()));
|
||||
tod.make12();
|
||||
@ -5052,6 +5066,11 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
else
|
||||
os << ampm_names().first[1];
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
os << CharT{'%'} << modified << *fmt;
|
||||
}
|
||||
modified = CharT{};
|
||||
command = nullptr;
|
||||
}
|
||||
@ -5085,22 +5104,24 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#else
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
{
|
||||
os << fds.tod.s_;
|
||||
#if !ONLY_C_LOCALE
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
const CharT f[] = {'%', modified, *fmt};
|
||||
tm.tm_sec = static_cast<int>(fds.tod.s_.seconds().count());
|
||||
facet.put(os, os, os.fill(), &tm, begin(f), end(f));
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
os << CharT{'%'} << modified << *fmt;
|
||||
}
|
||||
#endif
|
||||
modified = CharT{};
|
||||
command = nullptr;
|
||||
}
|
||||
@ -5147,22 +5168,24 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
return os;
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#else
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
{
|
||||
os << (wd != 0 ? wd : 7u);
|
||||
#if !ONLY_C_LOCALE
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
const CharT f[] = {'%', modified, *fmt};
|
||||
tm.tm_wday = static_cast<int>(wd);
|
||||
facet.put(os, os, os.fill(), &tm, begin(f), end(f));
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
os << CharT{'%'} << modified << *fmt;
|
||||
}
|
||||
#endif
|
||||
modified = CharT{};
|
||||
command = nullptr;
|
||||
}
|
||||
@ -5176,8 +5199,10 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
auto ld = local_days(ymd);
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#else
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
{
|
||||
auto st = local_days(sun[1]/jan/ymd.year());
|
||||
if (ld < st)
|
||||
os << CharT{'0'} << CharT{'0'};
|
||||
@ -5188,8 +5213,8 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
os << CharT{'0'};
|
||||
os << wn;
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
const CharT f[] = {'%', modified, *fmt};
|
||||
@ -5200,11 +5225,11 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
tm.tm_yday = static_cast<int>((ld - local_days(ymd.year()/1/1)).count());
|
||||
facet.put(os, os, os.fill(), &tm, begin(f), end(f));
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
os << CharT{'%'} << modified << *fmt;
|
||||
}
|
||||
#endif
|
||||
modified = CharT{};
|
||||
command = nullptr;
|
||||
}
|
||||
@ -5217,8 +5242,10 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
auto ld = local_days(fds.ymd);
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#else
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
{
|
||||
auto y = year_month_day{ld + days{3}}.year();
|
||||
auto st = local_days((y - years{1})/12/thu[last]) + (mon-thu);
|
||||
if (ld < st)
|
||||
@ -5230,8 +5257,8 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
if (wn < 10)
|
||||
os << CharT{'0'};
|
||||
os << wn;
|
||||
#if !ONLY_C_LOCALE
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
const CharT f[] = {'%', modified, *fmt};
|
||||
@ -5243,11 +5270,11 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
tm.tm_yday = static_cast<int>((ld - local_days(ymd.year()/1/1)).count());
|
||||
facet.put(os, os, os.fill(), &tm, begin(f), end(f));
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
os << CharT{'%'} << modified << *fmt;
|
||||
}
|
||||
#endif
|
||||
modified = CharT{};
|
||||
command = nullptr;
|
||||
}
|
||||
@ -5262,22 +5289,24 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
return os;
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#else
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
{
|
||||
os << wd;
|
||||
#if !ONLY_C_LOCALE
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
const CharT f[] = {'%', modified, *fmt};
|
||||
tm.tm_wday = static_cast<int>(wd);
|
||||
facet.put(os, os, os.fill(), &tm, begin(f), end(f));
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
os << CharT{'%'} << modified << *fmt;
|
||||
}
|
||||
#endif
|
||||
modified = CharT{};
|
||||
command = nullptr;
|
||||
}
|
||||
@ -5291,8 +5320,10 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
auto ld = local_days(ymd);
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#else
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
{
|
||||
auto st = local_days(mon[1]/jan/ymd.year());
|
||||
if (ld < st)
|
||||
os << CharT{'0'} << CharT{'0'};
|
||||
@ -5303,8 +5334,8 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
os << CharT{'0'};
|
||||
os << wn;
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
const CharT f[] = {'%', modified, *fmt};
|
||||
@ -5315,11 +5346,11 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
tm.tm_yday = static_cast<int>((ld - local_days(ymd.year()/1/1)).count());
|
||||
facet.put(os, os, os.fill(), &tm, begin(f), end(f));
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
os << CharT{'%'} << modified << *fmt;
|
||||
}
|
||||
#endif
|
||||
modified = CharT{};
|
||||
command = nullptr;
|
||||
}
|
||||
@ -5329,11 +5360,11 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
case 'X':
|
||||
if (command)
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{'O'})
|
||||
os << CharT{'%'} << modified << *fmt;
|
||||
else
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
tm = std::tm{};
|
||||
tm.tm_sec = static_cast<int>(fds.tod.seconds().count());
|
||||
tm.tm_min = static_cast<int>(fds.tod.minutes().count());
|
||||
@ -5344,10 +5375,10 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
*fe++ = modified;
|
||||
*fe++ = *fmt;
|
||||
facet.put(os, os, os.fill(), &tm, begin(f), fe);
|
||||
}
|
||||
#else
|
||||
os << fds.tod;
|
||||
#endif
|
||||
}
|
||||
command = nullptr;
|
||||
modified = CharT{};
|
||||
}
|
||||
@ -5387,22 +5418,24 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
||||
auto y = fds.ymd.year();
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#else
|
||||
if (modified != CharT{'O'})
|
||||
#endif
|
||||
{
|
||||
os << y;
|
||||
#if !ONLY_C_LOCALE
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'E'})
|
||||
{
|
||||
const CharT f[] = {'%', modified, *fmt};
|
||||
tm.tm_year = static_cast<int>(y) - 1900;
|
||||
facet.put(os, os, os.fill(), &tm, begin(f), end(f));
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
os << CharT{'%'} << modified << *fmt;
|
||||
}
|
||||
#endif
|
||||
modified = CharT{};
|
||||
command = nullptr;
|
||||
}
|
||||
@ -5933,6 +5966,10 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
typename basic_istream<CharT, Traits>::sentry ok{is, true};
|
||||
if (ok)
|
||||
{
|
||||
date::detail::save_stream<CharT, Traits> ss(is);
|
||||
is.fill(' ');
|
||||
is.flags(std::ios::skipws | std::ios::dec);
|
||||
is.width(0);
|
||||
#if !ONLY_C_LOCALE
|
||||
auto& f = use_facet<time_get<CharT>>(is.getloc());
|
||||
std::tm tm{};
|
||||
@ -5976,6 +6013,8 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
case 'A':
|
||||
if (command)
|
||||
{
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
@ -5988,6 +6027,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
if (!is.fail())
|
||||
wd = i % 7;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
@ -6000,6 +6042,8 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
case 'h':
|
||||
if (command)
|
||||
{
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
@ -6012,6 +6056,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
if (!is.fail())
|
||||
m = i % 12 + 1;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
@ -6022,6 +6069,8 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
case 'c':
|
||||
if (command)
|
||||
{
|
||||
if (modified != CharT{'O'})
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
@ -6067,6 +6116,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
ws(is);
|
||||
read(is, rs{Y, 1, 4u});
|
||||
#endif
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
@ -6077,6 +6129,8 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
case 'x':
|
||||
if (command)
|
||||
{
|
||||
if (modified != CharT{'O'})
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
@ -6091,6 +6145,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
read(is, ru{m, 1, 2}, CharT{'/'}, ru{d, 1, 2}, CharT{'/'},
|
||||
rs{y, 1, 2});
|
||||
#endif
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
@ -6101,6 +6158,8 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
case 'X':
|
||||
if (command)
|
||||
{
|
||||
if (modified != CharT{'O'})
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
@ -6126,6 +6185,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
s = round<Duration>(duration<long double>{S});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
@ -6199,8 +6261,12 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
#else
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
{
|
||||
read(is, rs{d, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
@ -6213,9 +6279,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
d = tm.tm_mday;
|
||||
is.setstate(err);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
#endif
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
@ -6228,14 +6294,16 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#else
|
||||
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};
|
||||
#if !ONLY_C_LOCALE
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
@ -6244,9 +6312,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
h = hours{tm.tm_hour};
|
||||
is.setstate(err);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
#endif
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
@ -6298,14 +6366,16 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#else
|
||||
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};
|
||||
#if !ONLY_C_LOCALE
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
@ -6314,9 +6384,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
min = minutes{tm.tm_min};
|
||||
is.setstate(err);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
#endif
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
@ -6329,6 +6399,8 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
#else
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
read(is, rs{m, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
|
||||
#if !ONLY_C_LOCALE
|
||||
@ -6340,9 +6412,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
m = tm.tm_mon + 1;
|
||||
is.setstate(err);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
#endif
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
@ -6353,6 +6425,8 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
case 'n':
|
||||
case 't':
|
||||
if (command)
|
||||
{
|
||||
if (modified == CharT{})
|
||||
{
|
||||
// %n matches a single white space character
|
||||
// %t matches 0 or 1 white space characters
|
||||
@ -6371,6 +6445,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
}
|
||||
else if (*fmt == 'n')
|
||||
is.setstate(ios_base::failbit);
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
@ -6382,9 +6459,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
// Error if haven't yet seen %I
|
||||
if (command)
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
if (I == not_a_hour_12_value)
|
||||
goto broken;
|
||||
tm = std::tm{};
|
||||
@ -6395,9 +6472,6 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
goto broken;
|
||||
h = hours{tm.tm_hour};
|
||||
I = not_a_hour_12_value;
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
#else
|
||||
if (I == not_a_hour_12_value)
|
||||
goto broken;
|
||||
@ -6415,6 +6489,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
h = hours{0};
|
||||
I = not_a_hour_12_value;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
@ -6426,6 +6503,8 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
case 'r':
|
||||
if (command)
|
||||
{
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
f.get(is, nullptr, is, err, &tm, command, fmt+1);
|
||||
@ -6462,6 +6541,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
min = minutes{M};
|
||||
s = round<Duration>(duration<long double>{S});
|
||||
#endif
|
||||
}
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
@ -6497,16 +6579,18 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
{
|
||||
#else
|
||||
if (modified != CharT{'E'})
|
||||
#endif
|
||||
{
|
||||
using dfs = detail::decimal_format_seconds<Duration>;
|
||||
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});
|
||||
#if !ONLY_C_LOCALE
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
@ -6515,9 +6599,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
s = duration_cast<Duration>(seconds{tm.tm_sec});
|
||||
is.setstate(err);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
#endif
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
@ -6558,6 +6642,8 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
{
|
||||
#if !ONLY_C_LOCALE
|
||||
if (modified == CharT{})
|
||||
#else
|
||||
if (modified != CharT{'O'})
|
||||
#endif
|
||||
read(is, rs{Y, 1, width == -1 ? 4u : static_cast<unsigned>(width)});
|
||||
#if !ONLY_C_LOCALE
|
||||
@ -6569,9 +6655,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
Y = tm.tm_year + 1900;
|
||||
is.setstate(err);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
#endif
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
@ -6679,8 +6765,10 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
{
|
||||
#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() && *fmt == 'u')
|
||||
{
|
||||
@ -6689,8 +6777,8 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
else if (wd == 0)
|
||||
wd = 7;
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
}
|
||||
#if !ONLY_C_LOCALE
|
||||
else if (modified == CharT{'O'})
|
||||
{
|
||||
ios_base::iostate err = ios_base::goodbit;
|
||||
@ -6699,9 +6787,9 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
||||
wd = tm.tm_wday;
|
||||
is.setstate(err);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
read(is, CharT{'%'}, width, modified, *fmt);
|
||||
#endif
|
||||
command = nullptr;
|
||||
width = -1;
|
||||
modified = CharT{};
|
||||
|
Loading…
x
Reference in New Issue
Block a user