From 3f1aa09454304b6c9dd206d0252def42c2c4a576 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 11 Sep 2023 11:15:49 +0100 Subject: [PATCH] Work in progress --- include/etl/chrono.h | 39 +++++ include/etl/hash.h | 4 +- include/etl/private/chrono/day.h | 224 ++++++++++++++++++++++++++ include/etl/private/chrono/duration.h | 139 ++++++++++++++++ test/CMakeLists.txt | 3 + test/test_chrono_day.cpp | 216 +++++++++++++++++++++++++ test/vs2022/etl.vcxproj | 3 + test/vs2022/etl.vcxproj.filters | 15 ++ 8 files changed, 641 insertions(+), 2 deletions(-) create mode 100644 include/etl/chrono.h create mode 100644 include/etl/private/chrono/day.h create mode 100644 include/etl/private/chrono/duration.h create mode 100644 test/test_chrono_day.cpp diff --git a/include/etl/chrono.h b/include/etl/chrono.h new file mode 100644 index 000000000..0cf26e5b4 --- /dev/null +++ b/include/etl/chrono.h @@ -0,0 +1,39 @@ +///\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 + +#include "platform.h" + +#include "private/chrono/duration.h" +#include "private/chrono/day.h" + +#endif diff --git a/include/etl/hash.h b/include/etl/hash.h index 214ec8c51..9d012941a 100644 --- a/include/etl/hash.h +++ b/include/etl/hash.h @@ -156,8 +156,8 @@ namespace etl /// Specialisation for signed char. ///\ingroup hash //*************************************************************************** - template<> struct - hash + template <> + struct hash { ETL_STATIC_ASSERT(sizeof(size_t) >= sizeof(signed char), "size_t smaller than type"); diff --git a/include/etl/private/chrono/day.h b/include/etl/private/chrono/day.h new file mode 100644 index 000000000..61d19e8b2 --- /dev/null +++ b/include/etl/private/chrono/day.h @@ -0,0 +1,224 @@ +///\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_DAY_INCLUDED +#define ETL_CHRONO_DAY_INCLUDED + +#include "../../platform.h" +#include "../../hash.h" + +#include "duration.h" + +#include + +namespace etl +{ + namespace chrono + { + //*********************************************************************** + /// day + //*********************************************************************** + class day + { + public: + + //*********************************************************************** + ETL_CONSTEXPR day() + : value(0) + { + } + + //*********************************************************************** + ETL_CONSTEXPR day(unsigned value_) + : value(value_) + { + } + + //*********************************************************************** + ETL_CONSTEXPR day(const etl::chrono::day& other) + : value(other.value) + { + } + + //*********************************************************************** + ETL_CONSTEXPR etl::chrono::day& operator =(const etl::chrono::day& rhs) + { + value = rhs.value; + + return *this; + } + + //*********************************************************************** + template + ETL_CONSTEXPR etl::chrono::day& operator =(const etl::chrono::duration& rhs) + { + value = etl::chrono::duration_cast(rhs); + } + + //*********************************************************************** + ETL_CONSTEXPR etl::chrono::day& operator ++() ETL_NOEXCEPT + { + ++value; + + return *this; + } + + //*********************************************************************** + ETL_CONSTEXPR14 etl::chrono::day operator ++(int) ETL_NOEXCEPT + { + const etl::chrono::day temp = *this; + ++value; + + return temp; + } + + //*********************************************************************** + ETL_CONSTEXPR etl::chrono::day& operator --() ETL_NOEXCEPT + { + --value; + + return *this; + } + + //*********************************************************************** + ETL_CONSTEXPR14 etl::chrono::day operator --(int) ETL_NOEXCEPT + { + const etl::chrono::day temp = *this; + --value; + + return temp; + } + + //*********************************************************************** + ETL_CONSTEXPR etl::chrono::day& operator +=(const etl::chrono::days& ds) ETL_NOEXCEPT + { + value += static_cast(ds.count()); + + return *this; + } + + //*********************************************************************** + ETL_CONSTEXPR etl::chrono::day& operator -=(const etl::chrono::days& ds) ETL_NOEXCEPT + { + value -= static_cast(ds.count()); + + return *this; + } + + //*********************************************************************** + ETL_CONSTEXPR bool ok() const ETL_NOEXCEPT + { + return (value >= 1U) && (value <= 31U); + } + + //*********************************************************************** + ETL_CONSTEXPR operator unsigned() const ETL_NOEXCEPT + { + return static_cast(value); + } + + private: + + unsigned char value; + }; + + //*********************************************************************** + ETL_CONSTEXPR 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; + } + + //*********************************************************************** + ETL_CONSTEXPR 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; + } + + //*********************************************************************** + ETL_CONSTEXPR 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; + } + + //*********************************************************************** + ETL_CONSTEXPR etl::chrono::days operator -(const etl::chrono::day& d1, const etl::chrono::day& d2) ETL_NOEXCEPT + { + etl::chrono::days result; + + return etl::chrono::days(static_cast(d1) - static_cast(d2)); + } + } + + //************************************************************************* + /// Hash function. + //************************************************************************* +#if ETL_USING_8BIT_TYPES + template <> + struct hash + { + size_t operator()(const etl::chrono::day& d) const + { + unsigned value = d; + const uint8_t* p = reinterpret_cast(&value); + + return etl::private_hash::generic_hash(p, p + sizeof(unsigned)); + } + }; +#endif +} + +namespace etl +{ + namespace literals + { + namespace chrono_literals + { + //*********************************************************************** + ETL_CONSTEXPR etl::chrono::day operator ""_d(unsigned long long d) ETL_NOEXCEPT + { + return etl::chrono::day(d); + } + } + } +} + +#endif \ No newline at end of file diff --git a/include/etl/private/chrono/duration.h b/include/etl/private/chrono/duration.h new file mode 100644 index 000000000..3e4ec95e7 --- /dev/null +++ b/include/etl/private/chrono/duration.h @@ -0,0 +1,139 @@ +///\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_DURATION_INCLUDED +#define ETL_CHRONO_DURATION_INCLUDED + +#include "../../platform.h" +#include "../../ratio.h" +#include "../../static_assert.h" +#include "../../limits.h" + +namespace etl +{ + namespace chrono + { + //*********************************************************************** + /// duration + //*********************************************************************** + template > + class duration + { + public: + + //*********************************************************************** + ETL_CONSTEXPR duration() ETL_NOEXCEPT + { + } + + //*********************************************************************** + ETL_CONSTEXPR duration(const etl::chrono::duration& other) ETL_NOEXCEPT + : value(other.value) + { + } + + //*********************************************************************** + template< typename TValue2 > + ETL_CONSTEXPR explicit duration(const TValue2& value_) ETL_NOEXCEPT + : value(static_cast(value_)) + { + } + + //*********************************************************************** + template< typename TValue2, typename TPeriod2 > + ETL_CONSTEXPR duration(const etl::chrono::duration& other) ETL_NOEXCEPT + : value(static_cast(other.value)) + { + ETL_STATIC_ASSERT(!(etl::is_integral::value && etl::is_floating_point::value), "Cannot convert duration from floating point to integral"); + } + + //*********************************************************************** + static ETL_NODISCARD ETL_CONSTEXPR etl::chrono::duration< TValue, TPeriod> zero() ETL_NOEXCEPT + { + return etl::chrono::duration{ 0, TPeriod()}; + } + + //*********************************************************************** + static ETL_NODISCARD ETL_CONSTEXPR etl::chrono::duration min() ETL_NOEXCEPT + { + return etl::chrono::duration { etl::numeric_limits::min() }; + } + + //*********************************************************************** + static ETL_NODISCARD ETL_CONSTEXPR etl::chrono::duration max() ETL_NOEXCEPT + { + return etl::chrono::duration{ etl::numeric_limits::max() }; + } + + //*********************************************************************** + ETL_NODISCARD ETL_CONSTEXPR TValue count() const + { + return value; + } + + private: + + TValue value; + //TPeriod period; + }; + + //*********************************************************************** + /// Duration types + //*********************************************************************** +#if (ETL_USING_64BIT_TYPES) + typedef etl::chrono::duration nanoseconds; + typedef etl::chrono::duration microseconds; + typedef etl::chrono::duration milliseconds; + typedef etl::chrono::duration > seconds; +#else + typedef etl::chrono::duration nanoseconds; + typedef etl::chrono::duration microseconds; + typedef etl::chrono::duration milliseconds; + typedef etl::chrono::duration > seconds; +#endif + typedef etl::chrono::duration > minutes; + typedef etl::chrono::duration > hours; + typedef etl::chrono::duration > days; + typedef etl::chrono::duration > weeks; + typedef etl::chrono::duration > months; + typedef etl::chrono::duration > years; + + //*********************************************************************** + /// duration_cast + //*********************************************************************** + template + ETL_CONSTEXPR TToDuration duration_cast(const etl::chrono::duration& d) + { + return TToDuration(); + } + } +} + +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index af3359bd6..85265ab18 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -45,6 +45,9 @@ add_executable(etl_tests test_callback_timer_locked.cpp test_char_traits.cpp test_checksum.cpp + + test_chrono_day.cpp + test_circular_buffer.cpp test_circular_buffer_external_buffer.cpp test_circular_iterator.cpp diff --git a/test/test_chrono_day.cpp b/test/test_chrono_day.cpp new file mode 100644 index 000000000..f8a3d4535 --- /dev/null +++ b/test/test_chrono_day.cpp @@ -0,0 +1,216 @@ +/****************************************************************************** +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" + +#if ETL_USING_CPP20 + +#include "unit_test_framework.h" + +#include "etl/chrono.h" + +#include + +namespace +{ + SUITE(test_chrono_day) + { + //************************************************************************* + TEST(test_default_constructor) + { + std::chrono::day std_day; + etl::chrono::day day; + + CHECK_EQUAL(std_day.ok(), day.ok()); + } + + //************************************************************************* + TEST(test_constructor_in_range) + { + for (unsigned i = 0U; i < 256; ++i) + { + std::chrono::day std_day(i); + etl::chrono::day day(i); + + CHECK_EQUAL(std_day.ok(), day.ok()); + CHECK_EQUAL(unsigned(std_day), unsigned(day)); + } + } + + //************************************************************************* + TEST(test_pre_increment) + { + std::chrono::day std_day(0); + etl::chrono::day day(0); + + for (int i = 0; i < 255; ++i) + { + ++std_day; + ++day; + + CHECK_EQUAL(std_day.ok(), day.ok()); + CHECK_EQUAL(unsigned(std_day), unsigned(day)); + } + } + + //************************************************************************* + TEST(test_post_increment) + { + std::chrono::day std_day(0); + etl::chrono::day day(0); + + for (int i = 0; i < 255; ++i) + { + std::chrono::day std_last_day = std_day++; + etl::chrono::day last_day = day++; + + CHECK_EQUAL(std_last_day.ok(), last_day.ok()); + CHECK_EQUAL(unsigned(std_last_day), unsigned(last_day)); + + CHECK_EQUAL(std_day.ok(), day.ok()); + CHECK_EQUAL(unsigned(std_day), unsigned(day)); + } + } + + //************************************************************************* + TEST(test_pre_decrement) + { + std::chrono::day std_day(256); + etl::chrono::day day(256); + + for (int i = 0; i < 255; ++i) + { + --std_day; + --day; + + CHECK_EQUAL(std_day.ok(), day.ok()); + CHECK_EQUAL(unsigned(std_day), unsigned(day)); + } + } + + //************************************************************************* + TEST(test_post_decrement) + { + std::chrono::day std_day(256); + etl::chrono::day day(256); + + for (int i = 0; i < 255; ++i) + { + std::chrono::day std_last_day = std_day--; + etl::chrono::day last_day = day--; + + CHECK_EQUAL(std_last_day.ok(), last_day.ok()); + CHECK_EQUAL(unsigned(std_last_day), unsigned(last_day)); + + CHECK_EQUAL(std_day.ok(), day.ok()); + CHECK_EQUAL(unsigned(std_day), unsigned(day)); + } + } + + //************************************************************************* + TEST(test_plus_equal_days) + { + std::chrono::day std_day(0); + etl::chrono::day day(0); + + std::chrono::days std_days(2); + etl::chrono::days days(2); + + for (int i = 0; i < 128; ++i) + { + std_day += std_days; + day += days; + + CHECK_EQUAL(std_day.ok(), day.ok()); + CHECK_EQUAL(unsigned(std_day), unsigned(day)); + } + } + + //************************************************************************* + TEST(test_plus_days) + { + std::chrono::day std_day1(0); + std::chrono::day std_day2(0); + etl::chrono::day day1(0); + etl::chrono::day day2(0); + + std::chrono::days std_days(2); + etl::chrono::days days(2); + + for (int i = 0; i < 128; ++i) + { + std_day1 = std_days + std_day1; + std_day2 = std_day2 + std_days; + + day1 = days + day1; + day2 = day2 + days; + + CHECK_EQUAL(std_day1.ok(), day1.ok()); + CHECK_EQUAL(std_day2.ok(), day2.ok()); + CHECK_EQUAL(unsigned(std_day1), unsigned(day1)); + CHECK_EQUAL(unsigned(std_day2), unsigned(day2)); + } + } + + //************************************************************************* + TEST(test_minus_equal_days) + { + std::chrono::day std_day(256); + etl::chrono::day day(256); + + std::chrono::days std_days(2); + etl::chrono::days days(2); + + for (int i = 0; i < 128; ++i) + { + std_day -= std_days; + day -= days; + + CHECK_EQUAL(std_day.ok(), day.ok()); + CHECK_EQUAL(unsigned(std_day), unsigned(day)); + } + } + + //************************************************************************* + TEST(test_literal_days) + { + using namespace std::literals::chrono_literals; + using namespace etl::literals::chrono_literals; + + std::chrono::day std_day = 25d; + etl::chrono::day day = 25_d; + + CHECK_EQUAL(std_day.ok(), day.ok()); + CHECK_EQUAL(unsigned(std_day), unsigned(day)); + } + }; +} + +#endif \ No newline at end of file diff --git a/test/vs2022/etl.vcxproj b/test/vs2022/etl.vcxproj index 96785631a..6809a26e5 100644 --- a/test/vs2022/etl.vcxproj +++ b/test/vs2022/etl.vcxproj @@ -2942,6 +2942,7 @@ + @@ -3000,6 +3001,7 @@ + @@ -14337,6 +14339,7 @@ + diff --git a/test/vs2022/etl.vcxproj.filters b/test/vs2022/etl.vcxproj.filters index e96c1b617..ee1bc81b4 100644 --- a/test/vs2022/etl.vcxproj.filters +++ b/test/vs2022/etl.vcxproj.filters @@ -220,6 +220,12 @@ {c75cedd3-8b6c-4662-b965-aecbe7fd5d1c} + + {46e23f29-ce01-418f-8331-9c739774414c} + + + {1b1afa65-108a-4665-9e74-3c67a27ff917} + @@ -1362,6 +1368,12 @@ ETL\Utilities + + ETL\Utilities + + + ETL\Private + @@ -3425,6 +3437,9 @@ Tests\Misc + + Tests\Chrono +