Fix year_month arithmetic and correct chrono API behavior (#1257)

* Fix & add more tests for year_month arithmetic

* Minor addtions to previous commit

* More missing values to be uninitialized

* Update the default constructors to = default and correct default constructor tests accordingly

* Fix & add more tests for year_month arithmetic

* Minor addtions to previous commit

* More missing values to be uninitialized

* Update the default constructors to = default and correct default constructor tests accordingly

* Restore default constructor behavior for chrono calender
This commit is contained in:
Bo Rydberg 2026-01-16 09:02:46 +01:00 committed by GitHub
parent e9c2577d8e
commit 0644f9827b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 148 additions and 220 deletions

View File

@ -57,39 +57,10 @@ namespace etl
/// Construct from unsigned
//***********************************************************************
ETL_CONSTEXPR explicit day(unsigned value_) ETL_NOEXCEPT
: value(static_cast<unsigned char>(value_))
: value(static_cast<rep>(value_))
{
}
//***********************************************************************
/// Copy constructor
//***********************************************************************
ETL_CONSTEXPR14 day(const etl::chrono::day& other) ETL_NOEXCEPT
: value(other.value)
{
}
//***********************************************************************
/// Assignment operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::day& operator =(const etl::chrono::day& rhs) ETL_NOEXCEPT
{
value = rhs.value;
return *this;
}
//***********************************************************************
/// Assignment operator
//***********************************************************************
template <typename TToDuration, typename TValue2, typename TPeriod2>
ETL_CONSTEXPR14 etl::chrono::day& operator =(const etl::chrono::duration<TValue2, TPeriod2>& rhs)
{
value = etl::chrono::duration_cast<TToDuration, TValue2, TPeriod2>(rhs);
return *this;
}
//***********************************************************************
/// Pre-increment operator
//***********************************************************************
@ -105,7 +76,7 @@ namespace etl
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::day operator ++(int) ETL_NOEXCEPT
{
const etl::chrono::day temp = *this;
etl::chrono::day temp = *this;
++value;
return temp;
@ -126,7 +97,7 @@ namespace etl
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::day operator --(int) ETL_NOEXCEPT
{
const etl::chrono::day temp = *this;
etl::chrono::day temp = *this;
--value;
return temp;
@ -137,7 +108,7 @@ namespace etl
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::day& operator +=(const etl::chrono::days& ds) ETL_NOEXCEPT
{
value += static_cast<unsigned char>(ds.count());
value += static_cast<rep>(ds.count());
return *this;
}
@ -147,7 +118,7 @@ namespace etl
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::day& operator -=(const etl::chrono::days& ds) ETL_NOEXCEPT
{
value -= static_cast<unsigned char>(ds.count());
value -= static_cast<rep>(ds.count());
return *this;
}
@ -164,9 +135,9 @@ namespace etl
//***********************************************************************
/// Conversion operator to unsigned int
//***********************************************************************
ETL_CONSTEXPR14 operator unsigned() const ETL_NOEXCEPT
ETL_CONSTEXPR14 /*explicit*/ operator unsigned() const ETL_NOEXCEPT
{
return static_cast<unsigned>(value);
return value;
}
//***********************************************************************
@ -184,24 +155,6 @@ namespace etl
return 0;
}
//***********************************************************************
/// The minimum day value for which ok() will return <b>true</b>
//***********************************************************************
ETL_NODISCARD
static ETL_CONSTEXPR14 etl::chrono::day min() ETL_NOEXCEPT
{
return etl::chrono::day(1);
}
//***********************************************************************
/// The maximum day value for which ok() will return <b>true</b>
//***********************************************************************
ETL_NODISCARD
static ETL_CONSTEXPR14 etl::chrono::day max() ETL_NOEXCEPT
{
return etl::chrono::day(31);
}
private:
rep value;

View File

@ -72,24 +72,6 @@ namespace etl
{
}
//***********************************************************************
/// Copy constructor
//***********************************************************************
ETL_CONSTEXPR14 month(const etl::chrono::month& other) ETL_NOEXCEPT
: value(other.value)
{
}
//***********************************************************************
/// Assignment operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::month& operator =(const etl::chrono::month& rhs) ETL_NOEXCEPT
{
value = rhs.value;
return *this;
}
//***********************************************************************
/// Pre-increment operator
//***********************************************************************
@ -105,9 +87,9 @@ namespace etl
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::month operator ++(int) ETL_NOEXCEPT
{
const etl::chrono::month temp = *this;
etl::chrono::month temp = *this;
*this += etl::chrono::months(1);
++*this;
return temp;
}
@ -129,7 +111,7 @@ namespace etl
{
etl::chrono::month temp = *this;
*this -= etl::chrono::months(1);
--*this;
return temp;
}
@ -155,7 +137,7 @@ namespace etl
}
//***********************************************************************
/// Returns <b>true</b> if the month is within the valid 1 to 31 range
/// Returns <b>true</b> if the month is within the valid 1 to 12 range
//***********************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14 bool ok() const ETL_NOEXCEPT
@ -178,30 +160,12 @@ namespace etl
return 0;
}
//***********************************************************************
/// The minimum month value for which ok() will return <b>true</b>
//***********************************************************************
ETL_NODISCARD
static ETL_CONSTEXPR14 etl::chrono::month min() ETL_NOEXCEPT
{
return etl::chrono::month(1);
}
//***********************************************************************
/// The maximum month value for which ok() will return <b>true</b>
//***********************************************************************
ETL_NODISCARD
static ETL_CONSTEXPR14 etl::chrono::month max() ETL_NOEXCEPT
{
return etl::chrono::month(12);
}
//***********************************************************************
/// Conversion operator to unsigned int
//***********************************************************************
ETL_CONSTEXPR14 operator unsigned() const ETL_NOEXCEPT
ETL_CONSTEXPR14 /*explicit*/ operator unsigned() const ETL_NOEXCEPT
{
return static_cast<unsigned>(value);
return value;
}
private:
@ -331,10 +295,8 @@ namespace etl
etl::chrono::months ms(difference);
// Check for validity.
if (m1 == (m2 + ms))
{
return ms;
}
assert(m1 == (m2 + ms));
return ms;
}
return etl::chrono::months();

