diff --git a/include/etl/chrono.h b/include/etl/chrono.h index 2d20db82..8fce7d57 100644 --- a/include/etl/chrono.h +++ b/include/etl/chrono.h @@ -60,8 +60,10 @@ namespace etl } } +#include "private/chrono/time_point.h" #include "private/chrono/last_spec.h" #include "private/chrono/duration.h" +#include "private/chrono/system_clock.h" #include "private/chrono/day.h" #include "private/chrono/weekday.h" #include "private/chrono/month.h" @@ -69,8 +71,10 @@ namespace etl #include "private/chrono/month_weekday.h" #include "private/chrono/year.h" #include "private/chrono/year_month.h" +#include "private/chrono/year_month_day.h" +#include "private/chrono/year_month_weekday.h" #include "private/chrono/hh_mm_ss.h" -#include "private/chrono/operators.h" +#include "private/chrono/operators.h" #endif #undef ETL_IN_CHRONO_H diff --git a/include/etl/private/chrono/month.h b/include/etl/private/chrono/month.h index 1359c555..5b1e3678 100644 --- a/include/etl/private/chrono/month.h +++ b/include/etl/private/chrono/month.h @@ -42,6 +42,11 @@ namespace etl ETL_CONSTEXPR etl::chrono::month operator +(const etl::chrono::months& ms, const etl::chrono::month& m) ETL_NOEXCEPT; ETL_CONSTEXPR etl::chrono::month operator -(const etl::chrono::month& m, const etl::chrono::months& ms) ETL_NOEXCEPT; + namespace private_chrono + { + static ETL_CONSTANT unsigned char days_in_month[13] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + } + //*********************************************************************** /// month //*********************************************************************** @@ -380,6 +385,14 @@ namespace etl return m; } + //************************************************************************* + /// Returns the last day of the month + //************************************************************************* + ETL_CONSTEXPR etl::chrono::day day() const ETL_NOEXCEPT + { + return etl::chrono::day(private_chrono::days_in_month[static_cast(m)]); + } + //************************************************************************* /// Is the contained month OK? //************************************************************************* diff --git a/include/etl/private/chrono/month_day.h b/include/etl/private/chrono/month_day.h index 171480b4..97ce4def 100644 --- a/include/etl/private/chrono/month_day.h +++ b/include/etl/private/chrono/month_day.h @@ -36,11 +36,6 @@ namespace etl { namespace chrono { - namespace private_chrono - { - static ETL_CONSTANT unsigned char days_in_month[13] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - } - class month_day { public: @@ -53,7 +48,8 @@ namespace etl //************************************************************************* /// Construct from month and day. //************************************************************************* - ETL_CONSTEXPR month_day(const etl::chrono::month& m_, const etl::chrono::day& d_) ETL_NOEXCEPT + ETL_CONSTEXPR month_day(const etl::chrono::month& m_, + const etl::chrono::day& d_) ETL_NOEXCEPT : m(m_) , d(d_) { diff --git a/include/etl/private/chrono/month_weekday.h b/include/etl/private/chrono/month_weekday.h index e1f99d95..a7d895fc 100644 --- a/include/etl/private/chrono/month_weekday.h +++ b/include/etl/private/chrono/month_weekday.h @@ -43,7 +43,8 @@ namespace etl //************************************************************************* /// Construct from month and weekday_indexed. //************************************************************************* - ETL_CONSTEXPR month_weekday(const etl::chrono::month& m_, const etl::chrono::weekday_indexed& wdi_) ETL_NOEXCEPT + ETL_CONSTEXPR month_weekday(const etl::chrono::month& m_, + const etl::chrono::weekday_indexed& wdi_) ETL_NOEXCEPT : m(m_) , wdi(wdi_) { @@ -107,7 +108,8 @@ namespace etl //************************************************************************* /// Construct from month and weekday_indexed. //************************************************************************* - ETL_CONSTEXPR month_weekday_last(const etl::chrono::month& m_, const etl::chrono::weekday_last& wdl_) ETL_NOEXCEPT + ETL_CONSTEXPR month_weekday_last(const etl::chrono::month& m_, + const etl::chrono::weekday_last& wdl_) ETL_NOEXCEPT : m(m_) , wdl(wdl_) { diff --git a/include/etl/private/chrono/operators.h b/include/etl/private/chrono/operators.h index 169217e7..7872c88c 100644 --- a/include/etl/private/chrono/operators.h +++ b/include/etl/private/chrono/operators.h @@ -36,154 +36,293 @@ namespace etl { namespace chrono { - //// year_month - //constexpr auto operator/(const etl::chrono::year& y, - // const etl::chrono::month& m ) noexcept - // -> etl::chrono::year_month; + //************************************************************************* + // month_day + ETL_CONSTEXPR14 etl::chrono::month_day operator /(const etl::chrono::month& m, + const etl::chrono::day& d) ETL_NOEXCEPT + { + return etl::chrono::month_day(m, d); + } - //constexpr auto operator/( const etl::chrono::year& y, int m ) noexcept - // -> etl::chrono::year_month; + // month_day + ETL_CONSTEXPR14 etl::chrono::month_day operator /(const etl::chrono::month& m, + int d) ETL_NOEXCEPT + { + return etl::chrono::month_day(m, etl::chrono::day(d)); + } - //// month_day - //constexpr auto operator/( const etl::chrono::month& m, - // const etl::chrono::day& d ) noexcept - // -> etl::chrono::month_day; + // month_day + ETL_CONSTEXPR14 etl::chrono::month_day operator /(int m, + const etl::chrono::day& d) ETL_NOEXCEPT + { + return etl::chrono::month_day(etl::chrono::month(m), d); + } - //constexpr auto operator/( const etl::chrono::month& m, int d ) noexcept - // -> etl::chrono::month_day; + // month_day + ETL_CONSTEXPR14 etl::chrono::month_day operator /(const etl::chrono::day& d, + const etl::chrono::month& m) ETL_NOEXCEPT + { + return etl::chrono::month_day(m, d); + } - //constexpr auto operator/( int m, const etl::chrono::day& d ) noexcept - // -> etl::chrono::month_day; + // month_day + ETL_CONSTEXPR14 etl::chrono::month_day operator /(const etl::chrono::day& d, + int m) ETL_NOEXCEPT + { + return etl::chrono::month_day(etl::chrono::month(m), d); + } - //constexpr auto operator/( const etl::chrono::day& d, - // const etl::chrono::month& m ) noexcept - // -> etl::chrono::month_day; + //************************************************************************* + // month_day_last + ETL_CONSTEXPR14 etl::chrono::month_day_last operator /(const etl::chrono::month& m, + etl::chrono::last_spec) ETL_NOEXCEPT + { + return etl::chrono::month_day_last(m); + } - //constexpr auto operator/( const etl::chrono::day& d, int m ) noexcept - // -> etl::chrono::month_day; + // month_day_last + ETL_CONSTEXPR14 etl::chrono::month_day_last operator /(int m, + etl::chrono::last_spec) ETL_NOEXCEPT + { + return etl::chrono::month_day_last(etl::chrono::month(m)); + } - //// month_day_last - //constexpr auto operator/( const etl::chrono::month& m, - // etl::chrono::last_spec ) noexcept - // -> etl::chrono::month_day_last; + // month_day_last + ETL_CONSTEXPR14 etl::chrono::month_day_last operator /(etl::chrono::last_spec, + const etl::chrono::month& m) ETL_NOEXCEPT + { + return etl::chrono::month_day_last(m); + } + + // month_day_last + ETL_CONSTEXPR14 etl::chrono::month_day_last operator/(etl::chrono::last_spec, + int m) ETL_NOEXCEPT + { + return etl::chrono::month_day_last(etl::chrono::month(m)); + } - //constexpr auto operator/( int m, etl::chrono::last_spec ) noexcept - // -> etl::chrono::month_day_last; + //************************************************************************* + // month_weekday + ETL_CONSTEXPR14 etl::chrono::month_weekday operator /(const etl::chrono::month& m, + const etl::chrono::weekday_indexed& wdi) ETL_NOEXCEPT + { + return etl::chrono::month_weekday(m, wdi); + } - //constexpr auto operator/( etl::chrono::last_spec, - // const etl::chrono::month& m ) noexcept - // -> etl::chrono::month_day_last; + // month_weekday + ETL_CONSTEXPR14 etl::chrono::month_weekday operator /(int m, + const etl::chrono::weekday_indexed& wdi) ETL_NOEXCEPT + { + return etl::chrono::month_weekday(etl::chrono::month(m), wdi); + } - //constexpr auto operator/( etl::chrono::last_spec, int m ) noexcept - // -> etl::chrono::month_day_last; + // month_weekday + ETL_CONSTEXPR14 etl::chrono::month_weekday operator /(const etl::chrono::weekday_indexed& wdi, + const etl::chrono::month& m) ETL_NOEXCEPT + { + return etl::chrono::month_weekday(m, wdi); + } - //// month_weekday - //constexpr auto operator/( const etl::chrono::month& m, - // const etl::chrono::weekday_indexed& wdi ) noexcept - // -> etl::chrono::month_weekday; + // month_weekday + ETL_CONSTEXPR14 etl::chrono::month_weekday operator /(const etl::chrono::weekday_indexed& wdi, + int m) ETL_NOEXCEPT + { + return etl::chrono::month_weekday(etl::chrono::month(m), wdi); + } - //constexpr auto operator/( int m, const etl::chrono::weekday_indexed& wdi ) noexcept - // -> etl::chrono::month_weekday; + //************************************************************************* + // month_weekday_last + ETL_CONSTEXPR14 etl::chrono::month_weekday_last operator /(const etl::chrono::month& m, + const etl::chrono::weekday_last& wdl) ETL_NOEXCEPT + { + return etl::chrono::month_weekday_last(m, wdl); + } - //constexpr auto operator/(const etl::chrono::weekday_indexed& wdi, - // const etl::chrono::month& m ) noexcept - // -> etl::chrono::month_weekday; + // month_weekday_last + ETL_CONSTEXPR14 etl::chrono::month_weekday_last operator /(int m, + const etl::chrono::weekday_last& wdl) ETL_NOEXCEPT + { + return etl::chrono::month_weekday_last(etl::chrono::month(m), wdl); + } - //constexpr auto operator/( const etl::chrono::weekday_indexed& wdi, int m ) noexcept - // -> etl::chrono::month_weekday; + // month_weekday_last + ETL_CONSTEXPR14 etl::chrono::month_weekday_last operator /(const etl::chrono::weekday_last& wdl, + const etl::chrono::month& m) ETL_NOEXCEPT + { + return etl::chrono::month_weekday_last(m, wdl); + } - //// month_weekday_last - //constexpr auto operator/( const etl::chrono::month& m, - // const etl::chrono::weekday_last& wdl ) noexcept - // -> etl::chrono::month_weekday_last; + // month_weekday_last + ETL_CONSTEXPR14 etl::chrono::month_weekday_last operator /(const etl::chrono::weekday_last& wdl, + int m) ETL_NOEXCEPT + { + return etl::chrono::month_weekday_last(etl::chrono::month(m), wdl); + } - //constexpr auto operator/( int m, const etl::chrono::weekday_last& wdl ) noexcept - // -> etl::chrono::month_weekday_last; + //************************************************************************* + // year_month + ETL_CONSTEXPR14 etl::chrono::year_month operator /(const etl::chrono::year& y, + const etl::chrono::month& m) ETL_NOEXCEPT + { + return etl::chrono::year_month(y, m); + } - //constexpr auto operator/( const etl::chrono::weekday_last& wdl, - // const etl::chrono::month& m ) noexcept - // -> etl::chrono::month_weekday_last; + // year_month + ETL_CONSTEXPR14 etl::chrono::year_month operator /(const etl::chrono::year& y, + int m) ETL_NOEXCEPT + { + return etl::chrono::year_month(y, etl::chrono::month(m)); + } - //constexpr auto operator/( const etl::chrono::weekday_last& wdl, int m ) noexcept - // -> etl::chrono::month_weekday_last; + ////************************************************************************* + // year_month_day + ETL_CONSTEXPR14 etl::chrono::year_month_day operator /(const etl::chrono::year_month& ym, + const etl::chrono::day& d) ETL_NOEXCEPT + { + return etl::chrono::year_month_day(ym.year(), ym.month(), d); + } - //// year_month_day - //constexpr auto operator/( const etl::chrono::year_month& ym, - // const etl::chrono::day& d ) noexcept - // -> etl::chrono::year_month_day; + // year_month_day + ETL_CONSTEXPR14 etl::chrono::year_month_day operator /(const etl::chrono::year_month& ym, + int d ) ETL_NOEXCEPT + { + return etl::chrono::year_month_day(ym.year(), ym.month(), etl::chrono::day(d)); + } - //constexpr auto operator/( const etl::chrono::year_month& ym, int d ) noexcept - // -> etl::chrono::year_month_day; + // year_month_day + ETL_CONSTEXPR14 etl::chrono::year_month_day operator /(const etl::chrono::year& y, + const etl::chrono::month_day& md) ETL_NOEXCEPT + { + return etl::chrono::year_month_day(y, md.month(), md.day()); + } - //constexpr auto operator/( const etl::chrono::year& y, - // const etl::chrono::month_day& md ) noexcept - // -> etl::chrono::year_month_day; + // year_month_day + ETL_CONSTEXPR14 etl::chrono::year_month_day operator/(int y, + const etl::chrono::month_day& md) ETL_NOEXCEPT + { + return etl::chrono::year_month_day(etl::chrono::year(y), md.month(), md.day()); + } - //constexpr auto operator/( int y, const etl::chrono::month_day& md ) noexcept - // -> etl::chrono::year_month_day; + // year_month_day + ETL_CONSTEXPR14 etl::chrono::year_month_day operator /(const etl::chrono::month_day& md, + const etl::chrono::year& y) ETL_NOEXCEPT + { + return etl::chrono::year_month_day(y, md.month(), md.day()); + } - //constexpr auto operator/( const etl::chrono::month_day& md, - // const etl::chrono::year& y ) noexcept - // -> etl::chrono::year_month_day; + // year_month_day + ETL_CONSTEXPR14 etl::chrono::year_month_day operator /(const etl::chrono::month_day& md, + int y) ETL_NOEXCEPT + { + return etl::chrono::year_month_day(etl::chrono::year(y), md.month(), md.day()); + } - //constexpr auto operator/( const etl::chrono::month_day& md, int y ) noexcept - // -> etl::chrono::year_month_day; + //************************************************************************* + // year_month_day_last + ETL_CONSTEXPR14 etl::chrono::year_month_day_last operator /(const etl::chrono::year_month& ym, + etl::chrono::last_spec) ETL_NOEXCEPT + { + return etl::chrono::year_month_day_last(ym.year(), etl::chrono::month_day_last(ym.month())); + } - //// year_month_day_last - //constexpr auto operator/( const etl::chrono::year_month& ym, - // etl::chrono::last_spec ) noexcept - // -> etl::chrono::year_month_day_last; + // year_month_day_last + ETL_CONSTEXPR14 etl::chrono::year_month_day_last operator /(const etl::chrono::year& y, + const etl::chrono::month_day_last& mdl) ETL_NOEXCEPT + { + return etl::chrono::year_month_day_last(y, mdl); + } - //constexpr auto operator/( const etl::chrono::year& y, - // const etl::chrono::month_day_last& mdl ) noexcept - // -> etl::chrono::year_month_day_last; + // year_month_day_last + ETL_CONSTEXPR14 etl::chrono::year_month_day_last operator /(int y, + const etl::chrono::month_day_last& mdl) ETL_NOEXCEPT + { + return etl::chrono::year_month_day_last(etl::chrono::year(y), mdl); + } - //constexpr auto operator/( int y, const etl::chrono::month_day_last& mdl ) noexcept - // -> etl::chrono::year_month_day_last; + // year_month_day_last + ETL_CONSTEXPR14 etl::chrono::year_month_day_last operator /(const etl::chrono::month_day_last& mdl, + const etl::chrono::year& y) ETL_NOEXCEPT + { + return etl::chrono::year_month_day_last(y, mdl); + } - //constexpr auto operator/( const etl::chrono::month_day_last& mdl, - // const etl::chrono::year& y ) noexcept - // -> etl::chrono::year_month_day_last; + // year_month_day_last + ETL_CONSTEXPR14 etl::chrono::year_month_day_last operator /(const etl::chrono::month_day_last& mdl, + int y) ETL_NOEXCEPT + { + return etl::chrono::year_month_day_last(etl::chrono::year(y), mdl); + } - //constexpr auto operator/( const etl::chrono::month_day_last& mdl, int y ) noexcept - // -> etl::chrono::year_month_day_last; + //************************************************************************* + // year_month_weekday + ETL_CONSTEXPR14 etl::chrono::year_month_weekday operator /(const etl::chrono::year_month& ym, + const etl::chrono::weekday_indexed& wdi) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday(ym.year(), ym.month(), wdi); + } - //// year_month_weekday - //constexpr auto operator/( const etl::chrono::year_month& ym, - // const etl::chrono::weekday_indexed& wdi ) noexcept - // -> etl::chrono::year_month_weekday; + // year_month_weekday + ETL_CONSTEXPR14 etl::chrono::year_month_weekday operator /(const etl::chrono::year& y, + const etl::chrono::month_weekday& mwd) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday(y, mwd.month(), mwd.weekday_indexed()); + } - //constexpr auto operator/( const etl::chrono::year& y, - // const etl::chrono::month_weekday& mwd ) noexcept - // -> etl::chrono::year_month_weekday; + // year_month_weekday + ETL_CONSTEXPR14 etl::chrono::year_month_weekday operator/(int y, + const etl::chrono::month_weekday& mwd) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday(etl::chrono::year(y), mwd.month(), mwd.weekday_indexed()); + } - //constexpr auto operator/( int y, const etl::chrono::month_weekday& mwd ) noexcept - // -> etl::chrono::year_month_weekday; + // year_month_weekday + ETL_CONSTEXPR14 etl::chrono::year_month_weekday operator /(const etl::chrono::month_weekday& mwd, + const etl::chrono::year& y) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday(y, mwd.month(), mwd.weekday_indexed()); + } - //constexpr auto operator/( const etl::chrono::month_weekday& mwd, - // const etl::chrono::year& y ) noexcept - // -> etl::chrono::year_month_weekday; + // year_month_weekday + ETL_CONSTEXPR14 etl::chrono::year_month_weekday operator /(const etl::chrono::month_weekday& mwd, + int y) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday(etl::chrono::year(y), mwd.month(), mwd.weekday_indexed()); + } - //constexpr auto operator/( const etl::chrono::month_weekday& mwd, int y ) noexcept - // -> etl::chrono::year_month_weekday; + //************************************************************************* + // year_month_weekday_last + ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last operator /(const etl::chrono::year_month& ym, + const etl::chrono::weekday_last& wdl) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday_last(ym.year(), ym.month(), wdl); + } - //// year_month_weekday_last - //constexpr auto operator/( const etl::chrono::year_month& ym, - // const etl::chrono::weekday_last& wdl ) noexcept - // -> etl::chrono::year_month_weekday_last; + // year_month_weekday_last + ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last operator /(const etl::chrono::year& y, + const etl::chrono::month_weekday_last& mwdl) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday_last(y, mwdl.month(), mwdl.weekday_last()); + } - //constexpr auto operator/( const etl::chrono::year& y, - // const etl::chrono::month_weekday_last& mwdl ) noexcept - // -> etl::chrono::year_month_weekday_last; + // year_month_weekday_last + ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last operator/(int y, + const etl::chrono::month_weekday_last& mwdl) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday_last(etl::chrono::year(y), mwdl.month(), mwdl.weekday_last()); + } - //constexpr auto operator/( int y, const etl::chrono::month_weekday_last& mwdl ) noexcept - // -> etl::chrono::year_month_weekday_last; + // year_month_weekday_last + ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last operator /(const etl::chrono::month_weekday_last& mwdl, + const etl::chrono::year& y) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday_last(y, mwdl.month(), mwdl.weekday_last()); + } - //constexpr auto operator/( const etl::chrono::month_weekday_last& mwdl, - // const etl::chrono::year& y ) noexcept - // -> etl::chrono::year_month_weekday_last; - - //constexpr auto operator/( const etl::chrono::month_weekday_last& mwdl, int y ) noexcept - // -> etl::chrono::year_month_weekday_last; + // year_month_weekday_last + ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last operator /(const etl::chrono::month_weekday_last& mwdl, + int y) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday_last(etl::chrono::year(y), mwdl.month(), mwdl.weekday_last()); + } } } \ No newline at end of file diff --git a/include/etl/private/chrono/system_clock.h b/include/etl/private/chrono/system_clock.h new file mode 100644 index 00000000..99341313 --- /dev/null +++ b/include/etl/private/chrono/system_clock.h @@ -0,0 +1,51 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2025 John Wellbelove + +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. +******************************************************************************/ + +#ifndef ETL_IN_CHRONO_H + #error DO NOT DIRECTLY INCLUDE THIS FILE. USE CHRONO.H +#endif + +namespace etl +{ + namespace chrono + { + class system_clock + { + + }; + + template + using sys_time = etl::chrono::time_point; + + using sys_seconds = sys_time; + + using sys_days = sys_time; + } +} diff --git a/include/etl/private/chrono/time_point.h b/include/etl/private/chrono/time_point.h new file mode 100644 index 00000000..0d48acb3 --- /dev/null +++ b/include/etl/private/chrono/time_point.h @@ -0,0 +1,232 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2025 John Wellbelove + +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. +******************************************************************************/ + +#ifndef ETL_IN_CHRONO_H + #error DO NOT DIRECTLY INCLUDE THIS FILE. USE CHRONO.H +#endif + +namespace etl +{ + namespace chrono + { + //*************************************************************************** + /// Represents a point in time storing a TDuration indicating the time + /// interval from the start of the TClock's epoch. + //*************************************************************************** + template + class time_point + { + public: + + using clock = TClock; + using duration = TDuration; + using rep = typename TDuration::rep; + using period = typename TDuration::period; + + //*************************************************************************** + /// Default constructor. + //*************************************************************************** + ETL_CONSTEXPR time_point() ETL_NOEXCEPT + : dur(duration::zero()) + { + } + + //*************************************************************************** + /// Construct from a duration. + //*************************************************************************** + ETL_CONSTEXPR explicit time_point(const duration& dur_) ETL_NOEXCEPT + : dur(dur_) + { + } + + //*************************************************************************** + /// Copy constructor. + //*************************************************************************** + ETL_CONSTEXPR time_point(const time_point& rhs) ETL_NOEXCEPT + : dur(rhs.dur) + { + } + + //*************************************************************************** + /// Copy construct from another time_point with a different duration type. + //*************************************************************************** + template + explicit time_point(const time_point& rhs) ETL_NOEXCEPT + : dur(rhs.time_since_epoch()) + { + } + + //*************************************************************************** + /// Assignment operator. + //*************************************************************************** + time_point& operator =(const time_point& rhs) ETL_NOEXCEPT + { + dur = rhs.dur; + + return *this; + } + + //*************************************************************************** + /// Returns a duration representing the amount of time between this and the clock's epoch. + //*************************************************************************** + ETL_CONSTEXPR duration time_since_epoch() const ETL_NOEXCEPT + { + return dur; + } + + //*************************************************************************** + /// Adds a duration. + //*************************************************************************** + time_point& operator +=(const duration& rhs) ETL_NOEXCEPT + { + dur += rhs; + + return *this; + } + + //*************************************************************************** + /// Subtracts a duration. + //*************************************************************************** + time_point& operator -=(const duration& rhs) ETL_NOEXCEPT + { + dur -= rhs; + + return *this; + } + + //*************************************************************************** + /// Returns a time_point with the smallest possible duration. + //*************************************************************************** + static ETL_CONSTEXPR time_point min() ETL_NOEXCEPT + { + return time_point(duration::min()); + } + + //*************************************************************************** + /// Returns a time_point with the largest possible duration. + //*************************************************************************** + static ETL_CONSTEXPR time_point max() ETL_NOEXCEPT + { + return time_point(duration::max()); + } + + private: + + duration dur; + }; + + //*************************************************************************** + /// Equality operator + //*************************************************************************** + template + ETL_CONSTEXPR bool operator ==(const time_point& lhs, const time_point& rhs) + { + return lhs.time_since_epoch() == rhs.time_since_epoch(); + } + + //*************************************************************************** + /// Inequality operator + //*************************************************************************** + template + ETL_CONSTEXPR bool operator !=(const time_point& lhs, const time_point& rhs) + { + return !(lhs == rhs); + } + + //*************************************************************************** + /// Less-than operator + //*************************************************************************** + template + ETL_CONSTEXPR bool operator <(const time_point& lhs, const time_point& rhs) + { + return lhs.time_since_epoch() < rhs.time_since_epoch(); + } + + //*************************************************************************** + /// Less-than-equal operator + //*************************************************************************** + template + ETL_CONSTEXPR bool operator <=(const time_point& lhs, const time_point& rhs) + { + return !(rhs < lhs); + } + + //*************************************************************************** + /// Greater-than operator + //*************************************************************************** + template + ETL_CONSTEXPR bool operator >(const time_point& lhs, const time_point& rhs) + { + return rhs < lhs; + } + + //*************************************************************************** + /// Greater-than-equal operator + //*************************************************************************** + template + ETL_CONSTEXPR bool operator >=(const time_point& lhs, const time_point& rhs) + { + return !(lhs < rhs); + } + + //*************************************************************************** + /// Local time + //*************************************************************************** + //struct local_t + //{ + // using rep = size_t; + // using period = etl::chrono::seconds; + // using duration = etl::chrono::duration; + // using time_point = etl::chrono::time_point; + + // const bool is_steady = true; + + // time_point now() + // { + // return time_point(); + // } + //}; + + //template + //using local_time = etl::chrono::time_point; + + //using local_seconds = local_time; + //using local_days = local_time; + } + + //*************************************************************************** + /// Defines type, which is the common type of two std::chrono::time_points. + //*************************************************************************** + template + struct common_type, etl::chrono::time_point> + { + using type = etl::chrono::time_point::type>; + }; +} diff --git a/include/etl/private/chrono/weekday.h b/include/etl/private/chrono/weekday.h index f5e763ef..794edbce 100644 --- a/include/etl/private/chrono/weekday.h +++ b/include/etl/private/chrono/weekday.h @@ -384,7 +384,7 @@ namespace etl ETL_CONSTEXPR bool operator ==(const etl::chrono::weekday_indexed& wd1, const etl::chrono::weekday_indexed& wd2) ETL_NOEXCEPT { return (wd1.weekday() == wd2.weekday()) && - (wd1.index() == wd2.index()); + (wd1.index() == wd2.index()); } //*********************************************************************** diff --git a/include/etl/private/chrono/year.h b/include/etl/private/chrono/year.h index df90770d..ce723be2 100644 --- a/include/etl/private/chrono/year.h +++ b/include/etl/private/chrono/year.h @@ -168,7 +168,9 @@ namespace etl //*********************************************************************** ETL_CONSTEXPR bool is_leap() const ETL_NOEXCEPT { - return ((value % 4) == 0) && !((value % 400) == 0); + return ((value % 4) == 0) && // Divisible by 4 + (((value % 100) != 0) || // but not divisible by 100 + ((value % 400) == 0)); // unless divisible by 400 } //*********************************************************************** diff --git a/include/etl/private/chrono/year_month.h b/include/etl/private/chrono/year_month.h index 3c76033b..ef4ebe18 100644 --- a/include/etl/private/chrono/year_month.h +++ b/include/etl/private/chrono/year_month.h @@ -44,15 +44,16 @@ namespace etl /// Default constructor. //************************************************************************* year_month() - : y(etl::integral_limits::min) - , m(0) + : y() + , m() { } //************************************************************************* /// Construct from month and day. //************************************************************************* - ETL_CONSTEXPR year_month(const etl::chrono::year& y_, const etl::chrono::month& m_) ETL_NOEXCEPT + ETL_CONSTEXPR year_month(const etl::chrono::year& y_, + const etl::chrono::month& m_) ETL_NOEXCEPT : y(y_) , m(m_) { diff --git a/include/etl/private/chrono/year_month_day.h b/include/etl/private/chrono/year_month_day.h new file mode 100644 index 00000000..101dcfb3 --- /dev/null +++ b/include/etl/private/chrono/year_month_day.h @@ -0,0 +1,538 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2025 John Wellbelove + +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. +******************************************************************************/ + +#ifndef ETL_IN_CHRONO_H + #error DO NOT DIRECTLY INCLUDE THIS FILE. USE CHRONO.H +#endif + +namespace etl +{ + namespace chrono + { + //************************************************************************* + /// year_month_day + //************************************************************************* + class year_month_day + { + public: + + //************************************************************************* + /// Default constructor. + //************************************************************************* + year_month_day() + : y() + , m() + , d() + { + } + + //************************************************************************* + /// Construct from month and day. + //************************************************************************* + ETL_CONSTEXPR year_month_day(const etl::chrono::year& y_, + const etl::chrono::month& m_, + const etl::chrono::day& d_) ETL_NOEXCEPT + : y(y_) + , m(m_) + , d(d_) + { + } + + //************************************************************************* + /// Returns the year. + //************************************************************************* + ETL_CONSTEXPR etl::chrono::year year() const ETL_NOEXCEPT + { + return y; + } + + //************************************************************************* + /// Returns the month. + //************************************************************************* + ETL_CONSTEXPR etl::chrono::month month() const ETL_NOEXCEPT + { + return m; + } + + //************************************************************************* + /// Returns the day. + //************************************************************************* + ETL_CONSTEXPR etl::chrono::day day() const ETL_NOEXCEPT + { + return d; + } + + //************************************************************************* + /// Returns true if the year/month/day is valid. + //************************************************************************* + ETL_CONSTEXPR14 bool ok() const ETL_NOEXCEPT + { + // Check if the year, month, and day are valid individually + return y.ok() && + m.ok() && + d.ok() && + d <= etl::chrono::month_day_last(m).day(); + } + + //************************************************************************* + /// Adds etl::chrono::years + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_day operator +(const etl::chrono::year_month_day& ymd, + const etl::chrono::years& dy) ETL_NOEXCEPT + { + return etl::chrono::year_month_day(ymd.year() + dy, ymd.month(), ymd.day()); + } + + //************************************************************************* + /// Adds etl::chrono::years + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_day operator +(const etl::chrono::years& dy, + const etl::chrono::year_month_day& ymd) ETL_NOEXCEPT + { + return etl::chrono::year_month_day(ymd.year() + dy, ymd.month(), ymd.day()); + } + + //************************************************************************* + /// Adds etl::chrono::months + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_day operator +(const etl::chrono::year_month_day& ymd, + const etl::chrono::months& dm) ETL_NOEXCEPT + { + return etl::chrono::year_month_day(ymd.year(), ymd.month() + dm, ymd.day()); + } + + //************************************************************************* + /// Adds etl::chrono::months + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_day operator +(const etl::chrono::months& dm, + const etl::chrono::year_month_day& ymd) ETL_NOEXCEPT + { + return etl::chrono::year_month_day(ymd.year(), ymd.month() + dm, ymd.day()); + } + + //************************************************************************* + /// Subtracts etl::chrono::years + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_day operator -(const etl::chrono::year_month_day& ymd, + const etl::chrono::years& dy) ETL_NOEXCEPT + { + return etl::chrono::year_month_day(ymd.year() - dy, ymd.month(), ymd.day()); + } + + //************************************************************************* + /// Subtracts etl::chrono::months + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_day operator -(const etl::chrono::year_month_day& ymd, + const etl::chrono::months& dm) ETL_NOEXCEPT + { + return etl::chrono::year_month_day(ymd.year(), ymd.month() - dm, ymd.day()); + } + + //************************************************************************* + /// Equality operator. + //************************************************************************* + friend ETL_CONSTEXPR bool operator ==(const etl::chrono::year_month_day& lhs, + const etl::chrono::year_month_day& rhs) ETL_NOEXCEPT + { + return (lhs.y == rhs.y) && (lhs.m == rhs.m) && (lhs.d == rhs.d); + } + + //************************************************************************* + /// Inequality operator. + //************************************************************************* + friend ETL_CONSTEXPR bool operator !=(const etl::chrono::year_month_day& lhs, + const etl::chrono::year_month_day& rhs) ETL_NOEXCEPT + { + return !(lhs == rhs); + } + + //*********************************************************************** + /// Spaceship operator + //*********************************************************************** +#if ETL_USING_CPP20 + [[nodiscard]] friend constexpr auto operator <=>(const etl::chrono::year_month_day& lhs, + const etl::chrono::year_month_day& rhs) ETL_NOEXCEPT + { + auto cmp = lhs.year() <=> rhs.year(); + + if (cmp != 0) + { + return cmp; + } + + cmp = lhs.month() <=> rhs.month(); + + if (cmp != 0) + { + return cmp; + } + + return lhs.day() <=> rhs.day(); + } +#endif + + //*********************************************************************** + /// Compare year_month_day with another. + /// if year < other.year, returns -1; + /// else if year > other.year, returns 1; + /// if month < other.month, returns -1; + /// else if month > other.month, returns 1; + /// else if day < other.day, returns -1; + /// else if day > other.day, returns 1; + /// else returns 0; + //*********************************************************************** + ETL_CONSTEXPR14 int compare(const year_month_day& other) const ETL_NOEXCEPT + { + if (y < other.y) return -1; + if (y > other.y) return 1; + if (m < other.m) return -1; + if (m > other.m) return 1; + if (d < other.d) return -1; + if (d > other.d) return 1; + + return 0; + } + + //*********************************************************************** + /// Converts *this to etl::chrono::sys_days + //*********************************************************************** + //ETL_CONSTEXPR14 operator etl::chrono::sys_days() const ETL_NOEXCEPT + //{ + // // Start with the first day of the year + // etl::chrono::sys_days first_day_of_year = etl::chrono::sys_days(y / etl::chrono::January / etl::chrono::day(1)); + + // // Add the number of days in the months before the current month + // for (etl::chrono::month m = etl::chrono::January; m < m; ++m) + // { + // first_day_of_year += etl::chrono::days((unsigned)etl::chrono::month_day_last(m).day()); + // } + + // // Add the days in the current month + // first_day_of_year += d - etl::chrono::day(1); + + // return first_day_of_year; + //} + + ////*********************************************************************** + ///// Converts *this to etl::chrono::local_days + ////*********************************************************************** + //ETL_CONSTEXPR14 explicit operator etl::chrono::local_days() const ETL_NOEXCEPT + //{ + // return etl::chrono::local_days(); + //} + + private: + + etl::chrono::year y; + etl::chrono::month m; + etl::chrono::day d; + }; + + //************************************************************************* + /// year_month_day_last + //************************************************************************* + class year_month_day_last + { + public: + + //************************************************************************* + /// + //************************************************************************* + ETL_CONSTEXPR year_month_day_last(const etl::chrono::year& y, + const etl::chrono::month_day_last& mdl) ETL_NOEXCEPT + : y(y) + , m(mdl.month()) + { + + } + + //************************************************************************* + /// + //************************************************************************* + ETL_CONSTEXPR etl::chrono::year year() const ETL_NOEXCEPT + { + return y; + } + + //************************************************************************* + /// + //************************************************************************* + ETL_CONSTEXPR etl::chrono::month month() const ETL_NOEXCEPT + { + return m; + } + + //************************************************************************* + /// + //************************************************************************* + ETL_CONSTEXPR etl::chrono::day day() const ETL_NOEXCEPT + { + return etl::chrono::month_day_last(m).day(); + } + + //************************************************************************* + /// + //************************************************************************* + ETL_CONSTEXPR etl::chrono::month_day_last month_day_last() const ETL_NOEXCEPT + { + return etl::chrono::month_day_last(m); + } + + //************************************************************************* + /// + //************************************************************************* + ETL_CONSTEXPR etl::chrono::year_month_day_last& operator +=(const etl::chrono::years& dy) ETL_NOEXCEPT + { + y += dy; + + return *this; + } + + //************************************************************************* + /// + //************************************************************************* + ETL_CONSTEXPR etl::chrono::year_month_day_last& operator +=(const etl::chrono::months& dm) ETL_NOEXCEPT + { + m += dm; + + return *this; + } + + //************************************************************************* + /// + //************************************************************************* + ETL_CONSTEXPR etl::chrono::year_month_day_last& operator -=(const etl::chrono::years& dy) ETL_NOEXCEPT + { + y -= dy; + + return *this; + } + + //************************************************************************* + /// + //************************************************************************* + ETL_CONSTEXPR etl::chrono::year_month_day_last& operator -=(const etl::chrono::months& dm) ETL_NOEXCEPT + { + m -= dm; + + return *this; + } + + //************************************************************************* + /// Adds etl::chrono::years + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_day_last operator +(const etl::chrono::year_month_day_last& ymdl, + const etl::chrono::years& dy) ETL_NOEXCEPT + { + return etl::chrono::year_month_day_last(ymdl.year() + dy, ymdl.month_day_last()); + } + + //************************************************************************* + /// Adds etl::chrono::years + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_day_last operator +(const etl::chrono::years& dy, + const etl::chrono::year_month_day_last& ymdl) ETL_NOEXCEPT + { + return etl::chrono::year_month_day_last(ymdl.year() + dy, ymdl.month_day_last()); + } + + //************************************************************************* + /// Adds etl::chrono::months + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_day_last operator +(const etl::chrono::year_month_day_last& ymdl, + const etl::chrono::months& dm) ETL_NOEXCEPT + { + return etl::chrono::year_month_day_last(ymdl.year(), etl::chrono::month_day_last(ymdl.month() + dm)); + } + + //************************************************************************* + /// Adds etl::chrono::months + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_day_last operator +(const etl::chrono::months& dm, + const etl::chrono::year_month_day_last& ymdl) ETL_NOEXCEPT + { + return etl::chrono::year_month_day_last(ymdl.year(), etl::chrono::month_day_last(ymdl.month() + dm)); + } + + //************************************************************************* + /// Subtracts etl::chrono::years + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_day_last operator -(const etl::chrono::year_month_day_last& ymdl, + const etl::chrono::years& dy) ETL_NOEXCEPT + { + return etl::chrono::year_month_day_last(ymdl.year() - dy, ymdl.month_day_last()); + } + + //************************************************************************* + /// Subtracts etl::chrono::months + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_day_last operator -(const etl::chrono::year_month_day_last& ymdl, + const etl::chrono::months& dm) ETL_NOEXCEPT + { + return etl::chrono::year_month_day_last(ymdl.year(), etl::chrono::month_day_last(ymdl.month() - dm)); + } + + //************************************************************************* + /// Equality operator. + //************************************************************************* + friend ETL_CONSTEXPR bool operator ==(const etl::chrono::year_month_day_last& lhs, + const etl::chrono::year_month_day_last& rhs) ETL_NOEXCEPT + { + return (lhs.y == rhs.y) && (lhs.m == rhs.m); + } + + //************************************************************************* + /// Inequality operator. + //************************************************************************* + friend ETL_CONSTEXPR bool operator !=(const etl::chrono::year_month_day_last& lhs, + const etl::chrono::year_month_day_last& rhs) ETL_NOEXCEPT + { + return !(lhs == rhs); + } + + //*********************************************************************** + /// Spaceship operator + //*********************************************************************** +#if ETL_USING_CPP20 + [[nodiscard]] friend constexpr auto operator <=>(const etl::chrono::year_month_day_last& lhs, + const etl::chrono::year_month_day_last& rhs) ETL_NOEXCEPT + { + auto cmp = lhs.year() <=> rhs.year(); + + if (cmp != 0) + { + return cmp; + } + else + { + auto cmp = lhs.month() <=> rhs.month(); + + if (cmp != 0) + { + return cmp; + } + else + { + return lhs.month() <=> rhs.month(); + } + } + } +#endif + + //*********************************************************************** + /// Compare year_month_day with another. + /// if year < other.year, returns -1; + /// else if year > other.year, returns 1; + /// if month < other.month, returns -1; + /// else if month > other.month, returns 1; + /// else returns 0; + //*********************************************************************** + ETL_CONSTEXPR14 int compare(const year_month_day_last& other) const ETL_NOEXCEPT + { + if (y < other.y) return -1; + if (y > other.y) return 1; + if (m < other.m) return -1; + if (m > other.m) return 1; + + return 0; + } + + //************************************************************************* + /// + //************************************************************************* + //ETL_CONSTEXPR operator etl::chrono::sys_days() const ETL_NOEXCEPT + //{ + // etl::chrono::sys_days(); + //} + + //************************************************************************* + /// + //************************************************************************* + //ETL_CONSTEXPR explicit operator etl::chrono::local_days() const ETL_NOEXCEPT + //{ + + //} + + private: + + etl::chrono::year y; + etl::chrono::month m; + }; + } + + //************************************************************************* + /// Hash function for etl::chrono::year_month_day + //************************************************************************* +#if ETL_USING_8BIT_TYPES + template <> + struct hash + { + size_t operator()(const etl::chrono::year_month_day& ymd) const + { + uint8_t buffer[sizeof(unsigned int) + sizeof(unsigned int) + sizeof(unsigned int)]; + + unsigned int y = ymd.year(); + unsigned int m = ymd.month(); + unsigned int d = ymd.day(); + + memcpy(buffer, &y, sizeof(y)); + memcpy(buffer + sizeof(y), &m, sizeof(m)); + memcpy(buffer + sizeof(y) + sizeof(m), &d, sizeof(d)); + + return etl::private_hash::generic_hash(buffer, buffer + sizeof(unsigned int) + sizeof(unsigned int) + sizeof(unsigned int)); + } + }; +#endif + + //************************************************************************* + /// Hash function for etl::chrono::year_month_day_last + //************************************************************************* +#if ETL_USING_8BIT_TYPES + template <> + struct hash + { + size_t operator()(const etl::chrono::year_month_day_last& ymdl) const + { + uint8_t buffer[sizeof(unsigned int) + sizeof(unsigned int) + sizeof(unsigned int)]; + + unsigned int y = ymdl.year(); + unsigned int m = ymdl.month(); + unsigned int d = ymdl.day(); + + memcpy(buffer, &y, sizeof(y)); + memcpy(buffer + sizeof(y), &m, sizeof(m)); + memcpy(buffer + sizeof(y) + sizeof(m), &d, sizeof(d)); + + return etl::private_hash::generic_hash(buffer, buffer + sizeof(unsigned int) + sizeof(unsigned int) + sizeof(unsigned int)); + } + }; +#endif +} + diff --git a/include/etl/private/chrono/year_month_weekday.h b/include/etl/private/chrono/year_month_weekday.h new file mode 100644 index 00000000..03242c6e --- /dev/null +++ b/include/etl/private/chrono/year_month_weekday.h @@ -0,0 +1,518 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2025 John Wellbelove + +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. +******************************************************************************/ + +#ifndef ETL_IN_CHRONO_H + #error DO NOT DIRECTLY INCLUDE THIS FILE. USE CHRONO.H +#endif + +namespace etl +{ + namespace chrono + { + //************************************************************************* + /// year_month_weekday + //************************************************************************* + class year_month_weekday + { + public: + + //************************************************************************* + /// Default constructor. + //************************************************************************* + year_month_weekday() + : y() + , m() + , wdi() + { + } + + //************************************************************************* + /// Construct from month and day. + //************************************************************************* + ETL_CONSTEXPR year_month_weekday(const etl::chrono::year& y_, + const etl::chrono::month& m_, + const etl::chrono::weekday_indexed& wdi_) ETL_NOEXCEPT + : y(y_) + , m(m_) + , wdi(wdi_) + { + } + + //************************************************************************* + /// Returns the year. + //************************************************************************* + ETL_CONSTEXPR etl::chrono::year year() const ETL_NOEXCEPT + { + return y; + } + + //************************************************************************* + /// Returns the month. + //************************************************************************* + ETL_CONSTEXPR etl::chrono::month month() const ETL_NOEXCEPT + { + return m; + } + + //************************************************************************* + /// Returns the weekday. + //************************************************************************* + ETL_CONSTEXPR etl::chrono::weekday weekday() const ETL_NOEXCEPT + { + return wdi.weekday(); + } + + //************************************************************************* + /// Returns the weekday index. + //************************************************************************* + ETL_CONSTEXPR unsigned index() const ETL_NOEXCEPT + { + return wdi.index(); + } + + //************************************************************************* + /// Returns the weekday_indexed. + //************************************************************************* + ETL_CONSTEXPR etl::chrono::weekday_indexed weekday_indexed() const ETL_NOEXCEPT + { + return wdi; + } + + //************************************************************************* + /// Returns true if the year/month/day is valid. + //************************************************************************* + ETL_CONSTEXPR14 bool ok() const ETL_NOEXCEPT + { + return y.ok() && m.ok() && wdi.ok(); + } + + //************************************************************************* + /// Adds etl::chrono::years + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_weekday operator +(const etl::chrono::year_month_weekday& ymwd, + const etl::chrono::years& dy) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday(ymwd.year() + dy, ymwd.month(), ymwd.weekday_indexed()); + } + + //************************************************************************* + /// Adds etl::chrono::years + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_weekday operator +(const etl::chrono::years& dy, + const etl::chrono::year_month_weekday& ymwd) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday(ymwd.year() + dy, ymwd.month(), ymwd.weekday_indexed()); + } + + //************************************************************************* + /// Adds etl::chrono::months + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_weekday operator +(const etl::chrono::year_month_weekday& ymwd, + const etl::chrono::months& dm) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday(ymwd.year(), ymwd.month() + dm, ymwd.weekday_indexed()); + } + + //************************************************************************* + /// Adds etl::chrono::months + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_weekday operator +(const etl::chrono::months& dm, + const etl::chrono::year_month_weekday& ymwd) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday(ymwd.year(), ymwd.month() + dm, ymwd.weekday_indexed()); + } + + //************************************************************************* + /// Subtracts etl::chrono::years + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_weekday operator -(const etl::chrono::year_month_weekday& ymwd, + const etl::chrono::years& dy) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday(ymwd.year() - dy, ymwd.month(), ymwd.weekday_indexed()); + } + + //************************************************************************* + /// Subtracts etl::chrono::months + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_weekday operator -(const etl::chrono::year_month_weekday& ymwd, + const etl::chrono::months& dm) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday(ymwd.year(), ymwd.month() - dm, ymwd.weekday_indexed()); + } + + //************************************************************************* + /// Equality operator. + //************************************************************************* + friend ETL_CONSTEXPR bool operator ==(const etl::chrono::year_month_weekday& lhs, + const etl::chrono::year_month_weekday& rhs) ETL_NOEXCEPT + { + return (lhs.y == rhs.y) && (lhs.m == rhs.m) && (lhs.wdi == rhs.wdi); + } + + //************************************************************************* + /// Inequality operator. + //************************************************************************* + friend ETL_CONSTEXPR bool operator !=(const etl::chrono::year_month_weekday& lhs, + const etl::chrono::year_month_weekday& rhs) ETL_NOEXCEPT + { + return !(lhs == rhs); + } + + //*********************************************************************** + /// Converts *this to etl::chrono::sys_days + //*********************************************************************** + //ETL_CONSTEXPR14 operator etl::chrono::sys_days() const ETL_NOEXCEPT + //{ + // // Start with the first day of the given year and month + // etl::chrono::year_month_day first_day_of_month(y, m, etl::chrono::day(1)); + + // // Convert the first day of the month to sys_days + // etl::chrono::sys_days first_day_sys_days = static_cast(first_day_of_month); + + // // Determine the weekday of the first day of the month + // etl::chrono::weekday first_weekday = etl::chrono::weekday(first_day_sys_days); + + // // Calculate the offset to the desired weekday + // int offset = (wd.weekday().c_encoding() - first_weekday.c_encoding() + 7) % 7; + + // // Calculate the day of the month for the desired weekday_indexed + // int day_of_month = 1 + offset + (wdi.index() - 1) * 7; + + // // Ensure the calculated day is valid for the given month + // if (day_of_month > etl::chrono::month_day_last(m).day().count()) + // { + // day_of_month = 0; // Invalid day + // } + + // // Create a year_month_day object for the calculated day + // etl::chrono::year_month_day ymwd(y, m, etl::chrono::day(day_of_month)); + + // // Convert the year_month_day to sys_days + // return static_cast(ymwd); + //} + + ////*********************************************************************** + ///// Converts *this to etl::chrono::local_days + ////*********************************************************************** + //ETL_CONSTEXPR14 explicit operator etl::chrono::local_days() const ETL_NOEXCEPT + //{ + // return etl::chrono::local_days(); + //} + + private: + + etl::chrono::year y; + etl::chrono::month m; + etl::chrono::weekday_indexed wdi; + }; + + //************************************************************************* + /// year_month_weekday_last + //************************************************************************* + class year_month_weekday_last + { + public: + + //************************************************************************* + /// Construct from year, month, weekday_last + //************************************************************************* + ETL_CONSTEXPR year_month_weekday_last(const etl::chrono::year& y_, + const etl::chrono::month& m_, + const etl::chrono::weekday_last& wdl_) ETL_NOEXCEPT + : y(y_) + , m(m_) + , wdl(wdl_) + { + } + + //************************************************************************* + /// Returns the year. + //************************************************************************* + ETL_CONSTEXPR etl::chrono::year year() const ETL_NOEXCEPT + { + return y; + } + + //************************************************************************* + /// Returns the month. + //************************************************************************* + ETL_CONSTEXPR etl::chrono::month month() const ETL_NOEXCEPT + { + return m; + } + + //************************************************************************* + /// Returns the weekday. + //************************************************************************* + ETL_CONSTEXPR etl::chrono::weekday weekday() const ETL_NOEXCEPT + { + return wdl.weekday(); + } + + //************************************************************************* + /// Returns the weekday_last. + //************************************************************************* + ETL_CONSTEXPR etl::chrono::weekday_last weekday_last() const ETL_NOEXCEPT + { + return wdl; + } + + //************************************************************************* + /// Adds etl::chrono::years. + //************************************************************************* + ETL_CONSTEXPR etl::chrono::year_month_weekday_last& operator +=(const etl::chrono::years& dy) ETL_NOEXCEPT + { + y += dy; + + return *this; + } + + //************************************************************************* + /// Adds etl::chrono::months. + //************************************************************************* + ETL_CONSTEXPR etl::chrono::year_month_weekday_last& operator +=(const etl::chrono::months& dm) ETL_NOEXCEPT + { + m += dm; + + return *this; + } + + //************************************************************************* + /// Subtracts etl::chrono::years. + //************************************************************************* + ETL_CONSTEXPR etl::chrono::year_month_weekday_last& operator -=(const etl::chrono::years& dy) ETL_NOEXCEPT + { + y -= dy; + + return *this; + } + + //************************************************************************* + /// Subtracts etl::chrono::months. + //************************************************************************* + ETL_CONSTEXPR etl::chrono::year_month_weekday_last& operator -=(const etl::chrono::months& dm) ETL_NOEXCEPT + { + m -= dm; + + return *this; + } + + //************************************************************************* + /// Adds etl::chrono::years and const etl::chrono::year_month_weekday_last. + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last operator +(const etl::chrono::year_month_weekday_last& ymwdl, + const etl::chrono::years& dy) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday_last(ymwdl.year() + dy, ymwdl.month(), ymwdl.weekday_last()); + } + + //************************************************************************* + /// Adds etl::chrono::years and const etl::chrono::year_month_weekday_last. + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last operator +(const etl::chrono::years& dy, + const etl::chrono::year_month_weekday_last& ymwdl) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday_last(ymwdl.year() + dy, ymwdl.month(), ymwdl.weekday_last()); + } + + //************************************************************************* + /// Adds const etl::chrono::year_month_weekday_last and etl::chrono::months. + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last operator +(const etl::chrono::year_month_weekday_last& ymwdl, + const etl::chrono::months& dm) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday_last(ymwdl.year(), ymwdl.month() + dm, ymwdl.weekday_last()); + } + + //************************************************************************* + /// Adds etl::chrono::months and const etl::chrono::year_month_weekday_last. + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last operator +(const etl::chrono::months& dm, + const etl::chrono::year_month_weekday_last& ymwdl) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday_last(ymwdl.year(), ymwdl.month() + dm, ymwdl.weekday_last()); + } + + //************************************************************************* + /// Subtracts etl::chrono::years from const etl::chrono::year_month_weekday_last. + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last operator -(const etl::chrono::year_month_weekday_last& ymwdl, + const etl::chrono::years& dy) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday_last(ymwdl.year() - dy, ymwdl.month(), ymwdl.weekday_last()); + } + + //************************************************************************* + /// Subtracts etl::chrono::months from const etl::chrono::year_month_weekday_last + //************************************************************************* + friend ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last operator -(const etl::chrono::year_month_weekday_last& ymwdl, + const etl::chrono::months& dm) ETL_NOEXCEPT + { + return etl::chrono::year_month_weekday_last(ymwdl.year(), ymwdl.month() - dm, ymwdl.weekday_last()); + } + + //************************************************************************* + /// Equality operator. + //************************************************************************* + friend ETL_CONSTEXPR bool operator ==(const etl::chrono::year_month_weekday_last& lhs, + const etl::chrono::year_month_weekday_last& rhs) ETL_NOEXCEPT + { + return (lhs.y == rhs.y) && (lhs.m == rhs.m) && (lhs.weekday() == rhs.weekday()); + } + + //************************************************************************* + /// Inequality operator. + //************************************************************************* + friend ETL_CONSTEXPR bool operator !=(const etl::chrono::year_month_weekday_last& lhs, + const etl::chrono::year_month_weekday_last& rhs) ETL_NOEXCEPT + { + return !(lhs == rhs); + } + + //*********************************************************************** + /// Spaceship operator + //*********************************************************************** +#if ETL_USING_CPP20 + [[nodiscard]] friend constexpr auto operator <=>(const etl::chrono::year_month_weekday_last& lhs, + const etl::chrono::year_month_weekday_last& rhs) ETL_NOEXCEPT + { + auto cmp = lhs.year() <=> rhs.year(); + + if (cmp != 0) + { + return cmp; + } + else + { + auto cmp = lhs.month() <=> rhs.month(); + + if (cmp != 0) + { + return cmp; + } + else + { + return lhs.weekday().c_encoding() <=> rhs.weekday().c_encoding(); + } + } + } +#endif + + //*********************************************************************** + /// Compare year_month_weekday with another. + /// if year < other.year, returns -1; + /// else if year > other.year, returns 1; + /// if month < other.month, returns -1; + /// else if month > other.month, returns 1; + /// else returns 0; + //*********************************************************************** + ETL_CONSTEXPR14 int compare(const year_month_weekday_last& other) const ETL_NOEXCEPT + { + if (y < other.y) return -1; + if (y > other.y) return 1; + if (m < other.m) return -1; + if (m > other.m) return 1; + + return 0; + } + + //************************************************************************* + /// + //************************************************************************* + //ETL_CONSTEXPR operator etl::chrono::sys_days() const ETL_NOEXCEPT + //{ + // etl::chrono::sys_days(); + //} + + //************************************************************************* + /// + //************************************************************************* + //ETL_CONSTEXPR explicit operator etl::chrono::local_days() const ETL_NOEXCEPT + //{ + + //} + + private: + + etl::chrono::year y; + etl::chrono::month m; + etl::chrono::weekday_last wdl; + }; + } + + //************************************************************************* + /// Hash function for etl::chrono::year_month_weekday + //************************************************************************* +#if ETL_USING_8BIT_TYPES + template <> + struct hash + { + size_t operator()(const etl::chrono::year_month_weekday& ymwd) const + { + uint8_t buffer[sizeof(unsigned int) + sizeof(unsigned int) + sizeof(unsigned int)]; + + unsigned int y = ymwd.year(); + unsigned int m = ymwd.month(); + unsigned int d = ymwd.weekday().c_encoding(); + + memcpy(buffer, &y, sizeof(y)); + memcpy(buffer + sizeof(y), &m, sizeof(m)); + memcpy(buffer + sizeof(y) + sizeof(m), &d, sizeof(d)); + + return etl::private_hash::generic_hash(buffer, buffer + sizeof(unsigned int) + sizeof(unsigned int) + sizeof(unsigned int)); + } + }; +#endif + + //************************************************************************* + /// Hash function for etl::chrono::year_month_weekday_last + //************************************************************************* +#if ETL_USING_8BIT_TYPES + template <> + struct hash + { + size_t operator()(const etl::chrono::year_month_weekday_last& ymwdl) const + { + uint8_t buffer[sizeof(unsigned int) + sizeof(unsigned int) + sizeof(unsigned int)]; + + unsigned int y = ymwdl.year(); + unsigned int m = ymwdl.month(); + unsigned int d = ymwdl.weekday_last().weekday().c_encoding(); + + memcpy(buffer, &y, sizeof(y)); + memcpy(buffer + sizeof(y), &m, sizeof(m)); + memcpy(buffer + sizeof(y) + sizeof(m), &d, sizeof(d)); + + return etl::private_hash::generic_hash(buffer, buffer + sizeof(unsigned int) + sizeof(unsigned int) + sizeof(unsigned int)); + } + }; +#endif +} + diff --git a/test/test_chrono_month_day_last.cpp b/test/test_chrono_month_day_last.cpp index ec9b6ae4..f47792c7 100644 --- a/test/test_chrono_month_day_last.cpp +++ b/test/test_chrono_month_day_last.cpp @@ -84,6 +84,19 @@ namespace CHECK_TRUE(month_day_last_october.ok()); CHECK_TRUE(month_day_last_november.ok()); CHECK_TRUE(month_day_last_december.ok()); + + CHECK_EQUAL(31, month_day_last_january.day()); + CHECK_EQUAL(29, month_day_last_february.day()); + CHECK_EQUAL(31, month_day_last_march.day()); + CHECK_EQUAL(30, month_day_last_april.day()); + CHECK_EQUAL(31, month_day_last_may.day()); + CHECK_EQUAL(30, month_day_last_june.day()); + CHECK_EQUAL(31, month_day_last_july.day()); + CHECK_EQUAL(31, month_day_last_august.day()); + CHECK_EQUAL(30, month_day_last_september.day()); + CHECK_EQUAL(31, month_day_last_october.day()); + CHECK_EQUAL(30, month_day_last_november.day()); + CHECK_EQUAL(31, month_day_last_december.day()); } //************************************************************************* diff --git a/test/test_chrono_operators.cpp b/test/test_chrono_operators.cpp index 30e398d3..f9fca7ff 100644 --- a/test/test_chrono_operators.cpp +++ b/test/test_chrono_operators.cpp @@ -37,28 +37,254 @@ SOFTWARE. #include #include -// Set to 0 to reference against std::chrono -#define ETL_USING_ETL_CHRONO 1 - -#if ETL_USING_ETL_CHRONO - #define Chrono etl::chrono -#else - #if ETL_USING_CPP20 - #include - #define Chrono std::chrono - #else - #error std::chrono not supported - #endif -#endif +using namespace etl::literals::chrono_literals; namespace { SUITE(test_chrono_operators) { //************************************************************************* - TEST(test_operator_for_year_month) + TEST(test_construction_operator_for_month_day) { + etl::chrono::month_day md1 = etl::chrono::January / etl::chrono::day(2); + etl::chrono::month_day md2 = etl::chrono::February / 3; + etl::chrono::month_day md3 = 3 / etl::chrono::day(4); + etl::chrono::month_day md4 = etl::chrono::day(5) / etl::chrono::April; + etl::chrono::month_day md5 = etl::chrono::day(6) / 5; + CHECK_EQUAL(etl::chrono::January, md1.month()); + CHECK_EQUAL(etl::chrono::day(2), md1.day()); + + CHECK_EQUAL(etl::chrono::February, md2.month()); + CHECK_EQUAL(etl::chrono::day(3), md2.day()); + + CHECK_EQUAL(etl::chrono::March, md3.month()); + CHECK_EQUAL(etl::chrono::day(4), md3.day()); + + CHECK_EQUAL(etl::chrono::April, md4.month()); + CHECK_EQUAL(etl::chrono::day(5), md4.day()); + + CHECK_EQUAL(etl::chrono::May, md5.month()); + CHECK_EQUAL(etl::chrono::day(6), md5.day()); + } + + //************************************************************************* + TEST(test_construction_operator_for_month_day_last) + { + etl::chrono::month_day_last mdl1 = etl::chrono::January / etl::chrono::last; + etl::chrono::month_day_last mdl2 = 2 / etl::chrono::last; + etl::chrono::month_day_last mdl3 = etl::chrono::last / etl::chrono::March; + etl::chrono::month_day_last mdl4 = etl::chrono::last / 4; + + CHECK_EQUAL(etl::chrono::January, mdl1.month()); + CHECK_EQUAL(etl::chrono::February, mdl2.month()); + CHECK_EQUAL(etl::chrono::March, mdl3.month()); + CHECK_EQUAL(etl::chrono::April, mdl4.month()); + } + + //************************************************************************* + TEST(test_construction_operator_for_month_weekday) + { + etl::chrono::month_weekday mwd1 = etl::chrono::January / etl::chrono::weekday_indexed(etl::chrono::Monday, 0); + etl::chrono::month_weekday mwd2 = 2 / etl::chrono::weekday_indexed(etl::chrono::Wednesday, 1); + etl::chrono::month_weekday mwd3 = etl::chrono::weekday_indexed(etl::chrono::Friday, 2) / etl::chrono::March; + etl::chrono::month_weekday mwd4 = etl::chrono::weekday_indexed(etl::chrono::Sunday, 3) / 4; + + CHECK_EQUAL(etl::chrono::January, mwd1.month()); + CHECK_EQUAL(etl::chrono::weekday_indexed(etl::chrono::Monday, 0).weekday().c_encoding(), + mwd1.weekday_indexed().weekday().c_encoding()); + CHECK_EQUAL(etl::chrono::weekday_indexed(etl::chrono::Monday, 0).index(), + mwd1.weekday_indexed().index()); + + CHECK_EQUAL(etl::chrono::February, mwd2.month()); + CHECK_EQUAL(etl::chrono::weekday_indexed(etl::chrono::Wednesday, 1).weekday().c_encoding(), + mwd2.weekday_indexed().weekday().c_encoding()); + CHECK_EQUAL(etl::chrono::weekday_indexed(etl::chrono::Wednesday, 1).index(), + mwd2.weekday_indexed().index()); + + + CHECK_EQUAL(etl::chrono::March, mwd3.month()); + CHECK_EQUAL(etl::chrono::weekday_indexed(etl::chrono::Friday, 2).weekday().c_encoding(), + mwd3.weekday_indexed().weekday().c_encoding()); + CHECK_EQUAL(etl::chrono::weekday_indexed(etl::chrono::Friday, 2).index(), + mwd3.weekday_indexed().index()); + + CHECK_EQUAL(etl::chrono::April, mwd4.month()); + CHECK_EQUAL(etl::chrono::weekday_indexed(etl::chrono::Sunday, 3).weekday().c_encoding(), + mwd4.weekday_indexed().weekday().c_encoding()); + CHECK_EQUAL(etl::chrono::weekday_indexed(etl::chrono::Sunday, 3).index(), + mwd4.weekday_indexed().index()); + } + + //************************************************************************* + TEST(test_construction_operator_for_month_weekday_last) + { + etl::chrono::month_weekday_last mdl1 = etl::chrono::January / etl::chrono::weekday_last(etl::chrono::Monday); + etl::chrono::month_weekday_last mdl2 = 2 / etl::chrono::weekday_last(etl::chrono::Tuesday); + etl::chrono::month_weekday_last mdl3 = etl::chrono::weekday_last(etl::chrono::Wednesday) / etl::chrono::March; + etl::chrono::month_weekday_last mdl4 = etl::chrono::weekday_last(etl::chrono::Thursday) / 4; + + CHECK_EQUAL(etl::chrono::January, mdl1.month()); + CHECK_EQUAL(etl::chrono::Monday.c_encoding(), mdl1.weekday_last().weekday().c_encoding()); + CHECK_EQUAL(etl::chrono::February, mdl2.month()); + CHECK_EQUAL(etl::chrono::Tuesday.c_encoding(), mdl2.weekday_last().weekday().c_encoding()); + CHECK_EQUAL(etl::chrono::March, mdl3.month()); + CHECK_EQUAL(etl::chrono::Wednesday.c_encoding(), mdl3.weekday_last().weekday().c_encoding()); + CHECK_EQUAL(etl::chrono::April, mdl4.month()); + CHECK_EQUAL(etl::chrono::Thursday.c_encoding(), mdl4.weekday_last().weekday().c_encoding()); + } + + //************************************************************************* + TEST(test_construction_operator_for_year_month) + { + etl::chrono::year_month ym1 = 2000_year / etl::chrono::April; + etl::chrono::year_month ym2 = 2001_year / 5; + + CHECK_EQUAL(2000_year, ym1.year()); + CHECK_EQUAL(etl::chrono::April, ym1.month()); + + CHECK_EQUAL(2001_year, ym2.year()); + CHECK_EQUAL(etl::chrono::May, ym2.month()); + } + + //************************************************************************* + TEST(test_construction_operator_for_year_month_day) + { + etl::chrono::year_month_day ymd1 = etl::chrono::year_month(etl::chrono::year(2000), etl::chrono::January) / etl::chrono::day(1); + etl::chrono::year_month_day ymd2 = etl::chrono::year_month(etl::chrono::year(2001), etl::chrono::February) / 2; + etl::chrono::year_month_day ymd3 = etl::chrono::year(2002) / etl::chrono::month_day(etl::chrono::March, etl::chrono::day(3)); + etl::chrono::year_month_day ymd4 = 2003 / etl::chrono::month_day(etl::chrono::April, etl::chrono::day(4)); + etl::chrono::year_month_day ymd5 = etl::chrono::month_day(etl::chrono::May, etl::chrono::day(5)) / etl::chrono::year(2004); + etl::chrono::year_month_day ymd6 = etl::chrono::month_day(etl::chrono::June, etl::chrono::day(6)) / 2005; + + CHECK_EQUAL(etl::chrono::year(2000), ymd1.year()); + CHECK_EQUAL(etl::chrono::January, ymd1.month()); + CHECK_EQUAL(etl::chrono::day(1), ymd1.day()); + + CHECK_EQUAL(etl::chrono::year(2001), ymd2.year()); + CHECK_EQUAL(etl::chrono::February, ymd2.month()); + CHECK_EQUAL(etl::chrono::day(2), ymd2.day()); + + CHECK_EQUAL(etl::chrono::year(2002), ymd3.year()); + CHECK_EQUAL(etl::chrono::March, ymd3.month()); + CHECK_EQUAL(etl::chrono::day(3), ymd3.day()); + + CHECK_EQUAL(etl::chrono::year(2003), ymd4.year()); + CHECK_EQUAL(etl::chrono::April, ymd4.month()); + CHECK_EQUAL(etl::chrono::day(4), ymd4.day()); + + CHECK_EQUAL(etl::chrono::year(2004), ymd5.year()); + CHECK_EQUAL(etl::chrono::May, ymd5.month()); + CHECK_EQUAL(etl::chrono::day(5), ymd5.day()); + + CHECK_EQUAL(etl::chrono::year(2005), ymd6.year()); + CHECK_EQUAL(etl::chrono::June, ymd6.month()); + CHECK_EQUAL(etl::chrono::day(6), ymd6.day()); + } + + //************************************************************************* + TEST(test_construction_operator_for_year_month_day_last) + { + etl::chrono::year_month_day_last ymdl1 = etl::chrono::year_month(etl::chrono::year(2000), etl::chrono::January) / etl::chrono::last; + etl::chrono::year_month_day_last ymdl2 = etl::chrono::year(2001) / etl::chrono::month_day_last(etl::chrono::February); + etl::chrono::year_month_day_last ymdl3 = 2002 / etl::chrono::month_day_last(etl::chrono::March); + etl::chrono::year_month_day_last ymdl4 = etl::chrono::month_day_last(etl::chrono::April) / etl::chrono::year(2003); + etl::chrono::year_month_day_last ymdl5 = etl::chrono::month_day_last(etl::chrono::May) / 2004; + + CHECK_EQUAL(etl::chrono::year(2000), ymdl1.year()); + CHECK_EQUAL(etl::chrono::January, ymdl1.month()); + CHECK_EQUAL(etl::chrono::month_day_last(etl::chrono::January).day(), ymdl1.day()); + CHECK_TRUE(etl::chrono::month_day_last(etl::chrono::January) == ymdl1.month_day_last()); + + CHECK_EQUAL(etl::chrono::year(2001), ymdl2.year()); + CHECK_EQUAL(etl::chrono::February, ymdl2.month()); + CHECK_EQUAL(etl::chrono::month_day_last(etl::chrono::February).day(), ymdl2.day()); + CHECK_TRUE(etl::chrono::month_day_last(etl::chrono::February) == ymdl2.month_day_last()); + + CHECK_EQUAL(etl::chrono::year(2002), ymdl3.year()); + CHECK_EQUAL(etl::chrono::March, ymdl3.month()); + CHECK_EQUAL(etl::chrono::month_day_last(etl::chrono::March).day(), ymdl3.day()); + CHECK_TRUE(etl::chrono::month_day_last(etl::chrono::March) == ymdl3.month_day_last()); + + CHECK_EQUAL(etl::chrono::year(2003), ymdl4.year()); + CHECK_EQUAL(etl::chrono::April, ymdl4.month()); + CHECK_EQUAL(etl::chrono::month_day_last(etl::chrono::April).day(), ymdl4.day()); + CHECK_TRUE(etl::chrono::month_day_last(etl::chrono::April) == ymdl4.month_day_last()); + + CHECK_EQUAL(etl::chrono::year(2004), ymdl5.year()); + CHECK_EQUAL(etl::chrono::May, ymdl5.month()); + CHECK_EQUAL(etl::chrono::month_day_last(etl::chrono::May).day(), ymdl5.day()); + CHECK_TRUE(etl::chrono::month_day_last(etl::chrono::May) == ymdl5.month_day_last()); + } + + //************************************************************************* + TEST(test_construction_operator_for_year_month_weekday) + { + etl::chrono::year_month_weekday ymwd1 = etl::chrono::year_month(etl::chrono::year(2000), etl::chrono::January) / etl::chrono::weekday_indexed(etl::chrono::Monday, 0); + etl::chrono::year_month_weekday ymwd2 = etl::chrono::year(2001) / etl::chrono::month_weekday(etl::chrono::February, etl::chrono::weekday_indexed(etl::chrono::Tuesday, 1)); + etl::chrono::year_month_weekday ymwd3 = 2002 / etl::chrono::month_weekday(etl::chrono::March, etl::chrono::weekday_indexed(etl::chrono::Wednesday, 2)); + etl::chrono::year_month_weekday ymwd4 = etl::chrono::month_weekday(etl::chrono::April, etl::chrono::weekday_indexed(etl::chrono::Thursday, 3)) / etl::chrono::year(2003); + etl::chrono::year_month_weekday ymwd5 = etl::chrono::month_weekday(etl::chrono::May, etl::chrono::weekday_indexed(etl::chrono::Friday, 4)) / 2004; + + CHECK_EQUAL(etl::chrono::year(2000), ymwd1.year()); + CHECK_EQUAL(etl::chrono::January, ymwd1.month()); + CHECK_EQUAL(etl::chrono::Monday.c_encoding(), ymwd1.weekday().c_encoding()); + CHECK_EQUAL(etl::chrono::Monday.c_encoding(), ymwd1.weekday_indexed().weekday().c_encoding()); + CHECK_EQUAL(0, ymwd1.weekday_indexed().index()); + + CHECK_EQUAL(etl::chrono::year(2001), ymwd2.year()); + CHECK_EQUAL(etl::chrono::February, ymwd2.month()); + CHECK_EQUAL(etl::chrono::Tuesday.c_encoding(), ymwd2.weekday().c_encoding()); + CHECK_EQUAL(etl::chrono::Tuesday.c_encoding(), ymwd2.weekday_indexed().weekday().c_encoding()); + CHECK_EQUAL(1, ymwd2.weekday_indexed().index()); + + CHECK_EQUAL(etl::chrono::year(2002), ymwd3.year()); + CHECK_EQUAL(etl::chrono::March, ymwd3.month()); + CHECK_EQUAL(etl::chrono::Wednesday.c_encoding(), ymwd3.weekday().c_encoding()); + CHECK_EQUAL(etl::chrono::Wednesday.c_encoding(), ymwd3.weekday_indexed().weekday().c_encoding()); + CHECK_EQUAL(2, ymwd3.weekday_indexed().index()); + + CHECK_EQUAL(etl::chrono::year(2003), ymwd4.year()); + CHECK_EQUAL(etl::chrono::April, ymwd4.month()); + CHECK_EQUAL(etl::chrono::Thursday.c_encoding(), ymwd4.weekday().c_encoding()); + CHECK_EQUAL(etl::chrono::Thursday.c_encoding(), ymwd4.weekday_indexed().weekday().c_encoding()); + CHECK_EQUAL(3, ymwd4.weekday_indexed().index()); + + CHECK_EQUAL(etl::chrono::year(2004), ymwd5.year()); + CHECK_EQUAL(etl::chrono::May, ymwd5.month()); + CHECK_EQUAL(etl::chrono::Friday.c_encoding(), ymwd5.weekday().c_encoding()); + CHECK_EQUAL(etl::chrono::Friday.c_encoding(), ymwd5.weekday_indexed().weekday().c_encoding()); + CHECK_EQUAL(4, ymwd5.weekday_indexed().index()); + } + + //************************************************************************* + TEST(test_construction_operator_for_year_month_weekday_last) + { + etl::chrono::year_month_weekday_last ymdl1 = etl::chrono::year_month(etl::chrono::year(2000), etl::chrono::January) / etl::chrono::weekday_last(etl::chrono::Monday); + etl::chrono::year_month_weekday_last ymdl2 = etl::chrono::year(2001) / etl::chrono::month_weekday_last(etl::chrono::February, etl::chrono::weekday_last(etl::chrono::Tuesday)); + etl::chrono::year_month_weekday_last ymdl3 = 2002 / etl::chrono::month_weekday_last(etl::chrono::March, etl::chrono::weekday_last(etl::chrono::Wednesday)); + etl::chrono::year_month_weekday_last ymdl4 = etl::chrono::month_weekday_last(etl::chrono::April, etl::chrono::weekday_last(etl::chrono::Thursday)) / etl::chrono::year(2003); + etl::chrono::year_month_weekday_last ymdl5 = etl::chrono::month_weekday_last(etl::chrono::May, etl::chrono::weekday_last(etl::chrono::Friday))/ 2004; + + CHECK_EQUAL(etl::chrono::year(2000), ymdl1.year()); + CHECK_EQUAL(etl::chrono::January, ymdl1.month()); + CHECK_EQUAL(etl::chrono::weekday_last(etl::chrono::Monday).weekday().c_encoding(), ymdl1.weekday().c_encoding()); + + CHECK_EQUAL(etl::chrono::year(2001), ymdl2.year()); + CHECK_EQUAL(etl::chrono::February, ymdl2.month()); + CHECK_EQUAL(etl::chrono::weekday_last(etl::chrono::Tuesday).weekday().c_encoding(), ymdl2.weekday().c_encoding()); + + CHECK_EQUAL(etl::chrono::year(2002), ymdl3.year()); + CHECK_EQUAL(etl::chrono::March, ymdl3.month()); + CHECK_EQUAL(etl::chrono::weekday_last(etl::chrono::Wednesday).weekday().c_encoding(), ymdl3.weekday().c_encoding()); + + CHECK_EQUAL(etl::chrono::year(2003), ymdl4.year()); + CHECK_EQUAL(etl::chrono::April, ymdl4.month()); + CHECK_EQUAL(etl::chrono::weekday_last(etl::chrono::Thursday).weekday().c_encoding(), ymdl4.weekday().c_encoding()); + + CHECK_EQUAL(etl::chrono::year(2004), ymdl5.year()); + CHECK_EQUAL(etl::chrono::May, ymdl5.month()); + CHECK_EQUAL(etl::chrono::weekday_last(etl::chrono::Friday).weekday().c_encoding(), ymdl5.weekday().c_encoding()); } }; -} +} \ No newline at end of file diff --git a/test/test_chrono_year.cpp b/test/test_chrono_year.cpp index 70c17c8a..90f909a6 100644 --- a/test/test_chrono_year.cpp +++ b/test/test_chrono_year.cpp @@ -243,7 +243,7 @@ namespace { for (int i = -32767; i <= 32767; ++i) { - bool is_leap = ((i % 4) == 0) && ((i % 400) != 0); + bool is_leap = ((i % 4) == 0) && (((i % 100) != 0) || ((i % 400) == 0)); etl::chrono::year year(i); diff --git a/test/vs2022/etl.vcxproj b/test/vs2022/etl.vcxproj index af492705..8489c79f 100644 --- a/test/vs2022/etl.vcxproj +++ b/test/vs2022/etl.vcxproj @@ -3195,9 +3195,13 @@ + + + + @@ -8472,6 +8476,7 @@ + diff --git a/test/vs2022/etl.vcxproj.filters b/test/vs2022/etl.vcxproj.filters index 02a49851..7dea846b 100644 --- a/test/vs2022/etl.vcxproj.filters +++ b/test/vs2022/etl.vcxproj.filters @@ -1497,6 +1497,18 @@ ETL\Private\chrono + + ETL\Private\chrono + + + ETL\Private\chrono + + + ETL\Private\chrono + + + ETL\Private\chrono + @@ -3551,6 +3563,9 @@ Tests\Chrono + + Tests\Chrono +