diff options
Diffstat (limited to 'src/third_party/boost-1.60.0/boost/chrono/io_v1/chrono_io.hpp')
-rw-r--r-- | src/third_party/boost-1.60.0/boost/chrono/io_v1/chrono_io.hpp | 637 |
1 files changed, 637 insertions, 0 deletions
diff --git a/src/third_party/boost-1.60.0/boost/chrono/io_v1/chrono_io.hpp b/src/third_party/boost-1.60.0/boost/chrono/io_v1/chrono_io.hpp new file mode 100644 index 00000000000..12d9f5436f0 --- /dev/null +++ b/src/third_party/boost-1.60.0/boost/chrono/io_v1/chrono_io.hpp @@ -0,0 +1,637 @@ + +// chrono_io +// +// (C) Copyright Howard Hinnant +// (C) Copyright 2010 Vicente J. Botet Escriba +// 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). +// +// This code was adapted by Vicente from Howard Hinnant's experimental work +// on chrono i/o under lvm/libc++ to Boost + +#ifndef BOOST_CHRONO_IO_V1_CHRONO_IO_HPP +#define BOOST_CHRONO_IO_V1_CHRONO_IO_HPP + +#include <boost/chrono/chrono.hpp> +#include <boost/chrono/process_cpu_clocks.hpp> +#include <boost/chrono/thread_clock.hpp> +#include <boost/chrono/clock_string.hpp> +#include <boost/ratio/ratio_io.hpp> +#include <locale> +#include <boost/type_traits/is_scalar.hpp> +#include <boost/type_traits/is_signed.hpp> +#include <boost/mpl/if.hpp> +#include <boost/integer/common_factor_rt.hpp> +#include <boost/chrono/detail/scan_keyword.hpp> +#include <boost/utility/enable_if.hpp> +#include <boost/chrono/detail/no_warning/signed_unsigned_cmp.hpp> + +namespace boost +{ + +namespace chrono +{ + +template <class CharT> +class duration_punct + : public std::locale::facet +{ +public: + typedef std::basic_string<CharT> string_type; + enum {use_long, use_short}; + +private: + bool use_short_; + string_type long_seconds_; + string_type long_minutes_; + string_type long_hours_; + string_type short_seconds_; + string_type short_minutes_; + string_type short_hours_; + + template <class Period> + string_type short_name(Period) const + {return ::boost::ratio_string<Period, CharT>::short_name() + short_seconds_;} + + string_type short_name(ratio<1>) const {return short_seconds_;} + string_type short_name(ratio<60>) const {return short_minutes_;} + string_type short_name(ratio<3600>) const {return short_hours_;} + + template <class Period> + string_type long_name(Period) const + {return ::boost::ratio_string<Period, CharT>::long_name() + long_seconds_;} + + string_type long_name(ratio<1>) const {return long_seconds_;} + string_type long_name(ratio<60>) const {return long_minutes_;} + string_type long_name(ratio<3600>) const {return long_hours_;} + + void init_C(); +public: + static std::locale::id id; + + explicit duration_punct(int use = use_long) + : use_short_(use==use_short) {init_C();} + + duration_punct(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); + + duration_punct(int use, const duration_punct& d); + + template <class Period> + string_type short_name() const + {return short_name(typename Period::type());} + + template <class Period> + string_type long_name() const + {return long_name(typename Period::type());} + + template <class Period> + string_type plural() const + {return long_name(typename Period::type());} + + template <class Period> + string_type singular() const + { + return string_type(long_name(typename Period::type()), 0, long_name(typename Period::type()).size()-1); + } + + template <class Period> + string_type name() const + { + if (use_short_) return short_name<Period>(); + else { + return long_name<Period>(); + } + } + template <class Period, class D> + string_type name(D v) const + { + if (use_short_) return short_name<Period>(); + else + { + if (v==-1 || v==1) + return singular<Period>(); + else + return plural<Period>(); + } + } + + bool is_short_name() const {return use_short_;} + bool is_long_name() const {return !use_short_;} +}; + +template <class CharT> +std::locale::id +duration_punct<CharT>::id; + +template <class CharT> +void +duration_punct<CharT>::init_C() +{ + short_seconds_ = CharT('s'); + short_minutes_ = CharT('m'); + short_hours_ = CharT('h'); + const CharT s[] = {'s', 'e', 'c', 'o', 'n', 'd', 's'}; + const CharT m[] = {'m', 'i', 'n', 'u', 't', 'e', 's'}; + const CharT h[] = {'h', 'o', 'u', 'r', 's'}; + long_seconds_.assign(s, s + sizeof(s)/sizeof(s[0])); + long_minutes_.assign(m, m + sizeof(m)/sizeof(m[0])); + long_hours_.assign(h, h + sizeof(h)/sizeof(h[0])); +} + +template <class CharT> +duration_punct<CharT>::duration_punct(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) + : use_short_(use==use_short), + long_seconds_(long_seconds), + long_minutes_(long_minutes), + long_hours_(long_hours), + short_seconds_(short_seconds), + short_minutes_(short_minutes), + short_hours_(short_hours) +{} + +template <class CharT> +duration_punct<CharT>::duration_punct(int use, const duration_punct& d) + : use_short_(use==use_short), + long_seconds_(d.long_seconds_), + long_minutes_(d.long_minutes_), + long_hours_(d.long_hours_), + short_seconds_(d.short_seconds_), + short_minutes_(d.short_minutes_), + short_hours_(d.short_hours_) +{} + +template <class CharT, class Traits> +std::basic_ostream<CharT, Traits>& +duration_short(std::basic_ostream<CharT, Traits>& os) +{ + typedef duration_punct<CharT> Facet; + std::locale loc = os.getloc(); + if (std::has_facet<Facet>(loc)) + { + const Facet& f = std::use_facet<Facet>(loc); + if (f.is_long_name()) + os.imbue(std::locale(loc, new Facet(Facet::use_short, f))); + } + else + os.imbue(std::locale(loc, new Facet(Facet::use_short))); + return os; +} + +template <class CharT, class Traits> +std::basic_ostream<CharT, Traits>& +duration_long(std::basic_ostream<CharT, Traits>& os) +{ + typedef duration_punct<CharT> Facet; + std::locale loc = os.getloc(); + if (std::has_facet<Facet>(loc)) + { + const Facet& f = std::use_facet<Facet>(loc); + if (f.is_short_name()) + os.imbue(std::locale(loc, new Facet(Facet::use_long, f))); + } + return os; +} + +template <class CharT, class Traits, class Rep, class Period> +std::basic_ostream<CharT, Traits>& +operator<<(std::basic_ostream<CharT, Traits>& os, const duration<Rep, Period>& d) +{ + typedef duration_punct<CharT> Facet; + std::locale loc = os.getloc(); + if (!std::has_facet<Facet>(loc)) + os.imbue(std::locale(loc, new Facet)); + const Facet& f = std::use_facet<Facet>(os.getloc()); + return os << d.count() << ' ' << f.template name<Period>(d.count()); +} + +namespace chrono_detail { +template <class Rep, bool = is_scalar<Rep>::value> +struct duration_io_intermediate +{ + typedef Rep type; +}; + +template <class Rep> +struct duration_io_intermediate<Rep, true> +{ + typedef typename mpl::if_c + < + is_floating_point<Rep>::value, + long double, + typename mpl::if_c + < + is_signed<Rep>::value, + long long, + unsigned long long + >::type + >::type type; +}; + +template <typename intermediate_type> +typename enable_if<is_integral<intermediate_type>, bool>::type +reduce(intermediate_type& r, unsigned long long& den, std::ios_base::iostate& err) +{ + typedef typename common_type<intermediate_type, unsigned long long>::type common_type_t; + + // Reduce r * num / den + common_type_t t = integer::gcd<common_type_t>(common_type_t(r), common_type_t(den)); + r /= t; + den /= t; + if (den != 1) + { + // Conversion to Period is integral and not exact + err |= std::ios_base::failbit; + return false; + } + return true; +} +template <typename intermediate_type> +typename disable_if<is_integral<intermediate_type>, bool>::type +reduce(intermediate_type& , unsigned long long& , std::ios_base::iostate& ) +{ + return true; +} + +} + +template <class CharT, class Traits, class Rep, class Period> +std::basic_istream<CharT, Traits>& +operator>>(std::basic_istream<CharT, Traits>& is, duration<Rep, Period>& d) +{ + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + typedef duration_punct<CharT> Facet; + std::locale loc = is.getloc(); + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + if (!std::has_facet<Facet>(loc)) { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.imbue(std::locale(loc, new Facet)); + } + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + loc = is.getloc(); + const Facet& f = std::use_facet<Facet>(loc); + typedef typename chrono_detail::duration_io_intermediate<Rep>::type intermediate_type; + intermediate_type r; + std::ios_base::iostate err = std::ios_base::goodbit; + // read value into r + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is >> r; + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + if (is.good()) + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // now determine unit + typedef std::istreambuf_iterator<CharT, Traits> in_iterator; + in_iterator i(is); + in_iterator e; + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + if (i != e && *i == ' ') // mandatory ' ' after value + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + ++i; + if (i != e) + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // unit is num / den (yet to be determined) + unsigned long long num = 0; + unsigned long long den = 0; + if (*i == '[') + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // parse [N/D]s or [N/D]seconds format + ++i; + CharT x; + is >> num >> x >> den; + if (!is.good() || (x != '/')) + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(is.failbit); + return is; + } + i = in_iterator(is); + if (*i != ']') + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(is.failbit); + return is; + } + ++i; + const std::basic_string<CharT> units[] = + { + f.template singular<ratio<1> >(), + f.template plural<ratio<1> >(), + f.template short_name<ratio<1> >() + }; + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + const std::basic_string<CharT>* k = chrono_detail::scan_keyword(i, e, + units, units + sizeof(units)/sizeof(units[0]), + //~ std::use_facet<std::ctype<CharT> >(loc), + err); + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(err); + switch ((k - units) / 3) + { + case 0: + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + break; + default: + is.setstate(err); + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + return is; + } + } + else + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // parse SI name, short or long + const std::basic_string<CharT> units[] = + { + f.template singular<atto>(), + f.template plural<atto>(), + f.template short_name<atto>(), + f.template singular<femto>(), + f.template plural<femto>(), + f.template short_name<femto>(), + f.template singular<pico>(), + f.template plural<pico>(), + f.template short_name<pico>(), + f.template singular<nano>(), + f.template plural<nano>(), + f.template short_name<nano>(), + f.template singular<micro>(), + f.template plural<micro>(), + f.template short_name<micro>(), + f.template singular<milli>(), + f.template plural<milli>(), + f.template short_name<milli>(), + f.template singular<centi>(), + f.template plural<centi>(), + f.template short_name<centi>(), + f.template singular<deci>(), + f.template plural<deci>(), + f.template short_name<deci>(), + f.template singular<deca>(), + f.template plural<deca>(), + f.template short_name<deca>(), + f.template singular<hecto>(), + f.template plural<hecto>(), + f.template short_name<hecto>(), + f.template singular<kilo>(), + f.template plural<kilo>(), + f.template short_name<kilo>(), + f.template singular<mega>(), + f.template plural<mega>(), + f.template short_name<mega>(), + f.template singular<giga>(), + f.template plural<giga>(), + f.template short_name<giga>(), + f.template singular<tera>(), + f.template plural<tera>(), + f.template short_name<tera>(), + f.template singular<peta>(), + f.template plural<peta>(), + f.template short_name<peta>(), + f.template singular<exa>(), + f.template plural<exa>(), + f.template short_name<exa>(), + f.template singular<ratio<1> >(), + f.template plural<ratio<1> >(), + f.template short_name<ratio<1> >(), + f.template singular<ratio<60> >(), + f.template plural<ratio<60> >(), + f.template short_name<ratio<60> >(), + f.template singular<ratio<3600> >(), + f.template plural<ratio<3600> >(), + f.template short_name<ratio<3600> >() + }; + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + const std::basic_string<CharT>* k = chrono_detail::scan_keyword(i, e, + units, units + sizeof(units)/sizeof(units[0]), + //~ std::use_facet<std::ctype<CharT> >(loc), + err); + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + switch ((k - units) / 3) + { + 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: + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(err|is.failbit); + return is; + } + } + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // 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 = integer::gcd<unsigned long long>(num, Period::num); + unsigned long long gcd_d1_d2 = integer::gcd<unsigned long long>(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 > (std::numeric_limits<unsigned long long>::max)() / d2 || + den > (std::numeric_limits<unsigned long long>::max)() / n2) + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // (num/den) / Period overflows + is.setstate(err|is.failbit); + return is; + } + num *= d2; + den *= n2; + + typedef typename common_type<intermediate_type, unsigned long long>::type common_type_t; + + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // num / den is now factor to multiply by r + if (!chrono_detail::reduce(r, den, err)) + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(err|is.failbit); + return is; + } + + //if (r > ((duration_values<common_type_t>::max)() / num)) + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + if (chrono::detail::gt(r,((duration_values<common_type_t>::max)() / num))) + { + // Conversion to Period overflowed + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(err|is.failbit); + return is; + } + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + common_type_t t = r * num; + t /= den; + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + + if (t > duration_values<common_type_t>::zero()) + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + Rep pt = t; + if ( (duration_values<Rep>::max)() < pt) + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // Conversion to Period overflowed + is.setstate(err|is.failbit); + return is; + } + } + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + // Success! Store it. + r = Rep(t); + d = duration<Rep, Period>(r); + is.setstate(err); + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + return is; + } + else { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + is.setstate(is.failbit | is.eofbit); + return is; + } + } + else + { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + if (i == e) + is.setstate(is.failbit|is.eofbit); + else + is.setstate(is.failbit); + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + return is; + } + } + else { + //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl; + //is.setstate(is.failbit); + return is; + } +} + + +template <class CharT, class Traits, class Clock, class Duration> +std::basic_ostream<CharT, Traits>& +operator<<(std::basic_ostream<CharT, Traits>& os, + const time_point<Clock, Duration>& tp) +{ + return os << tp.time_since_epoch() << clock_string<Clock, CharT>::since(); +} + +template <class CharT, class Traits, class Clock, class Duration> +std::basic_istream<CharT, Traits>& +operator>>(std::basic_istream<CharT, Traits>& is, + time_point<Clock, Duration>& tp) +{ + Duration d; + is >> d; + if (is.good()) + { + const std::basic_string<CharT> units=clock_string<Clock, CharT>::since(); + std::ios_base::iostate err = std::ios_base::goodbit; + typedef std::istreambuf_iterator<CharT, Traits> in_iterator; + in_iterator i(is); + in_iterator e; + std::ptrdiff_t k = chrono_detail::scan_keyword(i, e, + &units, &units + 1, + //~ std::use_facet<std::ctype<CharT> >(is.getloc()), + err) - &units; + is.setstate(err); + if (k == 1) + { + is.setstate(err | is.failbit); + // failed to read epoch string + return is; + } + tp = time_point<Clock, Duration>(d); + } + else + is.setstate(is.failbit); + return is; +} +} // chrono + +} + +#endif // BOOST_CHRONO_CHRONO_IO_HPP |