Merge branch 'feature/add-time-date-classes' into development

# Conflicts:
#	include/etl/tuple.h
#	test/vs2022/etl.vcxproj.filters
This commit is contained in:
John Wellbelove 2025-05-14 19:23:21 +01:00
commit 7b603e201c
52 changed files with 10981 additions and 414 deletions

3
.gitignore vendored
View File

@ -397,3 +397,6 @@ test/syntax_check/bgcc
test/syntax_check/bclang
test/vs2022/Debug Clang C++20
test/vs2022/Debug MSVC C++20 - Forve C++03 - No virtual messages
test/reflog.txt
test/etl_error_handler/assert_function/build-make
test/syntax_check/bgcc

92
include/etl/chrono.h Normal file
View File

@ -0,0 +1,92 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 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_CHRONO_INCLUDED
#define ETL_CHRONO_INCLUDED
#define ETL_IN_CHRONO_H
#include "platform.h"
#if ETL_NOT_USING_CPP11 && !defined(ETL_IN_UNIT_TEST)
#error NOT SUPPORTED FOR C++03 OR BELOW
#endif
#if ETL_USING_CPP11
#include "type_traits.h"
#include "integral_limits.h"
#include "string_view.h"
#include "hash.h"
#include <stdint.h>
#include <time.h>
namespace etl
{
namespace chrono
{
template <typename TRep>
struct treat_as_floating_point : etl::is_floating_point<TRep>
{
};
#if ETL_USING_CPP17
template <typename TRep>
constexpr bool treat_as_floating_point_v = treat_as_floating_point<TRep>::value;
#endif
}
// Use the same type as defined in time.h.
using time_t = ::time_t;
}
#include "private/chrono/last_spec.h"
#include "private/chrono/duration.h"
#include "private/chrono/time_point.h"
#include "private/chrono/clocks.h"
#include "private/chrono/day.h"
#include "private/chrono/weekday.h"
#include "private/chrono/month.h"
#include "private/chrono/month_day.h"
#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/time_zone.h"
#endif
#undef ETL_IN_CHRONO_H
#endif

View File

@ -37,6 +37,22 @@ SOFTWARE.
namespace etl
{
//***************************************************************************
// Greatest Common Divisor.
// Compile time.
//***************************************************************************
template <intmax_t A, intmax_t B>
struct gcd_const
{
static ETL_CONSTANT intmax_t value = gcd_const<B, A % B>::value;
};
template <intmax_t A>
struct gcd_const<A, 0>
{
static ETL_CONSTANT intmax_t value = A;
};
//***************************************************************************
// Greatest Common Divisor.
// For unsigned types.

View File

@ -2448,6 +2448,21 @@ typedef integral_constant<bool, true> true_type;
template <typename T, typename... TTypes>
inline constexpr size_t count_of_v = etl::count_of<T, TTypes...>::value;
#endif
#if ETL_USING_CPP11
//*********************************************
/// is_specialization
template <typename T, template <typename...> class Template>
struct is_specialization : etl::false_type {};
template <template <typename...> class Template, typename... TArgs>
struct is_specialization<Template<TArgs...>, Template> : etl::true_type {};
#endif
#if ETL_USING_CPP17
template <typename T, template <typename...> class Template>
inline constexpr bool is_specialization_v = etl::is_specialization<T, Template>::value;
#endif
}
// Helper macros

View File

@ -159,8 +159,8 @@ namespace etl
/// Specialisation for signed char.
///\ingroup hash
//***************************************************************************
template<> struct
hash<signed char>
template <>
struct hash<signed char>
{
ETL_STATIC_ASSERT(sizeof(size_t) >= sizeof(signed char), "size_t smaller than type");

View File

@ -38,6 +38,16 @@ SOFTWARE.
namespace etl
{
//***************************************************************************
// Least Common Multiple.
// Compile time.
//***************************************************************************
template <intmax_t A, intmax_t B>
struct lcm_const
{
static ETL_CONSTANT intmax_t value = (A / gcd_const<A, B>::value) * B;
};
//***************************************************************************
// Least Common Multiple.
// For unsigned types.

View File

@ -0,0 +1,192 @@
///\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
#if !defined(ETL_CHRONO_SYSTEM_CLOCK_DURATION)
#define ETL_CHRONO_SYSTEM_CLOCK_DURATION etl::chrono::nanoseconds
#endif
#if !defined(ETL_CHRONO_SYSTEM_CLOCK_IS_STEADY)
#define ETL_CHRONO_SYSTEM_CLOCK_IS_STEADY true
#endif
#if !defined(ETL_CHRONO_HIGH_RESOLUTION_CLOCK_DURATION)
#define ETL_CHRONO_HIGH_RESOLUTION_CLOCK_DURATION etl::chrono::nanoseconds
#endif
#if !defined(ETL_CHRONO_HIGH_RESOLUTION_CLOCK_IS_STEADY)
#define ETL_CHRONO_HIGH_RESOLUTION_CLOCK_IS_STEADY true
#endif
#if !defined(ETL_CHRONO_STEADY_CLOCK_DURATION)
#define ETL_CHRONO_STEADY_CLOCK_DURATION etl::chrono::nanoseconds
#endif
extern "C" ETL_CHRONO_SYSTEM_CLOCK_DURATION::rep etl_get_system_clock();
extern "C" ETL_CHRONO_HIGH_RESOLUTION_CLOCK_DURATION::rep etl_get_high_resolution_clock();
extern "C" ETL_CHRONO_STEADY_CLOCK_DURATION::rep etl_get_steady_clock();
namespace etl
{
namespace chrono
{
namespace private_chrono
{
template <bool b>
struct is_steady_trait
{
static ETL_CONSTANT bool is_steady = b;
};
template <bool b>
ETL_CONSTANT bool is_steady_trait<b>::is_steady;
}
//*************************************************************************
/// The system clock time
//*************************************************************************
class system_clock : public private_chrono::is_steady_trait<ETL_CHRONO_SYSTEM_CLOCK_IS_STEADY>
{
public:
using duration = ETL_CHRONO_SYSTEM_CLOCK_DURATION;
using rep = duration::rep;
using period = duration::period;
using time_point = etl::chrono::time_point<system_clock, duration>;
//*************************************************************************
static time_point now() ETL_NOEXCEPT
{
return time_point(duration(etl_get_system_clock()));
}
//*************************************************************************
static etl::time_t to_time_t(const time_point& t) ETL_NOEXCEPT
{
// Get the duration since the epoch
duration dur = t.time_since_epoch();
// Convert the duration to seconds
return dur.count() / duration::period::den;
}
//*************************************************************************
static time_point from_time_t(etl::time_t t) ETL_NOEXCEPT
{
// Convert seconds to the appropriate duration
duration dur(t * duration::period::den);
// Construct and return the time_point
return time_point(dur);
}
};
//*************************************************************************
/// The high resolution clock time
//*************************************************************************
class high_resolution_clock : public private_chrono::is_steady_trait<ETL_CHRONO_HIGH_RESOLUTION_CLOCK_IS_STEADY>
{
public:
using duration = ETL_CHRONO_HIGH_RESOLUTION_CLOCK_DURATION;
using rep = duration::rep;
using period = duration::period;
using time_point = etl::chrono::time_point<high_resolution_clock, duration>;
//*************************************************************************
static time_point now() ETL_NOEXCEPT
{
return time_point(duration(etl_get_high_resolution_clock()));
}
};
//*************************************************************************
/// The steady clock time
//*************************************************************************
class steady_clock : public private_chrono::is_steady_trait<true>
{
public:
using duration = ETL_CHRONO_STEADY_CLOCK_DURATION;
using rep = duration::rep;
using period = duration::period;
using time_point = etl::chrono::time_point<steady_clock, duration>;
//*************************************************************************
static time_point now() ETL_NOEXCEPT
{
return time_point(duration(etl_get_steady_clock()));
}
};
//***************************************************************************
/// System time
//***************************************************************************
template<class Duration>
using sys_time = etl::chrono::time_point<etl::chrono::system_clock, Duration> ;
using sys_seconds = sys_time<etl::chrono::seconds>;
using sys_days = sys_time<etl::chrono::days>;
//***************************************************************************
/// Local time
//***************************************************************************
struct local_t
{
};
template <typename TDuration>
using local_time = etl::chrono::time_point<etl::chrono::local_t, TDuration>;
using local_seconds = local_time<etl::chrono::seconds>;
using local_days = local_time<etl::chrono::days>;
//*************************************************************************
/// Cast a time point from one clock to another.
/// This implementation assumes all clock epochs are the same.
//*************************************************************************
template <typename TToClock, typename TFromClock, typename TFromDuration>
ETL_CONSTEXPR14 etl::chrono::time_point<TToClock, typename TToClock::duration>
clock_cast(const etl::chrono::time_point<TFromClock, TFromDuration>& from_time_point) ETL_NOEXCEPT
{
// Get the duration since the epoch of the FromClock
auto from_duration = from_time_point.time_since_epoch();
// Convert the duration to the ToClock's duration type
auto to_duration = etl::chrono::duration_cast<typename TToClock::duration>(from_duration);
// Construct and return the time_point for the ToClock
return etl::chrono::time_point<TToClock, typename TToClock::duration>(to_duration);
}
}
}

View File

@ -0,0 +1,344 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 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
{
//***********************************************************************
/// day
//***********************************************************************
class day
{
public:
//***********************************************************************
/// Default constructor
//***********************************************************************
ETL_CONSTEXPR day() ETL_NOEXCEPT
: value(0)
{
}
//***********************************************************************
/// Construct from unsigned
//***********************************************************************
ETL_CONSTEXPR explicit day(unsigned value_) ETL_NOEXCEPT
: value(static_cast<unsigned char>(value_))
{
}
//***********************************************************************
/// Copy constructor
//***********************************************************************
ETL_CONSTEXPR 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;
}
//***********************************************************************
/// Pre-increment 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;
}
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::day& operator ++() ETL_NOEXCEPT
{
++value;
return *this;
}
//***********************************************************************
/// Post-increment operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::day operator ++(int) ETL_NOEXCEPT
{
const etl::chrono::day temp = *this;
++value;
return temp;
}
//***********************************************************************
/// Pre-decrement operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::day& operator --() ETL_NOEXCEPT
{
--value;
return *this;
}
//***********************************************************************
/// Post-decrement operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::day operator --(int) ETL_NOEXCEPT
{
const etl::chrono::day temp = *this;
--value;
return temp;
}
//***********************************************************************
/// Plus-equals operator adding etl::chrono::days
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::day& operator +=(const etl::chrono::days& ds) ETL_NOEXCEPT
{
value += static_cast<unsigned char>(ds.count());
return *this;
}
//***********************************************************************
/// Minus-equals operator subtracting etl::chrono::days
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::day& operator -=(const etl::chrono::days& ds) ETL_NOEXCEPT
{
value -= static_cast<unsigned char>(ds.count());
return *this;
}
//***********************************************************************
/// Returns <b>true</b> if the day is within the valid 1 to 31 range
//***********************************************************************
ETL_CONSTEXPR14 bool ok() const ETL_NOEXCEPT
{
return (value >= 1U) && (value <= 31U);
}
//***********************************************************************
/// Conversion operator to unsigned int
//***********************************************************************
ETL_CONSTEXPR14 operator unsigned() const ETL_NOEXCEPT
{
return static_cast<unsigned>(value);
}
//***********************************************************************
/// Compare day with another.
/// if day < other, returns -1;
/// else if day > other, returns 1;
/// else returns 0;
//***********************************************************************
ETL_CONSTEXPR14 int compare(const day& other) const ETL_NOEXCEPT
{
if (value < other.value) return -1;
if (value > other.value) return 1;
return 0;
}
//***********************************************************************
/// The minimum day value for which ok() will return <b>true</b>
//***********************************************************************
static ETL_CONSTEXPR etl::chrono::day min() ETL_NOEXCEPT
{
return etl::chrono::day(1);
}
//***********************************************************************
/// The maximum day value for which ok() will return <b>true</b>
//***********************************************************************
static ETL_CONSTEXPR etl::chrono::day max() ETL_NOEXCEPT
{
return etl::chrono::day(31);
}
private:
uint_least8_t value;
};
//***********************************************************************
/// Equality operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator ==(const etl::chrono::day& d1, const etl::chrono::day& d2) ETL_NOEXCEPT
{
return (static_cast<unsigned>(d1) == static_cast<unsigned>(d2));
}
//***********************************************************************
/// Inequality operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator !=(const etl::chrono::day& d1, const etl::chrono::day& d2) ETL_NOEXCEPT
{
return !(d1 == d2);
}
//***********************************************************************
/// Less-than operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator <(const etl::chrono::day& d1, const etl::chrono::day& d2) ETL_NOEXCEPT
{
return (static_cast<unsigned>(d1) < static_cast<unsigned>(d2));
}
//***********************************************************************
/// Less-than-or-equal operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator <=(const etl::chrono::day& d1, const etl::chrono::day& d2) ETL_NOEXCEPT
{
return (static_cast<unsigned>(d1) <= static_cast<unsigned>(d2));
}
//***********************************************************************
/// Greater-than operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator >(const etl::chrono::day& d1, const etl::chrono::day& d2) ETL_NOEXCEPT
{
return (static_cast<unsigned>(d1) > static_cast<unsigned>(d2));
}
//***********************************************************************
/// Greater-than-or-equal operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator >=(const etl::chrono::day& d1, const etl::chrono::day& d2) ETL_NOEXCEPT
{
return (static_cast<unsigned>(d1) >= static_cast<unsigned>(d2));
}
//***********************************************************************
/// Spaceship operator
//***********************************************************************
#if ETL_USING_CPP20
[[nodiscard]] inline constexpr auto operator <=>(const etl::chrono::day& d1, const etl::chrono::day& d2) noexcept
{
return (static_cast<unsigned>(d1) <=> static_cast<unsigned>(d2));
}
#endif
//***********************************************************************
/// Add etl::chrono::days to etl::chrono::day
///\return etl::chrono::day
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::day operator +(const etl::chrono::day& d, const etl::chrono::days& ds) ETL_NOEXCEPT
{
etl::chrono::day result(d);
result += ds;
return result;
}
//***********************************************************************
/// Add etl::chrono::day to etl::chrono::days
///\return etl::chrono::day
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::day operator +(const etl::chrono::days& ds, const etl::chrono::day& d) ETL_NOEXCEPT
{
etl::chrono::day result(d);
result += ds;
return result;
}
//***********************************************************************
/// Subtract etl::chrono::days from etl::chrono::day
///\return etl::chrono::day
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::day operator -(const etl::chrono::day& d, const etl::chrono::days& ds) ETL_NOEXCEPT
{
etl::chrono::day result(d);
result -= ds;
return result;
}
//***********************************************************************
/// Subtract etl::chrono::day from etl::chrono::day
///\return etl::chrono::days
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::days operator -(const etl::chrono::day& d1, const etl::chrono::day& d2) ETL_NOEXCEPT
{
return etl::chrono::days(static_cast<int>(static_cast<unsigned>(d1)) -
static_cast<int>(static_cast<unsigned>(d2)));
}
}
//*************************************************************************
/// Hash function for etl::chrono::day
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <>
struct hash<etl::chrono::day>
{
size_t operator()(const etl::chrono::day& d) const
{
unsigned value = d;
const uint8_t* p = reinterpret_cast<const uint8_t*>(&value);
return etl::private_hash::generic_hash<size_t>(p, p + sizeof(unsigned));
}
};
#endif
}
#if ETL_HAS_CHRONO_LITERALS_DAY
namespace etl
{
namespace literals
{
namespace chrono_literals
{
//***********************************************************************
/// Literal for days
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::day operator ""_day(unsigned long long d) noexcept
{
return etl::chrono::day(static_cast<unsigned>(d));
}
}
}
}
#endif

View File

@ -0,0 +1,813 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 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
#include "../../ratio.h"
#include "../../static_assert.h"
#include "../../limits.h"
#include "../../type_traits.h"
namespace etl
{
namespace chrono
{
namespace private_chrono
{
// Helper to find the greatest common divisor
template <intmax_t A, intmax_t B>
struct gcd
{
static ETL_CONSTANT intmax_t value = gcd<B, A % B>::value;
};
template <intmax_t A>
struct gcd<A, 0>
{
static ETL_CONSTANT intmax_t value = A;
};
// Helper to find the least common multiple
template <intmax_t A, intmax_t B>
struct lcm
{
static ETL_CONSTANT intmax_t value = (A / gcd<A, B>::value) * B;
};
}
//***********************************************************************
/// duration_values
//***********************************************************************
template <typename TRep>
struct duration_values
{
//***********************************************************************
static ETL_CONSTEXPR TRep zero() ETL_NOEXCEPT
{
return TRep(0);
}
//***********************************************************************
static ETL_CONSTEXPR TRep min() ETL_NOEXCEPT
{
return etl::numeric_limits<TRep>::min();
}
//***********************************************************************
static ETL_CONSTEXPR TRep max() ETL_NOEXCEPT
{
return etl::numeric_limits<TRep>::max();
}
};
template <typename TRep, typename TPeriod>
class duration;
template <typename TToDuration, typename TRep, typename TPeriod>
ETL_CONSTEXPR14 TToDuration duration_cast(const etl::chrono::duration<TRep, TPeriod>& d) ETL_NOEXCEPT;
//***********************************************************************
/// duration
//***********************************************************************
template <typename TRep, typename TPeriod = etl::ratio<1> >
class duration
{
public:
typedef TRep rep;
typedef typename TPeriod::type period;
//***********************************************************************
ETL_CONSTEXPR duration() ETL_NOEXCEPT
: value(0)
{
}
//***********************************************************************
ETL_CONSTEXPR duration(const etl::chrono::duration<TRep, TPeriod>& other) ETL_NOEXCEPT
: value(other.value)
{
}
//***********************************************************************
template <typename TRep2>
ETL_CONSTEXPR explicit duration(const TRep2& value_) ETL_NOEXCEPT
: value(static_cast<TRep>(value_))
{
}
//***********************************************************************
template <typename TRep2, typename TPeriod2, typename etl::enable_if<etl::ratio_divide<TPeriod2, TPeriod>::den == 1, int>::type = 0>
ETL_CONSTEXPR14 duration(const etl::chrono::duration<TRep2, TPeriod2>& other) ETL_NOEXCEPT
: value(etl::chrono::duration_cast<etl::chrono::duration<TRep, TPeriod> >(other).count())
{
ETL_STATIC_ASSERT(!(etl::is_integral<TRep>::value && etl::is_floating_point<TRep2>::value), "Cannot convert duration from floating point to integral");
}
//***********************************************************************
ETL_CONSTEXPR14
etl::chrono::duration<TRep, TPeriod> operator =(const etl::chrono::duration<TRep, TPeriod>& other) ETL_NOEXCEPT
{
value = other.count();
return *this;
}
//***********************************************************************
template <typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14
etl::chrono::duration<TRep, TPeriod> operator =(const etl::chrono::duration<TRep2, TPeriod2>& other) ETL_NOEXCEPT
{
value = etl::chrono::duration_cast<etl::chrono::duration<TRep, TPeriod> >(other).count();
return *this;
}
//***********************************************************************
ETL_CONSTEXPR14 TRep count() const ETL_NOEXCEPT
{
return value;
}
//***********************************************************************
ETL_CONSTEXPR14 etl::common_type_t<duration> operator +() const ETL_NOEXCEPT
{
return etl::common_type_t<duration>(*this);
}
//***********************************************************************
ETL_CONSTEXPR14 etl::common_type_t<duration> operator -() const ETL_NOEXCEPT
{
return etl::common_type_t<duration>(-value);
}
//***********************************************************************
static ETL_CONSTEXPR14 etl::chrono::duration<TRep, TPeriod> zero() ETL_NOEXCEPT
{
return etl::chrono::duration<TRep, TPeriod>(etl::chrono::duration_values<TRep>::zero());
}
//***********************************************************************
static ETL_CONSTEXPR14 etl::chrono::duration<TRep, TPeriod> min() ETL_NOEXCEPT
{
return etl::chrono::duration<TRep, TPeriod>(etl::chrono::duration_values<TRep>::min());
}
//***********************************************************************
static ETL_CONSTEXPR14 etl::chrono::duration<TRep, TPeriod> max() ETL_NOEXCEPT
{
return etl::chrono::duration<TRep, TPeriod>(etl::chrono::duration_values<TRep>::max());
}
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::duration<TRep, TPeriod> absolute() const ETL_NOEXCEPT
{
return etl::chrono::duration<TRep, TPeriod>(value < 0 ? -value : value);
}
//***********************************************************************
ETL_CONSTEXPR14 duration& operator ++() ETL_NOEXCEPT
{
++value;
return *this;
}
//***********************************************************************
ETL_CONSTEXPR14 duration operator ++(int) ETL_NOEXCEPT
{
duration temp(*this);
++value;
return temp;
}
//***********************************************************************
ETL_CONSTEXPR14 duration& operator --() ETL_NOEXCEPT
{
--value;
return *this;
}
//***********************************************************************
ETL_CONSTEXPR14 duration operator --(int) ETL_NOEXCEPT
{
duration temp(*this);
--value;
return temp;
}
//***********************************************************************
ETL_CONSTEXPR14 duration& operator +=(const duration<TRep, TPeriod>& d) ETL_NOEXCEPT
{
value += d.count();
return *this;
}
//***********************************************************************
ETL_CONSTEXPR14 duration& operator -=(const duration<TRep, TPeriod>& d) ETL_NOEXCEPT
{
value -= d.count();
return *this;
}
//***********************************************************************
ETL_CONSTEXPR14 duration& operator *=(const TRep& r) ETL_NOEXCEPT
{
value *= r;
return *this;
}
//***********************************************************************
ETL_CONSTEXPR14 duration& operator /=(const TRep& r) ETL_NOEXCEPT
{
value /= r;
return *this;
}
//***********************************************************************
ETL_CONSTEXPR14 duration& operator %=(const TRep& r) ETL_NOEXCEPT
{
value %= r;
return *this;
}
//***********************************************************************
ETL_CONSTEXPR14 duration& operator %=(const duration<TRep, TPeriod>& d) ETL_NOEXCEPT
{
value %= d.count();
return *this;
}
//***********************************************************************
/// Compare duration with another.
/// if duration < other, returns -1;
/// else if duration > other, returns 1;
/// else returns 0;
//***********************************************************************
template <typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14 int compare(const duration<TRep2, TPeriod2>& other) const ETL_NOEXCEPT
{
// Determine the common type of the two durations.
using common_duration = typename etl::common_type<etl::chrono::duration<TRep, TPeriod>, etl::chrono::duration<TRep2, TPeriod2>>::type;
common_duration lhs_converted = etl::chrono::duration_cast<common_duration>(*this);
common_duration rhs_converted = etl::chrono::duration_cast<common_duration>(other);
if (lhs_converted.count() < rhs_converted.count()) return -1;
if (lhs_converted.count() > rhs_converted.count()) return 1;
return 0;
}
private:
TRep value;
};
//***********************************************************************
/// Duration types
//***********************************************************************
#if (ETL_USING_64BIT_TYPES)
typedef etl::chrono::duration<int64_t, etl::nano> nanoseconds;
typedef etl::chrono::duration<int64_t, etl::micro> microseconds;
typedef etl::chrono::duration<int64_t, etl::milli> milliseconds;
typedef etl::chrono::duration<int64_t, etl::ratio<1U> > seconds;
#else
typedef etl::chrono::duration<int32_t, etl::nano> nanoseconds;
typedef etl::chrono::duration<int32_t, etl::micro> microseconds;
typedef etl::chrono::duration<int32_t, etl::milli> milliseconds;
typedef etl::chrono::duration<int32_t, etl::ratio<1U> > seconds;
#endif
typedef etl::chrono::duration<int32_t, etl::ratio<60U> > minutes;
typedef etl::chrono::duration<int32_t, etl::ratio<3600U> > hours;
typedef etl::chrono::duration<int32_t, etl::ratio<86400U> > days;
typedef etl::chrono::duration<int32_t, etl::ratio<604800U> > weeks;
typedef etl::chrono::duration<int32_t, etl::ratio<2629746U> > months;
typedef etl::chrono::duration<int32_t, etl::ratio<31556952U> > years;
//***********************************************************************
/// duration_cast
//***********************************************************************
template <typename TToDuration, typename TRep, typename TPeriod>
ETL_CONSTEXPR14 TToDuration duration_cast(const etl::chrono::duration<TRep, TPeriod>& d) ETL_NOEXCEPT
{
typedef TRep from_rep;
typedef TPeriod from_period;
typedef typename TToDuration::rep to_rep;
typedef typename TToDuration::period to_period;
typedef typename etl::ratio_divide<from_period, to_period> ratio_divide_t;
typedef typename etl::common_type<from_rep, to_rep, intmax_t>::type common_t;
common_t ct_count = static_cast<common_t>(d.count());
common_t ct_num = static_cast<common_t>(ratio_divide_t::type::num);
common_t ct_den = static_cast<common_t>(ratio_divide_t::type::den);
if ETL_IF_CONSTEXPR((from_period::num == to_period::num) && (from_period::den == to_period::den))
{
return TToDuration(static_cast<to_rep>(d.count()));
}
else if ETL_IF_CONSTEXPR(ratio_divide_t::num == 1)
{
return TToDuration(static_cast<to_rep>(ct_count / ct_den));
}
else if ETL_IF_CONSTEXPR(ratio_divide_t::den == 1)
{
return TToDuration(static_cast<to_rep>(ct_count * ct_num));
}
else
{
return TToDuration(static_cast<to_rep>((ct_count * ct_num) / ct_den));
}
}
template <typename T>
struct is_duration : etl::false_type {};
template <typename TRep, typename TPeriod>
struct is_duration<etl::chrono::duration<TRep, TPeriod>> : etl::true_type {};
}
//*************************************************************************
/// Hash function for etl::chrono::duration
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <typename TRep, typename TPeriod>
struct hash<etl::chrono::duration<TRep, TPeriod> >
{
ETL_CONSTEXPR14 size_t operator()(const etl::chrono::duration<TRep, TPeriod>& d) const ETL_NOEXCEPT
{
uint8_t buffer[sizeof(TRep) + sizeof(intmax_t) + sizeof(intmax_t)];
TRep value = d.count();
intmax_t num = TPeriod::num;
intmax_t den = TPeriod::den;
memcpy(buffer, &value, sizeof(TRep));
memcpy(buffer + sizeof(TRep), &num, sizeof(intmax_t));
memcpy(buffer + sizeof(TRep) + sizeof(intmax_t), &den, sizeof(intmax_t));
return etl::private_hash::generic_hash<size_t>(buffer, buffer + sizeof(TRep) + sizeof(intmax_t) + sizeof(intmax_t));
}
};
#endif
//***********************************************************************
/// Find the common type of two duration types.
//***********************************************************************
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
struct common_type<etl::chrono::duration<TRep1, TPeriod1>, etl::chrono::duration<TRep2, TPeriod2> >
{
private:
typedef typename etl::common_type<TRep1, TRep2>::type value_type;
typedef etl::ratio<etl::chrono::private_chrono::gcd<TPeriod1::num, TPeriod2::num>::value,
etl::chrono::private_chrono::lcm<TPeriod1::den, TPeriod2::den>::value> period_type;
public:
using type = etl::chrono::duration<value_type, period_type>;
};
//***********************************************************************
/// Check equality.
//***********************************************************************
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14 bool operator ==(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs) ETL_NOEXCEPT
{
typedef typename etl::common_type<etl::chrono::duration<TRep1, TPeriod1>, etl::chrono::duration<TRep2, TPeriod2> >::type common_t;
common_t l = etl::chrono::duration_cast<common_t>(lhs);
common_t r = etl::chrono::duration_cast<common_t>(rhs);
return l.count() == r.count();
}
//***********************************************************************
/// Check inequality.
//***********************************************************************
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14 bool operator !=(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs) ETL_NOEXCEPT
{
return !(lhs == rhs);
}
//***********************************************************************
/// Less-than.
//***********************************************************************
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14 bool operator <(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs) ETL_NOEXCEPT
{
typedef typename etl::common_type<etl::chrono::duration<TRep1, TPeriod1>, etl::chrono::duration<TRep2, TPeriod2> >::type common_t;
common_t l = etl::chrono::duration_cast<common_t>(lhs);
common_t r = etl::chrono::duration_cast<common_t>(rhs);
return l.count() < r.count();
}
//***********************************************************************
/// Less-than-or-equal.
//***********************************************************************
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14 bool operator <=(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs) ETL_NOEXCEPT
{
return !(rhs < lhs);
}
//***********************************************************************
/// Greater-than.
//***********************************************************************
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14 bool operator >(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs) ETL_NOEXCEPT
{
return rhs < lhs;
}
//***********************************************************************
/// Greater-than-or-equal.
//***********************************************************************
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14 bool operator >=(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs) ETL_NOEXCEPT
{
return !(lhs < rhs);
}
//***********************************************************************
/// Spaceship operator
//***********************************************************************
#if ETL_USING_CPP20
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
[[nodiscard]] constexpr auto operator <=>(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs) ETL_NOEXCEPT
{
typedef typename etl::common_type<etl::chrono::duration<TRep1, TPeriod1>, etl::chrono::duration<TRep2, TPeriod2> >::type common_t;
common_t l = etl::chrono::duration_cast<common_t>(lhs);
common_t r = etl::chrono::duration_cast<common_t>(rhs);
return (l.count() <=> r.count());
}
#endif
//***********************************************************************
/// Operator +
//***********************************************************************
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14 typename etl::common_type<etl::chrono::duration<TRep1, TPeriod1>, etl::chrono::duration<TRep2, TPeriod2> >::type
operator +(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs) ETL_NOEXCEPT
{
// Determine the common type of the two durations.
using common_duration = typename etl::common_type<etl::chrono::duration<TRep1, TPeriod1>, etl::chrono::duration<TRep2, TPeriod2>>::type;
// Convert both durations to the common type.
common_duration lhs_converted = etl::chrono::duration_cast<common_duration>(lhs);
common_duration rhs_converted = etl::chrono::duration_cast<common_duration>(rhs);
// Return the sum of the two converted durations.
return common_duration(lhs_converted.count() + rhs_converted.count());
}
//***********************************************************************
/// Operator -
//***********************************************************************
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14 typename etl::common_type<etl::chrono::duration<TRep1, TPeriod1>, etl::chrono::duration<TRep2, TPeriod2> >::type
operator -(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs) ETL_NOEXCEPT
{
// Determine the common type of the two durations.
using common_duration = typename etl::common_type<etl::chrono::duration<TRep1, TPeriod1>, etl::chrono::duration<TRep2, TPeriod2>>::type;
// Convert both durations to the common type.
common_duration lhs_converted = etl::chrono::duration_cast<common_duration>(lhs);
common_duration rhs_converted = etl::chrono::duration_cast<common_duration>(rhs);
// Return the difference of the two converted durations.
return common_duration(lhs_converted.count() - rhs_converted.count());
}
//***********************************************************************
/// Operator *
//***********************************************************************
template <typename TRep1, typename TPeriod1, typename TRep2>
ETL_CONSTEXPR14
typename enable_if<!etl::is_specialization<TRep2, etl::chrono::duration>::value, etl::chrono::duration<typename etl::common_type<TRep1, TRep2>::type, TPeriod1>>::type
operator *(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const TRep2& rhs) ETL_NOEXCEPT
{
using common_rep = typename etl::common_type<TRep1, TRep2>::type;
using result_duration = etl::chrono::duration<common_rep, TPeriod1>;
// Multiply the count of the duration by the scalar value
return result_duration(static_cast<common_rep>(lhs.count()) * static_cast<common_rep>(rhs));
}
//***********************************************************************
/// Operator *
//***********************************************************************
template <typename TRep1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14 etl::chrono::duration<typename etl::common_type<TRep1, TRep2>::type, TPeriod2>
operator *(const TRep1& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs) ETL_NOEXCEPT
{
using common_rep = typename etl::common_type<TRep1, TRep2>::type;
using result_duration = etl::chrono::duration<common_rep, TPeriod2>;
// Multiply the count of the duration by the scalar value
return result_duration(static_cast<common_rep>(rhs.count()) * static_cast<common_rep>(lhs));
}
//***********************************************************************
/// Operator /
//***********************************************************************
template <typename TRep1, typename TPeriod1, typename TRep2>
ETL_CONSTEXPR14
typename enable_if<!etl::is_specialization<TRep2, etl::chrono::duration>::value, etl::chrono::duration<typename etl::common_type<TRep1, TRep2>::type, TPeriod1>>::type
operator /(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const TRep2& rhs) ETL_NOEXCEPT
{
using common_rep = typename etl::common_type<TRep1, TRep2>::type;
using result_duration = etl::chrono::duration<common_rep, TPeriod1>;
// Divide the count of the duration by the scalar value
return result_duration(static_cast<common_rep>(lhs.count()) / static_cast<common_rep>(rhs));
}
//***********************************************************************
/// Operator /
//***********************************************************************
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14 typename etl::common_type<TRep1, TRep2>::type
operator /(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs) ETL_NOEXCEPT
{
// Determine the common type of the two durations.
using common_duration = typename etl::common_type<etl::chrono::duration<TRep1, TPeriod1>, etl::chrono::duration<TRep2, TPeriod2>>::type;
common_duration lhs_converted = etl::chrono::duration_cast<common_duration>(lhs);
common_duration rhs_converted = etl::chrono::duration_cast<common_duration>(rhs);
return typename etl::common_type<TRep1, TRep2>::type(lhs_converted.count() / rhs_converted.count());
}
//***********************************************************************
/// Operator %
//***********************************************************************
template <typename TRep1, typename TPeriod1, typename TRep2>
ETL_CONSTEXPR14
etl::chrono::duration<typename etl::common_type<TRep1, TRep2>::type, TPeriod1>
operator %(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const TRep2& rhs) ETL_NOEXCEPT
{
using common_rep = typename etl::common_type<TRep1, TRep2>::type;
using common_dur = etl::chrono::duration<common_rep, TPeriod1>;
// Mod the count of the duration by the scalar value
return common_dur(static_cast<common_rep>(lhs.count()) % rhs);
}
//***********************************************************************
/// Operator %
//***********************************************************************
template <typename TRep1, typename TPeriod1, typename TRep2, typename TPeriod2>
ETL_CONSTEXPR14
typename etl::common_type<etl::chrono::duration<TRep1, TPeriod1>, etl::chrono::duration<TRep2, TPeriod2>>::type
operator %(const etl::chrono::duration<TRep1, TPeriod1>& lhs,
const etl::chrono::duration<TRep2, TPeriod2>& rhs) ETL_NOEXCEPT
{
// Determine the common type of the two durations.
using common_duration = typename etl::common_type<etl::chrono::duration<TRep1, TPeriod1>, etl::chrono::duration<TRep2, TPeriod2>>::type;
common_duration lhs_converted = etl::chrono::duration_cast<common_duration>(lhs);
common_duration rhs_converted = etl::chrono::duration_cast<common_duration>(rhs);
return common_duration(lhs_converted.count() % rhs_converted.count());
}
//***********************************************************************
/// Rounds down a duration to the nearest lower precision.
//***********************************************************************
template <typename TToDuration, typename TRep, typename TPeriod>
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_specialization<TToDuration, etl::chrono::duration>::value, TToDuration>::type
floor(const etl::chrono::duration<TRep, TPeriod>& d) ETL_NOEXCEPT
{
TToDuration result = etl::chrono::duration_cast<TToDuration>(d);
if (result > d)
{
--result;
}
return result;
}
//***********************************************************************
/// Rounds up a duration to the nearest higher precision.
//***********************************************************************
template <typename TToDuration, typename TRep, typename TPeriod>
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_specialization<TToDuration, etl::chrono::duration>::value, TToDuration>::type
ceil(const etl::chrono::duration<TRep, TPeriod>& d) ETL_NOEXCEPT
{
TToDuration result = etl::chrono::duration_cast<TToDuration>(d);
if (result < d)
{
++result;
}
return result;
}
//***********************************************************************
/// Rounds a duration to the nearest precision.
/// If the duration is exactly halfway, it rounds away from zero.
//***********************************************************************
template <typename TToDuration, typename TRep, typename TPeriod>
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_specialization<TToDuration, etl::chrono::duration>::value, TToDuration>::type
round(const etl::chrono::duration<TRep, TPeriod>& d) ETL_NOEXCEPT
{
// Convert the input duration to the target duration type
TToDuration lower = floor<TToDuration>(d);
TToDuration upper = ceil<TToDuration>(lower + TToDuration(1));
auto lower_diff = d - lower;
auto upper_diff = upper - d;
if ((lower_diff < upper_diff) ||
((lower_diff == upper_diff) &&
etl::is_even(lower.count())))
{
return lower;
}
else
{
return upper;
}
}
//***********************************************************************
/// Returns the absolute value of a duration.
//***********************************************************************
template<class TRep, class TPeriod, typename = etl::enable_if_t<etl::numeric_limits<TRep>::is_signed>>
ETL_CONSTEXPR14 etl::chrono::duration<TRep, TPeriod> abs(etl::chrono::duration<TRep, TPeriod> d) ETL_NOEXCEPT
{
return d.count() >= 0 ? +d : -d;
}
}
#if ETL_HAS_CHRONO_LITERALS_DURATION
namespace etl
{
namespace literals
{
namespace chrono_literals
{
//***********************************************************************
/// Literal for hours duration
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::hours operator ""_hours(unsigned long long h) ETL_NOEXCEPT
{
return etl::chrono::hours(static_cast<etl::chrono::hours::rep>(h));
}
//***********************************************************************
/// Literal for floating point hours duration
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::duration<double, ratio<3600>> operator""_h(long double h) ETL_NOEXCEPT
{
return etl::chrono::duration<double, ratio<3600>>(h);
}
//***********************************************************************
/// Literal for minutes duration
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::minutes operator ""_minutes(unsigned long long m) ETL_NOEXCEPT
{
return etl::chrono::minutes(static_cast<etl::chrono::minutes::rep>(m));
}
//***********************************************************************
/// Literal for floating point minutes duration
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::duration<double, ratio<60>> operator ""_minutes(long double m) ETL_NOEXCEPT
{
return etl::chrono::duration<double, ratio<60>>(m);
}
//***********************************************************************
/// Literal for seconds duration
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::seconds operator ""_seconds(unsigned long long s) ETL_NOEXCEPT
{
return etl::chrono::seconds(static_cast<etl::chrono::seconds::rep>(s));
}
//***********************************************************************
/// Literal for floating point seconds duration
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::duration<double> operator ""_seconds(long double s) ETL_NOEXCEPT
{
return etl::chrono::duration<double>(s);
}
//***********************************************************************
/// Literal for milliseconds duration
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::milliseconds operator ""_milliseconds(unsigned long long s) ETL_NOEXCEPT
{
return etl::chrono::milliseconds(static_cast<etl::chrono::milliseconds::rep>(s));
}
//***********************************************************************
/// Literal for floating point milliseconds duration
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::duration<double, milli> operator ""_milliseconds(long double s) ETL_NOEXCEPT
{
return etl::chrono::duration<double, milli>(s);
}
//***********************************************************************
/// Literal for microseconds duration
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::microseconds operator ""_microseconds(unsigned long long s) ETL_NOEXCEPT
{
return etl::chrono::microseconds(static_cast<etl::chrono::microseconds::rep>(s));
}
//***********************************************************************
/// Literal for floating point microseconds duration
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::duration<double, micro> operator ""_microseconds(long double s) ETL_NOEXCEPT
{
return etl::chrono::duration<double, micro>(s);
}
//***********************************************************************
/// Literal for nanoseconds duration
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::nanoseconds operator ""_nanoseconds(unsigned long long s) ETL_NOEXCEPT
{
return etl::chrono::nanoseconds(static_cast<etl::chrono::nanoseconds::rep>(s));
}
//***********************************************************************
/// Literal for floating point microseconds duration
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::duration<double, nano> operator ""_nanoseconds(long double s) ETL_NOEXCEPT
{
return etl::chrono::duration<double, nano>(s);
}
}
}
}
#endif

