@@ -788,6 +788,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
time_since_epoch() const
{ return __d; }
+#if __cplusplus > 201703L
+ constexpr time_point&
+ operator++()
+ {
+ ++__d;
+ return *this;
+ }
+
+ constexpr time_point
+ operator++(int)
+ { return time_point{__d++}; }
+
+ constexpr time_point&
+ operator--()
+ {
+ --__d;
+ return *this;
+ }
+
+ constexpr time_point
+ operator--(int)
+ { return time_point{__d--}; }
+#endif
+
// arithmetic
_GLIBCXX17_CONSTEXPR time_point&
operator+=(const duration& __dur)
@@ -1075,6 +1099,1835 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using local_time = time_point<local_t, _Duration>;
using local_seconds = local_time<seconds>;
using local_days = local_time<days>;
+
+ class utc_clock;
+ class tai_clock;
+ class gps_clock;
+
+ template<typename _Duration>
+ using utc_time = time_point<utc_clock, _Duration>;
+ using utc_seconds = utc_time<seconds>;
+
+ template<typename _Duration>
+ using tai_time = time_point<tai_clock, _Duration>;
+ using tai_seconds = tai_time<seconds>;
+
+ template<typename _Duration>
+ using gps_time = time_point<gps_clock, _Duration>;
+ using gps_seconds = gps_time<seconds>;
+
+ template<> struct is_clock<utc_clock> : true_type { };
+ template<> struct is_clock<tai_clock> : true_type { };
+ template<> struct is_clock<gps_clock> : true_type { };
+
+ template<> inline constexpr bool is_clock_v<utc_clock> = true;
+ template<> inline constexpr bool is_clock_v<tai_clock> = true;
+ template<> inline constexpr bool is_clock_v<gps_clock> = true;
+
+ struct leap_second_info
+ {
+ bool is_leap_second;
+ seconds elapsed;
+ };
+
+ // CALENDRICAL TYPES
+
+ // CLASS DECLARATIONS
+ class day;
+ class month;
+ class year;
+ class weekday;
+ class weekday_indexed;
+ class weekday_last;
+ class month_day;
+ class month_day_last;
+ class month_weekday;
+ class month_weekday_last;
+ class year_month;
+ class year_month_day;
+ class year_month_day_last;
+ class year_month_weekday;
+ class year_month_weekday_last;
+
+ struct last_spec
+ {
+ explicit last_spec() = default;
+
+ friend constexpr month_day_last
+ operator/(int __m, last_spec) noexcept;
+
+ friend constexpr month_day_last
+ operator/(last_spec, int __m) noexcept;
+ };
+
+ inline constexpr last_spec last{};
+
+ namespace __detail
+ {
+ // Compute the remainder of the Euclidean division of __n divided by __d.
+ // Euclidean division truncates toward negative infinity and always
+ // produces a remainder in the range of [0,__d-1] (whereas standard
+ // division truncates toward zero and yields a nonpositive remainder
+ // for negative __n).
+ constexpr unsigned
+ __modulo(long long __n, unsigned __d)
+ {
+ if (__n >= 0)
+ return __n % __d;
+ else
+ return (__d + (__n % __d)) % __d;
+ }
+
+ inline constexpr unsigned __days_per_month[12]
+ = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+ inline constexpr unsigned __last_day[12]
+ = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ }
+
+ // DAY
+
+ class day
+ {
+ private:
+ unsigned char _M_d;
+
+ public:
+ day() = default;
+
+ explicit constexpr
+ day(unsigned __d) noexcept
+ : _M_d(__d)
+ { }
+
+ constexpr day&
+ operator++() noexcept
+ {
+ ++_M_d;
+ return *this;
+ }
+
+ constexpr day
+ operator++(int) noexcept
+ {
+ auto __ret = *this;
+ ++(*this);
+ return __ret;
+ }
+
+ constexpr day&
+ operator--() noexcept
+ {
+ --_M_d;
+ return *this;
+ }
+
+ constexpr day
+ operator--(int) noexcept
+ {
+ auto __ret = *this;
+ --(*this);
+ return __ret;
+ }
+
+ constexpr day&
+ operator+=(const days& __d) noexcept
+ {
+ *this = *this + __d;
+ return *this;
+ }
+
+ constexpr day&
+ operator-=(const days& __d) noexcept
+ {
+ *this = *this - __d;
+ return *this;
+ }
+
+ constexpr explicit
+ operator unsigned() const noexcept
+ { return _M_d; }
+
+ constexpr bool
+ ok() const noexcept
+ { return 1 <= _M_d && _M_d <= 31; }
+
+ friend constexpr bool
+ operator==(const day& __x, const day& __y) noexcept
+ { return unsigned{__x} == unsigned{__y}; }
+
+ friend constexpr strong_ordering
+ operator<=>(const day& __x, const day& __y) noexcept
+ { return unsigned{__x} <=> unsigned{__y}; }
+
+ friend constexpr day
+ operator+(const day& __x, const days& __y) noexcept
+ { return day(unsigned{__x} + __y.count()); }
+
+ friend constexpr day
+ operator+(const days& __x, const day& __y) noexcept
+ { return __y + __x; }
+
+ friend constexpr day
+ operator-(const day& __x, const days& __y) noexcept
+ { return __x + -__y; }
+
+ friend constexpr days
+ operator-(const day& __x, const day& __y) noexcept
+ { return days{int(unsigned{__x}) - int(unsigned{__y})}; }
+
+ friend constexpr month_day
+ operator/(const month& __m, const day& __d) noexcept;
+
+ friend constexpr month_day
+ operator/(int __m, const day& __d) noexcept;
+
+ friend constexpr month_day
+ operator/(const day& __d, const month& __m) noexcept;
+
+ friend constexpr month_day
+ operator/(const day& __d, int __m) noexcept;
+
+ friend constexpr year_month_day
+ operator/(const year_month& __ym, const day& __d) noexcept;
+
+ // TODO: Implement operator<<, to_stream, from_stream.
+ };
+
+ // MONTH
+
+ class month
+ {
+ private:
+ unsigned char _M_m;
+
+ public:
+ month() = default;
+
+ explicit constexpr
+ month(unsigned __m) noexcept
+ : _M_m(__m)
+ { }
+
+ constexpr month&
+ operator++() noexcept
+ {
+ *this += months{1};
+ return *this;
+ }
+
+ constexpr month
+ operator++(int) noexcept
+ {
+ auto __ret = *this;
+ ++(*this);
+ return __ret;
+ }
+
+ constexpr month&
+ operator--() noexcept
+ {
+ *this -= months{1};
+ return *this;
+ }
+
+ constexpr month
+ operator--(int) noexcept
+ {
+ auto __ret = *this;
+ --(*this);
+ return __ret;
+ }
+
+ constexpr month&
+ operator+=(const months& __m) noexcept
+ {
+ *this = *this + __m;
+ return *this;
+ }
+
+ constexpr month&
+ operator-=(const months& __m) noexcept
+ {
+ *this = *this - __m;
+ return *this;
+ }
+
+ explicit constexpr
+ operator unsigned() const noexcept
+ { return _M_m; }
+
+ constexpr bool
+ ok() const noexcept
+ { return 1 <= _M_m && _M_m <= 12; }
+
+ friend constexpr bool
+ operator==(const month& __x, const month& __y) noexcept
+ { return unsigned{__x} == unsigned{__y}; }
+
+ friend constexpr strong_ordering
+ operator<=>(const month& __x, const month& __y) noexcept
+ { return unsigned{__x} <=> unsigned{__y}; }
+
+ friend constexpr month
+ operator+(const month& __x, const months& __y) noexcept
+ {
+ auto __n = static_cast<long long>(unsigned{__x}) + (__y.count() - 1);
+ return month{__detail::__modulo(__n, 12) + 1};
+ }
+
+ friend constexpr month
+ operator+(const months& __x, const month& __y) noexcept
+ { return __y + __x; }
+
+ friend constexpr month
+ operator-(const month& __x, const months& __y) noexcept
+ { return __x + -__y; }
+
+ friend constexpr months
+ operator-(const month& __x, const month& __y) noexcept
+ {
+ const auto __dm = int(unsigned(__x)) - int(unsigned(__y));
+ return months{__dm < 0 ? 12 + __dm : __dm};
+ }
+
+ friend constexpr year_month
+ operator/(const year& __y, const month& __m) noexcept;
+
+ friend constexpr month_day
+ operator/(const month& __m, int __d) noexcept;
+
+ friend constexpr month_day_last
+ operator/(const month& __m, last_spec) noexcept;
+
+ friend constexpr month_day_last
+ operator/(last_spec, const month& __m) noexcept;
+
+ friend constexpr month_weekday
+ operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
+
+ friend constexpr month_weekday
+ operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
+
+ friend constexpr month_weekday_last
+ operator/(const month& __m, const weekday_last& __wdl) noexcept;
+
+ friend constexpr month_weekday_last
+ operator/(const weekday_last& __wdl, const month& __m) noexcept;
+
+ // TODO: Implement operator<<, to_stream, from_stream.
+ };
+
+ inline constexpr month January{1};
+ inline constexpr month February{2};
+ inline constexpr month March{3};
+ inline constexpr month April{4};
+ inline constexpr month May{5};
+ inline constexpr month June{6};
+ inline constexpr month July{7};
+ inline constexpr month August{8};
+ inline constexpr month September{9};
+ inline constexpr month October{10};
+ inline constexpr month November{11};
+ inline constexpr month December{12};
+
+ // YEAR
+
+ class year
+ {
+ private:
+ short _M_y;
+
+ public:
+ year() = default;
+
+ explicit constexpr
+ year(int __y) noexcept
+ : _M_y{static_cast<short>(__y)}
+ { }
+
+ static constexpr year
+ min() noexcept
+ { return year{-32767}; }
+
+ static constexpr year
+ max() noexcept
+ { return year{32767}; }
+
+ constexpr year&
+ operator++() noexcept
+ {
+ ++_M_y;
+ return *this;
+ }
+
+ constexpr year
+ operator++(int) noexcept
+ {
+ auto __ret = *this;
+ ++(*this);
+ return __ret;
+ }
+
+ constexpr year&
+ operator--() noexcept
+ {
+ --_M_y;
+ return *this;
+ }
+
+ constexpr year
+ operator--(int) noexcept
+ {
+ auto __ret = *this;
+ --(*this);
+ return __ret;
+ }
+
+ constexpr year&
+ operator+=(const years& __y) noexcept
+ {
+ *this = *this + __y;
+ return *this;
+ }
+
+ constexpr year&
+ operator-=(const years& __y) noexcept
+ {
+ *this = *this - __y;
+ return *this;
+ }
+
+ constexpr year
+ operator+() const noexcept
+ { return *this; }
+
+ constexpr year
+ operator-() const noexcept
+ { return year{-_M_y}; }
+
+ constexpr bool
+ is_leap() const noexcept
+ { return _M_y % 4 == 0 && (_M_y % 100 != 0 || _M_y % 400 == 0); }
+
+ explicit constexpr
+ operator int() const noexcept
+ { return _M_y; }
+
+ constexpr bool
+ ok() const noexcept
+ { return min()._M_y <= _M_y && _M_y <= max()._M_y; }
+
+ friend constexpr bool
+ operator==(const year& __x, const year& __y) noexcept
+ { return int{__x} == int{__y}; }
+
+ friend constexpr strong_ordering
+ operator<=>(const year& __x, const year& __y) noexcept
+ { return int{__x} <=> int{__y}; }
+
+ friend constexpr year
+ operator+(const year& __x, const years& __y) noexcept
+ { return year{int{__x} + __y.count()}; }
+
+ friend constexpr year
+ operator+(const years& __x, const year& __y) noexcept
+ { return __y + __x; }
+
+ friend constexpr year
+ operator-(const year& __x, const years& __y) noexcept
+ { return __x + -__y; }
+
+ friend constexpr years
+ operator-(const year& __x, const year& __y) noexcept
+ { return years{int{__x} - int{__y}}; }
+
+ friend constexpr year_month
+ operator/(const year& __y, int __m) noexcept;
+
+ friend constexpr year_month_day
+ operator/(const year& __y, const month_day& __md) noexcept;
+
+ friend constexpr year_month_day
+ operator/(const month_day& __md, const year& __y) noexcept;
+
+ friend constexpr year_month_day_last
+ operator/(const year& __y, const month_day_last& __mdl) noexcept;
+
+ friend constexpr year_month_day_last
+ operator/(const month_day_last& __mdl, const year& __y) noexcept;
+
+ friend constexpr year_month_weekday
+ operator/(const year& __y, const month_weekday& __mwd) noexcept;
+
+ friend constexpr year_month_weekday
+ operator/(const month_weekday& __mwd, const year& __y) noexcept;
+
+ friend constexpr year_month_weekday_last
+ operator/(const year& __y, const month_weekday_last& __mwdl) noexcept;
+
+ friend constexpr year_month_weekday_last
+ operator/(const month_weekday_last& __mwdl, const year& __y) noexcept;
+
+ // TODO: Implement operator<<, to_stream, from_stream.
+ };
+
+ // WEEKDAY
+
+ class weekday
+ {
+ private:
+ unsigned char _M_wd;
+
+ static constexpr weekday
+ _S_from_days(const days& __d)
+ {
+ auto __n = __d.count();
+ return weekday(__n >= -4 ? (__n + 4) % 7 : (__n + 5) % 7 + 6);
+ }
+
+ public:
+ weekday() = default;
+
+ explicit constexpr
+ weekday(unsigned __wd) noexcept
+ : _M_wd(__wd == 7 ? 0 : __wd) // __wd % 7 ?
+ { }
+
+ constexpr
+ weekday(const sys_days& __dp) noexcept
+ : weekday{_S_from_days(__dp.time_since_epoch())}
+ { }
+
+ explicit constexpr
+ weekday(const local_days& __dp) noexcept
+ : weekday{sys_days{__dp.time_since_epoch()}}
+ { }
+
+ constexpr weekday&
+ operator++() noexcept
+ {
+ *this += days{1};
+ return *this;
+ }
+
+ constexpr weekday
+ operator++(int) noexcept
+ {
+ auto __ret = *this;
+ ++(*this);
+ return __ret;
+ }
+
+ constexpr weekday&
+ operator--() noexcept
+ {
+ *this -= days{1};
+ return *this;
+ }
+
+ constexpr weekday
+ operator--(int) noexcept
+ {
+ auto __ret = *this;
+ --(*this);
+ return __ret;
+ }
+
+ constexpr weekday&
+ operator+=(const days& __d) noexcept
+ {
+ *this = *this + __d;
+ return *this;
+ }
+
+ constexpr weekday&
+ operator-=(const days& __d) noexcept
+ {
+ *this = *this - __d;
+ return *this;
+ }
+
+ constexpr unsigned
+ c_encoding() const noexcept
+ { return _M_wd; }
+
+ constexpr unsigned
+ iso_encoding() const noexcept
+ { return _M_wd == 0u ? 7u : _M_wd; }
+
+ constexpr bool
+ ok() const noexcept
+ { return _M_wd <= 6; }
+
+ constexpr weekday_indexed
+ operator[](unsigned __index) const noexcept;
+
+ constexpr weekday_last
+ operator[](last_spec) const noexcept;
+
+ friend constexpr bool
+ operator==(const weekday& __x, const weekday& __y) noexcept
+ { return __x._M_wd == __y._M_wd; }
+
+ friend constexpr weekday
+ operator+(const weekday& __x, const days& __y) noexcept
+ {
+ auto __n = static_cast<long long>(__x._M_wd) + __y.count();
+ return weekday{__detail::__modulo(__n, 7)};
+ }
+
+ friend constexpr weekday
+ operator+(const days& __x, const weekday& __y) noexcept
+ { return __y + __x; }
+
+ friend constexpr weekday
+ operator-(const weekday& __x, const days& __y) noexcept
+ { return __x + -__y; }
+
+ friend constexpr days
+ operator-(const weekday& __x, const weekday& __y) noexcept
+ {
+ auto __n = static_cast<long long>(__x._M_wd) - __y._M_wd;
+ return days{__detail::__modulo(__n, 7)};
+ }
+
+ // TODO: operator<<, from_stream.
+ };
+
+ inline constexpr weekday Sunday{0};
+ inline constexpr weekday Monday{1};
+ inline constexpr weekday Tuesday{2};
+ inline constexpr weekday Wednesday{3};
+ inline constexpr weekday Thursday{4};
+ inline constexpr weekday Friday{5};
+ inline constexpr weekday Saturday{6};
+
+ // WEEKDAY_INDEXED
+
+ class weekday_indexed
+ {
+ private:
+ chrono::weekday _M_wd;
+ unsigned char _M_index;
+
+ public:
+ weekday_indexed() = default;
+
+ constexpr
+ weekday_indexed(const chrono::weekday& __wd, unsigned __index) noexcept
+ : _M_wd(__wd), _M_index(__index)
+ { }
+
+ constexpr chrono::weekday
+ weekday() const noexcept
+ { return _M_wd; }
+
+ constexpr unsigned
+ index() const noexcept
+ { return _M_index; };
+
+ constexpr bool
+ ok() const noexcept
+ { return _M_wd.ok() && 1 <= _M_index && _M_index <= 5; }
+
+ friend constexpr bool
+ operator==(const weekday_indexed& __x, const weekday_indexed& __y) noexcept
+ { return __x.weekday() == __y.weekday() && __x.index() == __y.index(); }
+
+ friend constexpr month_weekday
+ operator/(const month& __m, const weekday_indexed& __wdi) noexcept;
+
+ friend constexpr month_weekday
+ operator/(int __m, const weekday_indexed& __wdi) noexcept;
+
+ friend constexpr month_weekday
+ operator/(const weekday_indexed& __wdi, const month& __m) noexcept;
+
+ friend constexpr month_weekday
+ operator/(const weekday_indexed& __wdi, int __m) noexcept;
+
+ friend constexpr year_month_weekday
+ operator/(const year_month& __ym, const weekday_indexed& __wdi) noexcept;
+
+ // TODO: Implement operator<<.
+ };
+
+ constexpr weekday_indexed
+ weekday::operator[](unsigned __index) const noexcept
+ { return {*this, __index}; }
+
+ // WEEKDAY_LAST
+
+ class weekday_last
+ {
+ private:
+ chrono::weekday _M_wd;
+
+ public:
+ explicit constexpr
+ weekday_last(const chrono::weekday& __wd) noexcept
+ : _M_wd{__wd}
+ { }
+
+ constexpr chrono::weekday
+ weekday() const noexcept
+ { return _M_wd; }
+
+ constexpr bool
+ ok() const noexcept
+ { return _M_wd.ok(); }
+
+ friend constexpr bool
+ operator==(const weekday_last& __x, const weekday_last& __y) noexcept
+ { return __x.weekday() == __y.weekday(); }
+
+ friend constexpr month_weekday_last
+ operator/(int __m, const weekday_last& __wdl) noexcept;
+
+ friend constexpr month_weekday_last
+ operator/(const weekday_last& __wdl, int __m) noexcept;
+
+ friend constexpr year_month_weekday_last
+ operator/(const year_month& __ym, const weekday_last& __wdl) noexcept;
+
+ // TODO: Implement operator<<.
+ };
+
+ constexpr weekday_last
+ weekday::operator[](last_spec) const noexcept
+ { return weekday_last{*this}; }
+
+ // MONTH_DAY
+
+ class month_day
+ {
+ private:
+ chrono::month _M_m;
+ chrono::day _M_d;
+
+ public:
+ month_day() = default;
+
+ constexpr
+ month_day(const chrono::month& __m, const chrono::day& __d) noexcept
+ : _M_m{__m}, _M_d{__d}
+ { }
+
+ constexpr chrono::month
+ month() const noexcept
+ { return _M_m; }
+
+ constexpr chrono::day
+ day() const noexcept
+ { return _M_d; }
+
+ constexpr bool
+ ok() const noexcept
+ {
+ return _M_m.ok()
+ && 1u <= unsigned(_M_d)
+ && unsigned(_M_d) <= __detail::__days_per_month[unsigned(_M_m) - 1];
+ }
+
+ friend constexpr bool
+ operator==(const month_day& __x, const month_day& __y) noexcept
+ { return __x.month() == __y.month() && __x.day() == __y.day(); }
+
+ friend constexpr strong_ordering
+ operator<=>(const month_day& __x, const month_day& __y) noexcept
+ = default;
+
+ friend constexpr month_day
+ operator/(const chrono::month& __m, const chrono::day& __d) noexcept
+ { return {__m, __d}; }
+
+ friend constexpr month_day
+ operator/(const chrono::month& __m, int __d) noexcept
+ { return {__m, chrono::day(unsigned(__d))}; }
+
+ friend constexpr month_day
+ operator/(int __m, const chrono::day& __d) noexcept
+ { return {chrono::month(unsigned(__m)), __d}; }
+
+ friend constexpr month_day
+ operator/(const chrono::day& __d, const chrono::month& __m) noexcept
+ { return {__m, __d}; }
+
+ friend constexpr month_day
+ operator/(const chrono::day& __d, int __m) noexcept
+ { return {chrono::month(unsigned(__m)), __d}; }
+
+ friend constexpr year_month_day
+ operator/(int __y, const month_day& __md) noexcept;
+
+ friend constexpr year_month_day
+ operator/(const month_day& __md, int __y) noexcept;
+
+ // TODO: Implement operator<<, from_stream.
+ };
+
+ // MONTH_DAY_LAST
+
+ class month_day_last
+ {
+ private:
+ chrono::month _M_m;
+
+ public:
+ explicit constexpr
+ month_day_last(const chrono::month& __m) noexcept
+ : _M_m{__m}
+ { }
+
+ constexpr chrono::month
+ month() const noexcept
+ { return _M_m; }
+
+ constexpr bool
+ ok() const noexcept
+ { return _M_m.ok(); }
+
+ friend constexpr bool
+ operator==(const month_day_last& __x, const month_day_last& __y) noexcept
+ { return __x.month() == __y.month(); }
+
+ friend constexpr strong_ordering
+ operator<=>(const month_day_last& __x, const month_day_last& __y) noexcept
+ = default;
+
+ friend constexpr month_day_last
+ operator/(const chrono::month& __m, last_spec) noexcept
+ { return month_day_last{__m}; }
+
+ friend constexpr month_day_last
+ operator/(int __m, last_spec) noexcept
+ { return chrono::month(unsigned(__m)) / last; }
+
+ friend constexpr month_day_last
+ operator/(last_spec, const chrono::month& __m) noexcept
+ { return __m / last; }
+
+ friend constexpr month_day_last
+ operator/(last_spec, int __m) noexcept
+ { return __m / last; }
+
+ friend constexpr year_month_day_last
+ operator/(int __y, const month_day_last& __mdl) noexcept;
+
+ friend constexpr year_month_day_last
+ operator/(const month_day_last& __mdl, int __y) noexcept;
+
+ // TODO: Implement operator<<.
+ };
+
+ // MONTH_WEEKDAY
+
+ class month_weekday
+ {
+ private:
+ chrono::month _M_m;
+ chrono::weekday_indexed _M_wdi;
+
+ public:
+ constexpr
+ month_weekday(const chrono::month& __m,
+ const chrono::weekday_indexed& __wdi) noexcept
+ : _M_m{__m}, _M_wdi{__wdi}
+ { }
+
+ constexpr chrono::month
+ month() const noexcept
+ { return _M_m; }
+
+ constexpr chrono::weekday_indexed
+ weekday_indexed() const noexcept
+ { return _M_wdi; }
+
+ constexpr bool
+ ok() const noexcept
+ { return _M_m.ok() && _M_wdi.ok(); }
+
+ friend constexpr bool
+ operator==(const month_weekday& __x, const month_weekday& __y) noexcept
+ {
+ return __x.month() == __y.month()
+ && __x.weekday_indexed() == __y.weekday_indexed();
+ }
+
+ friend constexpr month_weekday
+ operator/(const chrono::month& __m,
+ const chrono::weekday_indexed& __wdi) noexcept
+ { return {__m, __wdi}; }
+
+ friend constexpr month_weekday
+ operator/(int __m, const chrono::weekday_indexed& __wdi) noexcept
+ { return chrono::month(unsigned(__m)) / __wdi; }
+
+ friend constexpr month_weekday
+ operator/(const chrono::weekday_indexed& __wdi,
+ const chrono::month& __m) noexcept
+ { return __m / __wdi; }
+
+ friend constexpr month_weekday
+ operator/(const chrono::weekday_indexed& __wdi, int __m) noexcept
+ { return __m / __wdi; }
+
+ friend constexpr year_month_weekday
+ operator/(int __y, const month_weekday& __mwd) noexcept;
+
+ friend constexpr year_month_weekday
+ operator/(const month_weekday& __mwd, int __y) noexcept;
+
+ // TODO: Implement operator<<.
+ };
+
+ // MONTH_WEEKDAY_LAST
+
+ class month_weekday_last
+ {
+ private:
+ chrono::month _M_m;
+ chrono::weekday_last _M_wdl;
+
+ public:
+ constexpr
+ month_weekday_last(const chrono::month& __m,
+ const chrono::weekday_last& __wdl) noexcept
+ :_M_m{__m}, _M_wdl{__wdl}
+ { }
+
+ constexpr chrono::month
+ month() const noexcept
+ { return _M_m; }
+
+ constexpr chrono::weekday_last
+ weekday_last() const noexcept
+ { return _M_wdl; }
+
+ constexpr bool
+ ok() const noexcept
+ { return _M_m.ok() && _M_wdl.ok(); }
+
+ friend constexpr bool
+ operator==(const month_weekday_last& __x,
+ const month_weekday_last& __y) noexcept
+ {
+ return __x.month() == __y.month()
+ && __x.weekday_last() == __y.weekday_last();
+ }
+
+ friend constexpr month_weekday_last
+ operator/(const chrono::month& __m,
+ const chrono::weekday_last& __wdl) noexcept
+ { return {__m, __wdl}; }
+
+ friend constexpr month_weekday_last
+ operator/(int __m, const chrono::weekday_last& __wdl) noexcept
+ { return chrono::month(unsigned(__m)) / __wdl; }
+
+ friend constexpr month_weekday_last
+ operator/(const chrono::weekday_last& __wdl,
+ const chrono::month& __m) noexcept
+ { return __m / __wdl; }
+
+ friend constexpr month_weekday_last
+ operator/(const chrono::weekday_last& __wdl, int __m) noexcept
+ { return chrono::month(unsigned(__m)) / __wdl; }
+
+ friend constexpr year_month_weekday_last
+ operator/(int __y, const month_weekday_last& __mwdl) noexcept;
+
+ friend constexpr year_month_weekday_last
+ operator/(const month_weekday_last& __mwdl, int __y) noexcept;
+
+ // TODO: Implement operator<<.
+ };
+
+ // YEAR_MONTH
+
+ class year_month
+ {
+ private:
+ chrono::year _M_y;
+ chrono::month _M_m;
+
+ public:
+ year_month() = default;
+
+ constexpr
+ year_month(const chrono::year& __y, const chrono::month& __m) noexcept
+ : _M_y{__y}, _M_m{__m}
+ { }
+
+ constexpr chrono::year
+ year() const noexcept
+ { return _M_y; }
+
+ constexpr chrono::month
+ month() const noexcept
+ { return _M_m; }
+
+ constexpr year_month&
+ operator+=(const months& __dm) noexcept
+ {
+ *this = *this + __dm;
+ return *this;
+ }
+
+ constexpr year_month&
+ operator-=(const months& __dm) noexcept
+ {
+ *this = *this - __dm;
+ return *this;
+ }
+
+ constexpr year_month&
+ operator+=(const years& __dy) noexcept
+ {
+ *this = *this + __dy;
+ return *this;
+ }
+
+ constexpr year_month&
+ operator-=(const years& __dy) noexcept
+ {
+ *this = *this - __dy;
+ return *this;
+ }
+
+ constexpr bool
+ ok() const noexcept
+ { return _M_y.ok() && _M_m.ok(); }
+
+ friend constexpr bool
+ operator==(const year_month& __x, const year_month& __y) noexcept
+ { return __x.year() == __y.year() && __x.month() == __y.month(); }
+
+ friend constexpr strong_ordering
+ operator<=>(const year_month& __x, const year_month& __y) noexcept
+ = default;
+
+ friend constexpr year_month
+ operator+(const year_month& __ym, const months& __dm) noexcept
+ {
+ // TODO: Optimize?
+ auto __m = __ym.month() + __dm;
+ auto __i = unsigned{__ym.month()} - 1 + __dm.count();
+ auto __y = (__i < 0
+ ? __ym.year() + years{(__i - 11) / 12}
+ : __ym.year() + years{__i / 12});
+ return __y / __m;
+ }
+
+ friend constexpr year_month
+ operator+(const months& __dm, const year_month& __ym) noexcept
+ { return __ym + __dm; }
+
+ friend constexpr year_month
+ operator-(const year_month& __ym, const months& __dm) noexcept
+ { return __ym + -__dm; }
+
+ friend constexpr months
+ operator-(const year_month& __x, const year_month& __y) noexcept
+ {
+ return (__x.year() - __y.year()
+ + months{static_cast<int>(unsigned{__x.month()})
+ - static_cast<int>(unsigned{__y.month()})});
+ }
+
+ friend constexpr year_month
+ operator+(const year_month& __ym, const years& __dy) noexcept
+ { return (__ym.year() + __dy) / __ym.month(); }
+
+ friend constexpr year_month
+ operator+(const years& __dy, const year_month& __ym) noexcept
+ { return __ym + __dy; }
+
+ friend constexpr year_month
+ operator-(const year_month& __ym, const years& __dy) noexcept
+ { return __ym + -__dy; }
+
+ friend constexpr year_month
+ operator/(const chrono::year& __y, const chrono::month& __m) noexcept
+ { return {__y, __m}; }
+
+ friend constexpr year_month
+ operator/(const chrono::year& __y, int __m) noexcept
+ { return {__y, chrono::month(unsigned(__m))}; }
+
+ friend constexpr year_month_day
+ operator/(const year_month& __ym, int __d) noexcept;
+
+ friend constexpr year_month_day_last
+ operator/(const year_month& __ym, last_spec) noexcept;
+
+ // TODO: Implement operator<<, from_stream.
+ };
+
+ // YEAR_MONTH_DAY
+
+ class year_month_day
+ {
+ private:
+ chrono::year _M_y;
+ chrono::month _M_m;
+ chrono::day _M_d;
+
+ static constexpr year_month_day _S_from_days(const days& __dp) noexcept;
+
+ constexpr days _M_days_since_epoch() const noexcept;
+
+ public:
+ year_month_day() = default;
+
+ constexpr
+ year_month_day(const chrono::year& __y, const chrono::month& __m,
+ const chrono::day& __d) noexcept
+ : _M_y{__y}, _M_m{__m}, _M_d{__d}
+ { }
+
+ constexpr
+ year_month_day(const year_month_day_last& __ymdl) noexcept;
+
+ constexpr
+ year_month_day(const sys_days& __dp) noexcept
+ : year_month_day(_S_from_days(__dp.time_since_epoch()))
+ { }
+
+ explicit constexpr
+ year_month_day(const local_days& __dp) noexcept
+ : year_month_day(sys_days{__dp.time_since_epoch()})
+ { }
+
+ constexpr year_month_day&
+ operator+=(const months& __m) noexcept
+ {
+ *this = *this + __m;
+ return *this;
+ }
+
+ constexpr year_month_day&
+ operator-=(const months& __m) noexcept
+ {
+ *this = *this - __m;
+ return *this;
+ }
+
+ constexpr year_month_day&
+ operator+=(const years& __y) noexcept
+ {
+ *this = *this + __y;
+ return *this;
+ }
+
+ constexpr year_month_day&
+ operator-=(const years& __y) noexcept
+ {
+ *this = *this - __y;
+ return *this;
+ }
+
+ constexpr chrono::year
+ year() const noexcept
+ { return _M_y; }
+
+ constexpr chrono::month
+ month() const noexcept
+ { return _M_m; }
+
+ constexpr chrono::day
+ day() const noexcept
+ { return _M_d; }
+
+ constexpr
+ operator sys_days() const noexcept
+ { return sys_days{_M_days_since_epoch()}; }
+
+ explicit constexpr
+ operator local_days() const noexcept
+ { return local_days{sys_days{*this}.time_since_epoch()}; }
+
+ constexpr bool ok() const noexcept;
+
+ friend constexpr bool
+ operator==(const year_month_day& __x, const year_month_day& __y) noexcept
+ {
+ return __x.year() == __y.year()
+ && __x.month() == __y.month()
+ && __x.day() == __y.day();
+ }
+
+ friend constexpr strong_ordering
+ operator<=>(const year_month_day& __x, const year_month_day& __y) noexcept
+ = default;
+
+ friend constexpr year_month_day
+ operator+(const year_month_day& __ymd, const months& __dm) noexcept
+ { return (__ymd.year() / __ymd.month() + __dm) / __ymd.day(); }
+
+ friend constexpr year_month_day
+ operator+(const months& __dm, const year_month_day& __ymd) noexcept
+ { return __ymd + __dm; }
+
+ friend constexpr year_month_day
+ operator+(const year_month_day& __ymd, const years& __dy) noexcept
+ { return (__ymd.year() + __dy) / __ymd.month() / __ymd.day(); }
+
+ friend constexpr year_month_day
+ operator+(const years& __dy, const year_month_day& __ymd) noexcept
+ { return __ymd + __dy; }
+
+ friend constexpr year_month_day
+ operator-(const year_month_day& __ymd, const months& __dm) noexcept
+ { return __ymd + -__dm; }
+
+ friend constexpr year_month_day
+ operator-(const year_month_day& __ymd, const years& __dy) noexcept
+ { return __ymd + -__dy; }
+
+ friend constexpr year_month_day
+ operator/(const year_month& __ym, const chrono::day& __d) noexcept
+ { return {__ym.year(), __ym.month(), __d}; }
+
+ friend constexpr year_month_day
+ operator/(const year_month& __ym, int __d) noexcept
+ { return __ym / chrono::day{unsigned(__d)}; }
+
+ friend constexpr year_month_day
+ operator/(const chrono::year& __y, const month_day& __md) noexcept
+ { return __y / __md.month() / __md.day(); }
+
+ friend constexpr year_month_day
+ operator/(int __y, const month_day& __md) noexcept
+ { return chrono::year{__y} / __md; }
+
+ friend constexpr year_month_day
+ operator/(const month_day& __md, const chrono::year& __y) noexcept
+ { return __y / __md; }
+
+ friend constexpr year_month_day
+ operator/(const month_day& __md, int __y) noexcept
+ { return chrono::year(__y) / __md; }
+
+ // TODO: Implement operator<<, from_stream.
+ };
+
+ // Construct from days since 1970/01/01. Magic.
+ constexpr year_month_day
+ year_month_day::_S_from_days(const days& __dp) noexcept
+ {
+ const auto __z = __dp.count() + 719468;
+ const auto __era = (__z >= 0 ? __z : __z - 146096) / 146097;
+ const auto __doe = static_cast<unsigned>(__z - __era * 146097);
+ const auto __yoe
+ = (__doe - __doe / 1460 + __doe / 36524 - __doe / 146096) / 365;
+ const auto __y = static_cast<days::rep>(__yoe) + __era * 400;
+ const auto __doy = __doe - (365 * __yoe + __yoe / 4 - __yoe / 100);
+ const auto __mp = (5 * __doy + 2) / 153;
+ const auto __d = __doy - (153 * __mp + 2) / 5 + 1;
+ const auto __m = __mp < 10 ? __mp + 3 : __mp - 9;
+ return year_month_day{chrono::year(__y + (__m <= 2)),
+ chrono::month(__m), chrono::day(__d)};
+ }
+
+ // Days since 1970/01/01. Magic.
+ constexpr days
+ year_month_day::_M_days_since_epoch() const noexcept
+ {
+ const auto __y = static_cast<int>(_M_y) - (_M_m <= February);
+ const auto __m = static_cast<unsigned>(_M_m);
+ const auto __d = static_cast<unsigned>(_M_d);
+ const auto __era = (__y >= 0 ? __y : __y - 399) / 400;
+ // Year of "era" [0, 399].
+ const auto __yoe = static_cast<unsigned>(__y - __era * 400);
+ // Day of year [0, 365].
+ const auto __doy = (153 * (__m > 2 ? __m - 3 : __m + 9) + 2) / 5 + __d - 1;
+ // Day of "era" [0, 146096].
+ const auto __doe = __yoe * 365 + __yoe / 4 - __yoe / 100 + __doy;
+ const auto __days = __era * 146097 + static_cast<int>(__doe) - 719468;
+ return days{__days};
+ }
+
+ // YEAR_MONTH_DAY_LAST
+
+ class year_month_day_last
+ {
+ private:
+ chrono::year _M_y;
+ chrono::month_day_last _M_mdl;
+
+ public:
+ constexpr
+ year_month_day_last(const chrono::year& __y,
+ const chrono::month_day_last& __mdl) noexcept
+ : _M_y{__y}, _M_mdl{__mdl}
+ { }
+
+ constexpr year_month_day_last&
+ operator+=(const months& __m) noexcept
+ {
+ *this = *this + __m;
+ return *this;
+ }
+
+ constexpr year_month_day_last&
+ operator-=(const months& __m) noexcept
+ {
+ *this = *this - __m;
+ return *this;
+ }
+
+ constexpr year_month_day_last&
+ operator+=(const years& __y) noexcept
+ {
+ *this = *this + __y;
+ return *this;
+ }
+
+ constexpr year_month_day_last&
+ operator-=(const years& __y) noexcept
+ {
+ *this = *this - __y;
+ return *this;
+ }
+
+ constexpr chrono::year
+ year() const noexcept
+ { return _M_y; }
+
+ constexpr chrono::month
+ month() const noexcept
+ { return _M_mdl.month(); }
+
+ constexpr chrono::month_day_last
+ month_day_last() const noexcept
+ { return _M_mdl; }
+
+ // Return A day representing the last day of this year, month pair.
+ constexpr chrono::day
+ day() const noexcept
+ {
+ if (!_M_mdl.ok() || (month() == February && _M_y.is_leap()))
+ return chrono::day{29};
+ return chrono::day{__detail::__last_day[unsigned(month()) - 1]};
+ }
+
+ constexpr
+ operator sys_days() const noexcept
+ { return sys_days{year() / month() / day()}; }
+
+ explicit constexpr
+ operator local_days() const noexcept
+ { return local_days{sys_days{*this}.time_since_epoch()}; }
+
+ constexpr bool
+ ok() const noexcept
+ { return _M_y.ok() && _M_mdl.ok(); }
+
+ friend constexpr bool
+ operator==(const year_month_day_last& __x,
+ const year_month_day_last& __y) noexcept
+ {
+ return __x.year() == __y.year()
+ && __x.month_day_last() == __y.month_day_last();
+ }
+
+ friend constexpr strong_ordering
+ operator<=>(const year_month_day_last& __x,
+ const year_month_day_last& __y) noexcept
+ = default;
+
+ friend constexpr year_month_day_last
+ operator+(const year_month_day_last& __ymdl,
+ const months& __dm) noexcept
+ { return (__ymdl.year() / __ymdl.month() + __dm) / last; }
+
+ friend constexpr year_month_day_last
+ operator+(const months& __dm,
+ const year_month_day_last& __ymdl) noexcept
+ { return __ymdl + __dm; }
+
+ friend constexpr year_month_day_last
+ operator-(const year_month_day_last& __ymdl,
+ const months& __dm) noexcept
+ { return __ymdl + -__dm; }
+
+ friend constexpr year_month_day_last
+ operator+(const year_month_day_last& __ymdl,
+ const years& __dy) noexcept
+ { return {__ymdl.year() + __dy, __ymdl.month_day_last()}; }
+
+ friend constexpr year_month_day_last
+ operator+(const years& __dy,
+ const year_month_day_last& __ymdl) noexcept
+ { return __ymdl + __dy; }
+
+ friend constexpr year_month_day_last
+ operator-(const year_month_day_last& __ymdl,
+ const years& __dy) noexcept
+ { return __ymdl + -__dy; }
+
+ friend constexpr year_month_day_last
+ operator/(const year_month& __ym, last_spec) noexcept
+ { return {__ym.year(), chrono::month_day_last{__ym.month()}}; }
+
+ friend constexpr year_month_day_last
+ operator/(const chrono::year& __y,
+ const chrono::month_day_last& __mdl) noexcept
+ { return {__y, __mdl}; }
+
+ friend constexpr year_month_day_last
+ operator/(int __y, const chrono::month_day_last& __mdl) noexcept
+ { return chrono::year(__y) / __mdl; }
+
+ friend constexpr year_month_day_last
+ operator/(const chrono::month_day_last& __mdl,
+ const chrono::year& __y) noexcept
+ { return __y / __mdl; }
+
+ friend constexpr year_month_day_last
+ operator/(const chrono::month_day_last& __mdl, int __y) noexcept
+ { return chrono::year(__y) / __mdl; }
+
+ // TODO: Implement operator<<.
+ };
+
+ // year_month_day ctor from year_month_day_last
+ constexpr
+ year_month_day::year_month_day(const year_month_day_last& __ymdl) noexcept
+ : _M_y{__ymdl.year()}, _M_m{__ymdl.month()}, _M_d{__ymdl.day()}
+ { }
+
+ constexpr bool
+ year_month_day::ok() const noexcept
+ {
+ if (!_M_y.ok() || !_M_m.ok())
+ return false;
+ return chrono::day{1} <= _M_d && _M_d <= (_M_y / _M_m / last).day();
+ }
+
+ // YEAR_MONTH_WEEKDAY
+
+ class year_month_weekday
+ {
+ private:
+ chrono::year _M_y;
+ chrono::month _M_m;
+ chrono::weekday_indexed _M_wdi;
+
+ static constexpr year_month_weekday
+ _S_from_sys_days(const sys_days& __dp)
+ {
+ year_month_day __ymd{__dp};
+ chrono::weekday __wd{__dp};
+ auto __index = __wd[(unsigned{__ymd.day()} - 1) / 7 + 1];
+ return {__ymd.year(), __ymd.month(), __index};
+ }
+
+ public:
+ year_month_weekday() = default;
+
+ constexpr
+ year_month_weekday(const chrono::year& __y, const chrono::month& __m,
+ const chrono::weekday_indexed& __wdi) noexcept
+ : _M_y{__y}, _M_m{__m}, _M_wdi{__wdi}
+ { }
+
+ constexpr
+ year_month_weekday(const sys_days& __dp) noexcept
+ : year_month_weekday{_S_from_sys_days(__dp)}
+ { }
+
+ explicit constexpr
+ year_month_weekday(const local_days& __dp) noexcept
+ : year_month_weekday{sys_days{__dp.time_since_epoch()}}
+ { }
+
+ constexpr year_month_weekday&
+ operator+=(const months& __m) noexcept
+ {
+ *this = *this + __m;
+ return *this;
+ }
+
+ constexpr year_month_weekday&
+ operator-=(const months& __m) noexcept
+ {
+ *this = *this - __m;
+ return *this;
+ }
+
+ constexpr year_month_weekday&
+ operator+=(const years& __y) noexcept
+ {
+ *this = *this + __y;
+ return *this;
+ }
+
+ constexpr year_month_weekday&
+ operator-=(const years& __y) noexcept
+ {
+ *this = *this - __y;
+ return *this;
+ }
+
+ constexpr chrono::year
+ year() const noexcept
+ { return _M_y; }
+
+ constexpr chrono::month
+ month() const noexcept
+ { return _M_m; }
+
+ constexpr chrono::weekday
+ weekday() const noexcept
+ { return _M_wdi.weekday(); }
+
+ constexpr unsigned
+ index() const noexcept
+ { return _M_wdi.index(); }
+
+ constexpr chrono::weekday_indexed
+ weekday_indexed() const noexcept
+ { return _M_wdi; }
+
+ constexpr
+ operator sys_days() const noexcept
+ {
+ auto __d = sys_days{year() / month() / 1};
+ return __d + (weekday() - chrono::weekday(__d) + days{(index()-1)*7});
+ }
+
+ explicit constexpr
+ operator local_days() const noexcept
+ { return local_days{sys_days{*this}.time_since_epoch()}; }
+
+ constexpr bool
+ ok() const noexcept
+ {
+ if (!_M_y.ok() || !_M_m.ok() || !_M_wdi.ok())
+ return false;
+ if (_M_wdi.index() <= 4)
+ return true;
+ days __d = (_M_wdi.weekday()
+ - chrono::weekday{sys_days{_M_y / _M_m / 1}}
+ + days((_M_wdi.index()-1)*7 + 1));
+ __glibcxx_assert(__d >= 1);
+ return __d.count() <= unsigned{(_M_y / _M_m / last).day()};
+ }
+
+ friend constexpr bool
+ operator==(const year_month_weekday& __x,
+ const year_month_weekday& __y) noexcept
+ {
+ return __x.year() == __y.year()
+ && __x.month() == __y.month()
+ && __x.weekday() == __y.weekday();
+ }
+
+ friend constexpr year_month_weekday
+ operator+(const year_month_weekday& __ymwd, const months& __dm) noexcept
+ { return (__ymwd.year() / __ymwd.month() + __dm) / __ymwd.weekday_indexed(); }
+
+ friend constexpr year_month_weekday
+ operator+(const months& __dm, const year_month_weekday& __ymwd) noexcept
+ { return __ymwd + __dm; }
+
+ friend constexpr year_month_weekday
+ operator+(const year_month_weekday& __ymwd, const years& __dy) noexcept
+ { return {__ymwd.year() + __dy, __ymwd.month(), __ymwd.weekday_indexed()}; }
+
+ friend constexpr year_month_weekday
+ operator+(const years& __dy, const year_month_weekday& __ymwd) noexcept
+ { return __ymwd + __dy; }
+
+ friend constexpr year_month_weekday
+ operator-(const year_month_weekday& __ymwd, const months& __dm) noexcept
+ { return __ymwd + -__dm; }
+
+ friend constexpr year_month_weekday
+ operator-(const year_month_weekday& __ymwd, const years& __dy) noexcept
+ { return __ymwd + -__dy; }
+
+ friend constexpr year_month_weekday
+ operator/(const year_month& __ym,
+ const chrono::weekday_indexed& __wdi) noexcept
+ { return {__ym.year(), __ym.month(), __wdi}; }
+
+ friend constexpr year_month_weekday
+ operator/(const chrono::year& __y, const month_weekday& __mwd) noexcept
+ { return {__y, __mwd.month(), __mwd.weekday_indexed()}; }
+
+ friend constexpr year_month_weekday
+ operator/(int __y, const month_weekday& __mwd) noexcept
+ { return chrono::year(__y) / __mwd; }
+
+ friend constexpr year_month_weekday
+ operator/(const month_weekday& __mwd, const chrono::year& __y) noexcept
+ { return __y / __mwd; }
+
+ friend constexpr year_month_weekday
+ operator/(const month_weekday& __mwd, int __y) noexcept
+ { return chrono::year(__y) / __mwd; }
+
+ // TODO: Implement operator<<.
+ };
+
+ // YEAR_MONTH_WEEKDAY_LAST
+
+ class year_month_weekday_last
+ {
+ private:
+ chrono::year _M_y;
+ chrono::month _M_m;
+ chrono::weekday_last _M_wdl;
+
+ public:
+ constexpr
+ year_month_weekday_last(const chrono::year& __y, const chrono::month& __m,
+ const chrono::weekday_last& __wdl) noexcept
+ : _M_y{__y}, _M_m{__m}, _M_wdl{__wdl}
+ { }
+
+ constexpr year_month_weekday_last&
+ operator+=(const months& __m) noexcept
+ {
+ *this = *this + __m;
+ return *this;
+ }
+
+ constexpr year_month_weekday_last&
+ operator-=(const months& __m) noexcept
+ {
+ *this = *this - __m;
+ return *this;
+ }
+
+ constexpr year_month_weekday_last&
+ operator+=(const years& __y) noexcept
+ {
+ *this = *this + __y;
+ return *this;
+ }
+
+ constexpr year_month_weekday_last&
+ operator-=(const years& __y) noexcept
+ {
+ *this = *this - __y;
+ return *this;
+ }
+
+ constexpr chrono::year
+ year() const noexcept
+ { return _M_y; }
+
+ constexpr chrono::month
+ month() const noexcept
+ { return _M_m; }
+
+ constexpr chrono::weekday
+ weekday() const noexcept
+ { return _M_wdl.weekday(); }
+
+ constexpr chrono::weekday_last
+ weekday_last() const noexcept
+ { return _M_wdl; }
+
+ constexpr
+ operator sys_days() const noexcept
+ {
+ const auto __d = sys_days{_M_y / _M_m / last};
+ return sys_days{(__d - (chrono::weekday{__d}
+ - _M_wdl.weekday())).time_since_epoch()};
+ }
+
+ explicit constexpr
+ operator local_days() const noexcept
+ { return local_days{sys_days{*this}.time_since_epoch()}; }
+
+ constexpr bool
+ ok() const noexcept
+ { return _M_y.ok() && _M_m.ok() && _M_wdl.ok(); }
+
+ friend constexpr bool
+ operator==(const year_month_weekday_last& __x,
+ const year_month_weekday_last& __y) noexcept
+ {
+ return __x.year() == __y.year()
+ && __x.month() == __y.month()
+ && __x.weekday_last() == __y.weekday_last();
+ }
+
+ friend constexpr year_month_weekday_last
+ operator+(const year_month_weekday_last& __ymwdl,
+ const months& __dm) noexcept
+ { return (__ymwdl.year() / __ymwdl.month() + __dm) / __ymwdl.weekday_last(); }
+
+ friend constexpr year_month_weekday_last
+ operator+(const months& __dm,
+ const year_month_weekday_last& __ymwdl) noexcept
+ { return __ymwdl + __dm; }
+
+ friend constexpr year_month_weekday_last
+ operator+(const year_month_weekday_last& __ymwdl,
+ const years& __dy) noexcept
+ { return {__ymwdl.year() + __dy, __ymwdl.month(), __ymwdl.weekday_last()}; }
+
+ friend constexpr year_month_weekday_last
+ operator+(const years& __dy,
+ const year_month_weekday_last& __ymwdl) noexcept
+ { return __ymwdl + __dy; }
+
+ friend constexpr year_month_weekday_last
+ operator-(const year_month_weekday_last& __ymwdl,
+ const months& __dm) noexcept
+ { return __ymwdl + -__dm; }
+
+ friend constexpr year_month_weekday_last
+ operator-(const year_month_weekday_last& __ymwdl,
+ const years& __dy) noexcept
+ { return __ymwdl + -__dy; }
+
+ friend constexpr year_month_weekday_last
+ operator/(const year_month& __ym,
+ const chrono::weekday_last& __wdl) noexcept
+ { return {__ym.year(), __ym.month(), __wdl}; }
+
+ friend constexpr year_month_weekday_last
+ operator/(const chrono::year& __y,
+ const chrono::month_weekday_last& __mwdl) noexcept
+ { return {__y, __mwdl.month(), __mwdl.weekday_last()}; }
+
+ friend constexpr year_month_weekday_last
+ operator/(int __y, const chrono::month_weekday_last& __mwdl) noexcept
+ { return chrono::year(__y) / __mwdl; }
+
+ friend constexpr year_month_weekday_last
+ operator/(const chrono::month_weekday_last& __mwdl,
+ const chrono::year& __y) noexcept
+ { return __y / __mwdl; }
+
+ friend constexpr year_month_weekday_last
+ operator/(const chrono::month_weekday_last& __mwdl, int __y) noexcept
+ { return chrono::year(__y) / __mwdl; }
+
+ // TODO: Implement operator<<.
+ };
+
+ // HH_MM_SS
+
+ namespace __detail
+ {
+ consteval long long
+ __pow10(unsigned __n)
+ {
+ long long __r = 1;
+ while (__n-- > 0)
+ __r *= 10;
+ return __r;
+ }
+ }
+
+ template<typename _Duration>
+ class hh_mm_ss
+ {
+ private:
+ static constexpr int
+ _S_fractional_width()
+ {
+ int __multiplicity_2 = 0;
+ int __multiplicity_5 = 0;
+ auto __den = _Duration::period::den;
+ while ((__den % 2) == 0)
+ {
+ ++__multiplicity_2;
+ __den /= 2;
+ }
+ while ((__den % 5) == 0)
+ {
+ ++__multiplicity_5;
+ __den /= 5;
+ }
+ if (__den != 1)
+ return 6;
+
+ int __width = (__multiplicity_2 > __multiplicity_5
+ ? __multiplicity_2 : __multiplicity_5);
+ if (__width > 18)
+ __width = 18;
+ return __width;
+ }
+
+ public:
+ static constexpr unsigned fractional_width = {_S_fractional_width()};
+
+ using precision
+ = duration<common_type_t<typename _Duration::rep,
+ chrono::seconds::rep>,
+ ratio<1, __detail::__pow10(fractional_width)>>;
+
+ constexpr
+ hh_mm_ss() noexcept
+ : hh_mm_ss{_Duration::zero()}
+ { }
+
+ constexpr explicit
+ hh_mm_ss(_Duration __d) noexcept
+ : _M_is_neg (__d < _Duration::zero()),
+ _M_h (duration_cast<chrono::hours>(abs(__d))),
+ _M_m (duration_cast<chrono::minutes>(abs(__d) - hours())),
+ _M_s (duration_cast<chrono::seconds>(abs(__d) - hours() - minutes()))
+ {
+ if constexpr (treat_as_floating_point_v<typename precision::rep>)
+ _M_ss = abs(__d) - hours() - minutes() - seconds();
+ else
+ _M_ss = duration_cast<precision>(abs(__d) - hours()
+ - minutes() - seconds());
+ }
+
+ constexpr bool
+ is_negative() const noexcept
+ { return _M_is_neg; }
+
+ constexpr chrono::hours
+ hours() const noexcept
+ { return _M_h; }
+
+ constexpr chrono::minutes
+ minutes() const noexcept
+ { return _M_m; }
+
+ constexpr chrono::seconds
+ seconds() const noexcept
+ { return _M_s; }
+
+ constexpr precision
+ subseconds() const noexcept
+ { return _M_ss; }
+
+ constexpr explicit
+ operator precision() const noexcept
+ { return to_duration(); }
+
+ constexpr precision
+ to_duration() const noexcept
+ {
+ if (_M_is_neg)
+ return -(_M_h + _M_m + _M_s + _M_ss);
+ else
+ return _M_h + _M_m + _M_s + _M_ss;
+ }
+
+ // TODO: Implement operator<<.
+
+ private:
+ bool _M_is_neg;
+ chrono::hours _M_h;
+ chrono::minutes _M_m;
+ chrono::seconds _M_s;
+ precision _M_ss;
+ };
#endif // C++20
// @}
@@ -1191,6 +3044,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator""ns()
{ return __check_overflow<chrono::nanoseconds, _Digits...>(); }
+#if __cplusplus > 201703L
+ constexpr chrono::day
+ operator""d(unsigned long long __d) noexcept
+ { return chrono::day{static_cast<unsigned>(__d)}; }
+
+ constexpr chrono::year
+ operator""y(unsigned long long __y) noexcept
+ { return chrono::year{static_cast<int>(__y)}; }
+#endif // C++20
+
#pragma GCC diagnostic pop
} // inline namespace chrono_literals
} // inline namespace literals
@@ -1200,6 +3063,50 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using namespace literals::chrono_literals;
} // namespace chrono
+#if __cplusplus > 201703L
+ namespace chrono
+ {
+ // 12/24 HOURS FUNCTIONS
+
+ constexpr bool
+ is_am(const hours& __h) noexcept
+ { return 0h <= __h && __h <= 11h; }
+
+ constexpr bool
+ is_pm(const hours& __h) noexcept
+ { return 12h <= __h && __h <= 23h; }
+
+ constexpr hours
+ make12(const hours& __h) noexcept
+ {
+ if (__h == 0h)
+ return 12h;
+ else if (__h > 12h)
+ return __h - 12h;
+ return __h;
+ }
+
+ constexpr hours
+ make24(const hours& __h, bool __is_pm) noexcept
+ {
+ if (!__is_pm)
+ {
+ if (__h == 12h)
+ return 0h;
+ else
+ return __h;
+ }
+ else
+ {
+ if (__h == 12h)
+ return __h;
+ else
+ return __h + 12h;
+ }
+ }
+ }
+#endif
+
#if __cplusplus >= 201703L
namespace filesystem
{
new file mode 100644
@@ -0,0 +1,42 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2008-2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 20.8.4 Class template time_point [time.point]
+
+#include <chrono>
+
+constexpr bool
+test_time_point_increment_ops()
+{
+ using namespace std::chrono;
+ bool ok = true;
+ time_point<local_t, seconds> tp(seconds(1));
+
+ ok &= tp.time_since_epoch() == 1s;
+ ok &= (tp++).time_since_epoch() == 1s;
+ ok &= tp.time_since_epoch() == 2s;
+ ok &= (++tp).time_since_epoch() == 3s;
+ ok &= (tp--).time_since_epoch() == 3s;
+ ok &= tp.time_since_epoch() == 2s;
+ ok &= (--tp).time_since_epoch() == 1s;
+ ok &= tp.time_since_epoch() == 1s;
+ return ok;
+}
+static_assert(test_time_point_increment_ops());
new file mode 100644
@@ -0,0 +1,67 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Class template day [time.cal.day]
+
+#include <chrono>
+
+constexpr void
+constexpr_day()
+{
+ using namespace std::chrono;
+
+ day dd{};
+ ++(++dd);
+ dd++;
+ --(--dd);
+ dd--;
+ dd += days{3};
+ dd -= days{3};
+
+ static_assert(day{1} + days{2} == day{3});
+ static_assert(days{2} + day{1} == day{3});
+ static_assert(day{3} - day{1} == days{2});
+ static_assert(day{3} - days{1} == day{2});
+
+ static_assert(++day{4} == day{5});
+ static_assert(day{4}++ == day{4});
+ static_assert(--day{4} == day{3});
+ static_assert(day{4}-- == day{4});
+ static_assert((day{4} += days{3}) == day{7});
+ static_assert((day{4} -= days{3}) == day{1});
+
+ static_assert(!day{}.ok());
+ static_assert(day{1}.ok());
+ static_assert(day{31}.ok());
+ static_assert(!day{32}.ok());
+
+ static_assert(unsigned{day{7}} == 7);
+
+ static_assert(!(day{0} == day{1}));
+ static_assert( (day{0} != day{2}));
+ static_assert( (day{0} < day{3}));
+ static_assert(!(day{0} > day{4}));
+ static_assert( (day{0} <= day{5}));
+ static_assert(!(day{0} >= day{6}));
+
+ static_assert(day{0} <=> day{1} == std::strong_ordering::less);
+ static_assert(day{3} <=> day{3} == std::strong_ordering::equal);
+ static_assert(day{5} <=> day{2} == std::strong_ordering::greater);
+}
new file mode 100644
@@ -0,0 +1,63 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Class template hh_mm_ss [time.hh_mm_ss]
+
+#include <chrono>
+
+constexpr void
+constexpr_hh_mm_ss()
+{
+ using namespace std::chrono;
+ using std::ratio;
+
+ static_assert(hh_mm_ss<hours>::fractional_width == 0);
+ static_assert(hh_mm_ss<minutes>::fractional_width == 0);
+ static_assert(hh_mm_ss<seconds>::fractional_width == 0);
+ static_assert(hh_mm_ss<milliseconds>::fractional_width == 3);
+ static_assert(hh_mm_ss<microseconds>::fractional_width == 6);
+ static_assert(hh_mm_ss<nanoseconds>::fractional_width == 9);
+ static_assert(hh_mm_ss<duration<int, ratio<1, 2>>>::fractional_width == 1);
+ static_assert(hh_mm_ss<duration<int, ratio<1, 3>>>::fractional_width == 6);
+ static_assert(hh_mm_ss<duration<int, ratio<1, 4>>>::fractional_width == 2);
+ static_assert(hh_mm_ss<duration<int, ratio<2, 4>>>::fractional_width == 1);
+ static_assert(hh_mm_ss<duration<int, ratio<1, 5>>>::fractional_width == 1);
+ static_assert(hh_mm_ss<duration<int, ratio<1, 6>>>::fractional_width == 6);
+ static_assert(hh_mm_ss<duration<int, ratio<1, 7>>>::fractional_width == 6);
+ static_assert(hh_mm_ss<duration<int, ratio<1, 8>>>::fractional_width == 3);
+ static_assert(hh_mm_ss<duration<int, ratio<1, 9>>>::fractional_width == 6);
+ static_assert(hh_mm_ss<duration<int, ratio<1, 10>>>::fractional_width == 1);
+ static_assert(hh_mm_ss<duration<int, ratio<756, 625>>>::fractional_width == 4);
+ static_assert(hh_mm_ss<duration<int, ratio<1, (1ll << 62)>>>::fractional_width
+ == 18);
+
+ constexpr auto hms = hh_mm_ss{-(8h + 9min + 10s + 11ms + 12us + 13ns)};
+ static_assert(__is_same(decltype(hms)::precision, nanoseconds));
+ static_assert(hms.hours() == 8h);
+ static_assert(hms.minutes() == 9min);
+ static_assert(hms.seconds() == 10s);
+ static_assert(hms.subseconds() == 11ms + 12us + 13ns);
+ static_assert(hms.is_negative());
+ static_assert(hh_mm_ss{hms.to_duration()}.to_duration() == hms.to_duration());
+
+ static_assert(seconds{hh_mm_ss{100min}} == 100min);
+
+ // TODO: treat_as_floating_point_v
+}
new file mode 100644
@@ -0,0 +1,35 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Function is_am [time.12]
+
+#include <chrono>
+
+constexpr void
+constexpr_is_am()
+{
+ using namespace std::chrono;
+ static_assert(is_am(0h));
+ static_assert(is_am(5h));
+ static_assert(is_am(11h));
+ static_assert(!is_am(12h));
+ static_assert(!is_am(15h));
+ static_assert(!is_am(23h));
+}
new file mode 100644
@@ -0,0 +1,35 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Function is_pm [time.12]
+
+#include <chrono>
+
+constexpr void
+constexpr_is_pm()
+{
+ using namespace std::chrono;
+ static_assert(!is_pm(0h));
+ static_assert(!is_pm(5h));
+ static_assert(!is_pm(11h));
+ static_assert(is_pm(12h));
+ static_assert(is_pm(15h));
+ static_assert(is_pm(23h));
+}
new file mode 100644
@@ -0,0 +1,36 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Function is_pm [time.12]
+
+#include <chrono>
+
+constexpr void
+constexpr_make12()
+{
+ using namespace std::chrono;
+ static_assert(make12(0h) == 12h);
+ static_assert(make12(1h) == 1h);
+ static_assert(make12(5h) == 5h);
+ static_assert(make12(12h) == 12h);
+ static_assert(make12(13h) == 1h);
+ static_assert(make12(19h) == 7h);
+ static_assert(make12(23h) == 11h);
+}
new file mode 100644
@@ -0,0 +1,41 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Function is_pm [time.12]
+
+#include <chrono>
+
+constexpr void
+constexpr_make24()
+{
+ using namespace std::chrono;
+
+ static_assert(make24(0h, false) == 0h);
+ static_assert(make24(1h, false) == 1h);
+ static_assert(make24(5h, false) == 5h);
+ static_assert(make24(11h, false) == 11h);
+ static_assert(make24(12h, false) == 0h);
+
+ static_assert(make24(0h, true) == 12h);
+ static_assert(make24(1h, true) == 13h);
+ static_assert(make24(5h, true) == 17h);
+ static_assert(make24(11h, true) == 23h);
+ static_assert(make24(12h, true) == 12h);
+}
new file mode 100644
@@ -0,0 +1,75 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Class template day [time.cal.month]
+
+#include <chrono>
+
+constexpr void
+constexpr_month()
+{
+ using namespace std::chrono;
+
+ month dm{};
+ ++(++dm);
+ dm++;
+ --(--dm);
+ dm--;
+ dm += months{3};
+ dm -= months{3};
+
+ static_assert(February + months{11} == January);
+ static_assert(January + months{1200} == January);
+ static_assert(January + months{1201} == February);
+ static_assert(months{-1200} + January == January);
+ static_assert(months{-1201} + January == December);
+ static_assert(January - months{1200} == January);
+ static_assert(January - months{-1200} == January);
+ static_assert(January - months{1201} == December);
+
+ static_assert(January - February == months{11});
+ static_assert(February - January == months{1});
+ static_assert(June - June == months{});
+
+ static_assert(++month{4} == month{5});
+ static_assert(month{4}++ == month{4});
+ static_assert(--month{4} == month{3});
+ static_assert(month{4}-- == month{4});
+ static_assert((month{4} += months{3}) == month{7});
+ static_assert((month{4} -= months{3}) == month{1});
+
+ static_assert(!month{}.ok());
+ static_assert(month{1}.ok());
+ static_assert(month{12}.ok());
+ static_assert(!month{13}.ok());
+
+ static_assert(unsigned{month{7}} == 7);
+
+ static_assert(!(month{0} == month{1}));
+ static_assert( (month{0} != month{2}));
+ static_assert( (month{0} < month{3}));
+ static_assert(!(month{0} > month{4}));
+ static_assert( (month{0} <= month{5}));
+ static_assert(!(month{0} >= month{6}));
+
+ static_assert(month{0} <=> month{1} == std::strong_ordering::less);
+ static_assert(month{3} <=> month{3} == std::strong_ordering::equal);
+ static_assert(month{5} <=> month{2} == std::strong_ordering::greater);
+}
new file mode 100644
@@ -0,0 +1,73 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Class template month_day [time.cal.month_day]
+
+#include <chrono>
+
+using namespace std::chrono;
+
+constexpr void
+constexpr_month_day()
+{
+ month_day md0 = April/4;
+ month_day md2 = 4d/April;
+
+ constexpr auto md1 = month_day{month{3}, day{13}};
+ static_assert(md1.month() == month{3});
+ static_assert(md1.day() == day{13});
+
+ static_assert(!month_day{month{1}, day{}}.ok());
+ static_assert( month_day{month{2}, day{1}}.ok());
+ static_assert( month_day{month{3}, day{31}}.ok());
+ static_assert(!month_day{month{4}, day{32}}.ok());
+ static_assert(!month_day{month{0}, day{11}}.ok());
+ static_assert(!month_day{month{13}, day{7}}.ok());
+ static_assert( month_day{month{2}, day{28}}.ok());
+ static_assert( month_day{month{2}, day{29}}.ok());
+ static_assert(!month_day{month{2}, day{30}}.ok());
+
+ using md = month_day;
+ static_assert(!(md{month{1}, day{0}} == md{month{1}, day{1}}));
+ static_assert( (md{month{2}, day{0}} != md{month{2}, day{2}}));
+ static_assert( (md{month{3}, day{0}} < md{month{3}, day{3}}));
+ static_assert(!(md{month{4}, day{0}} > md{month{4}, day{4}}));
+ static_assert( (md{month{5}, day{0}} <= md{month{5}, day{5}}));
+ static_assert(!(md{month{6}, day{0}} >= md{month{6}, day{6}}));
+ static_assert( (md{month{10}, day{13}} == md{month{10}, day{13}}));
+ static_assert( (md{month{9}, day{13}} != md{month{10}, day{13}}));
+ static_assert( (md{month{8}, day{13}} < md{month{10}, day{13}}));
+ static_assert( (md{month{11}, day{13}} > md{month{10}, day{13}}));
+ static_assert( (md{month{10}, day{13}} <= md{month{10}, day{13}}));
+ static_assert( (md{month{10}, day{13}} >= md{month{10}, day{13}}));
+
+ static_assert( (md{month{10}, day{13}} <=> md{month{10}, day{13}})
+ == std::strong_ordering::equal);
+ static_assert( (md{month{3}, day{0}} <=> md{month{3}, day{3}})
+ == std::strong_ordering::less);
+ static_assert( (md{month{11}, day{13}} <=> md{month{10}, day{13}})
+ == std::strong_ordering::greater);
+
+ static_assert(August/14d == month_day{month{8}, day{14}});
+ static_assert(August/14 == month_day{month{8}, day{14}});
+ static_assert(8/14d == month_day{month{8}, day{14}});
+ static_assert(14d/August == month_day{month{8}, day{14}});
+ static_assert(14d/8 == month_day{month{8}, day{14}});
+}
new file mode 100644
@@ -0,0 +1,65 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Class template day [time.cal.month_day_last]
+
+#include <chrono>
+
+constexpr void
+constexpr_month_day_last()
+{
+ using namespace std::chrono;
+ using mdl = month_day_last;
+
+ constexpr auto mdl0 = February / last;
+ static_assert(mdl0.month() == February);
+
+ constexpr auto mdl1 = month_day_last{month{3}};
+ static_assert(mdl1.month() == month{3});
+
+ static_assert( mdl{month{3}}.ok());
+ static_assert(!mdl{month{0}}.ok());
+ static_assert(!mdl{month{13}}.ok());
+
+ static_assert( (mdl{month{1}} == mdl{month{1}}));
+ static_assert(!(mdl{month{2}} != mdl{month{2}}));
+ static_assert(!(mdl{month{3}} < mdl{month{3}}));
+ static_assert(!(mdl{month{4}} > mdl{month{4}}));
+ static_assert( (mdl{month{5}} <= mdl{month{5}}));
+ static_assert( (mdl{month{6}} >= mdl{month{6}}));
+ static_assert( (mdl{month{10}} == mdl{month{10}}));
+ static_assert( (mdl{month{9}} != mdl{month{10}}));
+ static_assert( (mdl{month{8}} < mdl{month{10}}));
+ static_assert( (mdl{month{11}} > mdl{month{10}}));
+ static_assert( (mdl{month{10}} <= mdl{month{10}}));
+ static_assert( (mdl{month{10}} >= mdl{month{10}}));
+
+ static_assert( (mdl{month{1}} <=> mdl{month{1}})
+ == std::strong_ordering::equal);
+ static_assert( (mdl{month{11}} <=> mdl{month{10}})
+ == std::strong_ordering::greater);
+ static_assert( (mdl{month{8}} <=> mdl{month{10}})
+ == std::strong_ordering::less);
+
+ static_assert(August/last == mdl{month{8}});
+ static_assert(8/last == mdl{month{8}});
+ static_assert(last/August == mdl{month{8}});
+ static_assert(last/8 == mdl{month{8}});
+}
new file mode 100644
@@ -0,0 +1,48 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Class template day [time.cal.month_weekday]
+
+#include <chrono>
+
+constexpr void
+constexpr_month_weekday()
+{
+ using namespace std::chrono;
+ using mwd = month_weekday;
+
+ // mwd0 is the third Tuesday of February of an as yet unspecified year.
+ constexpr auto mwd0 = February / Tuesday[3];
+ static_assert(mwd0.ok());
+ static_assert(mwd0.month() == February);
+ static_assert(mwd0.weekday_indexed() == Tuesday[3]);
+
+ static_assert(!mwd{month{0}, Tuesday[3]}.ok());
+ static_assert(!mwd{February, Tuesday[0]}.ok());
+
+ static_assert(mwd{January, Monday[2]} == mwd{January, Monday[2]});
+ static_assert(mwd{January, Monday[2]} != mwd{January, Monday[3]});
+ static_assert(mwd{February, Monday[2]} != mwd{January, Monday[2]});
+
+ static_assert(August/Friday[2] == mwd{month{8}, weekday_indexed{weekday{5u}, 2}});
+ static_assert(8/Friday[2] == mwd{month{8}, weekday_indexed{weekday{5u}, 2}});
+ static_assert(Friday[2]/August == mwd{month{8}, weekday_indexed{weekday{5u}, 2}});
+ static_assert(Friday[2]/8 == mwd{month{8}, weekday_indexed{weekday{5u}, 2}});
+}
new file mode 100644
@@ -0,0 +1,48 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Class template day [time.cal.month_weekday_last]
+
+#include <chrono>
+
+constexpr void
+constexpr_month_weekday_last()
+{
+ using namespace std::chrono;
+ using mwdl = month_weekday_last;
+
+ // mwd0 is the third Tuesday of February of an as yet unspecified year.
+ constexpr auto mwdl0 = February / Tuesday[last];
+ static_assert(mwdl0.ok());
+ static_assert(mwdl0.month() == February);
+ static_assert(mwdl0.weekday_last() == Tuesday[last]);
+
+ static_assert(!mwdl{January, weekday_last{weekday{10}}}.ok());
+ static_assert(!mwdl{month{0}, Tuesday[last]}.ok());
+
+ static_assert(mwdl{January, Monday[last]} == mwdl{January, Monday[last]});
+ static_assert(mwdl{January, Monday[last]} != mwdl{January, Tuesday[last]});
+ static_assert(mwdl{February, Monday[last]} != mwdl{January, Monday[last]});
+
+ static_assert(August/Friday[last] == mwdl{month{8}, weekday_last{weekday{5u}}});
+ static_assert(8/Friday[last] == mwdl{month{8}, weekday_last{weekday{5u}}});
+ static_assert(Friday[last]/August == mwdl{month{8}, weekday_last{weekday{5u}}});
+ static_assert(Friday[last]/8 == mwdl{month{8}, weekday_last{weekday{5u}}});
+}
new file mode 100644
@@ -0,0 +1,102 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Class template day [time.cal.weekday]
+
+#include <chrono>
+
+constexpr void
+constexpr_weekday()
+{
+ using namespace std::chrono;
+
+ weekday dwd{};
+ ++dwd;
+ dwd++;
+ --dwd;
+ dwd--;
+ dwd += days{3};
+ dwd -= days{3};
+
+ static_assert(weekday{3}[2].weekday() == weekday{3});
+ static_assert(weekday{3}[last].weekday() == weekday{3});
+
+ static_assert(weekday{sys_days{1900y/January/1}} == Monday);
+ static_assert(weekday{sys_days{1970y/January/1}} == Thursday);
+ static_assert(weekday{sys_days{2020y/August/21}} == Friday);
+
+ static_assert(weekday{local_days{1900y/January/1}} == Monday);
+ static_assert(weekday{local_days{1970y/January/1}} == Thursday);
+ static_assert(weekday{local_days{2020y/August/21}} == Friday);
+
+ static_assert(++weekday{3} == weekday{4});
+ static_assert(weekday{3}++ == weekday{3});
+ static_assert(--weekday{3} == weekday{2});
+ static_assert(weekday{3}-- == weekday{3});
+ static_assert((weekday{3} += days{3}) == weekday{6});
+ static_assert((weekday{3} -= days{3}) == weekday{0});
+
+ static_assert(Monday + days{7000} == Monday);
+ static_assert(Monday + days{-7000} == Monday);
+ static_assert(days{7001} + Monday == Tuesday);
+ static_assert(days{-7001} + Monday == Sunday);
+ static_assert(Monday - days{7000} == Monday);
+ static_assert(Monday - days{-7000} == Monday);
+ static_assert(Monday - days{7001} == Sunday);
+
+ static_assert([] {
+ constexpr unsigned diff_tbl[7][7]
+ = { { 0, 6, 5, 4, 3, 2, 1},
+ { 1, 0, 6, 5, 4, 3, 2},
+ { 2, 1, 0, 6, 5, 4, 3},
+ { 3, 2, 1, 0, 6, 5, 4},
+ { 4, 3, 2, 1, 0, 6, 5},
+ { 5, 4, 3, 2, 1, 0, 6},
+ { 6, 5, 4, 3, 2, 1, 0} };
+ for (unsigned x = 0; x < 7; x++)
+ for (unsigned y = 0; y < 7; y++)
+ {
+ if (weekday{x} - weekday{y} != days{diff_tbl[x][y]})
+ return false;
+ if (weekday{x} - days{diff_tbl[x][y]} != weekday{y})
+ return false;
+ if (weekday{x} != weekday{y} + days{diff_tbl[x][y]})
+ return false;
+ if (weekday{x} != days{diff_tbl[x][y]} + weekday{y})
+ return false;
+ }
+ return true;
+ }());
+
+ static_assert(Sunday.c_encoding() == 0);
+ static_assert(Sunday.iso_encoding() == 7);
+ static_assert(Monday.c_encoding() == 1);
+ static_assert(Monday.iso_encoding() == 1);
+
+ static_assert(!weekday{127}.ok());
+ static_assert(weekday{0}.ok());
+ static_assert(weekday{6}.ok());
+ static_assert(weekday{7}.ok()); // Ctor wraps 7 to 0.
+ static_assert(!weekday{8}.ok());
+
+ static_assert(weekday{7} == weekday{0});
+ static_assert(!(weekday{0} == weekday{1}));
+ static_assert( (weekday{0} != weekday{2}));
+}
new file mode 100644
@@ -0,0 +1,53 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Class template day [time.cal.weekday_indexed]
+
+#include <chrono>
+
+constexpr void
+constexpr_weekday_indexed()
+{
+ using namespace std::chrono;
+
+ weekday_indexed dwdi{};
+
+ // wdi0 is the second Sunday of an as yet unspecified month.
+ constexpr auto wdi0 = Sunday[2];
+ static_assert(wdi0.weekday() == Sunday);
+ static_assert(wdi0.index() == 2);
+
+ constexpr weekday_indexed wdi1 = {weekday{3}, 2};
+ static_assert(wdi1.weekday() == weekday{3});
+ static_assert(wdi1.index() == 2);
+
+ static_assert(!weekday_indexed{weekday{127}, 1}.ok());
+ static_assert(weekday_indexed{weekday{0}, 1}.ok());
+ static_assert(weekday_indexed{weekday{6}, 2}.ok());
+ static_assert(weekday_indexed{weekday{7}, 3}.ok()); // Weekday wraps 7 to 0.
+ static_assert(!weekday_indexed{weekday{8}, 1}.ok());
+ static_assert(!weekday_indexed{weekday{6}, 6}.ok());
+
+ static_assert(weekday{7}[1] == weekday{0}[1]);
+ static_assert(!(weekday{0}[2] == weekday{1}[2]));
+ static_assert(!(weekday{0}[2] == weekday{0}[3]));
+ static_assert( (weekday{0}[3] != weekday{2}[3]));
+ static_assert( (weekday{0}[3] != weekday{0}[2]));
+}
new file mode 100644
@@ -0,0 +1,48 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Class template day [time.cal.weekday_last]
+
+#include <chrono>
+
+constexpr void
+constexpr_weekday_last()
+{
+ using namespace std::chrono;
+
+ constexpr auto wdl0 = Sunday[last];
+ static_assert(wdl0.weekday() == Sunday);
+
+ constexpr auto wdl1 = weekday{3}[2];
+ static_assert(wdl1.weekday() == weekday{3});
+ static_assert(wdl1.index() == 2);
+ constexpr auto wdll = weekday{3}[last];
+ static_assert(wdll.weekday() == weekday{3});
+
+ static_assert(!weekday_last{weekday{127}}.ok());
+ static_assert(weekday_last{weekday{0}}.ok());
+ static_assert(weekday_last{weekday{6}}.ok());
+ static_assert(weekday_last{weekday{7}}.ok()); // Weekday wraps 7 to 0.
+ static_assert(!weekday_last{weekday{8}}.ok());
+
+ static_assert( (weekday_last{weekday{7}} == weekday_last{weekday{0}}));
+ static_assert(!(weekday_last{weekday{0}} == weekday_last{weekday{1}}));
+ static_assert( (weekday_last{weekday{0}} != weekday_last{weekday{2}}));
+}
new file mode 100644
@@ -0,0 +1,85 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Class template day [time.cal.year]
+
+#include <chrono>
+
+constexpr void
+constexpr_year()
+{
+ using namespace std::chrono;
+
+ year dy{};
+ ++(++dy);
+ dy++;
+ --(--dy);
+ dy--;
+ dy += years{3};
+ dy -= years{3};
+
+ static_assert(++year{4} == year{5});
+ static_assert(year{4}++ == year{4});
+ static_assert(--year{4} == year{3});
+ static_assert(year{4}-- == year{4});
+ static_assert((year{4} += years{3}) == year{7});
+ static_assert((year{4} -= years{3}) == year{1});
+
+ static_assert(year{3} + years{7} == year{10});
+ static_assert(years{3} + year{7} == year{10});
+ static_assert(year{3} - years{7} == year{-4});
+ static_assert(year{10} - year{30} == years{-20});
+
+ const auto my = -dy;
+ const auto py = +dy;
+
+ static_assert((-year{1066} == year{-1066}));
+ static_assert((-year{-332} == year{332}));
+ static_assert((+year{1066} == year{1066}));
+ static_assert((+year{-332} == year{-332}));
+
+ year::min();
+ year::max();
+
+ static_assert(year{-12345}.ok());
+ static_assert(year{1}.ok());
+ static_assert(year{12}.ok());
+ static_assert(year{13}.ok());
+
+ static_assert(int{year{-42}} == -42);
+
+ static_assert(!(year{0} == year{1}));
+ static_assert( (year{0} != year{2}));
+ static_assert( (year{0} < year{3}));
+ static_assert(!(year{0} > year{4}));
+ static_assert( (year{0} <= year{5}));
+ static_assert(!(year{0} >= year{6}));
+
+ static_assert(year{10} <=> year{11} == std::strong_ordering::less);
+ static_assert(year{13} <=> year{13} == std::strong_ordering::equal);
+ static_assert(year{15} <=> year{12} == std::strong_ordering::greater);
+
+ static_assert( year{400}.is_leap());
+ static_assert( year{1984}.is_leap());
+ static_assert(!year{1}.is_leap());
+ static_assert( year{1600}.is_leap());
+ static_assert(!year{3000}.is_leap());
+ static_assert(!year{2019}.is_leap());
+}
new file mode 100644
@@ -0,0 +1,86 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Class template year_month [time.cal.year_month]
+
+#include <chrono>
+
+constexpr void
+constexpr_year_month()
+{
+ using namespace std::chrono;
+ using ym = year_month;
+
+ ym ym0 = 2015y/April;
+ ym0 += years{100};
+ ym0 -= years{100};
+ ym0 += months{50};
+ ym0 -= months{50};
+
+ constexpr ym ym1 = {2015y, June};
+ static_assert(ym1.year() == year{2015});
+ static_assert(ym1.month() == June);
+ static_assert(ym1.ok());
+
+ constexpr ym ym2 = {2016y, May};
+ static_assert(ym2.year() == year{2016});
+ static_assert(ym2.month() == May);
+ static_assert(ym2.ok());
+
+ static_assert(ym1 == ym1);
+ static_assert(ym1 != ym2);
+ static_assert(ym1 < ym2);
+ static_assert(ym1 <= ym2);
+ static_assert(ym2 > ym1);
+ static_assert(ym2 >= ym2);
+
+ static_assert(ym1 <=> ym1 == std::strong_ordering::equal);
+ static_assert(ym1 <=> ym2 == std::strong_ordering::less);
+ static_assert(ym2 <=> ym1 == std::strong_ordering::greater);
+
+ static_assert(2015y/August == ym{year{2015}, August});
+ static_assert(2015y/8 == ym{year{2015}, August});
+
+ static_assert(ym1 + months{6} == 2015y/December);
+ static_assert(ym1 + months{7} == 2016y/January);
+ static_assert(months{24} + ym1 == 2017y/June);
+ static_assert(months{25} + ym1 == 2017y/July);
+
+ static_assert(ym1 + months{-5} == 2015y/January);
+ static_assert(ym1 + months{-6} == 2014y/December);
+ static_assert(ym1 + months{-24} == 2013y/June);
+ static_assert(ym1 + months{-25} == 2013y/May);
+
+ static_assert(ym1 - months{5} == 2015y/January);
+ static_assert(ym1 - months{6} == 2014y/December);
+ static_assert(ym1 - months{24} == 2013y/June);
+ static_assert(ym1 - months{25} == 2013y/May);
+
+ static_assert(ym2 - ym1 == months{11});
+ static_assert(ym1 - ym2 == -months{11});
+
+ static_assert(ym2 + years{1} == 2017y/May);
+ static_assert(ym2 + years{-1} == 2015y/May);
+ static_assert(ym2 - years{1} == 2015y/May);
+
+ static_assert(2017y/33 + months{0} == 2019y/9);
+
+ static_assert(2010y/January + months{-12} == 2009y/January);
+}
new file mode 100644
@@ -0,0 +1,91 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Class template day [time.cal.year_month_day]
+
+#include <chrono>
+
+constexpr void
+constexpr_year_month_day()
+{
+ using namespace std::chrono;
+ using ymd = year_month_day;
+
+ constexpr ymd ymd1{year{1984}, August, 3d};
+ static_assert(ymd1.ok());
+ static_assert(ymd1.year() == year{1984});
+ static_assert(ymd1.month() == August);
+ static_assert(ymd1.day() == 3d);
+ //static_assert(sys_days(ymd1) == time_point_cast<days>(days{5356}));
+ //static_assert(local_days(ymd1) == time_point_cast<days>(days{5356}));
+
+ static_assert(2015y/August/14d == ymd{year{2015}, month{8}, day{14}});
+ static_assert(2015y/August/14 == ymd{year{2015}, month{8}, day{14}});
+ static_assert(2015y/(August/14d) == ymd{year{2015}, month{8}, day{14}});
+ static_assert(2015/(August/14d) == ymd{year{2015}, month{8}, day{14}});
+ static_assert(August/14d/2015y == ymd{year{2015}, month{8}, day{14}});
+ static_assert(August/14d/2015 == ymd{year{2015}, month{8}, day{14}});
+
+ static_assert(((ymd{1000y, January, 1d} += months{1}) += years{1})
+ == February/1d/1001y);
+ static_assert(((ymd{1000y, January, 1d} -= years{1}) -= months{1})
+ == December/1d/998y);
+
+ static_assert(!ymd{1000y, February, 30d}.ok());
+
+ static_assert(June/1d/1977y == June/1d/1977y);
+ static_assert(June/1d/1977y != June/1d/1987y);
+ static_assert(May/15d/1950y <=> May/15d/1950y == std::strong_ordering::equal);
+ static_assert(May/15d/1950y <=> May/14d/1950y == std::strong_ordering::greater);
+ static_assert(April/15d/1950y <=> May/14d/1950y == std::strong_ordering::less);
+
+ static_assert(January/1d/1900y + months{13} == February/1d/1901y);
+ static_assert(months{13} + January/1d/1900y == February/1d/1901y);
+ static_assert(January/1d/1900y + years{1} == January/1d/1901y);
+ static_assert(years{1} + January/1d/1900y == January/1d/1901y);
+ static_assert(January/1d/1900y - months{13} == December/1d/1898y);
+ static_assert(January/1d/1900y - years{1} == January/1d/1899y);
+
+ // N.B. unix seems to be a macro somewhere!
+ constexpr ymd myunix = 1970y/1/1;
+ static_assert(myunix.ok());
+ static_assert(myunix.year() == year{1970});
+ static_assert(myunix.month() == January);
+ static_assert(myunix.day() == day{1});
+ static_assert(sys_days(myunix).time_since_epoch() == days{0});
+ //static_assert(local_days(myunix) == time_point_cast<days>(days{0}));
+
+ static_assert(sys_days{August/20d/2020y}.time_since_epoch() == days{18494});
+
+ static_assert(ymd{sys_days{2017y/January/0}} == 2016y/December/31);
+ static_assert(ymd{sys_days{2017y/January/31}} == 2017y/January/31);
+ static_assert(ymd{sys_days{2017y/January/32}} == 2017y/February/1);
+ static_assert(ymd{sys_days{2017y/33/59 + months{0}}} == 2019y/10/29);
+
+ static_assert(ymd{local_days{2017y/January/0}} == 2016y/December/31);
+ static_assert(ymd{local_days{2017y/January/31}} == 2017y/January/31);
+ static_assert(ymd{local_days{2017y/January/32}} == 2017y/February/1);
+ static_assert(ymd{local_days{2017y/33/59 + months{0}}} == 2019y/10/29);
+
+ static_assert((2000y/February/29d).ok());
+ static_assert(!(2001y/February/29d).ok());
+ static_assert(!(2100y/February/29d).ok());
+ static_assert(!(1999y/February/29d).ok());
+}
new file mode 100644
@@ -0,0 +1,82 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Class template day [time.cal.year_month_day_last]
+
+#include <chrono>
+
+constexpr void
+constexpr_year_month_day_last()
+{
+ using namespace std::chrono;
+ using mdl = month_day_last;
+ using ymdl = year_month_day_last;
+
+ year_month_day_last ymdl1{year{1066}, mdl{October}};
+ ymdl1 += months{9};
+ ymdl1 -= months{9};
+ ymdl1 += years{12};
+ ymdl1 -= years{12};
+
+ constexpr ymdl ymdl2{year{1984}, mdl{August}};
+ static_assert(ymdl2.year() == year{1984});
+ static_assert(ymdl2.month() == August);
+ static_assert(ymdl2.month_day_last() == mdl{August});
+ static_assert(ymdl2.day() == day{31});
+ static_assert(sys_days(ymdl2).time_since_epoch().count() == 5356);
+ static_assert(local_days(ymdl2).time_since_epoch().count() == 5356);
+
+ static_assert( (ymdl{year{1984}, mdl{August}}.ok()));
+ static_assert(!(ymdl{year{1984}, mdl{month{13}}}.ok()));
+
+ static_assert(2015y/August/last == ymdl{year{2015}, month_day_last{month{8}}});
+ static_assert(2015y/(August/last) == ymdl{year{2015}, month_day_last{month{8}}});
+ static_assert(2015/(August/last) == ymdl{year{2015}, month_day_last{month{8}}});
+ static_assert(August/last/2015y == ymdl{year{2015}, month_day_last{month{8}}});
+ static_assert(August/last/2015 == ymdl{year{2015}, month_day_last{month{8}}});
+
+ static_assert(January/last/2000 <=> January/last/2000
+ == std::strong_ordering::equal);
+ static_assert(January/last/2000 <=> February/last/2000
+ == std::strong_ordering::less);
+ static_assert(January/last/2000 <=> January/last/1999
+ == std::strong_ordering::greater);
+
+ static_assert(January/last/2000 + months{13} == February/last/2001);
+ static_assert(January/last/2000 + months{-1} == December/last/1999);
+ static_assert(January/last/2000 - months{13} == December/last/1998);
+ static_assert(January/last/2000 - months{-13} == February/last/2001);
+
+ static_assert(January/last/2000 + years{5} == January/last/2005);
+ static_assert(January/last/2000 - years{5} == January/last/1995);
+
+ static_assert(year_month_day{January/last/2000} == January/31/2000);
+ static_assert(year_month_day{February/last/2000} == February/29/2000);
+ static_assert(year_month_day{March/last/2000} == March/31/2000);
+ static_assert(year_month_day{April/last/2000} == April/30/2000);
+ static_assert(year_month_day{May/last/2000} == May/31/2000);
+ static_assert(year_month_day{June/last/2000} == June/30/2000);
+ static_assert(year_month_day{July/last/2000} == July/31/2000);
+ static_assert(year_month_day{August/last/2000} == August/31/2000);
+ static_assert(year_month_day{September/last/2000} == September/30/2000);
+ static_assert(year_month_day{October/last/2000} == October/31/2000);
+ static_assert(year_month_day{November/last/2000} == November/30/2000);
+ static_assert(year_month_day{December/last/2000} == December/31/2000);
+}
new file mode 100644
@@ -0,0 +1,74 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Class template day [time.cal.year_month_weekday]
+
+#include <chrono>
+
+constexpr void
+constexpr_year_month_weekday()
+{
+ using namespace std::chrono;
+ using ymwd = year_month_weekday;
+
+ year_month_weekday ymwd1{};
+ ymwd1 += months{9};
+ ymwd1 -= months{9};
+ ymwd1 += years{12};
+ ymwd1 -= years{12};
+
+ constexpr ymwd ymwd2{year{1984}, month{August},
+ weekday_indexed{Wednesday, 3}};
+ static_assert(ymwd2.ok());
+ static_assert(ymwd2.year() == year{1984});
+ static_assert(ymwd2.month() == August);
+ static_assert(ymwd2.weekday() == Wednesday);
+ static_assert(ymwd2.index() == 3);
+ static_assert(ymwd2.weekday_indexed() == weekday_indexed{Wednesday, 3});
+ static_assert(ymwd{sys_days{ymwd2}} == ymwd2);
+ static_assert(ymwd{local_days{ymwd2}} == ymwd2);
+
+ static_assert(2015y/August/Friday[2] == ymwd{year{2015}, month{8}, weekday_indexed{weekday{5u}, 2}});
+ static_assert(2015y/(August/Friday[2]) == ymwd{year{2015}, month{8}, weekday_indexed{weekday{5u}, 2}});
+ static_assert(2015/(August/Friday[2]) == ymwd{year{2015}, month{8}, weekday_indexed{weekday{5u}, 2}});
+ static_assert(August/Friday[2]/2015y == ymwd{year{2015}, month{8}, weekday_indexed{weekday{5u}, 2}});
+ static_assert(August/Friday[2]/2015 == ymwd{year{2015}, month{8}, weekday_indexed{weekday{5u}, 2}});
+
+ static_assert(January/Tuesday[2]/1900y + months{1} == February/Tuesday[2]/1900y);
+ static_assert(months{1} + January/Tuesday[2]/1900y == February/Tuesday[2]/1900y);
+ static_assert(January/Tuesday[2]/1900y - months{1} == December/Tuesday[2]/1899y);
+ static_assert(January/Tuesday[2]/1900y + years{1} == January/Tuesday[2]/1901y);
+ static_assert(years{1} + January/Tuesday[2]/1900y == January/Tuesday[2]/1901y);
+ static_assert(January/Tuesday[2]/1900y - years{1} == January/Tuesday[2]/1899y);
+
+ // N.B. unix seems to be a macro somewhere!
+ constexpr ymwd myunix(local_days{days{0}});
+ static_assert(myunix.ok());
+ static_assert(myunix.year() == year{1970});
+ static_assert(myunix.month() == January);
+ static_assert(myunix.weekday() == Thursday);
+ static_assert(myunix.index() == 1);
+ static_assert(myunix.weekday_indexed() == weekday_indexed{Thursday, 1});
+ static_assert(ymwd{sys_days{myunix}} == myunix);
+ static_assert(ymwd{local_days{myunix}} == myunix);
+
+ static_assert((2020y/August/Monday[5]).ok());
+ static_assert(!(2020y/August/Tuesday[5]).ok());
+}
new file mode 100644
@@ -0,0 +1,61 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2020 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Class template month_day [time.cal.month_day]
+
+#include <chrono>
+
+constexpr void
+constexpr_year_month_weekday_last()
+{
+ using namespace std::chrono;
+ using ymwdl = year_month_weekday_last;
+
+ constexpr ymwdl ymwdl1 = {2015y, August, weekday_last{Friday}};
+ static_assert(ymwdl1.ok());
+ static_assert(ymwdl1.year() == 2015y);
+ static_assert(ymwdl1.month() == August);
+ static_assert(ymwdl1.weekday() == Friday);
+ static_assert(ymwdl1.weekday_last() == Friday[last]);
+ static_assert(year_month_day{sys_days{ymwdl1}} == 2015y/August/28d);
+ static_assert(year_month_day{local_days{ymwdl1}} == 2015y/August/28d);
+
+ static_assert(2015y/August/Friday[last] == ymwdl{year{2015}, month{8}, weekday_last{weekday{5u}}});
+ static_assert(2015y/(August/Friday[last]) == ymwdl{year{2015}, month{8}, weekday_last{weekday{5u}}});
+ static_assert(2015/(August/Friday[last]) == ymwdl{year{2015}, month{8}, weekday_last{weekday{5u}}});
+ static_assert(August/Friday[last]/2015y == ymwdl{year{2015}, month{8}, weekday_last{weekday{5u}}});
+ static_assert(August/Friday[last]/2015 == ymwdl{year{2015}, month{8}, weekday_last{weekday{5u}}});
+
+ static_assert((ymwdl{ymwdl1} += months{5} -= months{5}) == ymwdl1);
+ static_assert((ymwdl{ymwdl1} += years{5} -= years{5}) == ymwdl1);
+
+ static_assert(ymwdl1 + months{10} == 2016y/June/Friday[last]);
+ static_assert(months{10} + ymwdl1 == ymwdl1 + months{10});
+ static_assert(ymwdl1 - months{10} == 2014y/October/Friday[last]);
+
+ static_assert(ymwdl1 + years{10} == 2025y/August/Friday[last]);
+ static_assert(years{10} + ymwdl1 == ymwdl1 + years{10});
+ static_assert(ymwdl1 - years{10} == 2005y/August/Friday[last]);
+
+ constexpr ymwdl ymwdl2 = Saturday[last]/August/2015y;
+ static_assert(ymwdl2.ok());
+ static_assert(ymwdl1 == ymwdl1);
+ static_assert(ymwdl1 != ymwdl2);
+}