diff --git a/chrono_io/chrono_io b/chrono_io/chrono_io new file mode 100644 index 000000000..8de9d4f45 --- /dev/null +++ b/chrono_io/chrono_io @@ -0,0 +1,1140 @@ +// chrono_io +// +// (C) Copyright Howard Hinnant +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). + +#ifndef _CHRONO_IO +#define _CHRONO_IO + +/* + + chrono_io synopsis + +#include +#include + +namespace std +{ +namespace chrono +{ + +template +class durationpunct + : public locale::facet +{ +public: + static locale::id id; + + typedef basic_string string_type; + enum {use_long, use_short}; + + explicit durationpunct(int use = use_long); + + durationpunct(int use, + const string_type& long_seconds, const string_type& long_minutes, + const string_type& long_hours, const string_type& short_seconds, + const string_type& short_minutes, const string_type& short_hours); + + durationpunct(int use, const durationpunct& d); + + template string_type short_name() const; + template string_type long_name() const; + template string_type name() const; + + bool is_short_name() const; + bool is_long_name() const; +}; + +template + basic_ostream& + duration_short(basic_ostream& os); + +template + basic_ostream& + duration_long(basic_ostream& os); + +template + basic_ostream& + operator<<(basic_ostream& os, const duration& d); + +template + basic_istream& + operator>>(basic_istream& is, duration& d); + +template + basic_ostream& + operator<<(basic_ostream& os, + const time_point& tp); + +template + basic_ostream& + operator<<(basic_ostream& os, + const time_point& tp); + +template + basic_ostream& + operator<<(basic_ostream& os, + const time_point& tp); + +template + basic_istream& + operator>>(basic_istream& is, + time_point& tp); + +template + basic_istream& + operator>>(basic_istream& is, + time_point& tp); + +template + basic_istream& + operator>>(basic_istream& is, + time_point& tp); + +template +class timepunct + : public std::locale::facet +{ +public: + typedef std::basic_string string_type; + + static std::locale::id id; + + explicit timepunct(std::size_t refs = 0, + const string_type& fmt = string_type(), + bool local = false); + + explicit timepunct(std::size_t refs, + string_type&& fmt, + bool local = false); + + const string_type& fmt() const {return fmt_;} + bool local() const {return local_;} +}; + +template + unspecfiied + local_fmt(std::basic_string fmt = std::basic_string()); + +template + unspecfiied + local_fmt(const CharT* fmt); + +template + unspecfiied + utc_fmt(std::basic_string fmt = std::basic_string()); + +template + unspecfiied + utc_fmt(const CharT* fmt); + +} // chrono +} // std + +*/ + +#include +#include "ratio_io" + +namespace std { + +namespace chrono +{ + +template +To +round(const duration& d) +{ + To t0 = duration_cast(d); + To t1 = t0; + ++t1; + typedef typename common_type >::type _D; + _D diff0 = d - t0; + _D diff1 = t1 - d; + if (diff0 == diff1) + { + if (t0.count() & 1) + return t1; + return t0; + } + else if (diff0 < diff1) + return t0; + return t1; +} + +template +class durationpunct + : public locale::facet +{ +public: + typedef basic_string<_CharT> string_type; + enum {use_long, use_short}; + +private: + bool __use_short_; + string_type __seconds_; + string_type __minutes_; + string_type __hours_; +public: + static locale::id id; + + explicit durationpunct(size_t refs = 0, + int __use = use_long) + : locale::facet(refs), __use_short_(__use) {} + + durationpunct(size_t refs, int __use, + string_type __seconds, string_type __minutes, + string_type __hours) + : locale::facet(refs), __use_short_(__use), + __seconds_(std::move(__seconds)), + __minutes_(std::move(__minutes)), + __hours_(std::move(__hours)) {} + + bool is_short_name() const {return __use_short_;} + bool is_long_name() const {return !__use_short_;} + + string_type seconds() const {return __seconds_;} + string_type minutes() const {return __minutes_;} + string_type hours() const {return __hours_;} +}; + +template +locale::id +durationpunct<_CharT>::id; + +enum {prefix, symbol}; +enum {utc, local}; + +template +struct __duration_manip +{ + bool __use_short_; + basic_string<_CharT> __seconds_; + basic_string<_CharT> __minutes_; + basic_string<_CharT> __hours_; + + __duration_manip(bool __use_short, basic_string<_CharT> __seconds, + basic_string<_CharT> __minutes, basic_string<_CharT> __hours) + : __use_short_(__use_short), + __seconds_(std::move(__seconds)), + __minutes_(std::move(__minutes)), + __hours_(std::move(__hours)) {} +}; + +class duration_fmt +{ + int form_; +public: + explicit duration_fmt(int f) : form_(f) {} + // explicit + operator int() const {return form_;} +}; + +template +std::basic_ostream& +operator <<(std::basic_ostream& os, duration_fmt d) +{ + os.imbue(std::locale(os.getloc(), new durationpunct(0, d == symbol))); + return os; +} + +template +std::basic_istream& +operator >>(std::basic_istream& is, duration_fmt d) +{ + is.imbue(std::locale(is.getloc(), new durationpunct(0, d == symbol))); + return is; +} + +template +std::basic_ostream& +operator <<(std::basic_ostream& os, __duration_manip m) +{ + os.imbue(std::locale(os.getloc(), new durationpunct(0, m.__use_short_, + std::move(m.__seconds_), std::move(m.__minutes_), std::move(m.__hours_)))); + return os; +} + +template +std::basic_istream& +operator >>(std::basic_istream& is, __duration_manip m) +{ + is.imbue(std::locale(is.getloc(), new durationpunct(0, m.__use_short_, + std::move(m.__seconds_), std::move(m.__minutes_), std::move(m.__hours_)))); + return is; +} + +inline +__duration_manip +duration_short() +{ + return __duration_manip(durationpunct::use_short, "", "", ""); +} + +template +inline +__duration_manip<_CharT> +duration_short(basic_string<_CharT> __seconds, + basic_string<_CharT> __minutes, + basic_string<_CharT> __hours) +{ + return __duration_manip<_CharT>(durationpunct<_CharT>::use_short, + std::move(__seconds), std::move(__minutes), + std::move(__hours)); +} + +inline +__duration_manip +duration_long() +{ + return __duration_manip(durationpunct::use_long, "", "", ""); +} + +template +inline +typename enable_if +< + is_convertible<_T2, basic_string<_CharT> >::value && + is_convertible<_T3, basic_string<_CharT> >::value, + __duration_manip<_CharT> +>::type +duration_long(basic_string<_CharT> __seconds, + _T2 __minutes, + _T3 __hours) +{ + typedef basic_string<_CharT> string_type; + return __duration_manip<_CharT>(durationpunct<_CharT>::use_long, + std::move(__seconds), + string_type(std::move(__minutes)), + string_type(std::move(__hours))); +} + +template +inline +typename enable_if +< + is_convertible<_T2, basic_string<_CharT> >::value && + is_convertible<_T3, basic_string<_CharT> >::value, + __duration_manip<_CharT> +>::type +duration_long(const _CharT* __seconds, + _T2 __minutes, + _T3 __hours) +{ + typedef basic_string<_CharT> string_type; + return __duration_manip<_CharT>(durationpunct<_CharT>::use_long, + string_type(__seconds), + string_type(std::move(__minutes)), + string_type(std::move(__hours))); +} + +template +basic_string<_CharT> +__get_unit(bool __is_long, const basic_string<_CharT>& __seconds, + const basic_string<_CharT>&, const basic_string<_CharT>&, _Period) +{ + if (__is_long) + { + if (__seconds.empty()) + { + _CharT __p[] = {'s', 'e', 'c', 'o', 'n', 'd', 's', 0}; + return ratio_string<_Period, _CharT>::prefix() + __p; + } + return ratio_string<_Period, _CharT>::prefix() + __seconds; + } + if (__seconds.empty()) + return ratio_string<_Period, _CharT>::symbol() + 's'; + return ratio_string<_Period, _CharT>::symbol() + __seconds; +} + +template +inline +basic_string<_CharT> +__get_unit(bool __is_long, const basic_string<_CharT>& __seconds, + const basic_string<_CharT>&, const basic_string<_CharT>&, ratio<1>) +{ + if (__seconds.empty()) + { + if (__is_long) + { + _CharT __p[] = {'s', 'e', 'c', 'o', 'n', 'd', 's'}; + return basic_string<_CharT>(__p, __p + sizeof(__p) / sizeof(_CharT)); + } + else + return basic_string<_CharT>(1, 's'); + } + return __seconds; +} + +template +basic_string<_CharT> +__get_unit(bool __is_long, const basic_string<_CharT>&, + const basic_string<_CharT>& __minutes, + const basic_string<_CharT>&, ratio<60>) +{ + if (__minutes.empty()) + { + if (__is_long) + { + _CharT __p[] = {'m', 'i', 'n', 'u', 't', 'e', 's'}; + return basic_string<_CharT>(__p, __p + sizeof(__p) / sizeof(_CharT)); + } + else + return basic_string<_CharT>(1, 'm'); + } + return __minutes; +} + +template +inline +basic_string<_CharT> +__get_unit(bool __is_long, const basic_string<_CharT>&, + const basic_string<_CharT>&, + const basic_string<_CharT>& __hours, ratio<3600>) +{ + if (__hours.empty()) + { + if (__is_long) + { + _CharT __p[] = {'h', 'o', 'u', 'r', 's'}; + return basic_string<_CharT>(__p, __p + sizeof(__p) / sizeof(_CharT)); + } + else + return basic_string<_CharT>(1, 'h'); + } + return __hours; +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, const duration<_Rep, _Period>& __d) +{ + typename basic_ostream<_CharT, _Traits>::sentry ok(__os); + if (ok) + { + typedef durationpunct<_CharT> _F; + typedef basic_string<_CharT> string_type; + bool failed = false; + try + { + bool __is_long = true; + string_type __seconds; + string_type __minutes; + string_type __hours; + locale __loc = __os.getloc(); + if (has_facet<_F>(__loc)) + { + const _F& f = use_facet<_F>(__loc); + __is_long = f.is_long_name(); + __seconds = f.seconds(); + __minutes = f.minutes(); + __hours = f.hours(); + } + string_type __unit = __get_unit(__is_long, __seconds, __minutes, + __hours, typename _Period::type()); + __os << __d.count() << ' ' << __unit; + } + catch (...) + { + failed = true; + } + if (failed) + __os.setstate(ios_base::failbit | ios_base::badbit); + } + return __os; +} + +template ::value> +struct __duration_io_intermediate +{ + typedef _Rep type; +}; + +template +struct __duration_io_intermediate<_Rep, true> +{ + typedef typename conditional + < + is_floating_point<_Rep>::value, + long double, + typename conditional + < + is_signed<_Rep>::value, + long long, + unsigned long long + >::type + >::type type; +}; + +template +T +__gcd(T x, T y) +{ + while (y != 0) + { + T old_x = x; + x = y; + y = old_x % y; + } + return x; +} + +template <> +long double +inline +__gcd(long double x, long double y) +{ + (void)x; + (void)y; + return 1; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, duration<_Rep, _Period>& __d) +{ + typedef basic_string<_CharT> string_type; + typedef durationpunct<_CharT> _F; + typedef typename __duration_io_intermediate<_Rep>::type _IR; + _IR __r; + // read value into __r + __is >> __r; + if (__is.good()) + { + // now determine unit + typedef istreambuf_iterator<_CharT, _Traits> _I; + _I __i(__is); + _I __e; + if (__i != __e && *__i == ' ') // mandatory ' ' after value + { + ++__i; + if (__i != __e) + { + string_type __seconds; + string_type __minutes; + string_type __hours; + locale __loc = __is.getloc(); + if (has_facet<_F>(__loc)) + { + const _F& f = use_facet<_F>(__loc); + __seconds = f.seconds(); + __minutes = f.minutes(); + __hours = f.hours(); + } + // unit is num / den (yet to be determined) + unsigned long long num = 0; + unsigned long long den = 0; + if (*__i == '[') + { + // parse [N/D]s or [N/D]seconds format + ++__i; + _CharT __x; + __is >> num >> __x >> den; + if (!__is.good() || __x != '/') + { + __is.setstate(__is.failbit); + return __is; + } + __i = _I(__is); + if (*__i != ']') + { + __is.setstate(__is.failbit); + return __is; + } + ++__i; + const basic_string<_CharT> __units[] = + { + __get_unit(true, __seconds, __minutes, __hours, ratio<1>()), + __get_unit(false, __seconds, __minutes, __hours, ratio<1>()) + }; + ios_base::iostate __err = ios_base::goodbit; + const basic_string<_CharT>* __k = __scan_keyword(__i, __e, + __units, __units + sizeof(__units)/sizeof(__units[0]), + use_facet >(__loc), + __err); + switch ((__k - __units) / 2) + { + case 0: + break; + default: + __is.setstate(__err); + return __is; + } + } + else + { + // parse SI name, short or long + const basic_string<_CharT> __units[] = + { + __get_unit(true, __seconds, __minutes, __hours, atto()), + __get_unit(false, __seconds, __minutes, __hours, atto()), + __get_unit(true, __seconds, __minutes, __hours, femto()), + __get_unit(false, __seconds, __minutes, __hours, femto()), + __get_unit(true, __seconds, __minutes, __hours, pico()), + __get_unit(false, __seconds, __minutes, __hours, pico()), + __get_unit(true, __seconds, __minutes, __hours, nano()), + __get_unit(false, __seconds, __minutes, __hours, nano()), + __get_unit(true, __seconds, __minutes, __hours, micro()), + __get_unit(false, __seconds, __minutes, __hours, micro()), + __get_unit(true, __seconds, __minutes, __hours, milli()), + __get_unit(false, __seconds, __minutes, __hours, milli()), + __get_unit(true, __seconds, __minutes, __hours, centi()), + __get_unit(false, __seconds, __minutes, __hours, centi()), + __get_unit(true, __seconds, __minutes, __hours, deci()), + __get_unit(false, __seconds, __minutes, __hours, deci()), + __get_unit(true, __seconds, __minutes, __hours, deca()), + __get_unit(false, __seconds, __minutes, __hours, deca()), + __get_unit(true, __seconds, __minutes, __hours, hecto()), + __get_unit(false, __seconds, __minutes, __hours, hecto()), + __get_unit(true, __seconds, __minutes, __hours, kilo()), + __get_unit(false, __seconds, __minutes, __hours, kilo()), + __get_unit(true, __seconds, __minutes, __hours, mega()), + __get_unit(false, __seconds, __minutes, __hours, mega()), + __get_unit(true, __seconds, __minutes, __hours, giga()), + __get_unit(false, __seconds, __minutes, __hours, giga()), + __get_unit(true, __seconds, __minutes, __hours, tera()), + __get_unit(false, __seconds, __minutes, __hours, tera()), + __get_unit(true, __seconds, __minutes, __hours, peta()), + __get_unit(false, __seconds, __minutes, __hours, peta()), + __get_unit(true, __seconds, __minutes, __hours, exa()), + __get_unit(false, __seconds, __minutes, __hours, exa()), + __get_unit(true, __seconds, __minutes, __hours, ratio<1>()), + __get_unit(false, __seconds, __minutes, __hours, ratio<1>()), + __get_unit(true, __seconds, __minutes, __hours, ratio<60>()), + __get_unit(false, __seconds, __minutes, __hours, ratio<60>()), + __get_unit(true, __seconds, __minutes, __hours, ratio<3600>()), + __get_unit(false, __seconds, __minutes, __hours, ratio<3600>()) + }; + ios_base::iostate __err = ios_base::goodbit; + const basic_string<_CharT>* __k = __scan_keyword(__i, __e, + __units, __units + sizeof(__units)/sizeof(__units[0]), + use_facet >(__loc), + __err); + switch ((__k - __units) / 2) + { + case 0: + num = 1ULL; + den = 1000000000000000000ULL; + break; + case 1: + num = 1ULL; + den = 1000000000000000ULL; + break; + case 2: + num = 1ULL; + den = 1000000000000ULL; + break; + case 3: + num = 1ULL; + den = 1000000000ULL; + break; + case 4: + num = 1ULL; + den = 1000000ULL; + break; + case 5: + num = 1ULL; + den = 1000ULL; + break; + case 6: + num = 1ULL; + den = 100ULL; + break; + case 7: + num = 1ULL; + den = 10ULL; + break; + case 8: + num = 10ULL; + den = 1ULL; + break; + case 9: + num = 100ULL; + den = 1ULL; + break; + case 10: + num = 1000ULL; + den = 1ULL; + break; + case 11: + num = 1000000ULL; + den = 1ULL; + break; + case 12: + num = 1000000000ULL; + den = 1ULL; + break; + case 13: + num = 1000000000000ULL; + den = 1ULL; + break; + case 14: + num = 1000000000000000ULL; + den = 1ULL; + break; + case 15: + num = 1000000000000000000ULL; + den = 1ULL; + break; + case 16: + num = 1; + den = 1; + break; + case 17: + num = 60; + den = 1; + break; + case 18: + num = 3600; + den = 1; + break; + default: + __is.setstate(__err); + return __is; + } + } + // unit is num/den + // __r should be multiplied by (num/den) / _Period + // Reduce (num/den) / _Period to lowest terms + unsigned long long __gcd_n1_n2 = __gcd(num, _Period::num); + unsigned long long __gcd_d1_d2 = __gcd(den, _Period::den); + num /= __gcd_n1_n2; + den /= __gcd_d1_d2; + unsigned long long __n2 = _Period::num / __gcd_n1_n2; + unsigned long long __d2 = _Period::den / __gcd_d1_d2; + if (num > numeric_limits::max() / __d2 || + den > numeric_limits::max() / __n2) + { + // (num/den) / _Period overflows + __is.setstate(__is.failbit); + return __is; + } + num *= __d2; + den *= __n2; + // num / den is now factor to multiply by __r + typedef typename common_type<_IR, unsigned long long>::type _CT; + if (is_integral<_IR>::value) + { + // Reduce __r * num / den + _CT __t = __gcd<_CT>(__r, den); + __r /= __t; + den /= __t; + if (den != 1) + { + // Conversion to _Period is integral and not exact + __is.setstate(__is.failbit); + return __is; + } + } + if (__r > duration_values<_CT>::max() / num) + { + // Conversion to _Period overflowed + __is.setstate(__is.failbit); + return __is; + } + _CT __t = __r * num; + __t /= den; + if (duration_values<_Rep>::max() < __t) + { + // Conversion to _Period overflowed + __is.setstate(__is.failbit); + return __is; + } + // Success! Store it. + __r = _Rep(__t); + __d = duration<_Rep, _Period>(__r); + } + else + __is.setstate(__is.failbit | __is.eofbit); + } + else + { + if (__i == __e) + __is.setstate(__is.eofbit); + __is.setstate(__is.failbit); + } + } + else + __is.setstate(__is.failbit); + return __is; +} + +template +class timepunct + : public std::locale::facet +{ +public: + typedef std::basic_string string_type; + +private: + string_type fmt_; + bool local_; + +public: + static std::locale::id id; + + explicit timepunct(std::size_t refs = 0, + const string_type& fmt = string_type(), + bool local = false) + : std::locale::facet(refs), + fmt_(fmt), + local_(local) {} + + explicit timepunct(std::size_t refs, + string_type&& fmt, + bool local = false) + : std::locale::facet(refs), + fmt_(std::move(fmt)), + local_(local) {} + + const string_type& fmt() const {return fmt_;} + bool local() const {return local_;} +}; + +template +std::locale::id +timepunct::id; + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const time_point& __tp) +{ + return __os << __tp.time_since_epoch() << " since boot"; +} + +template +struct __time_manip +{ + std::basic_string fmt_; + bool local_; + + __time_manip(std::basic_string fmt, bool local) + : fmt_(std::move(fmt)), + local_(local) {} +}; + +template +std::basic_ostream& +operator <<(std::basic_ostream& os, __time_manip m) +{ + os.imbue(std::locale(os.getloc(), new timepunct(0, std::move(m.fmt_), m.local_))); + return os; +} + +template +std::basic_istream& +operator >>(std::basic_istream& is, __time_manip m) +{ + is.imbue(std::locale(is.getloc(), new timepunct(0, std::move(m.fmt_), m.local_))); + return is; +} + +template +inline +__time_manip +local_fmt(std::basic_string fmt) +{ + return __time_manip(std::move(fmt), true); +} + +template +inline +__time_manip +local_fmt(const charT* fmt) +{ + return __time_manip(fmt, true); +} + +inline +__time_manip +local_fmt() +{ + return __time_manip("", true); +} + +template +inline +__time_manip +utc_fmt(std::basic_string fmt) +{ + return __time_manip(std::move(fmt), false); +} + +template +inline +__time_manip +utc_fmt(const charT* fmt) +{ + return __time_manip(fmt, false); +} + +inline +__time_manip +utc_fmt() +{ + return __time_manip("", false); +} + +class __time_man +{ + int form_; +public: + explicit __time_man(int f) : form_(f) {} + // explicit + operator int() const {return form_;} +}; + +template +std::basic_ostream& +operator <<(std::basic_ostream& os, __time_man m) +{ + os.imbue(std::locale(os.getloc(), new timepunct(0, basic_string(), m == local))); + return os; +} + +template +std::basic_istream& +operator >>(std::basic_istream& is, __time_man m) +{ + is.imbue(std::locale(is.getloc(), new timepunct(0, basic_string(), m == local))); + return is; +} + + +inline +__time_man +time_fmt(int f) +{ + return __time_man(f); +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + time_point& __tp) +{ + _Duration __d; + __is >> __d; + if (__is.good()) + { + const _CharT __u[] = {' ', 's', 'i', 'n', 'c', 'e', ' ', 'b', 'o', 'o', 't'}; + const basic_string<_CharT> __units(__u, __u + sizeof(__u)/sizeof(__u[0])); + ios_base::iostate __err = ios_base::goodbit; + typedef istreambuf_iterator<_CharT, _Traits> _I; + _I __i(__is); + _I __e; + ptrdiff_t __k = __scan_keyword(__i, __e, + &__units, &__units + 1, + use_facet >(__is.getloc()), + __err) - &__units; + if (__k == 1) + { + // failed to read epoch string + __is.setstate(__err); + return __is; + } + __tp = time_point(__d); + } + else + __is.setstate(__is.failbit); + return __is; +} + +template +basic_ostream<_CharT, _Traits>& +operator<<(basic_ostream<_CharT, _Traits>& __os, + const time_point& __tp) +{ + typename basic_ostream<_CharT, _Traits>::sentry ok(__os); + if (ok) + { + bool failed = false; + try + { + const _CharT* pb = nullptr; + const _CharT* pe = pb; + bool __local = false; + typedef timepunct<_CharT> F; + locale loc = __os.getloc(); + if (has_facet(loc)) + { + const F& f = use_facet(loc); + pb = f.fmt().data(); + pe = pb + f.fmt().size(); + __local = f.local(); + } + time_t __t = system_clock::to_time_t(__tp); + tm __tm; + if (__local) + { + if (localtime_r(&__t, &__tm) == 0) + failed = true; + } + else + { + if (gmtime_r(&__t, &__tm) == 0) + failed = true; + } + if (!failed) + { + const time_put<_CharT>& tp = use_facet >(loc); + if (pb == pe) + { + _CharT pattern[] = {'%', 'F', ' ', '%', 'H', ':', '%', 'M', ':'}; + pb = pattern; + pe = pb + sizeof(pattern) / sizeof(_CharT); + failed = tp.put(__os, __os, __os.fill(), &__tm, pb, pe).failed(); + if (!failed) + { + duration __d = __tp - system_clock::from_time_t(__t) + + seconds(__tm.tm_sec); + if (__d.count() < 10) + __os << _CharT('0'); + ios::fmtflags __flgs = __os.flags(); + __os.setf(ios::fixed, ios::floatfield); + __os << __d.count(); + __os.flags(__flgs); + if (__local) + { + _CharT sub_pattern[] = {' ', '%', 'z'}; + pb = sub_pattern; + pe = pb + + sizeof(sub_pattern) / sizeof(_CharT); + failed = tp.put(__os, __os, __os.fill(), &__tm, pb, pe).failed(); + } + else + { + _CharT sub_pattern[] = {' ', '+', '0', '0', '0', '0', 0}; + __os << sub_pattern; + } + } + } + else + failed = tp.put(__os, __os, __os.fill(), &__tm, pb, pe).failed(); + } + } + catch (...) + { + failed = true; + } + if (failed) + __os.setstate(ios_base::failbit | ios_base::badbit); + } + return __os; +} + +template +basic_istream<_CharT, _Traits>& +operator>>(basic_istream<_CharT, _Traits>& __is, + time_point& __tp) +{ + typename basic_istream<_CharT,_Traits>::sentry ok(__is); + if (ok) + { + ios_base::iostate err = ios_base::goodbit; + try + { + const _CharT* pb = nullptr; + const _CharT* pe = pb; + bool __local = false; + typedef timepunct<_CharT> F; + locale loc = __is.getloc(); + if (has_facet(loc)) + { + const F& f = use_facet(loc); + pb = f.fmt().data(); + pe = pb + f.fmt().size(); + __local = f.local(); + } + const time_get<_CharT>& tg = use_facet >(loc); + tm __tm = {0}; + if (pb == pe) + { + _CharT pattern[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd', + ' ', '%', 'H', ':', '%', 'M', ':'}; + pb = pattern; + pe = pb + sizeof(pattern) / sizeof(_CharT); + tg.get(__is, 0, __is, err, &__tm, pb, pe); + if (err & ios_base::failbit) + goto __exit; + typedef istreambuf_iterator<_CharT, _Traits> _I; + double __sec; + _CharT __c = _CharT(); + __is >> __sec; + if (__is.fail()) + { + err |= ios_base::failbit; + goto __exit; + } + _I __i(__is); + _I __eof; + __c = *__i; + if (++__i == __eof || __c != ' ') + { + err |= ios_base::failbit; + goto __exit; + } + __c = *__i; + if (++__i == __eof || (__c != '+' && __c != '-')) + { + err |= ios_base::failbit; + goto __exit; + } + int __n = __c == '-' ? 1 : -1; + __c = *__i; + if (++__i == __eof || !isdigit(__c)) + { + err |= ios_base::failbit; + goto __exit; + } + int __min = (__c - '0') * 600; + __c = *__i; + if (++__i == __eof || !isdigit(__c)) + { + err |= ios_base::failbit; + goto __exit; + } + __min += (__c - '0') * 60; + __c = *__i; + if (++__i == __eof || !isdigit(__c)) + { + err |= ios_base::failbit; + goto __exit; + } + __min += (__c - '0') * 10; + __c = *__i; + if (!isdigit(__c)) + { + err |= ios_base::failbit; + goto __exit; + } + ++__i; + __min += __c - '0'; + __min *= __n; + time_t __t; + __t = timegm(&__tm); + __tp = system_clock::from_time_t(__t) + minutes(__min) + + round(duration(__sec)); + } + else + { + tg.get(__is, 0, __is, err, &__tm, pb, pe); + } + } + catch (...) + { + err |= ios_base::badbit | ios_base::failbit; + } + __exit: + __is.setstate(err); + } + return __is; +} + +} // chrono + +} + +#endif // _CHRONO_IO diff --git a/chrono_io/ratio_io b/chrono_io/ratio_io new file mode 100644 index 000000000..ade52376c --- /dev/null +++ b/chrono_io/ratio_io @@ -0,0 +1,601 @@ +// ratio_io +// +// (C) Copyright Howard Hinnant +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). + +#ifndef _RATIO_IO +#define _RATIO_IO + +/* + + ratio_io synopsis + +#include +#include + +namespace std +{ + +template +struct ratio_string +{ + static basic_string symbol(); + static basic_string prefix(); +}; + +} // std + +*/ + +#include +#include +#include + +namespace std { + +template +struct ratio_string +{ + static basic_string<_CharT> symbol() {return prefix();} + static basic_string<_CharT> prefix(); +}; + +template +basic_string<_CharT> +ratio_string<_Ratio, _CharT>::prefix() +{ + basic_ostringstream<_CharT> __os; + __os << _CharT('[') << _Ratio::num << _CharT('/') + << _Ratio::den << _CharT(']'); + return __os.str(); +} + +// atto + +template <> +struct ratio_string +{ + static string symbol() {return string(1, 'a');} + static string prefix() {return string("atto");} +}; + +#if HAS_UNICODE_SUPPORT + +template <> +struct ratio_string +{ + static u16string symbol() {return u16string(1, u'a');} + static u16string prefix() {return u16string(u"atto");} +}; + +template <> +struct ratio_string +{ + static u32string symbol() {return u32string(1, U'a');} + static u32string prefix() {return u32string(U"atto");} +}; + +#endif + +template <> +struct ratio_string +{ + static wstring symbol() {return wstring(1, L'a');} + static wstring prefix() {return wstring(L"atto");} +}; + +// femto + +template <> +struct ratio_string +{ + static string symbol() {return string(1, 'f');} + static string prefix() {return string("femto");} +}; + +#if HAS_UNICODE_SUPPORT + +template <> +struct ratio_string +{ + static u16string symbol() {return u16string(1, u'f');} + static u16string prefix() {return u16string(u"femto");} +}; + +template <> +struct ratio_string +{ + static u32string symbol() {return u32string(1, U'f');} + static u32string prefix() {return u32string(U"femto");} +}; + +#endif + +template <> +struct ratio_string +{ + static wstring symbol() {return wstring(1, L'f');} + static wstring prefix() {return wstring(L"femto");} +}; + +// pico + +template <> +struct ratio_string +{ + static string symbol() {return string(1, 'p');} + static string prefix() {return string("pico");} +}; + +#if HAS_UNICODE_SUPPORT + +template <> +struct ratio_string +{ + static u16string symbol() {return u16string(1, u'p');} + static u16string prefix() {return u16string(u"pico");} +}; + +template <> +struct ratio_string +{ + static u32string symbol() {return u32string(1, U'p');} + static u32string prefix() {return u32string(U"pico");} +}; + +#endif + +template <> +struct ratio_string +{ + static wstring symbol() {return wstring(1, L'p');} + static wstring prefix() {return wstring(L"pico");} +}; + +// nano + +template <> +struct ratio_string +{ + static string symbol() {return string(1, 'n');} + static string prefix() {return string("nano");} +}; + +#if HAS_UNICODE_SUPPORT + +template <> +struct ratio_string +{ + static u16string symbol() {return u16string(1, u'n');} + static u16string prefix() {return u16string(u"nano");} +}; + +template <> +struct ratio_string +{ + static u32string symbol() {return u32string(1, U'n');} + static u32string prefix() {return u32string(U"nano");} +}; + +#endif + +template <> +struct ratio_string +{ + static wstring symbol() {return wstring(1, L'n');} + static wstring prefix() {return wstring(L"nano");} +}; + +// micro + +template <> +struct ratio_string +{ + static string symbol() {return string("\xC2\xB5");} + static string prefix() {return string("micro");} +}; + +#if HAS_UNICODE_SUPPORT + +template <> +struct ratio_string +{ + static u16string symbol() {return u16string(1, u'\xB5');} + static u16string prefix() {return u16string(u"micro");} +}; + +template <> +struct ratio_string +{ + static u32string symbol() {return u32string(1, U'\xB5');} + static u32string prefix() {return u32string(U"micro");} +}; + +#endif + +template <> +struct ratio_string +{ + static wstring symbol() {return wstring(1, L'\xB5');} + static wstring prefix() {return wstring(L"micro");} +}; + +// milli + +template <> +struct ratio_string +{ + static string symbol() {return string(1, 'm');} + static string prefix() {return string("milli");} +}; + +#if HAS_UNICODE_SUPPORT + +template <> +struct ratio_string +{ + static u16string symbol() {return u16string(1, u'm');} + static u16string prefix() {return u16string(u"milli");} +}; + +template <> +struct ratio_string +{ + static u32string symbol() {return u32string(1, U'm');} + static u32string prefix() {return u32string(U"milli");} +}; + +#endif + +template <> +struct ratio_string +{ + static wstring symbol() {return wstring(1, L'm');} + static wstring prefix() {return wstring(L"milli");} +}; + +// centi + +template <> +struct ratio_string +{ + static string symbol() {return string(1, 'c');} + static string prefix() {return string("centi");} +}; + +#if HAS_UNICODE_SUPPORT + +template <> +struct ratio_string +{ + static u16string symbol() {return u16string(1, u'c');} + static u16string prefix() {return u16string(u"centi");} +}; + +template <> +struct ratio_string +{ + static u32string symbol() {return u32string(1, U'c');} + static u32string prefix() {return u32string(U"centi");} +}; + +#endif + +template <> +struct ratio_string +{ + static wstring symbol() {return wstring(1, L'c');} + static wstring prefix() {return wstring(L"centi");} +}; + +// deci + +template <> +struct ratio_string +{ + static string symbol() {return string(1, 'd');} + static string prefix() {return string("deci");} +}; + +#if HAS_UNICODE_SUPPORT + +template <> +struct ratio_string +{ + static u16string symbol() {return u16string(1, u'd');} + static u16string prefix() {return u16string(u"deci");} +}; + +template <> +struct ratio_string +{ + static u32string symbol() {return u32string(1, U'd');} + static u32string prefix() {return u32string(U"deci");} +}; + +#endif + +template <> +struct ratio_string +{ + static wstring symbol() {return wstring(1, L'd');} + static wstring prefix() {return wstring(L"deci");} +}; + +// deca + +template <> +struct ratio_string +{ + static string symbol() {return string("da");} + static string prefix() {return string("deca");} +}; + +#if HAS_UNICODE_SUPPORT + +template <> +struct ratio_string +{ + static u16string symbol() {return u16string(u"da");} + static u16string prefix() {return u16string(u"deca");} +}; + +template <> +struct ratio_string +{ + static u32string symbol() {return u32string(U"da");} + static u32string prefix() {return u32string(U"deca");} +}; + +#endif + +template <> +struct ratio_string +{ + static wstring symbol() {return wstring(L"da");} + static wstring prefix() {return wstring(L"deca");} +}; + +// hecto + +template <> +struct ratio_string +{ + static string symbol() {return string(1, 'h');} + static string prefix() {return string("hecto");} +}; + +#if HAS_UNICODE_SUPPORT + +template <> +struct ratio_string +{ + static u16string symbol() {return u16string(1, u'h');} + static u16string prefix() {return u16string(u"hecto");} +}; + +template <> +struct ratio_string +{ + static u32string symbol() {return u32string(1, U'h');} + static u32string prefix() {return u32string(U"hecto");} +}; + +#endif + +template <> +struct ratio_string +{ + static wstring symbol() {return wstring(1, L'h');} + static wstring prefix() {return wstring(L"hecto");} +}; + +// kilo + +template <> +struct ratio_string +{ + static string symbol() {return string(1, 'k');} + static string prefix() {return string("kilo");} +}; + +#if HAS_UNICODE_SUPPORT + +template <> +struct ratio_string +{ + static u16string symbol() {return u16string(1, u'k');} + static u16string prefix() {return u16string(u"kilo");} +}; + +template <> +struct ratio_string +{ + static u32string symbol() {return u32string(1, U'k');} + static u32string prefix() {return u32string(U"kilo");} +}; + +#endif + +template <> +struct ratio_string +{ + static wstring symbol() {return wstring(1, L'k');} + static wstring prefix() {return wstring(L"kilo");} +}; + +// mega + +template <> +struct ratio_string +{ + static string symbol() {return string(1, 'M');} + static string prefix() {return string("mega");} +}; + +#if HAS_UNICODE_SUPPORT + +template <> +struct ratio_string +{ + static u16string symbol() {return u16string(1, u'M');} + static u16string prefix() {return u16string(u"mega");} +}; + +template <> +struct ratio_string +{ + static u32string symbol() {return u32string(1, U'M');} + static u32string prefix() {return u32string(U"mega");} +}; + +#endif + +template <> +struct ratio_string +{ + static wstring symbol() {return wstring(1, L'M');} + static wstring prefix() {return wstring(L"mega");} +}; + +// giga + +template <> +struct ratio_string +{ + static string symbol() {return string(1, 'G');} + static string prefix() {return string("giga");} +}; + +#if HAS_UNICODE_SUPPORT + +template <> +struct ratio_string +{ + static u16string symbol() {return u16string(1, u'G');} + static u16string prefix() {return u16string(u"giga");} +}; + +template <> +struct ratio_string +{ + static u32string symbol() {return u32string(1, U'G');} + static u32string prefix() {return u32string(U"giga");} +}; + +#endif + +template <> +struct ratio_string +{ + static wstring symbol() {return wstring(1, L'G');} + static wstring prefix() {return wstring(L"giga");} +}; + +// tera + +template <> +struct ratio_string +{ + static string symbol() {return string(1, 'T');} + static string prefix() {return string("tera");} +}; + +#if HAS_UNICODE_SUPPORT + +template <> +struct ratio_string +{ + static u16string symbol() {return u16string(1, u'T');} + static u16string prefix() {return u16string(u"tera");} +}; + +template <> +struct ratio_string +{ + static u32string symbol() {return u32string(1, U'T');} + static u32string prefix() {return u32string(U"tera");} +}; + +#endif + +template <> +struct ratio_string +{ + static wstring symbol() {return wstring(1, L'T');} + static wstring prefix() {return wstring(L"tera");} +}; + +// peta + +template <> +struct ratio_string +{ + static string symbol() {return string(1, 'P');} + static string prefix() {return string("peta");} +}; + +#if HAS_UNICODE_SUPPORT + +template <> +struct ratio_string +{ + static u16string symbol() {return u16string(1, u'P');} + static u16string prefix() {return u16string(u"peta");} +}; + +template <> +struct ratio_string +{ + static u32string symbol() {return u32string(1, U'P');} + static u32string prefix() {return u32string(U"peta");} +}; + +#endif + +template <> +struct ratio_string +{ + static wstring symbol() {return wstring(1, L'P');} + static wstring prefix() {return wstring(L"peta");} +}; + +// exa + +template <> +struct ratio_string +{ + static string symbol() {return string(1, 'E');} + static string prefix() {return string("exa");} +}; + +#if HAS_UNICODE_SUPPORT + +template <> +struct ratio_string +{ + static u16string symbol() {return u16string(1, u'E');} + static u16string prefix() {return u16string(u"exa");} +}; + +template <> +struct ratio_string +{ + static u32string symbol() {return u32string(1, U'E');} + static u32string prefix() {return u32string(U"exa");} +}; + +#endif + +template <> +struct ratio_string +{ + static wstring symbol() {return wstring(1, L'E');} + static wstring prefix() {return wstring(L"exa");} +}; + +} + +#endif // _RATIO_IO diff --git a/libdevcore/CommonIO.h b/libdevcore/CommonIO.h index 03fc9cffc..314600e43 100644 --- a/libdevcore/CommonIO.h +++ b/libdevcore/CommonIO.h @@ -35,6 +35,7 @@ #include #include #include +#include #include "Common.h" #include "Base64.h"