From 999c210d285a60850c6882eb95372f902e9a294e Mon Sep 17 00:00:00 2001 From: mike919192 <91038685+mike919192@users.noreply.github.com> Date: Wed, 10 Sep 2025 05:52:22 -0400 Subject: [PATCH 01/18] Debug assert (#1175) * debug assert POC * Swith to ETL_CONSTEXPR14 * Finish TODO checks * First and last can be equal * Add ETL_DEBUG_THROW_EXCEPTIONS * Try allowing c++11 constexpr * Add macro for throwing from c++11 constexpr * Remove braces * Add extra asserts in size_t overload functions * Fill out debug asserts * Line up comments --- include/etl/array.h | 46 ++++++++++++++++++++++++++++-- include/etl/error_handler.h | 56 +++++++++++++++++++++++++++++++++++++ include/etl/expected.h | 24 ++++------------ include/etl/platform.h | 10 +++++++ test/etl_profile.h | 2 ++ test/test_array.cpp | 25 +++++++++++++++++ 6 files changed, 143 insertions(+), 20 deletions(-) diff --git a/include/etl/array.h b/include/etl/array.h index c0cf8f98..e0854854 100644 --- a/include/etl/array.h +++ b/include/etl/array.h @@ -145,6 +145,8 @@ namespace etl ETL_CONSTEXPR14 reference operator[](size_t i) { + ETL_DEBUG_ASSERT(i < SIZE, ETL_ERROR(array_out_of_range)); + return _buffer[i]; } @@ -156,7 +158,14 @@ namespace etl ETL_NODISCARD ETL_CONSTEXPR const_reference operator[](size_t i) const { + //throwing from c++11 constexpr requires a special macro +#if ETL_USING_CPP11 && !ETL_USING_CPP14 && ETL_DEBUG_USING_EXCEPTIONS + ETL_DEBUG_ASSERT_OR_RETURN_VALUE_CPP11_CONSTEXPR(i < SIZE, ETL_ERROR(array_out_of_range), _buffer[i]); +#else + ETL_DEBUG_ASSERT(i < SIZE, ETL_ERROR(array_out_of_range)); + return _buffer[i]; +#endif } //************************************************************************* @@ -166,6 +175,8 @@ namespace etl ETL_CONSTEXPR14 reference front() { + ETL_STATIC_ASSERT(SIZE > 0, "Array is empty."); + return _buffer[0]; } @@ -175,6 +186,8 @@ namespace etl ETL_NODISCARD ETL_CONSTEXPR const_reference front() const { + ETL_STATIC_ASSERT(SIZE > 0, "Array is empty."); + return _buffer[0]; } @@ -185,6 +198,8 @@ namespace etl ETL_CONSTEXPR14 reference back() { + ETL_STATIC_ASSERT(SIZE > 0, "Array is empty."); + return _buffer[SIZE - 1]; } @@ -194,6 +209,8 @@ namespace etl ETL_NODISCARD ETL_CONSTEXPR const_reference back() const { + ETL_STATIC_ASSERT(SIZE > 0, "Array is empty."); + return _buffer[SIZE - 1]; } @@ -429,6 +446,8 @@ namespace etl //************************************************************************* inline iterator insert_at(size_t position, parameter_t value) { + ETL_DEBUG_ASSERT(position < SIZE, ETL_ERROR(array_out_of_range)); + return insert(begin() + position, value); } @@ -439,6 +458,8 @@ namespace etl //************************************************************************* iterator insert(const_iterator position, parameter_t value) { + ETL_DEBUG_ASSERT(cbegin() <= position && position < cend(), ETL_ERROR(array_out_of_range)); + iterator p = to_iterator(position); etl::move_backward(p, end() - 1, end()); @@ -456,6 +477,8 @@ namespace etl template inline iterator insert_at(size_t position, TIterator first, const TIterator last) { + ETL_DEBUG_ASSERT(position < SIZE, ETL_ERROR(array_out_of_range)); + return insert(begin() + position, first, last); } @@ -468,6 +491,8 @@ namespace etl template iterator insert(const_iterator position, TIterator first, const TIterator last) { + ETL_DEBUG_ASSERT(cbegin() <= position && position < cend(), ETL_ERROR(array_out_of_range)); + iterator p = to_iterator(position); iterator result(p); @@ -494,6 +519,8 @@ namespace etl //************************************************************************* inline iterator erase_at(size_t position) { + ETL_DEBUG_ASSERT(position < SIZE, ETL_ERROR(array_out_of_range)); + return erase(begin() + position); } @@ -504,6 +531,8 @@ namespace etl //************************************************************************* iterator erase(const_iterator position) { + ETL_DEBUG_ASSERT(cbegin() <= position && position < cend(), ETL_ERROR(array_out_of_range)); + iterator p = to_iterator(position); etl::move(p + 1, end(), p); @@ -518,6 +547,8 @@ namespace etl //************************************************************************* iterator erase_range(size_t first, size_t last) { + ETL_DEBUG_ASSERT(first <= last && last <= SIZE, ETL_ERROR(array_out_of_range)); + return erase(begin() + first, begin() + last); } @@ -529,6 +560,8 @@ namespace etl //************************************************************************* iterator erase(const_iterator first, const_iterator last) { + ETL_DEBUG_ASSERT(cbegin() <= first && first <= last && last <= cend(), ETL_ERROR(array_out_of_range)); + iterator p = to_iterator(first); etl::move(last, cend(), p); return p; @@ -541,6 +574,8 @@ namespace etl //************************************************************************* inline iterator erase_at(size_t position, parameter_t value) { + ETL_DEBUG_ASSERT(position < SIZE, ETL_ERROR(array_out_of_range)); + return erase(begin() + position, value); } @@ -551,6 +586,8 @@ namespace etl //************************************************************************* iterator erase(const_iterator position, parameter_t value) { + ETL_DEBUG_ASSERT(cbegin() <= position && position < cend(), ETL_ERROR(array_out_of_range)); + iterator p = to_iterator(position); etl::move(p + 1, end(), p); @@ -567,16 +604,21 @@ namespace etl //************************************************************************* iterator erase_range(size_t first, size_t last, parameter_t value) { + ETL_DEBUG_ASSERT(first <= last && last <= SIZE, ETL_ERROR(array_out_of_range)); + return erase(begin() + first, begin() + last, value); } //************************************************************************* /// Erases a range of values from the array. - ///\param position The iterator to the position to erase at. - ///\param value The value to use to overwrite the last elements in the array. + ///\param first The first item to erase. + ///\param last The one past the last item to erase. + ///\param value The value to use to overwrite the last elements in the array. //************************************************************************* iterator erase(const_iterator first, const_iterator last, parameter_t value) { + ETL_DEBUG_ASSERT(cbegin() <= first && first <= last && last <= cend(), ETL_ERROR(array_out_of_range)); + iterator p = to_iterator(first); p = etl::move(last, cend(), p); diff --git a/include/etl/error_handler.h b/include/etl/error_handler.h index 07237f89..75e71381 100644 --- a/include/etl/error_handler.h +++ b/include/etl/error_handler.h @@ -364,6 +364,62 @@ namespace etl #endif #endif +#if ETL_IS_DEBUG_BUILD + #if defined(ETL_DEBUG_USE_ASSERT_FUNCTION) + #define ETL_DEBUG_ASSERT(b, e) {if (!(b)) ETL_UNLIKELY {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e));}} // If the condition fails, calls the assert function + #define ETL_DEBUG_ASSERT_OR_RETURN(b, e) {if (!(b)) ETL_UNLIKELY {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); return;}} // If the condition fails, calls the assert function and return + #define ETL_DEBUG_ASSERT_OR_RETURN_VALUE(b, e, v) {if (!(b)) ETL_UNLIKELY {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); return (v);}} // If the condition fails, calls the assert function and return a value + + #define ETL_DEBUG_ASSERT_FAIL(e) {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e));} // Calls the assert function + #define ETL_DEBUG_ASSERT_FAIL_AND_RETURN(e) {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); return;} // Calls the assert function and return + #define ETL_DEBUG_ASSERT_FAIL_AND_RETURN_VALUE(e, v) {etl::private_error_handler::assert_handler<0>::assert_function_ptr((e)); return (v);} // Calls the assert function and return a value + #elif ETL_DEBUG_USING_EXCEPTIONS + #if defined(ETL_DEBUG_LOG_ERRORS) + #define ETL_DEBUG_ASSERT(b, e) {if (!(b)) ETL_UNLIKELY {etl::error_handler::error((e)); throw((e));}} // If the condition fails, calls the error handler then throws an exception. + #define ETL_DEBUG_ASSERT_OR_RETURN_VALUE_CPP11_CONSTEXPR(b, e, v) if (!(b)) ETL_UNLIKELY {etl::error_handler::error((e));} return (b) ? (v) : throw(e) // throwing from c++11 constexpr requires ? operator + #define ETL_DEBUG_ASSERT_OR_RETURN(b, e) {if (!(b)) ETL_UNLIKELY {etl::error_handler::error((e)); throw((e)); return;}} // If the condition fails, calls the error handler then throws an exception. + #define ETL_DEBUG_ASSERT_OR_RETURN_VALUE(b, e, v) {if (!(b)) ETL_UNLIKELY {etl::error_handler::error((e)); throw((e)); return(v);}} // If the condition fails, calls the error handler then throws an exception. + + #define ETL_DEBUG_ASSERT_FAIL(e) {etl::error_handler::error((e)); throw((e));} // Calls the error handler then throws an exception. + #define ETL_DEBUG_ASSERT_FAIL_AND_RETURN(e) {etl::error_handler::error((e)); throw((e)); return;} // Calls the error handler then throws an exception. + #define ETL_DEBUG_ASSERT_FAIL_AND_RETURN_VALUE(e, v) {etl::error_handler::error((e)); throw((e)); return(v);} // Calls the error handler then throws an exception. + #else + #define ETL_DEBUG_ASSERT(b, e) {if (!(b)) ETL_UNLIKELY {throw((e));}} // If the condition fails, throws an exception. + #define ETL_DEBUG_ASSERT_OR_RETURN_VALUE_CPP11_CONSTEXPR(b, e, v) return (b) ? (v) : throw(e) // throwing from c++11 constexpr requires ? operator + #define ETL_DEBUG_ASSERT_OR_RETURN(b, e) {if (!(b)) ETL_UNLIKELY {throw((e));}} // If the condition fails, throws an exception. + #define ETL_DEBUG_ASSERT_OR_RETURN_VALUE(b, e, v) {if (!(b)) ETL_UNLIKELY {throw((e));}} // If the condition fails, throws an exception. + + #define ETL_DEBUG_ASSERT_FAIL(e) {throw((e));} // Throws an exception. + #define ETL_DEBUG_ASSERT_FAIL_AND_RETURN(e) {throw((e));} // Throws an exception. + #define ETL_DEBUG_ASSERT_FAIL_AND_RETURN_VALUE(e, v) {throw((e));} // Throws an exception. + #endif + #elif defined(ETL_DEBUG_LOG_ERRORS) + #define ETL_DEBUG_ASSERT(b, e) {if (!(b)) ETL_UNLIKELY {etl::error_handler::error((e));}} // If the condition fails, calls the error handler + #define ETL_DEBUG_ASSERT_OR_RETURN(b, e) {if (!(b)) ETL_UNLIKELY {etl::error_handler::error((e)); return;}} // If the condition fails, calls the error handler and return + #define ETL_DEBUG_ASSERT_OR_RETURN_VALUE(b, e, v) {if (!(b)) ETL_UNLIKELY {etl::error_handler::error((e)); return (v);}} // If the condition fails, calls the error handler and return a value + + #define ETL_DEBUG_ASSERT_FAIL(e) {etl::error_handler::error((e));} // Calls the error handler + #define ETL_DEBUG_ASSERT_FAIL_AND_RETURN(e) {etl::error_handler::error((e)); return;} // Calls the error handler and return + #define ETL_DEBUG_ASSERT_FAIL_AND_RETURN_VALUE(e, v) {etl::error_handler::error((e)); return (v);} // Calls the error handler and return a value + #else + #define ETL_DEBUG_ASSERT(b, e) assert((b)) // If the condition fails, asserts. + #define ETL_DEBUG_ASSERT_OR_RETURN(b, e) {if (!(b)) ETL_UNLIKELY {assert(false); return;}} // If the condition fails, asserts and return. + #define ETL_DEBUG_ASSERT_OR_RETURN_VALUE(b, e, v) {if (!(b)) ETL_UNLIKELY {assert(false); return(v);}} // If the condition fails, asserts and return a value. + + #define ETL_DEBUG_ASSERT_FAIL(e) assert(false) // Asserts. + #define ETL_DEBUG_ASSERT_FAIL_AND_RETURN(e) {assert(false); return;} // Asserts. + #define ETL_DEBUG_ASSERT_FAIL_AND_RETURN_VALUE(e, v) {assert(false); return(v);} // Asserts. + #endif +#else + #define ETL_DEBUG_ASSERT(b, e) // Does nothing. + #define ETL_DEBUG_ASSERT_OR_RETURN(b, e) {if (!(b)) ETL_UNLIKELY return;} // Returns. + #define ETL_DEBUG_ASSERT_OR_RETURN_VALUE(b, e, v) {if (!(b)) ETL_UNLIKELY return(v);} // Returns a value. + + #define ETL_DEBUG_ASSERT_FAIL(e) // Does nothing. + #define ETL_DEBUG_ASSERT_FAIL_AND_RETURN(e) {return;} // Returns. + #define ETL_DEBUG_ASSERT_FAIL_AND_RETURN_VALUE(e, v) {return(v);} // Returns a value. +#endif + #if defined(ETL_VERBOSE_ERRORS) #define ETL_ERROR(e) (e(__FILE__, __LINE__)) // Make an exception with the file name and line number. #define ETL_ERROR_WITH_VALUE(e, v) (e(__FILE__, __LINE__, (v))) // Make an exception with the file name, line number and value. diff --git a/include/etl/expected.h b/include/etl/expected.h index 49c3d82b..2e761348 100644 --- a/include/etl/expected.h +++ b/include/etl/expected.h @@ -675,9 +675,7 @@ namespace etl //******************************************* value_type* operator ->() { -#if ETL_IS_DEBUG_BUILD - ETL_ASSERT(has_value(), ETL_ERROR(expected_invalid)); -#endif + ETL_DEBUG_ASSERT(has_value(), ETL_ERROR(expected_invalid)); return etl::addressof(etl::get(storage)); } @@ -687,9 +685,7 @@ namespace etl //******************************************* const value_type* operator ->() const { -#if ETL_IS_DEBUG_BUILD - ETL_ASSERT(has_value(), ETL_ERROR(expected_invalid)); -#endif + ETL_DEBUG_ASSERT(has_value(), ETL_ERROR(expected_invalid)); return etl::addressof(etl::get(storage)); } @@ -699,9 +695,7 @@ namespace etl //******************************************* value_type& operator *() ETL_LVALUE_REF_QUALIFIER { -#if ETL_IS_DEBUG_BUILD - ETL_ASSERT(has_value(), ETL_ERROR(expected_invalid)); -#endif + ETL_DEBUG_ASSERT(has_value(), ETL_ERROR(expected_invalid)); return etl::get(storage); } @@ -711,9 +705,7 @@ namespace etl //******************************************* const value_type& operator *() const ETL_LVALUE_REF_QUALIFIER { -#if ETL_IS_DEBUG_BUILD - ETL_ASSERT(has_value(), ETL_ERROR(expected_invalid)); -#endif + ETL_DEBUG_ASSERT(has_value(), ETL_ERROR(expected_invalid)); return etl::get(storage); } @@ -724,9 +716,7 @@ namespace etl //******************************************* value_type&& operator *()&& { -#if ETL_IS_DEBUG_BUILD - ETL_ASSERT(has_value(), ETL_ERROR(expected_invalid)); -#endif + ETL_DEBUG_ASSERT(has_value(), ETL_ERROR(expected_invalid)); return etl::move(etl::get(storage)); } @@ -736,9 +726,7 @@ namespace etl //******************************************* const value_type&& operator *() const&& { -#if ETL_IS_DEBUG_BUILD - ETL_ASSERT(has_value(), ETL_ERROR(expected_invalid)); -#endif + ETL_DEBUG_ASSERT(has_value(), ETL_ERROR(expected_invalid)); return etl::move(etl::get(storage)); } diff --git a/include/etl/platform.h b/include/etl/platform.h index 012a379b..af0b9a6d 100644 --- a/include/etl/platform.h +++ b/include/etl/platform.h @@ -251,6 +251,16 @@ SOFTWARE. #define ETL_NOT_USING_EXCEPTIONS 1 #endif +//************************************* +// Indicate if C++ exceptions are enabled for debug asserts. +#if ETL_IS_DEBUG_BUILD && defined(ETL_DEBUG_THROW_EXCEPTIONS) + #define ETL_DEBUG_USING_EXCEPTIONS 1 + #define ETL_DEBUG_NOT_USING_EXCEPTIONS 0 +#else + #define ETL_DEBUG_USING_EXCEPTIONS 0 + #define ETL_DEBUG_NOT_USING_EXCEPTIONS 1 +#endif + //************************************* // Indicate if nullptr is used. #if ETL_NO_NULLPTR_SUPPORT diff --git a/test/etl_profile.h b/test/etl_profile.h index d6475c6a..b396bfde 100644 --- a/test/etl_profile.h +++ b/test/etl_profile.h @@ -31,7 +31,9 @@ SOFTWARE. #ifndef ETL_PROFILE_H_INCLUDED #define ETL_PROFILE_H_INCLUDED +#define ETL_DEBUG #define ETL_THROW_EXCEPTIONS +#define ETL_DEBUG_THROW_EXCEPTIONS #define ETL_VERBOSE_ERRORS #define ETL_CHECK_PUSH_POP #define ETL_ISTRING_REPAIR_ENABLE diff --git a/test/test_array.cpp b/test/test_array.cpp index 4fd6a263..c779ab76 100644 --- a/test/test_array.cpp +++ b/test/test_array.cpp @@ -134,6 +134,9 @@ namespace { CHECK_EQUAL(data[i], compare_data[i]); } + + //ETL_DEBUG and ETL_THROW_EXCEPTIONS are defined + CHECK_THROW({ int d = data[data.size()]; (void)d; }, etl::array_out_of_range); } //************************************************************************* @@ -145,6 +148,9 @@ namespace { CHECK_EQUAL(data[i], compare_data[i]); } + + //ETL_DEBUG and ETL_THROW_EXCEPTIONS are defined + CHECK_THROW({ int d = data[data.size()]; (void)d; }, etl::array_out_of_range); } //************************************************************************* @@ -443,6 +449,10 @@ namespace CHECK_EQUAL(data[9], *result); isEqual = std::equal(data.begin(), data.end(), std::begin(check3)); CHECK(isEqual); + + // Insert out of range + //ETL_DEBUG and ETL_THROW_EXCEPTIONS are defined + CHECK_THROW({ result = data.insert_at(data.size(), 99); }, etl::array_out_of_range); } //************************************************************************* @@ -493,6 +503,10 @@ namespace CHECK_EQUAL(data[4], *result); isEqual = std::equal(data.begin(), data.end(), std::begin(check5)); CHECK(isEqual); + + // Insert out of range + //ETL_DEBUG and ETL_THROW_EXCEPTIONS are defined + CHECK_THROW({ result = data.insert_at(data.size(), &source2[0], &source2[13]); }, etl::array_out_of_range); } //************************************************************************* @@ -547,6 +561,10 @@ namespace CHECK_EQUAL(data[9], *result); isEqual = std::equal(data.begin(), data.end(), std::begin(check3b)); CHECK(isEqual); + + // Erase out of range + //ETL_DEBUG and ETL_THROW_EXCEPTIONS are defined + CHECK_THROW({ result = data.erase_at(data.size()); }, etl::array_out_of_range); } //************************************************************************* @@ -601,6 +619,13 @@ namespace CHECK_EQUAL(data[5], *result); isEqual = std::equal(data.begin(), data.end(), std::begin(check3b)); CHECK(isEqual); + + //ETL_DEBUG and ETL_THROW_EXCEPTIONS are defined + // first is greater than last + CHECK_THROW({ result = data.erase_range(6, 5, 99); }, etl::array_out_of_range); + + // Erase out of range + CHECK_THROW({ result = data.erase_range(5, data.size() + 1, 99); }, etl::array_out_of_range); } //************************************************************************* From df30de28773246760f75c73b2baee3372fea9fe2 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 10 Sep 2025 10:50:02 +0100 Subject: [PATCH 02/18] removed navis file from project --- test/vs2022/etl.vcxproj | 3 --- test/vs2022/etl.vcxproj.filters | 5 ----- 2 files changed, 8 deletions(-) diff --git a/test/vs2022/etl.vcxproj b/test/vs2022/etl.vcxproj index 8a6a48f0..3d361cfb 100644 --- a/test/vs2022/etl.vcxproj +++ b/test/vs2022/etl.vcxproj @@ -11654,9 +11654,6 @@ - - - diff --git a/test/vs2022/etl.vcxproj.filters b/test/vs2022/etl.vcxproj.filters index e36573c9..3b9bf643 100644 --- a/test/vs2022/etl.vcxproj.filters +++ b/test/vs2022/etl.vcxproj.filters @@ -3948,9 +3948,4 @@ Resource Files\Images - - - Resource Files - - \ No newline at end of file From ea91dabee5aa0186cedf62c2cfae62b9f9d29008 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Wed, 10 Sep 2025 11:37:30 +0200 Subject: [PATCH 03/18] Regression fix: Support zero arguments emplace() in etl::optional (#1183) * Added coderabbitai configuration * Added builtin mem function tests * Modified etl::typed_storage * Modified etl::typed_storage # Conflicts: # include/etl/alignment.h * Added ETL_NOEXCEPT and ETL_NOEXCEPT_IF_NO_THROW * Added etl::typed_storage_ext and swap for same * Added etl::typed_storage_ext and swap for same # Conflicts: # include/etl/alignment.h * Added release notes * Fixes to GCC -O2 errors * Changed char* parameters to value_type* parameters * Fixed compilation issues for const containers unit tests * Added automatic selection of __builtin_memxxx functions for GCC and clang * Added enhanced coderabbit configuration * Updated version and release notes * Disabled constexpr const container tests for C++11 * Attempted fixes for MacOS compilation * Attempted fixes for MacOS compilation * Attempted fixes for MacOS compilation * Attempted fixes for MacOS compilation * Updated version and release notes * feat: removed unreachable break statements (#1169) * Updated version and release notes * Modified etl::typed_storage # Conflicts: # include/etl/alignment.h * Support zero arguments emplace() in etl::optional For non-fundamental types, a recent change in etl::optional was introduced that doesn't support zero arguments emplace() anymore. This change fixes it and adds the respective test. --------- Co-authored-by: John Wellbelove Co-authored-by: Drew Rife --- include/etl/optional.h | 11 +++++++++++ test/test_optional.cpp | 16 ++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/include/etl/optional.h b/include/etl/optional.h index 48289116..e8e40439 100644 --- a/include/etl/optional.h +++ b/include/etl/optional.h @@ -536,6 +536,17 @@ namespace etl return storage.u.value; } + + //************************************************************************* + /// Emplaces with zero arguments, i.e. default construct emplace. + //************************************************************************* + ETL_CONSTEXPR20_STL + T& emplace() + { + storage.construct(); + + return storage.u.value; + } #else //************************************************************************* /// Emplaces a value. diff --git a/test/test_optional.cpp b/test/test_optional.cpp index e9623b87..c5a34d08 100644 --- a/test/test_optional.cpp +++ b/test/test_optional.cpp @@ -218,15 +218,27 @@ namespace } //************************************************************************* - TEST(test_emplace_zero_parameters) + TEST(test_emplace_zero_parameters_fundamental) { etl::optional result = 1; - result.emplace(); + CHECK_EQUAL(0, static_cast(result.emplace())); CHECK_TRUE(result.has_value()); CHECK_EQUAL(0, int(result.value())); } + //************************************************************************* + TEST(test_emplace_zero_parameters_non_fundamental) + { + etl::optional result = std::string("abc"); + + std::string& ref = result.emplace(); + CHECK_EQUAL(std::string(), ref); + CHECK_EQUAL(&ref, &result.value()); + CHECK_TRUE(result.has_value()); + CHECK_EQUAL("", std::string(result.value())); + } + //************************************************************************* TEST(test_emplace_return) { From 193b6ba3e8c3dabdba7bef9b95b4b135d8243e50 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Wed, 10 Sep 2025 11:41:09 +0200 Subject: [PATCH 04/18] Fix etl::typed_storage by supporting omitted destructors (#1182) * Added coderabbitai configuration * Added builtin mem function tests * Modified etl::typed_storage * Modified etl::typed_storage # Conflicts: # include/etl/alignment.h * Added ETL_NOEXCEPT and ETL_NOEXCEPT_IF_NO_THROW * Added etl::typed_storage_ext and swap for same * Added etl::typed_storage_ext and swap for same # Conflicts: # include/etl/alignment.h * Added release notes * Fixes to GCC -O2 errors * Changed char* parameters to value_type* parameters * Fixed compilation issues for const containers unit tests * Added automatic selection of __builtin_memxxx functions for GCC and clang * Added enhanced coderabbit configuration * Updated version and release notes * Disabled constexpr const container tests for C++11 * Attempted fixes for MacOS compilation * Attempted fixes for MacOS compilation * Attempted fixes for MacOS compilation * Attempted fixes for MacOS compilation * Updated version and release notes * feat: removed unreachable break statements (#1169) * Updated version and release notes * Modified etl::typed_storage # Conflicts: # include/etl/alignment.h * Fix etl::typed_storage by supporting omitted destructors In a recent change to alignment.h, the etl::typed_storage was changed in a way that in case of an already constructed object, the object is created via assignment. However, this contradicts the original use case that led to etl::typed_storage in the first place: https://github.com/ETLCPP/etl/pull/1023 The goal is to omit destructors (and at the same time support classes with deleted assignment operators), so they can be optimized out at link time. This change reverts commit ac7b268 to restore the original functionality and changes the test to reflect the original use case. * Fix missing create() in non-C++11 typed_storage_ext constructor * Typo fix --------- Co-authored-by: John Wellbelove Co-authored-by: Drew Rife Co-authored-by: John Wellbelove --- include/etl/alignment.h | 101 ++++++++++++++-------------------------- test/test_alignment.cpp | 12 ++++- 2 files changed, 47 insertions(+), 66 deletions(-) diff --git a/include/etl/alignment.h b/include/etl/alignment.h index c289b4a4..73527765 100644 --- a/include/etl/alignment.h +++ b/include/etl/alignment.h @@ -450,17 +450,10 @@ namespace etl template reference create(TArgs&&... args) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) { - if (has_value()) - { - storage.value = T(args...); - } - else - { - valid = true; - ::new (&storage.value) value_type(etl::forward(args)...); - } - - return storage.value; + ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (&storage.value) value_type(etl::forward(args)...); + valid = true; + return *p; } #else //*************************************************************************** @@ -470,17 +463,10 @@ namespace etl template reference create(const T1& t1) { - if (has_value()) - { - storage.value = T(t1); - } - else - { - valid = true; - ::new (&storage.value) value_type(t1); - } - - return storage.value; + ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (&storage.value) value_type(t1); + valid = true; + return *p; } //*************************************************************************** @@ -490,17 +476,10 @@ namespace etl template reference create(const T1& t1, const T2& t2) { - if (has_value()) - { - storage.value = T(t1, t2); - } - else - { - valid = true; - ::new (&storage.value) value_type(t1, t2); - } - - return storage.value; + ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (&storage.value) value_type(t1, t2); + valid = true; + return *p; } //*************************************************************************** @@ -510,17 +489,10 @@ namespace etl template reference create(const T1& t1, const T2& t2, const T3& t3) { - if (has_value()) - { - storage.value = T(t1, t2, t3); - } - else - { - valid = true; - ::new (&storage.value) value_type(t1, t2, t3); - } - - return storage.value; + ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (&storage.value) value_type(t1, t2, t3); + valid = true; + return *p; } //*************************************************************************** @@ -530,17 +502,10 @@ namespace etl template reference create(const T1& t1, const T2& t2, const T3& t3, const T4& t4) { - if (has_value()) - { - storage.value = T(t1, t2, t3, t4); - } - else - { - valid = true; - ::new (&storage.value) value_type(t1, t2, t3, t4); - } - - return storage.value; + ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (&storage.value) value_type(t1, t2, t3, t4); + valid = true; + return *p; } #endif @@ -684,6 +649,7 @@ namespace etl , valid(false) { ETL_ASSERT(etl::is_aligned(pbuffer_, etl::alignment_of::value), ETL_ERROR(etl::alignment_error)); + create(t1); } //*************************************************************************** @@ -744,62 +710,67 @@ namespace etl #if ETL_USING_CPP11 //*************************************************************************** /// Constructs the instance of T forwarding the given \p args to its constructor. - /// \returns the instance of T which has been constructed in the internal byte array. + /// \returns the instance of T which has been constructed in the external buffer. //*************************************************************************** template reference create(TArgs&&... args) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) { ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (pbuffer) value_type(etl::forward(args)...); valid = true; - return *::new (pbuffer) value_type(etl::forward(args)...); + return *p; } #else //*************************************************************************** /// Constructs the instance of T with type T1 - /// \returns the instance of T which has been constructed in the internal byte array. + /// \returns the instance of T which has been constructed in the external buffer. //*************************************************************************** template reference create(const T1& t1) { ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (pbuffer) value_type(t1); valid = true; - return *::new (pbuffer) value_type(t1); + return *p; } //*************************************************************************** /// Constructs the instance of T with types T1, T2 - /// \returns the instance of T which has been constructed in the internal byte array. + /// \returns the instance of T which has been constructed in the external buffer. //*************************************************************************** template reference create(const T1& t1, const T2& t2) { ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (pbuffer) value_type(t1, t2); valid = true; - return *::new (pbuffer) value_type(t1, t2); + return *p; } //*************************************************************************** /// Constructs the instance of T with types T1, T2, T3 - /// \returns the instance of T which has been constructed in the internal byte array. + /// \returns the instance of T which has been constructed in the external buffer. //*************************************************************************** template reference create(const T1& t1, const T2& t2, const T3& t3) { ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (pbuffer) value_type(t1, t2, t3); valid = true; - return *::new (pbuffer) value_type(t1, t2, t3); + return *p; } //*************************************************************************** /// Constructs the instance of T with types T1, T2, T3, T4 - /// \returns the instance of T which has been constructed in the internal byte array. + /// \returns the instance of T which has been constructed in the external buffer. //*************************************************************************** template reference create(const T1& t1, const T2& t2, const T3& t3, const T4& t4) { ETL_ASSERT(!has_value(), ETL_ERROR(etl::typed_storage_error)); + pointer p = ::new (pbuffer) value_type(t1, t2, t3, t4); valid = true; - return *::new (pbuffer) value_type(t1, t2, t3, t4); + return *p; } #endif diff --git a/test/test_alignment.cpp b/test/test_alignment.cpp index c38acedb..24ff4c28 100644 --- a/test/test_alignment.cpp +++ b/test/test_alignment.cpp @@ -48,6 +48,7 @@ void f(int) { } +// Demonstrator class for etl::typed_storage tests struct A_t { A_t(uint32_t v_x, uint8_t v_y) @@ -56,13 +57,22 @@ struct A_t { } + // Just for test purpose. In production code, etl::typed_storage + // actually supports the use case of destructors being optimized + // away since they are not necessary for global objects that are + // never destroyed ~A_t() { x = 0; y = 0; } - bool operator==(A_t& other) + // etl::typed_storage helps implementing the use case of becoming + // independent of the destructor. By deleting the assignment operator, + // we make sure that the destructor is not linked + A_t& operator=(const A_t&) = delete; + + bool operator==(const A_t& other) const { return other.x == x && other.y == y; } From b5e065e1c8a5a232109353fe9a3df56800213abb Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 10 Sep 2025 20:52:16 +0100 Subject: [PATCH 05/18] Updated version and release notes --- arduino/library-arduino.json | 2 +- arduino/library-arduino.properties | 2 +- include/etl/version.h | 2 +- library.json | 2 +- library.properties | 2 +- support/Release notes.txt | 7 +++++++ version.txt | 2 +- 7 files changed, 13 insertions(+), 6 deletions(-) diff --git a/arduino/library-arduino.json b/arduino/library-arduino.json index 5e951baa..917ae676 100644 --- a/arduino/library-arduino.json +++ b/arduino/library-arduino.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library ETL", - "version": "20.43.1", + "version": "20.43.2", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/arduino/library-arduino.properties b/arduino/library-arduino.properties index ad368df4..cee37df3 100644 --- a/arduino/library-arduino.properties +++ b/arduino/library-arduino.properties @@ -1,5 +1,5 @@ name=Embedded Template Library ETL -version=20.43.1 +version=20.43.2 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/include/etl/version.h b/include/etl/version.h index b5c6ea9e..cabd4d69 100644 --- a/include/etl/version.h +++ b/include/etl/version.h @@ -40,7 +40,7 @@ SOFTWARE. #define ETL_VERSION_MAJOR 20 #define ETL_VERSION_MINOR 43 -#define ETL_VERSION_PATCH 1 +#define ETL_VERSION_PATCH 2 #define ETL_VERSION ETL_STRING(ETL_VERSION_MAJOR) "." ETL_STRING(ETL_VERSION_MINOR) "." ETL_STRING(ETL_VERSION_PATCH) #define ETL_VERSION_W ETL_WIDE_STRING(ETL_VERSION_MAJOR) L"." ETL_WIDE_STRING(ETL_VERSION_MINOR) L"." ETL_WIDE_STRING(ETL_VERSION_PATCH) diff --git a/library.json b/library.json index 303c5d4b..57cf258f 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library", - "version": "20.43.1", + "version": "20.43.2", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/library.properties b/library.properties index cc7168ad..4079e46f 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Embedded Template Library -version=20.43.1 +version=20.43.2 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/support/Release notes.txt b/support/Release notes.txt index 9916964d..77d9728d 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,4 +1,11 @@ =============================================================================== +20.43.2 + +Pull Requests: +#1182 Fix etl::typed_storage by supporting omitted destructors +#1183 Regression fix: Support zero arguments emplace() in etl::optional + +=============================================================================== 20.43.1 Updates: diff --git a/version.txt b/version.txt index 411c7d3b..f9ffdf0b 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -20.43.1 +20.43.2 From 042a62154e75414f4d8b5e10bfc5bb3b6fb3459c Mon Sep 17 00:00:00 2001 From: David Ockey <2897027+ockeydockey@users.noreply.github.com> Date: Thu, 11 Sep 2025 10:23:50 -0500 Subject: [PATCH 06/18] Removed forced unsigned int cast in type_def bit-shift operators (#1178) * Removed UB in type_def bit-shift operators * Changed shift operators to allow both signed and unsigned operands for shifts This allows the library user to explicitly use unsigned values to avoid UB * Fixed constexpr errors for CPP11 * Changed is_arithmetic checks to use is_integral since valid shifts require integral operands * Removed need for CPP11 since changes are CPP03 compatible --- include/etl/type_def.h | 33 +++++++++++++++++++++++++++++---- test/test_type_def.cpp | 19 ++++++++++++++++--- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/include/etl/type_def.h b/include/etl/type_def.h index 4815b670..30701932 100644 --- a/include/etl/type_def.h +++ b/include/etl/type_def.h @@ -290,14 +290,18 @@ namespace etl } //********************************************************************* - ETL_CONSTEXPR14 type_def& operator <<=(int rhs) ETL_NOEXCEPT + template + ETL_CONSTEXPR14 typename etl::enable_if::value, type_def&>::type + operator <<=(T rhs) ETL_NOEXCEPT { value <<= rhs; return *this; } //********************************************************************* - ETL_CONSTEXPR14 type_def& operator >>=(int rhs) ETL_NOEXCEPT + template + ETL_CONSTEXPR14 typename etl::enable_if::value, type_def&>::type + operator >>=(T rhs) ETL_NOEXCEPT { value >>= rhs; return *this; @@ -589,19 +593,40 @@ namespace etl //********************************************************************* // << operator //********************************************************************* - friend ETL_CONSTEXPR type_def operator <<(const type_def& lhs, int rhs) ETL_NOEXCEPT + template + friend ETL_CONSTEXPR typename etl::enable_if::value, type_def>::type + operator <<(const type_def& lhs, T rhs) ETL_NOEXCEPT { return type_def(lhs.value << rhs); } + //********************************************************************* + template + friend ETL_CONSTEXPR typename etl::enable_if<(etl::is_integral::value && etl::is_integral::value), T>::type + operator <<(T lhs, const type_def& rhs) ETL_NOEXCEPT + { + return lhs << rhs.value; + } + //********************************************************************* // >> operator //********************************************************************* - friend ETL_CONSTEXPR type_def operator >>(const type_def& lhs, int rhs) ETL_NOEXCEPT + template + friend ETL_CONSTEXPR typename etl::enable_if::value, type_def>::type + operator >>(const type_def& lhs, T rhs) ETL_NOEXCEPT { return type_def(lhs.value >> rhs); } + //********************************************************************* + template + friend ETL_CONSTEXPR + typename etl::enable_if<(etl::is_integral::value && etl::is_integral::value), T>::type + operator >>(T lhs, const type_def& rhs) ETL_NOEXCEPT + { + return lhs >> rhs.value; + } + //********************************************************************* // < operator //********************************************************************* diff --git a/test/test_type_def.cpp b/test/test_type_def.cpp index 30d27772..facb2ed8 100644 --- a/test/test_type_def.cpp +++ b/test/test_type_def.cpp @@ -179,7 +179,9 @@ namespace CHECK_EQUAL(i |= 0x003DU, uint32_t(t |= type_t(0x003DU))); CHECK_EQUAL(i ^= 0xAA55U, uint32_t(t ^= 0xAA55U)); CHECK_EQUAL(i ^= 0xAA55U, uint32_t(t ^= type_t(0xAA55U))); + CHECK_EQUAL(i <<= 2, uint32_t(t <<= 2)); CHECK_EQUAL(i <<= 2U, uint32_t(t <<= 2U)); + CHECK_EQUAL(i >>= 2, uint32_t(t >>= 2)); CHECK_EQUAL(i >>= 2U, uint32_t(t >>= 2U)); CHECK_EQUAL(i %= 23, uint32_t(t %= 23)); @@ -195,8 +197,10 @@ namespace uint32_t i1 = 0x5A3DUL; uint32_t i2 = 0xB47AUL; + uint32_t i3 = 3UL; type_t t1(0x5A3DUL); type_t t2(0xB47AUL); + type_t t3(3UL); CHECK_EQUAL(i1 + Two, t1 + Two); CHECK_EQUAL(Two + i1, Two + t1); @@ -205,11 +209,11 @@ namespace CHECK_EQUAL(i1 - Two, t1 - Two); CHECK_EQUAL(i2 - i1, i2 - t1); CHECK_EQUAL(i2 - i1, t2 - t1); - + CHECK_EQUAL(i1 * Two, t1 * Two); CHECK_EQUAL(Two * i1, Two * t1); CHECK_EQUAL(i1 * i2, t1 * t2); - + CHECK_EQUAL(i1 / Two, t1 / Two); CHECK_EQUAL(i2 / i1, i2 / t1); CHECK_EQUAL(i2 / i1, t2 / t1); @@ -227,7 +231,16 @@ namespace CHECK_EQUAL(uint32_t(0xAA55) ^ i1, type_t(0xAA55UL) ^ t1); CHECK_EQUAL(i1 << 2, t1 << 2); + CHECK_EQUAL(i1 << 2U, t1 << 2U); + CHECK_EQUAL(2 << i3, 2 << t3); + CHECK_EQUAL(2U << i3, 2U << t3); + CHECK_EQUAL(i1 << i3, t1 << t3); + CHECK_EQUAL(i1 >> 2, t1 >> 2); + CHECK_EQUAL(i1 >> 2U, t1 >> 2U); + CHECK_EQUAL(42 >> i3, 42 >> t3); + CHECK_EQUAL(42U >> i3, 42U >> t3); + CHECK_EQUAL(i1 >> i3, t1 >> t3); CHECK_EQUAL(i1 % uint32_t(23), t1 % uint32_t(23)); CHECK_EQUAL(uint32_t(23) % i1, uint32_t(23) % t1); @@ -313,7 +326,7 @@ namespace return value; } - + TEST(test_arithmetic_constexpr) { constexpr arithmetic_type_t value_plus = CreatePlus(); From bc027139e27f1d891e0242f3578405e6955a86e0 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 11 Sep 2025 18:21:10 +0100 Subject: [PATCH 07/18] Delete project navis files --- test/vs2022/delegate.natvis | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 test/vs2022/delegate.natvis diff --git a/test/vs2022/delegate.natvis b/test/vs2022/delegate.natvis new file mode 100644 index 00000000..30055445 --- /dev/null +++ b/test/vs2022/delegate.natvis @@ -0,0 +1,19 @@ + + + + + [etl::delegate invalid] + [etl::delegate -> free/static] + [etl::delegate -> bound instance] + [etl::delegate] + + invocation.stub != 0 + "uninitialised" + "free/static" + "object / functor" + (void*)invocation.object + 0x0 + invocation.stub + + + \ No newline at end of file From 59ec7855c1319020c22ecc1e3dd45f73e8e29a88 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 11 Sep 2025 18:21:54 +0100 Subject: [PATCH 08/18] Add force CI check on piull requests --- .github/workflows/clang-c++11.yml | 1 + .github/workflows/clang-c++14.yml | 1 + .github/workflows/clang-c++17.yml | 1 + .github/workflows/clang-c++20.yml | 1 + .github/workflows/clang-syntax-checks.yml | 1 + .github/workflows/gcc-c++11.yml | 1 + .github/workflows/gcc-c++14.yml | 1 + .github/workflows/gcc-c++17.yml | 1 + .github/workflows/gcc-c++20.yml | 1 + .github/workflows/gcc-syntax-checks.yml | 1 + .github/workflows/msvc.yml | 1 + 11 files changed, 11 insertions(+) diff --git a/.github/workflows/clang-c++11.yml b/.github/workflows/clang-c++11.yml index 2e243e80..610b4529 100644 --- a/.github/workflows/clang-c++11.yml +++ b/.github/workflows/clang-c++11.yml @@ -4,6 +4,7 @@ on: branches: [ master, development, pull-request/* ] pull_request: branches: [ master, pull-request/* ] + types: [opened, synchronize, reopened] jobs: diff --git a/.github/workflows/clang-c++14.yml b/.github/workflows/clang-c++14.yml index 7d2338d3..233eabff 100644 --- a/.github/workflows/clang-c++14.yml +++ b/.github/workflows/clang-c++14.yml @@ -4,6 +4,7 @@ on: branches: [ master, development, pull-request/* ] pull_request: branches: [ master, pull-request/* ] + types: [opened, synchronize, reopened] jobs: diff --git a/.github/workflows/clang-c++17.yml b/.github/workflows/clang-c++17.yml index 62afaf42..2c659fc6 100644 --- a/.github/workflows/clang-c++17.yml +++ b/.github/workflows/clang-c++17.yml @@ -4,6 +4,7 @@ on: branches: [ master, development, pull-request/* ] pull_request: branches: [ master, pull-request/* ] + types: [opened, synchronize, reopened] jobs: diff --git a/.github/workflows/clang-c++20.yml b/.github/workflows/clang-c++20.yml index e403e5c0..d1e640a6 100644 --- a/.github/workflows/clang-c++20.yml +++ b/.github/workflows/clang-c++20.yml @@ -4,6 +4,7 @@ on: branches: [ master, development, pull-request/* ] pull_request: branches: [ master, pull-request/* ] + types: [opened, synchronize, reopened] jobs: diff --git a/.github/workflows/clang-syntax-checks.yml b/.github/workflows/clang-syntax-checks.yml index c0c5f4e2..0b32ecb2 100644 --- a/.github/workflows/clang-syntax-checks.yml +++ b/.github/workflows/clang-syntax-checks.yml @@ -4,6 +4,7 @@ on: branches: [ master, development, pull-request/* ] pull_request: branches: [ master, pull-request/* ] + types: [opened, synchronize, reopened] jobs: build-clang-cpp03-linux-STL: diff --git a/.github/workflows/gcc-c++11.yml b/.github/workflows/gcc-c++11.yml index f4cea1b3..100d179c 100644 --- a/.github/workflows/gcc-c++11.yml +++ b/.github/workflows/gcc-c++11.yml @@ -4,6 +4,7 @@ on: branches: [ master, development, pull-request/* ] pull_request: branches: [ master, pull-request/* ] + types: [opened, synchronize, reopened] jobs: diff --git a/.github/workflows/gcc-c++14.yml b/.github/workflows/gcc-c++14.yml index a24f9312..881f4607 100644 --- a/.github/workflows/gcc-c++14.yml +++ b/.github/workflows/gcc-c++14.yml @@ -4,6 +4,7 @@ on: branches: [ master, development, pull-request/* ] pull_request: branches: [ master, pull-request/* ] + types: [opened, synchronize, reopened] jobs: diff --git a/.github/workflows/gcc-c++17.yml b/.github/workflows/gcc-c++17.yml index f16538ff..931c9a6d 100644 --- a/.github/workflows/gcc-c++17.yml +++ b/.github/workflows/gcc-c++17.yml @@ -4,6 +4,7 @@ on: branches: [ master, development, pull-request/* ] pull_request: branches: [ master, pull-request/* ] + types: [opened, synchronize, reopened] jobs: diff --git a/.github/workflows/gcc-c++20.yml b/.github/workflows/gcc-c++20.yml index 35de10cf..9240046a 100644 --- a/.github/workflows/gcc-c++20.yml +++ b/.github/workflows/gcc-c++20.yml @@ -4,6 +4,7 @@ on: branches: [ master, development, pull-request/* ] pull_request: branches: [ master, pull-request/* ] + types: [opened, synchronize, reopened] jobs: diff --git a/.github/workflows/gcc-syntax-checks.yml b/.github/workflows/gcc-syntax-checks.yml index 106d6d3b..6db13f7b 100644 --- a/.github/workflows/gcc-syntax-checks.yml +++ b/.github/workflows/gcc-syntax-checks.yml @@ -4,6 +4,7 @@ on: branches: [ master, development, pull-request/* ] pull_request: branches: [ master, pull-request/* ] + types: [opened, synchronize, reopened] jobs: build-gcc-cpp03-linux-STL: diff --git a/.github/workflows/msvc.yml b/.github/workflows/msvc.yml index f910048a..466e8171 100644 --- a/.github/workflows/msvc.yml +++ b/.github/workflows/msvc.yml @@ -4,6 +4,7 @@ on: branches: [ master, development, pull-request/* ] pull_request: branches: [ master, pull-request/* ] + types: [opened, synchronize, reopened] jobs: build-windows-msvc-stl: From 5dfdea711589ffac88bfd2e512f083da7cfb6870 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 10 Sep 2025 14:34:06 +0100 Subject: [PATCH 09/18] Removed #define ETL_DEBUG as this is a project define --- test/etl_profile.h | 1 - 1 file changed, 1 deletion(-) diff --git a/test/etl_profile.h b/test/etl_profile.h index b396bfde..d98f6141 100644 --- a/test/etl_profile.h +++ b/test/etl_profile.h @@ -31,7 +31,6 @@ SOFTWARE. #ifndef ETL_PROFILE_H_INCLUDED #define ETL_PROFILE_H_INCLUDED -#define ETL_DEBUG #define ETL_THROW_EXCEPTIONS #define ETL_DEBUG_THROW_EXCEPTIONS #define ETL_VERBOSE_ERRORS From 95ff22821c291ae9570359881a451efacc651a93 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 10 Sep 2025 14:34:57 +0100 Subject: [PATCH 10/18] Added more ETL_NOEXCEPT to etl::array --- include/etl/array.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/etl/array.h b/include/etl/array.h index e0854854..fbf5063a 100644 --- a/include/etl/array.h +++ b/include/etl/array.h @@ -116,7 +116,7 @@ namespace etl //************************************************************************* ETL_NODISCARD ETL_CONSTEXPR14 - reference at(size_t i) + reference at(size_t i) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) { ETL_ASSERT(i < SIZE, ETL_ERROR(array_out_of_range)); @@ -129,7 +129,7 @@ namespace etl //************************************************************************* ETL_NODISCARD ETL_CONSTEXPR14 - const_reference at(size_t i) const + const_reference at(size_t i) const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) { ETL_ASSERT(i < SIZE, ETL_ERROR(array_out_of_range)); @@ -143,7 +143,7 @@ namespace etl //************************************************************************* ETL_NODISCARD ETL_CONSTEXPR14 - reference operator[](size_t i) + reference operator[](size_t i) ETL_NOEXCEPT_EXPR(ETL_DEBUG_NOT_USING_EXCEPTIONS) { ETL_DEBUG_ASSERT(i < SIZE, ETL_ERROR(array_out_of_range)); @@ -156,7 +156,7 @@ namespace etl ///\param i The index of the element to access. //************************************************************************* ETL_NODISCARD - ETL_CONSTEXPR const_reference operator[](size_t i) const + ETL_CONSTEXPR const_reference operator[](size_t i) const ETL_NOEXCEPT_EXPR(ETL_DEBUG_NOT_USING_EXCEPTIONS) { //throwing from c++11 constexpr requires a special macro #if ETL_USING_CPP11 && !ETL_USING_CPP14 && ETL_DEBUG_USING_EXCEPTIONS @@ -173,7 +173,7 @@ namespace etl //************************************************************************* ETL_NODISCARD ETL_CONSTEXPR14 - reference front() + reference front() ETL_NOEXCEPT { ETL_STATIC_ASSERT(SIZE > 0, "Array is empty."); @@ -184,7 +184,7 @@ namespace etl /// Returns a const reference to the first element. //************************************************************************* ETL_NODISCARD - ETL_CONSTEXPR const_reference front() const + ETL_CONSTEXPR const_reference front() const ETL_NOEXCEPT { ETL_STATIC_ASSERT(SIZE > 0, "Array is empty."); @@ -196,7 +196,7 @@ namespace etl //************************************************************************* ETL_NODISCARD ETL_CONSTEXPR14 - reference back() + reference back() ETL_NOEXCEPT { ETL_STATIC_ASSERT(SIZE > 0, "Array is empty."); @@ -207,7 +207,7 @@ namespace etl /// Returns a const reference to the last element. //************************************************************************* ETL_NODISCARD - ETL_CONSTEXPR const_reference back() const + ETL_CONSTEXPR const_reference back() const ETL_NOEXCEPT { ETL_STATIC_ASSERT(SIZE > 0, "Array is empty."); From 88e2aaeec0e3f88acaf074ac862fd40c0f5922e3 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 12 Sep 2025 20:19:27 +0100 Subject: [PATCH 11/18] Removed ETL_NOEXCEPT from delegate operator(), call_if(), and call_or() Removed ETL_NOEXCEPT from closureoperator(), call_if(), and call_or() --- include/etl/private/delegate_cpp11.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/etl/private/delegate_cpp11.h b/include/etl/private/delegate_cpp11.h index a922a3e3..7c9382d2 100644 --- a/include/etl/private/delegate_cpp11.h +++ b/include/etl/private/delegate_cpp11.h @@ -372,7 +372,7 @@ namespace etl //************************************************************************* /// Execute the delegate. //************************************************************************* - ETL_CONSTEXPR14 TReturn operator()(TParams... args) const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + ETL_CONSTEXPR14 TReturn operator()(TParams... args) const { ETL_ASSERT(is_valid(), ETL_ERROR(delegate_uninitialised)); @@ -386,7 +386,7 @@ namespace etl template ETL_CONSTEXPR14 typename etl::enable_if_t::value, bool> - call_if(TParams... args) const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + call_if(TParams... args) const { if (is_valid()) { @@ -406,7 +406,7 @@ namespace etl template ETL_CONSTEXPR14 typename etl::enable_if_t::value, etl::optional> - call_if(TParams... args) const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + call_if(TParams... args) const { etl::optional result; @@ -423,7 +423,7 @@ namespace etl /// Run time alternative. //************************************************************************* template - ETL_CONSTEXPR14 TReturn call_or(TAlternative alternative, TParams... args) const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + ETL_CONSTEXPR14 TReturn call_or(TAlternative alternative, TParams... args) const { if (is_valid()) { @@ -440,7 +440,7 @@ namespace etl /// Compile time alternative. //************************************************************************* template - ETL_CONSTEXPR14 TReturn call_or(TParams... args) const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + ETL_CONSTEXPR14 TReturn call_or(TParams... args) const { if (is_valid()) { From 8ed8a47c555a5a41ea8e4febdc13806c75c410f3 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 12 Sep 2025 20:20:19 +0100 Subject: [PATCH 12/18] Updated version and release notes --- arduino/library-arduino.json | 2 +- arduino/library-arduino.properties | 2 +- include/etl/closure.h | 12 ++++++------ include/etl/version.h | 2 +- library.json | 2 +- library.properties | 2 +- version.txt | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/arduino/library-arduino.json b/arduino/library-arduino.json index 917ae676..bfe01943 100644 --- a/arduino/library-arduino.json +++ b/arduino/library-arduino.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library ETL", - "version": "20.43.2", + "version": "20.43.3", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/arduino/library-arduino.properties b/arduino/library-arduino.properties index cee37df3..5204c0fc 100644 --- a/arduino/library-arduino.properties +++ b/arduino/library-arduino.properties @@ -1,5 +1,5 @@ name=Embedded Template Library ETL -version=20.43.2 +version=20.43.3 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/include/etl/closure.h b/include/etl/closure.h index bc4c137a..a1e885b0 100644 --- a/include/etl/closure.h +++ b/include/etl/closure.h @@ -71,7 +71,7 @@ namespace etl /// \param f The delegate to be invoked. /// \param args The arguments to bind to the delegate. //********************************************************************* - ETL_CONSTEXPR14 closure(const delegate_type& f, const TArgs... args) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + ETL_CONSTEXPR14 closure(const delegate_type& f, const TArgs... args) : m_f(f) , m_args(args...) { @@ -81,7 +81,7 @@ namespace etl /// Invoke the stored delegate with the bound arguments. /// \return The result of the delegate invocation. //********************************************************************* - ETL_CONSTEXPR14 TReturn operator()() const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + ETL_CONSTEXPR14 TReturn operator()() const { return execute(etl::index_sequence_for{}); } @@ -94,7 +94,7 @@ namespace etl /// \param arg The new value to bind. //********************************************************************* template - ETL_CONSTEXPR14 void bind(UArg arg) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + ETL_CONSTEXPR14 void bind(UArg arg) { static_assert(etl::is_convertible>::value, "Argument is not convertible"); static_assert(!etl::is_reference::value, "Cannot bind reference arguments"); @@ -108,7 +108,7 @@ namespace etl /// \param args The new values to bind. ///********************************************************************* template - ETL_CONSTEXPR14 void bind(UArgs&&... args) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + ETL_CONSTEXPR14 void bind(UArgs&&... args) { static_assert(sizeof...(UArgs) == sizeof...(TArgs), "Argument count mismatch"); bind_impl(etl::make_index_sequence{}, etl::forward(args)...); @@ -121,7 +121,7 @@ namespace etl /// \param args The new values to bind. ///********************************************************************* template - ETL_CONSTEXPR14 void bind_impl(etl::index_sequence, UArgs&&... args) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + ETL_CONSTEXPR14 void bind_impl(etl::index_sequence, UArgs&&... args) { // Expand the pack and call bind(arg) for each argument int dummy[] = {0, (bind(etl::forward(args)), 0)...}; @@ -134,7 +134,7 @@ namespace etl /// \return The result of the delegate invocation. //********************************************************************* template - ETL_CONSTEXPR14 TReturn execute(etl::index_sequence) const ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + ETL_CONSTEXPR14 TReturn execute(etl::index_sequence) const { return m_f(etl::get(m_args)...); } diff --git a/include/etl/version.h b/include/etl/version.h index cabd4d69..90c97396 100644 --- a/include/etl/version.h +++ b/include/etl/version.h @@ -40,7 +40,7 @@ SOFTWARE. #define ETL_VERSION_MAJOR 20 #define ETL_VERSION_MINOR 43 -#define ETL_VERSION_PATCH 2 +#define ETL_VERSION_PATCH 3 #define ETL_VERSION ETL_STRING(ETL_VERSION_MAJOR) "." ETL_STRING(ETL_VERSION_MINOR) "." ETL_STRING(ETL_VERSION_PATCH) #define ETL_VERSION_W ETL_WIDE_STRING(ETL_VERSION_MAJOR) L"." ETL_WIDE_STRING(ETL_VERSION_MINOR) L"." ETL_WIDE_STRING(ETL_VERSION_PATCH) diff --git a/library.json b/library.json index 57cf258f..3f83f304 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library", - "version": "20.43.2", + "version": "20.43.3", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/library.properties b/library.properties index 4079e46f..1428e78e 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Embedded Template Library -version=20.43.2 +version=20.43.3 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/version.txt b/version.txt index f9ffdf0b..4ba170c4 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -20.43.2 +20.43.3 From f5bdca7216cac54ee8d06cd04e90c259c0a5ed83 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 12 Sep 2025 20:38:41 +0100 Subject: [PATCH 13/18] Updated version and release notes --- support/Release notes.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/support/Release notes.txt b/support/Release notes.txt index 77d9728d..0559b6d3 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,4 +1,10 @@ =============================================================================== +20.43.3 + +Removed ETL_NOEXCEPT from delegate operator(), call_if(), and call_or() +Removed ETL_NOEXCEPT from closure + +=============================================================================== 20.43.2 Pull Requests: From 9f7e4abd420823e045be3b3a0018d46b4b6624bf Mon Sep 17 00:00:00 2001 From: Marco Nilsson Date: Sat, 13 Sep 2025 09:23:15 +0200 Subject: [PATCH 14/18] Remove noexcept from delegate method stubs. (#1185) In addition to removing noexcept from call_if, this is also needed to prevent an abort when cancelling a pthread that is executing a delegate. --- include/etl/private/delegate_cpp11.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/etl/private/delegate_cpp11.h b/include/etl/private/delegate_cpp11.h index 7c9382d2..79182656 100644 --- a/include/etl/private/delegate_cpp11.h +++ b/include/etl/private/delegate_cpp11.h @@ -583,7 +583,7 @@ namespace etl /// Stub call for a member function. Run time instance. //************************************************************************* template - static ETL_CONSTEXPR14 TReturn method_stub(void* object, TParams... params) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + static ETL_CONSTEXPR14 TReturn method_stub(void* object, TParams... params) { T* p = static_cast(object); return (p->*Method)(etl::forward(params)...); @@ -593,7 +593,7 @@ namespace etl /// Stub call for a const member function. Run time instance. //************************************************************************* template - static ETL_CONSTEXPR14 TReturn const_method_stub(void* object, TParams... params) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + static ETL_CONSTEXPR14 TReturn const_method_stub(void* object, TParams... params) { T* const p = static_cast(object); return (p->*Method)(etl::forward(params)...); @@ -603,7 +603,7 @@ namespace etl /// Stub call for a member function. Compile time instance. //************************************************************************* template - static ETL_CONSTEXPR14 TReturn method_instance_stub(void*, TParams... params) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + static ETL_CONSTEXPR14 TReturn method_instance_stub(void*, TParams... params) { return (Instance.*Method)(etl::forward(params)...); } @@ -612,7 +612,7 @@ namespace etl /// Stub call for a const member function. Compile time instance. //************************************************************************* template - static ETL_CONSTEXPR14 TReturn const_method_instance_stub(void*, TParams... params) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + static ETL_CONSTEXPR14 TReturn const_method_instance_stub(void*, TParams... params) { return (Instance.*Method)(etl::forward(params)...); } @@ -622,7 +622,7 @@ namespace etl /// Stub call for a function operator. Compile time instance. //************************************************************************* template - static ETL_CONSTEXPR14 TReturn operator_instance_stub(void*, TParams... params) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + static ETL_CONSTEXPR14 TReturn operator_instance_stub(void*, TParams... params) { return Instance.operator()(etl::forward(params)...); } @@ -632,7 +632,7 @@ namespace etl /// Stub call for a free function. //************************************************************************* template - static ETL_CONSTEXPR14 TReturn function_stub(void*, TParams... params) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + static ETL_CONSTEXPR14 TReturn function_stub(void*, TParams... params) { return (Method)(etl::forward(params)...); } @@ -641,7 +641,7 @@ namespace etl /// Stub call for a lambda or functor function. //************************************************************************* template - static ETL_CONSTEXPR14 TReturn lambda_stub(void* object, TParams... arg) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + static ETL_CONSTEXPR14 TReturn lambda_stub(void* object, TParams... arg) { TLambda* p = static_cast(object); return (p->operator())(etl::forward(arg)...); @@ -651,7 +651,7 @@ namespace etl /// Stub call for a const lambda or functor function. //************************************************************************* template - static ETL_CONSTEXPR14 TReturn const_lambda_stub(void* object, TParams... arg) ETL_NOEXCEPT_EXPR(ETL_NOT_USING_EXCEPTIONS) + static ETL_CONSTEXPR14 TReturn const_lambda_stub(void* object, TParams... arg) { const TLambda* p = static_cast(object); return (p->operator())(etl::forward(arg)...); From cabfa28401c82750ae13a2aa7f2277c552a9a928 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 13 Sep 2025 08:28:22 +0100 Subject: [PATCH 15/18] Updated version and release notes --- arduino/library-arduino.json | 2 +- arduino/library-arduino.properties | 2 +- include/etl/version.h | 2 +- library.json | 2 +- library.properties | 2 +- support/Release notes.txt | 5 +++++ version.txt | 2 +- 7 files changed, 11 insertions(+), 6 deletions(-) diff --git a/arduino/library-arduino.json b/arduino/library-arduino.json index bfe01943..039673b5 100644 --- a/arduino/library-arduino.json +++ b/arduino/library-arduino.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library ETL", - "version": "20.43.3", + "version": "20.43.4", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/arduino/library-arduino.properties b/arduino/library-arduino.properties index 5204c0fc..64150f49 100644 --- a/arduino/library-arduino.properties +++ b/arduino/library-arduino.properties @@ -1,5 +1,5 @@ name=Embedded Template Library ETL -version=20.43.3 +version=20.43.4 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/include/etl/version.h b/include/etl/version.h index 90c97396..145240ce 100644 --- a/include/etl/version.h +++ b/include/etl/version.h @@ -40,7 +40,7 @@ SOFTWARE. #define ETL_VERSION_MAJOR 20 #define ETL_VERSION_MINOR 43 -#define ETL_VERSION_PATCH 3 +#define ETL_VERSION_PATCH 4 #define ETL_VERSION ETL_STRING(ETL_VERSION_MAJOR) "." ETL_STRING(ETL_VERSION_MINOR) "." ETL_STRING(ETL_VERSION_PATCH) #define ETL_VERSION_W ETL_WIDE_STRING(ETL_VERSION_MAJOR) L"." ETL_WIDE_STRING(ETL_VERSION_MINOR) L"." ETL_WIDE_STRING(ETL_VERSION_PATCH) diff --git a/library.json b/library.json index 3f83f304..3a6d76e7 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library", - "version": "20.43.3", + "version": "20.43.4", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/library.properties b/library.properties index 1428e78e..f0e30104 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Embedded Template Library -version=20.43.3 +version=20.43.4 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/support/Release notes.txt b/support/Release notes.txt index 0559b6d3..9e3ac3b4 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,4 +1,9 @@ =============================================================================== +20.43.4 + +#1185 Remove noexcept from delegate method stubs. + +=============================================================================== 20.43.3 Removed ETL_NOEXCEPT from delegate operator(), call_if(), and call_or() diff --git a/version.txt b/version.txt index 4ba170c4..cfc1db88 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -20.43.3 +20.43.4 From 191d4fb0f040a79728ba35bebafde8579513bc2c Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Wed, 17 Sep 2025 21:16:57 +0200 Subject: [PATCH 16/18] Guards around usage of std::initializer_list in optional.h (#1186) * Guards around usage of std::initializer_list in optional.h In optional.h, ETL_HAS_INITIALIZER_LIST is being used to guard against cases where std::initializer_list is not available. But not consistently. This changes fixes it by adding it in the remaining places. * Fixed #undef in optional.h Instead of undefining ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14, ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL was undefined twice (one of the misspelled). * Fix comment typos --- include/etl/gcd.h | 2 +- include/etl/lcm.h | 2 +- include/etl/optional.h | 6 +++++- include/etl/private/chrono/duration.h | 2 +- include/etl/ratio.h | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/include/etl/gcd.h b/include/etl/gcd.h index 8a954e0d..0926b2f0 100644 --- a/include/etl/gcd.h +++ b/include/etl/gcd.h @@ -21,7 +21,7 @@ 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 Value1 PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +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 diff --git a/include/etl/lcm.h b/include/etl/lcm.h index ef3008f6..3ffc9821 100644 --- a/include/etl/lcm.h +++ b/include/etl/lcm.h @@ -21,7 +21,7 @@ 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 Value1 PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +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 diff --git a/include/etl/optional.h b/include/etl/optional.h index e8e40439..12d90239 100644 --- a/include/etl/optional.h +++ b/include/etl/optional.h @@ -195,6 +195,7 @@ namespace etl storage.construct(etl::forward(args)...); } +#if ETL_HAS_INITIALIZER_LIST //******************************************* /// Construct from initializer_list and arguments. //******************************************* @@ -205,6 +206,7 @@ namespace etl { storage.construct(ilist, etl::forward(args)...); } +#endif #endif //*************************************************************************** @@ -816,6 +818,7 @@ namespace etl storage.construct(etl::forward(args)...); } +#if ETL_HAS_INITIALIZER_LIST //******************************************* /// Construct from initializer_list and arguments. //******************************************* @@ -826,6 +829,7 @@ namespace etl { storage.construct(ilist, etl::forward(args)...); } +#endif #endif //*************************************************************************** @@ -2313,7 +2317,7 @@ ETL_CONSTEXPR20_STL void swap(etl::optional& lhs, etl::optional& rhs) #undef ETL_OPTIONAL_ENABLE_CPP14 #undef ETL_OPTIONAL_ENABLE_CPP20_STL +#undef ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP14 #undef ETL_OPTIONAL_ENABLE_CONSTEXPR_BOOL_RETURN_CPP20_STL -#undef ETL_OPTIONAL_ENABLE_COMSTEXPR_BOOL_RETURN_CPP20_STL #endif diff --git a/include/etl/private/chrono/duration.h b/include/etl/private/chrono/duration.h index a629c01c..cd81e9d9 100644 --- a/include/etl/private/chrono/duration.h +++ b/include/etl/private/chrono/duration.h @@ -21,7 +21,7 @@ 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 Value1 PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +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 diff --git a/include/etl/ratio.h b/include/etl/ratio.h index 2f2b5075..7e671589 100644 --- a/include/etl/ratio.h +++ b/include/etl/ratio.h @@ -21,7 +21,7 @@ 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 Value1 PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +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 From e88a74362bf2eb206b6741c857b72804e2b57f98 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 22 Sep 2025 10:41:50 +0100 Subject: [PATCH 17/18] Modified to use new ETL_ASSERTs --- .gitignore | 1 + include/etl/deque.h | 78 ++++++++---------------- include/etl/error_handler.h | 27 ++++++--- include/etl/forward_list.h | 43 +++++-------- include/etl/indirect_vector.h | 10 ++- include/etl/intrusive_forward_list.h | 5 +- include/etl/intrusive_list.h | 10 ++- include/etl/intrusive_queue.h | 4 +- include/etl/intrusive_stack.h | 5 +- include/etl/list.h | 91 +++++++++++----------------- include/etl/private/pvoidvector.h | 15 ++--- include/etl/queue.h | 45 ++++++-------- include/etl/stack.h | 45 ++++++-------- include/etl/vector.h | 46 ++++++-------- 14 files changed, 172 insertions(+), 253 deletions(-) diff --git a/.gitignore b/.gitignore index 679552e6..068e7602 100644 --- a/.gitignore +++ b/.gitignore @@ -410,3 +410,4 @@ examples/UniquePtrWithPool/CMakeCache.txt examples/UniquePtrWithPool/UniquePtrWithPool test/vs2022/Debug Clang C++20 - Optimised -O2 include/etl/header_file_list.txt +temp diff --git a/include/etl/deque.h b/include/etl/deque.h index f70ba26e..44043cdc 100644 --- a/include/etl/deque.h +++ b/include/etl/deque.h @@ -1757,9 +1757,8 @@ namespace etl //************************************************************************* void push_back(const_reference item) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(deque_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(deque_full)); + create_element_back(item); } @@ -1771,9 +1770,8 @@ namespace etl //************************************************************************* void push_back(rvalue_reference item) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(deque_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(deque_full)); + create_element_back(etl::move(item)); } #endif @@ -1786,9 +1784,7 @@ namespace etl template reference emplace_back(Args && ... args) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(deque_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(deque_full)); ::new (&(*_end)) T(etl::forward(args)...); ++_end; @@ -1805,9 +1801,7 @@ namespace etl //************************************************************************* reference emplace_back() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(deque_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(deque_full)); ::new (&(*_end)) T(); ++_end; @@ -1823,9 +1817,7 @@ namespace etl template reference emplace_back(const T1& value1) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(deque_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(deque_full)); ::new (&(*_end)) T(value1); ++_end; @@ -1841,9 +1833,7 @@ namespace etl template reference emplace_back(const T1& value1, const T2& value2) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(deque_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(deque_full)); ::new (&(*_end)) T(value1, value2); ++_end; @@ -1859,9 +1849,7 @@ namespace etl template reference emplace_back(const T1& value1, const T2& value2, const T3& value3) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(deque_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(deque_full)); ::new (&(*_end)) T(value1, value2, value3); ++_end; @@ -1877,9 +1865,7 @@ namespace etl template reference emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(deque_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(deque_full)); ::new (&(*_end)) T(value1, value2, value3, value4); ++_end; @@ -1894,9 +1880,8 @@ namespace etl //************************************************************************* void pop_back() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!empty(), ETL_ERROR(deque_empty)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(deque_empty)); + destroy_element_back(); } @@ -1907,9 +1892,8 @@ namespace etl //************************************************************************* void push_front(const_reference item) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(deque_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(deque_full)); + create_element_front(item); } @@ -1921,9 +1905,8 @@ namespace etl //************************************************************************* void push_front(rvalue_reference item) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(deque_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(deque_full)); + create_element_front(etl::move(item)); } #endif @@ -1936,9 +1919,7 @@ namespace etl template reference emplace_front(Args && ... args) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(deque_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(deque_full)); --_begin; ::new (&(*_begin)) T(etl::forward(args)...); @@ -1955,9 +1936,7 @@ namespace etl //************************************************************************* reference emplace_front() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(deque_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(deque_full)); --_begin; ::new (&(*_begin)) T(); @@ -1973,9 +1952,7 @@ namespace etl template reference emplace_front(const T1& value1) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(deque_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(deque_full)); --_begin; ::new (&(*_begin)) T(value1); @@ -1991,9 +1968,7 @@ namespace etl template reference emplace_front(const T1& value1, const T2& value2) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(deque_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(deque_full)); --_begin; ::new (&(*_begin)) T(value1, value2); @@ -2009,9 +1984,7 @@ namespace etl template reference emplace_front(const T1& value1, const T2& value2, const T3& value3) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(deque_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(deque_full)); --_begin; ::new (&(*_begin)) T(value1, value2, value3); @@ -2027,9 +2000,7 @@ namespace etl template reference emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(deque_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(deque_full)); --_begin; ::new (&(*_begin)) T(value1, value2, value3, value4); @@ -2044,9 +2015,8 @@ namespace etl //************************************************************************* void pop_front() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!empty(), ETL_ERROR(deque_empty)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(deque_empty)); + destroy_element_front(); } diff --git a/include/etl/error_handler.h b/include/etl/error_handler.h index 75e71381..a6586250 100644 --- a/include/etl/error_handler.h +++ b/include/etl/error_handler.h @@ -420,18 +420,31 @@ namespace etl #define ETL_DEBUG_ASSERT_FAIL_AND_RETURN_VALUE(e, v) {return(v);} // Returns a value. #endif +//************************************* +#if defined(ETL_CHECK_PUSH_POP) + #define ETL_ASSERT_CHECK_PUSH_POP(b, e) ETL_ASSERT(b, e) + #define ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(b, e) ETL_ASSERT_OR_RETURN(b, e) +#else + #define ETL_ASSERT_CHECK_PUSH_POP(b, e) + #define ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(b, e) +#endif + +//************************************* +#ifdef ETL_CHECK_INDEX_OPERATOR + #define ETL_ASSERT_CHECK_INDEX_OPERATOR(b, e) ETL_ASSERT(b,e) +#else + #define ETL_ASSERT_CHECK_INDEX_OPERATOR(b, e) +#endif + +//************************************* #if defined(ETL_VERBOSE_ERRORS) #define ETL_ERROR(e) (e(__FILE__, __LINE__)) // Make an exception with the file name and line number. #define ETL_ERROR_WITH_VALUE(e, v) (e(__FILE__, __LINE__, (v))) // Make an exception with the file name, line number and value. -#else - #define ETL_ERROR(e) (e("", __LINE__)) // Make an exception with the line number. - #define ETL_ERROR_WITH_VALUE(e, v) (e("", __LINE__, (v))) // Make an exception with the file name, line number and value. -#endif - -#if defined(ETL_VERBOSE_ERRORS) #define ETL_ERROR_TEXT(verbose_text, terse_text) (verbose_text) // Use the verbose text. #else - #define ETL_ERROR_TEXT(verbose_text, terse_text) (terse_text) // Use the terse text. + #define ETL_ERROR(e) (e("", __LINE__)) // Make an exception with the line number. + #define ETL_ERROR_WITH_VALUE(e, v) (e("", __LINE__, (v))) // Make an exception with the file name, line number and value. + #define ETL_ERROR_TEXT(verbose_text, terse_text) (terse_text) // Use the terse text. #endif #endif diff --git a/include/etl/forward_list.h b/include/etl/forward_list.h index 4af4bd4a..58ef66f3 100644 --- a/include/etl/forward_list.h +++ b/include/etl/forward_list.h @@ -694,9 +694,7 @@ namespace etl //************************************************************************* void push_front(const T& value) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(forward_list_full)); data_node_t& data_node = allocate_data_node(value); insert_node_after(start_node, data_node); @@ -708,9 +706,7 @@ namespace etl //************************************************************************* void push_front(rvalue_reference value) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(forward_list_full)); data_node_t& data_node = allocate_data_node(etl::move(value)); insert_node_after(start_node, data_node); @@ -724,9 +720,8 @@ namespace etl template reference emplace_front(Args && ... args) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full)); + data_node_t* p_data_node = allocate_data_node(); ::new (&(p_data_node->value)) T(etl::forward(args)...); ETL_INCREMENT_DEBUG_COUNT; @@ -739,9 +734,8 @@ namespace etl //************************************************************************* reference emplace_front() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full)); + data_node_t* p_data_node = allocate_data_node(); ::new (&(p_data_node->value)) T(); ETL_INCREMENT_DEBUG_COUNT; @@ -755,9 +749,8 @@ namespace etl template reference emplace_front(const T1& value1) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full)); + data_node_t* p_data_node = allocate_data_node(); ::new (&(p_data_node->value)) T(value1); ETL_INCREMENT_DEBUG_COUNT; @@ -771,9 +764,8 @@ namespace etl template reference emplace_front(const T1& value1, const T2& value2) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full)); + data_node_t* p_data_node = allocate_data_node(); ::new (&(p_data_node->value)) T(value1, value2); ETL_INCREMENT_DEBUG_COUNT; @@ -787,9 +779,8 @@ namespace etl template reference emplace_front(const T1& value1, const T2& value2, const T3& value3) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full)); + data_node_t* p_data_node = allocate_data_node(); ::new (&(p_data_node->value)) T(value1, value2, value3); ETL_INCREMENT_DEBUG_COUNT; @@ -803,9 +794,8 @@ namespace etl template reference emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(forward_list_full)); + data_node_t* p_data_node = allocate_data_node(); ::new (&(p_data_node->value)) T(value1, value2, value3, value4); ETL_INCREMENT_DEBUG_COUNT; @@ -819,9 +809,8 @@ namespace etl //************************************************************************* void pop_front() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!empty(), ETL_ERROR(forward_list_empty)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(forward_list_empty)); + remove_node_after(start_node); } diff --git a/include/etl/indirect_vector.h b/include/etl/indirect_vector.h index bac0502f..36d6c695 100644 --- a/include/etl/indirect_vector.h +++ b/include/etl/indirect_vector.h @@ -757,9 +757,8 @@ namespace etl //********************************************************************* void push_back(const_reference value) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(size() != capacity(), ETL_ERROR(vector_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(size() != capacity(), ETL_ERROR(vector_full)); + T* p = storage.create(value); lookup.push_back(p); } @@ -772,9 +771,8 @@ namespace etl //********************************************************************* void push_back(rvalue_reference value) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(size() != capacity(), ETL_ERROR(vector_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(size() != capacity(), ETL_ERROR(vector_full)); + T* p = storage.create(etl::move(value)); lookup.push_back(p); } diff --git a/include/etl/intrusive_forward_list.h b/include/etl/intrusive_forward_list.h index d68dd6ad..262c8052 100644 --- a/include/etl/intrusive_forward_list.h +++ b/include/etl/intrusive_forward_list.h @@ -206,9 +206,8 @@ namespace etl //************************************************************************* void pop_front() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT_OR_RETURN(!empty(), ETL_ERROR(intrusive_forward_list_empty)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(intrusive_forward_list_empty)); + disconnect_link_after(start); } diff --git a/include/etl/intrusive_list.h b/include/etl/intrusive_list.h index 970d0589..36f3966d 100644 --- a/include/etl/intrusive_list.h +++ b/include/etl/intrusive_list.h @@ -172,9 +172,8 @@ namespace etl //************************************************************************* void pop_front() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!empty(), ETL_ERROR(intrusive_list_empty)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(intrusive_list_empty)); + disconnect_link(get_head()); } @@ -193,9 +192,8 @@ namespace etl //************************************************************************* void pop_back() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!empty(), ETL_ERROR(intrusive_list_empty)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(intrusive_list_empty)); + disconnect_link(get_tail()); } diff --git a/include/etl/intrusive_queue.h b/include/etl/intrusive_queue.h index 6e7c1382..6b51598e 100644 --- a/include/etl/intrusive_queue.h +++ b/include/etl/intrusive_queue.h @@ -124,9 +124,7 @@ namespace etl //************************************************************************* void pop() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT_OR_RETURN(!empty(), ETL_ERROR(intrusive_queue_empty)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(intrusive_queue_empty)); link_type* p_front = terminator.etl_next; diff --git a/include/etl/intrusive_stack.h b/include/etl/intrusive_stack.h index fe0a123f..c93c27cb 100644 --- a/include/etl/intrusive_stack.h +++ b/include/etl/intrusive_stack.h @@ -115,9 +115,8 @@ namespace etl //************************************************************************* void pop() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT_OR_RETURN(!empty(), ETL_ERROR(intrusive_stack_empty)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(intrusive_stack_empty)); + link_type* p_next = p_top->etl_next; p_top->clear(); p_top = p_next; diff --git a/include/etl/list.h b/include/etl/list.h index 4a773bcc..ea070c0e 100644 --- a/include/etl/list.h +++ b/include/etl/list.h @@ -837,9 +837,8 @@ namespace etl //************************************************************************* void push_front(const T& value) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(list_full)); + insert_node(get_head(), allocate_data_node(value)); } @@ -849,9 +848,8 @@ namespace etl //************************************************************************* void push_front(rvalue_reference value) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(list_full)); + insert_node(get_head(), allocate_data_node(etl::move(value))); } #endif @@ -863,9 +861,9 @@ namespace etl template reference emplace_front(Args && ... args) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif + + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full)); + ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool)); data_node_t* p_data_node = allocate_data_node(); @@ -880,9 +878,8 @@ namespace etl //************************************************************************* reference emplace_front() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full)); + ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool)); data_node_t* p_data_node = allocate_data_node(); @@ -898,9 +895,8 @@ namespace etl template reference emplace_front(const T1& value1) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full)); + ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool)); data_node_t* p_data_node = allocate_data_node(); @@ -916,9 +912,8 @@ namespace etl template reference emplace_front(const T1& value1, const T2& value2) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full)); + ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool)); data_node_t* p_data_node = allocate_data_node(); @@ -934,9 +929,8 @@ namespace etl template reference emplace_front(const T1& value1, const T2& value2, const T3& value3) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full)); + ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool)); data_node_t* p_data_node = allocate_data_node(); @@ -952,9 +946,8 @@ namespace etl template reference emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full)); + ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool)); data_node_t* p_data_node = allocate_data_node(); @@ -970,9 +963,8 @@ namespace etl //************************************************************************* void pop_front() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!empty(), ETL_ERROR(list_empty)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(list_empty)); + node_t& node = get_head(); remove_node(node); } @@ -982,9 +974,8 @@ namespace etl //************************************************************************* void push_back(const T& value) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(list_full)); + insert_node(terminal_node, allocate_data_node(value)); } @@ -994,9 +985,8 @@ namespace etl //************************************************************************* void push_back(rvalue_reference value) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(list_full)); + insert_node(terminal_node, allocate_data_node(etl::move(value))); } #endif @@ -1008,9 +998,8 @@ namespace etl template reference emplace_back(Args && ... args) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full)); + ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool)); data_node_t* p_data_node = allocate_data_node(); @@ -1022,9 +1011,8 @@ namespace etl #else reference emplace_back() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full)); + ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool)); data_node_t* p_data_node = allocate_data_node(); @@ -1037,9 +1025,8 @@ namespace etl template reference emplace_back(const T1& value1) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full)); + ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool)); data_node_t* p_data_node = allocate_data_node(); @@ -1052,9 +1039,8 @@ namespace etl template reference emplace_back(const T1& value1, const T2& value2) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full)); + ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool)); data_node_t* p_data_node = allocate_data_node(); @@ -1067,9 +1053,8 @@ namespace etl template reference emplace_back(const T1& value1, const T2& value2, const T3& value3) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full)); + ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool)); data_node_t* p_data_node = allocate_data_node(); @@ -1082,9 +1067,8 @@ namespace etl template reference emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(list_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(list_full)); + ETL_ASSERT(p_node_pool != ETL_NULLPTR, ETL_ERROR(list_no_pool)); data_node_t* p_data_node = allocate_data_node(); @@ -1100,9 +1084,8 @@ namespace etl //************************************************************************* void pop_back() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!empty(), ETL_ERROR(list_empty)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(list_empty)); + node_t& node = get_tail(); remove_node(node); } diff --git a/include/etl/private/pvoidvector.h b/include/etl/private/pvoidvector.h index 728fceb0..9786d740 100644 --- a/include/etl/private/pvoidvector.h +++ b/include/etl/private/pvoidvector.h @@ -400,9 +400,8 @@ namespace etl //********************************************************************* void push_back(value_type value) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT_OR_RETURN(size() != CAPACITY, ETL_ERROR(vector_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(size() != CAPACITY, ETL_ERROR(vector_full)); + *p_end++ = value; } @@ -413,9 +412,8 @@ namespace etl //********************************************************************* void emplace_back(value_type value) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT_OR_RETURN(size() != CAPACITY, ETL_ERROR(vector_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(size() != CAPACITY, ETL_ERROR(vector_full)); + * p_end++ = value; } @@ -425,9 +423,8 @@ namespace etl //************************************************************************* void pop_back() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT_OR_RETURN(size() > 0, ETL_ERROR(vector_empty)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(size() > 0, ETL_ERROR(vector_empty)); + --p_end; } diff --git a/include/etl/queue.h b/include/etl/queue.h index 47e9d470..4c4fcd9f 100644 --- a/include/etl/queue.h +++ b/include/etl/queue.h @@ -308,9 +308,8 @@ namespace etl //************************************************************************* void push(const_reference value) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(queue_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(queue_full)); + ::new (&p_buffer[in]) T(value); add_in(); } @@ -323,9 +322,8 @@ namespace etl //************************************************************************* void push(rvalue_reference value) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(queue_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(queue_full)); + ::new (&p_buffer[in]) T(etl::move(value)); add_in(); } @@ -340,9 +338,8 @@ namespace etl template reference emplace(Args && ... args) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(queue_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(queue_full)); + reference value = p_buffer[in]; ::new (&value) T(etl::forward(args)...); add_in(); @@ -355,9 +352,8 @@ namespace etl //************************************************************************* reference emplace() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(queue_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(queue_full)); + reference value = p_buffer[in]; ::new (&value) T(); add_in(); @@ -372,9 +368,8 @@ namespace etl template reference emplace(const T1& value1) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(queue_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(queue_full)); + reference value = p_buffer[in]; ::new (&value) T(value1); add_in(); @@ -390,9 +385,8 @@ namespace etl template reference emplace(const T1& value1, const T2& value2) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(queue_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(queue_full)); + reference value = p_buffer[in]; ::new (&value) T(value1, value2); add_in(); @@ -409,9 +403,8 @@ namespace etl template reference emplace(const T1& value1, const T2& value2, const T3& value3) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(queue_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(queue_full)); + reference value = p_buffer[in]; ::new (&value) T(value1, value2, value3); add_in(); @@ -429,9 +422,8 @@ namespace etl template reference emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(queue_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(queue_full)); + reference value = p_buffer[in]; ::new (&value) T(value1, value2, value3, value4); add_in(); @@ -468,9 +460,8 @@ namespace etl //************************************************************************* void pop() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT_OR_RETURN(!empty(), ETL_ERROR(queue_empty)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(queue_empty)); + p_buffer[out].~T(); del_out(); } diff --git a/include/etl/stack.h b/include/etl/stack.h index 1c375906..2bcee404 100644 --- a/include/etl/stack.h +++ b/include/etl/stack.h @@ -253,9 +253,8 @@ namespace etl //************************************************************************* void push(const_reference value) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(stack_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(stack_full)); + base_t::add_in(); ::new (&p_buffer[top_index]) T(value); } @@ -268,9 +267,8 @@ namespace etl //************************************************************************* void push(rvalue_reference value) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(stack_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(stack_full)); + base_t::add_in(); ::new (&p_buffer[top_index]) T(etl::move(value)); } @@ -285,9 +283,8 @@ namespace etl template reference emplace(Args && ... args) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(stack_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full)); + base_t::add_in(); ::new (&p_buffer[top_index]) T(etl::forward(args)...); @@ -301,9 +298,8 @@ namespace etl //************************************************************************* reference emplace() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(stack_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full)); + base_t::add_in(); ::new (&p_buffer[top_index]) T(); @@ -318,9 +314,8 @@ namespace etl template reference emplace(const T1& value1) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(stack_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full)); + base_t::add_in(); ::new (&p_buffer[top_index]) T(value1); @@ -335,9 +330,8 @@ namespace etl template reference emplace(const T1& value1, const T2& value2) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(stack_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full)); + base_t::add_in(); ::new (&p_buffer[top_index]) T(value1, value2); @@ -352,9 +346,8 @@ namespace etl template reference emplace(const T1& value1, const T2& value2, const T3& value3) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(stack_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full)); + base_t::add_in(); ::new (&p_buffer[top_index]) T(value1, value2, value3); @@ -369,9 +362,8 @@ namespace etl template reference emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(!full(), ETL_ERROR(stack_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full)); + base_t::add_in(); ::new (&p_buffer[top_index]) T(value1, value2, value3, value4); @@ -412,9 +404,8 @@ namespace etl //************************************************************************* void pop() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT_OR_RETURN(!empty(), ETL_ERROR(stack_empty)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(stack_empty)); + p_buffer[top_index].~T(); base_t::del_out(); } diff --git a/include/etl/vector.h b/include/etl/vector.h index 575c008a..e85d58f2 100644 --- a/include/etl/vector.h +++ b/include/etl/vector.h @@ -433,9 +433,8 @@ namespace etl //********************************************************************* void push_back(const_reference value) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT_OR_RETURN(size() != CAPACITY, ETL_ERROR(vector_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(size() != CAPACITY, ETL_ERROR(vector_full)); + create_back(value); } @@ -447,9 +446,8 @@ namespace etl //********************************************************************* void push_back(rvalue_reference value) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT_OR_RETURN(size() != CAPACITY, ETL_ERROR(vector_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(size() != CAPACITY, ETL_ERROR(vector_full)); + create_back(etl::move(value)); } #endif @@ -463,9 +461,8 @@ namespace etl template reference emplace_back(Args && ... args) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(size() != CAPACITY, ETL_ERROR(vector_full)); + ::new (p_end) T(etl::forward(args)...); ++p_end; ETL_INCREMENT_DEBUG_COUNT; @@ -479,9 +476,8 @@ namespace etl //********************************************************************* reference emplace_back() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(size() != CAPACITY, ETL_ERROR(vector_full)); + ::new (p_end) T(); ++p_end; ETL_INCREMENT_DEBUG_COUNT; @@ -496,9 +492,8 @@ namespace etl template reference emplace_back(const T1& value1) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(size() != CAPACITY, ETL_ERROR(vector_full)); + ::new (p_end) T(value1); ++p_end; ETL_INCREMENT_DEBUG_COUNT; @@ -513,9 +508,8 @@ namespace etl template reference emplace_back(const T1& value1, const T2& value2) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(size() != CAPACITY, ETL_ERROR(vector_full)); + ::new (p_end) T(value1, value2); ++p_end; ETL_INCREMENT_DEBUG_COUNT; @@ -530,9 +524,8 @@ namespace etl template reference emplace_back(const T1& value1, const T2& value2, const T3& value3) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(size() != CAPACITY, ETL_ERROR(vector_full)); + ::new (p_end) T(value1, value2, value3); ++p_end; ETL_INCREMENT_DEBUG_COUNT; @@ -547,9 +540,8 @@ namespace etl template reference emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4) { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); -#endif + ETL_ASSERT_CHECK_PUSH_POP(size() != CAPACITY, ETL_ERROR(vector_full)); + ::new (p_end) T(value1, value2, value3, value4); ++p_end; ETL_INCREMENT_DEBUG_COUNT; @@ -560,12 +552,12 @@ namespace etl //************************************************************************* /// Removes an element from the end of the vector. /// Does nothing if the vector is empty. + /// If asserts or exceptions are enabled, emits vector_empty if the vector is empty. //************************************************************************* void pop_back() { -#if defined(ETL_CHECK_PUSH_POP) - ETL_ASSERT_OR_RETURN(size() > 0, ETL_ERROR(vector_empty)); -#endif + ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(size() > 0, ETL_ERROR(vector_empty)); + destroy_back(); } From 3295cb30cab38a9cfd6ca41573ab348bd904b354 Mon Sep 17 00:00:00 2001 From: mike919192 <91038685+mike919192@users.noreply.github.com> Date: Tue, 23 Sep 2025 11:26:19 -0400 Subject: [PATCH 18/18] etl array checks (#1188) * Regression fix: Support zero arguments emplace() in etl::optional (#1183) * Added coderabbitai configuration * Added builtin mem function tests * Modified etl::typed_storage * Modified etl::typed_storage # Conflicts: # include/etl/alignment.h * Added ETL_NOEXCEPT and ETL_NOEXCEPT_IF_NO_THROW * Added etl::typed_storage_ext and swap for same * Added etl::typed_storage_ext and swap for same # Conflicts: # include/etl/alignment.h * Added release notes * Fixes to GCC -O2 errors * Changed char* parameters to value_type* parameters * Fixed compilation issues for const containers unit tests * Added automatic selection of __builtin_memxxx functions for GCC and clang * Added enhanced coderabbit configuration * Updated version and release notes * Disabled constexpr const container tests for C++11 * Attempted fixes for MacOS compilation * Attempted fixes for MacOS compilation * Attempted fixes for MacOS compilation * Attempted fixes for MacOS compilation * Updated version and release notes * feat: removed unreachable break statements (#1169) * Updated version and release notes * Modified etl::typed_storage # Conflicts: # include/etl/alignment.h * Support zero arguments emplace() in etl::optional For non-fundamental types, a recent change in etl::optional was introduced that doesn't support zero arguments emplace() anymore. This change fixes it and adds the respective test. --------- Co-authored-by: John Wellbelove Co-authored-by: Drew Rife * Fix etl::typed_storage by supporting omitted destructors (#1182) * Added coderabbitai configuration * Added builtin mem function tests * Modified etl::typed_storage * Modified etl::typed_storage # Conflicts: # include/etl/alignment.h * Added ETL_NOEXCEPT and ETL_NOEXCEPT_IF_NO_THROW * Added etl::typed_storage_ext and swap for same * Added etl::typed_storage_ext and swap for same # Conflicts: # include/etl/alignment.h * Added release notes * Fixes to GCC -O2 errors * Changed char* parameters to value_type* parameters * Fixed compilation issues for const containers unit tests * Added automatic selection of __builtin_memxxx functions for GCC and clang * Added enhanced coderabbit configuration * Updated version and release notes * Disabled constexpr const container tests for C++11 * Attempted fixes for MacOS compilation * Attempted fixes for MacOS compilation * Attempted fixes for MacOS compilation * Attempted fixes for MacOS compilation * Updated version and release notes * feat: removed unreachable break statements (#1169) * Updated version and release notes * Modified etl::typed_storage # Conflicts: # include/etl/alignment.h * Fix etl::typed_storage by supporting omitted destructors In a recent change to alignment.h, the etl::typed_storage was changed in a way that in case of an already constructed object, the object is created via assignment. However, this contradicts the original use case that led to etl::typed_storage in the first place: https://github.com/ETLCPP/etl/pull/1023 The goal is to omit destructors (and at the same time support classes with deleted assignment operators), so they can be optimized out at link time. This change reverts commit ac7b268 to restore the original functionality and changes the test to reflect the original use case. * Fix missing create() in non-C++11 typed_storage_ext constructor * Typo fix --------- Co-authored-by: John Wellbelove Co-authored-by: Drew Rife Co-authored-by: John Wellbelove * removed navis file from project * Updated version and release notes * Removed forced unsigned int cast in type_def bit-shift operators (#1178) * Removed UB in type_def bit-shift operators * Changed shift operators to allow both signed and unsigned operands for shifts This allows the library user to explicitly use unsigned values to avoid UB * Fixed constexpr errors for CPP11 * Changed is_arithmetic checks to use is_integral since valid shifts require integral operands * Removed need for CPP11 since changes are CPP03 compatible * Delete project navis files * Add force CI check on piull requests * Removed ETL_NOEXCEPT from delegate operator(), call_if(), and call_or() Removed ETL_NOEXCEPT from closureoperator(), call_if(), and call_or() * Updated version and release notes * Updated version and release notes * Remove noexcept from delegate method stubs. (#1185) In addition to removing noexcept from call_if, this is also needed to prevent an abort when cancelling a pthread that is executing a delegate. * Updated version and release notes * Re architect the extra checks * Add CHECK_EXTRA * Fix newline at end of file * The check index macro also needs to be defined to throw * Remove ETL_VERBOSE_ERRORS macros --------- Co-authored-by: Roland Reichwein Co-authored-by: John Wellbelove Co-authored-by: Drew Rife Co-authored-by: John Wellbelove Co-authored-by: David Ockey <2897027+ockeydockey@users.noreply.github.com> Co-authored-by: Marco Nilsson --- include/etl/array.h | 36 ++++++++++++++++++------------------ include/etl/error_handler.h | 7 +++++++ test/etl_profile.h | 2 ++ test/test_array.cpp | 6 ------ 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/include/etl/array.h b/include/etl/array.h index fbf5063a..a238269e 100644 --- a/include/etl/array.h +++ b/include/etl/array.h @@ -145,7 +145,7 @@ namespace etl ETL_CONSTEXPR14 reference operator[](size_t i) ETL_NOEXCEPT_EXPR(ETL_DEBUG_NOT_USING_EXCEPTIONS) { - ETL_DEBUG_ASSERT(i < SIZE, ETL_ERROR(array_out_of_range)); + ETL_ASSERT_CHECK_INDEX_OPERATOR(i < SIZE, ETL_ERROR(array_out_of_range)); return _buffer[i]; } @@ -158,11 +158,11 @@ namespace etl ETL_NODISCARD ETL_CONSTEXPR const_reference operator[](size_t i) const ETL_NOEXCEPT_EXPR(ETL_DEBUG_NOT_USING_EXCEPTIONS) { - //throwing from c++11 constexpr requires a special macro -#if ETL_USING_CPP11 && !ETL_USING_CPP14 && ETL_DEBUG_USING_EXCEPTIONS - ETL_DEBUG_ASSERT_OR_RETURN_VALUE_CPP11_CONSTEXPR(i < SIZE, ETL_ERROR(array_out_of_range), _buffer[i]); + // Throwing from c++11 constexpr requires special syntax +#if ETL_USING_CPP11 && !ETL_USING_CPP14 && ETL_USING_EXCEPTIONS && defined(ETL_CHECK_INDEX_OPERATOR) + return i < SIZE ? _buffer[i] : throw(ETL_ERROR(array_out_of_range)); #else - ETL_DEBUG_ASSERT(i < SIZE, ETL_ERROR(array_out_of_range)); + ETL_ASSERT_CHECK_INDEX_OPERATOR(i < SIZE, ETL_ERROR(array_out_of_range)); return _buffer[i]; #endif @@ -446,7 +446,7 @@ namespace etl //************************************************************************* inline iterator insert_at(size_t position, parameter_t value) { - ETL_DEBUG_ASSERT(position < SIZE, ETL_ERROR(array_out_of_range)); + ETL_ASSERT_CHECK_EXTRA(position < SIZE, ETL_ERROR(array_out_of_range)); return insert(begin() + position, value); } @@ -458,7 +458,7 @@ namespace etl //************************************************************************* iterator insert(const_iterator position, parameter_t value) { - ETL_DEBUG_ASSERT(cbegin() <= position && position < cend(), ETL_ERROR(array_out_of_range)); + ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position < cend(), ETL_ERROR(array_out_of_range)); iterator p = to_iterator(position); @@ -477,7 +477,7 @@ namespace etl template inline iterator insert_at(size_t position, TIterator first, const TIterator last) { - ETL_DEBUG_ASSERT(position < SIZE, ETL_ERROR(array_out_of_range)); + ETL_ASSERT_CHECK_EXTRA(position < SIZE, ETL_ERROR(array_out_of_range)); return insert(begin() + position, first, last); } @@ -491,7 +491,7 @@ namespace etl template iterator insert(const_iterator position, TIterator first, const TIterator last) { - ETL_DEBUG_ASSERT(cbegin() <= position && position < cend(), ETL_ERROR(array_out_of_range)); + ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position < cend(), ETL_ERROR(array_out_of_range)); iterator p = to_iterator(position); iterator result(p); @@ -519,7 +519,7 @@ namespace etl //************************************************************************* inline iterator erase_at(size_t position) { - ETL_DEBUG_ASSERT(position < SIZE, ETL_ERROR(array_out_of_range)); + ETL_ASSERT_CHECK_EXTRA(position < SIZE, ETL_ERROR(array_out_of_range)); return erase(begin() + position); } @@ -531,7 +531,7 @@ namespace etl //************************************************************************* iterator erase(const_iterator position) { - ETL_DEBUG_ASSERT(cbegin() <= position && position < cend(), ETL_ERROR(array_out_of_range)); + ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position < cend(), ETL_ERROR(array_out_of_range)); iterator p = to_iterator(position); etl::move(p + 1, end(), p); @@ -547,7 +547,7 @@ namespace etl //************************************************************************* iterator erase_range(size_t first, size_t last) { - ETL_DEBUG_ASSERT(first <= last && last <= SIZE, ETL_ERROR(array_out_of_range)); + ETL_ASSERT_CHECK_EXTRA(first <= last && last <= SIZE, ETL_ERROR(array_out_of_range)); return erase(begin() + first, begin() + last); } @@ -560,7 +560,7 @@ namespace etl //************************************************************************* iterator erase(const_iterator first, const_iterator last) { - ETL_DEBUG_ASSERT(cbegin() <= first && first <= last && last <= cend(), ETL_ERROR(array_out_of_range)); + ETL_ASSERT_CHECK_EXTRA(cbegin() <= first && first <= last && last <= cend(), ETL_ERROR(array_out_of_range)); iterator p = to_iterator(first); etl::move(last, cend(), p); @@ -574,7 +574,7 @@ namespace etl //************************************************************************* inline iterator erase_at(size_t position, parameter_t value) { - ETL_DEBUG_ASSERT(position < SIZE, ETL_ERROR(array_out_of_range)); + ETL_ASSERT_CHECK_EXTRA(position < SIZE, ETL_ERROR(array_out_of_range)); return erase(begin() + position, value); } @@ -586,7 +586,7 @@ namespace etl //************************************************************************* iterator erase(const_iterator position, parameter_t value) { - ETL_DEBUG_ASSERT(cbegin() <= position && position < cend(), ETL_ERROR(array_out_of_range)); + ETL_ASSERT_CHECK_EXTRA(cbegin() <= position && position < cend(), ETL_ERROR(array_out_of_range)); iterator p = to_iterator(position); @@ -604,8 +604,8 @@ namespace etl //************************************************************************* iterator erase_range(size_t first, size_t last, parameter_t value) { - ETL_DEBUG_ASSERT(first <= last && last <= SIZE, ETL_ERROR(array_out_of_range)); - + ETL_ASSERT_CHECK_EXTRA(first <= last && last <= SIZE, ETL_ERROR(array_out_of_range)); + return erase(begin() + first, begin() + last, value); } @@ -617,7 +617,7 @@ namespace etl //************************************************************************* iterator erase(const_iterator first, const_iterator last, parameter_t value) { - ETL_DEBUG_ASSERT(cbegin() <= first && first <= last && last <= cend(), ETL_ERROR(array_out_of_range)); + ETL_ASSERT_CHECK_EXTRA(cbegin() <= first && first <= last && last <= cend(), ETL_ERROR(array_out_of_range)); iterator p = to_iterator(first); diff --git a/include/etl/error_handler.h b/include/etl/error_handler.h index a6586250..2a2c2d89 100644 --- a/include/etl/error_handler.h +++ b/include/etl/error_handler.h @@ -436,6 +436,13 @@ namespace etl #define ETL_ASSERT_CHECK_INDEX_OPERATOR(b, e) #endif +//************************************* +#ifdef ETL_CHECK_EXTRA + #define ETL_ASSERT_CHECK_EXTRA(b, e) ETL_ASSERT(b,e) +#else + #define ETL_ASSERT_CHECK_EXTRA(b, e) +#endif + //************************************* #if defined(ETL_VERBOSE_ERRORS) #define ETL_ERROR(e) (e(__FILE__, __LINE__)) // Make an exception with the file name and line number. diff --git a/test/etl_profile.h b/test/etl_profile.h index d98f6141..a7c680ff 100644 --- a/test/etl_profile.h +++ b/test/etl_profile.h @@ -35,6 +35,8 @@ SOFTWARE. #define ETL_DEBUG_THROW_EXCEPTIONS #define ETL_VERBOSE_ERRORS #define ETL_CHECK_PUSH_POP +#define ETL_CHECK_INDEX_OPERATOR +#define ETL_CHECK_EXTRA #define ETL_ISTRING_REPAIR_ENABLE #define ETL_IVECTOR_REPAIR_ENABLE #define ETL_IDEQUE_REPAIR_ENABLE diff --git a/test/test_array.cpp b/test/test_array.cpp index c779ab76..857719f2 100644 --- a/test/test_array.cpp +++ b/test/test_array.cpp @@ -135,7 +135,6 @@ namespace CHECK_EQUAL(data[i], compare_data[i]); } - //ETL_DEBUG and ETL_THROW_EXCEPTIONS are defined CHECK_THROW({ int d = data[data.size()]; (void)d; }, etl::array_out_of_range); } @@ -149,7 +148,6 @@ namespace CHECK_EQUAL(data[i], compare_data[i]); } - //ETL_DEBUG and ETL_THROW_EXCEPTIONS are defined CHECK_THROW({ int d = data[data.size()]; (void)d; }, etl::array_out_of_range); } @@ -451,7 +449,6 @@ namespace CHECK(isEqual); // Insert out of range - //ETL_DEBUG and ETL_THROW_EXCEPTIONS are defined CHECK_THROW({ result = data.insert_at(data.size(), 99); }, etl::array_out_of_range); } @@ -505,7 +502,6 @@ namespace CHECK(isEqual); // Insert out of range - //ETL_DEBUG and ETL_THROW_EXCEPTIONS are defined CHECK_THROW({ result = data.insert_at(data.size(), &source2[0], &source2[13]); }, etl::array_out_of_range); } @@ -563,7 +559,6 @@ namespace CHECK(isEqual); // Erase out of range - //ETL_DEBUG and ETL_THROW_EXCEPTIONS are defined CHECK_THROW({ result = data.erase_at(data.size()); }, etl::array_out_of_range); } @@ -620,7 +615,6 @@ namespace isEqual = std::equal(data.begin(), data.end(), std::begin(check3b)); CHECK(isEqual); - //ETL_DEBUG and ETL_THROW_EXCEPTIONS are defined // first is greater than last CHECK_THROW({ result = data.erase_range(6, 5, 99); }, etl::array_out_of_range);