From a2e02d8dfa280fb3c2c6f55431ddc11f81e33c23 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 20 Jul 2022 16:07:32 +0100 Subject: [PATCH 01/10] Added Log Errors event handler tests --- .gitignore | 1 + .../log_errors/CMakeLists.txt | 33 ++++ .../log_errors/etl_profile.h | 0 .../log_errors/test_error_handler.cpp | 180 ++++++++++++++++++ test/vs2019/etl.vcxproj | 86 ++++++++- test/vs2019/etl.vcxproj.filters | 24 +++ 6 files changed, 323 insertions(+), 1 deletion(-) create mode 100644 test/etl_error_handler/log_errors/CMakeLists.txt create mode 100644 test/etl_error_handler/log_errors/etl_profile.h create mode 100644 test/etl_error_handler/log_errors/test_error_handler.cpp diff --git a/.gitignore b/.gitignore index 4ca9b6954..500914621 100644 --- a/.gitignore +++ b/.gitignore @@ -362,3 +362,4 @@ test/build-etl_initializer_list-GCC-Debug test/etl_initializer_list/etl_initializer_list.vcxproj.filters test/etl_initializer_list/build-make test/vs-build +test/etl_error_handler/build-log_errors-GCC-Debug diff --git a/test/etl_error_handler/log_errors/CMakeLists.txt b/test/etl_error_handler/log_errors/CMakeLists.txt new file mode 100644 index 000000000..67642447a --- /dev/null +++ b/test/etl_error_handler/log_errors/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.5.0) +project(etl_error_handler_unit_tests) + +add_definitions(-DETL_DEBUG) +add_definitions(-DETL_LOG_ERRORS) + +include_directories(${PROJECT_SOURCE_DIR}/../../../include) + +set(TEST_SOURCE_FILES + test_error_handler.cpp + ) + +add_executable(etl_tests + ${TEST_SOURCE_FILES} + ) + +target_include_directories(etl_tests + PUBLIC + ${CMAKE_CURRENT_LIST_DIR} + ) + +# Enable the 'make test' CMake target using the executable defined above +add_test(etl_error_handler_unit_tests etl_tests) + +# Since ctest will only show you the results of the single executable +# define a target that will output all of the failing or passing tests +# as they appear from UnitTest++ +add_custom_target(test_verbose COMMAND ${CMAKE_CTEST_COMMAND} --verbose) + + +#RSG +set_property(TARGET etl_tests PROPERTY CXX_STANDARD 17) + diff --git a/test/etl_error_handler/log_errors/etl_profile.h b/test/etl_error_handler/log_errors/etl_profile.h new file mode 100644 index 000000000..e69de29bb diff --git a/test/etl_error_handler/log_errors/test_error_handler.cpp b/test/etl_error_handler/log_errors/test_error_handler.cpp new file mode 100644 index 000000000..04d05d372 --- /dev/null +++ b/test/etl_error_handler/log_errors/test_error_handler.cpp @@ -0,0 +1,180 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/std +https://www.etlcpp.com + +Copyright(c) 2022 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include "etl/error_handler.h" + +#include +#include + +etl::error_handler eh; + +//#define ETL_ASSERT_FAIL(e) assert(false) // Asserts. +//#define ETL_ASSERT_FAIL_AND_RETURN(e) {assert(false); return;} // Asserts. +//#define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) + +//***************************************************************************** +struct ErrorLog +{ + ErrorLog() + : exception_count(0) + { + } + + void Log(const etl::exception& e) + { + ++exception_count; + } + + int exception_count; +}; + +int assert_return_count = 0; + +//***************************************************************************** +class test_exception : public etl::exception +{ +public: + + test_exception(string_type reason_, string_type file_name_, numeric_type line_number_) + : exception(reason_, file_name_, line_number_) + { + } +}; + +//***************************************************************************** +class test_exception_1 : public test_exception +{ +public: + + test_exception_1(string_type file_name_, numeric_type line_number_) + : test_exception(ETL_ERROR_TEXT("Test Exception 1", "1A"), file_name_, line_number_) + { + } +}; + +//***************************************************************************** +void Assert(bool state) +{ + ETL_ASSERT(state, ETL_ERROR(test_exception_1)); +} + +//***************************************************************************** +void AssertFail() +{ + ETL_ASSERT_FAIL(ETL_ERROR(test_exception_1)); +} + +//***************************************************************************** +void AssertAndReturn(bool state) +{ + ETL_ASSERT_AND_RETURN(state, ETL_ERROR(test_exception_1)); + + ++assert_return_count; +} + +//***************************************************************************** +void AssertFailAndReturn() +{ + ETL_ASSERT_FAIL_AND_RETURN(ETL_ERROR(test_exception_1)); + + ++assert_return_count; +} + +//***************************************************************************** +bool AssertAndReturnValue(bool state) +{ + ETL_ASSERT_AND_RETURN_VALUE(state, ETL_ERROR(test_exception_1), true); + + ++assert_return_count; + return false; +} + +//***************************************************************************** +bool AssertFailAndReturnValue() +{ + ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(test_exception_1), true); + + ++assert_return_count; + return false; +} + +//***************************************************************************** +int main() +{ + static ErrorLog error_log; + + etl::error_handler::set_callback(error_log); + + Assert(false); + Assert(true); + AssertFail(); + + AssertAndReturn(false); + AssertAndReturn(true); + AssertFailAndReturn(); + + if (AssertAndReturnValue(false)) + { + ++assert_return_count; + } + + if (AssertAndReturnValue(true)) + { + ++assert_return_count; + } + + if (AssertFailAndReturnValue()) + { + ++assert_return_count; + } + + bool error_count_passed = (error_log.exception_count == 6); + + if (error_count_passed) + { + std::cout << "Error Count Passed\n"; + } + else + { + std::cout << "Error Count Failed\n"; + } + + bool assert_return_count_passed = (assert_return_count == 4); + + if (assert_return_count_passed) + { + std::cout << "Assert Return Count Passed\n"; + } + else + { + std::cout << "Assert Return Count Failed\n"; + } + + return (error_count_passed && assert_return_count_passed) ? 0 : 1; +} + diff --git a/test/vs2019/etl.vcxproj b/test/vs2019/etl.vcxproj index 8b83ad4c8..5d0aa29e1 100644 --- a/test/vs2019/etl.vcxproj +++ b/test/vs2019/etl.vcxproj @@ -2655,6 +2655,34 @@ + + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true true @@ -2728,6 +2756,34 @@ + + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true true @@ -11930,6 +11986,34 @@ + + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true true @@ -11978,4 +12062,4 @@ - + \ No newline at end of file diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index 6ddd45f58..c64a775c4 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -205,6 +205,21 @@ {0014395b-c658-4903-a15f-d21acb676d79} + + {69ed2e1e-f009-4a1a-abf2-a9144142b533} + + + {78498646-3058-4d15-9d21-2243ca5d5cd4} + + + {19d7da41-01e8-4449-8b9b-14be81447752} + + + {de372ec9-d193-4956-871f-065414a9d3be} + + + {1c718339-9f2d-4c83-a39e-66b7300df135} + @@ -1290,6 +1305,9 @@ Tests\Initializer List + + Tests\Error Handler\Log Errors + @@ -3284,6 +3302,9 @@ Tests\Initializer List + + Tests\Error Handler\Log Errors + @@ -3423,6 +3444,9 @@ Tests\Initializer List + + Tests\Error Handler\Log Errors + From c2ceca3d8f641a468ef37673251393b9c77f7290 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 20 Jul 2022 16:11:25 +0100 Subject: [PATCH 02/10] Generator test --- scripts/generator_test.py | 42 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 scripts/generator_test.py diff --git a/scripts/generator_test.py b/scripts/generator_test.py new file mode 100644 index 000000000..079e3c03d --- /dev/null +++ b/scripts/generator_test.py @@ -0,0 +1,42 @@ +import subprocess +from os.path import abspath +from pathlib import Path +import filecmp + +root_path = Path(abspath(__file__)).parent +generator_folder = root_path/"include" / "etl" / "generators" + +# Create folder where generator outputs can go for purpose of comparison +test_folder = root_path / "build" / "generator_tmp" +test_folder.mkdir(parents=True, exist_ok= True) + +all_ok = True +for generator in generator_folder.iterdir(): + if generator.suffix != ".h": + continue + generator_path = str(generator_folder / generator) + output_name = generator.name[:-12] + ".h" + output_path = str(test_folder / output_name) + + cog_cmd = [ + "cog", + "-d", + "-e", + f"-o{output_path}", + "-DHandlers=16", + "-DNTypes=16", + "-DIsOneOf=16", + generator_path + ] + + subprocess.run(cog_cmd) + + # Compare generator output against actual file output + actual_path = str(generator_folder.parent / output_name) + if not filecmp.cmp(actual_path, output_path): + print(f"Generator for {output_name} does not match file contents") + all_ok = False + +if not all_ok: + exit(1) +exit(0) \ No newline at end of file From 4316a4d7afd1df09d6d9db49a27504adf0a5620b Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 24 Jul 2022 12:52:58 +0100 Subject: [PATCH 03/10] Added tests for error handler macros Fixed missing value parameter for exception + log configuration --- include/etl/error_handler.h | 2 +- .../exceptions/CMakeLists.txt | 33 +++ .../exceptions/etl_profile.h | 0 .../exceptions/test_error_handler.cpp | 223 ++++++++++++++++ .../log_errors/test_error_handler.cpp | 28 +- .../log_errors_and_exceptions/CMakeLists.txt | 34 +++ .../log_errors_and_exceptions/etl_profile.h | 0 .../test_error_handler.cpp | 246 ++++++++++++++++++ test/runtests.sh | 145 +++++++++++ 9 files changed, 694 insertions(+), 17 deletions(-) create mode 100644 test/etl_error_handler/exceptions/CMakeLists.txt create mode 100644 test/etl_error_handler/exceptions/etl_profile.h create mode 100644 test/etl_error_handler/exceptions/test_error_handler.cpp create mode 100644 test/etl_error_handler/log_errors_and_exceptions/CMakeLists.txt create mode 100644 test/etl_error_handler/log_errors_and_exceptions/etl_profile.h create mode 100644 test/etl_error_handler/log_errors_and_exceptions/test_error_handler.cpp diff --git a/include/etl/error_handler.h b/include/etl/error_handler.h index 3546b8cd9..5bedd4ae8 100644 --- a/include/etl/error_handler.h +++ b/include/etl/error_handler.h @@ -283,7 +283,7 @@ namespace etl #define ETL_ASSERT_FAIL(e) {etl::error_handler::error((e)); throw((e));} // Calls the error handler then throws an exception. #define ETL_ASSERT_FAIL_AND_RETURN(e) {etl::error_handler::error((e)); throw((e)); return;} // Calls the error handler then throws an exception. - #define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e) {etl::error_handler::error((e)); throw((e)); return(v);} // Calls the error handler then throws an exception. + #define ETL_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_ASSERT(b, e) {if (!(b)) {throw((e));}} // If the condition fails, throws an exception. #define ETL_ASSERT_AND_RETURN(b, e) {if (!(b)) {throw((e)); return;}} // If the condition fails, throws an exception. diff --git a/test/etl_error_handler/exceptions/CMakeLists.txt b/test/etl_error_handler/exceptions/CMakeLists.txt new file mode 100644 index 000000000..9239b8735 --- /dev/null +++ b/test/etl_error_handler/exceptions/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.5.0) +project(etl_error_handler_unit_tests) + +add_definitions(-DETL_DEBUG) +add_definitions(-DETL_THROW_EXCEPTIONS) + +include_directories(${PROJECT_SOURCE_DIR}/../../../include) + +set(TEST_SOURCE_FILES + test_error_handler.cpp + ) + +add_executable(etl_tests + ${TEST_SOURCE_FILES} + ) + +target_include_directories(etl_tests + PUBLIC + ${CMAKE_CURRENT_LIST_DIR} + ) + +# Enable the 'make test' CMake target using the executable defined above +add_test(etl_error_handler_unit_tests etl_tests) + +# Since ctest will only show you the results of the single executable +# define a target that will output all of the failing or passing tests +# as they appear from UnitTest++ +add_custom_target(test_verbose COMMAND ${CMAKE_CTEST_COMMAND} --verbose) + + +#RSG +set_property(TARGET etl_tests PROPERTY CXX_STANDARD 17) + diff --git a/test/etl_error_handler/exceptions/etl_profile.h b/test/etl_error_handler/exceptions/etl_profile.h new file mode 100644 index 000000000..e69de29bb diff --git a/test/etl_error_handler/exceptions/test_error_handler.cpp b/test/etl_error_handler/exceptions/test_error_handler.cpp new file mode 100644 index 000000000..fe83d0d30 --- /dev/null +++ b/test/etl_error_handler/exceptions/test_error_handler.cpp @@ -0,0 +1,223 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/std +https://www.etlcpp.com + +Copyright(c) 2022 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include "etl/error_handler.h" + +#include +#include + +//***************************************************************************** +int exception_count = 0; +int return_count = 0; + +//***************************************************************************** +class test_exception : public etl::exception +{ +public: + + test_exception(string_type reason_, string_type file_name_, numeric_type line_number_) + : exception(reason_, file_name_, line_number_) + { + } +}; + +//***************************************************************************** +class test_exception_1 : public test_exception +{ +public: + + test_exception_1(string_type file_name_, numeric_type line_number_) + : test_exception(ETL_ERROR_TEXT("Test Exception 1", "1A"), file_name_, line_number_) + { + } +}; + +//***************************************************************************** +void Assert(bool state) +{ + ETL_ASSERT(state, ETL_ERROR(test_exception_1)); +} + +//***************************************************************************** +void AssertFail() +{ + ETL_ASSERT_FAIL(ETL_ERROR(test_exception_1)); +} + +//***************************************************************************** +void AssertAndReturn(bool state) +{ + ETL_ASSERT_AND_RETURN(state, ETL_ERROR(test_exception_1)); + + ++return_count; +} + +//***************************************************************************** +void AssertFailAndReturn() +{ + ETL_ASSERT_FAIL_AND_RETURN(ETL_ERROR(test_exception_1)); + + ++return_count; +} + +//***************************************************************************** +bool AssertAndReturnValue(bool state) +{ + ETL_ASSERT_AND_RETURN_VALUE(state, ETL_ERROR(test_exception_1), true); + + ++return_count; + return false; +} + +//***************************************************************************** +bool AssertFailAndReturnValue() +{ + ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(test_exception_1), true); + + ++return_count; + return false; +} + +//***************************************************************************** +int main() +{ + try + { + Assert(false); + } + catch (test_exception_1 e) + { + ++exception_count; + } + + try + { + Assert(true); + } + catch (test_exception_1 e) + { + ++exception_count; + } + + try + { + AssertFail(); + } + catch (test_exception_1 e) + { + ++exception_count; + } + + try + { + AssertAndReturn(false); + } + catch (test_exception_1 e) + { + ++exception_count; + } + + try + { + AssertAndReturn(true); + } + catch (test_exception_1 e) + { + ++exception_count; + } + + try + { + AssertFailAndReturn(); + } + catch (test_exception_1 e) + { + ++exception_count; + } + + try + { + if (AssertAndReturnValue(false)) + { + ++return_count; + } + } + catch (test_exception_1 e) + { + ++exception_count; + } + + try + { + if (AssertAndReturnValue(true)) + { + ++return_count; + } + } + catch (test_exception_1 e) + { + ++exception_count; + } + + try + { + if (AssertFailAndReturnValue()) + { + ++return_count; + } + } + catch (test_exception_1 e) + { + ++exception_count; + } + + bool exception_count_passed = (exception_count == 6); + + if (exception_count_passed) + { + std::cout << "Exception Count Passed\n"; + } + else + { + std::cout << "Exception Count Failed\n"; + } + + bool return_count_passed = (return_count == 2); + + if (return_count_passed) + { + std::cout << "Return Count Passed\n"; + } + else + { + std::cout << "Return Count Failed\n"; + } + + return (exception_count_passed && return_count_passed) ? 0 : 1; +} + diff --git a/test/etl_error_handler/log_errors/test_error_handler.cpp b/test/etl_error_handler/log_errors/test_error_handler.cpp index 04d05d372..925cfb08d 100644 --- a/test/etl_error_handler/log_errors/test_error_handler.cpp +++ b/test/etl_error_handler/log_errors/test_error_handler.cpp @@ -33,24 +33,20 @@ SOFTWARE. etl::error_handler eh; -//#define ETL_ASSERT_FAIL(e) assert(false) // Asserts. -//#define ETL_ASSERT_FAIL_AND_RETURN(e) {assert(false); return;} // Asserts. -//#define ETL_ASSERT_FAIL_AND_RETURN_VALUE(e, v) - //***************************************************************************** struct ErrorLog { ErrorLog() - : exception_count(0) + : log_count(0) { } void Log(const etl::exception& e) { - ++exception_count; + ++log_count; } - int exception_count; + int log_count; }; int assert_return_count = 0; @@ -153,28 +149,28 @@ int main() ++assert_return_count; } - bool error_count_passed = (error_log.exception_count == 6); + bool log_count_passed = (error_log.log_count == 6); - if (error_count_passed) + if (log_count_passed) { - std::cout << "Error Count Passed\n"; + std::cout << "Log Count Passed\n"; } else { - std::cout << "Error Count Failed\n"; + std::cout << "Log Count Failed\n"; } - bool assert_return_count_passed = (assert_return_count == 4); + bool return_count_passed = (assert_return_count == 4); - if (assert_return_count_passed) + if (return_count_passed) { - std::cout << "Assert Return Count Passed\n"; + std::cout << "Return Count Passed\n"; } else { - std::cout << "Assert Return Count Failed\n"; + std::cout << "Return Count Failed\n"; } - return (error_count_passed && assert_return_count_passed) ? 0 : 1; + return (log_count_passed && return_count_passed) ? 0 : 1; } diff --git a/test/etl_error_handler/log_errors_and_exceptions/CMakeLists.txt b/test/etl_error_handler/log_errors_and_exceptions/CMakeLists.txt new file mode 100644 index 000000000..fcdb12a89 --- /dev/null +++ b/test/etl_error_handler/log_errors_and_exceptions/CMakeLists.txt @@ -0,0 +1,34 @@ +cmake_minimum_required(VERSION 3.5.0) +project(etl_error_handler_unit_tests) + +add_definitions(-DETL_DEBUG) +add_definitions(-DETL_THROW_EXCEPTIONS) +add_definitions(-DETL_LOG_ERRORS) + +include_directories(${PROJECT_SOURCE_DIR}/../../../include) + +set(TEST_SOURCE_FILES + test_error_handler.cpp + ) + +add_executable(etl_tests + ${TEST_SOURCE_FILES} + ) + +target_include_directories(etl_tests + PUBLIC + ${CMAKE_CURRENT_LIST_DIR} + ) + +# Enable the 'make test' CMake target using the executable defined above +add_test(etl_error_handler_unit_tests etl_tests) + +# Since ctest will only show you the results of the single executable +# define a target that will output all of the failing or passing tests +# as they appear from UnitTest++ +add_custom_target(test_verbose COMMAND ${CMAKE_CTEST_COMMAND} --verbose) + + +#RSG +set_property(TARGET etl_tests PROPERTY CXX_STANDARD 17) + diff --git a/test/etl_error_handler/log_errors_and_exceptions/etl_profile.h b/test/etl_error_handler/log_errors_and_exceptions/etl_profile.h new file mode 100644 index 000000000..e69de29bb diff --git a/test/etl_error_handler/log_errors_and_exceptions/test_error_handler.cpp b/test/etl_error_handler/log_errors_and_exceptions/test_error_handler.cpp new file mode 100644 index 000000000..19a2bbcdf --- /dev/null +++ b/test/etl_error_handler/log_errors_and_exceptions/test_error_handler.cpp @@ -0,0 +1,246 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/std +https://www.etlcpp.com + +Copyright(c) 2022 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include "etl/error_handler.h" + +#include +#include + +etl::error_handler eh; + +//***************************************************************************** +struct ErrorLog +{ + ErrorLog() + : log_count(0) + { + } + + void Log(const etl::exception& e) + { + ++log_count; + } + + int log_count; +}; + +int exception_count = 0; +int return_count = 0; + +//***************************************************************************** +class test_exception : public etl::exception +{ +public: + + test_exception(string_type reason_, string_type file_name_, numeric_type line_number_) + : exception(reason_, file_name_, line_number_) + { + } +}; + +//***************************************************************************** +class test_exception_1 : public test_exception +{ +public: + + test_exception_1(string_type file_name_, numeric_type line_number_) + : test_exception(ETL_ERROR_TEXT("Test Exception 1", "1A"), file_name_, line_number_) + { + } +}; + +//***************************************************************************** +void Assert(bool state) +{ + ETL_ASSERT(state, ETL_ERROR(test_exception_1)); +} + +//***************************************************************************** +void AssertFail() +{ + ETL_ASSERT_FAIL(ETL_ERROR(test_exception_1)); +} + +//***************************************************************************** +void AssertAndReturn(bool state) +{ + ETL_ASSERT_AND_RETURN(state, ETL_ERROR(test_exception_1)); + + ++return_count; +} + +//***************************************************************************** +void AssertFailAndReturn() +{ + ETL_ASSERT_FAIL_AND_RETURN(ETL_ERROR(test_exception_1)); + + ++return_count; +} + +//***************************************************************************** +bool AssertAndReturnValue(bool state) +{ + ETL_ASSERT_AND_RETURN_VALUE(state, ETL_ERROR(test_exception_1), true); + + ++return_count; + return false; +} + +//***************************************************************************** +bool AssertFailAndReturnValue() +{ + ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(test_exception_1), true); + + ++return_count; + return false; +} + +//***************************************************************************** +int main() +{ + ErrorLog error_log; + + etl::error_handler::set_callback(error_log); + + try + { + Assert(false); + } + catch (test_exception_1 e) + { + ++exception_count; + } + + try + { + Assert(true); + } + catch (test_exception_1 e) + { + ++exception_count; + } + + try + { + AssertFail(); + } + catch (test_exception_1 e) + { + ++exception_count; + } + + try + { + AssertAndReturn(false); + } + catch (test_exception_1 e) + { + ++exception_count; + } + + try + { + AssertAndReturn(true); + } + catch (test_exception_1 e) + { + ++exception_count; + } + + try + { + AssertFailAndReturn(); + } + catch (test_exception_1 e) + { + ++exception_count; + } + + try + { + AssertAndReturnValue(false); + } + catch (test_exception_1 e) + { + ++exception_count; + } + + try + { + AssertAndReturnValue(true); + } + catch (test_exception_1 e) + { + ++exception_count; + } + + try + { + AssertFailAndReturnValue(); + } + catch (test_exception_1 e) + { + ++exception_count; + } + + bool log_count_passed = (error_log.log_count == 6); + + if (log_count_passed) + { + std::cout << "Log Count Passed\n"; + } + else + { + std::cout << "Log Count Failed\n"; + } + + bool return_count_passed = (return_count == 2); + + if (return_count_passed) + { + std::cout << "Return Count Passed\n"; + } + else + { + std::cout << "Return Count Failed\n"; + } + + bool exception_count_passed = (exception_count == 6); + + if (exception_count_passed) + { + std::cout << "Exception Count Passed\n"; + } + else + { + std::cout << "Exception Count Failed\n"; + } + + return (log_count_passed && return_count_passed && exception_count_passed) ? 0 : 1; +} + diff --git a/test/runtests.sh b/test/runtests.sh index 18504ddb7..08025ea0d 100644 --- a/test/runtests.sh +++ b/test/runtests.sh @@ -218,6 +218,151 @@ else echo "****************\n**** Failed ****\n****************" | tee -a ../log.txt exit $? fi + +echo "" +echo "-----------------------------------------------" | tee -a log.txt +echo " GCC - Error macros 'log_errors' test" | tee -a log.txt +echo "-----------------------------------------------" | tee -a log.txt +cd ../../etl_error_handler/log_errors +mkdir -p build-make || exit 1 +cd build-make || exit 1 +gcc --version | grep gcc | tee -a log.txt +cmake --cmake-clean-cache -DCMAKE_CXX_COMPILER="g++" -DCMAKE_C_COMPILER="gcc" .. +make -j8 +if [ $? -eq 0 ]; then + echo "<<<< Passed Error macros 'log_errors' Compilation >>>>" +else + echo "****************\n**** Failed Error macros 'log_errors' ****\n****************" | tee -a ../log.txt + exit $? +fi +./etl_tests +if [ $? -eq 0 ]; then + echo "<<<< Passed Tests >>>>" +else + echo "****************\n**** Failed Error macros 'log_errors' ****\n****************" | tee -a ../log.txt + exit $? +fi + +echo "" +echo "-----------------------------------------------" | tee -a log.txt +echo " GCC - Error macros 'exceptions' test" | tee -a log.txt +echo "-----------------------------------------------" | tee -a log.txt +cd ../../../etl_error_handler/exceptions +mkdir -p build-make || exit 1 +cd build-make || exit 1 +gcc --version | grep gcc | tee -a log.txt +cmake --cmake-clean-cache -DCMAKE_CXX_COMPILER="g++" -DCMAKE_C_COMPILER="gcc" .. +make -j8 +if [ $? -eq 0 ]; then + echo "<<<< Passed Error macros 'exceptions' Compilation >>>>" +else + echo "****************\n**** Failed Error macros 'exceptions' ****\n****************" | tee -a ../log.txt + exit $? +fi +./etl_tests +if [ $? -eq 0 ]; then + echo "<<<< Passed Tests >>>>" +else + echo "****************\n**** Failed Error macros 'exceptions' ****\n****************" | tee -a ../log.txt + exit $? +fi + +echo "" +echo "-----------------------------------------------" | tee -a log.txt +echo " GCC - Error macros 'log_errors and exceptions' test" | tee -a log.txt +echo "-----------------------------------------------" | tee -a log.txt +cd ../../../etl_error_handler/log_errors_and_exceptions +mkdir -p build-make || exit 1 +cd build-make || exit 1 +gcc --version | grep gcc | tee -a log.txt +cmake --cmake-clean-cache -DCMAKE_CXX_COMPILER="g++" -DCMAKE_C_COMPILER="gcc" .. +make -j8 +if [ $? -eq 0 ]; then + echo "<<<< Passed Error macros 'log_errors and exceptions' Compilation >>>>" +else + echo "****************\n**** Failed Error macros 'log_errors and exceptions' ****\n****************" | tee -a ../log.txt + exit $? +fi +./etl_tests +if [ $? -eq 0 ]; then + echo "<<<< Passed Tests >>>>" +else + echo "****************\n**** Failed Error macros 'log_errors and exceptions' ****\n****************" | tee -a ../log.txt + exit $? +fi + +echo "" +echo "-----------------------------------------------" | tee -a log.txt +echo " Clang - Error macros 'log_errors' test" | tee -a log.txt +echo "-----------------------------------------------" | tee -a log.txt +cd ../../../etl_error_handler/log_errors +mkdir -p build-make || exit 1 +cd build-make || exit 1 +clang --version | grep clang | tee -a log.txt +cmake --cmake-clean-cache -DCMAKE_CXX_COMPILER="clang++" -DCMAKE_C_COMPILER="clang" .. +make -j8 +if [ $? -eq 0 ]; then + echo "<<<< Passed Error macros 'log_errors' Compilation >>>>" +else + echo "****************\n**** Failed Error macros 'log_errors' ****\n****************" | tee -a ../log.txt + exit $? +fi +./etl_tests +if [ $? -eq 0 ]; then + echo "<<<< Passed Tests >>>>" +else + echo "****************\n**** Failed Error macros 'log_errors' ****\n****************" | tee -a ../log.txt + exit $? +fi + +echo "" +echo "-----------------------------------------------" | tee -a log.txt +echo " Clang - Error macros 'exceptions' test" | tee -a log.txt +echo "-----------------------------------------------" | tee -a log.txt +cd ../../../etl_error_handler/exceptions +mkdir -p build-make || exit 1 +cd build-make || exit 1 +clang --version | grep clang | tee -a log.txt +cmake --cmake-clean-cache -DCMAKE_CXX_COMPILER="clang++" -DCMAKE_C_COMPILER="clang" .. +make -j8 +if [ $? -eq 0 ]; then + echo "<<<< Passed Error macros 'exceptions' Compilation >>>>" +else + echo "****************\n**** Failed Error macros 'exceptions' ****\n****************" | tee -a ../log.txt + exit $? +fi +./etl_tests +if [ $? -eq 0 ]; then + echo "<<<< Passed Tests >>>>" +else + echo "****************\n**** Failed Error macros 'exceptions' ****\n****************" | tee -a ../log.txt + exit $? +fi + +echo "" +echo "-----------------------------------------------" | tee -a log.txt +echo " Clang - Error macros 'log_errors and exceptions' test" | tee -a log.txt +echo "-----------------------------------------------" | tee -a log.txt +cd ../../../etl_error_handler/log_errors_and_exceptions +mkdir -p build-make || exit 1 +cd build-make || exit 1 +clang --version | grep clang | tee -a log.txt +cmake --cmake-clean-cache -DCMAKE_CXX_COMPILER="clang++" -DCMAKE_C_COMPILER="clang" .. +make -j8 +if [ $? -eq 0 ]; then + echo "<<<< Passed Error macros 'log_errors and exceptions' Compilation >>>>" +else + echo "****************\n**** Failed Error macros 'log_errors and exceptions' ****\n****************" | tee -a ../log.txt + exit $? +fi +./etl_tests +if [ $? -eq 0 ]; then + echo "<<<< Passed Tests >>>>" +else + echo "****************\n**** Failed Error macros 'log_errors and exceptions' ****\n****************" | tee -a ../log.txt + exit $? +fi + cd ../.. echo "" From b2e1c35540fb9acee3bb5989712b61348f9ec1a1 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 24 Jul 2022 12:56:44 +0100 Subject: [PATCH 04/10] Fixed swap function for circular_buffer_ext Fixed circular_buffer iterator -> operators Added functions and macros to etl::debug_count --- include/etl/circular_buffer.h | 57 +++--- include/etl/debug_count.h | 83 ++++++--- test/test_circular_buffer.cpp | 58 +++++- test/test_circular_buffer_external_buffer.cpp | 64 ++++++- test/vs2019/etl.vcxproj | 169 ++++++++++++++++++ test/vs2019/etl.vcxproj.filters | 24 ++- 6 files changed, 387 insertions(+), 68 deletions(-) diff --git a/include/etl/circular_buffer.h b/include/etl/circular_buffer.h index 2ae9fc72b..006df3bb6 100644 --- a/include/etl/circular_buffer.h +++ b/include/etl/circular_buffer.h @@ -83,7 +83,7 @@ namespace etl //************************************************************************* size_type size() const { - return (in >= out) ? in - out : BUFFER_SIZE - (out - in); + return (in >= out) ? in - out : buffer_size - (out - in); } //************************************************************************* @@ -98,7 +98,7 @@ namespace etl size_t i = in; ++i; - if (i == BUFFER_SIZE) ETL_UNLIKELY + if (i == buffer_size) ETL_UNLIKELY { i = 0U; } @@ -115,20 +115,20 @@ namespace etl //************************************************************************* size_type max_size() const { - return BUFFER_SIZE - 1U; + return buffer_size - 1U; } //************************************************************************* size_type capacity() const { - return BUFFER_SIZE - 1U; + return buffer_size - 1U; } protected: //************************************************************************* - circular_buffer_base(size_type BUFFER_SIZE_) - : BUFFER_SIZE(BUFFER_SIZE_) + circular_buffer_base(size_type buffer_size_) + : buffer_size(buffer_size_) , in(0U) , out(0U) { @@ -138,7 +138,7 @@ namespace etl void increment_in() { ++in; - if (in == BUFFER_SIZE) ETL_UNLIKELY + if (in == buffer_size) ETL_UNLIKELY { in = 0U; } @@ -148,13 +148,13 @@ namespace etl void increment_out() { ++out; - if (out == BUFFER_SIZE) ETL_UNLIKELY + if (out == buffer_size) ETL_UNLIKELY { out = 0U; } } - const size_type BUFFER_SIZE; + size_type buffer_size; size_type in; ///< Index to the next write. size_type out; ///< Index to the next read. ETL_DECLARE_DEBUG_COUNT; ///< Internal debugging. @@ -230,7 +230,7 @@ namespace etl //************************************************************************* pointer operator ->() const { - return picb->pbuffer[current]; + return &picb->pbuffer[current]; } //************************************************************************* @@ -241,7 +241,7 @@ namespace etl ++current; // Did we reach the end of the buffer? - if (current == picb->BUFFER_SIZE) + if (current == picb->buffer_size) { current = 0U; } @@ -269,7 +269,7 @@ namespace etl // Are we at the end of the buffer? if (current == 0U) { - current = picb->BUFFER_SIZE - 1; + current = picb->buffer_size - 1; } else { @@ -296,8 +296,8 @@ namespace etl //************************************************************************* iterator& operator +=(int n) { - current += size_type(picb->BUFFER_SIZE + n); - current %= picb->BUFFER_SIZE; + current += size_type(picb->buffer_size + n); + current %= picb->buffer_size; return (*this); } @@ -407,7 +407,7 @@ namespace etl { if (index < firstIndex) { - return picb->BUFFER_SIZE + current - firstIndex; + return picb->buffer_size + current - firstIndex; } else { @@ -501,7 +501,7 @@ namespace etl //************************************************************************* const_pointer operator ->() const { - return picb->pbuffer[current]; + return &(picb->pbuffer[current]); } //************************************************************************* @@ -512,7 +512,7 @@ namespace etl ++current; // Did we reach the end of the buffer? - if (current == picb->BUFFER_SIZE) + if (current == picb->buffer_size) { current = 0U; } @@ -540,7 +540,7 @@ namespace etl // Are we at the end of the buffer? if (current == 0U) { - current = picb->BUFFER_SIZE - 1; + current = picb->buffer_size - 1; } else { @@ -567,8 +567,8 @@ namespace etl //************************************************************************* const_iterator& operator +=(int n) { - current += size_type(picb->BUFFER_SIZE + n); - current %= picb->BUFFER_SIZE; + current += size_type(picb->buffer_size + n); + current %= picb->buffer_size; return (*this); } @@ -820,7 +820,7 @@ namespace etl { ETL_ASSERT(!empty(), ETL_ERROR(circular_buffer_empty)); - return pbuffer[in == 0U ? BUFFER_SIZE - 1 : in - 1U]; + return pbuffer[in == 0U ? buffer_size - 1 : in - 1U]; } //************************************************************************* @@ -831,7 +831,7 @@ namespace etl { ETL_ASSERT(!empty(), ETL_ERROR(circular_buffer_empty)); - return pbuffer[in == 0U ? BUFFER_SIZE - 1 : in - 1U]; + return pbuffer[in == 0U ? buffer_size - 1 : in - 1U]; } //************************************************************************* @@ -839,7 +839,7 @@ namespace etl //************************************************************************* reference operator [](size_t index) { - return pbuffer[(out + index) % BUFFER_SIZE]; + return pbuffer[(out + index) % buffer_size]; } //************************************************************************* @@ -848,7 +848,7 @@ namespace etl //************************************************************************* const_reference operator [](size_t index) const { - return pbuffer[(out + index) % BUFFER_SIZE]; + return pbuffer[(out + index) % buffer_size]; } //************************************************************************* @@ -1025,7 +1025,7 @@ namespace etl { const difference_type index = other.get_index(); const difference_type reference_index = other.container().out; - const size_t buffer_size = other.container().BUFFER_SIZE; + const size_t buffer_size = other.container().buffer_size; if (index < reference_index) { @@ -1294,13 +1294,18 @@ namespace etl //************************************************************************* /// Swap with another circular buffer //************************************************************************* - void swap(circular_buffer_ext& other) + void swap(circular_buffer_ext& other) ETL_NOEXCEPT { using ETL_OR_STD::swap; // Allow ADL swap(this->in, other.in); swap(this->out, other.out); swap(this->pbuffer, other.pbuffer); + swap(this->buffer_size, other.buffer_size); + +#if defined(ETL_DEBUG_COUNT) + swap(this->etl_debug_count, other.etl_debug_count); +#endif } //************************************************************************* diff --git a/include/etl/debug_count.h b/include/etl/debug_count.h index aa81274f3..5b6bd5be7 100644 --- a/include/etl/debug_count.h +++ b/include/etl/debug_count.h @@ -31,24 +31,27 @@ SOFTWARE. #ifndef ETL_DEBUG_COUNT_INCLUDED #define ETL_DEBUG_COUNT_INCLUDED -#include #include +#include -#include "platform.h" #include "atomic.h" +#include "platform.h" ///\defgroup debug_count debug count ///\ingroup utilities #if defined(ETL_DEBUG_COUNT) -#define ETL_DECLARE_DEBUG_COUNT etl::debug_count etl_debug_count; -#define ETL_INCREMENT_DEBUG_COUNT ++etl_debug_count; -#define ETL_DECREMENT_DEBUG_COUNT --etl_debug_count; -#define ETL_ADD_DEBUG_COUNT(n) etl_debug_count += (n); -#define ETL_SUBTRACT_DEBUG_COUNT(n) etl_debug_count -= (n); -#define ETL_RESET_DEBUG_COUNT etl_debug_count.clear(); -#define ETL_OBJECT_RESET_DEBUG_COUNT(object) object.etl_debug_count.clear(); + #define ETL_DECLARE_DEBUG_COUNT etl::debug_count etl_debug_count; + #define ETL_SET_DEBUG_COUNT(n) etl_debug_count.set(n) + #define ETL_GET_DEBUG_COUNT etl_debug_count.get() + #define ETL_INCREMENT_DEBUG_COUNT ++etl_debug_count; + #define ETL_DECREMENT_DEBUG_COUNT --etl_debug_count; + #define ETL_ADD_DEBUG_COUNT(n) etl_debug_count += (n); + #define ETL_SUBTRACT_DEBUG_COUNT(n) etl_debug_count -= (n); + #define ETL_RESET_DEBUG_COUNT etl_debug_count.clear(); + #define ETL_OBJECT_RESET_DEBUG_COUNT(object) object.etl_debug_count.clear(); + #define ETL_OBJECT_GET_DEBUG_COUNT(object) object.etl_debug_count.get() namespace etl { @@ -62,7 +65,6 @@ namespace etl class debug_count { public: - debug_count() : count(0) { @@ -73,13 +75,13 @@ namespace etl assert(count == 0); } - debug_count& operator ++() + debug_count& operator++() { ++count; return *this; } - debug_count& operator --() + debug_count& operator--() { --count; assert(count >= 0); @@ -87,48 +89,85 @@ namespace etl } template - debug_count& operator +=(T n) + debug_count& operator+=(T n) { count += int32_t(n); return *this; } template - debug_count& operator -=(T n) + debug_count& operator-=(T n) { count -= int32_t(n); return *this; } - operator int32_t() + debug_count& operator=(const debug_count& other) + { + count.store(other.count.load()); + + return *this; + } + + #if ETL_HAS_ATOMIC + void swap(debug_count& other) ETL_NOEXCEPT // NOT ATOMIC + { + int32_t temp = other.count.load(); + other.count.store(count.load()); + count.store(temp); + } + #else + void swap(debug_count& other) ETL_NOEXCEPT + { + swap(count, other.count); + } + #endif + + operator int32_t() const { return count; } + int32_t get() const + { + return int32_t(count); + } + + void set(int32_t n) + { + count = n; + } + void clear() { count = 0; } - private: + friend static void swap(etl::debug_count& lhs, etl::debug_count& rhs) + { + lhs.swap(rhs); + } -#if ETL_HAS_ATOMIC + private: + #if ETL_HAS_ATOMIC etl::atomic_int32_t count; -#else + #else int32_t count; -#endif + #endif }; - -} +} // namespace etl #else #define ETL_DECLARE_DEBUG_COUNT + #define ETL_SET_DEBUG_COUNT(n) + #define ETL_GET_DEBUG_COUNT #define ETL_INCREMENT_DEBUG_COUNT #define ETL_DECREMENT_DEBUG_COUNT #define ETL_ADD_DEBUG_COUNT(n) #define ETL_SUBTRACT_DEBUG_COUNT(n) #define ETL_RESET_DEBUG_COUNT #define ETL_OBJECT_RESET_DEBUG_COUNT(object) -#endif // ETL_DEBUG_COUNT + #define ETL_OBJECT_GET_DEBUG_COUNT(object) +#endif // ETL_DEBUG_COUNT #endif diff --git a/test/test_circular_buffer.cpp b/test/test_circular_buffer.cpp index 9eba942c1..7f59080a9 100644 --- a/test/test_circular_buffer.cpp +++ b/test/test_circular_buffer.cpp @@ -74,7 +74,6 @@ namespace Data data = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; Compare compare = { Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; - CHECK(data.begin() != data.end()); CHECK(data.cbegin() != data.cend()); CHECK_EQUAL(compare.size(), data.size()); @@ -188,6 +187,48 @@ namespace CHECK(isEqual); } + //************************************************************************* + TEST(test_iterator_to_pointer_operator) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data; + data.push(test.begin(), test.end()); + + Data::iterator itr = data.begin(); + + CHECK_EQUAL(test[0].value, (itr++)->value); + CHECK_EQUAL(test[1].value, (itr++)->value); + CHECK_EQUAL(test[2].value, (itr++)->value); + CHECK_EQUAL(test[3].value, (itr++)->value); + CHECK_EQUAL(test[4].value, (itr++)->value); + CHECK_EQUAL(test[5].value, (itr++)->value); + CHECK_EQUAL(test[6].value, (itr++)->value); + CHECK_EQUAL(test[7].value, (itr++)->value); + CHECK_EQUAL(test[8].value, (itr++)->value); + CHECK_EQUAL(test[9].value, (itr++)->value); + } + + //************************************************************************* + TEST(test_const_iterator_to_pointer_operator) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data; + data.push(test.begin(), test.end()); + + Data::const_iterator itr = data.begin(); + + CHECK_EQUAL(test[0].value, (itr++)->value); + CHECK_EQUAL(test[1].value, (itr++)->value); + CHECK_EQUAL(test[2].value, (itr++)->value); + CHECK_EQUAL(test[3].value, (itr++)->value); + CHECK_EQUAL(test[4].value, (itr++)->value); + CHECK_EQUAL(test[5].value, (itr++)->value); + CHECK_EQUAL(test[6].value, (itr++)->value); + CHECK_EQUAL(test[7].value, (itr++)->value); + CHECK_EQUAL(test[8].value, (itr++)->value); + CHECK_EQUAL(test[9].value, (itr++)->value); + } + //************************************************************************* TEST(test_push_full_range_reverse_iterator) { @@ -894,18 +935,19 @@ namespace //************************************************************************* TEST(test_swap) { - // Over-write by 3 - Compare input{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; - Compare output{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4") }; + Compare input2{ Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; Data data1; Data data2; - data1.push(input.begin(), input.end()); - data2.push(input.rbegin(), input.rend()); + data1.push(input1.begin(), input1.end()); + data2.push(input2.begin(), input2.end()); swap(data1, data2); - CHECK(std::equal(output.rbegin() + 3, output.rend(), data1.begin())); - CHECK(std::equal(output.begin() + 3, output.end(), data2.begin())); + CHECK_EQUAL(input1.size(), data2.size()); + CHECK_EQUAL(input2.size(), data1.size()); + CHECK(std::equal(input1.begin(), input1.end(), data2.begin())); + CHECK(std::equal(input2.begin(), input2.end(), data1.begin())); } //************************************************************************* diff --git a/test/test_circular_buffer_external_buffer.cpp b/test/test_circular_buffer_external_buffer.cpp index 1fac21421..1c1d08aa7 100644 --- a/test/test_circular_buffer_external_buffer.cpp +++ b/test/test_circular_buffer_external_buffer.cpp @@ -197,6 +197,48 @@ namespace CHECK(isEqual); } + //************************************************************************* + TEST(test_iterator_to_pointer_operator) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Data::iterator itr = data.begin(); + + CHECK_EQUAL(test[0].value, (itr++)->value); + CHECK_EQUAL(test[1].value, (itr++)->value); + CHECK_EQUAL(test[2].value, (itr++)->value); + CHECK_EQUAL(test[3].value, (itr++)->value); + CHECK_EQUAL(test[4].value, (itr++)->value); + CHECK_EQUAL(test[5].value, (itr++)->value); + CHECK_EQUAL(test[6].value, (itr++)->value); + CHECK_EQUAL(test[7].value, (itr++)->value); + CHECK_EQUAL(test[8].value, (itr++)->value); + CHECK_EQUAL(test[9].value, (itr++)->value); + } + + //************************************************************************* + TEST(test_const_iterator_to_pointer_operator) + { + Compare test{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9") }; + Data data(buffer1.raw, SIZE); + data.push(test.begin(), test.end()); + + Data::const_iterator itr = data.begin(); + + CHECK_EQUAL(test[0].value, (itr++)->value); + CHECK_EQUAL(test[1].value, (itr++)->value); + CHECK_EQUAL(test[2].value, (itr++)->value); + CHECK_EQUAL(test[3].value, (itr++)->value); + CHECK_EQUAL(test[4].value, (itr++)->value); + CHECK_EQUAL(test[5].value, (itr++)->value); + CHECK_EQUAL(test[6].value, (itr++)->value); + CHECK_EQUAL(test[7].value, (itr++)->value); + CHECK_EQUAL(test[8].value, (itr++)->value); + CHECK_EQUAL(test[9].value, (itr++)->value); + } + //************************************************************************* TEST(test_push_full_range_reverse_iterator) { @@ -903,18 +945,22 @@ namespace //************************************************************************* TEST(test_swap) { - // Over-write by 3 - Compare input{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; - Compare output{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4"), Ndc("5"), Ndc("6"), Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; - Data data1(buffer1.raw, SIZE); - Data data2(buffer2.raw, SIZE); - data1.push(input.begin(), input.end()); - data2.push(input.rbegin(), input.rend()); + etl::uninitialized_buffer_of buffer1; + etl::uninitialized_buffer_of buffer2; + + Compare input1{ Ndc("0"), Ndc("1"), Ndc("2"), Ndc("3"), Ndc("4") }; + Compare input2{ Ndc("7"), Ndc("8"), Ndc("9"), Ndc("10"), Ndc("11"), Ndc("12") }; + Data data1(buffer1.raw, 5U); + Data data2(buffer2.raw, 6U); + data1.push(input1.begin(), input1.end()); + data2.push(input2.begin(), input2.end()); swap(data1, data2); - CHECK(std::equal(output.rbegin() + 3, output.rend(), data1.begin())); - CHECK(std::equal(output.begin() + 3, output.end(), data2.begin())); + CHECK_EQUAL(input1.size(), data2.size()); + CHECK_EQUAL(input2.size(), data1.size()); + CHECK(std::equal(input1.begin(), input1.end(), data2.begin())); + CHECK(std::equal(input2.begin(), input2.end(), data1.begin())); } //************************************************************************* diff --git a/test/vs2019/etl.vcxproj b/test/vs2019/etl.vcxproj index 5d0aa29e1..9a1a1e69b 100644 --- a/test/vs2019/etl.vcxproj +++ b/test/vs2019/etl.vcxproj @@ -2655,6 +2655,62 @@ + + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true true @@ -2756,6 +2812,62 @@ + + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true true @@ -11975,6 +12087,7 @@ + @@ -11986,6 +12099,62 @@ + + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true true diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index c64a775c4..d7fccd5ff 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -217,9 +217,6 @@ {de372ec9-d193-4956-871f-065414a9d3be} - - {1c718339-9f2d-4c83-a39e-66b7300df135} - @@ -1308,6 +1305,12 @@ Tests\Error Handler\Log Errors + + Tests\Error Handler\Exceptions + + + Tests\Error Handler\Exceptions_And_Log_Errors + @@ -3305,6 +3308,12 @@ Tests\Error Handler\Log Errors + + Tests\Error Handler\Exceptions + + + Tests\Error Handler\Exceptions_And_Log_Errors + @@ -3409,6 +3418,9 @@ Tests\Scripts + + Tests\Scripts + @@ -3447,6 +3459,12 @@ Tests\Error Handler\Log Errors + + Tests\Error Handler\Exceptions + + + Tests\Error Handler\Exceptions_And_Log_Errors + From df017592277f0d52f0697fc8a33c3ccfd56cd9fe Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 24 Jul 2022 13:01:07 +0100 Subject: [PATCH 05/10] Optimised container move for external buffers --- .gitignore | 7 +++++++ include/etl/forward_list.h | 23 +++++++---------------- include/etl/list.h | 20 ++++++-------------- 3 files changed, 20 insertions(+), 30 deletions(-) diff --git a/.gitignore b/.gitignore index 500914621..124c39b03 100644 --- a/.gitignore +++ b/.gitignore @@ -363,3 +363,10 @@ test/etl_initializer_list/etl_initializer_list.vcxproj.filters test/etl_initializer_list/build-make test/vs-build test/etl_error_handler/build-log_errors-GCC-Debug +test/etl_error_handler/build-exceptions_and_log_errors-GCC-Debug +test/etl_error_handler/build-exceptions-GCC-Debug +test/etl_error_handler/exceptions_and_log_errors/.vs +test/etl_error_handler/exceptions/build-make +test/etl_error_handler/log_errors/build-make +test/etl_error_handler/log_errors_and_exceptions/build-make +test/etl_error_handler/log_errors_and_exceptions/.vs diff --git a/include/etl/forward_list.h b/include/etl/forward_list.h index 7f8d03a92..b33cb029a 100644 --- a/include/etl/forward_list.h +++ b/include/etl/forward_list.h @@ -1485,34 +1485,25 @@ namespace etl if (!rhs.empty()) { - node_t* p_last_node = &this->start_node; - node_t* p_rhs_node = rhs.start_node.next; - // Are we using the same pool? if (this->get_node_pool() == rhs.get_node_pool()) { - // Just link the nodes to the new forward_list. - do - { - node_t* p_node = p_rhs_node; - p_rhs_node = p_rhs_node->next; - - insert_node_after(*p_last_node, *p_node); + // Just link the nodes to this list. + this->start_node.next = rhs.start_node.next; - p_last_node = p_node; - - ETL_INCREMENT_DEBUG_COUNT; - - } while (p_rhs_node != ETL_NULLPTR); + ETL_SET_DEBUG_COUNT(ETL_OBJECT_GET_DEBUG_COUNT(rhs)); ETL_OBJECT_RESET_DEBUG_COUNT(rhs); rhs.start_node.next = ETL_NULLPTR; } else { + node_t* p_last_node = &this->start_node; + node_t* p_rhs_node = rhs.start_node.next; + // Add all of the elements. etl::iforward_list::iterator first = rhs.begin(); - etl::iforward_list::iterator last = rhs.end(); + etl::iforward_list::iterator last = rhs.end(); while (first != last) { diff --git a/include/etl/list.h b/include/etl/list.h index 82c157094..c6a525619 100644 --- a/include/etl/list.h +++ b/include/etl/list.h @@ -1824,7 +1824,7 @@ namespace etl #if ETL_USING_CPP11 //************************************************************************* - /// Move a forward list + /// Move a list //************************************************************************* void move_container(ilist&& rhs) { @@ -1837,21 +1837,13 @@ namespace etl // Are we using the same pool? if (this->get_node_pool() == rhs.get_node_pool()) { - node_t* p_rhs_node = &rhs.get_head(); + // Just link the nodes to this list. + join(terminal_node, rhs.get_head()); + join(rhs.get_tail(), terminal_node); - // Just link the nodes to the new forward_list. - do - { - ETL_ASSERT(!full(), ETL_ERROR(list_full)); - - node_t* p_node = p_rhs_node; - p_rhs_node = p_rhs_node->next; - insert_node(terminal_node, *p_node); - - ETL_INCREMENT_DEBUG_COUNT; - - } while (p_rhs_node != &rhs.terminal_node); + ETL_SET_DEBUG_COUNT(ETL_OBJECT_GET_DEBUG_COUNT(rhs)); + // Clear the rhs. ETL_OBJECT_RESET_DEBUG_COUNT(rhs); rhs.join(rhs.terminal_node, rhs.terminal_node); } From 648b2490e0bb053073ac3249f8bc0cc33121624d Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 24 Jul 2022 13:01:22 +0100 Subject: [PATCH 06/10] Comment edits --- include/etl/flat_map.h | 2 +- include/etl/flat_multimap.h | 2 +- include/etl/flat_multiset.h | 2 +- include/etl/flat_set.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/etl/flat_map.h b/include/etl/flat_map.h index a44a2e5dc..2947142e4 100644 --- a/include/etl/flat_map.h +++ b/include/etl/flat_map.h @@ -963,7 +963,7 @@ namespace etl #if ETL_USING_CPP11 //************************************************************************* /// Move a flat_map. - /// Assumes the rhs is initialised and empty. + /// Assumes the flat_map is initialised and empty. //************************************************************************* void move_container(iflat_map&& rhs) { diff --git a/include/etl/flat_multimap.h b/include/etl/flat_multimap.h index 391e331d2..cf9e7d92b 100644 --- a/include/etl/flat_multimap.h +++ b/include/etl/flat_multimap.h @@ -848,7 +848,7 @@ namespace etl #if ETL_USING_CPP11 //************************************************************************* /// Move a flat_multimap. - /// Assumes the rhs is initialised and empty. + /// Assumes the flat_multimap is initialised and empty. //************************************************************************* void move_container(iflat_multimap&& rhs) { diff --git a/include/etl/flat_multiset.h b/include/etl/flat_multiset.h index fad898165..203083499 100644 --- a/include/etl/flat_multiset.h +++ b/include/etl/flat_multiset.h @@ -801,7 +801,7 @@ namespace etl #if ETL_USING_CPP11 //************************************************************************* /// Move a flat_multimap. - /// Assumes the rhs is initialised and empty. + /// Assumes the flat_multimap is initialised and empty. //************************************************************************* void move_container(iflat_multiset&& rhs) { diff --git a/include/etl/flat_set.h b/include/etl/flat_set.h index f764ba1d5..75d89d012 100644 --- a/include/etl/flat_set.h +++ b/include/etl/flat_set.h @@ -888,7 +888,7 @@ namespace etl #if ETL_USING_CPP11 //************************************************************************* /// Move a flat_set. - /// Assumes the rhs is initialised and empty. + /// Assumes the flat_set is initialised and empty. //************************************************************************* void move_container(iflat_set&& rhs) { From 72740b52251957ee1ab6f8a156b60678a361baec Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 24 Jul 2022 17:24:46 +0100 Subject: [PATCH 07/10] Fixed swap function for circular_buffer_ext Fixed circular_buffer iterator -> operators Added functions and macros to etl::debug_count --- include/etl/circular_buffer.h | 2 +- include/etl/debug_count.h | 13 ++++++++----- version.txt | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/etl/circular_buffer.h b/include/etl/circular_buffer.h index 006df3bb6..5f8ccddf6 100644 --- a/include/etl/circular_buffer.h +++ b/include/etl/circular_buffer.h @@ -1304,7 +1304,7 @@ namespace etl swap(this->buffer_size, other.buffer_size); #if defined(ETL_DEBUG_COUNT) - swap(this->etl_debug_count, other.etl_debug_count); + this->etl_debug_count.swap(other.etl_debug_count); #endif } diff --git a/include/etl/debug_count.h b/include/etl/debug_count.h index 5b6bd5be7..8fb497880 100644 --- a/include/etl/debug_count.h +++ b/include/etl/debug_count.h @@ -62,6 +62,8 @@ namespace etl /// Does nothing in a non-debug build. ///\ingroup reference //*************************************************************************** + + class debug_count { public: @@ -143,11 +145,6 @@ namespace etl count = 0; } - friend static void swap(etl::debug_count& lhs, etl::debug_count& rhs) - { - lhs.swap(rhs); - } - private: #if ETL_HAS_ATOMIC etl::atomic_int32_t count; @@ -157,6 +154,12 @@ namespace etl }; } // namespace etl + +static void swap(etl::debug_count& lhs, etl::debug_count& rhs) +{ + lhs.swap(rhs); +} + #else #define ETL_DECLARE_DEBUG_COUNT #define ETL_SET_DEBUG_COUNT(n) diff --git a/version.txt b/version.txt index 48834758c..2fbada118 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -20.31.2 +20.31.3 From 23bf8507852988266de9b958dab133ae864ea7a0 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 24 Jul 2022 17:26:39 +0100 Subject: [PATCH 08/10] Updated release versions --- 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 | 8 ++++++++ 6 files changed, 13 insertions(+), 5 deletions(-) diff --git a/arduino/library-arduino.json b/arduino/library-arduino.json index ecdadda0b..13da623f0 100644 --- a/arduino/library-arduino.json +++ b/arduino/library-arduino.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library - Arduino", - "version": "20.31.2", + "version": "20.31.3", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/arduino/library-arduino.properties b/arduino/library-arduino.properties index b8a144446..7aab941fb 100644 --- a/arduino/library-arduino.properties +++ b/arduino/library-arduino.properties @@ -1,5 +1,5 @@ name=Embedded Template Library - Arduino -version=20.31.2 +version=20.31.3 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/include/etl/version.h b/include/etl/version.h index 7a6072911..89c308f95 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 31 -#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 5d3fbdea8..43cfc27b4 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library", - "version": "20.31.2", + "version": "20.31.3", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/library.properties b/library.properties index fe2fe6fd3..5400b6f3a 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Embedded Template Library -version=20.31.2 +version=20.31.3 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/support/Release notes.txt b/support/Release notes.txt index 28ab32df9..2044dce72 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,3 +1,11 @@ +=============================================================================== +20.31.3 +#569 Fixed swap function for circular_buffer_ext +#568 Fixed circular_buffer iterator -> operators +Optimised container move for external buffers +Added functions and macros to etl::debug_count +Added tests for error handler macros + =============================================================================== 20.31.2 #567 error-handler: only return when the condition is false From ea49e6a80fe31cf4af48527d009aeded884abd74 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 24 Jul 2022 17:43:46 +0100 Subject: [PATCH 09/10] Updated generators scripts --- include/etl/generators/generate.bat | 3 ++- scripts/generator_test.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/etl/generators/generate.bat b/include/etl/generators/generate.bat index 889542b2c..2f3f7948a 100644 --- a/include/etl/generators/generate.bat +++ b/include/etl/generators/generate.bat @@ -5,4 +5,5 @@ python -m cogapp -d -e -o../smallest.h -DNTypes=16 smallest_generator.h python -m cogapp -d -e -o../type_traits.h -DIsOneOf=16 type_traits_generator.h python -m cogapp -d -e -o../type_lookup.h -DNTypes=16 type_lookup_generator.h python -m cogapp -d -e -o../type_select.h -DNTypes=16 type_select_generator.h -python -m cogapp -d -e -o../message_packet.h -DHandlers=16 message_packet_generator.h \ No newline at end of file +python -m cogapp -d -e -o../message_packet.h -DHandlers=16 message_packet_generator.h +python -m cogapp -d -e -o../variant_pool.h -DNTypes=16 variant_pool_generator.h \ No newline at end of file diff --git a/scripts/generator_test.py b/scripts/generator_test.py index 079e3c03d..cad66737a 100644 --- a/scripts/generator_test.py +++ b/scripts/generator_test.py @@ -3,7 +3,7 @@ from pathlib import Path import filecmp -root_path = Path(abspath(__file__)).parent +root_path = Path(abspath(__file__)).parent.parent generator_folder = root_path/"include" / "etl" / "generators" # Create folder where generator outputs can go for purpose of comparison From e4cf3909569527bf392342c9c964889f9b595311 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 24 Jul 2022 17:45:37 +0100 Subject: [PATCH 10/10] Updated variant_pool generator --- .../etl/generators/variant_pool_generator.h | 432 ++++++++++-------- include/etl/variant_pool.h | 52 ++- 2 files changed, 267 insertions(+), 217 deletions(-) diff --git a/include/etl/generators/variant_pool_generator.h b/include/etl/generators/variant_pool_generator.h index 8a53244f0..22f7dc3eb 100644 --- a/include/etl/generators/variant_pool_generator.h +++ b/include/etl/generators/variant_pool_generator.h @@ -66,69 +66,52 @@ cog.outl("//******************************************************************** #include #include "platform.h" -#include "error_handler.h" -#include "exception.h" -#include "largest.h" +#include "pool.h" #include "type_traits.h" -#include "alignment.h" #include "static_assert.h" -#include "type_lookup.h" -#include "pool.h" - -#include "utility.h" +#include "largest.h" namespace etl { - //*************************************************************************** - class variant_pool_exception : public etl::exception - { - public: - - variant_pool_exception(string_type reason_, string_type file_name_, numeric_type line_number_) - : exception(reason_, file_name_, line_number_) - { - } - }; - - //*************************************************************************** - class variant_pool_cannot_create : public etl::variant_pool_exception - { - public: - - variant_pool_cannot_create(string_type file_name_, numeric_type line_number_) - : variant_pool_exception(ETL_ERROR_TEXT("variant_pool:cannot create", ETL_VARIANT_POOL_FILE_ID"A"), file_name_, line_number_) - { - } - }; - - //*************************************************************************** - class variant_pool_did_not_create : public etl::variant_pool_exception - { - public: - - variant_pool_did_not_create(string_type file_name_, numeric_type line_number_) - : variant_pool_exception(ETL_ERROR_TEXT("variant_pool:did not create", ETL_VARIANT_POOL_FILE_ID"B"), file_name_, line_number_) - { - } - }; - //*************************************************************************** /*[[[cog import cog cog.outl("template " % int(NTypes)) + cog.outl("class variant_pool") + cog.out(" : public etl::generic_pool<") + cog.out("etl::largest<") + for n in range(1, int(NTypes)): + cog.out("T%s, " % n) + cog.outl("T%s>::size," % int(NTypes)) + cog.out(" etl::largest<") + for n in range(1, int(NTypes)): + cog.out("T%s, " % n) + cog.outl("T%s>::alignment," % int(NTypes)) + cog.outl(" MAX_SIZE_>") ]]]*/ /*[[[end]]]*/ - class variant_pool { public: + /*[[[cog + import cog + cog.out("typedef etl::generic_pool<") + cog.out("etl::largest<") + for n in range(1, int(NTypes)): + cog.out("T%s, " % n) + cog.outl("T%s>::size," % int(NTypes)) + cog.out(" etl::largest<") + for n in range(1, int(NTypes)): + cog.out("T%s, " % n) + cog.outl("T%s>::alignment," % int(NTypes)) + cog.outl(" MAX_SIZE_> base_t;") + ]]]*/ + /*[[[end]]]*/ + static const size_t MAX_SIZE = MAX_SIZE_; //************************************************************************* @@ -157,23 +140,7 @@ namespace etl ]]]*/ /*[[[end]]]*/ - T* p = ETL_NULLPTR; - - if (pool.full()) - { - ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create)); - } - else - { - p = pool.template allocate(); - - if (p != ETL_NULLPTR) - { - new (p) T(); - } - } - - return p; + return base_t::template create(); } //************************************************************************* @@ -194,23 +161,7 @@ namespace etl ]]]*/ /*[[[end]]]*/ - T* p = ETL_NULLPTR; - - if (pool.full()) - { - ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create)); - } - else - { - p = pool.template allocate(); - - if (p != ETL_NULLPTR) - { - new (p) T(p1); - } - } - - return p; + return base_t::template create(p1); } //************************************************************************* @@ -231,23 +182,7 @@ namespace etl ]]]*/ /*[[[end]]]*/ - T* p = ETL_NULLPTR; - - if (pool.full()) - { - ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create)); - } - else - { - p = pool.template allocate(); - - if (p != ETL_NULLPTR) - { - new (p) T(p1, p2); - } - } - - return p; + return base_t::template create(p1, p2); } //************************************************************************* @@ -268,23 +203,7 @@ namespace etl ]]]*/ /*[[[end]]]*/ - T* p = ETL_NULLPTR; - - if (pool.full()) - { - ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create)); - } - else - { - p = pool.template allocate(); - - if (p != ETL_NULLPTR) - { - new (p) T(p1, p2, p3); - } - } - - return p; + return base_t::template create(p1, p2, p3); } //************************************************************************* @@ -305,23 +224,7 @@ namespace etl ]]]*/ /*[[[end]]]*/ - T* p = ETL_NULLPTR; - - if (pool.full()) - { - ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create)); - } - else - { - p = pool.template allocate(); - - if (p != ETL_NULLPTR) - { - new (p) T(p1, p2, p3, p4); - } - } - - return p; + return base_t::template create(p1, p2, p3, p4); } #else //************************************************************************* @@ -342,23 +245,7 @@ namespace etl ]]]*/ /*[[[end]]]*/ - T* p = ETL_NULLPTR; - - if (pool.full()) - { - ETL_ASSERT(false, ETL_ERROR(etl::variant_pool_cannot_create)); - } - else - { - p = pool.template allocate(); - - if (p != ETL_NULLPTR) - { - new (p) T(ETL_OR_STD::forward(args)...); - } - } - - return p; + return base_t::template create(args...); } #endif @@ -379,24 +266,13 @@ namespace etl cog.outl("T%s>::value ||" % int(NTypes)) for n in range(1, int(NTypes)): - cog.outl(" etl::is_base_of::value ||" % n) - cog.outl(" etl::is_base_of::value), \"Invalid type\");" % int(NTypes)) + cog.outl(" etl::is_base_of::value ||" % n) + cog.outl(" etl::is_base_of::value), \"Invalid type\");" % int(NTypes)) ]]]*/ /*[[[end]]]*/ - p->~T(); - - void* vp = reinterpret_cast(const_cast(p)); - - if (pool.is_in_pool(vp)) - { - pool.release(vp); - } - else - { - ETL_ASSERT(false, ETL_ERROR(variant_pool_did_not_create)); - } + base_t::destroy(p); } //************************************************************************* @@ -407,66 +283,222 @@ namespace etl return MAX_SIZE; } + private: + + variant_pool(const variant_pool&) ETL_DELETE; + variant_pool& operator =(const variant_pool&) ETL_DELETE; + }; + + //*************************************************************************** + /*[[[cog + import cog + cog.outl("template " % int(NTypes)) + cog.outl("class variant_pool_ext") + cog.out(" : public etl::generic_pool_ext<") + cog.out("etl::largest<") + for n in range(1, int(NTypes)): + cog.out("T%s, " % n) + cog.outl("T%s>::size," % int(NTypes)) + cog.out(" etl::largest<") + for n in range(1, int(NTypes)): + cog.out("T%s, " % n) + cog.outl("T%s>::alignment>" % int(NTypes)) + ]]]*/ + /*[[[end]]]*/ + { + public: + + /*[[[cog + import cog + cog.out("typedef etl::generic_pool_ext<") + cog.out("etl::largest<") + for n in range(1, int(NTypes)): + cog.out("T%s, " % n) + cog.outl("T%s>::size," % int(NTypes)) + cog.out(" etl::largest<") + for n in range(1, int(NTypes)): + cog.out("T%s, " % n) + cog.outl("T%s>::alignment> base_t;" % int(NTypes)) + ]]]*/ + /*[[[end]]]*/ + //************************************************************************* - /// Returns the number of free items in the variant_pool. + /// Default constructor. //************************************************************************* - size_t available() const + variant_pool_ext(typename base_t::element* buffer, size_t size) + : base_t(buffer, size) { - return pool.available(); + } + +#if ETL_CPP11_NOT_SUPPORTED || ETL_USING_STLPORT + //************************************************************************* + /// Creates the object. Default constructor. + //************************************************************************* + template + T* create() + { + /*[[[cog + import cog + cog.out("ETL_STATIC_ASSERT((etl::is_one_of::value), \"Unsupported type\");" % int(NTypes)) + ]]]*/ + /*[[[end]]]*/ + + return base_t::template create(); + } + + //************************************************************************* + /// Creates the object. One parameter constructor. + //************************************************************************* + template + T* create(const TP1& p1) + { + /*[[[cog + import cog + cog.out("ETL_STATIC_ASSERT((etl::is_one_of::value), \"Unsupported type\");" % int(NTypes)) + ]]]*/ + /*[[[end]]]*/ + + return base_t::template create(p1); } //************************************************************************* - /// Returns the number of allocated items in the variant_pool. + /// Creates the object. Two parameter constructor. //************************************************************************* - size_t size() const + template + T* create(const TP1& p1, const TP2& p2) { - return pool.size(); + /*[[[cog + import cog + cog.out("ETL_STATIC_ASSERT((etl::is_one_of::value), \"Unsupported type\");" % int(NTypes)) + ]]]*/ + /*[[[end]]]*/ + + return base_t::template create(p1, p2); } //************************************************************************* - /// Checks to see if there are no allocated items in the variant_pool. - /// \return true if there are none allocated. + /// Creates the object. Three parameter constructor. //************************************************************************* - bool empty() const + template + T* create(const TP1& p1, const TP2& p2, const TP3& p3) { - return pool.empty(); + /*[[[cog + import cog + cog.out("ETL_STATIC_ASSERT((etl::is_one_of::value), \"Unsupported type\");" % int(NTypes)) + ]]]*/ + /*[[[end]]]*/ + + return base_t::template create(p1, p2, p3); } //************************************************************************* - /// Checks to see if there are no free items in the variant_pool. - /// \return true if there are none free. + /// Creates the object. Four parameter constructor. //************************************************************************* - bool full() const + template + T* create(const TP1& p1, const TP2& p2, const TP3& p3, const TP4& p4) { - return pool.full(); + /*[[[cog + import cog + cog.out("ETL_STATIC_ASSERT((etl::is_one_of::value), \"Unsupported type\");" % int(NTypes)) + ]]]*/ + /*[[[end]]]*/ + + return base_t::template create(p1, p2, p3, p4); } +#else + //************************************************************************* + /// Creates the object from a type. Variadic parameter constructor. + //************************************************************************* + template + T* create(Args&&... args) + { + /*[[[cog + import cog + cog.out("ETL_STATIC_ASSERT((etl::is_one_of::value), \"Unsupported type\");" % int(NTypes)) + ]]]*/ + /*[[[end]]]*/ - private: + return base_t::template create(args...); + } +#endif - variant_pool(const variant_pool&); - variant_pool& operator =(const variant_pool&); + //************************************************************************* + /// Destroys the object. + //************************************************************************* + template + void destroy(const T* const p) + { + /*[[[cog + import cog + cog.out("ETL_STATIC_ASSERT((etl::is_one_of::value ||" % int(NTypes)) - // The pool. - /*[[[cog - import cog - cog.out("etl::generic_pool::size," % int(NTypes)) + for n in range(1, int(NTypes)): + cog.outl(" etl::is_base_of::value ||" % n) + cog.outl(" etl::is_base_of::value), \"Invalid type\");" % int(NTypes)) - cog.out(" etl::largest<") - for n in range(1, int(NTypes)): - cog.out("T%s, " % n) - if n % 16 == 0: - cog.outl("") - cog.out(" ") - cog.outl("T%s>::alignment," % int(NTypes)) - cog.outl(" MAX_SIZE> pool;") - ]]]*/ - /*[[[end]]]*/ + ]]]*/ + /*[[[end]]]*/ + + base_t::destroy(p); + } + + //************************************************************************* + /// Returns the maximum number of items in the variant_pool. + //************************************************************************* + size_t max_size() const + { + return base_t::max_size(); + } + + private: + + variant_pool_ext(const variant_pool_ext&) ETL_DELETE; + variant_pool_ext& operator =(const variant_pool_ext&) ETL_DELETE; }; } diff --git a/include/etl/variant_pool.h b/include/etl/variant_pool.h index 493bda301..42592cb70 100644 --- a/include/etl/variant_pool.h +++ b/include/etl/variant_pool.h @@ -79,9 +79,10 @@ namespace etl typename T14 = void, typename T15 = void, typename T16 = void> - class variant_pool : public etl::generic_pool::size, - etl::largest::alignment, - MAX_SIZE_> + class variant_pool + : public etl::generic_pool::size, + etl::largest::alignment, + MAX_SIZE_> { public: @@ -226,16 +227,20 @@ namespace etl typename T16 = void> class variant_pool_ext : public etl::generic_pool_ext::size, - etl::largest::alignment> { + etl::largest::alignment> + { public: + typedef etl::generic_pool_ext::size, - etl::largest::alignment> - base_t; + etl::largest::alignment> base_t; //************************************************************************* /// Default constructor. //************************************************************************* - variant_pool_ext(typename base_t::element* buffer, size_t size) : base_t(buffer, size) {} + variant_pool_ext(typename base_t::element* buffer, size_t size) + : base_t(buffer, size) + { + } #if ETL_CPP11_NOT_SUPPORTED || ETL_USING_STLPORT //************************************************************************* @@ -311,13 +316,23 @@ namespace etl template void destroy(const T* const p) { - ETL_STATIC_ASSERT( - (etl::is_one_of::value || etl::is_base_of::value || - etl::is_base_of::value || etl::is_base_of::value || etl::is_base_of::value || etl::is_base_of::value || - etl::is_base_of::value || etl::is_base_of::value || etl::is_base_of::value || etl::is_base_of::value || - etl::is_base_of::value || etl::is_base_of::value || etl::is_base_of::value || etl::is_base_of::value || - etl::is_base_of::value || etl::is_base_of::value || etl::is_base_of::value), - "Invalid type"); + ETL_STATIC_ASSERT((etl::is_one_of::value || + etl::is_base_of::value || + etl::is_base_of::value || + etl::is_base_of::value || + etl::is_base_of::value || + etl::is_base_of::value || + etl::is_base_of::value || + etl::is_base_of::value || + etl::is_base_of::value || + etl::is_base_of::value || + etl::is_base_of::value || + etl::is_base_of::value || + etl::is_base_of::value || + etl::is_base_of::value || + etl::is_base_of::value || + etl::is_base_of::value || + etl::is_base_of::value), "Invalid type"); base_t::destroy(p); } @@ -325,12 +340,15 @@ namespace etl //************************************************************************* /// Returns the maximum number of items in the variant_pool. //************************************************************************* - // redundant also declared in ipool::max_size() - size_t max_size() const { return base_t::max_size(); } + size_t max_size() const + { + return base_t::max_size(); + } private: + variant_pool_ext(const variant_pool_ext&) ETL_DELETE; - variant_pool_ext& operator=(const variant_pool_ext&) ETL_DELETE; + variant_pool_ext& operator =(const variant_pool_ext&) ETL_DELETE; }; }