Chris@16: // (C) Copyright Howard Hinnant Chris@16: // (C) Copyright 2010-2011 Vicente J. Botet Escriba Chris@16: // Use, modification and distribution are subject to the Boost Software License, Chris@16: // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt). Chris@16: Chris@16: //===-------------------------- locale ------------------------------------===// Chris@16: // Chris@16: // The LLVM Compiler Infrastructure Chris@16: // Chris@16: // This file is dual licensed under the MIT and the University of Illinois Open Chris@16: // Source Licenses. See LICENSE.TXT for details. Chris@16: // Chris@16: //===----------------------------------------------------------------------===// Chris@16: Chris@16: // This code was adapted by Vicente from Howard Hinnant's experimental work Chris@16: // on chrono i/o to Boost and some functions from libc++/locale to emulate the missing time_get::get() Chris@16: Chris@16: #ifndef BOOST_CHRONO_IO_TIME_POINT_IO_HPP Chris@16: #define BOOST_CHRONO_IO_TIME_POINT_IO_HPP Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #define BOOST_CHRONO_INTERNAL_TIMEGM \ Chris@16: ( defined BOOST_WINDOWS && ! defined(__CYGWIN__) ) \ Chris@101: || (defined(sun) || defined(__sun)) \ Chris@101: || (defined __IBMCPP__) \ Chris@101: || defined __ANDROID__ \ Chris@101: || defined __QNXNTO__ \ Chris@101: || (defined(_AIX) && defined __GNUC__) Chris@16: Chris@16: #define BOOST_CHRONO_INTERNAL_GMTIME \ Chris@16: (defined BOOST_WINDOWS && ! defined(__CYGWIN__)) \ Chris@16: || ( (defined(sun) || defined(__sun)) && defined __GNUC__) \ Chris@101: || (defined __IBMCPP__) \ Chris@101: || defined __ANDROID__ \ Chris@101: || (defined(_AIX) && defined __GNUC__) Chris@16: Chris@16: #define BOOST_CHRONO_USES_INTERNAL_TIME_GET Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace chrono Chris@16: { Chris@16: typedef double fractional_seconds; Chris@16: namespace detail Chris@16: { Chris@16: Chris@16: Chris@16: template > Chris@16: struct time_get Chris@16: { Chris@16: std::time_get const &that_; Chris@16: time_get(std::time_get const& that) : that_(that) {} Chris@16: Chris@16: typedef std::time_get facet; Chris@16: typedef typename facet::iter_type iter_type; Chris@16: typedef typename facet::char_type char_type; Chris@16: typedef std::basic_string string_type; Chris@16: Chris@16: static int Chris@16: get_up_to_n_digits( Chris@16: InputIterator& b, InputIterator e, Chris@16: std::ios_base::iostate& err, Chris@16: const std::ctype& ct, Chris@16: int n) Chris@16: { Chris@16: // Precondition: n >= 1 Chris@16: if (b == e) Chris@16: { Chris@16: err |= std::ios_base::eofbit | std::ios_base::failbit; Chris@16: return 0; Chris@16: } Chris@16: // get first digit Chris@16: CharT c = *b; Chris@16: if (!ct.is(std::ctype_base::digit, c)) Chris@16: { Chris@16: err |= std::ios_base::failbit; Chris@16: return 0; Chris@16: } Chris@16: int r = ct.narrow(c, 0) - '0'; Chris@16: for (++b, --n; b != e && n > 0; ++b, --n) Chris@16: { Chris@16: // get next digit Chris@16: c = *b; Chris@16: if (!ct.is(std::ctype_base::digit, c)) Chris@16: return r; Chris@16: r = r * 10 + ct.narrow(c, 0) - '0'; Chris@16: } Chris@16: if (b == e) Chris@16: err |= std::ios_base::eofbit; Chris@16: return r; Chris@16: } Chris@16: Chris@16: Chris@16: void get_day( Chris@16: int& d, Chris@16: iter_type& b, iter_type e, Chris@16: std::ios_base::iostate& err, Chris@16: const std::ctype& ct) const Chris@16: { Chris@16: int t = get_up_to_n_digits(b, e, err, ct, 2); Chris@16: if (!(err & std::ios_base::failbit) && 1 <= t && t <= 31) Chris@16: d = t; Chris@16: else Chris@16: err |= std::ios_base::failbit; Chris@16: } Chris@16: Chris@16: void get_month( Chris@16: int& m, Chris@16: iter_type& b, iter_type e, Chris@16: std::ios_base::iostate& err, Chris@16: const std::ctype& ct) const Chris@16: { Chris@16: int t = get_up_to_n_digits(b, e, err, ct, 2) - 1; Chris@16: if (!(err & std::ios_base::failbit) && t <= 11) Chris@16: m = t; Chris@16: else Chris@16: err |= std::ios_base::failbit; Chris@16: } Chris@16: Chris@16: Chris@16: void get_year4(int& y, Chris@16: iter_type& b, iter_type e, Chris@16: std::ios_base::iostate& err, Chris@16: const std::ctype& ct) const Chris@16: { Chris@16: int t = get_up_to_n_digits(b, e, err, ct, 4); Chris@16: if (!(err & std::ios_base::failbit)) Chris@16: y = t - 1900; Chris@16: } Chris@16: Chris@16: void Chris@16: get_hour(int& h, Chris@16: iter_type& b, iter_type e, Chris@16: std::ios_base::iostate& err, Chris@16: const std::ctype& ct) const Chris@16: { Chris@16: int t = get_up_to_n_digits(b, e, err, ct, 2); Chris@16: if (!(err & std::ios_base::failbit) && t <= 23) Chris@16: h = t; Chris@16: else Chris@16: err |= std::ios_base::failbit; Chris@16: } Chris@16: Chris@16: void Chris@16: get_minute(int& m, Chris@16: iter_type& b, iter_type e, Chris@16: std::ios_base::iostate& err, Chris@16: const std::ctype& ct) const Chris@16: { Chris@16: int t = get_up_to_n_digits(b, e, err, ct, 2); Chris@16: if (!(err & std::ios_base::failbit) && t <= 59) Chris@16: m = t; Chris@16: else Chris@16: err |= std::ios_base::failbit; Chris@16: } Chris@16: Chris@16: void get_second(int& s, Chris@16: iter_type& b, iter_type e, Chris@16: std::ios_base::iostate& err, Chris@16: const std::ctype& ct) const Chris@16: { Chris@16: int t = get_up_to_n_digits(b, e, err, ct, 2); Chris@16: if (!(err & std::ios_base::failbit) && t <= 60) Chris@16: s = t; Chris@16: else Chris@16: err |= std::ios_base::failbit; Chris@16: } Chris@16: Chris@16: void get_white_space(iter_type& b, iter_type e, Chris@16: std::ios_base::iostate& err, Chris@16: const std::ctype& ct) const Chris@16: { Chris@16: for (; b != e && ct.is(std::ctype_base::space, *b); ++b) Chris@16: ; Chris@16: if (b == e) Chris@16: err |= std::ios_base::eofbit; Chris@16: } Chris@16: Chris@16: void get_12_hour(int& h, Chris@16: iter_type& b, iter_type e, Chris@16: std::ios_base::iostate& err, Chris@16: const std::ctype& ct) const Chris@16: { Chris@16: int t = get_up_to_n_digits(b, e, err, ct, 2); Chris@16: if (!(err & std::ios_base::failbit) && 1 <= t && t <= 12) Chris@16: h = t; Chris@16: else Chris@16: err |= std::ios_base::failbit; Chris@16: } Chris@16: Chris@16: void get_percent(iter_type& b, iter_type e, Chris@16: std::ios_base::iostate& err, Chris@16: const std::ctype& ct) const Chris@16: { Chris@16: if (b == e) Chris@16: { Chris@16: err |= std::ios_base::eofbit | std::ios_base::failbit; Chris@16: return; Chris@16: } Chris@16: if (ct.narrow(*b, 0) != '%') Chris@16: err |= std::ios_base::failbit; Chris@16: else if(++b == e) Chris@16: err |= std::ios_base::eofbit; Chris@16: } Chris@16: Chris@16: void get_day_year_num(int& d, Chris@16: iter_type& b, iter_type e, Chris@16: std::ios_base::iostate& err, Chris@16: const std::ctype& ct) const Chris@16: { Chris@16: int t = get_up_to_n_digits(b, e, err, ct, 3); Chris@16: if (!(err & std::ios_base::failbit) && t <= 365) Chris@16: d = t; Chris@16: else Chris@16: err |= std::ios_base::failbit; Chris@16: } Chris@16: Chris@16: void Chris@16: get_weekday(int& w, Chris@16: iter_type& b, iter_type e, Chris@16: std::ios_base::iostate& err, Chris@16: const std::ctype& ct) const Chris@16: { Chris@16: int t = get_up_to_n_digits(b, e, err, ct, 1); Chris@16: if (!(err & std::ios_base::failbit) && t <= 6) Chris@16: w = t; Chris@16: else Chris@16: err |= std::ios_base::failbit; Chris@16: } Chris@16: #if 0 Chris@16: Chris@16: void Chris@16: get_am_pm(int& h, Chris@16: iter_type& b, iter_type e, Chris@16: std::ios_base::iostate& err, Chris@16: const std::ctype& ct) const Chris@16: { Chris@16: const string_type* ap = am_pm(); Chris@16: if (ap[0].size() + ap[1].size() == 0) Chris@16: { Chris@16: err |= ios_base::failbit; Chris@16: return; Chris@16: } Chris@16: ptrdiff_t i = detail::scan_keyword(b, e, ap, ap+2, ct, err, false) - ap; Chris@16: if (i == 0 && h == 12) Chris@16: h = 0; Chris@16: else if (i == 1 && h < 12) Chris@16: h += 12; Chris@16: } Chris@16: Chris@16: #endif Chris@16: Chris@16: InputIterator get( Chris@16: iter_type b, iter_type e, Chris@16: std::ios_base& iob, Chris@16: std::ios_base::iostate& err, Chris@16: std::tm* tm, Chris@16: char fmt, char) const Chris@16: { Chris@16: err = std::ios_base::goodbit; Chris@16: const std::ctype& ct = std::use_facet >(iob.getloc()); Chris@16: Chris@16: switch (fmt) Chris@16: { Chris@16: case 'a': Chris@16: case 'A': Chris@16: { Chris@16: std::tm tm2; Chris@16: std::memset(&tm2, 0, sizeof(std::tm)); Chris@16: that_.get_weekday(b, e, iob, err, &tm2); Chris@16: //tm->tm_wday = tm2.tm_wday; Chris@16: } Chris@16: break; Chris@16: case 'b': Chris@16: case 'B': Chris@16: case 'h': Chris@16: { Chris@16: std::tm tm2; Chris@16: std::memset(&tm2, 0, sizeof(std::tm)); Chris@16: that_.get_monthname(b, e, iob, err, &tm2); Chris@16: //tm->tm_mon = tm2.tm_mon; Chris@16: } Chris@16: break; Chris@16: // case 'c': Chris@16: // { Chris@16: // const string_type& fm = c(); Chris@16: // b = get(b, e, iob, err, tm, fm.data(), fm.data() + fm.size()); Chris@16: // } Chris@16: // break; Chris@16: case 'd': Chris@16: case 'e': Chris@16: get_day(tm->tm_mday, b, e, err, ct); Chris@16: break; Chris@16: case 'D': Chris@16: { Chris@16: const char_type fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'}; Chris@16: b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0])); Chris@16: } Chris@16: break; Chris@16: case 'F': Chris@16: { Chris@16: const char_type fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'}; Chris@16: b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0])); Chris@16: } Chris@16: break; Chris@16: case 'H': Chris@16: get_hour(tm->tm_hour, b, e, err, ct); Chris@16: break; Chris@16: case 'I': Chris@16: get_12_hour(tm->tm_hour, b, e, err, ct); Chris@16: break; Chris@16: case 'j': Chris@16: get_day_year_num(tm->tm_yday, b, e, err, ct); Chris@16: break; Chris@16: case 'm': Chris@16: get_month(tm->tm_mon, b, e, err, ct); Chris@16: break; Chris@16: case 'M': Chris@16: get_minute(tm->tm_min, b, e, err, ct); Chris@16: break; Chris@16: case 'n': Chris@16: case 't': Chris@16: get_white_space(b, e, err, ct); Chris@16: break; Chris@16: // case 'p': Chris@16: // get_am_pm(tm->tm_hour, b, e, err, ct); Chris@16: // break; Chris@16: case 'r': Chris@16: { Chris@16: const char_type fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'}; Chris@16: b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0])); Chris@16: } Chris@16: break; Chris@16: case 'R': Chris@16: { Chris@16: const char_type fm[] = {'%', 'H', ':', '%', 'M'}; Chris@16: b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0])); Chris@16: } Chris@16: break; Chris@16: case 'S': Chris@16: get_second(tm->tm_sec, b, e, err, ct); Chris@16: break; Chris@16: case 'T': Chris@16: { Chris@16: const char_type fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'}; Chris@16: b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0])); Chris@16: } Chris@16: break; Chris@16: case 'w': Chris@16: { Chris@16: get_weekday(tm->tm_wday, b, e, err, ct); Chris@16: } Chris@16: break; Chris@16: case 'x': Chris@16: return that_.get_date(b, e, iob, err, tm); Chris@16: // case 'X': Chris@16: // return that_.get_time(b, e, iob, err, tm); Chris@16: // { Chris@16: // const string_type& fm = X(); Chris@16: // b = that_.get(b, e, iob, err, tm, fm.data(), fm.data() + fm.size()); Chris@16: // } Chris@16: // break; Chris@16: // case 'y': Chris@16: // get_year(tm->tm_year, b, e, err, ct); Chris@16: break; Chris@16: case 'Y': Chris@16: get_year4(tm->tm_year, b, e, err, ct); Chris@16: break; Chris@16: case '%': Chris@16: get_percent(b, e, err, ct); Chris@16: break; Chris@16: default: Chris@16: err |= std::ios_base::failbit; Chris@16: } Chris@16: return b; Chris@16: } Chris@16: Chris@16: Chris@16: InputIterator get( Chris@16: iter_type b, iter_type e, Chris@16: std::ios_base& iob, Chris@16: std::ios_base::iostate& err, std::tm* tm, Chris@16: const char_type* fmtb, const char_type* fmte) const Chris@16: { Chris@16: const std::ctype& ct = std::use_facet >(iob.getloc()); Chris@16: err = std::ios_base::goodbit; Chris@16: while (fmtb != fmte && err == std::ios_base::goodbit) Chris@16: { Chris@16: if (b == e) Chris@16: { Chris@16: err = std::ios_base::failbit; Chris@16: break; Chris@16: } Chris@16: if (ct.narrow(*fmtb, 0) == '%') Chris@16: { Chris@16: if (++fmtb == fmte) Chris@16: { Chris@16: err = std::ios_base::failbit; Chris@16: break; Chris@16: } Chris@16: char cmd = ct.narrow(*fmtb, 0); Chris@16: char opt = '\0'; Chris@16: if (cmd == 'E' || cmd == '0') Chris@16: { Chris@16: if (++fmtb == fmte) Chris@16: { Chris@16: err = std::ios_base::failbit; Chris@16: break; Chris@16: } Chris@16: opt = cmd; Chris@16: cmd = ct.narrow(*fmtb, 0); Chris@16: } Chris@16: b = get(b, e, iob, err, tm, cmd, opt); Chris@16: ++fmtb; Chris@16: } Chris@16: else if (ct.is(std::ctype_base::space, *fmtb)) Chris@16: { Chris@16: for (++fmtb; fmtb != fmte && ct.is(std::ctype_base::space, *fmtb); ++fmtb) Chris@16: ; Chris@16: for ( ; b != e && ct.is(std::ctype_base::space, *b); ++b) Chris@16: ; Chris@16: } Chris@16: else if (ct.toupper(*b) == ct.toupper(*fmtb)) Chris@16: { Chris@16: ++b; Chris@16: ++fmtb; Chris@16: } Chris@16: else Chris@16: err = std::ios_base::failbit; Chris@16: } Chris@16: if (b == e) Chris@16: err |= std::ios_base::eofbit; Chris@16: return b; Chris@16: } Chris@16: Chris@16: }; Chris@16: Chris@16: Chris@16: template Chris@16: class time_manip: public manip > Chris@16: { Chris@16: std::basic_string fmt_; Chris@16: timezone tz_; Chris@16: public: Chris@16: Chris@16: time_manip(timezone tz, std::basic_string fmt) Chris@16: // todo move semantics Chris@16: : Chris@16: fmt_(fmt), tz_(tz) Chris@16: { Chris@16: } Chris@16: Chris@16: /** Chris@16: * Change the timezone and time format ios state; Chris@16: */ Chris@16: void operator()(std::ios_base &ios) const Chris@16: { Chris@16: set_time_fmt (ios, fmt_); Chris@16: set_timezone(ios, tz_); Chris@16: } Chris@16: }; Chris@16: Chris@16: class time_man: public manip Chris@16: { Chris@16: timezone tz_; Chris@16: public: Chris@16: Chris@16: time_man(timezone tz) Chris@16: // todo move semantics Chris@16: : Chris@16: tz_(tz) Chris@16: { Chris@16: } Chris@16: Chris@16: /** Chris@16: * Change the timezone and time format ios state; Chris@16: */ Chris@16: void operator()(std::ios_base &ios) const Chris@16: { Chris@16: //set_time_fmt(ios, ""); Chris@16: set_timezone(ios, tz_); Chris@16: } Chris@16: }; Chris@16: Chris@16: } Chris@16: Chris@16: template Chris@16: inline detail::time_manip time_fmt(timezone tz, const CharT* fmt) Chris@16: { Chris@16: return detail::time_manip(tz, fmt); Chris@16: } Chris@16: Chris@16: template Chris@16: inline detail::time_manip time_fmt(timezone tz, std::basic_string fmt) Chris@16: { Chris@16: // todo move semantics Chris@16: return detail::time_manip(tz, fmt); Chris@16: } Chris@16: Chris@16: inline detail::time_man time_fmt(timezone f) Chris@16: { Chris@16: return detail::time_man(f); Chris@16: } Chris@16: Chris@16: /** Chris@16: * time_fmt_io_saver i/o saver. Chris@16: * Chris@16: * See Boost.IO i/o state savers for a motivating compression. Chris@16: */ Chris@16: template > Chris@16: struct time_fmt_io_saver Chris@16: { Chris@16: Chris@16: //! the type of the state to restore Chris@101: //typedef std::basic_ostream state_type; Chris@101: typedef std::ios_base state_type; Chris@101: Chris@16: //! the type of aspect to save Chris@16: typedef std::basic_string aspect_type; Chris@16: Chris@16: /** Chris@16: * Explicit construction from an i/o stream. Chris@16: * Chris@16: * Store a reference to the i/o stream and the value of the associated @c time format . Chris@16: */ Chris@16: explicit time_fmt_io_saver(state_type &s) : Chris@101: s_save_(s), a_save_(get_time_fmt(s_save_)) Chris@16: { Chris@16: } Chris@16: Chris@16: /** Chris@16: * Construction from an i/o stream and a @c time format to restore. Chris@16: * Chris@16: * Stores a reference to the i/o stream and the value @c new_value to restore given as parameter. Chris@16: */ Chris@16: time_fmt_io_saver(state_type &s, aspect_type new_value) : Chris@101: s_save_(s), a_save_(get_time_fmt(s_save_)) Chris@16: { Chris@101: set_time_fmt(s_save_, new_value); Chris@16: } Chris@16: Chris@16: /** Chris@16: * Destructor. Chris@16: * Chris@16: * Restores the i/o stream with the format to be restored. Chris@16: */ Chris@16: ~time_fmt_io_saver() Chris@16: { Chris@16: this->restore(); Chris@16: } Chris@16: Chris@16: /** Chris@16: * Restores the i/o stream with the time format to be restored. Chris@16: */ Chris@16: void restore() Chris@16: { Chris@101: set_time_fmt(s_save_, a_save_); Chris@16: } Chris@16: private: Chris@16: state_type& s_save_; Chris@16: aspect_type a_save_; Chris@16: }; Chris@16: Chris@16: /** Chris@16: * timezone_io_saver i/o saver. Chris@16: * Chris@16: * See Boost.IO i/o state savers for a motivating compression. Chris@16: */ Chris@16: struct timezone_io_saver Chris@16: { Chris@16: Chris@16: //! the type of the state to restore Chris@16: typedef std::ios_base state_type; Chris@16: //! the type of aspect to save Chris@16: typedef timezone aspect_type; Chris@16: Chris@16: /** Chris@16: * Explicit construction from an i/o stream. Chris@16: * Chris@16: * Store a reference to the i/o stream and the value of the associated @c timezone. Chris@16: */ Chris@16: explicit timezone_io_saver(state_type &s) : Chris@16: s_save_(s), a_save_(get_timezone(s_save_)) Chris@16: { Chris@16: } Chris@16: Chris@16: /** Chris@16: * Construction from an i/o stream and a @c timezone to restore. Chris@16: * Chris@16: * Stores a reference to the i/o stream and the value @c new_value to restore given as parameter. Chris@16: */ Chris@16: timezone_io_saver(state_type &s, aspect_type new_value) : Chris@101: s_save_(s), a_save_(get_timezone(s_save_)) Chris@16: { Chris@101: set_timezone(s_save_, new_value); Chris@16: } Chris@16: Chris@16: /** Chris@16: * Destructor. Chris@16: * Chris@16: * Restores the i/o stream with the format to be restored. Chris@16: */ Chris@16: ~timezone_io_saver() Chris@16: { Chris@16: this->restore(); Chris@16: } Chris@16: Chris@16: /** Chris@16: * Restores the i/o stream with the timezone to be restored. Chris@16: */ Chris@16: void restore() Chris@16: { Chris@16: set_timezone(s_save_, a_save_); Chris@16: } Chris@16: private: Chris@16: timezone_io_saver& operator=(timezone_io_saver const& rhs) ; Chris@16: Chris@16: state_type& s_save_; Chris@16: aspect_type a_save_; Chris@16: }; Chris@16: Chris@16: /** Chris@16: * Chris@16: * @param os Chris@16: * @param tp Chris@16: * @Effects Behaves as a formatted output function. After constructing a @c sentry object, if the @ sentry Chris@16: * converts to true, calls to @c facet.put(os,os,os.fill(),tp) where @c facet is the @c time_point_put Chris@16: * facet associated to @c os or a new created instance of the default @c time_point_put facet. Chris@16: * @return @c os. Chris@16: */ Chris@16: template Chris@16: std::basic_ostream& Chris@16: operator<<(std::basic_ostream& os, const time_point& tp) Chris@16: { Chris@16: Chris@16: bool failed = false; Chris@16: BOOST_TRY Chris@16: { Chris@16: std::ios_base::iostate err = std::ios_base::goodbit; Chris@16: BOOST_TRY Chris@16: { Chris@16: typename std::basic_ostream::sentry opfx(os); Chris@16: if (bool(opfx)) Chris@16: { Chris@16: if (!std::has_facet >(os.getloc())) Chris@16: { Chris@16: if (time_point_put ().put(os, os, os.fill(), tp) .failed()) Chris@16: { Chris@16: err = std::ios_base::badbit; Chris@16: } Chris@16: } Chris@16: else Chris@16: { Chris@16: if (std::use_facet >(os.getloc()) .put(os, os, os.fill(), tp).failed()) Chris@16: { Chris@16: err = std::ios_base::badbit; Chris@16: } Chris@16: } Chris@16: os.width(0); Chris@16: } Chris@16: } Chris@16: BOOST_CATCH (...) Chris@16: { Chris@16: bool flag = false; Chris@16: BOOST_TRY Chris@16: { Chris@16: os.setstate(std::ios_base::failbit); Chris@16: } Chris@16: BOOST_CATCH (std::ios_base::failure ) Chris@16: { Chris@16: flag = true; Chris@16: } Chris@16: BOOST_CATCH_END Chris@16: if (flag) throw; Chris@16: } Chris@16: BOOST_CATCH_END Chris@16: if (err) os.setstate(err); Chris@16: return os; Chris@16: } Chris@16: BOOST_CATCH (...) Chris@16: { Chris@16: failed = true; Chris@16: } Chris@16: BOOST_CATCH_END Chris@16: if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit); Chris@16: return os; Chris@16: } Chris@16: Chris@16: template Chris@16: std::basic_istream& Chris@16: operator>>(std::basic_istream& is, time_point& tp) Chris@16: { Chris@16: std::ios_base::iostate err = std::ios_base::goodbit; Chris@16: Chris@16: BOOST_TRY Chris@16: { Chris@16: typename std::basic_istream::sentry ipfx(is); Chris@16: if (bool(ipfx)) Chris@16: { Chris@16: if (!std::has_facet >(is.getloc())) Chris@16: { Chris@16: time_point_get ().get(is, std::istreambuf_iterator(), is, err, tp); Chris@16: } Chris@16: else Chris@16: { Chris@16: std::use_facet >(is.getloc()).get(is, std::istreambuf_iterator(), is, Chris@16: err, tp); Chris@16: } Chris@16: } Chris@16: } Chris@16: BOOST_CATCH (...) Chris@16: { Chris@16: bool flag = false; Chris@16: BOOST_TRY Chris@16: { Chris@16: is.setstate(std::ios_base::failbit); Chris@16: } Chris@16: BOOST_CATCH (std::ios_base::failure ) Chris@16: { Chris@16: flag = true; Chris@16: } Chris@16: BOOST_CATCH_END Chris@16: if (flag) throw; Chris@16: } Chris@16: BOOST_CATCH_END Chris@16: if (err) is.setstate(err); Chris@16: return is; Chris@16: } Chris@16: Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: Chris@101: //#if BOOST_CHRONO_INTERNAL_TIMEGM Chris@101: Chris@16: inline int32_t is_leap(int32_t year) Chris@16: { Chris@16: if(year % 400 == 0) Chris@16: return 1; Chris@16: if(year % 100 == 0) Chris@16: return 0; Chris@16: if(year % 4 == 0) Chris@16: return 1; Chris@16: return 0; Chris@16: } Chris@16: inline int32_t days_from_0(int32_t year) Chris@16: { Chris@16: year--; Chris@16: return 365 * year + (year / 400) - (year/100) + (year / 4); Chris@16: } Chris@16: inline int32_t days_from_1970(int32_t year) Chris@16: { Chris@16: static const int days_from_0_to_1970 = days_from_0(1970); Chris@16: return days_from_0(year) - days_from_0_to_1970; Chris@16: } Chris@16: inline int32_t days_from_1jan(int32_t year,int32_t month,int32_t day) Chris@16: { Chris@16: static const int32_t days[2][12] = Chris@16: { Chris@16: { 0,31,59,90,120,151,181,212,243,273,304,334}, Chris@16: { 0,31,60,91,121,152,182,213,244,274,305,335} Chris@16: }; Chris@16: Chris@16: return days[is_leap(year)][month-1] + day - 1; Chris@16: } Chris@16: Chris@16: inline time_t internal_timegm(std::tm const *t) Chris@16: { Chris@16: int year = t->tm_year + 1900; Chris@16: int month = t->tm_mon; Chris@16: if(month > 11) Chris@16: { Chris@16: year += month/12; Chris@16: month %= 12; Chris@16: } Chris@16: else if(month < 0) Chris@16: { Chris@16: int years_diff = (-month + 11)/12; Chris@16: year -= years_diff; Chris@16: month+=12 * years_diff; Chris@16: } Chris@16: month++; Chris@16: int day = t->tm_mday; Chris@16: int day_of_year = days_from_1jan(year,month,day); Chris@16: int days_since_epoch = days_from_1970(year) + day_of_year ; Chris@16: Chris@16: time_t seconds_in_day = 3600 * 24; Chris@16: time_t result = seconds_in_day * days_since_epoch + 3600 * t->tm_hour + 60 * t->tm_min + t->tm_sec; Chris@16: Chris@16: return result; Chris@16: } Chris@101: //#endif Chris@16: Chris@16: /** Chris@16: * from_ymd could be made more efficient by using a table Chris@16: * day_count_table indexed by the y%400. Chris@16: * This table could contain the day_count Chris@16: * by*365 + by/4 - by/100 + by/400 Chris@16: * Chris@16: * from_ymd = (by/400)*days_by_400_years+day_count_table[by%400] + Chris@16: * days_in_year_before[is_leap_table[by%400]][m-1] + d; Chris@16: */ Chris@16: inline unsigned days_before_years(int32_t y) Chris@16: { Chris@16: return y * 365 + y / 4 - y / 100 + y / 400; Chris@16: } Chris@16: Chris@16: // Returns year/month/day triple in civil calendar Chris@16: // Preconditions: z is number of days since 1970-01-01 and is in the range: Chris@16: // [numeric_limits::min(), numeric_limits::max()-719468]. Chris@16: template Chris@16: //constexpr Chris@16: void Chris@16: inline civil_from_days(Int z, Int& y, unsigned& m, unsigned& d) BOOST_NOEXCEPT Chris@16: { Chris@16: BOOST_STATIC_ASSERT_MSG(std::numeric_limits::digits >= 18, Chris@16: "This algorithm has not been ported to a 16 bit unsigned integer"); Chris@16: BOOST_STATIC_ASSERT_MSG(std::numeric_limits::digits >= 20, Chris@16: "This algorithm has not been ported to a 16 bit signed integer"); Chris@16: z += 719468; Chris@16: const Int era = (z >= 0 ? z : z - 146096) / 146097; Chris@16: const unsigned doe = static_cast(z - era * 146097); // [0, 146096] Chris@16: const unsigned yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365; // [0, 399] Chris@16: y = static_cast(yoe) + era * 400; Chris@16: const unsigned doy = doe - (365*yoe + yoe/4 - yoe/100); // [0, 365] Chris@16: const unsigned mp = (5*doy + 2)/153; // [0, 11] Chris@16: d = doy - (153*mp+2)/5 + 1; // [1, 31] Chris@16: m = mp + (mp < 10 ? 3 : -9); // [1, 12] Chris@16: y += (m <= 2); Chris@16: --m; Chris@16: } Chris@16: inline std::tm * internal_gmtime(std::time_t const* t, std::tm *tm) Chris@16: { Chris@16: if (t==0) return 0; Chris@16: if (tm==0) return 0; Chris@16: Chris@16: #if 0 Chris@16: static const unsigned char Chris@16: day_of_year_month[2][366] = Chris@16: { Chris@16: { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 }, Chris@16: Chris@16: { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 Chris@16: Chris@16: } }; Chris@16: Chris@16: static const int32_t days_in_year_before[2][13] = Chris@16: { Chris@16: { -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 }, Chris@16: { -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 } Chris@16: }; Chris@16: #endif Chris@16: Chris@16: const time_t seconds_in_day = 3600 * 24; Chris@16: int32_t days_since_epoch = static_cast(*t / seconds_in_day); Chris@16: int32_t hms = static_cast(*t - seconds_in_day*days_since_epoch); Chris@16: if (hms < 0) { Chris@16: days_since_epoch-=1; Chris@16: hms = seconds_in_day+hms; Chris@16: } Chris@16: Chris@16: #if 0 Chris@16: int32_t x = days_since_epoch; Chris@16: int32_t y = static_cast (static_cast (x + 2) * 400 Chris@16: / 146097); Chris@16: const int32_t ym1 = y - 1; Chris@16: int32_t doy = x - days_before_years(y); Chris@16: const int32_t doy1 = x - days_before_years(ym1); Chris@16: const int32_t N = std::numeric_limits::digits - 1; Chris@16: const int32_t mask1 = doy >> N; // arithmetic rshift - not portable - but nearly universal Chris@16: const int32_t mask0 = ~mask1; Chris@16: doy = (doy & mask0) | (doy1 & mask1); Chris@16: y = (y & mask0) | (ym1 & mask1); Chris@16: //y -= 32767 + 2; Chris@16: y += 70; Chris@16: tm->tm_year=y; Chris@16: const int32_t leap = is_leap(y); Chris@16: tm->tm_mon = day_of_year_month[leap][doy]-1; Chris@16: tm->tm_mday = doy - days_in_year_before[leap][tm->tm_mon] ; Chris@16: #else Chris@16: int32_t y; Chris@16: unsigned m, d; Chris@16: civil_from_days(days_since_epoch, y, m, d); Chris@16: tm->tm_year=y-1900; tm->tm_mon=m; tm->tm_mday=d; Chris@16: #endif Chris@16: Chris@16: tm->tm_hour = hms / 3600; Chris@16: const int ms = hms % 3600; Chris@16: tm->tm_min = ms / 60; Chris@16: tm->tm_sec = ms % 60; Chris@16: Chris@16: tm->tm_isdst = -1; Chris@16: (void)mktime(tm); Chris@16: return tm; Chris@16: } Chris@16: Chris@16: } // detail Chris@16: #ifndef BOOST_CHRONO_NO_UTC_TIMEPOINT Chris@16: Chris@16: #if defined BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT Chris@16: Chris@16: template Chris@16: std::basic_ostream& Chris@16: operator<<(std::basic_ostream& os, const time_point& tp) Chris@16: { Chris@16: typename std::basic_ostream::sentry ok(os); Chris@16: if (bool(ok)) Chris@16: { Chris@16: bool failed = false; Chris@16: BOOST_TRY Chris@16: { Chris@16: const CharT* pb = 0; //nullptr; Chris@16: const CharT* pe = pb; Chris@16: std::basic_string fmt = get_time_fmt (os); Chris@16: pb = fmt.data(); Chris@16: pe = pb + fmt.size(); Chris@16: Chris@16: timezone tz = get_timezone(os); Chris@16: std::locale loc = os.getloc(); Chris@16: time_t t = system_clock::to_time_t(time_point_cast(tp)); Chris@16: std::tm tm; Chris@16: std::memset(&tm, 0, sizeof(std::tm)); Chris@16: if (tz == timezone::local) Chris@16: { Chris@16: #if defined BOOST_WINDOWS && ! defined(__CYGWIN__) Chris@16: std::tm *tmp = 0; Chris@16: if ((tmp=localtime(&t)) == 0) Chris@16: failed = true; Chris@16: else Chris@16: tm =*tmp; Chris@16: #else Chris@16: if (localtime_r(&t, &tm) == 0) failed = true; Chris@16: #endif Chris@16: } Chris@16: else Chris@16: { Chris@16: #if BOOST_CHRONO_INTERNAL_GMTIME Chris@16: if (detail::internal_gmtime(&t, &tm) == 0) failed = true; Chris@16: Chris@16: #elif defined BOOST_WINDOWS && ! defined(__CYGWIN__) Chris@16: std::tm *tmp = 0; Chris@16: if((tmp = gmtime(&t)) == 0) Chris@16: failed = true; Chris@16: else Chris@16: tm = *tmp; Chris@16: #else Chris@16: if (gmtime_r(&t, &tm) == 0) failed = true; Chris@16: tm.tm_isdst = -1; Chris@16: (void)mktime(&tm); Chris@16: Chris@16: #endif Chris@16: Chris@16: } Chris@16: if (!failed) Chris@16: { Chris@16: const std::time_put& tpf = std::use_facet >(loc); Chris@16: if (pb == pe) Chris@16: { Chris@16: CharT pattern[] = Chris@16: { '%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', '%', 'H', ':', '%', 'M', ':' }; Chris@16: pb = pattern; Chris@16: pe = pb + sizeof (pattern) / sizeof(CharT); Chris@16: failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed(); Chris@16: if (!failed) Chris@16: { Chris@16: duration d = tp - system_clock::from_time_t(t) + seconds(tm.tm_sec); Chris@16: if (d.count() < 10) os << CharT('0'); Chris@16: //if (! os.good()) { Chris@16: // throw "exception"; Chris@16: //} Chris@16: std::ios::fmtflags flgs = os.flags(); Chris@16: os.setf(std::ios::fixed, std::ios::floatfield); Chris@16: //if (! os.good()) { Chris@16: //throw "exception"; Chris@16: //} Chris@16: os.precision(9); Chris@16: os << d.count(); Chris@16: //if (! os.good()) { Chris@16: //throw "exception"; Chris@16: //} Chris@16: os.flags(flgs); Chris@16: if (tz == timezone::local) Chris@16: { Chris@16: CharT sub_pattern[] = Chris@16: { ' ', '%', 'z' }; Chris@16: pb = sub_pattern; Chris@16: pe = pb + +sizeof (sub_pattern) / sizeof(CharT); Chris@16: failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed(); Chris@16: } Chris@16: else Chris@16: { Chris@16: CharT sub_pattern[] = Chris@16: { ' ', '+', '0', '0', '0', '0', 0 }; Chris@16: os << sub_pattern; Chris@16: } Chris@16: } Chris@16: } Chris@16: else Chris@16: { Chris@16: failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed(); Chris@16: } Chris@16: } Chris@16: } Chris@16: BOOST_CATCH (...) Chris@16: { Chris@16: failed = true; Chris@16: } Chris@16: BOOST_CATCH_END Chris@16: if (failed) Chris@16: { Chris@16: os.setstate(std::ios_base::failbit | std::ios_base::badbit); Chris@16: } Chris@16: } Chris@16: return os; Chris@16: } Chris@16: #endif Chris@16: Chris@16: namespace detail Chris@16: { Chris@16: Chris@16: template Chris@16: minutes extract_z(InputIterator& b, InputIterator e, std::ios_base::iostate& err, const std::ctype& ct) Chris@16: { Chris@16: int min = 0; Chris@16: if (b != e) Chris@16: { Chris@16: char cn = ct.narrow(*b, 0); Chris@16: if (cn != '+' && cn != '-') Chris@16: { Chris@16: err |= std::ios_base::failbit; Chris@16: return minutes(0); Chris@16: } Chris@16: int sn = cn == '-' ? -1 : 1; Chris@16: int hr = 0; Chris@16: for (int i = 0; i < 2; ++i) Chris@16: { Chris@16: if (++b == e) Chris@16: { Chris@16: err |= std::ios_base::eofbit | std::ios_base::failbit; Chris@16: return minutes(0); Chris@16: } Chris@16: cn = ct.narrow(*b, 0); Chris@16: if (! ('0' <= cn && cn <= '9')) Chris@16: { Chris@16: err |= std::ios_base::failbit; Chris@16: return minutes(0); Chris@16: } Chris@16: hr = hr * 10 + cn - '0'; Chris@16: } Chris@16: for (int i = 0; i < 2; ++i) Chris@16: { Chris@16: if (++b == e) Chris@16: { Chris@16: err |= std::ios_base::eofbit | std::ios_base::failbit; Chris@16: return minutes(0); Chris@16: } Chris@16: cn = ct.narrow(*b, 0); Chris@16: if (! ('0' <= cn && cn <= '9')) Chris@16: { Chris@16: err |= std::ios_base::failbit; Chris@16: return minutes(0); Chris@16: } Chris@16: min = min * 10 + cn - '0'; Chris@16: } Chris@16: if (++b == e) { Chris@16: err |= std::ios_base::eofbit; Chris@16: } Chris@16: min += hr * 60; Chris@16: min *= sn; Chris@16: } Chris@16: else Chris@16: { Chris@16: err |= std::ios_base::eofbit | std::ios_base::failbit; Chris@16: } Chris@16: return minutes(min); Chris@16: } Chris@16: Chris@16: } // detail Chris@16: Chris@16: #if defined BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT Chris@16: Chris@16: template Chris@16: std::basic_istream& Chris@16: operator>>(std::basic_istream& is, time_point& tp) Chris@16: { Chris@16: typename std::basic_istream::sentry ok(is); Chris@16: if (bool(ok)) Chris@16: { Chris@16: std::ios_base::iostate err = std::ios_base::goodbit; Chris@16: BOOST_TRY Chris@16: { Chris@16: const CharT* pb = 0; //nullptr; Chris@16: const CharT* pe = pb; Chris@16: std::basic_string fmt = get_time_fmt (is); Chris@16: pb = fmt.data(); Chris@16: pe = pb + fmt.size(); Chris@16: Chris@16: timezone tz = get_timezone(is); Chris@16: std::locale loc = is.getloc(); Chris@16: const std::time_get& tg = std::use_facet >(loc); Chris@16: const std::ctype& ct = std::use_facet >(loc); Chris@16: tm tm; // {0} Chris@16: std::memset(&tm, 0, sizeof(std::tm)); Chris@16: Chris@16: typedef std::istreambuf_iterator It; Chris@16: if (pb == pe) Chris@16: { Chris@16: CharT pattern[] = Chris@16: { '%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', '%', 'H', ':', '%', 'M', ':' }; Chris@16: pb = pattern; Chris@16: pe = pb + sizeof (pattern) / sizeof(CharT); Chris@16: Chris@16: #if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET Chris@16: const detail::time_get& dtg(tg); Chris@16: dtg.get(is, 0, is, err, &tm, pb, pe); Chris@16: #else Chris@16: tg.get(is, 0, is, err, &tm, pb, pe); Chris@16: #endif Chris@16: if (err & std::ios_base::failbit) goto exit; Chris@16: fractional_seconds sec; Chris@16: CharT c = CharT(); Chris@16: std::ios::fmtflags flgs = is.flags(); Chris@16: is.setf(std::ios::fixed, std::ios::floatfield); Chris@16: is.precision(9); Chris@16: is >> sec; Chris@16: is.flags(flgs); Chris@16: if (is.fail()) Chris@16: { Chris@16: err |= std::ios_base::failbit; Chris@16: goto exit; Chris@16: } Chris@16: It i(is); Chris@16: It eof; Chris@16: c = *i; Chris@16: if (++i == eof || c != ' ') Chris@16: { Chris@16: err |= std::ios_base::failbit; Chris@16: goto exit; Chris@16: } Chris@16: minutes min = detail::extract_z(i, eof, err, ct); Chris@16: Chris@16: if (err & std::ios_base::failbit) goto exit; Chris@16: time_t t; Chris@16: Chris@16: #if BOOST_CHRONO_INTERNAL_TIMEGM Chris@16: t = detail::internal_timegm(&tm); Chris@16: #else Chris@16: t = timegm(&tm); Chris@16: #endif Chris@16: tp = time_point_cast( Chris@16: system_clock::from_time_t(t) - min + round (duration (sec)) Chris@16: ); Chris@16: } Chris@16: else Chris@16: { Chris@16: const CharT z[2] = Chris@16: { '%', 'z' }; Chris@16: const CharT* fz = std::search(pb, pe, z, z + 2); Chris@16: #if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET Chris@16: const detail::time_get& dtg(tg); Chris@16: dtg.get(is, 0, is, err, &tm, pb, fz); Chris@16: #else Chris@16: tg.get(is, 0, is, err, &tm, pb, fz); Chris@16: #endif Chris@16: minutes minu(0); Chris@16: if (fz != pe) Chris@16: { Chris@16: if (err != std::ios_base::goodbit) Chris@16: { Chris@16: err |= std::ios_base::failbit; Chris@16: goto exit; Chris@16: } Chris@16: It i(is); Chris@16: It eof; Chris@16: minu = detail::extract_z(i, eof, err, ct); Chris@16: if (err & std::ios_base::failbit) goto exit; Chris@16: if (fz + 2 != pe) Chris@16: { Chris@16: if (err != std::ios_base::goodbit) Chris@16: { Chris@16: err |= std::ios_base::failbit; Chris@16: goto exit; Chris@16: } Chris@16: #if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET Chris@16: const detail::time_get& dtg(tg); Chris@16: dtg.get(is, 0, is, err, &tm, fz + 2, pe); Chris@16: #else Chris@16: tg.get(is, 0, is, err, &tm, fz + 2, pe); Chris@16: #endif Chris@16: if (err & std::ios_base::failbit) goto exit; Chris@16: } Chris@16: } Chris@16: tm.tm_isdst = -1; Chris@16: time_t t; Chris@16: if (tz == timezone::utc || fz != pe) Chris@16: { Chris@16: #if BOOST_CHRONO_INTERNAL_TIMEGM Chris@16: t = detail::internal_timegm(&tm); Chris@16: #else Chris@16: t = timegm(&tm); Chris@16: #endif Chris@16: } Chris@16: else Chris@16: { Chris@16: t = mktime(&tm); Chris@16: } Chris@16: tp = time_point_cast( Chris@16: system_clock::from_time_t(t) - minu Chris@16: ); Chris@16: } Chris@16: } Chris@16: BOOST_CATCH (...) Chris@16: { Chris@16: err |= std::ios_base::badbit | std::ios_base::failbit; Chris@16: } Chris@16: BOOST_CATCH_END Chris@16: exit: is.setstate(err); Chris@16: } Chris@16: return is; Chris@16: } Chris@16: Chris@16: #endif Chris@16: #endif //UTC Chris@16: } // chrono Chris@16: Chris@16: } Chris@16: Chris@16: #endif // header