diff --git a/include/date/date.h b/include/date/date.h index d2b7bf7..4eb1c3d 100644 --- a/include/date/date.h +++ b/include/date/date.h @@ -7,6 +7,7 @@ // Copyright (c) 2016 Adrian Colomitchi // Copyright (c) 2017 Florian Dang // Copyright (c) 2017 Paul Thompson +// Copyright (c) 2018 Tomasz Kamiński // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -95,12 +96,14 @@ namespace date # define CONSTCD11 # define CONSTCD14 # define NOEXCEPT _NOEXCEPT +# define NOEXCEPT_COND(...) # else // VS2017 and later # define CONSTDATA constexpr const # define CONSTCD11 constexpr # define CONSTCD14 constexpr # define NOEXCEPT noexcept +# define NOEXCEPT_COND(...) noexcept(__VA_ARGS__) # endif #elif defined(__SUNPRO_CC) && __SUNPRO_CC <= 0x5150 @@ -109,6 +112,7 @@ namespace date # define CONSTCD11 constexpr # define CONSTCD14 # define NOEXCEPT noexcept +# define NOEXCEPT_COND(...) noexcept(__VA_ARGS__) #elif __cplusplus >= 201402 // C++14 @@ -116,12 +120,14 @@ namespace date # define CONSTCD11 constexpr # define CONSTCD14 constexpr # define NOEXCEPT noexcept +# define NOEXCEPT_COND(...) noexcept(__VA_ARGS__) #else // C++11 # define CONSTDATA constexpr const # define CONSTCD11 constexpr # define CONSTCD14 # define NOEXCEPT noexcept +# define NOEXCEPT_COND(...) noexcept(__VA_ARGS__) #endif #ifndef HAS_VOID_T @@ -490,6 +496,11 @@ template std::basic_ostream& operator<<(std::basic_ostream& os, const weekday_last& wdl); +#define NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS \ + NOEXCEPT_COND(std::is_nothrow_constructible::value \ + || (!std::is_convertible::value \ + && std::is_nothrow_constructible::value)) + // year_month class year_month @@ -504,10 +515,19 @@ public: CONSTCD11 date::year year() const NOEXCEPT; CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD14 year_month& operator+=(const months& dm) NOEXCEPT; - CONSTCD14 year_month& operator-=(const months& dm) NOEXCEPT; - CONSTCD14 year_month& operator+=(const years& dy) NOEXCEPT; - CONSTCD14 year_month& operator-=(const years& dy) NOEXCEPT; + template ::value + >::type> + CONSTCD14 year_month& operator+=(const Duration& d) + NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; + + template ::value + >::type> + CONSTCD14 year_month& operator-=(const Duration& d) + NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; CONSTCD11 bool ok() const NOEXCEPT; }; @@ -524,9 +544,27 @@ CONSTCD14 year_month operator+(const months& dm, const year_month& ym) NOEXCEPT; CONSTCD14 year_month operator-(const year_month& ym, const months& dm) NOEXCEPT; CONSTCD11 months operator-(const year_month& x, const year_month& y) NOEXCEPT; -CONSTCD11 year_month operator+(const year_month& ym, const years& dy) NOEXCEPT; -CONSTCD11 year_month operator+(const years& dy, const year_month& ym) NOEXCEPT; -CONSTCD11 year_month operator-(const year_month& ym, const years& dy) NOEXCEPT; + +template ::value + >::type> +CONSTCD11 year_month operator+(const year_month& ym, const Duration& d) +NOEXCEPT_COND(std::is_nothrow_constructible::value); + +template ::value + >::type> +CONSTCD11 year_month operator+(const Duration& d, const year_month& ym) +NOEXCEPT_COND(std::is_nothrow_constructible::value); + +template ::value + >::type> +CONSTCD11 year_month operator-(const year_month& ym, const Duration& d) +NOEXCEPT_COND(std::is_nothrow_constructible::value); template std::basic_ostream& @@ -650,10 +688,19 @@ public: CONSTCD14 year_month_day(sys_days dp) NOEXCEPT; CONSTCD14 explicit year_month_day(local_days dp) NOEXCEPT; - CONSTCD14 year_month_day& operator+=(const months& m) NOEXCEPT; - CONSTCD14 year_month_day& operator-=(const months& m) NOEXCEPT; - CONSTCD14 year_month_day& operator+=(const years& y) NOEXCEPT; - CONSTCD14 year_month_day& operator-=(const years& y) NOEXCEPT; + template ::value + >::type> + CONSTCD14 year_month_day& operator+=(const Duration& d) + NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; + + template ::value + >::type> + CONSTCD14 year_month_day& operator-=(const Duration& d) + NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; CONSTCD11 date::year year() const NOEXCEPT; CONSTCD11 date::month month() const NOEXCEPT; @@ -675,12 +722,29 @@ CONSTCD11 bool operator> (const year_month_day& x, const year_month_day& y) NOEX CONSTCD11 bool operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT; CONSTCD11 bool operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT; -CONSTCD14 year_month_day operator+(const year_month_day& ymd, const months& dm) NOEXCEPT; -CONSTCD14 year_month_day operator+(const months& dm, const year_month_day& ymd) NOEXCEPT; -CONSTCD14 year_month_day operator-(const year_month_day& ymd, const months& dm) NOEXCEPT; -CONSTCD11 year_month_day operator+(const year_month_day& ymd, const years& dy) NOEXCEPT; -CONSTCD11 year_month_day operator+(const years& dy, const year_month_day& ymd) NOEXCEPT; -CONSTCD11 year_month_day operator-(const year_month_day& ymd, const years& dy) NOEXCEPT; + +CONSTCD11 year_month operator/(const year& y, const month& m) NOEXCEPT; + +template ::value + >::type> +CONSTCD11 year_month_day operator+(const year_month_day& ymd, const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; + +template ::value + >::type> +CONSTCD11 year_month_day operator+(const Duration& d, const year_month_day& ymd) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; + +template ::value + >::type> +CONSTCD11 year_month_day operator-(const year_month_day& ymd, const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; template std::basic_ostream& @@ -697,10 +761,19 @@ public: CONSTCD11 year_month_day_last(const date::year& y, const date::month_day_last& mdl) NOEXCEPT; - CONSTCD14 year_month_day_last& operator+=(const months& m) NOEXCEPT; - CONSTCD14 year_month_day_last& operator-=(const months& m) NOEXCEPT; - CONSTCD14 year_month_day_last& operator+=(const years& y) NOEXCEPT; - CONSTCD14 year_month_day_last& operator-=(const years& y) NOEXCEPT; + template ::value + >::type> + CONSTCD14 year_month_day_last& operator+=(const Duration& d) + NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; + + template ::value + >::type> + CONSTCD14 year_month_day_last& operator-=(const Duration& d) + NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; CONSTCD11 date::year year() const NOEXCEPT; CONSTCD11 date::month month() const NOEXCEPT; @@ -725,29 +798,29 @@ CONSTCD11 CONSTCD11 bool operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; -CONSTCD14 -year_month_day_last -operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; - -CONSTCD14 -year_month_day_last -operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT; - +template ::value + >::type> CONSTCD11 -year_month_day_last -operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; + year_month_day_last operator+(const year_month_day_last& ymd, const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; +template ::value + >::type> CONSTCD11 -year_month_day_last -operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT; - -CONSTCD14 -year_month_day_last -operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; + year_month_day_last operator+(const Duration& d, const year_month_day_last& ymd) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; +template ::value + >::type> CONSTCD11 -year_month_day_last -operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; + year_month_day_last operator-(const year_month_day_last& ymd, const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; template std::basic_ostream& @@ -768,10 +841,19 @@ public: CONSTCD14 year_month_weekday(const sys_days& dp) NOEXCEPT; CONSTCD14 explicit year_month_weekday(const local_days& dp) NOEXCEPT; - CONSTCD14 year_month_weekday& operator+=(const months& m) NOEXCEPT; - CONSTCD14 year_month_weekday& operator-=(const months& m) NOEXCEPT; - CONSTCD14 year_month_weekday& operator+=(const years& y) NOEXCEPT; - CONSTCD14 year_month_weekday& operator-=(const years& y) NOEXCEPT; + template ::value + >::type> + CONSTCD14 year_month_weekday& operator+=(const Duration& d) + NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; + + template ::value + >::type> + CONSTCD14 year_month_weekday& operator-=(const Duration& d) + NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; CONSTCD11 date::year year() const NOEXCEPT; CONSTCD11 date::month month() const NOEXCEPT; @@ -793,29 +875,26 @@ CONSTCD11 CONSTCD11 bool operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT; -CONSTCD14 -year_month_weekday -operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; +template ::value + >::type> +CONSTCD11 year_month_weekday operator+(const year_month_weekday& ymd, const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; -CONSTCD14 -year_month_weekday -operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT; +template ::value + >::type> +CONSTCD11 year_month_weekday operator+(const Duration& d, const year_month_weekday& ymd) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; -CONSTCD11 -year_month_weekday -operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT; - -CONSTCD14 -year_month_weekday -operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; +template ::value + >::type> +CONSTCD11 year_month_weekday operator-(const year_month_weekday& ymd, const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; template std::basic_ostream& @@ -833,10 +912,19 @@ public: CONSTCD11 year_month_weekday_last(const date::year& y, const date::month& m, const date::weekday_last& wdl) NOEXCEPT; - CONSTCD14 year_month_weekday_last& operator+=(const months& m) NOEXCEPT; - CONSTCD14 year_month_weekday_last& operator-=(const months& m) NOEXCEPT; - CONSTCD14 year_month_weekday_last& operator+=(const years& y) NOEXCEPT; - CONSTCD14 year_month_weekday_last& operator-=(const years& y) NOEXCEPT; + template ::value + >::type> + CONSTCD14 year_month_weekday_last& operator+=(const Duration& d) + NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; + + template ::value + >::type> + CONSTCD14 year_month_weekday_last& operator-=(const Duration& d) + NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; CONSTCD11 date::year year() const NOEXCEPT; CONSTCD11 date::month month() const NOEXCEPT; @@ -859,29 +947,29 @@ CONSTCD11 bool operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT; -CONSTCD14 -year_month_weekday_last -operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; - -CONSTCD14 -year_month_weekday_last -operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT; - +template ::value + >::type> CONSTCD11 -year_month_weekday_last -operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; + year_month_weekday_last operator+(const year_month_weekday_last& ymd, const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; +template ::value + >::type> CONSTCD11 -year_month_weekday_last -operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT; - -CONSTCD14 -year_month_weekday_last -operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; + year_month_weekday_last operator+(const Duration& d, const year_month_weekday_last& ymd) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; +template ::value + >::type> CONSTCD11 -year_month_weekday_last -operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; + year_month_weekday_last operator-(const year_month_weekday_last& ymd, const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS; template std::basic_ostream& @@ -1982,39 +2070,25 @@ CONSTCD11 inline year year_month::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month::month() const NOEXCEPT {return m_;} CONSTCD11 inline bool year_month::ok() const NOEXCEPT {return y_.ok() && m_.ok();} +template CONSTCD14 inline year_month& -year_month::operator+=(const months& dm) NOEXCEPT +year_month::operator+=(const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS { - *this = *this + dm; + *this = *this + d; return *this; } +template CONSTCD14 inline year_month& -year_month::operator-=(const months& dm) NOEXCEPT +year_month::operator-=(const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS { - *this = *this - dm; - return *this; -} - -CONSTCD14 -inline -year_month& -year_month::operator+=(const years& dy) NOEXCEPT -{ - *this = *this + dy; - return *this; -} - -CONSTCD14 -inline -year_month& -year_month::operator-=(const years& dy) NOEXCEPT -{ - *this = *this - dy; + *this = *this - d; return *this; } @@ -2104,28 +2178,34 @@ operator-(const year_month& x, const year_month& y) NOEXCEPT months(static_cast(x.month()) - static_cast(y.month())); } +template CONSTCD11 inline year_month -operator+(const year_month& ym, const years& dy) NOEXCEPT +operator+(const year_month& ym, const Duration& d) +NOEXCEPT_COND(std::is_nothrow_constructible::value) { - return (ym.year() + dy) / ym.month(); + return (ym.year() + years(d)) / ym.month();; } +template CONSTCD11 inline year_month -operator+(const years& dy, const year_month& ym) NOEXCEPT +operator+(const Duration& d, const year_month& ym) +NOEXCEPT_COND(std::is_nothrow_constructible::value) { - return ym + dy; + return ym + years(d); } +template CONSTCD11 inline year_month -operator-(const year_month& ym, const years& dy) NOEXCEPT +operator-(const year_month& ym, const Duration& d) +NOEXCEPT_COND(std::is_nothrow_constructible::value) { - return ym + -dy; + return ym + -years(d); } template @@ -2397,42 +2477,6 @@ year_month_day_last::year_month_day_last(const date::year& y, , mdl_(mdl) {} -CONSTCD14 -inline -year_month_day_last& -year_month_day_last::operator+=(const months& m) NOEXCEPT -{ - *this = *this + m; - return *this; -} - -CONSTCD14 -inline -year_month_day_last& -year_month_day_last::operator-=(const months& m) NOEXCEPT -{ - *this = *this - m; - return *this; -} - -CONSTCD14 -inline -year_month_day_last& -year_month_day_last::operator+=(const years& y) NOEXCEPT -{ - *this = *this + y; - return *this; -} - -CONSTCD14 -inline -year_month_day_last& -year_month_day_last::operator-=(const years& y) NOEXCEPT -{ - *this = *this - y; - return *this; -} - CONSTCD11 inline year year_month_day_last::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_day_last::month() const NOEXCEPT {return mdl_.month();} @@ -2460,6 +2504,28 @@ year_month_day_last::day() const NOEXCEPT d[static_cast(month()) - 1] : date::day{29}; } +template +CONSTCD14 +inline +year_month_day_last& +year_month_day_last::operator+=(const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + *this = *this + d; + return *this; +} + +template +CONSTCD14 +inline +year_month_day_last& +year_month_day_last::operator-=(const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + *this = *this - d; + return *this; +} + CONSTCD14 inline year_month_day_last::operator sys_days() const NOEXCEPT @@ -2532,6 +2598,36 @@ operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT return !(x < y); } +template +CONSTCD11 +inline +year_month_day_last +operator+(const year_month_day_last& ymd, const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + return (ymd.year() / ymd.month() + d) / last_spec(); +} + +template +CONSTCD11 +inline +year_month_day_last +operator+(const Duration& d, const year_month_day_last& ymd) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + return (ymd.year() / ymd.month() + d) / last_spec(); +} + +template +CONSTCD11 +inline +year_month_day_last +operator-(const year_month_day_last& ymd, const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + return (ymd.year() / ymd.month() - d) / last_spec(); +} + template inline std::basic_ostream& @@ -2540,54 +2636,6 @@ operator<<(std::basic_ostream& os, const year_month_day_last& ymd return os << ymdl.year() << '/' << ymdl.month_day_last(); } -CONSTCD14 -inline -year_month_day_last -operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT -{ - return (ymdl.year() / ymdl.month() + dm) / last; -} - -CONSTCD14 -inline -year_month_day_last -operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT -{ - return ymdl + dm; -} - -CONSTCD14 -inline -year_month_day_last -operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT -{ - return ymdl + (-dm); -} - -CONSTCD11 -inline -year_month_day_last -operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT -{ - return {ymdl.year()+dy, ymdl.month_day_last()}; -} - -CONSTCD11 -inline -year_month_day_last -operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT -{ - return ymdl + dy; -} - -CONSTCD11 -inline -year_month_day_last -operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT -{ - return ymdl + (-dy); -} - // year_month_day CONSTCD11 @@ -2623,39 +2671,25 @@ CONSTCD11 inline year year_month_day::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_day::month() const NOEXCEPT {return m_;} CONSTCD11 inline day year_month_day::day() const NOEXCEPT {return d_;} +template CONSTCD14 inline year_month_day& -year_month_day::operator+=(const months& m) NOEXCEPT +year_month_day::operator+=(const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS { - *this = *this + m; + *this = *this + d; return *this; } +template CONSTCD14 inline year_month_day& -year_month_day::operator-=(const months& m) NOEXCEPT +year_month_day::operator-=(const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS { - *this = *this - m; - return *this; -} - -CONSTCD14 -inline -year_month_day& -year_month_day::operator+=(const years& y) NOEXCEPT -{ - *this = *this + y; - return *this; -} - -CONSTCD14 -inline -year_month_day& -year_month_day::operator-=(const years& y) NOEXCEPT -{ - *this = *this - y; + *this = *this - d; return *this; } @@ -2754,6 +2788,36 @@ operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT return !(x < y); } +template +CONSTCD11 +inline +year_month_day +operator+(const year_month_day& ymd, const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + return (ymd.year() / ymd.month() + d) / ymd.day(); +} + +template +CONSTCD11 +inline +year_month_day +operator+(const Duration& d, const year_month_day& ymd) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + return (ymd.year() / ymd.month() + d) / ymd.day(); +} + +template +CONSTCD11 +inline +year_month_day +operator-(const year_month_day& ymd, const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + return (ymd.year() / ymd.month() - d) / ymd.day(); +} + template inline std::basic_ostream& @@ -2792,54 +2856,6 @@ year_month_day::from_days(days dp) NOEXCEPT return year_month_day{date::year{y + (m <= 2)}, date::month(m), date::day(d)}; } -CONSTCD14 -inline -year_month_day -operator+(const year_month_day& ymd, const months& dm) NOEXCEPT -{ - return (ymd.year() / ymd.month() + dm) / ymd.day(); -} - -CONSTCD14 -inline -year_month_day -operator+(const months& dm, const year_month_day& ymd) NOEXCEPT -{ - return ymd + dm; -} - -CONSTCD14 -inline -year_month_day -operator-(const year_month_day& ymd, const months& dm) NOEXCEPT -{ - return ymd + (-dm); -} - -CONSTCD11 -inline -year_month_day -operator+(const year_month_day& ymd, const years& dy) NOEXCEPT -{ - return (ymd.year() + dy) / ymd.month() / ymd.day(); -} - -CONSTCD11 -inline -year_month_day -operator+(const years& dy, const year_month_day& ymd) NOEXCEPT -{ - return ymd + dy; -} - -CONSTCD11 -inline -year_month_day -operator-(const year_month_day& ymd, const years& dy) NOEXCEPT -{ - return ymd + (-dy); -} - // year_month_weekday CONSTCD11 @@ -2864,42 +2880,6 @@ year_month_weekday::year_month_weekday(const local_days& dp) NOEXCEPT : year_month_weekday(from_days(dp.time_since_epoch())) {} -CONSTCD14 -inline -year_month_weekday& -year_month_weekday::operator+=(const months& m) NOEXCEPT -{ - *this = *this + m; - return *this; -} - -CONSTCD14 -inline -year_month_weekday& -year_month_weekday::operator-=(const months& m) NOEXCEPT -{ - *this = *this - m; - return *this; -} - -CONSTCD14 -inline -year_month_weekday& -year_month_weekday::operator+=(const years& y) NOEXCEPT -{ - *this = *this + y; - return *this; -} - -CONSTCD14 -inline -year_month_weekday& -year_month_weekday::operator-=(const years& y) NOEXCEPT -{ - *this = *this - y; - return *this; -} - CONSTCD11 inline year year_month_weekday::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_weekday::month() const NOEXCEPT {return m_;} @@ -2927,6 +2907,26 @@ year_month_weekday::weekday_indexed() const NOEXCEPT return wdi_; } +template +CONSTCD14 +year_month_weekday& +year_month_weekday::operator+=(const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + *this = *this + d; + return *this; +} + +template +CONSTCD14 +year_month_weekday& +year_month_weekday::operator-=(const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + *this = *this - d; + return *this; +} + CONSTCD14 inline year_month_weekday::operator sys_days() const NOEXCEPT @@ -2992,6 +2992,36 @@ operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT return !(x == y); } +template +CONSTCD11 +inline +year_month_weekday +operator+(const year_month_weekday& ymd, const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + return (ymd.year() / ymd.month() + d) / ymd.weekday_indexed(); +} + +template +CONSTCD11 +inline +year_month_weekday +operator+(const Duration& d, const year_month_weekday& ymd) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + return (ymd.year() / ymd.month() + d) / ymd.weekday_indexed();; +} + +template +CONSTCD11 +inline +year_month_weekday +operator-(const year_month_weekday& ymd, const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + return (ymd.year() / ymd.month() - d) / ymd.weekday_indexed(); +} + template inline std::basic_ostream& @@ -3001,54 +3031,6 @@ operator<<(std::basic_ostream& os, const year_month_weekday& ymwd << '/' << ymwdi.weekday_indexed(); } -CONSTCD14 -inline -year_month_weekday -operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT -{ - return (ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed(); -} - -CONSTCD14 -inline -year_month_weekday -operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT -{ - return ymwd + dm; -} - -CONSTCD14 -inline -year_month_weekday -operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT -{ - return ymwd + (-dm); -} - -CONSTCD11 -inline -year_month_weekday -operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT -{ - return {ymwd.year()+dy, ymwd.month(), ymwd.weekday_indexed()}; -} - -CONSTCD11 -inline -year_month_weekday -operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT -{ - return ymwd + dy; -} - -CONSTCD11 -inline -year_month_weekday -operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT -{ - return ymwd + (-dy); -} - // year_month_weekday_last CONSTCD11 @@ -3061,42 +3043,6 @@ year_month_weekday_last::year_month_weekday_last(const date::year& y, , wdl_(wdl) {} -CONSTCD14 -inline -year_month_weekday_last& -year_month_weekday_last::operator+=(const months& m) NOEXCEPT -{ - *this = *this + m; - return *this; -} - -CONSTCD14 -inline -year_month_weekday_last& -year_month_weekday_last::operator-=(const months& m) NOEXCEPT -{ - *this = *this - m; - return *this; -} - -CONSTCD14 -inline -year_month_weekday_last& -year_month_weekday_last::operator+=(const years& y) NOEXCEPT -{ - *this = *this + y; - return *this; -} - -CONSTCD14 -inline -year_month_weekday_last& -year_month_weekday_last::operator-=(const years& y) NOEXCEPT -{ - *this = *this - y; - return *this; -} - CONSTCD11 inline year year_month_weekday_last::year() const NOEXCEPT {return y_;} CONSTCD11 inline month year_month_weekday_last::month() const NOEXCEPT {return m_;} @@ -3116,6 +3062,28 @@ year_month_weekday_last::weekday_last() const NOEXCEPT return wdl_; } +template +CONSTCD14 +inline +year_month_weekday_last& +year_month_weekday_last::operator+=(const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + *this = *this + d; + return *this; +} + +template +CONSTCD14 +inline +year_month_weekday_last& +year_month_weekday_last::operator-=(const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + *this = *this - d; + return *this; +} + CONSTCD14 inline year_month_weekday_last::operator sys_days() const NOEXCEPT @@ -3164,6 +3132,36 @@ operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) N return !(x == y); } +template +CONSTCD11 +inline +year_month_weekday_last +operator+(const year_month_weekday_last& ymd, const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + return (ymd.year() / ymd.month() + d) / ymd.weekday_last(); +} + +template +CONSTCD11 +inline +year_month_weekday_last +operator+(const Duration& d, const year_month_weekday_last& ymd) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + return (ymd.year() / ymd.month() + d) / ymd.weekday_last();; +} + +template +CONSTCD11 +inline +year_month_weekday_last +operator-(const year_month_weekday_last& ymd, const Duration& d) +NOEXCEPT_CONVERTIBLE_TO_YEARS_OR_MONTHS +{ + return (ymd.year() / ymd.month() - d) / ymd.weekday_last(); +} + template inline std::basic_ostream& @@ -3172,54 +3170,6 @@ operator<<(std::basic_ostream& os, const year_month_weekday_last& return os << ymwdl.year() << '/' << ymwdl.month() << '/' << ymwdl.weekday_last(); } -CONSTCD14 -inline -year_month_weekday_last -operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT -{ - return (ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last(); -} - -CONSTCD14 -inline -year_month_weekday_last -operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT -{ - return ymwdl + dm; -} - -CONSTCD14 -inline -year_month_weekday_last -operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT -{ - return ymwdl + (-dm); -} - -CONSTCD11 -inline -year_month_weekday_last -operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT -{ - return {ymwdl.year()+dy, ymwdl.month(), ymwdl.weekday_last()}; -} - -CONSTCD11 -inline -year_month_weekday_last -operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT -{ - return ymwdl + dy; -} - -CONSTCD11 -inline -year_month_weekday_last -operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT -{ - return ymwdl + (-dy); -} - // year_month from operator/() CONSTCD11 diff --git a/test/clock_cast_test/custom_clock.pass.cpp b/test/clock_cast_test/custom_clock.pass.cpp index d9c9d8b..8d3ccba 100644 --- a/test/clock_cast_test/custom_clock.pass.cpp +++ b/test/clock_cast_test/custom_clock.pass.cpp @@ -30,16 +30,16 @@ int conversions = 0; //to/from impl struct mil_clock { - using duration = std::common_type_t; + using duration = typename std::common_type::type; using rep = duration::rep; using period = duration::period; using time_point = std::chrono::time_point; - static constexpr date::sys_days epoch = date::year{2000}/date::month{0}/date::day{1}; + static constexpr date::sys_days epoch{date::days{1000}}; template static - std::chrono::time_point> + std::chrono::time_point::type> to_sys(std::chrono::time_point const& tp) { ++conversions; @@ -48,11 +48,11 @@ struct mil_clock template static - std::chrono::time_point> + std::chrono::time_point::type> from_sys(std::chrono::time_point const& tp) { ++conversions; - using res = std::chrono::time_point>; + using res = std::chrono::time_point::type>; return res(tp - epoch); } @@ -103,11 +103,11 @@ namespace date struct clock_time_conversion { template - std::chrono::time_point> + std::chrono::time_point::type> operator()(std::chrono::time_point const& tp) { ++conversions; - using res = std::chrono::time_point>; + using res = std::chrono::time_point::type>; return res(tp.time_since_epoch() - mil_clock::epoch.time_since_epoch()); } }; diff --git a/test/clock_cast_test/to_sys_return_utc_time.fail.cpp b/test/clock_cast_test/to_sys_return_utc_time.fail.cpp index d5364ce..6fc7a2b 100644 --- a/test/clock_cast_test/to_sys_return_utc_time.fail.cpp +++ b/test/clock_cast_test/to_sys_return_utc_time.fail.cpp @@ -34,7 +34,7 @@ struct bad_clock date::utc_time to_sys(std::chrono::time_point const& tp) { - return utc_time(tp.time_since_epoch()); + return date::utc_time(tp.time_since_epoch()); } }; diff --git a/test/date_test/multi_year_duration_addition.pass.cpp b/test/date_test/multi_year_duration_addition.pass.cpp new file mode 100644 index 0000000..0de3479 --- /dev/null +++ b/test/date_test/multi_year_duration_addition.pass.cpp @@ -0,0 +1,297 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Tomasz Kamiński +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include "date.h" +#include +#include +#include + +#define CPP11_ASSERT(...) static_assert(__VA_ARGS__, "") + +#if __cplusplus >= 201402 +// C++14 +# define CPP14_ASSERT(...) static_assert(__VA_ARGS__, "") +#else +// C++11 +# define CPP14_ASSERT(...) assert(__VA_ARGS__) +#endif + +#define NOEXCEPT_ASSERT(...) static_assert(noexcept(__VA_ARGS__), "") + +//Invocation involves a conversion between duration that is currently +//not marked as noexcept. +#define NOEXCEPT_CONVERSION(...) + +template +constexpr T copy(T const& t) noexcept { return t; } + + +int +main() +{ + using namespace date; + using namespace std::chrono; + + using decades = duration, years::period>>; + using decamonths = duration, months::period>>; + + constexpr months one_month{1}; + constexpr years one_year{1}; + constexpr decades one_decade{1}; + constexpr decamonths one_decamonth{1}; + + { + constexpr year_month ym = 2001_y/feb; + CPP14_ASSERT(ym + one_month == 2001_y/mar); + NOEXCEPT_ASSERT(ym + one_month); + CPP14_ASSERT(one_month + ym == 2001_y/mar); + NOEXCEPT_ASSERT(one_month + ym); + CPP14_ASSERT(ym - one_month == 2001_y/jan); + NOEXCEPT_ASSERT(ym - one_month); + CPP14_ASSERT((copy(ym) += one_month) == 2001_y/mar); + NOEXCEPT_ASSERT(copy(ym) += one_month); + CPP14_ASSERT((copy(ym) -= one_month) == 2001_y/jan); + NOEXCEPT_ASSERT(copy(ym) -= one_month); + + CPP11_ASSERT(ym + one_year == 2002_y/feb); + NOEXCEPT_ASSERT(ym + one_year); + CPP11_ASSERT(one_year + ym == 2002_y/feb); + NOEXCEPT_ASSERT(one_year + ym); + CPP11_ASSERT(ym - one_year == 2000_y/feb); + NOEXCEPT_ASSERT(ym - one_year); + CPP14_ASSERT((copy(ym) += one_year) == 2002_y/feb); + NOEXCEPT_ASSERT(copy(ym) += one_year); + CPP14_ASSERT((copy(ym) -= one_year) == 2000_y/feb); + NOEXCEPT_ASSERT(copy(ym) -= one_year); + + CPP11_ASSERT(ym + one_decade == 2011_y/feb); + NOEXCEPT_CONVERSION(ym + one_decade); + CPP11_ASSERT(one_decade + ym == 2011_y/feb); + NOEXCEPT_CONVERSION(one_decade + ym); + CPP11_ASSERT(ym - one_decade == 1991_y/feb); + NOEXCEPT_CONVERSION(ym - one_decade); + CPP14_ASSERT((copy(ym) += one_decade) == 2011_y/feb); + NOEXCEPT_CONVERSION(copy(ym) += one_decade); + CPP14_ASSERT((copy(ym) -= one_decade) == 1991_y/feb); + NOEXCEPT_CONVERSION(copy(ym) -= one_decade); + + CPP14_ASSERT(ym + one_decamonth == 2001_y/dec); + NOEXCEPT_CONVERSION(ym + one_decamonth); + CPP14_ASSERT(one_decamonth + ym == 2001_y/dec); + NOEXCEPT_CONVERSION(one_decamonth + ym); + CPP14_ASSERT(ym - one_decamonth == 2000_y/apr); + NOEXCEPT_CONVERSION(ym - one_decamonth); + CPP14_ASSERT((copy(ym) += one_decamonth) == 2001_y/dec); + NOEXCEPT_CONVERSION(copy(ym) += one_decamonth); + CPP14_ASSERT((copy(ym) -= one_decamonth) == 2000_y/apr); + NOEXCEPT_CONVERSION(copy(ym) -= one_decamonth); + } + + { + constexpr year_month_day ym = 2001_y/feb/10; + CPP14_ASSERT(ym + one_month == 2001_y/mar/10); + NOEXCEPT_ASSERT(ym + one_month); + CPP14_ASSERT(one_month + ym == 2001_y/mar/10); + NOEXCEPT_ASSERT(one_month + ym); + CPP14_ASSERT(ym - one_month == 2001_y/jan/10); + NOEXCEPT_ASSERT(ym - one_month); + CPP14_ASSERT((copy(ym) += one_month) == 2001_y/mar/10); + NOEXCEPT_ASSERT(copy(ym) += one_month); + CPP14_ASSERT((copy(ym) -= one_month) == 2001_y/jan/10); + NOEXCEPT_ASSERT(copy(ym) -= one_month); + + CPP11_ASSERT(ym + one_year == 2002_y/feb/10); + NOEXCEPT_ASSERT(ym + one_year); + CPP11_ASSERT(one_year + ym == 2002_y/feb/10); + NOEXCEPT_ASSERT(one_year + ym); + CPP11_ASSERT(ym - one_year == 2000_y/feb/10); + NOEXCEPT_ASSERT(ym - one_year); + CPP14_ASSERT((copy(ym) += one_year) == 2002_y/feb/10); + NOEXCEPT_ASSERT(copy(ym) += one_year); + CPP14_ASSERT((copy(ym) -= one_year) == 2000_y/feb/10); + NOEXCEPT_ASSERT(copy(ym) -= one_year); + + CPP11_ASSERT(ym + one_decade == 2011_y/feb/10); + NOEXCEPT_CONVERSION(ym + one_decade); + CPP11_ASSERT(one_decade + ym == 2011_y/feb/10); + NOEXCEPT_CONVERSION(one_decade + ym); + CPP11_ASSERT(ym - one_decade == 1991_y/feb/10); + NOEXCEPT_CONVERSION(ym - one_decade); + CPP14_ASSERT((copy(ym) += one_decade) == 2011_y/feb/10); + NOEXCEPT_CONVERSION(copy(ym) += one_decade); + CPP14_ASSERT((copy(ym) -= one_decade) == 1991_y/feb/10); + NOEXCEPT_CONVERSION(copy(ym) -= one_decade); + + CPP14_ASSERT(ym + one_decamonth == 2001_y/dec/10); + NOEXCEPT_CONVERSION(ym + one_decamonth); + CPP14_ASSERT(one_decamonth + ym == 2001_y/dec/10); + NOEXCEPT_CONVERSION(one_decamonth + ym); + CPP14_ASSERT(ym - one_decamonth == 2000_y/apr/10); + NOEXCEPT_CONVERSION(ym - one_decamonth); + CPP14_ASSERT((copy(ym) += one_decamonth) == 2001_y/dec/10); + NOEXCEPT_CONVERSION(copy(ym) += one_decamonth); + CPP14_ASSERT((copy(ym) -= one_decamonth) == 2000_y/apr/10); + NOEXCEPT_CONVERSION(copy(ym) -= one_decamonth); + } + + { + constexpr year_month_day_last ym = 2001_y/feb/last; + CPP14_ASSERT(ym + one_month == 2001_y/mar/last); + NOEXCEPT_ASSERT(ym + one_month); + CPP14_ASSERT(one_month + ym == 2001_y/mar/last); + NOEXCEPT_ASSERT(one_month + ym); + CPP14_ASSERT(ym - one_month == 2001_y/jan/last); + NOEXCEPT_ASSERT(ym - one_month); + CPP14_ASSERT((copy(ym) += one_month) == 2001_y/mar/last); + NOEXCEPT_ASSERT(copy(ym) += one_month); + CPP14_ASSERT((copy(ym) -= one_month) == 2001_y/jan/last); + NOEXCEPT_ASSERT(copy(ym) -= one_month); + + CPP11_ASSERT(ym + one_year == 2002_y/feb/last); + NOEXCEPT_ASSERT(ym + one_year); + CPP11_ASSERT(one_year + ym == 2002_y/feb/last); + NOEXCEPT_ASSERT(one_year + ym); + CPP11_ASSERT(ym - one_year == 2000_y/feb/last); + NOEXCEPT_ASSERT(ym - one_year); + CPP14_ASSERT((copy(ym) += one_year) == 2002_y/feb/last); + NOEXCEPT_ASSERT(copy(ym) += one_year); + CPP14_ASSERT((copy(ym) -= one_year) == 2000_y/feb/last); + NOEXCEPT_ASSERT(copy(ym) -= one_year); + + CPP11_ASSERT(ym + one_decade == 2011_y/feb/last); + NOEXCEPT_CONVERSION(ym + one_decade); + CPP11_ASSERT(one_decade + ym == 2011_y/feb/last); + NOEXCEPT_CONVERSION(one_decade + ym); + CPP11_ASSERT(ym - one_decade == 1991_y/feb/last); + NOEXCEPT_CONVERSION(ym - one_decade); + CPP14_ASSERT((copy(ym) += one_decade) == 2011_y/feb/last); + NOEXCEPT_CONVERSION(copy(ym) += one_decade); + CPP14_ASSERT((copy(ym) -= one_decade) == 1991_y/feb/last); + NOEXCEPT_CONVERSION(copy(ym) -= one_decade); + + CPP14_ASSERT(ym + one_decamonth == 2001_y/dec/last); + NOEXCEPT_CONVERSION(ym + one_decamonth); + CPP14_ASSERT(one_decamonth + ym == 2001_y/dec/last); + NOEXCEPT_CONVERSION(one_decamonth + ym); + CPP14_ASSERT(ym - one_decamonth == 2000_y/apr/last); + NOEXCEPT_CONVERSION(ym - one_decamonth); + CPP14_ASSERT((copy(ym) += one_decamonth) == 2001_y/dec/last); + NOEXCEPT_CONVERSION(copy(ym) += one_decamonth); + CPP14_ASSERT((copy(ym) -= one_decamonth) == 2000_y/apr/last); + NOEXCEPT_CONVERSION(copy(ym) -= one_decamonth); + } + + { + constexpr year_month_weekday ym = 2001_y/feb/fri[4]; + CPP14_ASSERT(ym + one_month == 2001_y/mar/fri[4]); + NOEXCEPT_ASSERT(ym + one_month); + CPP14_ASSERT(one_month + ym == 2001_y/mar/fri[4]); + NOEXCEPT_ASSERT(one_month + ym); + CPP14_ASSERT(ym - one_month == 2001_y/jan/fri[4]); + NOEXCEPT_ASSERT(ym - one_month); + CPP14_ASSERT((copy(ym) += one_month) == 2001_y/mar/fri[4]); + NOEXCEPT_ASSERT(copy(ym) += one_month); + CPP14_ASSERT((copy(ym) -= one_month) == 2001_y/jan/fri[4]); + NOEXCEPT_ASSERT(copy(ym) -= one_month); + + CPP11_ASSERT(ym + one_year == 2002_y/feb/fri[4]); + NOEXCEPT_ASSERT(ym + one_year); + CPP11_ASSERT(one_year + ym == 2002_y/feb/fri[4]); + NOEXCEPT_ASSERT(one_year + ym); + CPP11_ASSERT(ym - one_year == 2000_y/feb/fri[4]); + NOEXCEPT_ASSERT(ym - one_year); + CPP14_ASSERT((copy(ym) += one_year) == 2002_y/feb/fri[4]); + NOEXCEPT_ASSERT(copy(ym) += one_year); + CPP14_ASSERT((copy(ym) -= one_year) == 2000_y/feb/fri[4]); + NOEXCEPT_ASSERT(copy(ym) -= one_year); + + CPP11_ASSERT(ym + one_decade == 2011_y/feb/fri[4]); + NOEXCEPT_CONVERSION(ym + one_decade); + CPP11_ASSERT(one_decade + ym == 2011_y/feb/fri[4]); + NOEXCEPT_CONVERSION(one_decade + ym); + CPP11_ASSERT(ym - one_decade == 1991_y/feb/fri[4]); + NOEXCEPT_CONVERSION(ym - one_decade); + CPP14_ASSERT((copy(ym) += one_decade) == 2011_y/feb/fri[4]); + NOEXCEPT_CONVERSION(copy(ym) += one_decade); + CPP14_ASSERT((copy(ym) -= one_decade) == 1991_y/feb/fri[4]); + NOEXCEPT_CONVERSION(copy(ym) -= one_decade); + + CPP14_ASSERT(ym + one_decamonth == 2001_y/dec/fri[4]); + NOEXCEPT_CONVERSION(ym + one_decamonth); + CPP14_ASSERT(one_decamonth + ym == 2001_y/dec/fri[4]); + NOEXCEPT_CONVERSION(one_decamonth + ym); + CPP14_ASSERT(ym - one_decamonth == 2000_y/apr/fri[4]); + NOEXCEPT_CONVERSION(ym - one_decamonth); + CPP14_ASSERT((copy(ym) += one_decamonth) == 2001_y/dec/fri[4]); + NOEXCEPT_CONVERSION(copy(ym) += one_decamonth); + CPP14_ASSERT((copy(ym) -= one_decamonth) == 2000_y/apr/fri[4]); + NOEXCEPT_CONVERSION(copy(ym) -= one_decamonth); + } + + { + constexpr year_month_weekday_last ym = 2001_y/feb/fri[last]; + CPP14_ASSERT(ym + one_month == 2001_y/mar/fri[last]); + NOEXCEPT_ASSERT(ym + one_month); + CPP14_ASSERT(one_month + ym == 2001_y/mar/fri[last]); + NOEXCEPT_ASSERT(one_month + ym); + CPP14_ASSERT(ym - one_month == 2001_y/jan/fri[last]); + NOEXCEPT_ASSERT(ym - one_month); + CPP14_ASSERT((copy(ym) += one_month) == 2001_y/mar/fri[last]); + NOEXCEPT_ASSERT(copy(ym) += one_month); + CPP14_ASSERT((copy(ym) -= one_month) == 2001_y/jan/fri[last]); + NOEXCEPT_ASSERT(copy(ym) -= one_month); + + CPP11_ASSERT(ym + one_year == 2002_y/feb/fri[last]); + NOEXCEPT_ASSERT(ym + one_year); + CPP11_ASSERT(one_year + ym == 2002_y/feb/fri[last]); + NOEXCEPT_ASSERT(one_year + ym); + CPP11_ASSERT(ym - one_year == 2000_y/feb/fri[last]); + NOEXCEPT_ASSERT(ym - one_year); + CPP14_ASSERT((copy(ym) += one_year) == 2002_y/feb/fri[last]); + NOEXCEPT_ASSERT(copy(ym) += one_year); + CPP14_ASSERT((copy(ym) -= one_year) == 2000_y/feb/fri[last]); + NOEXCEPT_ASSERT(copy(ym) -= one_year); + + CPP11_ASSERT(ym + one_decade == 2011_y/feb/fri[last]); + NOEXCEPT_CONVERSION(ym + one_decade); + CPP11_ASSERT(one_decade + ym == 2011_y/feb/fri[last]); + NOEXCEPT_CONVERSION(one_decade + ym); + CPP11_ASSERT(ym - one_decade == 1991_y/feb/fri[last]); + NOEXCEPT_CONVERSION(ym - one_decade); + CPP14_ASSERT((copy(ym) += one_decade) == 2011_y/feb/fri[last]); + NOEXCEPT_CONVERSION(copy(ym) += one_decade); + CPP14_ASSERT((copy(ym) -= one_decade) == 1991_y/feb/fri[last]); + NOEXCEPT_CONVERSION(copy(ym) -= one_decade); + + CPP14_ASSERT(ym + one_decamonth == 2001_y/dec/fri[last]); + NOEXCEPT_CONVERSION(ym + one_decamonth); + CPP14_ASSERT(one_decamonth + ym == 2001_y/dec/fri[last]); + NOEXCEPT_CONVERSION(one_decamonth + ym); + CPP14_ASSERT(ym - one_decamonth == 2000_y/apr/fri[last]); + NOEXCEPT_CONVERSION(ym - one_decamonth); + CPP14_ASSERT((copy(ym) += one_decamonth) == 2001_y/dec/fri[last]); + NOEXCEPT_CONVERSION(copy(ym) += one_decamonth); + CPP14_ASSERT((copy(ym) -= one_decamonth) == 2000_y/apr/fri[last]); + NOEXCEPT_CONVERSION(copy(ym) -= one_decamonth); + } + +}