-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc++][chrono] Fixes year_month year wrapping. #74938
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Adding months to a year_month should wrap the year when the month becomes greater than twelve or less than one. This fixes the issue for year_month. Other classes with a year and month do not have this issue. This has been verified and tests are added to avoid possible regressions. Also fixes some variable copy-paste errors in the tests. Fixes llvm#73162
@llvm/pr-subscribers-libcxx Author: Mark de Wever (mordante) ChangesAdding months to a year_month should wrap the year when the month becomes greater than twelve or less than one. This fixes the issue for year_month. Other classes with a year and month do not have this issue. This has been verified and tests are added to avoid possible regressions. Also fixes some variable copy-paste errors in the tests. Fixes #73162 Patch is 31.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/74938.diff 15 Files Affected:
diff --git a/libcxx/include/__chrono/year_month.h b/libcxx/include/__chrono/year_month.h
index f4eea8427fc51..d1657b61015b9 100644
--- a/libcxx/include/__chrono/year_month.h
+++ b/libcxx/include/__chrono/year_month.h
@@ -36,10 +36,10 @@ class year_month {
: __y_{__yval}, __m_{__mval} {}
_LIBCPP_HIDE_FROM_ABI inline constexpr chrono::year year() const noexcept { return __y_; }
_LIBCPP_HIDE_FROM_ABI inline constexpr chrono::month month() const noexcept { return __m_; }
- _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const months& __dm) noexcept { this->__m_ += __dm; return *this; }
- _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const months& __dm) noexcept { this->__m_ -= __dm; return *this; }
- _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const years& __dy) noexcept { this->__y_ += __dy; return *this; }
- _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const years& __dy) noexcept { this->__y_ -= __dy; return *this; }
+ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const months& __dm) noexcept;
+ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const months& __dm) noexcept;
+ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator+=(const years& __dy) noexcept;
+ _LIBCPP_HIDE_FROM_ABI inline constexpr year_month& operator-=(const years& __dy) noexcept;
_LIBCPP_HIDE_FROM_ABI inline constexpr bool ok() const noexcept { return __y_.ok() && __m_.ok(); }
};
@@ -92,6 +92,26 @@ _LIBCPP_HIDE_FROM_ABI constexpr
year_month operator-(const year_month& __lhs, const years& __rhs) noexcept
{ return __lhs + -__rhs; }
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month& year_month::operator+=(const months& __dm) noexcept {
+ *this = *this + __dm;
+ return *this;
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month& year_month::operator-=(const months& __dm) noexcept {
+ *this = *this - __dm;
+ return *this;
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month& year_month::operator+=(const years& __dy) noexcept {
+ *this = *this + __dy;
+ return *this;
+}
+
+_LIBCPP_HIDE_FROM_ABI inline constexpr year_month& year_month::operator-=(const years& __dy) noexcept {
+ *this = *this - __dy;
+ return *this;
+}
+
} // namespace chrono
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.members/plus_minus_equal_month.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.members/plus_minus_equal_month.pass.cpp
index 6d1273ead7391..cc9fff83a1cff 100644
--- a/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.members/plus_minus_equal_month.pass.cpp
+++ b/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.members/plus_minus_equal_month.pass.cpp
@@ -38,6 +38,16 @@ constexpr bool test() {
assert(ym.year() == y);
}
+ { // Test year wrapping
+ year_month ym{year{2020}, month{4}};
+
+ ym += months{12};
+ assert((ym == year_month{year{2021}, month{4}}));
+
+ ym -= months{12};
+ assert((ym == year_month{year{2020}, month{4}}));
+ }
+
return true;
}
diff --git a/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/minus.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/minus.pass.cpp
index 5bacee9af7f82..977c566e745ac 100644
--- a/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/minus.pass.cpp
+++ b/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/minus.pass.cpp
@@ -46,12 +46,17 @@ constexpr bool test() {
{ // year_month - months
year_month ym{year{1234}, std::chrono::November};
- for (int i = 0; i <= 10; ++i) // TODO test wrap-around
- {
+ for (int i = 0; i <= 10; ++i) {
year_month ym1 = ym - months{i};
assert(static_cast<int>(ym1.year()) == 1234);
assert(ym1.month() == month(11 - i));
}
+ // Test the year wraps around.
+ for (int i = 12; i <= 15; ++i) {
+ year_month ym1 = ym - months{i};
+ assert(static_cast<int>(ym1.year()) == 1233);
+ assert(ym1.month() == month(11 - i + 12));
+ }
}
{ // year_month - year_month
diff --git a/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/plus.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/plus.pass.cpp
index 315d74b75bbcc..60747a29714d1 100644
--- a/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/plus.pass.cpp
+++ b/libcxx/test/std/time/time.cal/time.cal.ym/time.cal.ym.nonmembers/plus.pass.cpp
@@ -29,10 +29,10 @@
#include "test_macros.h"
-using year = std::chrono::year;
-using years = std::chrono::years;
-using month = std::chrono::month;
-using months = std::chrono::months;
+using year = std::chrono::year;
+using years = std::chrono::years;
+using month = std::chrono::month;
+using months = std::chrono::months;
using year_month = std::chrono::year_month;
// year_month + years
@@ -40,10 +40,8 @@ constexpr bool test_ym_plus_y() {
ASSERT_NOEXCEPT(std::declval<year_month>() + std::declval<years>());
ASSERT_NOEXCEPT(std::declval<years>() + std::declval<year_month>());
- ASSERT_SAME_TYPE(
- year_month, decltype(std::declval<year_month>() + std::declval<years>()));
- ASSERT_SAME_TYPE(
- year_month, decltype(std::declval<years>() + std::declval<year_month>()));
+ ASSERT_SAME_TYPE(year_month, decltype(std::declval<year_month>() + std::declval<years>()));
+ ASSERT_SAME_TYPE(year_month, decltype(std::declval<years>() + std::declval<year_month>()));
year_month ym{year{1234}, std::chrono::January};
for (int i = 0; i <= 10; ++i) {
@@ -64,10 +62,17 @@ constexpr bool test_ym_plus_m() {
ASSERT_NOEXCEPT(std::declval<year_month>() + std::declval<months>());
ASSERT_NOEXCEPT(std::declval<months>() + std::declval<year_month>());
- ASSERT_SAME_TYPE(year_month, decltype(std::declval<year_month>() +
- std::declval<months>()));
- ASSERT_SAME_TYPE(year_month, decltype(std::declval<months>() +
- std::declval<year_month>()));
+ ASSERT_SAME_TYPE(year_month, decltype(std::declval<year_month>() + std::declval<months>()));
+ ASSERT_SAME_TYPE(year_month, decltype(std::declval<months>() + std::declval<year_month>()));
+
+ {
+ // [time.cal.ym.nonmembers]/4
+ // Returns: A year_month value z such that z.ok() && z - ym == dm is true.
+ year_month ym = {year{1234}, std::chrono::January};
+ months dm = months{42};
+ year_month z = ym + dm;
+ assert(z.ok() && z - ym == dm);
+ }
year_month ym{year{1234}, std::chrono::January};
for (int i = 0; i <= 11; ++i) {
@@ -89,7 +94,6 @@ constexpr bool test_ym_plus_m() {
assert(ym2.month() == month(1 + i % 12));
assert(ym1 == ym2);
}
-
return true;
}
diff --git a/libcxx/test/std/time/time.cal/time.cal.ymd/time.cal.ymd.members/plus_minus_equal_month.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.ymd/time.cal.ymd.members/plus_minus_equal_month.pass.cpp
index f656d8f6cc056..40db399b110b8 100644
--- a/libcxx/test/std/time/time.cal/time.cal.ymd/time.cal.ymd.members/plus_minus_equal_month.pass.cpp
+++ b/libcxx/test/std/time/time.cal/time.cal.ymd/time.cal.ymd.members/plus_minus_equal_month.pass.cpp
@@ -42,6 +42,40 @@ constexpr bool test() {
assert(static_cast<unsigned>((ymd).month()) == i + 1);
}
+ { // Validate the ok status when the day is not present in the new month.
+ year_month_day ymd{year{2020}, month{3}, day{31}};
+ ymd += months{1};
+ assert((ymd == year_month_day{year{2020}, month{4}, day{31}}));
+ assert(!ymd.ok());
+
+ ymd -= months{1};
+ assert((ymd == year_month_day{year{2020}, month{3}, day{31}}));
+ assert(ymd.ok());
+ }
+
+ { // Validate the ok status when the day becomes present in the new month.
+ year_month_day ymd{year{2020}, month{4}, day{31}};
+ assert(!ymd.ok());
+
+ ymd += months{1};
+ assert((ymd == year_month_day{year{2020}, month{5}, day{31}}));
+ assert(ymd.ok());
+
+ ymd -= months{2};
+ assert((ymd == year_month_day{year{2020}, month{3}, day{31}}));
+ assert(ymd.ok());
+ }
+
+ { // Test year wrapping
+ year_month_day ymd{year{2020}, month{4}, day{31}};
+
+ ymd += months{12};
+ assert((ymd == year_month_day{year{2021}, month{4}, day{31}}));
+
+ ymd -= months{12};
+ assert((ymd == year_month_day{year{2020}, month{4}, day{31}}));
+ }
+
return true;
}
diff --git a/libcxx/test/std/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/plus.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/plus.pass.cpp
index 27626e40fceb7..b172cb1384570 100644
--- a/libcxx/test/std/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/plus.pass.cpp
+++ b/libcxx/test/std/time/time.cal/time.cal.ymd/time.cal.ymd.nonmembers/plus.pass.cpp
@@ -39,32 +39,43 @@ using year_month_day = std::chrono::year_month_day;
constexpr bool test() {
{ // year_month_day + months
year_month_day ym{year{1234}, std::chrono::January, day{12}};
- for (int i = 0; i <= 10; ++i) // TODO test wrap-around
- {
- year_month_day ym1 = ym + months{i};
- year_month_day ym2 = months{i} + ym;
- assert(static_cast<int>(ym1.year()) == 1234);
- assert(static_cast<int>(ym2.year()) == 1234);
- assert(ym1.month() == month(1 + i));
- assert(ym2.month() == month(1 + i));
- assert(ym1.day() == day{12});
- assert(ym2.day() == day{12});
- assert(ym1 == ym2);
+ for (int i = 0; i <= 10; ++i) {
+ year_month_day ymd1 = ym + months{i};
+ year_month_day ymd2 = months{i} + ym;
+ assert(static_cast<int>(ymd1.year()) == 1234);
+ assert(static_cast<int>(ymd2.year()) == 1234);
+ assert(ymd1.month() == month(1 + i));
+ assert(ymd2.month() == month(1 + i));
+ assert(ymd1.day() == day{12});
+ assert(ymd2.day() == day{12});
+ assert(ymd1 == ymd2);
+ }
+ // Test the year wraps around.
+ for (int i = 12; i <= 15; ++i) {
+ year_month_day ymd1 = ym + months{i};
+ year_month_day ymd2 = months{i} + ym;
+ assert(static_cast<int>(ymd1.year()) == 1235);
+ assert(static_cast<int>(ymd2.year()) == 1235);
+ assert(ymd1.month() == month(1 + i - 12));
+ assert(ymd2.month() == month(1 + i - 12));
+ assert(ymd1.day() == day{12});
+ assert(ymd2.day() == day{12});
+ assert(ymd1 == ymd2);
}
}
{ // year_month_day + years
year_month_day ym{year{1234}, std::chrono::January, day{12}};
for (int i = 0; i <= 10; ++i) {
- year_month_day ym1 = ym + years{i};
- year_month_day ym2 = years{i} + ym;
- assert(static_cast<int>(ym1.year()) == i + 1234);
- assert(static_cast<int>(ym2.year()) == i + 1234);
- assert(ym1.month() == std::chrono::January);
- assert(ym2.month() == std::chrono::January);
- assert(ym1.day() == day{12});
- assert(ym2.day() == day{12});
- assert(ym1 == ym2);
+ year_month_day ymd1 = ym + years{i};
+ year_month_day ymd2 = years{i} + ym;
+ assert(static_cast<int>(ymd1.year()) == i + 1234);
+ assert(static_cast<int>(ymd2.year()) == i + 1234);
+ assert(ymd1.month() == std::chrono::January);
+ assert(ymd2.month() == std::chrono::January);
+ assert(ymd1.day() == day{12});
+ assert(ymd2.day() == day{12});
+ assert(ymd1 == ymd2);
}
}
diff --git a/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/plus_minus_equal_month.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/plus_minus_equal_month.pass.cpp
index dfa0f002bfb92..1c08479596016 100644
--- a/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/plus_minus_equal_month.pass.cpp
+++ b/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.members/plus_minus_equal_month.pass.cpp
@@ -29,15 +29,25 @@ constexpr bool test() {
for (unsigned i = 0; i <= 10; ++i) {
year y{1234};
month_day_last mdl{month{i}};
- year_month_day_last ym(y, mdl);
- assert(static_cast<unsigned>((ym += months{2}).month()) == i + 2);
- assert(ym.year() == y);
- assert(static_cast<unsigned>((ym).month()) == i + 2);
- assert(ym.year() == y);
- assert(static_cast<unsigned>((ym -= months{1}).month()) == i + 1);
- assert(ym.year() == y);
- assert(static_cast<unsigned>((ym).month()) == i + 1);
- assert(ym.year() == y);
+ year_month_day_last ymdl(y, mdl);
+ assert(static_cast<unsigned>((ymdl += months{2}).month()) == i + 2);
+ assert(ymdl.year() == y);
+ assert(static_cast<unsigned>((ymdl).month()) == i + 2);
+ assert(ymdl.year() == y);
+ assert(static_cast<unsigned>((ymdl -= months{1}).month()) == i + 1);
+ assert(ymdl.year() == y);
+ assert(static_cast<unsigned>((ymdl).month()) == i + 1);
+ assert(ymdl.year() == y);
+ }
+
+ { // Test year wrapping
+ year_month_day_last ymdl{year{2020}, month_day_last{month{4}}};
+
+ ymdl += months{12};
+ assert((ymdl == year_month_day_last{year{2021}, month_day_last{month{4}}}));
+
+ ymdl -= months{12};
+ assert((ymdl == year_month_day_last{year{2020}, month_day_last{month{4}}}));
}
return true;
diff --git a/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/minus.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/minus.pass.cpp
index 009790a450e9d..22d1acfbe2827 100644
--- a/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/minus.pass.cpp
+++ b/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/minus.pass.cpp
@@ -38,22 +38,27 @@ constexpr bool test() {
{ // year_month_day_last - years
- year_month_day_last ym{year{1234}, month_day_last{December}};
+ year_month_day_last ymdl{year{1234}, month_day_last{December}};
for (int i = 0; i <= 10; ++i) {
- year_month_day_last ym1 = ym - years{i};
- assert(static_cast<int>(ym1.year()) == 1234 - i);
- assert(ym1.month() == December);
+ year_month_day_last ymdl1 = ymdl - years{i};
+ assert(static_cast<int>(ymdl1.year()) == 1234 - i);
+ assert(ymdl1.month() == December);
}
}
{ // year_month_day_last - months
- // TODO test wrapping
- year_month_day_last ym{year{1234}, month_day_last{December}};
+ year_month_day_last ymdl{year{1234}, month_day_last{December}};
for (unsigned i = 0; i <= 10; ++i) {
- year_month_day_last ym1 = ym - months{i};
- assert(static_cast<int>(ym1.year()) == 1234);
- assert(static_cast<unsigned>(ym1.month()) == 12U - i);
+ year_month_day_last ymdl1 = ymdl - months{i};
+ assert(static_cast<int>(ymdl1.year()) == 1234);
+ assert(static_cast<unsigned>(ymdl1.month()) == 12U - i);
+ }
+ // Test the year wraps around.
+ for (unsigned i = 12; i <= 15; ++i) {
+ year_month_day_last ymdl1 = ymdl - months{i};
+ assert(static_cast<int>(ymdl1.year()) == 1233);
+ assert(static_cast<unsigned>(ymdl1.month()) == 12U - i + 12);
}
}
diff --git a/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/plus.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/plus.pass.cpp
index 4cbc3d1a1994e..1a4609e761baa 100644
--- a/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/plus.pass.cpp
+++ b/libcxx/test/std/time/time.cal/time.cal.ymdlast/time.cal.ymdlast.nonmembers/plus.pass.cpp
@@ -49,29 +49,37 @@ constexpr bool test() {
{ // year_month_day_last + months
year_month_day_last ym{year{1234}, month_day_last{January}};
- for (int i = 0; i <= 10; ++i) // TODO test wrap-around
- {
- year_month_day_last ym1 = ym + months{i};
- year_month_day_last ym2 = months{i} + ym;
- assert(static_cast<int>(ym1.year()) == 1234);
- assert(static_cast<int>(ym2.year()) == 1234);
- assert(ym1.month() == month(1 + i));
- assert(ym2.month() == month(1 + i));
- assert(ym1 == ym2);
+ for (int i = 0; i <= 10; ++i) {
+ year_month_day_last ymdl1 = ym + months{i};
+ year_month_day_last ymdl2 = months{i} + ym;
+ assert(static_cast<int>(ymdl1.year()) == 1234);
+ assert(static_cast<int>(ymdl2.year()) == 1234);
+ assert(ymdl1.month() == month(1 + i));
+ assert(ymdl2.month() == month(1 + i));
+ assert(ymdl1 == ymdl2);
+ }
+ // Test the year wraps around.
+ for (int i = 12; i <= 15; ++i) {
+ year_month_day_last ymdl1 = ym + months{i};
+ year_month_day_last ymdl2 = months{i} + ym;
+ assert(static_cast<int>(ymdl1.year()) == 1235);
+ assert(static_cast<int>(ymdl2.year()) == 1235);
+ assert(ymdl1.month() == month(1 + i - 12));
+ assert(ymdl2.month() == month(1 + i - 12));
+ assert(ymdl1 == ymdl2);
}
}
{ // year_month_day_last + years
-
year_month_day_last ym{year{1234}, month_day_last{January}};
for (int i = 0; i <= 10; ++i) {
- year_month_day_last ym1 = ym + years{i};
- year_month_day_last ym2 = years{i} + ym;
- assert(static_cast<int>(ym1.year()) == i + 1234);
- assert(static_cast<int>(ym2.year()) == i + 1234);
- assert(ym1.month() == std::chrono::January);
- assert(ym2.month() == std::chrono::January);
- assert(ym1 == ym2);
+ year_month_day_last ymdl1 = ym + years{i};
+ year_month_day_last ymdl2 = years{i} + ym;
+ assert(static_cast<int>(ymdl1.year()) == i + 1234);
+ assert(static_cast<int>(ymdl2.year()) == i + 1234);
+ assert(ymdl1.month() == std::chrono::January);
+ assert(ymdl2.month() == std::chrono::January);
+ assert(ymdl1 == ymdl2);
}
}
diff --git a/libcxx/test/std/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/plus_minus_equal_month.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/plus_minus_equal_month.pass.cpp
index 8b49540be3fa2..6aaab2dbfb31d 100644
--- a/libcxx/test/std/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/plus_minus_equal_month.pass.cpp
+++ b/libcxx/test/std/time/time.cal/time.cal.ymwd/time.cal.ymwd.members/plus_minus_equal_month.pass.cpp
@@ -54,6 +54,16 @@ constexpr bool test() {
assert(ymwd.index() == 2);
}
+ { // Test year wrapping
+ year_month_weekday ymwd{year{2020}, month{4}, weekday_indexed{Tuesday, 2}};
+
+ ymwd += months{12};
+ assert((ymwd == year_month_weekday{year{2021}, month{4}, weekday_indexed{Tuesday, 2}}));
+
+ ymwd -= months{12};
+ assert((ymwd == year_month_weekday{year{2020}, month{4}, weekday_indexed{Tuesday, 2}}));
+ }
+
return true;
}
diff --git a/libcxx/test/std/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/minus.pass.cpp b/libcxx/test/std/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/minus.pass.cpp
index 2ab3462d7f7d1..5546d34ca22dd 100644
--- a/libcxx/test/std/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/minus.pass.cpp
+++ b/libcxx/test/std/time/time.cal/time.cal.ymwd/time.cal.ymwd.nonmembers/minus.pass.cpp
@@ -35,24 +35,32 @@ constexpr bool test() {
constexpr weekday Tuesday = std::chrono::Tuesday;
{ // year_month_weekday - years
- year_month_weekday ym{year{1234}, November, weekday_indexed{Tuesday, 1}};
+ year_month_weekday ymwd{year{1234}, November, weekday_indexed{Tuesday, 1}};
for (int i = 0; i <= 10; ++i) {
- year_month_weekday ym1 = ym - years{i};
- assert(static_cast<int>(ym1.year()) == 1234 - i);
- assert(ym1.month() == November);
- assert(ym1.weekday() == Tuesday);
- assert(ym1.index() == 1);
+ year_month_weekday ymwd1 = ymwd - years{i};
+ assert(static_cast<int>(ymwd1.year()) == 1234 - i);
+ assert(ymwd1.month() == November);
+ assert(ymwd1.weekday() == Tuesday);
+ assert(ymwd1.index() == 1);
}
}
{ // year_month_weekday - months
- year_month_weekday ym{year{1234}, November, weekday_indexed{Tuesday, 2}};
+ year_month_weekday ymwd{year{1234}, November, weekday_indexed{Tuesday, 2}};
for (unsigned i = 1; i <= 10; ++i) {
- year_month_weekday ym1 = ym - months{i};
- assert(ym1.year() == year{1234});
- assert(ym1.month() == month{11 - i});
- assert(ym1.weekday() == Tuesday);
- assert(ym1.index() == 2);
+ year_month_weekday ymwd1 = ymwd - months{i};
+ assert(ymwd1.year() == year{1234});
+ assert(ymwd1.month() == month{11 - i});
+ assert(ymwd1.weekday() == Tuesday);
+ assert(ymwd1.index(...
[truncated]
|
Adding months to a year_month should wrap the year when the month becomes greater than twelve or less than one.
This fixes the issue for year_month. Other classes with a year and month do not have this issue. This has been verified and tests are added to avoid possible regressions.
Also fixes some variable copy-paste errors in the tests.
Fixes #73162