mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-13 15:41:50 -05:00
ecaa982b9f
git-svn-id: svn+ssh://svn.code.sf.net/p/wsjt/wsjt/branches/wsjtx@7593 ab8295b8-cf94-4d9e-aec4-7959e3be5d79
638 lines
24 KiB
C++
638 lines
24 KiB
C++
|
|
// 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
|