View File

@ -0,0 +1,205 @@
///\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
#include "../../absolute.h"
#include "../../power.h"
namespace etl
{
//***********************************************************************
/// absolute
/// Enabled for etl::chrono::duration
//***********************************************************************
template <typename TDuration>
ETL_NODISCARD
ETL_CONSTEXPR14
typename etl::enable_if<etl::chrono::is_duration<TDuration>::value, TDuration>::type
absolute(TDuration dur) ETL_NOEXCEPT
{
return TDuration((dur.count() < 0) ? -dur.count() : dur.count());
}
namespace chrono
{
//***********************************************************************
/// hh_mm_ss
//***********************************************************************
template <typename TDuration>
class hh_mm_ss
{
private:
// Helper template to calculate the number of digits in a denominator at compile time
template <uintmax_t Den, int Width = 0>
struct fractional_width_helper
{
static constexpr int value = fractional_width_helper<Den / 10, Width + 1>::value;
};
// Base case: when Den == 1, stop recursion
template <int Width>
struct fractional_width_helper<1, Width>
{
static constexpr int value = Width;
};
// Special case: when Den == 0 (invalid denominator), return 0
template <int Width>
struct fractional_width_helper<0, Width>
{
static constexpr int value = 0;
};
// Calculate fractional width for TDuration
template <typename TDur>
struct calculate_fractional_width
{
static constexpr int value = (TDur::period::den == 1)
? 0
: fractional_width_helper<TDur::period::den>::value;
};
public:
ETL_STATIC_ASSERT(etl::chrono::is_duration<TDuration>::value, "TDuration is not a etl::chrono::duration type");
static constexpr int fractional_width = calculate_fractional_width<TDuration>::value;
//***********************************************************************
/// The return type for to_duration.
//***********************************************************************
using precision = etl::chrono::duration<common_type_t<typename TDuration::rep, etl::chrono::seconds::rep>,
ratio<1, etl::power<10, fractional_width>::value>>;
//***********************************************************************
/// Default constructor.
//***********************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14
hh_mm_ss() ETL_NOEXCEPT
: d(TDuration::zero())
{
}
//***********************************************************************
/// Construct from duration.
//***********************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14
explicit hh_mm_ss(TDuration d_) ETL_NOEXCEPT
: d(d_)
{
}
//***********************************************************************
/// Checks for negative duration.
//***********************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14
bool is_negative() const ETL_NOEXCEPT
{
return d < TDuration::zero();
}
//***********************************************************************
/// Returns the hours.
//***********************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::hours hours() const ETL_NOEXCEPT
{
auto dur = etl::absolute(d);
return etl::chrono::duration_cast<etl::chrono::hours>(dur);
}
//***********************************************************************
/// Returns the minutes.
//***********************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14 etl::chrono::minutes minutes() const ETL_NOEXCEPT
{
auto dur = etl::absolute(d) - hours();
return etl::chrono::duration_cast<etl::chrono::minutes>(dur);
}
//***********************************************************************
/// Returns the seconds.
//***********************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14
etl::chrono::seconds seconds() const ETL_NOEXCEPT
{
auto dur = etl::absolute(d) - hours() - minutes();
return etl::chrono::duration_cast<etl::chrono::seconds>(dur);
}
//***********************************************************************
/// Returns the subseconds.
//***********************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14 precision subseconds() const ETL_NOEXCEPT
{
return etl::absolute(d) - etl::chrono::duration_cast<etl::chrono::seconds>(etl::absolute(d));
}
//***********************************************************************
/// Returns the duration.
//***********************************************************************
ETL_CONSTEXPR14 explicit operator precision() const ETL_NOEXCEPT
{
return to_duration();
}
//***********************************************************************
/// Returns the duration.
//***********************************************************************
ETL_NODISCARD
ETL_CONSTEXPR14
precision to_duration() const ETL_NOEXCEPT
{
return d;
}
private:
TDuration d;
};
template <typename TDuration>
constexpr int etl::chrono::hh_mm_ss<TDuration>::fractional_width;
}
}

View File

@ -0,0 +1,52 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 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
{
struct last_spec
{
//ETL_CONSTEXPR14 explicit last_spec()
//{
//}
};
#if ETL_USING_CPP17
inline constexpr last_spec last{};
#else
static ETL_CONSTANT last_spec last{};
#endif
}
}

View File

@ -0,0 +1,480 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 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 month;
ETL_CONSTEXPR14 etl::chrono::month operator +(const etl::chrono::month& m, const etl::chrono::months& ms) ETL_NOEXCEPT;
ETL_CONSTEXPR14 etl::chrono::month operator +(const etl::chrono::months& ms, const etl::chrono::month& m) ETL_NOEXCEPT;
ETL_CONSTEXPR14 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, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
}
//***********************************************************************
/// month
//***********************************************************************
class month
{
public:
//***********************************************************************
/// Default constructor
//***********************************************************************
ETL_CONSTEXPR month() ETL_NOEXCEPT
: value(0)
{
}
//***********************************************************************
/// Construct from unsigned
//***********************************************************************
ETL_CONSTEXPR explicit month(unsigned value_) ETL_NOEXCEPT
: value(value_)
{
}
//***********************************************************************
/// Copy constructor
//***********************************************************************
ETL_CONSTEXPR 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
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::month& operator ++() ETL_NOEXCEPT
{
*this += etl::chrono::months(1);
return *this;
}
//***********************************************************************
/// Post-increment operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::month operator ++(int) ETL_NOEXCEPT
{
const etl::chrono::month temp = *this;
*this += etl::chrono::months(1);
return temp;
}
//***********************************************************************
/// Pre-decrement operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::month& operator --() ETL_NOEXCEPT
{
*this -= etl::chrono::months(1);
return *this;
}
//***********************************************************************
/// Post-decrement operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::month operator --(int) ETL_NOEXCEPT
{
etl::chrono::month temp = *this;
*this -= etl::chrono::months(1);
return temp;
}
//***********************************************************************
/// Plus-equals operator adding etl::chrono::months
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::month& operator +=(const etl::chrono::months& ms) ETL_NOEXCEPT
{
*this = *this + ms;
return *this;
}
//***********************************************************************
/// Minus-equals operator subtracting etl::chrono::months
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::month& operator -=(const etl::chrono::months& ms) ETL_NOEXCEPT
{
*this = *this - ms;
return *this;
}
//***********************************************************************
/// Returns <b>true</b> if the month is within the valid 1 to 31 range
//***********************************************************************
ETL_CONSTEXPR bool ok() const ETL_NOEXCEPT
{
return (value >= 1U) && (value <= 12U);
}
//***********************************************************************
/// Compare month with another.
/// if month < other, returns -1;
/// else if month > other, returns 1;
/// else returns 0;
//***********************************************************************
ETL_CONSTEXPR14 int compare(const month& other) const ETL_NOEXCEPT
{
if (value < other.value) return -1;
if (value > other.value) return 1;
return 0;
}
//***********************************************************************
/// The minimum month value for which ok() will return <b>true</b>
//***********************************************************************
static ETL_CONSTEXPR etl::chrono::month min() ETL_NOEXCEPT
{
return etl::chrono::month(1);
}
//***********************************************************************
/// The maximum month value for which ok() will return <b>true</b>
//***********************************************************************
static ETL_CONSTEXPR etl::chrono::month max() ETL_NOEXCEPT
{
return etl::chrono::month(12);
}
//***********************************************************************
/// Conversion operator to unsigned int
//***********************************************************************
ETL_CONSTEXPR operator unsigned() const ETL_NOEXCEPT
{
return static_cast<unsigned>(value);
}
private:
uint_least8_t value;
};
//***********************************************************************
/// Equality operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator ==(const etl::chrono::month& d1, const etl::chrono::month& d2) ETL_NOEXCEPT
{
return (static_cast<unsigned>(d1) == static_cast<unsigned>(d2));
}
//***********************************************************************
/// Inequality operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator !=(const etl::chrono::month& d1, const etl::chrono::month& d2) ETL_NOEXCEPT
{
return !(d1 == d2);
}
//***********************************************************************
/// Less-than operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator <(const etl::chrono::month& d1, const etl::chrono::month& d2) ETL_NOEXCEPT
{
return (static_cast<unsigned>(d1) < static_cast<unsigned>(d2));
}
//***********************************************************************
/// Less-than-or-equal operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator <=(const etl::chrono::month& d1, const etl::chrono::month& d2) ETL_NOEXCEPT
{
return (static_cast<unsigned>(d1) <= static_cast<unsigned>(d2));
}
//***********************************************************************
/// Greater-than operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator >(const etl::chrono::month& d1, const etl::chrono::month& d2) ETL_NOEXCEPT
{
return (static_cast<unsigned>(d1) > static_cast<unsigned>(d2));
}
//***********************************************************************
/// Greater-than-or-equal operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator >=(const etl::chrono::month& d1, const etl::chrono::month& d2) ETL_NOEXCEPT
{
return (static_cast<unsigned>(d1) >= static_cast<unsigned>(d2));
}
//***********************************************************************
/// Spaceship operator
//***********************************************************************
#if ETL_USING_CPP20
[[nodiscard]] inline constexpr auto operator <=>(const etl::chrono::month& d1, const etl::chrono::month& d2) noexcept
{
return (static_cast<unsigned>(d1) <=> static_cast<unsigned>(d2));
}
#endif
//***********************************************************************
/// Add etl::chrono::months to etl::chrono::month
///\return etl::chrono::month
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::month operator +(const etl::chrono::month& m, const etl::chrono::months& ms) ETL_NOEXCEPT
{
unsigned int value = static_cast<unsigned int>(m);
value = value % 12U;
if (value == 0U)
{
value = 12U;
}
int delta = ms.count() % 12;
// Adjust to allow a limited +-11 month delta
value += 11U;
value += delta;
value %= 12U;
++value;
return etl::chrono::month(value);
}
//***********************************************************************
/// Add etl::chrono::month to etl::chrono::months
///\return etl::chrono::month
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::month operator +(const etl::chrono::months& ms, const etl::chrono::month& m) ETL_NOEXCEPT
{
return m + ms;
}
//***********************************************************************
/// Subtract etl::chrono::months from etl::chrono::month
///\return etl::chrono::month
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::month operator -(const etl::chrono::month& m, const etl::chrono::months& ms) ETL_NOEXCEPT
{
return m + etl::chrono::months(-ms.count());
}
//***********************************************************************
/// Subtract etl::chrono::month from etl::chrono::month
///\return etl::chrono::months
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::months operator -(const etl::chrono::month& m1, const etl::chrono::month& m2) ETL_NOEXCEPT
{
if (m1.ok() && m2.ok())
{
// Calculate the signed difference.
int difference = static_cast<int>(static_cast<unsigned>(m1)) - static_cast<int>(static_cast<unsigned>(m2));
// Adjust for wrap-around.
if (difference < 0)
{
difference += 12;
}
etl::chrono::months ms(difference);
// Check for validity.
if (m1 == (m2 + ms))
{
return ms;
}
}
return etl::chrono::months();
}
#if ETL_USING_CPP17
inline constexpr etl::chrono::month January{ 1 };
inline constexpr etl::chrono::month February{ 2 };
inline constexpr etl::chrono::month March{ 3 };
inline constexpr etl::chrono::month April{ 4 };
inline constexpr etl::chrono::month May{ 5 };
inline constexpr etl::chrono::month June{ 6 };
inline constexpr etl::chrono::month July{ 7 };
inline constexpr etl::chrono::month August{ 8 };
inline constexpr etl::chrono::month September{ 9 };
inline constexpr etl::chrono::month October{ 10 };
inline constexpr etl::chrono::month November{ 11 };
inline constexpr etl::chrono::month December{ 12 };
#else
static ETL_CONSTANT etl::chrono::month January{ 1 };
static ETL_CONSTANT etl::chrono::month February{ 2 };
static ETL_CONSTANT etl::chrono::month March{ 3 };
static ETL_CONSTANT etl::chrono::month April{ 4 };
static ETL_CONSTANT etl::chrono::month May{ 5 };
static ETL_CONSTANT etl::chrono::month June{ 6 };
static ETL_CONSTANT etl::chrono::month July{ 7 };
static ETL_CONSTANT etl::chrono::month August{ 8 };
static ETL_CONSTANT etl::chrono::month September{ 9 };
static ETL_CONSTANT etl::chrono::month October{ 10 };
static ETL_CONSTANT etl::chrono::month November{ 11 };
static ETL_CONSTANT etl::chrono::month December{ 12 };
#endif
//*************************************************************************
/// month_day_last
//*************************************************************************
class month_day_last
{
public:
//*************************************************************************
/// Construct from month.
//*************************************************************************
ETL_CONSTEXPR14 explicit month_day_last(const etl::chrono::month& m_) ETL_NOEXCEPT
: m(m_)
{
}
//*************************************************************************
/// Get the month.
//*************************************************************************
ETL_CONSTEXPR14 etl::chrono::month month() const ETL_NOEXCEPT
{
return m;
}
//*************************************************************************
/// Is the contained month OK?
//*************************************************************************
bool ok() const ETL_NOEXCEPT
{
return m.ok();
}
private:
etl::chrono::month m;
};
//***********************************************************************
/// Equality operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator ==(const etl::chrono::month_day_last& mdl1, const etl::chrono::month_day_last& mdl2) ETL_NOEXCEPT
{
return (static_cast<unsigned>(mdl1.month()) == static_cast<unsigned>(mdl2.month()));
}
//***********************************************************************
/// Inequality operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator !=(const etl::chrono::month_day_last& mdl1, const etl::chrono::month_day_last& mdl2) ETL_NOEXCEPT
{
return !(mdl1 == mdl2);
}
//***********************************************************************
/// Spaceship operator
//***********************************************************************
#if ETL_USING_CPP20
[[nodiscard]] inline constexpr auto operator <=>(const etl::chrono::month_day_last& mdl1, const etl::chrono::month_day_last& mdl2) noexcept
{
return (static_cast<unsigned>(mdl1.month()) <=> static_cast<unsigned>(mdl2.month()));
}
#endif
}
//*************************************************************************
/// Hash function for etl::chrono::month
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <>
struct hash<etl::chrono::month>
{
size_t operator()(const etl::chrono::month& m) const
{
unsigned value = m;
const uint8_t* p = reinterpret_cast<const uint8_t*>(&value);
return etl::private_hash::generic_hash<size_t>(p, p + sizeof(unsigned));
}
};
#endif
//*************************************************************************
/// Hash function for etl::chrono::month_day_last
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <>
struct hash<etl::chrono::month_day_last>
{
size_t operator()(const etl::chrono::month_day_last& mdl) const
{
unsigned value = (unsigned)mdl.month();
const uint8_t* p = reinterpret_cast<const uint8_t*>(&value);
return etl::private_hash::generic_hash<size_t>(p, p + sizeof(unsigned));
}
};
#endif
}
#if ETL_HAS_CHRONO_LITERALS_MONTH
namespace etl
{
namespace literals
{
namespace chrono_literals
{
//***********************************************************************
/// Literal for months
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::month operator ""_month(unsigned long long m) noexcept
{
return etl::chrono::month(static_cast<unsigned char>(m));
}
}
}
}
#endif

View File

@ -0,0 +1,230 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 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 month_day
{
public:
//*************************************************************************
/// Default constructor.
//*************************************************************************
month_day() = default;
//*************************************************************************
/// Construct from month and day.
//*************************************************************************
ETL_CONSTEXPR month_day(const etl::chrono::month& m_,
const etl::chrono::day& d_) ETL_NOEXCEPT
: m(m_)
, d(d_)
{
}
//*************************************************************************
/// 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 month/day is valid.
//*************************************************************************
ETL_CONSTEXPR14 bool ok() const ETL_NOEXCEPT
{
if (!m.ok() || !d.ok())
{
return false;
}
unsigned max_day = 0;
unsigned m_v = static_cast<unsigned>(m);
max_day = private_chrono::days_in_month[m_v];
return (max_day > 0) &&
(static_cast<unsigned>(d) >= 1) &&
(static_cast<unsigned>(d) <= max_day);
}
//*************************************************************************
/// Equality operator.
//*************************************************************************
friend ETL_CONSTEXPR14 bool operator ==(const etl::chrono::month_day& lhs,
const etl::chrono::month_day& rhs) ETL_NOEXCEPT
{
return (lhs.d == rhs.d) && (lhs.m == rhs.m);
}
//*************************************************************************
/// Equality operator.
//*************************************************************************
friend ETL_CONSTEXPR14 bool operator !=(const etl::chrono::month_day& lhs,
const etl::chrono::month_day& rhs) ETL_NOEXCEPT
{
return !(lhs == rhs);
}
//*************************************************************************
/// Less-than operator.
//*************************************************************************
ETL_NODISCARD friend ETL_CONSTEXPR14
bool operator <(const etl::chrono::month_day& lhs,
const etl::chrono::month_day& rhs) ETL_NOEXCEPT
{
if (lhs.month() < rhs.month())
{
return true;
}
else if (lhs.month() == rhs.month())
{
return lhs.day() < rhs.day();
}
else
{
return false;
}
}
//*************************************************************************
/// Less-than-equal operator.
//*************************************************************************
ETL_NODISCARD friend ETL_CONSTEXPR14
bool operator <=(const etl::chrono::month_day& lhs,
const etl::chrono::month_day& rhs) ETL_NOEXCEPT
{
return !(rhs < lhs);
}
//*************************************************************************
/// Greater-than operator.
//*************************************************************************
ETL_NODISCARD friend ETL_CONSTEXPR14
bool operator >(const etl::chrono::month_day& lhs,
const etl::chrono::month_day& rhs) ETL_NOEXCEPT
{
return rhs < lhs;
}
//*************************************************************************
/// Greater-than-equal operator.
//*************************************************************************
ETL_NODISCARD friend ETL_CONSTEXPR14
bool operator >=(const etl::chrono::month_day& lhs,
const etl::chrono::month_day& rhs) ETL_NOEXCEPT
{
return !(lhs < rhs);
}
//***********************************************************************
/// Spaceship operator
//***********************************************************************
#if ETL_USING_CPP20
[[nodiscard]] friend constexpr auto operator <=>(const etl::chrono::month_day& lhs,
const etl::chrono::month_day& rhs) noexcept
{
auto cmp = lhs.month() <=> rhs.month();
if (cmp != 0)
{
return cmp;
}
else
{
return lhs.day() <=> rhs.day();
}
}
#endif
//***********************************************************************
/// Compare month_day with another.
/// 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 month_day& other) const ETL_NOEXCEPT
{
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;
}
private:
etl::chrono::month m;
etl::chrono::day d;
};
}
//*************************************************************************
/// Hash function for etl::chrono::month_day
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <>
struct hash<etl::chrono::month_day>
{
size_t operator()(const etl::chrono::month_day& md) const
{
uint8_t buffer[sizeof(unsigned int) + sizeof(unsigned int)];
unsigned int m = md.month();
unsigned int d = md.day();
memcpy(buffer, &m, sizeof(m));
memcpy(buffer + sizeof(m), &d, sizeof(d));
return etl::private_hash::generic_hash<size_t>(buffer, buffer + sizeof(unsigned int) + sizeof(unsigned int));
}
};
#endif
}

View File

