annotate DEPENDENCIES/generic/include/boost/chrono/io/time_point_io.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // (C) Copyright Howard Hinnant
Chris@16 2 // (C) Copyright 2010-2011 Vicente J. Botet Escriba
Chris@16 3 // Use, modification and distribution are subject to the Boost Software License,
Chris@16 4 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 5 // http://www.boost.org/LICENSE_1_0.txt).
Chris@16 6
Chris@16 7 //===-------------------------- locale ------------------------------------===//
Chris@16 8 //
Chris@16 9 // The LLVM Compiler Infrastructure
Chris@16 10 //
Chris@16 11 // This file is dual licensed under the MIT and the University of Illinois Open
Chris@16 12 // Source Licenses. See LICENSE.TXT for details.
Chris@16 13 //
Chris@16 14 //===----------------------------------------------------------------------===//
Chris@16 15
Chris@16 16 // This code was adapted by Vicente from Howard Hinnant's experimental work
Chris@16 17 // on chrono i/o to Boost and some functions from libc++/locale to emulate the missing time_get::get()
Chris@16 18
Chris@16 19 #ifndef BOOST_CHRONO_IO_TIME_POINT_IO_HPP
Chris@16 20 #define BOOST_CHRONO_IO_TIME_POINT_IO_HPP
Chris@16 21
Chris@16 22 #include <boost/chrono/io/time_point_put.hpp>
Chris@16 23 #include <boost/chrono/io/time_point_get.hpp>
Chris@16 24 #include <boost/chrono/io/duration_io.hpp>
Chris@16 25 #include <boost/chrono/io/ios_base_state.hpp>
Chris@16 26 #include <boost/chrono/io/utility/manip_base.hpp>
Chris@16 27 #include <boost/chrono/time_point.hpp>
Chris@16 28 #include <boost/chrono/clock_string.hpp>
Chris@16 29 #include <boost/chrono/round.hpp>
Chris@16 30 #include <boost/chrono/detail/scan_keyword.hpp>
Chris@16 31 #include <boost/static_assert.hpp>
Chris@16 32 #include <boost/detail/no_exceptions_support.hpp>
Chris@16 33 #include <cstring>
Chris@16 34 #include <locale>
Chris@16 35 #include <ctime>
Chris@16 36
Chris@16 37 #define BOOST_CHRONO_INTERNAL_TIMEGM \
Chris@16 38 ( defined BOOST_WINDOWS && ! defined(__CYGWIN__) ) \
Chris@101 39 || (defined(sun) || defined(__sun)) \
Chris@101 40 || (defined __IBMCPP__) \
Chris@101 41 || defined __ANDROID__ \
Chris@101 42 || defined __QNXNTO__ \
Chris@101 43 || (defined(_AIX) && defined __GNUC__)
Chris@16 44
Chris@16 45 #define BOOST_CHRONO_INTERNAL_GMTIME \
Chris@16 46 (defined BOOST_WINDOWS && ! defined(__CYGWIN__)) \
Chris@16 47 || ( (defined(sun) || defined(__sun)) && defined __GNUC__) \
Chris@101 48 || (defined __IBMCPP__) \
Chris@101 49 || defined __ANDROID__ \
Chris@101 50 || (defined(_AIX) && defined __GNUC__)
Chris@16 51
Chris@16 52 #define BOOST_CHRONO_USES_INTERNAL_TIME_GET
Chris@16 53
Chris@16 54 namespace boost
Chris@16 55 {
Chris@16 56 namespace chrono
Chris@16 57 {
Chris@16 58 typedef double fractional_seconds;
Chris@16 59 namespace detail
Chris@16 60 {
Chris@16 61
Chris@16 62
Chris@16 63 template <class CharT, class InputIterator = std::istreambuf_iterator<CharT> >
Chris@16 64 struct time_get
Chris@16 65 {
Chris@16 66 std::time_get<CharT> const &that_;
Chris@16 67 time_get(std::time_get<CharT> const& that) : that_(that) {}
Chris@16 68
Chris@16 69 typedef std::time_get<CharT> facet;
Chris@16 70 typedef typename facet::iter_type iter_type;
Chris@16 71 typedef typename facet::char_type char_type;
Chris@16 72 typedef std::basic_string<char_type> string_type;
Chris@16 73
Chris@16 74 static int
Chris@16 75 get_up_to_n_digits(
Chris@16 76 InputIterator& b, InputIterator e,
Chris@16 77 std::ios_base::iostate& err,
Chris@16 78 const std::ctype<CharT>& ct,
Chris@16 79 int n)
Chris@16 80 {
Chris@16 81 // Precondition: n >= 1
Chris@16 82 if (b == e)
Chris@16 83 {
Chris@16 84 err |= std::ios_base::eofbit | std::ios_base::failbit;
Chris@16 85 return 0;
Chris@16 86 }
Chris@16 87 // get first digit
Chris@16 88 CharT c = *b;
Chris@16 89 if (!ct.is(std::ctype_base::digit, c))
Chris@16 90 {
Chris@16 91 err |= std::ios_base::failbit;
Chris@16 92 return 0;
Chris@16 93 }
Chris@16 94 int r = ct.narrow(c, 0) - '0';
Chris@16 95 for (++b, --n; b != e && n > 0; ++b, --n)
Chris@16 96 {
Chris@16 97 // get next digit
Chris@16 98 c = *b;
Chris@16 99 if (!ct.is(std::ctype_base::digit, c))
Chris@16 100 return r;
Chris@16 101 r = r * 10 + ct.narrow(c, 0) - '0';
Chris@16 102 }
Chris@16 103 if (b == e)
Chris@16 104 err |= std::ios_base::eofbit;
Chris@16 105 return r;
Chris@16 106 }
Chris@16 107
Chris@16 108
Chris@16 109 void get_day(
Chris@16 110 int& d,
Chris@16 111 iter_type& b, iter_type e,
Chris@16 112 std::ios_base::iostate& err,
Chris@16 113 const std::ctype<char_type>& ct) const
Chris@16 114 {
Chris@16 115 int t = get_up_to_n_digits(b, e, err, ct, 2);
Chris@16 116 if (!(err & std::ios_base::failbit) && 1 <= t && t <= 31)
Chris@16 117 d = t;
Chris@16 118 else
Chris@16 119 err |= std::ios_base::failbit;
Chris@16 120 }
Chris@16 121
Chris@16 122 void get_month(
Chris@16 123 int& m,
Chris@16 124 iter_type& b, iter_type e,
Chris@16 125 std::ios_base::iostate& err,
Chris@16 126 const std::ctype<char_type>& ct) const
Chris@16 127 {
Chris@16 128 int t = get_up_to_n_digits(b, e, err, ct, 2) - 1;
Chris@16 129 if (!(err & std::ios_base::failbit) && t <= 11)
Chris@16 130 m = t;
Chris@16 131 else
Chris@16 132 err |= std::ios_base::failbit;
Chris@16 133 }
Chris@16 134
Chris@16 135
Chris@16 136 void get_year4(int& y,
Chris@16 137 iter_type& b, iter_type e,
Chris@16 138 std::ios_base::iostate& err,
Chris@16 139 const std::ctype<char_type>& ct) const
Chris@16 140 {
Chris@16 141 int t = get_up_to_n_digits(b, e, err, ct, 4);
Chris@16 142 if (!(err & std::ios_base::failbit))
Chris@16 143 y = t - 1900;
Chris@16 144 }
Chris@16 145
Chris@16 146 void
Chris@16 147 get_hour(int& h,
Chris@16 148 iter_type& b, iter_type e,
Chris@16 149 std::ios_base::iostate& err,
Chris@16 150 const std::ctype<char_type>& ct) const
Chris@16 151 {
Chris@16 152 int t = get_up_to_n_digits(b, e, err, ct, 2);
Chris@16 153 if (!(err & std::ios_base::failbit) && t <= 23)
Chris@16 154 h = t;
Chris@16 155 else
Chris@16 156 err |= std::ios_base::failbit;
Chris@16 157 }
Chris@16 158
Chris@16 159 void
Chris@16 160 get_minute(int& m,
Chris@16 161 iter_type& b, iter_type e,
Chris@16 162 std::ios_base::iostate& err,
Chris@16 163 const std::ctype<char_type>& ct) const
Chris@16 164 {
Chris@16 165 int t = get_up_to_n_digits(b, e, err, ct, 2);
Chris@16 166 if (!(err & std::ios_base::failbit) && t <= 59)
Chris@16 167 m = t;
Chris@16 168 else
Chris@16 169 err |= std::ios_base::failbit;
Chris@16 170 }
Chris@16 171
Chris@16 172 void get_second(int& s,
Chris@16 173 iter_type& b, iter_type e,
Chris@16 174 std::ios_base::iostate& err,
Chris@16 175 const std::ctype<char_type>& ct) const
Chris@16 176 {
Chris@16 177 int t = get_up_to_n_digits(b, e, err, ct, 2);
Chris@16 178 if (!(err & std::ios_base::failbit) && t <= 60)
Chris@16 179 s = t;
Chris@16 180 else
Chris@16 181 err |= std::ios_base::failbit;
Chris@16 182 }
Chris@16 183
Chris@16 184 void get_white_space(iter_type& b, iter_type e,
Chris@16 185 std::ios_base::iostate& err,
Chris@16 186 const std::ctype<char_type>& ct) const
Chris@16 187 {
Chris@16 188 for (; b != e && ct.is(std::ctype_base::space, *b); ++b)
Chris@16 189 ;
Chris@16 190 if (b == e)
Chris@16 191 err |= std::ios_base::eofbit;
Chris@16 192 }
Chris@16 193
Chris@16 194 void get_12_hour(int& h,
Chris@16 195 iter_type& b, iter_type e,
Chris@16 196 std::ios_base::iostate& err,
Chris@16 197 const std::ctype<char_type>& ct) const
Chris@16 198 {
Chris@16 199 int t = get_up_to_n_digits(b, e, err, ct, 2);
Chris@16 200 if (!(err & std::ios_base::failbit) && 1 <= t && t <= 12)
Chris@16 201 h = t;
Chris@16 202 else
Chris@16 203 err |= std::ios_base::failbit;
Chris@16 204 }
Chris@16 205
Chris@16 206 void get_percent(iter_type& b, iter_type e,
Chris@16 207 std::ios_base::iostate& err,
Chris@16 208 const std::ctype<char_type>& ct) const
Chris@16 209 {
Chris@16 210 if (b == e)
Chris@16 211 {
Chris@16 212 err |= std::ios_base::eofbit | std::ios_base::failbit;
Chris@16 213 return;
Chris@16 214 }
Chris@16 215 if (ct.narrow(*b, 0) != '%')
Chris@16 216 err |= std::ios_base::failbit;
Chris@16 217 else if(++b == e)
Chris@16 218 err |= std::ios_base::eofbit;
Chris@16 219 }
Chris@16 220
Chris@16 221 void get_day_year_num(int& d,
Chris@16 222 iter_type& b, iter_type e,
Chris@16 223 std::ios_base::iostate& err,
Chris@16 224 const std::ctype<char_type>& ct) const
Chris@16 225 {
Chris@16 226 int t = get_up_to_n_digits(b, e, err, ct, 3);
Chris@16 227 if (!(err & std::ios_base::failbit) && t <= 365)
Chris@16 228 d = t;
Chris@16 229 else
Chris@16 230 err |= std::ios_base::failbit;
Chris@16 231 }
Chris@16 232
Chris@16 233 void
Chris@16 234 get_weekday(int& w,
Chris@16 235 iter_type& b, iter_type e,
Chris@16 236 std::ios_base::iostate& err,
Chris@16 237 const std::ctype<char_type>& ct) const
Chris@16 238 {
Chris@16 239 int t = get_up_to_n_digits(b, e, err, ct, 1);
Chris@16 240 if (!(err & std::ios_base::failbit) && t <= 6)
Chris@16 241 w = t;
Chris@16 242 else
Chris@16 243 err |= std::ios_base::failbit;
Chris@16 244 }
Chris@16 245 #if 0
Chris@16 246
Chris@16 247 void
Chris@16 248 get_am_pm(int& h,
Chris@16 249 iter_type& b, iter_type e,
Chris@16 250 std::ios_base::iostate& err,
Chris@16 251 const std::ctype<char_type>& ct) const
Chris@16 252 {
Chris@16 253 const string_type* ap = am_pm();
Chris@16 254 if (ap[0].size() + ap[1].size() == 0)
Chris@16 255 {
Chris@16 256 err |= ios_base::failbit;
Chris@16 257 return;
Chris@16 258 }
Chris@16 259 ptrdiff_t i = detail::scan_keyword(b, e, ap, ap+2, ct, err, false) - ap;
Chris@16 260 if (i == 0 && h == 12)
Chris@16 261 h = 0;
Chris@16 262 else if (i == 1 && h < 12)
Chris@16 263 h += 12;
Chris@16 264 }
Chris@16 265
Chris@16 266 #endif
Chris@16 267
Chris@16 268 InputIterator get(
Chris@16 269 iter_type b, iter_type e,
Chris@16 270 std::ios_base& iob,
Chris@16 271 std::ios_base::iostate& err,
Chris@16 272 std::tm* tm,
Chris@16 273 char fmt, char) const
Chris@16 274 {
Chris@16 275 err = std::ios_base::goodbit;
Chris@16 276 const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(iob.getloc());
Chris@16 277
Chris@16 278 switch (fmt)
Chris@16 279 {
Chris@16 280 case 'a':
Chris@16 281 case 'A':
Chris@16 282 {
Chris@16 283 std::tm tm2;
Chris@16 284 std::memset(&tm2, 0, sizeof(std::tm));
Chris@16 285 that_.get_weekday(b, e, iob, err, &tm2);
Chris@16 286 //tm->tm_wday = tm2.tm_wday;
Chris@16 287 }
Chris@16 288 break;
Chris@16 289 case 'b':
Chris@16 290 case 'B':
Chris@16 291 case 'h':
Chris@16 292 {
Chris@16 293 std::tm tm2;
Chris@16 294 std::memset(&tm2, 0, sizeof(std::tm));
Chris@16 295 that_.get_monthname(b, e, iob, err, &tm2);
Chris@16 296 //tm->tm_mon = tm2.tm_mon;
Chris@16 297 }
Chris@16 298 break;
Chris@16 299 // case 'c':
Chris@16 300 // {
Chris@16 301 // const string_type& fm = c();
Chris@16 302 // b = get(b, e, iob, err, tm, fm.data(), fm.data() + fm.size());
Chris@16 303 // }
Chris@16 304 // break;
Chris@16 305 case 'd':
Chris@16 306 case 'e':
Chris@16 307 get_day(tm->tm_mday, b, e, err, ct);
Chris@16 308 break;
Chris@16 309 case 'D':
Chris@16 310 {
Chris@16 311 const char_type fm[] = {'%', 'm', '/', '%', 'd', '/', '%', 'y'};
Chris@16 312 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
Chris@16 313 }
Chris@16 314 break;
Chris@16 315 case 'F':
Chris@16 316 {
Chris@16 317 const char_type fm[] = {'%', 'Y', '-', '%', 'm', '-', '%', 'd'};
Chris@16 318 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
Chris@16 319 }
Chris@16 320 break;
Chris@16 321 case 'H':
Chris@16 322 get_hour(tm->tm_hour, b, e, err, ct);
Chris@16 323 break;
Chris@16 324 case 'I':
Chris@16 325 get_12_hour(tm->tm_hour, b, e, err, ct);
Chris@16 326 break;
Chris@16 327 case 'j':
Chris@16 328 get_day_year_num(tm->tm_yday, b, e, err, ct);
Chris@16 329 break;
Chris@16 330 case 'm':
Chris@16 331 get_month(tm->tm_mon, b, e, err, ct);
Chris@16 332 break;
Chris@16 333 case 'M':
Chris@16 334 get_minute(tm->tm_min, b, e, err, ct);
Chris@16 335 break;
Chris@16 336 case 'n':
Chris@16 337 case 't':
Chris@16 338 get_white_space(b, e, err, ct);
Chris@16 339 break;
Chris@16 340 // case 'p':
Chris@16 341 // get_am_pm(tm->tm_hour, b, e, err, ct);
Chris@16 342 // break;
Chris@16 343 case 'r':
Chris@16 344 {
Chris@16 345 const char_type fm[] = {'%', 'I', ':', '%', 'M', ':', '%', 'S', ' ', '%', 'p'};
Chris@16 346 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
Chris@16 347 }
Chris@16 348 break;
Chris@16 349 case 'R':
Chris@16 350 {
Chris@16 351 const char_type fm[] = {'%', 'H', ':', '%', 'M'};
Chris@16 352 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
Chris@16 353 }
Chris@16 354 break;
Chris@16 355 case 'S':
Chris@16 356 get_second(tm->tm_sec, b, e, err, ct);
Chris@16 357 break;
Chris@16 358 case 'T':
Chris@16 359 {
Chris@16 360 const char_type fm[] = {'%', 'H', ':', '%', 'M', ':', '%', 'S'};
Chris@16 361 b = get(b, e, iob, err, tm, fm, fm + sizeof(fm)/sizeof(fm[0]));
Chris@16 362 }
Chris@16 363 break;
Chris@16 364 case 'w':
Chris@16 365 {
Chris@16 366 get_weekday(tm->tm_wday, b, e, err, ct);
Chris@16 367 }
Chris@16 368 break;
Chris@16 369 case 'x':
Chris@16 370 return that_.get_date(b, e, iob, err, tm);
Chris@16 371 // case 'X':
Chris@16 372 // return that_.get_time(b, e, iob, err, tm);
Chris@16 373 // {
Chris@16 374 // const string_type& fm = X();
Chris@16 375 // b = that_.get(b, e, iob, err, tm, fm.data(), fm.data() + fm.size());
Chris@16 376 // }
Chris@16 377 // break;
Chris@16 378 // case 'y':
Chris@16 379 // get_year(tm->tm_year, b, e, err, ct);
Chris@16 380 break;
Chris@16 381 case 'Y':
Chris@16 382 get_year4(tm->tm_year, b, e, err, ct);
Chris@16 383 break;
Chris@16 384 case '%':
Chris@16 385 get_percent(b, e, err, ct);
Chris@16 386 break;
Chris@16 387 default:
Chris@16 388 err |= std::ios_base::failbit;
Chris@16 389 }
Chris@16 390 return b;
Chris@16 391 }
Chris@16 392
Chris@16 393
Chris@16 394 InputIterator get(
Chris@16 395 iter_type b, iter_type e,
Chris@16 396 std::ios_base& iob,
Chris@16 397 std::ios_base::iostate& err, std::tm* tm,
Chris@16 398 const char_type* fmtb, const char_type* fmte) const
Chris@16 399 {
Chris@16 400 const std::ctype<char_type>& ct = std::use_facet<std::ctype<char_type> >(iob.getloc());
Chris@16 401 err = std::ios_base::goodbit;
Chris@16 402 while (fmtb != fmte && err == std::ios_base::goodbit)
Chris@16 403 {
Chris@16 404 if (b == e)
Chris@16 405 {
Chris@16 406 err = std::ios_base::failbit;
Chris@16 407 break;
Chris@16 408 }
Chris@16 409 if (ct.narrow(*fmtb, 0) == '%')
Chris@16 410 {
Chris@16 411 if (++fmtb == fmte)
Chris@16 412 {
Chris@16 413 err = std::ios_base::failbit;
Chris@16 414 break;
Chris@16 415 }
Chris@16 416 char cmd = ct.narrow(*fmtb, 0);
Chris@16 417 char opt = '\0';
Chris@16 418 if (cmd == 'E' || cmd == '0')
Chris@16 419 {
Chris@16 420 if (++fmtb == fmte)
Chris@16 421 {
Chris@16 422 err = std::ios_base::failbit;
Chris@16 423 break;
Chris@16 424 }
Chris@16 425 opt = cmd;
Chris@16 426 cmd = ct.narrow(*fmtb, 0);
Chris@16 427 }
Chris@16 428 b = get(b, e, iob, err, tm, cmd, opt);
Chris@16 429 ++fmtb;
Chris@16 430 }
Chris@16 431 else if (ct.is(std::ctype_base::space, *fmtb))
Chris@16 432 {
Chris@16 433 for (++fmtb; fmtb != fmte && ct.is(std::ctype_base::space, *fmtb); ++fmtb)
Chris@16 434 ;
Chris@16 435 for ( ; b != e && ct.is(std::ctype_base::space, *b); ++b)
Chris@16 436 ;
Chris@16 437 }
Chris@16 438 else if (ct.toupper(*b) == ct.toupper(*fmtb))
Chris@16 439 {
Chris@16 440 ++b;
Chris@16 441 ++fmtb;
Chris@16 442 }
Chris@16 443 else
Chris@16 444 err = std::ios_base::failbit;
Chris@16 445 }
Chris@16 446 if (b == e)
Chris@16 447 err |= std::ios_base::eofbit;
Chris@16 448 return b;
Chris@16 449 }
Chris@16 450
Chris@16 451 };
Chris@16 452
Chris@16 453
Chris@16 454 template <class CharT>
Chris@16 455 class time_manip: public manip<time_manip<CharT> >
Chris@16 456 {
Chris@16 457 std::basic_string<CharT> fmt_;
Chris@16 458 timezone tz_;
Chris@16 459 public:
Chris@16 460
Chris@16 461 time_manip(timezone tz, std::basic_string<CharT> fmt)
Chris@16 462 // todo move semantics
Chris@16 463 :
Chris@16 464 fmt_(fmt), tz_(tz)
Chris@16 465 {
Chris@16 466 }
Chris@16 467
Chris@16 468 /**
Chris@16 469 * Change the timezone and time format ios state;
Chris@16 470 */
Chris@16 471 void operator()(std::ios_base &ios) const
Chris@16 472 {
Chris@16 473 set_time_fmt<CharT> (ios, fmt_);
Chris@16 474 set_timezone(ios, tz_);
Chris@16 475 }
Chris@16 476 };
Chris@16 477
Chris@16 478 class time_man: public manip<time_man>
Chris@16 479 {
Chris@16 480 timezone tz_;
Chris@16 481 public:
Chris@16 482
Chris@16 483 time_man(timezone tz)
Chris@16 484 // todo move semantics
Chris@16 485 :
Chris@16 486 tz_(tz)
Chris@16 487 {
Chris@16 488 }
Chris@16 489
Chris@16 490 /**
Chris@16 491 * Change the timezone and time format ios state;
Chris@16 492 */
Chris@16 493 void operator()(std::ios_base &ios) const
Chris@16 494 {
Chris@16 495 //set_time_fmt<typename out_stream::char_type>(ios, "");
Chris@16 496 set_timezone(ios, tz_);
Chris@16 497 }
Chris@16 498 };
Chris@16 499
Chris@16 500 }
Chris@16 501
Chris@16 502 template <class CharT>
Chris@16 503 inline detail::time_manip<CharT> time_fmt(timezone tz, const CharT* fmt)
Chris@16 504 {
Chris@16 505 return detail::time_manip<CharT>(tz, fmt);
Chris@16 506 }
Chris@16 507
Chris@16 508 template <class CharT>
Chris@16 509 inline detail::time_manip<CharT> time_fmt(timezone tz, std::basic_string<CharT> fmt)
Chris@16 510 {
Chris@16 511 // todo move semantics
Chris@16 512 return detail::time_manip<CharT>(tz, fmt);
Chris@16 513 }
Chris@16 514
Chris@16 515 inline detail::time_man time_fmt(timezone f)
Chris@16 516 {
Chris@16 517 return detail::time_man(f);
Chris@16 518 }
Chris@16 519
Chris@16 520 /**
Chris@16 521 * time_fmt_io_saver i/o saver.
Chris@16 522 *
Chris@16 523 * See Boost.IO i/o state savers for a motivating compression.
Chris@16 524 */
Chris@16 525 template <typename CharT = char, typename Traits = std::char_traits<CharT> >
Chris@16 526 struct time_fmt_io_saver
Chris@16 527 {
Chris@16 528
Chris@16 529 //! the type of the state to restore
Chris@101 530 //typedef std::basic_ostream<CharT, Traits> state_type;
Chris@101 531 typedef std::ios_base state_type;
Chris@101 532
Chris@16 533 //! the type of aspect to save
Chris@16 534 typedef std::basic_string<CharT, Traits> aspect_type;
Chris@16 535
Chris@16 536 /**
Chris@16 537 * Explicit construction from an i/o stream.
Chris@16 538 *
Chris@16 539 * Store a reference to the i/o stream and the value of the associated @c time format .
Chris@16 540 */
Chris@16 541 explicit time_fmt_io_saver(state_type &s) :
Chris@101 542 s_save_(s), a_save_(get_time_fmt<CharT>(s_save_))
Chris@16 543 {
Chris@16 544 }
Chris@16 545
Chris@16 546 /**
Chris@16 547 * Construction from an i/o stream and a @c time format to restore.
Chris@16 548 *
Chris@16 549 * Stores a reference to the i/o stream and the value @c new_value to restore given as parameter.
Chris@16 550 */
Chris@16 551 time_fmt_io_saver(state_type &s, aspect_type new_value) :
Chris@101 552 s_save_(s), a_save_(get_time_fmt<CharT>(s_save_))
Chris@16 553 {
Chris@101 554 set_time_fmt(s_save_, new_value);
Chris@16 555 }
Chris@16 556
Chris@16 557 /**
Chris@16 558 * Destructor.
Chris@16 559 *
Chris@16 560 * Restores the i/o stream with the format to be restored.
Chris@16 561 */
Chris@16 562 ~time_fmt_io_saver()
Chris@16 563 {
Chris@16 564 this->restore();
Chris@16 565 }
Chris@16 566
Chris@16 567 /**
Chris@16 568 * Restores the i/o stream with the time format to be restored.
Chris@16 569 */
Chris@16 570 void restore()
Chris@16 571 {
Chris@101 572 set_time_fmt(s_save_, a_save_);
Chris@16 573 }
Chris@16 574 private:
Chris@16 575 state_type& s_save_;
Chris@16 576 aspect_type a_save_;
Chris@16 577 };
Chris@16 578
Chris@16 579 /**
Chris@16 580 * timezone_io_saver i/o saver.
Chris@16 581 *
Chris@16 582 * See Boost.IO i/o state savers for a motivating compression.
Chris@16 583 */
Chris@16 584 struct timezone_io_saver
Chris@16 585 {
Chris@16 586
Chris@16 587 //! the type of the state to restore
Chris@16 588 typedef std::ios_base state_type;
Chris@16 589 //! the type of aspect to save
Chris@16 590 typedef timezone aspect_type;
Chris@16 591
Chris@16 592 /**
Chris@16 593 * Explicit construction from an i/o stream.
Chris@16 594 *
Chris@16 595 * Store a reference to the i/o stream and the value of the associated @c timezone.
Chris@16 596 */
Chris@16 597 explicit timezone_io_saver(state_type &s) :
Chris@16 598 s_save_(s), a_save_(get_timezone(s_save_))
Chris@16 599 {
Chris@16 600 }
Chris@16 601
Chris@16 602 /**
Chris@16 603 * Construction from an i/o stream and a @c timezone to restore.
Chris@16 604 *
Chris@16 605 * Stores a reference to the i/o stream and the value @c new_value to restore given as parameter.
Chris@16 606 */
Chris@16 607 timezone_io_saver(state_type &s, aspect_type new_value) :
Chris@101 608 s_save_(s), a_save_(get_timezone(s_save_))
Chris@16 609 {
Chris@101 610 set_timezone(s_save_, new_value);
Chris@16 611 }
Chris@16 612
Chris@16 613 /**
Chris@16 614 * Destructor.
Chris@16 615 *
Chris@16 616 * Restores the i/o stream with the format to be restored.
Chris@16 617 */
Chris@16 618 ~timezone_io_saver()
Chris@16 619 {
Chris@16 620 this->restore();
Chris@16 621 }
Chris@16 622
Chris@16 623 /**
Chris@16 624 * Restores the i/o stream with the timezone to be restored.
Chris@16 625 */
Chris@16 626 void restore()
Chris@16 627 {
Chris@16 628 set_timezone(s_save_, a_save_);
Chris@16 629 }
Chris@16 630 private:
Chris@16 631 timezone_io_saver& operator=(timezone_io_saver const& rhs) ;
Chris@16 632
Chris@16 633 state_type& s_save_;
Chris@16 634 aspect_type a_save_;
Chris@16 635 };
Chris@16 636
Chris@16 637 /**
Chris@16 638 *
Chris@16 639 * @param os
Chris@16 640 * @param tp
Chris@16 641 * @Effects Behaves as a formatted output function. After constructing a @c sentry object, if the @ sentry
Chris@16 642 * converts to true, calls to @c facet.put(os,os,os.fill(),tp) where @c facet is the @c time_point_put<CharT>
Chris@16 643 * facet associated to @c os or a new created instance of the default @c time_point_put<CharT> facet.
Chris@16 644 * @return @c os.
Chris@16 645 */
Chris@16 646 template <class CharT, class Traits, class Clock, class Duration>
Chris@16 647 std::basic_ostream<CharT, Traits>&
Chris@16 648 operator<<(std::basic_ostream<CharT, Traits>& os, const time_point<Clock, Duration>& tp)
Chris@16 649 {
Chris@16 650
Chris@16 651 bool failed = false;
Chris@16 652 BOOST_TRY
Chris@16 653 {
Chris@16 654 std::ios_base::iostate err = std::ios_base::goodbit;
Chris@16 655 BOOST_TRY
Chris@16 656 {
Chris@16 657 typename std::basic_ostream<CharT, Traits>::sentry opfx(os);
Chris@16 658 if (bool(opfx))
Chris@16 659 {
Chris@16 660 if (!std::has_facet<time_point_put<CharT> >(os.getloc()))
Chris@16 661 {
Chris@16 662 if (time_point_put<CharT> ().put(os, os, os.fill(), tp) .failed())
Chris@16 663 {
Chris@16 664 err = std::ios_base::badbit;
Chris@16 665 }
Chris@16 666 }
Chris@16 667 else
Chris@16 668 {
Chris@16 669 if (std::use_facet<time_point_put<CharT> >(os.getloc()) .put(os, os, os.fill(), tp).failed())
Chris@16 670 {
Chris@16 671 err = std::ios_base::badbit;
Chris@16 672 }
Chris@16 673 }
Chris@16 674 os.width(0);
Chris@16 675 }
Chris@16 676 }
Chris@16 677 BOOST_CATCH (...)
Chris@16 678 {
Chris@16 679 bool flag = false;
Chris@16 680 BOOST_TRY
Chris@16 681 {
Chris@16 682 os.setstate(std::ios_base::failbit);
Chris@16 683 }
Chris@16 684 BOOST_CATCH (std::ios_base::failure )
Chris@16 685 {
Chris@16 686 flag = true;
Chris@16 687 }
Chris@16 688 BOOST_CATCH_END
Chris@16 689 if (flag) throw;
Chris@16 690 }
Chris@16 691 BOOST_CATCH_END
Chris@16 692 if (err) os.setstate(err);
Chris@16 693 return os;
Chris@16 694 }
Chris@16 695 BOOST_CATCH (...)
Chris@16 696 {
Chris@16 697 failed = true;
Chris@16 698 }
Chris@16 699 BOOST_CATCH_END
Chris@16 700 if (failed) os.setstate(std::ios_base::failbit | std::ios_base::badbit);
Chris@16 701 return os;
Chris@16 702 }
Chris@16 703
Chris@16 704 template <class CharT, class Traits, class Clock, class Duration>
Chris@16 705 std::basic_istream<CharT, Traits>&
Chris@16 706 operator>>(std::basic_istream<CharT, Traits>& is, time_point<Clock, Duration>& tp)
Chris@16 707 {
Chris@16 708 std::ios_base::iostate err = std::ios_base::goodbit;
Chris@16 709
Chris@16 710 BOOST_TRY
Chris@16 711 {
Chris@16 712 typename std::basic_istream<CharT, Traits>::sentry ipfx(is);
Chris@16 713 if (bool(ipfx))
Chris@16 714 {
Chris@16 715 if (!std::has_facet<time_point_get<CharT> >(is.getloc()))
Chris@16 716 {
Chris@16 717 time_point_get<CharT> ().get(is, std::istreambuf_iterator<CharT, Traits>(), is, err, tp);
Chris@16 718 }
Chris@16 719 else
Chris@16 720 {
Chris@16 721 std::use_facet<time_point_get<CharT> >(is.getloc()).get(is, std::istreambuf_iterator<CharT, Traits>(), is,
Chris@16 722 err, tp);
Chris@16 723 }
Chris@16 724 }
Chris@16 725 }
Chris@16 726 BOOST_CATCH (...)
Chris@16 727 {
Chris@16 728 bool flag = false;
Chris@16 729 BOOST_TRY
Chris@16 730 {
Chris@16 731 is.setstate(std::ios_base::failbit);
Chris@16 732 }
Chris@16 733 BOOST_CATCH (std::ios_base::failure )
Chris@16 734 {
Chris@16 735 flag = true;
Chris@16 736 }
Chris@16 737 BOOST_CATCH_END
Chris@16 738 if (flag) throw;
Chris@16 739 }
Chris@16 740 BOOST_CATCH_END
Chris@16 741 if (err) is.setstate(err);
Chris@16 742 return is;
Chris@16 743 }
Chris@16 744
Chris@16 745
Chris@16 746 namespace detail
Chris@16 747 {
Chris@16 748
Chris@101 749 //#if BOOST_CHRONO_INTERNAL_TIMEGM
Chris@101 750
Chris@16 751 inline int32_t is_leap(int32_t year)
Chris@16 752 {
Chris@16 753 if(year % 400 == 0)
Chris@16 754 return 1;
Chris@16 755 if(year % 100 == 0)
Chris@16 756 return 0;
Chris@16 757 if(year % 4 == 0)
Chris@16 758 return 1;
Chris@16 759 return 0;
Chris@16 760 }
Chris@16 761 inline int32_t days_from_0(int32_t year)
Chris@16 762 {
Chris@16 763 year--;
Chris@16 764 return 365 * year + (year / 400) - (year/100) + (year / 4);
Chris@16 765 }
Chris@16 766 inline int32_t days_from_1970(int32_t year)
Chris@16 767 {
Chris@16 768 static const int days_from_0_to_1970 = days_from_0(1970);
Chris@16 769 return days_from_0(year) - days_from_0_to_1970;
Chris@16 770 }
Chris@16 771 inline int32_t days_from_1jan(int32_t year,int32_t month,int32_t day)
Chris@16 772 {
Chris@16 773 static const int32_t days[2][12] =
Chris@16 774 {
Chris@16 775 { 0,31,59,90,120,151,181,212,243,273,304,334},
Chris@16 776 { 0,31,60,91,121,152,182,213,244,274,305,335}
Chris@16 777 };
Chris@16 778
Chris@16 779 return days[is_leap(year)][month-1] + day - 1;
Chris@16 780 }
Chris@16 781
Chris@16 782 inline time_t internal_timegm(std::tm const *t)
Chris@16 783 {
Chris@16 784 int year = t->tm_year + 1900;
Chris@16 785 int month = t->tm_mon;
Chris@16 786 if(month > 11)
Chris@16 787 {
Chris@16 788 year += month/12;
Chris@16 789 month %= 12;
Chris@16 790 }
Chris@16 791 else if(month < 0)
Chris@16 792 {
Chris@16 793 int years_diff = (-month + 11)/12;
Chris@16 794 year -= years_diff;
Chris@16 795 month+=12 * years_diff;
Chris@16 796 }
Chris@16 797 month++;
Chris@16 798 int day = t->tm_mday;
Chris@16 799 int day_of_year = days_from_1jan(year,month,day);
Chris@16 800 int days_since_epoch = days_from_1970(year) + day_of_year ;
Chris@16 801
Chris@16 802 time_t seconds_in_day = 3600 * 24;
Chris@16 803 time_t result = seconds_in_day * days_since_epoch + 3600 * t->tm_hour + 60 * t->tm_min + t->tm_sec;
Chris@16 804
Chris@16 805 return result;
Chris@16 806 }
Chris@101 807 //#endif
Chris@16 808
Chris@16 809 /**
Chris@16 810 * from_ymd could be made more efficient by using a table
Chris@16 811 * day_count_table indexed by the y%400.
Chris@16 812 * This table could contain the day_count
Chris@16 813 * by*365 + by/4 - by/100 + by/400
Chris@16 814 *
Chris@16 815 * from_ymd = (by/400)*days_by_400_years+day_count_table[by%400] +
Chris@16 816 * days_in_year_before[is_leap_table[by%400]][m-1] + d;
Chris@16 817 */
Chris@16 818 inline unsigned days_before_years(int32_t y)
Chris@16 819 {
Chris@16 820 return y * 365 + y / 4 - y / 100 + y / 400;
Chris@16 821 }
Chris@16 822
Chris@16 823 // Returns year/month/day triple in civil calendar
Chris@16 824 // Preconditions: z is number of days since 1970-01-01 and is in the range:
Chris@16 825 // [numeric_limits<Int>::min(), numeric_limits<Int>::max()-719468].
Chris@16 826 template <class Int>
Chris@16 827 //constexpr
Chris@16 828 void
Chris@16 829 inline civil_from_days(Int z, Int& y, unsigned& m, unsigned& d) BOOST_NOEXCEPT
Chris@16 830 {
Chris@16 831 BOOST_STATIC_ASSERT_MSG(std::numeric_limits<unsigned>::digits >= 18,
Chris@16 832 "This algorithm has not been ported to a 16 bit unsigned integer");
Chris@16 833 BOOST_STATIC_ASSERT_MSG(std::numeric_limits<Int>::digits >= 20,
Chris@16 834 "This algorithm has not been ported to a 16 bit signed integer");
Chris@16 835 z += 719468;
Chris@16 836 const Int era = (z >= 0 ? z : z - 146096) / 146097;
Chris@16 837 const unsigned doe = static_cast<unsigned>(z - era * 146097); // [0, 146096]
Chris@16 838 const unsigned yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365; // [0, 399]
Chris@16 839 y = static_cast<Int>(yoe) + era * 400;
Chris@16 840 const unsigned doy = doe - (365*yoe + yoe/4 - yoe/100); // [0, 365]
Chris@16 841 const unsigned mp = (5*doy + 2)/153; // [0, 11]
Chris@16 842 d = doy - (153*mp+2)/5 + 1; // [1, 31]
Chris@16 843 m = mp + (mp < 10 ? 3 : -9); // [1, 12]
Chris@16 844 y += (m <= 2);
Chris@16 845 --m;
Chris@16 846 }
Chris@16 847 inline std::tm * internal_gmtime(std::time_t const* t, std::tm *tm)
Chris@16 848 {
Chris@16 849 if (t==0) return 0;
Chris@16 850 if (tm==0) return 0;
Chris@16 851
Chris@16 852 #if 0
Chris@16 853 static const unsigned char
Chris@16 854 day_of_year_month[2][366] =
Chris@16 855 {
Chris@16 856 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 },
Chris@16 857
Chris@16 858 { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12
Chris@16 859
Chris@16 860 } };
Chris@16 861
Chris@16 862 static const int32_t days_in_year_before[2][13] =
Chris@16 863 {
Chris@16 864 { -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 },
Chris@16 865 { -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }
Chris@16 866 };
Chris@16 867 #endif
Chris@16 868
Chris@16 869 const time_t seconds_in_day = 3600 * 24;
Chris@16 870 int32_t days_since_epoch = static_cast<int32_t>(*t / seconds_in_day);
Chris@16 871 int32_t hms = static_cast<int32_t>(*t - seconds_in_day*days_since_epoch);
Chris@16 872 if (hms < 0) {
Chris@16 873 days_since_epoch-=1;
Chris@16 874 hms = seconds_in_day+hms;
Chris@16 875 }
Chris@16 876
Chris@16 877 #if 0
Chris@16 878 int32_t x = days_since_epoch;
Chris@16 879 int32_t y = static_cast<int32_t> (static_cast<long long> (x + 2) * 400
Chris@16 880 / 146097);
Chris@16 881 const int32_t ym1 = y - 1;
Chris@16 882 int32_t doy = x - days_before_years(y);
Chris@16 883 const int32_t doy1 = x - days_before_years(ym1);
Chris@16 884 const int32_t N = std::numeric_limits<int>::digits - 1;
Chris@16 885 const int32_t mask1 = doy >> N; // arithmetic rshift - not portable - but nearly universal
Chris@16 886 const int32_t mask0 = ~mask1;
Chris@16 887 doy = (doy & mask0) | (doy1 & mask1);
Chris@16 888 y = (y & mask0) | (ym1 & mask1);
Chris@16 889 //y -= 32767 + 2;
Chris@16 890 y += 70;
Chris@16 891 tm->tm_year=y;
Chris@16 892 const int32_t leap = is_leap(y);
Chris@16 893 tm->tm_mon = day_of_year_month[leap][doy]-1;
Chris@16 894 tm->tm_mday = doy - days_in_year_before[leap][tm->tm_mon] ;
Chris@16 895 #else
Chris@16 896 int32_t y;
Chris@16 897 unsigned m, d;
Chris@16 898 civil_from_days(days_since_epoch, y, m, d);
Chris@16 899 tm->tm_year=y-1900; tm->tm_mon=m; tm->tm_mday=d;
Chris@16 900 #endif
Chris@16 901
Chris@16 902 tm->tm_hour = hms / 3600;
Chris@16 903 const int ms = hms % 3600;
Chris@16 904 tm->tm_min = ms / 60;
Chris@16 905 tm->tm_sec = ms % 60;
Chris@16 906
Chris@16 907 tm->tm_isdst = -1;
Chris@16 908 (void)mktime(tm);
Chris@16 909 return tm;
Chris@16 910 }
Chris@16 911
Chris@16 912 } // detail
Chris@16 913 #ifndef BOOST_CHRONO_NO_UTC_TIMEPOINT
Chris@16 914
Chris@16 915 #if defined BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT
Chris@16 916
Chris@16 917 template <class CharT, class Traits, class Duration>
Chris@16 918 std::basic_ostream<CharT, Traits>&
Chris@16 919 operator<<(std::basic_ostream<CharT, Traits>& os, const time_point<system_clock, Duration>& tp)
Chris@16 920 {
Chris@16 921 typename std::basic_ostream<CharT, Traits>::sentry ok(os);
Chris@16 922 if (bool(ok))
Chris@16 923 {
Chris@16 924 bool failed = false;
Chris@16 925 BOOST_TRY
Chris@16 926 {
Chris@16 927 const CharT* pb = 0; //nullptr;
Chris@16 928 const CharT* pe = pb;
Chris@16 929 std::basic_string<CharT> fmt = get_time_fmt<CharT> (os);
Chris@16 930 pb = fmt.data();
Chris@16 931 pe = pb + fmt.size();
Chris@16 932
Chris@16 933 timezone tz = get_timezone(os);
Chris@16 934 std::locale loc = os.getloc();
Chris@16 935 time_t t = system_clock::to_time_t(time_point_cast<system_clock::duration>(tp));
Chris@16 936 std::tm tm;
Chris@16 937 std::memset(&tm, 0, sizeof(std::tm));
Chris@16 938 if (tz == timezone::local)
Chris@16 939 {
Chris@16 940 #if defined BOOST_WINDOWS && ! defined(__CYGWIN__)
Chris@16 941 std::tm *tmp = 0;
Chris@16 942 if ((tmp=localtime(&t)) == 0)
Chris@16 943 failed = true;
Chris@16 944 else
Chris@16 945 tm =*tmp;
Chris@16 946 #else
Chris@16 947 if (localtime_r(&t, &tm) == 0) failed = true;
Chris@16 948 #endif
Chris@16 949 }
Chris@16 950 else
Chris@16 951 {
Chris@16 952 #if BOOST_CHRONO_INTERNAL_GMTIME
Chris@16 953 if (detail::internal_gmtime(&t, &tm) == 0) failed = true;
Chris@16 954
Chris@16 955 #elif defined BOOST_WINDOWS && ! defined(__CYGWIN__)
Chris@16 956 std::tm *tmp = 0;
Chris@16 957 if((tmp = gmtime(&t)) == 0)
Chris@16 958 failed = true;
Chris@16 959 else
Chris@16 960 tm = *tmp;
Chris@16 961 #else
Chris@16 962 if (gmtime_r(&t, &tm) == 0) failed = true;
Chris@16 963 tm.tm_isdst = -1;
Chris@16 964 (void)mktime(&tm);
Chris@16 965
Chris@16 966 #endif
Chris@16 967
Chris@16 968 }
Chris@16 969 if (!failed)
Chris@16 970 {
Chris@16 971 const std::time_put<CharT>& tpf = std::use_facet<std::time_put<CharT> >(loc);
Chris@16 972 if (pb == pe)
Chris@16 973 {
Chris@16 974 CharT pattern[] =
Chris@16 975 { '%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', '%', 'H', ':', '%', 'M', ':' };
Chris@16 976 pb = pattern;
Chris@16 977 pe = pb + sizeof (pattern) / sizeof(CharT);
Chris@16 978 failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed();
Chris@16 979 if (!failed)
Chris@16 980 {
Chris@16 981 duration<fractional_seconds> d = tp - system_clock::from_time_t(t) + seconds(tm.tm_sec);
Chris@16 982 if (d.count() < 10) os << CharT('0');
Chris@16 983 //if (! os.good()) {
Chris@16 984 // throw "exception";
Chris@16 985 //}
Chris@16 986 std::ios::fmtflags flgs = os.flags();
Chris@16 987 os.setf(std::ios::fixed, std::ios::floatfield);
Chris@16 988 //if (! os.good()) {
Chris@16 989 //throw "exception";
Chris@16 990 //}
Chris@16 991 os.precision(9);
Chris@16 992 os << d.count();
Chris@16 993 //if (! os.good()) {
Chris@16 994 //throw "exception";
Chris@16 995 //}
Chris@16 996 os.flags(flgs);
Chris@16 997 if (tz == timezone::local)
Chris@16 998 {
Chris@16 999 CharT sub_pattern[] =
Chris@16 1000 { ' ', '%', 'z' };
Chris@16 1001 pb = sub_pattern;
Chris@16 1002 pe = pb + +sizeof (sub_pattern) / sizeof(CharT);
Chris@16 1003 failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed();
Chris@16 1004 }
Chris@16 1005 else
Chris@16 1006 {
Chris@16 1007 CharT sub_pattern[] =
Chris@16 1008 { ' ', '+', '0', '0', '0', '0', 0 };
Chris@16 1009 os << sub_pattern;
Chris@16 1010 }
Chris@16 1011 }
Chris@16 1012 }
Chris@16 1013 else
Chris@16 1014 {
Chris@16 1015 failed = tpf.put(os, os, os.fill(), &tm, pb, pe).failed();
Chris@16 1016 }
Chris@16 1017 }
Chris@16 1018 }
Chris@16 1019 BOOST_CATCH (...)
Chris@16 1020 {
Chris@16 1021 failed = true;
Chris@16 1022 }
Chris@16 1023 BOOST_CATCH_END
Chris@16 1024 if (failed)
Chris@16 1025 {
Chris@16 1026 os.setstate(std::ios_base::failbit | std::ios_base::badbit);
Chris@16 1027 }
Chris@16 1028 }
Chris@16 1029 return os;
Chris@16 1030 }
Chris@16 1031 #endif
Chris@16 1032
Chris@16 1033 namespace detail
Chris@16 1034 {
Chris@16 1035
Chris@16 1036 template <class CharT, class InputIterator>
Chris@16 1037 minutes extract_z(InputIterator& b, InputIterator e, std::ios_base::iostate& err, const std::ctype<CharT>& ct)
Chris@16 1038 {
Chris@16 1039 int min = 0;
Chris@16 1040 if (b != e)
Chris@16 1041 {
Chris@16 1042 char cn = ct.narrow(*b, 0);
Chris@16 1043 if (cn != '+' && cn != '-')
Chris@16 1044 {
Chris@16 1045 err |= std::ios_base::failbit;
Chris@16 1046 return minutes(0);
Chris@16 1047 }
Chris@16 1048 int sn = cn == '-' ? -1 : 1;
Chris@16 1049 int hr = 0;
Chris@16 1050 for (int i = 0; i < 2; ++i)
Chris@16 1051 {
Chris@16 1052 if (++b == e)
Chris@16 1053 {
Chris@16 1054 err |= std::ios_base::eofbit | std::ios_base::failbit;
Chris@16 1055 return minutes(0);
Chris@16 1056 }
Chris@16 1057 cn = ct.narrow(*b, 0);
Chris@16 1058 if (! ('0' <= cn && cn <= '9'))
Chris@16 1059 {
Chris@16 1060 err |= std::ios_base::failbit;
Chris@16 1061 return minutes(0);
Chris@16 1062 }
Chris@16 1063 hr = hr * 10 + cn - '0';
Chris@16 1064 }
Chris@16 1065 for (int i = 0; i < 2; ++i)
Chris@16 1066 {
Chris@16 1067 if (++b == e)
Chris@16 1068 {
Chris@16 1069 err |= std::ios_base::eofbit | std::ios_base::failbit;
Chris@16 1070 return minutes(0);
Chris@16 1071 }
Chris@16 1072 cn = ct.narrow(*b, 0);
Chris@16 1073 if (! ('0' <= cn && cn <= '9'))
Chris@16 1074 {
Chris@16 1075 err |= std::ios_base::failbit;
Chris@16 1076 return minutes(0);
Chris@16 1077 }
Chris@16 1078 min = min * 10 + cn - '0';
Chris@16 1079 }
Chris@16 1080 if (++b == e) {
Chris@16 1081 err |= std::ios_base::eofbit;
Chris@16 1082 }
Chris@16 1083 min += hr * 60;
Chris@16 1084 min *= sn;
Chris@16 1085 }
Chris@16 1086 else
Chris@16 1087 {
Chris@16 1088 err |= std::ios_base::eofbit | std::ios_base::failbit;
Chris@16 1089 }
Chris@16 1090 return minutes(min);
Chris@16 1091 }
Chris@16 1092
Chris@16 1093 } // detail
Chris@16 1094
Chris@16 1095 #if defined BOOST_CHRONO_PROVIDES_DATE_IO_FOR_SYSTEM_CLOCK_TIME_POINT
Chris@16 1096
Chris@16 1097 template <class CharT, class Traits, class Duration>
Chris@16 1098 std::basic_istream<CharT, Traits>&
Chris@16 1099 operator>>(std::basic_istream<CharT, Traits>& is, time_point<system_clock, Duration>& tp)
Chris@16 1100 {
Chris@16 1101 typename std::basic_istream<CharT, Traits>::sentry ok(is);
Chris@16 1102 if (bool(ok))
Chris@16 1103 {
Chris@16 1104 std::ios_base::iostate err = std::ios_base::goodbit;
Chris@16 1105 BOOST_TRY
Chris@16 1106 {
Chris@16 1107 const CharT* pb = 0; //nullptr;
Chris@16 1108 const CharT* pe = pb;
Chris@16 1109 std::basic_string<CharT> fmt = get_time_fmt<CharT> (is);
Chris@16 1110 pb = fmt.data();
Chris@16 1111 pe = pb + fmt.size();
Chris@16 1112
Chris@16 1113 timezone tz = get_timezone(is);
Chris@16 1114 std::locale loc = is.getloc();
Chris@16 1115 const std::time_get<CharT>& tg = std::use_facet<std::time_get<CharT> >(loc);
Chris@16 1116 const std::ctype<CharT>& ct = std::use_facet<std::ctype<CharT> >(loc);
Chris@16 1117 tm tm; // {0}
Chris@16 1118 std::memset(&tm, 0, sizeof(std::tm));
Chris@16 1119
Chris@16 1120 typedef std::istreambuf_iterator<CharT, Traits> It;
Chris@16 1121 if (pb == pe)
Chris@16 1122 {
Chris@16 1123 CharT pattern[] =
Chris@16 1124 { '%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', '%', 'H', ':', '%', 'M', ':' };
Chris@16 1125 pb = pattern;
Chris@16 1126 pe = pb + sizeof (pattern) / sizeof(CharT);
Chris@16 1127
Chris@16 1128 #if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET
Chris@16 1129 const detail::time_get<CharT>& dtg(tg);
Chris@16 1130 dtg.get(is, 0, is, err, &tm, pb, pe);
Chris@16 1131 #else
Chris@16 1132 tg.get(is, 0, is, err, &tm, pb, pe);
Chris@16 1133 #endif
Chris@16 1134 if (err & std::ios_base::failbit) goto exit;
Chris@16 1135 fractional_seconds sec;
Chris@16 1136 CharT c = CharT();
Chris@16 1137 std::ios::fmtflags flgs = is.flags();
Chris@16 1138 is.setf(std::ios::fixed, std::ios::floatfield);
Chris@16 1139 is.precision(9);
Chris@16 1140 is >> sec;
Chris@16 1141 is.flags(flgs);
Chris@16 1142 if (is.fail())
Chris@16 1143 {
Chris@16 1144 err |= std::ios_base::failbit;
Chris@16 1145 goto exit;
Chris@16 1146 }
Chris@16 1147 It i(is);
Chris@16 1148 It eof;
Chris@16 1149 c = *i;
Chris@16 1150 if (++i == eof || c != ' ')
Chris@16 1151 {
Chris@16 1152 err |= std::ios_base::failbit;
Chris@16 1153 goto exit;
Chris@16 1154 }
Chris@16 1155 minutes min = detail::extract_z(i, eof, err, ct);
Chris@16 1156
Chris@16 1157 if (err & std::ios_base::failbit) goto exit;
Chris@16 1158 time_t t;
Chris@16 1159
Chris@16 1160 #if BOOST_CHRONO_INTERNAL_TIMEGM
Chris@16 1161 t = detail::internal_timegm(&tm);
Chris@16 1162 #else
Chris@16 1163 t = timegm(&tm);
Chris@16 1164 #endif
Chris@16 1165 tp = time_point_cast<Duration>(
Chris@16 1166 system_clock::from_time_t(t) - min + round<system_clock::duration> (duration<fractional_seconds> (sec))
Chris@16 1167 );
Chris@16 1168 }
Chris@16 1169 else
Chris@16 1170 {
Chris@16 1171 const CharT z[2] =
Chris@16 1172 { '%', 'z' };
Chris@16 1173 const CharT* fz = std::search(pb, pe, z, z + 2);
Chris@16 1174 #if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET
Chris@16 1175 const detail::time_get<CharT>& dtg(tg);
Chris@16 1176 dtg.get(is, 0, is, err, &tm, pb, fz);
Chris@16 1177 #else
Chris@16 1178 tg.get(is, 0, is, err, &tm, pb, fz);
Chris@16 1179 #endif
Chris@16 1180 minutes minu(0);
Chris@16 1181 if (fz != pe)
Chris@16 1182 {
Chris@16 1183 if (err != std::ios_base::goodbit)
Chris@16 1184 {
Chris@16 1185 err |= std::ios_base::failbit;
Chris@16 1186 goto exit;
Chris@16 1187 }
Chris@16 1188 It i(is);
Chris@16 1189 It eof;
Chris@16 1190 minu = detail::extract_z(i, eof, err, ct);
Chris@16 1191 if (err & std::ios_base::failbit) goto exit;
Chris@16 1192 if (fz + 2 != pe)
Chris@16 1193 {
Chris@16 1194 if (err != std::ios_base::goodbit)
Chris@16 1195 {
Chris@16 1196 err |= std::ios_base::failbit;
Chris@16 1197 goto exit;
Chris@16 1198 }
Chris@16 1199 #if defined BOOST_CHRONO_USES_INTERNAL_TIME_GET
Chris@16 1200 const detail::time_get<CharT>& dtg(tg);
Chris@16 1201 dtg.get(is, 0, is, err, &tm, fz + 2, pe);
Chris@16 1202 #else
Chris@16 1203 tg.get(is, 0, is, err, &tm, fz + 2, pe);
Chris@16 1204 #endif
Chris@16 1205 if (err & std::ios_base::failbit) goto exit;
Chris@16 1206 }
Chris@16 1207 }
Chris@16 1208 tm.tm_isdst = -1;
Chris@16 1209 time_t t;
Chris@16 1210 if (tz == timezone::utc || fz != pe)
Chris@16 1211 {
Chris@16 1212 #if BOOST_CHRONO_INTERNAL_TIMEGM
Chris@16 1213 t = detail::internal_timegm(&tm);
Chris@16 1214 #else
Chris@16 1215 t = timegm(&tm);
Chris@16 1216 #endif
Chris@16 1217 }
Chris@16 1218 else
Chris@16 1219 {
Chris@16 1220 t = mktime(&tm);
Chris@16 1221 }
Chris@16 1222 tp = time_point_cast<Duration>(
Chris@16 1223 system_clock::from_time_t(t) - minu
Chris@16 1224 );
Chris@16 1225 }
Chris@16 1226 }
Chris@16 1227 BOOST_CATCH (...)
Chris@16 1228 {
Chris@16 1229 err |= std::ios_base::badbit | std::ios_base::failbit;
Chris@16 1230 }
Chris@16 1231 BOOST_CATCH_END
Chris@16 1232 exit: is.setstate(err);
Chris@16 1233 }
Chris@16 1234 return is;
Chris@16 1235 }
Chris@16 1236
Chris@16 1237 #endif
Chris@16 1238 #endif //UTC
Chris@16 1239 } // chrono
Chris@16 1240
Chris@16 1241 }
Chris@16 1242
Chris@16 1243 #endif // header