Coverage Report

Created: 2026-06-07 06:05

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