@ -0,0 +1,213 @@
///\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 month_weekday
{
public:
//*************************************************************************
/// Construct from month and weekday_indexed.
//*************************************************************************
ETL_CONSTEXPR month_weekday(const etl::chrono::month& m_,
const etl::chrono::weekday_indexed& wdi_) ETL_NOEXCEPT
: m(m_)
, wdi(wdi_)
{
}
//*************************************************************************
/// Returns the month.
//*************************************************************************
ETL_CONSTEXPR etl::chrono::month month() const ETL_NOEXCEPT
{
return m;
}
//*************************************************************************
/// Returns the weekday_indexed.
//*************************************************************************
ETL_CONSTEXPR etl::chrono::weekday_indexed weekday_indexed() const ETL_NOEXCEPT
{
return wdi;
}
//*************************************************************************
/// Returns true if the month/day is valid.
//*************************************************************************
ETL_CONSTEXPR bool ok() const ETL_NOEXCEPT
{
return m.ok() && wdi.ok();
}
//*************************************************************************
/// Equality operator.
//*************************************************************************
friend ETL_CONSTEXPR14 bool operator ==(const etl::chrono::month_weekday& lhs,
const etl::chrono::month_weekday& rhs) ETL_NOEXCEPT
{
return (lhs.m == rhs.m) && (lhs.wdi == rhs.wdi);
}
//*************************************************************************
/// Equality operator.
//*************************************************************************
friend ETL_CONSTEXPR14 bool operator !=(const etl::chrono::month_weekday& lhs,
const etl::chrono::month_weekday& rhs) ETL_NOEXCEPT
{
return !(lhs == rhs);
}
private:
etl::chrono::month m;
etl::chrono::weekday_indexed wdi;
};
//*************************************************************************
/// Construct from month and weekday_last.
//*************************************************************************
class month_weekday_last
{
public:
//*************************************************************************
/// Construct from month and weekday_indexed.
//*************************************************************************
ETL_CONSTEXPR month_weekday_last(const etl::chrono::month& m_,
const etl::chrono::weekday_last& wdl_) ETL_NOEXCEPT
: m(m_)
, wdl(wdl_)
{
}
//*************************************************************************
/// Returns the month.
//*************************************************************************
ETL_CONSTEXPR etl::chrono::month month() const ETL_NOEXCEPT
{
return m;
}
//*************************************************************************
/// Returns the weekday_indexed.
//*************************************************************************
ETL_CONSTEXPR etl::chrono::weekday_last weekday_last() const ETL_NOEXCEPT
{
return wdl;
}
//*************************************************************************
/// Returns true if the month/day is valid.
//*************************************************************************
ETL_CONSTEXPR bool ok() const ETL_NOEXCEPT
{
return m.ok() && wdl.ok();
}
//*************************************************************************
/// Equality operator.
//*************************************************************************
friend ETL_CONSTEXPR14 bool operator ==(const etl::chrono::month_weekday_last& lhs,
const etl::chrono::month_weekday_last& rhs) ETL_NOEXCEPT
{
return (lhs.m == rhs.m) && (lhs.wdl == rhs.wdl);
}
//*************************************************************************
/// Equality operator.
//*************************************************************************
friend ETL_CONSTEXPR14 bool operator !=(const etl::chrono::month_weekday_last& lhs,
const etl::chrono::month_weekday_last& rhs) ETL_NOEXCEPT
{
return !(lhs == rhs);
}
private:
etl::chrono::month m;
etl::chrono::weekday_last wdl;
};
}
//*************************************************************************
/// Hash function for etl::chrono::month_weekday
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <>
struct hash<etl::chrono::month_weekday>
{
size_t operator()(const etl::chrono::month_weekday& mw) const
{
uint8_t buffer[3U * sizeof(unsigned int)];
unsigned int a = mw.month();
unsigned int b = mw.weekday_indexed().weekday().c_encoding();
unsigned int c = mw.weekday_indexed().index();
memcpy(buffer, &a, sizeof(a));
memcpy(buffer + sizeof(a), &b, sizeof(b));
memcpy(buffer + sizeof(b), &b, sizeof(c));
return etl::private_hash::generic_hash<size_t>(buffer, buffer + 3U * sizeof(unsigned int));
}
};
#endif
//*************************************************************************
/// Hash function for etl::chrono::month_weekday_last
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <>
struct hash<etl::chrono::month_weekday_last>
{
size_t operator()(const etl::chrono::month_weekday_last& mw) const
{
uint8_t buffer[2U * sizeof(unsigned int)];
unsigned int a = mw.month();
unsigned int b = mw.weekday_last().weekday().c_encoding();
memcpy(buffer, &a, sizeof(a));
memcpy(buffer + sizeof(a), &b, sizeof(b));
return etl::private_hash::generic_hash<size_t>(buffer, buffer + 2U * sizeof(unsigned int));
}
};
#endif
}

View File

@ -0,0 +1,328 @@
///\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
{
//*************************************************************************
// month_day
inline 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);
}
// month_day
inline 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
inline 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);
}
// month_day
inline 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);
}
// month_day
inline 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);
}
//*************************************************************************
// month_day_last
inline 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);
}
// month_day_last
inline 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
inline 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
inline 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));
}
//*************************************************************************
// month_weekday
inline 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);
}
// month_weekday
inline 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);
}
// month_weekday
inline 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
inline 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);
}
//*************************************************************************
// month_weekday_last
inline 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);
}
// month_weekday_last
inline 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);
}
// month_weekday_last
inline 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
inline 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);
}
//*************************************************************************
// year_month
inline 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);
}
// year_month
inline 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));
}
////*************************************************************************
// year_month_day
inline 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
inline 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));
}
// year_month_day
inline 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());
}
// year_month_day
inline 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());
}
// year_month_day
inline 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());
}
// year_month_day
inline 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());
}
//*************************************************************************
// year_month_day_last
inline 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
inline 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);
}
// year_month_day_last
inline 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);
}
// year_month_day_last
inline 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);
}
// year_month_day_last
inline 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);
}
//*************************************************************************
// year_month_weekday
inline 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
inline 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());
}
// year_month_weekday
inline 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());
}
// year_month_weekday
inline 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());
}
// year_month_weekday
inline 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());
}
//*************************************************************************
// year_month_weekday_last
inline 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
inline 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());
}
// year_month_weekday_last
inline 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());
}
// year_month_weekday_last
inline 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());
}
// year_month_weekday_last
inline 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());
}
}
}

View File

@ -0,0 +1,263 @@
///\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 <typename TClock, typename TDuration = typename TClock::duration>
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 <typename TDuration2>
explicit time_point(const time_point<clock, TDuration2>& 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_CONSTEXPR14 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;
};
//***********************************************************************
/// Rounds down a duration to the nearest lower precision.
//***********************************************************************
template <typename TToDuration, typename TClock, typename TDuration>
ETL_CONSTEXPR14
etl::chrono::time_point<TClock, TToDuration>
floor(const etl::chrono::time_point<TClock, TDuration>& tp) ETL_NOEXCEPT
{
return etl::chrono::time_point<TClock, TToDuration>(floor<TToDuration>(tp.time_since_epoch()));
}
//***********************************************************************
/// Rounds up a duration to the nearest higher precision.
//***********************************************************************
template <typename TToDuration, typename TClock, typename TDuration>
ETL_CONSTEXPR14
etl::chrono::time_point<TClock, TToDuration>
ceil(const etl::chrono::time_point<TClock, TDuration>& tp) ETL_NOEXCEPT
{
return etl::chrono::time_point<TClock, TToDuration>(ceil<TToDuration>(tp.time_since_epoch()));
}
//***********************************************************************
/// Rounds a duration to the nearest precision.
/// If the duration is exactly halfway, it rounds away from zero.
//***********************************************************************
template <typename TToDuration, typename TClock, typename TDuration>
ETL_CONSTEXPR14
etl::chrono::time_point<TClock, TToDuration>
round(const etl::chrono::time_point<TClock, TDuration>& tp) ETL_NOEXCEPT
{
return etl::chrono::time_point<TClock, TToDuration>(round<TToDuration>(tp.time_since_epoch()));
}
template <typename TToDuration, typename TClock, typename TDuration>
ETL_CONSTEXPR14
etl::chrono::time_point<TClock, TToDuration>
time_point_cast(const etl::chrono::time_point<TClock, TDuration>& tp) ETL_NOEXCEPT
{
TToDuration dur = etl::chrono::duration_cast<TToDuration>(tp.time_since_epoch());
return etl::chrono::time_point<TClock, TToDuration>(dur);
}
//***************************************************************************
/// Equality operator
//***************************************************************************
template <typename TClock, typename TDuration1, typename TDuration2>
ETL_CONSTEXPR14 bool operator ==(const time_point<TClock, TDuration1>& lhs, const time_point<TClock, TDuration2>& rhs) ETL_NOEXCEPT
{
return lhs.time_since_epoch() == rhs.time_since_epoch();
}
//***************************************************************************
/// Inequality operator
//***************************************************************************
template <typename TClock, typename TDuration1, typename TDuration2>
ETL_CONSTEXPR14 bool operator !=(const time_point<TClock, TDuration1>& lhs, const time_point<TClock, TDuration2>& rhs) ETL_NOEXCEPT
{
return !(lhs == rhs);
}
//***************************************************************************
/// Less-than operator
//***************************************************************************
template <typename TClock, typename TDuration1, typename TDuration2>
ETL_CONSTEXPR14 bool operator <(const time_point<TClock, TDuration1>& lhs, const time_point<TClock, TDuration2>& rhs) ETL_NOEXCEPT
{
return lhs.time_since_epoch() < rhs.time_since_epoch();
}
//***************************************************************************
/// Less-than-equal operator
//***************************************************************************
template <typename TClock, typename TDuration1, typename TDuration2>
ETL_CONSTEXPR14 bool operator <=(const time_point<TClock, TDuration1>& lhs, const time_point<TClock, TDuration2>& rhs) ETL_NOEXCEPT
{
return !(rhs < lhs);
}
//***************************************************************************
/// Greater-than operator
//***************************************************************************
template <typename TClock, typename TDuration1, typename TDuration2>
ETL_CONSTEXPR14 bool operator >(const time_point<TClock, TDuration1>& lhs, const time_point<TClock, TDuration2>& rhs) ETL_NOEXCEPT
{
return rhs < lhs;
}
//***************************************************************************
/// Greater-than-equal operator
//***************************************************************************
template <typename TClock, typename TDuration1, typename TDuration2>
ETL_CONSTEXPR14 bool operator >=(const time_point<TClock, TDuration1>& lhs, const time_point<TClock, TDuration2>& rhs) ETL_NOEXCEPT
{
return !(lhs < rhs);
}
}
//***********************************************************************
/// Spaceship operator
//***********************************************************************
#if ETL_USING_CPP20
template <typename TClock, typename TDuration1, typename TDuration2>
[[nodiscard]] constexpr auto operator <=>(const etl::chrono::time_point<TClock, TDuration1>& lhs, const etl::chrono::time_point<TClock, TDuration2>& rhs) noexcept
{
return (lhs.time_since_epoch() <=> rhs.time_since_epoch());
}
#endif
//***************************************************************************
/// Defines type, which is the common type of two etl::chrono::time_points.
//***************************************************************************
template <typename TClock, typename TDuration1, typename TDuration2>
struct common_type<etl::chrono::time_point<TClock, TDuration1>, etl::chrono::time_point<TClock, TDuration2>>
{
using type = etl::chrono::time_point<TClock, typename etl::common_type<TDuration1, TDuration2>::type>;
};
}

View File

@ -0,0 +1,80 @@
///\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 time_zone
//{
//public:
// /// Obtains the name of this time_zone.
// etl::string_view name() const ETL_NOEXCEPT
// {
// return etl::string_view(tz_name, etl::strlen(tz_name));
// }
// template <typename TDuration>
// etl::chrono::sys_info get_info(const etl::chrono::sys_time<TDuration>& tp) const
// {
// }
// template <typename TDuration>
// etl::chrono::local_info get_info(const etl::chrono::local_time<TDuration>& tp) const
// {
// return etl::chrono::local_info();
// }
// template <typename TDuration>
// etl::chrono::sys_time<etl::common_type_t<TDuration, etl::chrono::seconds>> to_sys(const etl::chrono::local_time<TDuration>& tp) const
// {
// etl::chrono::sys_time<etl::common_type_t<TDuration, etl::chrono::seconds>>()
// }
// template <typename TDuration>
// etl::chrono::sys_time<etl::common_type_t<TDuration, etl::chrono::seconds>> to_sys(const etl::chrono::local_time<TDuration>& tp,
// etl::chrono::choose z) const
// {
// etl::chrono::sys_time<etl::common_type_t<TDuration, etl::chrono::seconds>>();
// }
//private:
// static const char *tz_name;
//};
}
}

View File

@ -0,0 +1,540 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 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 weekday;
class weekday_indexed;
class weekday_last;
struct last_spec;
ETL_CONSTEXPR14 etl::chrono::weekday operator +(const etl::chrono::weekday& m, const etl::chrono::days& ds) ETL_NOEXCEPT;
ETL_CONSTEXPR14 etl::chrono::weekday operator +(const etl::chrono::days& ds, const etl::chrono::weekday& m) ETL_NOEXCEPT;
ETL_CONSTEXPR14 etl::chrono::weekday operator -(const etl::chrono::weekday& m, const etl::chrono::days& ds) ETL_NOEXCEPT;
//***********************************************************************
/// weekday
//***********************************************************************
class weekday
{
public:
//***********************************************************************
/// Default constructor
//***********************************************************************
ETL_CONSTEXPR weekday() ETL_NOEXCEPT
: value(255U)
{
}
//***********************************************************************
/// Construct from unsigned
//***********************************************************************
ETL_CONSTEXPR explicit weekday(unsigned value_) ETL_NOEXCEPT
: value(value_ == 7U ? 0U :value_)
{
}
//***********************************************************************
/// Copy constructor
//***********************************************************************
ETL_CONSTEXPR weekday(const etl::chrono::weekday& other) ETL_NOEXCEPT
: value(other.value)
{
}
//***********************************************************************
/// Assignment operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::weekday& operator =(const etl::chrono::weekday& rhs) ETL_NOEXCEPT
{
value = rhs.value;
return *this;
}
//***********************************************************************
/// Pre-increment operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::weekday& operator ++() ETL_NOEXCEPT
{
*this += etl::chrono::days(1);
return *this;
}
//***********************************************************************
/// Post-increment operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::weekday operator ++(int) ETL_NOEXCEPT
{
const etl::chrono::weekday temp = *this;
*this += etl::chrono::days(1);
return temp;
}
//***********************************************************************
/// Pre-decrement operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::weekday& operator --() ETL_NOEXCEPT
{
*this -= etl::chrono::days(1);
return *this;
}
//***********************************************************************
/// Post-decrement operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::weekday operator --(int) ETL_NOEXCEPT
{
etl::chrono::weekday temp = *this;
*this -= etl::chrono::days(1);
return temp;
}
//***********************************************************************
/// Plus-equals operator adding etl::chrono::days
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::weekday& operator +=(const etl::chrono::days& ds) ETL_NOEXCEPT
{
*this = *this + ds;
return *this;
}
//***********************************************************************
/// Minus-equals operator subtracting etl::chrono::days
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::weekday& operator -=(const etl::chrono::days& ds) ETL_NOEXCEPT
{
*this = *this - ds;
return *this;
}
//***********************************************************************
/// Returns <b>true</b> if the weekday is within the valid 1 to 31 range
//***********************************************************************
ETL_CONSTEXPR bool ok() const ETL_NOEXCEPT
{
return (c_encoding() <= 6U);
}
//***********************************************************************
/// The minimum weekday value for which ok() will return <b>true</b>
/// C encoding.
//***********************************************************************
static ETL_CONSTEXPR unsigned min() ETL_NOEXCEPT
{
return 0;
}
//***********************************************************************
/// The maximum weekday value for which ok() will return <b>true</b>
/// C encoding.
//***********************************************************************
static ETL_CONSTEXPR unsigned max() ETL_NOEXCEPT
{
return 6;
}
//***********************************************************************
/// Get the C encoding of the weekday
//***********************************************************************
ETL_CONSTEXPR unsigned c_encoding() const ETL_NOEXCEPT
{
return value;
}
//***********************************************************************
/// Get the ISO encoding of the weekday
//***********************************************************************
ETL_CONSTEXPR unsigned iso_encoding() const ETL_NOEXCEPT
{
return (value == 0U) ? 7U : value;
}
//***********************************************************************
/// Index operator from index
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::weekday_indexed operator[](unsigned index) const ETL_NOEXCEPT;
//***********************************************************************
/// Index operator from etl::chrono::last_spec
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::weekday_last operator[](etl::chrono::last_spec last) const ETL_NOEXCEPT;
//***********************************************************************
/// Returns <b>true</b> if the day is a weekend.
//***********************************************************************
ETL_CONSTEXPR bool is_weekend() const ETL_NOEXCEPT
{
return (c_encoding() == 0U) || (c_encoding() == 6U);
}
private:
// The weekday value in C encoding.
unsigned char value;
};
//***********************************************************************
/// Equality operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator ==(const etl::chrono::weekday& wd1, const etl::chrono::weekday& wd2) ETL_NOEXCEPT
{
return (wd1.c_encoding() == wd2.c_encoding());
}
//***********************************************************************
/// Inequality operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator !=(const etl::chrono::weekday& wd1, const etl::chrono::weekday& wd2) ETL_NOEXCEPT
{
return !(wd1 == wd2);
}
//***********************************************************************
/// Add etl::chrono::days to etl::chrono::weekday
///\return etl::chrono::weekday
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::weekday operator +(const etl::chrono::weekday& wd, const etl::chrono::days& ds) ETL_NOEXCEPT
{
int delta = ds.count() % 7;
unsigned int value = wd.c_encoding();
// Adjust to allow a limited +-7 weekday delta
value %= 7U;
value += 7U;
value += delta;
value %= 7U;
return etl::chrono::weekday(value);
}
//***********************************************************************
/// Add etl::chrono::weekday to etl::chrono::days
///\return etl::chrono::weekday
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::weekday operator +(const etl::chrono::days& ds, const etl::chrono::weekday& wd) ETL_NOEXCEPT
{
return wd + ds;
}
//***********************************************************************
/// Subtract etl::chrono::days from etl::chrono::weekday
///\return etl::chrono::weekday
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::weekday operator -(const etl::chrono::weekday& m, const etl::chrono::days& ds) ETL_NOEXCEPT
{
return m + etl::chrono::days(-ds.count());
}
//***********************************************************************
/// Subtract etl::chrono::weekday from etl::chrono::weekday
///\return etl::chrono::days
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::days operator -(const etl::chrono::weekday& wd1, const etl::chrono::weekday& wd2) ETL_NOEXCEPT
{
if (wd1.ok() && wd2.ok())
{
int diff = static_cast<int>(wd1.c_encoding()) - static_cast<int>(wd2.c_encoding());
return etl::chrono::days((diff + 7) % 7);
}
return etl::chrono::days(0);
}
#if ETL_USING_CPP17
inline constexpr etl::chrono::weekday Sunday{ 0U };
inline constexpr etl::chrono::weekday Monday{ 1U };
inline constexpr etl::chrono::weekday Tuesday{ 2U };
inline constexpr etl::chrono::weekday Wednesday{ 3U };
inline constexpr etl::chrono::weekday Thursday{ 4U };
inline constexpr etl::chrono::weekday Friday{ 5U };
inline constexpr etl::chrono::weekday Saturday{ 6U };
#else
static ETL_CONSTANT etl::chrono::weekday Sunday{ 0U };
static ETL_CONSTANT etl::chrono::weekday Monday{ 1U };
static ETL_CONSTANT etl::chrono::weekday Tuesday{ 2U };
static ETL_CONSTANT etl::chrono::weekday Wednesday{ 3U };
static ETL_CONSTANT etl::chrono::weekday Thursday{ 4U };
static ETL_CONSTANT etl::chrono::weekday Friday{ 5U };
static ETL_CONSTANT etl::chrono::weekday Saturday{ 6U };
#endif
//***********************************************************************
/// weekday_indexed
//***********************************************************************
class weekday_indexed
{
public:
//***********************************************************************
/// Default constructor
//***********************************************************************
ETL_CONSTEXPR weekday_indexed() ETL_NOEXCEPT
: wd()
, i()
{
}
//***********************************************************************
/// Construct from weekday and index
//***********************************************************************
ETL_CONSTEXPR weekday_indexed(const etl::chrono::weekday& wd_, unsigned index_) ETL_NOEXCEPT
: wd(wd_)
, i(static_cast<uint_least8_t>(index_))
{
}
//***********************************************************************
/// Copy constructor
//***********************************************************************
ETL_CONSTEXPR 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
//***********************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::chrono::weekday weekday() const ETL_NOEXCEPT
{
return wd;
}
//***********************************************************************
/// Get index
//***********************************************************************
ETL_NODISCARD ETL_CONSTEXPR unsigned index() const ETL_NOEXCEPT
{
return i;
}
//***********************************************************************
/// Returns <b>true</b> if the weekday and index are valid
//***********************************************************************
ETL_NODISCARD ETL_CONSTEXPR bool ok() const ETL_NOEXCEPT
{
return wd.ok() && (i >= 1U) && (i <= 5U);
}
private:
etl::chrono::weekday wd;
uint_least8_t i;
};
//***********************************************************************
/// Equality operator
//***********************************************************************
inline ETL_CONSTEXPR14 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());
}
//***********************************************************************
/// Inequality operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator !=(const etl::chrono::weekday_indexed& wd1, const etl::chrono::weekday_indexed& wd2) ETL_NOEXCEPT
{
return !(wd1 == wd2);
}
//***********************************************************************
/// weekday_last
//***********************************************************************
class weekday_last
{
public:
//***********************************************************************
/// Construct from unsigned
//***********************************************************************
ETL_CONSTEXPR explicit weekday_last(const etl::chrono::weekday& wd_) ETL_NOEXCEPT
: wd(wd_)
{
}
//***********************************************************************
/// Copy constructor
//***********************************************************************
ETL_CONSTEXPR weekday_last(const etl::chrono::weekday_last& other) ETL_NOEXCEPT
: wd(other.wd)
{
}
//***********************************************************************
/// Assignment operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::weekday_last& operator =(const etl::chrono::weekday_last& rhs) ETL_NOEXCEPT
{
wd = rhs.wd;
return *this;
}
//***********************************************************************
/// Get weekday
//***********************************************************************
ETL_NODISCARD ETL_CONSTEXPR14 etl::chrono::weekday weekday() const ETL_NOEXCEPT
{
return wd;
}
//***********************************************************************
/// Returns <b>true</b> if the weekday is valid
//***********************************************************************
ETL_NODISCARD ETL_CONSTEXPR14 bool ok() const ETL_NOEXCEPT
{
return wd.ok();
}
private:
etl::chrono::weekday wd;
};
//***********************************************************************
/// Equality operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator ==(const etl::chrono::weekday_last& wd1, const etl::chrono::weekday_last& wd2) ETL_NOEXCEPT
{
return (wd1.weekday() == wd2.weekday());
}
//***********************************************************************
/// weekday index operator from index
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::weekday_indexed etl::chrono::weekday::operator[](unsigned index) const ETL_NOEXCEPT
{
return etl::chrono::weekday_indexed(*this, index);
}
//***********************************************************************
/// Index operator from etl::chrono::last_spec
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::weekday_last etl::chrono::weekday::operator[](etl::chrono::last_spec) const ETL_NOEXCEPT
{
return etl::chrono::weekday_last(*this);
}
}
//*************************************************************************
/// Hash function for etl::chrono::weekday
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <>
struct hash<etl::chrono::weekday>
{
size_t operator()(const etl::chrono::weekday& wd) const
{
unsigned value = wd.c_encoding();
const uint8_t* p = reinterpret_cast<const uint8_t*>(&value);
return etl::private_hash::generic_hash<size_t>(p, p + sizeof(unsigned));
}
};
#endif
//*************************************************************************
/// Hash function for etl::chrono::weekday_indexed
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <>
struct hash<etl::chrono::weekday_indexed>
{
size_t operator()(const etl::chrono::weekday_indexed& wdi) const
{
return etl::hash<etl::chrono::weekday>()(wdi.weekday()) ^ etl::hash<unsigned>()(wdi.index());
}
};
#endif
//*************************************************************************
/// Hash function for etl::chrono::weekday_last
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <>
struct hash<etl::chrono::weekday_last>
{
size_t operator()(const etl::chrono::weekday_last& wdl) const
{
return etl::hash<etl::chrono::weekday>()(wdl.weekday());
}
};
#endif
}
#if ETL_HAS_CHRONO_LITERALS_WEEKDAY
namespace etl
{
namespace literals
{
namespace chrono_literals
{
//***********************************************************************
/// Literal for weekdays
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::weekday operator ""_weekday(unsigned long long wd) noexcept
{
return etl::chrono::weekday(static_cast<unsigned char>(wd));
}
}
}
}
#endif

View File

@ -0,0 +1,345 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 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
//***********************************************************************
class year
{
public:
//***********************************************************************
/// Default constructor
//***********************************************************************
ETL_CONSTEXPR year() ETL_NOEXCEPT
: value(0)
{
}
//***********************************************************************
/// Construct from unsigned
//***********************************************************************
ETL_CONSTEXPR explicit year(unsigned value_) ETL_NOEXCEPT
: value(value_)
{
}
//***********************************************************************
/// Copy constructor
//***********************************************************************
ETL_CONSTEXPR 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
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::year& operator ++() ETL_NOEXCEPT
{
++value;
return *this;
}
//***********************************************************************
/// Post-increment operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::year operator ++(int) ETL_NOEXCEPT
{
const etl::chrono::year temp = *this;
++value;
return temp;
}
//***********************************************************************
/// Pre-decrement operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::year& operator --() ETL_NOEXCEPT
{
--value;
return *this;
}
//***********************************************************************
/// Post-decrement operator
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::year operator --(int) ETL_NOEXCEPT
{
const etl::chrono::year temp = *this;
--value;
return temp;
}
//***********************************************************************
/// Plus-equals operator adding etl::chrono::years
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::year& operator +=(const etl::chrono::years& ys) ETL_NOEXCEPT
{
value += static_cast<unsigned char>(ys.count());
return *this;
}
//***********************************************************************
/// Minus-equals operator subtracting etl::chrono::years
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::year& operator -=(const etl::chrono::years& ys) ETL_NOEXCEPT
{
value -= static_cast<unsigned char>(ys.count());
return *this;
}
//***********************************************************************
/// Returns <b>true</b> if the year is within the valid -32767 to 32767 range
//***********************************************************************
ETL_CONSTEXPR bool ok() const ETL_NOEXCEPT
{
return (value != etl::integral_limits<int16_t>::min);
}
//***********************************************************************
/// The minimum year value for which ok() will return <b>true</b>
//***********************************************************************
static ETL_CONSTEXPR etl::chrono::year min() ETL_NOEXCEPT
{
return etl::chrono::year(-32767);
}
//***********************************************************************
/// The maximum year value for which ok() will return <b>true</b>
//***********************************************************************
static ETL_CONSTEXPR etl::chrono::year max() ETL_NOEXCEPT
{
return etl::chrono::year(32767);
}
//***********************************************************************
/// Returns <b>true</b> if the year is a leap year
//***********************************************************************
ETL_CONSTEXPR bool is_leap() const ETL_NOEXCEPT
{
return ((value % 4) == 0) && // Divisible by 4
(((value % 100) != 0) || // but not divisible by 100
((value % 400) == 0)); // unless divisible by 400
}
//***********************************************************************
/// Conversion operator to unsigned int
//***********************************************************************
ETL_CONSTEXPR operator int() const ETL_NOEXCEPT
{
return static_cast<int>(value);
}
private:
int16_t value;
};
//***********************************************************************
/// Equality operator
//***********************************************************************
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));
}
//***********************************************************************
/// Inequality operator
//***********************************************************************
inline ETL_CONSTEXPR14 bool operator !=(const etl::chrono::year& y1, const etl::chrono::year& y2) ETL_NOEXCEPT
{
return !(y1 == y2);
}
//***********************************************************************
/// Less-than operator
//***********************************************************************
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));
}
//***********************************************************************
/// Less-than-or-equal operator
//***********************************************************************
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));
}
//***********************************************************************
/// Greater-than operator
//***********************************************************************
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));
}
//***********************************************************************
/// Greater-than-or-equal operator
//***********************************************************************
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));
}
//***********************************************************************
/// Spaceship operator
//***********************************************************************
#if ETL_USING_CPP20
[[nodiscard]] inline constexpr auto operator <=>(const etl::chrono::year& y1, const etl::chrono::year& y2) noexcept
{
return (static_cast<unsigned>(y1) <=> static_cast<unsigned>(y2));
}
#endif
//***********************************************************************
/// Add etl::chrono::years to etl::chrono::year
///\return etl::chrono::year
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::year operator +(const etl::chrono::year& y, const etl::chrono::years& ys) ETL_NOEXCEPT
{
etl::chrono::year result(y);
result += ys;
return result;
}
//***********************************************************************
/// Add etl::chrono::year to etl::chrono::years
///\return etl::chrono::year
//***********************************************************************
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::years from etl::chrono::year
///\return etl::chrono::year
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::year operator -(const etl::chrono::year& y, const etl::chrono::years& ys) ETL_NOEXCEPT
{
etl::chrono::year result(y);
result -= ys;
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)));
}
}
//*************************************************************************
/// Hash function for etl::chrono::year
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <>
struct hash<etl::chrono::year>
{
size_t operator()(const etl::chrono::year& y) const
{
int value = y;
const uint8_t* p = reinterpret_cast<const uint8_t*>(&value);
return etl::private_hash::generic_hash<size_t>(p, p + sizeof(int));
}
};
#endif
}
#if ETL_HAS_CHRONO_LITERALS_YEAR
namespace etl
{
namespace literals
{
namespace chrono_literals
{
//***********************************************************************
/// Literal for years
//***********************************************************************
inline ETL_CONSTEXPR14 etl::chrono::year operator ""_year(unsigned long long y) noexcept
{
return etl::chrono::year(static_cast<int16_t>(y));
}
}
}
}
#endif

View File