View File

@ -362,26 +362,6 @@ namespace etl
{
}
//***********************************************************************
/// Copy constructor
//***********************************************************************
ETL_CONSTEXPR14 weekday_indexed(const etl::chrono::weekday_indexed& other) ETL_NOEXCEPT
: wd(other.wd)
, i(other.i)
{
}
//***********************************************************************
/// Assignment operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::weekday_indexed& operator =(const etl::chrono::weekday_indexed& rhs) ETL_NOEXCEPT
{
wd = rhs.wd;
i = rhs.i;
return *this;
}
//***********************************************************************
/// Get weekday
//***********************************************************************

View File

@ -54,31 +54,13 @@ namespace etl
}
//***********************************************************************
/// Construct from unsigned
/// Construct from int
//***********************************************************************
ETL_CONSTEXPR explicit year(unsigned value_) ETL_NOEXCEPT
ETL_CONSTEXPR explicit year(int value_) ETL_NOEXCEPT
: value(value_)
{
}
//***********************************************************************
/// Copy constructor
//***********************************************************************
ETL_CONSTEXPR14 year(const etl::chrono::year& other) ETL_NOEXCEPT
: value(other.value)
{
}
//***********************************************************************
/// Assignment operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::year& operator =(const etl::chrono::year& rhs) ETL_NOEXCEPT
{
value = rhs.value;
return *this;
}
//***********************************************************************
/// Pre-increment operator
//***********************************************************************
@ -94,7 +76,7 @@ namespace etl
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::year operator ++(int) ETL_NOEXCEPT
{
const etl::chrono::year temp = *this;
etl::chrono::year temp = *this;
++value;
return temp;
@ -115,7 +97,7 @@ namespace etl
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::year operator --(int) ETL_NOEXCEPT
{
const etl::chrono::year temp = *this;
etl::chrono::year temp = *this;
--value;
return temp;
@ -126,7 +108,7 @@ namespace etl
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::year& operator +=(const etl::chrono::years& ys) ETL_NOEXCEPT
{
value += static_cast<unsigned char>(ys.count());
value += ys.count();
return *this;
}
@ -136,7 +118,7 @@ namespace etl
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::year& operator -=(const etl::chrono::years& ys) ETL_NOEXCEPT
{
value -= static_cast<unsigned char>(ys.count());
value -= ys.count();
return *this;
}
@ -182,9 +164,9 @@ namespace etl
//***********************************************************************
/// Conversion operator to unsigned int
//***********************************************************************
ETL_CONSTEXPR14 operator int() const ETL_NOEXCEPT
ETL_CONSTEXPR14 /*explicit*/ operator int() const ETL_NOEXCEPT
{
return static_cast<int>(value);
return value;
}
//***********************************************************************
@ -212,7 +194,7 @@ namespace etl
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator ==(const etl::chrono::year& y1, const etl::chrono::year& y2) ETL_NOEXCEPT
{
return (static_cast<unsigned>(y1) == static_cast<unsigned>(y2));
return (static_cast<int>(y1) == static_cast<int>(y2));
}
//***********************************************************************
@ -228,7 +210,7 @@ namespace etl
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator <(const etl::chrono::year& y1, const etl::chrono::year& y2) ETL_NOEXCEPT
{
return (static_cast<unsigned>(y1) < static_cast<unsigned>(y2));
return (static_cast<int>(y1) < static_cast<int>(y2));
}
//***********************************************************************
@ -236,7 +218,7 @@ namespace etl
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator <=(const etl::chrono::year& y1, const etl::chrono::year& y2) ETL_NOEXCEPT
{
return (static_cast<unsigned>(y1) <= static_cast<unsigned>(y2));
return (static_cast<int>(y1) <= static_cast<int>(y2));
}
//***********************************************************************
@ -244,7 +226,7 @@ namespace etl
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator >(const etl::chrono::year& y1, const etl::chrono::year& y2) ETL_NOEXCEPT
{
return (static_cast<unsigned>(y1) > static_cast<unsigned>(y2));
return (static_cast<int>(y1) > static_cast<int>(y2));
}
//***********************************************************************
@ -252,7 +234,7 @@ namespace etl
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator >=(const etl::chrono::year& y1, const etl::chrono::year& y2) ETL_NOEXCEPT
{
return (static_cast<unsigned>(y1) >= static_cast<unsigned>(y2));
return (static_cast<int>(y1) >= static_cast<int>(y2));
}
//***********************************************************************
@ -261,7 +243,7 @@ namespace etl
#if ETL_USING_CPP20
[[nodiscard]] inline constexpr auto operator <=>(const etl::chrono::year& y1, const etl::chrono::year& y2) ETL_NOEXCEPT
{
return (static_cast<unsigned>(y1) <=> static_cast<unsigned>(y2));
return (static_cast<int>(y1) <=> static_cast<int>(y2));
}
#endif
@ -304,27 +286,13 @@ namespace etl
return result;
}
//***********************************************************************
/// Subtract etl::chrono::year from etl::chrono::years
///\return etl::chrono::years
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::year operator -(const etl::chrono::years& ys, const etl::chrono::year& y) ETL_NOEXCEPT
{
etl::chrono::year result(y);
result -= ys;
return result;
}
//***********************************************************************
/// Subtract etl::chrono::year from etl::chrono::year
///\return etl::chrono::years
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::years operator -(const etl::chrono::year& y1, const etl::chrono::year& y2) ETL_NOEXCEPT
{
return etl::chrono::years(static_cast<int>(static_cast<unsigned>(y1)) -
static_cast<int>(static_cast<unsigned>(y2)));
return etl::chrono::years(static_cast<int>(y1) - static_cast<int>(y2));
}
}
@ -337,7 +305,7 @@ namespace etl
{
size_t operator()(const etl::chrono::year& y) const
{
etl::chrono::year::rep value = static_cast<etl::chrono::year::rep>(static_cast<unsigned>(y));
etl::chrono::year::rep value = static_cast<etl::chrono::year::rep>(static_cast<int>(y));
const uint8_t* p = reinterpret_cast<const uint8_t*>(&value);
return etl::private_hash::generic_hash<size_t>(p, p + sizeof(value));
@ -362,7 +330,7 @@ namespace etl
inline ETL_CONSTEXPR14 etl::chrono::year operator ""_y(unsigned long long y) ETL_NOEXCEPT
#endif
{
return etl::chrono::year(static_cast<int16_t>(y));
return etl::chrono::year(static_cast<int>(y));
}
}
}

