65 #include <type_traits>
72 # pragma GCC diagnostic push
73 # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 7)
74 # pragma GCC diagnostic ignored "-Wpedantic"
78 # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
83 # pragma warning(push)
85 # pragma warning(disable : 4127)
96 # define ONLY_C_LOCALE 0
99 #ifndef HAS_UNCAUGHT_EXCEPTIONS
100 # if __cplusplus >= 201703 || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
101 # define HAS_UNCAUGHT_EXCEPTIONS 1
103 # define HAS_UNCAUGHT_EXCEPTIONS 0
108 # if __cplusplus >= 201703 || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
109 # define HAS_VOID_T 1
111 # define HAS_VOID_T 0
119 template <
typename R1,
typename R2>
120 using ratio_multiply = decltype(std::ratio_multiply<R1, R2>{});
122 template <
typename R1,
typename R2>
123 using ratio_divide = decltype(std::ratio_divide<R1, R2>{});
132 using days = std::chrono::duration
133 <int, detail::ratio_multiply<std::ratio<24>, std::chrono::hours::period>>;
135 using weeks = std::chrono::duration
136 <int, detail::ratio_multiply<std::ratio<7>, days::period>>;
138 using years = std::chrono::duration
139 <int, detail::ratio_multiply<std::ratio<146097, 400>, days::period>>;
141 using months = std::chrono::duration
142 <int, detail::ratio_divide<years::period, std::ratio<12>>>;
146 template <
class Duration>
147 using sys_time = std::chrono::time_point<std::chrono::system_clock, Duration>;
149 using sys_days = sys_time<days>;
150 using sys_seconds = sys_time<std::chrono::seconds>;
154 template <
class Duration>
155 using local_time = std::chrono::time_point<local_t, Duration>;
157 using local_seconds = local_time<std::chrono::seconds>;
158 using local_days = local_time<days>;
164 explicit last_spec() =
default;
172 class weekday_indexed;
176 class month_day_last;
178 class month_weekday_last;
182 class year_month_day;
183 class year_month_day_last;
184 class year_month_weekday;
185 class year_month_weekday_last;
189 constexpr year_month operator/(
const year& y,
const month& m) noexcept;
190 constexpr year_month operator/(
const year& y,
int m) noexcept;
192 constexpr month_day operator/(
const day& d,
const month& m) noexcept;
193 constexpr month_day operator/(
const day& d,
int m) noexcept;
194 constexpr month_day operator/(
const month& m,
const day& d) noexcept;
195 constexpr month_day operator/(
const month& m,
int d) noexcept;
196 constexpr month_day operator/(
int m,
const day& d) noexcept;
198 constexpr month_day_last operator/(
const month& m, last_spec) noexcept;
199 constexpr month_day_last operator/(
int m, last_spec) noexcept;
200 constexpr month_day_last operator/(last_spec,
const month& m) noexcept;
201 constexpr month_day_last operator/(last_spec,
int m) noexcept;
203 constexpr month_weekday operator/(
const month& m,
const weekday_indexed& wdi) noexcept;
204 constexpr month_weekday operator/(
int m,
const weekday_indexed& wdi) noexcept;
205 constexpr month_weekday operator/(
const weekday_indexed& wdi,
const month& m) noexcept;
206 constexpr month_weekday operator/(
const weekday_indexed& wdi,
int m) noexcept;
208 constexpr month_weekday_last operator/(
const month& m,
const weekday_last& wdl) noexcept;
209 constexpr month_weekday_last operator/(
int m,
const weekday_last& wdl) noexcept;
210 constexpr month_weekday_last operator/(
const weekday_last& wdl,
const month& m) noexcept;
211 constexpr month_weekday_last operator/(
const weekday_last& wdl,
int m) noexcept;
213 constexpr year_month_day operator/(
const year_month& ym,
const day& d) noexcept;
214 constexpr year_month_day operator/(
const year_month& ym,
int d) noexcept;
215 constexpr year_month_day operator/(
const year& y,
const month_day& md) noexcept;
216 constexpr year_month_day operator/(
int y,
const month_day& md) noexcept;
217 constexpr year_month_day operator/(
const month_day& md,
const year& y) noexcept;
218 constexpr year_month_day operator/(
const month_day& md,
int y) noexcept;
221 year_month_day_last operator/(
const year_month& ym, last_spec) noexcept;
223 year_month_day_last operator/(
const year& y,
const month_day_last& mdl) noexcept;
225 year_month_day_last operator/(
int y,
const month_day_last& mdl) noexcept;
227 year_month_day_last operator/(
const month_day_last& mdl,
const year& y) noexcept;
229 year_month_day_last operator/(
const month_day_last& mdl,
int y) noexcept;
231 constexpr year_month_weekday
232 operator/(
const year_month& ym,
const weekday_indexed& wdi) noexcept;
234 constexpr year_month_weekday
235 operator/(
const year& y,
const month_weekday& mwd) noexcept;
237 constexpr year_month_weekday
238 operator/(
int y,
const month_weekday& mwd) noexcept;
240 constexpr year_month_weekday
241 operator/(
const month_weekday& mwd,
const year& y) noexcept;
243 constexpr year_month_weekday
244 operator/(
const month_weekday& mwd,
int y) noexcept;
246 constexpr year_month_weekday_last
247 operator/(
const year_month& ym,
const weekday_last& wdl) noexcept;
249 constexpr year_month_weekday_last
250 operator/(
const year& y,
const month_weekday_last& mwdl) noexcept;
252 constexpr year_month_weekday_last
253 operator/(
int y,
const month_weekday_last& mwdl) noexcept;
255 constexpr year_month_weekday_last
256 operator/(
const month_weekday_last& mwdl,
const year& y) noexcept;
258 constexpr year_month_weekday_last
259 operator/(
const month_weekday_last& mwdl,
int y) noexcept;
271 explicit constexpr day(
unsigned d) noexcept;
273 constexpr day& operator++() noexcept;
274 constexpr day operator++(
int) noexcept;
275 constexpr day& operator--() noexcept;
276 constexpr day operator--(
int) noexcept;
278 constexpr day& operator+=(const days& d) noexcept;
279 constexpr day& operator-=(const days& d) noexcept;
281 constexpr explicit operator
unsigned() const noexcept;
282 constexpr
bool ok() const noexcept;
285 constexpr
bool operator==(const day& x, const day& y) noexcept;
286 constexpr
bool operator!=(const day& x, const day& y) noexcept;
287 constexpr
bool operator< (const day& x, const day& y) noexcept;
288 constexpr
bool operator> (const day& x, const day& y) noexcept;
289 constexpr
bool operator<=(const day& x, const day& y) noexcept;
290 constexpr
bool operator>=(const day& x, const day& y) noexcept;
292 constexpr day operator+(const day& x, const days& y) noexcept;
293 constexpr day operator+(const days& x, const day& y) noexcept;
294 constexpr day operator-(const day& x, const days& y) noexcept;
295 constexpr days operator-(const day& x, const day& y) noexcept;
297 template<class CharT, class Traits>
298 std::basic_ostream<CharT, Traits>&
299 operator<<(std::basic_ostream<CharT, Traits>& os, const day& d);
309 explicit constexpr month(
unsigned m) noexcept;
311 constexpr month& operator++() noexcept;
312 constexpr month operator++(
int) noexcept;
313 constexpr month& operator--() noexcept;
314 constexpr month operator--(
int) noexcept;
316 constexpr month& operator+=(const months& m) noexcept;
317 constexpr month& operator-=(const months& m) noexcept;
319 constexpr explicit operator
unsigned() const noexcept;
320 constexpr
bool ok() const noexcept;
323 constexpr
bool operator==(const month& x, const month& y) noexcept;
324 constexpr
bool operator!=(const month& x, const month& y) noexcept;
325 constexpr
bool operator< (const month& x, const month& y) noexcept;
326 constexpr
bool operator> (const month& x, const month& y) noexcept;
327 constexpr
bool operator<=(const month& x, const month& y) noexcept;
328 constexpr
bool operator>=(const month& x, const month& y) noexcept;
330 constexpr month operator+(const month& x, const months& y) noexcept;
331 constexpr month operator+(const months& x, const month& y) noexcept;
332 constexpr month operator-(const month& x, const months& y) noexcept;
333 constexpr months operator-(const month& x, const month& y) noexcept;
335 template<class CharT, class Traits>
336 std::basic_ostream<CharT, Traits>&
337 operator<<(std::basic_ostream<CharT, Traits>& os, const month& m);
347 explicit constexpr year(
int y) noexcept;
349 constexpr year& operator++() noexcept;
350 constexpr year operator++(
int) noexcept;
351 constexpr year& operator--() noexcept;
352 constexpr year operator--(
int) noexcept;
354 constexpr year& operator+=(const years& y) noexcept;
355 constexpr year& operator-=(const years& y) noexcept;
357 constexpr year operator-() const noexcept;
358 constexpr year operator+() const noexcept;
360 constexpr
bool is_leap() const noexcept;
362 constexpr explicit operator
int() const noexcept;
363 constexpr
bool ok() const noexcept;
365 static constexpr year min() noexcept {
return year{-32767}; }
366 static constexpr year max() noexcept {
return year{32767}; }
369 constexpr
bool operator==(
const year& x,
const year& y) noexcept;
370 constexpr
bool operator!=(
const year& x,
const year& y) noexcept;
371 constexpr
bool operator< (
const year& x,
const year& y) noexcept;
372 constexpr
bool operator> (
const year& x,
const year& y) noexcept;
373 constexpr
bool operator<=(
const year& x,
const year& y) noexcept;
374 constexpr
bool operator>=(
const year& x,
const year& y) noexcept;
376 constexpr year operator+(
const year& x,
const years& y) noexcept;
377 constexpr year operator+(
const years& x,
const year& y) noexcept;
378 constexpr year operator-(
const year& x,
const years& y) noexcept;
379 constexpr years operator-(
const year& x,
const year& y) noexcept;
381 template<
class CharT,
class Traits>
382 std::basic_ostream<CharT, Traits>&
383 operator<<(std::basic_ostream<CharT, Traits>& os,
const year& y);
392 explicit constexpr weekday(
unsigned wd) noexcept;
393 constexpr weekday(
const sys_days& dp) noexcept;
394 constexpr
explicit weekday(
const local_days& dp) noexcept;
396 constexpr weekday& operator++() noexcept;
397 constexpr weekday operator++(
int) noexcept;
398 constexpr weekday& operator--() noexcept;
399 constexpr weekday operator--(
int) noexcept;
401 constexpr weekday& operator+=(const days& d) noexcept;
402 constexpr weekday& operator-=(const days& d) noexcept;
404 constexpr
bool ok() const noexcept;
406 constexpr
unsigned c_encoding() const noexcept;
407 constexpr
unsigned iso_encoding() const noexcept;
409 constexpr weekday_indexed operator[](
unsigned index) const noexcept;
410 constexpr weekday_last operator[](last_spec) const noexcept;
413 static constexpr
unsigned char weekday_from_days(
int z) noexcept;
415 friend constexpr
bool operator==(const weekday& x, const weekday& y) noexcept;
416 friend constexpr days operator-(const weekday& x, const weekday& y) noexcept;
417 friend constexpr weekday operator+(const weekday& x, const days& y) noexcept;
418 template<class CharT, class Traits>
419 friend std::basic_ostream<CharT, Traits>&
420 operator<<(std::basic_ostream<CharT, Traits>& os, const weekday& wd);
421 friend class weekday_indexed;
424 constexpr
bool operator==(const weekday& x, const weekday& y) noexcept;
425 constexpr
bool operator!=(const weekday& x, const weekday& y) noexcept;
427 constexpr weekday operator+(const weekday& x, const days& y) noexcept;
428 constexpr weekday operator+(const days& x, const weekday& y) noexcept;
429 constexpr weekday operator-(const weekday& x, const days& y) noexcept;
430 constexpr days operator-(const weekday& x, const weekday& y) noexcept;
432 template<class CharT, class Traits>
433 std::basic_ostream<CharT, Traits>&
434 operator<<(std::basic_ostream<CharT, Traits>& os, const weekday& wd);
438 class weekday_indexed
440 unsigned char wd_ : 4;
441 unsigned char index_ : 4;
444 weekday_indexed() =
default;
445 constexpr weekday_indexed(
const gul14::date::weekday& wd,
unsigned index) noexcept;
447 constexpr gul14::date::weekday weekday() const noexcept;
448 constexpr
unsigned index() const noexcept;
449 constexpr
bool ok() const noexcept;
452 constexpr
bool operator==(const weekday_indexed& x, const weekday_indexed& y) noexcept;
453 constexpr
bool operator!=(const weekday_indexed& x, const weekday_indexed& y) noexcept;
455 template<class CharT, class Traits>
456 std::basic_ostream<CharT, Traits>&
457 operator<<(std::basic_ostream<CharT, Traits>& os, const weekday_indexed& wdi);
463 gul14::date::weekday wd_;
466 explicit constexpr weekday_last(
const gul14::date::weekday& wd) noexcept;
468 constexpr gul14::date::weekday weekday() const noexcept;
469 constexpr
bool ok() const noexcept;
472 constexpr
bool operator==(const weekday_last& x, const weekday_last& y) noexcept;
473 constexpr
bool operator!=(const weekday_last& x, const weekday_last& y) noexcept;
475 template<class CharT, class Traits>
476 std::basic_ostream<CharT, Traits>&
477 operator<<(std::basic_ostream<CharT, Traits>& os, const weekday_last& wdl);
482 struct unspecified_month_disambiguator {};
490 gul14::date::year y_;
491 gul14::date::month m_;
494 year_month() =
default;
495 constexpr year_month(
const gul14::date::year& y,
const gul14::date::month& m) noexcept;
497 constexpr gul14::date::year year() const noexcept;
498 constexpr
gul14::date::month month() const noexcept;
500 template<class = detail::unspecified_month_disambiguator>
501 constexpr year_month& operator+=(const months& dm) noexcept;
502 template<class = detail::unspecified_month_disambiguator>
503 constexpr year_month& operator-=(const months& dm) noexcept;
504 constexpr year_month& operator+=(const years& dy) noexcept;
505 constexpr year_month& operator-=(const years& dy) noexcept;
507 constexpr
bool ok() const noexcept;
510 constexpr
bool operator==(const year_month& x, const year_month& y) noexcept;
511 constexpr
bool operator!=(const year_month& x, const year_month& y) noexcept;
512 constexpr
bool operator< (const year_month& x, const year_month& y) noexcept;
513 constexpr
bool operator> (const year_month& x, const year_month& y) noexcept;
514 constexpr
bool operator<=(const year_month& x, const year_month& y) noexcept;
515 constexpr
bool operator>=(const year_month& x, const year_month& y) noexcept;
517 template<class = detail::unspecified_month_disambiguator>
518 constexpr year_month operator+(const year_month& ym, const months& dm) noexcept;
519 template<class = detail::unspecified_month_disambiguator>
520 constexpr year_month operator+(const months& dm, const year_month& ym) noexcept;
521 template<class = detail::unspecified_month_disambiguator>
522 constexpr year_month operator-(const year_month& ym, const months& dm) noexcept;
524 constexpr months operator-(const year_month& x, const year_month& y) noexcept;
525 constexpr year_month operator+(const year_month& ym, const years& dy) noexcept;
526 constexpr year_month operator+(const years& dy, const year_month& ym) noexcept;
527 constexpr year_month operator-(const year_month& ym, const years& dy) noexcept;
529 template<class CharT, class Traits>
530 std::basic_ostream<CharT, Traits>&
531 operator<<(std::basic_ostream<CharT, Traits>& os, const year_month& ym);
537 gul14::date::month m_;
541 month_day() =
default;
542 constexpr month_day(
const gul14::date::month& m,
const gul14::date::day& d) noexcept;
544 constexpr gul14::date::month month() const noexcept;
545 constexpr
gul14::date::day day() const noexcept;
547 constexpr
bool ok() const noexcept;
550 constexpr
bool operator==(const month_day& x, const month_day& y) noexcept;
551 constexpr
bool operator!=(const month_day& x, const month_day& y) noexcept;
552 constexpr
bool operator< (const month_day& x, const month_day& y) noexcept;
553 constexpr
bool operator> (const month_day& x, const month_day& y) noexcept;
554 constexpr
bool operator<=(const month_day& x, const month_day& y) noexcept;
555 constexpr
bool operator>=(const month_day& x, const month_day& y) noexcept;
557 template<class CharT, class Traits>
558 std::basic_ostream<CharT, Traits>&
559 operator<<(std::basic_ostream<CharT, Traits>& os, const month_day& md);
565 gul14::date::month m_;
568 constexpr
explicit month_day_last(
const gul14::date::month& m) noexcept;
570 constexpr gul14::date::month month() const noexcept;
571 constexpr
bool ok() const noexcept;
574 constexpr
bool operator==(const month_day_last& x, const month_day_last& y) noexcept;
575 constexpr
bool operator!=(const month_day_last& x, const month_day_last& y) noexcept;
576 constexpr
bool operator< (const month_day_last& x, const month_day_last& y) noexcept;
577 constexpr
bool operator> (const month_day_last& x, const month_day_last& y) noexcept;
578 constexpr
bool operator<=(const month_day_last& x, const month_day_last& y) noexcept;
579 constexpr
bool operator>=(const month_day_last& x, const month_day_last& y) noexcept;
581 template<class CharT, class Traits>
582 std::basic_ostream<CharT, Traits>&
583 operator<<(std::basic_ostream<CharT, Traits>& os, const month_day_last& mdl);
589 gul14::date::month m_;
590 gul14::date::weekday_indexed wdi_;
592 constexpr month_weekday(
const gul14::date::month& m,
593 const gul14::date::weekday_indexed& wdi) noexcept;
595 constexpr gul14::date::month month() const noexcept;
596 constexpr
gul14::date::weekday_indexed weekday_indexed() const noexcept;
598 constexpr
bool ok() const noexcept;
601 constexpr
bool operator==(const month_weekday& x, const month_weekday& y) noexcept;
602 constexpr
bool operator!=(const month_weekday& x, const month_weekday& y) noexcept;
604 template<class CharT, class Traits>
605 std::basic_ostream<CharT, Traits>&
606 operator<<(std::basic_ostream<CharT, Traits>& os, const month_weekday& mwd);
610 class month_weekday_last
612 gul14::date::month m_;
613 gul14::date::weekday_last wdl_;
616 constexpr month_weekday_last(
const gul14::date::month& m,
617 const gul14::date::weekday_last& wd) noexcept;
619 constexpr gul14::date::month month() const noexcept;
620 constexpr
gul14::date::weekday_last weekday_last() const noexcept;
622 constexpr
bool ok() const noexcept;
626 bool operator==(const month_weekday_last& x, const month_weekday_last& y) noexcept;
628 bool operator!=(const month_weekday_last& x, const month_weekday_last& y) noexcept;
630 template<class CharT, class Traits>
631 std::basic_ostream<CharT, Traits>&
632 operator<<(std::basic_ostream<CharT, Traits>& os, const month_weekday_last& mwdl);
638 gul14::date::year y_;
639 gul14::date::month m_;
643 year_month_day() =
default;
644 constexpr year_month_day(
const gul14::date::year& y,
const gul14::date::month& m,
645 const gul14::date::day& d) noexcept;
646 constexpr year_month_day(
const year_month_day_last& ymdl) noexcept;
648 constexpr year_month_day(sys_days dp) noexcept;
649 constexpr
explicit year_month_day(local_days dp) noexcept;
651 template<
class = detail::unspecified_month_disambiguator>
652 constexpr year_month_day& operator+=(
const months& m) noexcept;
653 template<
class = detail::unspecified_month_disambiguator>
654 constexpr year_month_day& operator-=(
const months& m) noexcept;
655 constexpr year_month_day& operator+=(
const years& y) noexcept;
656 constexpr year_month_day& operator-=(
const years& y) noexcept;
658 constexpr gul14::date::year year() const noexcept;
659 constexpr
gul14::date::month month() const noexcept;
660 constexpr
gul14::date::day day() const noexcept;
662 constexpr operator sys_days() const noexcept;
663 constexpr explicit operator local_days() const noexcept;
664 constexpr
bool ok() const noexcept;
667 static constexpr year_month_day from_days(days dp) noexcept;
668 constexpr days to_days() const noexcept;
671 constexpr
bool operator==(const year_month_day& x, const year_month_day& y) noexcept;
672 constexpr
bool operator!=(const year_month_day& x, const year_month_day& y) noexcept;
673 constexpr
bool operator< (const year_month_day& x, const year_month_day& y) noexcept;
674 constexpr
bool operator> (const year_month_day& x, const year_month_day& y) noexcept;
675 constexpr
bool operator<=(const year_month_day& x, const year_month_day& y) noexcept;
676 constexpr
bool operator>=(const year_month_day& x, const year_month_day& y) noexcept;
678 template<class = detail::unspecified_month_disambiguator>
679 constexpr year_month_day operator+(const year_month_day& ymd, const months& dm) noexcept;
680 template<class = detail::unspecified_month_disambiguator>
681 constexpr year_month_day operator+(const months& dm, const year_month_day& ymd) noexcept;
682 template<class = detail::unspecified_month_disambiguator>
683 constexpr year_month_day operator-(const year_month_day& ymd, const months& dm) noexcept;
684 constexpr year_month_day operator+(const year_month_day& ymd, const years& dy) noexcept;
685 constexpr year_month_day operator+(const years& dy, const year_month_day& ymd) noexcept;
686 constexpr year_month_day operator-(const year_month_day& ymd, const years& dy) noexcept;
688 template<class CharT, class Traits>
689 std::basic_ostream<CharT, Traits>&
690 operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_day& ymd);
694 class year_month_day_last
696 gul14::date::year y_;
697 gul14::date::month_day_last mdl_;
700 constexpr year_month_day_last(
const gul14::date::year& y,
701 const gul14::date::month_day_last& mdl) noexcept;
703 template<
class = detail::unspecified_month_disambiguator>
704 constexpr year_month_day_last& operator+=(
const months& m) noexcept;
705 template<
class = detail::unspecified_month_disambiguator>
706 constexpr year_month_day_last& operator-=(
const months& m) noexcept;
707 constexpr year_month_day_last& operator+=(
const years& y) noexcept;
708 constexpr year_month_day_last& operator-=(
const years& y) noexcept;
710 constexpr gul14::date::year year() const noexcept;
711 constexpr
gul14::date::month month() const noexcept;
712 constexpr
gul14::date::month_day_last month_day_last() const noexcept;
713 constexpr
gul14::date::day day() const noexcept;
715 constexpr operator sys_days() const noexcept;
716 constexpr explicit operator local_days() const noexcept;
717 constexpr
bool ok() const noexcept;
721 bool operator==(const year_month_day_last& x, const year_month_day_last& y) noexcept;
723 bool operator!=(const year_month_day_last& x, const year_month_day_last& y) noexcept;
725 bool operator< (const year_month_day_last& x, const year_month_day_last& y) noexcept;
727 bool operator> (const year_month_day_last& x, const year_month_day_last& y) noexcept;
729 bool operator<=(const year_month_day_last& x, const year_month_day_last& y) noexcept;
731 bool operator>=(const year_month_day_last& x, const year_month_day_last& y) noexcept;
733 template<class = detail::unspecified_month_disambiguator>
736 operator+(const year_month_day_last& ymdl, const months& dm) noexcept;
738 template<class = detail::unspecified_month_disambiguator>
741 operator+(const months& dm, const year_month_day_last& ymdl) noexcept;
745 operator+(const year_month_day_last& ymdl, const years& dy) noexcept;
749 operator+(const years& dy, const year_month_day_last& ymdl) noexcept;
751 template<class = detail::unspecified_month_disambiguator>
754 operator-(const year_month_day_last& ymdl, const months& dm) noexcept;
758 operator-(const year_month_day_last& ymdl, const years& dy) noexcept;
760 template<class CharT, class Traits>
761 std::basic_ostream<CharT, Traits>&
762 operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_day_last& ymdl);
766 class year_month_weekday
768 gul14::date::year y_;
769 gul14::date::month m_;
770 gul14::date::weekday_indexed wdi_;
773 year_month_weekday() =
default;
774 constexpr year_month_weekday(
const gul14::date::year& y,
const gul14::date::month& m,
775 const gul14::date::weekday_indexed& wdi) noexcept;
776 constexpr year_month_weekday(
const sys_days& dp) noexcept;
777 constexpr
explicit year_month_weekday(
const local_days& dp) noexcept;
779 template<
class = detail::unspecified_month_disambiguator>
780 constexpr year_month_weekday& operator+=(
const months& m) noexcept;
781 template<
class = detail::unspecified_month_disambiguator>
782 constexpr year_month_weekday& operator-=(
const months& m) noexcept;
783 constexpr year_month_weekday& operator+=(
const years& y) noexcept;
784 constexpr year_month_weekday& operator-=(
const years& y) noexcept;
786 constexpr gul14::date::year year() const noexcept;
787 constexpr
gul14::date::month month() const noexcept;
788 constexpr
gul14::date::weekday weekday() const noexcept;
789 constexpr
unsigned index() const noexcept;
790 constexpr
gul14::date::weekday_indexed weekday_indexed() const noexcept;
792 constexpr operator sys_days() const noexcept;
793 constexpr explicit operator local_days() const noexcept;
794 constexpr
bool ok() const noexcept;
797 static constexpr year_month_weekday from_days(days dp) noexcept;
798 constexpr days to_days() const noexcept;
802 bool operator==(const year_month_weekday& x, const year_month_weekday& y) noexcept;
804 bool operator!=(const year_month_weekday& x, const year_month_weekday& y) noexcept;
806 template<class = detail::unspecified_month_disambiguator>
809 operator+(const year_month_weekday& ymwd, const months& dm) noexcept;
811 template<class = detail::unspecified_month_disambiguator>
814 operator+(const months& dm, const year_month_weekday& ymwd) noexcept;
818 operator+(const year_month_weekday& ymwd, const years& dy) noexcept;
822 operator+(const years& dy, const year_month_weekday& ymwd) noexcept;
824 template<class = detail::unspecified_month_disambiguator>
827 operator-(const year_month_weekday& ymwd, const months& dm) noexcept;
831 operator-(const year_month_weekday& ymwd, const years& dy) noexcept;
833 template<class CharT, class Traits>
834 std::basic_ostream<CharT, Traits>&
835 operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday& ymwdi);
839 class year_month_weekday_last
841 gul14::date::year y_;
842 gul14::date::month m_;
843 gul14::date::weekday_last wdl_;
846 constexpr year_month_weekday_last(
const gul14::date::year& y,
const gul14::date::month& m,
847 const gul14::date::weekday_last& wdl) noexcept;
849 template<
class = detail::unspecified_month_disambiguator>
850 constexpr year_month_weekday_last& operator+=(
const months& m) noexcept;
851 template<
class = detail::unspecified_month_disambiguator>
852 constexpr year_month_weekday_last& operator-=(
const months& m) noexcept;
853 constexpr year_month_weekday_last& operator+=(
const years& y) noexcept;
854 constexpr year_month_weekday_last& operator-=(
const years& y) noexcept;
856 constexpr gul14::date::year year() const noexcept;
857 constexpr
gul14::date::month month() const noexcept;
858 constexpr
gul14::date::weekday weekday() const noexcept;
859 constexpr
gul14::date::weekday_last weekday_last() const noexcept;
861 constexpr operator sys_days() const noexcept;
862 constexpr explicit operator local_days() const noexcept;
863 constexpr
bool ok() const noexcept;
866 constexpr days to_days() const noexcept;
871 operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) noexcept;
875 operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) noexcept;
877 template<class = detail::unspecified_month_disambiguator>
879 year_month_weekday_last
880 operator+(const year_month_weekday_last& ymwdl, const months& dm) noexcept;
882 template<class = detail::unspecified_month_disambiguator>
884 year_month_weekday_last
885 operator+(const months& dm, const year_month_weekday_last& ymwdl) noexcept;
888 year_month_weekday_last
889 operator+(const year_month_weekday_last& ymwdl, const years& dy) noexcept;
892 year_month_weekday_last
893 operator+(const years& dy, const year_month_weekday_last& ymwdl) noexcept;
895 template<class = detail::unspecified_month_disambiguator>
897 year_month_weekday_last
898 operator-(const year_month_weekday_last& ymwdl, const months& dm) noexcept;
901 year_month_weekday_last
902 operator-(const year_month_weekday_last& ymwdl, const years& dy) noexcept;
904 template<class CharT, class Traits>
905 std::basic_ostream<CharT, Traits>&
906 operator<<(std::basic_ostream<CharT, Traits>& os, const year_month_weekday_last& ymwdl);
908 #if !defined(_MSC_VER) || (_MSC_VER >= 1900)
909 inline namespace literals
912 constexpr gul14::date::day
operator "" _d(
unsigned long long d) noexcept;
913 constexpr gul14::date::year
operator "" _y(
unsigned long long y) noexcept;
941 template <
class T,
class = std::
void_t<>>
947 struct is_clock<T, std::
void_t<decltype(T::now()), typename T::rep, typename T::period,
948 typename T::duration, typename T::time_point,
949 decltype(T::is_steady)>>
953 template<
class T>
inline constexpr
bool is_clock_v = is_clock<T>::value;
964 template<
class CharT,
class Traits = std::
char_traits<CharT>>
968 std::basic_ios<CharT, Traits>& is_;
970 std::ios::fmtflags flags_;
971 std::streamsize precision_;
972 std::streamsize width_;
973 std::basic_ostream<CharT, Traits>* tie_;
981 is_.precision(precision_);
987 save_istream(
const save_istream&) =
delete;
988 save_istream& operator=(
const save_istream&) =
delete;
990 explicit save_istream(std::basic_ios<CharT, Traits>& is)
994 , precision_(is.precision())
995 , width_(is.width(0))
996 , tie_(is.tie(nullptr))
1004 template<
class CharT,
class Traits = std::
char_traits<CharT>>
1006 :
private save_istream<CharT, Traits>
1011 if ((this->flags_ & std::ios::unitbuf) &&
1012 #
if HAS_UNCAUGHT_EXCEPTIONS
1013 std::uncaught_exceptions() == 0 &&
1015 !std::uncaught_exception() &&
1018 this->is_.rdbuf()->pubsync();
1021 save_ostream(
const save_ostream&) =
delete;
1022 save_ostream& operator=(
const save_ostream&) =
delete;
1024 explicit save_ostream(std::basic_ios<CharT, Traits>& os)
1025 : save_istream<CharT, Traits>(os)
1031 struct choose_trunc_type
1033 static const int digits = std::numeric_limits<T>::digits;
1034 using type =
typename std::conditional
1038 typename std::conditional
1042 #ifdef __SIZEOF_INT128__
1053 typename std::enable_if
1055 !std::chrono::treat_as_floating_point<T>::value,
1065 typename std::enable_if
1067 std::chrono::treat_as_floating_point<T>::value,
1072 using std::numeric_limits;
1073 using I =
typename choose_trunc_type<T>::type;
1074 constexpr
const auto digits = numeric_limits<T>::digits;
1075 static_assert(digits < numeric_limits<I>::digits,
"");
1076 constexpr
const auto max = I{1} << (digits-1);
1077 constexpr
const auto min = -max;
1078 const auto negative = t < T{0};
1079 if (min <= t && t <= max && t != 0 && t == t)
1081 t =
static_cast<T
>(
static_cast<I
>(t));
1082 if (t == 0 && negative)
1088 template <std::
intmax_t Xp, std::
intmax_t Yp>
1091 static const std::intmax_t value = static_gcd<Yp, Xp % Yp>::value;
1094 template <std::
intmax_t Xp>
1095 struct static_gcd<Xp, 0>
1097 static const std::intmax_t value = Xp;
1101 struct static_gcd<0, 0>
1103 static const std::intmax_t value = 1;
1106 template <
class R1,
class R2>
1110 static const std::intmax_t gcd_n1_n2 = static_gcd<R1::num, R2::num>::value;
1111 static const std::intmax_t gcd_d1_d2 = static_gcd<R1::den, R2::den>::value;
1112 static const std::intmax_t n1 = R1::num / gcd_n1_n2;
1113 static const std::intmax_t d1 = R1::den / gcd_d1_d2;
1114 static const std::intmax_t n2 = R2::num / gcd_n1_n2;
1115 static const std::intmax_t d2 = R2::den / gcd_d1_d2;
1116 #ifdef __cpp_constexpr
1117 static const std::intmax_t max = std::numeric_limits<std::intmax_t>::max();
1119 static const std::intmax_t max = LLONG_MAX;
1122 template <std::
intmax_t Xp, std::
intmax_t Yp,
bool overflow>
1125 static const std::intmax_t value = Xp * Yp;
1128 template <std::
intmax_t Xp, std::
intmax_t Yp>
1129 struct mul<Xp, Yp, true>
1131 static const std::intmax_t value = 1;
1135 static const bool value = (n1 <= max / d2) && (n2 <= max / d1);
1136 typedef std::ratio<mul<n1, d2, !value>::value,
1137 mul<n2, d1, !value>::value> type;
1143 template <
class To,
class Rep,
class Period>
1145 typename std::enable_if
1147 detail::no_overflow<Period, typename To::period>::value,
1150 trunc(
const std::chrono::duration<Rep, Period>& d)
1152 return To{detail::trunc(std::chrono::duration_cast<To>(d).count())};
1155 template <
class To,
class Rep,
class Period>
1157 typename std::enable_if
1159 !detail::no_overflow<Period, typename To::period>::value,
1162 trunc(
const std::chrono::duration<Rep, Period>& d)
1164 using std::chrono::duration_cast;
1165 using std::chrono::duration;
1166 using rep =
typename std::common_type<Rep, typename To::rep>::type;
1167 return To{detail::trunc(duration_cast<To>(duration_cast<duration<rep>>(d)).count())};
1170 #ifndef HAS_CHRONO_ROUNDING
1171 # if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023918 || (_MSC_FULL_VER >= 190000000 && defined (__clang__)))
1172 # define HAS_CHRONO_ROUNDING 1
1173 # elif defined(__cpp_lib_chrono) && __cplusplus > 201402 && __cpp_lib_chrono >= 201510
1174 # define HAS_CHRONO_ROUNDING 1
1175 # elif defined(_LIBCPP_VERSION) && __cplusplus > 201402 && _LIBCPP_VERSION >= 3800
1176 # define HAS_CHRONO_ROUNDING 1
1178 # define HAS_CHRONO_ROUNDING 0
1182 #if HAS_CHRONO_ROUNDING == 0
1185 template <
class To,
class Rep,
class Period>
1187 typename std::enable_if
1189 detail::no_overflow<Period, typename To::period>::value,
1192 floor(
const std::chrono::duration<Rep, Period>& d)
1194 auto t = trunc<To>(d);
1200 template <
class To,
class Rep,
class Period>
1202 typename std::enable_if
1204 !detail::no_overflow<Period, typename To::period>::value,
1207 floor(
const std::chrono::duration<Rep, Period>& d)
1209 using rep =
typename std::common_type<Rep, typename To::rep>::type;
1210 return floor<To>(floor<std::chrono::duration<rep>>(d));
1214 template <
class To,
class Rep,
class Period>
1217 round(
const std::chrono::duration<Rep, Period>& d)
1219 auto t0 = floor<To>(d);
1220 auto t1 = t0 + To{1};
1221 if (t1 == To{0} && t0 < To{0})
1223 auto diff0 = d - t0;
1224 auto diff1 = t1 - d;
1227 if (t0 - trunc<To>(t0/2)*2 == To{0})
1237 template <
class To,
class Rep,
class Period>
1240 ceil(
const std::chrono::duration<Rep, Period>& d)
1242 auto t = trunc<To>(d);
1248 template <
class Rep,
class Period,
1249 class =
typename std::enable_if
1251 std::numeric_limits<Rep>::is_signed
1254 std::chrono::duration<Rep, Period>
1255 abs(std::chrono::duration<Rep, Period> d)
1257 return d >= d.zero() ? d : -d;
1261 template <
class To,
class Clock,
class FromDuration>
1263 std::chrono::time_point<Clock, To>
1264 floor(
const std::chrono::time_point<Clock, FromDuration>& tp)
1266 using std::chrono::time_point;
1267 return time_point<Clock, To>{gul14::date::floor<To>(tp.time_since_epoch())};
1271 template <
class To,
class Clock,
class FromDuration>
1273 std::chrono::time_point<Clock, To>
1274 round(
const std::chrono::time_point<Clock, FromDuration>& tp)
1276 using std::chrono::time_point;
1277 return time_point<Clock, To>{round<To>(tp.time_since_epoch())};
1281 template <
class To,
class Clock,
class FromDuration>
1283 std::chrono::time_point<Clock, To>
1284 ceil(
const std::chrono::time_point<Clock, FromDuration>& tp)
1286 using std::chrono::time_point;
1287 return time_point<Clock, To>{ceil<To>(tp.time_since_epoch())};
1292 using std::chrono::floor;
1293 using std::chrono::ceil;
1294 using std::chrono::round;
1302 template <
class To,
class Rep,
class Period>
1304 typename std::enable_if
1306 !std::chrono::treat_as_floating_point<typename To::rep>::value,
1309 round_i(
const std::chrono::duration<Rep, Period>& d)
1311 return round<To>(d);
1314 template <
class To,
class Rep,
class Period>
1316 typename std::enable_if
1318 std::chrono::treat_as_floating_point<typename To::rep>::value,
1321 round_i(
const std::chrono::duration<Rep, Period>& d)
1326 template <
class To,
class Clock,
class FromDuration>
1328 std::chrono::time_point<Clock, To>
1329 round_i(
const std::chrono::time_point<Clock, FromDuration>& tp)
1331 using std::chrono::time_point;
1332 return time_point<Clock, To>{round_i<To>(tp.time_since_epoch())};
1338 template <
class To,
class Clock,
class FromDuration>
1340 std::chrono::time_point<Clock, To>
1341 trunc(
const std::chrono::time_point<Clock, FromDuration>& tp)
1343 using std::chrono::time_point;
1344 return time_point<Clock, To>{trunc<To>(tp.time_since_epoch())};
1349 constexpr
inline day::day(
unsigned d) noexcept : d_(
static_cast<decltype(d_)
>(d)) {}
1350 constexpr
inline day& day::operator++() noexcept {++d_;
return *
this;}
1351 constexpr
inline day day::operator++(
int) noexcept {
auto tmp(*
this); ++(*this);
return tmp;}
1352 constexpr
inline day& day::operator--() noexcept {--d_;
return *
this;}
1353 constexpr
inline day day::operator--(
int) noexcept {
auto tmp(*
this); --(*this);
return tmp;}
1354 constexpr
inline day& day::operator+=(
const days& d) noexcept {*
this = *
this + d;
return *
this;}
1355 constexpr
inline day& day::operator-=(
const days& d) noexcept {*
this = *
this - d;
return *
this;}
1356 constexpr
inline day::operator unsigned() const noexcept {
return d_;}
1357 constexpr
inline bool day::ok() const noexcept {
return 1 <= d_ && d_ <= 31;}
1359 constexpr
inline bool
1360 operator==(
const day& x,
const day& y) noexcept
1362 return static_cast<unsigned>(x) ==
static_cast<unsigned>(y);
1365 constexpr
inline bool
1366 operator!=(
const day& x,
const day& y) noexcept
1371 constexpr
inline bool
1372 operator<(
const day& x,
const day& y) noexcept
1374 return static_cast<unsigned>(x) <
static_cast<unsigned>(y);
1377 constexpr
inline bool
1378 operator>(
const day& x,
const day& y) noexcept
1383 constexpr
inline bool
1384 operator<=(
const day& x,
const day& y) noexcept
1389 constexpr
inline bool
1390 operator>=(
const day& x,
const day& y) noexcept
1395 constexpr
inline days
1396 operator-(
const day& x,
const day& y) noexcept
1398 return days{
static_cast<days::rep
>(
static_cast<unsigned>(x)
1399 -
static_cast<unsigned>(y))};
1402 constexpr
inline day
1403 operator+(
const day& x,
const days& y) noexcept
1405 return day{
static_cast<unsigned>(x) +
static_cast<unsigned>(y.count())};
1408 constexpr
inline day
1409 operator+(
const days& x,
const day& y) noexcept
1414 constexpr
inline day
1415 operator-(
const day& x,
const days& y) noexcept
1423 template<
class CharT,
class Traits>
1424 std::basic_ostream<CharT, Traits>&
1425 low_level_fmt(std::basic_ostream<CharT, Traits>& os,
const day& d)
1427 detail::save_ostream<CharT, Traits> _(os);
1429 os.flags(std::ios::dec | std::ios::right);
1431 os << static_cast<unsigned>(d);
1437 template<
class CharT,
class Traits>
1439 std::basic_ostream<CharT, Traits>&
1440 operator<<(std::basic_ostream<CharT, Traits>& os,
const day& d)
1442 detail::low_level_fmt(os, d);
1444 os <<
" is not a valid day";
1450 constexpr
inline month::month(
unsigned m) noexcept : m_(
static_cast<decltype(m_)
>(m)) {}
1451 constexpr
inline month& month::operator++() noexcept {*
this += months{1};
return *
this;}
1452 constexpr
inline month month::operator++(
int) noexcept {
auto tmp(*
this); ++(*this);
return tmp;}
1453 constexpr
inline month& month::operator--() noexcept {*
this -= months{1};
return *
this;}
1454 constexpr
inline month month::operator--(
int) noexcept {
auto tmp(*
this); --(*this);
return tmp;}
1456 constexpr
inline month&
1457 month::operator+=(
const months& m) noexcept
1463 constexpr
inline month&
1464 month::operator-=(
const months& m) noexcept
1470 constexpr
inline month::operator unsigned() const noexcept {
return m_;}
1471 constexpr
inline bool month::ok() const noexcept {
return 1 <= m_ && m_ <= 12;}
1473 constexpr
inline bool
1474 operator==(
const month& x,
const month& y) noexcept
1476 return static_cast<unsigned>(x) ==
static_cast<unsigned>(y);
1479 constexpr
inline bool
1480 operator!=(
const month& x,
const month& y) noexcept
1485 constexpr
inline bool
1486 operator<(
const month& x,
const month& y) noexcept
1488 return static_cast<unsigned>(x) <
static_cast<unsigned>(y);
1491 constexpr
inline bool
1492 operator>(
const month& x,
const month& y) noexcept
1497 constexpr
inline bool
1498 operator<=(
const month& x,
const month& y) noexcept
1503 constexpr
inline bool
1504 operator>=(
const month& x,
const month& y) noexcept
1509 constexpr
inline months
1510 operator-(
const month& x,
const month& y) noexcept
1512 auto const d =
static_cast<unsigned>(x) -
static_cast<unsigned>(y);
1513 return months(d <= 11 ? d : d + 12);
1516 constexpr
inline month
1517 operator+(
const month& x,
const months& y) noexcept
1519 auto const mu =
static_cast<long long>(
static_cast<unsigned>(x)) + y.count() - 1;
1520 auto const yr = (mu >= 0 ? mu : mu-11) / 12;
1521 return month{
static_cast<unsigned>(mu - yr * 12 + 1)};
1524 constexpr
inline month
1525 operator+(
const months& x,
const month& y) noexcept
1530 constexpr
inline month
1531 operator-(
const month& x,
const months& y) noexcept
1539 template<
class CharT,
class Traits>
1540 std::basic_ostream<CharT, Traits>&
1541 low_level_fmt(std::basic_ostream<CharT, Traits>& os,
const month& m)
1545 CharT fmt[] = {
'%',
'b', 0};
1546 os << format(os.getloc(), fmt, m);
1549 os << static_cast<unsigned>(m);
1555 template<
class CharT,
class Traits>
1557 std::basic_ostream<CharT, Traits>&
1558 operator<<(std::basic_ostream<CharT, Traits>& os,
const month& m)
1560 detail::low_level_fmt(os, m);
1562 os <<
" is not a valid month";
1568 constexpr
inline year::year(
int y) noexcept : y_(
static_cast<decltype(y_)
>(y)) {}
1569 constexpr
inline year& year::operator++() noexcept {++y_;
return *
this;}
1570 constexpr
inline year year::operator++(
int) noexcept {
auto tmp(*
this); ++(*this);
return tmp;}
1571 constexpr
inline year& year::operator--() noexcept {--y_;
return *
this;}
1572 constexpr
inline year year::operator--(
int) noexcept {
auto tmp(*
this); --(*this);
return tmp;}
1573 constexpr
inline year& year::operator+=(
const years& y) noexcept {*
this = *
this + y;
return *
this;}
1574 constexpr
inline year& year::operator-=(
const years& y) noexcept {*
this = *
this - y;
return *
this;}
1575 constexpr
inline year year::operator-() const noexcept {
return year{-y_};}
1576 constexpr
inline year year::operator+() const noexcept {
return *
this;}
1578 constexpr
inline bool
1579 year::is_leap() const noexcept
1581 return y_ % 4 == 0 && (y_ % 100 != 0 || y_ % 400 == 0);
1584 constexpr
inline year::operator int() const noexcept {
return y_;}
1586 constexpr
inline bool
1587 year::ok() const noexcept
1589 return y_ != std::numeric_limits<short>::min();
1592 constexpr
inline bool
1593 operator==(
const year& x,
const year& y) noexcept
1595 return static_cast<int>(x) ==
static_cast<int>(y);
1598 constexpr
inline bool
1599 operator!=(
const year& x,
const year& y) noexcept
1604 constexpr
inline bool
1605 operator<(
const year& x,
const year& y) noexcept
1607 return static_cast<int>(x) <
static_cast<int>(y);
1610 constexpr
inline bool
1611 operator>(
const year& x,
const year& y) noexcept
1616 constexpr
inline bool
1617 operator<=(
const year& x,
const year& y) noexcept
1622 constexpr
inline bool
1623 operator>=(
const year& x,
const year& y) noexcept
1628 constexpr
inline years
1629 operator-(
const year& x,
const year& y) noexcept
1631 return years{
static_cast<int>(x) -
static_cast<int>(y)};
1634 constexpr
inline year
1635 operator+(
const year& x,
const years& y) noexcept
1637 return year{
static_cast<int>(x) + y.count()};
1640 constexpr
inline year
1641 operator+(
const years& x,
const year& y) noexcept
1646 constexpr
inline year
1647 operator-(
const year& x,
const years& y) noexcept
1649 return year{
static_cast<int>(x) - y.count()};
1655 template<
class CharT,
class Traits>
1656 std::basic_ostream<CharT, Traits>&
1657 low_level_fmt(std::basic_ostream<CharT, Traits>& os,
const year& y)
1659 detail::save_ostream<CharT, Traits> _(os);
1661 os.flags(std::ios::dec | std::ios::internal);
1662 os.width(4 + (y < year{0}));
1663 os.imbue(std::locale::classic());
1664 os << static_cast<int>(y);
1670 template<
class CharT,
class Traits>
1672 std::basic_ostream<CharT, Traits>&
1673 operator<<(std::basic_ostream<CharT, Traits>& os,
const year& y)
1675 detail::low_level_fmt(os, y);
1677 os <<
" is not a valid year";
1685 weekday::weekday_from_days(
int z) noexcept
1687 auto u =
static_cast<unsigned>(z);
1688 return static_cast<unsigned char>(z >= -4 ? (u+4) % 7 : u % 7);
1692 weekday::weekday(
unsigned wd) noexcept
1693 : wd_(
static_cast<decltype(wd_)
>(wd != 7 ? wd : 0))
1697 weekday::weekday(
const sys_days& dp) noexcept
1698 : wd_(weekday_from_days(dp.time_since_epoch().count()))
1702 weekday::weekday(
const local_days& dp) noexcept
1703 : wd_(weekday_from_days(dp.time_since_epoch().count()))
1706 constexpr
inline weekday& weekday::operator++() noexcept {*
this += days{1};
return *
this;}
1707 constexpr
inline weekday weekday::operator++(
int) noexcept {
auto tmp(*
this); ++(*this);
return tmp;}
1708 constexpr
inline weekday& weekday::operator--() noexcept {*
this -= days{1};
return *
this;}
1709 constexpr
inline weekday weekday::operator--(
int) noexcept {
auto tmp(*
this); --(*this);
return tmp;}
1711 constexpr
inline weekday&
1712 weekday::operator+=(
const days& d) noexcept
1718 constexpr
inline weekday&
1719 weekday::operator-=(
const days& d) noexcept
1725 constexpr
inline bool weekday::ok() const noexcept {
return wd_ <= 6;}
1727 constexpr
inline unsigned weekday::c_encoding() const noexcept
1729 return unsigned{wd_};
1732 constexpr
inline unsigned weekday::iso_encoding() const noexcept
1734 return unsigned{((wd_ == 0u) ? 7u : wd_)};
1737 constexpr
inline bool
1738 operator==(
const weekday& x,
const weekday& y) noexcept
1740 return x.wd_ == y.wd_;
1743 constexpr
inline bool
1744 operator!=(
const weekday& x,
const weekday& y) noexcept
1749 constexpr
inline days
1750 operator-(
const weekday& x,
const weekday& y) noexcept
1752 auto const wdu = x.wd_ - y.wd_;
1753 auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7;
1754 return days{wdu - wk * 7};
1757 constexpr
inline weekday
1758 operator+(
const weekday& x,
const days& y) noexcept
1760 auto const wdu =
static_cast<long long>(
static_cast<unsigned>(x.wd_)) + y.count();
1761 auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7;
1762 return weekday{
static_cast<unsigned>(wdu - wk * 7)};
1765 constexpr
inline weekday
1766 operator+(
const days& x,
const weekday& y) noexcept
1771 constexpr
inline weekday
1772 operator-(
const weekday& x,
const days& y) noexcept
1780 template<
class CharT,
class Traits>
1781 std::basic_ostream<CharT, Traits>&
1782 low_level_fmt(std::basic_ostream<CharT, Traits>& os,
const weekday& wd)
1786 CharT fmt[] = {
'%',
'a', 0};
1787 os << format(fmt, wd);
1790 os << wd.c_encoding();
1796 template<
class CharT,
class Traits>
1798 std::basic_ostream<CharT, Traits>&
1799 operator<<(std::basic_ostream<CharT, Traits>& os,
const weekday& wd)
1801 detail::low_level_fmt(os, wd);
1803 os <<
" is not a valid weekday";
1807 #if !defined(_MSC_VER) || (_MSC_VER >= 1900)
1808 inline namespace literals
1813 operator "" _d(
unsigned long long d) noexcept
1815 return gul14::date::day{
static_cast<unsigned>(d)};
1820 operator "" _y(
unsigned long long y) noexcept
1822 return gul14::date::year(
static_cast<int>(y));
1826 constexpr
const gul14::date::last_spec last{};
1828 constexpr
const gul14::date::month jan{1};
1829 constexpr
const gul14::date::month feb{2};
1830 constexpr
const gul14::date::month mar{3};
1831 constexpr
const gul14::date::month apr{4};
1832 constexpr
const gul14::date::month may{5};
1833 constexpr
const gul14::date::month jun{6};
1834 constexpr
const gul14::date::month jul{7};
1835 constexpr
const gul14::date::month aug{8};
1836 constexpr
const gul14::date::month sep{9};
1837 constexpr
const gul14::date::month oct{10};
1838 constexpr
const gul14::date::month nov{11};
1839 constexpr
const gul14::date::month dec{12};
1841 constexpr
const gul14::date::weekday sun{0u};
1842 constexpr
const gul14::date::weekday mon{1u};
1843 constexpr
const gul14::date::weekday tue{2u};
1844 constexpr
const gul14::date::weekday wed{3u};
1845 constexpr
const gul14::date::weekday thu{4u};
1846 constexpr
const gul14::date::weekday fri{5u};
1847 constexpr
const gul14::date::weekday sat{6u};
1849 #if !defined(_MSC_VER) || (_MSC_VER >= 1900)
1853 constexpr
const gul14::date::month January{1};
1854 constexpr
const gul14::date::month February{2};
1855 constexpr
const gul14::date::month March{3};
1856 constexpr
const gul14::date::month April{4};
1857 constexpr
const gul14::date::month May{5};
1858 constexpr
const gul14::date::month June{6};
1859 constexpr
const gul14::date::month July{7};
1860 constexpr
const gul14::date::month August{8};
1861 constexpr
const gul14::date::month September{9};
1862 constexpr
const gul14::date::month October{10};
1863 constexpr
const gul14::date::month November{11};
1864 constexpr
const gul14::date::month December{12};
1866 constexpr
const gul14::date::weekday Monday{1};
1867 constexpr
const gul14::date::weekday Tuesday{2};
1868 constexpr
const gul14::date::weekday Wednesday{3};
1869 constexpr
const gul14::date::weekday Thursday{4};
1870 constexpr
const gul14::date::weekday Friday{5};
1871 constexpr
const gul14::date::weekday Saturday{6};
1872 constexpr
const gul14::date::weekday Sunday{7};
1878 weekday_indexed::weekday() const noexcept
1880 return gul14::date::weekday{
static_cast<unsigned>(wd_)};
1883 constexpr
inline unsigned weekday_indexed::index() const noexcept {
return index_;}
1885 constexpr
inline bool
1886 weekday_indexed::ok() const noexcept
1888 return weekday().ok() && 1 <= index_ && index_ <= 5;
1892 # pragma GCC diagnostic push
1893 # pragma GCC diagnostic ignored "-Wconversion"
1897 weekday_indexed::weekday_indexed(
const gul14::date::weekday& wd,
unsigned index) noexcept
1898 : wd_(
static_cast<decltype(wd_)
>(
static_cast<unsigned>(wd.wd_)))
1899 , index_(
static_cast<decltype(index_)
>(index))
1903 # pragma GCC diagnostic pop
1909 template<
class CharT,
class Traits>
1910 std::basic_ostream<CharT, Traits>&
1911 low_level_fmt(std::basic_ostream<CharT, Traits>& os,
const weekday_indexed& wdi)
1913 return low_level_fmt(os, wdi.weekday()) <<
'[' << wdi.index() <<
']';
1918 template<
class CharT,
class Traits>
1920 std::basic_ostream<CharT, Traits>&
1921 operator<<(std::basic_ostream<CharT, Traits>& os,
const weekday_indexed& wdi)
1923 detail::low_level_fmt(os, wdi);
1925 os <<
" is not a valid weekday_indexed";
1929 constexpr
inline weekday_indexed
1930 weekday::operator[](
unsigned index)
const noexcept
1932 return {*
this, index};
1935 constexpr
inline bool
1936 operator==(
const weekday_indexed& x,
const weekday_indexed& y) noexcept
1938 return x.weekday() == y.weekday() && x.index() == y.index();
1941 constexpr
inline bool
1942 operator!=(
const weekday_indexed& x,
const weekday_indexed& y) noexcept
1949 constexpr
inline gul14::date::weekday weekday_last::weekday() const noexcept {
return wd_;}
1950 constexpr
inline bool weekday_last::ok() const noexcept {
return wd_.ok();}
1951 constexpr
inline weekday_last::weekday_last(
const gul14::date::weekday& wd) noexcept : wd_(wd) {}
1953 constexpr
inline bool
1954 operator==(
const weekday_last& x,
const weekday_last& y) noexcept
1956 return x.weekday() == y.weekday();
1959 constexpr
inline bool
1960 operator!=(
const weekday_last& x,
const weekday_last& y) noexcept
1968 template<
class CharT,
class Traits>
1969 std::basic_ostream<CharT, Traits>&
1970 low_level_fmt(std::basic_ostream<CharT, Traits>& os,
const weekday_last& wdl)
1972 return low_level_fmt(os, wdl.weekday()) <<
"[last]";
1977 template<
class CharT,
class Traits>
1979 std::basic_ostream<CharT, Traits>&
1980 operator<<(std::basic_ostream<CharT, Traits>& os,
const weekday_last& wdl)
1982 detail::low_level_fmt(os, wdl);
1984 os <<
" is not a valid weekday_last";
1990 weekday::operator[](last_spec)
const noexcept
1992 return weekday_last{*
this};
1998 year_month::year_month(
const gul14::date::year& y,
const gul14::date::month& m) noexcept
2003 constexpr
inline year year_month::year() const noexcept {
return y_;}
2004 constexpr
inline month year_month::month() const noexcept {
return m_;}
2005 constexpr
inline bool year_month::ok() const noexcept {
return y_.ok() && m_.ok();}
2008 constexpr
inline year_month&
2009 year_month::operator+=(
const months& dm) noexcept
2016 constexpr
inline year_month&
2017 year_month::operator-=(
const months& dm) noexcept
2023 constexpr
inline year_month&
2024 year_month::operator+=(
const years& dy) noexcept
2030 constexpr
inline year_month&
2031 year_month::operator-=(
const years& dy) noexcept
2037 constexpr
inline bool
2038 operator==(
const year_month& x,
const year_month& y) noexcept
2040 return x.year() == y.year() && x.month() == y.month();
2043 constexpr
inline bool
2044 operator!=(
const year_month& x,
const year_month& y) noexcept
2049 constexpr
inline bool
2050 operator<(
const year_month& x,
const year_month& y) noexcept
2052 return x.year() < y.year() ? true
2053 : (x.year() > y.year() ? false
2054 : (x.month() < y.month()));
2057 constexpr
inline bool
2058 operator>(
const year_month& x,
const year_month& y) noexcept
2063 constexpr
inline bool
2064 operator<=(
const year_month& x,
const year_month& y) noexcept
2069 constexpr
inline bool
2070 operator>=(
const year_month& x,
const year_month& y) noexcept
2076 constexpr
inline year_month
2077 operator+(
const year_month& ym,
const months& dm) noexcept
2079 auto dmi =
static_cast<int>(
static_cast<unsigned>(ym.month())) - 1 + dm.count();
2080 auto dy = (dmi >= 0 ? dmi : dmi-11) / 12;
2081 dmi = dmi - dy * 12 + 1;
2082 return (ym.year() + years(dy)) / month(
static_cast<unsigned>(dmi));
2086 constexpr
inline year_month
2087 operator+(
const months& dm,
const year_month& ym) noexcept
2093 constexpr
inline year_month
2094 operator-(
const year_month& ym,
const months& dm) noexcept
2099 constexpr
inline months
2100 operator-(
const year_month& x,
const year_month& y) noexcept
2102 return (x.year() - y.year()) +
2103 months(
static_cast<unsigned>(x.month()) -
static_cast<unsigned>(y.month()));
2106 constexpr
inline year_month
2107 operator+(
const year_month& ym,
const years& dy) noexcept
2109 return (ym.year() + dy) / ym.month();
2112 constexpr
inline year_month
2113 operator+(
const years& dy,
const year_month& ym) noexcept
2118 constexpr
inline year_month
2119 operator-(
const year_month& ym,
const years& dy) noexcept
2127 template<
class CharT,
class Traits>
2128 std::basic_ostream<CharT, Traits>&
2129 low_level_fmt(std::basic_ostream<CharT, Traits>& os,
const year_month& ym)
2131 low_level_fmt(os, ym.year()) <<
'/';
2132 return low_level_fmt(os, ym.month());
2137 template<
class CharT,
class Traits>
2139 std::basic_ostream<CharT, Traits>&
2140 operator<<(std::basic_ostream<CharT, Traits>& os,
const year_month& ym)
2142 detail::low_level_fmt(os, ym);
2144 os <<
" is not a valid year_month";
2151 month_day::month_day(
const gul14::date::month& m,
const gul14::date::day& d) noexcept
2156 constexpr
inline gul14::date::month month_day::month() const noexcept {
return m_;}
2157 constexpr
inline gul14::date::day month_day::day() const noexcept {
return d_;}
2159 constexpr
inline bool
2160 month_day::ok() const noexcept
2162 constexpr
const gul14::date::day d[] =
2164 gul14::date::day(31), gul14::date::day(29), gul14::date::day(31),
2165 gul14::date::day(30), gul14::date::day(31), gul14::date::day(30),
2166 gul14::date::day(31), gul14::date::day(31), gul14::date::day(30),
2167 gul14::date::day(31), gul14::date::day(30), gul14::date::day(31)
2169 return m_.ok() && gul14::date::day{1} <= d_ && d_ <= d[static_cast<unsigned>(m_)-1];
2172 constexpr
inline bool
2173 operator==(
const month_day& x,
const month_day& y) noexcept
2175 return x.month() == y.month() && x.day() == y.day();
2178 constexpr
inline bool
2179 operator!=(
const month_day& x,
const month_day& y) noexcept
2184 constexpr
inline bool
2185 operator<(
const month_day& x,
const month_day& y) noexcept
2187 return x.month() < y.month() ? true
2188 : (x.month() > y.month() ? false
2189 : (x.day() < y.day()));
2192 constexpr
inline bool
2193 operator>(
const month_day& x,
const month_day& y) noexcept
2198 constexpr
inline bool
2199 operator<=(
const month_day& x,
const month_day& y) noexcept
2204 constexpr
inline bool
2205 operator>=(
const month_day& x,
const month_day& y) noexcept
2213 template<
class CharT,
class Traits>
2214 std::basic_ostream<CharT, Traits>&
2215 low_level_fmt(std::basic_ostream<CharT, Traits>& os,
const month_day& md)
2217 low_level_fmt(os, md.month()) <<
'/';
2218 return low_level_fmt(os, md.day());
2223 template<
class CharT,
class Traits>
2225 std::basic_ostream<CharT, Traits>&
2226 operator<<(std::basic_ostream<CharT, Traits>& os,
const month_day& md)
2228 detail::low_level_fmt(os, md);
2230 os <<
" is not a valid month_day";
2236 constexpr
inline month month_day_last::month() const noexcept {
return m_;}
2237 constexpr
inline bool month_day_last::ok() const noexcept {
return m_.ok();}
2238 constexpr
inline month_day_last::month_day_last(
const gul14::date::month& m) noexcept : m_(m) {}
2240 constexpr
inline bool
2241 operator==(
const month_day_last& x,
const month_day_last& y) noexcept
2243 return x.month() == y.month();
2246 constexpr
inline bool
2247 operator!=(
const month_day_last& x,
const month_day_last& y) noexcept
2252 constexpr
inline bool
2253 operator<(
const month_day_last& x,
const month_day_last& y) noexcept
2255 return x.month() < y.month();
2258 constexpr
inline bool
2259 operator>(
const month_day_last& x,
const month_day_last& y) noexcept
2264 constexpr
inline bool
2265 operator<=(
const month_day_last& x,
const month_day_last& y) noexcept
2270 constexpr
inline bool
2271 operator>=(
const month_day_last& x,
const month_day_last& y) noexcept
2279 template<
class CharT,
class Traits>
2280 std::basic_ostream<CharT, Traits>&
2281 low_level_fmt(std::basic_ostream<CharT, Traits>& os,
const month_day_last& mdl)
2283 return low_level_fmt(os, mdl.month()) <<
"/last";
2288 template<
class CharT,
class Traits>
2290 std::basic_ostream<CharT, Traits>&
2291 operator<<(std::basic_ostream<CharT, Traits>& os,
const month_day_last& mdl)
2293 detail::low_level_fmt(os, mdl);
2295 os <<
" is not a valid month_day_last";
2302 month_weekday::month_weekday(
const gul14::date::month& m,
2303 const gul14::date::weekday_indexed& wdi) noexcept
2308 constexpr
inline month month_weekday::month() const noexcept {
return m_;}
2310 constexpr
inline weekday_indexed
2311 month_weekday::weekday_indexed() const noexcept
2316 constexpr
inline bool
2317 month_weekday::ok() const noexcept
2319 return m_.ok() && wdi_.ok();
2322 constexpr
inline bool
2323 operator==(
const month_weekday& x,
const month_weekday& y) noexcept
2325 return x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed();
2328 constexpr
inline bool
2329 operator!=(
const month_weekday& x,
const month_weekday& y) noexcept
2337 template<
class CharT,
class Traits>
2338 std::basic_ostream<CharT, Traits>&
2339 low_level_fmt(std::basic_ostream<CharT, Traits>& os,
const month_weekday& mwd)
2341 low_level_fmt(os, mwd.month()) <<
'/';
2342 return low_level_fmt(os, mwd.weekday_indexed());
2347 template<
class CharT,
class Traits>
2349 std::basic_ostream<CharT, Traits>&
2350 operator<<(std::basic_ostream<CharT, Traits>& os,
const month_weekday& mwd)
2352 detail::low_level_fmt(os, mwd);
2354 os <<
" is not a valid month_weekday";
2361 month_weekday_last::month_weekday_last(
const gul14::date::month& m,
2362 const gul14::date::weekday_last& wdl) noexcept
2367 constexpr
inline month month_weekday_last::month() const noexcept {
return m_;}
2369 constexpr
inline weekday_last
2370 month_weekday_last::weekday_last() const noexcept
2375 constexpr
inline bool
2376 month_weekday_last::ok() const noexcept
2378 return m_.ok() && wdl_.ok();
2381 constexpr
inline bool
2382 operator==(
const month_weekday_last& x,
const month_weekday_last& y) noexcept
2384 return x.month() == y.month() && x.weekday_last() == y.weekday_last();
2387 constexpr
inline bool
2388 operator!=(
const month_weekday_last& x,
const month_weekday_last& y) noexcept
2396 template<
class CharT,
class Traits>
2397 std::basic_ostream<CharT, Traits>&
2398 low_level_fmt(std::basic_ostream<CharT, Traits>& os,
const month_weekday_last& mwdl)
2400 low_level_fmt(os, mwdl.month()) <<
'/';
2401 return low_level_fmt(os, mwdl.weekday_last());
2406 template<
class CharT,
class Traits>
2408 std::basic_ostream<CharT, Traits>&
2409 operator<<(std::basic_ostream<CharT, Traits>& os,
const month_weekday_last& mwdl)
2411 detail::low_level_fmt(os, mwdl);
2413 os <<
" is not a valid month_weekday_last";
2419 constexpr
inline year_month_day_last::year_month_day_last(
const gul14::date::year& y,
2420 const gul14::date::month_day_last& mdl) noexcept
2426 constexpr
inline year_month_day_last&
2427 year_month_day_last::operator+=(
const months& m) noexcept
2434 constexpr
inline year_month_day_last&
2435 year_month_day_last::operator-=(
const months& m) noexcept
2441 constexpr
inline year_month_day_last&
2442 year_month_day_last::operator+=(
const years& y) noexcept
2448 constexpr
inline year_month_day_last&
2449 year_month_day_last::operator-=(
const years& y) noexcept
2455 constexpr
inline year year_month_day_last::year() const noexcept {
return y_;}
2456 constexpr
inline month year_month_day_last::month() const noexcept {
return mdl_.month();}
2460 year_month_day_last::month_day_last() const noexcept
2467 year_month_day_last::day() const noexcept
2469 constexpr
const gul14::date::day d[] =
2471 gul14::date::day(31), gul14::date::day(28), gul14::date::day(31),
2472 gul14::date::day(30), gul14::date::day(31), gul14::date::day(30),
2473 gul14::date::day(31), gul14::date::day(31), gul14::date::day(30),
2474 gul14::date::day(31), gul14::date::day(30), gul14::date::day(31)
2476 return (month() != February || !y_.is_leap()) && mdl_.ok() ?
2477 d[
static_cast<unsigned>(month()) - 1] : gul14::date::day{29};
2481 year_month_day_last::operator sys_days() const noexcept
2483 return sys_days(year()/month()/day());
2487 year_month_day_last::operator local_days() const noexcept
2489 return local_days(year()/month()/day());
2492 constexpr
inline bool
2493 year_month_day_last::ok() const noexcept
2495 return y_.ok() && mdl_.ok();
2498 constexpr
inline bool
2499 operator==(
const year_month_day_last& x,
const year_month_day_last& y) noexcept
2501 return x.year() == y.year() && x.month_day_last() == y.month_day_last();
2504 constexpr
inline bool
2505 operator!=(
const year_month_day_last& x,
const year_month_day_last& y) noexcept
2510 constexpr
inline bool
2511 operator<(
const year_month_day_last& x,
const year_month_day_last& y) noexcept
2513 return x.year() < y.year() ? true
2514 : (x.year() > y.year() ? false
2515 : (x.month_day_last() < y.month_day_last()));
2518 constexpr
inline bool
2519 operator>(
const year_month_day_last& x,
const year_month_day_last& y) noexcept
2524 constexpr
inline bool
2525 operator<=(
const year_month_day_last& x,
const year_month_day_last& y) noexcept
2530 constexpr
inline bool
2531 operator>=(
const year_month_day_last& x,
const year_month_day_last& y) noexcept
2539 template<
class CharT,
class Traits>
2540 std::basic_ostream<CharT, Traits>&
2541 low_level_fmt(std::basic_ostream<CharT, Traits>& os,
const year_month_day_last& ymdl)
2543 low_level_fmt(os, ymdl.year()) <<
'/';
2544 return low_level_fmt(os, ymdl.month_day_last());
2549 template<
class CharT,
class Traits>
2551 std::basic_ostream<CharT, Traits>&
2552 operator<<(std::basic_ostream<CharT, Traits>& os,
const year_month_day_last& ymdl)
2554 detail::low_level_fmt(os, ymdl);
2556 os <<
" is not a valid year_month_day_last";
2563 operator+(
const year_month_day_last& ymdl,
const months& dm) noexcept
2565 return (ymdl.year() / ymdl.month() + dm) / last;
2571 operator+(
const months& dm,
const year_month_day_last& ymdl) noexcept
2579 operator-(
const year_month_day_last& ymdl,
const months& dm) noexcept
2581 return ymdl + (-dm);
2586 operator+(
const year_month_day_last& ymdl,
const years& dy) noexcept
2588 return {ymdl.year()+dy, ymdl.month_day_last()};
2593 operator+(
const years& dy,
const year_month_day_last& ymdl) noexcept
2600 operator-(
const year_month_day_last& ymdl,
const years& dy) noexcept
2602 return ymdl + (-dy);
2608 year_month_day::year_month_day(
const gul14::date::year& y,
const gul14::date::month& m,
2609 const gul14::date::day& d) noexcept
2616 year_month_day::year_month_day(
const year_month_day_last& ymdl) noexcept
2623 year_month_day::year_month_day(sys_days dp) noexcept
2624 : year_month_day(from_days(dp.time_since_epoch()))
2628 year_month_day::year_month_day(local_days dp) noexcept
2629 : year_month_day(from_days(dp.time_since_epoch()))
2632 constexpr
inline year year_month_day::year() const noexcept {
return y_;}
2633 constexpr
inline month year_month_day::month() const noexcept {
return m_;}
2634 constexpr
inline day year_month_day::day() const noexcept {
return d_;}
2639 year_month_day::operator+=(
const months& m) noexcept
2648 year_month_day::operator-=(
const months& m) noexcept
2656 year_month_day::operator+=(
const years& y) noexcept
2664 year_month_day::operator-=(
const years& y) noexcept
2672 year_month_day::to_days() const noexcept
2674 static_assert(std::numeric_limits<unsigned>::digits >= 18,
2675 "This algorithm has not been ported to a 16 bit unsigned integer");
2676 static_assert(std::numeric_limits<int>::digits >= 20,
2677 "This algorithm has not been ported to a 16 bit signed integer");
2678 auto const y =
static_cast<int>(y_) - (m_ <= February);
2679 auto const m =
static_cast<unsigned>(m_);
2680 auto const d =
static_cast<unsigned>(d_);
2681 auto const era = (y >= 0 ? y : y-399) / 400;
2682 auto const yoe =
static_cast<unsigned>(y - era * 400);
2683 auto const doy = (153*(m > 2 ? m-3 : m+9) + 2)/5 + d-1;
2684 auto const doe = yoe * 365 + yoe/4 - yoe/100 + doy;
2685 return days{era * 146097 +
static_cast<int>(doe) - 719468};
2689 year_month_day::operator sys_days() const noexcept
2691 return sys_days{to_days()};
2695 year_month_day::operator local_days() const noexcept
2697 return local_days{to_days()};
2700 constexpr
inline bool
2701 year_month_day::ok() const noexcept
2703 if (!(y_.ok() && m_.ok()))
2705 return gul14::date::day{1} <= d_ && d_ <= (y_ / m_ / last).day();
2708 constexpr
inline bool
2709 operator==(
const year_month_day& x,
const year_month_day& y) noexcept
2711 return x.year() == y.year() && x.month() == y.month() && x.day() == y.day();
2714 constexpr
inline bool
2715 operator!=(
const year_month_day& x,
const year_month_day& y) noexcept
2720 constexpr
inline bool
2721 operator<(
const year_month_day& x,
const year_month_day& y) noexcept
2723 return x.year() < y.year() ? true
2724 : (x.year() > y.year() ? false
2725 : (x.month() < y.month() ? true
2726 : (x.month() > y.month() ? false
2727 : (x.day() < y.day()))));
2730 constexpr
inline bool
2731 operator>(
const year_month_day& x,
const year_month_day& y) noexcept
2736 constexpr
inline bool
2737 operator<=(
const year_month_day& x,
const year_month_day& y) noexcept
2742 constexpr
inline bool
2743 operator>=(
const year_month_day& x,
const year_month_day& y) noexcept
2748 template<
class CharT,
class Traits>
2750 std::basic_ostream<CharT, Traits>&
2751 operator<<(std::basic_ostream<CharT, Traits>& os,
const year_month_day& ymd)
2753 detail::save_ostream<CharT, Traits> _(os);
2755 os.flags(std::ios::dec | std::ios::right);
2756 os.imbue(std::locale::classic());
2757 os << static_cast<int>(ymd.year()) <<
'-';
2759 os << static_cast<unsigned>(ymd.month()) <<
'-';
2761 os << static_cast<unsigned>(ymd.day());
2763 os <<
" is not a valid year_month_day";
2769 year_month_day::from_days(days dp) noexcept
2771 static_assert(std::numeric_limits<unsigned>::digits >= 18,
2772 "This algorithm has not been ported to a 16 bit unsigned integer");
2773 static_assert(std::numeric_limits<int>::digits >= 20,
2774 "This algorithm has not been ported to a 16 bit signed integer");
2775 auto const z = dp.count() + 719468;
2776 auto const era = (z >= 0 ? z : z - 146096) / 146097;
2777 auto const doe =
static_cast<unsigned>(z - era * 146097);
2778 auto const yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365;
2779 auto const y =
static_cast<days::rep
>(yoe) + era * 400;
2780 auto const doy = doe - (365*yoe + yoe/4 - yoe/100);
2781 auto const mp = (5*doy + 2)/153;
2782 auto const d = doy - (153*mp+2)/5 + 1;
2783 auto const m = mp < 10 ? mp+3 : mp-9;
2784 return year_month_day{gul14::date::year{y + (m <= 2)}, gul14::date::month(m), gul14::date::day(d)};
2790 operator+(
const year_month_day& ymd,
const months& dm) noexcept
2792 return (ymd.year() / ymd.month() + dm) / ymd.day();
2798 operator+(
const months& dm,
const year_month_day& ymd) noexcept
2806 operator-(
const year_month_day& ymd,
const months& dm) noexcept
2813 operator+(
const year_month_day& ymd,
const years& dy) noexcept
2815 return (ymd.year() + dy) / ymd.month() / ymd.day();
2820 operator+(
const years& dy,
const year_month_day& ymd) noexcept
2827 operator-(
const year_month_day& ymd,
const years& dy) noexcept
2835 year_month_weekday::year_month_weekday(
const gul14::date::year& y,
const gul14::date::month& m,
2836 const gul14::date::weekday_indexed& wdi)
2844 year_month_weekday::year_month_weekday(
const sys_days& dp) noexcept
2845 : year_month_weekday(from_days(dp.time_since_epoch()))
2849 year_month_weekday::year_month_weekday(
const local_days& dp) noexcept
2850 : year_month_weekday(from_days(dp.time_since_epoch()))
2856 year_month_weekday::operator+=(
const months& m) noexcept
2865 year_month_weekday::operator-=(
const months& m) noexcept
2873 year_month_weekday::operator+=(
const years& y) noexcept
2881 year_month_weekday::operator-=(
const years& y) noexcept
2887 constexpr
inline year year_month_weekday::year() const noexcept {
return y_;}
2888 constexpr
inline month year_month_weekday::month() const noexcept {
return m_;}
2892 year_month_weekday::weekday() const noexcept
2894 return wdi_.weekday();
2899 year_month_weekday::index() const noexcept
2901 return wdi_.index();
2906 year_month_weekday::weekday_indexed() const noexcept
2912 year_month_weekday::operator sys_days() const noexcept
2914 return sys_days{to_days()};
2918 year_month_weekday::operator local_days() const noexcept
2920 return local_days{to_days()};
2923 constexpr
inline bool
2924 year_month_weekday::ok() const noexcept
2926 if (!y_.ok() || !m_.ok() || !wdi_.weekday().ok() || wdi_.index() < 1)
2928 if (wdi_.index() <= 4)
2930 auto d2 = wdi_.weekday() - gul14::date::weekday(
static_cast<sys_days
>(y_/m_/1)) +
2931 days((wdi_.index()-1)*7 + 1);
2932 return static_cast<unsigned>(d2.count()) <=
static_cast<unsigned>((y_/m_/last).day());
2937 year_month_weekday::from_days(days d) noexcept
2940 auto const wd = gul14::date::weekday(dp);
2941 auto const ymd = year_month_day(dp);
2942 return {ymd.year(), ymd.month(), wd[(
static_cast<unsigned>(ymd.day())-1)/7+1]};
2947 year_month_weekday::to_days() const noexcept
2949 auto d = sys_days(y_/m_/1);
2950 return (d + (wdi_.weekday() - gul14::date::weekday(d) + days{(wdi_.index()-1)*7})
2951 ).time_since_epoch();
2954 constexpr
inline bool
2955 operator==(
const year_month_weekday& x,
const year_month_weekday& y) noexcept
2957 return x.year() == y.year() && x.month() == y.month() &&
2958 x.weekday_indexed() == y.weekday_indexed();
2961 constexpr
inline bool
2962 operator!=(
const year_month_weekday& x,
const year_month_weekday& y) noexcept
2967 template<
class CharT,
class Traits>
2969 std::basic_ostream<CharT, Traits>&
2970 operator<<(std::basic_ostream<CharT, Traits>& os,
const year_month_weekday& ymwdi)
2972 detail::low_level_fmt(os, ymwdi.year()) <<
'/';
2973 detail::low_level_fmt(os, ymwdi.month()) <<
'/';
2974 detail::low_level_fmt(os, ymwdi.weekday_indexed());
2976 os <<
" is not a valid year_month_weekday";
2983 operator+(
const year_month_weekday& ymwd,
const months& dm) noexcept
2985 return (ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed();
2991 operator+(
const months& dm,
const year_month_weekday& ymwd) noexcept
2999 operator-(
const year_month_weekday& ymwd,
const months& dm) noexcept
3001 return ymwd + (-dm);
3006 operator+(
const year_month_weekday& ymwd,
const years& dy) noexcept
3008 return {ymwd.year()+dy, ymwd.month(), ymwd.weekday_indexed()};
3013 operator+(
const years& dy,
const year_month_weekday& ymwd) noexcept
3020 operator-(
const year_month_weekday& ymwd,
const years& dy) noexcept
3022 return ymwd + (-dy);
3028 year_month_weekday_last::year_month_weekday_last(
const gul14::date::year& y,
3029 const gul14::date::month& m,
3030 const gul14::date::weekday_last& wdl) noexcept
3038 year_month_weekday_last&
3039 year_month_weekday_last::operator+=(
const months& m) noexcept
3047 year_month_weekday_last&
3048 year_month_weekday_last::operator-=(
const months& m) noexcept
3055 year_month_weekday_last&
3056 year_month_weekday_last::operator+=(
const years& y) noexcept
3063 year_month_weekday_last&
3064 year_month_weekday_last::operator-=(
const years& y) noexcept
3070 constexpr
inline year year_month_weekday_last::year() const noexcept {
return y_;}
3071 constexpr
inline month year_month_weekday_last::month() const noexcept {
return m_;}
3075 year_month_weekday_last::weekday() const noexcept
3077 return wdl_.weekday();
3082 year_month_weekday_last::weekday_last() const noexcept
3088 year_month_weekday_last::operator sys_days() const noexcept
3090 return sys_days{to_days()};
3094 year_month_weekday_last::operator local_days() const noexcept
3096 return local_days{to_days()};
3099 constexpr
inline bool
3100 year_month_weekday_last::ok() const noexcept
3102 return y_.ok() && m_.ok() && wdl_.ok();
3107 year_month_weekday_last::to_days() const noexcept
3109 auto const d = sys_days(y_/m_/last);
3110 return (d - (gul14::date::weekday{d} - wdl_.weekday())).time_since_epoch();
3113 constexpr
inline bool
3114 operator==(
const year_month_weekday_last& x,
const year_month_weekday_last& y) noexcept
3116 return x.year() == y.year() && x.month() == y.month() &&
3117 x.weekday_last() == y.weekday_last();
3120 constexpr
inline bool
3121 operator!=(
const year_month_weekday_last& x,
const year_month_weekday_last& y) noexcept
3126 template<
class CharT,
class Traits>
3128 std::basic_ostream<CharT, Traits>&
3129 operator<<(std::basic_ostream<CharT, Traits>& os,
const year_month_weekday_last& ymwdl)
3131 detail::low_level_fmt(os, ymwdl.year()) <<
'/';
3132 detail::low_level_fmt(os, ymwdl.month()) <<
'/';
3133 detail::low_level_fmt(os, ymwdl.weekday_last());
3135 os <<
" is not a valid year_month_weekday_last";
3141 year_month_weekday_last
3142 operator+(
const year_month_weekday_last& ymwdl,
const months& dm) noexcept
3144 return (ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last();
3149 year_month_weekday_last
3150 operator+(
const months& dm,
const year_month_weekday_last& ymwdl) noexcept
3157 year_month_weekday_last
3158 operator-(
const year_month_weekday_last& ymwdl,
const months& dm) noexcept
3160 return ymwdl + (-dm);
3164 year_month_weekday_last
3165 operator+(
const year_month_weekday_last& ymwdl,
const years& dy) noexcept
3167 return {ymwdl.year()+dy, ymwdl.month(), ymwdl.weekday_last()};
3171 year_month_weekday_last
3172 operator+(
const years& dy,
const year_month_weekday_last& ymwdl) noexcept
3178 year_month_weekday_last
3179 operator-(
const year_month_weekday_last& ymwdl,
const years& dy) noexcept
3181 return ymwdl + (-dy);
3188 operator/(
const year& y,
const month& m) noexcept
3195 operator/(
const year& y,
int m) noexcept
3197 return y / month(
static_cast<unsigned>(m));
3204 operator/(
const month& m,
const day& d) noexcept
3211 operator/(
const day& d,
const month& m) noexcept
3218 operator/(
const month& m,
int d) noexcept
3220 return m / day(
static_cast<unsigned>(d));
3225 operator/(
int m,
const day& d) noexcept
3227 return month(
static_cast<unsigned>(m)) / d;
3230 constexpr
inline month_day operator/(
const day& d,
int m) noexcept {
return m / d;}
3236 operator/(
const month& m, last_spec) noexcept
3238 return month_day_last{m};
3243 operator/(last_spec,
const month& m) noexcept
3250 operator/(
int m, last_spec) noexcept
3252 return month(
static_cast<unsigned>(m))/last;
3257 operator/(last_spec,
int m) noexcept
3266 operator/(
const month& m,
const weekday_indexed& wdi) noexcept
3273 operator/(
const weekday_indexed& wdi,
const month& m) noexcept
3280 operator/(
int m,
const weekday_indexed& wdi) noexcept
3282 return month(
static_cast<unsigned>(m)) / wdi;
3287 operator/(
const weekday_indexed& wdi,
int m) noexcept
3296 operator/(
const month& m,
const weekday_last& wdl) noexcept
3303 operator/(
const weekday_last& wdl,
const month& m) noexcept
3310 operator/(
int m,
const weekday_last& wdl) noexcept
3312 return month(
static_cast<unsigned>(m)) / wdl;
3317 operator/(
const weekday_last& wdl,
int m) noexcept
3326 operator/(
const year_month& ym,
const day& d) noexcept
3328 return {ym.year(), ym.month(), d};
3333 operator/(
const year_month& ym,
int d) noexcept
3335 return ym / day(
static_cast<unsigned>(d));
3340 operator/(
const year& y,
const month_day& md) noexcept
3342 return y / md.month() / md.day();
3347 operator/(
int y,
const month_day& md) noexcept
3349 return year(y) / md;
3354 operator/(
const month_day& md,
const year& y) noexcept
3361 operator/(
const month_day& md,
int y) noexcept
3363 return year(y) / md;
3370 operator/(
const year_month& ym, last_spec) noexcept
3372 return {ym.year(), month_day_last{ym.month()}};
3377 operator/(
const year& y,
const month_day_last& mdl) noexcept
3384 operator/(
int y,
const month_day_last& mdl) noexcept
3386 return year(y) / mdl;
3391 operator/(
const month_day_last& mdl,
const year& y) noexcept
3398 operator/(
const month_day_last& mdl,
int y) noexcept
3400 return year(y) / mdl;
3407 operator/(
const year_month& ym,
const weekday_indexed& wdi) noexcept
3409 return {ym.year(), ym.month(), wdi};
3414 operator/(
const year& y,
const month_weekday& mwd) noexcept
3416 return {y, mwd.month(), mwd.weekday_indexed()};
3421 operator/(
int y,
const month_weekday& mwd) noexcept
3423 return year(y) / mwd;
3428 operator/(
const month_weekday& mwd,
const year& y) noexcept
3435 operator/(
const month_weekday& mwd,
int y) noexcept
3437 return year(y) / mwd;
3443 year_month_weekday_last
3444 operator/(
const year_month& ym,
const weekday_last& wdl) noexcept
3446 return {ym.year(), ym.month(), wdl};
3450 year_month_weekday_last
3451 operator/(
const year& y,
const month_weekday_last& mwdl) noexcept
3453 return {y, mwdl.month(), mwdl.weekday_last()};
3457 year_month_weekday_last
3458 operator/(
int y,
const month_weekday_last& mwdl) noexcept
3460 return year(y) / mwdl;
3464 year_month_weekday_last
3465 operator/(
const month_weekday_last& mwdl,
const year& y) noexcept
3471 year_month_weekday_last
3472 operator/(
const month_weekday_last& mwdl,
int y) noexcept
3474 return year(y) / mwdl;
3477 template <
class Duration>
3480 template <
class CharT,
class Traits,
class Duration>
3481 std::basic_ostream<CharT, Traits>&
3482 to_stream(std::basic_ostream<CharT, Traits>& os,
const CharT* fmt,
3483 const fields<Duration>& fds,
const std::string* abbrev =
nullptr,
3484 const std::chrono::seconds* offset_sec =
nullptr);
3486 template <
class CharT,
class Traits,
class Duration,
class Alloc>
3487 std::basic_istream<CharT, Traits>&
3488 from_stream(std::basic_istream<CharT, Traits>& is,
const CharT* fmt,
3489 fields<Duration>& fds, std::basic_string<CharT, Traits, Alloc>* abbrev =
nullptr,
3490 std::chrono::minutes* offset =
nullptr);
3497 struct undocumented {
explicit undocumented() =
default;};
3508 template <std::uint64_t n, std::uint64_t d,
unsigned w = 0,
3509 bool should_continue = n%d != 0 && (w < 19)>
3512 static_assert(d > 0,
"width called with zero denominator");
3513 static constexpr
const unsigned value = 1 + width<n%d*10, d, w+1>::value;
3516 template <std::u
int64_t n, std::u
int64_t d,
unsigned w>
3517 struct width<n, d, w, false>
3519 static constexpr
const unsigned value = 0;
3522 template <
unsigned exp>
3526 static constexpr
const std::uint64_t h = static_pow10<exp/2>::value;
3528 static constexpr
const std::uint64_t value = h * h * (exp % 2 ? 10 : 1);
3532 struct static_pow10<0>
3534 static constexpr
const std::uint64_t value = 1;
3537 template <
class Duration>
3538 class decimal_format_seconds
3540 using CT =
typename std::common_type<Duration, std::chrono::seconds>::type;
3541 using rep =
typename CT::rep;
3542 static unsigned constexpr
const trial_width =
3543 detail::width<CT::period::num, CT::period::den>::value;
3545 static unsigned constexpr
const width = trial_width < 19 ? trial_width : 6u;
3546 using precision = std::chrono::duration<rep,
3547 std::ratio<1, static_pow10<width>::value>>;
3550 std::chrono::seconds s_;
3554 constexpr decimal_format_seconds()
3559 constexpr
explicit decimal_format_seconds(
const Duration& d) noexcept
3560 : s_(std::chrono::duration_cast<std::chrono::seconds>(d))
3561 , sub_s_(std::chrono::duration_cast<precision>(d - s_))
3564 constexpr std::chrono::seconds& seconds() noexcept {
return s_;}
3565 constexpr std::chrono::seconds seconds() const noexcept {
return s_;}
3566 constexpr precision subseconds() const noexcept {
return sub_s_;}
3568 constexpr precision to_duration() const noexcept
3573 constexpr
bool in_conventional_range() const noexcept
3575 return sub_s_ < std::chrono::seconds{1} && s_ < std::chrono::minutes{1};
3578 template <
class CharT,
class Traits>
3580 std::basic_ostream<CharT, Traits>&
3581 operator<<(std::basic_ostream<CharT, Traits>& os,
const decimal_format_seconds& x)
3583 return x.print(os, std::chrono::treat_as_floating_point<rep>{});
3586 template <
class CharT,
class Traits>
3587 std::basic_ostream<CharT, Traits>&
3588 print(std::basic_ostream<CharT, Traits>& os, std::true_type)
const
3590 gul14::date::detail::save_ostream<CharT, Traits> _(os);
3591 std::chrono::duration<rep> d = s_ + sub_s_;
3592 if (d < std::chrono::seconds{10})
3594 os.precision(width+6);
3595 os << std::fixed << d.count();
3599 template <
class CharT,
class Traits>
3600 std::basic_ostream<CharT, Traits>&
3601 print(std::basic_ostream<CharT, Traits>& os, std::false_type)
const
3603 gul14::date::detail::save_ostream<CharT, Traits> _(os);
3605 os.flags(std::ios::dec | std::ios::right);
3611 os << std::use_facet<std::numpunct<CharT>>(os.getloc()).decimal_point();
3615 gul14::date::detail::save_ostream<CharT, Traits> _s(os);
3616 os.imbue(std::locale::classic());
3618 os << sub_s_.count();
3624 template <
class Rep,
class Period>
3626 typename std::enable_if
3628 std::numeric_limits<Rep>::is_signed,
3629 std::chrono::duration<Rep, Period>
3631 abs(std::chrono::duration<Rep, Period> d)
3633 return d >= d.zero() ? +d : -d;
3636 template <
class Rep,
class Period>
3638 typename std::enable_if
3640 !std::numeric_limits<Rep>::is_signed,
3641 std::chrono::duration<Rep, Period>
3643 abs(std::chrono::duration<Rep, Period> d)
3650 template <
class Duration>
3653 using dfs = detail::decimal_format_seconds<
typename std::common_type<Duration,
3654 std::chrono::seconds>::type>;
3656 std::chrono::hours h_;
3657 std::chrono::minutes m_;
3662 static unsigned constexpr
const fractional_width = dfs::width;
3663 using precision =
typename dfs::precision;
3665 constexpr hh_mm_ss() noexcept
3666 : hh_mm_ss(Duration::zero())
3669 constexpr
explicit hh_mm_ss(Duration d) noexcept
3670 : h_(std::chrono::duration_cast<std::chrono::hours>(
detail::abs(d)))
3671 , m_(std::chrono::duration_cast<std::chrono::minutes>(
detail::abs(d)) - h_)
3673 , neg_(d < Duration::zero())
3676 constexpr std::chrono::hours hours() const noexcept {
return h_;}
3677 constexpr std::chrono::minutes minutes() const noexcept {
return m_;}
3678 constexpr std::chrono::seconds seconds() const noexcept {
return s_.seconds();}
3679 constexpr std::chrono::seconds&
3680 seconds(detail::undocumented) noexcept {
return s_.seconds();}
3681 constexpr precision subseconds() const noexcept {
return s_.subseconds();}
3682 constexpr
bool is_negative() const noexcept {
return neg_;}
3684 constexpr
explicit operator precision() const noexcept {
return to_duration();}
3685 constexpr precision to_duration() const noexcept
3686 {
return (s_.to_duration() + m_ + h_) * (1-2*neg_);}
3688 constexpr
bool in_conventional_range() const noexcept
3690 return !neg_ && h_ < days{1} && m_ < std::chrono::hours{1} &&
3691 s_.in_conventional_range();
3696 template <
class charT,
class traits>
3698 std::basic_ostream<charT, traits>&
3699 operator<<(std::basic_ostream<charT, traits>& os, hh_mm_ss
const& tod)
3701 if (tod.is_negative())
3703 if (tod.h_ < std::chrono::hours{10})
3705 os << tod.h_.count() <<
':';
3706 if (tod.m_ < std::chrono::minutes{10})
3708 os << tod.m_.count() <<
':' << tod.s_;
3712 template <
class CharT,
class Traits,
class Duration2>
3714 std::basic_ostream<CharT, Traits>&
3715 gul14::date::to_stream(std::basic_ostream<CharT, Traits>& os,
const CharT* fmt,
3716 const fields<Duration2>& fds,
const std::string* abbrev,
3717 const std::chrono::seconds* offset_sec);
3719 template <
class CharT,
class Traits,
class Duration2,
class Alloc>
3721 std::basic_istream<CharT, Traits>&
3722 gul14::date::from_stream(std::basic_istream<CharT, Traits>& is,
const CharT* fmt,
3723 fields<Duration2>& fds,
3724 std::basic_string<CharT, Traits, Alloc>* abbrev, std::chrono::minutes* offset);
3727 inline constexpr
bool
3728 is_am(std::chrono::hours
const& h) noexcept
3730 using std::chrono::hours;
3731 return hours{0} <= h && h < hours{12};
3734 inline constexpr
bool
3735 is_pm(std::chrono::hours
const& h) noexcept
3737 using std::chrono::hours;
3738 return hours{12} <= h && h < hours{24};
3741 inline constexpr std::chrono::hours
3742 make12(std::chrono::hours h) noexcept
3744 using std::chrono::hours;
3758 inline constexpr std::chrono::hours
3759 make24(std::chrono::hours h,
bool is_pm) noexcept
3761 using std::chrono::hours;
3767 else if (h == hours{12})
3772 template <
class Duration>
3773 using time_of_day = hh_mm_ss<Duration>;
3775 template <
class Rep,
class Period>
3777 hh_mm_ss<std::chrono::duration<Rep, Period>>
3778 make_time(
const std::chrono::duration<Rep, Period>& d)
3780 return hh_mm_ss<std::chrono::duration<Rep, Period>>(d);
3783 template <
class CharT,
class Traits,
class Duration>
3785 typename std::enable_if
3787 std::ratio_less<typename Duration::period, days::period>::value
3788 , std::basic_ostream<CharT, Traits>&
3790 operator<<(std::basic_ostream<CharT, Traits>& os,
const sys_time<Duration>& tp)
3792 auto const dp = gul14::date::floor<days>(tp);
3793 return os << year_month_day(dp) <<
' ' << make_time(tp-dp);
3796 template <
class CharT,
class Traits>
3798 std::basic_ostream<CharT, Traits>&
3799 operator<<(std::basic_ostream<CharT, Traits>& os,
const sys_days& dp)
3801 return os << year_month_day(dp);
3804 template <
class CharT,
class Traits,
class Duration>
3806 std::basic_ostream<CharT, Traits>&
3807 operator<<(std::basic_ostream<CharT, Traits>& os,
const local_time<Duration>& ut)
3809 return (os << sys_time<Duration>{ut.time_since_epoch()});
3815 template <
class CharT, std::
size_t N>
3816 class string_literal;
3818 template <
class CharT1,
class CharT2, std::
size_t N1, std::
size_t N2>
3820 string_literal<
typename std::conditional<
sizeof(CharT2) <=
sizeof(CharT1), CharT1, CharT2>::type,
3822 operator+(
const string_literal<CharT1, N1>& x,
const string_literal<CharT2, N2>& y) noexcept;
3824 template <
class CharT, std::
size_t N>
3825 class string_literal
3829 constexpr string_literal() noexcept
3834 using const_iterator =
const CharT*;
3836 string_literal(string_literal
const&) =
default;
3837 string_literal& operator=(string_literal
const&) =
delete;
3839 template <std::size_t N1 = 2,
3840 class =
typename std::enable_if<N1 == N>::type>
3841 constexpr string_literal(CharT c) noexcept
3846 template <std::size_t N1 = 3,
3847 class =
typename std::enable_if<N1 == N>::type>
3848 constexpr string_literal(CharT c1, CharT c2) noexcept
3853 template <std::size_t N1 = 4,
3854 class =
typename std::enable_if<N1 == N>::type>
3855 constexpr string_literal(CharT c1, CharT c2, CharT c3) noexcept
3860 constexpr string_literal(
const CharT(&a)[N]) noexcept
3863 for (std::size_t i = 0; i < N; ++i)
3867 template <
class U = CharT,
3868 class =
typename std::enable_if<(1 <
sizeof(U))>::type>
3869 constexpr string_literal(
const char(&a)[N]) noexcept
3872 for (std::size_t i = 0; i < N; ++i)
3876 template <
class CharT2,
3877 class =
typename std::enable_if<!std::is_same<CharT2, CharT>::value>::type>
3878 constexpr string_literal(string_literal<CharT2, N>
const& a) noexcept
3881 for (std::size_t i = 0; i < N; ++i)
3885 constexpr
const CharT* data() const noexcept {
return p_;}
3886 constexpr std::size_t size() const noexcept {
return N-1;}
3888 constexpr const_iterator begin() const noexcept {
return p_;}
3889 constexpr const_iterator end() const noexcept {
return p_ + N-1;}
3891 constexpr CharT
const& operator[](std::size_t n)
const noexcept
3896 template <
class Traits>
3898 std::basic_ostream<CharT, Traits>&
3899 operator<<(std::basic_ostream<CharT, Traits>& os,
const string_literal& s)
3904 template <
class CharT1,
class CharT2, std::
size_t N1, std::
size_t N2>
3907 string_literal<
typename std::conditional<
sizeof(CharT2) <=
sizeof(CharT1), CharT1, CharT2>::type,
3909 operator+(
const string_literal<CharT1, N1>& x,
const string_literal<CharT2, N2>& y) noexcept;
3912 template <
class CharT>
3914 string_literal<CharT, 3>
3915 operator+(
const string_literal<CharT, 2>& x,
const string_literal<CharT, 2>& y) noexcept
3917 return string_literal<CharT, 3>(x[0], y[0]);
3920 template <
class CharT>
3922 string_literal<CharT, 4>
3923 operator+(
const string_literal<CharT, 3>& x,
const string_literal<CharT, 2>& y) noexcept
3925 return string_literal<CharT, 4>(x[0], x[1], y[0]);
3928 template <
class CharT1,
class CharT2, std::
size_t N1, std::
size_t N2>
3930 string_literal<
typename std::conditional<
sizeof(CharT2) <=
sizeof(CharT1), CharT1, CharT2>::type,
3932 operator+(
const string_literal<CharT1, N1>& x,
const string_literal<CharT2, N2>& y) noexcept
3934 using CT =
typename std::conditional<
sizeof(CharT2) <=
sizeof(CharT1), CharT1, CharT2>::type;
3936 string_literal<CT, N1 + N2 - 1> r;
3938 for (; i < N1-1; ++i)
3939 r.p_[i] = CT(x.p_[i]);
3940 for (std::size_t j = 0; j < N2; ++j, ++i)
3941 r.p_[i] = CT(y.p_[j]);
3947 template <
class CharT,
class Traits,
class Alloc, std::
size_t N>
3949 std::basic_string<CharT, Traits, Alloc>
3950 operator+(std::basic_string<CharT, Traits, Alloc> x,
const string_literal<CharT, N>& y)
3952 x.append(y.data(), y.size());
3956 #if __cplusplus >= 201402 && (!defined(__EDG_VERSION__) || __EDG_VERSION__ > 411)
3958 template <
class CharT,
3959 class = std::enable_if_t<std::is_same<CharT, char>::value ||
3960 std::is_same<CharT, wchar_t>::value ||
3961 std::is_same<CharT, char16_t>::value ||
3962 std::is_same<CharT, char32_t>::value>>
3964 string_literal<CharT, 2>
3965 msl(CharT c) noexcept
3967 return string_literal<CharT, 2>{c};
3972 to_string_len(std::intmax_t i)
3983 template <std::
intmax_t N>
3988 string_literal<char, to_string_len(N)+1>
3992 return msl(
char(N % 10 +
'0'));
3995 template <std::
intmax_t N>
4000 string_literal<char, to_string_len(N)+1>
4004 return msl<N/10>() + msl(
char(N % 10 +
'0'));
4007 template <
class CharT, std::
intmax_t N, std::
intmax_t D>
4011 std::ratio<N, D>::type::den != 1,
4012 string_literal<CharT, to_string_len(std::ratio<N, D>::type::num) +
4013 to_string_len(std::ratio<N, D>::type::den) + 4>
4015 msl(std::ratio<N, D>) noexcept
4017 using R =
typename std::ratio<N, D>::type;
4018 return msl(CharT{
'['}) + msl<R::num>() + msl(CharT{
'/'}) +
4019 msl<R::den>() + msl(CharT{
']'});
4022 template <
class CharT, std::
intmax_t N, std::
intmax_t D>
4026 std::ratio<N, D>::type::den == 1,
4027 string_literal<CharT, to_string_len(std::ratio<N, D>::type::num) + 3>
4029 msl(std::ratio<N, D>) noexcept
4031 using R =
typename std::ratio<N, D>::type;
4032 return msl(CharT{
'['}) + msl<R::num>() + msl(CharT{
']'});
4040 to_string(std::uint64_t x)
4042 return std::to_string(x);
4045 template <
class CharT>
4047 std::basic_string<CharT>
4048 to_string(std::uint64_t x)
4050 auto y = std::to_string(x);
4051 return std::basic_string<CharT>(y.begin(), y.end());
4054 template <
class CharT, std::
intmax_t N, std::
intmax_t D>
4056 typename std::enable_if
4058 std::ratio<N, D>::type::den != 1,
4059 std::basic_string<CharT>
4061 msl(std::ratio<N, D>)
4063 using R =
typename std::ratio<N, D>::type;
4064 return std::basic_string<CharT>(1,
'[') + to_string<CharT>(R::num) + CharT{
'/'} +
4065 to_string<CharT>(R::den) + CharT{
']'};
4068 template <
class CharT, std::
intmax_t N, std::
intmax_t D>
4070 typename std::enable_if
4072 std::ratio<N, D>::type::den == 1,
4073 std::basic_string<CharT>
4075 msl(std::ratio<N, D>)
4077 using R =
typename std::ratio<N, D>::type;
4078 return std::basic_string<CharT>(1,
'[') + to_string<CharT>(R::num) + CharT{
']'};
4083 template <
class CharT>
4085 string_literal<CharT, 2>
4086 msl(std::atto) noexcept
4088 return string_literal<CharT, 2>{
'a'};
4091 template <
class CharT>
4093 string_literal<CharT, 2>
4094 msl(std::femto) noexcept
4096 return string_literal<CharT, 2>{
'f'};
4099 template <
class CharT>
4101 string_literal<CharT, 2>
4102 msl(std::pico) noexcept
4104 return string_literal<CharT, 2>{
'p'};
4107 template <
class CharT>
4109 string_literal<CharT, 2>
4110 msl(std::nano) noexcept
4112 return string_literal<CharT, 2>{
'n'};
4115 template <
class CharT>
4117 typename std::enable_if
4119 std::is_same<CharT, char>::value,
4120 string_literal<char, 3>
4122 msl(std::micro) noexcept
4124 return string_literal<char, 3>{
'\xC2',
'\xB5'};
4127 template <
class CharT>
4129 typename std::enable_if
4131 !std::is_same<CharT, char>::value,
4132 string_literal<CharT, 2>
4134 msl(std::micro) noexcept
4136 return string_literal<CharT, 2>{CharT{
static_cast<unsigned char>(
'\xB5')}};
4139 template <
class CharT>
4141 string_literal<CharT, 2>
4142 msl(std::milli) noexcept
4144 return string_literal<CharT, 2>{
'm'};
4147 template <
class CharT>
4149 string_literal<CharT, 2>
4150 msl(std::centi) noexcept
4152 return string_literal<CharT, 2>{
'c'};
4155 template <
class CharT>
4157 string_literal<CharT, 3>
4158 msl(std::deca) noexcept
4160 return string_literal<CharT, 3>{
'd',
'a'};
4163 template <
class CharT>
4165 string_literal<CharT, 2>
4166 msl(std::deci) noexcept
4168 return string_literal<CharT, 2>{
'd'};
4171 template <
class CharT>
4173 string_literal<CharT, 2>
4174 msl(std::hecto) noexcept
4176 return string_literal<CharT, 2>{
'h'};
4179 template <
class CharT>
4181 string_literal<CharT, 2>
4182 msl(std::kilo) noexcept
4184 return string_literal<CharT, 2>{
'k'};
4187 template <
class CharT>
4189 string_literal<CharT, 2>
4190 msl(std::mega) noexcept
4192 return string_literal<CharT, 2>{
'M'};
4195 template <
class CharT>
4197 string_literal<CharT, 2>
4198 msl(std::giga) noexcept
4200 return string_literal<CharT, 2>{
'G'};
4203 template <
class CharT>
4205 string_literal<CharT, 2>
4206 msl(std::tera) noexcept
4208 return string_literal<CharT, 2>{
'T'};
4211 template <
class CharT>
4213 string_literal<CharT, 2>
4214 msl(std::peta) noexcept
4216 return string_literal<CharT, 2>{
'P'};
4219 template <
class CharT>
4221 string_literal<CharT, 2>
4222 msl(std::exa) noexcept
4224 return string_literal<CharT, 2>{
'E'};
4227 template <
class CharT,
class Period>
4231 -> decltype(msl<CharT>(p) + string_literal<CharT, 2>{
's'})
4233 return msl<CharT>(p) + string_literal<CharT, 2>{
's'};
4236 template <
class CharT>
4238 string_literal<CharT, 2>
4239 get_units(std::ratio<1>)
4241 return string_literal<CharT, 2>{
's'};
4244 template <
class CharT>
4246 string_literal<CharT, 2>
4247 get_units(std::ratio<3600>)
4249 return string_literal<CharT, 2>{
'h'};
4252 template <
class CharT>
4254 string_literal<CharT, 4>
4255 get_units(std::ratio<60>)
4257 return string_literal<CharT, 4>{
'm',
'i',
'n'};
4260 template <
class CharT>
4262 string_literal<CharT, 2>
4263 get_units(std::ratio<86400>)
4265 return string_literal<CharT, 2>{
'd'};
4268 template <
class CharT,
class Traits = std::
char_traits<CharT>>
4272 struct make_string<char>
4274 template <
class Rep>
4279 return std::to_string(n);
4283 template <
class Traits>
4284 struct make_string<char, Traits>
4286 template <
class Rep>
4288 std::basic_string<char, Traits>
4291 auto s = std::to_string(n);
4292 return std::basic_string<char, Traits>(s.begin(), s.end());
4297 struct make_string<wchar_t>
4299 template <
class Rep>
4304 return std::to_wstring(n);
4308 template <
class Traits>
4309 struct make_string<wchar_t, Traits>
4311 template <
class Rep>
4313 std::basic_string<wchar_t, Traits>
4316 auto s = std::to_wstring(n);
4317 return std::basic_string<wchar_t, Traits>(s.begin(), s.end());
4325 constexpr
const year nanyear{-32768};
4327 template <
class Duration>
4330 year_month_day ymd{nanyear/0/0};
4332 hh_mm_ss<Duration> tod{};
4333 bool has_tod =
false;
4335 #if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ <= 409)
4336 fields() : ymd{nanyear/0/0}, wd{8u}, tod{}, has_tod{false} {}
4341 fields(year_month_day ymd_) : ymd(ymd_) {}
4342 fields(weekday wd_) : wd(wd_) {}
4343 fields(hh_mm_ss<Duration> tod_) : tod(tod_), has_tod(true) {}
4345 fields(year_month_day ymd_, weekday wd_) : ymd(ymd_), wd(wd_) {}
4346 fields(year_month_day ymd_, hh_mm_ss<Duration> tod_) : ymd(ymd_), tod(tod_),
4349 fields(weekday wd_, hh_mm_ss<Duration> tod_) : wd(wd_), tod(tod_), has_tod(true) {}
4351 fields(year_month_day ymd_, weekday wd_, hh_mm_ss<Duration> tod_)
4362 template <
class CharT,
class Traits,
class Duration>
4364 extract_weekday(std::basic_ostream<CharT, Traits>& os,
const fields<Duration>& fds)
4366 if (!fds.ymd.ok() && !fds.wd.ok())
4369 os.setstate(std::ios::failbit);
4375 wd = weekday{sys_days(fds.ymd)};
4376 if (fds.wd.ok() && wd != fds.wd)
4379 os.setstate(std::ios::failbit);
4385 return static_cast<unsigned>((wd - Sunday).count());
4388 template <
class CharT,
class Traits,
class Duration>
4390 extract_month(std::basic_ostream<CharT, Traits>& os,
const fields<Duration>& fds)
4392 if (!fds.ymd.month().ok())
4395 os.setstate(std::ios::failbit);
4398 return static_cast<unsigned>(fds.ymd.month());
4409 std::pair<const std::string*, const std::string*>
4412 static const std::string nm[] =
4429 return std::make_pair(nm, nm+
sizeof(nm)/
sizeof(nm[0]));
4433 std::pair<const std::string*, const std::string*>
4436 static const std::string nm[] =
4463 return std::make_pair(nm, nm+
sizeof(nm)/
sizeof(nm[0]));
4467 std::pair<const std::string*, const std::string*>
4470 static const std::string nm[] =
4475 return std::make_pair(nm, nm+
sizeof(nm)/
sizeof(nm[0]));
4478 template <
class CharT,
class Traits,
class FwdIter>
4480 scan_keyword(std::basic_istream<CharT, Traits>& is, FwdIter kb, FwdIter ke)
4482 size_t nkw =
static_cast<size_t>(std::distance(kb, ke));
4483 const unsigned char doesnt_match =
'\0';
4484 const unsigned char might_match =
'\1';
4485 const unsigned char does_match =
'\2';
4486 unsigned char statbuf[100];
4487 unsigned char* status = statbuf;
4488 std::unique_ptr<
unsigned char, void(*)(
void*)> stat_hold(0, free);
4489 if (nkw >
sizeof(statbuf))
4491 status = (
unsigned char*)std::malloc(nkw);
4492 if (status ==
nullptr)
4493 throw std::bad_alloc();
4494 stat_hold.reset(status);
4496 size_t n_might_match = nkw;
4497 size_t n_does_match = 0;
4499 unsigned char* st = status;
4500 for (
auto ky = kb; ky != ke; ++ky, ++st)
4512 for (
size_t indx = 0; is && n_might_match > 0; ++indx)
4515 auto ic = is.peek();
4518 is.setstate(std::ios::eofbit);
4521 auto c =
static_cast<char>(toupper(
static_cast<unsigned char>(ic)));
4522 bool consume =
false;
4530 for (
auto ky = kb; ky != ke; ++ky, ++st)
4532 if (*st == might_match)
4534 if (c ==
static_cast<char>(toupper(
static_cast<unsigned char>((*ky)[indx]))))
4537 if (ky->size() == indx+1)
4558 if (n_might_match + n_does_match > 1)
4561 for (
auto ky = kb; ky != ke; ++ky, ++st)
4563 if (*st == does_match && ky->size() != indx+1)
4574 for (st = status; kb != ke; ++kb, ++st)
4575 if (*st == does_match)
4578 is.setstate(std::ios::failbit);
4586 template <
class CharT,
class Traits,
class Duration>
4587 std::basic_ostream<CharT, Traits>&
4588 to_stream(std::basic_ostream<CharT, Traits>& os,
const CharT* fmt,
4589 const fields<Duration>& fds,
const std::string* abbrev,
4590 const std::chrono::seconds* offset_sec)
4593 using detail::weekday_names;
4594 using detail::month_names;
4595 using detail::ampm_names;
4597 using detail::save_ostream;
4598 using detail::get_units;
4599 using detail::extract_weekday;
4600 using detail::extract_month;
4602 using std::chrono::duration_cast;
4603 using std::chrono::seconds;
4604 using std::chrono::minutes;
4605 using std::chrono::hours;
4606 gul14::date::detail::save_ostream<CharT, Traits> ss(os);
4608 os.flags(std::ios::skipws | std::ios::dec);
4611 bool insert_negative = fds.has_tod && fds.tod.to_duration() < Duration::zero();
4613 auto& facet = std::use_facet<std::time_put<CharT>>(os.getloc());
4615 const CharT* command =
nullptr;
4616 CharT modified = CharT{};
4625 if (modified == CharT{})
4627 tm.tm_wday =
static_cast<int>(extract_weekday(os, fds));
4631 const CharT f[] = {
'%', *fmt};
4632 facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
4634 os << weekday_names().first[tm.tm_wday+7*(*fmt ==
'a')];
4639 os << CharT{
'%'} << modified << *fmt;
4652 if (modified == CharT{})
4654 tm.tm_mon =
static_cast<int>(extract_month(os, fds)) - 1;
4656 const CharT f[] = {
'%', *fmt};
4657 facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
4659 os << month_names().first[tm.tm_mon+12*(*fmt !=
'B')];
4664 os << CharT{
'%'} << modified << *fmt;
4676 if (modified == CharT{
'O'})
4677 os << CharT{
'%'} << modified << *fmt;
4681 os.setstate(std::ios::failbit);
4682 if (*fmt ==
'c' && !fds.has_tod)
4683 os.setstate(std::ios::failbit);
4686 auto const& ymd = fds.ymd;
4687 auto ld = local_days(ymd);
4690 tm.tm_sec =
static_cast<int>(fds.tod.seconds().count());
4691 tm.tm_min =
static_cast<int>(fds.tod.minutes().count());
4692 tm.tm_hour =
static_cast<int>(fds.tod.hours().count());
4694 tm.tm_mday =
static_cast<int>(
static_cast<unsigned>(ymd.day()));
4695 tm.tm_mon =
static_cast<int>(extract_month(os, fds) - 1);
4696 tm.tm_year =
static_cast<int>(ymd.year()) - 1900;
4697 tm.tm_wday =
static_cast<int>(extract_weekday(os, fds));
4700 tm.tm_yday =
static_cast<int>((ld - local_days(ymd.year()/1/1)).count());
4702 auto fe = std::begin(f) + 1;
4703 if (modified == CharT{
'E'})
4706 facet.put(os, os, os.fill(), &tm, std::begin(f), fe);
4710 auto wd =
static_cast<int>(extract_weekday(os, fds));
4711 os << weekday_names().first[
static_cast<unsigned>(wd)+7]
4713 os << month_names().first[extract_month(os, fds)-1+12] <<
' ';
4714 auto d =
static_cast<int>(
static_cast<unsigned>(fds.ymd.day()));
4718 << make_time(duration_cast<seconds>(fds.tod.to_duration()))
4719 <<
' ' << fds.ymd.year();
4724 auto const& ymd = fds.ymd;
4725 save_ostream<CharT, Traits> _(os);
4727 os.flags(std::ios::dec | std::ios::right);
4729 os << static_cast<unsigned>(ymd.month()) << CharT{
'/'};
4731 os << static_cast<unsigned>(ymd.day()) << CharT{
'/'};
4733 os << static_cast<int>(ymd.year()) % 100;
4746 if (modified == CharT{
'O'})
4747 os << CharT{
'%'} << modified << *fmt;
4750 if (!fds.ymd.year().ok())
4751 os.setstate(std::ios::failbit);
4752 auto y =
static_cast<int>(fds.ymd.year());
4754 if (modified == CharT{})
4757 save_ostream<CharT, Traits> _(os);
4759 os.flags(std::ios::dec | std::ios::right);
4773 else if (modified == CharT{
'E'})
4775 tm.tm_year = y - 1900;
4776 CharT f[3] = {
'%',
'E',
'C'};
4777 facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
4791 if (modified == CharT{
'E'})
4792 os << CharT{
'%'} << modified << *fmt;
4795 if (!fds.ymd.day().ok())
4796 os.setstate(std::ios::failbit);
4797 auto d =
static_cast<int>(
static_cast<unsigned>(fds.ymd.day()));
4799 if (modified == CharT{})
4802 save_ostream<CharT, Traits> _(os);
4803 if (*fmt == CharT{
'd'})
4807 os.flags(std::ios::dec | std::ios::right);
4812 else if (modified == CharT{
'O'})
4815 CharT f[3] = {
'%',
'O', *fmt};
4816 facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
4829 if (modified == CharT{})
4832 os.setstate(std::ios::failbit);
4833 auto const& ymd = fds.ymd;
4834 save_ostream<CharT, Traits> _(os);
4836 os.flags(std::ios::dec | std::ios::right);
4838 os << static_cast<unsigned>(ymd.month()) << CharT{
'/'};
4840 os << static_cast<unsigned>(ymd.day()) << CharT{
'/'};
4842 os << static_cast<int>(ymd.year()) % 100;
4846 os << CharT{
'%'} << modified << *fmt;
4857 if (modified == CharT{})
4860 os.setstate(std::ios::failbit);
4861 auto const& ymd = fds.ymd;
4862 save_ostream<CharT, Traits> _(os);
4863 os.imbue(std::locale::classic());
4865 os.flags(std::ios::dec | std::ios::right);
4867 os << static_cast<int>(ymd.year()) << CharT{
'-'};
4869 os << static_cast<unsigned>(ymd.month()) << CharT{
'-'};
4871 os << static_cast<unsigned>(ymd.day());
4875 os << CharT{
'%'} << modified << *fmt;
4887 if (modified == CharT{})
4890 os.setstate(std::ios::failbit);
4891 auto ld = local_days(fds.ymd);
4892 auto y = year_month_day{ld + days{3}}.year();
4893 auto start = local_days((y-years{1})/December/Thursday[last]) +
4897 if (*fmt == CharT{
'G'})
4901 save_ostream<CharT, Traits> _(os);
4903 os.flags(std::ios::dec | std::ios::right);
4905 os << std::abs(static_cast<int>(y)) % 100;
4910 os << CharT{
'%'} << modified << *fmt;
4922 if (modified == CharT{
'E'})
4923 os << CharT{
'%'} << modified << *fmt;
4927 os.setstate(std::ios::failbit);
4928 if (insert_negative)
4931 insert_negative =
false;
4935 if (modified == CharT{})
4938 auto h = *fmt == CharT{
'I'} ? gul14::date::make12(hms.hours()) : hms.hours();
4944 else if (modified == CharT{
'O'})
4946 const CharT f[] = {
'%', modified, *fmt};
4947 tm.tm_hour =
static_cast<int>(hms.hours().count());
4948 facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
4961 if (modified == CharT{})
4963 if (fds.ymd.ok() || fds.has_tod)
4968 auto ld = local_days(fds.ymd);
4969 auto y = fds.ymd.year();
4970 doy = ld - local_days(y/January/1) + days{1};
4974 doy = duration_cast<days>(fds.tod.to_duration());
4976 save_ostream<CharT, Traits> _(os);
4978 os.flags(std::ios::dec | std::ios::right);
4984 os.setstate(std::ios::failbit);
4989 os << CharT{
'%'} << modified << *fmt;
5000 if (modified == CharT{
'E'})
5001 os << CharT{
'%'} << modified << *fmt;
5004 if (!fds.ymd.month().ok())
5005 os.setstate(std::ios::failbit);
5006 auto m =
static_cast<unsigned>(fds.ymd.month());
5008 if (modified == CharT{})
5016 else if (modified == CharT{
'O'})
5018 const CharT f[] = {
'%', modified, *fmt};
5019 tm.tm_mon =
static_cast<int>(m-1);
5020 facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5033 if (modified == CharT{
'E'})
5034 os << CharT{
'%'} << modified << *fmt;
5038 os.setstate(std::ios::failbit);
5039 if (insert_negative)
5042 insert_negative =
false;
5045 if (modified == CharT{})
5048 if (fds.tod.minutes() < minutes{10})
5050 os << fds.tod.minutes().count();
5053 else if (modified == CharT{
'O'})
5055 const CharT f[] = {
'%', modified, *fmt};
5056 tm.tm_min =
static_cast<int>(fds.tod.minutes().count());
5057 facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5070 if (modified == CharT{})
5074 os << CharT{
'%'} << modified << *fmt;
5085 if (modified == CharT{})
5088 os.setstate(std::ios::failbit);
5090 const CharT f[] = {
'%', *fmt};
5091 tm.tm_hour =
static_cast<int>(fds.tod.hours().count());
5092 facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5094 if (gul14::date::is_am(fds.tod.hours()))
5095 os << ampm_names().first[0];
5097 os << ampm_names().first[1];
5102 os << CharT{
'%'} << modified << *fmt;
5114 if (modified == CharT{})
5117 os.setstate(std::ios::failbit);
5118 auto d = fds.tod.to_duration();
5120 os << get_units<CharT>(
typename decltype(d)::period::type{});
5126 os << CharT{
'%'} << modified << *fmt;
5137 if (modified == CharT{})
5140 os.setstate(std::ios::failbit);
5142 const CharT f[] = {
'%', *fmt};
5143 tm.tm_hour =
static_cast<int>(fds.tod.hours().count());
5144 tm.tm_min =
static_cast<int>(fds.tod.minutes().count());
5145 tm.tm_sec =
static_cast<int>(fds.tod.seconds().count());
5146 facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5148 hh_mm_ss<seconds> tod(duration_cast<seconds>(fds.tod.to_duration()));
5149 save_ostream<CharT, Traits> _(os);
5152 os << gul14::date::make12(tod.hours()).count() << CharT{
':'};
5154 os << tod.minutes().count() << CharT{
':'};
5156 os << tod.seconds().count() << CharT{
' '};
5157 if (gul14::date::is_am(tod.hours()))
5158 os << ampm_names().first[0];
5160 os << ampm_names().first[1];
5165 os << CharT{
'%'} << modified << *fmt;
5176 if (modified == CharT{})
5179 os.setstate(std::ios::failbit);
5180 if (fds.tod.hours() < hours{10})
5182 os << fds.tod.hours().count() << CharT{
':'};
5183 if (fds.tod.minutes() < minutes{10})
5185 os << fds.tod.minutes().count();
5189 os << CharT{
'%'} << modified << *fmt;
5200 if (modified == CharT{
'E'})
5201 os << CharT{
'%'} << modified << *fmt;
5205 os.setstate(std::ios::failbit);
5206 if (insert_negative)
5209 insert_negative =
false;
5212 if (modified == CharT{})
5218 else if (modified == CharT{
'O'})
5220 const CharT f[] = {
'%', modified, *fmt};
5221 tm.tm_sec =
static_cast<int>(fds.tod.s_.seconds().count());
5222 facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5235 if (modified == CharT{})
5239 os << CharT{
'%'} << modified << *fmt;
5250 if (modified == CharT{})
5253 os.setstate(std::ios::failbit);
5258 os << CharT{
'%'} << modified << *fmt;
5269 if (modified == CharT{
'E'})
5270 os << CharT{
'%'} << modified << *fmt;
5273 auto wd = extract_weekday(os, fds);
5275 if (modified == CharT{})
5278 os << (wd != 0 ? wd : 7u);
5281 else if (modified == CharT{
'O'})
5283 const CharT f[] = {
'%', modified, *fmt};
5284 tm.tm_wday =
static_cast<int>(wd);
5285 facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5298 if (modified == CharT{
'E'})
5299 os << CharT{
'%'} << modified << *fmt;
5302 auto const& ymd = fds.ymd;
5304 os.setstate(std::ios::failbit);
5305 auto ld = local_days(ymd);
5307 if (modified == CharT{})
5310 auto st = local_days(Sunday[1]/January/ymd.year());
5312 os << CharT{
'0'} << CharT{
'0'};
5315 auto wn = duration_cast<weeks>(ld - st).count() + 1;
5322 else if (modified == CharT{
'O'})
5324 const CharT f[] = {
'%', modified, *fmt};
5325 tm.tm_year =
static_cast<int>(ymd.year()) - 1900;
5326 tm.tm_wday =
static_cast<int>(extract_weekday(os, fds));
5329 tm.tm_yday =
static_cast<int>((ld - local_days(ymd.year()/1/1)).count());
5330 facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5343 if (modified == CharT{
'E'})
5344 os << CharT{
'%'} << modified << *fmt;
5348 os.setstate(std::ios::failbit);
5349 auto ld = local_days(fds.ymd);
5351 if (modified == CharT{})
5354 auto y = year_month_day{ld + days{3}}.year();
5355 auto st = local_days((y-years{1})/12/Thursday[last]) +
5360 st = local_days((y - years{1})/12/Thursday[last]) +
5363 auto wn = duration_cast<weeks>(ld - st).count() + 1;
5369 else if (modified == CharT{
'O'})
5371 const CharT f[] = {
'%', modified, *fmt};
5372 auto const& ymd = fds.ymd;
5373 tm.tm_year =
static_cast<int>(ymd.year()) - 1900;
5374 tm.tm_wday =
static_cast<int>(extract_weekday(os, fds));
5377 tm.tm_yday =
static_cast<int>((ld - local_days(ymd.year()/1/1)).count());
5378 facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5391 auto wd = extract_weekday(os, fds);
5395 if (modified == CharT{})
5397 if (modified != CharT{
'E'})
5403 else if (modified == CharT{
'O'})
5405 const CharT f[] = {
'%', modified, *fmt};
5406 tm.tm_wday =
static_cast<int>(wd);
5407 facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5412 os << CharT{
'%'} << modified << *fmt;
5423 if (modified == CharT{
'E'})
5424 os << CharT{
'%'} << modified << *fmt;
5427 auto const& ymd = fds.ymd;
5429 os.setstate(std::ios::failbit);
5430 auto ld = local_days(ymd);
5432 if (modified == CharT{})
5435 auto st = local_days(Monday[1]/January/ymd.year());
5437 os << CharT{
'0'} << CharT{
'0'};
5440 auto wn = duration_cast<weeks>(ld - st).count() + 1;
5447 else if (modified == CharT{
'O'})
5449 const CharT f[] = {
'%', modified, *fmt};
5450 tm.tm_year =
static_cast<int>(ymd.year()) - 1900;
5451 tm.tm_wday =
static_cast<int>(extract_weekday(os, fds));
5454 tm.tm_yday =
static_cast<int>((ld - local_days(ymd.year()/1/1)).count());
5455 facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5468 if (modified == CharT{
'O'})
5469 os << CharT{
'%'} << modified << *fmt;
5473 os.setstate(std::ios::failbit);
5476 tm.tm_sec =
static_cast<int>(fds.tod.seconds().count());
5477 tm.tm_min =
static_cast<int>(fds.tod.minutes().count());
5478 tm.tm_hour =
static_cast<int>(fds.tod.hours().count());
5480 auto fe = std::begin(f) + 1;
5481 if (modified == CharT{
'E'})
5484 facet.put(os, os, os.fill(), &tm, std::begin(f), fe);
5498 if (!fds.ymd.year().ok())
5499 os.setstate(std::ios::failbit);
5500 auto y =
static_cast<int>(fds.ymd.year());
5502 if (modified == CharT{})
5513 const CharT f[] = {
'%', modified, *fmt};
5514 tm.tm_year = y - 1900;
5515 facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5527 if (modified == CharT{
'O'})
5528 os << CharT{
'%'} << modified << *fmt;
5531 if (!fds.ymd.year().ok())
5532 os.setstate(std::ios::failbit);
5533 auto y = fds.ymd.year();
5535 if (modified == CharT{})
5538 save_ostream<CharT, Traits> _(os);
5539 os.imbue(std::locale::classic());
5543 else if (modified == CharT{
'E'})
5545 const CharT f[] = {
'%', modified, *fmt};
5546 tm.tm_year =
static_cast<int>(y) - 1900;
5547 facet.put(os, os, os.fill(), &tm, std::begin(f), std::end(f));
5560 if (offset_sec ==
nullptr)
5563 os.setstate(ios::failbit);
5566 auto m = duration_cast<minutes>(*offset_sec);
5567 auto neg = m < minutes{0};
5569 auto h = duration_cast<hours>(m);
5578 if (modified != CharT{})
5580 if (m < minutes{10})
5592 if (modified == CharT{})
5594 if (abbrev ==
nullptr)
5597 os.setstate(ios::failbit);
5600 for (
auto c : *abbrev)
5605 os << CharT{
'%'} << modified << *fmt;
5617 if (modified == CharT{})
5623 os << CharT{
'%'} << modified << *fmt;
5634 if (modified == CharT{})
5641 os << CharT{
'%'} << modified << CharT{
'%'};
5655 if (modified != CharT{})
5666 if (modified != CharT{})
5671 template <
class CharT,
class Traits>
5673 std::basic_ostream<CharT, Traits>&
5674 to_stream(std::basic_ostream<CharT, Traits>& os,
const CharT* fmt,
const year& y)
5676 using CT = std::chrono::seconds;
5677 fields<CT> fds{y/0/0};
5678 return to_stream(os, fmt, fds);
5681 template <
class CharT,
class Traits>
5683 std::basic_ostream<CharT, Traits>&
5684 to_stream(std::basic_ostream<CharT, Traits>& os,
const CharT* fmt,
const month& m)
5686 using CT = std::chrono::seconds;
5687 fields<CT> fds{m/0/nanyear};
5688 return to_stream(os, fmt, fds);
5691 template <
class CharT,
class Traits>
5693 std::basic_ostream<CharT, Traits>&
5694 to_stream(std::basic_ostream<CharT, Traits>& os,
const CharT* fmt,
const day& d)
5696 using CT = std::chrono::seconds;
5697 fields<CT> fds{d/0/nanyear};
5698 return to_stream(os, fmt, fds);
5701 template <
class CharT,
class Traits>
5703 std::basic_ostream<CharT, Traits>&
5704 to_stream(std::basic_ostream<CharT, Traits>& os,
const CharT* fmt,
const weekday& wd)
5706 using CT = std::chrono::seconds;
5708 return to_stream(os, fmt, fds);
5711 template <
class CharT,
class Traits>
5713 std::basic_ostream<CharT, Traits>&
5714 to_stream(std::basic_ostream<CharT, Traits>& os,
const CharT* fmt,
const year_month& ym)
5716 using CT = std::chrono::seconds;
5717 fields<CT> fds{ym/0};
5718 return to_stream(os, fmt, fds);
5721 template <
class CharT,
class Traits>
5723 std::basic_ostream<CharT, Traits>&
5724 to_stream(std::basic_ostream<CharT, Traits>& os,
const CharT* fmt,
const month_day& md)
5726 using CT = std::chrono::seconds;
5727 fields<CT> fds{md/nanyear};
5728 return to_stream(os, fmt, fds);
5731 template <
class CharT,
class Traits>
5733 std::basic_ostream<CharT, Traits>&
5734 to_stream(std::basic_ostream<CharT, Traits>& os,
const CharT* fmt,
5735 const year_month_day& ymd)
5737 using CT = std::chrono::seconds;
5738 fields<CT> fds{ymd};
5739 return to_stream(os, fmt, fds);
5742 template <
class CharT,
class Traits,
class Rep,
class Period>
5744 std::basic_ostream<CharT, Traits>&
5745 to_stream(std::basic_ostream<CharT, Traits>& os,
const CharT* fmt,
5746 const std::chrono::duration<Rep, Period>& d)
5748 using Duration = std::chrono::duration<Rep, Period>;
5749 using CT =
typename std::common_type<Duration, std::chrono::seconds>::type;
5750 fields<CT> fds{hh_mm_ss<CT>{d}};
5751 return to_stream(os, fmt, fds);
5754 template <
class CharT,
class Traits,
class Duration>
5755 std::basic_ostream<CharT, Traits>&
5756 to_stream(std::basic_ostream<CharT, Traits>& os,
const CharT* fmt,
5757 const local_time<Duration>& tp,
const std::string* abbrev =
nullptr,
5758 const std::chrono::seconds* offset_sec =
nullptr)
5760 using CT =
typename std::common_type<Duration, std::chrono::seconds>::type;
5761 auto ld = std::chrono::time_point_cast<days>(tp);
5764 fds = fields<CT>{year_month_day{ld}, hh_mm_ss<CT>{tp-local_seconds{ld}}};
5766 fds = fields<CT>{year_month_day{ld - days{1}},
5767 hh_mm_ss<CT>{days{1} - (local_seconds{ld} - tp)}};
5768 return to_stream(os, fmt, fds, abbrev, offset_sec);
5771 template <
class CharT,
class Traits,
class Duration>
5772 std::basic_ostream<CharT, Traits>&
5773 to_stream(std::basic_ostream<CharT, Traits>& os,
const CharT* fmt,
5774 const sys_time<Duration>& tp)
5776 using std::chrono::seconds;
5777 using CT =
typename std::common_type<Duration, seconds>::type;
5778 const std::string abbrev(
"UTC");
5779 constexpr
const seconds offset{0};
5780 auto sd = std::chrono::time_point_cast<days>(tp);
5783 fds = fields<CT>{year_month_day{sd}, hh_mm_ss<CT>{tp-sys_seconds{sd}}};
5785 fds = fields<CT>{year_month_day{sd - days{1}},
5786 hh_mm_ss<CT>{days{1} - (sys_seconds{sd} - tp)}};
5787 return to_stream(os, fmt, fds, &abbrev, &offset);
5792 template <
class CharT,
class Streamable>
5794 format(
const std::locale& loc,
const CharT* fmt,
const Streamable& tp)
5795 -> decltype(to_stream(std::declval<std::basic_ostream<CharT>&>(), fmt, tp),
5796 std::basic_string<CharT>{})
5798 std::basic_ostringstream<CharT> os;
5799 os.exceptions(std::ios::failbit | std::ios::badbit);
5801 to_stream(os, fmt, tp);
5805 template <
class CharT,
class Streamable>
5807 format(
const CharT* fmt,
const Streamable& tp)
5808 -> decltype(to_stream(std::declval<std::basic_ostream<CharT>&>(), fmt, tp),
5809 std::basic_string<CharT>{})
5811 std::basic_ostringstream<CharT> os;
5812 os.exceptions(std::ios::failbit | std::ios::badbit);
5813 to_stream(os, fmt, tp);
5817 template <
class CharT,
class Traits,
class Alloc,
class Streamable>
5819 format(
const std::locale& loc,
const std::basic_string<CharT, Traits, Alloc>& fmt,
5820 const Streamable& tp)
5821 -> decltype(to_stream(std::declval<std::basic_ostream<CharT, Traits>&>(), fmt.c_str(), tp),
5822 std::basic_string<CharT, Traits, Alloc>{})
5824 std::basic_ostringstream<CharT, Traits, Alloc> os;
5825 os.exceptions(std::ios::failbit | std::ios::badbit);
5827 to_stream(os, fmt.c_str(), tp);
5831 template <
class CharT,
class Traits,
class Alloc,
class Streamable>
5833 format(
const std::basic_string<CharT, Traits, Alloc>& fmt,
const Streamable& tp)
5834 -> decltype(to_stream(std::declval<std::basic_ostream<CharT, Traits>&>(), fmt.c_str(), tp),
5835 std::basic_string<CharT, Traits, Alloc>{})
5837 std::basic_ostringstream<CharT, Traits, Alloc> os;
5838 os.exceptions(std::ios::failbit | std::ios::badbit);
5839 to_stream(os, fmt.c_str(), tp);
5848 template <
class CharT,
class Traits>
5850 read_char(std::basic_istream<CharT, Traits>& is, CharT fmt, std::ios::iostate& err)
5853 if (Traits::eq_int_type(ic, Traits::eof()) ||
5854 !Traits::eq(Traits::to_char_type(ic), fmt))
5856 err |= std::ios::failbit;
5857 is.setstate(std::ios::failbit);
5863 template <
class CharT,
class Traits>
5865 read_unsigned(std::basic_istream<CharT, Traits>& is,
unsigned m = 1,
unsigned M = 10)
5871 auto ic = is.peek();
5872 if (Traits::eq_int_type(ic, Traits::eof()))
5874 auto c =
static_cast<char>(Traits::to_char_type(ic));
5875 if (!(
'0' <= c && c <=
'9'))
5879 x = 10*x +
static_cast<unsigned>(c -
'0');
5884 is.setstate(std::ios::failbit);
5888 template <
class CharT,
class Traits>
5890 read_signed(std::basic_istream<CharT, Traits>& is,
unsigned m = 1,
unsigned M = 10)
5892 auto ic = is.peek();
5893 if (!Traits::eq_int_type(ic, Traits::eof()))
5895 auto c =
static_cast<char>(Traits::to_char_type(ic));
5896 if ((
'0' <= c && c <=
'9') || c ==
'-' || c ==
'+')
5898 if (c ==
'-' || c ==
'+')
5900 auto x =
static_cast<int>(read_unsigned(is, std::max(m, 1u), M));
5910 is.setstate(std::ios::failbit);
5914 template <
class CharT,
class Traits>
5916 read_long_double(std::basic_istream<CharT, Traits>& is,
unsigned m = 1,
unsigned M = 10)
5919 unsigned fcount = 0;
5920 unsigned long long i = 0;
5921 unsigned long long f = 0;
5922 bool parsing_fraction =
false;
5924 typename Traits::int_type decimal_point =
'.';
5926 auto decimal_point = Traits::to_int_type(
5927 std::use_facet<std::numpunct<CharT>>(is.getloc()).decimal_point());
5931 auto ic = is.peek();
5932 if (Traits::eq_int_type(ic, Traits::eof()))
5934 if (Traits::eq_int_type(ic, decimal_point))
5936 decimal_point = Traits::eof();
5937 parsing_fraction =
true;
5941 auto c =
static_cast<char>(Traits::to_char_type(ic));
5942 if (!(
'0' <= c && c <=
'9'))
5944 if (!parsing_fraction)
5946 i = 10*i +
static_cast<unsigned>(c -
'0');
5950 f = 10*f +
static_cast<unsigned>(c -
'0');
5960 is.setstate(std::ios::failbit);
5963 return static_cast<long double>(i) +
static_cast<long double>(f)/std::pow(10.L, fcount);
5987 template <
class CharT,
class Traits>
5989 read(std::basic_istream<CharT, Traits>&)
5993 template <
class CharT,
class Traits,
class ...Args>
5995 read(std::basic_istream<CharT, Traits>& is, CharT a0, Args&& ...args);
5997 template <
class CharT,
class Traits,
class ...Args>
5999 read(std::basic_istream<CharT, Traits>& is, rs a0, Args&& ...args);
6001 template <
class CharT,
class Traits,
class ...Args>
6003 read(std::basic_istream<CharT, Traits>& is, ru a0, Args&& ...args);
6005 template <
class CharT,
class Traits,
class ...Args>
6007 read(std::basic_istream<CharT, Traits>& is,
int a0, Args&& ...args);
6009 template <
class CharT,
class Traits,
class ...Args>
6011 read(std::basic_istream<CharT, Traits>& is, rld a0, Args&& ...args);
6013 template <
class CharT,
class Traits,
class ...Args>
6015 read(std::basic_istream<CharT, Traits>& is, CharT a0, Args&& ...args)
6020 auto ic = is.peek();
6021 if (Traits::eq_int_type(ic, Traits::eof()))
6023 is.setstate(std::ios::failbit | std::ios::eofbit);
6026 if (!Traits::eq(Traits::to_char_type(ic), a0))
6028 is.setstate(std::ios::failbit);
6033 read(is, std::forward<Args>(args)...);
6036 template <
class CharT,
class Traits,
class ...Args>
6038 read(std::basic_istream<CharT, Traits>& is, rs a0, Args&& ...args)
6040 auto x = read_signed(is, a0.m, a0.M);
6044 read(is, std::forward<Args>(args)...);
6047 template <
class CharT,
class Traits,
class ...Args>
6049 read(std::basic_istream<CharT, Traits>& is, ru a0, Args&& ...args)
6051 auto x = read_unsigned(is, a0.m, a0.M);
6054 a0.i =
static_cast<int>(x);
6055 read(is, std::forward<Args>(args)...);
6058 template <
class CharT,
class Traits,
class ...Args>
6060 read(std::basic_istream<CharT, Traits>& is,
int a0, Args&& ...args)
6064 auto u =
static_cast<unsigned>(a0);
6065 CharT buf[std::numeric_limits<unsigned>::digits10+2u] = {};
6069 *e++ =
static_cast<CharT
>(CharT(u % 10) + CharT{
'0'});
6072 std::reverse(buf, e);
6073 for (
auto p = buf; p != e && is.rdstate() == std::ios::goodbit; ++p)
6076 if (is.rdstate() == std::ios::goodbit)
6077 read(is, std::forward<Args>(args)...);
6080 template <
class CharT,
class Traits,
class ...Args>
6082 read(std::basic_istream<CharT, Traits>& is, rld a0, Args&& ...args)
6084 auto x = read_long_double(is, a0.m, a0.M);
6088 read(is, std::forward<Args>(args)...);
6091 template <
class T,
class CharT,
class Traits>
6094 checked_set(T& value, T from, T not_a_value, std::basic_ios<CharT, Traits>& is)
6098 if (value == not_a_value)
6099 value = std::move(from);
6100 else if (value != from)
6101 is.setstate(std::ios::failbit);
6107 template <
class CharT,
class Traits,
class Duration,
class Alloc = std::allocator<CharT>>
6108 std::basic_istream<CharT, Traits>&
6109 from_stream(std::basic_istream<CharT, Traits>& is,
const CharT* fmt,
6110 fields<Duration>& fds, std::basic_string<CharT, Traits, Alloc>* abbrev,
6111 std::chrono::minutes* offset)
6113 using std::numeric_limits;
6115 using std::chrono::duration;
6116 using std::chrono::duration_cast;
6117 using std::chrono::seconds;
6118 using std::chrono::minutes;
6119 using std::chrono::hours;
6120 using detail::round_i;
6121 typename std::basic_istream<CharT, Traits>::sentry ok{is,
true};
6124 gul14::date::detail::save_istream<CharT, Traits> ss(is);
6126 is.flags(std::ios::skipws | std::ios::dec);
6129 auto& f = std::use_facet<std::time_get<CharT>>(is.getloc());
6132 const CharT* command =
nullptr;
6133 auto modified = CharT{};
6136 constexpr
const int not_a_year = numeric_limits<short>::min();
6137 constexpr
const int not_a_2digit_year = 100;
6138 constexpr
const int not_a_century = not_a_year / 100;
6139 constexpr
const int not_a_month = 0;
6140 constexpr
const int not_a_day = 0;
6141 constexpr
const int not_a_hour = numeric_limits<int>::min();
6142 constexpr
const int not_a_hour_12_value = 0;
6143 constexpr
const int not_a_minute = not_a_hour;
6144 constexpr
const Duration not_a_second = Duration::min();
6145 constexpr
const int not_a_doy = -1;
6146 constexpr
const int not_a_weekday = 8;
6147 constexpr
const int not_a_week_num = 100;
6148 constexpr
const int not_a_ampm = -1;
6149 constexpr
const minutes not_a_offset = minutes::min();
6152 int y = not_a_2digit_year;
6153 int g = not_a_2digit_year;
6155 int C = not_a_century;
6156 int m = not_a_month;
6159 int wd = not_a_weekday;
6161 int I = not_a_hour_12_value;
6163 int M = not_a_minute;
6164 Duration s = not_a_second;
6165 int U = not_a_week_num;
6166 int V = not_a_week_num;
6167 int W = not_a_week_num;
6168 std::basic_string<CharT, Traits, Alloc> temp_abbrev;
6169 minutes temp_offset = not_a_offset;
6175 using detail::checked_set;
6176 for (; *fmt != CharT{} && !is.fail(); ++fmt)
6186 int trial_wd = not_a_weekday;
6187 if (*fmt ==
'a' || *fmt ==
'A')
6189 if (modified == CharT{})
6192 ios::iostate err = ios::goodbit;
6193 f.get(is,
nullptr, is, err, &tm, command, fmt+1);
6196 trial_wd = tm.tm_wday;
6198 auto nm = detail::weekday_names();
6199 auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6205 read(is, CharT{
'%'}, width, modified, *fmt);
6210 if (modified == CharT{})
6212 if (modified != CharT{
'E'})
6215 read(is, ru{trial_wd, 1, width == -1 ?
6216 1u :
static_cast<unsigned>(width)});
6221 if (!(1 <= trial_wd && trial_wd <= 7))
6223 trial_wd = not_a_weekday;
6224 is.setstate(ios::failbit);
6226 else if (trial_wd == 7)
6231 if (!(0 <= trial_wd && trial_wd <= 6))
6233 trial_wd = not_a_weekday;
6234 is.setstate(ios::failbit);
6240 else if (modified == CharT{
'O'})
6242 ios::iostate err = ios::goodbit;
6243 f.get(is,
nullptr, is, err, &tm, command, fmt+1);
6246 trial_wd = tm.tm_wday;
6250 read(is, CharT{
'%'}, width, modified, *fmt);
6252 if (trial_wd != not_a_weekday)
6253 checked_set(wd, trial_wd, not_a_weekday, is);
6266 if (modified == CharT{})
6268 int ttm = not_a_month;
6270 ios::iostate err = ios::goodbit;
6271 f.get(is,
nullptr, is, err, &tm, command, fmt+1);
6272 if ((err & ios::failbit) == 0)
6273 ttm = tm.tm_mon + 1;
6276 auto nm = detail::month_names();
6277 auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6281 checked_set(m, ttm, not_a_month, is);
6284 read(is, CharT{
'%'}, width, modified, *fmt);
6295 if (modified != CharT{
'O'})
6298 ios::iostate err = ios::goodbit;
6299 f.get(is,
nullptr, is, err, &tm, command, fmt+1);
6300 if ((err & ios::failbit) == 0)
6302 checked_set(Y, tm.tm_year + 1900, not_a_year, is);
6303 checked_set(m, tm.tm_mon + 1, not_a_month, is);
6304 checked_set(d, tm.tm_mday, not_a_day, is);
6305 checked_set(H, tm.tm_hour, not_a_hour, is);
6306 checked_set(M, tm.tm_min, not_a_minute, is);
6307 checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}),
6313 auto nm = detail::weekday_names();
6314 auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6315 checked_set(wd,
static_cast<int>(i % 7), not_a_weekday, is);
6317 nm = detail::month_names();
6318 i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6319 checked_set(m,
static_cast<int>(i % 12 + 1), not_a_month, is);
6322 read(is, rs{td, 1, 2});
6323 checked_set(d, td, not_a_day, is);
6325 using dfs = detail::decimal_format_seconds<Duration>;
6326 constexpr
const auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
6330 read(is, ru{tH, 1, 2}, CharT{
':'}, ru{tM, 1, 2},
6331 CharT{
':'}, rld{S, 1, w});
6332 checked_set(H, tH, not_a_hour, is);
6333 checked_set(M, tM, not_a_minute, is);
6334 checked_set(s, round_i<Duration>(duration<long double>{S}),
6337 int tY = not_a_year;
6338 read(is, rs{tY, 1, 4u});
6339 checked_set(Y, tY, not_a_year, is);
6343 read(is, CharT{
'%'}, width, modified, *fmt);
6354 if (modified != CharT{
'O'})
6357 ios::iostate err = ios::goodbit;
6358 f.get(is,
nullptr, is, err, &tm, command, fmt+1);
6359 if ((err & ios::failbit) == 0)
6361 checked_set(Y, tm.tm_year + 1900, not_a_year, is);
6362 checked_set(m, tm.tm_mon + 1, not_a_month, is);
6363 checked_set(d, tm.tm_mday, not_a_day, is);
6368 int ty = not_a_2digit_year;
6369 int tm = not_a_month;
6371 read(is, ru{tm, 1, 2}, CharT{
'/'}, ru{td, 1, 2}, CharT{
'/'},
6373 checked_set(y, ty, not_a_2digit_year, is);
6374 checked_set(m, tm, not_a_month, is);
6375 checked_set(d, td, not_a_day, is);
6379 read(is, CharT{
'%'}, width, modified, *fmt);
6390 if (modified != CharT{
'O'})
6393 ios::iostate err = ios::goodbit;
6394 f.get(is,
nullptr, is, err, &tm, command, fmt+1);
6395 if ((err & ios::failbit) == 0)
6397 checked_set(H, tm.tm_hour, not_a_hour, is);
6398 checked_set(M, tm.tm_min, not_a_minute, is);
6399 checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}),
6405 using dfs = detail::decimal_format_seconds<Duration>;
6406 constexpr
const auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
6407 int tH = not_a_hour;
6408 int tM = not_a_minute;
6410 read(is, ru{tH, 1, 2}, CharT{
':'}, ru{tM, 1, 2},
6411 CharT{
':'}, rld{S, 1, w});
6412 checked_set(H, tH, not_a_hour, is);
6413 checked_set(M, tM, not_a_minute, is);
6414 checked_set(s, round_i<Duration>(duration<long double>{S}),
6419 read(is, CharT{
'%'}, width, modified, *fmt);
6430 int tC = not_a_century;
6432 if (modified == CharT{})
6435 read(is, rs{tC, 1, width == -1 ? 2u :
static_cast<unsigned>(width)});
6440 ios::iostate err = ios::goodbit;
6441 f.get(is,
nullptr, is, err, &tm, command, fmt+1);
6442 if ((err & ios::failbit) == 0)
6444 auto tY = tm.tm_year + 1900;
6445 tC = (tY >= 0 ? tY : tY-99) / 100;
6450 checked_set(C, tC, not_a_century, is);
6461 if (modified == CharT{})
6463 int tn = not_a_month;
6465 int ty = not_a_2digit_year;
6466 read(is, ru{tn, 1, 2}, CharT{
'\0'}, CharT{
'/'}, CharT{
'\0'},
6467 ru{td, 1, 2}, CharT{
'\0'}, CharT{
'/'}, CharT{
'\0'},
6469 checked_set(y, ty, not_a_2digit_year, is);
6470 checked_set(m, tn, not_a_month, is);
6471 checked_set(d, td, not_a_day, is);
6474 read(is, CharT{
'%'}, width, modified, *fmt);
6485 if (modified == CharT{})
6487 int tY = not_a_year;
6488 int tn = not_a_month;
6490 read(is, rs{tY, 1, width == -1 ? 4u :
static_cast<unsigned>(width)},
6491 CharT{
'-'}, ru{tn, 1, 2}, CharT{
'-'}, ru{td, 1, 2});
6492 checked_set(Y, tY, not_a_year, is);
6493 checked_set(m, tn, not_a_month, is);
6494 checked_set(d, td, not_a_day, is);
6497 read(is, CharT{
'%'}, width, modified, *fmt);
6510 if (modified == CharT{})
6512 if (modified != CharT{
'E'})
6516 read(is, rs{td, 1, width == -1 ? 2u :
static_cast<unsigned>(width)});
6517 checked_set(d, td, not_a_day, is);
6520 else if (modified == CharT{
'O'})
6522 ios::iostate err = ios::goodbit;
6523 f.get(is,
nullptr, is, err, &tm, command, fmt+1);
6527 if ((err & ios::failbit) == 0)
6528 checked_set(d, tm.tm_mday, not_a_day, is);
6533 read(is, CharT{
'%'}, width, modified, *fmt);
6545 if (modified == CharT{})
6547 if (modified != CharT{
'E'})
6550 int tH = not_a_hour;
6551 read(is, ru{tH, 1, width == -1 ? 2u :
static_cast<unsigned>(width)});
6552 checked_set(H, tH, not_a_hour, is);
6555 else if (modified == CharT{
'O'})
6557 ios::iostate err = ios::goodbit;
6558 f.get(is,
nullptr, is, err, &tm, command, fmt+1);
6559 if ((err & ios::failbit) == 0)
6560 checked_set(H, tm.tm_hour, not_a_hour, is);
6565 read(is, CharT{
'%'}, width, modified, *fmt);
6576 if (modified == CharT{})
6578 int tI = not_a_hour_12_value;
6580 read(is, rs{tI, 1, width == -1 ? 2u :
static_cast<unsigned>(width)});
6581 if (!(1 <= tI && tI <= 12))
6582 is.setstate(ios::failbit);
6583 checked_set(I, tI, not_a_hour_12_value, is);
6586 read(is, CharT{
'%'}, width, modified, *fmt);
6597 if (modified == CharT{})
6600 read(is, ru{tj, 1, width == -1 ? 3u :
static_cast<unsigned>(width)});
6601 checked_set(j, tj, not_a_doy, is);
6604 read(is, CharT{
'%'}, width, modified, *fmt);
6616 if (modified == CharT{})
6618 if (modified != CharT{
'E'})
6621 int tM = not_a_minute;
6622 read(is, ru{tM, 1, width == -1 ? 2u :
static_cast<unsigned>(width)});
6623 checked_set(M, tM, not_a_minute, is);
6626 else if (modified == CharT{
'O'})
6628 ios::iostate err = ios::goodbit;
6629 f.get(is,
nullptr, is, err, &tm, command, fmt+1);
6630 if ((err & ios::failbit) == 0)
6631 checked_set(M, tm.tm_min, not_a_minute, is);
6636 read(is, CharT{
'%'}, width, modified, *fmt);
6648 if (modified == CharT{})
6650 if (modified != CharT{
'E'})
6653 int tn = not_a_month;
6654 read(is, rs{tn, 1, width == -1 ? 2u :
static_cast<unsigned>(width)});
6655 checked_set(m, tn, not_a_month, is);
6658 else if (modified == CharT{
'O'})
6660 ios::iostate err = ios::goodbit;
6661 f.get(is,
nullptr, is, err, &tm, command, fmt+1);
6662 if ((err & ios::failbit) == 0)
6663 checked_set(m, tm.tm_mon + 1, not_a_month, is);
6668 read(is, CharT{
'%'}, width, modified, *fmt);
6680 if (modified == CharT{})
6684 auto ic = is.peek();
6685 if (Traits::eq_int_type(ic, Traits::eof()))
6687 ios::iostate err = ios::eofbit;
6689 err |= ios::failbit;
6697 else if (*fmt ==
'n')
6698 is.setstate(ios::failbit);
6701 read(is, CharT{
'%'}, width, modified, *fmt);
6712 if (modified == CharT{})
6714 int tp = not_a_ampm;
6718 ios::iostate err = ios::goodbit;
6719 f.get(is,
nullptr, is, err, &tm, command, fmt+1);
6721 if (tm.tm_hour == 1)
6723 else if (tm.tm_hour == 13)
6728 auto nm = detail::ampm_names();
6729 auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6730 tp =
static_cast<decltype(tp)
>(i);
6732 checked_set(p, tp, not_a_ampm, is);
6735 read(is, CharT{
'%'}, width, modified, *fmt);
6747 if (modified == CharT{})
6750 ios::iostate err = ios::goodbit;
6751 f.get(is,
nullptr, is, err, &tm, command, fmt+1);
6752 if ((err & ios::failbit) == 0)
6754 checked_set(H, tm.tm_hour, not_a_hour, is);
6755 checked_set(M, tm.tm_min, not_a_hour, is);
6756 checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}),
6762 using dfs = detail::decimal_format_seconds<Duration>;
6763 constexpr
const auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
6765 int tI = not_a_hour_12_value;
6766 int tM = not_a_minute;
6767 read(is, ru{tI, 1, 2}, CharT{
':'}, ru{tM, 1, 2},
6768 CharT{
':'}, rld{S, 1, w});
6769 checked_set(I, tI, not_a_hour_12_value, is);
6770 checked_set(M, tM, not_a_minute, is);
6771 checked_set(s, round_i<Duration>(duration<long double>{S}),
6774 auto nm = detail::ampm_names();
6775 auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first;
6776 checked_set(p,
static_cast<int>(i), not_a_ampm, is);
6780 read(is, CharT{
'%'}, width, modified, *fmt);
6791 if (modified == CharT{})
6793 int tH = not_a_hour;
6794 int tM = not_a_minute;
6795 read(is, ru{tH, 1, 2}, CharT{
'\0'}, CharT{
':'}, CharT{
'\0'},
6796 ru{tM, 1, 2}, CharT{
'\0'});
6797 checked_set(H, tH, not_a_hour, is);
6798 checked_set(M, tM, not_a_minute, is);
6801 read(is, CharT{
'%'}, width, modified, *fmt);
6813 if (modified == CharT{})
6815 if (modified != CharT{
'E'})
6818 using dfs = detail::decimal_format_seconds<Duration>;
6819 constexpr
const auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
6821 read(is, rld{S, 1, width == -1 ? w :
static_cast<unsigned>(width)});
6822 checked_set(s, round_i<Duration>(duration<long double>{S}),
6826 else if (modified == CharT{
'O'})
6828 ios::iostate err = ios::goodbit;
6829 f.get(is,
nullptr, is, err, &tm, command, fmt+1);
6830 if ((err & ios::failbit) == 0)
6831 checked_set(s, duration_cast<Duration>(seconds{tm.tm_sec}),
6837 read(is, CharT{
'%'}, width, modified, *fmt);
6848 if (modified == CharT{})
6850 using dfs = detail::decimal_format_seconds<Duration>;
6851 constexpr
const auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width;
6852 int tH = not_a_hour;
6853 int tM = not_a_minute;
6855 read(is, ru{tH, 1, 2}, CharT{
':'}, ru{tM, 1, 2},
6856 CharT{
':'}, rld{S, 1, w});
6857 checked_set(H, tH, not_a_hour, is);
6858 checked_set(M, tM, not_a_minute, is);
6859 checked_set(s, round_i<Duration>(duration<long double>{S}),
6863 read(is, CharT{
'%'}, width, modified, *fmt);
6875 if (modified == CharT{})
6877 if (modified != CharT{
'O'})
6880 int tY = not_a_year;
6881 read(is, rs{tY, 1, width == -1 ? 4u :
static_cast<unsigned>(width)});
6882 checked_set(Y, tY, not_a_year, is);
6885 else if (modified == CharT{
'E'})
6887 ios::iostate err = ios::goodbit;
6888 f.get(is,
nullptr, is, err, &tm, command, fmt+1);
6889 if ((err & ios::failbit) == 0)
6890 checked_set(Y, tm.tm_year + 1900, not_a_year, is);
6895 read(is, CharT{
'%'}, width, modified, *fmt);
6907 if (modified == CharT{})
6910 int ty = not_a_2digit_year;
6911 read(is, ru{ty, 1, width == -1 ? 2u :
static_cast<unsigned>(width)});
6912 checked_set(y, ty, not_a_2digit_year, is);
6917 ios::iostate err = ios::goodbit;
6918 f.get(is,
nullptr, is, err, &tm, command, fmt+1);
6919 if ((err & ios::failbit) == 0)
6920 checked_set(Y, tm.tm_year + 1900, not_a_year, is);
6934 if (modified == CharT{})
6936 int tg = not_a_2digit_year;
6937 read(is, ru{tg, 1, width == -1 ? 2u :
static_cast<unsigned>(width)});
6938 checked_set(g, tg, not_a_2digit_year, is);
6941 read(is, CharT{
'%'}, width, modified, *fmt);
6952 if (modified == CharT{})
6954 int tG = not_a_year;
6955 read(is, rs{tG, 1, width == -1 ? 4u :
static_cast<unsigned>(width)});
6956 checked_set(G, tG, not_a_year, is);
6959 read(is, CharT{
'%'}, width, modified, *fmt);
6970 if (modified == CharT{})
6972 int tU = not_a_week_num;
6973 read(is, ru{tU, 1, width == -1 ? 2u :
static_cast<unsigned>(width)});
6974 checked_set(U, tU, not_a_week_num, is);
6977 read(is, CharT{
'%'}, width, modified, *fmt);
6988 if (modified == CharT{})
6990 int tV = not_a_week_num;
6991 read(is, ru{tV, 1, width == -1 ? 2u :
static_cast<unsigned>(width)});
6992 checked_set(V, tV, not_a_week_num, is);
6995 read(is, CharT{
'%'}, width, modified, *fmt);
7006 if (modified == CharT{})
7008 int tW = not_a_week_num;
7009 read(is, ru{tW, 1, width == -1 ? 2u :
static_cast<unsigned>(width)});
7010 checked_set(W, tW, not_a_week_num, is);
7013 read(is, CharT{
'%'}, width, modified, *fmt);
7025 if (modified == CharT{})
7031 read(is, CharT{
'%'}, width, modified, *fmt);
7043 if (modified == CharT{})
7046 read(is, CharT{
'%'}, width, modified, *fmt);
7058 minutes toff = not_a_offset;
7060 auto ic = is.peek();
7061 if (!Traits::eq_int_type(ic, Traits::eof()))
7063 auto c =
static_cast<char>(Traits::to_char_type(ic));
7067 if (modified == CharT{})
7069 read(is, rs{tH, 2, 2});
7075 if (!Traits::eq_int_type(ic, Traits::eof()))
7077 auto c =
static_cast<char>(Traits::to_char_type(ic));
7078 if (
'0' <= c && c <=
'9')
7080 read(is, ru{tM, 2, 2});
7082 toff += minutes{tM};
7089 read(is, rs{tH, 1, 2});
7095 if (!Traits::eq_int_type(ic, Traits::eof()))
7097 auto c =
static_cast<char>(Traits::to_char_type(ic));
7101 read(is, ru{tM, 2, 2});
7103 toff += minutes{tM};
7110 checked_set(temp_offset, toff, not_a_offset, is);
7121 if (modified == CharT{})
7123 std::basic_string<CharT, Traits, Alloc> buf;
7124 while (is.rdstate() == std::ios::goodbit)
7126 auto i = is.rdbuf()->sgetc();
7127 if (Traits::eq_int_type(i, Traits::eof()))
7129 is.setstate(ios::eofbit);
7132 auto wc = Traits::to_char_type(i);
7133 auto c =
static_cast<char>(wc);
7135 if (!(CharT{1} < wc && wc < CharT{127}) || !(isalnum(c) ||
7136 c ==
'_' || c ==
'/' || c ==
'-' || c ==
'+'))
7139 is.rdbuf()->sbumpc();
7142 is.setstate(ios::failbit);
7143 checked_set(temp_abbrev, buf, {}, is);
7146 read(is, CharT{
'%'}, width, modified, *fmt);
7157 if (width == -1 && modified == CharT{} &&
'0' <= *fmt && *fmt <=
'9')
7159 width =
static_cast<char>(*fmt) -
'0';
7160 while (
'0' <= fmt[1] && fmt[1] <=
'9')
7161 width = 10*width +
static_cast<char>(*++fmt) -
'0';
7165 if (modified == CharT{})
7166 read(is, CharT{
'%'}, width, *fmt);
7168 read(is, CharT{
'%'}, width, modified, *fmt);
7176 if (isspace(
static_cast<unsigned char>(*fmt)))
7189 if (is.rdstate() == ios::goodbit && command)
7191 if (modified == CharT{})
7192 read(is, CharT{
'%'}, width);
7194 read(is, CharT{
'%'}, width, modified);
7198 if (y != not_a_2digit_year)
7201 if (!(0 <= y && y <= 99))
7203 if (C == not_a_century)
7205 if (Y == not_a_year)
7214 C = (Y >= 0 ? Y : Y-100) / 100;
7221 tY = 100*(C+1) - (y == 0 ? 100 : y);
7222 if (Y != not_a_year && Y != tY)
7226 if (g != not_a_2digit_year)
7229 if (!(0 <= g && g <= 99))
7231 if (C == not_a_century)
7233 if (G == not_a_year)
7242 C = (G >= 0 ? G : G-100) / 100;
7249 tG = 100*(C+1) - (g == 0 ? 100 : g);
7250 if (G != not_a_year && G != tG)
7254 if (Y <
static_cast<int>(year::min()) || Y >
static_cast<int>(year::max()))
7256 bool computed =
false;
7257 if (G != not_a_year && V != not_a_week_num && wd != not_a_weekday)
7259 year_month_day ymd_trial = sys_days(year{G-1}/December/Thursday[last]) +
7260 (Monday-Thursday) + weeks{V-1} +
7261 (weekday{
static_cast<unsigned>(wd)}-Monday);
7262 if (Y == not_a_year)
7263 Y =
static_cast<int>(ymd_trial.year());
7264 else if (year{Y} != ymd_trial.year())
7266 if (m == not_a_month)
7267 m =
static_cast<int>(
static_cast<unsigned>(ymd_trial.month()));
7268 else if (month(
static_cast<unsigned>(m)) != ymd_trial.month())
7271 d =
static_cast<int>(
static_cast<unsigned>(ymd_trial.day()));
7272 else if (day(
static_cast<unsigned>(d)) != ymd_trial.day())
7276 if (Y != not_a_year && U != not_a_week_num && wd != not_a_weekday)
7278 year_month_day ymd_trial = sys_days(year{Y}/January/Sunday[1]) +
7280 (weekday{
static_cast<unsigned>(wd)} - Sunday);
7281 if (Y == not_a_year)
7282 Y =
static_cast<int>(ymd_trial.year());
7283 else if (year{Y} != ymd_trial.year())
7285 if (m == not_a_month)
7286 m =
static_cast<int>(
static_cast<unsigned>(ymd_trial.month()));
7287 else if (month(
static_cast<unsigned>(m)) != ymd_trial.month())
7290 d =
static_cast<int>(
static_cast<unsigned>(ymd_trial.day()));
7291 else if (day(
static_cast<unsigned>(d)) != ymd_trial.day())
7295 if (Y != not_a_year && W != not_a_week_num && wd != not_a_weekday)
7297 year_month_day ymd_trial = sys_days(year{Y}/January/Monday[1]) +
7299 (weekday{
static_cast<unsigned>(wd)} - Monday);
7300 if (Y == not_a_year)
7301 Y =
static_cast<int>(ymd_trial.year());
7302 else if (year{Y} != ymd_trial.year())
7304 if (m == not_a_month)
7305 m =
static_cast<int>(
static_cast<unsigned>(ymd_trial.month()));
7306 else if (month(
static_cast<unsigned>(m)) != ymd_trial.month())
7309 d =
static_cast<int>(
static_cast<unsigned>(ymd_trial.day()));
7310 else if (day(
static_cast<unsigned>(d)) != ymd_trial.day())
7314 if (j != not_a_doy && Y != not_a_year)
7316 auto ymd_trial = year_month_day{local_days(year{Y}/1/1) + days{j-1}};
7317 if (m == not_a_month)
7318 m =
static_cast<int>(
static_cast<unsigned>(ymd_trial.month()));
7319 else if (month(
static_cast<unsigned>(m)) != ymd_trial.month())
7322 d =
static_cast<int>(
static_cast<unsigned>(ymd_trial.day()));
7323 else if (day(
static_cast<unsigned>(d)) != ymd_trial.day())
7327 auto ymd = year{Y}/m/d;
7330 if (wd == not_a_weekday)
7331 wd =
static_cast<int>((weekday(sys_days(ymd)) - Sunday).count());
7332 else if (wd !=
static_cast<int>((weekday(sys_days(ymd)) - Sunday).count()))
7336 if (G != not_a_year || V != not_a_week_num)
7339 auto G_trial = year_month_day{sd + days{3}}.year();
7340 auto start = sys_days((G_trial - years{1})/December/Thursday[last]) +
7341 (Monday - Thursday);
7345 if (V != not_a_week_num)
7346 start = sys_days((G_trial - years{1})/December/Thursday[last])
7347 + (Monday - Thursday);
7349 if (G != not_a_year && G !=
static_cast<int>(G_trial))
7351 if (V != not_a_week_num)
7353 auto V_trial = duration_cast<weeks>(sd - start).count() + 1;
7358 if (U != not_a_week_num)
7360 auto start = sys_days(Sunday[1]/January/ymd.year());
7361 auto U_trial = floor<weeks>(sys_days(ymd) - start).count() + 1;
7365 if (W != not_a_week_num)
7367 auto start = sys_days(Monday[1]/January/ymd.year());
7368 auto W_trial = floor<weeks>(sys_days(ymd) - start).count() + 1;
7375 if (I != not_a_hour_12_value)
7377 if (!(1 <= I && I <= 12))
7379 if (p != not_a_ampm)
7387 if (H == not_a_hour)
7395 if (H != not_a_hour)
7399 if (H != 0 && H != 12)
7402 else if (!(I == H || I == H+12))
7411 if (H != not_a_hour)
7414 fds.tod = hh_mm_ss<Duration>{hours{H}};
7416 if (M != not_a_minute)
7419 fds.tod.m_ = minutes{M};
7421 if (s != not_a_second)
7424 fds.tod.s_ = detail::decimal_format_seconds<Duration>{s};
7429 fds.tod.h_ += hours{days{j}};
7431 if (wd != not_a_weekday)
7432 fds.wd = weekday{
static_cast<unsigned>(wd)};
7433 if (abbrev !=
nullptr)
7434 *abbrev = std::move(temp_abbrev);
7435 if (offset !=
nullptr && temp_offset != not_a_offset)
7436 *offset = temp_offset;
7441 is.setstate(ios::failbit);
7445 template <
class CharT,
class Traits,
class Alloc = std::allocator<CharT>>
7446 std::basic_istream<CharT, Traits>&
7447 from_stream(std::basic_istream<CharT, Traits>& is,
const CharT* fmt, year& y,
7448 std::basic_string<CharT, Traits, Alloc>* abbrev =
nullptr,
7449 std::chrono::minutes* offset =
nullptr)
7451 using CT = std::chrono::seconds;
7453 gul14::date::from_stream(is, fmt, fds, abbrev, offset);
7454 if (!fds.ymd.year().ok())
7455 is.setstate(std::ios::failbit);
7461 template <
class CharT,
class Traits,
class Alloc = std::allocator<CharT>>
7462 std::basic_istream<CharT, Traits>&
7463 from_stream(std::basic_istream<CharT, Traits>& is,
const CharT* fmt, month& m,
7464 std::basic_string<CharT, Traits, Alloc>* abbrev =
nullptr,
7465 std::chrono::minutes* offset =
nullptr)
7467 using CT = std::chrono::seconds;
7469 gul14::date::from_stream(is, fmt, fds, abbrev, offset);
7470 if (!fds.ymd.month().ok())
7471 is.setstate(std::ios::failbit);
7473 m = fds.ymd.month();
7477 template <
class CharT,
class Traits,
class Alloc = std::allocator<CharT>>
7478 std::basic_istream<CharT, Traits>&
7479 from_stream(std::basic_istream<CharT, Traits>& is,
const CharT* fmt, day& d,
7480 std::basic_string<CharT, Traits, Alloc>* abbrev =
nullptr,
7481 std::chrono::minutes* offset =
nullptr)
7483 using CT = std::chrono::seconds;
7485 gul14::date::from_stream(is, fmt, fds, abbrev, offset);
7486 if (!fds.ymd.day().ok())
7487 is.setstate(std::ios::failbit);
7493 template <
class CharT,
class Traits,
class Alloc = std::allocator<CharT>>
7494 std::basic_istream<CharT, Traits>&
7495 from_stream(std::basic_istream<CharT, Traits>& is,
const CharT* fmt, weekday& wd,
7496 std::basic_string<CharT, Traits, Alloc>* abbrev =
nullptr,
7497 std::chrono::minutes* offset =
nullptr)
7499 using CT = std::chrono::seconds;
7501 gul14::date::from_stream(is, fmt, fds, abbrev, offset);
7503 is.setstate(std::ios::failbit);
7509 template <
class CharT,
class Traits,
class Alloc = std::allocator<CharT>>
7510 std::basic_istream<CharT, Traits>&
7511 from_stream(std::basic_istream<CharT, Traits>& is,
const CharT* fmt, year_month& ym,
7512 std::basic_string<CharT, Traits, Alloc>* abbrev =
nullptr,
7513 std::chrono::minutes* offset =
nullptr)
7515 using CT = std::chrono::seconds;
7517 gul14::date::from_stream(is, fmt, fds, abbrev, offset);
7518 if (!fds.ymd.month().ok())
7519 is.setstate(std::ios::failbit);
7521 ym = fds.ymd.year()/fds.ymd.month();
7525 template <
class CharT,
class Traits,
class Alloc = std::allocator<CharT>>
7526 std::basic_istream<CharT, Traits>&
7527 from_stream(std::basic_istream<CharT, Traits>& is,
const CharT* fmt, month_day& md,
7528 std::basic_string<CharT, Traits, Alloc>* abbrev =
nullptr,
7529 std::chrono::minutes* offset =
nullptr)
7531 using CT = std::chrono::seconds;
7533 gul14::date::from_stream(is, fmt, fds, abbrev, offset);
7534 if (!fds.ymd.month().ok() || !fds.ymd.day().ok())
7535 is.setstate(std::ios::failbit);
7537 md = fds.ymd.month()/fds.ymd.day();
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,
7544 year_month_day& ymd, std::basic_string<CharT, Traits, Alloc>* abbrev =
nullptr,
7545 std::chrono::minutes* offset =
nullptr)
7547 using CT = std::chrono::seconds;
7549 gul14::date::from_stream(is, fmt, fds, abbrev, offset);
7551 is.setstate(std::ios::failbit);
7557 template <
class Duration,
class CharT,
class Traits,
class Alloc = std::allocator<CharT>>
7558 std::basic_istream<CharT, Traits>&
7559 from_stream(std::basic_istream<CharT, Traits>& is,
const CharT* fmt,
7560 sys_time<Duration>& tp, std::basic_string<CharT, Traits, Alloc>* abbrev =
nullptr,
7561 std::chrono::minutes* offset =
nullptr)
7563 using CT =
typename std::common_type<Duration, std::chrono::seconds>::type;
7564 using detail::round_i;
7565 std::chrono::minutes offset_local{};
7566 auto offptr = offset ? offset : &offset_local;
7569 gul14::date::from_stream(is, fmt, fds, abbrev, offptr);
7570 if (!fds.ymd.ok() || !fds.tod.in_conventional_range())
7571 is.setstate(std::ios::failbit);
7573 tp = round_i<Duration>(sys_days(fds.ymd) - *offptr + fds.tod.to_duration());
7577 template <
class Duration,
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,
7580 local_time<Duration>& tp, std::basic_string<CharT, Traits, Alloc>* abbrev =
nullptr,
7581 std::chrono::minutes* offset =
nullptr)
7583 using CT =
typename std::common_type<Duration, std::chrono::seconds>::type;
7584 using detail::round_i;
7587 gul14::date::from_stream(is, fmt, fds, abbrev, offset);
7588 if (!fds.ymd.ok() || !fds.tod.in_conventional_range())
7589 is.setstate(std::ios::failbit);
7591 tp = round_i<Duration>(local_seconds{local_days(fds.ymd)} + fds.tod.to_duration());
7595 template <
class Rep,
class Period,
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 std::chrono::duration<Rep, Period>& d,
7599 std::basic_string<CharT, Traits, Alloc>* abbrev =
nullptr,
7600 std::chrono::minutes* offset =
nullptr)
7602 using Duration = std::chrono::duration<Rep, Period>;
7603 using CT =
typename std::common_type<Duration, std::chrono::seconds>::type;
7604 using detail::round_i;
7606 gul14::date::from_stream(is, fmt, fds, abbrev, offset);
7608 is.setstate(std::ios::failbit);
7610 d = round_i<Duration>(fds.tod.to_duration());
7614 template <
class Parsable,
class CharT,
class Traits = std::
char_traits<CharT>,
7615 class Alloc = std::allocator<CharT>>
7618 const std::basic_string<CharT, Traits, Alloc> format_;
7620 std::basic_string<CharT, Traits, Alloc>* abbrev_;
7621 std::chrono::minutes* offset_;
7624 parse_manip(std::basic_string<CharT, Traits, Alloc> format, Parsable& tp,
7625 std::basic_string<CharT, Traits, Alloc>* abbrev =
nullptr,
7626 std::chrono::minutes* offset =
nullptr)
7627 : format_(std::move(format))
7633 parse_manip(
const CharT* format, Parsable& tp,
7634 std::basic_string<CharT, Traits, Alloc>* abbrev =
nullptr,
7635 std::chrono::minutes* offset =
nullptr)
7643 std::basic_string<CharT, Traits, Alloc>* abbrev =
nullptr,
7644 std::chrono::minutes* offset =
nullptr)
7652 template <
class Parsable,
class CharT,
class Traits,
class Alloc>
7653 std::basic_istream<CharT, Traits>&
7654 operator>>(std::basic_istream<CharT, Traits>& is,
7655 const parse_manip<Parsable, CharT, Traits, Alloc>& x)
7657 return gul14::date::from_stream(is, x.format_.c_str(), x.tp_, x.abbrev_, x.offset_);
7660 template <
class Parsable,
class CharT,
class Traits,
class Alloc>
7662 parse(
const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp)
7663 -> decltype(gul14::date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
7664 format.c_str(), tp),
7665 parse_manip<Parsable, CharT, Traits, Alloc>{format, tp})
7667 return {format, tp};
7670 template <
class Parsable,
class CharT,
class Traits,
class Alloc>
7672 parse(
const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp,
7673 std::basic_string<CharT, Traits, Alloc>& abbrev)
7674 -> decltype(gul14::date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
7675 format.c_str(), tp, &abbrev),
7676 parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, &abbrev})
7678 return {format, tp, &abbrev};
7681 template <
class Parsable,
class CharT,
class Traits,
class Alloc>
7683 parse(
const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp,
7684 std::chrono::minutes& offset)
7685 -> decltype(gul14::date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
7687 std::declval<std::basic_string<CharT, Traits, Alloc>*>(),
7689 parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, nullptr, &offset})
7691 return {format, tp,
nullptr, &offset};
7694 template <
class Parsable,
class CharT,
class Traits,
class Alloc>
7696 parse(
const std::basic_string<CharT, Traits, Alloc>& format, Parsable& tp,
7697 std::basic_string<CharT, Traits, Alloc>& abbrev, std::chrono::minutes& offset)
7698 -> decltype(gul14::date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(),
7699 format.c_str(), tp, &abbrev, &offset),
7700 parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, &abbrev, &offset})
7702 return {format, tp, &abbrev, &offset};
7707 template <
class Parsable,
class CharT>
7709 parse(
const CharT* format, Parsable& tp)
7710 -> decltype(gul14::date::from_stream(std::declval<std::basic_istream<CharT>&>(), format, tp),
7711 parse_manip<Parsable, CharT>{format, tp})
7713 return {format, tp};
7716 template <
class Parsable,
class CharT,
class Traits,
class Alloc>
7718 parse(
const CharT* format, Parsable& tp, std::basic_string<CharT, Traits, Alloc>& abbrev)
7719 -> decltype(gul14::date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format,
7721 parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, &abbrev})
7723 return {format, tp, &abbrev};
7726 template <
class Parsable,
class CharT>
7728 parse(
const CharT* format, Parsable& tp, std::chrono::minutes& offset)
7729 -> decltype(gul14::date::from_stream(std::declval<std::basic_istream<CharT>&>(), format,
7730 tp, std::declval<std::basic_string<CharT>*>(), &offset),
7731 parse_manip<Parsable, CharT>{format, tp,
nullptr, &offset})
7733 return {format, tp,
nullptr, &offset};
7736 template <
class Parsable,
class CharT,
class Traits,
class Alloc>
7738 parse(
const CharT* format, Parsable& tp,
7739 std::basic_string<CharT, Traits, Alloc>& abbrev, std::chrono::minutes& offset)
7740 -> decltype(gul14::date::from_stream(std::declval<std::basic_istream<CharT, Traits>&>(), format,
7741 tp, &abbrev, &offset),
7742 parse_manip<Parsable, CharT, Traits, Alloc>{format, tp, &abbrev, &offset})
7744 return {format, tp, &abbrev, &offset};
7749 template <
class CharT,
class Traits,
class Rep,
class Period>
7751 std::basic_ostream<CharT, Traits>&
7752 operator<<(std::basic_ostream<CharT, Traits>& os,
7753 const std::chrono::duration<Rep, Period>& d)
7755 return os << detail::make_string<CharT, Traits>::from(d.count()) +
7756 detail::get_units<CharT>(
typename Period::type{});
7763 # pragma warning(pop)
7767 # pragma GCC diagnostic pop
A view to a contiguous sequence of chars or char-like objects.
Definition: string_view.h:114
constexpr auto abs(ValueT n) noexcept -> std::enable_if_t< std::is_unsigned< ValueT >::value, ValueT >
Compute the absolute value of a number.
Definition: num_util.h:53
void void_t
A type mapping an arbitrary list of types to void (for SFINAE).
Definition: traits.h:92
Namespace gul14 contains all functions and classes of the General Utility Library.
Definition: doxygen.h:26
Provides a gul14::string_view that is fully compatible with C++17's std::string_view.