@ -0,0 +1,234 @@
///\file
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2023 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 year_month
{
public:
//*************************************************************************
/// Default constructor.
//*************************************************************************
year_month()
: y()
, m()
{
}
//*************************************************************************
/// Construct from month and day.
//*************************************************************************
ETL_CONSTEXPR year_month(const etl::chrono::year& y_,
const etl::chrono::month& m_) ETL_NOEXCEPT
: y(y_)
, m(m_)
{
}
//*************************************************************************
/// 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 true if the month/day is valid.
//*************************************************************************
ETL_CONSTEXPR bool ok() const ETL_NOEXCEPT
{
return y.ok() && m.ok();
}
//*************************************************************************
/// Adds etl::chrono::years
//*************************************************************************
friend ETL_CONSTEXPR14 etl::chrono::year_month operator +(const etl::chrono::year_month& ym,
const etl::chrono::years& dy) ETL_NOEXCEPT
{
return etl::chrono::year_month(ym.year() + dy, ym.month());
}
//*************************************************************************
/// Adds etl::chrono::years
//*************************************************************************
friend ETL_CONSTEXPR14 etl::chrono::year_month operator +(const etl::chrono::years& dy,
const etl::chrono::year_month& ym) ETL_NOEXCEPT
{
return etl::chrono::year_month(ym.year() + dy, ym.month());
}
//*************************************************************************
/// Adds etl::chrono::months
//*************************************************************************
friend 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);
}
//*************************************************************************
/// Adds etl::chrono::months
//*************************************************************************
friend 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);
}
//*************************************************************************
/// Subtracts etl::chrono::years
//*************************************************************************
friend ETL_CONSTEXPR14 etl::chrono::year_month operator -(const etl::chrono::year_month& ym,
const etl::chrono::years& dy) ETL_NOEXCEPT
{
return etl::chrono::year_month(ym.year() - dy, ym.month());
}
//*************************************************************************
/// Subtracts etl::chrono::months
//*************************************************************************
friend 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);
}
//*************************************************************************
/// Subtracts etl::chrono::year_month
//*************************************************************************
friend 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()))));
}
//*************************************************************************
/// Equality operator.
//*************************************************************************
friend ETL_CONSTEXPR14 bool operator ==(const etl::chrono::year_month& lhs,
const etl::chrono::year_month& rhs) ETL_NOEXCEPT
{
return (lhs.y == rhs.y) && (lhs.m == rhs.m);
}
//*************************************************************************
/// Inequality operator.
//*************************************************************************
friend ETL_CONSTEXPR14 bool operator !=(const etl::chrono::year_month& lhs,
const etl::chrono::year_month& rhs) ETL_NOEXCEPT
{
return !(lhs == rhs);
}
//***********************************************************************
/// Spaceship operator
//***********************************************************************
#if ETL_USING_CPP20
[[nodiscard]] friend constexpr auto operator <=>(const etl::chrono::year_month& lhs,
const etl::chrono::year_month& rhs) ETL_NOEXCEPT
{
auto cmp = lhs.year()<=> rhs.year();
if (cmp != 0)
{
return cmp;
}
else
{
return lhs.month() <=> rhs.month();
}
}
#endif
//***********************************************************************
/// Compare year_month with another.
/// 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& 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;
}
private:
etl::chrono::year y;
etl::chrono::month m;
};
}
//*************************************************************************
/// Hash function for etl::chrono::year_month
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <>
struct hash<etl::chrono::year_month>
{
size_t operator()(const etl::chrono::year_month& md) const
{
uint8_t buffer[sizeof(unsigned int) + sizeof(unsigned int)];
unsigned int y = md.year();
unsigned int m = md.month();
memcpy(buffer, &y, sizeof(y));
memcpy(buffer + sizeof(y), &m, sizeof(m));
return etl::private_hash::generic_hash<size_t>(buffer, buffer + sizeof(unsigned int) + sizeof(unsigned int));
}
};
#endif
}

View File

@ -0,0 +1,581 @@
///\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.
//*************************************************************************
ETL_CONSTEXPR 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 <= max_day_for_month();
}
//*************************************************************************
/// 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_CONSTEXPR14 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_CONSTEXPR14 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
{
int day_count = 0;
// Add days for years since 1970
for (etl::chrono::year yr(1970); yr < this->year(); ++yr)
{
day_count += yr.is_leap() ? 366 : 365;
}
// 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];
if (mth == etl::chrono::February && this->year().is_leap())
{
++day_count; // Add one day for leap year February
}
}
// Add days for the current month
day_count += static_cast<unsigned>(this->day()) - 1;
return sys_days(etl::chrono::days(day_count));
}
////***********************************************************************
///// Converts *this to etl::chrono::local_days
////***********************************************************************
//ETL_CONSTEXPR14 explicit operator etl::chrono::local_days() const ETL_NOEXCEPT
//{
//// Convert the year_month_day to sys_days first
//etl::chrono::sys_days sys_days_representation = static_cast<etl::chrono::sys_days>(*this);
//// Convert sys_days to local_days (assuming local_days is a wrapper around sys_days)
//return etl::chrono::local_days(sys_days_representation);
//}
private:
//***********************************************************************
/// Calculates the last day in the year/month.
/// Returns 0 if either the year or month are not OK.
//***********************************************************************
ETL_CONSTEXPR14 etl::chrono::day max_day_for_month() const
{
unsigned char count = 0;
if (y.ok() && m.ok())
{
count = private_chrono::days_in_month[m];
if (y.is_leap() && (m == February))
{
++count;
}
}
return etl::chrono::day(count);
}
etl::chrono::year y;
etl::chrono::month m;
etl::chrono::day d;
};
//*************************************************************************
/// year_month_day_last
//*************************************************************************
class year_month_day_last
{
public:
//*************************************************************************
///
//*************************************************************************
ETL_CONSTEXPR14 year_month_day_last(const etl::chrono::year& y_,
const etl::chrono::month_day_last& mdl_) ETL_NOEXCEPT
: y(y_)
, m(mdl_.month())
{
}
//*************************************************************************
///
//*************************************************************************
ETL_CONSTEXPR14 etl::chrono::year year() const ETL_NOEXCEPT
{
return y;
}
//*************************************************************************
///
//*************************************************************************
ETL_CONSTEXPR14 etl::chrono::month month() const ETL_NOEXCEPT
{
return m;
}
//*************************************************************************
///
//*************************************************************************
ETL_CONSTEXPR14 etl::chrono::day day() const ETL_NOEXCEPT
{
etl::chrono::day d = etl::chrono::day(etl::chrono::private_chrono::days_in_month[m]);
return (d == 28) && y.is_leap() ? etl::chrono::day(29) : d;
}
//*************************************************************************
///
//*************************************************************************
ETL_CONSTEXPR14 etl::chrono::month_day_last month_day_last() const ETL_NOEXCEPT
{
return etl::chrono::month_day_last(m);
}
//*************************************************************************
///
//*************************************************************************
ETL_CONSTEXPR14 bool ok() const ETL_NOEXCEPT
{
return y.ok() && m.ok();
}
//*************************************************************************
///
//*************************************************************************
ETL_CONSTEXPR14 etl::chrono::year_month_day_last& operator +=(const etl::chrono::years& dy) ETL_NOEXCEPT
{
y += dy;
return *this;
}
//*************************************************************************
///
//*************************************************************************
ETL_CONSTEXPR14 etl::chrono::year_month_day_last& operator +=(const etl::chrono::months& dm) ETL_NOEXCEPT
{
m += dm;
return *this;
}
//*************************************************************************
///
//*************************************************************************
ETL_CONSTEXPR14 etl::chrono::year_month_day_last& operator -=(const etl::chrono::years& dy) ETL_NOEXCEPT
{
y -= dy;
return *this;
}
//*************************************************************************
///
//*************************************************************************
ETL_CONSTEXPR14 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_CONSTEXPR14 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_CONSTEXPR14 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 cmp1 = lhs.year() <=> rhs.year();
if (cmp1 != 0)
{
return cmp1;
}
else
{
auto cmp2 = lhs.month() <=> rhs.month();
if (cmp2 != 0)
{
return cmp2;
}
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_CONSTEXPR14 operator etl::chrono::sys_days() const ETL_NOEXCEPT
//{
// etl::chrono::sys_days();
//}
//*************************************************************************
///
//*************************************************************************
//ETL_CONSTEXPR14 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<etl::chrono::year_month_day>
{
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<size_t>(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<etl::chrono::year_month_day_last>
{
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<size_t>(buffer, buffer + sizeof(unsigned int) + sizeof(unsigned int) + sizeof(unsigned int));
}
};
#endif
}

View File

@ -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.
//*************************************************************************
ETL_CONSTEXPR 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_CONSTEXPR 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_CONSTEXPR14 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_CONSTEXPR14 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<etl::chrono::sys_days>(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<etl::chrono::sys_days>(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_CONSTEXPR14 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_CONSTEXPR14 etl::chrono::year year() const ETL_NOEXCEPT
{
return y;
}
//*************************************************************************
/// Returns the month.
//*************************************************************************
ETL_CONSTEXPR14 etl::chrono::month month() const ETL_NOEXCEPT
{
return m;
}
//*************************************************************************
/// Returns the weekday.
//*************************************************************************
ETL_CONSTEXPR14 etl::chrono::weekday weekday() const ETL_NOEXCEPT
{
return wdl.weekday();
}
//*************************************************************************
/// Returns the weekday_last.
//*************************************************************************
ETL_CONSTEXPR14 etl::chrono::weekday_last weekday_last() const ETL_NOEXCEPT
{
return wdl;
}
//*************************************************************************
/// Adds etl::chrono::years.
//*************************************************************************
ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last& operator +=(const etl::chrono::years& dy) ETL_NOEXCEPT
{
y += dy;
return *this;
}
//*************************************************************************
/// Adds etl::chrono::months.
//*************************************************************************
ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last& operator +=(const etl::chrono::months& dm) ETL_NOEXCEPT
{
m += dm;
return *this;
}
//*************************************************************************
/// Subtracts etl::chrono::years.
//*************************************************************************
ETL_CONSTEXPR14 etl::chrono::year_month_weekday_last& operator -=(const etl::chrono::years& dy) ETL_NOEXCEPT
{
y -= dy;
return *this;
}
//*************************************************************************
/// Subtracts etl::chrono::months.
//*************************************************************************
ETL_CONSTEXPR14 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_CONSTEXPR14 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_CONSTEXPR14 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 cmp1 = lhs.year() <=> rhs.year();
if (cmp1 != 0)
{
return cmp1;
}
else
{
auto cmp2 = lhs.month() <=> rhs.month();
if (cmp2 != 0)
{
return cmp2;
}
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_CONSTEXPR14 operator etl::chrono::sys_days() const ETL_NOEXCEPT
//{
// etl::chrono::sys_days();
//}
//*************************************************************************
///
//*************************************************************************
//ETL_CONSTEXPR14 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<etl::chrono::year_month_weekday>
{
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<size_t>(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<etl::chrono::year_month_weekday_last>
{
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<size_t>(buffer, buffer + sizeof(unsigned int) + sizeof(unsigned int) + sizeof(unsigned int));
}
};
#endif
}

View File

@ -32,6 +32,8 @@ SOFTWARE.
#define ETL_RATIO_INCLUDED
#include "platform.h"
#include "static_assert.h"
#include "gcd.h"
#include "type_traits.h"
@ -43,22 +45,125 @@ SOFTWARE.
namespace etl
{
template <intmax_t NUM, intmax_t DEN = 1UL>
//***********************************************************************
/// ratio
//***********************************************************************
template <intmax_t Num, intmax_t Den = 1UL>
struct ratio
{
static ETL_CONSTANT intmax_t num = NUM;
static ETL_CONSTANT intmax_t den = DEN;
ETL_STATIC_ASSERT(Num != 0, "Numerator cannot be zero");
ETL_STATIC_ASSERT(Den != 0, "Denominator cannot be zero");
static ETL_CONSTANT intmax_t num = Num / etl::gcd_const<Num, Den>::value;
static ETL_CONSTANT intmax_t den = Den / etl::gcd_const<Num, Den>::value;
typedef etl::ratio<num, den> type;
};
template <intmax_t NUM, intmax_t DEN>
ETL_CONSTANT intmax_t ratio<NUM, DEN>::num;
template <intmax_t Num, intmax_t Den>
ETL_CONSTANT intmax_t ratio<Num, Den>::num;
template <intmax_t NUM, intmax_t DEN>
ETL_CONSTANT intmax_t ratio<NUM, DEN>::den;
template <intmax_t Num, intmax_t Den>
ETL_CONSTANT intmax_t ratio<Num, Den>::den;
#if ETL_USING_CPP11
//***********************************************************************
/// ratio_add
//***********************************************************************
template <typename TRatio1, typename TRatio2>
using ratio_add = etl::ratio<(TRatio1::num * TRatio2::den) + (TRatio2::num * TRatio1::den), TRatio1::den * TRatio2::den>;
//***********************************************************************
/// ratio_subtract
//***********************************************************************
template <typename TRatio1, typename TRatio2>
using ratio_subtract = etl::ratio<(TRatio1::num * TRatio2::den) - (TRatio2::num * TRatio1::den), TRatio1::den * TRatio2::den>;
//***********************************************************************
/// ratio_multiply
//***********************************************************************
template <typename TRatio1, typename TRatio2>
using ratio_multiply = etl::ratio<TRatio1::num * TRatio2::num, TRatio1::den * TRatio2::den>;
//***********************************************************************
/// ratio_divide
//***********************************************************************
template <typename TRatio1, typename TRatio2>
using ratio_divide = etl::ratio<TRatio1::num * TRatio2::den, TRatio1::den * TRatio2::num>;
#endif
//***********************************************************************
/// ratio_equal
//***********************************************************************
template <typename TRatio1, typename TRatio2>
struct ratio_equal : etl::bool_constant<(TRatio1::num == TRatio2::num) && (TRatio1::den == TRatio2::den)>
{
};
//***********************************************************************
/// ratio_not_equal
//***********************************************************************
template <typename TRatio1, typename TRatio2>
struct ratio_not_equal : etl::bool_constant<!etl::ratio_equal<TRatio1, TRatio2>::value>
{
};
//***********************************************************************
/// ratio_less
//***********************************************************************
template <typename TRatio1, typename TRatio2>
struct ratio_less : etl::bool_constant<(TRatio1::num * TRatio2::den) < (TRatio2::num * TRatio1::den)>
{
};
//***********************************************************************
/// ratio_less_equal
//***********************************************************************
template <typename TRatio1, typename TRatio2>
struct ratio_less_equal : etl::bool_constant<!etl::ratio_less<TRatio2, TRatio1>::value>
{
};
//***********************************************************************
/// ratio_greater
//***********************************************************************
template <typename TRatio1, typename TRatio2>
struct ratio_greater : etl::bool_constant<etl::ratio_less<TRatio2, TRatio1>::value>
{
};
//***********************************************************************
/// ratio_greater_equal
//***********************************************************************
template <typename TRatio1, typename TRatio2>
struct ratio_greater_equal : etl::bool_constant<!etl::ratio_less<TRatio1, TRatio2>::value>
{
};
#if ETL_USING_CPP17
template<typename R1, typename R2>
inline constexpr bool ratio_equal_v = ratio_equal<R1, R2>::value;
template<typename R1, typename R2>
inline constexpr bool ratio_not_equal_v = ratio_not_equal<R1, R2>::value;
template<typename R1, typename R2>
inline constexpr bool ratio_less_v = ratio_less<R1, R2>::value;
template<typename R1, typename R2>
inline constexpr bool ratio_less_equal_v = ratio_less_equal<R1, R2>::value;
template<typename R1, typename R2>
inline constexpr bool ratio_greater_v = ratio_greater<R1, R2>::value;
template<typename R1, typename R2>
inline constexpr bool ratio_greater_equal_v = ratio_greater_equal<R1, R2>::value;
#endif
//***********************************************************************
/// Predefined ration types.
//***********************************************************************
#if INT_MAX > INT32_MAX
typedef ratio<1, 1000000000000000000000000> yocto;
typedef ratio<1, 1000000000000000000000> zepto;
typedef ratio<1, 1000000000000000000> atto;
typedef ratio<1, 1000000000000000> femto;
typedef ratio<1, 1000000000000> pico;
@ -87,16 +192,17 @@ namespace etl
typedef ratio<1000000000000, 1> tera;
typedef ratio<1000000000000000, 1> peta;
typedef ratio<1000000000000000000, 1> exa;
typedef ratio<1000000000000000000000, 1> zetta;
typedef ratio<1000000000000000000000000, 1> yotta;
#endif
/// An approximation of PI to 6 digits.
/// An approximation of Pi.
typedef ratio<355, 113> ratio_pi;
/// An approximation of root 2.
typedef ratio<239, 169> ratio_root2;
/// An approximation of 1 over root 2.
typedef ratio<169, 239> ratio_1_over_root2;
/// An approximation of e.
typedef ratio<326, 120> ratio_e;
@ -184,67 +290,6 @@ namespace etl
};
}
template<typename R1, typename R2>
using ratio_add = typename private_ratio::ratio_add<R1, R2>::type;
template<typename R1, typename R2>
using ratio_subtract = typename private_ratio::ratio_subtract<R1, R2>::type;
template<typename R1, typename R2>
using ratio_multiply = typename private_ratio::ratio_multiply<R1, R2>::type;
template<typename R1, typename R2>
using ratio_divide = typename private_ratio::ratio_divide<R1, R2>::type;
template<typename R1, typename R2>
struct ratio_equal : etl::integral_constant<bool, (R1::num == R2::num && R1::den == R2::den)>
{
};
template<typename R1, typename R2>
struct ratio_not_equal : etl::integral_constant<bool, (R1::num != R2::num || R1::den != R2::den)>
{
};
template<typename R1, typename R2>
struct ratio_less : etl::integral_constant<bool, (R1::num * R2::den < R2::num * R1::den)>
{
};
template<typename R1, typename R2>
struct ratio_less_equal : etl::integral_constant<bool, (R1::num * R2::den <= R2::num * R1::den)>
{
};
template<typename R1, typename R2>
struct ratio_greater : etl::integral_constant<bool, (R1::num * R2::den > R2::num * R1::den)>
{
};
template<typename R1, typename R2>
struct ratio_greater_equal: etl::integral_constant<bool, (R1::num * R2::den >= R2::num * R1::den)>
{
};
#if ETL_USING_CPP14
template<typename R1, typename R2>
ETL_CONSTEXPR14 bool ratio_equal_v = ratio_equal<R1, R2>::value;
template<typename R1, typename R2>
ETL_CONSTEXPR14 bool ratio_not_equal_v = ratio_not_equal<R1, R2>::value;
template<typename R1, typename R2>
ETL_CONSTEXPR14 bool ratio_less_v = ratio_less<R1, R2>::value;
template<typename R1, typename R2>
ETL_CONSTEXPR14 bool ratio_less_equal_v = ratio_less_equal<R1, R2>::value;
template<typename R1, typename R2>
ETL_CONSTEXPR14 bool ratio_greater_v = ratio_greater<R1, R2>::value;
template<typename R1, typename R2>
ETL_CONSTEXPR14 bool ratio_greater_equal_v = ratio_greater_equal<R1, R2>::value;
#endif
#endif
}

View File

@ -1,5 +1,3 @@
///\file
/******************************************************************************
The MIT License(MIT)
@ -7,9 +5,7 @@ Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Documentation: https://www.etlcpp.com/algorithm.html
Copyright(c) 2024 John Wellbelove
Copyright(c) 2014 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
@ -35,11 +31,11 @@ SOFTWARE.
#include "platform.h"
#if ETL_NOT_USING_CPP11
#if !defined(ETL_IN_UNIT_TEST)
#error NOT SUPPORTED FOR C++03 OR BELOW
#endif
#else
#if ETL_NOT_USING_CPP11 && !defined(ETL_IN_UNIT_TEST)
#error NOT SUPPORTED FOR C++03 OR BELOW
#endif
#if ETL_USING_CPP11
#if ETL_USING_STL
#include <tuple>
@ -1298,5 +1294,6 @@ namespace std
using type = typename etl::nth_type_t<I, Types...>;
};
}
#endif
#endif

View File

@ -58,6 +58,24 @@ add_executable(etl_tests
test_callback_timer_locked.cpp
test_char_traits.cpp
test_checksum.cpp
test_chrono_clocks.cpp
test_chrono_day.cpp
test_chrono_duration.cpp
test_chrono_hh_mm_ss.cpp
test_chrono_month.cpp
test_chrono_month_day.cpp
test_chrono_month_day_last.cpp
test_chrono_month_weekday.cpp
test_chrono_month_weekday_last.cpp
test_chrono_operators.cpp
test_chrono_time_point.cpp
test_chrono_weekday.cpp
test_chrono_weekday_indexed.cpp
test_chrono_weekday_last.cpp
test_chrono_year.cpp
test_chrono_year_month.cpp
test_chrono_year_month_day.cpp
test_chrono_year_month_day_last.cpp
test_circular_buffer.cpp
test_circular_buffer_external_buffer.cpp
test_circular_iterator.cpp
@ -143,13 +161,11 @@ add_executable(etl_tests
test_fsm.cpp
test_function.cpp
test_functional.cpp
test_function_traits.cpp
test_gamma.cpp
test_hash.cpp
test_hfsm.cpp
test_hfsm_recurse_to_inner_state_on_start.cpp
test_histogram.cpp
test_index_of_type.cpp
test_indirect_vector.cpp
test_indirect_vector_external_buffer.cpp
test_instance_count.cpp
@ -224,7 +240,6 @@ add_executable(etl_tests
test_queue_spsc_locked.cpp
test_queue_spsc_locked_small.cpp
test_random.cpp
test_ratio.cpp
test_reference_flat_map.cpp
test_reference_flat_multimap.cpp
test_reference_flat_multiset.cpp
@ -236,7 +251,6 @@ add_executable(etl_tests
test_set.cpp
test_shared_message.cpp
test_singleton.cpp
test_singleton_base.cpp
test_smallest.cpp
test_span_dynamic_extent.cpp
test_span_fixed_extent.cpp
@ -286,15 +300,11 @@ add_executable(etl_tests
test_to_u32string.cpp
test_to_u8string.cpp
test_to_wstring.cpp
test_tuple.cpp
test_type_def.cpp
test_type_list.cpp
test_type_lookup.cpp
test_type_select.cpp
test_type_traits.cpp
test_unaligned_type.cpp
test_unaligned_type_ext.cpp
test_uncopyable.cpp
test_unordered_map.cpp
test_unordered_multimap.cpp
test_unordered_multiset.cpp

View File

@ -0,0 +1,5 @@
ETL_CONSTEXPR constexpr
ETL_CONSTEXPR14
ETL_CONSTEXPR17
ETL_CONSTEXPR20
ETL_IF_CONSTEXPR20

View File

@ -120,6 +120,12 @@ SOFTWARE.
#endif
#endif
#define ETL_CHRONO_SYSTEM_CLOCK_DURATION etl::chrono::milliseconds
#define ETL_CHRONO_HIGH_RESOLUTION_CLOCK_DURATION etl::chrono::nanoseconds
#define ETL_CHRONO_STEADY_CLOCK_DURATION etl::chrono::seconds
#define ETL_CHRONO_SYSTEM_CLOCK_IS_STEADY false
#if defined(ETL_DEVELOPMENT_OS_WINDOWS)
#define ETL_TARGET_OS_WINDOWS
#elif defined(ETL_DEVELOPMENT_OS_LINUX)

View File

@ -96,6 +96,7 @@ target_sources(tests PRIVATE
callback_timer_locked.h.t.cpp
char_traits.h.t.cpp
checksum.h.t.cpp
chrono.h.t.cpp
circular_buffer.h.t.cpp
circular_iterator.h.t.cpp
combinations.h.t.cpp

View File

@ -0,0 +1,28 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2025 J 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.
******************************************************************************/
#include <etl/chrono.h>

175
test/test_chrono_clocks.cpp Normal file
View File

@ -0,0 +1,175 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Documentation:
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.
******************************************************************************/
#include "etl/platform.h"
#include "unit_test_framework.h"
#include "etl/chrono.h"
#include <type_traits>
//*****************************************************************************
// Global clock functions.
//*****************************************************************************
namespace
{
int nanoseconds = 0;
int milliseconds = 0;
int seconds = 0;
}
extern "C"
{
etl::chrono::system_clock::rep etl_get_system_clock()
{
return etl::chrono::system_clock::rep(milliseconds);
}
etl::chrono::high_resolution_clock::rep etl_get_high_resolution_clock()
{
return etl::chrono::high_resolution_clock::rep(nanoseconds);
}
etl::chrono::steady_clock::rep etl_get_steady_clock()
{
return etl::chrono::steady_clock::rep(seconds);
}
}
namespace
{
SUITE(test_chrono_clocks)
{
//*************************************************************************
TEST(test_system_clock)
{
using Clock = etl::chrono::system_clock;
using TimePoint = etl::chrono::time_point<Clock>;
using Duration = ETL_CHRONO_SYSTEM_CLOCK_DURATION;
CHECK_TRUE((std::is_same<TimePoint, Clock::time_point>::value));
CHECK_TRUE((std::is_same<Duration, Clock::duration>::value));
CHECK_TRUE((std::is_same<Duration::rep, Clock::duration::rep>::value));
CHECK_TRUE((std::is_same<Duration::period, Clock::duration::period>::value));
CHECK_FALSE(Clock::is_steady); // Set in etl_profile.h
Clock::time_point now;
milliseconds = 1000;
now = Clock::now();
CHECK_EQUAL(1000, now.time_since_epoch().count());
milliseconds = 2000;
now = Clock::now();
CHECK_EQUAL(2000, now.time_since_epoch().count());
// Convert to seconds.
etl::time_t time = Clock::to_time_t(now);
CHECK_EQUAL(2, time);
// Convert back to a TimePoint.
TimePoint tp2 = Clock::from_time_t(time);
CHECK_EQUAL(2000, tp2.time_since_epoch().count());
}
//*************************************************************************
TEST(test_high_resolution_clock)
{
using Clock = etl::chrono::high_resolution_clock;
using TimePoint = etl::chrono::time_point<Clock>;
using Duration = ETL_CHRONO_HIGH_RESOLUTION_CLOCK_DURATION;
CHECK_TRUE((std::is_same<TimePoint, Clock::time_point>::value));
CHECK_TRUE((std::is_same<Duration, Clock::duration>::value));
CHECK_TRUE((std::is_same<Duration::rep, Clock::duration::rep>::value));
CHECK_TRUE((std::is_same<Duration::period, Clock::duration::period>::value));
CHECK_TRUE(Clock::is_steady);
Clock::time_point now;
nanoseconds = 1;
now = Clock::now();
CHECK_EQUAL(1, now.time_since_epoch().count());
nanoseconds = 2;
now = Clock::now();
CHECK_EQUAL(2, now.time_since_epoch().count());
}
//*************************************************************************
TEST(test_steady_clock)
{
using Clock = etl::chrono::steady_clock;
using TimePoint = etl::chrono::time_point<Clock>;
using Duration = ETL_CHRONO_STEADY_CLOCK_DURATION;
CHECK_TRUE((std::is_same<TimePoint, Clock::time_point>::value));
CHECK_TRUE((std::is_same<Duration, Clock::duration>::value));
CHECK_TRUE((std::is_same<Duration::rep, Clock::duration::rep>::value));
CHECK_TRUE((std::is_same<Duration::period, Clock::duration::period>::value));
CHECK_TRUE(Clock::is_steady);
Clock::time_point now;
seconds = 1;
now = Clock::now();
CHECK_EQUAL(1, now.time_since_epoch().count());
seconds = 2;
now = Clock::now();
CHECK_EQUAL(2, now.time_since_epoch().count());
}
//*************************************************************************
TEST(test_clock_cast)
{
using FromClock = etl::chrono::system_clock;
using FromTimePoint = etl::chrono::time_point<FromClock>;
using FromDuration = FromClock::duration;
using ToClock = etl::chrono::steady_clock;
using ToTimePoint = etl::chrono::time_point<ToClock>;
using ToDuration = ToClock::duration;
FromTimePoint from_tp(FromDuration(1000));
ToTimePoint to_tp = etl::chrono::clock_cast<ToClock>(from_tp);
auto num_sys_clock = FromDuration::period::den;
auto num_steady_clock = ToDuration::period::num;
auto sys_clock_count = from_tp.time_since_epoch().count();
auto scaled_steady_lock_count = (to_tp.time_since_epoch().count() * num_sys_clock) / num_steady_clock;
CHECK_EQUAL(sys_clock_count, scaled_steady_lock_count);
}
};
}

323
test/test_chrono_day.cpp Normal file
View File

@ -0,0 +1,323 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Documentation:
Copyright(c) 2023 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.
******************************************************************************/
#include "etl/platform.h"
#include "unit_test_framework.h"
#include "etl/chrono.h"
#include <vector>
#include <algorithm>
// 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 <chrono>
#define Chrono std::chrono
#else
#error std::chrono not supported
#endif
#endif
namespace
{
//*************************************************************************
bool expected_day_ok(Chrono::day day)
{
unsigned d = unsigned(day);
if ((d < 1) || (d > 31))
{
return (day.ok() == false);
}
else
{
return (day.ok() == true);
}
}
SUITE(test_chrono_day)
{
//*************************************************************************
TEST(test_default_constructor)
{
Chrono::day day;
CHECK_FALSE(day.ok());
}
//*************************************************************************
TEST(test_constructor_in_range)
{
for (unsigned expected = 1U; expected < 31; ++expected)
{
Chrono::day day(expected);
CHECK_TRUE(expected_day_ok(day));
CHECK_EQUAL(expected, unsigned(day));
}
}
//*************************************************************************
TEST(test_pre_increment)
{
Chrono::day day(0);
for (int expected = 0; expected < 256; ++expected, ++day)
{
CHECK_TRUE(expected_day_ok(day));
CHECK_EQUAL(expected, unsigned(day));
}
}
//*************************************************************************
TEST(test_post_increment)
{
Chrono::day day(0);
for (int expected = 0; expected < 256; expected++, day++)
{
CHECK_TRUE(expected_day_ok(day));
CHECK_EQUAL(expected, unsigned(day));
}
}
//*************************************************************************
TEST(test_pre_decrement)
{
Chrono::day day(255);
for (int expected = 255; expected > 0; --expected, --day)
{
CHECK_TRUE(expected_day_ok(day));
CHECK_EQUAL(expected, unsigned(day));
}
}
//*************************************************************************
TEST(test_post_decrement)
{
Chrono::day day(255);
for (int expected = 255; expected > 0; expected--, day--)
{
CHECK_TRUE(expected_day_ok(day));
CHECK_EQUAL(expected, unsigned(day));
}
}
//*************************************************************************
TEST(test_plus_equal_days)
{
Chrono::day day(0);
Chrono::days days(2);
for (int expected = 2; expected < 256; expected += 2)
{
day += days;
CHECK_TRUE(expected_day_ok(day));
CHECK_EQUAL(expected, unsigned(day));
}
}
//*************************************************************************
TEST(test_day_plus_days)
{
for (int d = 0; d < 256; ++d)
{
for (int ds = 0; ds < 256; ++ds)
{
Chrono::day day(d);
Chrono::days days(ds);
day = day + days;
unsigned expected = (d + ds) % 256;
CHECK_TRUE(expected_day_ok(day));
CHECK_EQUAL(expected, unsigned(day));
}
}
}
//*************************************************************************
TEST(test_days_plus_day)
{
for (int d = 0; d < 256; ++d)
{
for (int ds = 0; ds < d; ++ds)
{
Chrono::day day(d);
Chrono::days days(ds);
day = days + day;
unsigned expected = (d + ds) % 256;
CHECK_TRUE(expected_day_ok(day));
CHECK_EQUAL(expected, unsigned(day));
}
}
}
//*************************************************************************
TEST(test_minus_equal_days)
{
Chrono::day day(255);
Chrono::days days(2);
for (int expected = 253; expected > 0; expected -= 2)
{
day -= days;
CHECK_TRUE(expected_day_ok(day));
CHECK_EQUAL(expected, unsigned(day));
}
}
//*************************************************************************
TEST(test_day_minus_days)
{
Chrono::day day(255);
Chrono::days days(2);
for (int expected = 253; expected > 0; expected -= 2)
{
day = day - days;
CHECK_TRUE(expected_day_ok(day));
CHECK_EQUAL(expected, unsigned(day));
}
}
//*************************************************************************
TEST(test_day_minus_day)
{
for (int d1 = 0; d1 < 256; ++d1)
{
for (int d2 = 0; d2 < 256; ++d2)
{
Chrono::day day1(d1);
Chrono::day day2(d2);
Chrono::days result_days = day1 - day2;
int expected_days = d1 - d2;
CHECK_EQUAL(expected_days, result_days.count());
}
}
}
#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)
{
using namespace etl::literals::chrono_literals;
Chrono::day day = 25_day;
CHECK_TRUE(day.ok());
CHECK_EQUAL(25, unsigned(day));
}
#endif
//*************************************************************************
TEST(test_day_comparison_operators)
{
Chrono::day day10(10);
Chrono::day day20(20);
CHECK_TRUE(day10 == day10);
CHECK_FALSE(day10 != day10);
CHECK_TRUE(day10 < day20);
CHECK_FALSE(day10 < day10);
CHECK_FALSE(day20 < day10);
CHECK_TRUE(day10 <= day20);
CHECK_TRUE(day10 <= day10);
CHECK_FALSE(day20 <= day10);
CHECK_FALSE(day10 > day20);
CHECK_FALSE(day10 > day10);
CHECK_TRUE(day20 > day10);
CHECK_FALSE(day10 >= day20);
CHECK_TRUE(day10 >= day10);
CHECK_TRUE(day20 >= day10);
#if ETL_USING_CPP20
CHECK_TRUE((day10 <=> day10) == 0);
CHECK_TRUE((day10 <=> day20) < 0);
CHECK_TRUE((day20 <=> day10) > 0);
#endif
}
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_day_compare)
{
Chrono::day day10(10);
Chrono::day day20(20);
CHECK_EQUAL(0, day10.compare(day10));
CHECK_EQUAL(-1, day10.compare(day20));
CHECK_EQUAL(1, day20.compare(day10));
}
#endif
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_day_hashes_are_unique)
{
std::vector<size_t> hashes;
for (int i = 0; i < 256; ++i)
{
hashes.push_back(etl::hash<Chrono::day>()(Chrono::day(i)));
}
std::sort(hashes.begin(), hashes.end());
(void)std::unique(hashes.begin(), hashes.end());
CHECK_EQUAL(256U, hashes.size());
}
#endif
};
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,289 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Documentation:
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.
******************************************************************************/
#include "etl/platform.h"
#include "unit_test_framework.h"
#include "etl/chrono.h"
// Set to 0 to reference against std::chrono
#define ETL_USING_ETL_CHRONO 1
#if ETL_USING_ETL_CHRONO
#define Chrono etl::chrono
#define Ratio etl::ratio
#else
#if ETL_USING_CPP20
#include <chrono>
#define Chrono std::chrono
#define Ratio std::ratio
#else
#error std::chrono not supported
#endif
#endif
namespace
{
SUITE(test_chrono_hh_mm_ss)
{
//*************************************************************************
TEST(test_default_constructor)
{
using duration_type = Chrono::seconds;
// Create a duration of 0 hour, 0 minutes, 0 seconds
Chrono::hh_mm_ss<duration_type> time;
auto h = time.hours();
auto m = time.minutes();
auto s = time.seconds();
auto sub = time.subseconds();
auto dur = time.to_duration();
CHECK_EQUAL(Chrono::hours(0).count(), h.count());
CHECK_EQUAL(Chrono::minutes(0).count(), m.count());
CHECK_EQUAL(Chrono::seconds(0).count(), s.count());
CHECK_EQUAL(duration_type(0).count(), sub.count());
CHECK_EQUAL(0, dur.count());
CHECK_FALSE(time.is_negative());
CHECK_EQUAL(0, time.fractional_width);
CHECK_TRUE((std::is_same<duration_type, Chrono::hh_mm_ss<duration_type>::precision>::value));
}
//*************************************************************************
TEST(test_construction_with_seconds)
{
using duration_type = Chrono::seconds;
// Create a duration of 1 hour, 2 minutes, 3 seconds
duration_type duration = Chrono::hours(1) + Chrono::minutes(2) + Chrono::seconds(3);
Chrono::hh_mm_ss<duration_type> time(duration);
auto h = time.hours();
auto m = time.minutes();
auto s = time.seconds();
auto sub = time.subseconds();
auto dur = time.to_duration();
CHECK_EQUAL(Chrono::hours(1).count(), h.count());
CHECK_EQUAL(Chrono::minutes(2).count(), m.count());
CHECK_EQUAL(Chrono::seconds(3).count(), s.count());
CHECK_EQUAL(duration_type(0).count(), sub.count());
CHECK_EQUAL(3723, dur.count());
CHECK_FALSE(time.is_negative());
CHECK_EQUAL(0, time.fractional_width);
CHECK_TRUE((std::is_same<duration_type, Chrono::hh_mm_ss<duration_type>::precision>::value));
}
//*************************************************************************
TEST(test_construction_with_negative_seconds)
{
using duration_type = Chrono::seconds;
// Create a duration of minus 1 hour, 2 minutes, 3 seconds
duration_type duration = -(Chrono::hours(1) + Chrono::minutes(2) + Chrono::seconds(3));
Chrono::hh_mm_ss<duration_type> time(duration);
auto h = time.hours();
auto m = time.minutes();
auto s = time.seconds();
auto sub = time.subseconds();
auto dur = time.to_duration();
CHECK_EQUAL(Chrono::hours(1).count(), h.count());
CHECK_EQUAL(Chrono::minutes(2).count(), m.count());
CHECK_EQUAL(Chrono::seconds(3).count(), s.count());
CHECK_EQUAL(duration_type(0).count(), sub.count());
CHECK_EQUAL(-3723, dur.count());
CHECK_TRUE(time.is_negative());
CHECK_EQUAL(0, time.fractional_width);
CHECK_TRUE((std::is_same<duration_type, Chrono::hh_mm_ss<duration_type>::precision>::value));
}
//*************************************************************************
TEST(test_construction_with_milliseconds)
{
using duration_type = Chrono::milliseconds;
// Create a duration of 1 hour, 2 minutes, 3 seconds, 456 milliseconds
duration_type duration = Chrono::hours(1) + Chrono::minutes(2) + Chrono::seconds(3) + duration_type(456);
Chrono::hh_mm_ss<duration_type> time(duration);
auto h = time.hours();
auto m = time.minutes();
auto s = time.seconds();
auto sub = time.subseconds();
auto dur = time.to_duration();
CHECK_EQUAL(Chrono::hours(1).count(), h.count());
CHECK_EQUAL(Chrono::minutes(2).count(), m.count());
CHECK_EQUAL(Chrono::seconds(3).count(), s.count());
CHECK_EQUAL(duration_type(456).count(), sub.count());
CHECK_EQUAL(3723456, dur.count());
CHECK_FALSE(time.is_negative());
CHECK_EQUAL(3, time.fractional_width);
CHECK_TRUE((std::is_same<duration_type, Chrono::hh_mm_ss<duration_type>::precision>::value));
}
//*************************************************************************
TEST(test_construction_with_negative_milliseconds)
{
using duration_type = Chrono::milliseconds;
// Create a duration of minus 1 hour, 2 minutes, 3 seconds, 456 milliseconds
duration_type duration = -(Chrono::hours(1) + Chrono::minutes(2) + Chrono::seconds(3) + duration_type(456));
Chrono::hh_mm_ss<duration_type> time(duration);
auto h = time.hours();
auto m = time.minutes();
auto s = time.seconds();
auto sub = time.subseconds();
auto dur = time.to_duration();
CHECK_EQUAL(Chrono::hours(1).count(), h.count());
CHECK_EQUAL(Chrono::minutes(2).count(), m.count());
CHECK_EQUAL(Chrono::seconds(3).count(), s.count());
CHECK_EQUAL(duration_type(456).count(), sub.count());
CHECK_EQUAL(-3723456, dur.count());
CHECK_TRUE(time.is_negative());
CHECK_EQUAL(3, time.fractional_width);
CHECK_TRUE((std::is_same<duration_type, Chrono::hh_mm_ss<duration_type>::precision>::value));
}
//*************************************************************************
TEST(test_construction_with_float_seconds)
{
using duration_type = Chrono::duration<float, Ratio<1, 1>>;
// Create a duration of 1 hour, 2 minutes, 3.456 seconds
duration_type duration = Chrono::hours(1) + Chrono::minutes(2) + duration_type(3.456);
Chrono::hh_mm_ss<duration_type> time(duration);
auto h = time.hours();
auto m = time.minutes();
auto s = time.seconds();
auto sub = time.subseconds();
auto dur = time.to_duration();
CHECK_EQUAL(1, h.count());
CHECK_EQUAL(2, m.count());
CHECK_EQUAL(3, s.count());
CHECK_CLOSE(0.456f, sub.count(), 0.0001f);
CHECK_CLOSE(3723.456f, dur.count(), 0.0001f);
CHECK_FALSE(time.is_negative());
CHECK_EQUAL(0, time.fractional_width);
CHECK_TRUE((std::is_same<duration_type, Chrono::hh_mm_ss<duration_type>::precision>::value));
}
//*************************************************************************
TEST(test_construction_with_negative_float_seconds)
{
using duration_type = Chrono::duration<float, Ratio<1, 1>>;
// Create a duration of 1 hour, 2 minutes, 3.456 seconds
duration_type duration = -(Chrono::hours(1) + Chrono::minutes(2) + duration_type(3.456));
Chrono::hh_mm_ss<duration_type> time(duration);
auto h = time.hours();
auto m = time.minutes();
auto s = time.seconds();
auto sub = time.subseconds();
auto dur = time.to_duration();
CHECK_EQUAL(1, h.count());
CHECK_EQUAL(2, m.count());
CHECK_EQUAL(3, s.count());
CHECK_CLOSE(0.456f, sub.count(), 0.0001f);
CHECK_CLOSE(-3723.456f, dur.count(), 0.0001f);
CHECK_TRUE(time.is_negative());
CHECK_EQUAL(0, time.fractional_width);
CHECK_TRUE((std::is_same<duration_type, Chrono::hh_mm_ss<duration_type>::precision>::value));
}
//*************************************************************************
TEST(test_construction_with_double_seconds)
{
using duration_type = Chrono::duration<double, Ratio<1, 1>>;
// Create a duration of 1 hour, 2 minutes, 3.456 seconds
duration_type duration = Chrono::hours(1) + Chrono::minutes(2) + duration_type(3.456);
Chrono::hh_mm_ss<duration_type> time(duration);
auto h = time.hours();
auto m = time.minutes();
auto s = time.seconds();
auto sub = time.subseconds();
auto dur = time.to_duration();
CHECK_EQUAL(1, h.count());
CHECK_EQUAL(2, m.count());
CHECK_EQUAL(3, s.count());
CHECK_CLOSE(0.456, sub.count(), 0.0001);
CHECK_CLOSE(3723.456, dur.count(), 0.0001);
CHECK_FALSE(time.is_negative());
CHECK_EQUAL(0, time.fractional_width);
CHECK_TRUE((std::is_same<duration_type, Chrono::hh_mm_ss<duration_type>::precision>::value));
}
//*************************************************************************
TEST(test_construction_with_negative_double_seconds)
{
using duration_type = Chrono::duration<double, Ratio<1, 1>>;
// Create a duration of 1 hour, 2 minutes, 3.456 seconds
duration_type duration = -(Chrono::hours(1) + Chrono::minutes(2) + duration_type(3.456));
Chrono::hh_mm_ss<duration_type> time(duration);
auto h = time.hours();
auto m = time.minutes();
auto s = time.seconds();
auto sub = time.subseconds();
auto dur = time.to_duration();
CHECK_EQUAL(1, h.count());
CHECK_EQUAL(2, m.count());
CHECK_EQUAL(3, s.count());
CHECK_CLOSE(0.456, sub.count(), 0.0001);
CHECK_CLOSE(-3723.456, dur.count(), 0.0001);
CHECK_TRUE(time.is_negative());
CHECK_EQUAL(0, time.fractional_width);
CHECK_TRUE((std::is_same<duration_type, Chrono::hh_mm_ss<duration_type>::precision>::value));
}
};
}

403
test/test_chrono_month.cpp Normal file
View File

@ -0,0 +1,403 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Documentation:
Copyright(c) 2023 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.
******************************************************************************/
#include "etl/platform.h"
#include "unit_test_framework.h"
#include "etl/chrono.h"
#include <vector>
#include <algorithm>
// 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 <chrono>
#define Chrono std::chrono
#else
#error std::chrono not supported
#endif
#endif
namespace
{
//*************************************************************************
unsigned expected_month(int i)
{
i = i % 12;
if (i < 0)
{
i = 12 + i;
}
return i == 0 ? 12 : i;
}
//*************************************************************************
bool expected_month_ok(Chrono::month month)
{
unsigned m = unsigned(month);
if ((m < 1) || (m > 12))
{
return (month.ok() == false);
}
else
{
return (month.ok() == true);
}
}
SUITE(test_chrono_month)
{
//*************************************************************************
TEST(test_default_constructor)
{
Chrono::month month;
CHECK_TRUE(expected_month_ok(month));
}
//*************************************************************************
TEST(test_constructor_in_range)
{
for (unsigned i = 0U; i < 256; ++i)
{
Chrono::month month(i);
CHECK_TRUE(expected_month_ok(month));
CHECK_EQUAL(i, unsigned(month));
}
}
//*************************************************************************
TEST(test_pre_increment)
{
Chrono::month month(0);
for (int i = 1; i < 256; ++i)
{
++month;
CHECK_TRUE(expected_month_ok(month));
CHECK_EQUAL(expected_month(i), unsigned(month));
}
}
//*************************************************************************
TEST(test_post_increment)
{
Chrono::month month(0);
for (int i = 1; i < 256; ++i)
{
month++;
CHECK_TRUE(expected_month_ok(month));
CHECK_EQUAL(expected_month(i), unsigned(month));
}
}
//*************************************************************************
TEST(test_pre_decrement)
{
Chrono::month month(255);
for (int i = 254; i > 1; --i)
{
--month;
CHECK_TRUE(expected_month_ok(month));
CHECK_EQUAL(expected_month(i), unsigned(month));
}
}
//*************************************************************************
TEST(test_post_decrement)
{
Chrono::month month(255);
for (int i = 254; i > 1; --i)
{
month--;
CHECK_TRUE(expected_month_ok(month));
CHECK_EQUAL(expected_month(i), unsigned(month));
}
}
//*************************************************************************
TEST(test_plus_equal_months)
{
for (int m = 0; m <= 12; ++m)
{
for (int ms = 0; ms <= 24; ++ms)
{
Chrono::month month(m);
Chrono::months months(ms);
month += months;
CHECK_TRUE(expected_month_ok(month));
CHECK_EQUAL(expected_month(m + ms), unsigned(month));
}
}
}
//*************************************************************************
TEST(test_month_plus_months)
{
for (int m = 0; m <= 12; ++m)
{
for (int ms = 0; ms <= 24; ++ms)
{
Chrono::month month(m);
Chrono::months months(ms);
month = month + months;
CHECK_TRUE(expected_month_ok(month));
CHECK_EQUAL(expected_month(m + ms), unsigned(month));
}
}
}
//*************************************************************************
TEST(test_months_plus_month)
{
for (int m = 0; m <= 12; ++m)
{
for (int ms = 0; ms <= 24; ++ms)
{
Chrono::month month(m);
Chrono::months months(ms);
month = months + month;
CHECK_TRUE(expected_month_ok(month));
CHECK_EQUAL(expected_month(m + ms), unsigned(month));
}
}
}
//*************************************************************************
TEST(test_minus_equal_months)
{
for (int m = 0; m <= 12; ++m)
{
for (int ms = 0; ms <= 24; ++ms)
{
Chrono::month month(m);
Chrono::months months(ms);
month -= months;
CHECK_TRUE(expected_month_ok(month));
CHECK_EQUAL(expected_month(m - ms), unsigned(month));
}
}
}
//*************************************************************************
TEST(test_month_minus_months)
{
for (int m = 0; m <= 12; ++m)
{
for (int ms = 0; ms <= 24; ++ms)
{
Chrono::month month(m);
Chrono::months months(ms);
month = month - months;
CHECK_TRUE(expected_month_ok(month));
CHECK_EQUAL(expected_month(m - ms), unsigned(month));
}
}
}
//*************************************************************************
TEST(test_month_minus_month)
{
for (int m = 1; m < 13; ++m)
{
int m1 = m;
int m2 = 13 - m;
Chrono::month month1(m1);
Chrono::month month2(m2);
Chrono::months months12 = month1 - month2;
Chrono::months months21 = month2 - month1;
int difference12 = expected_month(m1) - expected_month(m2);
int difference21 = expected_month(m2) - expected_month(m1);
difference12 = (difference12 < 0) ? 12 + difference12: difference12;
difference21 = (difference21 < 0) ? 12 + difference21: difference21;
CHECK_EQUAL(difference12, months12.count());
CHECK_EQUAL(difference21, months21.count());
}
}
#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)
{
Chrono::month month1(Chrono::January);
Chrono::month month2(Chrono::February);
CHECK_EQUAL(0, month1.compare(month1));
CHECK_EQUAL(-1, month1.compare(month2));
CHECK_EQUAL(1, month2.compare(month1));
}
#endif
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_literal_month)
{
using namespace etl::literals::chrono_literals;
Chrono::month month1 = 1_month;
Chrono::month month2 = 2_month;
Chrono::month month3 = 3_month;
Chrono::month month4 = 4_month;
Chrono::month month5 = 5_month;
Chrono::month month6 = 6_month;
Chrono::month month7 = 7_month;
Chrono::month month8 = 8_month;
Chrono::month month9 = 9_month;
Chrono::month month10 = 10_month;
Chrono::month month11 = 11_month;
Chrono::month month12 = 12_month;
CHECK_TRUE(month1.ok());
CHECK_TRUE(month2.ok());
CHECK_TRUE(month3.ok());
CHECK_TRUE(month4.ok());
CHECK_TRUE(month5.ok());
CHECK_TRUE(month6.ok());
CHECK_TRUE(month7.ok());
CHECK_TRUE(month8.ok());
CHECK_TRUE(month9.ok());
CHECK_TRUE(month10.ok());
CHECK_TRUE(month11.ok());
CHECK_TRUE(month12.ok());
CHECK_EQUAL(1U, unsigned(month1));
CHECK_EQUAL(2U, unsigned(month2));
CHECK_EQUAL(3U, unsigned(month3));
CHECK_EQUAL(4U, unsigned(month4));
CHECK_EQUAL(5U, unsigned(month5));
CHECK_EQUAL(6U, unsigned(month6));
CHECK_EQUAL(7U, unsigned(month7));
CHECK_EQUAL(8U, unsigned(month8));
CHECK_EQUAL(9U, unsigned(month9));
CHECK_EQUAL(10U, unsigned(month10));
CHECK_EQUAL(11U, unsigned(month11));
CHECK_EQUAL(12U, unsigned(month12));
}
#endif
//*************************************************************************
TEST(test_month_comparison_operators)
{
Chrono::month month1(1);
Chrono::month month2(2);
CHECK_TRUE(month1 == month1);
CHECK_FALSE(month1 != month1);
CHECK_TRUE(month1 < month2);
CHECK_FALSE(month1 < month1);
CHECK_FALSE(month2 < month1);
CHECK_TRUE(month1 <= month2);
CHECK_TRUE(month1 <= month1);
CHECK_FALSE(month2 <= month1);
CHECK_FALSE(month1 > month2);
CHECK_FALSE(month1 > month1);
CHECK_TRUE(month2 > month1);
CHECK_FALSE(month1 >= month2);
CHECK_TRUE(month1 >= month1);
CHECK_TRUE(month2 >= month1);
#if ETL_USING_CPP20
CHECK_TRUE((month1 <=> month1) == 0);
CHECK_TRUE((month1 <=> month2) < 0);
CHECK_TRUE((month2 <=> month1) > 0);
#endif
}
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_month_hashes_are_unique)
{
std::vector<size_t> hashes;
for (int i = 0; i < 256; ++i)
{
hashes.push_back(etl::hash<Chrono::month>()(Chrono::month(i)));
}
std::sort(hashes.begin(), hashes.end());
(void)std::unique(hashes.begin(), hashes.end());
CHECK_EQUAL(256U, hashes.size());
}
#endif
//*************************************************************************
TEST(test_month_types)
{
CHECK_EQUAL(1U, static_cast<unsigned>(Chrono::January));
CHECK_EQUAL(2U, static_cast<unsigned>(Chrono::February));
CHECK_EQUAL(3U, static_cast<unsigned>(Chrono::March));
CHECK_EQUAL(4U, static_cast<unsigned>(Chrono::April));
CHECK_EQUAL(5U, static_cast<unsigned>(Chrono::May));
CHECK_EQUAL(6U, static_cast<unsigned>(Chrono::June));
CHECK_EQUAL(7U, static_cast<unsigned>(Chrono::July));
CHECK_EQUAL(8U, static_cast<unsigned>(Chrono::August));
CHECK_EQUAL(9U, static_cast<unsigned>(Chrono::September));
CHECK_EQUAL(10U, static_cast<unsigned>(Chrono::October));
CHECK_EQUAL(11U, static_cast<unsigned>(Chrono::November));
CHECK_EQUAL(12U, static_cast<unsigned>(Chrono::December));
}
};
}

