From a2bd57c89feb0f2fdadfbf5bd70b1b56ffb8e3b7 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 17 Apr 2024 13:26:06 +0100 Subject: [PATCH 1/3] #806 etl::variant_pool should support C++17 variadic parameters Added variadic version that supports >=C++11 --- .../etl/generators/type_traits_generator.h | 46 +++++++ .../etl/generators/variant_pool_generator.h | 115 ++++++++++++++++++ include/etl/type_traits.h | 46 +++++++ include/etl/variant_pool.h | 115 ++++++++++++++++++ test/etl_profile.h | 1 + test/test_type_traits.cpp | 36 ++++++ 6 files changed, 359 insertions(+) diff --git a/include/etl/generators/type_traits_generator.h b/include/etl/generators/type_traits_generator.h index d8c1ee60..35db7ea6 100644 --- a/include/etl/generators/type_traits_generator.h +++ b/include/etl/generators/type_traits_generator.h @@ -1406,6 +1406,52 @@ typedef integral_constant true_type; inline constexpr bool is_one_of_v = etl::is_one_of::value; #endif +#if ETL_USING_CPP11 + //*************************************************************************** + /// Template to determine if a type is a base of all types in a specified list. + ///\ingroup types + template + struct is_base_of_all + { + static const bool value = etl::is_base_of::value && + etl::is_base_of_all::value; + }; + + template + struct is_base_of_all + { + static const bool value = etl::is_base_of::value; + }; +#endif + +#if ETL_USING_CPP17 + template + inline constexpr bool is_base_of_all_v = etl::is_base_of_all::value; +#endif + +#if ETL_USING_CPP11 + //*************************************************************************** + /// Template to determine if a type is a base of any type in a specified list. + ///\ingroup types + template + struct is_base_of_any + { + static const bool value = etl::is_base_of::value || + etl::is_base_of_any::value; + }; + + template + struct is_base_of_any + { + static const bool value = etl::is_base_of::value; + }; +#endif + +#if ETL_USING_CPP17 + template + inline constexpr bool is_base_of_any_v = etl::is_base_of_any::value; +#endif + //*************************************************************************** /// A set of templates to allow related types to be derived. ///\ingroup types diff --git a/include/etl/generators/variant_pool_generator.h b/include/etl/generators/variant_pool_generator.h index 1ff76758..a212a1e5 100644 --- a/include/etl/generators/variant_pool_generator.h +++ b/include/etl/generators/variant_pool_generator.h @@ -73,6 +73,120 @@ cog.outl("//******************************************************************** namespace etl { +#if ETL_USING_CPP11 && !defined(ETL_VARIANT_POOL_FORCE_CPP03_IMPLEMENTATION) + //*************************************************************************** + template + class variant_pool + : public etl::generic_pool::size, + etl::largest::alignment, + MAX_SIZE_> + { + public: + + typedef etl::generic_pool::size, + etl::largest::alignment, + MAX_SIZE_> base_t; + + static const size_t MAX_SIZE = MAX_SIZE_; + + //************************************************************************* + /// Default constructor. + //************************************************************************* + variant_pool() + { + } + + //************************************************************************* + /// Creates the object from a type. Variadic parameter constructor. + //************************************************************************* + template + T* create(Args&&... args) + { + ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type"); + + return base_t::template create(etl::forward(args)...); + } + + //************************************************************************* + /// Destroys the object. + //************************************************************************* + template + void destroy(const T* const p) + { + ETL_STATIC_ASSERT((etl::is_one_of::value || etl::is_base_of_any::value), "Invalid type"); + + base_t::destroy(p); + } + + //************************************************************************* + /// Returns the maximum number of items in the variant_pool. + //************************************************************************* + size_t max_size() const + { + return MAX_SIZE; + } + + private: + + variant_pool(const variant_pool&) ETL_DELETE; + variant_pool& operator =(const variant_pool&) ETL_DELETE; + }; + + //*************************************************************************** + template + class variant_pool_ext + : public etl::generic_pool_ext::size, + etl::largest::alignment> + { + public: + + typedef etl::generic_pool_ext::size, + etl::largest::alignment> base_t; + + //************************************************************************* + /// Default constructor. + //************************************************************************* + variant_pool_ext(typename base_t::element* buffer, size_t size) + : base_t(buffer, size) + { + } + + //************************************************************************* + /// Creates the object from a type. Variadic parameter constructor. + //************************************************************************* + template + T* create(Args&&... args) + { + ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type"); + + return base_t::template create(etl::forward(args)...); + } + + //************************************************************************* + /// Destroys the object. + //************************************************************************* + template + void destroy(const T* const p) + { + ETL_STATIC_ASSERT((etl::is_one_of::value || etl::is_base_of_any::value), "Invalid type"); + + base_t::destroy(p); + } + + //************************************************************************* + /// Returns the maximum number of items in the variant_pool. + //************************************************************************* + size_t max_size() const + { + return base_t::max_size(); + } + + private: + + variant_pool_ext(const variant_pool_ext&) ETL_DELETE; + variant_pool_ext& operator =(const variant_pool_ext&) ETL_DELETE; + }; +#else //*************************************************************************** /*[[[cog import cog @@ -500,6 +614,7 @@ namespace etl variant_pool_ext(const variant_pool_ext&) ETL_DELETE; variant_pool_ext& operator =(const variant_pool_ext&) ETL_DELETE; }; +#endif } #endif diff --git a/include/etl/type_traits.h b/include/etl/type_traits.h index 43f01de3..14831ed8 100644 --- a/include/etl/type_traits.h +++ b/include/etl/type_traits.h @@ -1399,6 +1399,52 @@ typedef integral_constant true_type; inline constexpr bool is_one_of_v = etl::is_one_of::value; #endif +#if ETL_USING_CPP11 + //*************************************************************************** + /// Template to determine if a type is a base of all types in a specified list. + ///\ingroup types + template + struct is_base_of_all + { + static const bool value = etl::is_base_of::value && + etl::is_base_of_all::value; + }; + + template + struct is_base_of_all + { + static const bool value = etl::is_base_of::value; + }; +#endif + +#if ETL_USING_CPP17 + template + inline constexpr bool is_base_of_all_v = etl::is_base_of_all::value; +#endif + +#if ETL_USING_CPP11 + //*************************************************************************** + /// Template to determine if a type is a base of any type in a specified list. + ///\ingroup types + template + struct is_base_of_any + { + static const bool value = etl::is_base_of::value || + etl::is_base_of_any::value; + }; + + template + struct is_base_of_any + { + static const bool value = etl::is_base_of::value; + }; +#endif + +#if ETL_USING_CPP17 + template + inline constexpr bool is_base_of_any_v = etl::is_base_of_any::value; +#endif + //*************************************************************************** /// A set of templates to allow related types to be derived. ///\ingroup types diff --git a/include/etl/variant_pool.h b/include/etl/variant_pool.h index cb5ae7fd..d97b735a 100644 --- a/include/etl/variant_pool.h +++ b/include/etl/variant_pool.h @@ -61,6 +61,120 @@ SOFTWARE. namespace etl { +#if ETL_USING_CPP11 && !defined(ETL_VARIANT_POOL_FORCE_CPP03_IMPLEMENTATION) + //*************************************************************************** + template + class variant_pool + : public etl::generic_pool::size, + etl::largest::alignment, + MAX_SIZE_> + { + public: + + typedef etl::generic_pool::size, + etl::largest::alignment, + MAX_SIZE_> base_t; + + static const size_t MAX_SIZE = MAX_SIZE_; + + //************************************************************************* + /// Default constructor. + //************************************************************************* + variant_pool() + { + } + + //************************************************************************* + /// Creates the object from a type. Variadic parameter constructor. + //************************************************************************* + template + T* create(Args&&... args) + { + ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type"); + + return base_t::template create(etl::forward(args)...); + } + + //************************************************************************* + /// Destroys the object. + //************************************************************************* + template + void destroy(const T* const p) + { + ETL_STATIC_ASSERT((etl::is_one_of::value || etl::is_base_of_any::value), "Invalid type"); + + base_t::destroy(p); + } + + //************************************************************************* + /// Returns the maximum number of items in the variant_pool. + //************************************************************************* + size_t max_size() const + { + return MAX_SIZE; + } + + private: + + variant_pool(const variant_pool&) ETL_DELETE; + variant_pool& operator =(const variant_pool&) ETL_DELETE; + }; + + //*************************************************************************** + template + class variant_pool_ext + : public etl::generic_pool_ext::size, + etl::largest::alignment> + { + public: + + typedef etl::generic_pool_ext::size, + etl::largest::alignment> base_t; + + //************************************************************************* + /// Default constructor. + //************************************************************************* + variant_pool_ext(typename base_t::element* buffer, size_t size) + : base_t(buffer, size) + { + } + + //************************************************************************* + /// Creates the object from a type. Variadic parameter constructor. + //************************************************************************* + template + T* create(Args&&... args) + { + ETL_STATIC_ASSERT((etl::is_one_of::value), "Unsupported type"); + + return base_t::template create(etl::forward(args)...); + } + + //************************************************************************* + /// Destroys the object. + //************************************************************************* + template + void destroy(const T* const p) + { + ETL_STATIC_ASSERT((etl::is_one_of::value || etl::is_base_of_any::value), "Invalid type"); + + base_t::destroy(p); + } + + //************************************************************************* + /// Returns the maximum number of items in the variant_pool. + //************************************************************************* + size_t max_size() const + { + return base_t::max_size(); + } + + private: + + variant_pool_ext(const variant_pool_ext&) ETL_DELETE; + variant_pool_ext& operator =(const variant_pool_ext&) ETL_DELETE; + }; +#else //*************************************************************************** template ::value) == (std::is_trivially_copyable::value)); #endif #endif +#endif + } + + //************************************************************************* + TEST(test_is_base_of_any) + { + struct Base {}; + struct D1 : Base {}; + struct D2 : Base {}; + struct D3 : Base {}; + struct D4 {}; + +#if ETL_USING_CPP17 + CHECK_TRUE(bool(etl::is_base_of_any_v)); + CHECK_FALSE(bool(etl::is_base_of_any_v)); +#else + CHECK_TRUE(bool(etl::is_base_of_any::value)); + CHECK_FALSE(bool(etl::is_base_of_any::value)); +#endif + } + + //************************************************************************* + TEST(test_is_base_of_all) + { + struct Base {}; + struct D1 : Base {}; + struct D2 : Base {}; + struct D3 : Base {}; + struct D4 {}; + +#if ETL_USING_CPP17 + CHECK_TRUE(bool(etl::is_base_of_all_v)); + CHECK_FALSE(bool(etl::is_base_of_all_v)); +#else + CHECK_TRUE(bool(etl::is_base_of_all::value)); + CHECK_FALSE(bool(etl::is_base_of_all::value)); #endif } } From 4aab807b03d0e98c23c28408521518432ade308b Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 17 Apr 2024 22:02:33 +0100 Subject: [PATCH 2/3] Improvements to Unittest++ macros to fix odd VS2022 syntax colouring --- test/UnitTest++/CheckMacros.h | 22 +++++++++++----------- test/UnitTest++/TestMacros.h | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/test/UnitTest++/CheckMacros.h b/test/UnitTest++/CheckMacros.h index f655d884..063aab98 100644 --- a/test/UnitTest++/CheckMacros.h +++ b/test/UnitTest++/CheckMacros.h @@ -227,67 +227,67 @@ #ifdef CHECK #error CHECK already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK instead #else - #define CHECK UNITTEST_CHECK + #define CHECK(value) UNITTEST_CHECK((value)) #endif #ifdef CHECK_TRUE #error CHECK_TRUE already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_TRUE instead #else - #define CHECK_TRUE UNITTEST_CHECK + #define CHECK_TRUE(value) UNITTEST_CHECK((value)) #endif #ifdef CHECK_FALSE #error CHECK_FALSE already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_FALSE instead #else - #define CHECK_FALSE UNITTEST_CHECK_FALSE + #define CHECK_FALSE(value) UNITTEST_CHECK_FALSE((value)) #endif #ifdef CHECK_EQUAL #error CHECK_EQUAL already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_EQUAL instead #else - #define CHECK_EQUAL UNITTEST_CHECK_EQUAL + #define CHECK_EQUAL(expected, actual) UNITTEST_CHECK_EQUAL((expected), (actual)) #endif #ifdef CHECK_EQUAL_HEX #error CHECK_EQUAL_HEX already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_EQUAL_HEX instead #else - #define CHECK_EQUAL_HEX UNITTEST_CHECK_EQUAL_HEX + #define CHECK_EQUAL_HEX(expected, actual) UNITTEST_CHECK_EQUAL_HEX((expected), (actual)) #endif #ifdef CHECK_NOT_EQUAL #error CHECK_NOT_EQUAL already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_NOT_EQUAL instead #else - #define CHECK_NOT_EQUAL UNITTEST_CHECK_NOT_EQUAL + #define CHECK_NOT_EQUAL(expected, actual) UNITTEST_CHECK_NOT_EQUAL((expected), (actual)) #endif #ifdef CHECK_NOT_EQUAL_HEX #error CHECK_NOT_EQUAL_HEX already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_NOT_EQUAL_HEX instead #else - #define CHECK_NOT_EQUAL_HEX UNITTEST_CHECK_NOT_EQUAL_HEX + #define CHECK_NOT_EQUAL_HEX(expected, actual) UNITTEST_CHECK_NOT_EQUAL_HEX((expected), (actual)) #endif #ifdef CHECK_CLOSE #error CHECK_CLOSE already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_CLOSE instead #else - #define CHECK_CLOSE UNITTEST_CHECK_CLOSE + #define CHECK_CLOSE(expected, actual, tolerance) UNITTEST_CHECK_CLOSE((expected), (actual), (tolerance)) #endif #ifdef CHECK_ARRAY_EQUAL #error CHECK_ARRAY_EQUAL already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_ARRAY_EQUAL instead #else - #define CHECK_ARRAY_EQUAL UNITTEST_CHECK_ARRAY_EQUAL + #define CHECK_ARRAY_EQUAL(expected, actual, count) UNITTEST_CHECK_ARRAY_EQUAL((expected), (actual), (count)) #endif #ifdef CHECK_ARRAY_CLOSE #error CHECK_ARRAY_CLOSE already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_ARRAY_CLOSE instead #else - #define CHECK_ARRAY_CLOSE UNITTEST_CHECK_ARRAY_CLOSE + #define CHECK_ARRAY_CLOSE(expected, actual, count, tolerance) UNITTEST_CHECK_ARRAY_CLOSE((expected), (actual), (count), (tolerance)) #endif #ifdef CHECK_ARRAY2D_CLOSE #error CHECK_ARRAY2D_CLOSE already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_ARRAY2D_CLOSE instead #else - #define CHECK_ARRAY2D_CLOSE UNITTEST_CHECK_ARRAY2D_CLOSE + #define CHECK_ARRAY2D_CLOSE(expected, actual, rows, columns, tolerance) UNITTEST_CHECK_ARRAY2D_CLOSE((expected), (actual), (rows), (columns), (tolerance)) #endif #endif diff --git a/test/UnitTest++/TestMacros.h b/test/UnitTest++/TestMacros.h index 0c8e903d..f836abc5 100644 --- a/test/UnitTest++/TestMacros.h +++ b/test/UnitTest++/TestMacros.h @@ -113,13 +113,13 @@ #ifdef TEST #error TEST already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_TEST instead #else - #define TEST UNITTEST_TEST + #define TEST(Name) UNITTEST_TEST(Name) #endif #ifdef TEST_FIXTURE #error TEST_FIXTURE already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_TEST_FIXTURE instead #else - #define TEST_FIXTURE UNITTEST_TEST_FIXTURE + #define TEST_FIXTURE(Fixture,Name) UNITTEST_TEST_FIXTURE(Fixture,Name) #endif #endif From 800ce906273f5be5461ddefeec71ca7b650e0450 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 17 Apr 2024 22:03:01 +0100 Subject: [PATCH 3/3] Updated release notes --- support/Release notes.txt | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/support/Release notes.txt b/support/Release notes.txt index 82f4905d..afcbd6e7 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,7 +1,42 @@ =============================================================================== 20.38.11 -#812-Implement-SAE-J1850-CRC8 + +Fixes +#803 etl::unordered_map buffer overflow +#805 legacy etl::bitset set/reset does not work if the element type is greater than 8 bit +#819 etl::optional cannot return an optional object of self from member function +#820 etl::send_message does not allow for non-virtual calls +#825 Fixed extent etl::span shouldn't allow default constructor +#827 Declaration order for etl::first_set_bit_position in binary.h +#829 Possible bug on assign of etl::array +#830 gcc warning - potential null pointer dereference using etl::map +#845 etl::message_packet missing a copy constructor +#857 etl::expected emplace methods are missing-return +#868 etl::variant is missing comparison operators +#869 etl::fsm::receive function can call p_state process_event also when p_state is nullptr +#873 Validate allocated DataNode is not null to prevent gcc Wnull-dereference +#874 Allow direct removal of a node from an etl::intrusive_list + +Pull Requests: +#782 Set-is-full-error-when-adding-existing-item +#804 etl::variant (variadic) default constructed state +#812 Implement SAE-J1850 CRC8 +#843 In subspan function, add static checks on extents +#849 Fix string_stream add missing initializations of const format specifiers #850 Fixed names according to Arduino's guidelines +#854 In-place construction of shared message +#858 Fix unique_ptr assigning nullptr to a null unique_ptr causes an assert +#861 Implement constexpr strong typedef +#863 Add eq and ne operators for compare utility + +Features: +#812 Added: Implement-SAE-J1850-CRC8 +#774 Added: Truncating access for etl::bitset - Added extract() functions. +#818 Added: Apply-code-spell-check-across-entire-code-base +#806 etl::variant_pool should support C++17 variadic parameters +#847 Add has_active_timer to callback_timer +Added syntax checks to github ci + =============================================================================== 20.38.10