From 76bef1fe014712c08bd0942c662613024e39d786 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Sun, 29 May 2016 00:15:33 -0400 Subject: [PATCH] Support wide streams --- date.h | 193 ++++++++++++++++++++------------ iso_week.h | 85 +++++++++----- tz.cpp | 6 +- tz.h | 319 +++++++++++++++++++++++++++++++++++++++-------------- 4 files changed, 419 insertions(+), 184 deletions(-) diff --git a/date.h b/date.h index bff7942..410f0d6 100644 --- a/date.h +++ b/date.h @@ -247,7 +247,9 @@ CONSTCD11 day operator+(const days& x, const day& y) NOEXCEPT; CONSTCD11 day operator-(const day& x, const days& y) NOEXCEPT; CONSTCD11 days operator-(const day& x, const day& y) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const day& d); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const day& d); // month @@ -282,7 +284,9 @@ CONSTCD14 month operator+(const months& x, const month& y) NOEXCEPT; CONSTCD14 month operator-(const month& x, const months& y) NOEXCEPT; CONSTCD14 months operator-(const month& x, const month& y) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const month& m); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const month& m); // year @@ -322,7 +326,9 @@ CONSTCD11 year operator+(const years& x, const year& y) NOEXCEPT; CONSTCD11 year operator-(const year& x, const years& y) NOEXCEPT; CONSTCD11 years operator-(const year& x, const year& y) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const year& y); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const year& y); // weekday @@ -361,7 +367,9 @@ CONSTCD14 weekday operator+(const days& x, const weekday& y) NOEXCEPT; CONSTCD14 weekday operator-(const weekday& x, const days& y) NOEXCEPT; CONSTCD14 days operator-(const weekday& x, const weekday& y) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const weekday& wd); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const weekday& wd); // weekday_indexed @@ -381,7 +389,9 @@ public: CONSTCD11 bool operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; CONSTCD11 bool operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const weekday_indexed& wdi); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const weekday_indexed& wdi); // weekday_last @@ -399,7 +409,9 @@ public: CONSTCD11 bool operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT; CONSTCD11 bool operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const weekday_last& wdl); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const weekday_last& wdl); // year_month @@ -438,7 +450,9 @@ CONSTCD11 year_month operator+(const year_month& ym, const years& dy) NOEXCEPT; CONSTCD11 year_month operator+(const years& dy, const year_month& ym) NOEXCEPT; CONSTCD11 year_month operator-(const year_month& ym, const years& dy) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const year_month& ym); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_month& ym); // month_day @@ -463,7 +477,9 @@ CONSTCD11 bool operator> (const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator<=(const month_day& x, const month_day& y) NOEXCEPT; CONSTCD11 bool operator>=(const month_day& x, const month_day& y) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const month_day& md); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const month_day& md); // month_day_last @@ -485,7 +501,9 @@ CONSTCD11 bool operator> (const month_day_last& x, const month_day_last& y) NOEX CONSTCD11 bool operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT; CONSTCD11 bool operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const month_day_last& mdl); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const month_day_last& mdl); // month_weekday @@ -506,7 +524,9 @@ public: CONSTCD11 bool operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT; CONSTCD11 bool operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const month_weekday& mwd); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const month_weekday& mwd); // month_weekday_last @@ -530,7 +550,9 @@ CONSTCD11 CONSTCD11 bool operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const month_weekday_last& mwdl); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const month_weekday_last& mwdl); // class year_month_day @@ -580,7 +602,9 @@ CONSTCD11 year_month_day operator+(const year_month_day& ymd, const years& dy) CONSTCD11 year_month_day operator+(const years& dy, const year_month_day& ymd) NOEXCEPT; CONSTCD11 year_month_day operator-(const year_month_day& ymd, const years& dy) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const year_month_day& ymd); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_month_day& ymd); // year_month_day_last @@ -645,7 +669,9 @@ CONSTCD11 year_month_day_last operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const year_month_day_last& ymdl); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_month_day_last& ymdl); // year_month_weekday @@ -710,7 +736,9 @@ CONSTCD11 year_month_weekday operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const year_month_weekday& ymwdi); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_month_weekday& ymwdi); // year_month_weekday_last @@ -774,7 +802,9 @@ CONSTCD11 year_month_weekday_last operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const year_month_weekday_last& ymwdl); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_month_weekday_last& ymwdl); #if !defined(_MSC_VER) || (_MSC_VER >= 1900) inline namespace literals @@ -814,10 +844,11 @@ CONSTCD11 date::year operator "" _y(unsigned long long y) NOEXCEPT; // utilities namespace detail { +template> class save_stream { - std::ostream& os_; - char fill_; + std::basic_ostream& os_; + CharT fill_; std::ios::fmtflags flags_; std::locale loc_; @@ -832,7 +863,7 @@ public: save_stream(const save_stream&) = delete; save_stream& operator=(const save_stream&) = delete; - explicit save_stream(std::ostream& os) + explicit save_stream(std::basic_ostream& os) : os_(os) , fill_(os.fill()) , flags_(os.flags()) @@ -1133,11 +1164,12 @@ operator-(const day& x, const days& y) NOEXCEPT return x + -y; } +template inline -std::ostream& -operator<<(std::ostream& os, const day& d) +std::basic_ostream& +operator<<(std::basic_ostream& os, const day& d) { - detail::save_stream _(os); + detail::save_stream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); os.width(2); @@ -1255,9 +1287,10 @@ operator-(const month& x, const months& y) NOEXCEPT return x + -y; } +template inline -std::ostream& -operator<<(std::ostream& os, const month& m) +std::basic_ostream& +operator<<(std::basic_ostream& os, const month& m) { switch (static_cast(m)) { @@ -1421,11 +1454,12 @@ operator-(const year& x, const years& y) NOEXCEPT return year{static_cast(x) - y.count()}; } +template inline -std::ostream& -operator<<(std::ostream& os, const year& y) +std::basic_ostream& +operator<<(std::basic_ostream& os, const year& y) { - detail::save_stream _(os); + detail::save_stream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::internal); os.width(4 + (y < year{0})); @@ -1543,9 +1577,10 @@ operator-(const weekday& x, const days& y) NOEXCEPT return x + -y; } +template inline -std::ostream& -operator<<(std::ostream& os, const weekday& wd) +std::basic_ostream& +operator<<(std::basic_ostream& os, const weekday& wd) { switch (static_cast(wd)) { @@ -1652,9 +1687,10 @@ weekday_indexed::weekday_indexed(const date::weekday& wd, unsigned index) NOEXCE , index_(static_cast(index)) {} +template inline -std::ostream& -operator<<(std::ostream& os, const weekday_indexed& wdi) +std::basic_ostream& +operator<<(std::basic_ostream& os, const weekday_indexed& wdi) { return os << wdi.weekday() << '[' << wdi.index() << ']'; } @@ -1705,9 +1741,10 @@ operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT return !(x == y); } +template inline -std::ostream& -operator<<(std::ostream& os, const weekday_last& wdl) +std::basic_ostream& +operator<<(std::basic_ostream& os, const weekday_last& wdl) { return os << wdl.weekday() << "[last]"; } @@ -1875,9 +1912,10 @@ operator-(const year_month& ym, const years& dy) NOEXCEPT return ym + -dy; } +template inline -std::ostream& -operator<<(std::ostream& os, const year_month& ym) +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_month& ym) { return os << ym.year() << '/' << ym.month(); } @@ -1959,9 +1997,10 @@ operator>=(const month_day& x, const month_day& y) NOEXCEPT return !(x < y); } +template inline -std::ostream& -operator<<(std::ostream& os, const month_day& md) +std::basic_ostream& +operator<<(std::basic_ostream& os, const month_day& md) { return os << md.month() << '/' << md.day(); } @@ -2020,9 +2059,10 @@ operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT return !(x < y); } +template inline -std::ostream& -operator<<(std::ostream& os, const month_day_last& mdl) +std::basic_ostream& +operator<<(std::basic_ostream& os, const month_day_last& mdl) { return os << mdl.month() << "/last"; } @@ -2071,9 +2111,10 @@ operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT return !(x == y); } +template inline -std::ostream& -operator<<(std::ostream& os, const month_weekday& mwd) +std::basic_ostream& +operator<<(std::basic_ostream& os, const month_weekday& mwd) { return os << mwd.month() << '/' << mwd.weekday_indexed(); } @@ -2122,9 +2163,10 @@ operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT return !(x == y); } +template inline -std::ostream& -operator<<(std::ostream& os, const month_weekday_last& mwdl) +std::basic_ostream& +operator<<(std::basic_ostream& os, const month_weekday_last& mwdl) { return os << mwdl.month() << '/' << mwdl.weekday_last(); } @@ -2270,9 +2312,10 @@ operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT return !(x < y); } +template inline -std::ostream& -operator<<(std::ostream& os, const year_month_day_last& ymdl) +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_month_day_last& ymdl) { return os << ymdl.year() << '/' << ymdl.month_day_last(); } @@ -2487,11 +2530,12 @@ operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT return !(x < y); } +template inline -std::ostream& -operator<<(std::ostream& os, const year_month_day& ymd) +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_month_day& ymd) { - detail::save_stream _(os); + detail::save_stream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); os << ymd.year() << '-'; @@ -2718,9 +2762,10 @@ operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT return !(x == y); } +template inline -std::ostream& -operator<<(std::ostream& os, const year_month_weekday& ymwdi) +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_month_weekday& ymwdi) { return os << ymwdi.year() << '/' << ymwdi.month() << '/' << ymwdi.weekday_indexed(); @@ -2885,9 +2930,10 @@ operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) N return !(x == y); } +template inline -std::ostream& -operator<<(std::ostream& os, const year_month_weekday_last& ymwdl) +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_month_weekday_last& ymwdl) { return os << ymwdl.year() << '/' << ymwdl.month() << '/' << ymwdl.weekday_last(); } @@ -3435,12 +3481,13 @@ public: CONSTCD14 time_of_day_storage& make24() NOEXCEPT {base::make24(); return *this;} CONSTCD14 time_of_day_storage& make12() NOEXCEPT {base::make12(); return *this;} + template friend - std::ostream& - operator<<(std::ostream& os, const time_of_day_storage& t) + std::basic_ostream& + operator<<(std::basic_ostream& os, const time_of_day_storage& t) { using namespace std; - detail::save_stream _(os); + detail::save_stream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::right); if (t.mode_ != am && t.mode_ != pm) @@ -3501,12 +3548,13 @@ public: CONSTCD14 time_of_day_storage& make24() NOEXCEPT {base::make24(); return *this;} CONSTCD14 time_of_day_storage& make12() NOEXCEPT {base::make12(); return *this;} + template friend - std::ostream& - operator<<(std::ostream& os, const time_of_day_storage& t) + std::basic_ostream& + operator<<(std::basic_ostream& os, const time_of_day_storage& t) { using namespace std; - detail::save_stream _(os); + detail::save_stream _(os); if (static_cast(t) < std::chrono::hours{0}) os << '-'; os.fill('0'); @@ -3572,12 +3620,13 @@ public: CONSTCD14 time_of_day_storage& make24() NOEXCEPT {base::make24(); return *this;} CONSTCD14 time_of_day_storage& make12() NOEXCEPT {base::make12(); return *this;} + template friend - std::ostream& - operator<<(std::ostream& os, const time_of_day_storage& t) + std::basic_ostream& + operator<<(std::basic_ostream& os, const time_of_day_storage& t) { using namespace std; - detail::save_stream _(os); + detail::save_stream _(os); if (static_cast(t) < std::chrono::hours{0}) os << '-'; os.fill('0'); @@ -3652,12 +3701,13 @@ public: CONSTCD14 time_of_day_storage& make24() NOEXCEPT {base::make24(); return *this;} CONSTCD14 time_of_day_storage& make12() NOEXCEPT {base::make12(); return *this;} + template friend - std::ostream& - operator<<(std::ostream& os, const time_of_day_storage& t) + std::basic_ostream& + operator<<(std::basic_ostream& os, const time_of_day_storage& t) { using namespace std; - detail::save_stream _(os); + detail::save_stream _(os); if (static_cast(t) < std::chrono::hours{0}) os << '-'; os.fill('0'); @@ -3808,31 +3858,32 @@ make_time(std::chrono::hours h, std::chrono::minutes m, std::chrono::seconds s, return time_of_day>(h, m, s, sub_s, md); } -template +template inline typename std::enable_if < !std::chrono::treat_as_floating_point::value && std::ratio_less::value - , std::ostream& + , std::basic_ostream& >::type -operator<<(std::ostream& os, const sys_time& tp) +operator<<(std::basic_ostream& os, const sys_time& tp) { auto const dp = floor(tp); return os << year_month_day(dp) << ' ' << make_time(tp-dp); } +template inline -std::ostream& -operator<<(std::ostream& os, const sys_days& dp) +std::basic_ostream& +operator<<(std::basic_ostream& os, const sys_days& dp) { return os << year_month_day(dp); } -template +template inline -std::ostream& -operator<<(std::ostream& os, const local_time& ut) +std::basic_ostream& +operator<<(std::basic_ostream& os, const local_time& ut) { return os << sys_time{ut.time_since_epoch()}; } diff --git a/iso_week.h b/iso_week.h index 2b7aea8..2c80f54 100644 --- a/iso_week.h +++ b/iso_week.h @@ -125,7 +125,9 @@ CONSTCD14 weekday operator+(const days& x, const weekday& y) NOEXCEPT; CONSTCD14 weekday operator-(const weekday& x, const days& y) NOEXCEPT; CONSTCD14 days operator-(const weekday& x, const weekday& y) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const weekday& wd); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const weekday& wd); // year @@ -163,7 +165,9 @@ CONSTCD11 year operator+(const years& x, const year& y) NOEXCEPT; CONSTCD11 year operator-(const year& x, const years& y) NOEXCEPT; CONSTCD11 years operator-(const year& x, const year& y) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const year& y); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const year& y); // weeknum @@ -198,7 +202,9 @@ CONSTCD11 weeknum operator+(const weeks& x, const weeknum& y) NOEXCEPT; CONSTCD11 weeknum operator-(const weeknum& x, const weeks& y) NOEXCEPT; CONSTCD11 weeks operator-(const weeknum& x, const weeknum& y) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const weeknum& wn); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const weeknum& wn); // year_weeknum @@ -230,7 +236,9 @@ CONSTCD11 year_weeknum operator+(const year_weeknum& ym, const years& dy) NOEXCE CONSTCD11 year_weeknum operator+(const years& dy, const year_weeknum& ym) NOEXCEPT; CONSTCD11 year_weeknum operator-(const year_weeknum& ym, const years& dy) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const year_weeknum& ym); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_weeknum& ym); // year_lastweek @@ -261,7 +269,9 @@ CONSTCD11 year_lastweek operator+(const year_lastweek& ym, const years& dy) NOEX CONSTCD11 year_lastweek operator+(const years& dy, const year_lastweek& ym) NOEXCEPT; CONSTCD11 year_lastweek operator-(const year_lastweek& ym, const years& dy) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const year_lastweek& ym); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_lastweek& ym); // weeknum_weekday @@ -287,7 +297,9 @@ CONSTCD11 bool operator> (const weeknum_weekday& x, const weeknum_weekday& y) NO CONSTCD11 bool operator<=(const weeknum_weekday& x, const weeknum_weekday& y) NOEXCEPT; CONSTCD11 bool operator>=(const weeknum_weekday& x, const weeknum_weekday& y) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const weeknum_weekday& md); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const weeknum_weekday& md); // lastweek_weekday @@ -310,7 +322,9 @@ CONSTCD11 bool operator> (const lastweek_weekday& x, const lastweek_weekday& y) CONSTCD11 bool operator<=(const lastweek_weekday& x, const lastweek_weekday& y) NOEXCEPT; CONSTCD11 bool operator>=(const lastweek_weekday& x, const lastweek_weekday& y) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const lastweek_weekday& md); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const lastweek_weekday& md); // year_lastweek_weekday @@ -346,7 +360,9 @@ CONSTCD11 year_lastweek_weekday operator+(const year_lastweek_weekday& ywnwd, co CONSTCD11 year_lastweek_weekday operator+(const years& y, const year_lastweek_weekday& ywnwd) NOEXCEPT; CONSTCD11 year_lastweek_weekday operator-(const year_lastweek_weekday& ywnwd, const years& y) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const year_lastweek_weekday& ywnwd); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_lastweek_weekday& ywnwd); // class year_weeknum_weekday @@ -389,7 +405,9 @@ CONSTCD11 year_weeknum_weekday operator+(const year_weeknum_weekday& ywnwd, cons CONSTCD11 year_weeknum_weekday operator+(const years& y, const year_weeknum_weekday& ywnwd) NOEXCEPT; CONSTCD11 year_weeknum_weekday operator-(const year_weeknum_weekday& ywnwd, const years& y) NOEXCEPT; -std::ostream& operator<<(std::ostream& os, const year_weeknum_weekday& ywnwd); +template +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_weeknum_weekday& ywnwd); //----------------+ // Implementation | @@ -534,9 +552,10 @@ operator-(const weekday& x, const days& y) NOEXCEPT return x + -y; } +template inline -std::ostream& -operator<<(std::ostream& os, const weekday& wd) +std::basic_ostream& +operator<<(std::basic_ostream& os, const weekday& wd) { switch (static_cast(wd)) { @@ -687,11 +706,12 @@ operator-(const year& x, const years& y) NOEXCEPT return year{static_cast(x) - y.count()}; } +template inline -std::ostream& -operator<<(std::ostream& os, const year& y) +std::basic_ostream& +operator<<(std::basic_ostream& os, const year& y) { - date::detail::save_stream _(os); + date::detail::save_stream _(os); os.fill('0'); os.flags(std::ios::dec | std::ios::internal); os.width(4 + (y < year{0})); @@ -848,11 +868,12 @@ operator-(const weeknum& x, const weeks& y) NOEXCEPT return x + -y; } +template inline -std::ostream& -operator<<(std::ostream& os, const weeknum& wn) +std::basic_ostream& +operator<<(std::basic_ostream& os, const weeknum& wn) { - date::detail::save_stream _(os); + date::detail::save_stream _(os); os << 'W'; os.fill('0'); os.flags(std::ios::dec | std::ios::right); @@ -967,9 +988,10 @@ operator-(const year_weeknum& ym, const years& dy) NOEXCEPT return ym + -dy; } +template inline -std::ostream& -operator<<(std::ostream& os, const year_weeknum& ywn) +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_weeknum& ywn) { return os << ywn.year() << '-' << ywn.weeknum(); } @@ -1086,9 +1108,10 @@ operator-(const year_lastweek& ym, const years& dy) NOEXCEPT return ym + -dy; } +template inline -std::ostream& -operator<<(std::ostream& os, const year_lastweek& ywn) +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_lastweek& ywn) { return os << ywn.year() << "-W last"; } @@ -1164,9 +1187,10 @@ operator>=(const weeknum_weekday& x, const weeknum_weekday& y) NOEXCEPT return !(x < y); } +template inline -std::ostream& -operator<<(std::ostream& os, const weeknum_weekday& md) +std::basic_ostream& +operator<<(std::basic_ostream& os, const weeknum_weekday& md) { return os << md.weeknum() << '-' << md.weekday(); } @@ -1237,9 +1261,10 @@ operator>=(const lastweek_weekday& x, const lastweek_weekday& y) NOEXCEPT return !(x < y); } +template inline -std::ostream& -operator<<(std::ostream& os, const lastweek_weekday& md) +std::basic_ostream& +operator<<(std::basic_ostream& os, const lastweek_weekday& md) { return os << "W last-" << md.weekday(); } @@ -1380,9 +1405,10 @@ operator-(const year_lastweek_weekday& ywnwd, const years& y) NOEXCEPT return ywnwd + -y; } +template inline -std::ostream& -operator<<(std::ostream& os, const year_lastweek_weekday& ywnwd) +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_lastweek_weekday& ywnwd) { return os << ywnwd.year() << "-W last-" << ywnwd.weekday(); } @@ -1557,9 +1583,10 @@ operator-(const year_weeknum_weekday& ywnwd, const years& y) NOEXCEPT return ywnwd + -y; } +template inline -std::ostream& -operator<<(std::ostream& os, const year_weeknum_weekday& ywnwd) +std::basic_ostream& +operator<<(std::basic_ostream& os, const year_weeknum_weekday& ywnwd) { return os << ywnwd.year() << '-' << ywnwd.weeknum() << '-' << ywnwd.weekday(); } diff --git a/tz.cpp b/tz.cpp index b386f53..07a730b 100644 --- a/tz.cpp +++ b/tz.cpp @@ -1034,7 +1034,7 @@ operator<<(std::ostream& os, const Rule& r) { using namespace date; using namespace std::chrono; - detail::save_stream _(os); + detail::save_stream _(os); os.fill(' '); os.flags(std::ios::dec | std::ios::left); os.width(15); @@ -1853,7 +1853,7 @@ operator<<(std::ostream& os, const time_zone& z) { using namespace date; using namespace std::chrono; - detail::save_stream _(os); + detail::save_stream _(os); os.fill(' '); os.flags(std::ios::dec | std::ios::left); #if LAZY_INIT @@ -1919,7 +1919,7 @@ std::ostream& operator<<(std::ostream& os, const link& x) { using namespace date; - detail::save_stream _(os); + detail::save_stream _(os); os.fill(' '); os.flags(std::ios::dec | std::ios::left); os.width(35); diff --git a/tz.h b/tz.h index 5b42535..3b977b4 100644 --- a/tz.h +++ b/tz.h @@ -210,8 +210,7 @@ struct sys_info std::string abbrev; }; -std::ostream& -operator<<(std::ostream& os, const sys_info& r); +std::ostream& operator<<(std::ostream& os, const sys_info& r); struct local_info { @@ -220,12 +219,7 @@ struct local_info sys_info second; }; -std::ostream& -operator<<(std::ostream& os, const local_info& r); - -// deprecated: - -using Info = sys_info; +std::ostream& operator<<(std::ostream& os, const local_info& r); class time_zone; @@ -277,10 +271,10 @@ public: bool operator==(const zoned_time& x, const zoned_time& y); - template + template friend - std::ostream& - operator<<(std::ostream& os, const zoned_time& t); + std::basic_ostream& + operator<<(std::basic_ostream& os, const zoned_time& t); private: @@ -726,7 +720,8 @@ struct TZ_DB #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) }; -std::ostream& operator<<(std::ostream& os, const TZ_DB& db); +std::ostream& +operator<<(std::ostream& os, const TZ_DB& db); const TZ_DB& get_tzdb(); const TZ_DB& reload_tzdb(); @@ -995,10 +990,10 @@ make_zoned(const std::string& name, const sys_time& st) return {name, st}; } -template +template inline -std::ostream& -operator<<(std::ostream& os, const zoned_time& t) +std::basic_ostream& +operator<<(std::basic_ostream& os, const zoned_time& t) { auto i = t.zone_->get_info(t.tp_); auto lt = t.tp_ + i.offset; @@ -1088,9 +1083,9 @@ to_utc_time(sys_time st) namespace detail { -template -std::string -format(const std::locale& loc, std::string format, +template +std::basic_string +format(const std::locale& loc, std::basic_string format, local_time tp, const time_zone* zone = nullptr) { // Handle these specially @@ -1111,7 +1106,7 @@ format(const std::locale& loc, std::string format, case 'T': if (ratio_less>::value) { - ostringstream os; + basic_ostringstream os; os.imbue(loc); os << make_time(tp - floor(tp)); auto s = os.str(); @@ -1127,7 +1122,7 @@ format(const std::locale& loc, std::string format, { auto info = zone->get_info(tp).first; auto offset = duration_cast(info.offset); - ostringstream os; + basic_ostringstream os; if (offset >= minutes{0}) os << '+'; os << make_time(offset); @@ -1143,15 +1138,16 @@ format(const std::locale& loc, std::string format, else { auto info = zone->get_info(tp).first; - format.replace(i, 2, info.abbrev); + format.replace(i, 2, std::basic_string + (info.abbrev.begin(), info.abbrev.end())); i += info.abbrev.size() - 1; } break; } } } - auto& f = use_facet>(loc); - ostringstream os; + auto& f = use_facet>(loc); + basic_ostringstream os; auto tt = system_clock::to_time_t(sys_time{tp.time_since_epoch()}); std::tm tm{}; #ifndef _MSC_VER @@ -1165,78 +1161,136 @@ format(const std::locale& loc, std::string format, } // namespace detail -template +template inline -std::string -format(const std::locale& loc, std::string format, local_time tp) +std::basic_string +format(const std::locale& loc, std::basic_string format, + local_time tp) { return detail::format(loc, std::move(format), tp); } -template +template inline -std::string -format(std::string format, local_time tp) +std::basic_string +format(std::basic_string format, local_time tp) { return detail::format(std::locale{}, std::move(format), tp); } -template +template inline -std::string -format(const std::locale& loc, std::string format, const zoned_time& tp) +std::basic_string +format(const std::locale& loc, std::basic_string format, + const zoned_time& tp) { return detail::format(loc, std::move(format), tp.get_local_time(), tp.get_time_zone()); } -template +template inline -std::string -format(std::string format, const zoned_time& tp) +std::basic_string +format(std::basic_string format, const zoned_time& tp) { return detail::format(std::locale{}, std::move(format), tp.get_local_time(), tp.get_time_zone()); } -template +template inline -std::string -format(const std::locale& loc, std::string format, sys_time tp) +std::basic_string +format(const std::locale& loc, std::basic_string format, + sys_time tp) { return detail::format(loc, std::move(format), local_time{tp.time_since_epoch()}, locate_zone("UTC")); } -template +template inline -std::string -format(std::string format, sys_time tp) +std::basic_string +format(std::basic_string format, sys_time tp) { return detail::format(std::locale{}, std::move(format), local_time{tp.time_since_epoch()}, locate_zone("UTC")); } +// const CharT* formats + +template +inline +std::basic_string +format(const std::locale& loc, const CharT* format, local_time tp) +{ + return detail::format(loc, std::basic_string(format), tp); +} + +template +inline +std::basic_string +format(const CharT* format, local_time tp) +{ + return detail::format(std::locale{}, std::basic_string(format), tp); +} + +template +inline +std::basic_string +format(const std::locale& loc, const CharT* format, const zoned_time& tp) +{ + return detail::format(loc, std::basic_string(format), tp.get_local_time(), + tp.get_time_zone()); +} + +template +inline +std::basic_string +format(const CharT* format, const zoned_time& tp) +{ + return detail::format(std::locale{}, std::basic_string(format), + tp.get_local_time(), tp.get_time_zone()); +} + +template +inline +std::basic_string +format(const std::locale& loc, const CharT* format, sys_time tp) +{ + return detail::format(loc, std::basic_string(format), + local_time{tp.time_since_epoch()}, locate_zone("UTC")); +} + +template +inline +std::basic_string +format(const CharT* format, sys_time tp) +{ + return detail::format(std::locale{}, std::basic_string(format), + local_time{tp.time_since_epoch()}, locate_zone("UTC")); +} + // parse namespace detail { -template +template void -parse(std::istream& is, const std::string& format, sys_time& tp, - std::string& abbrev, std::chrono::minutes& offset) +parse(std::basic_istream& is, + const std::basic_string& format, sys_time& tp, + std::basic_string& abbrev, std::chrono::minutes& offset) { using namespace std; using namespace std::chrono; - istream::sentry ok{is}; + typename basic_istream::sentry ok{is}; if (ok) { - auto& f = use_facet>(is.getloc()); + auto& f = use_facet>(is.getloc()); ios_base::iostate err = ios_base::goodbit; std::tm tm{}; Duration subseconds{}; - std::string temp_abbrev; + std::basic_string temp_abbrev; minutes temp_offset{}; auto b = format.data(); @@ -1255,8 +1309,8 @@ parse(std::istream& is, const std::string& format, sys_time& tp, b = i+1; if (*i == 'T') { - const char hm[] = "%H:%M:"; - f.get(is, 0, is, err, &tm, hm, hm+6); + const CharT hm[] = {'%', 'H', ':', '%', 'M', ':', 0}; + f.get(is, 0, is, err, &tm, hm, hm); } if (ratio_less>::value) { @@ -1269,7 +1323,7 @@ parse(std::istream& is, const std::string& format, sys_time& tp, } else { - const char hm[] = "%S"; + const CharT hm[] = {'%', 'S'}; f.get(is, 0, is, err, &tm, hm, hm+2); } break; @@ -1279,7 +1333,7 @@ parse(std::istream& is, const std::string& format, sys_time& tp, b = i+1; if ((err & ios_base::failbit) == 0) { - char sign{}; + CharT sign{}; is >> sign; if (!is.fail() && (sign == '+' || sign == '-')) { @@ -1339,23 +1393,25 @@ parse(std::istream& is, const std::string& format, sys_time& tp, } // namespace detail -template +template inline void -parse(std::istream& is, const std::string& format, sys_time& tp) +parse(std::basic_istream& is, + const std::basic_string& format, sys_time& tp) { - std::string abbrev; + std::basic_string abbrev; std::chrono::minutes offset{}; detail::parse(is, format, tp, abbrev, offset); if (!is.fail()) tp = floor(tp - offset); } -template +template inline void -parse(std::istream& is, const std::string& format, sys_time& tp, - std::string& abbrev) +parse(std::basic_istream& is, + const std::basic_string& format, sys_time& tp, + std::basic_string& abbrev) { std::chrono::minutes offset{}; detail::parse(is, format, tp, abbrev, offset); @@ -1363,58 +1419,63 @@ parse(std::istream& is, const std::string& format, sys_time& tp, tp = floor(tp - offset); } -template +template inline void -parse(std::istream& is, const std::string& format, sys_time& tp, +parse(std::basic_istream& is, + const std::basic_string& format, sys_time& tp, std::chrono::minutes& offset) { - std::string abbrev; + std::basic_string abbrev; detail::parse(is, format, tp, abbrev, offset); if (!is.fail()) tp = floor(tp - offset); } -template +template inline void -parse(std::istream& is, const std::string& format, sys_time& tp, - std::string& abbrev, std::chrono::minutes& offset) +parse(std::basic_istream& is, + const std::basic_string& format, sys_time& tp, + std::basic_string& abbrev, std::chrono::minutes& offset) { detail::parse(is, format, tp, abbrev, offset); if (!is.fail()) tp = floor(tp - offset); } -template +template inline void -parse(std::istream& is, const std::string& format, sys_time& tp, - std::chrono::minutes& offset, std::string& abbrev) +parse(std::basic_istream& is, + const std::basic_string& format, sys_time& tp, + std::chrono::minutes& offset, std::basic_string& abbrev) { detail::parse(is, format, tp, abbrev, offset); if (!is.fail()) tp = floor(tp - offset); } -template +template inline void -parse(std::istream& is, const std::string& format, local_time& tp) +parse(std::basic_istream& is, + const std::basic_string& format, local_time& tp) { sys_time st; - std::string abbrev; + std::basic_string abbrev; std::chrono::minutes offset{}; detail::parse(is, format, st, abbrev, offset); if (!is.fail()) tp = local_time{st.time_since_epoch()}; } -template +template inline void -parse(std::istream& is, const std::string& format, local_time& tp, - std::string& abbrev) +parse(std::basic_istream& is, + const std::basic_string& format, local_time& tp, + std::basic_string& abbrev) { sys_time st; std::chrono::minutes offset{}; @@ -1423,24 +1484,26 @@ parse(std::istream& is, const std::string& format, local_time& tp, tp = local_time{st.time_since_epoch()}; } -template +template inline void -parse(std::istream& is, const std::string& format, local_time& tp, +parse(std::basic_istream& is, + const std::basic_string& format, local_time& tp, std::chrono::minutes& offset) { sys_time st; - std::string abbrev; + std::basic_string abbrev; detail::parse(is, format, st, abbrev, offset); if (!is.fail()) tp = local_time{st.time_since_epoch()}; } -template +template inline void -parse(std::istream& is, const std::string& format, local_time& tp, - std::string& abbrev, std::chrono::minutes& offset) +parse(std::basic_istream& is, + const std::basic_string& format, local_time& tp, + std::basic_string& abbrev, std::chrono::minutes& offset) { sys_time st; detail::parse(is, format, st, abbrev, offset); @@ -1448,11 +1511,12 @@ parse(std::istream& is, const std::string& format, local_time& tp, tp = local_time{st.time_since_epoch()}; } -template +template inline void -parse(std::istream& is, const std::string& format, local_time& tp, - std::chrono::minutes& offset, std::string& abbrev) +parse(std::basic_istream& is, + const std::basic_string& format, local_time& tp, + std::chrono::minutes& offset, std::basic_string& abbrev) { sys_time st; detail::parse(is, format, st, abbrev, offset); @@ -1460,6 +1524,99 @@ parse(std::istream& is, const std::string& format, local_time& tp, tp = local_time{st.time_since_epoch()}; } +// const CharT* formats + +template +inline +void +parse(std::basic_istream& is, const CharT* format, sys_time& tp) +{ + parse(is, std::basic_string(format), tp); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, sys_time& tp, + std::basic_string& abbrev) +{ + parse(is, std::basic_string(format), tp, abbrev); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, sys_time& tp, + std::chrono::minutes& offset) +{ + parse(is, std::basic_string(format), tp, offset); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, sys_time& tp, + std::basic_string& abbrev, std::chrono::minutes& offset) +{ + parse(is, std::basic_string(format), tp, abbrev, offset); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, sys_time& tp, + std::chrono::minutes& offset, std::basic_string& abbrev) +{ + parse(is, std::basic_string(format), tp, abbrev, offset); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, + local_time& tp) +{ + parse(is, std::basic_string(format), tp); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, + local_time& tp, std::basic_string& abbrev) +{ + parse(is, std::basic_string(format), tp, abbrev); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, + local_time& tp, std::chrono::minutes& offset) +{ + parse(is, std::basic_string(format), tp, offset); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, + local_time& tp, std::basic_string& abbrev, + std::chrono::minutes& offset) +{ + parse(is, std::basic_string(format), tp, abbrev, offset); +} + +template +inline +void +parse(std::basic_istream& is, const CharT* format, + local_time& tp, std::chrono::minutes& offset, + std::basic_string& abbrev) +{ + parse(is, std::basic_string(format), tp, abbrev, offset); +} + } // namespace date #endif // TZ_H