View File

@ -34,11 +34,22 @@ SOFTWARE.
#include "etl/chrono.h"
#include <chrono>
#include <array>
#include <vector>
#include <algorithm>
#if ETL_USING_CPP20
// 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 <chrono>
#define Chrono std::chrono
#else
#error std::chrono not supported
#endif
#endif
namespace
{
@ -47,338 +58,158 @@ namespace
//*************************************************************************
TEST(test_default_constructor)
{
etl::chrono::month_day md;
Chrono::month_day md;
CHECK_FALSE(md.ok());
CHECK_FALSE(md.ok()); // Default-constructed month_day is not valid
}
//*************************************************************************
TEST(test_constructor_in_range)
TEST(test_constructor_with_month_and_day)
{
for (unsigned i = 0U; i < 256; ++i)
{
std::chrono::month std_month(i);
etl::chrono::month month(i);
Chrono::month_day md{Chrono::January, Chrono::day{15}};
CHECK_EQUAL(std_month.ok(), month.ok());
CHECK_EQUAL(unsigned(std_month), unsigned(month));
}
CHECK_TRUE(md.ok()); // Valid month_day
CHECK_EQUAL(Chrono::January, md.month());
CHECK_EQUAL(Chrono::day{15}, md.day());
}
//*************************************************************************
TEST(test_pre_increment)
TEST(test_invalid_month_day)
{
std::chrono::month std_month(0);
etl::chrono::month month(0);
Chrono::month_day md{Chrono::month{13}, Chrono::day{15}}; // Invalid month (13)
for (int i = 0; i < 255; ++i)
{
++std_month;
++month;
CHECK_EQUAL(std_month.ok(), month.ok());
CHECK_EQUAL(unsigned(std_month), unsigned(month));
}
CHECK_FALSE(md.ok()); // Invalid month_day
}
//*************************************************************************
TEST(test_post_increment)
TEST(test_invalid_day_in_month_day)
{
std::chrono::month std_month(0);
etl::chrono::month month(0);
Chrono::month_day md{Chrono::January, Chrono::day{32}}; // Invalid day (32)
for (int i = 0; i < 256; ++i)
{
std::chrono::month std_last_month = std_month++;
etl::chrono::month last_month = month++;
CHECK_EQUAL(std_last_month.ok(), last_month.ok());
CHECK_EQUAL(unsigned(std_last_month), unsigned(last_month));
CHECK_EQUAL(std_month.ok(), month.ok());
CHECK_EQUAL(unsigned(std_month), unsigned(month));
}
CHECK_FALSE(md.ok()); // Invalid month_day
}
//*************************************************************************
TEST(test_pre_decrement)
{
std::chrono::month std_month(255);
etl::chrono::month month(255);
for (int i = 0; i < 256; ++i)
{
--std_month;
--month;
CHECK_EQUAL(std_month.ok(), month.ok());
CHECK_EQUAL(unsigned(std_month), unsigned(month));
}
}
//*************************************************************************
TEST(test_post_decrement)
{
std::chrono::month std_month(255);
etl::chrono::month month(255);
for (int i = 0; i < 256; ++i)
{
std::chrono::month std_last_month = std_month--;
etl::chrono::month last_month = month--;
CHECK_EQUAL(std_last_month.ok(), last_month.ok());
CHECK_EQUAL(unsigned(std_last_month), unsigned(last_month));
CHECK_EQUAL(std_month.ok(), month.ok());
CHECK_EQUAL(unsigned(std_month), unsigned(month));
}
}
//*************************************************************************
TEST(test_plus_equal_months)
{
for (int m = 0; m <= 12; ++m)
{
for (int ms = 0; ms <= 24; ++ms)
{
std::chrono::month std_month(m);
etl::chrono::month month(m);
std::chrono::months std_months(ms);
etl::chrono::months months(ms);
std_month += std_months;
month += months;
CHECK_EQUAL(std_month.ok(), month.ok());
CHECK_EQUAL(unsigned(std_month), unsigned(month));
}
}
}
//*************************************************************************
TEST(test_month_plus_months)
{
for (int m = 0; m <= 12; ++m)
{
for (int ms = 0; ms <= 24; ++ms)
{
std::chrono::month std_month(m);
etl::chrono::month month(m);
std::chrono::months std_months(ms);
etl::chrono::months months(ms);
std_month = std_month + std_months;
month = month + months;
CHECK_EQUAL(std_month.ok(), month.ok());
CHECK_EQUAL(unsigned(std_month), unsigned(month));
}
}
}
//*************************************************************************
TEST(test_months_plus_month)
{
for (int m = 0; m <= 12; ++m)
{
for (int ms = 0; ms <= 24; ++ms)
{
std::chrono::month std_month(m);
etl::chrono::month month(m);
std::chrono::months std_months(ms);
etl::chrono::months months(ms);
std_month = std_months + std_month;
month = months + month;
CHECK_EQUAL(std_month.ok(), month.ok());
CHECK_EQUAL(unsigned(std_month), unsigned(month));
}
}
}
//*************************************************************************
TEST(test_minus_equal_months)
{
for (int m = 0; m <= 12; ++m)
{
for (int ms = 0; ms <= 24; ++ms)
{
std::chrono::month std_month(m);
etl::chrono::month month(m);
std::chrono::months std_months(ms);
etl::chrono::months months(ms);
std_month -= std_months;
month -= months;
CHECK_EQUAL(std_month.ok(), month.ok());
CHECK_EQUAL(unsigned(std_month), unsigned(month));
}
}
}
//*************************************************************************
TEST(test_month_minus_months)
{
for (int m = 0; m <= 12; ++m)
{
for (int ms = 0; ms <= 24; ++ms)
{
std::chrono::month std_month(m);
etl::chrono::month month(m);
std::chrono::months std_months(ms);
etl::chrono::months months(ms);
std_month = std_month - std_months;
month = month - months;
CHECK_EQUAL(std_month.ok(), month.ok());
CHECK_EQUAL(unsigned(std_month), unsigned(month));
}
}
}
//*************************************************************************
TEST(test_month_minus_month)
{
for (int m = 0; m < 256; ++m)
{
std::chrono::month std_month1(m);
std::chrono::month std_month2(255 - m);
std::chrono::month month1(m);
std::chrono::month month2(255 - m);
auto std_months12 = std_month1 - std_month2;
auto std_months21 = std_month2 - std_month1;
auto months12 = month1 - month2;
auto months21 = month2 - month1;
CHECK_EQUAL(std_months12.count(), months12.count());
CHECK_EQUAL(std_months21.count(), months21.count());
}
}
//*************************************************************************
TEST(test_min_max_month)
{
CHECK_EQUAL(1U, etl::chrono::month::min());
CHECK_EQUAL(12U, etl::chrono::month::max());
}
//*************************************************************************
TEST(test_literal_month)
{
using namespace etl::literals::chrono_literals;
etl::chrono::month month1 = 1_month;
etl::chrono::month month2 = 2_month;
etl::chrono::month month3 = 3_month;
etl::chrono::month month4 = 4_month;
etl::chrono::month month5 = 5_month;
etl::chrono::month month6 = 6_month;
etl::chrono::month month7 = 7_month;
etl::chrono::month month8 = 8_month;
etl::chrono::month month9 = 9_month;
etl::chrono::month month10 = 10_month;
etl::chrono::month month11 = 11_month;
etl::chrono::month month12 = 12_month;
CHECK_TRUE(month1.ok());
CHECK_TRUE(month2.ok());
CHECK_TRUE(month3.ok());
CHECK_TRUE(month4.ok());
CHECK_TRUE(month5.ok());
CHECK_TRUE(month6.ok());
CHECK_TRUE(month7.ok());
CHECK_TRUE(month8.ok());
CHECK_TRUE(month9.ok());
CHECK_TRUE(month10.ok());
CHECK_TRUE(month11.ok());
CHECK_TRUE(month12.ok());
CHECK_EQUAL(1U, unsigned(month1));
CHECK_EQUAL(2U, unsigned(month2));
CHECK_EQUAL(3U, unsigned(month3));
CHECK_EQUAL(4U, unsigned(month4));
CHECK_EQUAL(5U, unsigned(month5));
CHECK_EQUAL(6U, unsigned(month6));
CHECK_EQUAL(7U, unsigned(month7));
CHECK_EQUAL(8U, unsigned(month8));
CHECK_EQUAL(9U, unsigned(month9));
CHECK_EQUAL(10U, unsigned(month10));
CHECK_EQUAL(11U, unsigned(month11));
CHECK_EQUAL(12U, unsigned(month12));
}
//*************************************************************************
TEST(test_month_comparison_operators)
{
etl::chrono::month month1(1);
etl::chrono::month month2(2);
CHECK_TRUE(month1 == month1);
CHECK_FALSE(month1 != month1);
CHECK_TRUE(month1 < month2);
CHECK_FALSE(month1 < month1);
CHECK_FALSE(month2 < month1);
CHECK_TRUE(month1 <= month2);
CHECK_TRUE(month1 <= month1);
CHECK_FALSE(month2 <= month1);
CHECK_FALSE(month1 > month2);
CHECK_FALSE(month1 > month1);
CHECK_TRUE(month2 > month1);
CHECK_FALSE(month1 >= month2);
CHECK_TRUE(month1 >= month1);
CHECK_TRUE(month2 >= month1);
#if ETL_USING_CPP20
CHECK_TRUE((month1 <=> month1) == 0);
CHECK_TRUE((month1 <=> month2) < 0);
CHECK_TRUE((month2 <=> month1) > 0);
//*************************************************************************
TEST(test_month_day_spaceship_operator)
{
Chrono::month_day md1{Chrono::January, Chrono::day{15}};
Chrono::month_day md2{Chrono::February, Chrono::day{10}};
Chrono::month_day md3{Chrono::January, Chrono::day{15}};
CHECK_TRUE((md1 <=> md3) == std::strong_ordering::equal); // Same month and day
CHECK_TRUE((md1 <=> md2) == std::strong_ordering::less); // Different month and day
CHECK_TRUE((md2 <=> md1) == std::strong_ordering::greater); // Same month and day
}
#endif
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_month_day_compare)
{
Chrono::month_day md1{Chrono::January, Chrono::day{15}};
Chrono::month_day md2{Chrono::February, Chrono::day{10}};
Chrono::month_day md3{Chrono::January, Chrono::day{15}};
CHECK_TRUE(md1.compare(md3) == 0); // Same month and day
CHECK_TRUE(md1.compare(md2) == -1); // Different month and day
CHECK_TRUE(md2.compare(md1) == 1); // Same month and day
}
#endif
//*************************************************************************
TEST(test_month_day_equality_operator)
{
Chrono::month_day md1{Chrono::January, Chrono::day{15}};
Chrono::month_day md2{Chrono::February, Chrono::day{10}};
Chrono::month_day md3{Chrono::January, Chrono::day{20}};
CHECK_TRUE(md1 == md1); // January == January
CHECK_FALSE(md1 == md2); // January != February
CHECK_FALSE(md1 == md3); // 20th != 15th in the same month
}
//*************************************************************************
TEST(test_month_hashes_are_unique)
TEST(test_month_day_not_equality_operator)
{
std::vector<size_t> hashes;
Chrono::month_day md1{Chrono::January, Chrono::day{15}};
Chrono::month_day md2{Chrono::February, Chrono::day{10}};
Chrono::month_day md3{Chrono::January, Chrono::day{20}};
for (int i = 0; i < 256; ++i)
{
hashes.push_back(etl::hash<etl::chrono::month>()(etl::chrono::month(i)));
}
std::sort(hashes.begin(), hashes.end());
(void)std::unique(hashes.begin(), hashes.end());
CHECK_EQUAL(256U, hashes.size());
CHECK_FALSE(md1 != md1); // January == January
CHECK_TRUE(md1 != md2); // January != February
CHECK_TRUE(md1 != md3); // 20th != 15th in the same month
}
//*************************************************************************
TEST(test_month_types)
TEST(test_month_day_less_than_operator)
{
CHECK_EQUAL(static_cast<unsigned>(std::chrono::January), static_cast<unsigned>(etl::chrono::January));
CHECK_EQUAL(static_cast<unsigned>(std::chrono::February), static_cast<unsigned>(etl::chrono::February));
CHECK_EQUAL(static_cast<unsigned>(std::chrono::March), static_cast<unsigned>(etl::chrono::March));
CHECK_EQUAL(static_cast<unsigned>(std::chrono::April), static_cast<unsigned>(etl::chrono::April));
CHECK_EQUAL(static_cast<unsigned>(std::chrono::May), static_cast<unsigned>(etl::chrono::May));
CHECK_EQUAL(static_cast<unsigned>(std::chrono::June), static_cast<unsigned>(etl::chrono::June));
CHECK_EQUAL(static_cast<unsigned>(std::chrono::July), static_cast<unsigned>(etl::chrono::July));
CHECK_EQUAL(static_cast<unsigned>(std::chrono::August), static_cast<unsigned>(etl::chrono::August));
CHECK_EQUAL(static_cast<unsigned>(std::chrono::September), static_cast<unsigned>(etl::chrono::September));
CHECK_EQUAL(static_cast<unsigned>(std::chrono::October), static_cast<unsigned>(etl::chrono::October));
CHECK_EQUAL(static_cast<unsigned>(std::chrono::November), static_cast<unsigned>(etl::chrono::November));
CHECK_EQUAL(static_cast<unsigned>(std::chrono::December), static_cast<unsigned>(etl::chrono::December));
Chrono::month_day md1{Chrono::January, Chrono::day{15}};
Chrono::month_day md2{Chrono::February, Chrono::day{10}};
Chrono::month_day md3{Chrono::January, Chrono::day{20}};
CHECK_TRUE(md1 < md2); // January < February
CHECK_TRUE(md1 < md3); // 15th < 20th in the same month
CHECK_FALSE(md2 < md1); // February !< January
CHECK_FALSE(md3 < md1); // 20th !< 15th in the same month
}
//*************************************************************************
TEST(test_month_day_less_than_equal_operator)
{
Chrono::month_day md1{Chrono::January, Chrono::day{15}};
Chrono::month_day md2{Chrono::February, Chrono::day{10}};
Chrono::month_day md3{Chrono::January, Chrono::day{20}};
CHECK_TRUE(md1 <= md1); // January <= January
CHECK_TRUE(md1 <= md2); // January <= February
CHECK_TRUE(md1 <= md3); // 15th <= 20th in the same month
CHECK_FALSE(md2 <= md1); // February !<= January
CHECK_FALSE(md3 <= md1); // 20th !<= 15th in the same month
}
//*************************************************************************
TEST(test_month_day_greater_than_operator)
{
Chrono::month_day md1{Chrono::January, Chrono::day{15}};
Chrono::month_day md2{Chrono::February, Chrono::day{10}};
Chrono::month_day md3{Chrono::January, Chrono::day{20}};
CHECK_TRUE(md2 > md1); // February > January
CHECK_TRUE(md3 > md1); // 20th > 15th in the same month
CHECK_FALSE(md1 > md2); // January !> February
CHECK_FALSE(md1 > md3); // 15th !> 20th in the same month
}
//*************************************************************************
TEST(test_month_day_greater_than_equal_operator)
{
Chrono::month_day md1{Chrono::January, Chrono::day{15}};
Chrono::month_day md2{Chrono::February, Chrono::day{10}};
Chrono::month_day md3{Chrono::January, Chrono::day{20}};
CHECK_TRUE(md1 >= md1); // January >= January
CHECK_TRUE(md2 >= md1); // February >= January
CHECK_TRUE(md3 >= md1); // 20th >= 15th in the same month
CHECK_FALSE(md1 >= md2); // January !>= February
CHECK_FALSE(md1 >= md3); // 15th !>= 20th in the same month
}
//*************************************************************************
TEST(test_month_day_min_max)
{
Chrono::month_day md_min{Chrono::January, Chrono::day{1}};
Chrono::month_day md_max{Chrono::December, Chrono::day{31}};
CHECK_TRUE(md_min.ok());
CHECK_TRUE(md_max.ok());
CHECK_EQUAL(Chrono::January, md_min.month());
CHECK_EQUAL(Chrono::day{1}, md_min.day());
CHECK_EQUAL(Chrono::December, md_max.month());
CHECK_EQUAL(Chrono::day{31}, md_max.day());
}
};
}
#endif

