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/array.h b/include/etl/array.h index c0cf8f98..a238269e 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,8 +143,10 @@ 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_ASSERT_CHECK_INDEX_OPERATOR(i < SIZE, ETL_ERROR(array_out_of_range)); + return _buffer[i]; } @@ -154,9 +156,16 @@ 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 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_ASSERT_CHECK_INDEX_OPERATOR(i < SIZE, ETL_ERROR(array_out_of_range)); + return _buffer[i]; +#endif } //************************************************************************* @@ -164,8 +173,10 @@ namespace etl //************************************************************************* ETL_NODISCARD ETL_CONSTEXPR14 - reference front() + reference front() ETL_NOEXCEPT { + ETL_STATIC_ASSERT(SIZE > 0, "Array is empty."); + return _buffer[0]; } @@ -173,8 +184,10 @@ 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."); + return _buffer[0]; } @@ -183,8 +196,10 @@ namespace etl //************************************************************************* ETL_NODISCARD ETL_CONSTEXPR14 - reference back() + reference back() ETL_NOEXCEPT { + ETL_STATIC_ASSERT(SIZE > 0, "Array is empty."); + return _buffer[SIZE - 1]; } @@ -192,8 +207,10 @@ 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."); + return _buffer[SIZE - 1]; } @@ -429,6 +446,8 @@ namespace etl //************************************************************************* inline iterator insert_at(size_t position, parameter_t value) { + ETL_ASSERT_CHECK_EXTRA(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_ASSERT_CHECK_EXTRA(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_ASSERT_CHECK_EXTRA(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_ASSERT_CHECK_EXTRA(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_ASSERT_CHECK_EXTRA(position < SIZE, ETL_ERROR(array_out_of_range)); + return erase(begin() + position); } @@ -504,6 +531,8 @@ namespace etl //************************************************************************* iterator erase(const_iterator position) { + 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); @@ -518,6 +547,8 @@ namespace etl //************************************************************************* iterator erase_range(size_t first, size_t last) { + ETL_ASSERT_CHECK_EXTRA(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_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); return p; @@ -541,6 +574,8 @@ namespace etl //************************************************************************* inline iterator erase_at(size_t position, parameter_t value) { + ETL_ASSERT_CHECK_EXTRA(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_ASSERT_CHECK_EXTRA(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_ASSERT_CHECK_EXTRA(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_ASSERT_CHECK_EXTRA(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/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 07237f89..2a2c2d89 100644 --- a/include/etl/error_handler.h +++ b/include/etl/error_handler.h @@ -364,18 +364,94 @@ 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_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 + +//************************************* +#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. #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/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/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/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/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(); } diff --git a/test/etl_profile.h b/test/etl_profile.h index d6475c6a..a7c680ff 100644 --- a/test/etl_profile.h +++ b/test/etl_profile.h @@ -32,8 +32,11 @@ SOFTWARE. #define ETL_PROFILE_H_INCLUDED #define ETL_THROW_EXCEPTIONS +#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 4fd6a263..857719f2 100644 --- a/test/test_array.cpp +++ b/test/test_array.cpp @@ -134,6 +134,8 @@ namespace { CHECK_EQUAL(data[i], compare_data[i]); } + + CHECK_THROW({ int d = data[data.size()]; (void)d; }, etl::array_out_of_range); } //************************************************************************* @@ -145,6 +147,8 @@ namespace { CHECK_EQUAL(data[i], compare_data[i]); } + + CHECK_THROW({ int d = data[data.size()]; (void)d; }, etl::array_out_of_range); } //************************************************************************* @@ -443,6 +447,9 @@ namespace CHECK_EQUAL(data[9], *result); isEqual = std::equal(data.begin(), data.end(), std::begin(check3)); CHECK(isEqual); + + // Insert out of range + CHECK_THROW({ result = data.insert_at(data.size(), 99); }, etl::array_out_of_range); } //************************************************************************* @@ -493,6 +500,9 @@ namespace CHECK_EQUAL(data[4], *result); isEqual = std::equal(data.begin(), data.end(), std::begin(check5)); CHECK(isEqual); + + // Insert out of range + CHECK_THROW({ result = data.insert_at(data.size(), &source2[0], &source2[13]); }, etl::array_out_of_range); } //************************************************************************* @@ -547,6 +557,9 @@ namespace CHECK_EQUAL(data[9], *result); isEqual = std::equal(data.begin(), data.end(), std::begin(check3b)); CHECK(isEqual); + + // Erase out of range + CHECK_THROW({ result = data.erase_at(data.size()); }, etl::array_out_of_range); } //************************************************************************* @@ -601,6 +614,12 @@ namespace CHECK_EQUAL(data[5], *result); isEqual = std::equal(data.begin(), data.end(), std::begin(check3b)); CHECK(isEqual); + + // 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); } //*************************************************************************