GNU Radio's SATNOGS Package
date.h
Go to the documentation of this file.
1 #ifndef DATE_H
2 #define DATE_H
3 
4 // The MIT License (MIT)
5 //
6 // Copyright (c) 2015, 2016, 2017 Howard Hinnant
7 // Copyright (c) 2016 Adrian Colomitchi
8 // Copyright (c) 2017 Florian Dang
9 // Copyright (c) 2017 Paul Thompson
10 // Copyright (c) 2018, 2019 Tomasz KamiƄski
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining a copy
13 // of this software and associated documentation files (the "Software"), to deal
14 // in the Software without restriction, including without limitation the rights
15 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 // copies of the Software, and to permit persons to whom the Software is
17 // furnished to do so, subject to the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be included in all
20 // copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 // SOFTWARE.
29 //
30 // Our apologies. When the previous paragraph was written, lowercase had not yet
31 // been invented (that would involve another several millennia of evolution).
32 // We did not mean to shout.
33 
34 #ifndef HAS_STRING_VIEW
35 # if __cplusplus >= 201703 || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
36 # define HAS_STRING_VIEW 1
37 # else
38 # define HAS_STRING_VIEW 0
39 # endif
40 #endif // HAS_STRING_VIEW
41 
42 #include <cassert>
43 #include <algorithm>
44 #include <cctype>
45 #include <chrono>
46 #include <climits>
47 #if !(__cplusplus >= 201402)
48 # include <cmath>
49 #endif
50 #include <cstddef>
51 #include <cstdint>
52 #include <cstdlib>
53 #include <ctime>
54 #include <ios>
55 #include <istream>
56 #include <iterator>
57 #include <limits>
58 #include <locale>
59 #include <memory>
60 #include <ostream>
61 #include <ratio>
62 #include <sstream>
63 #include <stdexcept>
64 #include <string>
65 #if HAS_STRING_VIEW
66 # include <string_view>
67 #endif
68 #include <utility>
69 #include <type_traits>
70 
71 #ifdef __GNUC__
72 # pragma GCC diagnostic push
73 # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR > 7)
74 # pragma GCC diagnostic ignored "-Wpedantic"
75 # endif
76 # if __GNUC__ < 5
77 // GCC 4.9 Bug 61489 Wrong warning with -Wmissing-field-initializers
78 # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
79 # endif
80 #endif
81 
82 #ifdef _MSC_VER
83 # pragma warning(push)
84 // warning C4127: conditional expression is constant
85 # pragma warning(disable : 4127)
86 #endif
87 
88 namespace date {
89 
90 //---------------+
91 // Configuration |
92 //---------------+
93 
94 #ifndef ONLY_C_LOCALE
95 # define ONLY_C_LOCALE 0
96 #endif
97 
98 #if defined(_MSC_VER) && (!defined(__clang__) || (_MSC_VER < 1910))
99 // MSVC
100 # ifndef _SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING
101 # define _SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING
102 # endif
103 # if _MSC_VER < 1910
104 // before VS2017
105 # define CONSTDATA const
106 # define CONSTCD11
107 # define CONSTCD14
108 # define NOEXCEPT _NOEXCEPT
109 # else
110 // VS2017 and later
111 # define CONSTDATA constexpr const
112 # define CONSTCD11 constexpr
113 # define CONSTCD14 constexpr
114 # define NOEXCEPT noexcept
115 # endif
116 
117 #elif defined(__SUNPRO_CC) && __SUNPRO_CC <= 0x5150
118 // Oracle Developer Studio 12.6 and earlier
119 # define CONSTDATA constexpr const
120 # define CONSTCD11 constexpr
121 # define CONSTCD14
122 # define NOEXCEPT noexcept
123 
124 #elif __cplusplus >= 201402
125 // C++14
126 # define CONSTDATA constexpr const
127 # define CONSTCD11 constexpr
128 # define CONSTCD14 constexpr
129 # define NOEXCEPT noexcept
130 #else
131 // C++11
132 # define CONSTDATA constexpr const
133 # define CONSTCD11 constexpr
134 # define CONSTCD14
135 # define NOEXCEPT noexcept
136 #endif
137 
138 #ifndef HAS_UNCAUGHT_EXCEPTIONS
139 # if __cplusplus > 201703
140 # define HAS_UNCAUGHT_EXCEPTIONS 1
141 # else
142 # define HAS_UNCAUGHT_EXCEPTIONS 0
143 # endif
144 #endif // HAS_UNCAUGHT_EXCEPTIONS
145 
146 #ifndef HAS_VOID_T
147 # if __cplusplus >= 201703
148 # define HAS_VOID_T 1
149 # else
150 # define HAS_VOID_T 0
151 # endif
152 #endif // HAS_VOID_T
153 
154 // Protect from Oracle sun macro
155 #ifdef sun
156 # undef sun
157 #endif
158 
159 //-----------+
160 // Interface |
161 //-----------+
162 
163 // durations
164 
165 using days = std::chrono::duration
166  <int, std::ratio_multiply<std::ratio<24>, std::chrono::hours::period>::type>;
167 
168 using weeks = std::chrono::duration
169  <int, std::ratio_multiply<std::ratio<7>, days::period>::type>;
170 
171 using years = std::chrono::duration
172  <int, std::ratio_multiply<std::ratio<146097, 400>, days::period>::type>;
173 
174 using months = std::chrono::duration
175  <int, std::ratio_divide<years::period, std::ratio<12>>::type>;
176 
177 // time_point
178 
179 template <class Duration>
180 using sys_time = std::chrono::time_point<std::chrono::system_clock, Duration>;
181 
184 
185 struct local_t {};
186 
187 template <class Duration>
188 using local_time = std::chrono::time_point<local_t, Duration>;
189 
192 
193 // types
194 
195 struct last_spec {
196  explicit last_spec() = default;
197 };
198 
199 class day;
200 class month;
201 class year;
202 
203 class weekday;
204 class weekday_indexed;
205 class weekday_last;
206 
207 class month_day;
208 class month_day_last;
209 class month_weekday;
210 class month_weekday_last;
211 
212 class year_month;
213 
214 class year_month_day;
215 class year_month_day_last;
216 class year_month_weekday;
218 
219 // date composition operators
220 
221 CONSTCD11 year_month operator/(const year &y, const month &m) NOEXCEPT;
222 CONSTCD11 year_month operator/(const year &y, int m) NOEXCEPT;
223 
224 CONSTCD11 month_day operator/(const day &d, const month &m) NOEXCEPT;
225 CONSTCD11 month_day operator/(const day &d, int m) NOEXCEPT;
226 CONSTCD11 month_day operator/(const month &m, const day &d) NOEXCEPT;
227 CONSTCD11 month_day operator/(const month &m, int d) NOEXCEPT;
228 CONSTCD11 month_day operator/(int m, const day &d) NOEXCEPT;
229 
234 
236  const weekday_indexed &wdi) NOEXCEPT;
238  const weekday_indexed &wdi) NOEXCEPT;
240  const month &m) NOEXCEPT;
242  int m) NOEXCEPT;
243 
245  const weekday_last &wdl) NOEXCEPT;
247  const weekday_last &wdl) NOEXCEPT;
249  const month &m) NOEXCEPT;
251  int m) NOEXCEPT;
252 
259 
260 CONSTCD11
262 CONSTCD11
264  const month_day_last &mdl) NOEXCEPT;
265 CONSTCD11
267  const month_day_last &mdl) NOEXCEPT;
268 CONSTCD11
270  const year &y) NOEXCEPT;
271 CONSTCD11
273  int y) NOEXCEPT;
274 
275 CONSTCD11
277 operator/(const year_month &ym, const weekday_indexed &wdi) NOEXCEPT;
278 
279 CONSTCD11
281 operator/(const year &y, const month_weekday &mwd) NOEXCEPT;
282 
283 CONSTCD11
285 operator/(int y, const month_weekday &mwd) NOEXCEPT;
286 
287 CONSTCD11
289 operator/(const month_weekday &mwd, const year &y) NOEXCEPT;
290 
291 CONSTCD11
293 operator/(const month_weekday &mwd, int y) NOEXCEPT;
294 
295 CONSTCD11
297 operator/(const year_month &ym, const weekday_last &wdl) NOEXCEPT;
298 
299 CONSTCD11
301 operator/(const year &y, const month_weekday_last &mwdl) NOEXCEPT;
302 
303 CONSTCD11
305 operator/(int y, const month_weekday_last &mwdl) NOEXCEPT;
306 
307 CONSTCD11
309 operator/(const month_weekday_last &mwdl, const year &y) NOEXCEPT;
310 
311 CONSTCD11
313 operator/(const month_weekday_last &mwdl, int y) NOEXCEPT;
314 
315 // Detailed interface
316 
317 // day
318 
319 class day {
320  unsigned char d_;
321 
322 public:
323  day() = default;
324  explicit CONSTCD11 day(unsigned d) NOEXCEPT;
325 
326  CONSTCD14 day &operator++() NOEXCEPT;
327  CONSTCD14 day operator++(int) NOEXCEPT;
328  CONSTCD14 day &operator--() NOEXCEPT;
329  CONSTCD14 day operator--(int) NOEXCEPT;
330 
331  CONSTCD14 day &operator+=(const days &d) NOEXCEPT;
332  CONSTCD14 day &operator-=(const days &d) NOEXCEPT;
333 
334  CONSTCD11 explicit operator unsigned() const NOEXCEPT;
335  CONSTCD11 bool ok() const NOEXCEPT;
336 };
337 
338 CONSTCD11 bool operator==(const day &x, const day &y) NOEXCEPT;
339 CONSTCD11 bool operator!=(const day &x, const day &y) NOEXCEPT;
340 CONSTCD11 bool operator< (const day &x, const day &y) NOEXCEPT;
341 CONSTCD11 bool operator> (const day &x, const day &y) NOEXCEPT;
342 CONSTCD11 bool operator<=(const day &x, const day &y) NOEXCEPT;
343 CONSTCD11 bool operator>=(const day &x, const day &y) NOEXCEPT;
344 
345 CONSTCD11 day operator+(const day &x, const days &y) NOEXCEPT;
346 CONSTCD11 day operator+(const days &x, const day &y) NOEXCEPT;
347 CONSTCD11 day operator-(const day &x, const days &y) NOEXCEPT;
348 CONSTCD11 days operator-(const day &x, const day &y) NOEXCEPT;
349 
350 template<class CharT, class Traits>
351 std::basic_ostream<CharT, Traits> &
352 operator<<(std::basic_ostream<CharT, Traits> &os, const day &d);
353 
354 // month
355 
356 class month {
357  unsigned char m_;
358 
359 public:
360  month() = default;
361  explicit CONSTCD11 month(unsigned m) NOEXCEPT;
362 
363  CONSTCD14 month &operator++() NOEXCEPT;
364  CONSTCD14 month operator++(int) NOEXCEPT;
365  CONSTCD14 month &operator--() NOEXCEPT;
366  CONSTCD14 month operator--(int) NOEXCEPT;
367 
368  CONSTCD14 month &operator+=(const months &m) NOEXCEPT;
369  CONSTCD14 month &operator-=(const months &m) NOEXCEPT;
370 
371  CONSTCD11 explicit operator unsigned() const NOEXCEPT;
372  CONSTCD11 bool ok() const NOEXCEPT;
373 };
374 
375 CONSTCD11 bool operator==(const month &x, const month &y) NOEXCEPT;
376 CONSTCD11 bool operator!=(const month &x, const month &y) NOEXCEPT;
377 CONSTCD11 bool operator< (const month &x, const month &y) NOEXCEPT;
378 CONSTCD11 bool operator> (const month &x, const month &y) NOEXCEPT;
379 CONSTCD11 bool operator<=(const month &x, const month &y) NOEXCEPT;
380 CONSTCD11 bool operator>=(const month &x, const month &y) NOEXCEPT;
381 
382 CONSTCD14 month operator+(const month &x, const months &y) NOEXCEPT;
383 CONSTCD14 month operator+(const months &x, const month &y) NOEXCEPT;
384 CONSTCD14 month operator-(const month &x, const months &y) NOEXCEPT;
385 CONSTCD14 months operator-(const month &x, const month &y) NOEXCEPT;
386 
387 template<class CharT, class Traits>
388 std::basic_ostream<CharT, Traits> &
389 operator<<(std::basic_ostream<CharT, Traits> &os, const month &m);
390 
391 // year
392 
393 class year {
394  short y_;
395 
396 public:
397  year() = default;
398  explicit CONSTCD11 year(int y) NOEXCEPT;
399 
400  CONSTCD14 year &operator++() NOEXCEPT;
401  CONSTCD14 year operator++(int) NOEXCEPT;
402  CONSTCD14 year &operator--() NOEXCEPT;
403  CONSTCD14 year operator--(int) NOEXCEPT;
404 
405  CONSTCD14 year &operator+=(const years &y) NOEXCEPT;
406  CONSTCD14 year &operator-=(const years &y) NOEXCEPT;
407 
410 
411  CONSTCD11 bool is_leap() const NOEXCEPT;
412 
413  CONSTCD11 explicit operator int() const NOEXCEPT;
414  CONSTCD11 bool ok() const NOEXCEPT;
415 
416  static CONSTCD11 year min() NOEXCEPT { return year{-32767}; }
417  static CONSTCD11 year max() NOEXCEPT { return year{32767}; }
418 };
419 
420 CONSTCD11 bool operator==(const year &x, const year &y) NOEXCEPT;
421 CONSTCD11 bool operator!=(const year &x, const year &y) NOEXCEPT;
422 CONSTCD11 bool operator< (const year &x, const year &y) NOEXCEPT;
423 CONSTCD11 bool operator> (const year &x, const year &y) NOEXCEPT;
424 CONSTCD11 bool operator<=(const year &x, const year &y) NOEXCEPT;
425 CONSTCD11 bool operator>=(const year &x, const year &y) NOEXCEPT;
426 
427 CONSTCD11 year operator+(const year &x, const years &y) NOEXCEPT;
428 CONSTCD11 year operator+(const years &x, const year &y) NOEXCEPT;
429 CONSTCD11 year operator-(const year &x, const years &y) NOEXCEPT;
430 CONSTCD11 years operator-(const year &x, const year &y) NOEXCEPT;
431 
432 template<class CharT, class Traits>
433 std::basic_ostream<CharT, Traits> &
434 operator<<(std::basic_ostream<CharT, Traits> &os, const year &y);
435 
436 // weekday
437 
438 class weekday {
439  unsigned char wd_;
440 public:
441  weekday() = default;
442  explicit CONSTCD11 weekday(unsigned wd) NOEXCEPT;
443  CONSTCD14 weekday(const sys_days &dp) NOEXCEPT;
444  CONSTCD14 explicit weekday(const local_days &dp) NOEXCEPT;
445 
446  CONSTCD14 weekday &operator++() NOEXCEPT;
447  CONSTCD14 weekday operator++(int) NOEXCEPT;
448  CONSTCD14 weekday &operator--() NOEXCEPT;
449  CONSTCD14 weekday operator--(int) NOEXCEPT;
450 
451  CONSTCD14 weekday &operator+=(const days &d) NOEXCEPT;
452  CONSTCD14 weekday &operator-=(const days &d) NOEXCEPT;
453 
454  CONSTCD11 bool ok() const NOEXCEPT;
455 
456  CONSTCD11 unsigned c_encoding() const NOEXCEPT;
457  CONSTCD11 unsigned iso_encoding() const NOEXCEPT;
458 
459  CONSTCD11 weekday_indexed operator[](unsigned index) const NOEXCEPT;
460  CONSTCD11 weekday_last operator[](last_spec) const NOEXCEPT;
461 
462 private:
463  static CONSTCD14 unsigned char weekday_from_days(int z) NOEXCEPT;
464 
465  friend CONSTCD11 bool operator==(const weekday &x, const weekday &y) NOEXCEPT;
466  friend CONSTCD14 days operator-(const weekday &x, const weekday &y) NOEXCEPT;
467  friend CONSTCD14 weekday operator+(const weekday &x, const days &y) NOEXCEPT;
468  template<class CharT, class Traits>
469  friend std::basic_ostream<CharT, Traits> &
470  operator<<(std::basic_ostream<CharT, Traits> &os, const weekday &wd);
471  friend class weekday_indexed;
472 };
473 
474 CONSTCD11 bool operator==(const weekday &x, const weekday &y) NOEXCEPT;
475 CONSTCD11 bool operator!=(const weekday &x, const weekday &y) NOEXCEPT;
476 
477 CONSTCD14 weekday operator+(const weekday &x, const days &y) NOEXCEPT;
478 CONSTCD14 weekday operator+(const days &x, const weekday &y) NOEXCEPT;
479 CONSTCD14 weekday operator-(const weekday &x, const days &y) NOEXCEPT;
480 CONSTCD14 days operator-(const weekday &x, const weekday &y) NOEXCEPT;
481 
482 template<class CharT, class Traits>
483 std::basic_ostream<CharT, Traits> &
484 operator<<(std::basic_ostream<CharT, Traits> &os, const weekday &wd);
485 
486 // weekday_indexed
487 
489  unsigned char wd_ : 4;
490  unsigned char index_ : 4;
491 
492 public:
493  weekday_indexed() = default;
494  CONSTCD11 weekday_indexed(const date::weekday &wd, unsigned index) NOEXCEPT;
495 
497  CONSTCD11 unsigned index() const NOEXCEPT;
498  CONSTCD11 bool ok() const NOEXCEPT;
499 };
500 
501 CONSTCD11 bool operator==(const weekday_indexed &x,
502  const weekday_indexed &y) NOEXCEPT;
503 CONSTCD11 bool operator!=(const weekday_indexed &x,
504  const weekday_indexed &y) NOEXCEPT;
505 
506 template<class CharT, class Traits>
507 std::basic_ostream<CharT, Traits> &
508 operator<<(std::basic_ostream<CharT, Traits> &os, const weekday_indexed &wdi);
509 
510 // weekday_last
511 
513  date::weekday wd_;
514 
515 public:
516  explicit CONSTCD11 weekday_last(const date::weekday &wd) NOEXCEPT;
517 
519  CONSTCD11 bool ok() const NOEXCEPT;
520 };
521 
522 CONSTCD11 bool operator==(const weekday_last &x,
523  const weekday_last &y) NOEXCEPT;
524 CONSTCD11 bool operator!=(const weekday_last &x,
525  const weekday_last &y) NOEXCEPT;
526 
527 template<class CharT, class Traits>
528 std::basic_ostream<CharT, Traits> &
529 operator<<(std::basic_ostream<CharT, Traits> &os, const weekday_last &wdl);
530 
531 namespace detail {
532 
534 
535 } // namespace detail
536 
537 // year_month
538 
539 class year_month {
540  date::year y_;
541  date::month m_;
542 
543 public:
544  year_month() = default;
545  CONSTCD11 year_month(const date::year &y, const date::month &m) NOEXCEPT;
546 
549 
550  template<class = detail::unspecified_month_disambiguator>
551  CONSTCD14 year_month & operator+=(const months &dm) NOEXCEPT;
552  template<class = detail::unspecified_month_disambiguator>
553  CONSTCD14 year_month & operator-=(const months &dm) NOEXCEPT;
554  CONSTCD14 year_month &operator+=(const years &dy) NOEXCEPT;
555  CONSTCD14 year_month &operator-=(const years &dy) NOEXCEPT;
556 
557  CONSTCD11 bool ok() const NOEXCEPT;
558 };
559 
560 CONSTCD11 bool operator==(const year_month &x, const year_month &y) NOEXCEPT;
561 CONSTCD11 bool operator!=(const year_month &x, const year_month &y) NOEXCEPT;
562 CONSTCD11 bool operator< (const year_month &x, const year_month &y) NOEXCEPT;
563 CONSTCD11 bool operator> (const year_month &x, const year_month &y) NOEXCEPT;
564 CONSTCD11 bool operator<=(const year_month &x, const year_month &y) NOEXCEPT;
565 CONSTCD11 bool operator>=(const year_month &x, const year_month &y) NOEXCEPT;
566 
567 template<class = detail::unspecified_month_disambiguator>
569 template<class = detail::unspecified_month_disambiguator>
571 template<class = detail::unspecified_month_disambiguator>
573 
575 CONSTCD11 year_month operator+(const year_month &ym, const years &dy) NOEXCEPT;
576 CONSTCD11 year_month operator+(const years &dy, const year_month &ym) NOEXCEPT;
577 CONSTCD11 year_month operator-(const year_month &ym, const years &dy) NOEXCEPT;
578 
579 template<class CharT, class Traits>
580 std::basic_ostream<CharT, Traits> &
581 operator<<(std::basic_ostream<CharT, Traits> &os, const year_month &ym);
582 
583 // month_day
584 
585 class month_day {
586  date::month m_;
587  date::day d_;
588 
589 public:
590  month_day() = default;
591  CONSTCD11 month_day(const date::month &m, const date::day &d) NOEXCEPT;
592 
595 
596  CONSTCD14 bool ok() const NOEXCEPT;
597 };
598 
599 CONSTCD11 bool operator==(const month_day &x, const month_day &y) NOEXCEPT;
600 CONSTCD11 bool operator!=(const month_day &x, const month_day &y) NOEXCEPT;
601 CONSTCD11 bool operator< (const month_day &x, const month_day &y) NOEXCEPT;
602 CONSTCD11 bool operator> (const month_day &x, const month_day &y) NOEXCEPT;
603 CONSTCD11 bool operator<=(const month_day &x, const month_day &y) NOEXCEPT;
604 CONSTCD11 bool operator>=(const month_day &x, const month_day &y) NOEXCEPT;
605 
606 template<class CharT, class Traits>
607 std::basic_ostream<CharT, Traits> &
608 operator<<(std::basic_ostream<CharT, Traits> &os, const month_day &md);
609 
610 // month_day_last
611 
613  date::month m_;
614 
615 public:
616  CONSTCD11 explicit month_day_last(const date::month &m) NOEXCEPT;
617 
619  CONSTCD11 bool ok() const NOEXCEPT;
620 };
621 
622 CONSTCD11 bool operator==(const month_day_last &x,
623  const month_day_last &y) NOEXCEPT;
624 CONSTCD11 bool operator!=(const month_day_last &x,
625  const month_day_last &y) NOEXCEPT;
626 CONSTCD11 bool operator< (const month_day_last &x,
627  const month_day_last &y) NOEXCEPT;
628 CONSTCD11 bool operator> (const month_day_last &x,
629  const month_day_last &y) NOEXCEPT;
630 CONSTCD11 bool operator<=(const month_day_last &x,
631  const month_day_last &y) NOEXCEPT;
632 CONSTCD11 bool operator>=(const month_day_last &x,
633  const month_day_last &y) NOEXCEPT;
634 
635 template<class CharT, class Traits>
636 std::basic_ostream<CharT, Traits> &
637 operator<<(std::basic_ostream<CharT, Traits> &os, const month_day_last &mdl);
638 
639 // month_weekday
640 
642  date::month m_;
644 public:
646  const date::weekday_indexed &wdi) NOEXCEPT;
647 
650 
651  CONSTCD11 bool ok() const NOEXCEPT;
652 };
653 
654 CONSTCD11 bool operator==(const month_weekday &x,
655  const month_weekday &y) NOEXCEPT;
656 CONSTCD11 bool operator!=(const month_weekday &x,
657  const month_weekday &y) NOEXCEPT;
658 
659 template<class CharT, class Traits>
660 std::basic_ostream<CharT, Traits> &
661 operator<<(std::basic_ostream<CharT, Traits> &os, const month_weekday &mwd);
662 
663 // month_weekday_last
664 
666  date::month m_;
667  date::weekday_last wdl_;
668 
669 public:
671  const date::weekday_last &wd) NOEXCEPT;
672 
675 
676  CONSTCD11 bool ok() const NOEXCEPT;
677 };
678 
679 CONSTCD11
680 bool operator==(const month_weekday_last &x,
681  const month_weekday_last &y) NOEXCEPT;
682 CONSTCD11
683 bool operator!=(const month_weekday_last &x,
684  const month_weekday_last &y) NOEXCEPT;
685 
686 template<class CharT, class Traits>
687 std::basic_ostream<CharT, Traits> &
688 operator<<(std::basic_ostream<CharT, Traits> &os,
689  const month_weekday_last &mwdl);
690 
691 // class year_month_day
692 
694  date::year y_;
695  date::month m_;
696  date::day d_;
697 
698 public:
699  year_month_day() = default;
700  CONSTCD11 year_month_day(const date::year &y, const date::month &m,
701  const date::day &d) NOEXCEPT;
703 
706 
707  template<class = detail::unspecified_month_disambiguator>
708  CONSTCD14 year_month_day & operator+=(const months &m) NOEXCEPT;
709  template<class = detail::unspecified_month_disambiguator>
710  CONSTCD14 year_month_day & operator-=(const months &m) NOEXCEPT;
711  CONSTCD14 year_month_day &operator+=(const years &y) NOEXCEPT;
712  CONSTCD14 year_month_day &operator-=(const years &y) NOEXCEPT;
713 
717 
718  CONSTCD14 operator sys_days() const NOEXCEPT;
719  CONSTCD14 explicit operator local_days() const NOEXCEPT;
720  CONSTCD14 bool ok() const NOEXCEPT;
721 
722 private:
723  static CONSTCD14 year_month_day from_days(days dp) NOEXCEPT;
724  CONSTCD14 days to_days() const NOEXCEPT;
725 };
726 
727 CONSTCD11 bool operator==(const year_month_day &x,
728  const year_month_day &y) NOEXCEPT;
729 CONSTCD11 bool operator!=(const year_month_day &x,
730  const year_month_day &y) NOEXCEPT;
731 CONSTCD11 bool operator< (const year_month_day &x,
732  const year_month_day &y) NOEXCEPT;
733 CONSTCD11 bool operator> (const year_month_day &x,
734  const year_month_day &y) NOEXCEPT;
735 CONSTCD11 bool operator<=(const year_month_day &x,
736  const year_month_day &y) NOEXCEPT;
737 CONSTCD11 bool operator>=(const year_month_day &x,
738  const year_month_day &y) NOEXCEPT;
739 
740 template<class = detail::unspecified_month_disambiguator>
742  const months &dm) NOEXCEPT;
743 template<class = detail::unspecified_month_disambiguator>
745  const year_month_day &ymd) NOEXCEPT;
746 template<class = detail::unspecified_month_disambiguator>
748  const months &dm) NOEXCEPT;
750  const years &dy) NOEXCEPT;
752  const year_month_day &ymd) NOEXCEPT;
754  const years &dy) NOEXCEPT;
755 
756 template<class CharT, class Traits>
757 std::basic_ostream<CharT, Traits> &
758 operator<<(std::basic_ostream<CharT, Traits> &os, const year_month_day &ymd);
759 
760 // year_month_day_last
761 
763  date::year y_;
765 
766 public:
768  const date::month_day_last &mdl) NOEXCEPT;
769 
770  template<class = detail::unspecified_month_disambiguator>
771  CONSTCD14 year_month_day_last & operator+=(const months &m) NOEXCEPT;
772  template<class = detail::unspecified_month_disambiguator>
773  CONSTCD14 year_month_day_last & operator-=(const months &m) NOEXCEPT;
774  CONSTCD14 year_month_day_last &operator+=(const years &y) NOEXCEPT;
775  CONSTCD14 year_month_day_last &operator-=(const years &y) NOEXCEPT;
776 
781 
782  CONSTCD14 operator sys_days() const NOEXCEPT;
783  CONSTCD14 explicit operator local_days() const NOEXCEPT;
784  CONSTCD11 bool ok() const NOEXCEPT;
785 };
786 
787 CONSTCD11
788 bool operator==(const year_month_day_last &x,
789  const year_month_day_last &y) NOEXCEPT;
790 CONSTCD11
791 bool operator!=(const year_month_day_last &x,
792  const year_month_day_last &y) NOEXCEPT;
793 CONSTCD11
794 bool operator< (const year_month_day_last &x,
795  const year_month_day_last &y) NOEXCEPT;
796 CONSTCD11
797 bool operator> (const year_month_day_last &x,
798  const year_month_day_last &y) NOEXCEPT;
799 CONSTCD11
800 bool operator<=(const year_month_day_last &x,
801  const year_month_day_last &y) NOEXCEPT;
802 CONSTCD11
803 bool operator>=(const year_month_day_last &x,
804  const year_month_day_last &y) NOEXCEPT;
805 
806 template<class = detail::unspecified_month_disambiguator>
807 CONSTCD14
809 operator+(const year_month_day_last &ymdl, const months &dm) NOEXCEPT;
810 
811 template<class = detail::unspecified_month_disambiguator>
812 CONSTCD14
814 operator+(const months &dm, const year_month_day_last &ymdl) NOEXCEPT;
815 
816 CONSTCD11
818 operator+(const year_month_day_last &ymdl, const years &dy) NOEXCEPT;
819 
820 CONSTCD11
822 operator+(const years &dy, const year_month_day_last &ymdl) NOEXCEPT;
823 
824 template<class = detail::unspecified_month_disambiguator>
825 CONSTCD14
827 operator-(const year_month_day_last &ymdl, const months &dm) NOEXCEPT;
828 
829 CONSTCD11
831 operator-(const year_month_day_last &ymdl, const years &dy) NOEXCEPT;
832 
833 template<class CharT, class Traits>
834 std::basic_ostream<CharT, Traits> &
835 operator<<(std::basic_ostream<CharT, Traits> &os,
836  const year_month_day_last &ymdl);
837 
838 // year_month_weekday
839 
841  date::year y_;
842  date::month m_;
844 
845 public:
846  year_month_weekday() = default;
848  const date::weekday_indexed &wdi) NOEXCEPT;
850  CONSTCD14 explicit year_month_weekday(const local_days &dp) NOEXCEPT;
851 
852  template<class = detail::unspecified_month_disambiguator>
853  CONSTCD14 year_month_weekday & operator+=(const months &m) NOEXCEPT;
854  template<class = detail::unspecified_month_disambiguator>
855  CONSTCD14 year_month_weekday & operator-=(const months &m) NOEXCEPT;
856  CONSTCD14 year_month_weekday &operator+=(const years &y) NOEXCEPT;
857  CONSTCD14 year_month_weekday &operator-=(const years &y) NOEXCEPT;
858 
862  CONSTCD11 unsigned index() const NOEXCEPT;
864 
865  CONSTCD14 operator sys_days() const NOEXCEPT;
866  CONSTCD14 explicit operator local_days() const NOEXCEPT;
867  CONSTCD14 bool ok() const NOEXCEPT;
868 
869 private:
870  static CONSTCD14 year_month_weekday from_days(days dp) NOEXCEPT;
871  CONSTCD14 days to_days() const NOEXCEPT;
872 };
873 
874 CONSTCD11
875 bool operator==(const year_month_weekday &x,
876  const year_month_weekday &y) NOEXCEPT;
877 CONSTCD11
878 bool operator!=(const year_month_weekday &x,
879  const year_month_weekday &y) NOEXCEPT;
880 
881 template<class = detail::unspecified_month_disambiguator>
882 CONSTCD14
884 operator+(const year_month_weekday &ymwd, const months &dm) NOEXCEPT;
885 
886 template<class = detail::unspecified_month_disambiguator>
887 CONSTCD14
889 operator+(const months &dm, const year_month_weekday &ymwd) NOEXCEPT;
890 
891 CONSTCD11
893 operator+(const year_month_weekday &ymwd, const years &dy) NOEXCEPT;
894 
895 CONSTCD11
897 operator+(const years &dy, const year_month_weekday &ymwd) NOEXCEPT;
898 
899 template<class = detail::unspecified_month_disambiguator>
900 CONSTCD14
902 operator-(const year_month_weekday &ymwd, const months &dm) NOEXCEPT;
903 
904 CONSTCD11
906 operator-(const year_month_weekday &ymwd, const years &dy) NOEXCEPT;
907 
908 template<class CharT, class Traits>
909 std::basic_ostream<CharT, Traits> &
910 operator<<(std::basic_ostream<CharT, Traits> &os,
911  const year_month_weekday &ymwdi);
912 
913 // year_month_weekday_last
914 
916  date::year y_;
917  date::month m_;
918  date::weekday_last wdl_;
919 
920 public:
922  const date::weekday_last &wdl) NOEXCEPT;
923 
924  template<class = detail::unspecified_month_disambiguator>
925  CONSTCD14 year_month_weekday_last & operator+=(const months &m) NOEXCEPT;
926  template<class = detail::unspecified_month_disambiguator>
927  CONSTCD14 year_month_weekday_last & operator-=(const months &m) NOEXCEPT;
928  CONSTCD14 year_month_weekday_last &operator+=(const years &y) NOEXCEPT;
929  CONSTCD14 year_month_weekday_last &operator-=(const years &y) NOEXCEPT;
930 
935 
936  CONSTCD14 operator sys_days() const NOEXCEPT;
937  CONSTCD14 explicit operator local_days() const NOEXCEPT;
938  CONSTCD11 bool ok() const NOEXCEPT;
939 
940 private:
941  CONSTCD14 days to_days() const NOEXCEPT;
942 };
943 
944 CONSTCD11
945 bool
948 
949 CONSTCD11
950 bool
953 
954 template<class = detail::unspecified_month_disambiguator>
955 CONSTCD14
957 operator+(const year_month_weekday_last &ymwdl, const months &dm) NOEXCEPT;
958 
959 template<class = detail::unspecified_month_disambiguator>
960 CONSTCD14
962 operator+(const months &dm, const year_month_weekday_last &ymwdl) NOEXCEPT;
963 
964 CONSTCD11
966 operator+(const year_month_weekday_last &ymwdl, const years &dy) NOEXCEPT;
967 
968 CONSTCD11
970 operator+(const years &dy, const year_month_weekday_last &ymwdl) NOEXCEPT;
971 
972 template<class = detail::unspecified_month_disambiguator>
973 CONSTCD14
975 operator-(const year_month_weekday_last &ymwdl, const months &dm) NOEXCEPT;
976 
977 CONSTCD11
979 operator-(const year_month_weekday_last &ymwdl, const years &dy) NOEXCEPT;
980 
981 template<class CharT, class Traits>
982 std::basic_ostream<CharT, Traits> &
983 operator<<(std::basic_ostream<CharT, Traits> &os,
984  const year_month_weekday_last &ymwdl);
985 
986 #if !defined(_MSC_VER) || (_MSC_VER >= 1900)
987 inline namespace literals {
988 
989 CONSTCD11 date::day operator "" _d(unsigned long long d) NOEXCEPT;
990 CONSTCD11 date::year operator "" _y(unsigned long long y) NOEXCEPT;
991 
992 } // inline namespace literals
993 #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900)
994 
995 // CONSTDATA date::month January{1};
996 // CONSTDATA date::month February{2};
997 // CONSTDATA date::month March{3};
998 // CONSTDATA date::month April{4};
999 // CONSTDATA date::month May{5};
1000 // CONSTDATA date::month June{6};
1001 // CONSTDATA date::month July{7};
1002 // CONSTDATA date::month August{8};
1003 // CONSTDATA date::month September{9};
1004 // CONSTDATA date::month October{10};
1005 // CONSTDATA date::month November{11};
1006 // CONSTDATA date::month December{12};
1007 //
1008 // CONSTDATA date::weekday Sunday{0u};
1009 // CONSTDATA date::weekday Monday{1u};
1010 // CONSTDATA date::weekday Tuesday{2u};
1011 // CONSTDATA date::weekday Wednesday{3u};
1012 // CONSTDATA date::weekday Thursday{4u};
1013 // CONSTDATA date::weekday Friday{5u};
1014 // CONSTDATA date::weekday Saturday{6u};
1015 
1016 #if HAS_VOID_T
1017 
1018 template <class T, class = std::void_t<>>
1019 struct is_clock
1020  : std::false_type {
1021 };
1022 
1023 template <class T>
1024 struct is_clock<T, std::void_t<decltype(T::now()), typename T::rep, typename T::period,
1025  typename T::duration, typename T::time_point,
1026  decltype(T::is_steady)>>
1027  : std::true_type {
1028  };
1029 
1030 #endif // HAS_VOID_T
1031 
1032 //----------------+
1033 // Implementation |
1034 //----------------+
1035 
1036 // utilities
1037 namespace detail {
1038 
1039 template<class CharT, class Traits = std::char_traits<CharT>>
1041 protected:
1042  std::basic_ios<CharT, Traits> &is_;
1043  CharT fill_;
1044  std::ios::fmtflags flags_;
1045  std::streamsize width_;
1046  std::basic_ostream<CharT, Traits> *tie_;
1047  std::locale loc_;
1048 
1049 public:
1051  {
1052  is_.fill(fill_);
1053  is_.flags(flags_);
1054  is_.width(width_);
1055  is_.imbue(loc_);
1056  is_.tie(tie_);
1057  }
1058 
1059  save_istream(const save_istream &) = delete;
1060  save_istream &operator=(const save_istream &) = delete;
1061 
1062  explicit save_istream(std::basic_ios<CharT, Traits> &is)
1063  : is_(is)
1064  , fill_(is.fill())
1065  , flags_(is.flags())
1066  , width_(is.width(0))
1067  , tie_(is.tie(nullptr))
1068  , loc_(is.getloc())
1069  {
1070  if (tie_ != nullptr) {
1071  tie_->flush();
1072  }
1073  }
1074 };
1075 
1076 template<class CharT, class Traits = std::char_traits<CharT>>
1078  : private save_istream<CharT, Traits> {
1079 public:
1081  {
1082  if ((this->flags_ & std::ios::unitbuf) &&
1084  std::uncaught_exceptions() == 0 &&
1085 #else
1086  !std::uncaught_exception() &&
1087 #endif
1088  this->is_.good()) {
1089  this->is_.rdbuf()->pubsync();
1090  }
1091  }
1092 
1093  save_ostream(const save_ostream &) = delete;
1094  save_ostream &operator=(const save_ostream &) = delete;
1095 
1096  explicit save_ostream(std::basic_ios<CharT, Traits> &os)
1097  : save_istream<CharT, Traits>(os)
1098  {
1099  }
1100 };
1101 
1102 template <class T>
1104  static const int digits = std::numeric_limits<T>::digits;
1105  using type = typename std::conditional
1106  <
1107  digits < 32,
1108  std::int32_t,
1109  typename std::conditional
1110  <
1111  digits < 64,
1112  std::int64_t,
1113 #ifdef __SIZEOF_INT128__
1114  __int128
1115 #else
1116  std::int64_t
1117 #endif
1118  >::type
1119  >::type;
1120 };
1121 
1122 template <class T>
1123 CONSTCD11
1124 inline
1125 typename std::enable_if
1126 <
1127 !std::chrono::treat_as_floating_point<T>::value,
1128 T
1129 >::type
1130 trunc(T t) NOEXCEPT {
1131  return t;
1132 }
1133 
1134 template <class T>
1135 CONSTCD14
1136 inline
1137 typename std::enable_if
1138 <
1139 std::chrono::treat_as_floating_point<T>::value,
1140  T
1141  >::type
1142 trunc(T t) NOEXCEPT {
1143  using std::numeric_limits;
1144  using I = typename choose_trunc_type<T>::type;
1145  CONSTDATA auto digits = numeric_limits<T>::digits;
1146  static_assert(digits < numeric_limits<I>::digits, "");
1147  CONSTDATA auto max = I{1} << (digits - 1);
1148  CONSTDATA auto min = -max;
1149  const auto negative = t < T{0};
1150  if (min <= t && t <= max && t != 0 && t == t)
1151  {
1152  t = static_cast<T>(static_cast<I>(t));
1153  if (t == 0 && negative) {
1154  t = -t;
1155  }
1156  }
1157  return t;
1158 }
1159 
1160 template <std::intmax_t Xp, std::intmax_t Yp>
1161 struct static_gcd {
1162  static const std::intmax_t value = static_gcd < Yp, Xp % Yp >::value;
1163 };
1164 
1165 template <std::intmax_t Xp>
1166 struct static_gcd<Xp, 0> {
1167  static const std::intmax_t value = Xp;
1168 };
1169 
1170 template <>
1171 struct static_gcd<0, 0> {
1172  static const std::intmax_t value = 1;
1173 };
1174 
1175 template <class R1, class R2>
1176 struct no_overflow {
1177 private:
1178  static const std::intmax_t gcd_n1_n2 = static_gcd<R1::num, R2::num>::value;
1179  static const std::intmax_t gcd_d1_d2 = static_gcd<R1::den, R2::den>::value;
1180  static const std::intmax_t n1 = R1::num / gcd_n1_n2;
1181  static const std::intmax_t d1 = R1::den / gcd_d1_d2;
1182  static const std::intmax_t n2 = R2::num / gcd_n1_n2;
1183  static const std::intmax_t d2 = R2::den / gcd_d1_d2;
1184  static const std::intmax_t max = INTMAX_MAX;
1185 
1186  template <std::intmax_t Xp, std::intmax_t Yp, bool overflow>
1187  struct mul { // overflow == false
1188  static const std::intmax_t value = Xp * Yp;
1189  };
1190 
1191  template <std::intmax_t Xp, std::intmax_t Yp>
1192  struct mul<Xp, Yp, true> {
1193  static const std::intmax_t value = 1;
1194  };
1195 
1196 public:
1197  static const bool value = (n1 <= max / d2) && (n2 <= max / d1);
1198  typedef std::ratio < mul < n1, d2, !value >::value,
1199  mul < n2, d1, !value >::value > type;
1200 };
1201 
1202 } // detail
1203 
1204 // trunc towards zero
1205 template <class To, class Rep, class Period>
1206 CONSTCD11
1207 inline
1208 typename std::enable_if
1209 <
1211  To
1212  >::type
1213  trunc(const std::chrono::duration<Rep, Period> &d)
1214 {
1215  return To{detail::trunc(std::chrono::duration_cast<To>(d).count())};
1216 }
1217 
1218 template <class To, class Rep, class Period>
1219 CONSTCD11
1220 inline
1221 typename std::enable_if
1222 <
1223 !detail::no_overflow<Period, typename To::period>::value,
1224 To
1225 >::type
1226 trunc(const std::chrono::duration<Rep, Period> &d)
1227 {
1228  using std::chrono::duration_cast;
1229  using std::chrono::duration;
1230  using rep = typename std::common_type<Rep, typename To::rep>::type;
1231  return To{detail::trunc(duration_cast<To>(duration_cast<duration<rep>>(d)).count())};
1232 }
1233 
1234 #ifndef HAS_CHRONO_ROUNDING
1235 # if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023918 || (_MSC_FULL_VER >= 190000000 && defined (__clang__)))
1236 # define HAS_CHRONO_ROUNDING 1
1237 # elif defined(__cpp_lib_chrono) && __cplusplus > 201402 && __cpp_lib_chrono >= 201510
1238 # define HAS_CHRONO_ROUNDING 1
1239 # elif defined(_LIBCPP_VERSION) && __cplusplus > 201402 && _LIBCPP_VERSION >= 3800
1240 # define HAS_CHRONO_ROUNDING 1
1241 # else
1242 # define HAS_CHRONO_ROUNDING 0
1243 # endif
1244 #endif // HAS_CHRONO_ROUNDING
1245 
1246 #if HAS_CHRONO_ROUNDING == 0
1247 
1248 // round down
1249 template <class To, class Rep, class Period>
1250 CONSTCD14
1251 inline
1252 typename std::enable_if
1253 <
1254 detail::no_overflow<Period, typename To::period>::value,
1255  To
1256  >::type
1257  floor(const std::chrono::duration<Rep, Period> &d)
1258 {
1259  auto t = trunc<To>(d);
1260  if (t > d)
1261  return t - To{1};
1262  return t;
1263 }
1264 
1265 template <class To, class Rep, class Period>
1266 CONSTCD14
1267 inline
1268 typename std::enable_if
1269 <
1270 !detail::no_overflow<Period, typename To::period>::value,
1271 To
1272 >::type
1273 floor(const std::chrono::duration<Rep, Period> &d)
1274 {
1275  using rep = typename std::common_type<Rep, typename To::rep>::type;
1276  return floor<To>(floor<std::chrono::duration<rep>>(d));
1277 }
1278 
1279 // round to nearest, to even on tie
1280 template <class To, class Rep, class Period>
1281 CONSTCD14
1282 inline
1283 To
1284 round(const std::chrono::duration<Rep, Period> &d)
1285 {
1286  auto t0 = floor<To>(d);
1287  auto t1 = t0 + To{1};
1288  if (t1 == To{0} && t0 < To{0})
1289  t1 = -t1;
1290  auto diff0 = d - t0;
1291  auto diff1 = t1 - d;
1292  if (diff0 == diff1) {
1293  if (t0 - trunc<To>(t0 / 2) * 2 == To{0})
1294  return t0;
1295  return t1;
1296  }
1297  if (diff0 < diff1) {
1298  return t0;
1299  }
1300  return t1;
1301 }
1302 
1303 // round up
1304 template <class To, class Rep, class Period>
1305 CONSTCD14
1306 inline
1307 To
1308 ceil(const std::chrono::duration<Rep, Period> &d)
1309 {
1310  auto t = trunc<To>(d);
1311  if (t < d)
1312  return t + To{1};
1313  return t;
1314 }
1315 
1316 template <class Rep, class Period,
1317  class = typename std::enable_if
1318  <
1319  std::numeric_limits<Rep>::is_signed
1320  >::type>
1321 CONSTCD11
1322 std::chrono::duration<Rep, Period>
1323 abs(std::chrono::duration<Rep, Period> d)
1324 {
1325  return d >= d.zero() ? d : -d;
1326 }
1327 
1328 // round down
1329 template <class To, class Clock, class FromDuration>
1330 CONSTCD11
1331 inline
1332 std::chrono::time_point<Clock, To>
1333 floor(const std::chrono::time_point<Clock, FromDuration> &tp)
1334 {
1335  using std::chrono::time_point;
1336  return time_point<Clock, To> {date::floor<To>(tp.time_since_epoch())};
1337 }
1338 
1339 // round to nearest, to even on tie
1340 template <class To, class Clock, class FromDuration>
1341 CONSTCD11
1342 inline
1343 std::chrono::time_point<Clock, To>
1344 round(const std::chrono::time_point<Clock, FromDuration> &tp)
1345 {
1346  using std::chrono::time_point;
1347  return time_point<Clock, To> {round<To>(tp.time_since_epoch())};
1348 }
1349 
1350 // round up
1351 template <class To, class Clock, class FromDuration>
1352 CONSTCD11
1353 inline
1354 std::chrono::time_point<Clock, To>
1355 ceil(const std::chrono::time_point<Clock, FromDuration> &tp)
1356 {
1357  using std::chrono::time_point;
1358  return time_point<Clock, To> {ceil<To>(tp.time_since_epoch())};
1359 }
1360 
1361 #else // HAS_CHRONO_ROUNDING == 1
1362 
1363 using std::chrono::floor;
1364 using std::chrono::ceil;
1365 using std::chrono::round;
1366 using std::chrono::abs;
1367 
1368 #endif // HAS_CHRONO_ROUNDING
1369 
1370 // trunc towards zero
1371 template <class To, class Clock, class FromDuration>
1372 CONSTCD11
1373 inline
1374 std::chrono::time_point<Clock, To>
1375 trunc(const std::chrono::time_point<Clock, FromDuration> &tp)
1376 {
1377  using std::chrono::time_point;
1378  return time_point<Clock, To> {trunc<To>(tp.time_since_epoch())};
1379 }
1380 
1381 // day
1382 
1383 CONSTCD11 inline day::day(unsigned d) NOEXCEPT :
1384 d_(static_cast<unsigned char>(d)) {}
1385 CONSTCD14 inline day &day::operator++() NOEXCEPT {++d_; return *this;}
1386 CONSTCD14 inline day day::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;}
1387 CONSTCD14 inline day &day::operator--() NOEXCEPT {--d_; return *this;}
1388 CONSTCD14 inline day day::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;}
1389 CONSTCD14 inline day &day::operator+=(const days &d) NOEXCEPT {*this = *this + d; return *this;}
1390 CONSTCD14 inline day &day::operator-=(const days &d) NOEXCEPT {*this = *this - d; return *this;}
1391 CONSTCD11 inline day::operator unsigned() const NOEXCEPT
1392 {
1393  return d_;
1394 }
1395 CONSTCD11 inline bool day::ok() const NOEXCEPT
1396 {
1397  return 1 <= d_ && d_ <= 31;
1398 }
1399 
1400 CONSTCD11
1401 inline
1402 bool
1403 operator==(const day &x, const day &y) NOEXCEPT {
1404  return static_cast<unsigned>(x) == static_cast<unsigned>(y);
1405 }
1406 
1407 CONSTCD11
1408 inline
1409 bool
1410 operator!=(const day &x, const day &y) NOEXCEPT {
1411  return !(x == y);
1412 }
1413 
1414 CONSTCD11
1415 inline
1416 bool
1417 operator<(const day &x, const day &y) NOEXCEPT {
1418  return static_cast<unsigned>(x) < static_cast<unsigned>(y);
1419 }
1420 
1421 CONSTCD11
1422 inline
1423 bool
1424 operator>(const day &x, const day &y) NOEXCEPT {
1425  return y < x;
1426 }
1427 
1428 CONSTCD11
1429 inline
1430 bool
1431 operator<=(const day &x, const day &y) NOEXCEPT {
1432  return !(y < x);
1433 }
1434 
1435 CONSTCD11
1436 inline
1437 bool
1438 operator>=(const day &x, const day &y) NOEXCEPT {
1439  return !(x < y);
1440 }
1441 
1442 CONSTCD11
1443 inline
1444 days
1445 operator-(const day &x, const day &y) NOEXCEPT {
1446  return days{
1447  static_cast<days::rep>(static_cast<unsigned>(x)
1448  - static_cast<unsigned>(y))};
1449 }
1450 
1451 CONSTCD11
1452 inline
1453 day
1454 operator+(const day &x, const days &y) NOEXCEPT {
1455  return day{static_cast<unsigned>(x) + static_cast<unsigned>(y.count())};
1456 }
1457 
1458 CONSTCD11
1459 inline
1460 day
1461 operator+(const days &x, const day &y) NOEXCEPT {
1462  return y + x;
1463 }
1464 
1465 CONSTCD11
1466 inline
1467 day
1468 operator-(const day &x, const days &y) NOEXCEPT {
1469  return x + -y;
1470 }
1471 
1472 template<class CharT, class Traits>
1473 inline
1474 std::basic_ostream<CharT, Traits> &
1475 operator<<(std::basic_ostream<CharT, Traits> &os, const day &d)
1476 {
1478  os.fill('0');
1479  os.flags(std::ios::dec | std::ios::right);
1480  os.width(2);
1481  os << static_cast<unsigned>(d);
1482  if (!d.ok()) {
1483  os << " is not a valid day";
1484  }
1485  return os;
1486 }
1487 
1488 // month
1489 
1490 CONSTCD11 inline month::month(unsigned m) NOEXCEPT :
1491 m_(static_cast<decltype(m_)>(m)) {}
1492 CONSTCD14 inline month &month::operator++() NOEXCEPT {*this += months{1}; return *this;}
1493 CONSTCD14 inline month month::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;}
1494 CONSTCD14 inline month &month::operator--() NOEXCEPT {*this -= months{1}; return *this;}
1495 CONSTCD14 inline month month::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;}
1496 
1497 CONSTCD14
1498 inline
1499 month &
1500 month::operator+=(const months &m) NOEXCEPT {
1501  *this = *this + m;
1502  return *this;
1503 }
1504 
1505 CONSTCD14
1506 inline
1507 month &
1508 month::operator-=(const months &m) NOEXCEPT {
1509  *this = *this - m;
1510  return *this;
1511 }
1512 
1513 CONSTCD11 inline month::operator unsigned() const NOEXCEPT
1514 {
1515  return m_;
1516 }
1517 CONSTCD11 inline bool month::ok() const NOEXCEPT
1518 {
1519  return 1 <= m_ && m_ <= 12;
1520 }
1521 
1522 CONSTCD11
1523 inline
1524 bool
1525 operator==(const month &x, const month &y) NOEXCEPT {
1526  return static_cast<unsigned>(x) == static_cast<unsigned>(y);
1527 }
1528 
1529 CONSTCD11
1530 inline
1531 bool
1532 operator!=(const month &x, const month &y) NOEXCEPT {
1533  return !(x == y);
1534 }
1535 
1536 CONSTCD11
1537 inline
1538 bool
1539 operator<(const month &x, const month &y) NOEXCEPT {
1540  return static_cast<unsigned>(x) < static_cast<unsigned>(y);
1541 }
1542 
1543 CONSTCD11
1544 inline
1545 bool
1546 operator>(const month &x, const month &y) NOEXCEPT {
1547  return y < x;
1548 }
1549 
1550 CONSTCD11
1551 inline
1552 bool
1553 operator<=(const month &x, const month &y) NOEXCEPT {
1554  return !(y < x);
1555 }
1556 
1557 CONSTCD11
1558 inline
1559 bool
1560 operator>=(const month &x, const month &y) NOEXCEPT {
1561  return !(x < y);
1562 }
1563 
1564 CONSTCD14
1565 inline
1566 months
1567 operator-(const month &x, const month &y) NOEXCEPT {
1568  auto const d = static_cast<unsigned>(x) - static_cast<unsigned>(y);
1569  return months(d <= 11 ? d : d + 12);
1570 }
1571 
1572 CONSTCD14
1573 inline
1574 month
1575 operator+(const month &x, const months &y) NOEXCEPT {
1576  auto const mu = static_cast<long long>(static_cast<unsigned>(x)) + (y.count() - 1);
1577  auto const yr = (mu >= 0 ? mu : mu - 11) / 12;
1578  return month{static_cast<unsigned>(mu - yr * 12 + 1)};
1579 }
1580 
1581 CONSTCD14
1582 inline
1583 month
1584 operator+(const months &x, const month &y) NOEXCEPT {
1585  return y + x;
1586 }
1587 
1588 CONSTCD14
1589 inline
1590 month
1591 operator-(const month &x, const months &y) NOEXCEPT {
1592  return x + -y;
1593 }
1594 
1595 template<class CharT, class Traits>
1596 inline
1597 std::basic_ostream<CharT, Traits> &
1598 operator<<(std::basic_ostream<CharT, Traits> &os, const month &m)
1599 {
1600  if (m.ok()) {
1601  CharT fmt[] = {'%', 'b', 0};
1602  os << format(os.getloc(), fmt, m);
1603  }
1604  else {
1605  os << static_cast<unsigned>(m) << " is not a valid month";
1606  }
1607  return os;
1608 }
1609 
1610 // year
1611 
1613 y_(static_cast<decltype(y_)>(y)) {}
1614 CONSTCD14 inline year &year::operator++() NOEXCEPT {++y_; return *this;}
1615 CONSTCD14 inline year year::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;}
1616 CONSTCD14 inline year &year::operator--() NOEXCEPT {--y_; return *this;}
1617 CONSTCD14 inline year year::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;}
1618 CONSTCD14 inline year &year::operator+=(const years &y) NOEXCEPT {*this = *this + y; return *this;}
1619 CONSTCD14 inline year &year::operator-=(const years &y) NOEXCEPT {*this = *this - y; return *this;}
1620 CONSTCD11 inline year year::operator-() const NOEXCEPT
1621 {
1622  return year{-y_};
1623 }
1624 CONSTCD11 inline year year::operator+() const NOEXCEPT
1625 {
1626  return *this;
1627 }
1628 
1629 CONSTCD11
1630 inline
1631 bool
1632 year::is_leap() const NOEXCEPT
1633 {
1634  return y_ % 4 == 0 && (y_ % 100 != 0 || y_ % 400 == 0);
1635 }
1636 
1637 CONSTCD11 inline year::operator int() const NOEXCEPT
1638 {
1639  return y_;
1640 }
1641 
1642 CONSTCD11
1643 inline
1644 bool
1645 year::ok() const NOEXCEPT
1646 {
1647  return y_ != std::numeric_limits<short>::min();
1648 }
1649 
1650 CONSTCD11
1651 inline
1652 bool
1653 operator==(const year &x, const year &y) NOEXCEPT {
1654  return static_cast<int>(x) == static_cast<int>(y);
1655 }
1656 
1657 CONSTCD11
1658 inline
1659 bool
1660 operator!=(const year &x, const year &y) NOEXCEPT {
1661  return !(x == y);
1662 }
1663 
1664 CONSTCD11
1665 inline
1666 bool
1667 operator<(const year &x, const year &y) NOEXCEPT {
1668  return static_cast<int>(x) < static_cast<int>(y);
1669 }
1670 
1671 CONSTCD11
1672 inline
1673 bool
1674 operator>(const year &x, const year &y) NOEXCEPT {
1675  return y < x;
1676 }
1677 
1678 CONSTCD11
1679 inline
1680 bool
1681 operator<=(const year &x, const year &y) NOEXCEPT {
1682  return !(y < x);
1683 }
1684 
1685 CONSTCD11
1686 inline
1687 bool
1688 operator>=(const year &x, const year &y) NOEXCEPT {
1689  return !(x < y);
1690 }
1691 
1692 CONSTCD11
1693 inline
1694 years
1695 operator-(const year &x, const year &y) NOEXCEPT {
1696  return years{static_cast<int>(x) - static_cast<int>(y)};
1697 }
1698 
1699 CONSTCD11
1700 inline
1701 year
1702 operator+(const year &x, const years &y) NOEXCEPT {
1703  return year{static_cast<int>(x) + y.count()};
1704 }
1705 
1706 CONSTCD11
1707 inline
1708 year
1709 operator+(const years &x, const year &y) NOEXCEPT {
1710  return y + x;
1711 }
1712 
1713 CONSTCD11
1714 inline
1715 year
1716 operator-(const year &x, const years &y) NOEXCEPT {
1717  return year{static_cast<int>(x) - y.count()};
1718 }
1719 
1720 template<class CharT, class Traits>
1721 inline
1722 std::basic_ostream<CharT, Traits> &
1723 operator<<(std::basic_ostream<CharT, Traits> &os, const year &y)
1724 {
1726  os.fill('0');
1727  os.flags(std::ios::dec | std::ios::internal);
1728  os.width(4 + (y < year{0}));
1729  os.imbue(std::locale::classic());
1730  os << static_cast<int>(y);
1731  if (!y.ok()) {
1732  os << " is not a valid year";
1733  }
1734  return os;
1735 }
1736 
1737 // weekday
1738 
1739 CONSTCD14
1740 inline
1741 unsigned char
1742 weekday::weekday_from_days(int z) NOEXCEPT {
1743  auto u = static_cast<unsigned>(z);
1744  return static_cast<unsigned char>(z >= -4 ? (u + 4) % 7 : u % 7);
1745 }
1746 
1747 CONSTCD11
1748 inline
1750 :
1751 wd_(static_cast<decltype(wd_)>(wd != 7 ? wd : 0))
1752 {}
1753 
1754 CONSTCD14
1755 inline
1757 :
1758 wd_(weekday_from_days(dp.time_since_epoch().count()))
1759 {}
1760 
1761 CONSTCD14
1762 inline
1764 :
1765 wd_(weekday_from_days(dp.time_since_epoch().count()))
1766 {}
1767 
1768 CONSTCD14 inline weekday &weekday::operator++() NOEXCEPT {*this += days{1}; return *this;}
1769 CONSTCD14 inline weekday weekday::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;}
1770 CONSTCD14 inline weekday &weekday::operator--() NOEXCEPT {*this -= days{1}; return *this;}
1771 CONSTCD14 inline weekday weekday::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;}
1772 
1773 CONSTCD14
1774 inline
1775 weekday &
1776 weekday::operator+=(const days &d) NOEXCEPT {
1777  *this = *this + d;
1778  return *this;
1779 }
1780 
1781 CONSTCD14
1782 inline
1783 weekday &
1784 weekday::operator-=(const days &d) NOEXCEPT {
1785  *this = *this - d;
1786  return *this;
1787 }
1788 
1789 CONSTCD11 inline bool weekday::ok() const NOEXCEPT
1790 {
1791  return wd_ <= 6;
1792 }
1793 
1794 CONSTCD11
1795 inline
1796 unsigned weekday::c_encoding() const NOEXCEPT
1797 {
1798  return unsigned{wd_};
1799 }
1800 
1801 CONSTCD11
1802 inline
1803 unsigned weekday::iso_encoding() const NOEXCEPT
1804 {
1805  return unsigned{((wd_ == 0u) ? 7u : wd_)};
1806 }
1807 
1808 CONSTCD11
1809 inline
1810 bool
1811 operator==(const weekday &x, const weekday &y) NOEXCEPT {
1812  return x.wd_ == y.wd_;
1813 }
1814 
1815 CONSTCD11
1816 inline
1817 bool
1818 operator!=(const weekday &x, const weekday &y) NOEXCEPT {
1819  return !(x == y);
1820 }
1821 
1822 CONSTCD14
1823 inline
1824 days
1825 operator-(const weekday &x, const weekday &y) NOEXCEPT {
1826  auto const wdu = x.wd_ - y.wd_;
1827  auto const wk = (wdu >= 0 ? wdu : wdu - 6) / 7;
1828  return days{wdu - wk * 7};
1829 }
1830 
1831 CONSTCD14
1832 inline
1833 weekday
1834 operator+(const weekday &x, const days &y) NOEXCEPT {
1835  auto const wdu = static_cast<long long>(static_cast<unsigned>(x.wd_)) + y.count();
1836  auto const wk = (wdu >= 0 ? wdu : wdu - 6) / 7;
1837  return weekday{static_cast<unsigned>(wdu - wk * 7)};
1838 }
1839 
1840 CONSTCD14
1841 inline
1842 weekday
1843 operator+(const days &x, const weekday &y) NOEXCEPT {
1844  return y + x;
1845 }
1846 
1847 CONSTCD14
1848 inline
1849 weekday
1850 operator-(const weekday &x, const days &y) NOEXCEPT {
1851  return x + -y;
1852 }
1853 
1854 template<class CharT, class Traits>
1855 inline
1856 std::basic_ostream<CharT, Traits> &
1857 operator<<(std::basic_ostream<CharT, Traits> &os, const weekday &wd)
1858 {
1859  if (wd.ok()) {
1860  CharT fmt[] = {'%', 'a', 0};
1861  os << format(fmt, wd);
1862  }
1863  else {
1864  os << static_cast<unsigned>(wd.wd_) << " is not a valid weekday";
1865  }
1866  return os;
1867 }
1868 
1869 #if !defined(_MSC_VER) || (_MSC_VER >= 1900)
1870 inline namespace literals {
1871 
1872 CONSTCD11
1873 inline
1874 date::day
1875 operator "" _d(unsigned long long d) NOEXCEPT {
1876  return date::day{static_cast<unsigned>(d)};
1877 }
1878 
1879 CONSTCD11
1880 inline
1881 date::year
1882 operator "" _y(unsigned long long y) NOEXCEPT {
1883  return date::year(static_cast<int>(y));
1884 }
1885 #endif // !defined(_MSC_VER) || (_MSC_VER >= 1900)
1886 
1888 
1901 
1909 
1910 #if !defined(_MSC_VER) || (_MSC_VER >= 1900)
1911 } // inline namespace literals
1912 #endif
1913 
1926 
1934 
1935 // weekday_indexed
1936 
1937 CONSTCD11
1938 inline
1939 weekday
1941 {
1942  return date::weekday{static_cast<unsigned>(wd_)};
1943 }
1944 
1945 CONSTCD11 inline unsigned weekday_indexed::index() const NOEXCEPT
1946 {
1947  return index_;
1948 }
1949 
1950 CONSTCD11
1951 inline
1952 bool
1953 weekday_indexed::ok() const NOEXCEPT
1954 {
1955  return weekday().ok() && 1 <= index_ && index_ <= 5;
1956 }
1957 
1958 #ifdef __GNUC__
1959 # pragma GCC diagnostic push
1960 # pragma GCC diagnostic ignored "-Wconversion"
1961 #endif // __GNUC__
1962 
1963 CONSTCD11
1964 inline
1966  unsigned index) NOEXCEPT
1967 :
1968 wd_(static_cast<decltype(wd_)>(static_cast<unsigned>(wd.wd_)))
1969 , index_(static_cast<decltype(index_)>(index))
1970 {}
1971 
1972 #ifdef __GNUC__
1973 # pragma GCC diagnostic pop
1974 #endif // __GNUC__
1975 
1976 template<class CharT, class Traits>
1977 inline
1978 std::basic_ostream<CharT, Traits> &
1979 operator<<(std::basic_ostream<CharT, Traits> &os, const weekday_indexed &wdi)
1980 {
1981  os << wdi.weekday() << '[' << wdi.index();
1982  if (!(1 <= wdi.index() && wdi.index() <= 5)) {
1983  os << " is not a valid index";
1984  }
1985  os << ']';
1986  return os;
1987 }
1988 
1989 CONSTCD11
1990 inline
1992 weekday::operator[](unsigned index) const NOEXCEPT
1993 {
1994  return {*this, index};
1995 }
1996 
1997 CONSTCD11
1998 inline
1999 bool
2000 operator==(const weekday_indexed &x, const weekday_indexed &y) NOEXCEPT {
2001  return x.weekday() == y.weekday() && x.index() == y.index();
2002 }
2003 
2004 CONSTCD11
2005 inline
2006 bool
2007 operator!=(const weekday_indexed &x, const weekday_indexed &y) NOEXCEPT {
2008  return !(x == y);
2009 }
2010 
2011 // weekday_last
2012 
2014 {
2015  return wd_;
2016 }
2017 CONSTCD11 inline bool weekday_last::ok() const NOEXCEPT
2018 {
2019  return wd_.ok();
2020 }
2022 wd_(wd) {}
2023 
2024 CONSTCD11
2025 inline
2026 bool
2027 operator==(const weekday_last &x, const weekday_last &y) NOEXCEPT {
2028  return x.weekday() == y.weekday();
2029 }
2030 
2031 CONSTCD11
2032 inline
2033 bool
2034 operator!=(const weekday_last &x, const weekday_last &y) NOEXCEPT {
2035  return !(x == y);
2036 }
2037 
2038 template<class CharT, class Traits>
2039 inline
2040 std::basic_ostream<CharT, Traits> &
2041 operator<<(std::basic_ostream<CharT, Traits> &os, const weekday_last &wdl)
2042 {
2043  return os << wdl.weekday() << "[last]";
2044 }
2045 
2046 CONSTCD11
2047 inline
2050 {
2051  return weekday_last{*this};
2052 }
2053 
2054 // year_month
2055 
2056 CONSTCD11
2057 inline
2059 :
2060 y_(y)
2061 , m_(m)
2062 {}
2063 
2064 CONSTCD11 inline year year_month::year() const NOEXCEPT
2065 {
2066  return y_;
2067 }
2068 CONSTCD11 inline month year_month::month() const NOEXCEPT
2069 {
2070  return m_;
2071 }
2072 CONSTCD11 inline bool year_month::ok() const NOEXCEPT
2073 {
2074  return y_.ok() && m_.ok();
2075 }
2076 
2077 template<class>
2078 CONSTCD14
2079 inline
2080 year_month &
2081 year_month::operator+=(const months &dm) NOEXCEPT {
2082  *this = *this + dm;
2083  return *this;
2084 }
2085 
2086 template<class>
2087 CONSTCD14
2088 inline
2089 year_month &
2090 year_month::operator-=(const months &dm) NOEXCEPT {
2091  *this = *this - dm;
2092  return *this;
2093 }
2094 
2095 CONSTCD14
2096 inline
2097 year_month &
2098 year_month::operator+=(const years &dy) NOEXCEPT {
2099  *this = *this + dy;
2100  return *this;
2101 }
2102 
2103 CONSTCD14
2104 inline
2105 year_month &
2106 year_month::operator-=(const years &dy) NOEXCEPT {
2107  *this = *this - dy;
2108  return *this;
2109 }
2110 
2111 CONSTCD11
2112 inline
2113 bool
2114 operator==(const year_month &x, const year_month &y) NOEXCEPT {
2115  return x.year() == y.year() && x.month() == y.month();
2116 }
2117 
2118 CONSTCD11
2119 inline
2120 bool
2121 operator!=(const year_month &x, const year_month &y) NOEXCEPT {
2122  return !(x == y);
2123 }
2124 
2125 CONSTCD11
2126 inline
2127 bool
2128 operator<(const year_month &x, const year_month &y) NOEXCEPT {
2129  return x.year() < y.year() ? true
2130  : (x.year() > y.year() ? false
2131  : (x.month() < y.month()));
2132 }
2133 
2134 CONSTCD11
2135 inline
2136 bool
2137 operator>(const year_month &x, const year_month &y) NOEXCEPT {
2138  return y < x;
2139 }
2140 
2141 CONSTCD11
2142 inline
2143 bool
2144 operator<=(const year_month &x, const year_month &y) NOEXCEPT {
2145  return !(y < x);
2146 }
2147 
2148 CONSTCD11
2149 inline
2150 bool
2151 operator>=(const year_month &x, const year_month &y) NOEXCEPT {
2152  return !(x < y);
2153 }
2154 
2155 template<class>
2156 CONSTCD14
2157 inline
2158 year_month
2159 operator+(const year_month &ym, const months &dm) NOEXCEPT {
2160  auto dmi = static_cast<int>(static_cast<unsigned>(ym.month())) - 1 + dm.count();
2161  auto dy = (dmi >= 0 ? dmi : dmi - 11) / 12;
2162  dmi = dmi - dy * 12 + 1;
2163  return (ym.year() + years(dy)) / month(static_cast<unsigned>(dmi));
2164 }
2165 
2166 template<class>
2167 CONSTCD14
2168 inline
2169 year_month
2170 operator+(const months &dm, const year_month &ym) NOEXCEPT {
2171  return ym + dm;
2172 }
2173 
2174 template<class>
2175 CONSTCD14
2176 inline
2177 year_month
2178 operator-(const year_month &ym, const months &dm) NOEXCEPT {
2179  return ym + -dm;
2180 }
2181 
2182 CONSTCD11
2183 inline
2184 months
2185 operator-(const year_month &x, const year_month &y) NOEXCEPT {
2186  return (x.year() - y.year()) +
2187  months(static_cast<unsigned>(x.month()) - static_cast<unsigned>(y.month()));
2188 }
2189 
2190 CONSTCD11
2191 inline
2192 year_month
2193 operator+(const year_month &ym, const years &dy) NOEXCEPT {
2194  return (ym.year() + dy) / ym.month();
2195 }
2196 
2197 CONSTCD11
2198 inline
2199 year_month
2200 operator+(const years &dy, const year_month &ym) NOEXCEPT {
2201  return ym + dy;
2202 }
2203 
2204 CONSTCD11
2205 inline
2206 year_month
2207 operator-(const year_month &ym, const years &dy) NOEXCEPT {
2208  return ym + -dy;
2209 }
2210 
2211 template<class CharT, class Traits>
2212 inline
2213 std::basic_ostream<CharT, Traits> &
2214 operator<<(std::basic_ostream<CharT, Traits> &os, const year_month &ym)
2215 {
2216  return os << ym.year() << '/' << ym.month();
2217 }
2218 
2219 // month_day
2220 
2221 CONSTCD11
2222 inline
2224 :
2225 m_(m)
2226 , d_(d)
2227 {}
2228 
2229 CONSTCD11 inline date::month month_day::month() const NOEXCEPT
2230 {
2231  return m_;
2232 }
2233 CONSTCD11 inline date::day month_day::day() const NOEXCEPT
2234 {
2235  return d_;
2236 }
2237 
2238 CONSTCD14
2239 inline
2240 bool
2241 month_day::ok() const NOEXCEPT
2242 {
2243  CONSTDATA date::day d[] = {
2244  date::day(31), date::day(29), date::day(31),
2245  date::day(30), date::day(31), date::day(30),
2246  date::day(31), date::day(31), date::day(30),
2247  date::day(31), date::day(30), date::day(31)
2248  };
2249  return m_.ok() && date::day{1} <= d_ &&d_ <= d[static_cast<unsigned>(m_) - 1];
2250 }
2251 
2252 CONSTCD11
2253 inline
2254 bool
2255 operator==(const month_day &x, const month_day &y) NOEXCEPT {
2256  return x.month() == y.month() && x.day() == y.day();
2257 }
2258 
2259 CONSTCD11
2260 inline
2261 bool
2262 operator!=(const month_day &x, const month_day &y) NOEXCEPT {
2263  return !(x == y);
2264 }
2265 
2266 CONSTCD11
2267 inline
2268 bool
2269 operator<(const month_day &x, const month_day &y) NOEXCEPT {
2270  return x.month() < y.month() ? true
2271  : (x.month() > y.month() ? false
2272  : (x.day() < y.day()));
2273 }
2274 
2275 CONSTCD11
2276 inline
2277 bool
2278 operator>(const month_day &x, const month_day &y) NOEXCEPT {
2279  return y < x;
2280 }
2281 
2282 CONSTCD11
2283 inline
2284 bool
2285 operator<=(const month_day &x, const month_day &y) NOEXCEPT {
2286  return !(y < x);
2287 }
2288 
2289 CONSTCD11
2290 inline
2291 bool
2292 operator>=(const month_day &x, const month_day &y) NOEXCEPT {
2293  return !(x < y);
2294 }
2295 
2296 template<class CharT, class Traits>
2297 inline
2298 std::basic_ostream<CharT, Traits> &
2299 operator<<(std::basic_ostream<CharT, Traits> &os, const month_day &md)
2300 {
2301  return os << md.month() << '/' << md.day();
2302 }
2303 
2304 // month_day_last
2305 
2306 CONSTCD11 inline month month_day_last::month() const NOEXCEPT
2307 {
2308  return m_;
2309 }
2310 CONSTCD11 inline bool month_day_last::ok() const NOEXCEPT
2311 {
2312  return m_.ok();
2313 }
2315 m_(m) {}
2316 
2317 CONSTCD11
2318 inline
2319 bool
2320 operator==(const month_day_last &x, const month_day_last &y) NOEXCEPT {
2321  return x.month() == y.month();
2322 }
2323 
2324 CONSTCD11
2325 inline
2326 bool
2327 operator!=(const month_day_last &x, const month_day_last &y) NOEXCEPT {
2328  return !(x == y);
2329 }
2330 
2331 CONSTCD11
2332 inline
2333 bool
2334 operator<(const month_day_last &x, const month_day_last &y) NOEXCEPT {
2335  return x.month() < y.month();
2336 }
2337 
2338 CONSTCD11
2339 inline
2340 bool
2341 operator>(const month_day_last &x, const month_day_last &y) NOEXCEPT {
2342  return y < x;
2343 }
2344 
2345 CONSTCD11
2346 inline
2347 bool
2348 operator<=(const month_day_last &x, const month_day_last &y) NOEXCEPT {
2349  return !(y < x);
2350 }
2351 
2352 CONSTCD11
2353 inline
2354 bool
2355 operator>=(const month_day_last &x, const month_day_last &y) NOEXCEPT {
2356  return !(x < y);
2357 }
2358 
2359 template<class CharT, class Traits>
2360 inline
2361 std::basic_ostream<CharT, Traits> &
2362 operator<<(std::basic_ostream<CharT, Traits> &os, const month_day_last &mdl)
2363 {
2364  return os << mdl.month() << "/last";
2365 }
2366 
2367 // month_weekday
2368 
2369 CONSTCD11
2370 inline
2372  const date::weekday_indexed &wdi) NOEXCEPT
2373 :
2374 m_(m)
2375 , wdi_(wdi)
2376 {}
2377 
2378 CONSTCD11 inline month month_weekday::month() const NOEXCEPT
2379 {
2380  return m_;
2381 }
2382 
2383 CONSTCD11
2384 inline
2387 {
2388  return wdi_;
2389 }
2390 
2391 CONSTCD11
2392 inline
2393 bool
2394 month_weekday::ok() const NOEXCEPT
2395 {
2396  return m_.ok() && wdi_.ok();
2397 }
2398 
2399 CONSTCD11
2400 inline
2401 bool
2402 operator==(const month_weekday &x, const month_weekday &y) NOEXCEPT {
2403  return x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed();
2404 }
2405 
2406 CONSTCD11
2407 inline
2408 bool
2409 operator!=(const month_weekday &x, const month_weekday &y) NOEXCEPT {
2410  return !(x == y);
2411 }
2412 
2413 template<class CharT, class Traits>
2414 inline
2415 std::basic_ostream<CharT, Traits> &
2416 operator<<(std::basic_ostream<CharT, Traits> &os, const month_weekday &mwd)
2417 {
2418  return os << mwd.month() << '/' << mwd.weekday_indexed();
2419 }
2420 
2421 // month_weekday_last
2422 
2423 CONSTCD11
2424 inline
2426  const date::weekday_last &wdl) NOEXCEPT
2427 :
2428 m_(m)
2429 , wdl_(wdl)
2430 {}
2431 
2433 {
2434  return m_;
2435 }
2436 
2437 CONSTCD11
2438 inline
2441 {
2442  return wdl_;
2443 }
2444 
2445 CONSTCD11
2446 inline
2447 bool
2448 month_weekday_last::ok() const NOEXCEPT
2449 {
2450  return m_.ok() && wdl_.ok();
2451 }
2452 
2453 CONSTCD11
2454 inline
2455 bool
2456 operator==(const month_weekday_last &x, const month_weekday_last &y) NOEXCEPT {
2457  return x.month() == y.month() && x.weekday_last() == y.weekday_last();
2458 }
2459 
2460 CONSTCD11
2461 inline
2462 bool
2463 operator!=(const month_weekday_last &x, const month_weekday_last &y) NOEXCEPT {
2464  return !(x == y);
2465 }
2466 
2467 template<class CharT, class Traits>
2468 inline
2469 std::basic_ostream<CharT, Traits> &
2470 operator<<(std::basic_ostream<CharT, Traits> &os,
2471  const month_weekday_last &mwdl)
2472 {
2473  return os << mwdl.month() << '/' << mwdl.weekday_last();
2474 }
2475 
2476 // year_month_day_last
2477 
2478 CONSTCD11
2479 inline
2481  const date::month_day_last &mdl) NOEXCEPT
2482 :
2483 y_(y)
2484 , mdl_(mdl)
2485 {}
2486 
2487 template<class>
2488 CONSTCD14
2489 inline
2492  *this = *this + m;
2493  return *this;
2494 }
2495 
2496 template<class>
2497 CONSTCD14
2498 inline
2501  *this = *this - m;
2502  return *this;
2503 }
2504 
2505 CONSTCD14
2506 inline
2509  *this = *this + y;
2510  return *this;
2511 }
2512 
2513 CONSTCD14
2514 inline
2517  *this = *this - y;
2518  return *this;
2519 }
2520 
2522 {
2523  return y_;
2524 }
2526 {
2527  return mdl_.month();
2528 }
2529 
2530 CONSTCD11
2531 inline
2534 {
2535  return mdl_;
2536 }
2537 
2538 CONSTCD14
2539 inline
2540 day
2542 {
2543  CONSTDATA date::day d[] = {
2544  date::day(31), date::day(28), date::day(31),
2545  date::day(30), date::day(31), date::day(30),
2546  date::day(31), date::day(31), date::day(30),
2547  date::day(31), date::day(30), date::day(31)
2548  };
2549  return (month() != February || !y_.is_leap()) && mdl_.ok() ?
2550  d[static_cast<unsigned>(month()) - 1] : date::day{29};
2551 }
2552 
2553 CONSTCD14
2554 inline
2555 year_month_day_last::operator sys_days() const NOEXCEPT
2556 {
2557  return sys_days(year() / month() / day());
2558 }
2559 
2560 CONSTCD14
2561 inline
2562 year_month_day_last::operator local_days() const NOEXCEPT
2563 {
2564  return local_days(year() / month() / day());
2565 }
2566 
2567 CONSTCD11
2568 inline
2569 bool
2570 year_month_day_last::ok() const NOEXCEPT
2571 {
2572  return y_.ok() && mdl_.ok();
2573 }
2574 
2575 CONSTCD11
2576 inline
2577 bool
2579  const year_month_day_last &y) NOEXCEPT {
2580  return x.year() == y.year() && x.month_day_last() == y.month_day_last();
2581 }
2582 
2583 CONSTCD11
2584 inline
2585 bool
2587  const year_month_day_last &y) NOEXCEPT {
2588  return !(x == y);
2589 }
2590 
2591 CONSTCD11
2592 inline
2593 bool
2594 operator<(const year_month_day_last &x, const year_month_day_last &y) NOEXCEPT {
2595  return x.year() < y.year() ? true
2596  : (x.year() > y.year() ? false
2597  : (x.month_day_last() < y.month_day_last()));
2598 }
2599 
2600 CONSTCD11
2601 inline
2602 bool
2603 operator>(const year_month_day_last &x, const year_month_day_last &y) NOEXCEPT {
2604  return y < x;
2605 }
2606 
2607 CONSTCD11
2608 inline
2609 bool
2611  const year_month_day_last &y) NOEXCEPT {
2612  return !(y < x);
2613 }
2614 
2615 CONSTCD11
2616 inline
2617 bool
2619  const year_month_day_last &y) NOEXCEPT {
2620  return !(x < y);
2621 }
2622 
2623 template<class CharT, class Traits>
2624 inline
2625 std::basic_ostream<CharT, Traits> &
2626 operator<<(std::basic_ostream<CharT, Traits> &os,
2627  const year_month_day_last &ymdl)
2628 {
2629  return os << ymdl.year() << '/' << ymdl.month_day_last();
2630 }
2631 
2632 template<class>
2633 CONSTCD14
2634 inline
2636 operator+(const year_month_day_last &ymdl, const months &dm) NOEXCEPT {
2637  return (ymdl.year() / ymdl.month() + dm) / last;
2638 }
2639 
2640 template<class>
2641 CONSTCD14
2642 inline
2644 operator+(const months &dm, const year_month_day_last &ymdl) NOEXCEPT {
2645  return ymdl + dm;
2646 }
2647 
2648 template<class>
2649 CONSTCD14
2650 inline
2652 operator-(const year_month_day_last &ymdl, const months &dm) NOEXCEPT {
2653  return ymdl + (-dm);
2654 }
2655 
2656 CONSTCD11
2657 inline
2659 operator+(const year_month_day_last &ymdl, const years &dy) NOEXCEPT {
2660  return {ymdl.year() + dy, ymdl.month_day_last()};
2661 }
2662 
2663 CONSTCD11
2664 inline
2666 operator+(const years &dy, const year_month_day_last &ymdl) NOEXCEPT {
2667  return ymdl + dy;
2668 }
2669 
2670 CONSTCD11
2671 inline
2673 operator-(const year_month_day_last &ymdl, const years &dy) NOEXCEPT {
2674  return ymdl + (-dy);
2675 }
2676 
2677 // year_month_day
2678 
2679 CONSTCD11
2680 inline
2682  const date::day &d) NOEXCEPT
2683 :
2684 y_(y)
2685 , m_(m)
2686 , d_(d)
2687 {}
2688 
2689 CONSTCD14
2690 inline
2692 :
2693 y_(ymdl.year())
2694 , m_(ymdl.month())
2695 , d_(ymdl.day())
2696 {}
2697 
2698 CONSTCD14
2699 inline
2701 :
2702 year_month_day(from_days(dp.time_since_epoch()))
2703 {}
2704 
2705 CONSTCD14
2706 inline
2708 :
2709 year_month_day(from_days(dp.time_since_epoch()))
2710 {}
2711 
2712 CONSTCD11 inline year year_month_day::year() const NOEXCEPT
2713 {
2714  return y_;
2715 }
2716 CONSTCD11 inline month year_month_day::month() const NOEXCEPT
2717 {
2718  return m_;
2719 }
2720 CONSTCD11 inline day year_month_day::day() const NOEXCEPT
2721 {
2722  return d_;
2723 }
2724 
2725 template<class>
2726 CONSTCD14
2727 inline
2730  *this = *this + m;
2731  return *this;
2732 }
2733 
2734 template<class>
2735 CONSTCD14
2736 inline
2739  *this = *this - m;
2740  return *this;
2741 }
2742 
2743 CONSTCD14
2744 inline
2746 year_month_day::operator+=(const years &y) NOEXCEPT {
2747  *this = *this + y;
2748  return *this;
2749 }
2750 
2751 CONSTCD14
2752 inline
2754 year_month_day::operator-=(const years &y) NOEXCEPT {
2755  *this = *this - y;
2756  return *this;
2757 }
2758 
2759 CONSTCD14
2760 inline
2761 days
2762 year_month_day::to_days() const NOEXCEPT
2763 {
2764  static_assert(std::numeric_limits<unsigned>::digits >= 18,
2765  "This algorithm has not been ported to a 16 bit unsigned integer");
2766  static_assert(std::numeric_limits<int>::digits >= 20,
2767  "This algorithm has not been ported to a 16 bit signed integer");
2768  auto const y = static_cast<int>(y_) - (m_ <= February);
2769  auto const m = static_cast<unsigned>(m_);
2770  auto const d = static_cast<unsigned>(d_);
2771  auto const era = (y >= 0 ? y : y - 399) / 400;
2772  auto const yoe = static_cast<unsigned>(y - era * 400); // [0, 399]
2773  auto const doy = (153 * (m > 2 ? m - 3 : m + 9) + 2) / 5 + d - 1; // [0, 365]
2774  auto const doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096]
2775  return days{era * 146097 + static_cast<int>(doe) - 719468};
2776 }
2777 
2778 CONSTCD14
2779 inline
2780 year_month_day::operator sys_days() const NOEXCEPT
2781 {
2782  return sys_days{to_days()};
2783 }
2784 
2785 CONSTCD14
2786 inline
2787 year_month_day::operator local_days() const NOEXCEPT
2788 {
2789  return local_days{to_days()};
2790 }
2791 
2792 CONSTCD14
2793 inline
2794 bool
2795 year_month_day::ok() const NOEXCEPT
2796 {
2797  if (!(y_.ok() && m_.ok())) {
2798  return false;
2799  }
2800  return date::day{1} <= d_ &&d_ <= (y_ / m_ / last).day();
2801 }
2802 
2803 CONSTCD11
2804 inline
2805 bool
2806 operator==(const year_month_day &x, const year_month_day &y) NOEXCEPT {
2807  return x.year() == y.year() && x.month() == y.month() && x.day() == y.day();
2808 }
2809 
2810 CONSTCD11
2811 inline
2812 bool
2813 operator!=(const year_month_day &x, const year_month_day &y) NOEXCEPT {
2814  return !(x == y);
2815 }
2816 
2817 CONSTCD11
2818 inline
2819 bool
2820 operator<(const year_month_day &x, const year_month_day &y) NOEXCEPT {
2821  return x.year() < y.year() ? true
2822  : (x.year() > y.year() ? false
2823  : (x.month() < y.month() ? true
2824  : (x.month() > y.month() ? false
2825  : (x.day() < y.day()))));
2826 }
2827 
2828 CONSTCD11
2829 inline
2830 bool
2831 operator>(const year_month_day &x, const year_month_day &y) NOEXCEPT {
2832  return y < x;
2833 }
2834 
2835 CONSTCD11
2836 inline
2837 bool
2838 operator<=(const year_month_day &x, const year_month_day &y) NOEXCEPT {
2839  return !(y < x);
2840 }
2841 
2842 CONSTCD11
2843 inline
2844 bool
2845 operator>=(const year_month_day &x, const year_month_day &y) NOEXCEPT {
2846  return !(x < y);
2847 }
2848 
2849 template<class CharT, class Traits>
2850 inline
2851 std::basic_ostream<CharT, Traits> &
2852 operator<<(std::basic_ostream<CharT, Traits> &os, const year_month_day &ymd)
2853 {
2855  os.fill('0');
2856  os.flags(std::ios::dec | std::ios::right);
2857  os << ymd.year() << '-';
2858  os.width(2);
2859  os << static_cast<unsigned>(ymd.month()) << '-';
2860  os << ymd.day();
2861  if (!ymd.ok()) {
2862  os << " is not a valid date";
2863  }
2864  return os;
2865 }
2866 
2867 CONSTCD14
2868 inline
2870 year_month_day::from_days(days dp) NOEXCEPT {
2871  static_assert(std::numeric_limits<unsigned>::digits >= 18,
2872  "This algorithm has not been ported to a 16 bit unsigned integer");
2873  static_assert(std::numeric_limits<int>::digits >= 20,
2874  "This algorithm has not been ported to a 16 bit signed integer");
2875  auto const z = dp.count() + 719468;
2876  auto const era = (z >= 0 ? z : z - 146096) / 146097;
2877  auto const doe = static_cast<unsigned>(z - era * 146097); // [0, 146096]
2878  auto const yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; // [0, 399]
2879  auto const y = static_cast<days::rep>(yoe) + era * 400;
2880  auto const doy = doe - (365 * yoe + yoe / 4 - yoe / 100); // [0, 365]
2881  auto const mp = (5 * doy + 2) / 153; // [0, 11]
2882  auto const d = doy - (153 * mp + 2) / 5 + 1; // [1, 31]
2883  auto const m = mp < 10 ? mp + 3 : mp - 9; // [1, 12]
2884  return year_month_day{date::year{y + (m <= 2)}, date::month(m), date::day(d)};
2885 }
2886 
2887 template<class>
2888 CONSTCD14
2889 inline
2891 operator+(const year_month_day &ymd, const months &dm) NOEXCEPT {
2892  return (ymd.year() / ymd.month() + dm) / ymd.day();
2893 }
2894 
2895 template<class>
2896 CONSTCD14
2897 inline
2899 operator+(const months &dm, const year_month_day &ymd) NOEXCEPT {
2900  return ymd + dm;
2901 }
2902 
2903 template<class>
2904 CONSTCD14
2905 inline
2907 operator-(const year_month_day &ymd, const months &dm) NOEXCEPT {
2908  return ymd + (-dm);
2909 }
2910 
2911 CONSTCD11
2912 inline
2914 operator+(const year_month_day &ymd, const years &dy) NOEXCEPT {
2915  return (ymd.year() + dy) / ymd.month() / ymd.day();
2916 }
2917 
2918 CONSTCD11
2919 inline
2921 operator+(const years &dy, const year_month_day &ymd) NOEXCEPT {
2922  return ymd + dy;
2923 }
2924 
2925 CONSTCD11
2926 inline
2928 operator-(const year_month_day &ymd, const years &dy) NOEXCEPT {
2929  return ymd + (-dy);
2930 }
2931 
2932 // year_month_weekday
2933 
2934 CONSTCD11
2935 inline
2937  const date::month &m,
2938  const date::weekday_indexed &wdi)
2939 NOEXCEPT
2940 :
2941 y_(y)
2942 , m_(m)
2943 , wdi_(wdi)
2944 {}
2945 
2946 CONSTCD14
2947 inline
2949 :
2950 year_month_weekday(from_days(dp.time_since_epoch()))
2951 {}
2952 
2953 CONSTCD14
2954 inline
2956 :
2957 year_month_weekday(from_days(dp.time_since_epoch()))
2958 {}
2959 
2960 template<class>
2961 CONSTCD14
2962 inline
2965  *this = *this + m;
2966  return *this;
2967 }
2968 
2969 template<class>
2970 CONSTCD14
2971 inline
2974  *this = *this - m;
2975  return *this;
2976 }
2977 
2978 CONSTCD14
2979 inline
2982  *this = *this + y;
2983  return *this;
2984 }
2985 
2986 CONSTCD14
2987 inline
2990  *this = *this - y;
2991  return *this;
2992 }
2993 
2994 CONSTCD11 inline year year_month_weekday::year() const NOEXCEPT
2995 {
2996  return y_;
2997 }
2999 {
3000  return m_;
3001 }
3002 
3003 CONSTCD11
3004 inline
3005 weekday
3007 {
3008  return wdi_.weekday();
3009 }
3010 
3011 CONSTCD11
3012 inline
3013 unsigned
3015 {
3016  return wdi_.index();
3017 }
3018 
3019 CONSTCD11
3020 inline
3023 {
3024  return wdi_;
3025 }
3026 
3027 CONSTCD14
3028 inline
3029 year_month_weekday::operator sys_days() const NOEXCEPT
3030 {
3031  return sys_days{to_days()};
3032 }
3033 
3034 CONSTCD14
3035 inline
3036 year_month_weekday::operator local_days() const NOEXCEPT
3037 {
3038  return local_days{to_days()};
3039 }
3040 
3041 CONSTCD14
3042 inline
3043 bool
3044 year_month_weekday::ok() const NOEXCEPT
3045 {
3046  if (!y_.ok() || !m_.ok() || !wdi_.weekday().ok() || wdi_.index() < 1) {
3047  return false;
3048  }
3049  if (wdi_.index() <= 4) {
3050  return true;
3051  }
3052  auto d2 = wdi_.weekday() - date::weekday(static_cast<sys_days>(y_ / m_ / 1)) +
3053  days((wdi_.index() - 1) * 7 + 1);
3054  return static_cast<unsigned>(d2.count()) <= static_cast<unsigned>((
3055  y_ / m_ / last).day());
3056 }
3057 
3058 CONSTCD14
3059 inline
3061 year_month_weekday::from_days(days d) NOEXCEPT {
3062  sys_days dp{d};
3063  auto const wd = date::weekday(dp);
3064  auto const ymd = year_month_day(dp);
3065  return {ymd.year(), ymd.month(), wd[(static_cast<unsigned>(ymd.day()) - 1) / 7 + 1]};
3066 }
3067 
3068 CONSTCD14
3069 inline
3070 days
3071 year_month_weekday::to_days() const NOEXCEPT
3072 {
3073  auto d = sys_days(y_ / m_ / 1);
3074  return (d + (wdi_.weekday() - date::weekday(d) + days{(wdi_.index() - 1) * 7})
3075  ).time_since_epoch();
3076 }
3077 
3078 CONSTCD11
3079 inline
3080 bool
3081 operator==(const year_month_weekday &x, const year_month_weekday &y) NOEXCEPT {
3082  return x.year() == y.year() && x.month() == y.month() &&
3083  x.weekday_indexed() == y.weekday_indexed();
3084 }
3085 
3086 CONSTCD11
3087 inline
3088 bool
3089 operator!=(const year_month_weekday &x, const year_month_weekday &y) NOEXCEPT {
3090  return !(x == y);
3091 }
3092 
3093 template<class CharT, class Traits>
3094 inline
3095 std::basic_ostream<CharT, Traits> &
3096 operator<<(std::basic_ostream<CharT, Traits> &os,
3097  const year_month_weekday &ymwdi)
3098 {
3099  return os << ymwdi.year() << '/' << ymwdi.month()
3100  << '/' << ymwdi.weekday_indexed();
3101 }
3102 
3103 template<class>
3104 CONSTCD14
3105 inline
3107 operator+(const year_month_weekday &ymwd, const months &dm) NOEXCEPT {
3108  return (ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed();
3109 }
3110 
3111 template<class>
3112 CONSTCD14
3113 inline
3115 operator+(const months &dm, const year_month_weekday &ymwd) NOEXCEPT {
3116  return ymwd + dm;
3117 }
3118 
3119 template<class>
3120 CONSTCD14
3121 inline
3123 operator-(const year_month_weekday &ymwd, const months &dm) NOEXCEPT {
3124  return ymwd + (-dm);
3125 }
3126 
3127 CONSTCD11
3128 inline
3130 operator+(const year_month_weekday &ymwd, const years &dy) NOEXCEPT {
3131  return {ymwd.year() + dy, ymwd.month(), ymwd.weekday_indexed()};
3132 }
3133 
3134 CONSTCD11
3135 inline
3137 operator+(const years &dy, const year_month_weekday &ymwd) NOEXCEPT {
3138  return ymwd + dy;
3139 }
3140 
3141 CONSTCD11
3142 inline
3144 operator-(const year_month_weekday &ymwd, const years &dy) NOEXCEPT {
3145  return ymwd + (-dy);
3146 }
3147 
3148 // year_month_weekday_last
3149 
3150 CONSTCD11
3151 inline
3153  const date::month &m,
3154  const date::weekday_last &wdl) NOEXCEPT
3155 :
3156 y_(y)
3157 , m_(m)
3158 , wdl_(wdl)
3159 {}
3160 
3161 template<class>
3162 CONSTCD14
3163 inline
3166  *this = *this + m;
3167  return *this;
3168 }
3169 
3170 template<class>
3171 CONSTCD14
3172 inline
3175  *this = *this - m;
3176  return *this;
3177 }
3178 
3179 CONSTCD14
3180 inline
3183  *this = *this + y;
3184  return *this;
3185 }
3186 
3187 CONSTCD14
3188 inline
3191  *this = *this - y;
3192  return *this;
3193 }
3194 
3196 {
3197  return y_;
3198 }
3200 {
3201  return m_;
3202 }
3203 
3204 CONSTCD11
3205 inline
3206 weekday
3208 {
3209  return wdl_.weekday();
3210 }
3211 
3212 CONSTCD11
3213 inline
3216 {
3217  return wdl_;
3218 }
3219 
3220 CONSTCD14
3221 inline
3222 year_month_weekday_last::operator sys_days() const NOEXCEPT
3223 {
3224  return sys_days{to_days()};
3225 }
3226 
3227 CONSTCD14
3228 inline
3229 year_month_weekday_last::operator local_days() const NOEXCEPT
3230 {
3231  return local_days{to_days()};
3232 }
3233 
3234 CONSTCD11
3235 inline
3236 bool
3238 {
3239  return y_.ok() && m_.ok() && wdl_.ok();
3240 }
3241 
3242 CONSTCD14
3243 inline
3244 days
3245 year_month_weekday_last::to_days() const NOEXCEPT
3246 {
3247  auto const d = sys_days(y_ / m_ / last);
3248  return (d - (date::weekday{d} - wdl_.weekday())).time_since_epoch();
3249 }
3250 
3251 CONSTCD11
3252 inline
3253 bool
3255  const year_month_weekday_last &y) NOEXCEPT {
3256  return x.year() == y.year() && x.month() == y.month() &&
3257  x.weekday_last() == y.weekday_last();
3258 }
3259 
3260 CONSTCD11
3261 inline
3262 bool
3264  const year_month_weekday_last &y) NOEXCEPT {
3265  return !(x == y);
3266 }
3267 
3268 template<class CharT, class Traits>
3269 inline
3270 std::basic_ostream<CharT, Traits> &
3271 operator<<(std::basic_ostream<CharT, Traits> &os,
3272  const year_month_weekday_last &ymwdl)
3273 {
3274  return os << ymwdl.year() << '/' << ymwdl.month() << '/' <<
3275  ymwdl.weekday_last();
3276 }
3277 
3278 template<class>
3279 CONSTCD14
3280 inline
3282 operator+(const year_month_weekday_last &ymwdl, const months &dm) NOEXCEPT {
3283  return (ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last();
3284 }
3285 
3286 template<class>
3287 CONSTCD14
3288 inline
3290 operator+(const months &dm, const year_month_weekday_last &ymwdl) NOEXCEPT {
3291  return ymwdl + dm;
3292 }
3293 
3294 template<class>
3295 CONSTCD14
3296 inline
3298 operator-(const year_month_weekday_last &ymwdl, const months &dm) NOEXCEPT {
3299  return ymwdl + (-dm);
3300 }
3301 
3302 CONSTCD11
3303 inline
3305 operator+(const year_month_weekday_last &ymwdl, const years &dy) NOEXCEPT {
3306  return {ymwdl.year() + dy, ymwdl.month(), ymwdl.weekday_last()};
3307 }
3308 
3309 CONSTCD11
3310 inline
3312 operator+(const years &dy, const year_month_weekday_last &ymwdl) NOEXCEPT {
3313  return ymwdl + dy;
3314 }
3315 
3316 CONSTCD11
3317 inline
3319 operator-(const year_month_weekday_last &ymwdl, const years &dy) NOEXCEPT {
3320  return ymwdl + (-dy);
3321 }
3322 
3323 // year_month from operator/()
3324 
3325 CONSTCD11
3326 inline
3327 year_month
3328 operator/(const year &y, const month &m) NOEXCEPT {
3329  return {y, m};
3330 }
3331 
3332 CONSTCD11
3333 inline
3334 year_month
3335 operator/(const year &y, int m) NOEXCEPT {
3336  return y / month(static_cast<unsigned>(m));
3337 }
3338 
3339 // month_day from operator/()
3340 
3341 CONSTCD11
3342 inline
3343 month_day
3344 operator/(const month &m, const day &d) NOEXCEPT {
3345  return {m, d};
3346 }
3347 
3348 CONSTCD11
3349 inline
3350 month_day
3351 operator/(const day &d, const month &m) NOEXCEPT {
3352  return m / d;
3353 }
3354 
3355 CONSTCD11
3356 inline
3357 month_day
3358 operator/(const month &m, int d) NOEXCEPT {
3359  return m / day(static_cast<unsigned>(d));
3360 }
3361 
3362 CONSTCD11
3363 inline
3364 month_day
3365 operator/(int m, const day &d) NOEXCEPT {
3366  return month(static_cast<unsigned>(m)) / d;
3367 }
3368 
3369 CONSTCD11 inline month_day operator/(const day &d, int m) NOEXCEPT {return m / d;}
3370 
3371 // month_day_last from operator/()
3372 
3373 CONSTCD11
3374 inline
3376 operator/(const month &m, last_spec) NOEXCEPT {
3377  return month_day_last{m};
3378 }
3379 
3380 CONSTCD11
3381 inline
3383 operator/(last_spec, const month &m) NOEXCEPT {
3384  return m / last;
3385 }
3386 
3387 CONSTCD11
3388 inline
3390 operator/(int m, last_spec) NOEXCEPT {
3391  return month(static_cast<unsigned>(m)) / last;
3392 }
3393 
3394 CONSTCD11
3395 inline
3397 operator/(last_spec, int m) NOEXCEPT {
3398  return m / last;
3399 }
3400 
3401 // month_weekday from operator/()
3402 
3403 CONSTCD11
3404 inline
3406 operator/(const month &m, const weekday_indexed &wdi) NOEXCEPT {
3407  return {m, wdi};
3408 }
3409 
3410 CONSTCD11
3411 inline
3413 operator/(const weekday_indexed &wdi, const month &m) NOEXCEPT {
3414  return m / wdi;
3415 }
3416 
3417 CONSTCD11
3418 inline
3420 operator/(int m, const weekday_indexed &wdi) NOEXCEPT {
3421  return month(static_cast<unsigned>(m)) / wdi;
3422 }
3423 
3424 CONSTCD11
3425 inline
3427 operator/(const weekday_indexed &wdi, int m) NOEXCEPT {
3428  return m / wdi;
3429 }
3430 
3431 // month_weekday_last from operator/()
3432 
3433 CONSTCD11
3434 inline
3436 operator/(const month &m, const weekday_last &wdl) NOEXCEPT {
3437  return {m, wdl};
3438 }
3439 
3440 CONSTCD11
3441 inline
3443 operator/(const weekday_last &wdl, const month &m) NOEXCEPT {
3444  return m / wdl;
3445 }
3446 
3447 CONSTCD11
3448 inline
3450 operator/(int m, const weekday_last &wdl) NOEXCEPT {
3451  return month(static_cast<unsigned>(m)) / wdl;
3452 }
3453 
3454 CONSTCD11
3455 inline
3457 operator/(const weekday_last &wdl, int m) NOEXCEPT {
3458  return m / wdl;
3459 }
3460 
3461 // year_month_day from operator/()
3462 
3463 CONSTCD11
3464 inline
3466 operator/(const year_month &ym, const day &d) NOEXCEPT {
3467  return {ym.year(), ym.month(), d};
3468 }
3469 
3470 CONSTCD11
3471 inline
3473 operator/(const year_month &ym, int d) NOEXCEPT {
3474  return ym / day(static_cast<unsigned>(d));
3475 }
3476 
3477 CONSTCD11
3478 inline
3480 operator/(const year &y, const month_day &md) NOEXCEPT {
3481  return y / md.month() / md.day();
3482 }
3483 
3484 CONSTCD11
3485 inline
3487 operator/(int y, const month_day &md) NOEXCEPT {
3488  return year(y) / md;
3489 }
3490 
3491 CONSTCD11
3492 inline
3494 operator/(const month_day &md, const year &y) NOEXCEPT {
3495  return y / md;
3496 }
3497 
3498 CONSTCD11
3499 inline
3501 operator/(const month_day &md, int y) NOEXCEPT {
3502  return year(y) / md;
3503 }
3504 
3505 // year_month_day_last from operator/()
3506 
3507 CONSTCD11
3508 inline
3510 operator/(const year_month &ym, last_spec) NOEXCEPT {
3511  return {ym.year(), month_day_last{ym.month()}};
3512 }
3513 
3514 CONSTCD11
3515 inline
3517 operator/(const year &y, const month_day_last &mdl) NOEXCEPT {
3518  return {y, mdl};
3519 }
3520 
3521 CONSTCD11
3522 inline
3524 operator/(int y, const month_day_last &mdl) NOEXCEPT {
3525  return year(y) / mdl;
3526 }
3527 
3528 CONSTCD11
3529 inline
3531 operator/(const month_day_last &mdl, const year &y) NOEXCEPT {
3532  return y / mdl;
3533 }
3534 
3535 CONSTCD11
3536 inline
3538 operator/(const month_day_last &mdl, int y) NOEXCEPT {
3539  return year(y) / mdl;
3540 }
3541 
3542 // year_month_weekday from operator/()
3543 
3544 CONSTCD11
3545 inline
3547 operator/(const year_month &ym, const weekday_indexed &wdi) NOEXCEPT {
3548  return {ym.year(), ym.month(), wdi};
3549 }
3550 
3551 CONSTCD11
3552 inline
3554 operator/(const year &y, const month_weekday &mwd) NOEXCEPT {
3555  return {y, mwd.month(), mwd.weekday_indexed()};
3556 }
3557 
3558 CONSTCD11
3559 inline
3561 operator/(int y, const month_weekday &mwd) NOEXCEPT {
3562  return year(y) / mwd;
3563 }
3564 
3565 CONSTCD11
3566 inline
3568 operator/(const month_weekday &mwd, const year &y) NOEXCEPT {
3569  return y / mwd;
3570 }
3571 
3572 CONSTCD11
3573 inline
3575 operator/(const month_weekday &mwd, int y) NOEXCEPT {
3576  return year(y) / mwd;
3577 }
3578 
3579 // year_month_weekday_last from operator/()
3580 
3581 CONSTCD11
3582 inline
3584 operator/(const year_month &ym, const weekday_last &wdl) NOEXCEPT {
3585  return {ym.year(), ym.month(), wdl};
3586 }
3587 
3588 CONSTCD11
3589 inline
3591 operator/(const year &y, const month_weekday_last &mwdl) NOEXCEPT {
3592  return {y, mwdl.month(), mwdl.weekday_last()};
3593 }
3594 
3595 CONSTCD11
3596 inline
3598 operator/(int y, const month_weekday_last &mwdl) NOEXCEPT {
3599  return year(y) / mwdl;
3600 }
3601 
3602 CONSTCD11
3603 inline
3605 operator/(const month_weekday_last &mwdl, const year &y) NOEXCEPT {
3606  return y / mwdl;
3607 }
3608 
3609 CONSTCD11
3610 inline
3612 operator/(const month_weekday_last &mwdl, int y) NOEXCEPT {
3613  return year(y) / mwdl;
3614 }
3615 
3616 template <class Duration>
3617 struct fields;
3618 
3619 template <class CharT, class Traits, class Duration>
3620 std::basic_ostream<CharT, Traits> &
3621 to_stream(std::basic_ostream<CharT, Traits> &os, const CharT *fmt,
3622  const fields<Duration> &fds, const std::string *abbrev = nullptr,
3623  const std::chrono::seconds *offset_sec = nullptr);
3624 
3625 template <class CharT, class Traits, class Duration, class Alloc>
3626 std::basic_istream<CharT, Traits> &
3627 from_stream(std::basic_istream<CharT, Traits> &is, const CharT *fmt,
3628  fields<Duration> &fds, std::basic_string<CharT, Traits, Alloc> *abbrev =
3629  nullptr,
3630  std::chrono::minutes *offset = nullptr);
3631 
3632 // hh_mm_ss
3633 
3634 namespace detail {
3635 
3637  explicit undocumented() = default;
3638 };
3639 
3640 // width<n>::value is the number of fractional decimal digits in 1/n
3641 // width<0>::value and width<1>::value are defined to be 0
3642 // If 1/n takes more than 18 fractional decimal digits,
3643 // the result is truncated to 19.
3644 // Example: width<2>::value == 1
3645 // Example: width<3>::value == 19
3646 // Example: width<4>::value == 2
3647 // Example: width<10>::value == 1
3648 // Example: width<1000>::value == 3
3649 template < std::uint64_t n, std::uint64_t d = 10, unsigned w = 0,
3650  bool should_continue = !(n < 2) && d != 0 && (w < 19) >
3651 struct width {
3653 };
3654 
3655 template <std::uint64_t n, std::uint64_t d, unsigned w>
3657  static CONSTDATA unsigned value = 0;
3658 };
3659 
3660 template <unsigned exp>
3662 private:
3663  static CONSTDATA std::uint64_t h = static_pow10 < exp / 2 >::value;
3664 public:
3665  static CONSTDATA std::uint64_t value = h * h * (exp % 2 ? 10 : 1);
3666 };
3667 
3668 template <>
3669 struct static_pow10<0> {
3670  static CONSTDATA std::uint64_t value = 1;
3671 };
3672 
3673 template <class Duration>
3675  using CT = typename std::common_type<Duration, std::chrono::seconds>::type;
3676  using rep = typename CT::rep;
3677 public:
3678  static unsigned constexpr width = detail::width<CT::period::den>::value < 19 ?
3680  using precision = std::chrono::duration<rep,
3681  std::ratio<1, static_pow10<width>::value>>;
3682 
3683 private:
3684  std::chrono::seconds s_;
3685  precision sub_s_;
3686 
3687 public:
3689  : s_()
3690  , sub_s_()
3691  {}
3692 
3693  CONSTCD11 explicit decimal_format_seconds(const Duration &d) NOEXCEPT
3694 :
3695  s_(std::chrono::duration_cast<std::chrono::seconds>(d))
3696  , sub_s_(std::chrono::treat_as_floating_point<rep>::value ? d - s_ :
3697  std::chrono::duration_cast<precision>(d - s_))
3698  {}
3699 
3700  CONSTCD14 std::chrono::seconds &seconds() NOEXCEPT {return s_;}
3701  CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT
3702  {
3703  return s_;
3704  }
3705  CONSTCD11 precision subseconds() const NOEXCEPT
3706  {
3707  return sub_s_;
3708  }
3709 
3711  {
3712  return s_ + sub_s_;
3713  }
3714 
3715  CONSTCD11 bool in_conventional_range() const NOEXCEPT
3716  {
3717  return sub_s_ < std::chrono::seconds{1} &&s_ < std::chrono::minutes{1};
3718  }
3719 
3720  template <class CharT, class Traits>
3721  friend
3722  std::basic_ostream<CharT, Traits> &
3723  operator<<(std::basic_ostream<CharT, Traits> &os,
3724  const decimal_format_seconds &x)
3725  {
3726  return x.print(os, std::chrono::treat_as_floating_point<rep> {});
3727  }
3728 
3729  template <class CharT, class Traits>
3730  std::basic_ostream<CharT, Traits> &
3731  print(std::basic_ostream<CharT, Traits> &os, std::true_type) const
3732  {
3734  std::chrono::duration<rep> d = s_ + sub_s_;
3735  if (d < std::chrono::seconds{10})
3736  os << '0';
3737  os << std::fixed << d.count();
3738  return os;
3739  }
3740 
3741  template <class CharT, class Traits>
3742  std::basic_ostream<CharT, Traits> &
3743  print(std::basic_ostream<CharT, Traits> &os, std::false_type) const
3744  {
3746  os.fill('0');
3747  os.flags(std::ios::dec | std::ios::right);
3748  os.width(2);
3749  os << s_.count();
3750  if (width > 0) {
3751 #if !ONLY_C_LOCALE
3752  os << std::use_facet<std::numpunct<CharT>>(os.getloc()).decimal_point();
3753 #else
3754  os << '.';
3755 #endif
3756  os.width(width);
3757  os << sub_s_.count();
3758  }
3759  return os;
3760  }
3761 };
3762 
3763 template <class Rep, class Period>
3764 inline
3765 CONSTCD11
3766 typename std::enable_if
3767 <
3768  std::numeric_limits<Rep>::is_signed,
3769  std::chrono::duration<Rep, Period>
3770  >::type
3771 abs(std::chrono::duration<Rep, Period> d)
3772 {
3773  return d >= d.zero() ? +d : -d;
3774 }
3775 
3776 template <class Rep, class Period>
3777 inline
3778 CONSTCD11
3779 typename std::enable_if
3780 <
3781  !std::numeric_limits<Rep>::is_signed,
3782  std::chrono::duration<Rep, Period>
3783  >::type
3784 abs(std::chrono::duration<Rep, Period> d)
3785 {
3786  return d;
3787 }
3788 
3789 } // namespace detail
3790 
3791 template <class Duration>
3792 class hh_mm_ss {
3793  using dfs = detail::decimal_format_seconds<typename std::common_type<Duration,
3794  std::chrono::seconds>::type>;
3795 
3796  std::chrono::hours h_;
3797  std::chrono::minutes m_;
3798  dfs s_;
3799  bool neg_;
3800 
3801 public:
3802  static unsigned CONSTDATA fractional_width = dfs::width;
3803  using precision = typename dfs::precision;
3804 
3805  CONSTCD11 hh_mm_ss() NOEXCEPT
3806 :
3807  hh_mm_ss(Duration::zero())
3808  {}
3809 
3810  CONSTCD11 explicit hh_mm_ss(Duration d) NOEXCEPT
3811 :
3812  h_(std::chrono::duration_cast<std::chrono::hours>(detail::abs(d)))
3813  , m_(std::chrono::duration_cast<std::chrono::minutes>(detail::abs(d)) - h_)
3814  , s_(detail::abs(d) - h_ - m_)
3815  , neg_(d < Duration::zero())
3816  {}
3817 
3818  CONSTCD11 std::chrono::hours hours() const NOEXCEPT
3819  {
3820  return h_;
3821  }
3822  CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT
3823  {
3824  return m_;
3825  }
3826  CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT
3827  {
3828  return s_.seconds();
3829  }
3830  CONSTCD14 std::chrono::seconds &
3831  seconds(detail::undocumented) NOEXCEPT {return s_.seconds();}
3832  CONSTCD11 precision subseconds() const NOEXCEPT
3833  {
3834  return s_.subseconds();
3835  }
3836  CONSTCD11 bool is_negative() const NOEXCEPT
3837  {
3838  return neg_;
3839  }
3840 
3841  CONSTCD11 explicit operator precision() const NOEXCEPT
3842  {
3843  return to_duration();
3844  }
3846  {
3847  return (h_ + m_ + s_.to_duration()) * (1 - 2 * neg_);
3848  }
3849 
3850  CONSTCD11 bool in_conventional_range() const NOEXCEPT
3851  {
3852  return !neg_ && h_ < days{1} &&m_ < std::chrono::hours{1} &&
3853  s_.in_conventional_range();
3854  }
3855 
3856 private:
3857 
3858  template <class charT, class traits>
3859  friend
3860  std::basic_ostream<charT, traits> &
3861  operator<<(std::basic_ostream<charT, traits> &os, hh_mm_ss const &tod)
3862  {
3863  if (tod.is_negative()) {
3864  os << '-';
3865  }
3866  if (tod.h_ < std::chrono::hours{10})
3867  os << '0';
3868  os << tod.h_.count() << ':';
3869  if (tod.m_ < std::chrono::minutes{10})
3870  os << '0';
3871  os << tod.m_.count() << ':' << tod.s_;
3872  return os;
3873  }
3874 
3875  template <class CharT, class Traits, class Duration2>
3876  friend
3877  std::basic_ostream<CharT, Traits> &
3878  date::to_stream(std::basic_ostream<CharT, Traits> &os, const CharT *fmt,
3879  const fields<Duration2> &fds, const std::string *abbrev,
3880  const std::chrono::seconds *offset_sec);
3881 
3882  template <class CharT, class Traits, class Duration2, class Alloc>
3883  friend
3884  std::basic_istream<CharT, Traits> &
3885  date::from_stream(std::basic_istream<CharT, Traits> &is, const CharT *fmt,
3886  fields<Duration2> &fds,
3887  std::basic_string<CharT, Traits, Alloc> *abbrev, std::chrono::minutes *offset);
3888 };
3889 
3890 inline
3891 CONSTCD14
3892 bool
3893 is_am(std::chrono::hours const &h) NOEXCEPT {
3894  using std::chrono::hours;
3895  return hours{0} <= h &&h < hours{12};
3896 }
3897 
3898 inline
3899 CONSTCD14
3900 bool
3901 is_pm(std::chrono::hours const &h) NOEXCEPT {
3902  using std::chrono::hours;
3903  return hours{12} <= h &&h < hours{24};
3904 }
3905 
3906 inline
3907 CONSTCD14
3908 std::chrono::hours
3909 make12(std::chrono::hours h) NOEXCEPT {
3910  using std::chrono::hours;
3911  if (h < hours{12})
3912  {
3913  if (h == hours{0})
3914  h = hours{12};
3915  }
3916  else
3917  {
3918  if (h != hours{12})
3919  h -= hours{12};
3920  }
3921  return h;
3922 }
3923 
3924 inline
3925 CONSTCD14
3926 std::chrono::hours
3927 make24(std::chrono::hours h, bool is_pm) NOEXCEPT {
3928  using std::chrono::hours;
3929  if (is_pm)
3930  {
3931  if (h != hours{12})
3932  h += hours{12};
3933  }
3934  else if (h == hours{12})
3935  h = hours{0};
3936  return h;
3937 }
3938 
3939 template <class Duration>
3941 
3942 template < class Rep, class Period,
3943  class = typename std::enable_if
3944  < !std::chrono::treat_as_floating_point<Rep>::value >::type >
3945 CONSTCD11
3946 inline
3948 make_time(const std::chrono::duration<Rep, Period> &d)
3949 {
3951 }
3952 
3953 template <class CharT, class Traits, class Duration>
3954 inline
3955 typename std::enable_if
3956 <
3957  !std::chrono::treat_as_floating_point<typename Duration::rep>::value &&
3958  std::ratio_less<typename Duration::period, days::period>::value
3959  , std::basic_ostream<CharT, Traits> &
3960  >::type
3961 operator<<(std::basic_ostream<CharT, Traits> &os, const sys_time<Duration> &tp)
3962 {
3963  auto const dp = date::floor<days>(tp);
3964  return os << year_month_day(dp) << ' ' << make_time(tp - dp);
3965 }
3966 
3967 template <class CharT, class Traits>
3968 inline
3969 std::basic_ostream<CharT, Traits> &
3970 operator<<(std::basic_ostream<CharT, Traits> &os, const sys_days &dp)
3971 {
3972  return os << year_month_day(dp);
3973 }
3974 
3975 template <class CharT, class Traits, class Duration>
3976 inline
3977 std::basic_ostream<CharT, Traits> &
3978 operator<<(std::basic_ostream<CharT, Traits> &os,
3979  const local_time<Duration> &ut)
3980 {
3981  return (os << sys_time<Duration> {ut.time_since_epoch()});
3982 }
3983 
3984 namespace detail {
3985 
3986 template <class CharT, std::size_t N>
3988 
3989 template <class CharT1, class CharT2, std::size_t N1, std::size_t N2>
3990 inline
3991 CONSTCD14
3992 string_literal < typename std::conditional < sizeof(CharT2) <= sizeof(CharT1),
3993  CharT1, CharT2 >::type,
3994  N1 + N2 - 1 >
3997 
3998 template <class CharT, std::size_t N>
3999 class string_literal {
4000  CharT p_[N];
4001 
4002  CONSTCD11 string_literal() NOEXCEPT
4003 :
4004  p_{}
4005  {}
4006 
4007 public:
4008  using const_iterator = const CharT*;
4009 
4010  string_literal(string_literal const &) = default;
4011  string_literal &operator=(string_literal const &) = delete;
4012 
4013  template <std::size_t N1 = 2,
4014  class = typename std::enable_if<N1 == N>::type>
4016 :
4017  p_{c} {
4018  }
4019 
4020  template <std::size_t N1 = 3,
4021  class = typename std::enable_if<N1 == N>::type>
4022  CONSTCD11 string_literal(CharT c1, CharT c2) NOEXCEPT
4023 :
4024  p_{c1, c2} {
4025  }
4026 
4027  template <std::size_t N1 = 4,
4028  class = typename std::enable_if<N1 == N>::type>
4029  CONSTCD11 string_literal(CharT c1, CharT c2, CharT c3) NOEXCEPT
4030 :
4031  p_{c1, c2, c3} {
4032  }
4033 
4034  CONSTCD14 string_literal(const CharT(&a)[N]) NOEXCEPT
4035 :
4036  p_{} {
4037  for (std::size_t i = 0; i < N; ++i)
4038  {
4039  p_[i] = a[i];
4040  }
4041  }
4042 
4043  template < class U = CharT,
4044  class = typename std::enable_if<(1 < sizeof(U))>::type>
4045  CONSTCD14 string_literal(const char(&a)[N]) NOEXCEPT
4046  : p_ {}
4047  {
4048  for (std::size_t i = 0; i < N; ++i) {
4049  p_[i] = a[i];
4050  }
4051  }
4052 
4053  template < class CharT2,
4054  class = typename std::enable_if < !std::is_same<CharT2, CharT>::value >::type >
4056 : p_ {}
4057  {
4058  for (std::size_t i = 0; i < N; ++i) {
4059  p_[i] = a[i];
4060  }
4061  }
4062 
4063  CONSTCD11 const CharT *data() const NOEXCEPT
4064  {
4065  return p_;
4066  }
4067  CONSTCD11 std::size_t size() const NOEXCEPT
4068  {
4069  return N - 1;
4070  }
4071 
4072  CONSTCD11 const_iterator begin() const NOEXCEPT
4073  {
4074  return p_;
4075  }
4076  CONSTCD11 const_iterator end() const NOEXCEPT
4077  {
4078  return p_ + N - 1;
4079  }
4080 
4081  CONSTCD11 CharT const &operator[](std::size_t n) const NOEXCEPT
4082  {
4083  return p_[n];
4084  }
4085 
4086  template <class Traits>
4087  friend
4088  std::basic_ostream<CharT, Traits> &
4089  operator<<(std::basic_ostream<CharT, Traits> &os, const string_literal &s)
4090  {
4091  return os << s.p_;
4092  }
4093 
4094  template <class CharT1, class CharT2, std::size_t N1, std::size_t N2>
4095  friend
4096  CONSTCD14
4097  string_literal < typename std::conditional < sizeof(CharT2) <= sizeof(CharT1),
4098  CharT1, CharT2 >::type,
4099  N1 + N2 - 1 >
4102 };
4103 
4104 template <class CharT>
4105 CONSTCD11
4106 inline
4109  const string_literal<CharT, 2> &y) NOEXCEPT {
4110  return string_literal<CharT, 3>(x[0], y[0]);
4111 }
4112 
4113 template <class CharT>
4114 CONSTCD11
4115 inline
4118  const string_literal<CharT, 2> &y) NOEXCEPT {
4119  return string_literal<CharT, 4>(x[0], x[1], y[0]);
4120 }
4121 
4122 template <class CharT1, class CharT2, std::size_t N1, std::size_t N2>
4123 CONSTCD14
4124 inline
4125 string_literal < typename std::conditional < sizeof(CharT2) <= sizeof(CharT1),
4126  CharT1, CharT2 >::type,
4127  N1 + N2 - 1 >
4129 const string_literal<CharT2, N2> &y) NOEXCEPT {
4130  using CT = typename std::conditional < sizeof(CharT2) <= sizeof(CharT1), CharT1, CharT2 >::type;
4131 
4132  string_literal < CT, N1 + N2 - 1 > r;
4133  std::size_t i = 0;
4134  for (; i < N1 - 1; ++i)
4135  {
4136  r.p_[i] = CT(x.p_[i]);
4137  }
4138  for (std::size_t j = 0; j < N2; ++j, ++i)
4139  {
4140  r.p_[i] = CT(y.p_[j]);
4141  }
4142 
4143  return r;
4144 }
4145 
4146 
4147 template <class CharT, class Traits, class Alloc, std::size_t N>
4148 inline
4149 std::basic_string<CharT, Traits, Alloc>
4150 operator+(std::basic_string<CharT, Traits, Alloc> x,
4151  const string_literal<CharT, N> &y)
4152 {
4153  x.append(y.data(), y.size());
4154  return x;
4155 }
4156 
4157 #if __cplusplus >= 201402 && (!defined(__EDG_VERSION__) || __EDG_VERSION__ > 411) \
4158  && (!defined(__SUNPRO_CC) || __SUNPRO_CC > 0x5150)
4159 
4160 template < class CharT,
4161 class = std::enable_if_t < std::is_same<CharT, char> {} ||
4162 std::is_same<CharT, wchar_t> {} ||
4163 std::is_same<CharT, char16_t> {} ||
4164 std::is_same<CharT, char32_t> {} >>
4165  CONSTCD14
4166  inline
4168 msl(CharT c) NOEXCEPT {
4169  return string_literal<CharT, 2>{c};
4170 }
4171 
4172 CONSTCD14
4173 inline
4174 std::size_t
4175 to_string_len(std::intmax_t i)
4176 {
4177  std::size_t r = 0;
4178  do {
4179  i /= 10;
4180  ++r;
4181  }
4182  while (i > 0);
4183  return r;
4184 }
4185 
4186 template <std::intmax_t N>
4187 CONSTCD14
4188 inline
4189 std::enable_if_t
4190 <
4191  N < 10,
4193  >
4194 msl() NOEXCEPT {
4195  return msl(char(N % 10 + '0'));
4196 }
4197 
4198 template <std::intmax_t N>
4199 CONSTCD14
4200 inline
4201 std::enable_if_t
4202 <
4203  10 <= N,
4205  >
4206 msl() NOEXCEPT {
4207  return msl < N / 10 > () + msl(char(N % 10 + '0'));
4208 }
4209 
4210 template <class CharT, std::intmax_t N, std::intmax_t D>
4211 CONSTCD14
4212 inline
4213 std::enable_if_t
4214 <
4217  to_string_len(std::ratio<N, D>::type::den) + 4 >
4218  >
4219 msl(std::ratio<N, D>) NOEXCEPT {
4220  using R = typename std::ratio<N, D>::type;
4221  return msl(CharT{'['}) + msl<R::num>() + msl(CharT{'/'}) +
4222  msl<R::den>() + msl(CharT{']'});
4223 }
4224 
4225 template <class CharT, std::intmax_t N, std::intmax_t D>
4226 CONSTCD14
4227 inline
4228 std::enable_if_t
4229 <
4232  >
4233 msl(std::ratio<N, D>) NOEXCEPT {
4234  using R = typename std::ratio<N, D>::type;
4235  return msl(CharT{'['}) + msl<R::num>() + msl(CharT{']'});
4236 }
4237 
4238 
4239 #else // __cplusplus < 201402 || (defined(__EDG_VERSION__) && __EDG_VERSION__ <= 411)
4240 
4241 inline
4242 std::string
4243 to_string(std::uint64_t x)
4244 {
4245  return std::to_string(x);
4246 }
4247 
4248 template <class CharT>
4249 inline
4250 std::basic_string<CharT>
4251 to_string(std::uint64_t x)
4252 {
4253  auto y = std::to_string(x);
4254  return std::basic_string<CharT>(y.begin(), y.end());
4255 }
4256 
4257 template <class CharT, std::intmax_t N, std::intmax_t D>
4258 inline
4259 typename std::enable_if
4260 <
4261  std::ratio<N, D>::type::den != 1,
4262  std::basic_string<CharT>
4263  >::type
4264 msl(std::ratio<N, D>)
4265 {
4266  using R = typename std::ratio<N, D>::type;
4267  return std::basic_string<CharT>(1, '[') + to_string<CharT>(R::num) + CharT{'/'} +
4268  to_string<CharT>(R::den) + CharT{']'};
4269 }
4270 
4271 template <class CharT, std::intmax_t N, std::intmax_t D>
4272 inline
4273 typename std::enable_if
4274 <
4275  std::ratio<N, D>::type::den == 1,
4276  std::basic_string<CharT>
4277  >::type
4278 msl(std::ratio<N, D>)
4279 {
4280  using R = typename std::ratio<N, D>::type;
4281  return std::basic_string<CharT>(1, '[') + to_string<CharT>(R::num) + CharT{']'};
4282 }
4283 
4284 #endif // __cplusplus < 201402 || (defined(__EDG_VERSION__) && __EDG_VERSION__ <= 411)
4285 
4286 template <class CharT>
4287 CONSTCD11
4288 inline
4290 msl(std::atto) NOEXCEPT {
4291  return string_literal<CharT, 2>{'a'};
4292 }
4293 
4294 template <class CharT>
4295 CONSTCD11
4296 inline
4298 msl(std::femto) NOEXCEPT {
4299  return string_literal<CharT, 2>{'f'};
4300 }
4301 
4302 template <class CharT>
4303 CONSTCD11
4304 inline
4306 msl(std::pico) NOEXCEPT {
4307  return string_literal<CharT, 2>{'p'};
4308 }
4309 
4310 template <class CharT>
4311 CONSTCD11
4312 inline
4314 msl(std::nano) NOEXCEPT {
4315  return string_literal<CharT, 2>{'n'};
4316 }
4317 
4318 template <class CharT>
4319 CONSTCD11
4320 inline
4321 typename std::enable_if
4322 <
4323  std::is_same<CharT, char>::value,
4325  >::type
4326 msl(std::micro) NOEXCEPT {
4327  return string_literal<char, 3>{'\xC2', '\xB5'};
4328 }
4329 
4330 template <class CharT>
4331 CONSTCD11
4332 inline
4333 typename std::enable_if
4334 <
4335  !std::is_same<CharT, char>::value,
4337  >::type
4338 msl(std::micro) NOEXCEPT {
4339  return string_literal<CharT, 2>{CharT{static_cast<unsigned char>('\xB5')}};
4340 }
4341 
4342 template <class CharT>
4343 CONSTCD11
4344 inline
4346 msl(std::milli) NOEXCEPT {
4347  return string_literal<CharT, 2>{'m'};
4348 }
4349 
4350 template <class CharT>
4351 CONSTCD11
4352 inline
4354 msl(std::centi) NOEXCEPT {
4355  return string_literal<CharT, 2>{'c'};
4356 }
4357 
4358 template <class CharT>
4359 CONSTCD11
4360 inline
4362 msl(std::deca) NOEXCEPT {
4363  return string_literal<CharT, 3>{'d', 'a'};
4364 }
4365 
4366 template <class CharT>
4367 CONSTCD11
4368 inline
4370 msl(std::deci) NOEXCEPT {
4371  return string_literal<CharT, 2>{'d'};
4372 }
4373 
4374 template <class CharT>
4375 CONSTCD11
4376 inline
4378 msl(std::hecto) NOEXCEPT {
4379  return string_literal<CharT, 2>{'h'};
4380 }
4381 
4382 template <class CharT>
4383 CONSTCD11
4384 inline
4386 msl(std::kilo) NOEXCEPT {
4387  return string_literal<CharT, 2>{'k'};
4388 }
4389 
4390 template <class CharT>
4391 CONSTCD11
4392 inline
4394 msl(std::mega) NOEXCEPT {
4395  return string_literal<CharT, 2>{'M'};
4396 }
4397 
4398 template <class CharT>
4399 CONSTCD11
4400 inline
4402 msl(std::giga) NOEXCEPT {
4403  return string_literal<CharT, 2>{'G'};
4404 }
4405 
4406 template <class CharT>
4407 CONSTCD11
4408 inline
4410 msl(std::tera) NOEXCEPT {
4411  return string_literal<CharT, 2>{'T'};
4412 }
4413 
4414 template <class CharT>
4415 CONSTCD11
4416 inline
4418 msl(std::peta) NOEXCEPT {
4419  return string_literal<CharT, 2>{'P'};
4420 }
4421 
4422 template <class CharT>
4423 CONSTCD11
4424 inline
4426 msl(std::exa) NOEXCEPT {
4427  return string_literal<CharT, 2>{'E'};
4428 }
4429 
4430 template <class CharT, class Period>
4431 CONSTCD11
4432 inline
4433 auto
4434 get_units(Period p)
4435 -> decltype(msl<CharT>(p) + string_literal<CharT, 2> {'s'})
4436 {
4437  return msl<CharT>(p) + string_literal<CharT, 2> {'s'};
4438 }
4439 
4440 template <class CharT>
4441 CONSTCD11
4442 inline
4444 get_units(std::ratio<1>)
4445 {
4446  return string_literal<CharT, 2> {'s'};
4447 }
4448 
4449 template <class CharT>
4450 CONSTCD11
4451 inline
4453 get_units(std::ratio<3600>)
4454 {
4455  return string_literal<CharT, 2> {'h'};
4456 }
4457 
4458 template <class CharT>
4459 CONSTCD11
4460 inline
4462 get_units(std::ratio<60>)
4463 {
4464  return string_literal<CharT, 4> {'m', 'i', 'n'};
4465 }
4466 
4467 template <class CharT>
4468 CONSTCD11
4469 inline
4471 get_units(std::ratio<86400>)
4472 {
4473  return string_literal<CharT, 2> {'d'};
4474 }
4475 
4476 template <class CharT, class Traits = std::char_traits<CharT>>
4477 struct make_string;
4478 
4479 template <>
4480 struct make_string<char> {
4481  template <class Rep>
4482  static
4483  std::string
4484  from(Rep n)
4485  {
4486  return std::to_string(n);
4487  }
4488 };
4489 
4490 template <class Traits>
4491 struct make_string<char, Traits> {
4492  template <class Rep>
4493  static
4494  std::basic_string<char, Traits>
4495  from(Rep n)
4496  {
4497  auto s = std::to_string(n);
4498  return std::basic_string<char, Traits>(s.begin(), s.end());
4499  }
4500 };
4501 
4502 template <>
4503 struct make_string<wchar_t> {
4504  template <class Rep>
4505  static
4506  std::wstring
4507  from(Rep n)
4508  {
4509  return std::to_wstring(n);
4510  }
4511 };
4512 
4513 template <class Traits>
4514 struct make_string<wchar_t, Traits> {
4515  template <class Rep>
4516  static
4517  std::basic_string<wchar_t, Traits>
4518  from(Rep n)
4519  {
4520  auto s = std::to_wstring(n);
4521  return std::basic_string<wchar_t, Traits>(s.begin(), s.end());
4522  }
4523 };
4524 
4525 } // namespace detail
4526 
4527 // to_stream
4528 
4530 
4531 template <class Duration>
4532 struct fields {
4533  year_month_day ymd{nanyear / 0 / 0};
4534  weekday wd{8u};
4536  bool has_tod = false;
4537 
4538  fields() = default;
4539 
4540  fields(year_month_day ymd_) : ymd(ymd_) {}
4541  fields(weekday wd_) : wd(wd_) {}
4542  fields(hh_mm_ss<Duration> tod_) : tod(tod_), has_tod(true) {}
4543 
4544  fields(year_month_day ymd_, weekday wd_) : ymd(ymd_), wd(wd_) {}
4545  fields(year_month_day ymd_, hh_mm_ss<Duration> tod_) : ymd(ymd_), tod(tod_),
4546  has_tod(true) {}
4547 
4548  fields(weekday wd_, hh_mm_ss<Duration> tod_) : wd(wd_), tod(tod_),
4549  has_tod(true) {}
4550 
4552  : ymd(ymd_)
4553  , wd(wd_)
4554  , tod(tod_)
4555  , has_tod(true)
4556  {}
4557 };
4558 
4559 namespace detail {
4560 
4561 template <class CharT, class Traits, class Duration>
4562 unsigned
4563 extract_weekday(std::basic_ostream<CharT, Traits> &os,
4564  const fields<Duration> &fds)
4565 {
4566  if (!fds.ymd.ok() && !fds.wd.ok()) {
4567  // fds does not contain a valid weekday
4568  os.setstate(std::ios::failbit);
4569  return 8;
4570  }
4571  weekday wd;
4572  if (fds.ymd.ok()) {
4573  wd = weekday{sys_days(fds.ymd)};
4574  if (fds.wd.ok() && wd != fds.wd) {
4575  // fds.ymd and fds.wd are inconsistent
4576  os.setstate(std::ios::failbit);
4577  return 8;
4578  }
4579  }
4580  else {
4581  wd = fds.wd;
4582  }
4583  return static_cast<unsigned>((wd - Sunday).count());
4584 }
4585 
4586 template <class CharT, class Traits, class Duration>
4587 unsigned
4588 extract_month(std::basic_ostream<CharT, Traits> &os,
4589  const fields<Duration> &fds)
4590 {
4591  if (!fds.ymd.month().ok()) {
4592  // fds does not contain a valid month
4593  os.setstate(std::ios::failbit);
4594  return 0;
4595  }
4596  return static_cast<unsigned>(fds.ymd.month());
4597 }
4598 
4599 } // namespace detail
4600 
4601 #if ONLY_C_LOCALE
4602 
4603 namespace detail {
4604 
4605 inline
4606 std::pair<const std::string *, const std::string *>
4607 weekday_names()
4608 {
4609  static const std::string nm[] = {
4610  "Sunday",
4611  "Monday",
4612  "Tuesday",
4613  "Wednesday",
4614  "Thursday",
4615  "Friday",
4616  "Saturday",
4617  "Sun",
4618  "Mon",
4619  "Tue",
4620  "Wed",
4621  "Thu",
4622  "Fri",
4623  "Sat"
4624  };
4625  return std::make_pair(nm, nm + sizeof(nm) / sizeof(nm[0]));
4626 }
4627 
4628 inline
4629 std::pair<const std::string *, const std::string *>
4630 month_names()
4631 {
4632  static const std::string nm[] = {
4633  "January",
4634  "February",
4635  "March",
4636  "April",
4637  "May",
4638  "June",
4639  "July",
4640  "August",
4641  "September",
4642  "October",
4643  "November",
4644  "December",
4645  "Jan",
4646  "Feb",
4647  "Mar",
4648  "Apr",
4649  "May",
4650  "Jun",
4651  "Jul",
4652  "Aug",
4653  "Sep",
4654  "Oct",
4655  "Nov",
4656  "Dec"
4657  };
4658  return std::make_pair(nm, nm + sizeof(nm) / sizeof(nm[0]));
4659 }
4660 
4661 inline
4662 std::pair<const std::string *, const std::string *>
4663 ampm_names()
4664 {
4665  static const std::string nm[] = {
4666  "AM",
4667  "PM"
4668  };
4669  return std::make_pair(nm, nm + sizeof(nm) / sizeof(nm[0]));
4670 }
4671 
4672 template <class CharT, class Traits, class FwdIter>
4673 FwdIter
4674 scan_keyword(std::basic_istream<CharT, Traits> &is, FwdIter kb, FwdIter ke)
4675 {
4676  size_t nkw = static_cast<size_t>(std::distance(kb, ke));
4677  const unsigned char doesnt_match = '\0';
4678  const unsigned char might_match = '\1';
4679  const unsigned char does_match = '\2';
4680  unsigned char statbuf[100];
4681  unsigned char *status = statbuf;
4682  std::unique_ptr<unsigned char, void(*)(void *)> stat_hold(0, free);
4683  if (nkw > sizeof(statbuf)) {
4684  status = (unsigned char *)std::malloc(nkw);
4685  if (status == nullptr) {
4686  throw std::bad_alloc();
4687  }
4688  stat_hold.reset(status);
4689  }
4690  size_t n_might_match = nkw; // At this point, any keyword might match
4691  size_t n_does_match = 0; // but none of them definitely do
4692  // Initialize all statuses to might_match, except for "" keywords are does_match
4693  unsigned char *st = status;
4694  for (auto ky = kb; ky != ke; ++ky, ++st) {
4695  if (!ky->empty()) {
4696  *st = might_match;
4697  }
4698  else {
4699  *st = does_match;
4700  --n_might_match;
4701  ++n_does_match;
4702  }
4703  }
4704  // While there might be a match, test keywords against the next CharT
4705  for (size_t indx = 0; is && n_might_match > 0; ++indx) {
4706  // Peek at the next CharT but don't consume it
4707  auto ic = is.peek();
4708  if (ic == EOF) {
4709  is.setstate(std::ios::eofbit);
4710  break;
4711  }
4712  auto c = static_cast<char>(toupper(ic));
4713  bool consume = false;
4714  // For each keyword which might match, see if the indx character is c
4715  // If a match if found, consume c
4716  // If a match is found, and that is the last character in the keyword,
4717  // then that keyword matches.
4718  // If the keyword doesn't match this character, then change the keyword
4719  // to doesn't match
4720  st = status;
4721  for (auto ky = kb; ky != ke; ++ky, ++st) {
4722  if (*st == might_match) {
4723  if (c == static_cast<char>(toupper((*ky)[indx]))) {
4724  consume = true;
4725  if (ky->size() == indx + 1) {
4726  *st = does_match;
4727  --n_might_match;
4728  ++n_does_match;
4729  }
4730  }
4731  else {
4732  *st = doesnt_match;
4733  --n_might_match;
4734  }
4735  }
4736  }
4737  // consume if we matched a character
4738  if (consume) {
4739  (void)is.get();
4740  // If we consumed a character and there might be a matched keyword that
4741  // was marked matched on a previous iteration, then such keywords
4742  // are now marked as not matching.
4743  if (n_might_match + n_does_match > 1) {
4744  st = status;
4745  for (auto ky = kb; ky != ke; ++ky, ++st) {
4746  if (*st == does_match && ky->size() != indx + 1) {
4747  *st = doesnt_match;
4748  --n_does_match;
4749  }
4750  }
4751  }
4752  }
4753  }
4754  // We've exited the loop because we hit eof and/or we have no more "might matches".
4755  // Return the first matching result
4756  for (st = status; kb != ke; ++kb, ++st)
4757  if (*st == does_match) {
4758  break;
4759  }
4760  if (kb == ke) {
4761  is.setstate(std::ios::failbit);
4762  }
4763  return kb;
4764 }
4765 
4766 } // namespace detail
4767 
4768 #endif // ONLY_C_LOCALE
4769 
4770 template <class CharT, class Traits, class Duration>
4771 std::basic_ostream<CharT, Traits> &
4772 to_stream(std::basic_ostream<CharT, Traits> &os, const CharT *fmt,
4773  const fields<Duration> &fds, const std::string *abbrev,
4774  const std::chrono::seconds *offset_sec)
4775 {
4776 #if ONLY_C_LOCALE
4777  using detail::weekday_names;
4778  using detail::month_names;
4779  using detail::ampm_names;
4780 #endif
4781  using detail::save_ostream;
4782  using detail::get_units;
4784  using detail::extract_month;
4785  using std::ios;
4786  using std::chrono::duration_cast;
4787  using std::chrono::seconds;
4788  using std::chrono::minutes;
4789  using std::chrono::hours;
4791  os.fill(' ');
4792  os.flags(std::ios::skipws | std::ios::dec);
4793  os.width(0);
4794  tm tm{};
4795  bool insert_negative = fds.has_tod && fds.tod.to_duration() < Duration::zero();
4796 #if !ONLY_C_LOCALE
4797  auto &facet = std::use_facet<std::time_put<CharT>>(os.getloc());
4798 #endif
4799  const CharT *command = nullptr;
4800  CharT modified = CharT{};
4801  for (; *fmt; ++fmt) {
4802  switch (*fmt) {
4803  case 'a':
4804  case 'A':
4805  if (command) {
4806  if (modified == CharT{}) {
4807  tm.tm_wday = static_cast<int>(extract_weekday(os, fds));
4808  if (os.fail()) {
4809  return os;
4810  }
4811 #if !ONLY_C_LOCALE
4812  const CharT f[] = {'%', *fmt};
4813  facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
4814 #else // ONLY_C_LOCALE
4815  os << weekday_names().first[tm.tm_wday + 7 * (*fmt == 'a')];
4816 #endif // ONLY_C_LOCALE
4817  }
4818  else {
4819  os << CharT{'%'} << modified << *fmt;
4820  modified = CharT{};
4821  }
4822  command = nullptr;
4823  }
4824  else {
4825  os << *fmt;
4826  }
4827  break;
4828  case 'b':
4829  case 'B':
4830  case 'h':
4831  if (command) {
4832  if (modified == CharT{}) {
4833  tm.tm_mon = static_cast<int>(extract_month(os, fds)) - 1;
4834 #if !ONLY_C_LOCALE
4835  const CharT f[] = {'%', *fmt};
4836  facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
4837 #else // ONLY_C_LOCALE
4838  os << month_names().first[tm.tm_mon + 12 * (*fmt != 'B')];
4839 #endif // ONLY_C_LOCALE
4840  }
4841  else {
4842  os << CharT{'%'} << modified << *fmt;
4843  modified = CharT{};
4844  }
4845  command = nullptr;
4846  }
4847  else {
4848  os << *fmt;
4849  }
4850  break;
4851  case 'c':
4852  case 'x':
4853  if (command) {
4854  if (modified == CharT{'O'})
4855  os << CharT{'%'} << modified << *fmt;
4856  else {
4857  if (!fds.ymd.ok()) {
4858  os.setstate(std::ios::failbit);
4859  }
4860  if (*fmt == 'c' && !fds.has_tod) {
4861  os.setstate(std::ios::failbit);
4862  }
4863 #if !ONLY_C_LOCALE
4864  tm = std::tm {};
4865  auto const &ymd = fds.ymd;
4866  auto ld = local_days(ymd);
4867  if (*fmt == 'c') {
4868  tm.tm_sec = static_cast<int>(fds.tod.seconds().count());
4869  tm.tm_min = static_cast<int>(fds.tod.minutes().count());
4870  tm.tm_hour = static_cast<int>(fds.tod.hours().count());
4871  }
4872  tm.tm_mday = static_cast<int>(static_cast<unsigned>(ymd.day()));
4873  tm.tm_mon = static_cast<int>(extract_month(os, fds) - 1);
4874  tm.tm_year = static_cast<int>(ymd.year()) - 1900;
4875  tm.tm_wday = static_cast<int>(extract_weekday(os, fds));
4876  if (os.fail()) {
4877  return os;
4878  }
4879  tm.tm_yday = static_cast<int>((ld - local_days(ymd.year() / 1 / 1)).count());
4880  CharT f[3] = {'%'};
4881  auto fe = std::begin(f) + 1;
4882  if (modified == CharT{'E'})
4883  *fe++ = modified;
4884  *fe++ = *fmt;
4885  facet.put(os, os, os.fill(), &tm, std::begin(f), fe);
4886 #else // ONLY_C_LOCALE
4887  if (*fmt == 'c') {
4888  auto wd = static_cast<int>(extract_weekday(os, fds));
4889  os << weekday_names().first[static_cast<unsigned>(wd) + 7]
4890  << ' ';
4891  os << month_names().first[extract_month(os, fds) - 1 + 12] << ' ';
4892  auto d = static_cast<int>(static_cast<unsigned>(fds.ymd.day()));
4893  if (d < 10) {
4894  os << ' ';
4895  }
4896  os << d << ' '
4897  << make_time(duration_cast<seconds>(fds.tod.to_duration()))
4898  << ' ' << fds.ymd.year();
4899 
4900  }
4901  else { // *fmt == 'x'
4902  auto const &ymd = fds.ymd;
4903  save_ostream<CharT, Traits> _(os);
4904  os.fill('0');
4905  os.flags(std::ios::dec | std::ios::right);
4906  os.width(2);
4907  os << static_cast<unsigned>(ymd.month()) << CharT{'/'};
4908  os.width(2);
4909  os << static_cast<unsigned>(ymd.day()) << CharT{'/'};
4910  os.width(2);
4911  os << static_cast<int>(ymd.year()) % 100;
4912  }
4913 #endif // ONLY_C_LOCALE
4914  }
4915  command = nullptr;
4916  modified = CharT{};
4917  }
4918  else {
4919  os << *fmt;
4920  }
4921  break;
4922  case 'C':
4923  if (command) {
4924  if (modified == CharT{'O'})
4925  os << CharT{'%'} << modified << *fmt;
4926  else {
4927  if (!fds.ymd.year().ok()) {
4928  os.setstate(std::ios::failbit);
4929  }
4930  auto y = static_cast<int>(fds.ymd.year());
4931 #if !ONLY_C_LOCALE
4932  if (modified == CharT {})
4933 #endif
4934  {
4935  save_ostream<CharT, Traits> _(os);
4936  os.fill('0');
4937  os.flags(std::ios::dec | std::ios::right);
4938  if (y >= 0) {
4939  os.width(2);
4940  os << y / 100;
4941  }
4942  else {
4943  os << CharT{'-'};
4944  os.width(2);
4945  os << -(y - 99) / 100;
4946  }
4947  }
4948 #if !ONLY_C_LOCALE
4949  else if (modified == CharT {'E'}) {
4950  tm.tm_year = y - 1900;
4951  CharT f[3] = {'%', 'E', 'C'};
4952  facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
4953  }
4954 #endif
4955  }
4956  command = nullptr;
4957  modified = CharT{};
4958  }
4959  else {
4960  os << *fmt;
4961  }
4962  break;
4963  case 'd':
4964  case 'e':
4965  if (command) {
4966  if (modified == CharT{'E'})
4967  os << CharT{'%'} << modified << *fmt;
4968  else {
4969  if (!fds.ymd.day().ok()) {
4970  os.setstate(std::ios::failbit);
4971  }
4972  auto d = static_cast<int>(static_cast<unsigned>(fds.ymd.day()));
4973 #if !ONLY_C_LOCALE
4974  if (modified == CharT {})
4975 #endif
4976  {
4977  save_ostream<CharT, Traits> _(os);
4978  if (*fmt == CharT{'d'})
4979  os.fill('0');
4980  else {
4981  os.fill(' ');
4982  }
4983  os.flags(std::ios::dec | std::ios::right);
4984  os.width(2);
4985  os << d;
4986  }
4987 #if !ONLY_C_LOCALE
4988  else if (modified == CharT {'O'}) {
4989  tm.tm_mday = d;
4990  CharT f[3] = {'%', 'O', *fmt};
4991  facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
4992  }
4993 #endif
4994  }
4995  command = nullptr;
4996  modified = CharT{};
4997  }
4998  else {
4999  os << *fmt;
5000  }
5001  break;
5002  case 'D':
5003  if (command) {
5004  if (modified == CharT{}) {
5005  if (!fds.ymd.ok()) {
5006  os.setstate(std::ios::failbit);
5007  }
5008  auto const &ymd = fds.ymd;
5009  save_ostream<CharT, Traits> _(os);
5010  os.fill('0');
5011  os.flags(std::ios::dec | std::ios::right);
5012  os.width(2);
5013  os << static_cast<unsigned>(ymd.month()) << CharT{'/'};
5014  os.width(2);
5015  os << static_cast<unsigned>(ymd.day()) << CharT{'/'};
5016  os.width(2);
5017  os << static_cast<int>(ymd.year()) % 100;
5018  }
5019  else {
5020  os << CharT{'%'} << modified << *fmt;
5021  modified = CharT{};
5022  }
5023  command = nullptr;
5024  }
5025  else {
5026  os << *fmt;
5027  }
5028  break;
5029  case 'F':
5030  if (command) {
5031  if (modified == CharT{}) {
5032  if (!fds.ymd.ok()) {
5033  os.setstate(std::ios::failbit);
5034  }
5035  auto const &ymd = fds.ymd;
5036  save_ostream<CharT, Traits> _(os);
5037  os.fill('0');
5038  os.flags(std::ios::dec | std::ios::right);
5039  os.width(4);
5040  os << static_cast<int>(ymd.year()) << CharT{'-'};
5041  os.width(2);
5042  os << static_cast<unsigned>(ymd.month()) << CharT{'-'};
5043  os.width(2);
5044  os << static_cast<unsigned>(ymd.day());
5045  }
5046  else {
5047  os << CharT{'%'} << modified << *fmt;
5048  modified = CharT{};
5049  }
5050  command = nullptr;
5051  }
5052  else {
5053  os << *fmt;
5054  }
5055  break;
5056  case 'g':
5057  case 'G':
5058  if (command) {
5059  if (modified == CharT{}) {
5060  if (!fds.ymd.ok()) {
5061  os.setstate(std::ios::failbit);
5062  }
5063  auto ld = local_days(fds.ymd);
5064  auto y = year_month_day{ld + days{3}}.year();
5065  auto start = local_days((y - years{1}) / December / Thursday[last]) +
5066  (Monday - Thursday);
5067  if (ld < start) {
5068  --y;
5069  }
5070  if (*fmt == CharT{'G'})
5071  os << y;
5072  else {
5073  save_ostream<CharT, Traits> _(os);
5074  os.fill('0');
5075  os.flags(std::ios::dec | std::ios::right);
5076  os.width(2);
5077  os << std::abs(static_cast<int>(y)) % 100;
5078  }
5079  }
5080  else {
5081  os << CharT{'%'} << modified << *fmt;
5082  modified = CharT{};
5083  }
5084  command = nullptr;
5085  }
5086  else {
5087  os << *fmt;
5088  }
5089  break;
5090  case 'H':
5091  case 'I':
5092  if (command) {
5093  if (modified == CharT{'E'})
5094  os << CharT{'%'} << modified << *fmt;
5095  else {
5096  if (!fds.has_tod) {
5097  os.setstate(std::ios::failbit);
5098  }
5099  if (insert_negative) {
5100  os << '-';
5101  insert_negative = false;
5102  }
5103  auto hms = fds.tod;
5104 #if !ONLY_C_LOCALE
5105  if (modified == CharT {})
5106 #endif
5107  {
5108  auto h = *fmt == CharT{'I'} ? make12(hms.hours()) : hms.hours();
5109  if (h < hours{10})
5110  os << CharT{'0'};
5111  os << h.count();
5112  }
5113 #if !ONLY_C_LOCALE
5114  else if (modified == CharT {'O'}) {
5115  const CharT f[] = {'%', modified, *fmt};
5116  tm.tm_hour = static_cast<int>(hms.hours().count());
5117  facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5118  }
5119 #endif
5120  }
5121  modified = CharT{};
5122  command = nullptr;
5123  }
5124  else {
5125  os << *fmt;
5126  }
5127  break;
5128  case 'j':
5129  if (command) {
5130  if (modified == CharT{}) {
5131  if (fds.ymd.ok() || fds.has_tod) {
5132  days doy;
5133  if (fds.ymd.ok()) {
5134  auto ld = local_days(fds.ymd);
5135  auto y = fds.ymd.year();
5136  doy = ld - local_days(y / January / 1) + days{1};
5137  }
5138  else {
5139  doy = duration_cast<days>(fds.tod.to_duration());
5140  }
5141  save_ostream<CharT, Traits> _(os);
5142  os.fill('0');
5143  os.flags(std::ios::dec | std::ios::right);
5144  os.width(3);
5145  os << doy.count();
5146  }
5147  else {
5148  os.setstate(std::ios::failbit);
5149  }
5150  }
5151  else {
5152  os << CharT{'%'} << modified << *fmt;
5153  modified = CharT{};
5154  }
5155  command = nullptr;
5156  }
5157  else {
5158  os << *fmt;
5159  }
5160  break;
5161  case 'm':
5162  if (command) {
5163  if (modified == CharT{'E'})
5164  os << CharT{'%'} << modified << *fmt;
5165  else {
5166  if (!fds.ymd.month().ok()) {
5167  os.setstate(std::ios::failbit);
5168  }
5169  auto m = static_cast<unsigned>(fds.ymd.month());
5170 #if !ONLY_C_LOCALE
5171  if (modified == CharT {})
5172 #endif
5173  {
5174  if (m < 10)
5175  os << CharT{'0'};
5176  os << m;
5177  }
5178 #if !ONLY_C_LOCALE
5179  else if (modified == CharT {'O'}) {
5180  const CharT f[] = {'%', modified, *fmt};
5181  tm.tm_mon = static_cast<int>(m - 1);
5182  facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5183  }
5184 #endif
5185  }
5186  modified = CharT{};
5187  command = nullptr;
5188  }
5189  else {
5190  os << *fmt;
5191  }
5192  break;
5193  case 'M':
5194  if (command) {
5195  if (modified == CharT{'E'})
5196  os << CharT{'%'} << modified << *fmt;
5197  else {
5198  if (!fds.has_tod) {
5199  os.setstate(std::ios::failbit);
5200  }
5201  if (insert_negative) {
5202  os << '-';
5203  insert_negative = false;
5204  }
5205 #if !ONLY_C_LOCALE
5206  if (modified == CharT {})
5207 #endif
5208  {
5209  if (fds.tod.minutes() < minutes{10})
5210  os << CharT{'0'};
5211  os << fds.tod.minutes().count();
5212  }
5213 #if !ONLY_C_LOCALE
5214  else if (modified == CharT {'O'}) {
5215  const CharT f[] = {'%', modified, *fmt};
5216  tm.tm_min = static_cast<int>(fds.tod.minutes().count());
5217  facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5218  }
5219 #endif
5220  }
5221  modified = CharT{};
5222  command = nullptr;
5223  }
5224  else {
5225  os << *fmt;
5226  }
5227  break;
5228  case 'n':
5229  if (command) {
5230  if (modified == CharT{})
5231  os << CharT{'\n'};
5232  else {
5233  os << CharT{'%'} << modified << *fmt;
5234  modified = CharT{};
5235  }
5236  command = nullptr;
5237  }
5238  else {
5239  os << *fmt;
5240  }
5241  break;
5242  case 'p':
5243  if (command) {
5244  if (modified == CharT{}) {
5245  if (!fds.has_tod) {
5246  os.setstate(std::ios::failbit);
5247  }
5248 #if !ONLY_C_LOCALE
5249  const CharT f[] = {'%', *fmt};
5250  tm.tm_hour = static_cast<int>(fds.tod.hours().count());
5251  facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5252 #else
5253  if (is_am(fds.tod.hours())) {
5254  os << ampm_names().first[0];
5255  }
5256  else {
5257  os << ampm_names().first[1];
5258  }
5259 #endif
5260  }
5261  else {
5262  os << CharT{'%'} << modified << *fmt;
5263  }
5264  modified = CharT{};
5265  command = nullptr;
5266  }
5267  else {
5268  os << *fmt;
5269  }
5270  break;
5271  case 'Q':
5272  case 'q':
5273  if (command) {
5274  if (modified == CharT{}) {
5275  if (!fds.has_tod) {
5276  os.setstate(std::ios::failbit);
5277  }
5278  auto d = fds.tod.to_duration();
5279  if (*fmt == 'q')
5280  os << get_units<CharT>(typename decltype(d)::period::type{});
5281  else {
5282  os << d.count();
5283  }
5284  }
5285  else {
5286  os << CharT{'%'} << modified << *fmt;
5287  }
5288  modified = CharT{};
5289  command = nullptr;
5290  }
5291  else {
5292  os << *fmt;
5293  }
5294  break;
5295  case 'r':
5296  if (command) {
5297  if (modified == CharT{}) {
5298  if (!fds.has_tod) {
5299  os.setstate(std::ios::failbit);
5300  }
5301 #if !ONLY_C_LOCALE
5302  const CharT f[] = {'%', *fmt};
5303  tm.tm_hour = static_cast<int>(fds.tod.hours().count());
5304  tm.tm_min = static_cast<int>(fds.tod.minutes().count());
5305  tm.tm_sec = static_cast<int>(fds.tod.seconds().count());
5306  facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5307 #else
5308  hh_mm_ss<seconds> tod(duration_cast<seconds>(fds.tod.to_duration()));
5309  save_ostream<CharT, Traits> _(os);
5310  os.fill('0');
5311  os.width(2);
5312  os << make12(tod.hours()).count() << CharT{':'};
5313  os.width(2);
5314  os << tod.minutes().count() << CharT{':'};
5315  os.width(2);
5316  os << tod.seconds().count() << CharT{' '};
5317  if (is_am(tod.hours())) {
5318  os << ampm_names().first[0];
5319  }
5320  else {
5321  os << ampm_names().first[1];
5322  }
5323 #endif
5324  }
5325  else {
5326  os << CharT{'%'} << modified << *fmt;
5327  }
5328  modified = CharT{};
5329  command = nullptr;
5330  }
5331  else {
5332  os << *fmt;
5333  }
5334  break;
5335  case 'R':
5336  if (command) {
5337  if (modified == CharT{}) {
5338  if (!fds.has_tod) {
5339  os.setstate(std::ios::failbit);
5340  }
5341  if (fds.tod.hours() < hours{10})
5342  os << CharT{'0'};
5343  os << fds.tod.hours().count() << CharT{':'};
5344  if (fds.tod.minutes() < minutes{10})
5345  os << CharT{'0'};
5346  os << fds.tod.minutes().count();
5347  }
5348  else {
5349  os << CharT{'%'} << modified << *fmt;
5350  modified = CharT{};
5351  }
5352  command = nullptr;
5353  }
5354  else {
5355  os << *fmt;
5356  }
5357  break;
5358  case 'S':
5359  if (command) {
5360  if (modified == CharT{'E'})
5361  os << CharT{'%'} << modified << *fmt;
5362  else {
5363  if (!fds.has_tod) {
5364  os.setstate(std::ios::failbit);
5365  }
5366  if (insert_negative) {
5367  os << '-';
5368  insert_negative = false;
5369  }
5370 #if !ONLY_C_LOCALE
5371  if (modified == CharT {})
5372 #endif
5373  {
5374  os << fds.tod.s_;
5375  }
5376 #if !ONLY_C_LOCALE
5377  else if (modified == CharT {'O'}) {
5378  const CharT f[] = {'%', modified, *fmt};
5379  tm.tm_sec = static_cast<int>(fds.tod.s_.seconds().count());
5380  facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5381  }
5382 #endif
5383  }
5384  modified = CharT{};
5385  command = nullptr;
5386  }
5387  else {
5388  os << *fmt;
5389  }
5390  break;
5391  case 't':
5392  if (command) {
5393  if (modified == CharT{})
5394  os << CharT{'\t'};
5395  else {
5396  os << CharT{'%'} << modified << *fmt;
5397  modified = CharT{};
5398  }
5399  command = nullptr;
5400  }
5401  else {
5402  os << *fmt;
5403  }
5404  break;
5405  case 'T':
5406  if (command) {
5407  if (modified == CharT{}) {
5408  if (!fds.has_tod) {
5409  os.setstate(std::ios::failbit);
5410  }
5411  os << fds.tod;
5412  }
5413  else {
5414  os << CharT{'%'} << modified << *fmt;
5415  modified = CharT{};
5416  }
5417  command = nullptr;
5418  }
5419  else {
5420  os << *fmt;
5421  }
5422  break;
5423  case 'u':
5424  if (command) {
5425  if (modified == CharT{'E'})
5426  os << CharT{'%'} << modified << *fmt;
5427  else {
5428  auto wd = extract_weekday(os, fds);
5429 #if !ONLY_C_LOCALE
5430  if (modified == CharT {})
5431 #endif
5432  {
5433  os << (wd != 0 ? wd : 7u);
5434  }
5435 #if !ONLY_C_LOCALE
5436  else if (modified == CharT {'O'}) {
5437  const CharT f[] = {'%', modified, *fmt};
5438  tm.tm_wday = static_cast<int>(wd);
5439  facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5440  }
5441 #endif
5442  }
5443  modified = CharT{};
5444  command = nullptr;
5445  }
5446  else {
5447  os << *fmt;
5448  }
5449  break;
5450  case 'U':
5451  if (command) {
5452  if (modified == CharT{'E'})
5453  os << CharT{'%'} << modified << *fmt;
5454  else {
5455  auto const &ymd = fds.ymd;
5456  if (!ymd.ok()) {
5457  os.setstate(std::ios::failbit);
5458  }
5459  auto ld = local_days(ymd);
5460 #if !ONLY_C_LOCALE
5461  if (modified == CharT {})
5462 #endif
5463  {
5464  auto st = local_days(Sunday[1] / January / ymd.year());
5465  if (ld < st)
5466  os << CharT{'0'} << CharT{'0'};
5467  else {
5468  auto wn = duration_cast<weeks>(ld - st).count() + 1;
5469  if (wn < 10)
5470  os << CharT{'0'};
5471  os << wn;
5472  }
5473  }
5474 #if !ONLY_C_LOCALE
5475  else if (modified == CharT {'O'}) {
5476  const CharT f[] = {'%', modified, *fmt};
5477  tm.tm_year = static_cast<int>(ymd.year()) - 1900;
5478  tm.tm_wday = static_cast<int>(extract_weekday(os, fds));
5479  if (os.fail()) {
5480  return os;
5481  }
5482  tm.tm_yday = static_cast<int>((ld - local_days(ymd.year() / 1 / 1)).count());
5483  facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5484  }
5485 #endif
5486  }
5487  modified = CharT{};
5488  command = nullptr;
5489  }
5490  else {
5491  os << *fmt;
5492  }
5493  break;
5494  case 'V':
5495  if (command) {
5496  if (modified == CharT{'E'})
5497  os << CharT{'%'} << modified << *fmt;
5498  else {
5499  if (!fds.ymd.ok()) {
5500  os.setstate(std::ios::failbit);
5501  }
5502  auto ld = local_days(fds.ymd);
5503 #if !ONLY_C_LOCALE
5504  if (modified == CharT {})
5505 #endif
5506  {
5507  auto y = year_month_day{ld + days{3}}.year();
5508  auto st = local_days((y - years{1}) / 12 / Thursday[last]) +
5509  (Monday - Thursday);
5510  if (ld < st) {
5511  --y;
5512  st = local_days((y - years{1}) / 12 / Thursday[last]) +
5513  (Monday - Thursday);
5514  }
5515  auto wn = duration_cast<weeks>(ld - st).count() + 1;
5516  if (wn < 10)
5517  os << CharT{'0'};
5518  os << wn;
5519  }
5520 #if !ONLY_C_LOCALE
5521  else if (modified == CharT {'O'}) {
5522  const CharT f[] = {'%', modified, *fmt};
5523  auto const &ymd = fds.ymd;
5524  tm.tm_year = static_cast<int>(ymd.year()) - 1900;
5525  tm.tm_wday = static_cast<int>(extract_weekday(os, fds));
5526  if (os.fail()) {
5527  return os;
5528  }
5529  tm.tm_yday = static_cast<int>((ld - local_days(ymd.year() / 1 / 1)).count());
5530  facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5531  }
5532 #endif
5533  }
5534  modified = CharT{};
5535  command = nullptr;
5536  }
5537  else {
5538  os << *fmt;
5539  }
5540  break;
5541  case 'w':
5542  if (command) {
5543  auto wd = extract_weekday(os, fds);
5544  if (os.fail()) {
5545  return os;
5546  }
5547 #if !ONLY_C_LOCALE
5548  if (modified == CharT {})
5549 #else
5550  if (modified != CharT {'E'})
5551 #endif
5552  {
5553  os << wd;
5554  }
5555 #if !ONLY_C_LOCALE
5556  else if (modified == CharT {'O'}) {
5557  const CharT f[] = {'%', modified, *fmt};
5558  tm.tm_wday = static_cast<int>(wd);
5559  facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5560  }
5561 #endif
5562  else {
5563  os << CharT{'%'} << modified << *fmt;
5564  }
5565  modified = CharT{};
5566  command = nullptr;
5567  }
5568  else {
5569  os << *fmt;
5570  }
5571  break;
5572  case 'W':
5573  if (command) {
5574  if (modified == CharT{'E'})
5575  os << CharT{'%'} << modified << *fmt;
5576  else {
5577  auto const &ymd = fds.ymd;
5578  if (!ymd.ok()) {
5579  os.setstate(std::ios::failbit);
5580  }
5581  auto ld = local_days(ymd);
5582 #if !ONLY_C_LOCALE
5583  if (modified == CharT {})
5584 #endif
5585  {
5586  auto st = local_days(Monday[1] / January / ymd.year());
5587  if (ld < st)
5588  os << CharT{'0'} << CharT{'0'};
5589  else {
5590  auto wn = duration_cast<weeks>(ld - st).count() + 1;
5591  if (wn < 10)
5592  os << CharT{'0'};
5593  os << wn;
5594  }
5595  }
5596 #if !ONLY_C_LOCALE
5597  else if (modified == CharT {'O'}) {
5598  const CharT f[] = {'%', modified, *fmt};
5599  tm.tm_year = static_cast<int>(ymd.year()) - 1900;
5600  tm.tm_wday = static_cast<int>(extract_weekday(os, fds));
5601  if (os.fail()) {
5602  return os;
5603  }
5604  tm.tm_yday = static_cast<int>((ld - local_days(ymd.year() / 1 / 1)).count());
5605  facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5606  }
5607 #endif
5608  }
5609  modified = CharT{};
5610  command = nullptr;
5611  }
5612  else {
5613  os << *fmt;
5614  }
5615  break;
5616  case 'X':
5617  if (command) {
5618  if (modified == CharT{'O'})
5619  os << CharT{'%'} << modified << *fmt;
5620  else {
5621  if (!fds.has_tod) {
5622  os.setstate(std::ios::failbit);
5623  }
5624 #if !ONLY_C_LOCALE
5625  tm = std::tm {};
5626  tm.tm_sec = static_cast<int>(fds.tod.seconds().count());
5627  tm.tm_min = static_cast<int>(fds.tod.minutes().count());
5628  tm.tm_hour = static_cast<int>(fds.tod.hours().count());
5629  CharT f[3] = {'%'};
5630  auto fe = std::begin(f) + 1;
5631  if (modified == CharT{'E'})
5632  *fe++ = modified;
5633  *fe++ = *fmt;
5634  facet.put(os, os, os.fill(), &tm, std::begin(f), fe);
5635 #else
5636  os << fds.tod;
5637 #endif
5638  }
5639  command = nullptr;
5640  modified = CharT{};
5641  }
5642  else {
5643  os << *fmt;
5644  }
5645  break;
5646  case 'y':
5647  if (command) {
5648  if (!fds.ymd.year().ok()) {
5649  os.setstate(std::ios::failbit);
5650  }
5651  auto y = static_cast<int>(fds.ymd.year());
5652 #if !ONLY_C_LOCALE
5653  if (modified == CharT {}) {
5654 #endif
5655  y = std::abs(y) % 100;
5656  if (y < 10)
5657  os << CharT{'0'};
5658  os << y;
5659 #if !ONLY_C_LOCALE
5660  }
5661  else {
5662  const CharT f[] = {'%', modified, *fmt};
5663  tm.tm_year = y - 1900;
5664  facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5665  }
5666 #endif
5667  modified = CharT {};
5668  command = nullptr;
5669  }
5670  else {
5671  os << *fmt;
5672  }
5673  break;
5674  case 'Y':
5675  if (command) {
5676  if (modified == CharT{'O'})
5677  os << CharT{'%'} << modified << *fmt;
5678  else {
5679  if (!fds.ymd.year().ok()) {
5680  os.setstate(std::ios::failbit);
5681  }
5682  auto y = fds.ymd.year();
5683 #if !ONLY_C_LOCALE
5684  if (modified == CharT {})
5685 #endif
5686  {
5687  os << y;
5688  }
5689 #if !ONLY_C_LOCALE
5690  else if (modified == CharT {'E'}) {
5691  const CharT f[] = {'%', modified, *fmt};
5692  tm.tm_year = static_cast<int>(y) - 1900;
5693  facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5694  }
5695 #endif
5696  }
5697  modified = CharT{};
5698  command = nullptr;
5699  }
5700  else {
5701  os << *fmt;
5702  }
5703  break;
5704  case 'z':
5705  if (command) {
5706  if (offset_sec == nullptr) {
5707  // Can not format %z with unknown offset
5708  os.setstate(ios::failbit);
5709  return os;
5710  }
5711  auto m = duration_cast<minutes>(*offset_sec);
5712  auto neg = m < minutes{0};
5713  m = date::abs(m);
5714  auto h = duration_cast<hours>(m);
5715  m -= h;
5716  if (neg)
5717  os << CharT{'-'};
5718  else
5719  os << CharT{'+'};
5720  if (h < hours{10})
5721  os << CharT{'0'};
5722  os << h.count();
5723  if (modified != CharT{})
5724  os << CharT{':'};
5725  if (m < minutes{10})
5726  os << CharT{'0'};
5727  os << m.count();
5728  command = nullptr;
5729  modified = CharT{};
5730  }
5731  else {
5732  os << *fmt;
5733  }
5734  break;
5735  case 'Z':
5736  if (command) {
5737  if (modified == CharT{}) {
5738  if (abbrev == nullptr) {
5739  // Can not format %Z with unknown time_zone
5740  os.setstate(ios::failbit);
5741  return os;
5742  }
5743  for (auto c : *abbrev) {
5744  os << CharT(c);
5745  }
5746  }
5747  else {
5748  os << CharT{'%'} << modified << *fmt;
5749  modified = CharT{};
5750  }
5751  command = nullptr;
5752  }
5753  else {
5754  os << *fmt;
5755  }
5756  break;
5757  case 'E':
5758  case 'O':
5759  if (command) {
5760  if (modified == CharT{}) {
5761  modified = *fmt;
5762  }
5763  else {
5764  os << CharT{'%'} << modified << *fmt;
5765  command = nullptr;
5766  modified = CharT{};
5767  }
5768  }
5769  else {
5770  os << *fmt;
5771  }
5772  break;
5773  case '%':
5774  if (command) {
5775  if (modified == CharT{}) {
5776  os << CharT{'%'};
5777  command = nullptr;
5778  }
5779  else {
5780  os << CharT{'%'} << modified << CharT{'%'};
5781  command = nullptr;
5782  modified = CharT{};
5783  }
5784  }
5785  else {
5786  command = fmt;
5787  }
5788  break;
5789  default:
5790  if (command) {
5791  os << CharT{'%'};
5792  command = nullptr;
5793  }
5794  if (modified != CharT{}) {
5795  os << modified;
5796  modified = CharT{};
5797  }
5798  os << *fmt;
5799  break;
5800  }
5801  }
5802  if (command)
5803  os << CharT{'%'};
5804  if (modified != CharT{})
5805  os << modified;
5806  return os;
5807 }
5808 
5809 template <class CharT, class Traits>
5810 inline
5811 std::basic_ostream<CharT, Traits> &
5812 to_stream(std::basic_ostream<CharT, Traits> &os, const CharT *fmt,
5813  const year &y)
5814 {
5815  using CT = std::chrono::seconds;
5816  fields<CT> fds{y / 0 / 0};
5817  return to_stream(os, fmt, fds);
5818 }
5819 
5820 template <class CharT, class Traits>
5821 inline
5822 std::basic_ostream<CharT, Traits> &
5823 to_stream(std::basic_ostream<CharT, Traits> &os, const CharT *fmt,
5824  const month &m)
5825 {
5826  using CT = std::chrono::seconds;
5827  fields<CT> fds{m / 0 / nanyear};
5828  return to_stream(os, fmt, fds);
5829 }
5830 
5831 template <class CharT, class Traits>
5832 inline
5833 std::basic_ostream<CharT, Traits> &
5834 to_stream(std::basic_ostream<CharT, Traits> &os, const CharT *fmt, const day &d)
5835 {
5836  using CT = std::chrono::seconds;
5837  fields<CT> fds{d / 0 / nanyear};
5838  return to_stream(os, fmt, fds);
5839 }
5840 
5841 template <class CharT, class Traits>
5842 inline
5843 std::basic_ostream<CharT, Traits> &
5844 to_stream(std::basic_ostream<CharT, Traits> &os, const CharT *fmt,
5845  const weekday &wd)
5846 {
5847  using CT = std::chrono::seconds;
5848  fields<CT> fds{wd};
5849  return to_stream(os, fmt, fds);
5850 }
5851 
5852 template <class CharT, class Traits>
5853 inline
5854 std::basic_ostream<CharT, Traits> &
5855 to_stream(std::basic_ostream<CharT, Traits> &os, const CharT *fmt,
5856  const year_month &ym)
5857 {
5858  using CT = std::chrono::seconds;
5859  fields<CT> fds{ym / 0};
5860  return to_stream(os, fmt, fds);
5861 }
5862 
5863 template <class CharT, class Traits>
5864 inline
5865 std::basic_ostream<CharT, Traits> &
5866 to_stream(std::basic_ostream<CharT, Traits> &os, const CharT *fmt,
5867  const month_day &md)
5868 {
5869  using CT = std::chrono::seconds;
5870  fields<CT> fds{md / nanyear};
5871  return to_stream(os, fmt, fds);
5872 }
5873 
5874 template <class CharT, class Traits>
5875 inline
5876 std::basic_ostream<CharT, Traits> &
5877 to_stream(std::basic_ostream<CharT, Traits> &os, const CharT *fmt,
5878  const year_month_day &ymd)
5879 {
5880  using CT = std::chrono::seconds;
5881  fields<CT> fds{ymd};
5882  return to_stream(os, fmt, fds);
5883 }
5884 
5885 template <class CharT, class Traits, class Rep, class Period>
5886 inline
5887 std::basic_ostream<CharT, Traits> &
5888 to_stream(std::basic_ostream<CharT, Traits> &os, const CharT *fmt,
5889  const std::chrono::duration<Rep, Period> &d)
5890 {
5891  using Duration = std::chrono::duration<Rep, Period>;
5892  using CT = typename std::common_type<Duration, std::chrono::seconds>::type;
5893  fields<CT> fds{hh_mm_ss<CT>{d}};
5894  return to_stream(os, fmt, fds);
5895 }
5896 
5897 template <class CharT, class Traits, class Duration>
5898 std::basic_ostream<CharT, Traits> &
5899 to_stream(std::basic_ostream<CharT, Traits> &os, const CharT *fmt,
5900  const local_time<Duration> &tp, const std::string *abbrev = nullptr,
5901  const std::chrono::seconds *offset_sec = nullptr)
5902 {
5903  using CT = typename std::common_type<Duration, std::chrono::seconds>::type;
5904  auto ld = floor<days>(tp);
5906  return to_stream(os, fmt, fds, abbrev, offset_sec);
5907 }
5908 
5909 template <class CharT, class Traits, class Duration>
5910 std::basic_ostream<CharT, Traits> &
5911 to_stream(std::basic_ostream<CharT, Traits> &os, const CharT *fmt,
5912  const sys_time<Duration> &tp)
5913 {
5914  using std::chrono::seconds;
5915  using CT = typename std::common_type<Duration, seconds>::type;
5916  const std::string abbrev("UTC");
5917  CONSTDATA seconds offset{0};
5918  auto sd = floor<days>(tp);
5919  fields<CT> fds{year_month_day{sd}, hh_mm_ss<CT>{tp - sys_seconds{sd}}};
5920  return to_stream(os, fmt, fds, &abbrev, &offset);
5921 }
5922 
5923 // format
5924 
5925 template <class CharT, class Streamable>
5926 auto
5927 format(const std::locale &loc, const CharT *fmt, const Streamable &tp)
5928 -> decltype(to_stream(std::declval<std::basic_ostream<CharT>&>(), fmt, tp),
5929 std::basic_string<CharT> {})
5930 {
5931  std::basic_ostringstream<CharT> os;
5932  os.exceptions(std::ios::failbit | std::ios::badbit);
5933  os.imbue(loc);
5934  to_stream(os, fmt, tp);
5935  return os.str();
5936 }
5937 
5938 template <class CharT, class Streamable>
5939 auto
5940 format(const CharT *fmt, const Streamable &tp)
5941 -> decltype(to_stream(std::declval<std::basic_ostream<CharT>&>(), fmt, tp),
5942 std::basic_string<CharT> {})
5943 {
5944  std::basic_ostringstream<CharT> os;
5945  os.exceptions(std::ios::failbit | std::ios::badbit);
5946  to_stream(os, fmt, tp);
5947  return os.str();
5948 }
5949 
5950 template <class CharT, class Traits, class Alloc, class Streamable>
5951 auto
5952 format(const std::locale &loc,
5953  const std::basic_string<CharT, Traits, Alloc> &fmt,
5954  const Streamable &tp)
5955 -> decltype(to_stream(std::declval<std::basic_ostream<CharT, Traits>&>(),
5956  fmt.c_str(), tp),
5957 std::basic_string<CharT, Traits, Alloc> {})
5958 {
5959  std::basic_ostringstream<CharT, Traits, Alloc> os;
5960  os.exceptions(std::ios::failbit | std::ios::badbit);
5961  os.imbue(loc);
5962  to_stream(os, fmt.c_str(), tp);
5963  return os.str();
5964 }
5965 
5966 template <class CharT, class Traits, class Alloc, class Streamable>
5967 auto
5968 format(const std::basic_string<CharT, Traits, Alloc> &fmt, const Streamable &tp)
5969 -> decltype(to_stream(std::declval<std::basic_ostream<CharT, Traits>&>(),
5970  fmt.c_str(), tp),
5971 std::basic_string<CharT, Traits, Alloc> {})
5972 {
5973  std::basic_ostringstream<CharT, Traits, Alloc> os;
5974  os.exceptions(std::ios::failbit | std::ios::badbit);
5975  to_stream(os, fmt.c_str(), tp);
5976  return os.str();
5977 }
5978 
5979 // parse
5980 
5981 namespace detail {
5982 
5983 template <class CharT, class Traits>
5984 bool
5985 read_char(std::basic_istream<CharT, Traits> &is, CharT fmt,
5986  std::ios::iostate &err)
5987 {
5988  auto ic = is.get();
5989  if (Traits::eq_int_type(ic, Traits::eof()) ||
5990  !Traits::eq(Traits::to_char_type(ic), fmt)) {
5991  err |= std::ios::failbit;
5992  is.setstate(std::ios::failbit);
5993  return false;
5994  }
5995  return true;
5996 }
5997 
5998 template <class CharT, class Traits>
5999 unsigned
6000 read_unsigned(std::basic_istream<CharT, Traits> &is, unsigned m = 1,
6001  unsigned M = 10)
6002 {
6003  unsigned x = 0;
6004  unsigned count = 0;
6005  while (true) {
6006  auto ic = is.peek();
6007  if (Traits::eq_int_type(ic, Traits::eof())) {
6008  break;
6009  }
6010  auto c = static_cast<char>(Traits::to_char_type(ic));
6011  if (!('0' <= c && c <= '9')) {
6012  break;
6013  }
6014  (void)is.get();
6015  ++count;
6016  x = 10 * x + static_cast<unsigned>(c - '0');
6017  if (count == M) {
6018  break;
6019  }
6020  }
6021  if (count < m) {
6022  is.setstate(std::ios::failbit);
6023  }
6024  return x;
6025 }
6026 
6027 template <class CharT, class Traits>
6028 int
6029 read_signed(std::basic_istream<CharT, Traits> &is, unsigned m = 1,
6030  unsigned M = 10)
6031 {
6032  auto ic = is.peek();
6033  if (!Traits::eq_int_type(ic, Traits::eof())) {
6034  auto c = static_cast<char>(Traits::to_char_type(ic));
6035  if (('0' <= c && c <= '9') || c == '-' || c == '+') {
6036  if (c == '-' || c == '+') {
6037  (void)is.get();
6038  }
6039  auto x = static_cast<int>(read_unsigned(is, std::max(m, 1u), M));
6040  if (!is.fail()) {
6041  if (c == '-') {
6042  x = -x;
6043  }
6044  return x;
6045  }
6046  }
6047  }
6048  if (m > 0) {
6049  is.setstate(std::ios::failbit);
6050  }
6051  return 0;
6052 }
6053 
6054 template <class CharT, class Traits>
6055 long double
6056 read_long_double(std::basic_istream<CharT, Traits> &is, unsigned m = 1,
6057  unsigned M = 10)
6058 {
6059  unsigned count = 0;
6060  auto decimal_point = Traits::to_int_type(
6061  std::use_facet<std::numpunct<CharT>>(is.getloc()).decimal_point());
6062  std::string buf;
6063  while (true) {
6064  auto ic = is.peek();
6065  if (Traits::eq_int_type(ic, Traits::eof())) {
6066  break;
6067  }
6068  if (Traits::eq_int_type(ic, decimal_point)) {
6069  buf += '.';
6070  decimal_point = Traits::eof();
6071  is.get();
6072  }
6073  else {
6074  auto c = static_cast<char>(Traits::to_char_type(ic));
6075  if (!('0' <= c && c <= '9')) {
6076  break;
6077  }
6078  buf += c;
6079  (void)is.get();
6080  }
6081  if (++count == M) {
6082  break;
6083  }
6084  }
6085  if (count < m) {
6086  is.setstate(std::ios::failbit);
6087  return 0;
6088  }
6089  return std::stold(buf);
6090 }
6091 
6092 struct rs {
6093  int &i;
6094  unsigned m;
6095  unsigned M;
6096 };
6097 
6098 struct ru {
6099  int &i;
6100  unsigned m;
6101  unsigned M;
6102 };
6103 
6104 struct rld {
6105  long double &i;
6106  unsigned m;
6107  unsigned M;
6108 };
6109 
6110 template <class CharT, class Traits>
6111 void
6112 read(std::basic_istream<CharT, Traits> &)
6113 {
6114 }
6115 
6116 template <class CharT, class Traits, class ...Args>
6117 void
6118 read(std::basic_istream<CharT, Traits> &is, CharT a0, Args &&...args);
6119 
6120 template <class CharT, class Traits, class ...Args>
6121 void
6122 read(std::basic_istream<CharT, Traits> &is, rs a0, Args &&...args);
6123 
6124 template <class CharT, class Traits, class ...Args>
6125 void
6126 read(std::basic_istream<CharT, Traits> &is, ru a0, Args &&...args);
6127 
6128 template <class CharT, class Traits, class ...Args>
6129 void
6130 read(std::basic_istream<CharT, Traits> &is, int a0, Args &&...args);
6131 
6132 template <class CharT, class Traits, class ...Args>
6133 void
6134 read(std::basic_istream<CharT, Traits> &is, rld a0, Args &&...args);
6135 
6136 template <class CharT, class Traits, class ...Args>
6137 void
6138 read(std::basic_istream<CharT, Traits> &is, CharT a0, Args &&...args)
6139 {
6140  // No-op if a0 == CharT{}
6141  if (a0 != CharT{}) {
6142  auto ic = is.peek();
6143  if (Traits::eq_int_type(ic, Traits::eof())) {
6144  is.setstate(std::ios::failbit | std::ios::eofbit);
6145  return;
6146  }
6147  if (!Traits::eq(Traits::to_char_type(ic), a0)) {
6148  is.setstate(std::ios::failbit);
6149  return;
6150  }
6151  (void)is.get();
6152  }
6153  read(is, std::forward<Args>(args)...);
6154 }
6155 
6156 template <class CharT, class Traits, class ...Args>
6157 void
6158 read(std::basic_istream<CharT, Traits> &is, rs a0, Args &&...args)
6159 {
6160  auto x = read_signed(is, a0.m, a0.M);
6161  if (is.fail()) {
6162  return;
6163  }
6164  a0.i = x;
6165  read(is, std::forward<Args>(args)...);
6166 }
6167 
6168 template <class CharT, class Traits, class ...Args>
6169 void
6170 read(std::basic_istream<CharT, Traits> &is, ru a0, Args &&...args)
6171 {
6172  auto x = read_unsigned(is, a0.m, a0.M);
6173  if (is.fail()) {
6174  return;
6175  }
6176  a0.i = static_cast<int>(x);
6177  read(is, std::forward<Args>(args)...);
6178 }
6179 
6180 template <class CharT, class Traits, class ...Args>
6181 void
6182 read(std::basic_istream<CharT, Traits> &is, int a0, Args &&...args)
6183 {
6184  if (a0 != -1) {
6185  auto u = static_cast<unsigned>(a0);
6186  CharT buf[std::numeric_limits<unsigned>::digits10 + 2] = {};
6187  auto e = buf;
6188  do {
6189  *e++ = static_cast<CharT>(CharT(u % 10) + CharT{'0'});
6190  u /= 10;
6191  }
6192  while (u > 0);
6193  std::reverse(buf, e);
6194  for (auto p = buf; p != e && is.rdstate() == std::ios::goodbit; ++p) {
6195  read(is, *p);
6196  }
6197  }
6198  if (is.rdstate() == std::ios::goodbit) {
6199  read(is, std::forward<Args>(args)...);
6200  }
6201 }
6202 
6203 template <class CharT, class Traits, class ...Args>
6204 void
6205 read(std::basic_istream<CharT, Traits> &is, rld a0, Args &&...args)
6206 {
6207  auto x = read_long_double(is, a0.m, a0.M);
6208  if (is.fail()) {
6209  return;
6210  }
6211  a0.i = x;
6212  read(is, std::forward<Args>(args)...);
6213 }
6214 
6215 template <class T, class CharT, class Traits>
6216 inline
6217 void
6218 checked_set(T &value, T from, T not_a_value, std::basic_ios<CharT, Traits> &is)
6219 {
6220  if (!is.fail()) {
6221  if (value == not_a_value) {
6222  value = std::move(from);
6223  }
6224  else if (value != from) {
6225  is.setstate(std::ios::failbit);
6226  }
6227  }
6228 }
6229 
6230 } // namespace detail;
6231 
6232 template <class CharT, class Traits, class Duration, class Alloc = std::allocator<CharT>>
6233 std::basic_istream<CharT, Traits> &
6234 from_stream(std::basic_istream<CharT, Traits> &is, const CharT *fmt,
6235  fields<Duration> &fds, std::basic_string<CharT, Traits, Alloc> *abbrev,
6236  std::chrono::minutes *offset)
6237 {
6238  using std::numeric_limits;
6239  using std::ios;
6240  using std::chrono::duration;
6241  using std::chrono::duration_cast;
6242  using std::chrono::seconds;
6243  using std::chrono::minutes;
6244  using std::chrono::hours;
6245  typename std::basic_istream<CharT, Traits>::sentry ok{is, true};
6246  if (ok) {
6248  is.fill(' ');
6249  is.flags(std::ios::skipws | std::ios::dec);
6250  is.width(0);
6251 #if !ONLY_C_LOCALE
6252  auto &f = std::use_facet<std::time_get<CharT>>(is.getloc());
6253  std::tm tm{};
6254 #endif
6255  const CharT *command = nullptr;
6256  auto modified = CharT{};
6257  auto width = -1;
6258 
6259  CONSTDATA int not_a_year = numeric_limits<int>::min();
6260  CONSTDATA int not_a_2digit_year = 100;
6261  CONSTDATA int not_a_century = not_a_year / 100;
6262  CONSTDATA int not_a_month = 0;
6263  CONSTDATA int not_a_day = 0;
6264  CONSTDATA int not_a_hour = numeric_limits<int>::min();
6265  CONSTDATA int not_a_hour_12_value = 0;
6266  CONSTDATA int not_a_minute = not_a_hour;
6267  CONSTDATA Duration not_a_second = Duration::min();
6268  CONSTDATA int not_a_doy = -1;
6269  CONSTDATA int not_a_weekday = 8;
6270  CONSTDATA int not_a_week_num = 100;
6271  CONSTDATA int not_a_ampm = -1;
6272  CONSTDATA minutes not_a_offset = minutes::min();
6273 
6274  int Y = not_a_year; // c, F, Y *
6275  int y = not_a_2digit_year; // D, x, y *
6276  int g = not_a_2digit_year; // g *
6277  int G = not_a_year; // G *
6278  int C = not_a_century; // C *
6279  int m = not_a_month; // b, B, h, m, c, D, F, x *
6280  int d = not_a_day; // c, d, D, e, F, x *
6281  int j = not_a_doy; // j *
6282  int wd = not_a_weekday; // a, A, u, w *
6283  int H = not_a_hour; // c, H, R, T, X *
6284  int I = not_a_hour_12_value; // I, r *
6285  int p = not_a_ampm; // p, r *
6286  int M = not_a_minute; // c, M, r, R, T, X *
6287  Duration s = not_a_second; // c, r, S, T, X *
6288  int U = not_a_week_num; // U *
6289  int V = not_a_week_num; // V *
6290  int W = not_a_week_num; // W *
6291  std::basic_string<CharT, Traits, Alloc> temp_abbrev; // Z *
6292  minutes temp_offset = not_a_offset; // z *
6293 
6294  using detail::read;
6295  using detail::rs;
6296  using detail::ru;
6297  using detail::rld;
6298  using detail::checked_set;
6299  for (; *fmt != CharT{} && !is.fail(); ++fmt) {
6300  switch (*fmt) {
6301  case 'a':
6302  case 'A':
6303  case 'u':
6304  case 'w': // wd: a, A, u, w
6305  if (command) {
6306  int trial_wd = not_a_weekday;
6307  if (*fmt == 'a' || *fmt == 'A') {
6308  if (modified == CharT{}) {
6309 #if !ONLY_C_LOCALE
6310  ios::iostate err = ios::goodbit;
6311  f.get(is, nullptr, is, err, &tm, command, fmt + 1);
6312  is.setstate(err);
6313  if (!is.fail()) {
6314  trial_wd = tm.tm_wday;
6315  }
6316 #else
6317  auto nm = detail::weekday_names();
6318  auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6319  if (!is.fail()) {
6320  trial_wd = i % 7;
6321  }
6322 #endif
6323  }
6324  else
6325  read(is, CharT{'%'}, width, modified, *fmt);
6326  }
6327  else { // *fmt == 'u' || *fmt == 'w'
6328 #if !ONLY_C_LOCALE
6329  if (modified == CharT {})
6330 #else
6331  if (modified != CharT {'E'})
6332 #endif
6333  {
6334  read(is, ru{trial_wd, 1, width == -1 ?
6335  1u : static_cast<unsigned>(width)});
6336  if (!is.fail()) {
6337  if (*fmt == 'u') {
6338  if (!(1 <= trial_wd && trial_wd <= 7)) {
6339  trial_wd = not_a_weekday;
6340  is.setstate(ios::failbit);
6341  }
6342  else if (trial_wd == 7) {
6343  trial_wd = 0;
6344  }
6345  }
6346  else { // *fmt == 'w'
6347  if (!(0 <= trial_wd && trial_wd <= 6)) {
6348  trial_wd = not_a_weekday;
6349  is.setstate(ios::failbit);
6350  }
6351  }
6352  }
6353  }
6354 #if !ONLY_C_LOCALE
6355  else if (modified == CharT {'O'}) {
6356  ios::iostate err = ios::goodbit;
6357  f.get(is, nullptr, is, err, &tm, command, fmt + 1);
6358  is.setstate(err);
6359  if (!is.fail()) {
6360  trial_wd = tm.tm_wday;
6361  }
6362  }
6363 #endif
6364  else
6365  read(is, CharT{'%'}, width, modified, *fmt);
6366  }
6367  if (trial_wd != not_a_weekday) {
6368  checked_set(wd, trial_wd, not_a_weekday, is);
6369  }
6370  }
6371  else { // !command
6372  read(is, *fmt);
6373  }
6374  command = nullptr;
6375  width = -1;
6376  modified = CharT{};
6377  break;
6378  case 'b':
6379  case 'B':
6380  case 'h':
6381  if (command) {
6382  if (modified == CharT{}) {
6383  int ttm = not_a_month;
6384 #if !ONLY_C_LOCALE
6385  ios::iostate err = ios::goodbit;
6386  f.get(is, nullptr, is, err, &tm, command, fmt + 1);
6387  if ((err & ios::failbit) == 0) {
6388  ttm = tm.tm_mon + 1;
6389  }
6390  is.setstate(err);
6391 #else
6392  auto nm = detail::month_names();
6393  auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6394  if (!is.fail()) {
6395  ttm = i % 12 + 1;
6396  }
6397 #endif
6398  checked_set(m, ttm, not_a_month, is);
6399  }
6400  else
6401  read(is, CharT{'%'}, width, modified, *fmt);
6402  command = nullptr;
6403  width = -1;
6404  modified = CharT{};
6405  }
6406  else {
6407  read(is, *fmt);
6408  }
6409  break;
6410  case 'c':
6411  if (command) {
6412  if (modified != CharT{'O'}) {
6413 #if !ONLY_C_LOCALE
6414  ios::iostate err = ios::goodbit;
6415  f.get(is, nullptr, is, err, &tm, command, fmt + 1);
6416  if ((err & ios::failbit) == 0) {
6417  checked_set(Y, tm.tm_year + 1900, not_a_year, is);
6418  checked_set(m, tm.tm_mon + 1, not_a_month, is);
6419  checked_set(d, tm.tm_mday, not_a_day, is);
6420  checked_set(H, tm.tm_hour, not_a_hour, is);
6421  checked_set(M, tm.tm_min, not_a_minute, is);
6422  checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}),
6423  not_a_second, is);
6424  }
6425  is.setstate(err);
6426 #else
6427  // "%a %b %e %T %Y"
6428  auto nm = detail::weekday_names();
6429  auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6430  checked_set(wd, static_cast<int>(i % 7), not_a_weekday, is);
6431  ws(is);
6432  nm = detail::month_names();
6433  i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6434  checked_set(m, static_cast<int>(i % 12 + 1), not_a_month, is);
6435  ws(is);
6436  int td = not_a_day;
6437  read(is, rs{td, 1, 2});
6438  checked_set(d, td, not_a_day, is);
6439  ws(is);
6441  CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
6442  int tH;
6443  int tM;
6444  long double S;
6445  read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2},
6446  CharT{':'}, rld{S, 1, w});
6447  checked_set(H, tH, not_a_hour, is);
6448  checked_set(M, tM, not_a_minute, is);
6449  checked_set(s, round<Duration>(duration<long double> {S}),
6450  not_a_second, is);
6451  ws(is);
6452  int tY = not_a_year;
6453  read(is, rs{tY, 1, 4u});
6454  checked_set(Y, tY, not_a_year, is);
6455 #endif
6456  }
6457  else
6458  read(is, CharT{'%'}, width, modified, *fmt);
6459  command = nullptr;
6460  width = -1;
6461  modified = CharT{};
6462  }
6463  else {
6464  read(is, *fmt);
6465  }
6466  break;
6467  case 'x':
6468  if (command) {
6469  if (modified != CharT{'O'}) {
6470 #if !ONLY_C_LOCALE
6471  ios::iostate err = ios::goodbit;
6472  f.get(is, nullptr, is, err, &tm, command, fmt + 1);
6473  if ((err & ios::failbit) == 0) {
6474  checked_set(Y, tm.tm_year + 1900, not_a_year, is);
6475  checked_set(m, tm.tm_mon + 1, not_a_month, is);
6476  checked_set(d, tm.tm_mday, not_a_day, is);
6477  }
6478  is.setstate(err);
6479 #else
6480  // "%m/%d/%y"
6481  int ty = not_a_2digit_year;
6482  int tm = not_a_month;
6483  int td = not_a_day;
6484  read(is, ru{tm, 1, 2}, CharT{'/'}, ru{td, 1, 2}, CharT{'/'},
6485  rs{ty, 1, 2});
6486  checked_set(y, ty, not_a_2digit_year, is);
6487  checked_set(m, tm, not_a_month, is);
6488  checked_set(d, td, not_a_day, is);
6489 #endif
6490  }
6491  else
6492  read(is, CharT{'%'}, width, modified, *fmt);
6493  command = nullptr;
6494  width = -1;
6495  modified = CharT{};
6496  }
6497  else {
6498  read(is, *fmt);
6499  }
6500  break;
6501  case 'X':
6502  if (command) {
6503  if (modified != CharT{'O'}) {
6504 #if !ONLY_C_LOCALE
6505  ios::iostate err = ios::goodbit;
6506  f.get(is, nullptr, is, err, &tm, command, fmt + 1);
6507  if ((err & ios::failbit) == 0) {
6508  checked_set(H, tm.tm_hour, not_a_hour, is);
6509  checked_set(M, tm.tm_min, not_a_minute, is);
6510  checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}),
6511  not_a_second, is);
6512  }
6513  is.setstate(err);
6514 #else
6515  // "%T"
6517  CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
6518  int tH = not_a_hour;
6519  int tM = not_a_minute;
6520  long double S;
6521  read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2},
6522  CharT{':'}, rld{S, 1, w});
6523  checked_set(H, tH, not_a_hour, is);
6524  checked_set(M, tM, not_a_minute, is);
6525  checked_set(s, round<Duration>(duration<long double> {S}),
6526  not_a_second, is);
6527 #endif
6528  }
6529  else
6530  read(is, CharT{'%'}, width, modified, *fmt);
6531  command = nullptr;
6532  width = -1;
6533  modified = CharT{};
6534  }
6535  else {
6536  read(is, *fmt);
6537  }
6538  break;
6539  case 'C':
6540  if (command) {
6541  int tC = not_a_century;
6542 #if !ONLY_C_LOCALE
6543  if (modified == CharT {}) {
6544 #endif
6545  read(is, rs {tC, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
6546 #if !ONLY_C_LOCALE
6547  }
6548  else {
6549  ios::iostate err = ios::goodbit;
6550  f.get(is, nullptr, is, err, &tm, command, fmt + 1);
6551  if ((err & ios::failbit) == 0) {
6552  auto tY = tm.tm_year + 1900;
6553  tC = (tY >= 0 ? tY : tY - 99) / 100;
6554  }
6555  is.setstate(err);
6556  }
6557 #endif
6558  checked_set(C, tC, not_a_century, is);
6559  command = nullptr;
6560  width = -1;
6561  modified = CharT{};
6562  }
6563  else {
6564  read(is, *fmt);
6565  }
6566  break;
6567  case 'D':
6568  if (command) {
6569  if (modified == CharT{}) {
6570  int tn = not_a_month;
6571  int td = not_a_day;
6572  int ty = not_a_2digit_year;
6573  read(is, ru{tn, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'},
6574  ru{td, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'},
6575  rs{ty, 1, 2});
6576  checked_set(y, ty, not_a_2digit_year, is);
6577  checked_set(m, tn, not_a_month, is);
6578  checked_set(d, td, not_a_day, is);
6579  }
6580  else
6581  read(is, CharT{'%'}, width, modified, *fmt);
6582  command = nullptr;
6583  width = -1;
6584  modified = CharT{};
6585  }
6586  else {
6587  read(is, *fmt);
6588  }
6589  break;
6590  case 'F':
6591  if (command) {
6592  if (modified == CharT{}) {
6593  int tY = not_a_year;
6594  int tn = not_a_month;
6595  int td = not_a_day;
6596  read(is, rs{tY, 1, width == -1 ? 4u : static_cast<unsigned>(width)},
6597  CharT{'-'}, ru{tn, 1, 2}, CharT{'-'}, ru{td, 1, 2});
6598  checked_set(Y, tY, not_a_year, is);
6599  checked_set(m, tn, not_a_month, is);
6600  checked_set(d, td, not_a_day, is);
6601  }
6602  else
6603  read(is, CharT{'%'}, width, modified, *fmt);
6604  command = nullptr;
6605  width = -1;
6606  modified = CharT{};
6607  }
6608  else {
6609  read(is, *fmt);
6610  }
6611  break;
6612  case 'd':
6613  case 'e':
6614  if (command) {
6615 #if !ONLY_C_LOCALE
6616  if (modified == CharT {})
6617 #else
6618  if (modified != CharT {'E'})
6619 #endif
6620  {
6621  int td = not_a_day;
6622  read(is, rs{td, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
6623  checked_set(d, td, not_a_day, is);
6624  }
6625 #if !ONLY_C_LOCALE
6626  else if (modified == CharT {'O'}) {
6627  ios::iostate err = ios::goodbit;
6628  f.get(is, nullptr, is, err, &tm, command, fmt + 1);
6629  command = nullptr;
6630  width = -1;
6631  modified = CharT{};
6632  if ((err & ios::failbit) == 0) {
6633  checked_set(d, tm.tm_mday, not_a_day, is);
6634  }
6635  is.setstate(err);
6636  }
6637 #endif
6638  else
6639  read(is, CharT{'%'}, width, modified, *fmt);
6640  command = nullptr;
6641  width = -1;
6642  modified = CharT{};
6643  }
6644  else {
6645  read(is, *fmt);
6646  }
6647  break;
6648  case 'H':
6649  if (command) {
6650 #if !ONLY_C_LOCALE
6651  if (modified == CharT {})
6652 #else
6653  if (modified != CharT {'E'})
6654 #endif
6655  {
6656  int tH = not_a_hour;
6657  read(is, ru{tH, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
6658  checked_set(H, tH, not_a_hour, is);
6659  }
6660 #if !ONLY_C_LOCALE
6661  else if (modified == CharT {'O'}) {
6662  ios::iostate err = ios::goodbit;
6663  f.get(is, nullptr, is, err, &tm, command, fmt + 1);
6664  if ((err & ios::failbit) == 0) {
6665  checked_set(H, tm.tm_hour, not_a_hour, is);
6666  }
6667  is.setstate(err);
6668  }
6669 #endif
6670  else
6671  read(is, CharT{'%'}, width, modified, *fmt);
6672  command = nullptr;
6673  width = -1;
6674  modified = CharT{};
6675  }
6676  else {
6677  read(is, *fmt);
6678  }
6679  break;
6680  case 'I':
6681  if (command) {
6682  if (modified == CharT{}) {
6683  int tI = not_a_hour_12_value;
6684  // reads in an hour into I, but most be in [1, 12]
6685  read(is, rs{tI, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
6686  if (!(1 <= tI && tI <= 12)) {
6687  is.setstate(ios::failbit);
6688  }
6689  checked_set(I, tI, not_a_hour_12_value, is);
6690  }
6691  else
6692  read(is, CharT{'%'}, width, modified, *fmt);
6693  command = nullptr;
6694  width = -1;
6695  modified = CharT{};
6696  }
6697  else {
6698  read(is, *fmt);
6699  }
6700  break;
6701  case 'j':
6702  if (command) {
6703  if (modified == CharT{}) {
6704  int tj = not_a_doy;
6705  read(is, ru{tj, 1, width == -1 ? 3u : static_cast<unsigned>(width)});
6706  checked_set(j, tj, not_a_doy, is);
6707  }
6708  else
6709  read(is, CharT{'%'}, width, modified, *fmt);
6710  command = nullptr;
6711  width = -1;
6712  modified = CharT{};
6713  }
6714  else {
6715  read(is, *fmt);
6716  }
6717  break;
6718  case 'M':
6719  if (command) {
6720 #if !ONLY_C_LOCALE
6721  if (modified == CharT {})
6722 #else
6723  if (modified != CharT {'E'})
6724 #endif
6725  {
6726  int tM = not_a_minute;
6727  read(is, ru{tM, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
6728  checked_set(M, tM, not_a_minute, is);
6729  }
6730 #if !ONLY_C_LOCALE
6731  else if (modified == CharT {'O'}) {
6732  ios::iostate err = ios::goodbit;
6733  f.get(is, nullptr, is, err, &tm, command, fmt + 1);
6734  if ((err & ios::failbit) == 0) {
6735  checked_set(M, tm.tm_min, not_a_minute, is);
6736  }
6737  is.setstate(err);
6738  }
6739 #endif
6740  else
6741  read(is, CharT{'%'}, width, modified, *fmt);
6742  command = nullptr;
6743  width = -1;
6744  modified = CharT{};
6745  }
6746  else {
6747  read(is, *fmt);
6748  }
6749  break;
6750  case 'm':
6751  if (command) {
6752 #if !ONLY_C_LOCALE
6753  if (modified == CharT {})
6754 #else
6755  if (modified != CharT {'E'})
6756 #endif
6757  {
6758  int tn = not_a_month;
6759  read(is, rs{tn, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
6760  checked_set(m, tn, not_a_month, is);
6761  }
6762 #if !ONLY_C_LOCALE
6763  else if (modified == CharT {'O'}) {
6764  ios::iostate err = ios::goodbit;
6765  f.get(is, nullptr, is, err, &tm, command, fmt + 1);
6766  if ((err & ios::failbit) == 0) {
6767  checked_set(m, tm.tm_mon + 1, not_a_month, is);
6768  }
6769  is.setstate(err);
6770  }
6771 #endif
6772  else
6773  read(is, CharT{'%'}, width, modified, *fmt);
6774  command = nullptr;
6775  width = -1;
6776  modified = CharT{};
6777  }
6778  else {
6779  read(is, *fmt);
6780  }
6781  break;
6782  case 'n':
6783  case 't':
6784  if (command) {
6785  if (modified == CharT{}) {
6786  // %n matches a single white space character
6787  // %t matches 0 or 1 white space characters
6788  auto ic = is.peek();
6789  if (Traits::eq_int_type(ic, Traits::eof())) {
6790  ios::iostate err = ios::eofbit;
6791  if (*fmt == 'n') {
6792  err |= ios::failbit;
6793  }
6794  is.setstate(err);
6795  break;
6796  }
6797  if (isspace(ic)) {
6798  (void)is.get();
6799  }
6800  else if (*fmt == 'n') {
6801  is.setstate(ios::failbit);
6802  }
6803  }
6804  else
6805  read(is, CharT{'%'}, width, modified, *fmt);
6806  command = nullptr;
6807  width = -1;
6808  modified = CharT{};
6809  }
6810  else {
6811  read(is, *fmt);
6812  }
6813  break;
6814  case 'p':
6815  if (command) {
6816  if (modified == CharT{}) {
6817  int tp = not_a_ampm;
6818 #if !ONLY_C_LOCALE
6819  tm = std::tm {};
6820  tm.tm_hour = 1;
6821  ios::iostate err = ios::goodbit;
6822  f.get(is, nullptr, is, err, &tm, command, fmt + 1);
6823  is.setstate(err);
6824  if (tm.tm_hour == 1) {
6825  tp = 0;
6826  }
6827  else if (tm.tm_hour == 13) {
6828  tp = 1;
6829  }
6830  else {
6831  is.setstate(err);
6832  }
6833 #else
6834  auto nm = detail::ampm_names();
6835  auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6836  tp = i;
6837 #endif
6838  checked_set(p, tp, not_a_ampm, is);
6839  }
6840  else
6841  read(is, CharT{'%'}, width, modified, *fmt);
6842  command = nullptr;
6843  width = -1;
6844  modified = CharT{};
6845  }
6846  else {
6847  read(is, *fmt);
6848  }
6849 
6850  break;
6851  case 'r':
6852  if (command) {
6853  if (modified == CharT{}) {
6854 #if !ONLY_C_LOCALE
6855  ios::iostate err = ios::goodbit;
6856  f.get(is, nullptr, is, err, &tm, command, fmt + 1);
6857  if ((err & ios::failbit) == 0) {
6858  checked_set(H, tm.tm_hour, not_a_hour, is);
6859  checked_set(M, tm.tm_min, not_a_hour, is);
6860  checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}),
6861  not_a_second, is);
6862  }
6863  is.setstate(err);
6864 #else
6865  // "%I:%M:%S %p"
6867  CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
6868  long double S;
6869  int tI = not_a_hour_12_value;
6870  int tM = not_a_minute;
6871  read(is, ru{tI, 1, 2}, CharT{':'}, ru{tM, 1, 2},
6872  CharT{':'}, rld{S, 1, w});
6873  checked_set(I, tI, not_a_hour_12_value, is);
6874  checked_set(M, tM, not_a_minute, is);
6875  checked_set(s, round<Duration>(duration<long double> {S}),
6876  not_a_second, is);
6877  ws(is);
6878  auto nm = detail::ampm_names();
6879  auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6880  checked_set(p, static_cast<int>(i), not_a_ampm, is);
6881 #endif
6882  }
6883  else
6884  read(is, CharT{'%'}, width, modified, *fmt);
6885  command = nullptr;
6886  width = -1;
6887  modified = CharT{};
6888  }
6889  else {
6890  read(is, *fmt);
6891  }
6892  break;
6893  case 'R':
6894  if (command) {
6895  if (modified == CharT{}) {
6896  int tH = not_a_hour;
6897  int tM = not_a_minute;
6898  read(is, ru{tH, 1, 2}, CharT{'\0'}, CharT{':'}, CharT{'\0'},
6899  ru{tM, 1, 2}, CharT{'\0'});
6900  checked_set(H, tH, not_a_hour, is);
6901  checked_set(M, tM, not_a_minute, is);
6902  }
6903  else
6904  read(is, CharT{'%'}, width, modified, *fmt);
6905  command = nullptr;
6906  width = -1;
6907  modified = CharT{};
6908  }
6909  else {
6910  read(is, *fmt);
6911  }
6912  break;
6913  case 'S':
6914  if (command) {
6915 #if !ONLY_C_LOCALE
6916  if (modified == CharT {})
6917 #else
6918  if (modified != CharT {'E'})
6919 #endif
6920  {
6922  CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
6923  long double S;
6924  read(is, rld{S, 1, width == -1 ? w : static_cast<unsigned>(width)});
6925  checked_set(s, round<Duration>(duration<long double> {S}),
6926  not_a_second, is);
6927  }
6928 #if !ONLY_C_LOCALE
6929  else if (modified == CharT {'O'}) {
6930  ios::iostate err = ios::goodbit;
6931  f.get(is, nullptr, is, err, &tm, command, fmt + 1);
6932  if ((err & ios::failbit) == 0)
6933  checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}),
6934  not_a_second, is);
6935  is.setstate(err);
6936  }
6937 #endif
6938  else
6939  read(is, CharT{'%'}, width, modified, *fmt);
6940  command = nullptr;
6941  width = -1;
6942  modified = CharT{};
6943  }
6944  else {
6945  read(is, *fmt);
6946  }
6947  break;
6948  case 'T':
6949  if (command) {
6950  if (modified == CharT{}) {
6952  CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
6953  int tH = not_a_hour;
6954  int tM = not_a_minute;
6955  long double S;
6956  read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2},
6957  CharT{':'}, rld{S, 1, w});
6958  checked_set(H, tH, not_a_hour, is);
6959  checked_set(M, tM, not_a_minute, is);
6960  checked_set(s, round<Duration>(duration<long double> {S}),
6961  not_a_second, is);
6962  }
6963  else
6964  read(is, CharT{'%'}, width, modified, *fmt);
6965  command = nullptr;
6966  width = -1;
6967  modified = CharT{};
6968  }
6969  else {
6970  read(is, *fmt);
6971  }
6972  break;
6973  case 'Y':
6974  if (command) {
6975 #if !ONLY_C_LOCALE
6976  if (modified == CharT {})
6977 #else
6978  if (modified != CharT {'O'})
6979 #endif
6980  {
6981  int tY = not_a_year;
6982  read(is, rs{tY, 1, width == -1 ? 4u : static_cast<unsigned>(width)});
6983  checked_set(Y, tY, not_a_year, is);
6984  }
6985 #if !ONLY_C_LOCALE
6986  else if (modified == CharT {'E'}) {
6987  ios::iostate err = ios::goodbit;
6988  f.get(is, nullptr, is, err, &tm, command, fmt + 1);
6989  if ((err & ios::failbit) == 0) {
6990  checked_set(Y, tm.tm_year + 1900, not_a_year, is);
6991  }
6992  is.setstate(err);
6993  }
6994 #endif
6995  else
6996  read(is, CharT{'%'}, width, modified, *fmt);
6997  command = nullptr;
6998  width = -1;
6999  modified = CharT{};
7000  }
7001  else {
7002  read(is, *fmt);
7003  }
7004  break;
7005  case 'y':
7006  if (command) {
7007 #if !ONLY_C_LOCALE
7008  if (modified == CharT {})
7009 #endif
7010  {
7011  int ty = not_a_2digit_year;
7012  read(is, ru{ty, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
7013  checked_set(y, ty, not_a_2digit_year, is);
7014  }
7015 #if !ONLY_C_LOCALE
7016  else {
7017  ios::iostate err = ios::goodbit;
7018  f.get(is, nullptr, is, err, &tm, command, fmt + 1);
7019  if ((err & ios::failbit) == 0) {
7020  checked_set(Y, tm.tm_year + 1900, not_a_year, is);
7021  }
7022  is.setstate(err);
7023  }
7024 #endif
7025  command = nullptr;
7026  width = -1;
7027  modified = CharT{};
7028  }
7029  else {
7030  read(is, *fmt);
7031  }
7032  break;
7033  case 'g':
7034  if (command) {
7035  if (modified == CharT{}) {
7036  int tg = not_a_2digit_year;
7037  read(is, ru{tg, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
7038  checked_set(g, tg, not_a_2digit_year, is);
7039  }
7040  else
7041  read(is, CharT{'%'}, width, modified, *fmt);
7042  command = nullptr;
7043  width = -1;
7044  modified = CharT{};
7045  }
7046  else {
7047  read(is, *fmt);
7048  }
7049  break;
7050  case 'G':
7051  if (command) {
7052  if (modified == CharT{}) {
7053  int tG = not_a_year;
7054  read(is, rs{tG, 1, width == -1 ? 4u : static_cast<unsigned>(width)});
7055  checked_set(G, tG, not_a_year, is);
7056  }
7057  else
7058  read(is, CharT{'%'}, width, modified, *fmt);
7059  command = nullptr;
7060  width = -1;
7061  modified = CharT{};
7062  }
7063  else {
7064  read(is, *fmt);
7065  }
7066  break;
7067  case 'U':
7068  if (command) {
7069  if (modified == CharT{}) {
7070  int tU = not_a_week_num;
7071  read(is, ru{tU, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
7072  checked_set(U, tU, not_a_week_num, is);
7073  }
7074  else
7075  read(is, CharT{'%'}, width, modified, *fmt);
7076  command = nullptr;
7077  width = -1;
7078  modified = CharT{};
7079  }
7080  else {
7081  read(is, *fmt);
7082  }
7083  break;
7084  case 'V':
7085  if (command) {
7086  if (modified == CharT{}) {
7087  int tV = not_a_week_num;
7088  read(is, ru{tV, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
7089  checked_set(V, tV, not_a_week_num, is);
7090  }
7091  else
7092  read(is, CharT{'%'}, width, modified, *fmt);
7093  command = nullptr;
7094  width = -1;
7095  modified = CharT{};
7096  }
7097  else {
7098  read(is, *fmt);
7099  }
7100  break;
7101  case 'W':
7102  if (command) {
7103  if (modified == CharT{}) {
7104  int tW = not_a_week_num;
7105  read(is, ru{tW, 1, width == -1 ? 2u : static_cast<unsigned>(width)});
7106  checked_set(W, tW, not_a_week_num, is);
7107  }
7108  else
7109  read(is, CharT{'%'}, width, modified, *fmt);
7110  command = nullptr;
7111  width = -1;
7112  modified = CharT{};
7113  }
7114  else {
7115  read(is, *fmt);
7116  }
7117  break;
7118  case 'E':
7119  case 'O':
7120  if (command) {
7121  if (modified == CharT{}) {
7122  modified = *fmt;
7123  }
7124  else {
7125  read(is, CharT{'%'}, width, modified, *fmt);
7126  command = nullptr;
7127  width = -1;
7128  modified = CharT{};
7129  }
7130  }
7131  else {
7132  read(is, *fmt);
7133  }
7134  break;
7135  case '%':
7136  if (command) {
7137  if (modified == CharT{})
7138  read(is, *fmt);
7139  else
7140  read(is, CharT{'%'}, width, modified, *fmt);
7141  command = nullptr;
7142  width = -1;
7143  modified = CharT{};
7144  }
7145  else {
7146  command = fmt;
7147  }
7148  break;
7149  case 'z':
7150  if (command) {
7151  int tH, tM;
7152  minutes toff = not_a_offset;
7153  bool neg = false;
7154  auto ic = is.peek();
7155  if (!Traits::eq_int_type(ic, Traits::eof())) {
7156  auto c = static_cast<char>(Traits::to_char_type(ic));
7157  if (c == '-') {
7158  neg = true;
7159  }
7160  }
7161  if (modified == CharT{}) {
7162  read(is, rs{tH, 2, 2});
7163  if (!is.fail())
7164  toff = hours{std::abs(tH)};
7165  if (is.good()) {
7166  ic = is.peek();
7167  if (!Traits::eq_int_type(ic, Traits::eof())) {
7168  auto c = static_cast<char>(Traits::to_char_type(ic));
7169  if ('0' <= c && c <= '9') {
7170  read(is, ru{tM, 2, 2});
7171  if (!is.fail())
7172  toff += minutes{tM};
7173  }
7174  }
7175  }
7176  }
7177  else {
7178  read(is, rs{tH, 1, 2});
7179  if (!is.fail())
7180  toff = hours{std::abs(tH)};
7181  if (is.good()) {
7182  ic = is.peek();
7183  if (!Traits::eq_int_type(ic, Traits::eof())) {
7184  auto c = static_cast<char>(Traits::to_char_type(ic));
7185  if (c == ':') {
7186  (void)is.get();
7187  read(is, ru{tM, 2, 2});
7188  if (!is.fail())
7189  toff += minutes{tM};
7190  }
7191  }
7192  }
7193  }
7194  if (neg) {
7195  toff = -toff;
7196  }
7197  checked_set(temp_offset, toff, not_a_offset, is);
7198  command = nullptr;
7199  width = -1;
7200  modified = CharT{};
7201  }
7202  else {
7203  read(is, *fmt);
7204  }
7205  break;
7206  case 'Z':
7207  if (command) {
7208  if (modified == CharT{}) {
7209  std::basic_string<CharT, Traits, Alloc> buf;
7210  while (is.rdstate() == std::ios::goodbit) {
7211  auto i = is.rdbuf()->sgetc();
7212  if (Traits::eq_int_type(i, Traits::eof())) {
7213  is.setstate(ios::eofbit);
7214  break;
7215  }
7216  auto wc = Traits::to_char_type(i);
7217  auto c = static_cast<char>(wc);
7218  // is c a valid time zone name or abbreviation character?
7219  if (!(CharT{1} < wc && wc < CharT{127}) || !(isalnum(c) ||
7220  c == '_' || c == '/' || c == '-' || c == '+'))
7221  break;
7222  buf.push_back(c);
7223  is.rdbuf()->sbumpc();
7224  }
7225  if (buf.empty()) {
7226  is.setstate(ios::failbit);
7227  }
7228  checked_set(temp_abbrev, buf, {}, is);
7229  }
7230  else
7231  read(is, CharT{'%'}, width, modified, *fmt);
7232  command = nullptr;
7233  width = -1;
7234  modified = CharT{};
7235  }
7236  else {
7237  read(is, *fmt);
7238  }
7239  break;
7240  default:
7241  if (command) {
7242  if (width == -1 && modified == CharT{} && '0' <= *fmt && *fmt <= '9') {
7243  width = static_cast<char>(*fmt) - '0';
7244  while ('0' <= fmt[1] && fmt[1] <= '9') {
7245  width = 10 * width + static_cast<char>(*++fmt) - '0';
7246  }
7247  }
7248  else {
7249  if (modified == CharT{})
7250  read(is, CharT{'%'}, width, *fmt);
7251  else
7252  read(is, CharT{'%'}, width, modified, *fmt);
7253  command = nullptr;
7254  width = -1;
7255  modified = CharT{};
7256  }
7257  }
7258  else { // !command
7259  if (isspace(static_cast<unsigned char>(*fmt))) {
7260  // space matches 0 or more white space characters
7261  if (is.good()) {
7262  ws(is);
7263  }
7264  }
7265  else {
7266  read(is, *fmt);
7267  }
7268  }
7269  break;
7270  }
7271  }
7272  // is.fail() || *fmt == CharT{}
7273  if (is.rdstate() == ios::goodbit && command) {
7274  if (modified == CharT{})
7275  read(is, CharT{'%'}, width);
7276  else
7277  read(is, CharT{'%'}, width, modified);
7278  }
7279  if (!is.fail()) {
7280  if (y != not_a_2digit_year) {
7281  // Convert y and an optional C to Y
7282  if (!(0 <= y && y <= 99)) {
7283  goto broken;
7284  }
7285  if (C == not_a_century) {
7286  if (Y == not_a_year) {
7287  if (y >= 69) {
7288  C = 19;
7289  }
7290  else {
7291  C = 20;
7292  }
7293  }
7294  else {
7295  C = (Y >= 0 ? Y : Y - 100) / 100;
7296  }
7297  }
7298  int tY;
7299  if (C >= 0) {
7300  tY = 100 * C + y;
7301  }
7302  else {
7303  tY = 100 * (C + 1) - (y == 0 ? 100 : y);
7304  }
7305  if (Y != not_a_year && Y != tY) {
7306  goto broken;
7307  }
7308  Y = tY;
7309  }
7310  if (g != not_a_2digit_year) {
7311  // Convert g and an optional C to G
7312  if (!(0 <= g && g <= 99)) {
7313  goto broken;
7314  }
7315  if (C == not_a_century) {
7316  if (G == not_a_year) {
7317  if (g >= 69) {
7318  C = 19;
7319  }
7320  else {
7321  C = 20;
7322  }
7323  }
7324  else {
7325  C = (G >= 0 ? G : G - 100) / 100;
7326  }
7327  }
7328  int tG;
7329  if (C >= 0) {
7330  tG = 100 * C + g;
7331  }
7332  else {
7333  tG = 100 * (C + 1) - (g == 0 ? 100 : g);
7334  }
7335  if (G != not_a_year && G != tG) {
7336  goto broken;
7337  }
7338  G = tG;
7339  }
7340  if (Y < static_cast<int>(year::min()) || Y > static_cast<int>(year::max())) {
7341  Y = not_a_year;
7342  }
7343  bool computed = false;
7344  if (G != not_a_year && V != not_a_week_num && wd != not_a_weekday) {
7345  year_month_day ymd_trial = sys_days(year{G - 1} / December / Thursday[last]) +
7346  (Monday - Thursday) + weeks{V - 1} +
7347  (weekday{static_cast<unsigned>(wd)} -Monday);
7348  if (Y == not_a_year) {
7349  Y = static_cast<int>(ymd_trial.year());
7350  }
7351  else if (year{Y} != ymd_trial.year())
7352  goto broken;
7353  if (m == not_a_month) {
7354  m = static_cast<int>(static_cast<unsigned>(ymd_trial.month()));
7355  }
7356  else if (month(static_cast<unsigned>(m)) != ymd_trial.month()) {
7357  goto broken;
7358  }
7359  if (d == not_a_day) {
7360  d = static_cast<int>(static_cast<unsigned>(ymd_trial.day()));
7361  }
7362  else if (day(static_cast<unsigned>(d)) != ymd_trial.day()) {
7363  goto broken;
7364  }
7365  computed = true;
7366  }
7367  if (Y != not_a_year && U != not_a_week_num && wd != not_a_weekday) {
7368  year_month_day ymd_trial = sys_days(year{Y} / January / Sunday[1]) +
7369  weeks{U - 1} +
7370  (weekday{static_cast<unsigned>(wd)} - Sunday);
7371  if (Y == not_a_year) {
7372  Y = static_cast<int>(ymd_trial.year());
7373  }
7374  else if (year{Y} != ymd_trial.year())
7375  goto broken;
7376  if (m == not_a_month) {
7377  m = static_cast<int>(static_cast<unsigned>(ymd_trial.month()));
7378  }
7379  else if (month(static_cast<unsigned>(m)) != ymd_trial.month()) {
7380  goto broken;
7381  }
7382  if (d == not_a_day) {
7383  d = static_cast<int>(static_cast<unsigned>(ymd_trial.day()));
7384  }
7385  else if (day(static_cast<unsigned>(d)) != ymd_trial.day()) {
7386  goto broken;
7387  }
7388  computed = true;
7389  }
7390  if (Y != not_a_year && W != not_a_week_num && wd != not_a_weekday) {
7391  year_month_day ymd_trial = sys_days(year{Y} / January / Monday[1]) +
7392  weeks{W - 1} +
7393  (weekday{static_cast<unsigned>(wd)} - Monday);
7394  if (Y == not_a_year) {
7395  Y = static_cast<int>(ymd_trial.year());
7396  }
7397  else if (year{Y} != ymd_trial.year())
7398  goto broken;
7399  if (m == not_a_month) {
7400  m = static_cast<int>(static_cast<unsigned>(ymd_trial.month()));
7401  }
7402  else if (month(static_cast<unsigned>(m)) != ymd_trial.month()) {
7403  goto broken;
7404  }
7405  if (d == not_a_day) {
7406  d = static_cast<int>(static_cast<unsigned>(ymd_trial.day()));
7407  }
7408  else if (day(static_cast<unsigned>(d)) != ymd_trial.day()) {
7409  goto broken;
7410  }
7411  computed = true;
7412  }
7413  if (j != not_a_doy && Y != not_a_year) {
7414  auto ymd_trial = year_month_day{local_days(year{Y} / 1 / 1) + days{j - 1}};
7415  if (m == 0) {
7416  m = static_cast<int>(static_cast<unsigned>(ymd_trial.month()));
7417  }
7418  else if (month(static_cast<unsigned>(m)) != ymd_trial.month()) {
7419  goto broken;
7420  }
7421  if (d == 0) {
7422  d = static_cast<int>(static_cast<unsigned>(ymd_trial.day()));
7423  }
7424  else if (day(static_cast<unsigned>(d)) != ymd_trial.day()) {
7425  goto broken;
7426  }
7427  j = not_a_doy;
7428  }
7429  auto ymd = year{Y} / m / d;
7430  if (ymd.ok()) {
7431  if (wd == not_a_weekday) {
7432  wd = static_cast<int>((weekday(sys_days(ymd)) - Sunday).count());
7433  }
7434  else if (wd != static_cast<int>((weekday(sys_days(ymd)) - Sunday).count())) {
7435  goto broken;
7436  }
7437  if (!computed) {
7438  if (G != not_a_year || V != not_a_week_num) {
7439  sys_days sd = ymd;
7440  auto G_trial = year_month_day{sd + days{3}}.year();
7441  auto start = sys_days((G_trial - years{1}) / December / Thursday[last]) +
7442  (Monday - Thursday);
7443  if (sd < start) {
7444  --G_trial;
7445  if (V != not_a_week_num)
7446  start = sys_days((G_trial - years{1}) / December / Thursday[last])
7447  + (Monday - Thursday);
7448  }
7449  if (G != not_a_year && G != static_cast<int>(G_trial)) {
7450  goto broken;
7451  }
7452  if (V != not_a_week_num) {
7453  auto V_trial = duration_cast<weeks>(sd - start).count() + 1;
7454  if (V != V_trial) {
7455  goto broken;
7456  }
7457  }
7458  }
7459  if (U != not_a_week_num) {
7460  auto start = sys_days(Sunday[1] / January / ymd.year());
7461  auto U_trial = floor<weeks>(sys_days(ymd) - start).count() + 1;
7462  if (U != U_trial) {
7463  goto broken;
7464  }
7465  }
7466  if (W != not_a_week_num) {
7467  auto start = sys_days(Monday[1] / January / ymd.year());
7468  auto W_trial = floor<weeks>(sys_days(ymd) - start).count() + 1;
7469  if (W != W_trial) {
7470  goto broken;
7471  }
7472  }
7473  }
7474  }
7475  fds.ymd = ymd;
7476  if (I != not_a_hour_12_value) {
7477  if (!(1 <= I && I <= 12)) {
7478  goto broken;
7479  }
7480  if (p != not_a_ampm) {
7481  // p is in [0, 1] == [AM, PM]
7482  // Store trial H in I
7483  if (I == 12) {
7484  --p;
7485  }
7486  I += p * 12;
7487  // Either set H from I or make sure H and I are consistent
7488  if (H == not_a_hour) {
7489  H = I;
7490  }
7491  else if (I != H) {
7492  goto broken;
7493  }
7494  }
7495  else { // p == not_a_ampm
7496  // if H, make sure H and I could be consistent
7497  if (H != not_a_hour) {
7498  if (I == 12) {
7499  if (H != 0 && H != 12) {
7500  goto broken;
7501  }
7502  }
7503  else if (!(I == H || I == H + 12)) {
7504  goto broken;
7505  }
7506  }
7507  }
7508  }
7509  if (H != not_a_hour) {
7510  fds.has_tod = true;
7511  fds.tod = hh_mm_ss<Duration> {hours{H}};
7512  }
7513  if (M != not_a_minute) {
7514  fds.has_tod = true;
7515  fds.tod.m_ = minutes{M};
7516  }
7517  if (s != not_a_second) {
7518  fds.has_tod = true;
7520  }
7521  if (j != not_a_doy) {
7522  fds.has_tod = true;
7523  fds.tod.h_ += hours{days{j}};
7524  }
7525  if (wd != not_a_weekday)
7526  fds.wd = weekday{static_cast<unsigned>(wd)};
7527  if (abbrev != nullptr) {
7528  *abbrev = std::move(temp_abbrev);
7529  }
7530  if (offset != nullptr && temp_offset != not_a_offset) {
7531  *offset = temp_offset;
7532  }
7533  }
7534  return is;
7535  }
7536 broken:
7537  is.setstate(ios::failbit);
7538  return is;
7539 }
7540 
7541 template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
7542 std::basic_istream<CharT, Traits> &
7543 from_stream(std::basic_istream<CharT, Traits> &is, const CharT *fmt, year &y,
7544  std::basic_string<CharT, Traits, Alloc> *abbrev = nullptr,
7545  std::chrono::minutes *offset = nullptr)
7546 {
7547  using CT = std::chrono::seconds;
7548  fields<CT> fds{};
7549  from_stream(is, fmt, fds, abbrev, offset);
7550  if (!fds.ymd.year().ok()) {
7551  is.setstate(std::ios::failbit);
7552  }
7553  if (!is.fail()) {
7554  y = fds.ymd.year();
7555  }
7556  return is;
7557 }
7558 
7559 template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
7560 std::basic_istream<CharT, Traits> &
7561 from_stream(std::basic_istream<CharT, Traits> &is, const CharT *fmt, month &m,
7562  std::basic_string<CharT, Traits, Alloc> *abbrev = nullptr,
7563  std::chrono::minutes *offset = nullptr)
7564 {
7565  using CT = std::chrono::seconds;
7566  fields<CT> fds{};
7567  from_stream(is, fmt, fds, abbrev, offset);
7568  if (!fds.ymd.month().ok()) {
7569  is.setstate(std::ios::failbit);
7570  }
7571  if (!is.fail()) {
7572  m = fds.ymd.month();
7573  }
7574  return is;
7575 }
7576 
7577 template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
7578 std::basic_istream<CharT, Traits> &
7579 from_stream(std::basic_istream<CharT, Traits> &is, const CharT *fmt, day &d,
7580  std::basic_string<CharT, Traits, Alloc> *abbrev = nullptr,
7581  std::chrono::minutes *offset = nullptr)
7582 {
7583  using CT = std::chrono::seconds;
7584  fields<CT> fds{};
7585  from_stream(is, fmt, fds, abbrev, offset);
7586  if (!fds.ymd.day().ok()) {
7587  is.setstate(std::ios::failbit);
7588  }
7589  if (!is.fail()) {
7590  d = fds.ymd.day();
7591  }
7592  return is;
7593 }
7594 
7595 template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
7596 std::basic_istream<CharT, Traits> &
7597 from_stream(std::basic_istream<CharT, Traits> &is, const CharT *fmt,
7598  weekday &wd,
7599  std::basic_string<CharT, Traits, Alloc> *abbrev = nullptr,
7600  std::chrono::minutes *offset = nullptr)
7601 {
7602  using CT = std::chrono::seconds;
7603  fields<CT> fds{};
7604  from_stream(is, fmt, fds, abbrev, offset);
7605  if (!fds.wd.ok()) {
7606  is.setstate(std::ios::failbit);
7607  }
7608  if (!is.fail()) {
7609  wd = fds.wd;
7610  }
7611  return is;
7612 }
7613 
7614 template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
7615 std::basic_istream<CharT, Traits> &
7616 from_stream(std::basic_istream<CharT, Traits> &is, const CharT *fmt,
7617  year_month &ym,
7618  std::basic_string<CharT, Traits, Alloc> *abbrev = nullptr,
7619  std::chrono::minutes *offset = nullptr)
7620 {
7621  using CT = std::chrono::seconds;
7622  fields<CT> fds{};
7623  from_stream(is, fmt, fds, abbrev, offset);
7624  if (!fds.ymd.month().ok()) {
7625  is.setstate(std::ios::failbit);
7626  }
7627  if (!is.fail()) {
7628  ym = fds.ymd.year() / fds.ymd.month();
7629  }
7630  return is;
7631 }
7632 
7633 template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
7634 std::basic_istream<CharT, Traits> &
7635 from_stream(std::basic_istream<CharT, Traits> &is, const CharT *fmt,
7636  month_day &md,
7637  std::basic_string<CharT, Traits, Alloc> *abbrev = nullptr,
7638  std::chrono::minutes *offset = nullptr)
7639 {
7640  using CT = std::chrono::seconds;
7641  fields<CT> fds{};
7642  from_stream(is, fmt, fds, abbrev, offset);
7643  if (!fds.ymd.month().ok() || !fds.ymd.day().ok()) {
7644  is.setstate(std::ios::failbit);
7645  }
7646  if (!is.fail()) {
7647  md = fds.ymd.month() / fds.ymd.day();
7648  }
7649  return is;
7650 }
7651 
7652 template <class CharT, class Traits, class Alloc = std::allocator<CharT>>
7653 std::basic_istream<CharT, Traits> &
7654 from_stream(std::basic_istream<CharT, Traits> &is, const CharT *fmt,
7655  year_month_day &ymd, std::basic_string<CharT, Traits, Alloc> *abbrev = nullptr,
7656  std::chrono::minutes *offset = nullptr)
7657 {
7658  using CT = std::chrono::seconds;
7659  fields<CT> fds{};
7660  from_stream(is, fmt, fds, abbrev, offset);
7661  if (!fds.ymd.ok()) {
7662  is.setstate(std::ios::failbit);
7663  }
7664  if (!is.fail()) {
7665  ymd = fds.ymd;
7666  }
7667  return is;
7668 }
7669 
7670 template <class Duration, class CharT, class Traits, class Alloc = std::allocator<CharT>>
7671 std::basic_istream<CharT, Traits> &
7672 from_stream(std::basic_istream<CharT, Traits> &is, const CharT *fmt,
7673  sys_time<Duration> &tp, std::basic_string<CharT, Traits, Alloc> *abbrev =
7674  nullptr,
7675  std::chrono::minutes *offset = nullptr)
7676 {
7677  using CT = typename std::common_type<Duration, std::chrono::seconds>::type;
7678  std::chrono::minutes offset_local{};
7679  auto offptr = offset ? offset : &offset_local;
7680  fields<CT> fds{};
7681  fds.has_tod = true;
7682  from_stream(is, fmt, fds, abbrev, offptr);
7683  if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) {
7684  is.setstate(std::ios::failbit);
7685  }
7686  if (!is.fail()) {
7687  tp = round<Duration>(sys_days(fds.ymd) - *offptr + fds.tod.to_duration());
7688  }
7689  return is;
7690 }
7691 
7692 template <class Duration, class CharT, class Traits, class Alloc = std::allocator<CharT>>
7693 std::basic_istream<CharT, Traits> &
7694 from_stream(std::basic_istream<CharT, Traits> &is, const CharT *fmt,
7696  std::basic_string<CharT, Traits, Alloc> *abbrev = nullptr,
7697  std::chrono::minutes *offset = nullptr)
7698 {
7699  using CT = typename std::common_type<Duration, std::chrono::seconds>::type;
7700  fields<CT> fds{};
7701  fds.has_tod = true;
7702  from_stream(is, fmt, fds, abbrev, offset);
7703  if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) {
7704  is.setstate(std::ios::failbit);
7705  }
7706  if (!is.fail())
7707  tp = round<Duration>(local_seconds{local_days(fds.ymd)} +
7708  fds.tod.to_duration());
7709  return is;
7710 }
7711 
7712 template <class Rep, class Period, class CharT, class Traits, class Alloc = std::allocator<CharT>>
7713 std::basic_istream<CharT, Traits> &
7714 from_stream(std::basic_istream<CharT, Traits> &is, const CharT *fmt,
7715  std::chrono::duration<Rep, Period> &d,
7716  std::basic_string<CharT, Traits, Alloc> *abbrev = nullptr,
7717  std::chrono::minutes *offset = nullptr)
7718 {
7719  using Duration = std::chrono::duration<Rep, Period>;
7720  using CT = typename std::common_type<Duration, std::chrono::seconds>::type;
7721  fields<CT> fds{};
7722  from_stream(is, fmt, fds, abbrev, offset);
7723  if (!fds.has_tod) {
7724  is.setstate(std::ios::failbit);
7725  }
7726  if (!is.fail()) {
7727  d = std::chrono::duration_cast<Duration>(fds.tod.to_duration());
7728  }
7729  return is;
7730 }
7731 
7732 template <class Parsable, class CharT, class Traits = std::char_traits<CharT>,
7733  class Alloc = std::allocator<CharT>>
7734 struct parse_manip {
7735  const std::basic_string<CharT, Traits, Alloc> format_;
7736  Parsable &tp_;
7737  std::basic_string<CharT, Traits, Alloc> *abbrev_;
7738  std::chrono::minutes *offset_;
7739 
7740 public:
7741  parse_manip(std::basic_string<CharT, Traits, Alloc> format, Parsable &tp,
7742  std::basic_string<CharT, Traits, Alloc> *abbrev = nullptr,
7743  std::chrono::minutes *offset = nullptr)
7744  : format_(std::move(format))
7745  , tp_(tp)
7746  , abbrev_(abbrev)
7747  , offset_(offset)
7748  {}
7749 
7750 };
7751 
7752 template <class Parsable, class CharT, class Traits, class Alloc>
7753 std::basic_istream<CharT, Traits> &
7754 operator>>(std::basic_istream<CharT, Traits> &is,
7755  const parse_manip<Parsable, CharT, Traits, Alloc> &x)
7756 {
7757  return from_stream(is, x.format_.c_str(), x.tp_, x.abbrev_, x.offset_);
7758 }
7759 
7760 template <class Parsable, class CharT, class Traits, class Alloc>
7761 inline
7762 auto
7763 parse(const std::basic_string<CharT, Traits, Alloc> &format, Parsable &tp)
7764 -> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
7765  format.c_str(), tp),
7766  parse_manip<Parsable, CharT, Traits, Alloc>
7767 {
7768  format, tp
7769 })
7770 {
7771  return {format, tp};
7772 }
7773 
7774 template <class Parsable, class CharT, class Traits, class Alloc>
7775 inline
7776 auto
7777 parse(const std::basic_string<CharT, Traits, Alloc> &format, Parsable &tp,
7778  std::basic_string<CharT, Traits, Alloc> &abbrev)
7779 -> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
7780  format.c_str(), tp, &abbrev),
7781  parse_manip<Parsable, CharT, Traits, Alloc>
7782 {
7783  format, tp, &abbrev
7784 })
7785 {
7786  return {format, tp, &abbrev};
7787 }
7788 
7789 template <class Parsable, class CharT, class Traits, class Alloc>
7790 inline
7791 auto
7792 parse(const std::basic_string<CharT, Traits, Alloc> &format, Parsable &tp,
7793  std::chrono::minutes &offset)
7794 -> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
7795  format.c_str(), tp,
7796  std::declval<std::basic_string<CharT, Traits, Alloc>*>(),
7797  &offset),
7798  parse_manip<Parsable, CharT, Traits, Alloc>
7799 {
7800  format, tp, nullptr, &offset
7801 })
7802 {
7803  return {format, tp, nullptr, &offset};
7804 }
7805 
7806 template <class Parsable, class CharT, class Traits, class Alloc>
7807 inline
7808 auto
7809 parse(const std::basic_string<CharT, Traits, Alloc> &format, Parsable &tp,
7810  std::basic_string<CharT, Traits, Alloc> &abbrev, std::chrono::minutes &offset)
7811 -> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
7812  format.c_str(), tp, &abbrev, &offset),
7813  parse_manip<Parsable, CharT, Traits, Alloc>
7814 {
7815  format, tp, &abbrev, &offset
7816 })
7817 {
7818  return {format, tp, &abbrev, &offset};
7819 }
7820 
7821 // const CharT* formats
7822 
7823 template <class Parsable, class CharT>
7824 inline
7825 auto
7826 parse(const CharT *format, Parsable &tp)
7827 -> decltype(from_stream(std::declval<std::basic_istream<CharT>&>(), format, tp),
7828  parse_manip<Parsable, CharT>
7829 {
7830  format, tp
7831 })
7832 {
7833  return {format, tp};
7834 }
7835 
7836 template <class Parsable, class CharT, class Traits, class Alloc>
7837 inline
7838 auto
7839 parse(const CharT *format, Parsable &tp,
7840  std::basic_string<CharT, Traits, Alloc> &abbrev)
7841 -> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
7842  format,
7843  tp, &abbrev),
7844  parse_manip<Parsable, CharT, Traits, Alloc>
7845 {
7846  format, tp, &abbrev
7847 })
7848 {
7849  return {format, tp, &abbrev};
7850 }
7851 
7852 template <class Parsable, class CharT>
7853 inline
7854 auto
7855 parse(const CharT *format, Parsable &tp, std::chrono::minutes &offset)
7856 -> decltype(from_stream(std::declval<std::basic_istream<CharT>&>(), format,
7857  tp, std::declval<std::basic_string<CharT>*>(), &offset),
7858  parse_manip<Parsable, CharT>
7859 {
7860  format, tp, nullptr, &offset
7861 })
7862 {
7863  return {format, tp, nullptr, &offset};
7864 }
7865 
7866 template <class Parsable, class CharT, class Traits, class Alloc>
7867 inline
7868 auto
7869 parse(const CharT *format, Parsable &tp,
7870  std::basic_string<CharT, Traits, Alloc> &abbrev, std::chrono::minutes &offset)
7871 -> decltype(from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
7872  format,
7873  tp, &abbrev, &offset),
7874  parse_manip<Parsable, CharT, Traits, Alloc>
7875 {
7876  format, tp, &abbrev, &offset
7877 })
7878 {
7879  return {format, tp, &abbrev, &offset};
7880 }
7881 
7882 // duration streaming
7883 
7884 template <class CharT, class Traits, class Rep, class Period>
7885 inline
7886 std::basic_ostream<CharT, Traits> &
7887 operator<<(std::basic_ostream<CharT, Traits> &os,
7888  const std::chrono::duration<Rep, Period> &d)
7889 {
7890  return os << detail::make_string<CharT, Traits>::from(d.count()) +
7891  detail::get_units<CharT>(typename Period::type{});
7892 }
7893 
7894 } // namespace date
7895 
7896 #ifdef _MSC_VER
7897 # pragma warning(pop)
7898 #endif
7899 
7900 #ifdef __GNUC__
7901 # pragma GCC diagnostic pop
7902 #endif
7903 
7904 #endif // DATE_H
7905 
CONSTCD14 bool ok() const NOEXCEPT
Definition: date.h:2241
Definition: date.h:693
CONSTCD11 bool ok() const NOEXCEPT
Definition: date.h:2017
unsigned read_unsigned(std::basic_istream< CharT, Traits > &is, unsigned m=1, unsigned M=10)
Definition: date.h:6000
CONSTCD11 bool ok() const NOEXCEPT
Definition: date.h:2448
int r
Definition: decode_rs.h:71
data_t t[NROOTS+1]
Definition: decode_rs.h:77
long double & i
Definition: date.h:6105
int i
Definition: decode_rs.h:71
Definition: date.h:6092
CONSTCD11 bool is_leap() const NOEXCEPT
Definition: date.h:1632
day()=default
CONSTCD14 bool ok() const NOEXCEPT
Definition: date.h:2795
unsigned m
Definition: date.h:6100
year()=default
CONSTDATA date::weekday Sunday
Definition: date.h:1933
CONSTDATA date::weekday sun
Definition: date.h:1902
Definition: date.h:512
CONSTDATA date::weekday Monday
Definition: date.h:1927
CONSTDATA date::weekday tue
Definition: date.h:1904
CONSTCD14 bool is_am(std::chrono::hours const &h) NOEXCEPT
Definition: date.h:3893
CONSTCD11 bool ok() const NOEXCEPT
Definition: date.h:2394
CONSTCD11 year_month_day_last(const date::year &y, const date::month_day_last &mdl) NOEXCEPT
Definition: date.h:2480
CONSTCD11 bool operator==(const day &x, const day &y) NOEXCEPT
Definition: date.h:1403
typename dfs::precision precision
Definition: date.h:3803
int j
Definition: decode_rs.h:71
Definition: rs-common.h:7
month()=default
unsigned M
Definition: date.h:6095
CONSTDATA date::month mar
Definition: date.h:1891
CONSTDATA date::month dec
Definition: date.h:1900
CONSTCD11 bool ok() const NOEXCEPT
Definition: date.h:1789
local_time< days > local_days
Definition: date.h:191
rs
Definition: init_rs.h:11
CONSTCD14 year_month_day_last & operator+=(const months &m) NOEXCEPT
Definition: date.h:2491
CharT fill_
Definition: date.h:1043
CONSTCD14 year & operator--() NOEXCEPT
Definition: date.h:1616
CONSTCD11 std::chrono::time_point< Clock, To > floor(const std::chrono::time_point< Clock, FromDuration > &tp)
Definition: date.h:1333
CONSTCD14 year & operator-=(const years &y) NOEXCEPT
Definition: date.h:1619
CONSTDATA date::weekday Friday
Definition: date.h:1931
std::chrono::duration< int, std::ratio_multiply< std::ratio< 146097, 400 >, days::period >::type > years
Definition: date.h:172
CONSTCD11 unsigned index() const NOEXCEPT
Definition: date.h:3014
#define NOEXCEPT
Definition: date.h:135
int count
Definition: decode_rs.h:79
std::ratio< mul< n1, d2, !value >::value, mul< n2, d1, !value >::value > type
Definition: date.h:1199
CONSTCD11 year operator+() const NOEXCEPT
Definition: date.h:1624
CONSTCD14 date::day day() const NOEXCEPT
Definition: date.h:2541
CONSTDATA date::month apr
Definition: date.h:1892
sys_time< std::chrono::seconds > sys_seconds
Definition: date.h:183
CONSTCD14 weekday & operator+=(const days &d) NOEXCEPT
Definition: date.h:1776
Definition: date.h:3792
CONSTCD11 date::year year() const NOEXCEPT
Definition: date.h:2521
year_month_day ymd
Definition: date.h:4533
std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, const parse_manip< Parsable, CharT, Traits, Alloc > &x)
Definition: date.h:7754
CONSTDATA date::month December
Definition: date.h:1925
CONSTCD11 day operator-(const day &x, const days &y) NOEXCEPT
Definition: date.h:1468
CONSTDATA date::month sep
Definition: date.h:1897
CONSTCD11 decimal_format_seconds(const Duration &d) NOEXCEPT
Definition: date.h:3693
CONSTCD11 date::month month() const NOEXCEPT
Definition: date.h:2716
CONSTCD11 bool in_conventional_range() const NOEXCEPT
Definition: date.h:3715
CONSTCD14 year_month_weekday_last & operator-=(const months &m) NOEXCEPT
Definition: date.h:3174
CONSTDATA date::month March
Definition: date.h:1916
std::chrono::duration< int, std::ratio_multiply< std::ratio< 7 >, days::period >::type > weeks
Definition: date.h:169
CONSTCD11 std::enable_if< !std::numeric_limits< Rep >::is_signed, std::chrono::duration< Rep, Period > >::type abs(std::chrono::duration< Rep, Period > d)
Definition: date.h:3784
CONSTCD11 bool in_conventional_range() const NOEXCEPT
Definition: date.h:3850
Definition: date.h:1077
void read(std::basic_istream< CharT, Traits > &)
Definition: date.h:6112
CONSTDATA date::month September
Definition: date.h:1922
CONSTCD11 date::year year() const NOEXCEPT
Definition: date.h:2712
CONSTCD11 hh_mm_ss() NOEXCEPT
Definition: date.h:3805
CONSTCD11 bool ok() const NOEXCEPT
Definition: date.h:2310
CONSTDATA date::weekday Saturday
Definition: date.h:1932
CONSTCD14 To ceil(const std::chrono::duration< Rep, Period > &d)
Definition: date.h:1308
fields(weekday wd_, hh_mm_ss< Duration > tod_)
Definition: date.h:4548
std::basic_istream< CharT, Traits > & from_stream(std::basic_istream< CharT, Traits > &is, const CharT *fmt, fields< Duration > &fds, std::basic_string< CharT, Traits, Alloc > *abbrev=nullptr, std::chrono::minutes *offset=nullptr)
Definition: date.h:6234
CONSTCD11 date::month_day_last month_day_last() const NOEXCEPT
Definition: date.h:2533
CONSTDATA date::weekday sat
Definition: date.h:1908
save_istream(std::basic_ios< CharT, Traits > &is)
Definition: date.h:1062
CONSTCD11 date::weekday_last weekday_last() const NOEXCEPT
Definition: date.h:3215
int & i
Definition: date.h:6099
void read(std::basic_istream< CharT, Traits > &is, rld a0, Args &&...args)
Definition: date.h:6205
unsigned m
Definition: date.h:6106
CONSTCD14 day & operator++() NOEXCEPT
Definition: date.h:1385
#define HAS_UNCAUGHT_EXCEPTIONS
Definition: date.h:142
CONSTDATA date::month January
Definition: date.h:1914
CONSTCD11 date::month month() const NOEXCEPT
Definition: date.h:2378
CONSTCD11 precision subseconds() const NOEXCEPT
Definition: date.h:3832
CONSTCD14 precision to_duration() const NOEXCEPT
Definition: date.h:3710
sys_time< days > sys_days
Definition: date.h:182
CONSTCD11 bool ok() const NOEXCEPT
Definition: date.h:1645
Definition: date.h:88
CONSTCD11 date::weekday weekday() const NOEXCEPT
Definition: date.h:3207
CONSTCD11 bool operator>(const day &x, const day &y) NOEXCEPT
Definition: date.h:1424
Definition: date.h:393
CONSTDATA date::month feb
Definition: date.h:1890
Definition: date.h:762
CONSTCD11 date::month month() const NOEXCEPT
Definition: date.h:2229
std::streamsize width_
Definition: date.h:1045
month_day()=default
auto format(const std::locale &loc, const CharT *fmt, const Streamable &tp) -> decltype(to_stream(std::declval< std::basic_ostream< CharT > &>(), fmt, tp), std::basic_string< CharT >
Definition: date.h:5927
static CONSTCD11 year min() NOEXCEPT
Definition: date.h:416
CONSTCD11 year_month operator/(const year &y, const month &m) NOEXCEPT
Definition: date.h:3328
CONSTCD11 decimal_format_seconds()
Definition: date.h:3688
CONSTDATA date::weekday Wednesday
Definition: date.h:1929
CONSTCD11 hh_mm_ss< std::chrono::duration< Rep, Period > > make_time(const std::chrono::duration< Rep, Period > &d)
Definition: date.h:3948
Definition: date.h:665
CONSTCD11 date::weekday_last weekday_last() const NOEXCEPT
Definition: date.h:2440
CONSTDATA date::month August
Definition: date.h:1921
CONSTCD11 std::chrono::time_point< Clock, To > ceil(const std::chrono::time_point< Clock, FromDuration > &tp)
Definition: date.h:1355
CONSTCD11 date::weekday weekday() const NOEXCEPT
Definition: date.h:2013
CONSTCD11 date::weekday_indexed weekday_indexed() const NOEXCEPT
Definition: date.h:3022
CONSTCD11 std::chrono::duration< Rep, Period > abs(std::chrono::duration< Rep, Period > d)
Definition: date.h:1323
std::basic_ostream< CharT, Traits > & print(std::basic_ostream< CharT, Traits > &os, std::false_type) const
Definition: date.h:3743
CONSTCD11 date::year year() const NOEXCEPT
Definition: date.h:3195
int read_signed(std::basic_istream< CharT, Traits > &is, unsigned m=1, unsigned M=10)
Definition: date.h:6029
fields(year_month_day ymd_, weekday wd_, hh_mm_ss< Duration > tod_)
Definition: date.h:4551
CONSTCD11 bool ok() const NOEXCEPT
Definition: date.h:1517
Definition: date.h:612
Definition: date.h:1103
std::chrono::duration< rep, std::ratio< 1, static_pow10< width >::value > > precision
Definition: date.h:3681
CONSTDATA date::month February
Definition: date.h:1915
CONSTCD14 weekday & operator++() NOEXCEPT
Definition: date.h:1768
CONSTCD14 std::chrono::hours make24(std::chrono::hours h, bool is_pm) NOEXCEPT
Definition: date.h:3927
Definition: date.h:1176
save_ostream(std::basic_ios< CharT, Traits > &os)
Definition: date.h:1096
CONSTCD11 bool ok() const NOEXCEPT
Definition: date.h:3237
CONSTCD11 date::weekday_indexed weekday_indexed() const NOEXCEPT
Definition: date.h:2386
Definition: date.h:6098
CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT
Definition: date.h:3822
CONSTCD11 bool ok() const NOEXCEPT
Definition: date.h:2072
fields(year_month_day ymd_)
Definition: date.h:4540
CONSTDATA date::month jun
Definition: date.h:1894
CONSTCD11 year operator-() const NOEXCEPT
Definition: date.h:1620
Definition: date.h:1040
CONSTDATA date::month oct
Definition: date.h:1898
std::ios::fmtflags flags_
Definition: date.h:1044
CONSTCD11 weekday_indexed operator[](unsigned index) const NOEXCEPT
Definition: date.h:1992
CONSTDATA date::month jan
Definition: date.h:1889
CONSTCD14 year & operator+=(const years &y) NOEXCEPT
Definition: date.h:1618
fields(year_month_day ymd_, hh_mm_ss< Duration > tod_)
Definition: date.h:4545
CONSTDATA date::weekday wed
Definition: date.h:1905
CONSTCD11 std::enable_if< std::numeric_limits< Rep >::is_signed, std::chrono::duration< Rep, Period > >::type abs(std::chrono::duration< Rep, Period > d)
Definition: date.h:3771
CONSTCD14 year_month_day_last & operator-=(const months &m) NOEXCEPT
Definition: date.h:2500
CONSTCD11 day operator+(const day &x, const days &y) NOEXCEPT
Definition: date.h:1454
CONSTDATA date::month July
Definition: date.h:1920
#define CONSTDATA
Definition: date.h:132
std::basic_ostream< CharT, Traits > & print(std::basic_ostream< CharT, Traits > &os, std::true_type) const
Definition: date.h:3731
CONSTCD11 bool ok() const NOEXCEPT
Definition: date.h:1395
fields(year_month_day ymd_, weekday wd_)
Definition: date.h:4544
CONSTDATA date::weekday mon
Definition: date.h:1903
CONSTCD11 weekday_last(const date::weekday &wd) NOEXCEPT
Definition: date.h:2021
Definition: date.h:488
std::chrono::duration< int, std::ratio_divide< years::period, std::ratio< 12 > >::type > months
Definition: date.h:175
CONSTCD14 year & operator++() NOEXCEPT
Definition: date.h:1614
CONSTCD14 To round(const std::chrono::duration< Rep, Period > &d)
Definition: date.h:1284
CONSTCD11 std::chrono::time_point< Clock, To > round(const std::chrono::time_point< Clock, FromDuration > &tp)
Definition: date.h:1344
CONSTCD11 date::weekday weekday() const NOEXCEPT
Definition: date.h:3006
std::basic_ostream< CharT, Traits > & to_stream(std::basic_ostream< CharT, Traits > &os, const CharT *fmt, const fields< Duration > &fds, const std::string *abbrev=nullptr, const std::chrono::seconds *offset_sec=nullptr)
Definition: date.h:4772
Definition: date.h:6104
CONSTCD11 bool operator>=(const day &x, const day &y) NOEXCEPT
Definition: date.h:1438
typename std::conditional< digits< 32, std::int32_t, typename std::conditional< digits< 64, std::int64_t, std::int64_t >::type >::type type
Definition: date.h:1119
CONSTCD14 bool is_pm(std::chrono::hours const &h) NOEXCEPT
Definition: date.h:3901
data_t tmp
Definition: decode_rs.h:74
CONSTDATA date::weekday Tuesday
Definition: date.h:1928
CONSTCD14 year_month_weekday & operator-=(const months &m) NOEXCEPT
Definition: date.h:2973
static CONSTCD11 year max() NOEXCEPT
Definition: date.h:417
unsigned M
Definition: date.h:6107
CONSTCD11 year_month_weekday_last(const date::year &y, const date::month &m, const date::weekday_last &wdl) NOEXCEPT
Definition: date.h:3152
CONSTCD11 date::year year() const NOEXCEPT
Definition: date.h:2064
CONSTDATA date::weekday fri
Definition: date.h:1907
CONSTDATA date::month May
Definition: date.h:1918
CONSTCD14 month & operator--() NOEXCEPT
Definition: date.h:1494
CONSTCD14 year_month_day & operator+=(const months &m) NOEXCEPT
Definition: date.h:2729
std::chrono::time_point< std::chrono::system_clock, Duration > sys_time
Definition: date.h:180
CONSTCD11 bool operator!=(const day &x, const day &y) NOEXCEPT
Definition: date.h:1410
CONSTCD11 date::month month() const NOEXCEPT
Definition: date.h:2068
bool has_tod
Definition: date.h:4536
CONSTCD14 day & operator+=(const days &d) NOEXCEPT
Definition: date.h:1389
CONSTDATA date::month November
Definition: date.h:1924
CONSTCD14 std::enable_if< detail::no_overflow< Period, typename To::period >::value, To >::type floor(const std::chrono::duration< Rep, Period > &d)
Definition: date.h:1257
CONSTCD14 month & operator++() NOEXCEPT
Definition: date.h:1492
CONSTCD14 std::chrono::seconds & seconds(detail::undocumented) NOEXCEPT
Definition: date.h:3831
#define CONSTCD14
Definition: date.h:134
CONSTCD14 day & operator--() NOEXCEPT
Definition: date.h:1387
CONSTDATA date::weekday thu
Definition: date.h:1906
CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT
Definition: date.h:3826
Definition: date.h:539
Definition: date.h:3661
CONSTCD11 date::month month() const NOEXCEPT
Definition: date.h:2432
CONSTDATA date::last_spec last
Definition: date.h:1887
CONSTCD11 date::day day() const NOEXCEPT
Definition: date.h:2720
CONSTCD14 year_month & operator+=(const months &dm) NOEXCEPT
Definition: date.h:2081
std::basic_ostream< CharT, Traits > * tie_
Definition: date.h:1046
weekday wd
Definition: date.h:4534
CONSTDATA date::month October
Definition: date.h:1923
CONSTCD11 std::enable_if<!std::chrono::treat_as_floating_point< T >::value, T >::type trunc(T t) NOEXCEPT
Definition: date.h:1130
~save_istream()
Definition: date.h:1050
Definition: date.h:915
fields(hh_mm_ss< Duration > tod_)
Definition: date.h:4542
CONSTCD11 unsigned index() const NOEXCEPT
Definition: date.h:1945
data_t loc[NROOTS]
Definition: decode_rs.h:78
CONSTCD14 std::chrono::hours make12(std::chrono::hours h) NOEXCEPT
Definition: date.h:3909
long double read_long_double(std::basic_istream< CharT, Traits > &is, unsigned m=1, unsigned M=10)
Definition: date.h:6056
fields(weekday wd_)
Definition: date.h:4541
CONSTCD11 precision subseconds() const NOEXCEPT
Definition: date.h:3705
local_time< std::chrono::seconds > local_seconds
Definition: date.h:190
Definition: date.h:585
CONSTDATA year nanyear
Definition: date.h:4529
CONSTCD11 std::chrono::hours hours() const NOEXCEPT
Definition: date.h:3818
CONSTCD11 date::weekday weekday() const NOEXCEPT
Definition: date.h:1940
CONSTDATA date::month June
Definition: date.h:1919
CONSTCD14 weekday & operator--() NOEXCEPT
Definition: date.h:1770
CONSTCD11 month_day_last(const date::month &m) NOEXCEPT
Definition: date.h:2314
std::chrono::duration< int, std::ratio_multiply< std::ratio< 24 >, std::chrono::hours::period >::type > days
Definition: date.h:166
CONSTCD11 bool ok() const NOEXCEPT
Definition: date.h:2570
Definition: date.h:3636
CONSTCD11 date::day day() const NOEXCEPT
Definition: date.h:2233
Definition: date.h:1161
Definition: date.h:185
CONSTCD11 hh_mm_ss(Duration d) NOEXCEPT
Definition: date.h:3810
unsigned m
Definition: date.h:6094
CONSTCD14 month & operator+=(const months &m) NOEXCEPT
Definition: date.h:1500
Definition: date.h:195
~save_ostream()
Definition: date.h:1080
CONSTCD14 year_month & operator-=(const months &dm) NOEXCEPT
Definition: date.h:2090
std::locale loc_
Definition: date.h:1047
year_month_day()=default
unsigned extract_month(std::basic_ostream< CharT, Traits > &os, const fields< Duration > &fds)
Definition: date.h:4588
data_t den
Definition: decode_rs.h:74
CONSTDATA date::weekday Thursday
Definition: date.h:1930
CONSTCD14 bool ok() const NOEXCEPT
Definition: date.h:3044
CONSTCD14 std::chrono::seconds & seconds() NOEXCEPT
Definition: date.h:3700
CONSTCD14 month & operator-=(const months &m) NOEXCEPT
Definition: date.h:1508
Definition: date.h:840
CONSTDATA date::month jul
Definition: date.h:1895
Definition: date.h:3617
bool read_char(std::basic_istream< CharT, Traits > &is, CharT fmt, std::ios::iostate &err)
Definition: date.h:5985
CONSTCD11 date::month month() const NOEXCEPT
Definition: date.h:2525
unsigned extract_weekday(std::basic_ostream< CharT, Traits > &os, const fields< Duration > &fds)
Definition: date.h:4563
std::basic_ios< CharT, Traits > & is_
Definition: date.h:1042
CONSTDATA date::month may
Definition: date.h:1893
void checked_set(T &value, T from, T not_a_value, std::basic_ios< CharT, Traits > &is)
Definition: date.h:6218
Definition: date.h:641
CONSTCD11 std::enable_if< detail::no_overflow< Period, typename To::period >::value, To >::type trunc(const std::chrono::duration< Rep, Period > &d)
Definition: date.h:1213
data_t u
Definition: decode_rs.h:74
unsigned M
Definition: date.h:6101
Definition: date.h:319
CONSTCD11 bool operator<(const day &x, const day &y) NOEXCEPT
Definition: date.h:1417
Definition: date.h:438
Definition: date.h:356
std::chrono::time_point< local_t, Duration > local_time
Definition: date.h:188
weekday()=default
CONSTDATA date::month aug
Definition: date.h:1896
CONSTCD14 day & operator-=(const days &d) NOEXCEPT
Definition: date.h:1390
year_month()=default
CONSTCD11 date::month month() const NOEXCEPT
Definition: date.h:2306
CONSTCD11 unsigned c_encoding() const NOEXCEPT
Definition: date.h:1796
CONSTCD14 weekday & operator-=(const days &d) NOEXCEPT
Definition: date.h:1784
int & i
Definition: date.h:6093
CONSTCD11 month_weekday(const date::month &m, const date::weekday_indexed &wdi) NOEXCEPT
Definition: date.h:2371
CONSTCD11 unsigned iso_encoding() const NOEXCEPT
Definition: date.h:1803
hh_mm_ss< Duration > tod
Definition: date.h:4535
CONSTDATA date::month April
Definition: date.h:1917
data_t s[NROOTS]
Definition: decode_rs.h:75
Definition: date.h:3987
Definition: date.h:3651
CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT
Definition: date.h:3701
CONSTCD11 bool is_negative() const NOEXCEPT
Definition: date.h:3836
CONSTCD14 year_month_weekday_last & operator+=(const months &m) NOEXCEPT
Definition: date.h:3165
CONSTCD11 bool ok() const NOEXCEPT
Definition: date.h:1953
CONSTDATA date::month nov
Definition: date.h:1899
CONSTCD11 precision to_duration() const NOEXCEPT
Definition: date.h:3845
CONSTCD11 date::month month() const NOEXCEPT
Definition: date.h:2998
CONSTCD14 year_month_day & operator-=(const months &m) NOEXCEPT
Definition: date.h:2738
CONSTCD11 month_weekday_last(const date::month &m, const date::weekday_last &wd) NOEXCEPT
Definition: date.h:2425
CONSTCD11 date::month month() const NOEXCEPT
Definition: date.h:3199
CONSTCD11 date::year year() const NOEXCEPT
Definition: date.h:2994
CONSTCD14 year_month_weekday & operator+=(const months &m) NOEXCEPT
Definition: date.h:2964
CONSTCD11 bool operator<=(const day &x, const day &y) NOEXCEPT
Definition: date.h:1431
#define CONSTCD11
Definition: date.h:133