View File

@ -0,0 +1,130 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Documentation:
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.
******************************************************************************/
#include "etl/platform.h"
#include "unit_test_framework.h"
#include "etl/chrono.h"
#include <vector>
#include <array>
#include <algorithm>
// 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 <chrono>
#define Chrono std::chrono
#else
#error std::chrono not supported
#endif
#endif
namespace
{
SUITE(test_chrono_month_day_last)
{
//*************************************************************************
TEST(test_constructor_in_range)
{
Chrono::month_day_last month_day_last_january(Chrono::January);
Chrono::month_day_last month_day_last_february(Chrono::February);
Chrono::month_day_last month_day_last_march(Chrono::March);
Chrono::month_day_last month_day_last_april(Chrono::April);
Chrono::month_day_last month_day_last_may(Chrono::May);
Chrono::month_day_last month_day_last_june(Chrono::June);
Chrono::month_day_last month_day_last_july(Chrono::July);
Chrono::month_day_last month_day_last_august(Chrono::August);
Chrono::month_day_last month_day_last_september(Chrono::September);
Chrono::month_day_last month_day_last_october(Chrono::October);
Chrono::month_day_last month_day_last_november(Chrono::November);
Chrono::month_day_last month_day_last_december(Chrono::December);
CHECK_TRUE(month_day_last_january.ok());
CHECK_TRUE(month_day_last_february.ok());
CHECK_TRUE(month_day_last_march.ok());
CHECK_TRUE(month_day_last_april.ok());
CHECK_TRUE(month_day_last_may.ok());
CHECK_TRUE(month_day_last_june.ok());
CHECK_TRUE(month_day_last_july.ok());
CHECK_TRUE(month_day_last_august.ok());
CHECK_TRUE(month_day_last_september.ok());
CHECK_TRUE(month_day_last_october.ok());
CHECK_TRUE(month_day_last_november.ok());
CHECK_TRUE(month_day_last_december.ok());
}
//*************************************************************************
TEST(test_month_day_last_comparison_operators)
{
Chrono::month_day_last month_day_last1(Chrono::January);
Chrono::month_day_last month_day_last2(Chrono::January);
Chrono::month_day_last month_day_last3(Chrono::February);
CHECK_TRUE(month_day_last1 == month_day_last2);
CHECK_FALSE(month_day_last1 == month_day_last3);
CHECK_FALSE(month_day_last1 != month_day_last2);
CHECK_TRUE(month_day_last1 != month_day_last3);
}
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_month_day_last_hashes_are_unique)
{
std::vector<size_t> hashes;
for (int i = 0; i < 6; ++i)
{
hashes.push_back(etl::hash<Chrono::month_day_last>()(Chrono::month_day_last(Chrono::January)));
hashes.push_back(etl::hash<Chrono::month_day_last>()(Chrono::month_day_last(Chrono::February)));
hashes.push_back(etl::hash<Chrono::month_day_last>()(Chrono::month_day_last(Chrono::March)));
hashes.push_back(etl::hash<Chrono::month_day_last>()(Chrono::month_day_last(Chrono::April)));
hashes.push_back(etl::hash<Chrono::month_day_last>()(Chrono::month_day_last(Chrono::May)));
hashes.push_back(etl::hash<Chrono::month_day_last>()(Chrono::month_day_last(Chrono::June)));
hashes.push_back(etl::hash<Chrono::month_day_last>()(Chrono::month_day_last(Chrono::July)));
hashes.push_back(etl::hash<Chrono::month_day_last>()(Chrono::month_day_last(Chrono::August)));
hashes.push_back(etl::hash<Chrono::month_day_last>()(Chrono::month_day_last(Chrono::September)));
hashes.push_back(etl::hash<Chrono::month_day_last>()(Chrono::month_day_last(Chrono::October)));
hashes.push_back(etl::hash<Chrono::month_day_last>()(Chrono::month_day_last(Chrono::November)));
hashes.push_back(etl::hash<Chrono::month_day_last>()(Chrono::month_day_last(Chrono::December)));
}
std::sort(hashes.begin(), hashes.end());
(void)std::unique(hashes.begin(), hashes.end());
}
#endif
};
}

View File

@ -0,0 +1,124 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Documentation:
Copyright(c) 2024 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.
******************************************************************************/
#include "etl/platform.h"
#include "unit_test_framework.h"
#include "etl/chrono.h"
#include <vector>
#include <algorithm>
// 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 <chrono>
#define Chrono std::chrono
#else
#error std::chrono not supported
#endif
#endif
namespace
{
SUITE(test_chrono_month_weekday)
{
//*************************************************************************
TEST(test_constructor_with_month_and_day)
{
Chrono::month_weekday mwd{ Chrono::January, Chrono::weekday_indexed(Chrono::Friday, 2) };
CHECK_TRUE(mwd.ok()); // Valid month_weekday
CHECK_EQUAL(Chrono::January, mwd.month());
CHECK_EQUAL(Chrono::Friday.c_encoding(), mwd.weekday_indexed().weekday().c_encoding());
CHECK_EQUAL(2, mwd.weekday_indexed().index());
}
//*************************************************************************
TEST(test_invalid_month_weekday)
{
Chrono::month_weekday mwd{Chrono::month{13}, Chrono::weekday_indexed(Chrono::Friday, 2)}; // Invalid month (13)
CHECK_FALSE(mwd.ok()); // Invalid month_weekday
}
//*************************************************************************
TEST(test_invalid_day_in_month_weekday)
{
Chrono::month_weekday mwd{Chrono::January, Chrono::weekday_indexed(Chrono::weekday{8}, 2)}; // Invalid day (8)
CHECK_FALSE(mwd.ok()); // Invalid month_weekday
}
//*************************************************************************
TEST(test_month_weekday_equality_operator)
{
Chrono::month_weekday mwd1{Chrono::January, Chrono::weekday_indexed(Chrono::Friday, 2)};
Chrono::month_weekday mwd2{Chrono::February, Chrono::weekday_indexed(Chrono::Friday, 2)};
CHECK_TRUE(mwd1 == mwd1); // January == January
CHECK_FALSE(mwd1 == mwd2); // January != February
CHECK_FALSE(mwd1 == mwd2); // Friday != Saturday
}
//*************************************************************************
TEST(test_month_weekday_not_equality_operator)
{
Chrono::month_weekday mwd1{Chrono::January, Chrono::weekday_indexed(Chrono::Friday, 2)};
Chrono::month_weekday mwd2{Chrono::February, Chrono::weekday_indexed(Chrono::Friday, 2)};
CHECK_FALSE(mwd1 != mwd1); // January == January
CHECK_TRUE(mwd1 != mwd2); // January != February
CHECK_TRUE(mwd1 != mwd2); // Friday != Saturday
}
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_month_weekday_hashes_are_unique)
{
std::vector<size_t> hashes;
for (int i = 0; i < 256; ++i)
{
hashes.push_back(etl::hash<Chrono::month_weekday>()(Chrono::month_weekday(Chrono::month((i % 12) + 1), Chrono::weekday_indexed(Chrono::weekday(i % 7), i % 5))));
}
std::sort(hashes.begin(), hashes.end());
(void)std::unique(hashes.begin(), hashes.end());
CHECK_EQUAL(256U, hashes.size());
}
#endif
};
}

View File

@ -0,0 +1,125 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Documentation:
Copyright(c) 2024 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.
******************************************************************************/
#include "etl/platform.h"
#include "unit_test_framework.h"
#include "etl/chrono.h"
#include <vector>
#include <algorithm>
// 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 <chrono>
#define Chrono std::chrono
#else
#error std::chrono not supported
#endif
#endif
namespace
{
SUITE(test_chrono_month_weekday_last)
{
//*************************************************************************
TEST(test_constructor_with_month_and_day)
{
Chrono::month_weekday_last mwdl{ Chrono::January, Chrono::weekday_last(Chrono::Friday)};
CHECK_TRUE(mwdl.ok()); // Valid month_weekday_last
CHECK_EQUAL(Chrono::January, mwdl.month());
CHECK_EQUAL(Chrono::Friday.c_encoding(), mwdl.weekday_last().weekday().c_encoding());
}
//*************************************************************************
TEST(test_invalid_month_weekday_last)
{
Chrono::month_weekday_last mwdl{Chrono::month{13}, Chrono::weekday_last(Chrono::Friday)}; // Invalid month (13)
CHECK_FALSE(mwdl.ok()); // Invalid month_weekday_last
}
//*************************************************************************
TEST(test_invalid_day_in_month_weekday_last)
{
Chrono::month_weekday_last mwdl{Chrono::January, Chrono::weekday_last(Chrono::weekday(8))}; // Invalid day (8)
CHECK_FALSE(mwdl.ok()); // Invalid month_weekday_last
}
//*************************************************************************
TEST(test_month_weekday_last_equality_operator)
{
Chrono::month_weekday_last mwd1{Chrono::January, Chrono::weekday_last(Chrono::Friday)};
Chrono::month_weekday_last mwd2{Chrono::February, Chrono::weekday_last(Chrono::Friday)};
Chrono::month_weekday_last mwd3{Chrono::January, Chrono::weekday_last(Chrono::Saturday)};
CHECK_TRUE(mwd1 == mwd1); // January == January
CHECK_FALSE(mwd1 == mwd2); // January != February
CHECK_FALSE(mwd1 == mwd3); // Friday != Saturday
}
//*************************************************************************
TEST(test_month_weekday_last_not_equality_operator)
{
Chrono::month_weekday_last mwd1{Chrono::January, Chrono::weekday_last(Chrono::Friday)};
Chrono::month_weekday_last mwd2{Chrono::February, Chrono::weekday_last(Chrono::Friday)};
Chrono::month_weekday_last mwd3{Chrono::January, Chrono::weekday_last(Chrono::Saturday)};
CHECK_FALSE(mwd1 != mwd1); // January == January
CHECK_TRUE(mwd1 != mwd2); // January != February
CHECK_TRUE(mwd1 != mwd3); // Friday != Saturday
}
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_month_weekday_last_hashes_are_unique)
{
std::vector<size_t> hashes;
for (int i = 0; i < 256; ++i)
{
hashes.push_back(etl::hash<Chrono::month_weekday_last>()(Chrono::month_weekday_last(Chrono::month((i % 12) + 1), Chrono::weekday_last(Chrono::weekday(i % 7)))));
}
std::sort(hashes.begin(), hashes.end());
(void)std::unique(hashes.begin(), hashes.end());
CHECK_EQUAL(256U, hashes.size());
}
#endif
};
}

View File

@ -0,0 +1,285 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Documentation:
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.
******************************************************************************/
#include "etl/platform.h"
#include "unit_test_framework.h"
#include "etl/chrono.h"
#include <vector>
#include <algorithm>
using namespace etl::literals::chrono_literals;
namespace
{
SUITE(test_chrono_operators)
{
//*************************************************************************
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).month(), ymdl1.month_day_last().month());
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).month(), ymdl2.month_day_last().month());
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).month(), ymdl3.month_day_last().month());
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).month(), ymdl4.month_day_last().month());
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).month(), ymdl5.month_day_last().month());
}
//*************************************************************************
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());
}
};
}

View File

@ -0,0 +1,362 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Documentation:
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.
******************************************************************************/
#include "etl/platform.h"
#include "unit_test_framework.h"
#include "etl/chrono.h"
#include <vector>
#include <algorithm>
// 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 <chrono>
#define Chrono std::chrono
#else
#error std::chrono not supported
#endif
#endif
namespace
{
struct test_clock
{
using duration = Chrono::hours;
};
using TimePoint = Chrono::time_point<test_clock>;
SUITE(test_chrono_time_point)
{
//*************************************************************************
TEST(test_default_constructor)
{
TimePoint tp;
CHECK_EQUAL(0, tp.time_since_epoch().count());
}
//*************************************************************************
TEST(test_constructor_with_duration)
{
auto num_days = Chrono::days::period::num;
auto num_hours = Chrono::hours::period::num;
for (int d = 1; d < 100; ++d)
{
TimePoint tp{ Chrono::days(d) };
auto hours = tp.time_since_epoch().count();
auto hours_scaled_to_days = (hours * num_hours) / num_days;
CHECK_EQUAL(d, hours_scaled_to_days);
}
}
//*************************************************************************
TEST(test_copy_constructor)
{
auto num_days = Chrono::days::period::num;
auto num_hours = Chrono::hours::period::num;
for (int d = 1; d < 100; ++d)
{
TimePoint tp{ Chrono::days(d) };
TimePoint tp2{ tp };
auto hours = tp2.time_since_epoch().count();
auto hours_scaled_to_days = (hours * num_hours) / num_days;
CHECK_EQUAL(d, hours_scaled_to_days);
}
}
//*************************************************************************
TEST(test_plus_equal_days)
{
auto num_days = Chrono::days::period::num;
auto num_hours = Chrono::hours::period::num;
Chrono::days ds(2);
TimePoint tp{ Chrono::days(0) };
for (int d = 1; d < 100; ++d)
{
tp += ds;
auto hours = tp.time_since_epoch().count();
auto hours_scaled_to_days = (hours * num_hours) / num_days;
CHECK_EQUAL(d * 2, hours_scaled_to_days);
}
}
//*************************************************************************
TEST(test_plus_equal_hours)
{
auto num_days = Chrono::days::period::num;
auto num_hours = Chrono::hours::period::num;
Chrono::hours hs(48);
TimePoint tp{ Chrono::days(0) };
for (int d = 1; d < 100; ++d)
{
tp += hs;
auto hours = tp.time_since_epoch().count();
auto hours_scaled_to_days = (hours * num_hours) / num_days;
CHECK_EQUAL(d * 2, hours_scaled_to_days);
}
}
//*************************************************************************
TEST(test_minus_equal_days)
{
auto num_days = Chrono::days::period::num;
auto num_hours = Chrono::hours::period::num;
Chrono::days ds(2);
TimePoint tp{ Chrono::days(100) };
for (int d = 1; d < 100; ++d)
{
tp -= ds;
auto hours = tp.time_since_epoch().count();
auto hours_scaled_to_days = (hours * num_hours) / num_days;
CHECK_EQUAL(100 - (d * 2), hours_scaled_to_days);
}
}
//*************************************************************************
TEST(test_minus_equal_hours)
{
auto num_days = Chrono::days::period::num;
auto num_hours = Chrono::hours::period::num;
Chrono::hours hs(48);
TimePoint tp{ Chrono::days(100) };
for (int d = 1; d < 100; ++d)
{
tp -= hs;
auto hours = tp.time_since_epoch().count();
auto hours_scaled_to_days = (hours * num_hours) / num_days;
CHECK_EQUAL(100 - (d * 2), hours_scaled_to_days);
}
}
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_min_max_time_point)
{
using Rep = TimePoint::duration::rep;
CHECK_EQUAL(etl::integral_limits<Rep>::min, TimePoint::min().time_since_epoch().count());
CHECK_EQUAL(etl::integral_limits<Rep>::max, TimePoint::max().time_since_epoch().count());
}
#endif
//*************************************************************************
TEST(test_time_point_comparison_operators)
{
// 10 days
TimePoint tp10h{ Chrono::hours(240) };
TimePoint tp10d{ Chrono::days(10) };
// 20 days
TimePoint tp20h{ Chrono::hours(480) };
TimePoint tp20d{ Chrono::days(20) };
// ==
CHECK_TRUE(tp10h == tp10h);
CHECK_TRUE(tp10d == tp10h);
CHECK_TRUE(tp10h == tp10d);
CHECK_FALSE(tp10h == tp20h);
CHECK_FALSE(tp20h == tp10h);
CHECK_FALSE(tp10h == tp20d);
CHECK_FALSE(tp10d == tp20h);
CHECK_FALSE(tp20h == tp10d);
CHECK_FALSE(tp20d == tp10h);
// <
CHECK_TRUE(tp10h < tp20h);
CHECK_TRUE(tp10d < tp20h);
CHECK_TRUE(tp10h < tp20d);
CHECK_FALSE(tp10h < tp10h);
CHECK_FALSE(tp10d < tp10h);
CHECK_FALSE(tp10h < tp10d);
CHECK_FALSE(tp20h < tp10h);
CHECK_FALSE(tp20d < tp10h);
CHECK_FALSE(tp20h < tp10d);
// <=
CHECK_TRUE(tp10h <= tp20h);
CHECK_TRUE(tp10d <= tp20h);
CHECK_TRUE(tp10h <= tp20d);
CHECK_TRUE(tp10h <= tp10h);
CHECK_TRUE(tp10d <= tp10h);
CHECK_TRUE(tp10h <= tp10d);
CHECK_FALSE(tp20h <= tp10h);
CHECK_FALSE(tp20d <= tp10h);
CHECK_FALSE(tp20h <= tp10d);
// >
CHECK_TRUE(tp20h > tp10h);
CHECK_TRUE(tp20d > tp10h);
CHECK_TRUE(tp20h > tp10d);
CHECK_FALSE(tp10h > tp10h);
CHECK_FALSE(tp10d > tp10h);
CHECK_FALSE(tp10h > tp10d);
CHECK_FALSE(tp10h > tp20h);
CHECK_FALSE(tp10d > tp20h);
CHECK_FALSE(tp10h > tp20d);
// >=
CHECK_TRUE(tp20h >= tp10h);
CHECK_TRUE(tp20d >= tp10h);
CHECK_TRUE(tp20h >= tp10d);
CHECK_TRUE(tp10h >= tp10h);
CHECK_TRUE(tp10d >= tp10h);
CHECK_TRUE(tp10h >= tp10d);
CHECK_FALSE(tp10h >= tp20h);
CHECK_FALSE(tp10d >= tp20h);
CHECK_FALSE(tp10h >= tp20d);
#if ETL_USING_CPP20
CHECK_TRUE((tp10h <=> tp10h) == 0);
CHECK_TRUE((tp10h <=> tp20h) < 0);
CHECK_TRUE((tp20h <=> tp10h) > 0);
CHECK_TRUE((tp10h <=> tp10d) == 0);
CHECK_TRUE((tp10d <=> tp20h) < 0);
CHECK_TRUE((tp20h <=> tp10d) > 0);
CHECK_TRUE((tp10d <=> tp10h) == 0);
CHECK_TRUE((tp10h <=> tp20d) < 0);
CHECK_TRUE((tp20d <=> tp10h) > 0);
#endif
}
//*************************************************************************
TEST(test_time_point_common_type)
{
using TimePointHours = Chrono::time_point<test_clock, Chrono::hours>;
using TimePointDays = Chrono::time_point<test_clock, Chrono::days>;
using CommonType = etl::common_type_t<TimePointHours, TimePointDays>;
CHECK_TRUE((std::is_same<TimePointHours::duration, CommonType::duration>::value));
CHECK_FALSE((std::is_same<TimePointDays::duration, CommonType::duration>::value));
}
//*************************************************************************
TEST(test_floor)
{
using TimePoint = Chrono::time_point<test_clock, Chrono::milliseconds>;
TimePoint tp(Chrono::milliseconds(1234)); // 1234 milliseconds
auto floored_tp = floor<Chrono::seconds>(tp);
CHECK_EQUAL(1, floored_tp.time_since_epoch().count());
TimePoint negative_tp(Chrono::milliseconds(-1234)); // -1234 milliseconds
auto floored_negative_tp = floor<Chrono::seconds>(negative_tp);
CHECK_EQUAL(-2, floored_negative_tp.time_since_epoch().count());
}
//*************************************************************************
TEST(test_ceil)
{
using TimePoint = Chrono::time_point<test_clock, Chrono::milliseconds>;
TimePoint tp(Chrono::milliseconds(1234)); // 1234 milliseconds
auto ceil_tp = ceil<Chrono::seconds>(tp);
CHECK_EQUAL(2, ceil_tp.time_since_epoch().count());
TimePoint negative_tp(Chrono::milliseconds(-1234)); // -1234 milliseconds
auto ceil_negative_tp = ceil<Chrono::seconds>(negative_tp);
CHECK_EQUAL(-1, ceil_negative_tp.time_since_epoch().count());
}
//*************************************************************************
TEST(test_round)
{
using TimePoint = Chrono::time_point<test_clock, Chrono::milliseconds>;
TimePoint tp1(Chrono::milliseconds(1500)); // 1500 milliseconds
auto round1 = round<Chrono::seconds>(tp1); // Round to seconds
CHECK_EQUAL(2, round1.time_since_epoch().count());
TimePoint tp2(Chrono::milliseconds(2500)); // 2500 milliseconds
auto round2 = round<Chrono::seconds>(tp2); // Round to seconds
CHECK_EQUAL(2, round2.time_since_epoch().count());
TimePoint tp3(Chrono::milliseconds(-1500)); // -1500 milliseconds
auto round3 = round<Chrono::seconds>(tp3); // Round to seconds
CHECK_EQUAL(-2, round3.time_since_epoch().count());
}
//*************************************************************************
TEST(test_time_point_cast)
{
using TimePointFrom = Chrono::time_point<test_clock, Chrono::seconds>;
using TimePointTo = Chrono::time_point<test_clock, Chrono::milliseconds>;
TimePointFrom from(Chrono::seconds(2));
TimePointTo to = Chrono::time_point_cast<TimePointTo::duration>(from);
auto expected = from.time_since_epoch().count() * (TimePointTo::period::den / TimePointFrom::period::den);
auto actual = to.time_since_epoch().count();
CHECK_EQUAL(expected, actual);
}
};
}

View File

