Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:48

0001 //  (C) Copyright Howard Hinnant
0002 //  (C) Copyright 2010-2011 Vicente J. Botet Escriba
0003 //  Use, modification and distribution are subject to the Boost Software License,
0004 //  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0005 //  http://www.boost.org/LICENSE_1_0.txt).
0006 
0007 //===-------------------------- locale ------------------------------------===//
0008 //
0009 //                     The LLVM Compiler Infrastructure
0010 //
0011 // This file is dual licensed under the MIT and the University of Illinois Open
0012 // Source Licenses. See LICENSE.TXT for details.
0013 //
0014 //===----------------------------------------------------------------------===//
0015 
0016 // This code was adapted by Vicente from Howard Hinnant's experimental work
0017 // on chrono i/o to Boost and some functions from libc++/locale to emulate the missing time_get::get()
0018 
0019 #ifndef BOOST_CHRONO_IO_TIME_POINT_IO_HPP
0020 #define BOOST_CHRONO_IO_TIME_POINT_IO_HPP
0021 
0022 #include <boost/chrono/io/time_point_put.hpp>
0023 #include <boost/chrono/io/time_point_get.hpp>
0024 #include <boost/chrono/io/duration_io.hpp>
0025 #include <boost/chrono/io/ios_base_state.hpp>
0026 #include <boost/chrono/io/utility/manip_base.hpp>
0027 #include <boost/chrono/time_point.hpp>
0028 #include <boost/chrono/clock_string.hpp>
0029 #include <boost/chrono/round.hpp>
0030 #include <boost/chrono/detail/scan_keyword.hpp>
0031 #include <boost/static_assert.hpp>
0032 #include <boost/core/no_exceptions_support.hpp>
0033 #include <cstring>
0034 #include <locale>
0035 #include <ctime>
0036 
0037 #if  ( defined BOOST_WINDOWS && ! defined(__CYGWIN__) )  \
0038   || (defined(sun) || defined(__sun)) \
0039   || (defined __IBMCPP__) \
0040   || defined __ANDROID__ \
0041   || defined __QNXNTO__ \
0042   || (defined(_AIX) && defined __GNUC__)
0043 #define  BOOST_CHRONO_INTERNAL_TIMEGM
0044 #endif
0045 
0046 #if (defined BOOST_WINDOWS && ! defined(__CYGWIN__)) \
0047   || ( (defined(sun) || defined(__sun)) && defined __GNUC__) \
0048   || (defined __IBMCPP__) \
0049   || defined __ANDROID__ \
0050   || (defined(_AIX) && defined __GNUC__)
0051 #define  BOOST_CHRONO_INTERNAL_GMTIME
0052 #endif
0053 
0054 #define  BOOST_CHRONO_USES_INTERNAL_TIME_GET
0055 
0056 namespace boost
0057 {
0058   namespace chrono
0059   {
0060     typedef double fractional_seconds;
0061     namespace detail
0062     {
0063 
0064 
0065       template <class CharT, class InputIterator = std::istreambuf_iterator<CharT> >
0066       struct time_get
0067       {
0068         std::time_get<CharT> const &that_;
0069         time_get(std::time_get<CharT> const& that) : that_(that) {}
0070 
0071         typedef std::time_get<CharT> facet;
0072         typedef typename facet::iter_type iter_type;
0073         typedef typename facet::char_type char_type;
0074         typedef std::basic_string<char_type> string_type;
0075 
0076         static int
0077         get_up_to_n_digits(
0078             InputIterator& b, InputIterator e,
0079             std::ios_base::iostate& err,
0080             const std::ctype<CharT>& ct,
0081             int n)
0082         {
0083             // Precondition:  n >= 1
0084             if (b == e)
0085             {
0086                 err |= std::ios_base::eofbit | std::ios_base::failbit;
0087                 return 0;
0088             }
0089             // get first digit
0090             CharT c = *b;
0091             if (!ct.is(std::ctype_base::digit, c))
0092             {
0093                 err |= std::ios_base::failbit;
0094                 return 0;
0095             }
0096             int r = ct.narrow(c, 0) - '0';
0097             for (++b, --n; b != e && n > 0; ++b, --n)
0098             {
0099                 // get next digit
0100                 c = *b;
0101                 if (!ct.is(std::ctype_base::digit, c))
0102                     return r;
0103                 r = r * 10 + ct.narrow(c, 0) - '0';
0104             }
0105             if (b == e)
0106                 err |= std::ios_base::eofbit;
0107             return r;
0108         }
0109 
0110 
0111         void get_day(
0112             int& d,
0113             iter_type& b, iter_type e,
0114             std::ios_base::iostate& err,
0115             const std::ctype<char_type>& ct) const
0116         {
0117             int t = get_up_to_n_digits(b, e, err, ct, 2);
0118             if (!(err & std::ios_base::failbit) && 1 <= t && t <= 31)
0119                 d = t;
0120             else
0121                 err |= std::ios_base::failbit;
0122         }
0123 
0124         void get_month(
0125             int& m,
0126             iter_type& b, iter_type e,
0127             std::ios_base::iostate& err,
0128             const std::ctype<char_type>& ct) const
0129         {
0130             int t = get_up_to_n_digits(b, e, err, ct, 2);
0131             if (!(err & std::ios_base::failbit) && 1 <= t && t <= 12)
0132                 m = --t;
0133             else
0134                 err |= std::ios_base::failbit;
0135         }
0136 
0137 
0138         void get_year4(int& y,
0139                                                       iter_type& b, iter_type e,
0140                                                       std::ios_base::iostate& err,
0141                                                       const std::ctype<char_type>& ct) const
0142         {
0143             int t = get_up_to_n_digits(b, e, err, ct, 4);
0144             if (!(err & std::ios_base::failbit))
0145                 y = t - 1900;
0146         }
0147 
0148         void
0149         get_hour(int& h,
0150                                                      iter_type& b, iter_type e,
0151                                                      std::ios_base::iostate& err,
0152                                                      const std::ctype<char_type>& ct) const
0153         {
0154             int t = get_up_to_n_digits(b, e, err, ct, 2);
0155             if (!(err & std::ios_base::failbit) && t <= 23)
0156                 h = t;
0157             else
0158                 err |= std::ios_base::failbit;
0159         }
0160 
0161         void
0162         get_minute(int& m,
0163                                                        iter_type& b, iter_type e,
0164                                                        std::ios_base::iostate& err,
0165                                                        const std::ctype<char_type>& ct) const
0166         {
0167             int t = get_up_to_n_digits(b, e, err, ct, 2);
0168             if (!(err & std::ios_base::failbit) && t <= 59)
0169                 m = t;
0170             else
0171                 err |= std::ios_base::failbit;
0172         }
0173 
0174         void  get_second(int& s,
0175                                                        iter_type& b, iter_type e,
0176                                                        std::ios_base::iostate& err,
0177                                                        const std::ctype<char_type>& ct) const
0178         {
0179             int t = get_up_to_n_digits(b, e, err, ct, 2);
0180             if (!(err & std::ios_base::failbit) && t <= 60)
0181                 s = t;
0182             else
0183                 err |= std::ios_base::failbit;
0184         }
0185 
0186         void get_white_space(iter_type& b, iter_type e,
0187                                                             std::ios_base::iostate& err,
0188                                                             const std::ctype<char_type>& ct) const
0189         {
0190             for (; b != e && ct.is(std::ctype_base::space, *b); ++b)
0191                 ;
0192             if (b == e)
0193                 err |= std::ios_base::eofbit;
0194         }
0195 
0196         void get_12_hour(int& h,
0197                                                         iter_type& b, iter_type e,
0198                                                         std::ios_base::iostate& err,
0199                                                         const std::ctype<char_type>& ct) const
0200         {
0201             int t = get_up_to_n_digits(b, e, err, ct, 2);
0202             if (!(err & std::ios_base::failbit) && 1 <= t && t <= 12)
0203                 h = t;
0204             else
0205                 err |= std::ios_base::failbit;
0206         }
0207 
0208         void get_percent(iter_type& b, iter_type e,
0209                                                         std::ios_base::iostate& err,
0210                                                         const std::ctype<char_type>& ct) const
0211         {
0212             if (b == e)
0213             {
0214                 err |= std::ios_base::eofbit | std::ios_base::failbit;
0215                 return;
0216             }
0217             if (ct.narrow(*b, 0) != '%')
0218                 err |= std::ios_base::failbit;
0219             else if(++b == e)
0220                 err |= std::ios_base::eofbit;
0221         }
0222 
0223         void get_day_year_num(int& d,
0224                                                              iter_type& b, iter_type e,
0225                                                              std::ios_base::iostate& err,
0226                                                              const std::ctype<char_type>& ct) const
0227         {
0228             int t = get_up_to_n_digits(b, e, err, ct, 3);
0229             if (!(err & std::ios_base::failbit) && 1 <= t && t <= 366)
0230                 d = --t;
0231             else
0232                 err |= std::ios_base::failbit;
0233         }
0234 
0235         void
0236         get_weekday(int& w,
0237                                                         iter_type& b, iter_type e,
0238                                                         std::ios_base::iostate& err,
0239                                                         const std::ctype<char_type>& ct) const
0240         {
0241             int t = get_up_to_n_digits(b, e, err, ct, 1);
0242             if (!(err & std::ios_base::failbit) && t <= 6)
0243                 w = t;
0244             else
0245                 err |= std::ios_base::failbit;
0246         }
0247 #if 0
0248 
0249         void
0250         get_am_pm(int& h,
0251                                                       iter_type& b, iter_type e,
0252                                                       std::ios_base::iostate& err,
0253                                                       const std::ctype<char_type>& ct) const
0254         {
0255             const string_type* ap = am_pm();
0256             if (ap[0].size() + ap[1].size() == 0)
0257             {
0258                 err |= ios_base::failbit;
0259                 return;
0260             }
0261             ptrdiff_t i = detail::scan_keyword(b, e, ap, ap+2, ct, err, false) - ap;
0262             if (i == 0 && h == 12)
0263                 h = 0;
0264             else if (i == 1 && h < 12)
0265                 h += 12;
0266         }
0267 
0268 #endif
0269 
0270         InputIterator get(
0271             iter_type b, iter_type e,
0272             std::ios_base& iob,
0273             std::ios_base::iostate& err,
0274             std::tm* tm,
0275             char fmt, char) const
0276         {
0277             err = std::ios_base::goodbit;
0278             const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(iob.getloc());
0279 
0280             switch (fmt)
0281             {
0282             case 'a':
0283             case 'A':
0284               {
0285                 std::tm tm2;
0286                 std::memset(&tm2, 0, sizeof(std::tm));
0287                 that_.get_weekday(b, e, iob, err, &tm2);
0288                 //tm->tm_wday = tm2.tm_wday;
0289               }
0290               break;
0291             case 'b':
0292             case 'B':
0293             case 'h':
0294               {
0295                 std::tm tm2;
0296                 std::memset(&tm2, 0, sizeof(std::tm));
0297                 that_.get_monthname(b, e, iob, err, &tm2);
0298                 //tm->tm_mon = tm2.tm_mon;
0299               }
0300               break;
0301 //            case 'c':
0302 //              {
0303 //                const string_type& fm = c();
0304 //                b = get(b, e, iob, err, tm, fm.data(), fm.data() + fm.size());
0305 //              }
0306 //              break;
0307             case 'd':
0308             case 'e':
0309               get_day(tm->tm_mday, b, e, err, ct);
0310               break;
0311             case 'D':
0312               {
0313                 const char_type fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
0314                 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
0315               }
0316               break;
0317             case 'F':
0318               {
0319                 const char_type fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
0320                 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
0321               }
0322               break;
0323             case 'H':
0324               get_hour(tm->tm_hour, b, e, err, ct);
0325               break;
0326             case 'I':
0327               get_12_hour(tm->tm_hour, b, e, err, ct);
0328               break;
0329             case 'j':
0330               get_day_year_num(tm->tm_yday, b, e, err, ct);
0331               break;
0332             case 'm':
0333               get_month(tm->tm_mon, b, e, err, ct);
0334               break;
0335             case 'M':
0336               get_minute(tm->tm_min, b, e, err, ct);
0337               break;
0338             case 'n':
0339             case 't':
0340               get_white_space(b, e, err, ct);
0341               break;
0342 //            case 'p':
0343 //              get_am_pm(tm->tm_hour, b, e, err, ct);
0344 //              break;
0345             case 'r':
0346               {
0347                 const char_type fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
0348                 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
0349               }
0350               break;
0351             case 'R':
0352               {
0353                 const char_type fm[] = {'%', 'H', ':', '%', 'M'};
0354                 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
0355               }
0356               break;
0357             case 'S':
0358               get_second(tm->tm_sec, b, e, err, ct);
0359               break;
0360             case 'T':
0361               {
0362                 const char_type fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
0363                 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
0364               }
0365               break;
0366             case 'w':
0367               {
0368                 get_weekday(tm->tm_wday, b, e, err, ct);
0369               }
0370               break;
0371             case 'x':
0372               return that_.get_date(b, e, iob, err, tm);
0373 //            case 'X':
0374 //              return that_.get_time(b, e, iob, err, tm);
0375 //              {
0376 //                const string_type& fm = X();
0377 //                b = that_.get(b, e, iob, err, tm, fm.data(), fm.data() + fm.size());
0378 //              }
0379 //              break;
0380 //            case 'y':
0381 //              get_year(tm->tm_year, b, e, err, ct);
0382                 break;
0383             case 'Y':
0384               get_year4(tm->tm_year, b, e, err, ct);
0385               break;
0386             case '%':
0387               get_percent(b, e, err, ct);
0388               break;
0389             default:
0390                 err |= std::ios_base::failbit;
0391             }
0392             return b;
0393         }
0394 
0395 
0396         InputIterator get(
0397           iter_type b, iter_type e,
0398           std::ios_base& iob,
0399           std::ios_base::iostate& err, std::tm* tm,
0400           const char_type* fmtb, const char_type* fmte) const
0401         {
0402           const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(iob.getloc());
0403           err = std::ios_base::goodbit;
0404           while (fmtb != fmte && err == std::ios_base::goodbit)
0405           {
0406               if (b == e)
0407               {
0408                   err = std::ios_base::failbit;
0409                   break;
0410               }
0411               if (ct.narrow(*fmtb, 0) == '%')
0412               {
0413                   if (++fmtb == fmte)
0414                   {
0415                       err = std::ios_base::failbit;
0416                       break;
0417                   }
0418                   char cmd = ct.narrow(*fmtb, 0);
0419                   char opt = '\0';
0420                   if (cmd == 'E' || cmd == '0')
0421                   {
0422                       if (++fmtb == fmte)
0423                       {
0424                           err = std::ios_base::failbit;
0425                           break;
0426                       }
0427                       opt = cmd;
0428                       cmd = ct.narrow(*fmtb, 0);
0429                   }
0430                   b = get(b, e, iob, err, tm, cmd, opt);
0431                   ++fmtb;
0432               }
0433               else if (ct.is(std::ctype_base::space, *fmtb))
0434               {
0435                   for (++fmtb; fmtb != fmte && ct.is(std::ctype_base::space, *fmtb); ++fmtb)
0436                       ;
0437                   for (        ;    b != e    && ct.is(std::ctype_base::space, *b);    ++b)
0438                       ;
0439               }
0440               else if (ct.toupper(*b) == ct.toupper(*fmtb))
0441               {
0442                   ++b;
0443                   ++fmtb;
0444               }
0445               else
0446                   err = std::ios_base::failbit;
0447           }
0448           if (b == e)
0449               err |= std::ios_base::eofbit;
0450           return b;
0451         }
0452 
0453       };
0454 
0455 
0456       template <class CharT>
0457       class time_manip: public manip<time_manip<CharT> >
0458       {
0459         std::basic_string<CharT> fmt_;
0460         timezone tz_;
0461       public:
0462 
0463         time_manip(timezone tz, std::basic_string<CharT> fmt)
0464         // todo move semantics
0465         :
0466           fmt_(fmt), tz_(tz)
0467         {
0468         }
0469 
0470         /**
0471          * Change the timezone and time format ios state;
0472          */
0473         void operator()(std::ios_base &ios) const
0474         {
0475           set_time_fmt<CharT> (ios, fmt_);
0476           set_timezone(ios, tz_);
0477         }
0478       };
0479 
0480       class time_man: public manip<time_man>
0481       {
0482         timezone tz_;
0483       public:
0484 
0485         time_man(timezone tz)
0486         // todo move semantics
0487         :
0488           tz_(tz)
0489         {
0490         }
0491 
0492         /**
0493          * Change the timezone and time format ios state;
0494          */
0495         void operator()(std::ios_base &ios) const
0496         {
0497           //set_time_fmt<typename out_stream::char_type>(ios, "");
0498           set_timezone(ios, tz_);
0499         }
0500       };
0501 
0502     }
0503 
0504     template <class CharT>
0505     inline detail::time_manip<CharT> time_fmt(timezone tz, const CharT* fmt)
0506     {
0507       return detail::time_manip<CharT>(tz, fmt);
0508     }
0509 
0510     template <class CharT>
0511     inline detail::time_manip<CharT> time_fmt(timezone tz, std::basic_string<CharT> fmt)
0512     {
0513       // todo move semantics
0514       return detail::time_manip<CharT>(tz, fmt);
0515     }
0516 
0517     inline detail::time_man time_fmt(timezone f)
0518     {
0519       return detail::time_man(f);
0520     }
0521 
0522     /**
0523      * time_fmt_io_saver i/o saver.
0524      *
0525      * See Boost.IO i/o state savers for a motivating compression.
0526      */
0527     template <typename CharT = char, typename Traits = std::char_traits<CharT> >
0528     struct time_fmt_io_saver
0529     {
0530 
0531       //! the type of the state to restore
0532       //typedef std::basic_ostream<CharT, Traits> state_type;
0533       typedef std::ios_base state_type;
0534 
0535       //! the type of aspect to save
0536       typedef std::basic_string<CharT, Traits> aspect_type;
0537 
0538       /**
0539        * Explicit construction from an i/o stream.
0540        *
0541        * Store a reference to the i/o stream and the value of the associated @c time format .
0542        */
0543       explicit time_fmt_io_saver(state_type &s) :
0544         s_save_(s), a_save_(get_time_fmt<CharT>(s_save_))
0545       {
0546       }
0547 
0548       /**
0549        * Construction from an i/o stream and a @c time format  to restore.
0550        *
0551        * Stores a reference to the i/o stream and the value @c new_value to restore given as parameter.
0552        */
0553       time_fmt_io_saver(state_type &s, aspect_type new_value) :
0554         s_save_(s), a_save_(get_time_fmt<CharT>(s_save_))
0555       {
0556         set_time_fmt(s_save_, new_value);
0557       }
0558 
0559       /**
0560        * Destructor.
0561        *
0562        * Restores the i/o stream with the format to be restored.
0563        */
0564       ~time_fmt_io_saver()
0565       {
0566         this->restore();
0567       }
0568 
0569       /**
0570        * Restores the i/o stream with the time format to be restored.
0571        */
0572       void restore()
0573       {
0574         set_time_fmt(s_save_, a_save_);
0575       }
0576     private:
0577       state_type& s_save_;
0578       aspect_type a_save_;
0579     };
0580 
0581     /**
0582      * timezone_io_saver i/o saver.
0583      *
0584      * See Boost.IO i/o state savers for a motivating compression.
0585      */
0586     struct timezone_io_saver
0587     {
0588 
0589       //! the type of the state to restore
0590       typedef std::ios_base state_type;
0591       //! the type of aspect to save
0592       typedef timezone aspect_type;
0593 
0594       /**
0595        * Explicit construction from an i/o stream.
0596        *
0597        * Store a reference to the i/o stream and the value of the associated @c timezone.
0598        */
0599       explicit timezone_io_saver(state_type &s) :
0600         s_save_(s), a_save_(get_timezone(s_save_))
0601       {
0602       }
0603 
0604       /**
0605        * Construction from an i/o stream and a @c timezone to restore.
0606        *
0607        * Stores a reference to the i/o stream and the value @c new_value to restore given as parameter.
0608        */
0609       timezone_io_saver(state_type &s, aspect_type new_value) :
0610         s_save_(s), a_save_(get_timezone(s_save_))
0611       {
0612         set_timezone(s_save_, new_value);
0613       }
0614 
0615       /**
0616        * Destructor.
0617        *
0618        * Restores the i/o stream with the format to be restored.
0619        */
0620       ~timezone_io_saver()
0621       {
0622         this->restore();
0623       }
0624 
0625       /**
0626        * Restores the i/o stream with the timezone to be restored.
0627        */
0628       void restore()
0629       {
0630         set_timezone(s_save_, a_save_);
0631       }
0632     private:
0633       timezone_io_saver& operator=(timezone_io_saver const& rhs) ;
0634 
0635       state_type& s_save_;
0636       aspect_type a_save_;
0637     };
0638 
0639     /**
0640      *
0641      * @param os
0642      * @param tp
0643      * @Effects Behaves as a formatted output function. After constructing a @c sentry object, if the @ sentry
0644      * converts to true, calls to @c facet.put(os,os,os.fill(),tp) where @c facet is the @c time_point_put<CharT>
0645      * facet associated to @c os or a new created instance of the default @c time_point_put<CharT> facet.
0646      * @return @c os.
0647      */
0648     template <class CharT, class Traits, class Clock, class Duration>
0649     std::basic_ostream<CharT, Traits>&
0650     operator<<(std::basic_ostream<CharT, Traits>& os, const time_point<Clock, Duration>& tp)
0651     {
0652 
0653       bool failed = false;
0654       BOOST_TRY
0655       {
0656         std::ios_base::iostate err = std::ios_base::goodbit;
0657         BOOST_TRY
0658         {
0659           typename std::basic_ostream<CharT, Traits>::sentry opfx(os);
0660           if (bool(opfx))
0661           {
0662             if (!std::has_facet<time_point_put<CharT> >(os.getloc()))
0663             {
0664               if (time_point_put<CharT> ().put(os, os, os.fill(), tp) .failed())
0665               {
0666                 err = std::ios_base::badbit;
0667               }
0668             }
0669             else
0670             {
0671               if (std::use_facet<time_point_put<CharT> >(os.getloc()) .put(os, os, os.fill(), tp).failed())
0672               {
0673                 err = std::ios_base::badbit;
0674               }
0675             }
0676             os.width(0);
0677           }
0678         }
0679         BOOST_CATCH (...)
0680         {
0681           bool flag = false;
0682           BOOST_TRY
0683           {
0684             os.setstate(std::ios_base::failbit);
0685           }
0686           BOOST_CATCH (const std::ios_base::failure& )
0687           {
0688             flag = true;
0689           }
0690           BOOST_CATCH_END
0691           if (flag) throw;
0692         }
0693         BOOST_CATCH_END
0694         if (err) os.setstate(err);
0695         return os;
0696       }
0697       BOOST_CATCH (...)
0698       {
0699         failed = true;
0700       }
0701       BOOST_CATCH_END
0702       if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit);
0703       return os;
0704     }
0705 
0706     template <class CharT, class Traits, class Clock, class Duration>
0707     std::basic_istream<CharT, Traits>&
0708     operator>>(std::basic_istream<CharT, Traits>& is, time_point<Clock, Duration>& tp)
0709     {
0710       std::ios_base::iostate err = std::ios_base::goodbit;
0711 
0712       BOOST_TRY
0713       {
0714         typename std::basic_istream<CharT, Traits>::sentry ipfx(is);
0715         if (bool(ipfx))
0716         {
0717           if (!std::has_facet<time_point_get<CharT> >(is.getloc()))
0718           {
0719             time_point_get<CharT> ().get(is, std::istreambuf_iterator<CharT, Traits>(), is, err, tp);
0720           }
0721           else
0722           {
0723             std::use_facet<time_point_get<CharT> >(is.getloc()).get(is, std::istreambuf_iterator<CharT, Traits>(), is,
0724                 err, tp);
0725           }
0726         }
0727       }
0728       BOOST_CATCH (...)
0729       {
0730         bool flag = false;
0731         BOOST_TRY
0732         {
0733           is.setstate(std::ios_base::failbit);
0734         }
0735         BOOST_CATCH (const std::ios_base::failure& )
0736         {
0737           flag = true;
0738         }
0739         BOOST_CATCH_END
0740         if (flag) throw;
0741       }
0742       BOOST_CATCH_END
0743       if (err) is.setstate(err);
0744       return is;
0745     }
0746 
0747 
0748     namespace detail
0749     {
0750 
0751 //#if defined BOOST_CHRONO_INTERNAL_TIMEGM
0752 
0753     inline int32_t is_leap(int32_t year)
0754     {
0755       if(year % 400 == 0)
0756       return 1;
0757       if(year % 100 == 0)
0758       return 0;
0759       if(year % 4 == 0)
0760       return 1;
0761       return 0;
0762     }
0763     inline int32_t days_from_0(int32_t year)
0764     {
0765       year--;
0766       return 365 * year + (year / 400) - (year/100) + (year / 4);
0767     }
0768     inline int32_t days_from_1970(int32_t year)
0769     {
0770       static const int32_t days_from_0_to_1970 = days_from_0(1970);
0771       return days_from_0(year) - days_from_0_to_1970;
0772     }
0773     inline int32_t days_from_1jan(int32_t year,int32_t month,int32_t day)
0774     {
0775       static const int32_t days[2][12] =
0776       {
0777         { 0,31,59,90,120,151,181,212,243,273,304,334},
0778         { 0,31,60,91,121,152,182,213,244,274,305,335}
0779       };
0780 
0781       return days[is_leap(year)][month-1] + day - 1;
0782     }
0783 
0784     inline time_t internal_timegm(std::tm const *t)
0785     {
0786       int year = t->tm_year + 1900;
0787       int month = t->tm_mon;
0788       if(month > 11)
0789       {
0790         year += month/12;
0791         month %= 12;
0792       }
0793       else if(month < 0)
0794       {
0795         int years_diff = (-month + 11)/12;
0796         year -= years_diff;
0797         month+=12 * years_diff;
0798       }
0799       month++;
0800       int day = t->tm_mday;
0801       int day_of_year = days_from_1jan(year,month,day);
0802       int days_since_epoch = days_from_1970(year) + day_of_year ;
0803 
0804       time_t seconds_in_day = 3600 * 24;
0805       time_t result = seconds_in_day * days_since_epoch + 3600 * t->tm_hour + 60 * t->tm_min + t->tm_sec;
0806 
0807       return result;
0808     }
0809 //#endif
0810 
0811     /**
0812     * from_ymd could be made more efficient by using a table
0813     * day_count_table indexed by the y%400.
0814     * This table could contain the day_count
0815     * by*365 + by/4 - by/100 + by/400
0816     *
0817     * from_ymd = (by/400)*days_by_400_years+day_count_table[by%400] +
0818     * days_in_year_before[is_leap_table[by%400]][m-1] + d;
0819     */
0820     inline unsigned days_before_years(int32_t y)
0821    {
0822      return y * 365 + y / 4 - y / 100 + y / 400;
0823    }
0824 
0825     // Returns year/month/day triple in civil calendar
0826     // Preconditions:  z is number of days since 1970-01-01 and is in the range:
0827     //                   [numeric_limits<Int>::min(), numeric_limits<Int>::max()-719468].
0828     template <class Int>
0829     //constexpr
0830     void
0831     inline civil_from_days(Int z, Int& y, unsigned& m, unsigned& d) BOOST_NOEXCEPT
0832     {
0833         BOOST_STATIC_ASSERT_MSG(std::numeric_limits<unsigned>::digits >= 18,
0834                  "This algorithm has not been ported to a 16 bit unsigned integer");
0835         BOOST_STATIC_ASSERT_MSG(std::numeric_limits<Int>::digits >= 20,
0836                  "This algorithm has not been ported to a 16 bit signed integer");
0837         z += 719468;
0838         const Int era = (z >= 0 ? z : z - 146096) / 146097;
0839         const unsigned doe = static_cast<unsigned>(z - era * 146097);          // [0, 146096]
0840         const unsigned yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365;  // [0, 399]
0841         y = static_cast<Int>(yoe) + era * 400;
0842         const unsigned doy = doe - (365*yoe + yoe/4 - yoe/100);                // [0, 365]
0843         const unsigned mp = (5*doy + 2)/153;                                   // [0, 11]
0844         d = doy - (153*mp+2)/5 + 1;                             // [1, 31]
0845         m = mp + (mp < 10 ? 3 : -9);                            // [1, 12]
0846         y += (m <= 2);
0847         --m;
0848     }
0849    inline std::tm * internal_gmtime(std::time_t const* t, std::tm *tm)
0850    {
0851       if (t==0) return 0;
0852       if (tm==0) return 0;
0853 
0854 #if 0
0855       static  const unsigned char
0856         day_of_year_month[2][366] =
0857            {
0858            { 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 },
0859 
0860            { 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
0861 
0862            } };
0863 
0864       static const int32_t days_in_year_before[2][13] =
0865      {
0866        { -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 },
0867        { -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }
0868      };
0869 #endif
0870 
0871      const time_t seconds_in_day = 3600 * 24;
0872      int32_t days_since_epoch = static_cast<int32_t>(*t / seconds_in_day);
0873      int32_t hms = static_cast<int32_t>(*t - seconds_in_day*days_since_epoch);
0874      if (hms < 0) {
0875        days_since_epoch-=1;
0876        hms = seconds_in_day+hms;
0877      }
0878 
0879 #if 0
0880      int32_t x = days_since_epoch;
0881      int32_t y = static_cast<int32_t> (static_cast<long long> (x + 2) * 400
0882            / 146097);
0883        const int32_t ym1 = y - 1;
0884        int32_t doy = x - days_before_years(y);
0885        const int32_t doy1 = x - days_before_years(ym1);
0886        const int32_t N = std::numeric_limits<int>::digits - 1;
0887        const int32_t mask1 = doy >> N; // arithmetic rshift - not portable - but nearly universal
0888        const int32_t mask0 = ~mask1;
0889        doy = (doy & mask0) | (doy1 & mask1);
0890        y = (y & mask0) | (ym1 & mask1);
0891        //y -= 32767 + 2;
0892        y += 70;
0893        tm->tm_year=y;
0894        const int32_t leap = is_leap(y);
0895        tm->tm_mon = day_of_year_month[leap][doy]-1;
0896        tm->tm_mday = doy - days_in_year_before[leap][tm->tm_mon] ;
0897 #else
0898        int32_t y;
0899        unsigned m, d;
0900        civil_from_days(days_since_epoch, y, m, d);
0901        tm->tm_year=y-1900; tm->tm_mon=m; tm->tm_mday=d;
0902 #endif
0903 
0904      tm->tm_hour = hms / 3600;
0905      const int ms = hms % 3600;
0906      tm->tm_min = ms / 60;
0907      tm->tm_sec = ms % 60;
0908 
0909      tm->tm_isdst = -1;
0910      (void)mktime(tm);
0911      return tm;
0912    }
0913 
0914     } // detail
0915 #ifndef BOOST_CHRONO_NO_UTC_TIMEPOINT
0916 
0917 #if defined BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT
0918 
0919     template <class CharT, class Traits, class Duration>
0920     std::basic_ostream<CharT, Traits>&
0921     operator<<(std::basic_ostream<CharT, Traits>& os, const time_point<system_clock, Duration>& tp)
0922     {
0923       typename std::basic_ostream<CharT, Traits>::sentry ok(os);
0924       if (bool(ok))
0925       {
0926         bool failed = false;
0927         BOOST_TRY
0928         {
0929           const CharT* pb = 0; //nullptr;
0930           const CharT* pe = pb;
0931           std::basic_string<CharT> fmt = get_time_fmt<CharT> (os);
0932           pb = fmt.data();
0933           pe = pb + fmt.size();
0934 
0935           timezone tz = get_timezone(os);
0936           std::locale loc = os.getloc();
0937           time_t t = system_clock::to_time_t(time_point_cast<system_clock::duration>(tp));
0938           std::tm tm;
0939           std::memset(&tm, 0, sizeof(std::tm));
0940           if (tz == timezone::local)
0941           {
0942 #if defined BOOST_WINDOWS && ! defined(__CYGWIN__)
0943 #if BOOST_MSVC < 1400  // localtime_s doesn't exist in vc7.1
0944             std::tm *tmp = 0;
0945             if ((tmp=localtime(&t)) == 0)
0946               failed = true;
0947             else
0948               tm =*tmp;
0949 # else
0950             if (localtime_s(&tm, &t) != 0) failed = true;
0951 # endif
0952 #else
0953             if (localtime_r(&t, &tm) == 0) failed = true;
0954 #endif
0955           }
0956           else
0957           {
0958 #if defined BOOST_CHRONO_INTERNAL_GMTIME
0959             if (detail::internal_gmtime(&t, &tm) == 0) failed = true;
0960 
0961 #elif defined BOOST_WINDOWS && ! defined(__CYGWIN__)
0962             std::tm *tmp = 0;
0963             if((tmp = gmtime(&t)) == 0)
0964               failed = true;
0965             else
0966               tm = *tmp;
0967 #else
0968             if (gmtime_r(&t, &tm) == 0) failed = true;
0969             tm.tm_isdst = -1;
0970             (void)mktime(&tm);
0971 
0972 #endif
0973 
0974           }
0975           if (!failed)
0976           {
0977             const std::time_put<CharT>& tpf = std::use_facet<std::time_put<CharT> >(loc);
0978             if (pb == pe)
0979             {
0980               CharT pattern[] =
0981               { '%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', '%', 'H', ':', '%', 'M', ':' };
0982               pb = pattern;
0983               pe = pb + sizeof (pattern) / sizeof(CharT);
0984               failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed();
0985               if (!failed)
0986               {
0987                 duration<fractional_seconds> d = tp - system_clock::from_time_t(t) + seconds(tm.tm_sec);
0988                 if (d.count() < 10) os << CharT('0');
0989                 //if (! os.good()) {
0990                 //  throw "exception";
0991                 //}
0992                 std::ios::fmtflags flgs = os.flags();
0993                 os.setf(std::ios::fixed, std::ios::floatfield);
0994                 //if (! os.good()) {
0995                 //throw "exception";
0996                 //}
0997                 os.precision(9);
0998                 os << d.count();
0999                 //if (! os.good()) {
1000                 //throw "exception";
1001                 //}
1002                 os.flags(flgs);
1003                 if (tz == timezone::local)
1004                 {
1005                   CharT sub_pattern[] =
1006                   { ' ', '%', 'z' };
1007                   pb = sub_pattern;
1008                   pe = pb + +sizeof (sub_pattern) / sizeof(CharT);
1009                   failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed();
1010                 }
1011                 else
1012                 {
1013                   CharT sub_pattern[] =
1014                   { ' ', '+', '0', '0', '0', '0', 0 };
1015                   os << sub_pattern;
1016                 }
1017               }
1018             }
1019             else
1020             {
1021               failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed();
1022             }
1023           }
1024         }
1025         BOOST_CATCH (...)
1026         {
1027           failed = true;
1028         }
1029         BOOST_CATCH_END
1030         if (failed)
1031         {
1032           os.setstate(std::ios_base::failbit | std::ios_base::badbit);
1033         }
1034       }
1035       return os;
1036     }
1037 #endif
1038 
1039     namespace detail
1040     {
1041 
1042       template <class CharT, class InputIterator>
1043       minutes extract_z(InputIterator& b, InputIterator e, std::ios_base::iostate& err, const std::ctype<CharT>& ct)
1044       {
1045         int min = 0;
1046         if (b != e)
1047         {
1048           char cn = ct.narrow(*b, 0);
1049           if (cn != '+' && cn != '-')
1050           {
1051             err |= std::ios_base::failbit;
1052             return minutes(0);
1053           }
1054           int sn = cn == '-' ? -1 : 1;
1055           int hr = 0;
1056           for (int i = 0; i < 2; ++i)
1057           {
1058             if (++b == e)
1059             {
1060               err |= std::ios_base::eofbit | std::ios_base::failbit;
1061               return minutes(0);
1062             }
1063             cn = ct.narrow(*b, 0);
1064             if (! ('0' <= cn && cn <= '9'))
1065             {
1066               err |= std::ios_base::failbit;
1067               return minutes(0);
1068             }
1069             hr = hr * 10 + cn - '0';
1070           }
1071           for (int i = 0; i < 2; ++i)
1072           {
1073             if (++b == e)
1074             {
1075               err |= std::ios_base::eofbit | std::ios_base::failbit;
1076               return minutes(0);
1077             }
1078             cn = ct.narrow(*b, 0);
1079             if (! ('0' <= cn && cn <= '9'))
1080             {
1081               err |= std::ios_base::failbit;
1082               return minutes(0);
1083             }
1084             min = min * 10 + cn - '0';
1085           }
1086           if (++b == e) {
1087             err |= std::ios_base::eofbit;
1088           }
1089           min += hr * 60;
1090           min *= sn;
1091         }
1092         else
1093         {
1094           err |= std::ios_base::eofbit | std::ios_base::failbit;
1095         }
1096         return minutes(min);
1097       }
1098 
1099     } // detail
1100 
1101 #if defined BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT
1102 
1103     template <class CharT, class Traits, class Duration>
1104     std::basic_istream<CharT, Traits>&
1105     operator>>(std::basic_istream<CharT, Traits>& is, time_point<system_clock, Duration>& tp)
1106     {
1107       typename std::basic_istream<CharT, Traits>::sentry ok(is);
1108       if (bool(ok))
1109       {
1110         std::ios_base::iostate err = std::ios_base::goodbit;
1111         BOOST_TRY
1112         {
1113           const CharT* pb = 0; //nullptr;
1114           const CharT* pe = pb;
1115           std::basic_string<CharT> fmt = get_time_fmt<CharT> (is);
1116           pb = fmt.data();
1117           pe = pb + fmt.size();
1118 
1119           timezone tz = get_timezone(is);
1120           std::locale loc = is.getloc();
1121           const std::time_get<CharT>& tg = std::use_facet<std::time_get<CharT> >(loc);
1122           const std::ctype<CharT>& ct = std::use_facet<std::ctype<CharT> >(loc);
1123           tm tm; // {0}
1124           std::memset(&tm, 0, sizeof(std::tm));
1125 
1126           typedef std::istreambuf_iterator<CharT, Traits> It;
1127           if (pb == pe)
1128           {
1129             CharT pattern[] =
1130             { '%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', '%', 'H', ':', '%', 'M', ':' };
1131             pb = pattern;
1132             pe = pb + sizeof (pattern) / sizeof(CharT);
1133 
1134 #if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET
1135             const detail::time_get<CharT>& dtg(tg);
1136             dtg.get(is, 0, is, err, &tm, pb, pe);
1137 #else
1138             tg.get(is, 0, is, err, &tm, pb, pe);
1139 #endif
1140             if (err & std::ios_base::failbit) goto exit;
1141             fractional_seconds sec;
1142             CharT c = CharT();
1143             std::ios::fmtflags flgs = is.flags();
1144             is.setf(std::ios::fixed, std::ios::floatfield);
1145             is.precision(9);
1146             is >> sec;
1147             is.flags(flgs);
1148             if (is.fail())
1149             {
1150               err |= std::ios_base::failbit;
1151               goto exit;
1152             }
1153             It i(is);
1154             It eof;
1155             c = *i;
1156             if (++i == eof || c != ' ')
1157             {
1158               err |= std::ios_base::failbit;
1159               goto exit;
1160             }
1161             minutes min = detail::extract_z(i, eof, err, ct);
1162 
1163             if (err & std::ios_base::failbit) goto exit;
1164             time_t t;
1165 
1166 #if defined BOOST_CHRONO_INTERNAL_TIMEGM
1167             t = detail::internal_timegm(&tm);
1168 #else
1169             t = timegm(&tm);
1170 #endif
1171             tp = time_point_cast<Duration>(
1172                 system_clock::from_time_t(t) - min + round<system_clock::duration> (duration<fractional_seconds> (sec))
1173                 );
1174           }
1175           else
1176           {
1177             const CharT z[2] =
1178             { '%', 'z' };
1179             const CharT* fz = std::search(pb, pe, z, z + 2);
1180 #if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET
1181             const detail::time_get<CharT>& dtg(tg);
1182             dtg.get(is, 0, is, err, &tm, pb, fz);
1183 #else
1184             tg.get(is, 0, is, err, &tm, pb, fz);
1185 #endif
1186             minutes minu(0);
1187             if (fz != pe)
1188             {
1189               if (err != std::ios_base::goodbit)
1190               {
1191                 err |= std::ios_base::failbit;
1192                 goto exit;
1193               }
1194               It i(is);
1195               It eof;
1196               minu = detail::extract_z(i, eof, err, ct);
1197               if (err & std::ios_base::failbit) goto exit;
1198               if (fz + 2 != pe)
1199               {
1200                 if (err != std::ios_base::goodbit)
1201                 {
1202                   err |= std::ios_base::failbit;
1203                   goto exit;
1204                 }
1205 #if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET
1206                 const detail::time_get<CharT>& dtg(tg);
1207                 dtg.get(is, 0, is, err, &tm, fz + 2, pe);
1208 #else
1209                 tg.get(is, 0, is, err, &tm, fz + 2, pe);
1210 #endif
1211                 if (err & std::ios_base::failbit) goto exit;
1212               }
1213             }
1214             tm.tm_isdst = -1;
1215             time_t t;
1216             if (tz == timezone::utc || fz != pe)
1217             {
1218 #if defined BOOST_CHRONO_INTERNAL_TIMEGM
1219               t = detail::internal_timegm(&tm);
1220 #else
1221               t = timegm(&tm);
1222 #endif
1223             }
1224             else
1225             {
1226               t = mktime(&tm);
1227             }
1228             tp = time_point_cast<Duration>(
1229                 system_clock::from_time_t(t) - minu
1230                 );
1231           }
1232         }
1233         BOOST_CATCH (...)
1234         {
1235           err |= std::ios_base::badbit | std::ios_base::failbit;
1236         }
1237         BOOST_CATCH_END
1238         exit: is.setstate(err);
1239       }
1240       return is;
1241     }
1242 
1243 #endif
1244 #endif //UTC
1245   } // chrono
1246 
1247 }
1248 
1249 #endif  // header