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