@ -0,0 +1,410 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Documentation:
Copyright(c) 2023 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.
******************************************************************************/
#include "etl/platform.h"
#include "unit_test_framework.h"
#include "etl/chrono.h"
#include <vector>
#include <algorithm>
#include <iostream>
// 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 <chrono>
#define Chrono std::chrono
#else
#error std::chrono not supported
#endif
#endif
namespace
{
SUITE(test_chrono_weekday)
{
//*************************************************************************
TEST(test_default_constructor)
{
Chrono::weekday weekday;
CHECK_FALSE(weekday.ok());
}
//*************************************************************************
TEST(test_constructor_in_range)
{
for (unsigned i = 0U; i < 7U; ++i)
{
Chrono::weekday weekday(i);
CHECK_TRUE(weekday.ok());
CHECK_EQUAL(i, weekday.c_encoding());
CHECK_EQUAL((i == 0U) ? 7U : i, weekday.iso_encoding());
}
}
//*************************************************************************
TEST(test_constructor_out_of_range)
{
for (unsigned i = 8U; i < 256U; ++i)
{
Chrono::weekday weekday(i);
CHECK_FALSE(weekday.ok());
CHECK_EQUAL(i, weekday.c_encoding());
CHECK_EQUAL((i == 0U) ? 7U : i, weekday.iso_encoding());
}
}
//*************************************************************************
TEST(test_pre_increment)
{
Chrono::weekday weekday(0);
unsigned count = 0;
for (int i = 0; i < 255; ++i)
{
++weekday;
++count;
CHECK_TRUE(weekday.ok());
CHECK_EQUAL(count % 7, weekday.c_encoding());
CHECK_EQUAL((count % 7 == 0U) ? 7U : count % 7, weekday.iso_encoding());
}
}
//*************************************************************************
TEST(test_post_increment)
{
Chrono::weekday weekday(0);
unsigned count = 0;
for (int i = 0; i < 255; ++i)
{
Chrono::weekday last_weekday = weekday++;
unsigned last_count = count++;
CHECK_TRUE(last_weekday.ok());
CHECK_EQUAL(last_count % 7, last_weekday.c_encoding());
CHECK_EQUAL((last_count % 7 == 0U) ? 7U : last_count % 7, last_weekday.iso_encoding());
CHECK_TRUE(weekday.ok());
CHECK_EQUAL(count % 7, weekday.c_encoding());
CHECK_EQUAL((count % 7 == 0U) ? 7U : count % 7, weekday.iso_encoding());
}
}
//*************************************************************************
TEST(test_pre_decrement)
{
Chrono::weekday weekday(255U);
unsigned count = 255U;
for (int i = 0; i < 255; ++i)
{
--weekday;
--count;
CHECK_TRUE(weekday.ok());
CHECK_EQUAL(count % 7, weekday.c_encoding());
CHECK_EQUAL((count % 7 == 0U) ? 7U : count % 7, weekday.iso_encoding());
}
}
//*************************************************************************
TEST(test_post_decrement)
{
Chrono::weekday weekday(255U);
unsigned count = 255U;
for (int i = 0; i < 255; ++i)
{
Chrono::weekday last_weekday = weekday--;
unsigned last_count = count--;
if (last_count == 255U)
{
CHECK_FALSE(last_weekday.ok());
CHECK_EQUAL(255U, last_weekday.c_encoding());
CHECK_EQUAL(255U, last_weekday.iso_encoding());
}
else
{
CHECK_TRUE(last_weekday.ok());
CHECK_EQUAL(last_count % 7, last_weekday.c_encoding());
CHECK_EQUAL((last_count % 7 == 0U) ? 7U : last_count % 7, last_weekday.iso_encoding());
}
CHECK_TRUE(weekday.ok());
CHECK_EQUAL(count % 7, weekday.c_encoding());
CHECK_EQUAL((count % 7 == 0U) ? 7U : count % 7, weekday.iso_encoding());
}
}
//*************************************************************************
TEST(test_plus_equal_days)
{
for (unsigned wd = 0; wd <= 6; ++wd)
{
for (unsigned ds = 0; ds <= 14; ++ds)
{
Chrono::weekday weekday(wd);
Chrono::days days(ds);
weekday += days;
unsigned expected = (wd + ds) % 7;
CHECK_TRUE(weekday.ok());
CHECK_EQUAL(expected, weekday.c_encoding());
CHECK_EQUAL((expected == 0U) ? 7U : expected, weekday.iso_encoding());
}
}
}
//*************************************************************************
TEST(test_weekday_plus_days)
{
for (unsigned wd = 0; wd <= 6; ++wd)
{
for (unsigned ds = 0; ds <= 14; ++ds)
{
Chrono::weekday weekday(wd);
Chrono::days days(ds);
weekday = weekday + days;
unsigned expected = (wd + ds) % 7;
CHECK_TRUE(weekday.ok());
CHECK_EQUAL(expected, weekday.c_encoding());
CHECK_EQUAL((expected == 0U) ? 7U : expected, weekday.iso_encoding());
}
}
}
//*************************************************************************
TEST(test_days_plus_weekday)
{
for (unsigned wd = 0; wd <= 6; ++wd)
{
for (unsigned ds = 0; ds <= 14; ++ds)
{
Chrono::weekday weekday(wd);
Chrono::days days(ds);
weekday = weekday + days;
unsigned expected = (ds + wd) % 7;
CHECK_TRUE(weekday.ok());
CHECK_EQUAL(expected, weekday.c_encoding());
CHECK_EQUAL((expected == 0U) ? 7U : expected, weekday.iso_encoding());
}
}
}
//*************************************************************************
TEST(test_minus_equal_days)
{
for (unsigned wd = 0; wd <= 6; ++wd)
{
for (unsigned ds = 0; ds <= 14; ++ds)
{
Chrono::weekday weekday(wd);
Chrono::days days(ds);
weekday -= days;
unsigned expected = ((wd + 7U) - (ds % 7U)) % 7U;
CHECK_TRUE(weekday.ok());
CHECK_EQUAL(expected, weekday.c_encoding());
CHECK_EQUAL((expected == 0U) ? 7U : expected, weekday.iso_encoding());
}
}
}
//*************************************************************************
TEST(test_weekday_minus_days)
{
for (unsigned wd = 0; wd <= 6; ++wd)
{
for (unsigned ds = 0; ds <= 14; ++ds)
{
Chrono::weekday weekday(wd);
Chrono::days days(ds);
weekday = weekday - days;
unsigned expected = ((wd + 7U) - (ds % 7U)) % 7U;
CHECK_TRUE(weekday.ok());
CHECK_EQUAL(expected, weekday.c_encoding());
CHECK_EQUAL((expected == 0U) ? 7U : expected, weekday.iso_encoding());
}
}
}
//*************************************************************************
TEST(test_weekday_minus_weekday)
{
for (int m = 0; m < 7; ++m)
{
Chrono::weekday weekday1(m);
Chrono::weekday weekday2(7 - m);
Chrono::weekday std_weekday1(m);
Chrono::weekday std_weekday2(7 - m);
auto days12 = weekday1 - weekday2;
auto days21 = weekday2 - weekday1;
auto std_days12 = std_weekday1 - std_weekday2;
auto std_days21 = std_weekday2 - std_weekday1;
CHECK_EQUAL(std_days12.count(), days12.count());
CHECK_EQUAL(std_days21.count(), days21.count());
}
}
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_min_max_weekday)
{
CHECK_EQUAL(Chrono::Sunday.c_encoding(), Chrono::weekday::min());
CHECK_EQUAL(Chrono::Saturday.c_encoding(), Chrono::weekday::max());
}
#endif
//*************************************************************************
TEST(test_weekday_constants)
{
CHECK_EQUAL(0U, Chrono::Sunday.c_encoding());
CHECK_EQUAL(1U, Chrono::Monday.c_encoding());
CHECK_EQUAL(2U, Chrono::Tuesday.c_encoding());
CHECK_EQUAL(3U, Chrono::Wednesday.c_encoding());
CHECK_EQUAL(4U, Chrono::Thursday.c_encoding());
CHECK_EQUAL(5U, Chrono::Friday.c_encoding());
CHECK_EQUAL(6U, Chrono::Saturday.c_encoding());
CHECK_EQUAL(7U, Chrono::Sunday.iso_encoding());
CHECK_EQUAL(1U, Chrono::Monday.iso_encoding());
CHECK_EQUAL(2U, Chrono::Tuesday.iso_encoding());
CHECK_EQUAL(3U, Chrono::Wednesday.iso_encoding());
CHECK_EQUAL(4U, Chrono::Thursday.iso_encoding());
CHECK_EQUAL(5U, Chrono::Friday.iso_encoding());
CHECK_EQUAL(6U, Chrono::Saturday.iso_encoding());
}
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_weekday_literals)
{
using namespace etl::literals::chrono_literals;
Chrono::weekday weekday0 = 0_weekday;
Chrono::weekday weekday1 = 1_weekday;
Chrono::weekday weekday2 = 2_weekday;
Chrono::weekday weekday3 = 3_weekday;
Chrono::weekday weekday4 = 4_weekday;
Chrono::weekday weekday5 = 5_weekday;
Chrono::weekday weekday6 = 6_weekday;
CHECK_TRUE(weekday0.ok());
CHECK_TRUE(weekday1.ok());
CHECK_TRUE(weekday2.ok());
CHECK_TRUE(weekday3.ok());
CHECK_TRUE(weekday4.ok());
CHECK_TRUE(weekday5.ok());
CHECK_TRUE(weekday6.ok());
CHECK_EQUAL(0U, weekday0.c_encoding());
CHECK_EQUAL(1U, weekday1.c_encoding());
CHECK_EQUAL(2U, weekday2.c_encoding());
CHECK_EQUAL(3U, weekday3.c_encoding());
CHECK_EQUAL(4U, weekday4.c_encoding());
CHECK_EQUAL(5U, weekday5.c_encoding());
CHECK_EQUAL(6U, weekday6.c_encoding());
}
#endif
//*************************************************************************
TEST(test_weekday_comparison_operators)
{
Chrono::weekday weekday1(1);
Chrono::weekday weekday2(2);
CHECK_TRUE(weekday1 == weekday1);
CHECK_FALSE(weekday1 != weekday1);
CHECK_FALSE(weekday1 == weekday2);
CHECK_TRUE(weekday1 != weekday2);
}
//*************************************************************************
TEST(test_weekday_index_operator_returning_weekday_indexed)
{
Chrono::weekday wd(Chrono::Friday);
Chrono::weekday_indexed wi = wd[2];
CHECK_EQUAL(2, wi.index());
CHECK_EQUAL(Chrono::Friday.c_encoding(), wi.weekday().c_encoding());
}
//*************************************************************************
TEST(test_weekday_index_operator_returning_weekday_last)
{
Chrono::weekday wd(Chrono::Friday);
Chrono::weekday_last wl = wd[Chrono::last];
CHECK_EQUAL(Chrono::Friday.c_encoding(), wl.weekday().c_encoding());
}
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_weekday_hashes_are_unique)
{
std::vector<size_t> hashes;
for (int i = 0; i < 256; ++i)
{
hashes.push_back(etl::hash<Chrono::weekday>()(Chrono::weekday(i)));
}
std::sort(hashes.begin(), hashes.end());
(void)std::unique(hashes.begin(), hashes.end());
CHECK_EQUAL(256U, hashes.size());
}
#endif
};
}

View File

@ -0,0 +1,163 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Documentation:
Copyright(c) 2024 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.
******************************************************************************/
#include "etl/platform.h"
#include "unit_test_framework.h"
#include "etl/chrono.h"
#include <vector>
#include <algorithm>
// 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 <chrono>
#define Chrono std::chrono
#else
#error std::chrono not supported
#endif
#endif
namespace
{
SUITE(test_chrono_weekday_indexed)
{
//*************************************************************************
TEST(test_default_constructor)
{
Chrono::weekday_indexed weekday_indexed;
CHECK_FALSE(weekday_indexed.ok());
}
//*************************************************************************
TEST(test_constructor_in_range)
{
for (unsigned i = 1U; i < 5U; ++i)
{
Chrono::weekday_indexed weekday_indexed_monday(Chrono::Monday, i);
Chrono::weekday_indexed weekday_indexed_tuesday(Chrono::Tuesday, i);
Chrono::weekday_indexed weekday_indexed_wednesday(Chrono::Wednesday, i);
Chrono::weekday_indexed weekday_indexed_thursday(Chrono::Thursday, i);
Chrono::weekday_indexed weekday_indexed_friday(Chrono::Friday, i);
Chrono::weekday_indexed weekday_indexed_saturday(Chrono::Saturday, i);
Chrono::weekday_indexed weekday_indexed_sunday(Chrono::Sunday, i);
CHECK_TRUE(weekday_indexed_monday.ok());
CHECK_TRUE(weekday_indexed_tuesday.ok());
CHECK_TRUE(weekday_indexed_wednesday.ok());
CHECK_TRUE(weekday_indexed_thursday.ok());
CHECK_TRUE(weekday_indexed_friday.ok());
CHECK_TRUE(weekday_indexed_saturday.ok());
CHECK_TRUE(weekday_indexed_sunday.ok());
CHECK_EQUAL(Chrono::Monday.c_encoding(), weekday_indexed_monday.weekday().c_encoding());
CHECK_EQUAL(Chrono::Tuesday.c_encoding(), weekday_indexed_tuesday.weekday().c_encoding());
CHECK_EQUAL(Chrono::Wednesday.c_encoding(), weekday_indexed_wednesday.weekday().c_encoding());
CHECK_EQUAL(Chrono::Thursday.c_encoding(), weekday_indexed_thursday.weekday().c_encoding());
CHECK_EQUAL(Chrono::Friday.c_encoding(), weekday_indexed_friday.weekday().c_encoding());
CHECK_EQUAL(Chrono::Saturday.c_encoding(), weekday_indexed_saturday.weekday().c_encoding());
CHECK_EQUAL(Chrono::Sunday.c_encoding(), weekday_indexed_sunday.weekday().c_encoding());
CHECK_EQUAL(i, weekday_indexed_monday.index());
CHECK_EQUAL(i, weekday_indexed_tuesday.index());
CHECK_EQUAL(i, weekday_indexed_wednesday.index());
CHECK_EQUAL(i, weekday_indexed_thursday.index());
CHECK_EQUAL(i, weekday_indexed_friday.index());
CHECK_EQUAL(i, weekday_indexed_saturday.index());
CHECK_EQUAL(i, weekday_indexed_sunday.index());
}
}
//*************************************************************************
TEST(test_constructor_out_of_range)
{
for (unsigned i = 6U; i < 256U; ++i)
{
Chrono::weekday_indexed weekday_indexed_monday(Chrono::Monday, i);
Chrono::weekday_indexed weekday_indexed_tuesday(Chrono::Tuesday, i);
Chrono::weekday_indexed weekday_indexed_wednesday(Chrono::Wednesday, i);
Chrono::weekday_indexed weekday_indexed_thursday(Chrono::Thursday, i);
Chrono::weekday_indexed weekday_indexed_friday(Chrono::Friday, i);
Chrono::weekday_indexed weekday_indexed_saturday(Chrono::Saturday, i);
Chrono::weekday_indexed weekday_indexed_sunday(Chrono::Sunday, i);
CHECK_FALSE(weekday_indexed_monday.ok());
CHECK_FALSE(weekday_indexed_tuesday.ok());
CHECK_FALSE(weekday_indexed_wednesday.ok());
CHECK_FALSE(weekday_indexed_thursday.ok());
CHECK_FALSE(weekday_indexed_friday.ok());
CHECK_FALSE(weekday_indexed_saturday.ok());
CHECK_FALSE(weekday_indexed_sunday.ok());
}
}
//*************************************************************************
TEST(test_weekday_indexed_comparison_operators)
{
Chrono::weekday_indexed weekday_indexed1(Chrono::Monday, 1);
Chrono::weekday_indexed weekday_indexed2(Chrono::Monday, 1);
Chrono::weekday_indexed weekday_indexed3(Chrono::Monday, 2);
Chrono::weekday_indexed weekday_indexed4(Chrono::Tuesday, 1);
CHECK_TRUE(weekday_indexed1 == weekday_indexed2);
CHECK_FALSE(weekday_indexed1 == weekday_indexed3);
CHECK_FALSE(weekday_indexed1 == weekday_indexed4);
}
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_weekday_indexed_hashes_are_unique)
{
std::vector<size_t> hashes;
for (int i = 0; i < 6; ++i)
{
hashes.push_back(etl::hash<Chrono::weekday_indexed>()(Chrono::weekday_indexed(Chrono::Monday, i)));
hashes.push_back(etl::hash<Chrono::weekday_indexed>()(Chrono::weekday_indexed(Chrono::Tuesday, i)));
hashes.push_back(etl::hash<Chrono::weekday_indexed>()(Chrono::weekday_indexed(Chrono::Wednesday, i)));
hashes.push_back(etl::hash<Chrono::weekday_indexed>()(Chrono::weekday_indexed(Chrono::Thursday, i)));
hashes.push_back(etl::hash<Chrono::weekday_indexed>()(Chrono::weekday_indexed(Chrono::Friday, i)));
hashes.push_back(etl::hash<Chrono::weekday_indexed>()(Chrono::weekday_indexed(Chrono::Saturday, i)));
hashes.push_back(etl::hash<Chrono::weekday_indexed>()(Chrono::weekday_indexed(Chrono::Sunday, i)));
}
std::sort(hashes.begin(), hashes.end());
(void)std::unique(hashes.begin(), hashes.end());
}
#endif
};
}

View File

@ -0,0 +1,135 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Documentation:
Copyright(c) 2024 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.
******************************************************************************/
#include "etl/platform.h"
#include "unit_test_framework.h"
#include "etl/chrono.h"
#include <vector>
#include <array>
#include <algorithm>
// 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 <chrono>
#define Chrono std::chrono
#else
#error std::chrono not supported
#endif
#endif
namespace
{
SUITE(test_chrono_weekday_last)
{
//*************************************************************************
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);
Chrono::weekday_last weekday_last_wednesday(Chrono::Wednesday);
Chrono::weekday_last weekday_last_thursday(Chrono::Thursday);
Chrono::weekday_last weekday_last_friday(Chrono::Friday);
Chrono::weekday_last weekday_last_saturday(Chrono::Saturday);
Chrono::weekday_last weekday_last_sunday(Chrono::Sunday);
CHECK_TRUE(weekday_last_monday.ok());
CHECK_TRUE(weekday_last_tuesday.ok());
CHECK_TRUE(weekday_last_wednesday.ok());
CHECK_TRUE(weekday_last_thursday.ok());
CHECK_TRUE(weekday_last_friday.ok());
CHECK_TRUE(weekday_last_saturday.ok());
CHECK_TRUE(weekday_last_sunday.ok());
CHECK_EQUAL(Chrono::Monday.c_encoding(), weekday_last_monday.weekday().c_encoding());
CHECK_EQUAL(Chrono::Tuesday.c_encoding(), weekday_last_tuesday.weekday().c_encoding());
CHECK_EQUAL(Chrono::Wednesday.c_encoding(), weekday_last_wednesday.weekday().c_encoding());
CHECK_EQUAL(Chrono::Thursday.c_encoding(), weekday_last_thursday.weekday().c_encoding());
CHECK_EQUAL(Chrono::Friday.c_encoding(), weekday_last_friday.weekday().c_encoding());
CHECK_EQUAL(Chrono::Saturday.c_encoding(), weekday_last_saturday.weekday().c_encoding());
CHECK_EQUAL(Chrono::Sunday.c_encoding(), weekday_last_sunday.weekday().c_encoding());
}
}
//*************************************************************************
TEST(test_constructor_out_of_range)
{
for (unsigned i = 8U; i < 256U; ++i)
{
auto wd = Chrono::weekday(i);
Chrono::weekday_last weekday_last(wd);
CHECK_FALSE(weekday_last.ok());
}
}
//*************************************************************************
TEST(test_weekday_last_comparison_operators)
{
Chrono::weekday_last weekday_last1(Chrono::Monday);
Chrono::weekday_last weekday_last2(Chrono::Monday);
Chrono::weekday_last weekday_last3(Chrono::Tuesday);
CHECK_TRUE(weekday_last1 == weekday_last2);
CHECK_FALSE(weekday_last1 == weekday_last3);
}
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_weekday_last_hashes_are_unique)
{
std::vector<size_t> hashes;
for (int i = 0; i < 6; ++i)
{
hashes.push_back(etl::hash<Chrono::weekday_last>()(Chrono::weekday_last(Chrono::Monday)));
hashes.push_back(etl::hash<Chrono::weekday_last>()(Chrono::weekday_last(Chrono::Tuesday)));
hashes.push_back(etl::hash<Chrono::weekday_last>()(Chrono::weekday_last(Chrono::Wednesday)));
hashes.push_back(etl::hash<Chrono::weekday_last>()(Chrono::weekday_last(Chrono::Thursday)));
hashes.push_back(etl::hash<Chrono::weekday_last>()(Chrono::weekday_last(Chrono::Friday)));
hashes.push_back(etl::hash<Chrono::weekday_last>()(Chrono::weekday_last(Chrono::Saturday)));
hashes.push_back(etl::hash<Chrono::weekday_last>()(Chrono::weekday_last(Chrono::Sunday)));
}
std::sort(hashes.begin(), hashes.end());
(void)std::unique(hashes.begin(), hashes.end());
}
#endif
};
}

313
test/test_chrono_year.cpp Normal file
View File

@ -0,0 +1,313 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Documentation:
Copyright(c) 2023 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.
******************************************************************************/
#include "etl/platform.h"
#include "unit_test_framework.h"
#include "etl/chrono.h"
#include <vector>
#include <algorithm>
// 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 <chrono>
#define Chrono std::chrono
#else
#error std::chrono not supported
#endif
#endif
namespace
{
SUITE(test_chrono_year)
{
//*************************************************************************
TEST(test_default_constructor)
{
etl::chrono::year year;
CHECK_TRUE(year.ok());
}
//*************************************************************************
TEST(test_constructor_in_range)
{
for (int32_t i = -32767; i <= 32767; ++i)
{
etl::chrono::year year(i);
CHECK_TRUE(year.ok());
CHECK_EQUAL(i, int(year));
}
}
//*************************************************************************
TEST(test_pre_increment)
{
etl::chrono::year year(-32767);
int count = int(year);
for (int32_t i = 0; i < 65534; ++i)
{
++count;
etl::chrono::year this_year = ++year;
CHECK_TRUE(year.ok());
CHECK_EQUAL(count, year);
CHECK_EQUAL(this_year, year);
}
}
//*************************************************************************
TEST(test_post_increment)
{
etl::chrono::year year(-32767);
int count = -32767;
for (int32_t i = 0; i < 65534; ++i)
{
etl::chrono::year last_year = year++;
CHECK_TRUE(last_year.ok());
CHECK_EQUAL(count, int(last_year));
++count;
CHECK_TRUE(year.ok());
CHECK_EQUAL(count, int(year));
}
}
//*************************************************************************
TEST(test_pre_decrement)
{
etl::chrono::year year(256);
int count = 256;
for (int i = 0; i < 255; ++i)
{
--year;
--count;
CHECK_TRUE(year.ok());
CHECK_EQUAL(count, int(year));
}
}
//*************************************************************************
TEST(test_post_decrement)
{
etl::chrono::year year(256);
int count = (int)year;
for (int i = 0; i < 255; ++i)
{
etl::chrono::year last_year = year--;
CHECK_TRUE(last_year.ok());
CHECK_EQUAL(count, int(last_year));
--count;
CHECK_TRUE(year.ok());
CHECK_EQUAL(count, int(year));
}
}
//*************************************************************************
TEST(test_plus_equal_years)
{
etl::chrono::year year(0);
etl::chrono::years years(2);
for (int i = 0; i < 128; ++i)
{
year += years;
CHECK_TRUE(year.ok());
CHECK_EQUAL((2 * i) + 2, int(year));
}
}
//*************************************************************************
TEST(test_year_plus_years)
{
etl::chrono::year year(0);
etl::chrono::years years(2);
for (int i = 0; i < 128; ++i)
{
year = year + years;
CHECK_TRUE(year.ok());
CHECK_EQUAL((2 * i) + 2, int(year));
}
}
//*************************************************************************
TEST(test_years_plus_year)
{
etl::chrono::year year(0);
etl::chrono::years years(2);
for (int i = 0; i < 128; ++i)
{
year = years + year;
CHECK_TRUE(year.ok());
CHECK_EQUAL((2 * i) + 2, int(year));
}
}
//*************************************************************************
TEST(test_minus_equal_years)
{
etl::chrono::year year(256);
etl::chrono::years years(2);
for (int i = 0; i < 128; ++i)
{
year -= years;
CHECK_TRUE(year.ok());
CHECK_EQUAL((256 - (2 * i)) - 2, int(year));
}
}
//*************************************************************************
TEST(test_year_minus_years)
{
etl::chrono::year year(256);
etl::chrono::years years(2);
for (int i = 0; i < 128; ++i)
{
year = year - years;
CHECK_TRUE(year.ok());
CHECK_EQUAL((256 - (2 * i)) - 2, int(year));
}
}
//*************************************************************************
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));
}
}
//*************************************************************************
TEST(test_is_leap)
{
for (int i = -32767; i <= 32767; ++i)
{
bool is_leap = ((i % 4) == 0) && (((i % 100) != 0) || ((i % 400) == 0));
etl::chrono::year year(i);
CHECK_EQUAL(is_leap, year.is_leap());
}
}
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_min_max_year)
{
CHECK_EQUAL(-32767, etl::chrono::year::min());
CHECK_EQUAL(32767, etl::chrono::year::max());
}
#endif
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_literal_year)
{
using namespace etl::literals::chrono_literals;
etl::chrono::year year = 25_year;
CHECK_TRUE(year.ok());
CHECK_EQUAL(25, int(year));
}
#endif
//*************************************************************************
TEST(test_year_comparison_operators)
{
etl::chrono::year year10(10);
etl::chrono::year year20(20);
CHECK_TRUE(year10 == year10);
CHECK_FALSE(year10 != year10);
CHECK_FALSE(year10 == year20);
CHECK_TRUE(year10 != year20);
#if ETL_USING_CPP20
CHECK_TRUE((year10 <=> year10) == 0);
CHECK_TRUE((year10 <=> year20) < 0);
CHECK_TRUE((year20 <=> year10) > 0);
#endif
}
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_year_hashes_are_unique)
{
std::vector<size_t> hashes;
for (int32_t i = -32767; i < 32768; ++i)
{
hashes.push_back(etl::hash<etl::chrono::year>()(etl::chrono::year(i)));
}
std::sort(hashes.begin(), hashes.end());
(void)std::unique(hashes.begin(), hashes.end());
CHECK_EQUAL(65535U, hashes.size());
}
#endif
};
}

View File

@ -0,0 +1,148 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Documentation:
Copyright(c) 2024 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.
******************************************************************************/
#include "etl/platform.h"
#include "unit_test_framework.h"
#include "etl/chrono.h"
#include <vector>
#include <algorithm>
// 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 <chrono>
#define Chrono std::chrono
#else
#error std::chrono not supported
#endif
#endif
namespace
{
SUITE(test_chrono_year_month)
{
//*************************************************************************
TEST(test_default_constructor)
{
Chrono::year_month ym;
CHECK_FALSE(ym.ok()); // Default-constructed year_month is not valid
}
//*************************************************************************
TEST(test_constructor_with_month_and_day)
{
Chrono::year_month ym{Chrono::year(2000), Chrono::January};
CHECK_TRUE(ym.ok()); // Valid year_month
CHECK_EQUAL(2000, (int)ym.year());
CHECK_EQUAL((unsigned)Chrono::January, (unsigned)ym.month());
}
//*************************************************************************
TEST(test_invalid_year_month)
{
Chrono::year_month ym{Chrono::year{32768}, Chrono::January}; // Invalid year
CHECK_FALSE(ym.ok()); // Invalid year_month
}
//*************************************************************************
TEST(test_invalid_month_in_year_month)
{
Chrono::year_month ym{Chrono::year{2000}, Chrono::month{13}}; // Invalid month (13)
CHECK_FALSE(ym.ok()); // Invalid year_month
}
#if ETL_USING_CPP20
//*************************************************************************
TEST(test_year_month_spaceship_operator)
{
Chrono::year_month ym1{Chrono::year(2000), Chrono::January};
Chrono::year_month ym2{Chrono::year(2001), Chrono::January};
Chrono::year_month ym3{Chrono::year(2000), Chrono::February};
CHECK_TRUE((ym1 <=> ym1) == std::strong_ordering::equal);
CHECK_TRUE((ym1 <=> ym2) == std::strong_ordering::less);
CHECK_TRUE((ym2 <=> ym1) == std::strong_ordering::greater);
CHECK_TRUE((ym1 <=> ym3) == std::strong_ordering::less);
CHECK_TRUE((ym3 <=> ym1) == std::strong_ordering::greater);
}
#endif
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_year_month_compare)
{
Chrono::year_month ym1{Chrono::year(2000), Chrono::January};
Chrono::year_month ym2{Chrono::year(2001), Chrono::January};
Chrono::year_month ym3{Chrono::year(2000), Chrono::February};
CHECK_TRUE(ym1.compare(ym1) == 0);
CHECK_TRUE(ym1.compare(ym2) == -1);
CHECK_TRUE(ym2.compare(ym1) == 1);
CHECK_TRUE(ym1.compare(ym3) == -1);
CHECK_TRUE(ym3.compare(ym1) == 1);
}
#endif
//*************************************************************************
TEST(test_year_month_equality_operator)
{
Chrono::year_month ym1{Chrono::year(2000), Chrono::January};
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_FALSE(ym1 == ym2); // Different year
CHECK_FALSE(ym1 == ym3); // Different month
}
//*************************************************************************
TEST(test_year_month_not_equality_operator)
{
Chrono::year_month ym1{Chrono::year(2000), Chrono::January};
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_TRUE(ym1 != ym2); // Different year
CHECK_TRUE(ym1 != ym3); // Different month
}
};
}

View File