View File

@ -135,7 +135,12 @@ namespace etl
inline ETL_CONSTEXPR14 etl::chrono::year_month operator +(const etl::chrono::year_month& ym,
const etl::chrono::months& dm) ETL_NOEXCEPT
{
return etl::chrono::year_month(ym.year(), ym.month() + dm);
int dmonths = static_cast<int>(static_cast<unsigned>(ym.month())) - 1 + dm.count();
int dyears = (dmonths - 11 * (dmonths < 0)) / 12;
dmonths -= dyears * 12;
++dmonths;
return etl::chrono::year_month((ym.year() + etl::chrono::years(dyears)),
etl::chrono::month(static_cast<unsigned>(dmonths)));
}
//*************************************************************************
@ -144,7 +149,7 @@ namespace etl
inline ETL_CONSTEXPR14 etl::chrono::year_month operator +(const etl::chrono::months& dm,
const etl::chrono::year_month& ym) ETL_NOEXCEPT
{
return etl::chrono::year_month(ym.year(), ym.month() + dm);
return ym + dm;
}
//*************************************************************************
@ -162,7 +167,7 @@ namespace etl
inline ETL_CONSTEXPR14 etl::chrono::year_month operator -(const etl::chrono::year_month& ym,
const etl::chrono::months& dm) ETL_NOEXCEPT
{
return etl::chrono::year_month(ym.year(), ym.month() - dm);
return ym + -dm;
}
//*************************************************************************
@ -171,7 +176,8 @@ namespace etl
inline ETL_CONSTEXPR14 etl::chrono::months operator -(const etl::chrono::year_month& ym1,
const etl::chrono::year_month& ym2) ETL_NOEXCEPT
{
return etl::chrono::months(static_cast<int>(((int(ym1.year()) - int(ym2.year())) * 12) + (unsigned(ym1.month()) - unsigned(ym2.month()))));
return etl::chrono::months((ym1.year() - ym2.year()) + etl::chrono::months(
static_cast<int>(static_cast<unsigned>(ym1.month())) - static_cast<int>(static_cast<unsigned>(ym2.month()))));
}
//*************************************************************************
@ -273,7 +279,7 @@ namespace etl
{
size_t operator()(const etl::chrono::year_month& ym) const
{
etl::chrono::year::rep y = static_cast<etl::chrono::year::rep>(static_cast<unsigned>(ym.year()));
etl::chrono::year::rep y = static_cast<etl::chrono::year::rep>(static_cast<int>(ym.year()));
etl::chrono::month::rep m = static_cast<etl::chrono::month::rep>(static_cast<unsigned>(ym.month()));
uint8_t buffer[sizeof(y) + sizeof(m)];

View File

@ -76,6 +76,9 @@ namespace etl
/// Construct from sys_days.
//*************************************************************************
ETL_CONSTEXPR14 year_month_day(const etl::chrono::sys_days& sd) ETL_NOEXCEPT
: y(0)
, m(0U)
, d(0U)
{
// Days since 1970-01-01
int days_since_epoch = static_cast<int>(sd.time_since_epoch().count());
@ -101,7 +104,7 @@ namespace etl
// Find the month
while (true)
{
unsigned char days_in_month = etl::chrono::private_chrono::days_in_month[current_month];
unsigned char days_in_month = etl::chrono::private_chrono::days_in_month[static_cast<unsigned>(current_month)];
if (current_month == etl::chrono::February && current_year.is_leap())
{
++days_in_month;
@ -126,6 +129,9 @@ namespace etl
/// Construct from local_days.
//*************************************************************************
ETL_CONSTEXPR14 year_month_day(const etl::chrono::local_days& ld) ETL_NOEXCEPT
: y(0)
, m(0)
, d(0)
{
etl::chrono::year_month_day ymd = sys_days(ld.time_since_epoch());
@ -254,7 +260,7 @@ namespace etl
// Add days for months in the current year
for (etl::chrono::month mth(1); mth < this->month(); ++mth)
{
day_count += private_chrono::days_in_month[mth];
day_count += private_chrono::days_in_month[static_cast<unsigned>(mth)];
if (mth == etl::chrono::February && this->year().is_leap())
{
@ -289,7 +295,7 @@ namespace etl
if (y.ok() && m.ok())
{
count = private_chrono::days_in_month[m];
count = private_chrono::days_in_month[static_cast<unsigned>(m)];
if (y.is_leap() && (m == February))
{
@ -507,9 +513,9 @@ namespace etl
ETL_NODISCARD
ETL_CONSTEXPR14 etl::chrono::day day() const ETL_NOEXCEPT
{
etl::chrono::day d = etl::chrono::day(etl::chrono::private_chrono::days_in_month[m]);
etl::chrono::day d = etl::chrono::day(etl::chrono::private_chrono::days_in_month[static_cast<unsigned>(m)]);
return (d == 28) && y.is_leap() ? etl::chrono::day(29) : d;
return (d == etl::chrono::day(28)) && y.is_leap() ? etl::chrono::day(29) : d;
}
//*************************************************************************
@ -788,7 +794,7 @@ namespace etl
{
size_t operator()(const etl::chrono::year_month_day& ymd) const
{
etl::chrono::year::rep y = static_cast<etl::chrono::year::rep>(static_cast<unsigned>(ymd.year()));
etl::chrono::year::rep y = static_cast<etl::chrono::year::rep>(static_cast<int>(ymd.year()));
etl::chrono::month::rep m = static_cast<etl::chrono::month::rep>(static_cast<unsigned>(ymd.month()));
etl::chrono::day::rep d = static_cast<etl::chrono::day::rep>(static_cast<unsigned>(ymd.day()));
@ -812,7 +818,7 @@ namespace etl
{
size_t operator()(const etl::chrono::year_month_day_last& ymdl) const
{
etl::chrono::year::rep y = static_cast<etl::chrono::year::rep>(static_cast<unsigned>(ymdl.year()));
etl::chrono::year::rep y = static_cast<etl::chrono::year::rep>(static_cast<int>(ymdl.year()));
etl::chrono::month::rep m = static_cast<etl::chrono::month::rep>(static_cast<unsigned>(ymdl.month()));
etl::chrono::day::rep d = static_cast<etl::chrono::day::rep>(static_cast<unsigned>(ymdl.day()));

View File

@ -69,6 +69,9 @@ namespace etl
/// Construct from sys_days.
//*************************************************************************
ETL_CONSTEXPR14 year_month_weekday(const etl::chrono::sys_days& sd) ETL_NOEXCEPT
: y(0)
, m(0U)
, wdi(etl::chrono::weekday(0), 0U)
{
// Extract year, month, and day
year_month_day ymd = year_month_day{sd};
@ -84,7 +87,7 @@ namespace etl
// We walk backward from the given day in steps of 7 days
unsigned index = 1;
for (int offset = static_cast<int>(dy) - 7; offset > 0; offset -= 7)
for (int offset = static_cast<int>(static_cast<unsigned>(dy)) - 7; offset > 0; offset -= 7)
{
++index;
}
@ -98,6 +101,9 @@ namespace etl
/// Construct from local_days.
//*************************************************************************
ETL_CONSTEXPR14 year_month_weekday(const etl::chrono::local_days& ld) ETL_NOEXCEPT
: y(0)
, m(0U)
, wdi(etl::chrono::weekday(0), 0U)
{
year_month_weekday ymwd(sys_days(ld.time_since_epoch()));
@ -506,7 +512,7 @@ namespace etl
{
size_t operator()(const etl::chrono::year_month_weekday& ymwd) const
{
etl::chrono::year::rep y = static_cast<etl::chrono::year::rep>(static_cast<unsigned>(ymwd.year()));
etl::chrono::year::rep y = static_cast<etl::chrono::year::rep>(static_cast<int>(ymwd.year()));
etl::chrono::month::rep m = static_cast<etl::chrono::month::rep>(static_cast<unsigned>(ymwd.month()));
unsigned int wd = ymwd.weekday().c_encoding();
@ -530,7 +536,7 @@ namespace etl
{
size_t operator()(const etl::chrono::year_month_weekday_last& ymwdl) const
{
etl::chrono::year::rep y = static_cast<etl::chrono::year::rep>(static_cast<unsigned>(ymwdl.year()));
etl::chrono::year::rep y = static_cast<etl::chrono::year::rep>(static_cast<int>(ymwdl.year()));
etl::chrono::month::rep m = static_cast<etl::chrono::month::rep>(static_cast<unsigned>(ymwdl.month()));
unsigned int wd = ymwdl.weekday().c_encoding();

View File

@ -240,15 +240,6 @@ namespace
}
}
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_min_max_day)
{
CHECK_EQUAL(1U, Chrono::day::min());
CHECK_EQUAL(31U, Chrono::day::max());
}
#endif
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_literal_day)

View File

@ -269,15 +269,6 @@ namespace
}
}
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_min_max_month)
{
CHECK_EQUAL(1U, Chrono::month::min());
CHECK_EQUAL(12U, Chrono::month::max());
}
#endif
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_month_compare)

View File

@ -59,7 +59,6 @@ namespace
//*************************************************************************
TEST(test_constructor_in_range)
{
for (unsigned i = 1U; i < 5U; ++i)
{
Chrono::weekday_last weekday_last_monday(Chrono::Monday);
Chrono::weekday_last weekday_last_tuesday(Chrono::Tuesday);

View File

@ -71,7 +71,7 @@ namespace
etl::chrono::year year(i);
CHECK_TRUE(year.ok());
CHECK_EQUAL(i, int(year));
CHECK_EQUAL(i, static_cast<int>(year));
}
}
@ -87,7 +87,7 @@ namespace
etl::chrono::year this_year = ++year;
CHECK_TRUE(year.ok());
CHECK_EQUAL(count, year);
CHECK_EQUAL(count, static_cast<int>(year));
CHECK_EQUAL(this_year, year);
}
}
@ -226,16 +226,11 @@ namespace
//*************************************************************************
TEST(test_year_minus_year)
{
etl::chrono::year year(256);
etl::chrono::years years(2);
for (int i = 0; i < 128; ++i)
{
year = years - year;
CHECK_TRUE(year.ok());
CHECK_EQUAL((256 - (2 * i)) - 2, int(year));
}
etl::chrono::year y1(2056);
CHECK_TRUE(y1 - y1 == etl::chrono::years(0));
etl::chrono::year y2(2);
CHECK_TRUE(y1 - y2 == etl::chrono::years(2054));
CHECK_TRUE(y2 - y1 == etl::chrono::years(-2054));
}
//*************************************************************************
@ -256,8 +251,8 @@ namespace
//*************************************************************************
TEST(test_min_max_year)
{
CHECK_EQUAL(-32767, etl::chrono::year::min());
CHECK_EQUAL(32767, etl::chrono::year::max());
CHECK_EQUAL(-32767, static_cast<int>(etl::chrono::year::min()));
CHECK_EQUAL(32767, static_cast<int>(etl::chrono::year::max()));
}
#endif

View File

@ -128,7 +128,7 @@ namespace
Chrono::year_month ym2{Chrono::year(2001), Chrono::January};
Chrono::year_month ym3{Chrono::year(2000), Chrono::February};
CHECK_TRUE(ym1 == ym1); // Same year/month/day
CHECK_TRUE(ym1 == ym1); // Same year/month
CHECK_FALSE(ym1 == ym2); // Different year
CHECK_FALSE(ym1 == ym3); // Different month
}
@ -140,9 +140,80 @@ namespace
Chrono::year_month ym2{Chrono::year(2001), Chrono::January};
Chrono::year_month ym3{Chrono::year(2000), Chrono::February};
CHECK_FALSE(ym1 != ym1); // Same year/month/day
CHECK_FALSE(ym1 != ym1); // Same year/month
CHECK_TRUE(ym1 != ym2); // Different year
CHECK_TRUE(ym1 != ym3); // Different month
}
//*************************************************************************
TEST(test_year_month_relational_operators)
{
Chrono::year_month ym1(Chrono::year(2021), Chrono::January);
CHECK_FALSE(ym1 < ym1); // Same year/month
CHECK_TRUE(ym1 <= ym1);
CHECK_FALSE(ym1 > ym1);
CHECK_TRUE(ym1 >= ym1);
Chrono::year_month ym2(Chrono::year(2026), Chrono::December);
CHECK_TRUE(ym1 < ym2); // left year/month strict less
CHECK_TRUE(ym1 <= ym2);
CHECK_FALSE(ym1 > ym2);
CHECK_FALSE(ym1 >= ym2);
CHECK_FALSE(ym2 < ym1); // left year/month strict greater
CHECK_FALSE(ym2 <= ym1);
CHECK_TRUE(ym2 > ym1);
CHECK_TRUE(ym2 >= ym1);
}
//*************************************************************************
TEST(test_year_month_year_month_diff_operator)
{
Chrono::year_month ym1(Chrono::year(2021), Chrono::January);
Chrono::months dms = ym1 - ym1;
CHECK_EQUAL(dms.count(), 0);
Chrono::year_month ym2(Chrono::year(2026), Chrono::December);
dms = ym2 - ym1; // positive
CHECK_EQUAL(dms.count(), (2026 - 2021) * 12 + 11);
dms = ym1 - ym2; // negative
CHECK_EQUAL(dms.count(), (2021 - 2026) * 12 - 11);
}
//*************************************************************************
TEST(test_year_month_add_sub_months_operators)
{
Chrono::year_month ym1(Chrono::year(2021), Chrono::January);
Chrono::months dms(0); // zero
CHECK_TRUE(dms + ym1 == ym1);
CHECK_TRUE(ym1 + dms == ym1);
CHECK_TRUE(ym1 - dms == ym1);
Chrono::year_month ym2(Chrono::year(2026), Chrono::December);
dms = ym1 - ym2; // negative
CHECK_TRUE(dms + ym2 == ym1);
CHECK_TRUE(ym2 + dms == ym1);
CHECK_TRUE(ym1 - dms == ym2);
dms = ym2 - ym1; // positive
CHECK_TRUE(dms + ym1 == ym2);
CHECK_TRUE(ym1 + dms == ym2);
CHECK_TRUE(ym2 - dms == ym1);
}
//*************************************************************************
TEST(test_year_month_add_sub_years_operator)
{
Chrono::year_month ym(Chrono::year(2021), Chrono::January);
Chrono::years dys(0); // zero
CHECK_TRUE((ym + dys == Chrono::year_month(ym.year() + dys, ym.month())));
CHECK_TRUE((dys + ym == Chrono::year_month(ym.year() + dys, ym.month())));
CHECK_TRUE((ym - dys == Chrono::year_month(ym.year() - dys, ym.month())));
dys = Chrono::years(-200); // negative
CHECK_TRUE((ym + dys == Chrono::year_month(ym.year() + dys, ym.month())));
CHECK_TRUE((dys + ym == Chrono::year_month(ym.year() + dys, ym.month())));
CHECK_TRUE((ym - dys == Chrono::year_month(ym.year() - dys, ym.month())));
dys = Chrono::years(300); // positive
CHECK_TRUE((ym + dys == Chrono::year_month(ym.year() + dys, ym.month())));
CHECK_TRUE((dys + ym == Chrono::year_month(ym.year() + dys, ym.month())));
CHECK_TRUE((ym - dys == Chrono::year_month(ym.year() - dys, ym.month())));
}
}
}

View File

@ -151,7 +151,7 @@ namespace
Chrono::year_month_day ymd{Chrono::sys_days(etl::chrono::days(10997))};
Chrono::year_month_day expected{Chrono::year(2000), Chrono::February, Chrono::day(10)};
CHECK_EQUAL((unsigned)expected.year(), (unsigned)ymd.year());
CHECK_EQUAL((int)expected.year(), (int)ymd.year());
CHECK_EQUAL((unsigned)expected.month(), (unsigned)ymd.month());
CHECK_EQUAL((unsigned)expected.day(), (unsigned)ymd.day());
}