mirror of
https://github.com/HowardHinnant/date.git
synced 2024-12-27 16:41:04 +08:00
Respect and minimize tie/flush in from/to_stream
* Save/restore tie, setting it to nullptr during the operation * On construction tie_->flush() * For ostreams only, flush if unitbuf
This commit is contained in:
parent
d53db7a1cb
commit
973bd393bc
@ -942,33 +942,61 @@ struct is_clock<T, std::void_t<decltype(T::now()), typename T::rep, typename T::
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template<class CharT, class Traits = std::char_traits<CharT>>
|
template<class CharT, class Traits = std::char_traits<CharT>>
|
||||||
class save_stream
|
class save_istream
|
||||||
{
|
{
|
||||||
std::basic_ios<CharT, Traits>& os_;
|
protected:
|
||||||
|
std::basic_ios<CharT, Traits>& is_;
|
||||||
CharT fill_;
|
CharT fill_;
|
||||||
std::ios::fmtflags flags_;
|
std::ios::fmtflags flags_;
|
||||||
std::streamsize width_;
|
std::streamsize width_;
|
||||||
|
std::basic_ostream<CharT, Traits>* tie_;
|
||||||
std::locale loc_;
|
std::locale loc_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~save_stream()
|
~save_istream()
|
||||||
{
|
{
|
||||||
os_.fill(fill_);
|
is_.fill(fill_);
|
||||||
os_.flags(flags_);
|
is_.flags(flags_);
|
||||||
os_.width(width_);
|
is_.width(width_);
|
||||||
os_.imbue(loc_);
|
is_.imbue(loc_);
|
||||||
|
is_.tie(tie_);
|
||||||
}
|
}
|
||||||
|
|
||||||
save_stream(const save_stream&) = delete;
|
save_istream(const save_istream&) = delete;
|
||||||
save_stream& operator=(const save_stream&) = delete;
|
save_istream& operator=(const save_istream&) = delete;
|
||||||
|
|
||||||
explicit save_stream(std::basic_ios<CharT, Traits>& os)
|
explicit save_istream(std::basic_ios<CharT, Traits>& is)
|
||||||
: os_(os)
|
: is_(is)
|
||||||
, fill_(os.fill())
|
, fill_(is.fill())
|
||||||
, flags_(os.flags())
|
, flags_(is.flags())
|
||||||
, width_(os.width(0))
|
, width_(is.width(0))
|
||||||
, loc_(os.getloc())
|
, tie_(is.tie(nullptr))
|
||||||
{}
|
, loc_(is.getloc())
|
||||||
|
{
|
||||||
|
if (tie_ != nullptr)
|
||||||
|
tie_->flush();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class CharT, class Traits = std::char_traits<CharT>>
|
||||||
|
class save_ostream
|
||||||
|
: private save_istream<CharT, Traits>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~save_ostream()
|
||||||
|
{
|
||||||
|
if ((this->flags_ & std::ios::unitbuf) && !std::uncaught_exception() &&
|
||||||
|
this->is_.good())
|
||||||
|
this->is_.rdbuf()->pubsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
save_ostream(const save_ostream&) = delete;
|
||||||
|
save_ostream& operator=(const save_ostream&) = delete;
|
||||||
|
|
||||||
|
explicit save_ostream(std::basic_ios<CharT, Traits>& os)
|
||||||
|
: save_istream<CharT, Traits>(os)
|
||||||
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@ -1357,7 +1385,7 @@ inline
|
|||||||
std::basic_ostream<CharT, Traits>&
|
std::basic_ostream<CharT, Traits>&
|
||||||
operator<<(std::basic_ostream<CharT, Traits>& os, const day& d)
|
operator<<(std::basic_ostream<CharT, Traits>& os, const day& d)
|
||||||
{
|
{
|
||||||
detail::save_stream<CharT, Traits> _(os);
|
detail::save_ostream<CharT, Traits> _(os);
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
os.flags(std::ios::dec | std::ios::right);
|
os.flags(std::ios::dec | std::ios::right);
|
||||||
os.width(2);
|
os.width(2);
|
||||||
@ -1625,7 +1653,7 @@ inline
|
|||||||
std::basic_ostream<CharT, Traits>&
|
std::basic_ostream<CharT, Traits>&
|
||||||
operator<<(std::basic_ostream<CharT, Traits>& os, const year& y)
|
operator<<(std::basic_ostream<CharT, Traits>& os, const year& y)
|
||||||
{
|
{
|
||||||
detail::save_stream<CharT, Traits> _(os);
|
detail::save_ostream<CharT, Traits> _(os);
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
os.flags(std::ios::dec | std::ios::internal);
|
os.flags(std::ios::dec | std::ios::internal);
|
||||||
os.width(4 + (y < year{0}));
|
os.width(4 + (y < year{0}));
|
||||||
@ -2731,7 +2759,7 @@ inline
|
|||||||
std::basic_ostream<CharT, Traits>&
|
std::basic_ostream<CharT, Traits>&
|
||||||
operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_day& ymd)
|
operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_day& ymd)
|
||||||
{
|
{
|
||||||
detail::save_stream<CharT, Traits> _(os);
|
detail::save_ostream<CharT, Traits> _(os);
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
os.flags(std::ios::dec | std::ios::right);
|
os.flags(std::ios::dec | std::ios::right);
|
||||||
os << ymd.year() << '-';
|
os << ymd.year() << '-';
|
||||||
@ -3644,7 +3672,7 @@ public:
|
|||||||
std::basic_ostream<CharT, Traits>&
|
std::basic_ostream<CharT, Traits>&
|
||||||
operator<<(std::basic_ostream<CharT, Traits>& os, const decimal_format_seconds& x)
|
operator<<(std::basic_ostream<CharT, Traits>& os, const decimal_format_seconds& x)
|
||||||
{
|
{
|
||||||
date::detail::save_stream<CharT, Traits> _(os);
|
date::detail::save_ostream<CharT, Traits> _(os);
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
os.flags(std::ios::dec | std::ios::right);
|
os.flags(std::ios::dec | std::ios::right);
|
||||||
os.width(2);
|
os.width(2);
|
||||||
@ -3689,7 +3717,7 @@ public:
|
|||||||
std::basic_ostream<CharT, Traits>&
|
std::basic_ostream<CharT, Traits>&
|
||||||
operator<<(std::basic_ostream<CharT, Traits>& os, const decimal_format_seconds& x)
|
operator<<(std::basic_ostream<CharT, Traits>& os, const decimal_format_seconds& x)
|
||||||
{
|
{
|
||||||
date::detail::save_stream<CharT, Traits> _(os);
|
date::detail::save_ostream<CharT, Traits> _(os);
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
os.flags(std::ios::dec | std::ios::right);
|
os.flags(std::ios::dec | std::ios::right);
|
||||||
os.width(2);
|
os.width(2);
|
||||||
@ -3889,7 +3917,7 @@ public:
|
|||||||
operator<<(std::basic_ostream<CharT, Traits>& os, const time_of_day_storage& t)
|
operator<<(std::basic_ostream<CharT, Traits>& os, const time_of_day_storage& t)
|
||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
detail::save_stream<CharT, Traits> _(os);
|
detail::save_ostream<CharT, Traits> _(os);
|
||||||
if (t.neg_)
|
if (t.neg_)
|
||||||
os << '-';
|
os << '-';
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
@ -3972,7 +4000,7 @@ public:
|
|||||||
operator<<(std::basic_ostream<CharT, Traits>& os, const time_of_day_storage& t)
|
operator<<(std::basic_ostream<CharT, Traits>& os, const time_of_day_storage& t)
|
||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
detail::save_stream<CharT, Traits> _(os);
|
detail::save_ostream<CharT, Traits> _(os);
|
||||||
if (t.neg_)
|
if (t.neg_)
|
||||||
os << '-';
|
os << '-';
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
@ -4062,7 +4090,7 @@ public:
|
|||||||
operator<<(std::basic_ostream<CharT, Traits>& os, const time_of_day_storage& t)
|
operator<<(std::basic_ostream<CharT, Traits>& os, const time_of_day_storage& t)
|
||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
detail::save_stream<CharT, Traits> _(os);
|
detail::save_ostream<CharT, Traits> _(os);
|
||||||
if (t.neg_)
|
if (t.neg_)
|
||||||
os << '-';
|
os << '-';
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
@ -4172,7 +4200,7 @@ public:
|
|||||||
operator<<(std::basic_ostream<CharT, Traits>& os, const time_of_day_storage& t)
|
operator<<(std::basic_ostream<CharT, Traits>& os, const time_of_day_storage& t)
|
||||||
{
|
{
|
||||||
using namespace std;
|
using namespace std;
|
||||||
detail::save_stream<CharT, Traits> _(os);
|
detail::save_ostream<CharT, Traits> _(os);
|
||||||
if (t.neg_)
|
if (t.neg_)
|
||||||
os << '-';
|
os << '-';
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
@ -4586,7 +4614,7 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
using namespace detail;
|
using namespace detail;
|
||||||
date::detail::save_stream<CharT, Traits> ss(os);
|
date::detail::save_ostream<CharT, Traits> ss(os);
|
||||||
os.fill(' ');
|
os.fill(' ');
|
||||||
os.flags(std::ios::skipws | std::ios::dec);
|
os.flags(std::ios::skipws | std::ios::dec);
|
||||||
os.width(0);
|
os.width(0);
|
||||||
@ -4704,7 +4732,7 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|||||||
else // *fmt == 'x'
|
else // *fmt == 'x'
|
||||||
{
|
{
|
||||||
auto const& ymd = fds.ymd;
|
auto const& ymd = fds.ymd;
|
||||||
save_stream<CharT, Traits> _(os);
|
save_ostream<CharT, Traits> _(os);
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
os.flags(std::ios::dec | std::ios::right);
|
os.flags(std::ios::dec | std::ios::right);
|
||||||
os.width(2);
|
os.width(2);
|
||||||
@ -4736,7 +4764,7 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|||||||
if (modified == CharT{})
|
if (modified == CharT{})
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
save_stream<CharT, Traits> _(os);
|
save_ostream<CharT, Traits> _(os);
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
os.flags(std::ios::dec | std::ios::right);
|
os.flags(std::ios::dec | std::ios::right);
|
||||||
if (y >= 0)
|
if (y >= 0)
|
||||||
@ -4781,7 +4809,7 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|||||||
if (modified == CharT{})
|
if (modified == CharT{})
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
save_stream<CharT, Traits> _(os);
|
save_ostream<CharT, Traits> _(os);
|
||||||
if (*fmt == CharT{'d'})
|
if (*fmt == CharT{'d'})
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
else
|
else
|
||||||
@ -4813,7 +4841,7 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|||||||
if (!fds.ymd.ok())
|
if (!fds.ymd.ok())
|
||||||
os.setstate(std::ios::failbit);
|
os.setstate(std::ios::failbit);
|
||||||
auto const& ymd = fds.ymd;
|
auto const& ymd = fds.ymd;
|
||||||
save_stream<CharT, Traits> _(os);
|
save_ostream<CharT, Traits> _(os);
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
os.flags(std::ios::dec | std::ios::right);
|
os.flags(std::ios::dec | std::ios::right);
|
||||||
os.width(2);
|
os.width(2);
|
||||||
@ -4841,7 +4869,7 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|||||||
if (!fds.ymd.ok())
|
if (!fds.ymd.ok())
|
||||||
os.setstate(std::ios::failbit);
|
os.setstate(std::ios::failbit);
|
||||||
auto const& ymd = fds.ymd;
|
auto const& ymd = fds.ymd;
|
||||||
save_stream<CharT, Traits> _(os);
|
save_ostream<CharT, Traits> _(os);
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
os.flags(std::ios::dec | std::ios::right);
|
os.flags(std::ios::dec | std::ios::right);
|
||||||
os.width(4);
|
os.width(4);
|
||||||
@ -4878,7 +4906,7 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|||||||
os << y;
|
os << y;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
save_stream<CharT, Traits> _(os);
|
save_ostream<CharT, Traits> _(os);
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
os.flags(std::ios::dec | std::ios::right);
|
os.flags(std::ios::dec | std::ios::right);
|
||||||
os.width(2);
|
os.width(2);
|
||||||
@ -4941,7 +4969,7 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|||||||
auto ld = local_days(fds.ymd);
|
auto ld = local_days(fds.ymd);
|
||||||
auto y = fds.ymd.year();
|
auto y = fds.ymd.year();
|
||||||
auto doy = ld - local_days(y/jan/1) + days{1};
|
auto doy = ld - local_days(y/jan/1) + days{1};
|
||||||
save_stream<CharT, Traits> _(os);
|
save_ostream<CharT, Traits> _(os);
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
os.flags(std::ios::dec | std::ios::right);
|
os.flags(std::ios::dec | std::ios::right);
|
||||||
os.width(3);
|
os.width(3);
|
||||||
@ -5081,7 +5109,7 @@ to_stream(std::basic_ostream<CharT, Traits>& os, const CharT* fmt,
|
|||||||
#else
|
#else
|
||||||
time_of_day<seconds> tod(duration_cast<seconds>(fds.tod.to_duration()));
|
time_of_day<seconds> tod(duration_cast<seconds>(fds.tod.to_duration()));
|
||||||
tod.make12();
|
tod.make12();
|
||||||
save_stream<CharT, Traits> _(os);
|
save_ostream<CharT, Traits> _(os);
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
os.width(2);
|
os.width(2);
|
||||||
os << tod.hours().count() << CharT{':'};
|
os << tod.hours().count() << CharT{':'};
|
||||||
@ -6019,7 +6047,7 @@ from_stream(std::basic_istream<CharT, Traits>& is, const CharT* fmt,
|
|||||||
typename basic_istream<CharT, Traits>::sentry ok{is, true};
|
typename basic_istream<CharT, Traits>::sentry ok{is, true};
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
date::detail::save_stream<CharT, Traits> ss(is);
|
date::detail::save_istream<CharT, Traits> ss(is);
|
||||||
is.fill(' ');
|
is.fill(' ');
|
||||||
is.flags(std::ios::skipws | std::ios::dec);
|
is.flags(std::ios::skipws | std::ios::dec);
|
||||||
is.width(0);
|
is.width(0);
|
||||||
|
@ -713,7 +713,7 @@ inline
|
|||||||
std::basic_ostream<CharT, Traits>&
|
std::basic_ostream<CharT, Traits>&
|
||||||
operator<<(std::basic_ostream<CharT, Traits>& os, const year& y)
|
operator<<(std::basic_ostream<CharT, Traits>& os, const year& y)
|
||||||
{
|
{
|
||||||
date::detail::save_stream<CharT, Traits> _(os);
|
date::detail::save_ostream<CharT, Traits> _(os);
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
os.flags(std::ios::dec | std::ios::internal);
|
os.flags(std::ios::dec | std::ios::internal);
|
||||||
os.width(4 + (y < year{0}));
|
os.width(4 + (y < year{0}));
|
||||||
@ -875,7 +875,7 @@ inline
|
|||||||
std::basic_ostream<CharT, Traits>&
|
std::basic_ostream<CharT, Traits>&
|
||||||
operator<<(std::basic_ostream<CharT, Traits>& os, const weeknum& wn)
|
operator<<(std::basic_ostream<CharT, Traits>& os, const weeknum& wn)
|
||||||
{
|
{
|
||||||
date::detail::save_stream<CharT, Traits> _(os);
|
date::detail::save_ostream<CharT, Traits> _(os);
|
||||||
os << 'W';
|
os << 'W';
|
||||||
os.fill('0');
|
os.fill('0');
|
||||||
os.flags(std::ios::dec | std::ios::right);
|
os.flags(std::ios::dec | std::ios::right);
|
||||||
|
@ -1224,7 +1224,7 @@ detail::operator<<(std::ostream& os, const Rule& r)
|
|||||||
{
|
{
|
||||||
using namespace date;
|
using namespace date;
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
detail::save_stream<char> _(os);
|
detail::save_ostream<char> _(os);
|
||||||
os.fill(' ');
|
os.fill(' ');
|
||||||
os.flags(std::ios::dec | std::ios::left);
|
os.flags(std::ios::dec | std::ios::left);
|
||||||
os.width(15);
|
os.width(15);
|
||||||
@ -2541,7 +2541,7 @@ operator<<(std::ostream& os, const time_zone& z)
|
|||||||
{
|
{
|
||||||
using namespace date;
|
using namespace date;
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
detail::save_stream<char> _(os);
|
detail::save_ostream<char> _(os);
|
||||||
os.fill(' ');
|
os.fill(' ');
|
||||||
os.flags(std::ios::dec | std::ios::left);
|
os.flags(std::ios::dec | std::ios::left);
|
||||||
std::call_once(*z.adjusted_,
|
std::call_once(*z.adjusted_,
|
||||||
@ -2715,7 +2715,7 @@ std::ostream&
|
|||||||
operator<<(std::ostream& os, const link& x)
|
operator<<(std::ostream& os, const link& x)
|
||||||
{
|
{
|
||||||
using namespace date;
|
using namespace date;
|
||||||
detail::save_stream<char> _(os);
|
detail::save_ostream<char> _(os);
|
||||||
os.fill(' ');
|
os.fill(' ');
|
||||||
os.flags(std::ios::dec | std::ios::left);
|
os.flags(std::ios::dec | std::ios::left);
|
||||||
os.width(35);
|
os.width(35);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user