@ -0,0 +1,176 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Documentation:
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.
******************************************************************************/
#include "etl/platform.h"
#include "unit_test_framework.h"
#include "etl/chrono.h"
#include <vector>
#include <algorithm>
// 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 <chrono>
#define Chrono std::chrono
#else
#error std::chrono not supported
#endif
#endif
namespace
{
SUITE(test_chrono_year_month_day)
{
//*************************************************************************
TEST(test_default_constructor)
{
Chrono::year_month_day ymd;
CHECK_FALSE(ymd.ok()); // Default-constructed year_month_day is not valid
}
//*************************************************************************
TEST(test_constructor_with_month_and_day)
{
Chrono::year_month_day ymd{Chrono::year(2000), Chrono::January, Chrono::day(1)};
CHECK_TRUE(ymd.ok()); // Valid year_month_day
CHECK_EQUAL(2000, (int)ymd.year());
CHECK_EQUAL((unsigned)Chrono::January, (unsigned)ymd.month());
CHECK_EQUAL(Chrono::day(1), ymd.day());
}
//*************************************************************************
TEST(test_invalid_year_month)
{
Chrono::year_month_day ymd{Chrono::year{32768}, Chrono::January, Chrono::day(1)}; // Invalid year
CHECK_FALSE(ymd.ok()); // Invalid year_month_day
}
//*************************************************************************
TEST(test_invalid_month_in_year_month)
{
Chrono::year_month_day ymd{Chrono::year{2000}, Chrono::month{13}, Chrono::day(1)}; // Invalid month (13)
CHECK_FALSE(ymd.ok()); // Invalid year_month_day
}
//*************************************************************************
TEST(test_invalid_day_in_year_month)
{
Chrono::year_month_day ymd{Chrono::year{2000}, Chrono::January, Chrono::day(32)}; // Invalid day (32)
CHECK_FALSE(ymd.ok()); // Invalid year_month_day
}
#if ETL_USING_CPP20
//*************************************************************************
TEST(test_year_month_day_spaceship_operator)
{
Chrono::year_month_day ym1{Chrono::year(2000), Chrono::January, Chrono::day(1)};
Chrono::year_month_day ym2{Chrono::year(2001), Chrono::January, Chrono::day(1)};
Chrono::year_month_day ym3{Chrono::year(2000), Chrono::February, Chrono::day(1)};
Chrono::year_month_day ym4{Chrono::year(2000), Chrono::January, Chrono::day(2)};
CHECK_TRUE((ym1 <=> ym1) == std::strong_ordering::equal);
CHECK_TRUE((ym1 <=> ym2) == std::strong_ordering::less);
CHECK_TRUE((ym2 <=> ym1) == std::strong_ordering::greater);
CHECK_TRUE((ym1 <=> ym3) == std::strong_ordering::less);
CHECK_TRUE((ym3 <=> ym1) == std::strong_ordering::greater);
CHECK_TRUE((ym1 <=> ym4) == std::strong_ordering::less);
CHECK_TRUE((ym4 <=> ym1) == std::strong_ordering::greater);
}
#endif
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_year_month_day_compare)
{
Chrono::year_month_day ym1{Chrono::year(2000), Chrono::January, Chrono::day(1)};
Chrono::year_month_day ym2{Chrono::year(2001), Chrono::January, Chrono::day(1)};
Chrono::year_month_day ym3{Chrono::year(2000), Chrono::February, Chrono::day(1)};
Chrono::year_month_day ym4{Chrono::year(2000), Chrono::January, Chrono::day(2)};
CHECK_TRUE(ym1.compare(ym1) == 0);
CHECK_TRUE(ym1.compare(ym2) == -1);
CHECK_TRUE(ym2.compare(ym1) == 1);
CHECK_TRUE(ym1.compare(ym3) == -1);
CHECK_TRUE(ym3.compare(ym1) == 1);
CHECK_TRUE(ym1.compare(ym4) == -1);
CHECK_TRUE(ym4.compare(ym1) == 1);
}
#endif
//*************************************************************************
TEST(test_to_sys_days)
{
Chrono::year_month_day ymd{Chrono::year(2000), Chrono::February, Chrono::day(10)};
Chrono::sys_days sd = Chrono::sys_days(ymd);
CHECK_EQUAL(10997, sd.time_since_epoch().count());
}
//*************************************************************************
TEST(test_year_month_day_equality_operator)
{
Chrono::year_month_day ym1{Chrono::year(2000), Chrono::January, Chrono::day(1)};
Chrono::year_month_day ym2{Chrono::year(2001), Chrono::January, Chrono::day(1)};
Chrono::year_month_day ym3{Chrono::year(2000), Chrono::February, Chrono::day(1)};
Chrono::year_month_day ym4{Chrono::year(2000), Chrono::January, Chrono::day(2)};
CHECK_TRUE(ym1 == ym1); // Same year/month/day
CHECK_FALSE(ym1 == ym2); // Different year
CHECK_FALSE(ym1 == ym3); // Different month
CHECK_FALSE(ym1 == ym4); // Different day
}
//*************************************************************************
TEST(test_year_month_day_not_equality_operator)
{
Chrono::year_month_day ym1{Chrono::year(2000), Chrono::January, Chrono::day(1)};
Chrono::year_month_day ym2{Chrono::year(2001), Chrono::January, Chrono::day(1)};
Chrono::year_month_day ym3{Chrono::year(2000), Chrono::February, Chrono::day(1)};
Chrono::year_month_day ym4{Chrono::year(2000), Chrono::January, Chrono::day(2)};
CHECK_FALSE(ym1 != ym1); // Same year/month/day
CHECK_TRUE(ym1 != ym2); // Different year
CHECK_TRUE(ym1 != ym3); // Different month
CHECK_TRUE(ym1 != ym4); // Different day
}
};
}

View File

@ -0,0 +1,148 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Documentation:
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.
******************************************************************************/
#include "etl/platform.h"
#include "unit_test_framework.h"
#include "etl/chrono.h"
#include <vector>
#include <array>
#include <algorithm>
// 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 <chrono>
#define Chrono std::chrono
#else
#error std::chrono not supported
#endif
#endif
namespace
{
SUITE(test_chrono_year_month_day_last)
{
//*************************************************************************
TEST(test_constructor_in_range)
{
Chrono::year_month_day_last year_month_day_last_2000_january(Chrono::year(2000), Chrono::month_day_last(Chrono::January));
Chrono::year_month_day_last year_month_day_last_2000_february(Chrono::year(2000), Chrono::month_day_last(Chrono::February));
Chrono::year_month_day_last year_month_day_last_2001_february(Chrono::year(2001), Chrono::month_day_last(Chrono::February));
Chrono::year_month_day_last year_month_day_last_2002_march(Chrono::year(2002), Chrono::month_day_last(Chrono::March));
Chrono::year_month_day_last year_month_day_last_2003_april(Chrono::year(2003), Chrono::month_day_last(Chrono::April));
Chrono::year_month_day_last year_month_day_last_2004_may(Chrono::year(2004), Chrono::month_day_last(Chrono::May));
Chrono::year_month_day_last year_month_day_last_2005_june(Chrono::year(2005), Chrono::month_day_last(Chrono::June));
Chrono::year_month_day_last year_month_day_last_2006_july(Chrono::year(2006), Chrono::month_day_last(Chrono::July));
Chrono::year_month_day_last year_month_day_last_2007_august(Chrono::year(2007), Chrono::month_day_last(Chrono::August));
Chrono::year_month_day_last year_month_day_last_2008_september(Chrono::year(2008), Chrono::month_day_last(Chrono::September));
Chrono::year_month_day_last year_month_day_last_2009_october(Chrono::year(2009), Chrono::month_day_last(Chrono::October));
Chrono::year_month_day_last year_month_day_last_2010_november(Chrono::year(2010), Chrono::month_day_last(Chrono::November));
Chrono::year_month_day_last year_month_day_last_2011_december(Chrono::year(2011), Chrono::month_day_last(Chrono::December));
CHECK_TRUE(year_month_day_last_2000_january.ok());
CHECK_TRUE(year_month_day_last_2000_february.ok());
CHECK_TRUE(year_month_day_last_2001_february.ok());
CHECK_TRUE(year_month_day_last_2002_march.ok());
CHECK_TRUE(year_month_day_last_2003_april.ok());
CHECK_TRUE(year_month_day_last_2004_may.ok());
CHECK_TRUE(year_month_day_last_2005_june.ok());
CHECK_TRUE(year_month_day_last_2006_july.ok());
CHECK_TRUE(year_month_day_last_2007_august.ok());
CHECK_TRUE(year_month_day_last_2008_september.ok());
CHECK_TRUE(year_month_day_last_2009_october.ok());
CHECK_TRUE(year_month_day_last_2010_november.ok());
CHECK_TRUE(year_month_day_last_2011_december.ok());
CHECK_EQUAL(31, (unsigned)year_month_day_last_2000_january.day());
CHECK_EQUAL(29, (unsigned)year_month_day_last_2000_february.day());
CHECK_EQUAL(28, (unsigned)year_month_day_last_2001_february.day());
CHECK_EQUAL(31, (unsigned)year_month_day_last_2002_march.day());
CHECK_EQUAL(30, (unsigned)year_month_day_last_2003_april.day());
CHECK_EQUAL(31, (unsigned)year_month_day_last_2004_may.day());
CHECK_EQUAL(30, (unsigned)year_month_day_last_2005_june.day());
CHECK_EQUAL(31, (unsigned)year_month_day_last_2006_july.day());
CHECK_EQUAL(31, (unsigned)year_month_day_last_2007_august.day());
CHECK_EQUAL(30, (unsigned)year_month_day_last_2008_september.day());
CHECK_EQUAL(31, (unsigned)year_month_day_last_2009_october.day());
CHECK_EQUAL(30, (unsigned)year_month_day_last_2010_november.day());
CHECK_EQUAL(31, (unsigned)year_month_day_last_2011_december.day());
}
//*************************************************************************
TEST(test_year_month_day_last_comparison_operators)
{
Chrono::year_month_day_last year_month_day_last1(Chrono::year(2000), Chrono::month_day_last(Chrono::January));
Chrono::year_month_day_last year_month_day_last2(Chrono::year(2001), Chrono::month_day_last(Chrono::January));
Chrono::year_month_day_last year_month_day_last3(Chrono::year(2000), Chrono::month_day_last(Chrono::February));
CHECK_TRUE(year_month_day_last1 == year_month_day_last1);
CHECK_FALSE(year_month_day_last1 == year_month_day_last2);
CHECK_FALSE(year_month_day_last1 == year_month_day_last3);
CHECK_FALSE(year_month_day_last1 != year_month_day_last1);
CHECK_TRUE(year_month_day_last1 != year_month_day_last2);
CHECK_TRUE(year_month_day_last1 != year_month_day_last3);
}
#if ETL_USING_ETL_CHRONO
//*************************************************************************
TEST(test_year_month_day_last_hashes_are_unique)
{
std::vector<size_t> hashes;
for (int i = 0; i < 6; ++i)
{
hashes.push_back(etl::hash<Chrono::year_month_day_last>()(Chrono::year_month_day_last(Chrono::year(2000), Chrono::month_day_last(Chrono::January))));
hashes.push_back(etl::hash<Chrono::year_month_day_last>()(Chrono::year_month_day_last(Chrono::year(2001), Chrono::month_day_last(Chrono::February))));
hashes.push_back(etl::hash<Chrono::year_month_day_last>()(Chrono::year_month_day_last(Chrono::year(2002), Chrono::month_day_last(Chrono::March))));
hashes.push_back(etl::hash<Chrono::year_month_day_last>()(Chrono::year_month_day_last(Chrono::year(2003), Chrono::month_day_last(Chrono::April))));
hashes.push_back(etl::hash<Chrono::year_month_day_last>()(Chrono::year_month_day_last(Chrono::year(2004), Chrono::month_day_last(Chrono::May))));
hashes.push_back(etl::hash<Chrono::year_month_day_last>()(Chrono::year_month_day_last(Chrono::year(2005), Chrono::month_day_last(Chrono::January))));
hashes.push_back(etl::hash<Chrono::year_month_day_last>()(Chrono::year_month_day_last(Chrono::year(2006), Chrono::month_day_last(Chrono::January))));
hashes.push_back(etl::hash<Chrono::year_month_day_last>()(Chrono::year_month_day_last(Chrono::year(2007), Chrono::month_day_last(Chrono::January))));
hashes.push_back(etl::hash<Chrono::year_month_day_last>()(Chrono::year_month_day_last(Chrono::year(2008), Chrono::month_day_last(Chrono::January))));
hashes.push_back(etl::hash<Chrono::year_month_day_last>()(Chrono::year_month_day_last(Chrono::year(2009), Chrono::month_day_last(Chrono::January))));
hashes.push_back(etl::hash<Chrono::year_month_day_last>()(Chrono::year_month_day_last(Chrono::year(2010), Chrono::month_day_last(Chrono::January))));
hashes.push_back(etl::hash<Chrono::year_month_day_last>()(Chrono::year_month_day_last(Chrono::year(2011), Chrono::month_day_last(Chrono::January))));
}
std::sort(hashes.begin(), hashes.end());
(void)std::unique(hashes.begin(), hashes.end());
}
#endif
};
}

View File

@ -5,7 +5,9 @@ Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2025 BMW AG
Documentation:
Copyright(c) 2024 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
@ -30,25 +32,66 @@ SOFTWARE.
#include "etl/ratio.h"
#if ETL_USING_CPP11
namespace
{
// Helper to find the greatest common divisor
template <intmax_t A, intmax_t B>
struct gcd
{
static ETL_CONSTANT intmax_t value = gcd<B, A % B>::value;
};
template <intmax_t A>
struct gcd<A, 0>
{
static ETL_CONSTANT intmax_t value = A;
};
SUITE(test_ratio)
{
//*************************************************************************
TEST(test_definitions)
{
constexpr intmax_t Num = 20;
constexpr intmax_t Den = 600;
intmax_t N = Num / gcd<Num, Den>::value;
intmax_t D = Den / gcd<Num, Den>::value;
using ratio = etl::ratio<Num, Den>;
using ratio_type = ratio::type;
CHECK_FALSE((std::is_same<ratio, ratio_type>::value));
CHECK_EQUAL(N, ratio::num);
CHECK_EQUAL(D, ratio::den);
CHECK_EQUAL(N, ratio_type::num);
CHECK_EQUAL(D, ratio_type::den);
}
//*************************************************************************
TEST(test_ratio_add)
{
using r1 = etl::ratio<1, 2>;
using r2 = etl::ratio<2, 3>;
using r3 = etl::ratio_add<r1, r2>;
using two_thirds = etl::ratio<2, 3>;
using one_sixth = etl::ratio<1, 6>;
using ratio = etl::ratio_add<two_thirds, one_sixth>;
CHECK((etl::ratio_equal<r3, etl::ratio<7, 6>>::value));
CHECK((!etl::ratio_equal<r3, etl::ratio<1, 6>>::value));
CHECK_TRUE((std::is_same<ratio, etl::ratio<15, 18>>::value));
CHECK_EQUAL(5, ratio::num);
CHECK_EQUAL(6, ratio::den);
}
//*************************************************************************
TEST(test_ratio_subtract)
{
using two_thirds = etl::ratio<2, 3>;
using one_sixth = etl::ratio<1, 6>;
using ratio = etl::ratio_subtract<two_thirds, one_sixth>;
CHECK_TRUE((std::is_same<ratio, etl::ratio<9, 18>>::value));
CHECK_EQUAL(1, ratio::num);
CHECK_EQUAL(2, ratio::den);
using r1 = etl::ratio<1, 2>;
using r2 = etl::ratio<2, 3>;
using r3 = etl::ratio_subtract<r1, r2>;
@ -60,6 +103,13 @@ namespace
//*************************************************************************
TEST(test_ratio_multiply)
{
using two_thirds = etl::ratio<2, 3>;
using one_sixth = etl::ratio<1, 6>;
using ratio = etl::ratio_multiply<two_thirds, one_sixth>;
CHECK_TRUE((std::is_same<ratio, etl::ratio<2, 18>>::value));
CHECK_EQUAL(1, ratio::num);
CHECK_EQUAL(9, ratio::den);
using r1 = etl::ratio<1, 2>;
using r2 = etl::ratio<2, 3>;
using r3 = etl::ratio_multiply<r1, r2>;
@ -71,6 +121,13 @@ namespace
//*************************************************************************
TEST(test_ratio_divide)
{
using two_thirds = etl::ratio<2, 3>;
using one_sixth = etl::ratio<1, 6>;
using ratio = etl::ratio_divide<two_thirds, one_sixth>;
CHECK_TRUE((std::is_same<ratio, etl::ratio<12, 3>>::value));
CHECK_EQUAL(4, ratio::num);
CHECK_EQUAL(1, ratio::den);
using r1 = etl::ratio<1, 2>;
using r2 = etl::ratio<2, 3>;
using r3 = etl::ratio_divide<r1, r2>;
@ -88,7 +145,7 @@ namespace
CHECK((etl::ratio_equal<r1, r1>::value));
CHECK((!etl::ratio_equal<r1, r2>::value));
#if ETL_USING_CPP14
#if ETL_USING_CPP17
CHECK((etl::ratio_equal_v<r1, r1>));
CHECK((!etl::ratio_equal_v<r1, r2>));
#endif
@ -103,7 +160,7 @@ namespace
CHECK((!etl::ratio_not_equal<r1, r1>::value));
CHECK((etl::ratio_not_equal<r1, r2>::value));
#if ETL_USING_CPP14
#if ETL_USING_CPP17
CHECK((!etl::ratio_not_equal_v<r1, r1>));
CHECK((etl::ratio_not_equal_v<r1, r2>));
#endif
@ -118,7 +175,7 @@ namespace
CHECK((etl::ratio_less<r1, r2>::value));
CHECK((!etl::ratio_less<r2, r1>::value));
#if ETL_USING_CPP14
#if ETL_USING_CPP17
CHECK((etl::ratio_less_v<r1, r2>));
CHECK((!etl::ratio_less_v<r1, r1>));
#endif
@ -133,7 +190,7 @@ namespace
CHECK((etl::ratio_less_equal<r1, r1>::value));
CHECK((etl::ratio_less_equal<r1, r2>::value));
#if ETL_USING_CPP14
#if ETL_USING_CPP17
CHECK((etl::ratio_less_equal_v<r1, r1>));
CHECK((etl::ratio_less_equal_v<r1, r1>));
#endif
@ -148,7 +205,7 @@ namespace
CHECK((etl::ratio_greater<r1, r2>::value));
CHECK((!etl::ratio_greater<r2, r1>::value));
#if ETL_USING_CPP14
#if ETL_USING_CPP17
CHECK((etl::ratio_greater_v<r1, r2>));
CHECK((!etl::ratio_greater_v<r2, r1>));
#endif
@ -163,7 +220,7 @@ namespace
CHECK((etl::ratio_greater_equal<r1, r1>::value));
CHECK((etl::ratio_greater_equal<r1, r2>::value));
#if ETL_USING_CPP14
#if ETL_USING_CPP17
CHECK((etl::ratio_greater_equal_v<r1, r1>));
CHECK((etl::ratio_greater_equal_v<r1, r2>));
#endif
@ -171,4 +228,3 @@ namespace
};
}
#endif

View File

@ -129,6 +129,17 @@ namespace
{
return first + second;
}
// Structs to test is_specialized
template <typename T>
struct specialized
{
};
template <typename T>
struct other_specialized
{
};
}
// Definitions for when the STL and compiler built-ins are not available.
@ -1447,6 +1458,18 @@ namespace
CHECK_EQUAL(1, (etl::count_of<char, char>::value));
CHECK_EQUAL(1, (etl::count_of<char, int, char>::value));
CHECK_EQUAL(2, (etl::count_of<char, int, char, double, char>::value));
#endif
}
//*************************************************************************
TEST(test_is_specialization)
{
#if ETL_USING_CPP17
CHECK_TRUE((etl::is_specialization_v<specialized<int>, specialized>));
CHECK_FALSE((etl::is_specialization_v<other_specialized<int>, specialized>));
#else
CHECK_TRUE((etl::is_specialization<specialized<int>, specialized>::value));
CHECK_FALSE((etl::is_specialization<other_specialized<int>, specialized>::value));
#endif
}
}

View File

@ -1419,7 +1419,7 @@
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<TreatWarningAsError>true</TreatWarningAsError>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<SupportJustMyCode>true</SupportJustMyCode>
<SupportJustMyCode>false</SupportJustMyCode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -1444,6 +1444,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<TreatWarningAsError>true</TreatWarningAsError>
<SupportJustMyCode>false</SupportJustMyCode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -1470,6 +1471,7 @@
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<TreatWarningAsError>true</TreatWarningAsError>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<SupportJustMyCode>false</SupportJustMyCode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -1494,6 +1496,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<TreatWarningAsError>true</TreatWarningAsError>
<SupportJustMyCode>false</SupportJustMyCode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -1518,6 +1521,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<TreatWarningAsError>true</TreatWarningAsError>
<SupportJustMyCode>false</SupportJustMyCode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -1542,6 +1546,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<TreatWarningAsError>true</TreatWarningAsError>
<SupportJustMyCode>false</SupportJustMyCode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -1566,6 +1571,7 @@
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<TreatWarningAsError>true</TreatWarningAsError>
<SupportJustMyCode>false</SupportJustMyCode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -1591,6 +1597,7 @@
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<TreatWarningAsError>true</TreatWarningAsError>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<SupportJustMyCode>false</SupportJustMyCode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -1616,6 +1623,7 @@
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<TreatWarningAsError>true</TreatWarningAsError>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<SupportJustMyCode>false</SupportJustMyCode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -1825,6 +1833,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
<TreatWarningAsError>true</TreatWarningAsError>
<SupportJustMyCode>false</SupportJustMyCode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -3110,6 +3119,7 @@
<ClInclude Include="..\..\include\etl\callback_timer_atomic.h" />
<ClInclude Include="..\..\include\etl\callback_timer_interrupt.h" />
<ClInclude Include="..\..\include\etl\callback_timer_locked.h" />
<ClInclude Include="..\..\include\etl\chrono.h" />
<ClInclude Include="..\..\include\etl\circular_buffer.h" />
<ClInclude Include="..\..\include\etl\circular_iterator.h" />
<ClInclude Include="..\..\include\etl\combinations.h" />
@ -3177,6 +3187,22 @@
<ClInclude Include="..\..\include\etl\poly_span.h" />
<ClInclude Include="..\..\include\etl\private\bitset_legacy.h" />
<ClInclude Include="..\..\include\etl\private\bitset_new.h" />
<ClInclude Include="..\..\include\etl\private\chrono\day.h" />
<ClInclude Include="..\..\include\etl\private\chrono\duration.h" />
<ClInclude Include="..\..\include\etl\private\chrono\hh_mm_ss.h" />
<ClInclude Include="..\..\include\etl\private\chrono\clocks.h" />
<ClInclude Include="..\..\include\etl\private\chrono\last_spec.h" />
<ClInclude Include="..\..\include\etl\private\chrono\month.h" />
<ClInclude Include="..\..\include\etl\private\chrono\month_day.h" />
<ClInclude Include="..\..\include\etl\private\chrono\month_weekday.h" />
<ClInclude Include="..\..\include\etl\private\chrono\operators.h" />
<ClInclude Include="..\..\include\etl\private\chrono\time_point.h" />
<ClInclude Include="..\..\include\etl\private\chrono\time_zone.h" />
<ClInclude Include="..\..\include\etl\private\chrono\weekday.h" />
<ClInclude Include="..\..\include\etl\private\chrono\year.h" />
<ClInclude Include="..\..\include\etl\private\chrono\year_month.h" />
<ClInclude Include="..\..\include\etl\private\chrono\year_month_day.h" />
<ClInclude Include="..\..\include\etl\private\chrono\year_month_weekday.h" />
<ClInclude Include="..\..\include\etl\private\diagnostic_array_bounds_push.h" />
<ClInclude Include="..\..\include\etl\private\diagnostic_cxx_20_compat_push.h" />
<ClInclude Include="..\..\include\etl\private\diagnostic_deprecated_push.h" />
@ -4418,6 +4444,22 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - Force C++03|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - Force C++03 - No virtual messages|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\syntax_check\chrono.h.t.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No virtual imessage|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++ 20 - No Tests|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++14|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release MSVC C++20 - No STL - Optimised -O2|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - Forve C++03 - No virtual messages|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release MSVC C++20 - No STL - Optimised -O2 - Sanitiser|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++17|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++17 - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release MSVC C++20 - Optimised O2|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No virtual messages|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++14 - No STL|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - Force C++03|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\syntax_check\circular_buffer.h.t.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug MSVC C++20 - No virtual imessage|Win32'">true</ExcludedFromBuild>
@ -8443,6 +8485,23 @@
<ClCompile Include="..\test_callback_timer_interrupt.cpp" />
<ClCompile Include="..\test_callback_timer_locked.cpp" />
<ClCompile Include="..\test_char_traits.cpp" />
<ClCompile Include="..\test_chrono_clocks.cpp" />
<ClCompile Include="..\test_chrono_day.cpp" />
<ClCompile Include="..\test_chrono_duration.cpp" />
<ClCompile Include="..\test_chrono_hh_mm_ss.cpp" />
<ClCompile Include="..\test_chrono_month.cpp" />
<ClCompile Include="..\test_chrono_month_day.cpp" />
<ClCompile Include="..\test_chrono_month_day_last.cpp" />
<ClCompile Include="..\test_chrono_month_weekday.cpp" />
<ClCompile Include="..\test_chrono_month_weekday_last.cpp" />
<ClCompile Include="..\test_chrono_operators.cpp" />
<ClCompile Include="..\test_chrono_weekday.cpp" />
<ClCompile Include="..\test_chrono_weekday_indexed.cpp" />
<ClCompile Include="..\test_chrono_weekday_last.cpp" />
<ClCompile Include="..\test_chrono_year.cpp" />
<ClCompile Include="..\test_chrono_year_month.cpp" />
<ClCompile Include="..\test_chrono_year_month_day.cpp" />
<ClCompile Include="..\test_chrono_year_month_day_last.cpp" />
<ClCompile Include="..\test_circular_buffer.cpp" />
<ClCompile Include="..\test_circular_buffer_external_buffer.cpp" />
<ClCompile Include="..\test_circular_iterator.cpp" />
@ -9466,6 +9525,7 @@
<ClCompile Include="..\test_successor.cpp" />
<ClCompile Include="..\test_task_scheduler.cpp" />
<ClCompile Include="..\test_threshold.cpp" />
<ClCompile Include="..\test_chrono_time_point.cpp" />
<ClCompile Include="..\test_to_arithmetic.cpp" />
<ClCompile Include="..\test_to_arithmetic_u16.cpp" />
<ClCompile Include="..\test_to_arithmetic_u32.cpp" />

View File

@ -220,6 +220,12 @@
<Filter Include="Tests\Messaging">
<UniqueIdentifier>{c75cedd3-8b6c-4662-b965-aecbe7fd5d1c}</UniqueIdentifier>
</Filter>
<Filter Include="ETL\Private\chrono">
<UniqueIdentifier>{46e23f29-ce01-418f-8331-9c739774414c}</UniqueIdentifier>
</Filter>
<Filter Include="Tests\Chrono">
<UniqueIdentifier>{1b1afa65-108a-4665-9e74-3c67a27ff917}</UniqueIdentifier>
</Filter>
<Filter Include="ETL\Codecs">
<UniqueIdentifier>{6bbca8f0-f707-45ee-9dad-6d41d401bbaf}</UniqueIdentifier>
</Filter>
@ -1374,6 +1380,30 @@
<ClInclude Include="..\..\include\etl\stringify.h">
<Filter>ETL\Utilities</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\chrono.h">
<Filter>ETL\Utilities</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\chrono\duration.h">
<Filter>ETL\Private\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\chrono\day.h">
<Filter>ETL\Private\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\chrono\month.h">
<Filter>ETL\Private\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\chrono\year.h">
<Filter>ETL\Private\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\chrono\weekday.h">
<Filter>ETL\Private\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\chrono\last_spec.h">
<Filter>ETL\Private\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\chrono\day.h">
<Filter>ETL\Utilities</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\base64_encoder.h">
<Filter>ETL\Codecs</Filter>
</ClInclude>
@ -1452,6 +1482,36 @@
<ClInclude Include="..\..\include\etl\tuple.h">
<Filter>ETL\Utilities</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\chrono\month_day.h">
<Filter>ETL\Private\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\chrono\operators.h">
<Filter>ETL\Private\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\chrono\month_weekday.h">
<Filter>ETL\Private\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\chrono\hh_mm_ss.h">
<Filter>ETL\Private\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\chrono\year_month.h">
<Filter>ETL\Private\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\chrono\year_month_day.h">
<Filter>ETL\Private\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\chrono\time_point.h">
<Filter>ETL\Private\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\chrono\year_month_weekday.h">
<Filter>ETL\Private\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\chrono\time_zone.h">
<Filter>ETL\Private\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\private\chrono\clocks.h">
<Filter>UnitTest++\Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\test_string_char.cpp">
@ -2522,6 +2582,18 @@
<ClCompile Include="..\test_macros.cpp">
<Filter>Tests\Misc</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_day.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_month.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_year.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_weekday.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\syntax_check\absolute.h.t.cpp">
<Filter>Tests\Syntax Checks\Source</Filter>
</ClCompile>
@ -3461,9 +3533,57 @@
<ClCompile Include="..\test_tuple.cpp">
<Filter>Tests\Containers</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_weekday_indexed.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_weekday_last.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_duration.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\test_ratio.cpp">
<Filter>Tests\Misc</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_month_day.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_month_day_last.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_month_weekday.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_month_weekday_last.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_hh_mm_ss.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\syntax_check\tuple.h.t.cpp">
<Filter>Tests\Syntax Checks\Source</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_year_month.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_operators.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_year_month_day.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_year_month_day_last.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_clocks.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\test_chrono_time_point.cpp">
<Filter>Tests\Chrono</Filter>
</ClCompile>
<ClCompile Include="..\syntax_check\chrono.h.t.cpp">
<Filter>Tests\Syntax Checks\Source</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\library.properties">

View File

@ -0,0 +1,4 @@
[cppcheck]
-i*.cpp
[cppcheck_files]
[cppcheck_includes]