From 18ab6457631100472039d8b49c2d75966a7e08b8 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 15 Oct 2022 14:28:58 +0100 Subject: [PATCH 01/60] Work-In-Progress --- .gitignore | 8 + include/etl/expected.h | 479 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 487 insertions(+) create mode 100644 include/etl/expected.h diff --git a/.gitignore b/.gitignore index dd68c752..d9577b4c 100644 --- a/.gitignore +++ b/.gitignore @@ -360,3 +360,11 @@ 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 examples/ArmTimerCallbacks - C++/ArmTimerCallbacks.uvoptx +test/vs2022/.vs +test/vs2022/random_clcg.csv +test/vs2022/random_hash.csv +test/vs2022/random_lsfr.csv +test/vs2022/random_lcg.csv +test/vs2022/random_mwc.csv +test/vs2022/random_pcg.csv +test/vs2022/random_xorshift.csv diff --git a/include/etl/expected.h b/include/etl/expected.h new file mode 100644 index 00000000..991625b7 --- /dev/null +++ b/include/etl/expected.h @@ -0,0 +1,479 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2022 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_EXPECTED_INCLUDED +#define ETL_EXPECTED_INCLUDED + +///\defgroup expected expected +///\ingroup utilities + +#include "platform.h" +#include "utility.h" + +namespace etl +{ + //*************************************************************************** + /// Unexpected type. + /// etl::unexpected represents an unexpected value stored in etl::expected. + //*************************************************************************** + template + class unexpected + { + public: + + //******************************************* + /// Copy constructor. + //******************************************* + ETL_CONSTEXPR unexpected(const unexpected& other) + : error_value(other.error_value) + { + } + + //******************************************* + /// Move constructor. + //******************************************* + ETL_CONSTEXPR unexpected(unexpected&& other) + : error_value(etl::move(other.error_value)) + { + } + +#if ETL_CPP11_SUPPORTED + //******************************************* + /// Construct from argument. + //******************************************* + template ::type, etl::unexpected>::value && + !etl::is_same::type, etl::in_place_t>::value, int>::type> + constexpr explicit unexpected(E&& e) + : error_value(etl::forward(e)) + { + } +#else + //******************************************* + /// Construct from argument. + //******************************************* + template + explicit unexpected(const E& e, typename etl::enable_if::type, etl::unexpected>::value && + !etl::is_same::type, etl::in_place_t>::value, int>::type = 0) + : error_value(e) + { + } +#endif + +#if ETL_CPP11_SUPPORTED + //******************************************* + /// Construct from arguments. + //******************************************* + template + constexpr explicit unexpected(etl::in_place_t, Args&&... args) + : error_value(etl::forward(args)...) + { + } + +#if ETL_HAS_INITIALIZER_LIST + //******************************************* + /// Construct from initializer_list and arguments. + //******************************************* + template + constexpr explicit unexpected(etl::in_place_t, std::initializer_list init, Args&&... args) + : error_value(init, etl::forward(args)...) + { + } +#endif + + //******************************************* + /// Assign from etl::unexpected. + //******************************************* + unexpected& operator =(const etl::unexpected& rhs) + { + error_value = rhs.error_value; + } + +#if ETL_CPP11_SUPPORTED + //******************************************* + /// Move assign from etl::unexpected. + //******************************************* + unexpected& operator =(etl::unexpected&& rhs) + { + error_value = etl::move(rhs.error_value); + } +#endif + + //******************************************* + /// Get the error. + //******************************************* + const TError& error() const + { + return error_type; + } + + //******************************************* + /// Swap with another etl::unexpected. + //******************************************* + swap(etl::unexpected& other) + { + using ETL_OR_STD::swap; + + swap(error_value, other.error_value); + } + + private: + + TError error_value; + }; + + //******************************************* + /// Equivalence operator. + //******************************************* + template + bool operator ==(const etl::unexpected& lhs, const etl::unexpected& rhs) + { + return lhs.error_value == rhs.error_value; + } + + //******************************************* + /// Swap etl::unexpected. + //******************************************* + template + void swap(etl::unexpected& lhs, etl::unexpected& rhs) + { + lhs.swap(rhs); + } + + //***************************************************************************** + /// unexpect_t + //***************************************************************************** + struct unexpect_t + { + explicit unexpect_t() + { + } + }; + + inline ETL_CONSTEXPR14 unexpect_t unexpect{}; + + //***************************************************************************** + /// Expected type. + //***************************************************************************** + template + class expected + { + public: + + typename TValue value_type; + typename TError error_type; + typename etl::unexpected unexpected_type; + +#if ETL_CPP11_SUPPORTED + template + using rebind = etl::expected; +#endif + + //******************************************* + /// Default constructor + //******************************************* + ETL_CONSTEXPR14 expected(const expected& other) ETL_NOEXCEPT + : data(TValue()) + { + } + + //******************************************* + /// Copy constructor + //******************************************* + ETL_CONSTEXPR14 expected(const expected& other) + : data(other.data) + { + } + +#if ETL_CPP11_SUPPORTED + //******************************************* + /// Move constructor + //******************************************* + ETL_CONSTEXPR14 expected(expected&& other) ETL_NOEXCEPT + : data(etl::move(other.data)) + { + } +#endif + + template + constexpr explicit() expected(const expected& other) + { + } + + template + constexpr explicit(expected(expected&& other) + { + } + +#if ETL_CPP11_SUPPORTED + template + constexpr explicit expected(U&& v) + { + } +#endif + + template + constexpr explicit expected(const etl::unexpected& e) + { + } + +#if ETL_CPP11_SUPPORTED + template + constexpr explicit expected(etl::unexpected&& e) + { + } +#endif + + constexpr explicit expected(etl::in_place_t) noexcept + { + } + + template + constexpr explicit expected(etl::in_place_t, Args&&... args) + { + } + + template + constexpr explicit expected(etl::in_place_t, std::initializer_list il, Args&&... args) + { + } + + template + constexpr explicit expected(etl::unexpect_t, Args&&... args) + { + } + + template + constexpr explicit expected(etl::unexpect_t, std::initializer_list il, Args&&... args) + { + } + +// //******************************************* +// // Construct from a value +// //******************************************* +// expected(const TValue& value) +// : data(value) +// { +// } +// +//#if ETL_CPP11_SUPPORTED +// //******************************************* +// // Move construct from a value +// //******************************************* +// expected(TValue&& value) +// : data(etl::move(value)) +// { +// } +//#endif + + ////******************************************* + ///// Construct from error + ////******************************************* + //expected(const TError& error) + // : data(error) + //{ + //} + + ////******************************************* + ///// Move construct from error + ////******************************************* + //expected(TError&& error) + // : data(etl::move(error)) + //{ + //} + + //******************************************* + /// Copy assign + //******************************************* + expected& operator =(const expected& other) + { + data = other.data; + return *this; + } + + //******************************************* + /// Move assign + //******************************************* + expected& operator =(expected&& other) + { + data = etl::move(other.data); + return *this; + } + + //******************************************* + /// Copy assign from value + //******************************************* + expected& operator =(const TValue& value) + { + data = value; + return *this; + } + + //******************************************* + /// Move assign from value + //******************************************* + expected& operator =(TValue&& value) + { + data = etl::move(value); + return *this; + } + + //******************************************* + /// Copy assign from error + //******************************************* + expected& operator =(const TError& error) + { + data = error; + return *this; + } + + //******************************************* + /// Move assign from error + //******************************************* + expected& operator =(TError&& error) + { + data = etl::move(error); + return *this; + } + + //******************************************* + /// Returns a const reference to the value. + /// Undefined if the expected does not contain an value. + //******************************************* + ETL_CONSTEXPR14 const TValue& value() const + { + return etl::get(data); + } + + //******************************************* + /// Returns an rvalue reference to the value. + /// Undefined if the expected does not contain an value. + //******************************************* + ETL_CONSTEXPR14 TValue&& value() + { + return etl::move(etl::get(etl::move(data))); + } + +#if ETL_CPP11_SUPPORTED + //******************************************* + /// + //******************************************* + template + ETL_CONSTEXPR14 TValue value_or(U&& default_value) const& + { + if (has_value()) + { + return value(); + } + else + { + return default_value; + } + } + + //******************************************* + /// + //******************************************* + template + ETL_CONSTEXPR14 TValue value_or(U&& default_value) && + { + if (has_value()) + { + return etl::move(value()); + } + else + { + return etl::move(default_value); + } + } +#else + //******************************************* + /// + //******************************************* + template + TValue value_or(const U& default_value) const + { + if (has_value()) + { + return value(); + } + else + { + return default_value; + } + } +#endif + + //******************************************* + /// Returns a const reference to the error. + /// Undefined if the expected does not contain an error. + //******************************************* + ETL_CONSTEXPR14 const TError& error() const + { + return etl::get(data); + } + +#if (ETL_CPP11_SUPPORTED) + //******************************************* + /// Returns an rvalue reference to the error. + /// Undefined if the expected does not contain an error. + //******************************************* + ETL_CONSTEXPR14 TError&& error() && + { + return etl::move(etl::get(data)); + } + + //******************************************* + /// Returns an rvalue reference to the error. + /// Undefined if the expected does not contain an error. + //******************************************* + ETL_CONSTEXPR14 TError&& error() const && + { + return etl::move(etl::get(data)); + } +#endif + + private: + + etl::variant data; + }; + + //***************************************************************************** + /// Result type. + /// Specialisation for void value type. + //***************************************************************************** + template + class expected + { + +} + + +#endif + From ddca5f554166906feb2551b7acd54b90b12d351e Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 15 Oct 2022 14:28:58 +0100 Subject: [PATCH 02/60] Work-In-Progress --- include/etl/expected.h | 479 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 479 insertions(+) create mode 100644 include/etl/expected.h diff --git a/include/etl/expected.h b/include/etl/expected.h new file mode 100644 index 00000000..991625b7 --- /dev/null +++ b/include/etl/expected.h @@ -0,0 +1,479 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2022 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_EXPECTED_INCLUDED +#define ETL_EXPECTED_INCLUDED + +///\defgroup expected expected +///\ingroup utilities + +#include "platform.h" +#include "utility.h" + +namespace etl +{ + //*************************************************************************** + /// Unexpected type. + /// etl::unexpected represents an unexpected value stored in etl::expected. + //*************************************************************************** + template + class unexpected + { + public: + + //******************************************* + /// Copy constructor. + //******************************************* + ETL_CONSTEXPR unexpected(const unexpected& other) + : error_value(other.error_value) + { + } + + //******************************************* + /// Move constructor. + //******************************************* + ETL_CONSTEXPR unexpected(unexpected&& other) + : error_value(etl::move(other.error_value)) + { + } + +#if ETL_CPP11_SUPPORTED + //******************************************* + /// Construct from argument. + //******************************************* + template ::type, etl::unexpected>::value && + !etl::is_same::type, etl::in_place_t>::value, int>::type> + constexpr explicit unexpected(E&& e) + : error_value(etl::forward(e)) + { + } +#else + //******************************************* + /// Construct from argument. + //******************************************* + template + explicit unexpected(const E& e, typename etl::enable_if::type, etl::unexpected>::value && + !etl::is_same::type, etl::in_place_t>::value, int>::type = 0) + : error_value(e) + { + } +#endif + +#if ETL_CPP11_SUPPORTED + //******************************************* + /// Construct from arguments. + //******************************************* + template + constexpr explicit unexpected(etl::in_place_t, Args&&... args) + : error_value(etl::forward(args)...) + { + } + +#if ETL_HAS_INITIALIZER_LIST + //******************************************* + /// Construct from initializer_list and arguments. + //******************************************* + template + constexpr explicit unexpected(etl::in_place_t, std::initializer_list init, Args&&... args) + : error_value(init, etl::forward(args)...) + { + } +#endif + + //******************************************* + /// Assign from etl::unexpected. + //******************************************* + unexpected& operator =(const etl::unexpected& rhs) + { + error_value = rhs.error_value; + } + +#if ETL_CPP11_SUPPORTED + //******************************************* + /// Move assign from etl::unexpected. + //******************************************* + unexpected& operator =(etl::unexpected&& rhs) + { + error_value = etl::move(rhs.error_value); + } +#endif + + //******************************************* + /// Get the error. + //******************************************* + const TError& error() const + { + return error_type; + } + + //******************************************* + /// Swap with another etl::unexpected. + //******************************************* + swap(etl::unexpected& other) + { + using ETL_OR_STD::swap; + + swap(error_value, other.error_value); + } + + private: + + TError error_value; + }; + + //******************************************* + /// Equivalence operator. + //******************************************* + template + bool operator ==(const etl::unexpected& lhs, const etl::unexpected& rhs) + { + return lhs.error_value == rhs.error_value; + } + + //******************************************* + /// Swap etl::unexpected. + //******************************************* + template + void swap(etl::unexpected& lhs, etl::unexpected& rhs) + { + lhs.swap(rhs); + } + + //***************************************************************************** + /// unexpect_t + //***************************************************************************** + struct unexpect_t + { + explicit unexpect_t() + { + } + }; + + inline ETL_CONSTEXPR14 unexpect_t unexpect{}; + + //***************************************************************************** + /// Expected type. + //***************************************************************************** + template + class expected + { + public: + + typename TValue value_type; + typename TError error_type; + typename etl::unexpected unexpected_type; + +#if ETL_CPP11_SUPPORTED + template + using rebind = etl::expected; +#endif + + //******************************************* + /// Default constructor + //******************************************* + ETL_CONSTEXPR14 expected(const expected& other) ETL_NOEXCEPT + : data(TValue()) + { + } + + //******************************************* + /// Copy constructor + //******************************************* + ETL_CONSTEXPR14 expected(const expected& other) + : data(other.data) + { + } + +#if ETL_CPP11_SUPPORTED + //******************************************* + /// Move constructor + //******************************************* + ETL_CONSTEXPR14 expected(expected&& other) ETL_NOEXCEPT + : data(etl::move(other.data)) + { + } +#endif + + template + constexpr explicit() expected(const expected& other) + { + } + + template + constexpr explicit(expected(expected&& other) + { + } + +#if ETL_CPP11_SUPPORTED + template + constexpr explicit expected(U&& v) + { + } +#endif + + template + constexpr explicit expected(const etl::unexpected& e) + { + } + +#if ETL_CPP11_SUPPORTED + template + constexpr explicit expected(etl::unexpected&& e) + { + } +#endif + + constexpr explicit expected(etl::in_place_t) noexcept + { + } + + template + constexpr explicit expected(etl::in_place_t, Args&&... args) + { + } + + template + constexpr explicit expected(etl::in_place_t, std::initializer_list il, Args&&... args) + { + } + + template + constexpr explicit expected(etl::unexpect_t, Args&&... args) + { + } + + template + constexpr explicit expected(etl::unexpect_t, std::initializer_list il, Args&&... args) + { + } + +// //******************************************* +// // Construct from a value +// //******************************************* +// expected(const TValue& value) +// : data(value) +// { +// } +// +//#if ETL_CPP11_SUPPORTED +// //******************************************* +// // Move construct from a value +// //******************************************* +// expected(TValue&& value) +// : data(etl::move(value)) +// { +// } +//#endif + + ////******************************************* + ///// Construct from error + ////******************************************* + //expected(const TError& error) + // : data(error) + //{ + //} + + ////******************************************* + ///// Move construct from error + ////******************************************* + //expected(TError&& error) + // : data(etl::move(error)) + //{ + //} + + //******************************************* + /// Copy assign + //******************************************* + expected& operator =(const expected& other) + { + data = other.data; + return *this; + } + + //******************************************* + /// Move assign + //******************************************* + expected& operator =(expected&& other) + { + data = etl::move(other.data); + return *this; + } + + //******************************************* + /// Copy assign from value + //******************************************* + expected& operator =(const TValue& value) + { + data = value; + return *this; + } + + //******************************************* + /// Move assign from value + //******************************************* + expected& operator =(TValue&& value) + { + data = etl::move(value); + return *this; + } + + //******************************************* + /// Copy assign from error + //******************************************* + expected& operator =(const TError& error) + { + data = error; + return *this; + } + + //******************************************* + /// Move assign from error + //******************************************* + expected& operator =(TError&& error) + { + data = etl::move(error); + return *this; + } + + //******************************************* + /// Returns a const reference to the value. + /// Undefined if the expected does not contain an value. + //******************************************* + ETL_CONSTEXPR14 const TValue& value() const + { + return etl::get(data); + } + + //******************************************* + /// Returns an rvalue reference to the value. + /// Undefined if the expected does not contain an value. + //******************************************* + ETL_CONSTEXPR14 TValue&& value() + { + return etl::move(etl::get(etl::move(data))); + } + +#if ETL_CPP11_SUPPORTED + //******************************************* + /// + //******************************************* + template + ETL_CONSTEXPR14 TValue value_or(U&& default_value) const& + { + if (has_value()) + { + return value(); + } + else + { + return default_value; + } + } + + //******************************************* + /// + //******************************************* + template + ETL_CONSTEXPR14 TValue value_or(U&& default_value) && + { + if (has_value()) + { + return etl::move(value()); + } + else + { + return etl::move(default_value); + } + } +#else + //******************************************* + /// + //******************************************* + template + TValue value_or(const U& default_value) const + { + if (has_value()) + { + return value(); + } + else + { + return default_value; + } + } +#endif + + //******************************************* + /// Returns a const reference to the error. + /// Undefined if the expected does not contain an error. + //******************************************* + ETL_CONSTEXPR14 const TError& error() const + { + return etl::get(data); + } + +#if (ETL_CPP11_SUPPORTED) + //******************************************* + /// Returns an rvalue reference to the error. + /// Undefined if the expected does not contain an error. + //******************************************* + ETL_CONSTEXPR14 TError&& error() && + { + return etl::move(etl::get(data)); + } + + //******************************************* + /// Returns an rvalue reference to the error. + /// Undefined if the expected does not contain an error. + //******************************************* + ETL_CONSTEXPR14 TError&& error() const && + { + return etl::move(etl::get(data)); + } +#endif + + private: + + etl::variant data; + }; + + //***************************************************************************** + /// Result type. + /// Specialisation for void value type. + //***************************************************************************** + template + class expected + { + +} + + +#endif + From 3892a45eeccfe514c23acc54a647217fd6194dea Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 15 Oct 2022 14:28:58 +0100 Subject: [PATCH 03/60] Work-In-Progress --- include/etl/expected.h | 479 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 479 insertions(+) create mode 100644 include/etl/expected.h diff --git a/include/etl/expected.h b/include/etl/expected.h new file mode 100644 index 00000000..991625b7 --- /dev/null +++ b/include/etl/expected.h @@ -0,0 +1,479 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2022 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_EXPECTED_INCLUDED +#define ETL_EXPECTED_INCLUDED + +///\defgroup expected expected +///\ingroup utilities + +#include "platform.h" +#include "utility.h" + +namespace etl +{ + //*************************************************************************** + /// Unexpected type. + /// etl::unexpected represents an unexpected value stored in etl::expected. + //*************************************************************************** + template + class unexpected + { + public: + + //******************************************* + /// Copy constructor. + //******************************************* + ETL_CONSTEXPR unexpected(const unexpected& other) + : error_value(other.error_value) + { + } + + //******************************************* + /// Move constructor. + //******************************************* + ETL_CONSTEXPR unexpected(unexpected&& other) + : error_value(etl::move(other.error_value)) + { + } + +#if ETL_CPP11_SUPPORTED + //******************************************* + /// Construct from argument. + //******************************************* + template ::type, etl::unexpected>::value && + !etl::is_same::type, etl::in_place_t>::value, int>::type> + constexpr explicit unexpected(E&& e) + : error_value(etl::forward(e)) + { + } +#else + //******************************************* + /// Construct from argument. + //******************************************* + template + explicit unexpected(const E& e, typename etl::enable_if::type, etl::unexpected>::value && + !etl::is_same::type, etl::in_place_t>::value, int>::type = 0) + : error_value(e) + { + } +#endif + +#if ETL_CPP11_SUPPORTED + //******************************************* + /// Construct from arguments. + //******************************************* + template + constexpr explicit unexpected(etl::in_place_t, Args&&... args) + : error_value(etl::forward(args)...) + { + } + +#if ETL_HAS_INITIALIZER_LIST + //******************************************* + /// Construct from initializer_list and arguments. + //******************************************* + template + constexpr explicit unexpected(etl::in_place_t, std::initializer_list init, Args&&... args) + : error_value(init, etl::forward(args)...) + { + } +#endif + + //******************************************* + /// Assign from etl::unexpected. + //******************************************* + unexpected& operator =(const etl::unexpected& rhs) + { + error_value = rhs.error_value; + } + +#if ETL_CPP11_SUPPORTED + //******************************************* + /// Move assign from etl::unexpected. + //******************************************* + unexpected& operator =(etl::unexpected&& rhs) + { + error_value = etl::move(rhs.error_value); + } +#endif + + //******************************************* + /// Get the error. + //******************************************* + const TError& error() const + { + return error_type; + } + + //******************************************* + /// Swap with another etl::unexpected. + //******************************************* + swap(etl::unexpected& other) + { + using ETL_OR_STD::swap; + + swap(error_value, other.error_value); + } + + private: + + TError error_value; + }; + + //******************************************* + /// Equivalence operator. + //******************************************* + template + bool operator ==(const etl::unexpected& lhs, const etl::unexpected& rhs) + { + return lhs.error_value == rhs.error_value; + } + + //******************************************* + /// Swap etl::unexpected. + //******************************************* + template + void swap(etl::unexpected& lhs, etl::unexpected& rhs) + { + lhs.swap(rhs); + } + + //***************************************************************************** + /// unexpect_t + //***************************************************************************** + struct unexpect_t + { + explicit unexpect_t() + { + } + }; + + inline ETL_CONSTEXPR14 unexpect_t unexpect{}; + + //***************************************************************************** + /// Expected type. + //***************************************************************************** + template + class expected + { + public: + + typename TValue value_type; + typename TError error_type; + typename etl::unexpected unexpected_type; + +#if ETL_CPP11_SUPPORTED + template + using rebind = etl::expected; +#endif + + //******************************************* + /// Default constructor + //******************************************* + ETL_CONSTEXPR14 expected(const expected& other) ETL_NOEXCEPT + : data(TValue()) + { + } + + //******************************************* + /// Copy constructor + //******************************************* + ETL_CONSTEXPR14 expected(const expected& other) + : data(other.data) + { + } + +#if ETL_CPP11_SUPPORTED + //******************************************* + /// Move constructor + //******************************************* + ETL_CONSTEXPR14 expected(expected&& other) ETL_NOEXCEPT + : data(etl::move(other.data)) + { + } +#endif + + template + constexpr explicit() expected(const expected& other) + { + } + + template + constexpr explicit(expected(expected&& other) + { + } + +#if ETL_CPP11_SUPPORTED + template + constexpr explicit expected(U&& v) + { + } +#endif + + template + constexpr explicit expected(const etl::unexpected& e) + { + } + +#if ETL_CPP11_SUPPORTED + template + constexpr explicit expected(etl::unexpected&& e) + { + } +#endif + + constexpr explicit expected(etl::in_place_t) noexcept + { + } + + template + constexpr explicit expected(etl::in_place_t, Args&&... args) + { + } + + template + constexpr explicit expected(etl::in_place_t, std::initializer_list il, Args&&... args) + { + } + + template + constexpr explicit expected(etl::unexpect_t, Args&&... args) + { + } + + template + constexpr explicit expected(etl::unexpect_t, std::initializer_list il, Args&&... args) + { + } + +// //******************************************* +// // Construct from a value +// //******************************************* +// expected(const TValue& value) +// : data(value) +// { +// } +// +//#if ETL_CPP11_SUPPORTED +// //******************************************* +// // Move construct from a value +// //******************************************* +// expected(TValue&& value) +// : data(etl::move(value)) +// { +// } +//#endif + + ////******************************************* + ///// Construct from error + ////******************************************* + //expected(const TError& error) + // : data(error) + //{ + //} + + ////******************************************* + ///// Move construct from error + ////******************************************* + //expected(TError&& error) + // : data(etl::move(error)) + //{ + //} + + //******************************************* + /// Copy assign + //******************************************* + expected& operator =(const expected& other) + { + data = other.data; + return *this; + } + + //******************************************* + /// Move assign + //******************************************* + expected& operator =(expected&& other) + { + data = etl::move(other.data); + return *this; + } + + //******************************************* + /// Copy assign from value + //******************************************* + expected& operator =(const TValue& value) + { + data = value; + return *this; + } + + //******************************************* + /// Move assign from value + //******************************************* + expected& operator =(TValue&& value) + { + data = etl::move(value); + return *this; + } + + //******************************************* + /// Copy assign from error + //******************************************* + expected& operator =(const TError& error) + { + data = error; + return *this; + } + + //******************************************* + /// Move assign from error + //******************************************* + expected& operator =(TError&& error) + { + data = etl::move(error); + return *this; + } + + //******************************************* + /// Returns a const reference to the value. + /// Undefined if the expected does not contain an value. + //******************************************* + ETL_CONSTEXPR14 const TValue& value() const + { + return etl::get(data); + } + + //******************************************* + /// Returns an rvalue reference to the value. + /// Undefined if the expected does not contain an value. + //******************************************* + ETL_CONSTEXPR14 TValue&& value() + { + return etl::move(etl::get(etl::move(data))); + } + +#if ETL_CPP11_SUPPORTED + //******************************************* + /// + //******************************************* + template + ETL_CONSTEXPR14 TValue value_or(U&& default_value) const& + { + if (has_value()) + { + return value(); + } + else + { + return default_value; + } + } + + //******************************************* + /// + //******************************************* + template + ETL_CONSTEXPR14 TValue value_or(U&& default_value) && + { + if (has_value()) + { + return etl::move(value()); + } + else + { + return etl::move(default_value); + } + } +#else + //******************************************* + /// + //******************************************* + template + TValue value_or(const U& default_value) const + { + if (has_value()) + { + return value(); + } + else + { + return default_value; + } + } +#endif + + //******************************************* + /// Returns a const reference to the error. + /// Undefined if the expected does not contain an error. + //******************************************* + ETL_CONSTEXPR14 const TError& error() const + { + return etl::get(data); + } + +#if (ETL_CPP11_SUPPORTED) + //******************************************* + /// Returns an rvalue reference to the error. + /// Undefined if the expected does not contain an error. + //******************************************* + ETL_CONSTEXPR14 TError&& error() && + { + return etl::move(etl::get(data)); + } + + //******************************************* + /// Returns an rvalue reference to the error. + /// Undefined if the expected does not contain an error. + //******************************************* + ETL_CONSTEXPR14 TError&& error() const && + { + return etl::move(etl::get(data)); + } +#endif + + private: + + etl::variant data; + }; + + //***************************************************************************** + /// Result type. + /// Specialisation for void value type. + //***************************************************************************** + template + class expected + { + +} + + +#endif + From a1ee6deec594ee3a071bce3bd75de4bdd5b12b8a Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 24 Oct 2022 17:15:25 +0100 Subject: [PATCH 04/60] Work-In-Progress --- include/etl/expected.h | 12 +++++++++++- test/vs2019/etl.vcxproj | 1 + test/vs2019/etl.vcxproj.filters | 3 +++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/etl/expected.h b/include/etl/expected.h index 991625b7..252008f2 100644 --- a/include/etl/expected.h +++ b/include/etl/expected.h @@ -95,6 +95,7 @@ namespace etl : error_value(etl::forward(args)...) { } +#endif #if ETL_HAS_INITIALIZER_LIST //******************************************* @@ -171,12 +172,14 @@ namespace etl //***************************************************************************** struct unexpect_t { - explicit unexpect_t() + ETL_CONSTEXPR14 explicit unexpect_t() { } }; +#if ETL_CPP14_SUPPORTED inline ETL_CONSTEXPR14 unexpect_t unexpect{}; +#endif //***************************************************************************** /// Expected type. @@ -471,7 +474,14 @@ namespace etl template class expected { + public: + + + private: + + TError error; + }; } diff --git a/test/vs2019/etl.vcxproj b/test/vs2019/etl.vcxproj index 63d366d5..c855b06b 100644 --- a/test/vs2019/etl.vcxproj +++ b/test/vs2019/etl.vcxproj @@ -2439,6 +2439,7 @@ + diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index bb5c004e..fffd334e 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -1341,6 +1341,9 @@ ETL\Strings + + ETL\Utilities + From a1bf74009f10fc9cefb3d6f57db58bb51076e8a1 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 27 Oct 2022 09:52:39 +0100 Subject: [PATCH 05/60] Work-In-Progress --- include/etl/expected.h | 308 ++++++++++++++++++++----------- include/etl/file_error_numbers.h | 2 +- include/etl/optional.h | 6 +- include/etl/result.h | 20 +- test/vs2019/etl.vcxproj.filters | 12 +- 5 files changed, 229 insertions(+), 119 deletions(-) diff --git a/include/etl/expected.h b/include/etl/expected.h index 252008f2..9b8d86e8 100644 --- a/include/etl/expected.h +++ b/include/etl/expected.h @@ -35,10 +35,56 @@ SOFTWARE. ///\ingroup utilities #include "platform.h" +#include "exception.h" +#include "error_handler.h" #include "utility.h" +#include "variant.h" namespace etl { + //*************************************************************************** + /// Base exception for et::expected + //*************************************************************************** + class expected_exception : public etl::exception + { + public: + + expected_exception(string_type reason_, string_type file_name_, numeric_type line_number_) + : exception(reason_, file_name_, line_number_) + { + } + }; + + //*************************************************************************** + /// expected_invalid + //*************************************************************************** + template + class expected_invalid; + + //******************************************* + template<> + class expected_invalid : public etl::expected_exception + { + public: + + expected_invalid(string_type file_name_, numeric_type line_number_) + : expected_exception(ETL_ERROR_TEXT("expected:invalid", ETL_EXPECTED_FILE_ID"A"), file_name_, line_number_) + { + } + }; + + //******************************************* + template + class expected_invalid : etl::expected_invalid + { + public: + + expected_invalid(string_type file_name_, numeric_type line_number_) + : expected_invalid(file_name_, line_number_) + { + } + }; + //*************************************************************************** /// Unexpected type. /// etl::unexpected represents an unexpected value stored in etl::expected. @@ -56,6 +102,7 @@ namespace etl { } +#if ETL_CPP11_SUPPORTED //******************************************* /// Move constructor. //******************************************* @@ -63,24 +110,25 @@ namespace etl : error_value(etl::move(other.error_value)) { } +#endif #if ETL_CPP11_SUPPORTED //******************************************* /// Construct from argument. //******************************************* - template ::type, etl::unexpected>::value && - !etl::is_same::type, etl::in_place_t>::value, int>::type> - constexpr explicit unexpected(E&& e) - : error_value(etl::forward(e)) + template ::type, etl::unexpected>::value && + !etl::is_same::type, etl::in_place_t>::value, int>::type> + constexpr explicit unexpected(TErr&& e) + : error_value(etl::forward(e)) { } #else //******************************************* /// Construct from argument. //******************************************* - template - explicit unexpected(const E& e, typename etl::enable_if::type, etl::unexpected>::value && - !etl::is_same::type, etl::in_place_t>::value, int>::type = 0) + template + explicit unexpected(const TErr& e, typename etl::enable_if::type, etl::unexpected>::value && + !etl::is_same::type, etl::in_place_t>::value, int>::type = 0) : error_value(e) { } @@ -111,7 +159,7 @@ namespace etl //******************************************* /// Assign from etl::unexpected. //******************************************* - unexpected& operator =(const etl::unexpected& rhs) + unexpected& operator =(const etl::unexpected& rhs) { error_value = rhs.error_value; } @@ -120,7 +168,7 @@ namespace etl //******************************************* /// Move assign from etl::unexpected. //******************************************* - unexpected& operator =(etl::unexpected&& rhs) + unexpected& operator =(etl::unexpected&& rhs) { error_value = etl::move(rhs.error_value); } @@ -137,7 +185,7 @@ namespace etl //******************************************* /// Swap with another etl::unexpected. //******************************************* - swap(etl::unexpected& other) + void swap(etl::unexpected& other) { using ETL_OR_STD::swap; @@ -195,13 +243,13 @@ namespace etl #if ETL_CPP11_SUPPORTED template - using rebind = etl::expected; + using rebind = etl::expected; #endif //******************************************* /// Default constructor //******************************************* - ETL_CONSTEXPR14 expected(const expected& other) ETL_NOEXCEPT + ETL_CONSTEXPR14 expected() ETL_NOEXCEPT : data(TValue()) { } @@ -209,7 +257,7 @@ namespace etl //******************************************* /// Copy constructor //******************************************* - ETL_CONSTEXPR14 expected(const expected& other) + ETL_CONSTEXPR14 expected(const expected& other) ETL_NOEXCEPT : data(other.data) { } @@ -224,111 +272,49 @@ namespace etl } #endif - template - constexpr explicit() expected(const expected& other) - { - } - - template - constexpr explicit(expected(expected&& other) - { - } - -#if ETL_CPP11_SUPPORTED - template - constexpr explicit expected(U&& v) - { - } -#endif - template - constexpr explicit expected(const etl::unexpected& e) + ETL_CONSTEXPR14 explicit expected(const etl::unexpected& ue) + : data(ue) { } #if ETL_CPP11_SUPPORTED template - constexpr explicit expected(etl::unexpected&& e) + ETL_CONSTEXPR14 explicit expected(etl::unexpected&& ue) + : data(etl::move(ue)) { } #endif - constexpr explicit expected(etl::in_place_t) noexcept + ETL_CONSTEXPR14 explicit expected(etl::in_place_t) ETL_NOEXCEPT + : data(TValue()) { } template - constexpr explicit expected(etl::in_place_t, Args&&... args) + ETL_CONSTEXPR14 explicit expected(etl::in_place_t, Args&&... args) + : data(etl::forward(args)...) { } template - constexpr explicit expected(etl::in_place_t, std::initializer_list il, Args&&... args) + ETL_CONSTEXPR14 explicit expected(etl::in_place_t, std::initializer_list il, Args&&... args) + : data(il, etl::forward(args)...) { } template - constexpr explicit expected(etl::unexpect_t, Args&&... args) + ETL_CONSTEXPR14 explicit expected(etl::unexpect_t, Args&&... args) + : data(etl::unexpected(args...)) { } template - constexpr explicit expected(etl::unexpect_t, std::initializer_list il, Args&&... args) + ETL_CONSTEXPR14 explicit expected(etl::unexpect_t, std::initializer_list il, Args&&... args) + : data(etl::unexpected(il, args...)) { } -// //******************************************* -// // Construct from a value -// //******************************************* -// expected(const TValue& value) -// : data(value) -// { -// } -// -//#if ETL_CPP11_SUPPORTED -// //******************************************* -// // Move construct from a value -// //******************************************* -// expected(TValue&& value) -// : data(etl::move(value)) -// { -// } -//#endif - - ////******************************************* - ///// Construct from error - ////******************************************* - //expected(const TError& error) - // : data(error) - //{ - //} - - ////******************************************* - ///// Move construct from error - ////******************************************* - //expected(TError&& error) - // : data(etl::move(error)) - //{ - //} - - //******************************************* - /// Copy assign - //******************************************* - expected& operator =(const expected& other) - { - data = other.data; - return *this; - } - - //******************************************* - /// Move assign - //******************************************* - expected& operator =(expected&& other) - { - data = etl::move(other.data); - return *this; - } - //******************************************* /// Copy assign from value //******************************************* @@ -365,6 +351,39 @@ namespace etl return *this; } +#if ETL_CPP11_SUPPORTED + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 T& value() & + { + return etl::get(data); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 const T& value() const& + { + return etl::get(data); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 T&& value() && + { + return etl::move(etl::get(data)); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 const T&& value() const&& + { + return etl::move(etl::get(data)); + } +#else //******************************************* /// Returns a const reference to the value. /// Undefined if the expected does not contain an value. @@ -373,15 +392,7 @@ namespace etl { return etl::get(data); } - - //******************************************* - /// Returns an rvalue reference to the value. - /// Undefined if the expected does not contain an value. - //******************************************* - ETL_CONSTEXPR14 TValue&& value() - { - return etl::move(etl::get(etl::move(data))); - } +#endif #if ETL_CPP11_SUPPORTED //******************************************* @@ -433,6 +444,39 @@ namespace etl } #endif +#if ETL_CPP11_SUPPORTED + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 const TError& error() const& ETL_NOEXCEPT + { + return etl::get(data); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 TError& error() & ETL_NOEXCEPT + { + return etl::get(data); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 const TError&& error() const&& ETL_NOEXCEPT + { + return etl::move(etl::get(data)); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 TError&& error() && ETL_NOEXCEPT + { + return etl::move(etl::get(data)); + } +#else //******************************************* /// Returns a const reference to the error. /// Undefined if the expected does not contain an error. @@ -441,34 +485,82 @@ namespace etl { return etl::get(data); } +#endif -#if (ETL_CPP11_SUPPORTED) +#if ETL_CPP11_SUPPORTED //******************************************* - /// Returns an rvalue reference to the error. - /// Undefined if the expected does not contain an error. + /// //******************************************* - ETL_CONSTEXPR14 TError&& error() && + template + ETL_CONSTEXPR14 T& emplace(Args&&... args) ETL_NOEXCEPT { - return etl::move(etl::get(data)); + data.emplace(args...); } //******************************************* - /// Returns an rvalue reference to the error. - /// Undefined if the expected does not contain an error. + /// //******************************************* - ETL_CONSTEXPR14 TError&& error() const && + template + ETL_CONSTEXPR14 T& emplace(std::initializer_list& il, Args&&... args) ETL_NOEXCEPT { - return etl::move(etl::get(data)); + data.emplace(il, args...); } #endif + //******************************************* + /// + //******************************************* + TValue* operator ->() + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); +#endif + + return etl::addressof(data.get()); + } + + //******************************************* + /// + //******************************************* + const TValue* operator ->() const + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); +#endif + + return etl::addressof(data.get()); + } + + //******************************************* + /// + //******************************************* + TValue& operator *() + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); +#endif + + return data.get(); + } + + //******************************************* + /// + //******************************************* + const TValue& operator *() const + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); +#endif + + return data.get(); + } + private: etl::variant data; }; //***************************************************************************** - /// Result type. /// Specialisation for void value type. //***************************************************************************** template diff --git a/include/etl/file_error_numbers.h b/include/etl/file_error_numbers.h index 7d6a0e1a..b0500c48 100644 --- a/include/etl/file_error_numbers.h +++ b/include/etl/file_error_numbers.h @@ -100,5 +100,5 @@ SOFTWARE. #define ETL_BIP_BUFFER_SPSC_ATOMIC_FILE_ID "67" #define ETL_REFERENCE_COUNTED_OBJECT_FILE_ID "68" #define ETL_TO_ARITHMETIC_FILE_ID "69" - +#define ETL_EXPECTED_FILE_ID "70" #endif diff --git a/include/etl/optional.h b/include/etl/optional.h index 9370b536..8de5197a 100644 --- a/include/etl/optional.h +++ b/include/etl/optional.h @@ -91,7 +91,7 @@ namespace etl public: optional_invalid(string_type file_name_, numeric_type line_number_) - : optional_exception("optional: invalid", file_name_, line_number_) + : optional_exception("optional:invalid", file_name_, line_number_) { } }; @@ -100,7 +100,7 @@ namespace etl /// An optional type. /// If the optional type is not initialised then a type is not constructed. /// See http://en.cppreference.com/w/cpp/utility/optional - ///\tparam The type to store. + ///\tparam T The type to store. ///\ingroup utilities //***************************************************************************** template ::value> @@ -516,6 +516,8 @@ namespace etl //***************************************************************************** /// For POD types. + ///\tparam T The type to store. + ///\ingroup utilities //***************************************************************************** template class optional diff --git a/include/etl/result.h b/include/etl/result.h index 9d79dbf4..33653c66 100644 --- a/include/etl/result.h +++ b/include/etl/result.h @@ -49,7 +49,7 @@ namespace etl /// Result type. //***************************************************************************** template - class result + class ETL_DEPRECATED result { public: @@ -66,6 +66,7 @@ namespace etl { } +#if ETL_CPP11_SUPPORTED //******************************************* /// Move constructor //******************************************* @@ -73,6 +74,7 @@ namespace etl : data(etl::move(other.data)) { } +#endif //******************************************* // Construct from a value @@ -85,7 +87,7 @@ namespace etl //******************************************* // Move construct from a value //******************************************* - result(TValue&& value) + result(TValue&& value) : data(etl::move(value)) { } @@ -101,10 +103,12 @@ namespace etl //******************************************* /// Move construct from error //******************************************* +#if ETL_CPP11_SUPPORTED result(TError&& error) : data(etl::move(error)) { } +#endif //******************************************* /// Copy assign @@ -136,11 +140,13 @@ namespace etl //******************************************* /// Move assign from value //******************************************* +#if ETL_CPP11_SUPPORTED result& operator =(TValue&& value) { data = etl::move(value); return *this; } +#endif //******************************************* /// Copy assign from error @@ -154,11 +160,13 @@ namespace etl //******************************************* /// Move assign from error //******************************************* +#if ETL_CPP11_SUPPORTED result& operator =(TError&& error) { data = etl::move(error); return *this; } +#endif //******************************************* /// true if result contains a value @@ -215,10 +223,12 @@ namespace etl /// Returns an rvalue reference to the error. /// Undefined if the result does not contain an error. //******************************************* +#if ETL_CPP11_SUPPORTED TError&& error() { return etl::move(etl::get(etl::move(data))); } +#endif private: @@ -269,10 +279,12 @@ namespace etl //******************************************* /// Move construct from error //******************************************* +#if ETL_CPP11_SUPPORTED result(TError&& err_) : err(etl::move(err_)) { } +#endif //******************************************* /// Copy assign from error @@ -286,11 +298,13 @@ namespace etl //******************************************* /// Move assign from error //******************************************* +#if ETL_CPP11_SUPPORTED result& operator =(TError&& err_) { err = etl::move(err_); return *this; } +#endif //******************************************* /// true if result contains a value @@ -321,10 +335,12 @@ namespace etl /// Returns an rvalue reference to the error. /// Undefined if the result does not contain an error. //******************************************* +#if ETL_CPP11_SUPPORTED TError&& error() { return etl::move(err); } +#endif private: diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index fffd334e..f3bb0187 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -345,9 +345,6 @@ ETL\Utilities - - ETL\Containers - ETL\Containers @@ -1344,6 +1341,9 @@ ETL\Utilities + + ETL\Utilities + @@ -2192,9 +2192,6 @@ Tests\Maths - - Tests\Containers - Tests\Errors @@ -3392,6 +3389,9 @@ Tests\Sanity Checks\Source + + Tests\Misc + From e9a13b8c9b9c29dc7f5ab75255d2cefc548cf2cc Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 27 Oct 2022 09:52:39 +0100 Subject: [PATCH 06/60] Work-In-Progress --- include/etl/file_error_numbers.h | 2 +- include/etl/optional.h | 6 ++++-- include/etl/result.h | 20 ++++++++++++++++++-- test/vs2019/etl.vcxproj.filters | 12 ++++++------ 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/include/etl/file_error_numbers.h b/include/etl/file_error_numbers.h index 7d6a0e1a..b0500c48 100644 --- a/include/etl/file_error_numbers.h +++ b/include/etl/file_error_numbers.h @@ -100,5 +100,5 @@ SOFTWARE. #define ETL_BIP_BUFFER_SPSC_ATOMIC_FILE_ID "67" #define ETL_REFERENCE_COUNTED_OBJECT_FILE_ID "68" #define ETL_TO_ARITHMETIC_FILE_ID "69" - +#define ETL_EXPECTED_FILE_ID "70" #endif diff --git a/include/etl/optional.h b/include/etl/optional.h index 9370b536..8de5197a 100644 --- a/include/etl/optional.h +++ b/include/etl/optional.h @@ -91,7 +91,7 @@ namespace etl public: optional_invalid(string_type file_name_, numeric_type line_number_) - : optional_exception("optional: invalid", file_name_, line_number_) + : optional_exception("optional:invalid", file_name_, line_number_) { } }; @@ -100,7 +100,7 @@ namespace etl /// An optional type. /// If the optional type is not initialised then a type is not constructed. /// See http://en.cppreference.com/w/cpp/utility/optional - ///\tparam The type to store. + ///\tparam T The type to store. ///\ingroup utilities //***************************************************************************** template ::value> @@ -516,6 +516,8 @@ namespace etl //***************************************************************************** /// For POD types. + ///\tparam T The type to store. + ///\ingroup utilities //***************************************************************************** template class optional diff --git a/include/etl/result.h b/include/etl/result.h index 9d79dbf4..33653c66 100644 --- a/include/etl/result.h +++ b/include/etl/result.h @@ -49,7 +49,7 @@ namespace etl /// Result type. //***************************************************************************** template - class result + class ETL_DEPRECATED result { public: @@ -66,6 +66,7 @@ namespace etl { } +#if ETL_CPP11_SUPPORTED //******************************************* /// Move constructor //******************************************* @@ -73,6 +74,7 @@ namespace etl : data(etl::move(other.data)) { } +#endif //******************************************* // Construct from a value @@ -85,7 +87,7 @@ namespace etl //******************************************* // Move construct from a value //******************************************* - result(TValue&& value) + result(TValue&& value) : data(etl::move(value)) { } @@ -101,10 +103,12 @@ namespace etl //******************************************* /// Move construct from error //******************************************* +#if ETL_CPP11_SUPPORTED result(TError&& error) : data(etl::move(error)) { } +#endif //******************************************* /// Copy assign @@ -136,11 +140,13 @@ namespace etl //******************************************* /// Move assign from value //******************************************* +#if ETL_CPP11_SUPPORTED result& operator =(TValue&& value) { data = etl::move(value); return *this; } +#endif //******************************************* /// Copy assign from error @@ -154,11 +160,13 @@ namespace etl //******************************************* /// Move assign from error //******************************************* +#if ETL_CPP11_SUPPORTED result& operator =(TError&& error) { data = etl::move(error); return *this; } +#endif //******************************************* /// true if result contains a value @@ -215,10 +223,12 @@ namespace etl /// Returns an rvalue reference to the error. /// Undefined if the result does not contain an error. //******************************************* +#if ETL_CPP11_SUPPORTED TError&& error() { return etl::move(etl::get(etl::move(data))); } +#endif private: @@ -269,10 +279,12 @@ namespace etl //******************************************* /// Move construct from error //******************************************* +#if ETL_CPP11_SUPPORTED result(TError&& err_) : err(etl::move(err_)) { } +#endif //******************************************* /// Copy assign from error @@ -286,11 +298,13 @@ namespace etl //******************************************* /// Move assign from error //******************************************* +#if ETL_CPP11_SUPPORTED result& operator =(TError&& err_) { err = etl::move(err_); return *this; } +#endif //******************************************* /// true if result contains a value @@ -321,10 +335,12 @@ namespace etl /// Returns an rvalue reference to the error. /// Undefined if the result does not contain an error. //******************************************* +#if ETL_CPP11_SUPPORTED TError&& error() { return etl::move(err); } +#endif private: diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index e6c75e07..1f0ab436 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -345,9 +345,6 @@ ETL\Utilities - - ETL\Containers - ETL\Containers @@ -1344,6 +1341,9 @@ ETL\Containers + + ETL\Utilities + @@ -2192,9 +2192,6 @@ Tests\Maths - - Tests\Containers - Tests\Errors @@ -3392,6 +3389,9 @@ Tests\Sanity Checks\Source + + Tests\Misc + From a01e974d7daa10f36535b2cccd44f54a077aded1 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 28 Dec 2022 17:36:51 +0000 Subject: [PATCH 07/60] Added etl::result specialisation Reverted code for etl::result specialisation --- include/etl/result.h | 154 ++++++++++++++++++++++++++++++++++++++----- test/CMakeLists.txt | 1 + test/test_result.cpp | 141 +++++++++++++++++++++++++++++---------- 3 files changed, 244 insertions(+), 52 deletions(-) diff --git a/include/etl/result.h b/include/etl/result.h index 9d79dbf4..6898c12a 100644 --- a/include/etl/result.h +++ b/include/etl/result.h @@ -173,7 +173,7 @@ namespace etl //******************************************* bool is_value() const { - return (data.index() == 0U); + return has_value(); } //******************************************* @@ -238,7 +238,6 @@ namespace etl /// Default Constructor //******************************************* result() - : err(TError()) { } @@ -246,7 +245,7 @@ namespace etl /// Copy constructor //******************************************* result(const result& other) - : err(other.err) + : data(other.data) { } @@ -254,50 +253,58 @@ namespace etl /// Move constructor //******************************************* result(result&& other) - : err(etl::move(other.err)) + : data(etl::move(other.data)) { } //******************************************* /// Construct from error //******************************************* - result(const TError& err_) - : err(err_) + result(const TError& err) + : data(err) { } //******************************************* /// Move construct from error //******************************************* - result(TError&& err_) - : err(etl::move(err_)) + result(TError&& err) + : data(etl::move(err)) { } //******************************************* /// Copy assign from error //******************************************* - result& operator =(const TError& err_) + result& operator =(const TError& err) { - err = err_; + data = err; return *this; } //******************************************* /// Move assign from error //******************************************* - result& operator =(TError&& err_) + result& operator =(TError&& err) { - err = etl::move(err_); + data = etl::move(err); return *this; } + //******************************************* + /// true if result contains a value + //******************************************* + bool has_value() const + { + return (data.index() == 0U); + } + //******************************************* /// true if result contains a value //******************************************* bool is_value() const { - return false; + return has_value(); } //******************************************* @@ -305,7 +312,7 @@ namespace etl //******************************************* bool is_error() const { - return true; + return (data.index() == 1U); } //******************************************* @@ -314,7 +321,7 @@ namespace etl //******************************************* const TError& error() const { - return err; + return etl::get(data); } //******************************************* @@ -323,12 +330,125 @@ namespace etl //******************************************* TError&& error() { - return etl::move(err); + return etl::get(etl::move(data)); } private: - TError err; + etl::variant data; + }; + + //***************************************************************************** + /// Result type. + /// Specialisation for void error type. + //***************************************************************************** + template + class result + { + public: + + //******************************************* + /// Default Constructor + //******************************************* + result() + { + } + + //******************************************* + /// Copy constructor + //******************************************* + result(const result& other) + : data(other.data) + { + } + + //******************************************* + /// Move constructor + //******************************************* + result(result&& other) + : data(etl::move(other.data)) + { + } + + //******************************************* + /// Construct from error + //******************************************* + result(const TValue& value) + : data(value) + { + } + + //******************************************* + /// Move construct from error + //******************************************* + result(TValue&& value) + : data(etl::move(value)) + { + } + + //******************************************* + /// Copy assign from error + //******************************************* + result& operator =(const TValue& value) + { + data = value; + return *this; + } + + //******************************************* + /// Move assign from error + //******************************************* + result& operator =(TValue&& value) + { + data = etl::move(err); + return *this; + } + + //******************************************* + /// true if result contains a value + //******************************************* + bool has_value() const + { + return (data.index() == 1U); + } + + //******************************************* + /// true if result contains a value + //******************************************* + bool is_value() const + { + return has_value(); + } + + //******************************************* + /// true if result contains an error + //******************************************* + bool is_error() const + { + return (data.index() == 0U); + } + + //******************************************* + /// Returns a const reference to the error. + /// Undefined if the result does not contain an error. + //******************************************* + const TValue& value() const + { + return etl::get(data); + } + + //******************************************* + /// Returns an rvalue reference to the error. + /// Undefined if the result does not contain an error. + //******************************************* + TValue&& value() + { + return etl::get(etl::move(data)); + } + + private: + + etl::variant data; }; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 75a5519a..58ecbda4 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -324,3 +324,4 @@ add_test(etl_unit_tests etl_tests) add_custom_target(test_verbose COMMAND ${CMAKE_CTEST_COMMAND} --verbose) set_property(TARGET etl_tests PROPERTY CXX_STANDARD 17) + \ No newline at end of file diff --git a/test/test_result.cpp b/test/test_result.cpp index ad0f5908..4fbb72bd 100644 --- a/test/test_result.cpp +++ b/test/test_result.cpp @@ -85,9 +85,10 @@ namespace std::string e; }; - using Result = etl::result; - using ResultV = etl::result; - using ResultM = etl::result; + using ResultValueError = etl::result; + using ResultVoidError = etl::result; + using ResultValueVoid = etl::result; + using ResultM = etl::result; } // Definitions for when the STL and compiler built-ins are not available. @@ -144,10 +145,10 @@ namespace SUITE(test_result) { //************************************************************************* - TEST(test_constructor_for_result_with_value) + TEST(test_construct_result_value_error_type_with_value) { Value input = { "value 1" }; - Result result(input); + ResultValueError result(input); Value output = result.value(); @@ -157,10 +158,10 @@ namespace } //************************************************************************* - TEST(test_constructor_for_const_result_with_value) + TEST(test_construct_const_result_value_error_type_with_value) { Value input = { "value 1" }; - const Result result(input); + const ResultValueError result(input); const Value& output = result.value(); @@ -170,7 +171,7 @@ namespace } //************************************************************************* - TEST(test_constructor_for_moveable_result_with_value) + TEST(test_construct_moveable_result_value_error_type_with_value) { ValueM input = { "value 1" }; ResultM result(etl::move(input)); @@ -183,10 +184,10 @@ namespace } //************************************************************************* - TEST(test_constructor_for_result_with_error) + TEST(test_construct_result_value_error_type_with_error) { Error input = { "error 1" }; - Result result(input); + ResultValueError result(input); Error output = result.error(); @@ -196,10 +197,10 @@ namespace } //************************************************************************* - TEST(test_constructor_for_const_result_with_error) + TEST(test_construct_const_result_value_error_type_with_error) { Error input = { "error 1" }; - const Result result(input); + const ResultValueError result(input); const Error& output = result.error(); @@ -209,7 +210,7 @@ namespace } //************************************************************************* - TEST(test_constructor_for_moveable_result_with_error) + TEST(test_construct_moveable_result_value_error_type_with_error) { ErrorM input = { "error 1" }; ResultM result(etl::move(input)); @@ -222,28 +223,28 @@ namespace } //************************************************************************* - TEST(test_constructor_for_result_void_value_with_value) + TEST(test_default_construct_result_void_error_type) { - ResultV result; + ResultVoidError result; - CHECK(!result.is_value()); - CHECK(result.is_error()); + CHECK(result.is_value()); + CHECK(!result.is_error()); } //************************************************************************* - TEST(test_constructor_for_const_result_void_value_with_value) + TEST(test_default_construct_const_result_void_error_type) { - const ResultV result; + const ResultVoidError result; - CHECK(!result.is_value()); - CHECK(result.is_error()); + CHECK(result.is_value()); + CHECK(!result.is_error()); } //************************************************************************* - TEST(test_constructor_for_result_void_value_with_error) + TEST(test_construct_result_void_error_type_with_error) { Error input = { "error 1" }; - ResultV result(input); + ResultVoidError result(input); Error output = result.error(); @@ -253,10 +254,10 @@ namespace } //************************************************************************* - TEST(test_constructor_for_const_result_void_value_with_error) + TEST(test_construct_const_result_void_error_type_with_error) { Error input = { "error 1" }; - const ResultV result(input); + const ResultVoidError result(input); const Error& output = result.error(); @@ -266,10 +267,10 @@ namespace } //************************************************************************* - TEST(test_constructor_for_moveable_result_void_value_with_error) + TEST(test_construct_moveable_result_void_error_type_with_error) { Error input = { "error 1" }; - ResultV result(etl::move(input)); + ResultVoidError result(etl::move(input)); Error output = etl::move(result.error()); @@ -279,10 +280,10 @@ namespace } //************************************************************************* - TEST(test_constructor_for_moveable_const_result_void_value_with_error) + TEST(test_construct_moveable_const_result_void_error_type_with_error) { Error input = { "error 1" }; - const ResultV result(etl::move(input)); + const ResultVoidError result(etl::move(input)); Error output = etl::move(result.error()); @@ -291,13 +292,83 @@ namespace CHECK(output.e == std::string("error 1")); } + //************************************************************************* + TEST(test_default_construct_result_value_void_type) + { + ResultValueVoid result; + + CHECK(!result.is_value()); + CHECK(result.is_error()); + } + + //************************************************************************* + TEST(test_default_construct_const_result_value_void_type) + { + const ResultValueVoid result; + + CHECK(!result.is_value()); + CHECK(result.is_error()); + } + + //************************************************************************* + TEST(test_construct_result_value_void_type_with_value) + { + Value input = { "value 1" }; + ResultValueVoid result(input); + + Value output = result.value(); + + CHECK(result.is_value()); + CHECK(!result.is_error()); + CHECK(output.v == input.v); + } + + //************************************************************************* + TEST(test_construct_const_result_value_void_type_with_value) + { + Value input = { "value 1" }; + const ResultValueVoid result(input); + + const Value output = result.value(); + + CHECK(result.is_value()); + CHECK(!result.is_error()); + CHECK(output.v == input.v); + } + + //************************************************************************* + TEST(test_construct_moveable_result_value_void_type_with_value) + { + Value input = { "value 1" }; + ResultValueVoid result(etl::move(input)); + + Value output = etl::move(result.value()); + + CHECK(result.is_value()); + CHECK(!result.is_error()); + CHECK(output.v == std::string("value 1")); + } + + //************************************************************************* + TEST(test_construct_moveable_const_result_value_void_type_with_value) + { + Value input = { "value 1" }; + const ResultValueVoid result(etl::move(input)); + + Value output = etl::move(result.value()); + + CHECK(result.is_value()); + CHECK(!result.is_error()); + CHECK(output.v == std::string("value 1")); + } + //************************************************************************* TEST(test_copy_construct_result) { Value input = { "value 1" }; - Result result(input); + ResultValueError result(input); - Result result2(result); + ResultValueError result2(result); Value output = result2.value(); @@ -312,9 +383,9 @@ namespace TEST(test_move_construct_result) { Value input = { "value 1" }; - Result result(input); + ResultValueError result(input); - Result result2(etl::move(result)); + ResultValueError result2(etl::move(result)); Value output = result.value(); Value output2 = result2.value(); @@ -331,10 +402,10 @@ namespace TEST(test_move_assign_result) { Value input = { "value 1" }; - Result result(input); + ResultValueError result(input); Value input2 = { "value 2" }; - Result result2(result); + ResultValueError result2(result); result2 = etl::move(result); From ddf557a0b26769cc15956bd982c724e1b18ef421 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 28 Dec 2022 17:36:51 +0000 Subject: [PATCH 08/60] Added etl::result specialisation Reverted code for etl::result specialisation --- include/etl/result.h | 45 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/include/etl/result.h b/include/etl/result.h index 6898c12a..95d0fc0c 100644 --- a/include/etl/result.h +++ b/include/etl/result.h @@ -36,6 +36,7 @@ SOFTWARE. #include "platform.h" #include "variant.h" +#include "optional.h" #if ETL_CPP11_NOT_SUPPORTED #if !defined(ETL_IN_UNIT_TEST) @@ -181,7 +182,7 @@ namespace etl //******************************************* bool is_error() const { - return (data.index() == 1U); + return !has_value(); } //******************************************* @@ -199,7 +200,7 @@ namespace etl //******************************************* TValue&& value() { - return etl::move(etl::get(etl::move(data))); + return etl::move(etl::get(data)); } //******************************************* @@ -217,7 +218,7 @@ namespace etl //******************************************* TError&& error() { - return etl::move(etl::get(etl::move(data))); + return etl::move(etl::get(data)); } private: @@ -260,34 +261,34 @@ namespace etl //******************************************* /// Construct from error //******************************************* - result(const TError& err) - : data(err) + result(const TError& error) + : data(error) { } //******************************************* /// Move construct from error //******************************************* - result(TError&& err) - : data(etl::move(err)) + result(TError&& error) + : data(etl::move(error)) { } //******************************************* /// Copy assign from error //******************************************* - result& operator =(const TError& err) + result& operator =(const TError& error) { - data = err; + data = error; return *this; } //******************************************* /// Move assign from error //******************************************* - result& operator =(TError&& err) + result& operator =(TError&& error) { - data = etl::move(err); + data = etl::move(error); return *this; } @@ -296,7 +297,7 @@ namespace etl //******************************************* bool has_value() const { - return (data.index() == 0U); + return !data.has_value(); } //******************************************* @@ -312,7 +313,7 @@ namespace etl //******************************************* bool is_error() const { - return (data.index() == 1U); + return !has_value(); } //******************************************* @@ -321,7 +322,7 @@ namespace etl //******************************************* const TError& error() const { - return etl::get(data); + return data.value(); } //******************************************* @@ -330,12 +331,12 @@ namespace etl //******************************************* TError&& error() { - return etl::get(etl::move(data)); + return etl::move(data.value()); } private: - etl::variant data; + etl::optional data; }; //***************************************************************************** @@ -400,7 +401,7 @@ namespace etl //******************************************* result& operator =(TValue&& value) { - data = etl::move(err); + data = etl::move(value); return *this; } @@ -409,7 +410,7 @@ namespace etl //******************************************* bool has_value() const { - return (data.index() == 1U); + return data.has_value(); } //******************************************* @@ -425,7 +426,7 @@ namespace etl //******************************************* bool is_error() const { - return (data.index() == 0U); + return !has_value(); } //******************************************* @@ -434,7 +435,7 @@ namespace etl //******************************************* const TValue& value() const { - return etl::get(data); + return data.value(); } //******************************************* @@ -443,12 +444,12 @@ namespace etl //******************************************* TValue&& value() { - return etl::get(etl::move(data)); + return etl::move(data.value()); } private: - etl::variant data; + etl::optional data; }; } From 58136cac7babe049f1f210d88a1d5277904c8ed9 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 30 Dec 2022 18:10:12 +0000 Subject: [PATCH 09/60] Fixed perfect forwarding for make_xxx helper functions --- include/etl/forward_list.h | 2 +- include/etl/indirect_vector.h | 2 +- include/etl/vector.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/etl/forward_list.h b/include/etl/forward_list.h index 68337fc5..466a8cee 100644 --- a/include/etl/forward_list.h +++ b/include/etl/forward_list.h @@ -1756,7 +1756,7 @@ namespace etl //************************************************************************* #if ETL_USING_CPP11 && ETL_HAS_INITIALIZER_LIST template - constexpr auto make_forward_list(T... t) -> etl::forward_list, sizeof...(T)> + constexpr auto make_forward_list(T&&... t) -> etl::forward_list, sizeof...(T)> { return { { etl::forward(t)... } }; } diff --git a/include/etl/indirect_vector.h b/include/etl/indirect_vector.h index 002cad02..bf057662 100644 --- a/include/etl/indirect_vector.h +++ b/include/etl/indirect_vector.h @@ -1433,7 +1433,7 @@ namespace etl //************************************************************************* #if ETL_USING_CPP11 && ETL_HAS_INITIALIZER_LIST template - constexpr auto make_indirect_vector(T... t) -> etl::indirect_vector, sizeof...(T)> + constexpr auto make_indirect_vector(T&&... t) -> etl::indirect_vector, sizeof...(T)> { return { { etl::forward(t)... } }; } diff --git a/include/etl/vector.h b/include/etl/vector.h index b10c3275..86a30d40 100644 --- a/include/etl/vector.h +++ b/include/etl/vector.h @@ -1353,7 +1353,7 @@ namespace etl //************************************************************************* #if ETL_USING_CPP11 && ETL_HAS_INITIALIZER_LIST template - constexpr auto make_vector(T... t) -> etl::vector, sizeof...(T)> + constexpr auto make_vector(T&&... t) -> etl::vector, sizeof...(T)> { return { { etl::forward(t)... } }; } From e66750de538bf0bf12ba0baaf3eee63c3a280053 Mon Sep 17 00:00:00 2001 From: Flaviu Tamas Date: Wed, 4 Jan 2023 04:39:28 -0500 Subject: [PATCH 10/60] Don't warn on tag missing when subproject (#653) (#655) Different solution than proposed in the issue, since that proposed solution would given unexpected results when an intermediate (untagged) commit is checked out. This change simply skips warning about a missing git version when this is a subproject, and uses the original version calculation logic. I've also renamed `determine_version` to `determine_version_with_file`. I'd originally done this in an intermediate version of this PR, but I think that keeping the renaming is clearer code. --- CMakeLists.txt | 2 +- cmake/helpers.cmake | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e571357f..1ce02e57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/helpers.cmake) set(MSG_PREFIX "etl |") determine_version_with_git(${GIT_DIR_LOOKUP_POLICY}) if(NOT ETL_VERSION) - determine_version("version.txt") + determine_version_with_file("version.txt") endif() project(etl VERSION ${ETL_VERSION} LANGUAGES CXX) diff --git a/cmake/helpers.cmake b/cmake/helpers.cmake index f27189d9..9249fb4e 100644 --- a/cmake/helpers.cmake +++ b/cmake/helpers.cmake @@ -1,4 +1,4 @@ -function(determine_version VER_FILE_NAME) +function(determine_version_with_file VER_FILE_NAME) file(READ ${VER_FILE_NAME} ETL_VERSION_RAW) # Remove trailing whitespaces and/or newline string(STRIP ${ETL_VERSION_RAW} ETL_VERSION) @@ -13,7 +13,11 @@ function(determine_version_with_git) git_describe(VERSION ${ARGN}) string(FIND ${VERSION} "." VALID_VERSION) if(VALID_VERSION EQUAL -1) - message(WARNING "Version string ${VERSION} retrieved with git describe is invalid") + if(PROJECT_IS_TOP_LEVEL) + # only warn if this is the top-level project, since we may be + # building from a tarball as a subproject + message(WARNING "Version string ${VERSION} retrieved with git describe is invalid") + endif() return() endif() message(STATUS "${MSG_PREFIX} Version string determined with git describe: ${VERSION}") From cc2306e1db8f6e3927d9d0d43e3eff516d6efe3a Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 4 Jan 2023 10:28:00 +0000 Subject: [PATCH 11/60] Removed superfluous semicolons --- include/etl/binary.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/etl/binary.h b/include/etl/binary.h index 658d41be..5d5a6128 100644 --- a/include/etl/binary.h +++ b/include/etl/binary.h @@ -2198,7 +2198,7 @@ namespace etl return (nbits == etl::integral_limits::bits) ? static_cast(etl::integral_limits::max) : static_cast((static_cast(1U) << nbits) - 1U); - }; + } //*********************************** template @@ -2214,7 +2214,7 @@ namespace etl ETL_CONSTEXPR T make_msb_mask(size_t nbits) { return static_cast(etl::reverse_bits(make_lsb_mask(nbits))); - }; + } //*************************************************************************** /// 8 bit binary byte constants. From 53d3dd7852071c302e55e7a16a6b0368a2bed148 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 5 Jan 2023 12:48:22 +0000 Subject: [PATCH 12/60] Updated version and release notes --- arduino/library-arduino.json | 2 +- arduino/library-arduino.properties | 2 +- include/etl/version.h | 2 +- library.json | 2 +- library.properties | 2 +- support/Release notes.txt | 5 +++++ version.txt | 2 +- 7 files changed, 11 insertions(+), 6 deletions(-) diff --git a/arduino/library-arduino.json b/arduino/library-arduino.json index 3a1e34ef..b585db35 100644 --- a/arduino/library-arduino.json +++ b/arduino/library-arduino.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library - Arduino", - "version": "20.35.8", + "version": "20.35.9", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/arduino/library-arduino.properties b/arduino/library-arduino.properties index a2245313..6e882d68 100644 --- a/arduino/library-arduino.properties +++ b/arduino/library-arduino.properties @@ -1,5 +1,5 @@ name=Embedded Template Library - Arduino -version=20.35.8 +version=20.35.9 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/include/etl/version.h b/include/etl/version.h index 8d30ca59..1176944c 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 35 -#define ETL_VERSION_PATCH 8 +#define ETL_VERSION_PATCH 9 #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 f5b98329..6c1382ff 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library", - "version": "20.35.8", + "version": "20.35.9", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/library.properties b/library.properties index 1730fc80..8e2d9c21 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Embedded Template Library -version=20.35.8 +version=20.35.9 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/support/Release notes.txt b/support/Release notes.txt index c714e8bf..0cb97325 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,3 +1,8 @@ +=============================================================================== +20.35.9 +#657 -Wpedantic-failure. Removed superfluous semicolons +#653 CMake - Don't warn on tag missing when subproject + =============================================================================== 20.35.8 #648 Improve is_constructible, is_copy_constructible, is_move_constructible for type traits with default definitions diff --git a/version.txt b/version.txt index fbf90e2c..e7f94ac3 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -20.35.8 +20.35.9 From e83c7786b826661640d9c2853d80b073c957ae89 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 5 Jan 2023 13:28:52 +0000 Subject: [PATCH 13/60] Removed testing for 18.04 Added testing for 22.04 --- .github/workflows/clang.yml | 4 ++-- .github/workflows/gcc.yml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/clang.yml b/.github/workflows/clang.yml index 7dfaf504..87c16ddf 100644 --- a/.github/workflows/clang.yml +++ b/.github/workflows/clang.yml @@ -11,7 +11,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-20.04] + os: [ubuntu-20.04, ubuntu-22.04] steps: - uses: actions/checkout@v2 @@ -63,7 +63,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-20.04] + os: [ubuntu-20.04, ubuntu-22.04] steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/gcc.yml b/.github/workflows/gcc.yml index 2042fbeb..701719ef 100644 --- a/.github/workflows/gcc.yml +++ b/.github/workflows/gcc.yml @@ -11,7 +11,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-18.04, ubuntu-20.04] + os: [ubuntu-20.04, ubuntu-22.04] steps: - uses: actions/checkout@v2 @@ -32,7 +32,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-18.04, ubuntu-20.04] + os: [ubuntu-20.04, ubuntu-22.04] steps: - uses: actions/checkout@v2 @@ -53,7 +53,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-18.04, ubuntu-20.04] + os: [ubuntu-20.04, ubuntu-22.04] steps: - uses: actions/checkout@v2 From 96d225d15353bd1375e63ad875796543093a31c6 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 5 Jan 2023 14:03:10 +0000 Subject: [PATCH 14/60] Updated Github Actions for Clang --- .github/workflows/clang.yml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/clang.yml b/.github/workflows/clang.yml index 87c16ddf..ee328390 100644 --- a/.github/workflows/clang.yml +++ b/.github/workflows/clang.yml @@ -6,12 +6,12 @@ on: branches: [ master ] jobs: - build-clang-9-linux-stl: - name: Clang-9 Linux - STL + build-clang-14-linux-stl: + name: Clang-14 Linux - STL runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-20.04, ubuntu-22.04] + os: [ubuntu-22.04] steps: - uses: actions/checkout@v2 @@ -19,9 +19,9 @@ jobs: - name: Build run: | sudo apt-get update - sudo apt-get install -y "clang-9" "lldb-9" "lld-9" "clang-format-9" - export CC=clang-9 - export CXX=clang++-9 + sudo apt-get install -y "clang-14" "lldb-14" "lld-14" "clang-format-14" + export CC=clang-14 + export CXX=clang++-14 export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 git fetch --tags cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03=OFF ./ @@ -31,12 +31,12 @@ jobs: - name: Run tests run: ./test/etl_tests - build-clang-9-linux-no-stl: - name: Clang-9 Linux - No STL + build-clang-14-linux-no-stl: + name: Clang-14 Linux - No STL runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-20.04] + os: [ubuntu-22.04] steps: - uses: actions/checkout@v2 @@ -44,9 +44,9 @@ jobs: - name: Build run: | sudo apt-get update - sudo apt-get install -y "clang-9" "lldb-9" "lld-9" "clang-format-9" - export CC=clang-9 - export CXX=clang++-9 + sudo apt-get install -y "clang-14" "lldb-14" "lld-14" "clang-format-14" + export CC=clang-14 + export CXX=clang++-14 export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 git fetch --tags cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03=OFF ./ @@ -58,12 +58,12 @@ jobs: - name: Run tests run: ./test/etl_tests - build-clang-9-linux-stl-force-cpp03: - name: Clang-9 Linux - STL - Force C++03 + build-clang-14-linux-stl-force-cpp03: + name: Clang-14 Linux - STL - Force C++03 runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-20.04, ubuntu-22.04] + os: [ubuntu-22.04] steps: - uses: actions/checkout@v2 @@ -71,9 +71,9 @@ jobs: - name: Build run: | sudo apt-get update - sudo apt-get install -y "clang-9" "lldb-9" "lld-9" "clang-format-9" - export CC=clang-9 - export CXX=clang++-9 + sudo apt-get install -y "clang-14" "lldb-14" "lld-14" "clang-format-14" + export CC=clang-14 + export CXX=clang++-14 export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 git fetch --tags cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03=ON ./ From 03bbff6f0c533200b550b35e63ebcd3086c553b2 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 5 Jan 2023 15:00:04 +0000 Subject: [PATCH 15/60] Updated version and release notes --- support/Release notes.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/support/Release notes.txt b/support/Release notes.txt index 0cb97325..fb75666b 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -2,6 +2,8 @@ 20.35.9 #657 -Wpedantic-failure. Removed superfluous semicolons #653 CMake - Don't warn on tag missing when subproject +Removed Ubuntu 18.04 from Github Actions +Added Ubuntu 22.04 to Github Actions =============================================================================== 20.35.8 From f0f23ebc11df7cbc0e028525d252dfdb8ce8e104 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 5 Jan 2023 19:21:56 +0000 Subject: [PATCH 16/60] clang updates for Github Actions --- .github/workflows/clang.yml | 38 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/.github/workflows/clang.yml b/.github/workflows/clang.yml index ee328390..bcb3722f 100644 --- a/.github/workflows/clang.yml +++ b/.github/workflows/clang.yml @@ -6,12 +6,12 @@ on: branches: [ master ] jobs: - build-clang-14-linux-stl: - name: Clang-14 Linux - STL + build-clang-linux-stl: + name: Clang Linux - STL runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-22.04] + os: [ubuntu-20.04, ubuntu-22.04] steps: - uses: actions/checkout@v2 @@ -19,9 +19,9 @@ jobs: - name: Build run: | sudo apt-get update - sudo apt-get install -y "clang-14" "lldb-14" "lld-14" "clang-format-14" - export CC=clang-14 - export CXX=clang++-14 + sudo apt-get install -y "clang" "lldb" "lld" "clang-format" + export CC=clang + export CXX=clang++ export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 git fetch --tags cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03=OFF ./ @@ -31,12 +31,12 @@ jobs: - name: Run tests run: ./test/etl_tests - build-clang-14-linux-no-stl: - name: Clang-14 Linux - No STL + build-clang-linux-no-stl: + name: Clang Linux - No STL runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-22.04] + os: [ubuntu-20.04, ubuntu-22.04] steps: - uses: actions/checkout@v2 @@ -44,26 +44,24 @@ jobs: - name: Build run: | sudo apt-get update - sudo apt-get install -y "clang-14" "lldb-14" "lld-14" "clang-format-14" - export CC=clang-14 - export CXX=clang++-14 + sudo apt-get install -y "clang" "lldb" "lld" "clang-format" + export CC=clang + export CXX=clang++ export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 git fetch --tags cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03=OFF ./ - gcc --version - cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03=OFF ./ clang --version make - name: Run tests run: ./test/etl_tests - build-clang-14-linux-stl-force-cpp03: - name: Clang-14 Linux - STL - Force C++03 + build-clang-linux-stl-force-cpp03: + name: Clang Linux - STL - Force C++03 runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-22.04] + os: [ubuntu-20.04, ubuntu-22.04] steps: - uses: actions/checkout@v2 @@ -71,9 +69,9 @@ jobs: - name: Build run: | sudo apt-get update - sudo apt-get install -y "clang-14" "lldb-14" "lld-14" "clang-format-14" - export CC=clang-14 - export CXX=clang++-14 + sudo apt-get install -y "clang" "lldb" "lld" "clang-format" + export CC=clang + export CXX=clang++ export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 git fetch --tags cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03=ON ./ From 07eacf2959b0c7f874b05e975be4852106edc3f8 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 7 Jan 2023 12:03:44 +0000 Subject: [PATCH 17/60] Added missing notes --- support/Release notes.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/support/Release notes.txt b/support/Release notes.txt index fb75666b..8bf89e22 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -2,6 +2,8 @@ 20.35.9 #657 -Wpedantic-failure. Removed superfluous semicolons #653 CMake - Don't warn on tag missing when subproject +#651 result specialization +#650 Fix result default ctor Removed Ubuntu 18.04 from Github Actions Added Ubuntu 22.04 to Github Actions From a507f8f2a67cd6fdb57822d56d1554e2560f998a Mon Sep 17 00:00:00 2001 From: Alex Hirsch Date: Sat, 7 Jan 2023 13:18:55 +0100 Subject: [PATCH 18/60] emplace member functions return reference to emplaced value (#659) --- include/etl/deque.h | 30 ++++++++++++++++++++---------- include/etl/forward_list.h | 15 ++++++++++----- include/etl/indirect_vector.h | 15 ++++++++++----- include/etl/list.h | 30 ++++++++++++++++++++---------- include/etl/optional.h | 15 ++++++++++----- include/etl/vector.h | 15 ++++++++++----- test/test_deque.cpp | 18 ++++++++++++++++++ test/test_forward_list.cpp | 9 +++++++++ test/test_indirect_vector.cpp | 10 ++++++++++ test/test_list.cpp | 18 ++++++++++++++++++ test/test_optional.cpp | 7 +++++++ test/test_vector.cpp | 7 +++++++ 12 files changed, 149 insertions(+), 40 deletions(-) diff --git a/include/etl/deque.h b/include/etl/deque.h index 8a514e27..aa075ac7 100644 --- a/include/etl/deque.h +++ b/include/etl/deque.h @@ -1742,7 +1742,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_back(Args && ... args) + reference emplace_back(Args && ... args) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(deque_full)); @@ -1752,6 +1752,7 @@ namespace etl ++_end; ++current_size; ETL_INCREMENT_DEBUG_COUNT + return back(); } #else @@ -1761,7 +1762,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_back(const T1& value1) + reference emplace_back(const T1& value1) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(deque_full)); @@ -1771,6 +1772,7 @@ namespace etl ++_end; ++current_size; ETL_INCREMENT_DEBUG_COUNT + return back(); } //************************************************************************* @@ -1778,7 +1780,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_back(const T1& value1, const T2& value2) + reference emplace_back(const T1& value1, const T2& value2) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(deque_full)); @@ -1788,6 +1790,7 @@ namespace etl ++_end; ++current_size; ETL_INCREMENT_DEBUG_COUNT + return back(); } //************************************************************************* @@ -1795,7 +1798,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_back(const T1& value1, const T2& value2, const T3& value3) + 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)); @@ -1805,6 +1808,7 @@ namespace etl ++_end; ++current_size; ETL_INCREMENT_DEBUG_COUNT + return back(); } //************************************************************************* @@ -1812,7 +1816,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + 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)); @@ -1822,6 +1826,7 @@ namespace etl ++_end; ++current_size; ETL_INCREMENT_DEBUG_COUNT + return back(); } #endif @@ -1870,7 +1875,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_front(Args && ... args) + reference emplace_front(Args && ... args) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(deque_full)); @@ -1880,6 +1885,7 @@ namespace etl ::new (&(*_begin)) T(etl::forward(args)...); ++current_size; ETL_INCREMENT_DEBUG_COUNT + return front(); } #else @@ -1889,7 +1895,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_front(const T1& value1) + reference emplace_front(const T1& value1) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(deque_full)); @@ -1899,6 +1905,7 @@ namespace etl ::new (&(*_begin)) T(value1); ++current_size; ETL_INCREMENT_DEBUG_COUNT + return front(); } //************************************************************************* @@ -1906,7 +1913,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2) + reference emplace_front(const T1& value1, const T2& value2) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(deque_full)); @@ -1916,6 +1923,7 @@ namespace etl ::new (&(*_begin)) T(value1, value2); ++current_size; ETL_INCREMENT_DEBUG_COUNT + return front(); } //************************************************************************* @@ -1923,7 +1931,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2, const T3& value3) + 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)); @@ -1933,6 +1941,7 @@ namespace etl ::new (&(*_begin)) T(value1, value2, value3); ++current_size; ETL_INCREMENT_DEBUG_COUNT + return front(); } //************************************************************************* @@ -1940,7 +1949,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + 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)); @@ -1950,6 +1959,7 @@ namespace etl ::new (&(*_begin)) T(value1, value2, value3, value4); ++current_size; ETL_INCREMENT_DEBUG_COUNT + return front(); } #endif diff --git a/include/etl/forward_list.h b/include/etl/forward_list.h index 466a8cee..8d1ac9d5 100644 --- a/include/etl/forward_list.h +++ b/include/etl/forward_list.h @@ -722,7 +722,7 @@ namespace etl /// Emplaces a value to the front of the list.. //************************************************************************* template - void emplace_front(Args && ... args) + reference emplace_front(Args && ... args) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); @@ -731,13 +731,14 @@ namespace etl ::new (&(p_data_node->value)) T(etl::forward(args)...); ETL_INCREMENT_DEBUG_COUNT insert_node_after(start_node, *p_data_node); + return front(); } #else //************************************************************************* /// Emplaces a value to the front of the list.. //************************************************************************* template - void emplace_front(const T1& value1) + reference emplace_front(const T1& value1) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); @@ -746,13 +747,14 @@ namespace etl ::new (&(p_data_node->value)) T(value1); ETL_INCREMENT_DEBUG_COUNT insert_node_after(start_node, *p_data_node); + return front(); } //************************************************************************* /// Emplaces a value to the front of the list.. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2) + reference emplace_front(const T1& value1, const T2& value2) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); @@ -761,13 +763,14 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2); ETL_INCREMENT_DEBUG_COUNT insert_node_after(start_node, *p_data_node); + return front(); } //************************************************************************* /// Emplaces a value to the front of the list.. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2, const T3& value3) + 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)); @@ -776,13 +779,14 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2, value3); ETL_INCREMENT_DEBUG_COUNT insert_node_after(start_node, *p_data_node); + return front(); } //************************************************************************* /// Emplaces a value to the front of the list.. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + 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)); @@ -791,6 +795,7 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2, value3, value4); ETL_INCREMENT_DEBUG_COUNT insert_node_after(start_node, *p_data_node); + return front(); } #endif // ETL_USING_CPP11 && ETL_NOT_USING_STLPORT diff --git a/include/etl/indirect_vector.h b/include/etl/indirect_vector.h index bf057662..78e592bf 100644 --- a/include/etl/indirect_vector.h +++ b/include/etl/indirect_vector.h @@ -782,10 +782,11 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(Args && ... args) + reference emplace_back(Args && ... args) { T* p = storage.create(etl::forward(args)...); lookup.push_back(p); + return back(); } #else //********************************************************************* @@ -794,10 +795,11 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(const T1& value1) + reference emplace_back(const T1& value1) { T* p = storage.create(T(value1)); lookup.push_back(p); + return back(); } //********************************************************************* @@ -806,10 +808,11 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(const T1& value1, const T2& value2) + reference emplace_back(const T1& value1, const T2& value2) { T* p = storage.create(T(value1, value2)); lookup.push_back(p); + return back(); } //********************************************************************* @@ -818,10 +821,11 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(const T1& value1, const T2& value2, const T3& value3) + reference emplace_back(const T1& value1, const T2& value2, const T3& value3) { T* p = storage.create(T(value1, value2, value3)); lookup.push_back(p); + return back(); } //********************************************************************* @@ -830,10 +834,11 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + reference emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4) { T* p = storage.create(T(value1, value2, value3, value4)); lookup.push_back(p); + return back(); } #endif diff --git a/include/etl/list.h b/include/etl/list.h index 6ba5070a..c5e78631 100644 --- a/include/etl/list.h +++ b/include/etl/list.h @@ -862,7 +862,7 @@ namespace etl /// Emplaces a value to the front of the list. //************************************************************************* template - void emplace_front(Args && ... args) + reference emplace_front(Args && ... args) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(list_full)); @@ -873,13 +873,14 @@ namespace etl ::new (&(p_data_node->value)) T(etl::forward(args)...); ETL_INCREMENT_DEBUG_COUNT insert_node(get_head(), *p_data_node); + return front(); } #else //************************************************************************* /// Emplaces a value to the front of the list. //************************************************************************* template - void emplace_front(const T1& value1) + reference emplace_front(const T1& value1) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(list_full)); @@ -890,13 +891,14 @@ namespace etl ::new (&(p_data_node->value)) T(value1); ETL_INCREMENT_DEBUG_COUNT insert_node(get_head(), *p_data_node); + return front(); } //************************************************************************* /// Emplaces a value to the front of the list. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2) + reference emplace_front(const T1& value1, const T2& value2) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(list_full)); @@ -907,13 +909,14 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2); ETL_INCREMENT_DEBUG_COUNT insert_node(get_head(), *p_data_node); + return front(); } //************************************************************************* /// Emplaces a value to the front of the list. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2, const T3& value3) + 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)); @@ -924,13 +927,14 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2, value3); ETL_INCREMENT_DEBUG_COUNT insert_node(get_head(), *p_data_node); + return front(); } //************************************************************************* /// Emplaces a value to the front of the list. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + 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)); @@ -941,6 +945,7 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2, value3, value4); ETL_INCREMENT_DEBUG_COUNT insert_node(get_head(), *p_data_node); + return front(); } #endif @@ -985,7 +990,7 @@ namespace etl //************************************************************************* #if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT template - void emplace_back(Args && ... args) + reference emplace_back(Args && ... args) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(list_full)); @@ -996,10 +1001,11 @@ namespace etl ::new (&(p_data_node->value)) T(etl::forward(args)...); ETL_INCREMENT_DEBUG_COUNT insert_node(terminal_node, *p_data_node); + return back(); } #else template - void emplace_back(const T1& value1) + reference emplace_back(const T1& value1) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(list_full)); @@ -1010,10 +1016,11 @@ namespace etl ::new (&(p_data_node->value)) T(value1); ETL_INCREMENT_DEBUG_COUNT insert_node(terminal_node, *p_data_node); + return back(); } template - void emplace_back(const T1& value1, const T2& value2) + reference emplace_back(const T1& value1, const T2& value2) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(list_full)); @@ -1024,10 +1031,11 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2); ETL_INCREMENT_DEBUG_COUNT insert_node(terminal_node, *p_data_node); + return back(); } template - void emplace_back(const T1& value1, const T2& value2, const T3& value3) + 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)); @@ -1038,10 +1046,11 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2, value3); ETL_INCREMENT_DEBUG_COUNT insert_node(terminal_node, *p_data_node); + return back(); } template - void emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + 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)); @@ -1052,6 +1061,7 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2, value3, value4); ETL_INCREMENT_DEBUG_COUNT insert_node(terminal_node, *p_data_node); + return back(); } #endif diff --git a/include/etl/optional.h b/include/etl/optional.h index 4707d55b..bf5d791a 100644 --- a/include/etl/optional.h +++ b/include/etl/optional.h @@ -427,7 +427,7 @@ namespace etl ///\param args The arguments to construct with. //************************************************************************* template - void emplace(Args && ... args) + T& emplace(Args && ... args) { if (valid) { @@ -437,6 +437,7 @@ namespace etl ::new (storage.template get_address()) T(ETL_OR_STD::forward(args)...); valid = true; + return storage; } #else //************************************************************************* @@ -444,7 +445,7 @@ namespace etl /// 1 parameter. //************************************************************************* template - void emplace(const T1& value1) + T& emplace(const T1& value1) { if (valid) { @@ -454,6 +455,7 @@ namespace etl ::new (storage.template get_address()) T(value1); valid = true; + return storage; } //************************************************************************* @@ -461,7 +463,7 @@ namespace etl /// 2 parameters. //************************************************************************* template - void emplace(const T1& value1, const T2& value2) + T& emplace(const T1& value1, const T2& value2) { if (valid) { @@ -471,6 +473,7 @@ namespace etl ::new (storage.template get_address()) T(value1, value2); valid = true; + return storage; } //************************************************************************* @@ -478,7 +481,7 @@ namespace etl /// 3 parameters. //************************************************************************* template - void emplace(const T1& value1, const T2& value2, const T3& value3) + T& emplace(const T1& value1, const T2& value2, const T3& value3) { if (valid) { @@ -488,6 +491,7 @@ namespace etl ::new (storage.template get_address()) T(value1, value2, value3); valid = true; + return storage; } //************************************************************************* @@ -495,7 +499,7 @@ namespace etl /// 4 parameters. //************************************************************************* template - void emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + T& emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4) { if (valid) { @@ -505,6 +509,7 @@ namespace etl ::new (storage.template get_address()) T(value1, value2, value3, value4); valid = true; + return storage; } #endif diff --git a/include/etl/vector.h b/include/etl/vector.h index 86a30d40..b6ebec27 100644 --- a/include/etl/vector.h +++ b/include/etl/vector.h @@ -459,7 +459,7 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(Args && ... args) + reference emplace_back(Args && ... args) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); @@ -467,6 +467,7 @@ namespace etl ::new (p_end) T(etl::forward(args)...); ++p_end; ETL_INCREMENT_DEBUG_COUNT + return back(); } #else //********************************************************************* @@ -475,7 +476,7 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(const T1& value1) + reference emplace_back(const T1& value1) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); @@ -483,6 +484,7 @@ namespace etl ::new (p_end) T(value1); ++p_end; ETL_INCREMENT_DEBUG_COUNT + return back(); } //********************************************************************* @@ -491,7 +493,7 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(const T1& value1, const T2& value2) + reference emplace_back(const T1& value1, const T2& value2) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); @@ -499,6 +501,7 @@ namespace etl ::new (p_end) T(value1, value2); ++p_end; ETL_INCREMENT_DEBUG_COUNT + return back(); } //********************************************************************* @@ -507,7 +510,7 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(const T1& value1, const T2& value2, const T3& value3) + 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)); @@ -515,6 +518,7 @@ namespace etl ::new (p_end) T(value1, value2, value3); ++p_end; ETL_INCREMENT_DEBUG_COUNT + return back(); } //********************************************************************* @@ -523,7 +527,7 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + 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)); @@ -531,6 +535,7 @@ namespace etl ::new (p_end) T(value1, value2, value3, value4); ++p_end; ETL_INCREMENT_DEBUG_COUNT + return back(); } #endif diff --git a/test/test_deque.cpp b/test/test_deque.cpp index 29c0b63d..d99d364b 100644 --- a/test/test_deque.cpp +++ b/test/test_deque.cpp @@ -1490,6 +1490,15 @@ namespace CHECK(std::equal(compare_data.begin(), compare_data.end(), data.begin())); } + //************************************************************************* + TEST(test_emplace_back_return) + { + DataNDC data; + + auto& back = data.emplace_back("42"); + CHECK_EQUAL(back, data.back()); + } + //************************************************************************* TEST(test_push_back_excess) { @@ -1602,6 +1611,15 @@ namespace CHECK(std::equal(compare_data.begin(), compare_data.end(), data.begin())); } + //************************************************************************* + TEST(test_emplace_front_return) + { + DataNDC data; + + auto& front = data.emplace_front("42"); + CHECK_EQUAL(front, data.front()); + } + //************************************************************************* TEST(test_push_front_excess) { diff --git a/test/test_forward_list.cpp b/test/test_forward_list.cpp index 21356c63..9e8a2712 100644 --- a/test/test_forward_list.cpp +++ b/test/test_forward_list.cpp @@ -694,6 +694,15 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_front_return) + { + DataNDC data; + + auto& front = data.emplace_front("42"); + CHECK_EQUAL(front, data.front()); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_emplace_after) { diff --git a/test/test_indirect_vector.cpp b/test/test_indirect_vector.cpp index 06ba7d2b..f6d3782b 100644 --- a/test/test_indirect_vector.cpp +++ b/test/test_indirect_vector.cpp @@ -715,6 +715,16 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back_return) + { + DataNDC data; + std::string value("A"); + + auto& back = data.emplace_back(value); + CHECK_EQUAL(back, data.back()); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_back_unique_ptr) { diff --git a/test/test_list.cpp b/test/test_list.cpp index 5e3cfd11..56ac2d04 100644 --- a/test/test_list.cpp +++ b/test/test_list.cpp @@ -731,6 +731,15 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_front_return) + { + DataNDC data; + + auto& front = data.emplace_front("42"); + CHECK_EQUAL(front, data.front()); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_front_excess) { @@ -887,6 +896,15 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back_return) + { + DataNDC data; + + auto& back = data.emplace_back("42"); + CHECK_EQUAL(back, data.back()); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_back_excess) { diff --git a/test/test_optional.cpp b/test/test_optional.cpp index 03eee1d1..9308af27 100644 --- a/test/test_optional.cpp +++ b/test/test_optional.cpp @@ -127,6 +127,13 @@ namespace CHECK_EQUAL(1, DataM::get_instance_count()); } + //************************************************************************* + TEST(test_emplace_return) + { + etl::optional data; + CHECK_EQUAL(42U, data.emplace(42U).value); + } + //************************************************************************* TEST(test_moveable) { diff --git a/test/test_vector.cpp b/test/test_vector.cpp index 70313f3f..747ccdd3 100644 --- a/test/test_vector.cpp +++ b/test/test_vector.cpp @@ -659,6 +659,13 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back_return) + { + Data data; + CHECK_EQUAL(42, data.emplace_back(42)); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_back_literal) { From a398207e3d4d7a4e1e4df83fe169af806251f2be Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 7 Jan 2023 15:20:25 +0000 Subject: [PATCH 19/60] emplace_front, emplace_back updates --- include/etl/private/ivectorpointer.h | 4 +- test/test_vector.cpp | 64 ++++++++++---------- test/test_vector_external_buffer.cpp | 32 ++++++++++ test/test_vector_non_trivial.cpp | 54 ++++++++++------- test/test_vector_pointer.cpp | 9 +++ test/test_vector_pointer_external_buffer.cpp | 9 +++ 6 files changed, 116 insertions(+), 56 deletions(-) diff --git a/include/etl/private/ivectorpointer.h b/include/etl/private/ivectorpointer.h index c2cffa7f..ac1e0746 100644 --- a/include/etl/private/ivectorpointer.h +++ b/include/etl/private/ivectorpointer.h @@ -354,9 +354,11 @@ namespace etl /// If asserts or exceptions are enabled, emits vector_full if the vector is already full. ///\param value The value to add. //********************************************************************* - void emplace_back(parameter_t value) + reference emplace_back(parameter_t value) { base_t::emplace_back(value); + + return back(); } //************************************************************************* diff --git a/test/test_vector.cpp b/test/test_vector.cpp index 747ccdd3..ee79fba5 100644 --- a/test/test_vector.cpp +++ b/test/test_vector.cpp @@ -634,38 +634,6 @@ namespace CHECK(is_equal); } - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_emplace_back) - { - Compare_Data compare_data; - Data data; - - for (int i = 0; i < int(SIZE); ++i) - { - compare_data.emplace_back(i); - } - - for (int i = 0; i < int(SIZE); ++i) - { - data.emplace_back(i); - } - - CHECK_EQUAL(compare_data.size(), data.size()); - - bool is_equal = std::equal(data.begin(), - data.end(), - compare_data.begin()); - - CHECK(is_equal); - } - - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_emplace_back_return) - { - Data data; - CHECK_EQUAL(42, data.emplace_back(42)); - } - //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_back_literal) { @@ -704,6 +672,38 @@ namespace CHECK_THROW(data.push_back(SIZE), etl::vector_full); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back) + { + Compare_Data compare_data; + Data data; + + for (int i = 0; i < int(SIZE); ++i) + { + compare_data.emplace_back(i); + } + + for (int i = 0; i < int(SIZE); ++i) + { + data.emplace_back(i); + } + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back_return) + { + Data data; + CHECK_EQUAL(42, data.emplace_back(42)); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_pop_back) { diff --git a/test/test_vector_external_buffer.cpp b/test/test_vector_external_buffer.cpp index 117bcdb1..ab5e816e 100644 --- a/test/test_vector_external_buffer.cpp +++ b/test/test_vector_external_buffer.cpp @@ -685,6 +685,38 @@ namespace CHECK_THROW(data.push_back(SIZE), etl::vector_full); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back) + { + Compare_Data compare_data; + Data data(buffer1, SIZE); + + for (int i = 0; i < int(SIZE); ++i) + { + compare_data.emplace_back(i); + } + + for (int i = 0; i < int(SIZE); ++i) + { + data.emplace_back(i); + } + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back_return) + { + Data data(buffer1, SIZE); + CHECK_EQUAL(42, data.emplace_back(42)); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_pop_back) { diff --git a/test/test_vector_non_trivial.cpp b/test/test_vector_non_trivial.cpp index 3b4efc27..7bbcdebf 100644 --- a/test/test_vector_non_trivial.cpp +++ b/test/test_vector_non_trivial.cpp @@ -662,29 +662,6 @@ namespace CHECK_THROW(data.push_back(NDC("Z")), etl::vector_full); } - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_emplace_back) - { - CompareDataNDC compare_data; - DataNDC data; - - for (size_t i = 0UL; i < SIZE; ++i) - { - std::string value(" "); - value[0] = char('A' + i); - compare_data.emplace_back(value, i); - data.emplace_back(value, i); - } - - CHECK_EQUAL(compare_data.size(), data.size()); - - bool is_equal = std::equal(data.begin(), - data.end(), - compare_data.begin()); - - CHECK(is_equal); - } - //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_back_unique_ptr) { @@ -711,6 +688,37 @@ namespace CHECK_EQUAL(4, *data[3]); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back) + { + CompareDataNDC compare_data; + DataNDC data; + + for (size_t i = 0UL; i < SIZE; ++i) + { + std::string value(" "); + value[0] = char('A' + i); + compare_data.emplace_back(value, i); + data.emplace_back(value, i); + } + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back_return) + { + DataNDC data; + + CHECK_EQUAL(NDC("A", 42), data.emplace_back("A", 42)); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_insert_int) { diff --git a/test/test_vector_pointer.cpp b/test/test_vector_pointer.cpp index d6aad71d..76a67ab3 100644 --- a/test/test_vector_pointer.cpp +++ b/test/test_vector_pointer.cpp @@ -1057,6 +1057,15 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back_return) + { + Data data; + int d = 42; + + CHECK_EQUAL(&d, data.emplace_back(&d)); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_pop_back) { diff --git a/test/test_vector_pointer_external_buffer.cpp b/test/test_vector_pointer_external_buffer.cpp index edad3ac9..db4b9910 100644 --- a/test/test_vector_pointer_external_buffer.cpp +++ b/test/test_vector_pointer_external_buffer.cpp @@ -1043,6 +1043,15 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back_return) + { + Data data(buffer1, SIZE); + int d = 42; + + CHECK_EQUAL(&d, data.emplace_back(&d)); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_pop_back) { From 76e2cb1899396e80e364cb2cf1aa5bda635dc22a Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 7 Jan 2023 15:23:17 +0000 Subject: [PATCH 20/60] Updated version and release info --- 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 | 4 ++++ version.txt | 2 +- 7 files changed, 10 insertions(+), 6 deletions(-) diff --git a/arduino/library-arduino.json b/arduino/library-arduino.json index b585db35..42bd6fba 100644 --- a/arduino/library-arduino.json +++ b/arduino/library-arduino.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library - Arduino", - "version": "20.35.9", + "version": "20.35.10", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/arduino/library-arduino.properties b/arduino/library-arduino.properties index 6e882d68..abbd8bb9 100644 --- a/arduino/library-arduino.properties +++ b/arduino/library-arduino.properties @@ -1,5 +1,5 @@ name=Embedded Template Library - Arduino -version=20.35.9 +version=20.35.10 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/include/etl/version.h b/include/etl/version.h index 1176944c..79240a7e 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 35 -#define ETL_VERSION_PATCH 9 +#define ETL_VERSION_PATCH 10 #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 6c1382ff..e2bc28d3 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library", - "version": "20.35.9", + "version": "20.35.10", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/library.properties b/library.properties index 8e2d9c21..1ae6a430 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Embedded Template Library -version=20.35.9 +version=20.35.10 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/support/Release notes.txt b/support/Release notes.txt index 8bf89e22..020d1c3c 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,3 +1,7 @@ +=============================================================================== +20.35.10 +#659-emplace-member-functions-return-reference-to-emplaced-value + =============================================================================== 20.35.9 #657 -Wpedantic-failure. Removed superfluous semicolons diff --git a/version.txt b/version.txt index e7f94ac3..afa2d91d 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -20.35.9 +20.35.10 From 900c69de8722d594ff98c45942f1f16c410ff53f Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 7 Jan 2023 18:46:14 +0000 Subject: [PATCH 21/60] Improved emplace testing Changed unit test macro CHECK_FALSE_EQUAL to CHECK_NOT_EQUAL --- support/Release notes.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support/Release notes.txt b/support/Release notes.txt index 020d1c3c..8925639b 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,6 +1,6 @@ =============================================================================== 20.35.10 -#659-emplace-member-functions-return-reference-to-emplaced-value +#659 emplace member functions return reference to emplaced value =============================================================================== 20.35.9 From 044fc1b2ffc82c14c6e1eb972801201c0d390068 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 7 Jan 2023 18:46:59 +0000 Subject: [PATCH 22/60] Improved emplace testing Changed unit test macro CHECK_FALSE_EQUAL to CHECK_NOT_EQUAL --- test/UnitTest++/CheckMacros.h | 14 +++++++------- test/test_deque.cpp | 2 ++ test/test_forward_list.cpp | 1 + test/test_indirect_vector.cpp | 6 ++++-- test/test_list.cpp | 2 ++ test/test_vector.cpp | 1 + test/test_vector_external_buffer.cpp | 1 + test/test_vector_non_trivial.cpp | 3 ++- test/test_vector_pointer.cpp | 6 ++++-- test/test_vector_pointer_external_buffer.cpp | 6 ++++-- 10 files changed, 28 insertions(+), 14 deletions(-) diff --git a/test/UnitTest++/CheckMacros.h b/test/UnitTest++/CheckMacros.h index 23a8dca9..0ee75dfd 100644 --- a/test/UnitTest++/CheckMacros.h +++ b/test/UnitTest++/CheckMacros.h @@ -97,7 +97,7 @@ }) \ UNITTEST_MULTILINE_MACRO_END -#define UNITTEST_CHECK_FALSE_EQUAL(expected, actual) \ +#define UNITTEST_CHECK_NOT_EQUAL(expected, actual) \ UNITTEST_MULTILINE_MACRO_BEGIN \ UNITTEST_IMPL_TRY \ ({ \ @@ -254,16 +254,16 @@ #define CHECK_EQUAL_HEX UNITTEST_CHECK_EQUAL_HEX #endif - #ifdef CHECK_FALSE_EQUAL - #error CHECK_FALSE_EQUAL already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_FALSE_EQUAL instead + #ifdef CHECK_NOT_EQUAL + #error CHECK_NOT_EQUAL already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_NOT_EQUAL instead #else - #define CHECK_FALSE_EQUAL UNITTEST_CHECK_FALSE_EQUAL + #define CHECK_NOT_EQUAL UNITTEST_CHECK_NOT_EQUAL #endif - #ifdef CHECK_FALSE_EQUAL_HEX - #error CHECK_FALSE_EQUAL_HEX already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_FALSE_EQUAL_HEX instead + #ifdef CHECK_NOT_EQUAL_HEX + #error CHECK_NOT_EQUAL_HEX already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_NOT_EQUAL_HEX instead #else - #define CHECK_FALSE_EQUAL_HEX UNITTEST_CHECK_FALSE_EQUAL_HEX + #define CHECK_NOT_EQUAL_HEX UNITTEST_CHECK_NOT_EQUAL_HEX #endif #ifdef CHECK_CLOSE diff --git a/test/test_deque.cpp b/test/test_deque.cpp index d99d364b..7d58f9fd 100644 --- a/test/test_deque.cpp +++ b/test/test_deque.cpp @@ -1495,6 +1495,7 @@ namespace { DataNDC data; + data.emplace_back("24"); auto& back = data.emplace_back("42"); CHECK_EQUAL(back, data.back()); } @@ -1616,6 +1617,7 @@ namespace { DataNDC data; + data.emplace_front("24"); auto& front = data.emplace_front("42"); CHECK_EQUAL(front, data.front()); } diff --git a/test/test_forward_list.cpp b/test/test_forward_list.cpp index 9e8a2712..43c85bde 100644 --- a/test/test_forward_list.cpp +++ b/test/test_forward_list.cpp @@ -699,6 +699,7 @@ namespace { DataNDC data; + data.emplace_front("24"); auto& front = data.emplace_front("42"); CHECK_EQUAL(front, data.front()); } diff --git a/test/test_indirect_vector.cpp b/test/test_indirect_vector.cpp index f6d3782b..97dc944f 100644 --- a/test/test_indirect_vector.cpp +++ b/test/test_indirect_vector.cpp @@ -719,9 +719,11 @@ namespace TEST_FIXTURE(SetupFixture, test_emplace_back_return) { DataNDC data; - std::string value("A"); + std::string value1("A"); + std::string value2("B"); - auto& back = data.emplace_back(value); + data.emplace_back(value1); + auto& back = data.emplace_back(value2); CHECK_EQUAL(back, data.back()); } diff --git a/test/test_list.cpp b/test/test_list.cpp index 56ac2d04..d65623ce 100644 --- a/test/test_list.cpp +++ b/test/test_list.cpp @@ -736,6 +736,7 @@ namespace { DataNDC data; + data.emplace_front("24"); auto& front = data.emplace_front("42"); CHECK_EQUAL(front, data.front()); } @@ -901,6 +902,7 @@ namespace { DataNDC data; + data.emplace_back("24"); auto& back = data.emplace_back("42"); CHECK_EQUAL(back, data.back()); } diff --git a/test/test_vector.cpp b/test/test_vector.cpp index ee79fba5..8804c703 100644 --- a/test/test_vector.cpp +++ b/test/test_vector.cpp @@ -701,6 +701,7 @@ namespace TEST_FIXTURE(SetupFixture, test_emplace_back_return) { Data data; + data.emplace_back(24); CHECK_EQUAL(42, data.emplace_back(42)); } diff --git a/test/test_vector_external_buffer.cpp b/test/test_vector_external_buffer.cpp index ab5e816e..aac5964f 100644 --- a/test/test_vector_external_buffer.cpp +++ b/test/test_vector_external_buffer.cpp @@ -714,6 +714,7 @@ namespace TEST_FIXTURE(SetupFixture, test_emplace_back_return) { Data data(buffer1, SIZE); + data.emplace_back(24); CHECK_EQUAL(42, data.emplace_back(42)); } diff --git a/test/test_vector_non_trivial.cpp b/test/test_vector_non_trivial.cpp index 7bbcdebf..f7779605 100644 --- a/test/test_vector_non_trivial.cpp +++ b/test/test_vector_non_trivial.cpp @@ -716,7 +716,8 @@ namespace { DataNDC data; - CHECK_EQUAL(NDC("A", 42), data.emplace_back("A", 42)); + data.emplace_back("A", 24); + CHECK_EQUAL(NDC("B", 42), data.emplace_back("B", 42)); } //************************************************************************* diff --git a/test/test_vector_pointer.cpp b/test/test_vector_pointer.cpp index 76a67ab3..f4152804 100644 --- a/test/test_vector_pointer.cpp +++ b/test/test_vector_pointer.cpp @@ -1061,9 +1061,11 @@ namespace TEST_FIXTURE(SetupFixture, test_emplace_back_return) { Data data; - int d = 42; + int d1 = 22; + int d2 = 42; - CHECK_EQUAL(&d, data.emplace_back(&d)); + data.emplace_back(&d1); + CHECK_EQUAL(&d2, data.emplace_back(&d2)); } //************************************************************************* diff --git a/test/test_vector_pointer_external_buffer.cpp b/test/test_vector_pointer_external_buffer.cpp index db4b9910..97c6fe9d 100644 --- a/test/test_vector_pointer_external_buffer.cpp +++ b/test/test_vector_pointer_external_buffer.cpp @@ -1047,9 +1047,11 @@ namespace TEST_FIXTURE(SetupFixture, test_emplace_back_return) { Data data(buffer1, SIZE); - int d = 42; + int d1 = 42; + int d2 = 24; - CHECK_EQUAL(&d, data.emplace_back(&d)); + data.emplace_back(&d1); + CHECK_EQUAL(&d2, data.emplace_back(&d2)); } //************************************************************************* From 8b0c2325af4581f6351b293e6ff3ca42030ab971 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 7 Jan 2023 19:02:56 +0000 Subject: [PATCH 23/60] Improved emplace testing --- test/test_vector.cpp | 4 +++- test/test_vector_external_buffer.cpp | 4 +++- test/test_vector_non_trivial.cpp | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/test/test_vector.cpp b/test/test_vector.cpp index 8804c703..facf99cc 100644 --- a/test/test_vector.cpp +++ b/test/test_vector.cpp @@ -701,8 +701,10 @@ namespace TEST_FIXTURE(SetupFixture, test_emplace_back_return) { Data data; + data.emplace_back(24); - CHECK_EQUAL(42, data.emplace_back(42)); + auto back = data.emplace_back(42); + CHECK_EQUAL(back, data.back()); } //************************************************************************* diff --git a/test/test_vector_external_buffer.cpp b/test/test_vector_external_buffer.cpp index aac5964f..f1e6e823 100644 --- a/test/test_vector_external_buffer.cpp +++ b/test/test_vector_external_buffer.cpp @@ -714,8 +714,10 @@ namespace TEST_FIXTURE(SetupFixture, test_emplace_back_return) { Data data(buffer1, SIZE); + data.emplace_back(24); - CHECK_EQUAL(42, data.emplace_back(42)); + auto back = data.emplace_back(42); + CHECK_EQUAL(back, data.back()); } //************************************************************************* diff --git a/test/test_vector_non_trivial.cpp b/test/test_vector_non_trivial.cpp index f7779605..ccc58775 100644 --- a/test/test_vector_non_trivial.cpp +++ b/test/test_vector_non_trivial.cpp @@ -717,7 +717,8 @@ namespace DataNDC data; data.emplace_back("A", 24); - CHECK_EQUAL(NDC("B", 42), data.emplace_back("B", 42)); + auto back = data.emplace_back("B", 42); + CHECK_EQUAL(back, data.back()); } //************************************************************************* From e255b34ecd51b9bdc90812ccdb2e6b5e2d34a7a3 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 19 Jan 2023 09:57:03 +0000 Subject: [PATCH 24/60] Added emplace by index to variant (variadic) --- include/etl/private/variant_variadic.h | 23 +++++++++++++++++- test/test_variant_variadic.cpp | 33 +++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/include/etl/private/variant_variadic.h b/include/etl/private/variant_variadic.h index b69017a2..42106ae7 100644 --- a/include/etl/private/variant_variadic.h +++ b/include/etl/private/variant_variadic.h @@ -681,7 +681,7 @@ namespace etl } //*************************************************************************** - /// Emplace with variadic constructor parameters. + /// Emplace by type with variadic constructor parameters. //*************************************************************************** template T& emplace(TArgs&&... args) @@ -701,6 +701,27 @@ namespace etl return *static_cast(data); } + //*************************************************************************** + /// Emplace by index with variadic constructor parameters. + //*************************************************************************** + template + typename etl::variant_alternative>::type emplace(TArgs&&... args) + { + static_assert(Index < etl::private_variant::parameter_pack::size, "Index out of range"); + + using type = typename etl::private_variant::parameter_pack::type_from_index::type; + + operation(private_variant::Destroy, data, nullptr); + + construct_in_place_args(data, etl::forward(args)...); + + operation = operation_type::value, etl::is_move_constructible::value>::do_operation; + + type_id = Index; + + return *static_cast(data); + } + //*************************************************************************** /// Move assignment operator for type. ///\param value The value to assign. diff --git a/test/test_variant_variadic.cpp b/test/test_variant_variadic.cpp index 3bc02e22..456c7737 100644 --- a/test/test_variant_variadic.cpp +++ b/test/test_variant_variadic.cpp @@ -542,7 +542,7 @@ namespace #endif //************************************************************************* - TEST(test_emplace_value) + TEST(test_emplace_value_by_type) { // Char. char c = 'a'; @@ -572,6 +572,37 @@ namespace CHECK_EQUAL(text, etl::get(variant_text_etl)); } + //************************************************************************* + TEST(test_emplace_value_by_index) + { + // Char. + char c = 'a'; + test_variant_etl_3 variant_char_etl; + + c = variant_char_etl.emplace<0>(c); + CHECK(c == 'a'); + CHECK(etl::holds_alternative(variant_char_etl)); + CHECK_EQUAL(c, etl::get(variant_char_etl)); + + // Int. + int i = 1; + test_variant_etl_3 variant_int_etl; + + i = variant_int_etl.emplace<1>(i); + CHECK(i == 1); + CHECK(etl::holds_alternative(variant_int_etl)); + CHECK_EQUAL(i, etl::get(variant_int_etl)); + + // String. + std::string text("Some Text"); + test_variant_etl_3 variant_text_etl; + + text = variant_text_etl.emplace<2>(text); + CHECK(text == "Some Text"); + CHECK(etl::holds_alternative(variant_text_etl)); + CHECK_EQUAL(text, etl::get(variant_text_etl)); + } + //************************************************************************* TEST(test_copy_constructor) { From 3beff5658761186903e9e6389bfc2e8e344531f3 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 19 Jan 2023 10:31:39 +0000 Subject: [PATCH 25/60] Fixed byte_stream_reader skip() Change '<' to '<=' --- include/etl/byte_stream.h | 2 +- test/test_byte_stream.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/etl/byte_stream.h b/include/etl/byte_stream.h index 934a8a45..2986ff56 100644 --- a/include/etl/byte_stream.h +++ b/include/etl/byte_stream.h @@ -749,7 +749,7 @@ namespace etl template bool skip(size_t n) { - if (n < available()) + if (n <= available()) { pcurrent += (n * sizeof(T)); return true; diff --git a/test/test_byte_stream.cpp b/test/test_byte_stream.cpp index 0ea6b069..4f89c3a8 100644 --- a/test/test_byte_stream.cpp +++ b/test/test_byte_stream.cpp @@ -1333,5 +1333,15 @@ namespace CHECK_EQUAL(expected[i], result[i]); } } + //************************************************************************* + TEST(read_byte_stream_skip) + { + etl::array data; + etl::byte_stream_reader r(data.begin(), data.size(), etl::endian::little); + CHECK_TRUE(r.skip(4)); + etl::optional> result = r.read(4); + CHECK_FALSE(result.has_value()); + CHECK_TRUE(r.empty()); + } }; } From 38c807401ea886f8d0e35dba7ab785c6ddf31e13 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 20 Jan 2023 10:53:47 +0000 Subject: [PATCH 26/60] Added emplace by index to variant (variadic) #660 byte_stream_reader::skip error --- arduino/library-arduino.json | 2 +- arduino/library-arduino.properties | 2 +- include/etl/private/variant_variadic.h | 2 +- include/etl/version.h | 2 +- library.json | 2 +- library.properties | 2 +- support/Release notes.txt | 5 +++++ version.txt | 2 +- 8 files changed, 12 insertions(+), 7 deletions(-) diff --git a/arduino/library-arduino.json b/arduino/library-arduino.json index 42bd6fba..9130ee02 100644 --- a/arduino/library-arduino.json +++ b/arduino/library-arduino.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library - Arduino", - "version": "20.35.10", + "version": "20.35.11", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/arduino/library-arduino.properties b/arduino/library-arduino.properties index abbd8bb9..6360d9c1 100644 --- a/arduino/library-arduino.properties +++ b/arduino/library-arduino.properties @@ -1,5 +1,5 @@ name=Embedded Template Library - Arduino -version=20.35.10 +version=20.35.11 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/include/etl/private/variant_variadic.h b/include/etl/private/variant_variadic.h index 42106ae7..fe003364 100644 --- a/include/etl/private/variant_variadic.h +++ b/include/etl/private/variant_variadic.h @@ -709,7 +709,7 @@ namespace etl { static_assert(Index < etl::private_variant::parameter_pack::size, "Index out of range"); - using type = typename etl::private_variant::parameter_pack::type_from_index::type; + using type = typename etl::private_variant::parameter_pack::template type_from_index::type; operation(private_variant::Destroy, data, nullptr); diff --git a/include/etl/version.h b/include/etl/version.h index 79240a7e..f5272b22 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 35 -#define ETL_VERSION_PATCH 10 +#define ETL_VERSION_PATCH 11 #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 e2bc28d3..2bc02502 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library", - "version": "20.35.10", + "version": "20.35.11", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/library.properties b/library.properties index 1ae6a430..8dd949ce 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Embedded Template Library -version=20.35.10 +version=20.35.11 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/support/Release notes.txt b/support/Release notes.txt index 8925639b..a696f5ea 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,3 +1,8 @@ +=============================================================================== +20.35.11 +Added emplace by index to variant (variadic) +#660 byte_stream_reader::skip error + =============================================================================== 20.35.10 #659 emplace member functions return reference to emplaced value diff --git a/version.txt b/version.txt index afa2d91d..fa556776 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -20.35.10 +20.35.11 From f8d5a84161f07f9a5f2ffe95ce42142e27e87797 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 20 Jan 2023 12:13:27 +0000 Subject: [PATCH 27/60] Change iterator constructor parameter from reference to pointer --- include/etl/intrusive_forward_list.h | 20 ++++++++-------- include/etl/intrusive_list.h | 36 ++++++++++++++-------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/include/etl/intrusive_forward_list.h b/include/etl/intrusive_forward_list.h index da74970b..55f29229 100644 --- a/include/etl/intrusive_forward_list.h +++ b/include/etl/intrusive_forward_list.h @@ -332,11 +332,6 @@ namespace etl { } - iterator(value_type* value) - : p_value(value) - { - } - iterator(const iterator& other) : p_value(other.p_value) { @@ -390,6 +385,11 @@ namespace etl private: + iterator(value_type* value) + : p_value(value) + { + } + value_type* p_value; }; @@ -407,11 +407,6 @@ namespace etl { } - const_iterator(const value_type* value) - : p_value(value) - { - } - const_iterator(const typename intrusive_forward_list::iterator& other) : p_value(other.p_value) { @@ -470,6 +465,11 @@ namespace etl private: + const_iterator(const value_type* value) + : p_value(value) + { + } + const value_type* p_value; }; diff --git a/include/etl/intrusive_list.h b/include/etl/intrusive_list.h index 800c9d8e..89e7d590 100644 --- a/include/etl/intrusive_list.h +++ b/include/etl/intrusive_list.h @@ -387,11 +387,6 @@ namespace etl { } - iterator(value_type& value) - : p_value(&value) - { - } - iterator(const iterator& other) : p_value(other.p_value) { @@ -460,6 +455,11 @@ namespace etl private: + iterator(value_type* value) + : p_value(value) + { + } + value_type* p_value; }; @@ -477,11 +477,6 @@ namespace etl { } - const_iterator(const value_type& value) - : p_value(&value) - { - } - const_iterator(const typename intrusive_list::iterator& other) : p_value(other.p_value) { @@ -555,6 +550,11 @@ namespace etl private: + const_iterator(const value_type* value) + : p_value(value) + { + } + const value_type* p_value; }; @@ -590,7 +590,7 @@ namespace etl //************************************************************************* iterator begin() { - return iterator(static_cast(*this->get_head())); + return iterator(static_cast(this->get_head())); } //************************************************************************* @@ -598,7 +598,7 @@ namespace etl //************************************************************************* const_iterator begin() const { - return const_iterator(static_cast(*this->get_head())); + return const_iterator(reinterpret_cast(this->get_head())); } //************************************************************************* @@ -606,7 +606,7 @@ namespace etl //************************************************************************* const_iterator cbegin() const { - return const_iterator(static_cast(*this->get_head())); + return const_iterator(reinterpret_cast(this->get_head())); } //************************************************************************* @@ -614,7 +614,7 @@ namespace etl //************************************************************************* iterator end() { - return iterator(static_cast(this->terminal_link)); + return iterator(static_cast(&this->terminal_link)); } //************************************************************************* @@ -622,7 +622,7 @@ namespace etl //************************************************************************* const_iterator end() const { - return const_iterator(static_cast(this->terminal_link)); + return const_iterator(static_cast(&this->terminal_link)); } //************************************************************************* @@ -630,7 +630,7 @@ namespace etl //************************************************************************* const_iterator cend() const { - return const_iterator(static_cast(this->terminal_link)); + return const_iterator(static_cast(&this->terminal_link)); } //************************************************************************* @@ -671,7 +671,7 @@ namespace etl iterator insert(const_iterator position, value_type& value) { this->insert_link(position.p_value->link_type::etl_previous, value); - return iterator(value); + return iterator(&value); } //************************************************************************* @@ -737,7 +737,7 @@ namespace etl } else { - return iterator(*static_cast(p_last)); + return iterator(static_cast(p_last)); } } From 6ce92da03ade4acd54f2a4f6cf8f84646bde7def Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 21 Jan 2023 10:45:14 +0000 Subject: [PATCH 28/60] Updated release notes --- support/Release notes.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/support/Release notes.txt b/support/Release notes.txt index a696f5ea..6b2f9159 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,3 +1,7 @@ +=============================================================================== +20.35.12 +#649 subscript-1 is out of bounds. Changed intrusive_list and intrusive_forward_list iterator constructor parameter from reference to pointer. + =============================================================================== 20.35.11 Added emplace by index to variant (variadic) From 5fb3e4c2e6049b05ec49653925780f6bef9a8f6b Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 2 Nov 2022 11:54:21 +0000 Subject: [PATCH 29/60] Work-In-Progress for full implementation of etl::expected fix set of ETL_NO_STL flag (#628) Co-authored-by: Sergey Skorokhod Removed duplicate include unique_ptr updates - Work in progress Updated versions & memory.h Fix duplicate function Fixed incorrect 'valid' flag in assignment operator for arithmetic specialisation Updated version and release notes Fix bug #636 in optional emplace for pod types (#638) Updated version info Updated generator test script Only build tests if top level project (#639) Removed trailing spaces Updated version info Incorrect C++03 enable_if syntax Updated version info Don't use `push_macro` and `pull_macro` with Tasking compiler (#643) * Autodetect Tasking compiler #642 * Don't use `push_macro` and `pop_macro` for Tasking compiler #642 Co-authored-by: Todd Snider #643 Don't use push_macro and pull_macro with Tasking compiler Updated etl::delgate to handle const functors correctly Updated version info Fixed functor delegate enable_if Updated release notes Avoid 'missing return statement at end of non-void function' in `etl::visit<>()`. (#645) * Avoid 'missing return statement at end of non-void function' in `etl::visit<>()`. For some definitions of `ETL_ASSERT()` there may be no return statement in case of an invalid type. This results in undefined behavior. Warning[Pe940]: missing return statement at end of non-void function "etl::visit(TVisitor &, TVariant const &) include\etl\private\variant_legacy.h 976 * Use more self-explaining code. Substitute ET_ASSERT() and return by dedicated macro. This moves the responsibility of how to handle errors to the dedicated place. improve is_constructible, is_copy_constructible, is_move_constructible for type traits with default definitions (#648) Removed unused ETL_USE_MEM_BUILTINS option Updated version info Updated release notes Added etl::result specialisation Reverted code for etl::result specialisation Added etl::result specialisation Reverted code for etl::result specialisation Fixed perfect forwarding for make_xxx helper functions Don't warn on tag missing when subproject (#653) (#655) Different solution than proposed in the issue, since that proposed solution would given unexpected results when an intermediate (untagged) commit is checked out. This change simply skips warning about a missing git version when this is a subproject, and uses the original version calculation logic. I've also renamed `determine_version` to `determine_version_with_file`. I'd originally done this in an intermediate version of this PR, but I think that keeping the renaming is clearer code. Removed superfluous semicolons Updated version and release notes Removed testing for 18.04 Added testing for 22.04 Updated Github Actions for Clang Updated version and release notes clang updates for Github Actions Added missing notes emplace member functions return reference to emplaced value (#659) emplace_front, emplace_back updates Updated version and release info Improved emplace testing Changed unit test macro CHECK_FALSE_EQUAL to CHECK_NOT_EQUAL Improved emplace testing Changed unit test macro CHECK_FALSE_EQUAL to CHECK_NOT_EQUAL Improved emplace testing Work-In-Progress Work-In-Progress Added indexed emplace More typedefs for etl::result Work in progress Work in progress Work in progress Changed default constructor Added function comments --- .github/workflows/clang.yml | 38 +- .github/workflows/gcc.yml | 6 +- CMakeLists.txt | 12 +- arduino/library-arduino.json | 2 +- arduino/library-arduino.properties | 2 +- cmake/helpers.cmake | 8 +- include/etl/array_view.h | 9 +- include/etl/binary.h | 4 +- include/etl/delegate.h | 2 +- include/etl/deque.h | 30 +- include/etl/expected.h | 691 ++++++++++++++++-- include/etl/forward_list.h | 17 +- .../etl/generators/type_traits_generator.h | 40 +- include/etl/indirect_vector.h | 17 +- include/etl/list.h | 30 +- include/etl/memory.h | 128 +++- include/etl/optional.h | 23 +- include/etl/private/delegate_cpp03.h | 159 +++- include/etl/private/delegate_cpp11.h | 64 +- include/etl/private/ivectorpointer.h | 4 +- include/etl/private/minmax_pop.h | 2 +- include/etl/private/minmax_push.h | 2 +- include/etl/private/variant_legacy.h | 32 +- include/etl/private/variant_variadic.h | 23 +- include/etl/profiles/determine_compiler.h | 13 + .../etl/profiles/determine_compiler_version.h | 3 + include/etl/result.h | 165 ++++- include/etl/span.h | 16 +- include/etl/type_traits.h | 40 +- include/etl/vector.h | 17 +- include/etl/version.h | 2 +- library.json | 2 +- library.properties | 2 +- meson.build | 6 +- scripts/generator_test.py | 7 +- support/Release notes.txt | 49 ++ test/CMakeLists.txt | 7 +- test/UnitTest++/CheckMacros.h | 14 +- test/runsanitychecks.sh | 158 +--- test/runtests.sh | 54 +- test/sanity-check/c++03/CMakeLists.txt | 6 +- test/sanity-check/c++11/CMakeLists.txt | 6 +- test/sanity-check/c++14/CMakeLists.txt | 6 +- test/sanity-check/c++17/CMakeLists.txt | 6 +- test/sanity-check/expected.h.t.cpp | 29 + test/test_delegate.cpp | 187 +++-- test/test_delegate_cpp03.cpp | 125 ++-- test/test_deque.cpp | 20 + test/test_expected.cpp | 446 +++++++++++ test/test_forward_list.cpp | 10 + test/test_indirect_vector.cpp | 12 + test/test_list.cpp | 20 + test/test_memory.cpp | 43 ++ test/test_optional.cpp | 35 + test/test_result.cpp | 192 ++--- test/test_type_traits.cpp | 15 - test/test_vector.cpp | 60 +- test/test_vector_external_buffer.cpp | 35 + test/test_vector_non_trivial.cpp | 56 +- test/test_vector_pointer.cpp | 11 + test/test_vector_pointer_external_buffer.cpp | 11 + test/vs2019/etl.vcxproj | 29 + test/vs2019/etl.vcxproj.filters | 15 +- version.txt | 2 +- 64 files changed, 2530 insertions(+), 747 deletions(-) create mode 100644 test/sanity-check/expected.h.t.cpp create mode 100644 test/test_expected.cpp diff --git a/.github/workflows/clang.yml b/.github/workflows/clang.yml index 7dfaf504..bcb3722f 100644 --- a/.github/workflows/clang.yml +++ b/.github/workflows/clang.yml @@ -6,12 +6,12 @@ on: branches: [ master ] jobs: - build-clang-9-linux-stl: - name: Clang-9 Linux - STL + build-clang-linux-stl: + name: Clang Linux - STL runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-20.04] + os: [ubuntu-20.04, ubuntu-22.04] steps: - uses: actions/checkout@v2 @@ -19,9 +19,9 @@ jobs: - name: Build run: | sudo apt-get update - sudo apt-get install -y "clang-9" "lldb-9" "lld-9" "clang-format-9" - export CC=clang-9 - export CXX=clang++-9 + sudo apt-get install -y "clang" "lldb" "lld" "clang-format" + export CC=clang + export CXX=clang++ export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 git fetch --tags cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03=OFF ./ @@ -31,12 +31,12 @@ jobs: - name: Run tests run: ./test/etl_tests - build-clang-9-linux-no-stl: - name: Clang-9 Linux - No STL + build-clang-linux-no-stl: + name: Clang Linux - No STL runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-20.04] + os: [ubuntu-20.04, ubuntu-22.04] steps: - uses: actions/checkout@v2 @@ -44,26 +44,24 @@ jobs: - name: Build run: | sudo apt-get update - sudo apt-get install -y "clang-9" "lldb-9" "lld-9" "clang-format-9" - export CC=clang-9 - export CXX=clang++-9 + sudo apt-get install -y "clang" "lldb" "lld" "clang-format" + export CC=clang + export CXX=clang++ export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 git fetch --tags cmake -DBUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03=OFF ./ - gcc --version - cmake -D BUILD_TESTS=ON -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03=OFF ./ clang --version make - name: Run tests run: ./test/etl_tests - build-clang-9-linux-stl-force-cpp03: - name: Clang-9 Linux - STL - Force C++03 + build-clang-linux-stl-force-cpp03: + name: Clang Linux - STL - Force C++03 runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-20.04] + os: [ubuntu-20.04, ubuntu-22.04] steps: - uses: actions/checkout@v2 @@ -71,9 +69,9 @@ jobs: - name: Build run: | sudo apt-get update - sudo apt-get install -y "clang-9" "lldb-9" "lld-9" "clang-format-9" - export CC=clang-9 - export CXX=clang++-9 + sudo apt-get install -y "clang" "lldb" "lld" "clang-format" + export CC=clang + export CXX=clang++ export ASAN_OPTIONS=alloc_dealloc_mismatch=0,detect_leaks=0 git fetch --tags cmake -D BUILD_TESTS=ON -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03=ON ./ diff --git a/.github/workflows/gcc.yml b/.github/workflows/gcc.yml index 2042fbeb..701719ef 100644 --- a/.github/workflows/gcc.yml +++ b/.github/workflows/gcc.yml @@ -11,7 +11,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-18.04, ubuntu-20.04] + os: [ubuntu-20.04, ubuntu-22.04] steps: - uses: actions/checkout@v2 @@ -32,7 +32,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-18.04, ubuntu-20.04] + os: [ubuntu-20.04, ubuntu-22.04] steps: - uses: actions/checkout@v2 @@ -53,7 +53,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-18.04, ubuntu-20.04] + os: [ubuntu-20.04, ubuntu-22.04] steps: - uses: actions/checkout@v2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 95b86b61..1ce02e57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/helpers.cmake) set(MSG_PREFIX "etl |") determine_version_with_git(${GIT_DIR_LOOKUP_POLICY}) if(NOT ETL_VERSION) - determine_version("version.txt") + determine_version_with_file("version.txt") endif() project(etl VERSION ${ETL_VERSION} LANGUAGES CXX) @@ -73,9 +73,9 @@ if(${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME}) "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake) install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/etl DESTINATION include) -endif() - -if (BUILD_TESTS) - enable_testing() - add_subdirectory(test) + + if (BUILD_TESTS) + enable_testing() + add_subdirectory(test) + endif() endif() diff --git a/arduino/library-arduino.json b/arduino/library-arduino.json index 3a6fb90a..42bd6fba 100644 --- a/arduino/library-arduino.json +++ b/arduino/library-arduino.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library - Arduino", - "version": "20.35.0", + "version": "20.35.10", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/arduino/library-arduino.properties b/arduino/library-arduino.properties index 6935809b..abbd8bb9 100644 --- a/arduino/library-arduino.properties +++ b/arduino/library-arduino.properties @@ -1,5 +1,5 @@ name=Embedded Template Library - Arduino -version=20.35.0 +version=20.35.10 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/cmake/helpers.cmake b/cmake/helpers.cmake index f27189d9..9249fb4e 100644 --- a/cmake/helpers.cmake +++ b/cmake/helpers.cmake @@ -1,4 +1,4 @@ -function(determine_version VER_FILE_NAME) +function(determine_version_with_file VER_FILE_NAME) file(READ ${VER_FILE_NAME} ETL_VERSION_RAW) # Remove trailing whitespaces and/or newline string(STRIP ${ETL_VERSION_RAW} ETL_VERSION) @@ -13,7 +13,11 @@ function(determine_version_with_git) git_describe(VERSION ${ARGN}) string(FIND ${VERSION} "." VALID_VERSION) if(VALID_VERSION EQUAL -1) - message(WARNING "Version string ${VERSION} retrieved with git describe is invalid") + if(PROJECT_IS_TOP_LEVEL) + # only warn if this is the top-level project, since we may be + # building from a tarball as a subproject + message(WARNING "Version string ${VERSION} retrieved with git describe is invalid") + endif() return() endif() message(STATUS "${MSG_PREFIX} Version string determined with git describe: ${VERSION}") diff --git a/include/etl/array_view.h b/include/etl/array_view.h index 5f367618..84ceeeab 100644 --- a/include/etl/array_view.h +++ b/include/etl/array_view.h @@ -40,7 +40,6 @@ SOFTWARE. #include "nullptr.h" #include "hash.h" #include "algorithm.h" -#include "memory.h" #include "type_traits.h" #if ETL_USING_STL && ETL_USING_CPP11 @@ -155,7 +154,7 @@ namespace etl /// Construct from etl::array. //************************************************************************* template - ETL_CONSTEXPR array_view(etl::array& a, typename etl::enable_if::type, typename etl::remove_cv::type>::value, void>::type) ETL_NOEXCEPT + ETL_CONSTEXPR array_view(etl::array& a, typename etl::enable_if::type, typename etl::remove_cv::type>::value, void>::type* = 0) ETL_NOEXCEPT : mbegin(a.data()) , mend(a.data() + a.size()) { @@ -165,7 +164,7 @@ namespace etl /// Construct from etl::array. //************************************************************************* template - ETL_CONSTEXPR array_view(const etl::array& a, typename etl::enable_if::type, typename etl::remove_cv::type>::value, void>::type) ETL_NOEXCEPT + ETL_CONSTEXPR array_view(const etl::array& a, typename etl::enable_if::type, typename etl::remove_cv::type>::value, void>::type* = 0) ETL_NOEXCEPT : mbegin(a.data()) , mend(a.data() + a.size()) { @@ -215,7 +214,7 @@ namespace etl template ETL_CONSTEXPR array_view(TContainer& a, typename etl::enable_if::type>::value && !etl::is_array::value && - etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type) ETL_NOEXCEPT + etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT : mbegin(a.data()) , mend(a.data() + a.size()) { @@ -228,7 +227,7 @@ namespace etl template ETL_CONSTEXPR array_view(const TContainer& a, typename etl::enable_if::type>::value && !etl::is_array::value && - etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type) ETL_NOEXCEPT + etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT : mbegin(a.data()) , mend(a.data() + a.size()) { diff --git a/include/etl/binary.h b/include/etl/binary.h index 658d41be..5d5a6128 100644 --- a/include/etl/binary.h +++ b/include/etl/binary.h @@ -2198,7 +2198,7 @@ namespace etl return (nbits == etl::integral_limits::bits) ? static_cast(etl::integral_limits::max) : static_cast((static_cast(1U) << nbits) - 1U); - }; + } //*********************************** template @@ -2214,7 +2214,7 @@ namespace etl ETL_CONSTEXPR T make_msb_mask(size_t nbits) { return static_cast(etl::reverse_bits(make_lsb_mask(nbits))); - }; + } //*************************************************************************** /// 8 bit binary byte constants. diff --git a/include/etl/delegate.h b/include/etl/delegate.h index 4220b65f..d0311927 100644 --- a/include/etl/delegate.h +++ b/include/etl/delegate.h @@ -33,7 +33,7 @@ SOFTWARE. #include "platform.h" -#if ETL_USING_CPP11 && !defined(ETL_CRC_FORCE_CPP03_IMPLEMENTATION) +#if ETL_USING_CPP11 && !defined(ETL_DELEGATE_FORCE_CPP03_IMPLEMENTATION) #include "private/delegate_cpp11.h" #else #include "private/delegate_cpp03.h" diff --git a/include/etl/deque.h b/include/etl/deque.h index 8a514e27..aa075ac7 100644 --- a/include/etl/deque.h +++ b/include/etl/deque.h @@ -1742,7 +1742,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_back(Args && ... args) + reference emplace_back(Args && ... args) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(deque_full)); @@ -1752,6 +1752,7 @@ namespace etl ++_end; ++current_size; ETL_INCREMENT_DEBUG_COUNT + return back(); } #else @@ -1761,7 +1762,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_back(const T1& value1) + reference emplace_back(const T1& value1) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(deque_full)); @@ -1771,6 +1772,7 @@ namespace etl ++_end; ++current_size; ETL_INCREMENT_DEBUG_COUNT + return back(); } //************************************************************************* @@ -1778,7 +1780,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_back(const T1& value1, const T2& value2) + reference emplace_back(const T1& value1, const T2& value2) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(deque_full)); @@ -1788,6 +1790,7 @@ namespace etl ++_end; ++current_size; ETL_INCREMENT_DEBUG_COUNT + return back(); } //************************************************************************* @@ -1795,7 +1798,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_back(const T1& value1, const T2& value2, const T3& value3) + 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)); @@ -1805,6 +1808,7 @@ namespace etl ++_end; ++current_size; ETL_INCREMENT_DEBUG_COUNT + return back(); } //************************************************************************* @@ -1812,7 +1816,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + 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)); @@ -1822,6 +1826,7 @@ namespace etl ++_end; ++current_size; ETL_INCREMENT_DEBUG_COUNT + return back(); } #endif @@ -1870,7 +1875,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_front(Args && ... args) + reference emplace_front(Args && ... args) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(deque_full)); @@ -1880,6 +1885,7 @@ namespace etl ::new (&(*_begin)) T(etl::forward(args)...); ++current_size; ETL_INCREMENT_DEBUG_COUNT + return front(); } #else @@ -1889,7 +1895,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_front(const T1& value1) + reference emplace_front(const T1& value1) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(deque_full)); @@ -1899,6 +1905,7 @@ namespace etl ::new (&(*_begin)) T(value1); ++current_size; ETL_INCREMENT_DEBUG_COUNT + return front(); } //************************************************************************* @@ -1906,7 +1913,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2) + reference emplace_front(const T1& value1, const T2& value2) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(deque_full)); @@ -1916,6 +1923,7 @@ namespace etl ::new (&(*_begin)) T(value1, value2); ++current_size; ETL_INCREMENT_DEBUG_COUNT + return front(); } //************************************************************************* @@ -1923,7 +1931,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2, const T3& value3) + 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)); @@ -1933,6 +1941,7 @@ namespace etl ::new (&(*_begin)) T(value1, value2, value3); ++current_size; ETL_INCREMENT_DEBUG_COUNT + return front(); } //************************************************************************* @@ -1940,7 +1949,7 @@ namespace etl /// If asserts or exceptions are enabled, throws an etl::deque_full if the deque is already full. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + 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)); @@ -1950,6 +1959,7 @@ namespace etl ::new (&(*_begin)) T(value1, value2, value3, value4); ++current_size; ETL_INCREMENT_DEBUG_COUNT + return front(); } #endif diff --git a/include/etl/expected.h b/include/etl/expected.h index 9ca6d03f..0baf4a88 100644 --- a/include/etl/expected.h +++ b/include/etl/expected.h @@ -34,9 +34,53 @@ SOFTWARE. #include "platform.h" #include "type_traits.h" #include "utility.h" +#include "variant.h" namespace etl { + //*************************************************************************** + /// Base exception for et::expected + //*************************************************************************** + class expected_exception : public etl::exception + { + public: + + expected_exception(string_type reason_, string_type file_name_, numeric_type line_number_) + : exception(reason_, file_name_, line_number_) + { + } + }; + + //*************************************************************************** + /// expected_invalid + //*************************************************************************** + template + class expected_invalid; + + //******************************************* + template<> + class expected_invalid : public etl::expected_exception + { + public: + + expected_invalid(string_type file_name_, numeric_type line_number_) + : expected_exception(ETL_ERROR_TEXT("expected:invalid", ETL_EXPECTED_FILE_ID"A"), file_name_, line_number_) + { + } + }; + + //******************************************* + template + class expected_invalid : etl::expected_invalid + { + public: + + expected_invalid(string_type file_name_, numeric_type line_number_) + : expected_invalid(file_name_, line_number_) + { + } + }; + //*************************************************************************** /// Unexpected type. /// etl::unexpected represents an unexpected value stored in etl::expected. @@ -46,6 +90,8 @@ namespace etl { public: + typedef TError error_type; + //******************************************* /// Copy constructor. //******************************************* @@ -114,8 +160,9 @@ namespace etl ETL_CONSTEXPR14 etl::unexpected& operator =(const etl::unexpected& rhs) { - error_value = rhs.error_value; + ETL_STATIC_ASSERT(etl::is_copy_constructible::value, "Error not copy assignable"); + error_value = rhs.error_value; return *this; } @@ -126,8 +173,9 @@ namespace etl ETL_CONSTEXPR14 etl::unexpected& operator =(etl::unexpected&& rhs) { - error_value = etl::move(rhs.error_value); + ETL_STATIC_ASSERT(etl::is_move_constructible::value, "Error not move assignable"); + error_value = etl::move(rhs.error_value); return *this; } #endif @@ -136,7 +184,7 @@ namespace etl //******************************************* /// Get the error. //******************************************* - constexpr const TError& error() const& noexcept + constexpr TError& error() & noexcept { return error_value; } @@ -144,16 +192,7 @@ namespace etl //******************************************* /// Get the error. //******************************************* - constexpr const TError&& error() const&& noexcept - { - return etl::move(error_value); - } - -#if ETL_USING_CPP14 - //******************************************* - /// Get the error. - //******************************************* - constexpr TError& error() & noexcept + constexpr const TError& error() const& noexcept { return error_value; } @@ -165,24 +204,14 @@ namespace etl { return etl::move(error_value); } -#else - //******************************************* - /// Get the error. - //******************************************* - TError& error() & noexcept - { - return error_value; - } //******************************************* /// Get the error. //******************************************* - TError&& error() && noexcept + constexpr TError&& error() const && noexcept { return etl::move(error_value); } -#endif - #else //******************************************* /// Get the error. @@ -210,8 +239,604 @@ namespace etl #if ETL_USING_CPP17 template - unexpected(TError) -> unexpected; + bool operator ==(const etl::unexpected& lhs, const etl::unexpected& rhs) + { + return lhs.error_value == rhs.error_value; + } + + //******************************************* + /// Swap etl::unexpected. + //******************************************* + template + void swap(etl::unexpected& lhs, etl::unexpected& rhs) + { + lhs.swap(rhs); + } + + //***************************************************************************** + /// unexpect_t + //***************************************************************************** + struct unexpect_t + { + ETL_CONSTEXPR14 explicit unexpect_t() + { + } + }; #endif + +#if ETL_USING_CPP17 + inline constexpr unexpect_t unexpect{}; +#else + static const unexpect_t unexpect; +#endif + + //***************************************************************************** + /// Expected type. + //***************************************************************************** + template + class expected + { + public: + + typedef etl::expected this_type; + typedef TValue value_type; + typedef TError error_type; + typedef etl::unexpected unexpected_type; + + template + using rebind = expected; + + //******************************************* + /// Default constructor + //******************************************* + ETL_CONSTEXPR14 expected() ETL_NOEXCEPT + : storage(etl::in_place_index, value_type()) + { + } + + //******************************************* + /// Constructor + //******************************************* + ETL_CONSTEXPR14 expected(const value_type& value_) ETL_NOEXCEPT + : storage(etl::in_place_index, value_) + { + } + + //******************************************* + /// Constructor + //******************************************* + ETL_CONSTEXPR14 expected(value_type&& value_) ETL_NOEXCEPT + : storage(etl::in_place_index, etl::move(value_)) + { + } + + //******************************************* + /// Copy constructor + //******************************************* + ETL_CONSTEXPR14 expected(const expected& other) ETL_NOEXCEPT + : storage(other.storage) + { + } + + //******************************************* + /// Move constructor + //******************************************* + ETL_CONSTEXPR14 expected(expected&& other) ETL_NOEXCEPT + : storage(etl::move(other.storage)) + { + } + + //******************************************* + /// Copy construct from unexpected type. + //******************************************* + template + ETL_CONSTEXPR14 explicit expected(const etl::unexpected& ue) + : storage(etl::in_place_index, ue.error()) + { + } + + //******************************************* + /// Move construct from unexpected type. + //******************************************* + template + ETL_CONSTEXPR14 explicit expected(etl::unexpected&& ue) + : storage(etl::in_place_index, etl::move(ue.error())) + { + } + + //******************************************* + /// Construct with default value type. + //******************************************* + ETL_CONSTEXPR14 explicit expected(etl::in_place_t) ETL_NOEXCEPT + : storage(value_type()) + { + } + + //******************************************* + /// Construct value type from arguments. + //******************************************* + template + ETL_CONSTEXPR14 explicit expected(etl::in_place_t, Args&&... args) + : storage(etl::forward(args)...) + { + } + + //******************************************* + /// Construct value type from initializser_list and arguments. + //******************************************* + template + ETL_CONSTEXPR14 explicit expected(etl::in_place_t, std::initializer_list il, Args&&... args) + : storage(il, etl::forward(args)...) + { + } + + //******************************************* + /// Construct error type from arguments. + //******************************************* + template + ETL_CONSTEXPR14 explicit expected(etl::unexpect_t, Args&&... args) + : storage(error_type(etl::forward(args)...)) + { + } + + //******************************************* + /// Construct error type from initializser_list and arguments. + //******************************************* + template + ETL_CONSTEXPR14 explicit expected(etl::unexpect_t, std::initializer_list il, Args&&... args) + : storage(error_type(il, etl::forward(args)...)) + { + } + + //******************************************* + /// + //******************************************* + this_type& operator =(const this_type& other) + { + ETL_STATIC_ASSERT(etl::is_copy_constructible::value && etl::is_copy_constructible::value, "Not copy assignable"); + + storage = other.storage; + + return *this; + } + + //******************************************* + /// + //******************************************* + this_type& operator =(this_type&& other) + { + ETL_STATIC_ASSERT(etl::is_move_constructible::value && etl::is_move_constructible::value, "Not move assignable"); + + storage = etl::move(other.storage); + return *this; + } + + //******************************************* + /// Copy assign from value + //******************************************* + expected& operator =(const value_type& value) + { + ETL_STATIC_ASSERT(etl::is_copy_constructible::value, "Value not copy assignable"); + + storage.emplace(value); + return *this; + } + + //******************************************* + /// Move assign from value + //******************************************* + expected& operator =(value_type&& value) + { + ETL_STATIC_ASSERT(etl::is_move_constructible::value, "Value not move assignable"); + + storage.emplace(etl::move(value)); + return *this; + } + + //******************************************* + /// Copy assign from error + //******************************************* + expected& operator =(const unexpected_type& error) + { + ETL_STATIC_ASSERT(etl::is_copy_constructible::value, "Error not copy assignable"); + + storage.emplace(error); + return *this; + } + + //******************************************* + /// Move assign from error + //******************************************* + expected& operator =(unexpected_type&& error) + { + ETL_STATIC_ASSERT(etl::is_move_constructible::value, "Error not move assignable"); + + storage.emplace(etl::move(error)); + return *this; + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 value_type& value()& + { + return etl::get(storage); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 const value_type& value() const& + { + return etl::get(storage); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 value_type&& value()&& + { + return etl::move(etl::get(storage)); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 const value_type&& value() const&& + { + return etl::move(etl::get(storage)); + } + + //******************************************* + /// + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + bool has_value() const + { + return (storage.index() == Value_Type); + } + + //******************************************* + /// + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + operator bool() const + { + return has_value(); + } + + //******************************************* + /// + //******************************************* + template + ETL_NODISCARD + ETL_CONSTEXPR14 + value_type value_or(U&& default_value) const& + { + if (has_value()) + { + return value(); + } + else + { + return default_value; + } + } + + //******************************************* + /// + //******************************************* + template + ETL_NODISCARD + ETL_CONSTEXPR14 + value_type value_or(U&& default_value)&& + { + if (has_value()) + { + return etl::move(value()); + } + else + { + return etl::move(default_value); + } + } + + //******************************************* + /// + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + error_type& error()& ETL_NOEXCEPT + { + return etl::get(storage); + } + + //******************************************* + /// + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + const error_type& error() const& ETL_NOEXCEPT + { + return etl::get(storage); + } + + //******************************************* + /// + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + error_type&& error() && ETL_NOEXCEPT + { + return etl::move(etl::get(storage)); + } + + //******************************************* + /// + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + const error_type&& error() const&& ETL_NOEXCEPT + { + return etl::move(etl::get(storage)); + } + + //******************************************* + /// + //******************************************* + template + ETL_CONSTEXPR14 value_type& emplace(Args&&... args) ETL_NOEXCEPT + { + storage.emplace(args...); + } + + //******************************************* + /// + //******************************************* + template + ETL_CONSTEXPR14 value_type& emplace(std::initializer_list& il, Args&&... args) ETL_NOEXCEPT + { + storage.emplace(il, args...); + } + + //******************************************* + /// + //******************************************* + value_type* operator ->() + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); +#endif + + return etl::addressof(storage.get()); + } + + //******************************************* + /// + //******************************************* + const value_type* operator ->() const + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); +#endif + + return etl::addressof(storage.get()); + } + + //******************************************* + /// + //******************************************* + value_type& operator *() + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); +#endif + + return storage.get(); + } + + //******************************************* + /// + //******************************************* + const value_type& operator *() const + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); +#endif + + return storage.get(); + } + + private: + + enum + { + Uninitialised, + Value_Type, + Error_Type + }; + + using storage_type = etl::variant; + storage_type storage; + }; + + //***************************************************************************** + /// Specialisation for void value type. + //***************************************************************************** + template + class expected + { + public: + + typedef etl::expected this_type; + typedef void value_type; + typedef TError error_type; + typedef etl::unexpected unexpected_type; + + //******************************************* + /// Default constructor + //******************************************* + ETL_CONSTEXPR14 + expected() + { + } + + //******************************************* + /// Copy construct from unexpected + //******************************************* + ETL_CONSTEXPR14 + expected(const unexpected_type& ue_) + : storage(ue_.error()) + { + } + + //******************************************* + /// Move construct from unexpected + //******************************************* + ETL_CONSTEXPR14 + expected(unexpected_type&& ue_) + : storage(etl::move(ue_.error())) + { + } + + //******************************************* + /// Copy construct + //******************************************* + ETL_CONSTEXPR14 + expected(const this_type& other) + : storage(other.storage) + { + } + + //******************************************* + /// Move construct + //******************************************* + ETL_CONSTEXPR14 + expected(this_type&& other) + : storage(etl::move(other.storage)) + { + } + + //******************************************* + /// Copy assign + //******************************************* + this_type& operator =(const this_type& other) + { + ETL_STATIC_ASSERT(etl::is_copy_constructible::value, "Not copy assignable"); + + storage = other.storage; + return *this; + } + + //******************************************* + /// Move assign + //******************************************* + this_type& operator =(this_type&& other) + { + ETL_STATIC_ASSERT(etl::is_move_constructible::value, "Not move assignable"); + + storage = etl::move(other.storage); + return *this; + } + + //******************************************* + /// Copy assign from error + //******************************************* + expected& operator =(const unexpected_type& error) + { + ETL_STATIC_ASSERT(etl::is_copy_constructible::value, "Error not copy assignable"); + + storage.emplace(error); + return *this; + } + + //******************************************* + /// Move assign from error + //******************************************* + expected& operator =(unexpected_type&& error) + { + ETL_STATIC_ASSERT(etl::is_move_constructible::value, "Error not move assignable"); + + storage.emplace(etl::move(error)); + return *this; + } + + //******************************************* + /// Returns true if expected has a value + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + bool has_value() const + { + return (storage.index() != Error_Type); + } + + //******************************************* + /// Returns true if expected has a value + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + operator bool() const + { + return has_value(); + } + + //******************************************* + /// Returns the error + /// Undefined behaviour if an error has not been set. + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + error_type& error()& ETL_NOEXCEPT + { + return etl::get(storage); + } + + //******************************************* + /// Returns the error + /// Undefined behaviour if an error has not been set. + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + const error_type& error() const& ETL_NOEXCEPT + { + return etl::get(storage); + } + + //******************************************* + /// Returns the error + /// Undefined behaviour if an error has not been set. + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + error_type&& error() && ETL_NOEXCEPT + { + return etl::move(etl::get(storage)); + } + + //******************************************* + /// Returns the error + /// Undefined behaviour if an error has not been set. + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + const error_type&& error() const&& ETL_NOEXCEPT + { + return etl::move(etl::get(storage)); + } + + private: + + enum + { + Uninitialised, + Error_Type + }; + + etl::variant storage; + }; } //******************************************* @@ -234,20 +859,4 @@ void swap(etl::unexpected& lhs, etl::unexpected& rhs) lhs.swap(rhs); } -//***************************************************************************** -/// unexpect_t -//***************************************************************************** -struct unexpect_t -{ - ETL_CONSTEXPR14 explicit unexpect_t() - { - } -}; - -#if ETL_CPP17_SUPPORTED -inline constexpr unexpect_t unexpect{}; -#else -static const unexpect_t unexpect; -#endif - #endif diff --git a/include/etl/forward_list.h b/include/etl/forward_list.h index 68337fc5..8d1ac9d5 100644 --- a/include/etl/forward_list.h +++ b/include/etl/forward_list.h @@ -722,7 +722,7 @@ namespace etl /// Emplaces a value to the front of the list.. //************************************************************************* template - void emplace_front(Args && ... args) + reference emplace_front(Args && ... args) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); @@ -731,13 +731,14 @@ namespace etl ::new (&(p_data_node->value)) T(etl::forward(args)...); ETL_INCREMENT_DEBUG_COUNT insert_node_after(start_node, *p_data_node); + return front(); } #else //************************************************************************* /// Emplaces a value to the front of the list.. //************************************************************************* template - void emplace_front(const T1& value1) + reference emplace_front(const T1& value1) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); @@ -746,13 +747,14 @@ namespace etl ::new (&(p_data_node->value)) T(value1); ETL_INCREMENT_DEBUG_COUNT insert_node_after(start_node, *p_data_node); + return front(); } //************************************************************************* /// Emplaces a value to the front of the list.. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2) + reference emplace_front(const T1& value1, const T2& value2) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(forward_list_full)); @@ -761,13 +763,14 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2); ETL_INCREMENT_DEBUG_COUNT insert_node_after(start_node, *p_data_node); + return front(); } //************************************************************************* /// Emplaces a value to the front of the list.. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2, const T3& value3) + 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)); @@ -776,13 +779,14 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2, value3); ETL_INCREMENT_DEBUG_COUNT insert_node_after(start_node, *p_data_node); + return front(); } //************************************************************************* /// Emplaces a value to the front of the list.. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + 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)); @@ -791,6 +795,7 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2, value3, value4); ETL_INCREMENT_DEBUG_COUNT insert_node_after(start_node, *p_data_node); + return front(); } #endif // ETL_USING_CPP11 && ETL_NOT_USING_STLPORT @@ -1756,7 +1761,7 @@ namespace etl //************************************************************************* #if ETL_USING_CPP11 && ETL_HAS_INITIALIZER_LIST template - constexpr auto make_forward_list(T... t) -> etl::forward_list, sizeof...(T)> + constexpr auto make_forward_list(T&&... t) -> etl::forward_list, sizeof...(T)> { return { { etl::forward(t)... } }; } diff --git a/include/etl/generators/type_traits_generator.h b/include/etl/generators/type_traits_generator.h index b7e16d8d..491ca081 100644 --- a/include/etl/generators/type_traits_generator.h +++ b/include/etl/generators/type_traits_generator.h @@ -714,7 +714,7 @@ namespace etl //*************************************************************************** /// is_enum ///\ingroup type_traits - /// Implemented by checking if type is convertable to an integer thru static_cast + /// Implemented by checking if type is convertible to an integer through static_cast namespace private_type_traits { @@ -1988,13 +1988,40 @@ namespace etl }; #if ETL_USING_CPP11 + //*************************************************************************** + /// is_constructible + namespace private_type_traits + { + template + struct is_constructible_ : etl::false_type {}; + + template + struct is_constructible_()...))>, T, Args...> : etl::true_type {}; + }; + + //********************************************* // is_constructible - template - struct is_constructible : public etl::bool_constant::value || etl::is_pointer::value> - { - }; -#endif + template + using is_constructible = private_type_traits::is_constructible_, T, Args...>; + + //********************************************* + // is_copy_constructible + template struct is_copy_constructible : public is_constructible::type>::type>{}; + template <> struct is_copy_constructible : public false_type{}; + template <> struct is_copy_constructible : public false_type{}; + template <> struct is_copy_constructible : public false_type{}; + template <> struct is_copy_constructible : public false_type{}; + + //********************************************* + // is_move_constructible + template struct is_move_constructible: public is_constructible::type>{}; + template <> struct is_move_constructible : public false_type{}; + template <> struct is_move_constructible : public false_type{}; + template <> struct is_move_constructible : public false_type{}; + template <> struct is_move_constructible : public false_type{}; + +#else //********************************************* // is_copy_constructible @@ -2009,6 +2036,7 @@ namespace etl struct is_move_constructible : public etl::bool_constant::value || etl::is_pointer::value> { }; +#endif //********************************************* // is_trivially_constructible diff --git a/include/etl/indirect_vector.h b/include/etl/indirect_vector.h index 002cad02..78e592bf 100644 --- a/include/etl/indirect_vector.h +++ b/include/etl/indirect_vector.h @@ -782,10 +782,11 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(Args && ... args) + reference emplace_back(Args && ... args) { T* p = storage.create(etl::forward(args)...); lookup.push_back(p); + return back(); } #else //********************************************************************* @@ -794,10 +795,11 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(const T1& value1) + reference emplace_back(const T1& value1) { T* p = storage.create(T(value1)); lookup.push_back(p); + return back(); } //********************************************************************* @@ -806,10 +808,11 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(const T1& value1, const T2& value2) + reference emplace_back(const T1& value1, const T2& value2) { T* p = storage.create(T(value1, value2)); lookup.push_back(p); + return back(); } //********************************************************************* @@ -818,10 +821,11 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(const T1& value1, const T2& value2, const T3& value3) + reference emplace_back(const T1& value1, const T2& value2, const T3& value3) { T* p = storage.create(T(value1, value2, value3)); lookup.push_back(p); + return back(); } //********************************************************************* @@ -830,10 +834,11 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + reference emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4) { T* p = storage.create(T(value1, value2, value3, value4)); lookup.push_back(p); + return back(); } #endif @@ -1433,7 +1438,7 @@ namespace etl //************************************************************************* #if ETL_USING_CPP11 && ETL_HAS_INITIALIZER_LIST template - constexpr auto make_indirect_vector(T... t) -> etl::indirect_vector, sizeof...(T)> + constexpr auto make_indirect_vector(T&&... t) -> etl::indirect_vector, sizeof...(T)> { return { { etl::forward(t)... } }; } diff --git a/include/etl/list.h b/include/etl/list.h index 6ba5070a..c5e78631 100644 --- a/include/etl/list.h +++ b/include/etl/list.h @@ -862,7 +862,7 @@ namespace etl /// Emplaces a value to the front of the list. //************************************************************************* template - void emplace_front(Args && ... args) + reference emplace_front(Args && ... args) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(list_full)); @@ -873,13 +873,14 @@ namespace etl ::new (&(p_data_node->value)) T(etl::forward(args)...); ETL_INCREMENT_DEBUG_COUNT insert_node(get_head(), *p_data_node); + return front(); } #else //************************************************************************* /// Emplaces a value to the front of the list. //************************************************************************* template - void emplace_front(const T1& value1) + reference emplace_front(const T1& value1) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(list_full)); @@ -890,13 +891,14 @@ namespace etl ::new (&(p_data_node->value)) T(value1); ETL_INCREMENT_DEBUG_COUNT insert_node(get_head(), *p_data_node); + return front(); } //************************************************************************* /// Emplaces a value to the front of the list. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2) + reference emplace_front(const T1& value1, const T2& value2) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(list_full)); @@ -907,13 +909,14 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2); ETL_INCREMENT_DEBUG_COUNT insert_node(get_head(), *p_data_node); + return front(); } //************************************************************************* /// Emplaces a value to the front of the list. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2, const T3& value3) + 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)); @@ -924,13 +927,14 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2, value3); ETL_INCREMENT_DEBUG_COUNT insert_node(get_head(), *p_data_node); + return front(); } //************************************************************************* /// Emplaces a value to the front of the list. //************************************************************************* template - void emplace_front(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + 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)); @@ -941,6 +945,7 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2, value3, value4); ETL_INCREMENT_DEBUG_COUNT insert_node(get_head(), *p_data_node); + return front(); } #endif @@ -985,7 +990,7 @@ namespace etl //************************************************************************* #if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT template - void emplace_back(Args && ... args) + reference emplace_back(Args && ... args) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(list_full)); @@ -996,10 +1001,11 @@ namespace etl ::new (&(p_data_node->value)) T(etl::forward(args)...); ETL_INCREMENT_DEBUG_COUNT insert_node(terminal_node, *p_data_node); + return back(); } #else template - void emplace_back(const T1& value1) + reference emplace_back(const T1& value1) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(list_full)); @@ -1010,10 +1016,11 @@ namespace etl ::new (&(p_data_node->value)) T(value1); ETL_INCREMENT_DEBUG_COUNT insert_node(terminal_node, *p_data_node); + return back(); } template - void emplace_back(const T1& value1, const T2& value2) + reference emplace_back(const T1& value1, const T2& value2) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(!full(), ETL_ERROR(list_full)); @@ -1024,10 +1031,11 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2); ETL_INCREMENT_DEBUG_COUNT insert_node(terminal_node, *p_data_node); + return back(); } template - void emplace_back(const T1& value1, const T2& value2, const T3& value3) + 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)); @@ -1038,10 +1046,11 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2, value3); ETL_INCREMENT_DEBUG_COUNT insert_node(terminal_node, *p_data_node); + return back(); } template - void emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + 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)); @@ -1052,6 +1061,7 @@ namespace etl ::new (&(p_data_node->value)) T(value1, value2, value3, value4); ETL_INCREMENT_DEBUG_COUNT insert_node(terminal_node, *p_data_node); + return back(); } #endif diff --git a/include/etl/memory.h b/include/etl/memory.h index ec6db9a4..0725d2e6 100644 --- a/include/etl/memory.h +++ b/include/etl/memory.h @@ -39,6 +39,7 @@ SOFTWARE. #include "nullptr.h" #include "alignment.h" #include "placement_new.h" + #include "private/addressof.h" #include @@ -1231,7 +1232,19 @@ namespace etl template struct default_delete { - void operator()(T* p) const + //********************************* + ETL_CONSTEXPR default_delete() ETL_NOEXCEPT + { + } + + //********************************* + template + default_delete(const default_delete&) ETL_NOEXCEPT + { + } + + //********************************* + void operator()(T * p) const ETL_NOEXCEPT { delete p; } @@ -1246,6 +1259,18 @@ namespace etl template struct default_delete { + //********************************* + ETL_CONSTEXPR default_delete() ETL_NOEXCEPT + { + } + + //********************************* + template + default_delete(const default_delete&) ETL_NOEXCEPT + { + } + + //********************************* template void operator()(U* p) const { @@ -1282,10 +1307,23 @@ namespace etl #if ETL_USING_CPP11 //********************************* - unique_ptr(unique_ptr&& p_) ETL_NOEXCEPT - : p(p_.release()) - , deleter(etl::move(p_.deleter)) + unique_ptr(unique_ptr&& other) ETL_NOEXCEPT { + if (&other != this) + { + p = other.release(); + deleter = etl::move(other.deleter); + } + } +#else + //********************************* + unique_ptr(unique_ptr& other) ETL_NOEXCEPT + { + if (&other != this) + { + p = other.release(); + deleter = other.deleter; + } } #endif @@ -1305,6 +1343,13 @@ namespace etl , deleter(etl::move(deleter_)) { } + + template + unique_ptr(unique_ptr&& u) ETL_NOEXCEPT + : p(u.release()) + , deleter(etl::forward(u.get_deleter())) + { + } #endif //********************************* @@ -1387,9 +1432,25 @@ namespace etl #if ETL_USING_CPP11 //********************************* - unique_ptr& operator =(unique_ptr&& p_) ETL_NOEXCEPT + unique_ptr& operator =(unique_ptr&& other) ETL_NOEXCEPT { - reset(p_.release()); + if (&other != this) + { + reset(other.release()); + deleter = etl::move(other.deleter); + } + + return *this; + } +#else + //********************************* + unique_ptr& operator =(unique_ptr& other) ETL_NOEXCEPT + { + if (&other != this) + { + reset(other.release()); + deleter = other.deleter; + } return *this; } @@ -1439,7 +1500,7 @@ namespace etl typedef T& reference; //********************************* - ETL_CONSTEXPR unique_ptr() ETL_NOEXCEPT + ETL_CONSTEXPR unique_ptr() ETL_NOEXCEPT : p(ETL_NULLPTR) { } @@ -1452,17 +1513,31 @@ namespace etl #if ETL_USING_CPP11 //********************************* - unique_ptr(unique_ptr&& p_) ETL_NOEXCEPT - : p(p_.release()) - , deleter(etl::move(p_.deleter)) + unique_ptr(unique_ptr&& other) ETL_NOEXCEPT { + if (&other != this) + { + p = other.release(); + deleter = etl::move(other.deleter); + } + } +#else + //********************************* + unique_ptr(unique_ptr& other) ETL_NOEXCEPT + { + if (&other != this) + { + p = other.release(); + deleter = other.deleter; + } } #endif //********************************* - unique_ptr(pointer p_, typename etl::conditional::value, - TDeleter, - typename etl::add_lvalue_reference::type>::type deleter_) ETL_NOEXCEPT + unique_ptr(pointer p_, + typename etl::conditional::value, + TDeleter, + typename etl::add_lvalue_reference::type>::type deleter_) ETL_NOEXCEPT : p(p_) , deleter(deleter_) { @@ -1475,6 +1550,13 @@ namespace etl , deleter(etl::move(deleter_)) { } + + template + unique_ptr(unique_ptr&& u) ETL_NOEXCEPT + : p(u.release()) + , deleter(etl::forward(u.get_deleter())) + { + } #endif //********************************* @@ -1556,9 +1638,25 @@ namespace etl #if ETL_USING_CPP11 //********************************* - unique_ptr& operator =(unique_ptr&& p_) ETL_NOEXCEPT + unique_ptr& operator =(unique_ptr&& other) ETL_NOEXCEPT { - reset(p_.release()); + if (&other != this) + { + reset(other.release()); + deleter = etl::move(other.deleter); + } + + return *this; + } +#else + //********************************* + unique_ptr& operator =(unique_ptr& other) ETL_NOEXCEPT + { + if (&other != this) + { + reset(other.release()); + deleter = other.deleter; + } return *this; } diff --git a/include/etl/optional.h b/include/etl/optional.h index 8de5197a..ebcb52a1 100644 --- a/include/etl/optional.h +++ b/include/etl/optional.h @@ -427,7 +427,7 @@ namespace etl ///\param args The arguments to construct with. //************************************************************************* template - void emplace(Args && ... args) + T& emplace(Args && ... args) { if (valid) { @@ -437,6 +437,7 @@ namespace etl ::new (storage.template get_address()) T(ETL_OR_STD::forward(args)...); valid = true; + return storage; } #else //************************************************************************* @@ -444,7 +445,7 @@ namespace etl /// 1 parameter. //************************************************************************* template - void emplace(const T1& value1) + T& emplace(const T1& value1) { if (valid) { @@ -454,6 +455,7 @@ namespace etl ::new (storage.template get_address()) T(value1); valid = true; + return storage; } //************************************************************************* @@ -461,7 +463,7 @@ namespace etl /// 2 parameters. //************************************************************************* template - void emplace(const T1& value1, const T2& value2) + T& emplace(const T1& value1, const T2& value2) { if (valid) { @@ -471,6 +473,7 @@ namespace etl ::new (storage.template get_address()) T(value1, value2); valid = true; + return storage; } //************************************************************************* @@ -478,7 +481,7 @@ namespace etl /// 3 parameters. //************************************************************************* template - void emplace(const T1& value1, const T2& value2, const T3& value3) + T& emplace(const T1& value1, const T2& value2, const T3& value3) { if (valid) { @@ -488,6 +491,7 @@ namespace etl ::new (storage.template get_address()) T(value1, value2, value3); valid = true; + return storage; } //************************************************************************* @@ -495,7 +499,7 @@ namespace etl /// 4 parameters. //************************************************************************* template - void emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + T& emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4) { if (valid) { @@ -505,6 +509,7 @@ namespace etl ::new (storage.template get_address()) T(value1, value2, value3, value4); valid = true; + return storage; } #endif @@ -613,7 +618,7 @@ namespace etl if (this != &other) { storage = etl::move(other.storage); - valid = true; + valid = other.valid; } return *this; @@ -766,12 +771,6 @@ namespace etl template ETL_CONSTEXPR14 void emplace(Args && ... args) { - if (valid) - { - // Destroy the old one. - storage.template get_reference().~T(); - } - storage = T(ETL_OR_STD::forward(args)...); valid = true; } diff --git a/include/etl/private/delegate_cpp03.h b/include/etl/private/delegate_cpp03.h index 8afb09c9..1116d800 100644 --- a/include/etl/private/delegate_cpp03.h +++ b/include/etl/private/delegate_cpp03.h @@ -174,11 +174,13 @@ namespace etl template class delegate; - - template class delegate : public private_delegate::call_if_impl, TReturn, TParam> { + private: + + typedef delegate delegate_type; + public: using private_delegate::call_if_impl, TReturn, TParam>::call_if; @@ -202,11 +204,20 @@ namespace etl // Construct from a functor. //************************************************************************* template - delegate(const TFunctor& instance) + delegate(TFunctor& instance, typename etl::enable_if::value && !etl::is_same::value, int>::type = 0) { assign((void*)(&instance), functor_stub); } + //************************************************************************* + // Construct from a const functor. + //************************************************************************* + template + delegate(const TFunctor& instance, typename etl::enable_if::value && !etl::is_same::value, int>::type = 0) + { + assign((void*)(&instance), const_functor_stub); + } + //************************************************************************* /// Create from function (Compile time). //************************************************************************* @@ -221,12 +232,23 @@ namespace etl //************************************************************************* template static - typename etl::enable_if::value, delegate>::type - create(const TFunctor& instance) + typename etl::enable_if::value &&!etl::is_same::value, delegate>::type + create(TFunctor& instance) { return delegate((void*)(&instance), functor_stub); } + //************************************************************************* + /// Create from a const Functor. + //************************************************************************* + template + static + typename etl::enable_if::value && !etl::is_same::value, delegate>::type + create(const TFunctor& instance) + { + return delegate((void*)(&instance), const_functor_stub); + } + //************************************************************************* /// Create from instance method (Run time). //************************************************************************* @@ -273,15 +295,25 @@ namespace etl } //************************************************************************* - /// Set from Lambda or Functor. + /// Set from Functor. //************************************************************************* template - typename etl::enable_if::value, void>::type - set(const TFunctor& instance) + typename etl::enable_if::value && !etl::is_same::value, void>::type + set(TFunctor& instance) { assign((void*)(&instance), functor_stub); } + //************************************************************************* + /// Set from const Functor. + //************************************************************************* + template + typename etl::enable_if::value && !etl::is_same::value, void>::type + set(const TFunctor& instance) + { + assign((void*)(&instance), const_functor_stub); + } + //************************************************************************* /// Set from instance method (Run time). //************************************************************************* @@ -384,16 +416,27 @@ namespace etl } //************************************************************************* - /// Create from Lambda or Functor. + /// Create from Functor. //************************************************************************* template - typename etl::enable_if::value, delegate&>::type - operator =(const TFunctor& instance) + typename etl::enable_if::value && !etl::is_same::value, delegate&>::type + operator =(TFunctor& instance) { assign((void*)(&instance), functor_stub); return *this; } + //************************************************************************* + /// Create from const Functor. + //************************************************************************* + template + typename etl::enable_if::value && !etl::is_same::value, delegate&>::type + operator =(const TFunctor& instance) + { + assign((void*)(&instance), const_functor_stub); + return *this; + } + //************************************************************************* /// Checks equality. //************************************************************************* @@ -549,7 +592,7 @@ namespace etl } //************************************************************************* - /// Stub call for a lambda or functor function. + /// Stub call for a functor function. //************************************************************************* template static TReturn functor_stub(void* object, TParam param) @@ -558,6 +601,16 @@ namespace etl return (p->operator())(param); } + //************************************************************************* + /// Stub call for a functor function. + //************************************************************************* + template + static TReturn const_functor_stub(void* object, TParam param) + { + const TFunctor* p = static_cast(object); + return (p->operator())(param); + } + //************************************************************************* /// The invocation object. //************************************************************************* @@ -568,9 +621,12 @@ namespace etl /// Specialisation for void parameter. //************************************************************************* template - class delegate - : public private_delegate::call_if_impl, TReturn, void> + class delegate : public private_delegate::call_if_impl, TReturn, void> { + private: + + typedef delegate delegate_type; + public: using private_delegate::call_if_impl< delegate, TReturn, void>::call_if; @@ -591,14 +647,23 @@ namespace etl } //************************************************************************* - // Construct from lambda or functor. + // Construct from functor. //************************************************************************* template - delegate(const TFunctor& instance) + delegate(TFunctor& instance, typename etl::enable_if::value && !etl::is_same::value, int>::type = 0) { assign((void*)(&instance), functor_stub); } + //************************************************************************* + // Construct from const functor. + //************************************************************************* + template + delegate(const TFunctor& instance, typename etl::enable_if::value && !etl::is_same::value, int>::type = 0) + { + assign((void*)(&instance), const_functor_stub); + } + //************************************************************************* /// Create from function (Compile time). //************************************************************************* @@ -609,16 +674,27 @@ namespace etl } //************************************************************************* - /// Create from Lambda or Functor. + /// Create from Functor. //************************************************************************* template static - typename etl::enable_if::value, delegate>::type - create(const TFunctor& instance) + typename etl::enable_if::value && !etl::is_same::value, delegate>::type + create(TFunctor& instance) { return delegate((void*)(&instance), functor_stub); } + //************************************************************************* + /// Create from const Functor. + //************************************************************************* + template + static + typename etl::enable_if::value && !etl::is_same::value, delegate>::type + create(const TFunctor& instance) + { + return delegate((void*)(&instance), const_functor_stub); + } + //************************************************************************* /// Create from instance method (Run time). //************************************************************************* @@ -665,15 +741,25 @@ namespace etl } //************************************************************************* - /// Set from Lambda or Functor. + /// Set from Functor. //************************************************************************* template - typename etl::enable_if::value, void>::type - set(const TFunctor& instance) + typename etl::enable_if::value && !etl::is_same::value, void>::type + set(TFunctor& instance) { assign((void*)(&instance), functor_stub); } + //************************************************************************* + /// Set from const Functor. + //************************************************************************* + template + typename etl::enable_if::value && !etl::is_same::value, void>::type + set(const TFunctor& instance) + { + assign((void*)(&instance), const_functor_stub); + } + //************************************************************************* /// Set from instance method (Run time). //************************************************************************* @@ -776,16 +862,27 @@ namespace etl } //************************************************************************* - /// Create from Lambda or Functor. + /// Create from Functor. //************************************************************************* template - typename etl::enable_if::value, delegate&>::type - operator =(const TFunctor& instance) + typename etl::enable_if::value && !etl::is_same::value, delegate&>::type + operator =(TFunctor& instance) { assign((void*)(&instance), functor_stub); return *this; } + //************************************************************************* + /// Create from const Functor. + //************************************************************************* + template + typename etl::enable_if::value && !etl::is_same::value, delegate&>::type + operator =(const TFunctor& instance) + { + assign((void*)(&instance), const_functor_stub); + return *this; + } + //************************************************************************* /// Checks equality. //************************************************************************* @@ -941,7 +1038,7 @@ namespace etl } //************************************************************************* - /// Stub call for a lambda or functor function. + /// Stub call for a functor function. //************************************************************************* template static TReturn functor_stub(void* object) @@ -950,6 +1047,16 @@ namespace etl return (p->operator())(); } + //************************************************************************* + /// Stub call for a const functor function. + //************************************************************************* + template + static TReturn const_functor_stub(void* object) + { + const TFunctor* p = static_cast(object); + return (p->operator())(); + } + //************************************************************************* /// The invocation object. //************************************************************************* diff --git a/include/etl/private/delegate_cpp11.h b/include/etl/private/delegate_cpp11.h index 0b2102f1..e85cd895 100644 --- a/include/etl/private/delegate_cpp11.h +++ b/include/etl/private/delegate_cpp11.h @@ -111,12 +111,21 @@ namespace etl //************************************************************************* // Construct from lambda or functor. //************************************************************************* - template ::value, void>> - ETL_CONSTEXPR14 delegate(const TLambda& instance) + template ::value && !etl::is_same, TLambda>::value, void>> + ETL_CONSTEXPR14 delegate(TLambda& instance) { assign((void*)(&instance), lambda_stub); } + //************************************************************************* + // Construct from const lambda or functor. + //************************************************************************* + template ::value && !etl::is_same, TLambda>::value, void>> + ETL_CONSTEXPR14 delegate(const TLambda& instance) + { + assign((void*)(&instance), const_lambda_stub); + } + //************************************************************************* /// Create from function (Compile time). //************************************************************************* @@ -130,13 +139,23 @@ namespace etl //************************************************************************* /// Create from Lambda or Functor. //************************************************************************* - template ::value, void>> + template ::value && !etl::is_same, TLambda>::value, void>> ETL_NODISCARD - static ETL_CONSTEXPR14 delegate create(const TLambda& instance) + static ETL_CONSTEXPR14 delegate create(TLambda& instance) { return delegate((void*)(&instance), lambda_stub); } + //************************************************************************* + /// Create from const Lambda or Functor. + //************************************************************************* + template ::value && !etl::is_same, TLambda>::value, void>> + ETL_NODISCARD + static ETL_CONSTEXPR14 delegate create(const TLambda& instance) + { + return delegate((void*)(&instance), const_lambda_stub); + } + //************************************************************************* /// Create from instance method (Run time). //************************************************************************* @@ -203,12 +222,21 @@ namespace etl //************************************************************************* /// Set from Lambda or Functor. //************************************************************************* - template ::value, void>> - ETL_CONSTEXPR14 void set(const TLambda& instance) + template ::value && !etl::is_same, TLambda>::value, void>> + ETL_CONSTEXPR14 void set(TLambda& instance) { assign((void*)(&instance), lambda_stub); } + //************************************************************************* + /// Set from const Lambda or Functor. + //************************************************************************* + template ::value && !etl::is_same, TLambda>::value, void>> + ETL_CONSTEXPR14 void set(const TLambda& instance) + { + assign((void*)(&instance), const_lambda_stub); + } + //************************************************************************* /// Set from instance method (Run time). //************************************************************************* @@ -347,13 +375,23 @@ namespace etl //************************************************************************* /// Create from Lambda or Functor. //************************************************************************* - template ::value, void>> - ETL_CONSTEXPR14 delegate& operator =(const TLambda& instance) + template ::value && !etl::is_same, TLambda>::value, void>> + ETL_CONSTEXPR14 delegate& operator =(TLambda& instance) { assign((void*)(&instance), lambda_stub); return *this; } + //************************************************************************* + /// Create from const Lambda or Functor. + //************************************************************************* + template ::value && !etl::is_same, TLambda>::value, void>> + ETL_CONSTEXPR14 delegate& operator =(const TLambda& instance) + { + assign((void*)(&instance), const_lambda_stub); + return *this; + } + //************************************************************************* /// Checks equality. //************************************************************************* @@ -517,6 +555,16 @@ namespace etl return (p->operator())(etl::forward(arg)...); } + //************************************************************************* + /// Stub call for a const lambda or functor function. + //************************************************************************* + template + static ETL_CONSTEXPR14 TReturn const_lambda_stub(void* object, TParams... arg) + { + const TLambda* p = static_cast(object); + return (p->operator())(etl::forward(arg)...); + } + //************************************************************************* /// The invocation object. //************************************************************************* diff --git a/include/etl/private/ivectorpointer.h b/include/etl/private/ivectorpointer.h index c2cffa7f..ac1e0746 100644 --- a/include/etl/private/ivectorpointer.h +++ b/include/etl/private/ivectorpointer.h @@ -354,9 +354,11 @@ namespace etl /// If asserts or exceptions are enabled, emits vector_full if the vector is already full. ///\param value The value to add. //********************************************************************* - void emplace_back(parameter_t value) + reference emplace_back(parameter_t value) { base_t::emplace_back(value); + + return back(); } //************************************************************************* diff --git a/include/etl/private/minmax_pop.h b/include/etl/private/minmax_pop.h index ea66ebbb..018673e3 100644 --- a/include/etl/private/minmax_pop.h +++ b/include/etl/private/minmax_pop.h @@ -32,7 +32,7 @@ SOFTWARE. * The header include guard has been intentionally omitted. * This file is intended to evaluated multiple times by design. */ -#if !defined(ETL_COMPILER_GREEN_HILLS) && !defined(ETL_COMPILER_IAR) +#if !defined(ETL_COMPILER_GREEN_HILLS) && !defined(ETL_COMPILER_IAR) && !defined(ETL_COMPILER_TASKING) #if !defined(ETL_COMPILER_ARM5) #pragma pop_macro("min") #pragma pop_macro("max") diff --git a/include/etl/private/minmax_push.h b/include/etl/private/minmax_push.h index 1e41bd6d..03aafcee 100644 --- a/include/etl/private/minmax_push.h +++ b/include/etl/private/minmax_push.h @@ -33,7 +33,7 @@ SOFTWARE. * This file is intended to evaluated multiple times by design. */ -#if !defined(ETL_COMPILER_GREEN_HILLS) && !defined(ETL_COMPILER_IAR) +#if !defined(ETL_COMPILER_GREEN_HILLS) && !defined(ETL_COMPILER_IAR) && !defined(ETL_COMPILER_TASKING) #if !defined(ETL_COMPILER_ARM5) #pragma push_macro("min") #pragma push_macro("max") diff --git a/include/etl/private/variant_legacy.h b/include/etl/private/variant_legacy.h index 9302a782..09c1897b 100644 --- a/include/etl/private/variant_legacy.h +++ b/include/etl/private/variant_legacy.h @@ -954,22 +954,22 @@ namespace etl return get::type>(variant); } -#define ETL_GEN_LEGACY_VISIT(VISITQUAL, VARIANTQUAL) \ - template \ - static TReturn visit(TVisitor VISITQUAL visitor, TVariant VARIANTQUAL variant) \ - { \ - switch (variant.index()) \ - { \ - case 0: return static_cast(visitor(get<0>(variant))); \ - case 1: return static_cast(visitor(get<1>(variant))); \ - case 2: return static_cast(visitor(get<2>(variant))); \ - case 3: return static_cast(visitor(get<3>(variant))); \ - case 4: return static_cast(visitor(get<4>(variant))); \ - case 5: return static_cast(visitor(get<5>(variant))); \ - case 6: return static_cast(visitor(get<6>(variant))); \ - case 7: return static_cast(visitor(get<7>(variant))); \ - default: ETL_ASSERT(false, ETL_ERROR(bad_variant_access)); \ - } \ +#define ETL_GEN_LEGACY_VISIT(VISITQUAL, VARIANTQUAL) \ + template \ + static TReturn visit(TVisitor VISITQUAL visitor, TVariant VARIANTQUAL variant) \ + { \ + switch (variant.index()) \ + { \ + case 0: return static_cast(visitor(get<0>(variant))); \ + case 1: return static_cast(visitor(get<1>(variant))); \ + case 2: return static_cast(visitor(get<2>(variant))); \ + case 3: return static_cast(visitor(get<3>(variant))); \ + case 4: return static_cast(visitor(get<4>(variant))); \ + case 5: return static_cast(visitor(get<5>(variant))); \ + case 6: return static_cast(visitor(get<6>(variant))); \ + case 7: return static_cast(visitor(get<7>(variant))); \ + default: ETL_ASSERT_FAIL_AND_RETURN_VALUE(ETL_ERROR(bad_variant_access), TReturn()); \ + } \ } ETL_GEN_LEGACY_VISIT(&, &) diff --git a/include/etl/private/variant_variadic.h b/include/etl/private/variant_variadic.h index b69017a2..3630596d 100644 --- a/include/etl/private/variant_variadic.h +++ b/include/etl/private/variant_variadic.h @@ -227,7 +227,7 @@ namespace etl default: { // This should never occur. - #if defined(ETL_IN_UNIT_TEST) + #if defined(ETL_DEBUG) assert(false); #endif break; @@ -701,6 +701,27 @@ namespace etl return *static_cast(data); } + //*************************************************************************** + /// Emplace with variadic constructor parameters. + //*************************************************************************** + template + etl::variant_alternative& emplace(TArgs&&... args) + { + static_assert(Index < etl::private_variant::parameter_pack::size, "Index of of range"); + + using type = etl::remove_cvref_t; + + operation(private_variant::Destroy, data, nullptr); + + construct_in_place_args(data, etl::forward(args)...); + + operation = operation_type::value, etl::is_move_constructible::value>::do_operation; + + type_id = Index; + + return etl::variant_alternative(*static_cast(data)); + } + //*************************************************************************** /// Move assignment operator for type. ///\param value The value to assign. diff --git a/include/etl/profiles/determine_compiler.h b/include/etl/profiles/determine_compiler.h index feb11de8..b9e91927 100644 --- a/include/etl/profiles/determine_compiler.h +++ b/include/etl/profiles/determine_compiler.h @@ -119,6 +119,13 @@ SOFTWARE. #endif #endif + #if !defined(ETL_COMPILER_TYPE_DETECTED) && !defined(ETL_COMPILER_TASKING) + #if defined(__TASKING__) + #define ETL_COMPILER_TASKING + #define ETL_COMPILER_TYPE_DETECTED + #endif + #endif + #if !defined(ETL_COMPILER_TYPE_DETECTED) #define ETL_COMPILER_GENERIC #endif @@ -187,6 +194,12 @@ SOFTWARE. #define ETL_USING_TEXAS_INSTRUMENTS_COMPILER 0 #endif +#if defined(ETL_COMPILER_TASKING) + #define ETL_USING_TASKING_COMPILER 1 +#else + #define ETL_USING_TASKING_COMPILER 0 +#endif + #if defined(ETL_COMPILER_GENERIC) #define ETL_USING_GENERIC_COMPILER 1 #else diff --git a/include/etl/profiles/determine_compiler_version.h b/include/etl/profiles/determine_compiler_version.h index 6835a75e..6705c058 100644 --- a/include/etl/profiles/determine_compiler_version.h +++ b/include/etl/profiles/determine_compiler_version.h @@ -64,6 +64,9 @@ SOFTWARE. #elif defined(ETL_COMPILER_TEXAS_INSTRUMENTS) #define ETL_COMPILER_VERSION __TI_COMPILER_VERSION__ #define ETL_COMPILER_FULL_VERSION __TI_COMPILER_VERSION__ + #elif defined(ETL_COMPILER_TASKING) + #define ETL_COMPILER_VERSION __REVISION__ + #define ETL_COMPILER_FULL_VERSION __VERSION__ #else #define ETL_COMPILER_VERSION 0 #define ETL_COMPILER_FULL_VERSION 0 diff --git a/include/etl/result.h b/include/etl/result.h index 33653c66..e01b6ee2 100644 --- a/include/etl/result.h +++ b/include/etl/result.h @@ -36,6 +36,7 @@ SOFTWARE. #include "platform.h" #include "variant.h" +#include "optional.h" #if ETL_CPP11_NOT_SUPPORTED #if !defined(ETL_IN_UNIT_TEST) @@ -53,6 +54,9 @@ namespace etl { public: + typedef TValue value_type; + typedef TError error_type; + //******************************************* /// Cannot be default constructed //******************************************* @@ -181,7 +185,7 @@ namespace etl //******************************************* bool is_value() const { - return (data.index() == 0U); + return has_value(); } //******************************************* @@ -189,7 +193,7 @@ namespace etl //******************************************* bool is_error() const { - return (data.index() == 1U); + return !has_value(); } //******************************************* @@ -207,7 +211,7 @@ namespace etl //******************************************* TValue&& value() { - return etl::move(etl::get(etl::move(data))); + return etl::move(etl::get(data)); } //******************************************* @@ -226,7 +230,7 @@ namespace etl #if ETL_CPP11_SUPPORTED TError&& error() { - return etl::move(etl::get(etl::move(data))); + return etl::move(etl::get(data)); } #endif @@ -244,11 +248,13 @@ namespace etl { public: + typedef void value_type; + typedef TError error_type; + //******************************************* /// Default Constructor //******************************************* result() - : err(TError()) { } @@ -256,7 +262,7 @@ namespace etl /// Copy constructor //******************************************* result(const result& other) - : err(other.err) + : data(other.data) { } @@ -264,15 +270,15 @@ namespace etl /// Move constructor //******************************************* result(result&& other) - : err(etl::move(other.err)) + : data(etl::move(other.data)) { } //******************************************* /// Construct from error //******************************************* - result(const TError& err_) - : err(err_) + result(const TError& error) + : data(error) { } @@ -280,8 +286,8 @@ namespace etl /// Move construct from error //******************************************* #if ETL_CPP11_SUPPORTED - result(TError&& err_) - : err(etl::move(err_)) + result(TError&& error) + : data(etl::move(error)) { } #endif @@ -289,9 +295,9 @@ namespace etl //******************************************* /// Copy assign from error //******************************************* - result& operator =(const TError& err_) + result& operator =(const TError& error) { - err = err_; + data = error; return *this; } @@ -301,17 +307,25 @@ namespace etl #if ETL_CPP11_SUPPORTED result& operator =(TError&& err_) { - err = etl::move(err_); + data = etl::move(error); return *this; } #endif + //******************************************* + /// true if result contains a value + //******************************************* + bool has_value() const + { + return !data.has_value(); + } + //******************************************* /// true if result contains a value //******************************************* bool is_value() const { - return false; + return has_value(); } //******************************************* @@ -319,7 +333,7 @@ namespace etl //******************************************* bool is_error() const { - return true; + return !has_value(); } //******************************************* @@ -328,7 +342,7 @@ namespace etl //******************************************* const TError& error() const { - return err; + return data.value(); } //******************************************* @@ -338,13 +352,126 @@ namespace etl #if ETL_CPP11_SUPPORTED TError&& error() { - return etl::move(err); + return etl::move(data.value()); } #endif private: - TError err; + etl::optional data; + }; + + //***************************************************************************** + /// Result type. + /// Specialisation for void error type. + //***************************************************************************** + template + class result + { + public: + + //******************************************* + /// Default Constructor + //******************************************* + result() + { + } + + //******************************************* + /// Copy constructor + //******************************************* + result(const result& other) + : data(other.data) + { + } + + //******************************************* + /// Move constructor + //******************************************* + result(result&& other) + : data(etl::move(other.data)) + { + } + + //******************************************* + /// Construct from error + //******************************************* + result(const TValue& value) + : data(value) + { + } + + //******************************************* + /// Move construct from error + //******************************************* + result(TValue&& value) + : data(etl::move(value)) + { + } + + //******************************************* + /// Copy assign from error + //******************************************* + result& operator =(const TValue& value) + { + data = value; + return *this; + } + + //******************************************* + /// Move assign from error + //******************************************* + result& operator =(TValue&& value) + { + data = etl::move(value); + return *this; + } + + //******************************************* + /// true if result contains a value + //******************************************* + bool has_value() const + { + return data.has_value(); + } + + //******************************************* + /// true if result contains a value + //******************************************* + bool is_value() const + { + return has_value(); + } + + //******************************************* + /// true if result contains an error + //******************************************* + bool is_error() const + { + return !has_value(); + } + + //******************************************* + /// Returns a const reference to the error. + /// Undefined if the result does not contain an error. + //******************************************* + const TValue& value() const + { + return data.value(); + } + + //******************************************* + /// Returns an rvalue reference to the error. + /// Undefined if the result does not contain an error. + //******************************************* + TValue&& value() + { + return etl::move(data.value()); + } + + private: + + etl::optional data; }; } diff --git a/include/etl/span.h b/include/etl/span.h index 405a1250..32f27106 100644 --- a/include/etl/span.h +++ b/include/etl/span.h @@ -134,7 +134,7 @@ namespace etl /// Construct from etl::array. //************************************************************************* template - ETL_CONSTEXPR span(etl::array& a, typename etl::enable_if<(N == Extent) && etl::is_same::type, typename etl::remove_cv::type>::value, void>::type) ETL_NOEXCEPT + ETL_CONSTEXPR span(etl::array& a, typename etl::enable_if<(N == Extent) && etl::is_same::type, typename etl::remove_cv::type>::value, void>::type* = 0) ETL_NOEXCEPT : pbegin(a.data()) { } @@ -143,7 +143,7 @@ namespace etl /// Construct from etl::array. //************************************************************************* template - ETL_CONSTEXPR span(const etl::array& a, typename etl::enable_if<(N == Extent) && etl::is_same::type, typename etl::remove_cv::type>::value, void>::type) ETL_NOEXCEPT + ETL_CONSTEXPR span(const etl::array& a, typename etl::enable_if<(N == Extent) && etl::is_same::type, typename etl::remove_cv::type>::value, void>::type* = 0) ETL_NOEXCEPT : pbegin(a.data()) { } @@ -189,7 +189,7 @@ namespace etl template span(TContainer& a, typename etl::enable_if::type>::value && !etl::is_array::value && - etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type) ETL_NOEXCEPT + etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT : pbegin(a.data()) { } @@ -201,7 +201,7 @@ namespace etl template ETL_CONSTEXPR span(const TContainer& a, typename etl::enable_if::type>::value && !etl::is_array::value&& - etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type) ETL_NOEXCEPT + etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT : pbegin(a.data()) { } @@ -510,7 +510,7 @@ namespace etl /// Construct from etl::array. //************************************************************************* template - ETL_CONSTEXPR span(etl::array& a, typename etl::enable_if::type, typename etl::remove_cv::type>::value, void>::type) ETL_NOEXCEPT + ETL_CONSTEXPR span(etl::array& a, typename etl::enable_if::type, typename etl::remove_cv::type>::value, void>::type* = 0) ETL_NOEXCEPT : pbegin(a.data()) , pend(a.data() + a.size()) { @@ -520,7 +520,7 @@ namespace etl /// Construct from etl::array. //************************************************************************* template - ETL_CONSTEXPR span(const etl::array& a, typename etl::enable_if::type, typename etl::remove_cv::type>::value, void>::type) ETL_NOEXCEPT + ETL_CONSTEXPR span(const etl::array& a, typename etl::enable_if::type, typename etl::remove_cv::type>::value, void>::type* = 0) ETL_NOEXCEPT : pbegin(a.data()) , pend(a.data() + a.size()) { @@ -570,7 +570,7 @@ namespace etl template ETL_CONSTEXPR span(TContainer& a, typename etl::enable_if::type>::value && !etl::is_array::value && - etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type) ETL_NOEXCEPT + etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT : pbegin(a.data()) , pend(a.data() + a.size()) { @@ -583,7 +583,7 @@ namespace etl template ETL_CONSTEXPR span(const TContainer& a, typename etl::enable_if::type>::value && !etl::is_array::value && - etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type) ETL_NOEXCEPT + etl::is_same::type, typename etl::remove_cv::type::value_type>::type>::value, void>::type* = 0) ETL_NOEXCEPT : pbegin(a.data()) , pend(a.data() + a.size()) { diff --git a/include/etl/type_traits.h b/include/etl/type_traits.h index 3ef8d979..80f2152c 100644 --- a/include/etl/type_traits.h +++ b/include/etl/type_traits.h @@ -702,7 +702,7 @@ namespace etl //*************************************************************************** /// is_enum ///\ingroup type_traits - /// Implemented by checking if type is convertable to an integer thru static_cast + /// Implemented by checking if type is convertible to an integer through static_cast namespace private_type_traits { @@ -1981,13 +1981,40 @@ namespace etl }; #if ETL_USING_CPP11 + //*************************************************************************** + /// is_constructible + namespace private_type_traits + { + template + struct is_constructible_ : etl::false_type {}; + + template + struct is_constructible_()...))>, T, Args...> : etl::true_type {}; + }; + + //********************************************* // is_constructible - template - struct is_constructible : public etl::bool_constant::value || etl::is_pointer::value> - { - }; -#endif + template + using is_constructible = private_type_traits::is_constructible_, T, Args...>; + + //********************************************* + // is_copy_constructible + template struct is_copy_constructible : public is_constructible::type>::type>{}; + template <> struct is_copy_constructible : public false_type{}; + template <> struct is_copy_constructible : public false_type{}; + template <> struct is_copy_constructible : public false_type{}; + template <> struct is_copy_constructible : public false_type{}; + + //********************************************* + // is_move_constructible + template struct is_move_constructible: public is_constructible::type>{}; + template <> struct is_move_constructible : public false_type{}; + template <> struct is_move_constructible : public false_type{}; + template <> struct is_move_constructible : public false_type{}; + template <> struct is_move_constructible : public false_type{}; + +#else //********************************************* // is_copy_constructible @@ -2002,6 +2029,7 @@ namespace etl struct is_move_constructible : public etl::bool_constant::value || etl::is_pointer::value> { }; +#endif //********************************************* // is_trivially_constructible diff --git a/include/etl/vector.h b/include/etl/vector.h index b10c3275..b6ebec27 100644 --- a/include/etl/vector.h +++ b/include/etl/vector.h @@ -459,7 +459,7 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(Args && ... args) + reference emplace_back(Args && ... args) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); @@ -467,6 +467,7 @@ namespace etl ::new (p_end) T(etl::forward(args)...); ++p_end; ETL_INCREMENT_DEBUG_COUNT + return back(); } #else //********************************************************************* @@ -475,7 +476,7 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(const T1& value1) + reference emplace_back(const T1& value1) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); @@ -483,6 +484,7 @@ namespace etl ::new (p_end) T(value1); ++p_end; ETL_INCREMENT_DEBUG_COUNT + return back(); } //********************************************************************* @@ -491,7 +493,7 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(const T1& value1, const T2& value2) + reference emplace_back(const T1& value1, const T2& value2) { #if defined(ETL_CHECK_PUSH_POP) ETL_ASSERT(size() != CAPACITY, ETL_ERROR(vector_full)); @@ -499,6 +501,7 @@ namespace etl ::new (p_end) T(value1, value2); ++p_end; ETL_INCREMENT_DEBUG_COUNT + return back(); } //********************************************************************* @@ -507,7 +510,7 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(const T1& value1, const T2& value2, const T3& value3) + 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)); @@ -515,6 +518,7 @@ namespace etl ::new (p_end) T(value1, value2, value3); ++p_end; ETL_INCREMENT_DEBUG_COUNT + return back(); } //********************************************************************* @@ -523,7 +527,7 @@ namespace etl ///\param value The value to add. //********************************************************************* template - void emplace_back(const T1& value1, const T2& value2, const T3& value3, const T4& value4) + 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)); @@ -531,6 +535,7 @@ namespace etl ::new (p_end) T(value1, value2, value3, value4); ++p_end; ETL_INCREMENT_DEBUG_COUNT + return back(); } #endif @@ -1353,7 +1358,7 @@ namespace etl //************************************************************************* #if ETL_USING_CPP11 && ETL_HAS_INITIALIZER_LIST template - constexpr auto make_vector(T... t) -> etl::vector, sizeof...(T)> + constexpr auto make_vector(T&&... t) -> etl::vector, sizeof...(T)> { return { { etl::forward(t)... } }; } diff --git a/include/etl/version.h b/include/etl/version.h index bf1bf269..79240a7e 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 35 -#define ETL_VERSION_PATCH 0 +#define ETL_VERSION_PATCH 10 #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 5f517484..e2bc28d3 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library", - "version": "20.35.0", + "version": "20.35.10", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/library.properties b/library.properties index 49b54c12..1ae6a430 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Embedded Template Library -version=20.35.0 +version=20.35.10 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/meson.build b/meson.build index 6bd1c8c1..fc5bad58 100644 --- a/meson.build +++ b/meson.build @@ -12,10 +12,8 @@ project('etl', ) compile_args = [] -if get_option('use_stl') - compile_args += '-DETL_NO_STL=0' -elif - compile_args += '-DETL_NO_STL=1' +if not get_option('use_stl') + compile_args += '-DETL_NO_STL' endif etl_dep = declare_dependency( diff --git a/scripts/generator_test.py b/scripts/generator_test.py index cad66737..14986988 100644 --- a/scripts/generator_test.py +++ b/scripts/generator_test.py @@ -37,6 +37,9 @@ for generator in generator_folder.iterdir(): print(f"Generator for {output_name} does not match file contents") all_ok = False -if not all_ok: +if all_ok: + print(f"\nAll generator tests passed\n") + exit(0) +else: + print(f"\nGenerator tests failed\n") exit(1) -exit(0) \ No newline at end of file diff --git a/support/Release notes.txt b/support/Release notes.txt index 96a866f6..8925639b 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,3 +1,52 @@ +=============================================================================== +20.35.10 +#659 emplace member functions return reference to emplaced value + +=============================================================================== +20.35.9 +#657 -Wpedantic-failure. Removed superfluous semicolons +#653 CMake - Don't warn on tag missing when subproject +#651 result specialization +#650 Fix result default ctor +Removed Ubuntu 18.04 from Github Actions +Added Ubuntu 22.04 to Github Actions + +=============================================================================== +20.35.8 +#648 Improve is_constructible, is_copy_constructible, is_move_constructible for type traits with default definitions +#645 Avoid 'missing return statement at end of non-void function' in `etl::visit<>()`. +Removed unused ETL_USE_MEM_BUILTINS option + +=============================================================================== +20.35.7 +Updated etl::delgate to handle const functors correctly + +=============================================================================== +20.35.6 +#643 Don't use push_macro and pull_macro with Tasking compiler + +=============================================================================== +20.35.5 +#641 Wrong usage of enable_if for none C++11 compilers + +=============================================================================== +20.35.4 +#639 Only build tests if top level project + +=============================================================================== +20.35.3 +#636 Fix bug in optional emplace for pod type specialisation + +=============================================================================== +20.35.2 +#634 Strange behavior in move assignment of optional + +=============================================================================== +20.35.1 +#628 Fixed set of ETL_NO_STL flag in meson.build +#631 unique_ptr derived copy or move to base does not compile +Removed duplicate include in etl::array_view + =============================================================================== 20.35.0 #596 Helper functions to convert strings to numeric values. etl::to_arithmetic diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5503424c..cf1df999 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -102,6 +102,7 @@ add_executable(etl_tests test_error_handler.cpp test_etl_traits.cpp test_exception.cpp + test_expected.cpp test_fixed_iterator.cpp test_fixed_sized_memory_block_allocator.cpp test_flags.cpp @@ -284,11 +285,6 @@ if (ETL_USE_TYPE_TRAITS_BUILTINS) target_compile_definitions(etl_tests PRIVATE -DETL_USE_TYPE_TRAITS_BUILTINS) endif() -if (ETL_USE_MEM_BUILTINS) - message(STATUS "Compiling for built-in memory functions") - target_compile_definitions(etl_tests PRIVATE -DETL_USE_MEM_BUILTINS) -endif() - if (ETL_USER_DEFINED_TYPE_TRAITS) message(STATUS "Compiling for user defined type traits") target_compile_definitions(etl_tests PRIVATE -DETL_USER_DEFINED_TYPE_TRAITS) @@ -329,3 +325,4 @@ add_test(etl_unit_tests etl_tests) add_custom_target(test_verbose COMMAND ${CMAKE_CTEST_COMMAND} --verbose) set_property(TARGET etl_tests PROPERTY CXX_STANDARD 17) + \ No newline at end of file diff --git a/test/UnitTest++/CheckMacros.h b/test/UnitTest++/CheckMacros.h index 23a8dca9..0ee75dfd 100644 --- a/test/UnitTest++/CheckMacros.h +++ b/test/UnitTest++/CheckMacros.h @@ -97,7 +97,7 @@ }) \ UNITTEST_MULTILINE_MACRO_END -#define UNITTEST_CHECK_FALSE_EQUAL(expected, actual) \ +#define UNITTEST_CHECK_NOT_EQUAL(expected, actual) \ UNITTEST_MULTILINE_MACRO_BEGIN \ UNITTEST_IMPL_TRY \ ({ \ @@ -254,16 +254,16 @@ #define CHECK_EQUAL_HEX UNITTEST_CHECK_EQUAL_HEX #endif - #ifdef CHECK_FALSE_EQUAL - #error CHECK_FALSE_EQUAL already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_FALSE_EQUAL instead + #ifdef CHECK_NOT_EQUAL + #error CHECK_NOT_EQUAL already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_NOT_EQUAL instead #else - #define CHECK_FALSE_EQUAL UNITTEST_CHECK_FALSE_EQUAL + #define CHECK_NOT_EQUAL UNITTEST_CHECK_NOT_EQUAL #endif - #ifdef CHECK_FALSE_EQUAL_HEX - #error CHECK_FALSE_EQUAL_HEX already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_FALSE_EQUAL_HEX instead + #ifdef CHECK_NOT_EQUAL_HEX + #error CHECK_NOT_EQUAL_HEX already defined, re-configure with UNITTEST_ENABLE_SHORT_MACROS set to 0 and use UNITTEST_CHECK_NOT_EQUAL_HEX instead #else - #define CHECK_FALSE_EQUAL_HEX UNITTEST_CHECK_FALSE_EQUAL_HEX + #define CHECK_NOT_EQUAL_HEX UNITTEST_CHECK_NOT_EQUAL_HEX #endif #ifdef CHECK_CLOSE diff --git a/test/runsanitychecks.sh b/test/runsanitychecks.sh index d7217d0d..5048f786 100644 --- a/test/runsanitychecks.sh +++ b/test/runsanitychecks.sh @@ -19,7 +19,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang g++ --version | head --lines=1 | tee -a ../log.txt -CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. cmake --build bgcc if [ $? -eq 0 ]; then echo "Passed" @@ -33,21 +33,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang g++ --version | head --lines=1 | tee -a ../log.txt -CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. -cmake --build bgcc -if [ $? -eq 0 ]; then - echo "Passed" -else - echo "****************\n**** Failed ****\n****************" | tee -a ../log.txt - exit $? -fi - -{ echo ""; echo "GCC - No STL - Force Builtins"; } | tee -a ../log.txt -rm -rdf bgcc -rm -rdf bclang -cmake -E make_directory bgcc bclang -g++ --version | head --lines=1 | tee -a ../log.txt -CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USE_MEM_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. cmake --build bgcc if [ $? -eq 0 ]; then echo "Passed" @@ -75,7 +61,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang clang++ --version | head --lines=1 | tee -a ../log.txt -CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. cmake --build bclang if [ $? -eq 0 ]; then echo "Passed" @@ -89,21 +75,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang clang++ --version | head --lines=1 | tee -a ../log.txt -CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. -cmake --build bclang -if [ $? -eq 0 ]; then - echo "Passed" -else - echo "****************\n**** Failed ****\n****************" | tee -a ../log.txt - exit $? -fi - -{ echo ""; echo "Clang - No STL - Force Builtins"; } | tee -a ../log.txt -rm -rdf bgcc -rm -rdf bclang -cmake -E make_directory bgcc bclang -clang++ --version | head --lines=1 | tee -a ../log.txt -CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USE_MEM_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. cmake --build bclang if [ $? -eq 0 ]; then echo "Passed" @@ -138,7 +110,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang g++ --version | head --lines=1 | tee -a ../log.txt -CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. cmake --build bgcc if [ $? -eq 0 ]; then echo "Passed" @@ -152,7 +124,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang g++ --version | head --lines=1 | tee -a ../log.txt -CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. cmake --build bgcc if [ $? -eq 0 ]; then echo "Passed" @@ -166,21 +138,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang g++ --version | head --lines=1 | tee -a ../log.txt -CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. -cmake --build bgcc -if [ $? -eq 0 ]; then - echo "Passed" -else - echo "****************\n**** Failed ****\n****************" | tee -a ../log.txt - exit $? -fi - -{ echo ""; echo "GCC - No STL - Force Builtins"; } | tee -a ../log.txt -rm -rdf bgcc -rm -rdf bclang -cmake -E make_directory bgcc bclang -g++ --version | head --lines=1 | tee -a ../log.txt -CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USE_MEM_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. cmake --build bgcc if [ $? -eq 0 ]; then echo "Passed" @@ -208,7 +166,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang clang++ --version | head --lines=1 | tee -a ../log.txt -CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. cmake --build bclang if [ $? -eq 0 ]; then echo "Passed" @@ -222,7 +180,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang clang++ --version | head --lines=1 | tee -a ../log.txt -CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. cmake --build bclang if [ $? -eq 0 ]; then echo "Passed" @@ -236,21 +194,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang clang++ --version | head --lines=1 | tee -a ../log.txt -CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. -cmake --build bclang -if [ $? -eq 0 ]; then - echo "Passed" -else - echo "****************\n**** Failed ****\n****************" | tee -a ../log.txt - exit $? -fi - -{ echo ""; echo "Clang - No STL - Force Builtins"; } | tee -a ../log.txt -rm -rdf bgcc -rm -rdf bclang -cmake -E make_directory bgcc bclang -clang++ --version | head --lines=1 | tee -a ../log.txt -CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USE_MEM_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. cmake --build bclang if [ $? -eq 0 ]; then echo "Passed" @@ -285,7 +229,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang g++ --version | head --lines=1 | tee -a ../log.txt -CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. cmake --build bgcc if [ $? -eq 0 ]; then echo "Passed" @@ -299,7 +243,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang g++ --version | head --lines=1 | tee -a ../log.txt -CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. cmake --build bgcc if [ $? -eq 0 ]; then echo "Passed" @@ -313,21 +257,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang g++ --version | head --lines=1 | tee -a ../log.txt -CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. -cmake --build bgcc -if [ $? -eq 0 ]; then - echo "Passed" -else - echo "****************\n**** Failed ****\n****************" | tee -a ../log.txt - exit $? -fi - -{ echo ""; echo "GCC - No STL - Force Builtins"; } | tee -a ../log.txt -rm -rdf bgcc -rm -rdf bclang -cmake -E make_directory bgcc bclang -g++ --version | head --lines=1 | tee -a ../log.txt -CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USE_MEM_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. cmake --build bgcc if [ $? -eq 0 ]; then echo "Passed" @@ -355,7 +285,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang clang++ --version | head --lines=1 | tee -a ../log.txt -CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. cmake --build bclang if [ $? -eq 0 ]; then echo "Passed" @@ -369,7 +299,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang clang++ --version | head --lines=1 | tee -a ../log.txt -CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. cmake --build bclang if [ $? -eq 0 ]; then echo "Passed" @@ -383,21 +313,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang clang++ --version | head --lines=1 | tee -a ../log.txt -CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. -cmake --build bclang -if [ $? -eq 0 ]; then - echo "Passed" -else - echo "****************\n**** Failed ****\n****************" | tee -a ../log.txt - exit $? -fi - -{ echo ""; echo "Clang - No STL - Force Builtins"; } | tee -a ../log.txt -rm -rdf bgcc -rm -rdf bclang -cmake -E make_directory bgcc bclang -clang++ --version | head --lines=1 | tee -a ../log.txt -CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USE_MEM_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. cmake --build bclang if [ $? -eq 0 ]; then echo "Passed" @@ -432,7 +348,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang g++ --version | head --lines=1 | tee -a ../log.txt -CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. cmake --build bgcc if [ $? -eq 0 ]; then echo "Passed" @@ -446,7 +362,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang g++ --version | head --lines=1 | tee -a ../log.txt -CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. cmake --build bgcc if [ $? -eq 0 ]; then echo "Passed" @@ -460,7 +376,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang g++ --version | head --lines=1 | tee -a ../log.txt -CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. cmake --build bgcc if [ $? -eq 0 ]; then echo "Passed" @@ -474,21 +390,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang g++ --version | head --lines=1 | tee -a ../log.txt -CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. -cmake --build bgcc -if [ $? -eq 0 ]; then - echo "Passed" -else - echo "****************\n**** Failed ****\n****************" | tee -a ../log.txt - exit $? -fi - -{ echo ""; echo "GCC - No STL - Force Builtins"; } | tee -a ../log.txt -rm -rdf bgcc -rm -rdf bclang -cmake -E make_directory bgcc bclang -g++ --version | head --lines=1 | tee -a ../log.txt -CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USE_MEM_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +CC=gcc CXX=g++ cmake -E chdir bgcc cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. cmake --build bgcc if [ $? -eq 0 ]; then echo "Passed" @@ -516,7 +418,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang clang++ --version | head --lines=1 | tee -a ../log.txt -CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. cmake --build bclang if [ $? -eq 0 ]; then echo "Passed" @@ -530,7 +432,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang clang++ --version | head --lines=1 | tee -a ../log.txt -CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. cmake --build bclang if [ $? -eq 0 ]; then echo "Passed" @@ -544,21 +446,7 @@ rm -rdf bgcc rm -rdf bclang cmake -E make_directory bgcc bclang clang++ --version | head --lines=1 | tee -a ../log.txt -CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. -cmake --build bclang -if [ $? -eq 0 ]; then - echo "Passed" -else - echo "****************\n**** Failed ****\n****************" | tee -a ../log.txt - exit $? -fi - -{ echo ""; echo "Clang - No STL - Force Builtins"; } | tee -a ../log.txt -rm -rdf bgcc -rm -rdf bclang -cmake -E make_directory bgcc bclang -clang++ --version | head --lines=1 | tee -a ../log.txt -CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USE_MEM_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +CC=clang CXX=clang++ cmake -E chdir bclang cmake -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. cmake --build bclang if [ $? -eq 0 ]; then echo "Passed" diff --git a/test/runtests.sh b/test/runtests.sh index f49aacaf..59695b0f 100644 --- a/test/runtests.sh +++ b/test/runtests.sh @@ -15,7 +15,7 @@ echo " GCC - STL" | tee -a log.txt echo "-----------------------------------------------" | tee -a log.txt rm * -rf gcc --version | grep gcc | tee -a log.txt -cmake -DCMAKE_CXX_COMPILER="g++" -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +cmake -DCMAKE_CXX_COMPILER="g++" -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. make -j4 if [ $? -eq 0 ]; then echo "<<<< Passed Compilation >>>>" @@ -36,7 +36,7 @@ echo " GCC - STL - Force C++03" | tee -a log.txt echo "-----------------------------------------------" | tee -a log.txt rm * -rf gcc --version | grep gcc | tee -a log.txt -cmake -DCMAKE_CXX_COMPILER="g++" -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. +cmake -DCMAKE_CXX_COMPILER="g++" -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. make -j4 if [ $? -eq 0 ]; then echo "<<<< Passed Compilation >>>>" @@ -57,28 +57,7 @@ echo " GCC - No STL" | tee -a log.txt echo "-----------------------------------------------" | tee -a log.txt rm * -rf gcc --version | grep gcc | tee -a log.txt -cmake -DCMAKE_CXX_COMPILER="g++" -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. -make -j4 -if [ $? -eq 0 ]; then - echo "<<<< Passed Compilation >>>>" -else - echo "****************\n**** Failed ****\n****************" | tee -a ../log.txt - exit $? -fi -./etl_tests -if [ $? -eq 0 ]; then - echo "<<<< Passed Tests >>>>" -else - echo "****************\n**** Failed ****\n****************" | tee -a ../log.txt - exit $? -fi -echo "" -echo "-----------------------------------------------" | tee -a log.txt -echo " GCC - No STL - Force Builtins" | tee -a log.txt -echo "-----------------------------------------------" | tee -a log.txt -rm * -rf -gcc --version | grep gcc | tee -a log.txt -cmake -DCMAKE_CXX_COMPILER="g++" -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USE_MEM_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +cmake -DCMAKE_CXX_COMPILER="g++" -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. make -j4 if [ $? -eq 0 ]; then echo "<<<< Passed Compilation >>>>" @@ -103,7 +82,7 @@ echo " Clang - STL" | tee -a log.txt echo "-----------------------------------------------" | tee -a log.txt rm * -rf clang --version | grep clang | tee -a log.txt -cmake -DCMAKE_CXX_COMPILER="clang++" -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +cmake -DCMAKE_CXX_COMPILER="clang++" -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. make -j4 if [ $? -eq 0 ]; then echo "<<<< Passed Compilation >>>>" @@ -124,7 +103,7 @@ echo " Clang - STL - Force C++03" | tee -a log.txt echo "-----------------------------------------------" | tee -a log.txt rm * -rf clang --version | grep clang | tee -a log.txt -cmake -DCMAKE_CXX_COMPILER="clang++" -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. +cmake -DCMAKE_CXX_COMPILER="clang++" -DNO_STL=OFF -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=ON .. make -j4 if [ $? -eq 0 ]; then echo "<<<< Passed Compilation >>>>" @@ -145,28 +124,7 @@ echo " Clang - No STL" | tee -a log.txt echo "-----------------------------------------------" | tee -a log.txt rm * -rf clang --version | grep clang | tee -a log.txt -cmake -DCMAKE_CXX_COMPILER="clang++" -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USE_MEM_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. -make -j4 -if [ $? -eq 0 ]; then - echo "<<<< Passed Compilation >>>>" -else - echo "****************\n**** Failed ****\n****************" | tee -a ../log.txt - exit $? -fi -./etl_tests -if [ $? -eq 0 ]; then - echo "<<<< Passed Tests >>>>" -else - echo "****************\n**** Failed ****\n****************" | tee -a ../log.txt - exit $? -fi -echo "" -echo "-----------------------------------------------" | tee -a log.txt -echo " Clang - No STL - Builtins" | tee -a log.txt -echo "-----------------------------------------------" | tee -a log.txt -rm * -rf -clang --version | grep clang | tee -a log.txt -cmake -DCMAKE_CXX_COMPILER="clang++" -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=ON -DETL_USE_MEM_BUILTINS=ON -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. +cmake -DCMAKE_CXX_COMPILER="clang++" -DNO_STL=ON -DETL_USE_TYPE_TRAITS_BUILTINS=OFF -DETL_USER_DEFINED_TYPE_TRAITS=OFF -DETL_FORCE_TEST_CPP03_IMPLEMENTATION=OFF .. make -j4 if [ $? -eq 0 ]; then echo "<<<< Passed Compilation >>>>" diff --git a/test/sanity-check/c++03/CMakeLists.txt b/test/sanity-check/c++03/CMakeLists.txt index 71ff8569..863f49cd 100644 --- a/test/sanity-check/c++03/CMakeLists.txt +++ b/test/sanity-check/c++03/CMakeLists.txt @@ -17,11 +17,6 @@ if (ETL_USE_TYPE_TRAITS_BUILTINS) add_definitions(-DETL_USE_TYPE_TRAITS_BUILTINS) endif() -if (ETL_USE_MEM_BUILTINS) - message(STATUS "Compiling for built-in memory functions") - add_definitions(-DETL_USE_MEM_BUILTINS) -endif() - if (ETL_USER_DEFINED_TYPE_TRAITS) message(STATUS "Compiling for user defined type traits") add_definitions(-DETL_USER_DEFINED_TYPE_TRAITS) @@ -134,6 +129,7 @@ target_sources(t98 PRIVATE etl_profile.h ../enum_type.h.t.cpp ../error_handler.h.t.cpp ../exception.h.t.cpp + ../expected.h.t.cpp ../factorial.h.t.cpp ../fibonacci.h.t.cpp ../file_error_numbers.h.t.cpp diff --git a/test/sanity-check/c++11/CMakeLists.txt b/test/sanity-check/c++11/CMakeLists.txt index e3821f3f..65687b9a 100644 --- a/test/sanity-check/c++11/CMakeLists.txt +++ b/test/sanity-check/c++11/CMakeLists.txt @@ -17,11 +17,6 @@ if (ETL_USE_TYPE_TRAITS_BUILTINS) add_definitions(-DETL_USE_TYPE_TRAITS_BUILTINS) endif() -if (ETL_USE_MEM_BUILTINS) - message(STATUS "Compiling for built-in memory functions") - add_definitions(-DETL_USE_MEM_BUILTINS) -endif() - if (ETL_USER_DEFINED_TYPE_TRAITS) message(STATUS "Compiling for user defined type traits") add_definitions(-DETL_USER_DEFINED_TYPE_TRAITS) @@ -134,6 +129,7 @@ target_sources(t11 PRIVATE etl_profile.h ../enum_type.h.t.cpp ../error_handler.h.t.cpp ../exception.h.t.cpp + ../expected.h.t.cpp ../factorial.h.t.cpp ../fibonacci.h.t.cpp ../file_error_numbers.h.t.cpp diff --git a/test/sanity-check/c++14/CMakeLists.txt b/test/sanity-check/c++14/CMakeLists.txt index 9176d7b1..a0462555 100644 --- a/test/sanity-check/c++14/CMakeLists.txt +++ b/test/sanity-check/c++14/CMakeLists.txt @@ -17,11 +17,6 @@ if (ETL_USE_TYPE_TRAITS_BUILTINS) add_definitions(-DETL_USE_TYPE_TRAITS_BUILTINS) endif() -if (ETL_USE_MEM_BUILTINS) - message(STATUS "Compiling for built-in memory functions") - add_definitions(-DETL_USE_MEM_BUILTINS) -endif() - if (ETL_USER_DEFINED_TYPE_TRAITS) message(STATUS "Compiling for user defined type traits") add_definitions(-DETL_USER_DEFINED_TYPE_TRAITS) @@ -134,6 +129,7 @@ target_sources(t14 PRIVATE etl_profile.h ../enum_type.h.t.cpp ../error_handler.h.t.cpp ../exception.h.t.cpp + ../expected.h.t.cpp ../factorial.h.t.cpp ../fibonacci.h.t.cpp ../file_error_numbers.h.t.cpp diff --git a/test/sanity-check/c++17/CMakeLists.txt b/test/sanity-check/c++17/CMakeLists.txt index f6a00b14..abaabd55 100644 --- a/test/sanity-check/c++17/CMakeLists.txt +++ b/test/sanity-check/c++17/CMakeLists.txt @@ -17,11 +17,6 @@ if (ETL_USE_TYPE_TRAITS_BUILTINS) add_definitions(-DETL_USE_TYPE_TRAITS_BUILTINS) endif() -if (ETL_USE_MEM_BUILTINS) - message(STATUS "Compiling for built-in memory functions") - add_definitions(-DETL_USE_MEM_BUILTINS) -endif() - if (ETL_USER_DEFINED_TYPE_TRAITS) message(STATUS "Compiling for user defined type traits") add_definitions(-DETL_USER_DEFINED_TYPE_TRAITS) @@ -134,6 +129,7 @@ target_sources(t17 PRIVATE etl_profile.h ../enum_type.h.t.cpp ../error_handler.h.t.cpp ../exception.h.t.cpp + ../expected.h.t.cpp ../factorial.h.t.cpp ../fibonacci.h.t.cpp ../file_error_numbers.h.t.cpp diff --git a/test/sanity-check/expected.h.t.cpp b/test/sanity-check/expected.h.t.cpp new file mode 100644 index 00000000..2fca92c3 --- /dev/null +++ b/test/sanity-check/expected.h.t.cpp @@ -0,0 +1,29 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2023 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include diff --git a/test/test_delegate.cpp b/test/test_delegate.cpp index ce0e1030..1a850941 100644 --- a/test/test_delegate.cpp +++ b/test/test_delegate.cpp @@ -37,10 +37,35 @@ SOFTWARE. namespace { + //***************************************************************************** + enum class FunctionCalled : int + { + Not_Called, + Free_Void_Called, + Free_Int_Called, + Free_Reference_Called, + Free_Moveableonly_Called, + Normal_Called, + Normal_Returning_Void_Called, + Alternative_Called, + Member_Void_Called, + Member_Void_Const_Called, + Member_Int_Called, + Member_Int_Const_Called, + Member_Reference_Called, + Member_Reference_Const_Called, + Member_Moveableonly_Called, + Member_Static_Called, + Operator_Called, + Operator_Const_Called, + Lambda_Called + }; + + FunctionCalled function_called = FunctionCalled::Not_Called; + //***************************************************************************** const int VALUE1 = 1; const int VALUE2 = 2; - bool function_called = false; bool parameter_correct = false; //***************************************************************************** @@ -70,7 +95,7 @@ namespace //***************************************************************************** void free_void() { - function_called = true; + function_called = FunctionCalled::Free_Void_Called; } //***************************************************************************** @@ -78,7 +103,7 @@ namespace //***************************************************************************** void free_int(int i, int j) { - function_called = true; + function_called = FunctionCalled::Free_Int_Called;; parameter_correct = (i == VALUE1) && (j == VALUE2); } @@ -87,7 +112,7 @@ namespace //***************************************************************************** void free_reference(const Data& data, int j) { - function_called = true; + function_called = FunctionCalled::Free_Reference_Called; parameter_correct = (data.d == VALUE1) && (j == VALUE2); } @@ -96,7 +121,7 @@ namespace //***************************************************************************** void free_moveableonly(MoveableOnlyData&& data) { - function_called = true; + function_called = FunctionCalled::Free_Moveableonly_Called; parameter_correct = (data.d == VALUE1); } @@ -105,7 +130,7 @@ namespace //***************************************************************************** int normal(int i, int j) { - function_called = true; + function_called = FunctionCalled::Normal_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); return i + j; @@ -116,7 +141,7 @@ namespace //***************************************************************************** void normal_returning_void(int i, int j) { - function_called = true; + function_called = FunctionCalled::Normal_Returning_Void_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); } @@ -125,7 +150,7 @@ namespace //***************************************************************************** int alternative(int i, int j) { - function_called = true; + function_called = FunctionCalled::Alternative_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); return i + j + 1; @@ -142,25 +167,25 @@ namespace // void void member_void() { - function_called = true; + function_called = FunctionCalled::Member_Void_Called; } void member_void_const() const { - function_called = true; + function_called = FunctionCalled::Member_Void_Const_Called; } //******************************************* // int void member_int(int i, int j) { - function_called = true; + function_called = FunctionCalled::Member_Int_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); } void member_int_const(int i, int j) const { - function_called = true; + function_called = FunctionCalled::Member_Int_Const_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); } @@ -168,13 +193,13 @@ namespace // reference void member_reference(const Data& data, int j) { - function_called = true; + function_called = FunctionCalled::Member_Reference_Called; parameter_correct = (data.d == VALUE1) && (j == VALUE2); } void member_reference_const(const Data& data, int j) const { - function_called = true; + function_called = FunctionCalled::Member_Reference_Const_Called; parameter_correct = (data.d == VALUE1) && (j == VALUE2); } @@ -182,7 +207,7 @@ namespace // moveable only data void member_moveableonly(MoveableOnlyData&& data) { - function_called = true; + function_called = FunctionCalled::Member_Moveableonly_Called; parameter_correct = (data.d == VALUE1); } @@ -190,7 +215,7 @@ namespace // static static void member_static(const Data& data, int j) { - function_called = true; + function_called = FunctionCalled::Member_Static_Called; parameter_correct = (data.d == VALUE1) && (j == VALUE2); } @@ -198,12 +223,12 @@ namespace // operator() void operator()() { - function_called = true; + function_called = FunctionCalled::Operator_Called; } void operator()() const { - function_called = true; + function_called = FunctionCalled::Operator_Const_Called; } }; @@ -226,7 +251,7 @@ namespace { SetupFixture() { - function_called = false; + function_called = FunctionCalled::Not_Called; parameter_correct = false; } }; @@ -272,7 +297,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Free_Void_Called); } //************************************************************************* @@ -282,7 +307,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Free_Void_Called); } //************************************************************************* @@ -292,7 +317,7 @@ namespace d(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Free_Int_Called); CHECK(parameter_correct); } @@ -303,7 +328,7 @@ namespace d(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Free_Int_Called); CHECK(parameter_correct); } @@ -317,7 +342,7 @@ namespace d(data, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Free_Reference_Called); CHECK(parameter_correct); } @@ -331,7 +356,7 @@ namespace d(data, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Free_Reference_Called); CHECK(parameter_correct); } @@ -345,7 +370,7 @@ namespace d(std::move(data)); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Free_Moveableonly_Called); CHECK(parameter_correct); } @@ -359,31 +384,31 @@ namespace d(std::move(data)); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Free_Moveableonly_Called); CHECK(parameter_correct); } //************************************************************************* TEST_FIXTURE(SetupFixture, test_lambda_int) { - etl::delegate d([](int i, int j) { function_called = true; parameter_correct = (i == VALUE1) && (j == VALUE2); }); + etl::delegate d([](int i, int j) { function_called = FunctionCalled::Lambda_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); }); d(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Lambda_Called); CHECK(parameter_correct); } //************************************************************************* TEST_FIXTURE(SetupFixture, test_lambda_int_create) { - auto lambda = [](int i, int j) { function_called = true; parameter_correct = (i == VALUE1) && (j == VALUE2); }; + auto lambda = [](int i, int j) { function_called = FunctionCalled::Lambda_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); }; etl::delegate d(lambda); d(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Lambda_Called); CHECK(parameter_correct); } @@ -396,7 +421,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Operator_Called); } //************************************************************************* @@ -408,7 +433,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Operator_Called); } //************************************************************************* @@ -420,7 +445,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Operator_Called); } //************************************************************************* @@ -432,7 +457,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Operator_Const_Called); } #if !defined(ETL_COMPILER_GCC) @@ -443,7 +468,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Operator_Called); } //************************************************************************* @@ -453,7 +478,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Operator_Called); } //************************************************************************* @@ -463,7 +488,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Operator_Const_Called); } //************************************************************************* @@ -473,7 +498,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Operator_Const_Called); } #endif @@ -488,7 +513,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Operator_Called); } //************************************************************************* @@ -500,7 +525,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Void_Called); } //************************************************************************* @@ -512,7 +537,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Void_Called); } //************************************************************************* @@ -524,7 +549,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Void_Const_Called); } //************************************************************************* @@ -536,7 +561,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Void_Const_Called); } //************************************************************************* @@ -548,7 +573,7 @@ namespace d(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Int_Called); CHECK(parameter_correct); } @@ -561,7 +586,7 @@ namespace d(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Int_Called); CHECK(parameter_correct); } @@ -574,7 +599,7 @@ namespace d(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Int_Const_Called); CHECK(parameter_correct); } @@ -587,7 +612,7 @@ namespace d(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Int_Const_Called); CHECK(parameter_correct); } @@ -602,7 +627,7 @@ namespace d(data, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Called); CHECK(parameter_correct); } @@ -617,7 +642,7 @@ namespace d(data, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Called); CHECK(parameter_correct); } @@ -632,7 +657,7 @@ namespace d(data, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Const_Called); CHECK(parameter_correct); } @@ -647,7 +672,7 @@ namespace d(data, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Const_Called); CHECK(parameter_correct); } @@ -662,7 +687,7 @@ namespace d(std::move(data)); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Moveableonly_Called); CHECK(parameter_correct); } @@ -677,7 +702,7 @@ namespace d(std::move(data)); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Moveableonly_Called); CHECK(parameter_correct); } @@ -691,7 +716,7 @@ namespace d(data, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Static_Called); CHECK(parameter_correct); } @@ -705,7 +730,7 @@ namespace d(data, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Static_Called); CHECK(parameter_correct); } @@ -717,7 +742,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Void_Called); } //************************************************************************* @@ -727,7 +752,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Void_Called); } //************************************************************************* @@ -737,7 +762,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Void_Const_Called); } //************************************************************************* @@ -747,7 +772,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Void_Const_Called); } //************************************************************************* @@ -757,7 +782,7 @@ namespace d(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Int_Called); CHECK(parameter_correct); } @@ -768,7 +793,7 @@ namespace d(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Int_Called); CHECK(parameter_correct); } @@ -779,7 +804,7 @@ namespace d(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Int_Const_Called); CHECK(parameter_correct); } @@ -790,7 +815,7 @@ namespace d(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Int_Const_Called); CHECK(parameter_correct); } @@ -804,7 +829,7 @@ namespace d(data, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Called); CHECK(parameter_correct); } @@ -818,7 +843,7 @@ namespace d(data, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Called); CHECK(parameter_correct); } @@ -832,7 +857,7 @@ namespace d(data, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Const_Called); CHECK(parameter_correct); } @@ -846,7 +871,7 @@ namespace d(data, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Const_Called); CHECK(parameter_correct); } @@ -859,7 +884,7 @@ namespace d(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Free_Int_Called); CHECK(parameter_correct); } @@ -868,11 +893,11 @@ namespace { etl::delegate d; - d.set([](int i, int j) { function_called = true; parameter_correct = (i == VALUE1) && (j == VALUE2); }); + d.set([](int i, int j) { function_called = FunctionCalled::Lambda_Called; parameter_correct = (i == VALUE1) && (j == VALUE2); }); d(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Lambda_Called); CHECK(parameter_correct); } @@ -889,7 +914,7 @@ namespace d(data, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Called); CHECK(parameter_correct); } @@ -906,7 +931,7 @@ namespace d(data, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Const_Called); CHECK(parameter_correct); } @@ -922,7 +947,7 @@ namespace d(data, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Called); CHECK(parameter_correct); } @@ -938,7 +963,7 @@ namespace d(data, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Const_Called); CHECK(parameter_correct); } #endif @@ -953,7 +978,7 @@ namespace d2(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Int_Called); CHECK(parameter_correct); } @@ -967,7 +992,7 @@ namespace d2(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Int_Called); CHECK(parameter_correct); } @@ -983,7 +1008,7 @@ namespace d2(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Int_Called); CHECK(parameter_correct); } @@ -1090,7 +1115,7 @@ namespace bool was_called = d.call_if(VALUE1, VALUE2); CHECK(was_called); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Normal_Returning_Void_Called); CHECK(parameter_correct); } @@ -1102,7 +1127,7 @@ namespace bool was_called = d.call_if(VALUE1, VALUE2); CHECK(!was_called); - CHECK(!function_called); + CHECK(function_called == FunctionCalled::Not_Called); CHECK(!parameter_correct); } @@ -1115,7 +1140,7 @@ namespace d(VALUE1, VALUE2); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Free_Int_Called); CHECK(parameter_correct); } }; diff --git a/test/test_delegate_cpp03.cpp b/test/test_delegate_cpp03.cpp index 36b29136..c6e19aa7 100644 --- a/test/test_delegate_cpp03.cpp +++ b/test/test_delegate_cpp03.cpp @@ -35,9 +35,34 @@ SOFTWARE. namespace { + //***************************************************************************** + enum class FunctionCalled : int + { + Not_Called, + Free_Void_Called, + Free_Int_Called, + Free_Reference_Called, + Free_Moveableonly_Called, + Normal_Called, + Normal_Returning_Void_Called, + Alternative_Called, + Member_Void_Called, + Member_Void_Const_Called, + Member_Int_Called, + Member_Int_Const_Called, + Member_Reference_Called, + Member_Reference_Const_Called, + Member_Moveableonly_Called, + Member_Static_Called, + Operator_Called, + Operator_Const_Called, + Lambda_Called + }; + + FunctionCalled function_called = FunctionCalled::Not_Called; + //***************************************************************************** const int VALUE1 = 1; - bool function_called = false; bool parameter_correct = false; //***************************************************************************** @@ -53,7 +78,7 @@ namespace //***************************************************************************** void free_void() { - function_called = true; + function_called = FunctionCalled::Free_Void_Called; } //***************************************************************************** @@ -61,7 +86,7 @@ namespace //***************************************************************************** void free_int(int i) { - function_called = true; + function_called = FunctionCalled::Free_Int_Called; parameter_correct = (i == VALUE1); } @@ -70,7 +95,7 @@ namespace //***************************************************************************** void free_reference(const Data& data) { - function_called = true; + function_called = FunctionCalled::Free_Reference_Called; parameter_correct = (data.d == VALUE1); } @@ -79,7 +104,7 @@ namespace //***************************************************************************** int normal(int i) { - function_called = true; + function_called = FunctionCalled::Normal_Called; parameter_correct = (i == VALUE1); return i; @@ -90,7 +115,7 @@ namespace //***************************************************************************** void normal_returning_void(int i) { - function_called = true; + function_called = FunctionCalled::Normal_Returning_Void_Called; parameter_correct = (i == VALUE1); } @@ -99,7 +124,7 @@ namespace //***************************************************************************** int alternative(int i) { - function_called = true; + function_called = FunctionCalled::Alternative_Called; parameter_correct = (i == VALUE1); return i + 1; @@ -116,25 +141,25 @@ namespace // void void member_void() { - function_called = true; + function_called = FunctionCalled::Member_Void_Called; } void member_void_const() const { - function_called = true; + function_called = FunctionCalled::Member_Void_Const_Called; } //******************************************* // int void member_int(int i) { - function_called = true; + function_called = FunctionCalled::Member_Int_Called; parameter_correct = (i == VALUE1); } void member_int_const(int i) const { - function_called = true; + function_called = FunctionCalled::Member_Int_Const_Called; parameter_correct = (i == VALUE1); } @@ -142,13 +167,13 @@ namespace // reference void member_reference(const Data& data) { - function_called = true; + function_called = FunctionCalled::Member_Reference_Called; parameter_correct = (data.d == VALUE1); } void member_reference_const(const Data& data) const { - function_called = true; + function_called = FunctionCalled::Member_Reference_Const_Called; parameter_correct = (data.d == VALUE1); } @@ -156,7 +181,7 @@ namespace // static static void member_static(const Data& data) { - function_called = true; + function_called = FunctionCalled::Member_Static_Called; parameter_correct = (data.d == VALUE1); } @@ -164,12 +189,12 @@ namespace // operator() void operator()() { - function_called = true; + function_called = FunctionCalled::Operator_Called; } void operator()() const { - function_called = true; + function_called = FunctionCalled::Operator_Const_Called; } }; @@ -192,7 +217,7 @@ namespace { SetupFixture() { - function_called = false; + function_called = FunctionCalled::Not_Called; parameter_correct = false; } }; @@ -217,7 +242,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Free_Void_Called); } //************************************************************************* @@ -227,7 +252,7 @@ namespace d(VALUE1); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Free_Int_Called); CHECK(parameter_correct); } @@ -241,7 +266,7 @@ namespace d(data); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Free_Reference_Called); CHECK(parameter_correct); } @@ -254,7 +279,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Operator_Called); } //************************************************************************* @@ -266,7 +291,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Operator_Called); } //************************************************************************* @@ -278,7 +303,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Operator_Const_Called); } #if !defined(ETL_COMPILER_GCC) @@ -289,7 +314,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Operator_Called); } //************************************************************************* @@ -299,7 +324,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Operator_Const_Called); } #endif @@ -314,7 +339,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Operator_Called); } //************************************************************************* @@ -326,7 +351,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Void_Called); } //************************************************************************* @@ -338,7 +363,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Void_Const_Called); } //************************************************************************* @@ -350,7 +375,7 @@ namespace d(VALUE1); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Int_Called); CHECK(parameter_correct); } @@ -363,7 +388,7 @@ namespace d(VALUE1); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Int_Const_Called); CHECK(parameter_correct); } @@ -378,7 +403,7 @@ namespace d(data); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Called); CHECK(parameter_correct); } @@ -393,7 +418,7 @@ namespace d(data); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Const_Called); CHECK(parameter_correct); } @@ -407,7 +432,7 @@ namespace d(data); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Static_Called); CHECK(parameter_correct); } @@ -419,7 +444,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Void_Called); } //************************************************************************* @@ -429,7 +454,7 @@ namespace d(); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Void_Const_Called); } //************************************************************************* @@ -439,7 +464,7 @@ namespace d(VALUE1); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Int_Called); CHECK(parameter_correct); } @@ -450,7 +475,7 @@ namespace d(VALUE1); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Int_Const_Called); CHECK(parameter_correct); } @@ -464,7 +489,7 @@ namespace d(data); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Called); CHECK(parameter_correct); } @@ -478,7 +503,7 @@ namespace d(data); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Const_Called); CHECK(parameter_correct); } @@ -491,7 +516,7 @@ namespace d(VALUE1); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Free_Int_Called); CHECK(parameter_correct); } @@ -500,11 +525,11 @@ namespace { etl_cpp03::delegate d; - d.set([](int i) { function_called = true; parameter_correct = (i == VALUE1); }); + d.set([](int i) { function_called = FunctionCalled::Lambda_Called; parameter_correct = (i == VALUE1); }); d(VALUE1); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Lambda_Called); CHECK(parameter_correct); } @@ -521,7 +546,7 @@ namespace d(data); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Called); CHECK(parameter_correct); } @@ -538,7 +563,7 @@ namespace d(data); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Const_Called); CHECK(parameter_correct); } @@ -554,7 +579,7 @@ namespace d(data); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Called); CHECK(parameter_correct); } @@ -570,7 +595,7 @@ namespace d(data); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Reference_Const_Called); CHECK(parameter_correct); } #endif @@ -585,7 +610,7 @@ namespace d2(VALUE1); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Int_Called); CHECK(parameter_correct); } @@ -601,7 +626,7 @@ namespace d2(VALUE1); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Member_Int_Called); CHECK(parameter_correct); } @@ -708,7 +733,7 @@ namespace bool was_called = d.call_if(VALUE1); CHECK(was_called); - CHECK(function_called); + CHECK(function_called == FunctionCalled::Normal_Returning_Void_Called); CHECK(parameter_correct); } @@ -720,7 +745,7 @@ namespace bool was_called = d.call_if(VALUE1); CHECK(!was_called); - CHECK(!function_called); + CHECK(function_called == FunctionCalled::Not_Called); CHECK(!parameter_correct); } }; diff --git a/test/test_deque.cpp b/test/test_deque.cpp index 29c0b63d..7d58f9fd 100644 --- a/test/test_deque.cpp +++ b/test/test_deque.cpp @@ -1490,6 +1490,16 @@ namespace CHECK(std::equal(compare_data.begin(), compare_data.end(), data.begin())); } + //************************************************************************* + TEST(test_emplace_back_return) + { + DataNDC data; + + data.emplace_back("24"); + auto& back = data.emplace_back("42"); + CHECK_EQUAL(back, data.back()); + } + //************************************************************************* TEST(test_push_back_excess) { @@ -1602,6 +1612,16 @@ namespace CHECK(std::equal(compare_data.begin(), compare_data.end(), data.begin())); } + //************************************************************************* + TEST(test_emplace_front_return) + { + DataNDC data; + + data.emplace_front("24"); + auto& front = data.emplace_front("42"); + CHECK_EQUAL(front, data.front()); + } + //************************************************************************* TEST(test_push_front_excess) { diff --git a/test/test_expected.cpp b/test/test_expected.cpp new file mode 100644 index 00000000..3f67f6f8 --- /dev/null +++ b/test/test_expected.cpp @@ -0,0 +1,446 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2022 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include "unit_test_framework.h" + +#include "etl/expected.h" +#include "etl/type_traits.h" + +#include +#include + +namespace +{ + struct Value + { + std::string v; + + Value() + { + } + + Value(const std::string v_) + : v(v_) + { + } + + operator std::string() const + { + return v; + } + }; + + struct ValueM + { + ValueM() + { + } + + ValueM(const std::string& v_) + : v(v_) + { + } + + ValueM(ValueM&&) = default; + ValueM& operator =(ValueM&&) = default; + + ValueM(const ValueM&) = delete; + ValueM& operator =(const ValueM&) = delete; + + std::string v; + }; + + struct Error + { + std::string e; + + Error() = default; + Error(const Error&) = default; + Error& operator =(const Error&) = default; + + Error(const std::string e_) + : e(e_) + { + } + + Error& operator =(const std::string e_) + { + e = e_; + } + + operator std::string() const + { + return e; + } + }; + + struct ErrorM + { + ErrorM() + { + } + + ErrorM(const std::string& e_) + : e(e_) + { + } + + ErrorM(ErrorM&&) = default; + ErrorM& operator =(ErrorM&&) = default; + + ErrorM(const ErrorM&) = delete; + ErrorM& operator =(const ErrorM&) = delete; + + std::string e; + }; + + using Expected = etl::expected; + using ExpectedV = etl::expected; + using ExpectedM = etl::expected; + using ExpectedVM = etl::expected; + + using Unexpected = etl::unexpected; + using UnexpectedV = etl::unexpected; + using UnexpectedM = etl::unexpected; +} + +namespace +{ + SUITE(test_result) + { + //************************************************************************* + TEST(test_default_constructor) + { + Expected expected; + + CHECK_TRUE(expected.has_value()); + CHECK_TRUE(bool(expected)); + } + + //************************************************************************* + TEST(test_constructor_for_result_with_value) + { + Value input = { "value 1" }; + Expected expected(input); + + Value output = expected.value(); + + CHECK_TRUE(expected.has_value()); + CHECK_TRUE(bool(expected)); + CHECK_TRUE(output.v == input.v); + } + + //************************************************************************* + TEST(test_constructor_for_const_result_with_value) + { + Value input = { "value 1" }; + const Expected expected(input); + + const Value& output = expected.value(); + + CHECK_TRUE(expected.has_value()); + CHECK_TRUE(bool(expected)); + CHECK_TRUE(output.v == input.v); + } + + //************************************************************************* + TEST(test_constructor_for_moveable_result_with_value) + { + ValueM input = { "value 1" }; + ExpectedM expected(etl::move(input)); + + ValueM output = etl::move(expected.value()); + + CHECK_TRUE(expected.has_value()); + CHECK_TRUE(bool(expected)); + CHECK_TRUE(output.v == std::string("value 1")); + } + + //************************************************************************* + TEST(test_constructor_for_result_with_error) + { + Error input = { "error 1" }; + Unexpected unexpected(input); + Expected expected(unexpected); + + Error output = expected.error(); + + CHECK_FALSE(expected.has_value()); + CHECK_FALSE(bool(expected)); + CHECK(output.e == input.e); + } + + //************************************************************************* + TEST(test_constructor_for_const_result_with_error) + { + const Error input = { "error 1" }; + const Unexpected unexpected(input); + const Expected expected(unexpected); + + const Error& output = expected.error(); + + CHECK_FALSE(expected.has_value()); + CHECK_FALSE(bool(expected)); + CHECK(output.e == input.e); + } + + //************************************************************************* + TEST(test_constructor_for_moveable_result_with_error) + { + ErrorM input = { "error 1" }; + UnexpectedM unexpected(etl::move(input)); + ExpectedM expected(etl::move(unexpected)); + + ErrorM output = etl::move(expected.error()); + + CHECK_FALSE(expected.has_value()); + CHECK_FALSE(bool(expected)); + CHECK_TRUE(output.e == std::string("error 1")); + } + + //************************************************************************* + TEST(test_constructor_for_result_void_value_with_value) + { + ExpectedV expected; + + CHECK_TRUE(expected.has_value()); + CHECK_TRUE(bool(expected)); + } + + //************************************************************************* + TEST(test_constructor_for_const_result_void_value_with_value) + { + const ExpectedV expected; + + CHECK_TRUE(expected.has_value()); + CHECK_TRUE(bool(expected)); + } + + //************************************************************************* + TEST(test_constructor_for_result_void_value_with_error) + { + Error input = { "error 1" }; + UnexpectedV unexpected(input); + ExpectedV expected(unexpected); + + Error output = expected.error(); + + CHECK_FALSE(expected.has_value()); + CHECK_FALSE(bool(expected)); + CHECK_TRUE(output.e == input.e); + } + + //************************************************************************* + TEST(test_constructor_for_const_result_void_value_with_error) + { + const Error input = { "error 1" }; + const UnexpectedV unexpected(input); + const ExpectedV expected(unexpected); + + const Error& output = expected.error(); + + CHECK_FALSE(expected.has_value()); + CHECK_FALSE(bool(expected)); + CHECK_TRUE(output.e == input.e); + } + + //************************************************************************* + TEST(test_constructor_for_moveable_result_void_value_with_error) + { + ErrorM input = { "error 1" }; + UnexpectedM unexpected(etl::move(input)); + ExpectedM expected(etl::move(unexpected)); + + ErrorM output = etl::move(expected.error()); + + CHECK_FALSE(expected.has_value()); + CHECK_FALSE(bool(expected)); + CHECK(output.e == std::string("error 1")); + } + + //************************************************************************* + TEST(test_copy_construct) + { + Value input1 = { "value 1" }; + Expected expected1(input1); + Expected expected2(expected1); + + Value output1 = expected2.value(); + + CHECK_TRUE(expected1.has_value()); + CHECK_TRUE(expected2.has_value()); + CHECK(output1.v == input1.v); + } + + //************************************************************************* + TEST(test_copy_assign) + { + Value input1 = { "value 1" }; + Expected expected1(input1); + + Value input2 = { "value 2" }; + Expected expected2(input2); + + expected2 = expected1; + + Value output1 = expected1.value(); + Value output2 = expected2.value(); + + CHECK_TRUE(expected1.has_value()); + CHECK_TRUE(expected2.has_value()); + + //CHECK(output1.v != input1.v); + //CHECK(output2.v != input1.v); + + //CHECK(output1.v == input2.v); + //CHECK(output2.v == input2.v); + } + + //************************************************************************* + TEST(test_move_construct) + { + ValueM input1 = { "value 1" }; + ExpectedM expected1(etl::move(input1)); + ExpectedM expected2(etl::move(expected1)); + + ValueM output1 = etl::move(expected1.value()); + ValueM output2 = etl::move(expected2.value()); + + CHECK_TRUE(expected1.has_value()); + CHECK_TRUE(expected2.has_value()); + + CHECK_EQUAL("", output1.v); + CHECK_EQUAL("value 1", output2.v); + } + + //************************************************************************* + TEST(test_move_assign) + { + ValueM input1 = { "value 1" }; + ExpectedM expected1(etl::move(input1)); + + ValueM input2 = { "value 2" }; + ExpectedM expected2(etl::move(input2)); + + expected2 = etl::move(expected1); + + ValueM output1 = etl::move(expected1.value()); + ValueM output2 = etl::move(expected2.value()); + + CHECK_TRUE(expected1.has_value()); + CHECK_TRUE(expected2.has_value()); + + CHECK_EQUAL("", output1.v); + CHECK_EQUAL("value 1", output2.v); + } + + //************************************************************************* + TEST(test_copy_construct_void_value) + { + Error input1 = { "error 1" }; + UnexpectedV unexpected1(input1); + ExpectedV expected1(unexpected1); + ExpectedV expected2(expected1); + + CHECK_FALSE(expected1.has_value()); + CHECK_FALSE(expected2.has_value()); + + Error output1 = expected1.error(); + Error output2 = expected2.error(); + + CHECK_EQUAL(input1.e, output1.e); + CHECK_EQUAL(input1.e, output2.e); + } + + //************************************************************************* + TEST(test_copy_assign_void_value) + { + Error input1 = { "error 1" }; + UnexpectedV unexpected1(input1); + + Error input2 = { "error 2" }; + UnexpectedV unexpected2(input2); + + ExpectedV expected1(unexpected1); + ExpectedV expected2(unexpected2); + + expected2 = expected1; + + Error output1 = expected1.error(); + Error output2 = expected2.error(); + + CHECK_FALSE(expected1.has_value()); + CHECK_FALSE(expected2.has_value()); + + CHECK_EQUAL(input1.e, output1.e); + CHECK_EQUAL(input1.e, output2.e); + } + + //************************************************************************* + TEST(test_move_construct_void_value) + { + ErrorM input1 = { "error 1" }; + UnexpectedM unexpected1(etl::move(input1)); + ExpectedVM expected1(etl::move(unexpected1)); + ExpectedVM expected2(etl::move(expected1)); + + ErrorM output1 = etl::move(expected1.error()); + ErrorM output2 = etl::move(expected2.error()); + + CHECK_FALSE(expected1.has_value()); + CHECK_FALSE(expected2.has_value()); + + CHECK_EQUAL("", output1.e); + CHECK_EQUAL("error 1", output2.e); + } + + //************************************************************************* + TEST(test_move_assign_void_value) + { + ErrorM input1 = { "error 1" }; + UnexpectedM unexpected1(etl::move(input1)); + + ErrorM input2 = { "error 2" }; + UnexpectedM unexpected2(etl::move(input2)); + + ExpectedVM expected1(etl::move(unexpected1)); + ExpectedVM expected2(etl::move(unexpected2)); + + expected2 = etl::move(expected1); + + ErrorM output1 = etl::move(expected1.error()); + ErrorM output2 = etl::move(expected2.error()); + + CHECK_FALSE(expected1.has_value()); + CHECK_FALSE(expected2.has_value()); + + CHECK_EQUAL("", output1.e); + CHECK_EQUAL("error 1", output2.e); + } + }; +} diff --git a/test/test_forward_list.cpp b/test/test_forward_list.cpp index 21356c63..43c85bde 100644 --- a/test/test_forward_list.cpp +++ b/test/test_forward_list.cpp @@ -694,6 +694,16 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_front_return) + { + DataNDC data; + + data.emplace_front("24"); + auto& front = data.emplace_front("42"); + CHECK_EQUAL(front, data.front()); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_emplace_after) { diff --git a/test/test_indirect_vector.cpp b/test/test_indirect_vector.cpp index 06ba7d2b..97dc944f 100644 --- a/test/test_indirect_vector.cpp +++ b/test/test_indirect_vector.cpp @@ -715,6 +715,18 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back_return) + { + DataNDC data; + std::string value1("A"); + std::string value2("B"); + + data.emplace_back(value1); + auto& back = data.emplace_back(value2); + CHECK_EQUAL(back, data.back()); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_back_unique_ptr) { diff --git a/test/test_list.cpp b/test/test_list.cpp index 5e3cfd11..d65623ce 100644 --- a/test/test_list.cpp +++ b/test/test_list.cpp @@ -731,6 +731,16 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_front_return) + { + DataNDC data; + + data.emplace_front("24"); + auto& front = data.emplace_front("42"); + CHECK_EQUAL(front, data.front()); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_front_excess) { @@ -887,6 +897,16 @@ namespace CHECK(are_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back_return) + { + DataNDC data; + + data.emplace_back("24"); + auto& back = data.emplace_back("42"); + CHECK_EQUAL(back, data.back()); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_back_excess) { diff --git a/test/test_memory.cpp b/test/test_memory.cpp index d1878d30..9854f172 100644 --- a/test/test_memory.cpp +++ b/test/test_memory.cpp @@ -41,6 +41,8 @@ SOFTWARE. #include #include +#include + namespace { @@ -1301,5 +1303,46 @@ namespace CHECK((reinterpret_cast(data) + 18) == p1); CHECK((reinterpret_cast(data) + 32) == p2); } + + //************************************************************************* + class Base + { + public: + virtual ~Base() {}; + virtual void function() = 0; + }; + + static bool function_was_called = false; + + class Derived : public Base + { + public: + Derived() + { + function_was_called = false; + } + + void function() + { + function_was_called = true; + } + }; + + void call(etl::unique_ptr ptr) + { + ptr->function(); + } + + TEST(test_derived_type) + { + CHECK(!function_was_called); + + etl::unique_ptr ptr(new Derived()); + CHECK(ptr.get() != ETL_NULLPTR); + + call(etl::move(ptr)); + CHECK(function_was_called); + CHECK(ptr.get() == ETL_NULLPTR); + } }; } diff --git a/test/test_optional.cpp b/test/test_optional.cpp index b4a743a9..9308af27 100644 --- a/test/test_optional.cpp +++ b/test/test_optional.cpp @@ -127,6 +127,13 @@ namespace CHECK_EQUAL(1, DataM::get_instance_count()); } + //************************************************************************* + TEST(test_emplace_return) + { + etl::optional data; + CHECK_EQUAL(42U, data.emplace(42U).value); + } + //************************************************************************* TEST(test_moveable) { @@ -466,5 +473,33 @@ namespace data.reset(); CHECK(!bool(data)); } + + //************************************************************************* + etl::optional get_optional_test_bug_634() + { + etl::optional result = 8; + result.reset(); + + return result; + } + + TEST(test_bug_634) + { + etl::optional result; + + result = get_optional_test_bug_634(); + + CHECK_EQUAL(false, result.has_value()); + } + + //************************************************************************* + TEST(test_optional_emplace_bug_636) + { + etl::optional result = 1; + result.emplace(2); + + CHECK_TRUE(result.has_value()); + CHECK_EQUAL(2, result.value()); + } }; } diff --git a/test/test_result.cpp b/test/test_result.cpp index ad0f5908..e2af3556 100644 --- a/test/test_result.cpp +++ b/test/test_result.cpp @@ -5,7 +5,7 @@ Embedded Template Library. https://github.com/ETLCPP/etl https://www.etlcpp.com -Copyright(c) 2017 John Wellbelove +Copyright(c) 2022 John Wellbelove Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal @@ -85,69 +85,21 @@ namespace std::string e; }; - using Result = etl::result; - using ResultV = etl::result; - using ResultM = etl::result; + using ResultValueError = etl::result; + using ResultVoidError = etl::result; + using ResultValueVoid = etl::result; + using ResultM = etl::result; } -// Definitions for when the STL and compiler built-ins are not available. -#if ETL_NOT_USING_STL && !defined(ETL_USE_TYPE_TRAITS_BUILTINS) - -using etl::is_copy_constructible; -using etl::is_move_constructible; - -//************************* -template <> -struct etl::is_copy_constructible : public etl::true_type -{ -}; - -template <> -struct etl::is_move_constructible : public etl::true_type -{ -}; - -template <> -struct etl::is_copy_constructible : public etl::true_type -{ -}; - -template <> -struct etl::is_move_constructible : public etl::true_type -{ -}; - -//************************* -template <> -struct etl::is_copy_constructible : public etl::false_type -{ -}; - -template <> -struct etl::is_move_constructible : public etl::false_type -{ -}; - -template <> -struct etl::is_copy_constructible : public etl::false_type -{ -}; - -template <> -struct etl::is_move_constructible : public etl::false_type -{ -}; -#endif - namespace { SUITE(test_result) { //************************************************************************* - TEST(test_constructor_for_result_with_value) + TEST(test_construct_result_value_error_type_with_value) { Value input = { "value 1" }; - Result result(input); + ResultValueError result(input); Value output = result.value(); @@ -157,10 +109,10 @@ namespace } //************************************************************************* - TEST(test_constructor_for_const_result_with_value) + TEST(test_construct_const_result_value_error_type_with_value) { Value input = { "value 1" }; - const Result result(input); + const ResultValueError result(input); const Value& output = result.value(); @@ -170,7 +122,7 @@ namespace } //************************************************************************* - TEST(test_constructor_for_moveable_result_with_value) + TEST(test_construct_moveable_result_value_error_type_with_value) { ValueM input = { "value 1" }; ResultM result(etl::move(input)); @@ -183,10 +135,10 @@ namespace } //************************************************************************* - TEST(test_constructor_for_result_with_error) + TEST(test_construct_result_value_error_type_with_error) { Error input = { "error 1" }; - Result result(input); + ResultValueError result(input); Error output = result.error(); @@ -196,10 +148,10 @@ namespace } //************************************************************************* - TEST(test_constructor_for_const_result_with_error) + TEST(test_construct_const_result_value_error_type_with_error) { Error input = { "error 1" }; - const Result result(input); + const ResultValueError result(input); const Error& output = result.error(); @@ -209,7 +161,7 @@ namespace } //************************************************************************* - TEST(test_constructor_for_moveable_result_with_error) + TEST(test_construct_moveable_result_value_error_type_with_error) { ErrorM input = { "error 1" }; ResultM result(etl::move(input)); @@ -222,28 +174,28 @@ namespace } //************************************************************************* - TEST(test_constructor_for_result_void_value_with_value) + TEST(test_default_construct_result_void_error_type) { - ResultV result; + ResultVoidError result; - CHECK(!result.is_value()); - CHECK(result.is_error()); + CHECK(result.is_value()); + CHECK(!result.is_error()); } //************************************************************************* - TEST(test_constructor_for_const_result_void_value_with_value) + TEST(test_default_construct_const_result_void_error_type) { - const ResultV result; + const ResultVoidError result; - CHECK(!result.is_value()); - CHECK(result.is_error()); + CHECK(result.is_value()); + CHECK(!result.is_error()); } //************************************************************************* - TEST(test_constructor_for_result_void_value_with_error) + TEST(test_construct_result_void_error_type_with_error) { Error input = { "error 1" }; - ResultV result(input); + ResultVoidError result(input); Error output = result.error(); @@ -253,10 +205,10 @@ namespace } //************************************************************************* - TEST(test_constructor_for_const_result_void_value_with_error) + TEST(test_construct_const_result_void_error_type_with_error) { Error input = { "error 1" }; - const ResultV result(input); + const ResultVoidError result(input); const Error& output = result.error(); @@ -266,10 +218,10 @@ namespace } //************************************************************************* - TEST(test_constructor_for_moveable_result_void_value_with_error) + TEST(test_construct_moveable_result_void_error_type_with_error) { Error input = { "error 1" }; - ResultV result(etl::move(input)); + ResultVoidError result(etl::move(input)); Error output = etl::move(result.error()); @@ -279,10 +231,10 @@ namespace } //************************************************************************* - TEST(test_constructor_for_moveable_const_result_void_value_with_error) + TEST(test_construct_moveable_const_result_void_error_type_with_error) { Error input = { "error 1" }; - const ResultV result(etl::move(input)); + const ResultVoidError result(etl::move(input)); Error output = etl::move(result.error()); @@ -291,13 +243,83 @@ namespace CHECK(output.e == std::string("error 1")); } + //************************************************************************* + TEST(test_default_construct_result_value_void_type) + { + ResultValueVoid result; + + CHECK(!result.is_value()); + CHECK(result.is_error()); + } + + //************************************************************************* + TEST(test_default_construct_const_result_value_void_type) + { + const ResultValueVoid result; + + CHECK(!result.is_value()); + CHECK(result.is_error()); + } + + //************************************************************************* + TEST(test_construct_result_value_void_type_with_value) + { + Value input = { "value 1" }; + ResultValueVoid result(input); + + Value output = result.value(); + + CHECK(result.is_value()); + CHECK(!result.is_error()); + CHECK(output.v == input.v); + } + + //************************************************************************* + TEST(test_construct_const_result_value_void_type_with_value) + { + Value input = { "value 1" }; + const ResultValueVoid result(input); + + const Value output = result.value(); + + CHECK(result.is_value()); + CHECK(!result.is_error()); + CHECK(output.v == input.v); + } + + //************************************************************************* + TEST(test_construct_moveable_result_value_void_type_with_value) + { + Value input = { "value 1" }; + ResultValueVoid result(etl::move(input)); + + Value output = etl::move(result.value()); + + CHECK(result.is_value()); + CHECK(!result.is_error()); + CHECK(output.v == std::string("value 1")); + } + + //************************************************************************* + TEST(test_construct_moveable_const_result_value_void_type_with_value) + { + Value input = { "value 1" }; + const ResultValueVoid result(etl::move(input)); + + Value output = etl::move(result.value()); + + CHECK(result.is_value()); + CHECK(!result.is_error()); + CHECK(output.v == std::string("value 1")); + } + //************************************************************************* TEST(test_copy_construct_result) { Value input = { "value 1" }; - Result result(input); + ResultValueError result(input); - Result result2(result); + ResultValueError result2(result); Value output = result2.value(); @@ -312,9 +334,9 @@ namespace TEST(test_move_construct_result) { Value input = { "value 1" }; - Result result(input); + ResultValueError result(input); - Result result2(etl::move(result)); + ResultValueError result2(etl::move(result)); Value output = result.value(); Value output2 = result2.value(); @@ -331,10 +353,10 @@ namespace TEST(test_move_assign_result) { Value input = { "value 1" }; - Result result(input); + ResultValueError result(input); Value input2 = { "value 2" }; - Result result2(result); + ResultValueError result2(result); result2 = etl::move(result); diff --git a/test/test_type_traits.cpp b/test/test_type_traits.cpp index 83848757..363d59d9 100644 --- a/test/test_type_traits.cpp +++ b/test/test_type_traits.cpp @@ -127,11 +127,6 @@ struct etl::is_assignable : public etl::true_type { }; -template <> -struct etl::is_constructible : public etl::true_type -{ -}; - template <> struct etl::is_copy_constructible : public etl::true_type { @@ -148,11 +143,6 @@ struct etl::is_assignable : public etl::true_type { }; -template <> -struct etl::is_constructible : public etl::true_type -{ -}; - template <> struct etl::is_copy_constructible : public etl::false_type { @@ -169,11 +159,6 @@ struct etl::is_assignable : public etl::true { }; -template <> -struct etl::is_constructible : public etl::true_type -{ -}; - template <> struct etl::is_copy_constructible : public etl::true_type { diff --git a/test/test_vector.cpp b/test/test_vector.cpp index 70313f3f..facf99cc 100644 --- a/test/test_vector.cpp +++ b/test/test_vector.cpp @@ -634,31 +634,6 @@ namespace CHECK(is_equal); } - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_emplace_back) - { - Compare_Data compare_data; - Data data; - - for (int i = 0; i < int(SIZE); ++i) - { - compare_data.emplace_back(i); - } - - for (int i = 0; i < int(SIZE); ++i) - { - data.emplace_back(i); - } - - CHECK_EQUAL(compare_data.size(), data.size()); - - bool is_equal = std::equal(data.begin(), - data.end(), - compare_data.begin()); - - CHECK(is_equal); - } - //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_back_literal) { @@ -697,6 +672,41 @@ namespace CHECK_THROW(data.push_back(SIZE), etl::vector_full); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back) + { + Compare_Data compare_data; + Data data; + + for (int i = 0; i < int(SIZE); ++i) + { + compare_data.emplace_back(i); + } + + for (int i = 0; i < int(SIZE); ++i) + { + data.emplace_back(i); + } + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back_return) + { + Data data; + + data.emplace_back(24); + auto back = data.emplace_back(42); + CHECK_EQUAL(back, data.back()); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_pop_back) { diff --git a/test/test_vector_external_buffer.cpp b/test/test_vector_external_buffer.cpp index 117bcdb1..f1e6e823 100644 --- a/test/test_vector_external_buffer.cpp +++ b/test/test_vector_external_buffer.cpp @@ -685,6 +685,41 @@ namespace CHECK_THROW(data.push_back(SIZE), etl::vector_full); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back) + { + Compare_Data compare_data; + Data data(buffer1, SIZE); + + for (int i = 0; i < int(SIZE); ++i) + { + compare_data.emplace_back(i); + } + + for (int i = 0; i < int(SIZE); ++i) + { + data.emplace_back(i); + } + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back_return) + { + Data data(buffer1, SIZE); + + data.emplace_back(24); + auto back = data.emplace_back(42); + CHECK_EQUAL(back, data.back()); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_pop_back) { diff --git a/test/test_vector_non_trivial.cpp b/test/test_vector_non_trivial.cpp index 3b4efc27..ccc58775 100644 --- a/test/test_vector_non_trivial.cpp +++ b/test/test_vector_non_trivial.cpp @@ -662,29 +662,6 @@ namespace CHECK_THROW(data.push_back(NDC("Z")), etl::vector_full); } - //************************************************************************* - TEST_FIXTURE(SetupFixture, test_emplace_back) - { - CompareDataNDC compare_data; - DataNDC data; - - for (size_t i = 0UL; i < SIZE; ++i) - { - std::string value(" "); - value[0] = char('A' + i); - compare_data.emplace_back(value, i); - data.emplace_back(value, i); - } - - CHECK_EQUAL(compare_data.size(), data.size()); - - bool is_equal = std::equal(data.begin(), - data.end(), - compare_data.begin()); - - CHECK(is_equal); - } - //************************************************************************* TEST_FIXTURE(SetupFixture, test_push_back_unique_ptr) { @@ -711,6 +688,39 @@ namespace CHECK_EQUAL(4, *data[3]); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back) + { + CompareDataNDC compare_data; + DataNDC data; + + for (size_t i = 0UL; i < SIZE; ++i) + { + std::string value(" "); + value[0] = char('A' + i); + compare_data.emplace_back(value, i); + data.emplace_back(value, i); + } + + CHECK_EQUAL(compare_data.size(), data.size()); + + bool is_equal = std::equal(data.begin(), + data.end(), + compare_data.begin()); + + CHECK(is_equal); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back_return) + { + DataNDC data; + + data.emplace_back("A", 24); + auto back = data.emplace_back("B", 42); + CHECK_EQUAL(back, data.back()); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_insert_int) { diff --git a/test/test_vector_pointer.cpp b/test/test_vector_pointer.cpp index d6aad71d..f4152804 100644 --- a/test/test_vector_pointer.cpp +++ b/test/test_vector_pointer.cpp @@ -1057,6 +1057,17 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back_return) + { + Data data; + int d1 = 22; + int d2 = 42; + + data.emplace_back(&d1); + CHECK_EQUAL(&d2, data.emplace_back(&d2)); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_pop_back) { diff --git a/test/test_vector_pointer_external_buffer.cpp b/test/test_vector_pointer_external_buffer.cpp index edad3ac9..97c6fe9d 100644 --- a/test/test_vector_pointer_external_buffer.cpp +++ b/test/test_vector_pointer_external_buffer.cpp @@ -1043,6 +1043,17 @@ namespace CHECK(is_equal); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_emplace_back_return) + { + Data data(buffer1, SIZE); + int d1 = 42; + int d2 = 24; + + data.emplace_back(&d1); + CHECK_EQUAL(&d2, data.emplace_back(&d2)); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_pop_back) { diff --git a/test/vs2019/etl.vcxproj b/test/vs2019/etl.vcxproj index c855b06b..a88a56dc 100644 --- a/test/vs2019/etl.vcxproj +++ b/test/vs2019/etl.vcxproj @@ -5630,6 +5630,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 + true true @@ -11381,6 +11409,7 @@ + diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index 1f0ab436..693b2073 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -1344,6 +1344,9 @@ ETL\Utilities + + ETL\Utilities + @@ -2228,9 +2231,6 @@ Tests\Misc - - Tests\Misc - Tests\Misc @@ -3392,6 +3392,15 @@ Tests\Misc + + Tests\Containers + + + Tests\Containers + + + Tests\Sanity Checks\Source + diff --git a/version.txt b/version.txt index 9c4538fe..afa2d91d 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -20.35.0 +20.35.10 From 8634480fa6549e348028d927cdd381a1b538e002 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 26 Jan 2023 10:51:35 +0000 Subject: [PATCH 30/60] Update README.md Added link to documentation --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 64fbf0a7..56c457b3 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ Embedded Template Library (ETL) [![](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/ETLCPP) +[Project documentation](https://www.etlcpp.com/) + ## Motivation C++ is a great language to use for embedded applications and templates are a powerful aspect. The standard library can offer a great deal of well tested functionality, but there are some parts of the standard library that do not fit well with deterministic behaviour and limited resource requirements. These limitations usually preclude the use of dynamically allocated memory and containers with open ended sizes. From deaf0c929ab8de7f67cc7a91eea4b833c6aecbad Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 26 Jan 2023 10:51:35 +0000 Subject: [PATCH 31/60] Update README.md Added link to documentation --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 64fbf0a7..56c457b3 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ Embedded Template Library (ETL) [![](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/ETLCPP) +[Project documentation](https://www.etlcpp.com/) + ## Motivation C++ is a great language to use for embedded applications and templates are a powerful aspect. The standard library can offer a great deal of well tested functionality, but there are some parts of the standard library that do not fit well with deterministic behaviour and limited resource requirements. These limitations usually preclude the use of dynamically allocated memory and containers with open ended sizes. From e67811065d0b18765a9322785c4831c57390f878 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 20 Jan 2023 12:13:27 +0000 Subject: [PATCH 32/60] Change iterator constructor parameter from reference to pointer Updated release notes Update README.md Added link to documentation Additional constructors for an initial value --- include/etl/cyclic_value.h | 28 ++++++++++++++++++++++++++-- test/test_cyclic_value.cpp | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/include/etl/cyclic_value.h b/include/etl/cyclic_value.h index 086ce9e7..03f19325 100644 --- a/include/etl/cyclic_value.h +++ b/include/etl/cyclic_value.h @@ -66,7 +66,7 @@ namespace etl public: //************************************************************************* - /// Constructor. + /// Default constructor. /// The initial value is set to the first value. //************************************************************************* cyclic_value() @@ -74,6 +74,16 @@ namespace etl { } + //************************************************************************* + /// Constructor. + /// Set to an initial value. + /// Clamped to the range. + //************************************************************************* + explicit cyclic_value(T initial) + { + set(initial); + } + //************************************************************************* /// Copy constructor. //************************************************************************* @@ -340,10 +350,24 @@ namespace etl cyclic_value(T first_, T last_) : value(first_), first_value(first_), - last_value(last_) + last_value(last_) { } + //************************************************************************* + /// Constructor. + /// Set to an initial value. + /// Clamped to the range. + ///\param first The first value in the range. + ///\param last The last value in the range. + //************************************************************************* + cyclic_value(T first_, T last_, T initial) + : first_value(first_) + , last_value(last_) + { + set(initial); + } + //************************************************************************* /// Copy constructor. //************************************************************************* diff --git a/test/test_cyclic_value.cpp b/test/test_cyclic_value.cpp index 70235546..a15d1699 100644 --- a/test/test_cyclic_value.cpp +++ b/test/test_cyclic_value.cpp @@ -87,6 +87,24 @@ namespace CHECK_EQUAL(value.last(), value.get()); } + //************************************************************************* + TEST(test_set_compile_time_initial_value_in_range) + { + etl::cyclic_value value(5); + + CHECK_EQUAL(5, value.get()); + } + + //************************************************************************* + TEST(test_set_compile_time_initial_value_out_of_range) + { + etl::cyclic_value value1(1); + etl::cyclic_value value2(8); + + CHECK_EQUAL(2, value1.get()); + CHECK_EQUAL(7, value2.get()); + } + //************************************************************************* TEST(test_set_run_time) { @@ -108,6 +126,24 @@ namespace CHECK_EQUAL(value.last(), value.get()); } + //************************************************************************* + TEST(test_set_run_time_initial_value_in_range) + { + etl::cyclic_value value(2, 7, 5); + + CHECK_EQUAL(5, value.get()); + } + + //************************************************************************* + TEST(test_set_run_time_initial_value_out_of_range) + { + etl::cyclic_value value1(2, 7, 1); + etl::cyclic_value value2(2, 7, 8); + + CHECK_EQUAL(2, value1.get()); + CHECK_EQUAL(7, value2.get()); + } + //************************************************************************* TEST(test_to_first_compile_time) { From df6f6d9d96e563c154768c4788747ca7d5cceea0 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 29 Jan 2023 20:46:41 +0100 Subject: [PATCH 33/60] Added destination_router_id parameter overrides to receive() virtuaL functions --- include/etl/message_broker.h | 35 ++++++++++++++++++++++++++++++----- test/test_message_broker.cpp | 21 +++++++++++++++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/include/etl/message_broker.h b/include/etl/message_broker.h index abedc8e1..08a0d0b6 100644 --- a/include/etl/message_broker.h +++ b/include/etl/message_broker.h @@ -184,6 +184,18 @@ namespace etl //******************************************* virtual void receive(const etl::imessage& msg) ETL_OVERRIDE + { + receive(etl::imessage_router::ALL_MESSAGE_ROUTERS, msg); + } + + virtual void receive(etl::shared_message shared_msg) ETL_OVERRIDE + { + receive(etl::imessage_router::ALL_MESSAGE_ROUTERS, shared_msg); + } + + //******************************************* + virtual void receive(etl::message_router_id_t destination_router_id, + const etl::imessage& msg) ETL_OVERRIDE { const etl::message_id_t id = msg.get_message_id(); @@ -200,7 +212,13 @@ namespace etl if (itr != message_ids.end()) { - sub->get_router()->receive(msg); + etl::imessage_router* router = sub->get_router(); + + if (destination_router_id == etl::imessage_router::ALL_MESSAGE_ROUTERS || + destination_router_id == router->get_message_router_id()) + { + sub->get_router()->receive(msg); + } } sub = sub->next_subscription(); @@ -212,12 +230,13 @@ namespace etl { etl::imessage_router& successor = get_successor(); - successor.receive(msg); + successor.receive(destination_router_id, msg); } } //******************************************* - virtual void receive(etl::shared_message shared_msg) ETL_OVERRIDE + virtual void receive(etl::message_router_id_t destination_router_id, + etl::shared_message shared_msg) ETL_OVERRIDE { const etl::message_id_t id = shared_msg.get_message().get_message_id(); @@ -234,7 +253,13 @@ namespace etl if (itr != message_ids.end()) { - sub->get_router()->receive(shared_msg); + etl::imessage_router* router = sub->get_router(); + + if (destination_router_id == etl::imessage_router::ALL_MESSAGE_ROUTERS || + destination_router_id == router->get_message_router_id()) + { + sub->get_router()->receive(shared_msg); + } } sub = sub->next_subscription(); @@ -244,7 +269,7 @@ namespace etl // Always pass the message on to a successor. if (has_successor()) { - get_successor().receive(shared_msg); + get_successor().receive(destination_router_id, shared_msg); } } diff --git a/test/test_message_broker.cpp b/test/test_message_broker.cpp index 8dbdf05e..3a414d8e 100644 --- a/test/test_message_broker.cpp +++ b/test/test_message_broker.cpp @@ -438,6 +438,27 @@ namespace CHECK_EQUAL(1, router3.message_unknown_count); } + //************************************************************************* + TEST(message_broker_send_messages_to_specific_subscribers) + { + Broker broker; + Router router1(1); + Router router2(2); + Router router3(3); + + Subscription subscription1{ router1, { Message1::ID, Message2::ID, Message3::ID, Message4::ID } }; + Subscription subscription2{ router2, { Message1::ID, Message2::ID } }; + Subscription subscription3{ router2, { Message1::ID, Message3::ID } }; + + broker.subscribe(subscription1); + broker.subscribe(subscription2); + broker.set_successor(router3); + + broker.receive(Message1()); + broker.receive(1, Message1()); + broker.receive(2, Message2()); + } + //************************************************************************* TEST(message_broker_send_messages_to_subscribers_after_unsubscribe) { From 580fd757b436b47989ad9202f14930251c25e528 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 29 Jan 2023 20:55:40 +0100 Subject: [PATCH 34/60] Added destination_router_id parameter overrides to receive() virtuaL functions --- include/etl/message_broker.h | 8 +- include/etl/message_bus.h | 158 +++++++++++++++++------------------ 2 files changed, 83 insertions(+), 83 deletions(-) diff --git a/include/etl/message_broker.h b/include/etl/message_broker.h index 08a0d0b6..ad99cb3f 100644 --- a/include/etl/message_broker.h +++ b/include/etl/message_broker.h @@ -195,7 +195,7 @@ namespace etl //******************************************* virtual void receive(etl::message_router_id_t destination_router_id, - const etl::imessage& msg) ETL_OVERRIDE + const etl::imessage& msg) ETL_OVERRIDE { const etl::message_id_t id = msg.get_message_id(); @@ -217,7 +217,7 @@ namespace etl if (destination_router_id == etl::imessage_router::ALL_MESSAGE_ROUTERS || destination_router_id == router->get_message_router_id()) { - sub->get_router()->receive(msg); + router->receive(msg); } } @@ -236,7 +236,7 @@ namespace etl //******************************************* virtual void receive(etl::message_router_id_t destination_router_id, - etl::shared_message shared_msg) ETL_OVERRIDE + etl::shared_message shared_msg) ETL_OVERRIDE { const etl::message_id_t id = shared_msg.get_message().get_message_id(); @@ -258,7 +258,7 @@ namespace etl if (destination_router_id == etl::imessage_router::ALL_MESSAGE_ROUTERS || destination_router_id == router->get_message_router_id()) { - sub->get_router()->receive(shared_msg); + router->receive(shared_msg); } } diff --git a/include/etl/message_bus.h b/include/etl/message_bus.h index 64b7958b..3ab24dba 100644 --- a/include/etl/message_bus.h +++ b/include/etl/message_bus.h @@ -155,85 +155,6 @@ namespace etl receive(etl::imessage_router::ALL_MESSAGE_ROUTERS, shared_msg); } - //******************************************** - virtual void receive(etl::message_router_id_t destination_router_id, - etl::shared_message shared_msg) ETL_OVERRIDE - { - switch (destination_router_id) - { - //***************************** - // Broadcast to all routers. - case etl::imessage_router::ALL_MESSAGE_ROUTERS: - { - router_list_t::iterator irouter = router_list.begin(); - - // Broadcast to everyone. - while (irouter != router_list.end()) - { - etl::imessage_router& router = **irouter; - - if (router.accepts(shared_msg.get_message().get_message_id())) - { - router.receive(shared_msg); - } - - ++irouter; - } - - break; - } - - //***************************** - // Must be an addressed message. - default: - { - // Find routers with the id. - ETL_OR_STD::pair range = etl::equal_range(router_list.begin(), - router_list.end(), - destination_router_id, - compare_router_id()); - - // Call all of them. - while (range.first != range.second) - { - if ((*(range.first))->accepts(shared_msg.get_message().get_message_id())) - { - (*(range.first))->receive(shared_msg); - } - - ++range.first; - } - - // Do any message buses. - // These are always at the end of the list. - router_list_t::iterator irouter = etl::lower_bound(router_list.begin(), - router_list.end(), - etl::imessage_bus::MESSAGE_BUS, - compare_router_id()); - - while (irouter != router_list.end()) - { - // So pass it on. - (*irouter)->receive(destination_router_id, shared_msg); - - ++irouter; - } - - break; - } - } - - if (has_successor()) - { - etl::imessage_router& successor = get_successor(); - - if (successor.accepts(shared_msg.get_message().get_message_id())) - { - successor.receive(destination_router_id, shared_msg); - } - } - } - //******************************************* virtual void receive(etl::message_router_id_t destination_router_id, const etl::imessage& message) ETL_OVERRIDE @@ -315,6 +236,85 @@ namespace etl } } + //******************************************** + virtual void receive(etl::message_router_id_t destination_router_id, + etl::shared_message shared_msg) ETL_OVERRIDE + { + switch (destination_router_id) + { + //***************************** + // Broadcast to all routers. + case etl::imessage_router::ALL_MESSAGE_ROUTERS: + { + router_list_t::iterator irouter = router_list.begin(); + + // Broadcast to everyone. + while (irouter != router_list.end()) + { + etl::imessage_router& router = **irouter; + + if (router.accepts(shared_msg.get_message().get_message_id())) + { + router.receive(shared_msg); + } + + ++irouter; + } + + break; + } + + //***************************** + // Must be an addressed message. + default: + { + // Find routers with the id. + ETL_OR_STD::pair range = etl::equal_range(router_list.begin(), + router_list.end(), + destination_router_id, + compare_router_id()); + + // Call all of them. + while (range.first != range.second) + { + if ((*(range.first))->accepts(shared_msg.get_message().get_message_id())) + { + (*(range.first))->receive(shared_msg); + } + + ++range.first; + } + + // Do any message buses. + // These are always at the end of the list. + router_list_t::iterator irouter = etl::lower_bound(router_list.begin(), + router_list.end(), + etl::imessage_bus::MESSAGE_BUS, + compare_router_id()); + + while (irouter != router_list.end()) + { + // So pass it on. + (*irouter)->receive(destination_router_id, shared_msg); + + ++irouter; + } + + break; + } + } + + if (has_successor()) + { + etl::imessage_router& successor = get_successor(); + + if (successor.accepts(shared_msg.get_message().get_message_id())) + { + successor.receive(destination_router_id, shared_msg); + } + } + } + using imessage_router::accepts; //******************************************* From 3c8f6940245bbd35644434c109aa3670a1ab9ee3 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 2 Feb 2023 19:37:33 +0100 Subject: [PATCH 35/60] Updated comment --- test/test_shared_message.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test_shared_message.cpp b/test/test_shared_message.cpp index 6d2af1e5..749c7822 100644 --- a/test/test_shared_message.cpp +++ b/test/test_shared_message.cpp @@ -260,6 +260,7 @@ namespace CHECK_EQUAL(0, router2.count_unknown_message); } + //************************************************************************* TEST(test_reference_counted_pool_exceptions) { using pool_message_parameters = etl::atomic_counted_message_pool::pool_message_parameters; From f858b36e821107c59cd9dbcc0894264a9db90b5d Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 27 Oct 2022 09:52:39 +0100 Subject: [PATCH 36/60] Work-In-Progress --- include/etl/file_error_numbers.h | 2 +- include/etl/optional.h | 6 ++++-- include/etl/result.h | 18 ++++++++++++++++-- test/vs2019/etl.vcxproj.filters | 12 ++++++------ 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/include/etl/file_error_numbers.h b/include/etl/file_error_numbers.h index 7d6a0e1a..b0500c48 100644 --- a/include/etl/file_error_numbers.h +++ b/include/etl/file_error_numbers.h @@ -100,5 +100,5 @@ SOFTWARE. #define ETL_BIP_BUFFER_SPSC_ATOMIC_FILE_ID "67" #define ETL_REFERENCE_COUNTED_OBJECT_FILE_ID "68" #define ETL_TO_ARITHMETIC_FILE_ID "69" - +#define ETL_EXPECTED_FILE_ID "70" #endif diff --git a/include/etl/optional.h b/include/etl/optional.h index bf5d791a..ebcb52a1 100644 --- a/include/etl/optional.h +++ b/include/etl/optional.h @@ -91,7 +91,7 @@ namespace etl public: optional_invalid(string_type file_name_, numeric_type line_number_) - : optional_exception("optional: invalid", file_name_, line_number_) + : optional_exception("optional:invalid", file_name_, line_number_) { } }; @@ -100,7 +100,7 @@ namespace etl /// An optional type. /// If the optional type is not initialised then a type is not constructed. /// See http://en.cppreference.com/w/cpp/utility/optional - ///\tparam The type to store. + ///\tparam T The type to store. ///\ingroup utilities //***************************************************************************** template ::value> @@ -521,6 +521,8 @@ namespace etl //***************************************************************************** /// For POD types. + ///\tparam T The type to store. + ///\ingroup utilities //***************************************************************************** template class optional diff --git a/include/etl/result.h b/include/etl/result.h index 95d0fc0c..f8523b8b 100644 --- a/include/etl/result.h +++ b/include/etl/result.h @@ -50,7 +50,7 @@ namespace etl /// Result type. //***************************************************************************** template - class result + class ETL_DEPRECATED result { public: @@ -67,6 +67,7 @@ namespace etl { } +#if ETL_CPP11_SUPPORTED //******************************************* /// Move constructor //******************************************* @@ -74,6 +75,7 @@ namespace etl : data(etl::move(other.data)) { } +#endif //******************************************* // Construct from a value @@ -86,7 +88,7 @@ namespace etl //******************************************* // Move construct from a value //******************************************* - result(TValue&& value) + result(TValue&& value) : data(etl::move(value)) { } @@ -102,10 +104,12 @@ namespace etl //******************************************* /// Move construct from error //******************************************* +#if ETL_CPP11_SUPPORTED result(TError&& error) : data(etl::move(error)) { } +#endif //******************************************* /// Copy assign @@ -137,11 +141,13 @@ namespace etl //******************************************* /// Move assign from value //******************************************* +#if ETL_CPP11_SUPPORTED result& operator =(TValue&& value) { data = etl::move(value); return *this; } +#endif //******************************************* /// Copy assign from error @@ -155,11 +161,13 @@ namespace etl //******************************************* /// Move assign from error //******************************************* +#if ETL_CPP11_SUPPORTED result& operator =(TError&& error) { data = etl::move(error); return *this; } +#endif //******************************************* /// true if result contains a value @@ -216,10 +224,12 @@ namespace etl /// Returns an rvalue reference to the error. /// Undefined if the result does not contain an error. //******************************************* +#if ETL_CPP11_SUPPORTED TError&& error() { return etl::move(etl::get(data)); } +#endif private: @@ -273,6 +283,7 @@ namespace etl : data(etl::move(error)) { } +#endif //******************************************* /// Copy assign from error @@ -291,6 +302,7 @@ namespace etl data = etl::move(error); return *this; } +#endif //******************************************* /// true if result contains a value @@ -329,10 +341,12 @@ namespace etl /// Returns an rvalue reference to the error. /// Undefined if the result does not contain an error. //******************************************* +#if ETL_CPP11_SUPPORTED TError&& error() { return etl::move(data.value()); } +#endif private: diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index e6c75e07..1f0ab436 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -345,9 +345,6 @@ ETL\Utilities - - ETL\Containers - ETL\Containers @@ -1344,6 +1341,9 @@ ETL\Containers + + ETL\Utilities + @@ -2192,9 +2192,6 @@ Tests\Maths - - Tests\Containers - Tests\Errors @@ -3392,6 +3389,9 @@ Tests\Sanity Checks\Source + + Tests\Misc + From bdea8c1622a6c296525328ae6c7e9777dc724b02 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 15 Oct 2022 14:28:58 +0100 Subject: [PATCH 37/60] Work-In-Progress --- include/etl/expected.h | 355 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 345 insertions(+), 10 deletions(-) diff --git a/include/etl/expected.h b/include/etl/expected.h index 9ca6d03f..bc46713f 100644 --- a/include/etl/expected.h +++ b/include/etl/expected.h @@ -31,6 +31,8 @@ SOFTWARE. #ifndef ETL_EXPECTED_INCLUDED #define ETL_EXPECTED_INCLUDED +///\defgroup expected expected +///\ingroup utilities #include "platform.h" #include "type_traits.h" #include "utility.h" @@ -49,7 +51,7 @@ namespace etl //******************************************* /// Copy constructor. //******************************************* - ETL_CONSTEXPR14 unexpected(const unexpected& other) + ETL_CONSTEXPR unexpected(const unexpected& other) : error_value(other.error_value) { } @@ -62,25 +64,24 @@ namespace etl : error_value(etl::move(other.error_value)) { } -#endif -#if ETL_USING_CPP11 +#if ETL_CPP11_SUPPORTED //******************************************* /// Construct from argument. //******************************************* - template ::type, etl::unexpected>::value && - !etl::is_same::type, etl::in_place_t>::value, int>::type> - constexpr explicit unexpected(TErr&& e) - : error_value(etl::forward(e)) + template ::type, etl::unexpected>::value && + !etl::is_same::type, etl::in_place_t>::value, int>::type> + constexpr explicit unexpected(E&& e) + : error_value(etl::forward(e)) { } #else //******************************************* /// Construct from argument. //******************************************* - template - explicit unexpected(const TErr& e, typename etl::enable_if::type, etl::unexpected >::value && - !etl::is_same::type, etl::in_place_t>::value, int>::type = 0) + template + explicit unexpected(const E& e, typename etl::enable_if::type, etl::unexpected>::value && + !etl::is_same::type, etl::in_place_t>::value, int>::type = 0) : error_value(e) { } @@ -208,6 +209,11 @@ namespace etl TError error_value; }; +#if ETL_USING_CPP17 + template + unexpected(TError) -> unexpected; +#endif + #if ETL_USING_CPP17 template unexpected(TError) -> unexpected; @@ -251,3 +257,332 @@ static const unexpect_t unexpect; #endif #endif + //******************************************* + /// Equivalence operator. + //******************************************* + template + bool operator ==(const etl::unexpected& lhs, const etl::unexpected& rhs) + { + return lhs.error_value == rhs.error_value; + } + + //******************************************* + /// Swap etl::unexpected. + //******************************************* + template + void swap(etl::unexpected& lhs, etl::unexpected& rhs) + { + lhs.swap(rhs); + } + + //***************************************************************************** + /// unexpect_t + //***************************************************************************** + struct unexpect_t + { + explicit unexpect_t() + { + } + }; + + inline ETL_CONSTEXPR14 unexpect_t unexpect{}; + + //***************************************************************************** + /// Expected type. + //***************************************************************************** + template + class expected + { + public: + + typename TValue value_type; + typename TError error_type; + typename etl::unexpected unexpected_type; + +#if ETL_CPP11_SUPPORTED + template + using rebind = etl::expected; +#endif + + //******************************************* + /// Default constructor + //******************************************* + ETL_CONSTEXPR14 expected(const expected& other) ETL_NOEXCEPT + : data(TValue()) + { + } + + //******************************************* + /// Copy constructor + //******************************************* + ETL_CONSTEXPR14 expected(const expected& other) + : data(other.data) + { + } + +#if ETL_CPP11_SUPPORTED + //******************************************* + /// Move constructor + //******************************************* + ETL_CONSTEXPR14 expected(expected&& other) ETL_NOEXCEPT + : data(etl::move(other.data)) + { + } +#endif + + template + constexpr explicit() expected(const expected& other) + { + } + + template + constexpr explicit(expected(expected&& other) + { + } + +#if ETL_CPP11_SUPPORTED + template + constexpr explicit expected(U&& v) + { + } +#endif + + template + constexpr explicit expected(const etl::unexpected& e) + { + } + +#if ETL_CPP11_SUPPORTED + template + constexpr explicit expected(etl::unexpected&& e) + { + } +#endif + + constexpr explicit expected(etl::in_place_t) noexcept + { + } + + template + constexpr explicit expected(etl::in_place_t, Args&&... args) + { + } + + template + constexpr explicit expected(etl::in_place_t, std::initializer_list il, Args&&... args) + { + } + + template + constexpr explicit expected(etl::unexpect_t, Args&&... args) + { + } + + template + constexpr explicit expected(etl::unexpect_t, std::initializer_list il, Args&&... args) + { + } + +// //******************************************* +// // Construct from a value +// //******************************************* +// expected(const TValue& value) +// : data(value) +// { +// } +// +//#if ETL_CPP11_SUPPORTED +// //******************************************* +// // Move construct from a value +// //******************************************* +// expected(TValue&& value) +// : data(etl::move(value)) +// { +// } +//#endif + + ////******************************************* + ///// Construct from error + ////******************************************* + //expected(const TError& error) + // : data(error) + //{ + //} + + ////******************************************* + ///// Move construct from error + ////******************************************* + //expected(TError&& error) + // : data(etl::move(error)) + //{ + //} + + //******************************************* + /// Copy assign + //******************************************* + expected& operator =(const expected& other) + { + data = other.data; + return *this; + } + + //******************************************* + /// Move assign + //******************************************* + expected& operator =(expected&& other) + { + data = etl::move(other.data); + return *this; + } + + //******************************************* + /// Copy assign from value + //******************************************* + expected& operator =(const TValue& value) + { + data = value; + return *this; + } + + //******************************************* + /// Move assign from value + //******************************************* + expected& operator =(TValue&& value) + { + data = etl::move(value); + return *this; + } + + //******************************************* + /// Copy assign from error + //******************************************* + expected& operator =(const TError& error) + { + data = error; + return *this; + } + + //******************************************* + /// Move assign from error + //******************************************* + expected& operator =(TError&& error) + { + data = etl::move(error); + return *this; + } + + //******************************************* + /// Returns a const reference to the value. + /// Undefined if the expected does not contain an value. + //******************************************* + ETL_CONSTEXPR14 const TValue& value() const + { + return etl::get(data); + } + + //******************************************* + /// Returns an rvalue reference to the value. + /// Undefined if the expected does not contain an value. + //******************************************* + ETL_CONSTEXPR14 TValue&& value() + { + return etl::move(etl::get(etl::move(data))); + } + +#if ETL_CPP11_SUPPORTED + //******************************************* + /// + //******************************************* + template + ETL_CONSTEXPR14 TValue value_or(U&& default_value) const& + { + if (has_value()) + { + return value(); + } + else + { + return default_value; + } + } + + //******************************************* + /// + //******************************************* + template + ETL_CONSTEXPR14 TValue value_or(U&& default_value) && + { + if (has_value()) + { + return etl::move(value()); + } + else + { + return etl::move(default_value); + } + } +#else + //******************************************* + /// + //******************************************* + template + TValue value_or(const U& default_value) const + { + if (has_value()) + { + return value(); + } + else + { + return default_value; + } + } +#endif + + //******************************************* + /// Returns a const reference to the error. + /// Undefined if the expected does not contain an error. + //******************************************* + ETL_CONSTEXPR14 const TError& error() const + { + return etl::get(data); + } + +#if (ETL_CPP11_SUPPORTED) + //******************************************* + /// Returns an rvalue reference to the error. + /// Undefined if the expected does not contain an error. + //******************************************* + ETL_CONSTEXPR14 TError&& error() && + { + return etl::move(etl::get(data)); + } + + //******************************************* + /// Returns an rvalue reference to the error. + /// Undefined if the expected does not contain an error. + //******************************************* + ETL_CONSTEXPR14 TError&& error() const && + { + return etl::move(etl::get(data)); + } +#endif + + private: + + etl::variant data; + }; + + //***************************************************************************** + /// Result type. + /// Specialisation for void value type. + //***************************************************************************** + template + class expected + { + +} + + +#endif + From 9a13b8c24fb9ff8f360b07a7df7bc81ffd549131 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 24 Oct 2022 17:15:25 +0100 Subject: [PATCH 38/60] Work-In-Progress --- include/etl/expected.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/include/etl/expected.h b/include/etl/expected.h index bc46713f..daeae148 100644 --- a/include/etl/expected.h +++ b/include/etl/expected.h @@ -280,12 +280,14 @@ static const unexpect_t unexpect; //***************************************************************************** struct unexpect_t { - explicit unexpect_t() + ETL_CONSTEXPR14 explicit unexpect_t() { } }; +#if ETL_CPP14_SUPPORTED inline ETL_CONSTEXPR14 unexpect_t unexpect{}; +#endif //***************************************************************************** /// Expected type. @@ -580,7 +582,14 @@ static const unexpect_t unexpect; template class expected { + public: + + + private: + + TError error; + }; } From 354f2042e68ed4bcb8db60d48c016aae3281ff83 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 27 Oct 2022 09:52:39 +0100 Subject: [PATCH 39/60] Work-In-Progress --- include/etl/expected.h | 302 +++++++++++++++++++++----------- include/etl/result.h | 9 +- test/vs2019/etl.vcxproj.filters | 3 + 3 files changed, 205 insertions(+), 109 deletions(-) diff --git a/include/etl/expected.h b/include/etl/expected.h index daeae148..cb890b1c 100644 --- a/include/etl/expected.h +++ b/include/etl/expected.h @@ -34,11 +34,56 @@ SOFTWARE. ///\defgroup expected expected ///\ingroup utilities #include "platform.h" -#include "type_traits.h" +#include "exception.h" +#include "error_handler.h" #include "utility.h" +#include "variant.h" namespace etl { + //*************************************************************************** + /// Base exception for et::expected + //*************************************************************************** + class expected_exception : public etl::exception + { + public: + + expected_exception(string_type reason_, string_type file_name_, numeric_type line_number_) + : exception(reason_, file_name_, line_number_) + { + } + }; + + //*************************************************************************** + /// expected_invalid + //*************************************************************************** + template + class expected_invalid; + + //******************************************* + template<> + class expected_invalid : public etl::expected_exception + { + public: + + expected_invalid(string_type file_name_, numeric_type line_number_) + : expected_exception(ETL_ERROR_TEXT("expected:invalid", ETL_EXPECTED_FILE_ID"A"), file_name_, line_number_) + { + } + }; + + //******************************************* + template + class expected_invalid : etl::expected_invalid + { + public: + + expected_invalid(string_type file_name_, numeric_type line_number_) + : expected_invalid(file_name_, line_number_) + { + } + }; + //*************************************************************************** /// Unexpected type. /// etl::unexpected represents an unexpected value stored in etl::expected. @@ -64,24 +109,25 @@ namespace etl : error_value(etl::move(other.error_value)) { } +#endif #if ETL_CPP11_SUPPORTED //******************************************* /// Construct from argument. //******************************************* - template ::type, etl::unexpected>::value && - !etl::is_same::type, etl::in_place_t>::value, int>::type> - constexpr explicit unexpected(E&& e) - : error_value(etl::forward(e)) + template ::type, etl::unexpected>::value && + !etl::is_same::type, etl::in_place_t>::value, int>::type> + constexpr explicit unexpected(TErr&& e) + : error_value(etl::forward(e)) { } #else //******************************************* /// Construct from argument. //******************************************* - template - explicit unexpected(const E& e, typename etl::enable_if::type, etl::unexpected>::value && - !etl::is_same::type, etl::in_place_t>::value, int>::type = 0) + template + explicit unexpected(const TErr& e, typename etl::enable_if::type, etl::unexpected>::value && + !etl::is_same::type, etl::in_place_t>::value, int>::type = 0) : error_value(e) { } @@ -303,13 +349,13 @@ static const unexpect_t unexpect; #if ETL_CPP11_SUPPORTED template - using rebind = etl::expected; + using rebind = etl::expected; #endif //******************************************* /// Default constructor //******************************************* - ETL_CONSTEXPR14 expected(const expected& other) ETL_NOEXCEPT + ETL_CONSTEXPR14 expected() ETL_NOEXCEPT : data(TValue()) { } @@ -317,7 +363,7 @@ static const unexpect_t unexpect; //******************************************* /// Copy constructor //******************************************* - ETL_CONSTEXPR14 expected(const expected& other) + ETL_CONSTEXPR14 expected(const expected& other) ETL_NOEXCEPT : data(other.data) { } @@ -332,111 +378,49 @@ static const unexpect_t unexpect; } #endif - template - constexpr explicit() expected(const expected& other) - { - } - - template - constexpr explicit(expected(expected&& other) - { - } - -#if ETL_CPP11_SUPPORTED - template - constexpr explicit expected(U&& v) - { - } -#endif - template - constexpr explicit expected(const etl::unexpected& e) + ETL_CONSTEXPR14 explicit expected(const etl::unexpected& ue) + : data(ue) { } #if ETL_CPP11_SUPPORTED template - constexpr explicit expected(etl::unexpected&& e) + ETL_CONSTEXPR14 explicit expected(etl::unexpected&& ue) + : data(etl::move(ue)) { } #endif - constexpr explicit expected(etl::in_place_t) noexcept + ETL_CONSTEXPR14 explicit expected(etl::in_place_t) ETL_NOEXCEPT + : data(TValue()) { } template - constexpr explicit expected(etl::in_place_t, Args&&... args) + ETL_CONSTEXPR14 explicit expected(etl::in_place_t, Args&&... args) + : data(etl::forward(args)...) { } template - constexpr explicit expected(etl::in_place_t, std::initializer_list il, Args&&... args) + ETL_CONSTEXPR14 explicit expected(etl::in_place_t, std::initializer_list il, Args&&... args) + : data(il, etl::forward(args)...) { } template - constexpr explicit expected(etl::unexpect_t, Args&&... args) + ETL_CONSTEXPR14 explicit expected(etl::unexpect_t, Args&&... args) + : data(etl::unexpected(args...)) { } template - constexpr explicit expected(etl::unexpect_t, std::initializer_list il, Args&&... args) + ETL_CONSTEXPR14 explicit expected(etl::unexpect_t, std::initializer_list il, Args&&... args) + : data(etl::unexpected(il, args...)) { } -// //******************************************* -// // Construct from a value -// //******************************************* -// expected(const TValue& value) -// : data(value) -// { -// } -// -//#if ETL_CPP11_SUPPORTED -// //******************************************* -// // Move construct from a value -// //******************************************* -// expected(TValue&& value) -// : data(etl::move(value)) -// { -// } -//#endif - - ////******************************************* - ///// Construct from error - ////******************************************* - //expected(const TError& error) - // : data(error) - //{ - //} - - ////******************************************* - ///// Move construct from error - ////******************************************* - //expected(TError&& error) - // : data(etl::move(error)) - //{ - //} - - //******************************************* - /// Copy assign - //******************************************* - expected& operator =(const expected& other) - { - data = other.data; - return *this; - } - - //******************************************* - /// Move assign - //******************************************* - expected& operator =(expected&& other) - { - data = etl::move(other.data); - return *this; - } - //******************************************* /// Copy assign from value //******************************************* @@ -473,6 +457,39 @@ static const unexpect_t unexpect; return *this; } +#if ETL_CPP11_SUPPORTED + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 T& value() & + { + return etl::get(data); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 const T& value() const& + { + return etl::get(data); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 T&& value() && + { + return etl::move(etl::get(data)); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 const T&& value() const&& + { + return etl::move(etl::get(data)); + } +#else //******************************************* /// Returns a const reference to the value. /// Undefined if the expected does not contain an value. @@ -481,15 +498,7 @@ static const unexpect_t unexpect; { return etl::get(data); } - - //******************************************* - /// Returns an rvalue reference to the value. - /// Undefined if the expected does not contain an value. - //******************************************* - ETL_CONSTEXPR14 TValue&& value() - { - return etl::move(etl::get(etl::move(data))); - } +#endif #if ETL_CPP11_SUPPORTED //******************************************* @@ -541,6 +550,39 @@ static const unexpect_t unexpect; } #endif +#if ETL_CPP11_SUPPORTED + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 const TError& error() const& ETL_NOEXCEPT + { + return etl::get(data); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 TError& error() & ETL_NOEXCEPT + { + return etl::get(data); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 const TError&& error() const&& ETL_NOEXCEPT + { + return etl::move(etl::get(data)); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 TError&& error() && ETL_NOEXCEPT + { + return etl::move(etl::get(data)); + } +#else //******************************************* /// Returns a const reference to the error. /// Undefined if the expected does not contain an error. @@ -549,34 +591,82 @@ static const unexpect_t unexpect; { return etl::get(data); } +#endif -#if (ETL_CPP11_SUPPORTED) +#if ETL_CPP11_SUPPORTED //******************************************* - /// Returns an rvalue reference to the error. - /// Undefined if the expected does not contain an error. + /// //******************************************* - ETL_CONSTEXPR14 TError&& error() && + template + ETL_CONSTEXPR14 T& emplace(Args&&... args) ETL_NOEXCEPT { - return etl::move(etl::get(data)); + data.emplace(args...); } //******************************************* - /// Returns an rvalue reference to the error. - /// Undefined if the expected does not contain an error. + /// //******************************************* - ETL_CONSTEXPR14 TError&& error() const && + template + ETL_CONSTEXPR14 T& emplace(std::initializer_list& il, Args&&... args) ETL_NOEXCEPT { - return etl::move(etl::get(data)); + data.emplace(il, args...); } #endif + //******************************************* + /// + //******************************************* + TValue* operator ->() + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); +#endif + + return etl::addressof(data.get()); + } + + //******************************************* + /// + //******************************************* + const TValue* operator ->() const + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); +#endif + + return etl::addressof(data.get()); + } + + //******************************************* + /// + //******************************************* + TValue& operator *() + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); +#endif + + return data.get(); + } + + //******************************************* + /// + //******************************************* + const TValue& operator *() const + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); +#endif + + return data.get(); + } + private: etl::variant data; }; //***************************************************************************** - /// Result type. /// Specialisation for void value type. //***************************************************************************** template diff --git a/include/etl/result.h b/include/etl/result.h index f8523b8b..0335132e 100644 --- a/include/etl/result.h +++ b/include/etl/result.h @@ -279,8 +279,9 @@ namespace etl //******************************************* /// Move construct from error //******************************************* - result(TError&& error) - : data(etl::move(error)) +#if ETL_CPP11_SUPPORTED + result(TError&& err_) + : err(etl::move(err_)) { } #endif @@ -297,7 +298,8 @@ namespace etl //******************************************* /// Move assign from error //******************************************* - result& operator =(TError&& error) +#if ETL_CPP11_SUPPORTED + result& operator =(TError&& err_) { data = etl::move(error); return *this; @@ -460,6 +462,7 @@ namespace etl { return etl::move(data.value()); } +#endif private: diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index 1f0ab436..bd2769ba 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -1344,6 +1344,9 @@ ETL\Utilities + + ETL\Utilities + From 4c92670a6d65099497c7d787d52fcf8d12e08766 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 2 Nov 2022 11:54:21 +0000 Subject: [PATCH 40/60] Work-In-Progress for full implementation of etl::expected fix set of ETL_NO_STL flag (#628) Co-authored-by: Sergey Skorokhod Removed duplicate include unique_ptr updates - Work in progress Updated versions & memory.h Fix duplicate function Fixed incorrect 'valid' flag in assignment operator for arithmetic specialisation Updated version and release notes Fix bug #636 in optional emplace for pod types (#638) Updated version info Updated generator test script Only build tests if top level project (#639) Removed trailing spaces Updated version info Incorrect C++03 enable_if syntax Updated version info Don't use `push_macro` and `pull_macro` with Tasking compiler (#643) * Autodetect Tasking compiler #642 * Don't use `push_macro` and `pop_macro` for Tasking compiler #642 Co-authored-by: Todd Snider #643 Don't use push_macro and pull_macro with Tasking compiler Updated etl::delgate to handle const functors correctly Updated version info Fixed functor delegate enable_if Updated release notes Avoid 'missing return statement at end of non-void function' in `etl::visit<>()`. (#645) * Avoid 'missing return statement at end of non-void function' in `etl::visit<>()`. For some definitions of `ETL_ASSERT()` there may be no return statement in case of an invalid type. This results in undefined behavior. Warning[Pe940]: missing return statement at end of non-void function "etl::visit(TVisitor &, TVariant const &) include\etl\private\variant_legacy.h 976 * Use more self-explaining code. Substitute ET_ASSERT() and return by dedicated macro. This moves the responsibility of how to handle errors to the dedicated place. improve is_constructible, is_copy_constructible, is_move_constructible for type traits with default definitions (#648) Removed unused ETL_USE_MEM_BUILTINS option Updated version info Updated release notes Added etl::result specialisation Reverted code for etl::result specialisation Added etl::result specialisation Reverted code for etl::result specialisation Fixed perfect forwarding for make_xxx helper functions Don't warn on tag missing when subproject (#653) (#655) Different solution than proposed in the issue, since that proposed solution would given unexpected results when an intermediate (untagged) commit is checked out. This change simply skips warning about a missing git version when this is a subproject, and uses the original version calculation logic. I've also renamed `determine_version` to `determine_version_with_file`. I'd originally done this in an intermediate version of this PR, but I think that keeping the renaming is clearer code. Removed superfluous semicolons Updated version and release notes Removed testing for 18.04 Added testing for 22.04 Updated Github Actions for Clang Updated version and release notes clang updates for Github Actions Added missing notes emplace member functions return reference to emplaced value (#659) emplace_front, emplace_back updates Updated version and release info Improved emplace testing Changed unit test macro CHECK_FALSE_EQUAL to CHECK_NOT_EQUAL Improved emplace testing Changed unit test macro CHECK_FALSE_EQUAL to CHECK_NOT_EQUAL Improved emplace testing Work-In-Progress Work-In-Progress Added indexed emplace More typedefs for etl::result Work in progress Work in progress Work in progress Changed default constructor Added function comments --- include/etl/expected.h | 646 +++++++++++++++++++++++-- include/etl/private/variant_variadic.h | 2 +- include/etl/result.h | 10 +- test/CMakeLists.txt | 1 + test/sanity-check/c++03/CMakeLists.txt | 1 + test/sanity-check/c++11/CMakeLists.txt | 1 + test/sanity-check/c++14/CMakeLists.txt | 1 + test/sanity-check/c++17/CMakeLists.txt | 1 + test/sanity-check/expected.h.t.cpp | 29 ++ test/test_expected.cpp | 446 +++++++++++++++++ test/test_result.cpp | 51 +- test/vs2019/etl.vcxproj | 29 ++ test/vs2019/etl.vcxproj.filters | 12 +- 13 files changed, 1131 insertions(+), 99 deletions(-) create mode 100644 test/sanity-check/expected.h.t.cpp create mode 100644 test/test_expected.cpp diff --git a/include/etl/expected.h b/include/etl/expected.h index cb890b1c..f2a91997 100644 --- a/include/etl/expected.h +++ b/include/etl/expected.h @@ -93,6 +93,8 @@ namespace etl { public: + typedef TError error_type; + //******************************************* /// Copy constructor. //******************************************* @@ -161,8 +163,9 @@ namespace etl ETL_CONSTEXPR14 etl::unexpected& operator =(const etl::unexpected& rhs) { - error_value = rhs.error_value; + ETL_STATIC_ASSERT(etl::is_copy_constructible::value, "Error not copy assignable"); + error_value = rhs.error_value; return *this; } @@ -173,8 +176,9 @@ namespace etl ETL_CONSTEXPR14 etl::unexpected& operator =(etl::unexpected&& rhs) { - error_value = etl::move(rhs.error_value); + ETL_STATIC_ASSERT(etl::is_move_constructible::value, "Error not move assignable"); + error_value = etl::move(rhs.error_value); return *this; } #endif @@ -183,7 +187,7 @@ namespace etl //******************************************* /// Get the error. //******************************************* - constexpr const TError& error() const& noexcept + constexpr TError& error() & noexcept { return error_value; } @@ -191,16 +195,7 @@ namespace etl //******************************************* /// Get the error. //******************************************* - constexpr const TError&& error() const&& noexcept - { - return etl::move(error_value); - } - -#if ETL_USING_CPP14 - //******************************************* - /// Get the error. - //******************************************* - constexpr TError& error() & noexcept + constexpr const TError& error() const& noexcept { return error_value; } @@ -212,24 +207,14 @@ namespace etl { return etl::move(error_value); } -#else - //******************************************* - /// Get the error. - //******************************************* - TError& error() & noexcept - { - return error_value; - } //******************************************* /// Get the error. //******************************************* - TError&& error() && noexcept + constexpr TError&& error() const && noexcept { return etl::move(error_value); } -#endif - #else //******************************************* /// Get the error. @@ -257,13 +242,604 @@ namespace etl #if ETL_USING_CPP17 template - unexpected(TError) -> unexpected; + bool operator ==(const etl::unexpected& lhs, const etl::unexpected& rhs) + { + return lhs.error_value == rhs.error_value; + } + + //******************************************* + /// Swap etl::unexpected. + //******************************************* + template + void swap(etl::unexpected& lhs, etl::unexpected& rhs) + { + lhs.swap(rhs); + } + + //***************************************************************************** + /// unexpect_t + //***************************************************************************** + struct unexpect_t + { + ETL_CONSTEXPR14 explicit unexpect_t() + { + } + }; #endif #if ETL_USING_CPP17 - template - unexpected(TError) -> unexpected; + inline constexpr unexpect_t unexpect{}; +#else + static const unexpect_t unexpect; #endif + + //***************************************************************************** + /// Expected type. + //***************************************************************************** + template + class expected + { + public: + + typedef etl::expected this_type; + typedef TValue value_type; + typedef TError error_type; + typedef etl::unexpected unexpected_type; + + template + using rebind = expected; + + //******************************************* + /// Default constructor + //******************************************* + ETL_CONSTEXPR14 expected() ETL_NOEXCEPT + : storage(etl::in_place_index, value_type()) + { + } + + //******************************************* + /// Constructor + //******************************************* + ETL_CONSTEXPR14 expected(const value_type& value_) ETL_NOEXCEPT + : storage(etl::in_place_index, value_) + { + } + + //******************************************* + /// Constructor + //******************************************* + ETL_CONSTEXPR14 expected(value_type&& value_) ETL_NOEXCEPT + : storage(etl::in_place_index, etl::move(value_)) + { + } + + //******************************************* + /// Copy constructor + //******************************************* + ETL_CONSTEXPR14 expected(const expected& other) ETL_NOEXCEPT + : storage(other.storage) + { + } + + //******************************************* + /// Move constructor + //******************************************* + ETL_CONSTEXPR14 expected(expected&& other) ETL_NOEXCEPT + : storage(etl::move(other.storage)) + { + } + + //******************************************* + /// Copy construct from unexpected type. + //******************************************* + template + ETL_CONSTEXPR14 explicit expected(const etl::unexpected& ue) + : storage(etl::in_place_index, ue.error()) + { + } + + //******************************************* + /// Move construct from unexpected type. + //******************************************* + template + ETL_CONSTEXPR14 explicit expected(etl::unexpected&& ue) + : storage(etl::in_place_index, etl::move(ue.error())) + { + } + + //******************************************* + /// Construct with default value type. + //******************************************* + ETL_CONSTEXPR14 explicit expected(etl::in_place_t) ETL_NOEXCEPT + : storage(value_type()) + { + } + + //******************************************* + /// Construct value type from arguments. + //******************************************* + template + ETL_CONSTEXPR14 explicit expected(etl::in_place_t, Args&&... args) + : storage(etl::forward(args)...) + { + } + + //******************************************* + /// Construct value type from initializser_list and arguments. + //******************************************* + template + ETL_CONSTEXPR14 explicit expected(etl::in_place_t, std::initializer_list il, Args&&... args) + : storage(il, etl::forward(args)...) + { + } + + //******************************************* + /// Construct error type from arguments. + //******************************************* + template + ETL_CONSTEXPR14 explicit expected(etl::unexpect_t, Args&&... args) + : storage(error_type(etl::forward(args)...)) + { + } + + //******************************************* + /// Construct error type from initializser_list and arguments. + //******************************************* + template + ETL_CONSTEXPR14 explicit expected(etl::unexpect_t, std::initializer_list il, Args&&... args) + : storage(error_type(il, etl::forward(args)...)) + { + } + + //******************************************* + /// + //******************************************* + this_type& operator =(const this_type& other) + { + ETL_STATIC_ASSERT(etl::is_copy_constructible::value && etl::is_copy_constructible::value, "Not copy assignable"); + + storage = other.storage; + + return *this; + } + + //******************************************* + /// + //******************************************* + this_type& operator =(this_type&& other) + { + ETL_STATIC_ASSERT(etl::is_move_constructible::value && etl::is_move_constructible::value, "Not move assignable"); + + storage = etl::move(other.storage); + return *this; + } + + //******************************************* + /// Copy assign from value + //******************************************* + expected& operator =(const value_type& value) + { + ETL_STATIC_ASSERT(etl::is_copy_constructible::value, "Value not copy assignable"); + + storage.emplace(value); + return *this; + } + + //******************************************* + /// Move assign from value + //******************************************* + expected& operator =(value_type&& value) + { + ETL_STATIC_ASSERT(etl::is_move_constructible::value, "Value not move assignable"); + + storage.emplace(etl::move(value)); + return *this; + } + + //******************************************* + /// Copy assign from error + //******************************************* + expected& operator =(const unexpected_type& error) + { + ETL_STATIC_ASSERT(etl::is_copy_constructible::value, "Error not copy assignable"); + + storage.emplace(error); + return *this; + } + + //******************************************* + /// Move assign from error + //******************************************* + expected& operator =(unexpected_type&& error) + { + ETL_STATIC_ASSERT(etl::is_move_constructible::value, "Error not move assignable"); + + storage.emplace(etl::move(error)); + return *this; + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 value_type& value()& + { + return etl::get(storage); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 const value_type& value() const& + { + return etl::get(storage); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 value_type&& value()&& + { + return etl::move(etl::get(storage)); + } + + //******************************************* + /// + //******************************************* + ETL_CONSTEXPR14 const value_type&& value() const&& + { + return etl::move(etl::get(storage)); + } + + //******************************************* + /// + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + bool has_value() const + { + return (storage.index() == Value_Type); + } + + //******************************************* + /// + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + operator bool() const + { + return has_value(); + } + + //******************************************* + /// + //******************************************* + template + ETL_NODISCARD + ETL_CONSTEXPR14 + value_type value_or(U&& default_value) const& + { + if (has_value()) + { + return value(); + } + else + { + return default_value; + } + } + + //******************************************* + /// + //******************************************* + template + ETL_NODISCARD + ETL_CONSTEXPR14 + value_type value_or(U&& default_value)&& + { + if (has_value()) + { + return etl::move(value()); + } + else + { + return etl::move(default_value); + } + } + + //******************************************* + /// + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + error_type& error()& ETL_NOEXCEPT + { + return etl::get(storage); + } + + //******************************************* + /// + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + const error_type& error() const& ETL_NOEXCEPT + { + return etl::get(storage); + } + + //******************************************* + /// + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + error_type&& error() && ETL_NOEXCEPT + { + return etl::move(etl::get(storage)); + } + + //******************************************* + /// + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + const error_type&& error() const&& ETL_NOEXCEPT + { + return etl::move(etl::get(storage)); + } + + //******************************************* + /// + //******************************************* + template + ETL_CONSTEXPR14 value_type& emplace(Args&&... args) ETL_NOEXCEPT + { + storage.emplace(args...); + } + + //******************************************* + /// + //******************************************* + template + ETL_CONSTEXPR14 value_type& emplace(std::initializer_list& il, Args&&... args) ETL_NOEXCEPT + { + storage.emplace(il, args...); + } + + //******************************************* + /// + //******************************************* + value_type* operator ->() + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); +#endif + + return etl::addressof(storage.get()); + } + + //******************************************* + /// + //******************************************* + const value_type* operator ->() const + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); +#endif + + return etl::addressof(storage.get()); + } + + //******************************************* + /// + //******************************************* + value_type& operator *() + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); +#endif + + return storage.get(); + } + + //******************************************* + /// + //******************************************* + const value_type& operator *() const + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); +#endif + + return storage.get(); + } + + private: + + enum + { + Uninitialised, + Value_Type, + Error_Type + }; + + using storage_type = etl::variant; + storage_type storage; + }; + + //***************************************************************************** + /// Specialisation for void value type. + //***************************************************************************** + template + class expected + { + public: + + typedef etl::expected this_type; + typedef void value_type; + typedef TError error_type; + typedef etl::unexpected unexpected_type; + + //******************************************* + /// Default constructor + //******************************************* + ETL_CONSTEXPR14 + expected() + { + } + + //******************************************* + /// Copy construct from unexpected + //******************************************* + ETL_CONSTEXPR14 + expected(const unexpected_type& ue_) + : storage(ue_.error()) + { + } + + //******************************************* + /// Move construct from unexpected + //******************************************* + ETL_CONSTEXPR14 + expected(unexpected_type&& ue_) + : storage(etl::move(ue_.error())) + { + } + + //******************************************* + /// Copy construct + //******************************************* + ETL_CONSTEXPR14 + expected(const this_type& other) + : storage(other.storage) + { + } + + //******************************************* + /// Move construct + //******************************************* + ETL_CONSTEXPR14 + expected(this_type&& other) + : storage(etl::move(other.storage)) + { + } + + //******************************************* + /// Copy assign + //******************************************* + this_type& operator =(const this_type& other) + { + ETL_STATIC_ASSERT(etl::is_copy_constructible::value, "Not copy assignable"); + + storage = other.storage; + return *this; + } + + //******************************************* + /// Move assign + //******************************************* + this_type& operator =(this_type&& other) + { + ETL_STATIC_ASSERT(etl::is_move_constructible::value, "Not move assignable"); + + storage = etl::move(other.storage); + return *this; + } + + //******************************************* + /// Copy assign from error + //******************************************* + expected& operator =(const unexpected_type& error) + { + ETL_STATIC_ASSERT(etl::is_copy_constructible::value, "Error not copy assignable"); + + storage.emplace(error); + return *this; + } + + //******************************************* + /// Move assign from error + //******************************************* + expected& operator =(unexpected_type&& error) + { + ETL_STATIC_ASSERT(etl::is_move_constructible::value, "Error not move assignable"); + + storage.emplace(etl::move(error)); + return *this; + } + + //******************************************* + /// Returns true if expected has a value + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + bool has_value() const + { + return (storage.index() != Error_Type); + } + + //******************************************* + /// Returns true if expected has a value + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + operator bool() const + { + return has_value(); + } + + //******************************************* + /// Returns the error + /// Undefined behaviour if an error has not been set. + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + error_type& error()& ETL_NOEXCEPT + { + return etl::get(storage); + } + + //******************************************* + /// Returns the error + /// Undefined behaviour if an error has not been set. + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + const error_type& error() const& ETL_NOEXCEPT + { + return etl::get(storage); + } + + //******************************************* + /// Returns the error + /// Undefined behaviour if an error has not been set. + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + error_type&& error() && ETL_NOEXCEPT + { + return etl::move(etl::get(storage)); + } + + //******************************************* + /// Returns the error + /// Undefined behaviour if an error has not been set. + //******************************************* + ETL_NODISCARD + ETL_CONSTEXPR14 + const error_type&& error() const&& ETL_NOEXCEPT + { + return etl::move(etl::get(storage)); + } + + private: + + enum + { + Uninitialised, + Error_Type + }; + + etl::variant storage; + }; } //******************************************* @@ -286,22 +862,6 @@ void swap(etl::unexpected& lhs, etl::unexpected& rhs) lhs.swap(rhs); } -//***************************************************************************** -/// unexpect_t -//***************************************************************************** -struct unexpect_t -{ - ETL_CONSTEXPR14 explicit unexpect_t() - { - } -}; - -#if ETL_CPP17_SUPPORTED -inline constexpr unexpect_t unexpect{}; -#else -static const unexpect_t unexpect; -#endif - #endif //******************************************* /// Equivalence operator. diff --git a/include/etl/private/variant_variadic.h b/include/etl/private/variant_variadic.h index fe003364..5d344b5c 100644 --- a/include/etl/private/variant_variadic.h +++ b/include/etl/private/variant_variadic.h @@ -227,7 +227,7 @@ namespace etl default: { // This should never occur. - #if defined(ETL_IN_UNIT_TEST) + #if defined(ETL_DEBUG) assert(false); #endif break; diff --git a/include/etl/result.h b/include/etl/result.h index 0335132e..0ddf637a 100644 --- a/include/etl/result.h +++ b/include/etl/result.h @@ -54,6 +54,9 @@ namespace etl { public: + typedef TValue value_type; + typedef TError error_type; + //******************************************* /// Cannot be default constructed //******************************************* @@ -245,6 +248,9 @@ namespace etl { public: + typedef void value_type; + typedef TError error_type; + //******************************************* /// Default Constructor //******************************************* @@ -280,8 +286,8 @@ namespace etl /// Move construct from error //******************************************* #if ETL_CPP11_SUPPORTED - result(TError&& err_) - : err(etl::move(err_)) + result(TError&& error) + : data(etl::move(error)) { } #endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 58ecbda4..cf1df999 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -102,6 +102,7 @@ add_executable(etl_tests test_error_handler.cpp test_etl_traits.cpp test_exception.cpp + test_expected.cpp test_fixed_iterator.cpp test_fixed_sized_memory_block_allocator.cpp test_flags.cpp diff --git a/test/sanity-check/c++03/CMakeLists.txt b/test/sanity-check/c++03/CMakeLists.txt index 40b4aa96..863f49cd 100644 --- a/test/sanity-check/c++03/CMakeLists.txt +++ b/test/sanity-check/c++03/CMakeLists.txt @@ -129,6 +129,7 @@ target_sources(t98 PRIVATE etl_profile.h ../enum_type.h.t.cpp ../error_handler.h.t.cpp ../exception.h.t.cpp + ../expected.h.t.cpp ../factorial.h.t.cpp ../fibonacci.h.t.cpp ../file_error_numbers.h.t.cpp diff --git a/test/sanity-check/c++11/CMakeLists.txt b/test/sanity-check/c++11/CMakeLists.txt index c08b6f51..65687b9a 100644 --- a/test/sanity-check/c++11/CMakeLists.txt +++ b/test/sanity-check/c++11/CMakeLists.txt @@ -129,6 +129,7 @@ target_sources(t11 PRIVATE etl_profile.h ../enum_type.h.t.cpp ../error_handler.h.t.cpp ../exception.h.t.cpp + ../expected.h.t.cpp ../factorial.h.t.cpp ../fibonacci.h.t.cpp ../file_error_numbers.h.t.cpp diff --git a/test/sanity-check/c++14/CMakeLists.txt b/test/sanity-check/c++14/CMakeLists.txt index f4a7d101..a0462555 100644 --- a/test/sanity-check/c++14/CMakeLists.txt +++ b/test/sanity-check/c++14/CMakeLists.txt @@ -129,6 +129,7 @@ target_sources(t14 PRIVATE etl_profile.h ../enum_type.h.t.cpp ../error_handler.h.t.cpp ../exception.h.t.cpp + ../expected.h.t.cpp ../factorial.h.t.cpp ../fibonacci.h.t.cpp ../file_error_numbers.h.t.cpp diff --git a/test/sanity-check/c++17/CMakeLists.txt b/test/sanity-check/c++17/CMakeLists.txt index 3f3ad303..abaabd55 100644 --- a/test/sanity-check/c++17/CMakeLists.txt +++ b/test/sanity-check/c++17/CMakeLists.txt @@ -129,6 +129,7 @@ target_sources(t17 PRIVATE etl_profile.h ../enum_type.h.t.cpp ../error_handler.h.t.cpp ../exception.h.t.cpp + ../expected.h.t.cpp ../factorial.h.t.cpp ../fibonacci.h.t.cpp ../file_error_numbers.h.t.cpp diff --git a/test/sanity-check/expected.h.t.cpp b/test/sanity-check/expected.h.t.cpp new file mode 100644 index 00000000..2fca92c3 --- /dev/null +++ b/test/sanity-check/expected.h.t.cpp @@ -0,0 +1,29 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2023 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include diff --git a/test/test_expected.cpp b/test/test_expected.cpp new file mode 100644 index 00000000..3f67f6f8 --- /dev/null +++ b/test/test_expected.cpp @@ -0,0 +1,446 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2022 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include "unit_test_framework.h" + +#include "etl/expected.h" +#include "etl/type_traits.h" + +#include +#include + +namespace +{ + struct Value + { + std::string v; + + Value() + { + } + + Value(const std::string v_) + : v(v_) + { + } + + operator std::string() const + { + return v; + } + }; + + struct ValueM + { + ValueM() + { + } + + ValueM(const std::string& v_) + : v(v_) + { + } + + ValueM(ValueM&&) = default; + ValueM& operator =(ValueM&&) = default; + + ValueM(const ValueM&) = delete; + ValueM& operator =(const ValueM&) = delete; + + std::string v; + }; + + struct Error + { + std::string e; + + Error() = default; + Error(const Error&) = default; + Error& operator =(const Error&) = default; + + Error(const std::string e_) + : e(e_) + { + } + + Error& operator =(const std::string e_) + { + e = e_; + } + + operator std::string() const + { + return e; + } + }; + + struct ErrorM + { + ErrorM() + { + } + + ErrorM(const std::string& e_) + : e(e_) + { + } + + ErrorM(ErrorM&&) = default; + ErrorM& operator =(ErrorM&&) = default; + + ErrorM(const ErrorM&) = delete; + ErrorM& operator =(const ErrorM&) = delete; + + std::string e; + }; + + using Expected = etl::expected; + using ExpectedV = etl::expected; + using ExpectedM = etl::expected; + using ExpectedVM = etl::expected; + + using Unexpected = etl::unexpected; + using UnexpectedV = etl::unexpected; + using UnexpectedM = etl::unexpected; +} + +namespace +{ + SUITE(test_result) + { + //************************************************************************* + TEST(test_default_constructor) + { + Expected expected; + + CHECK_TRUE(expected.has_value()); + CHECK_TRUE(bool(expected)); + } + + //************************************************************************* + TEST(test_constructor_for_result_with_value) + { + Value input = { "value 1" }; + Expected expected(input); + + Value output = expected.value(); + + CHECK_TRUE(expected.has_value()); + CHECK_TRUE(bool(expected)); + CHECK_TRUE(output.v == input.v); + } + + //************************************************************************* + TEST(test_constructor_for_const_result_with_value) + { + Value input = { "value 1" }; + const Expected expected(input); + + const Value& output = expected.value(); + + CHECK_TRUE(expected.has_value()); + CHECK_TRUE(bool(expected)); + CHECK_TRUE(output.v == input.v); + } + + //************************************************************************* + TEST(test_constructor_for_moveable_result_with_value) + { + ValueM input = { "value 1" }; + ExpectedM expected(etl::move(input)); + + ValueM output = etl::move(expected.value()); + + CHECK_TRUE(expected.has_value()); + CHECK_TRUE(bool(expected)); + CHECK_TRUE(output.v == std::string("value 1")); + } + + //************************************************************************* + TEST(test_constructor_for_result_with_error) + { + Error input = { "error 1" }; + Unexpected unexpected(input); + Expected expected(unexpected); + + Error output = expected.error(); + + CHECK_FALSE(expected.has_value()); + CHECK_FALSE(bool(expected)); + CHECK(output.e == input.e); + } + + //************************************************************************* + TEST(test_constructor_for_const_result_with_error) + { + const Error input = { "error 1" }; + const Unexpected unexpected(input); + const Expected expected(unexpected); + + const Error& output = expected.error(); + + CHECK_FALSE(expected.has_value()); + CHECK_FALSE(bool(expected)); + CHECK(output.e == input.e); + } + + //************************************************************************* + TEST(test_constructor_for_moveable_result_with_error) + { + ErrorM input = { "error 1" }; + UnexpectedM unexpected(etl::move(input)); + ExpectedM expected(etl::move(unexpected)); + + ErrorM output = etl::move(expected.error()); + + CHECK_FALSE(expected.has_value()); + CHECK_FALSE(bool(expected)); + CHECK_TRUE(output.e == std::string("error 1")); + } + + //************************************************************************* + TEST(test_constructor_for_result_void_value_with_value) + { + ExpectedV expected; + + CHECK_TRUE(expected.has_value()); + CHECK_TRUE(bool(expected)); + } + + //************************************************************************* + TEST(test_constructor_for_const_result_void_value_with_value) + { + const ExpectedV expected; + + CHECK_TRUE(expected.has_value()); + CHECK_TRUE(bool(expected)); + } + + //************************************************************************* + TEST(test_constructor_for_result_void_value_with_error) + { + Error input = { "error 1" }; + UnexpectedV unexpected(input); + ExpectedV expected(unexpected); + + Error output = expected.error(); + + CHECK_FALSE(expected.has_value()); + CHECK_FALSE(bool(expected)); + CHECK_TRUE(output.e == input.e); + } + + //************************************************************************* + TEST(test_constructor_for_const_result_void_value_with_error) + { + const Error input = { "error 1" }; + const UnexpectedV unexpected(input); + const ExpectedV expected(unexpected); + + const Error& output = expected.error(); + + CHECK_FALSE(expected.has_value()); + CHECK_FALSE(bool(expected)); + CHECK_TRUE(output.e == input.e); + } + + //************************************************************************* + TEST(test_constructor_for_moveable_result_void_value_with_error) + { + ErrorM input = { "error 1" }; + UnexpectedM unexpected(etl::move(input)); + ExpectedM expected(etl::move(unexpected)); + + ErrorM output = etl::move(expected.error()); + + CHECK_FALSE(expected.has_value()); + CHECK_FALSE(bool(expected)); + CHECK(output.e == std::string("error 1")); + } + + //************************************************************************* + TEST(test_copy_construct) + { + Value input1 = { "value 1" }; + Expected expected1(input1); + Expected expected2(expected1); + + Value output1 = expected2.value(); + + CHECK_TRUE(expected1.has_value()); + CHECK_TRUE(expected2.has_value()); + CHECK(output1.v == input1.v); + } + + //************************************************************************* + TEST(test_copy_assign) + { + Value input1 = { "value 1" }; + Expected expected1(input1); + + Value input2 = { "value 2" }; + Expected expected2(input2); + + expected2 = expected1; + + Value output1 = expected1.value(); + Value output2 = expected2.value(); + + CHECK_TRUE(expected1.has_value()); + CHECK_TRUE(expected2.has_value()); + + //CHECK(output1.v != input1.v); + //CHECK(output2.v != input1.v); + + //CHECK(output1.v == input2.v); + //CHECK(output2.v == input2.v); + } + + //************************************************************************* + TEST(test_move_construct) + { + ValueM input1 = { "value 1" }; + ExpectedM expected1(etl::move(input1)); + ExpectedM expected2(etl::move(expected1)); + + ValueM output1 = etl::move(expected1.value()); + ValueM output2 = etl::move(expected2.value()); + + CHECK_TRUE(expected1.has_value()); + CHECK_TRUE(expected2.has_value()); + + CHECK_EQUAL("", output1.v); + CHECK_EQUAL("value 1", output2.v); + } + + //************************************************************************* + TEST(test_move_assign) + { + ValueM input1 = { "value 1" }; + ExpectedM expected1(etl::move(input1)); + + ValueM input2 = { "value 2" }; + ExpectedM expected2(etl::move(input2)); + + expected2 = etl::move(expected1); + + ValueM output1 = etl::move(expected1.value()); + ValueM output2 = etl::move(expected2.value()); + + CHECK_TRUE(expected1.has_value()); + CHECK_TRUE(expected2.has_value()); + + CHECK_EQUAL("", output1.v); + CHECK_EQUAL("value 1", output2.v); + } + + //************************************************************************* + TEST(test_copy_construct_void_value) + { + Error input1 = { "error 1" }; + UnexpectedV unexpected1(input1); + ExpectedV expected1(unexpected1); + ExpectedV expected2(expected1); + + CHECK_FALSE(expected1.has_value()); + CHECK_FALSE(expected2.has_value()); + + Error output1 = expected1.error(); + Error output2 = expected2.error(); + + CHECK_EQUAL(input1.e, output1.e); + CHECK_EQUAL(input1.e, output2.e); + } + + //************************************************************************* + TEST(test_copy_assign_void_value) + { + Error input1 = { "error 1" }; + UnexpectedV unexpected1(input1); + + Error input2 = { "error 2" }; + UnexpectedV unexpected2(input2); + + ExpectedV expected1(unexpected1); + ExpectedV expected2(unexpected2); + + expected2 = expected1; + + Error output1 = expected1.error(); + Error output2 = expected2.error(); + + CHECK_FALSE(expected1.has_value()); + CHECK_FALSE(expected2.has_value()); + + CHECK_EQUAL(input1.e, output1.e); + CHECK_EQUAL(input1.e, output2.e); + } + + //************************************************************************* + TEST(test_move_construct_void_value) + { + ErrorM input1 = { "error 1" }; + UnexpectedM unexpected1(etl::move(input1)); + ExpectedVM expected1(etl::move(unexpected1)); + ExpectedVM expected2(etl::move(expected1)); + + ErrorM output1 = etl::move(expected1.error()); + ErrorM output2 = etl::move(expected2.error()); + + CHECK_FALSE(expected1.has_value()); + CHECK_FALSE(expected2.has_value()); + + CHECK_EQUAL("", output1.e); + CHECK_EQUAL("error 1", output2.e); + } + + //************************************************************************* + TEST(test_move_assign_void_value) + { + ErrorM input1 = { "error 1" }; + UnexpectedM unexpected1(etl::move(input1)); + + ErrorM input2 = { "error 2" }; + UnexpectedM unexpected2(etl::move(input2)); + + ExpectedVM expected1(etl::move(unexpected1)); + ExpectedVM expected2(etl::move(unexpected2)); + + expected2 = etl::move(expected1); + + ErrorM output1 = etl::move(expected1.error()); + ErrorM output2 = etl::move(expected2.error()); + + CHECK_FALSE(expected1.has_value()); + CHECK_FALSE(expected2.has_value()); + + CHECK_EQUAL("", output1.e); + CHECK_EQUAL("error 1", output2.e); + } + }; +} diff --git a/test/test_result.cpp b/test/test_result.cpp index 4fbb72bd..e2af3556 100644 --- a/test/test_result.cpp +++ b/test/test_result.cpp @@ -5,7 +5,7 @@ Embedded Template Library. https://github.com/ETLCPP/etl https://www.etlcpp.com -Copyright(c) 2017 John Wellbelove +Copyright(c) 2022 John Wellbelove Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal @@ -91,55 +91,6 @@ namespace using ResultM = etl::result; } -// Definitions for when the STL and compiler built-ins are not available. -#if ETL_NOT_USING_STL && !defined(ETL_USE_TYPE_TRAITS_BUILTINS) - -using etl::is_copy_constructible; -using etl::is_move_constructible; - -//************************* -template <> -struct etl::is_copy_constructible : public etl::true_type -{ -}; - -template <> -struct etl::is_move_constructible : public etl::true_type -{ -}; - -template <> -struct etl::is_copy_constructible : public etl::true_type -{ -}; - -template <> -struct etl::is_move_constructible : public etl::true_type -{ -}; - -//************************* -template <> -struct etl::is_copy_constructible : public etl::false_type -{ -}; - -template <> -struct etl::is_move_constructible : public etl::false_type -{ -}; - -template <> -struct etl::is_copy_constructible : public etl::false_type -{ -}; - -template <> -struct etl::is_move_constructible : public etl::false_type -{ -}; -#endif - namespace { SUITE(test_result) diff --git a/test/vs2019/etl.vcxproj b/test/vs2019/etl.vcxproj index c855b06b..a88a56dc 100644 --- a/test/vs2019/etl.vcxproj +++ b/test/vs2019/etl.vcxproj @@ -5630,6 +5630,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 + true true @@ -11381,6 +11409,7 @@ + diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index bd2769ba..693b2073 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -2231,9 +2231,6 @@ Tests\Misc - - Tests\Misc - Tests\Misc @@ -3395,6 +3392,15 @@ Tests\Misc + + Tests\Containers + + + Tests\Containers + + + Tests\Sanity Checks\Source + From a08d7f14dc5edc07aa4e037a0f57e188c7fab20c Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 7 Feb 2023 10:55:16 +0100 Subject: [PATCH 41/60] Fixed span templated copy constructor --- include/etl/span.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/etl/span.h b/include/etl/span.h index 32f27106..d28c06b0 100644 --- a/include/etl/span.h +++ b/include/etl/span.h @@ -604,8 +604,8 @@ namespace etl //************************************************************************* template ETL_CONSTEXPR span(const etl::span& other) ETL_NOEXCEPT - : pbegin(other.begin()) - , pend(other.begin() + N) + : pbegin(other.pbegin) + , pend(other.pend) { } From 1d12a861148e867b260cfbc3fb9c9cd1eb4d88ef Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 8 Feb 2023 16:40:15 +0100 Subject: [PATCH 42/60] Work in progress --- include/etl/expected.h | 384 ----------------------------------------- test/test_expected.cpp | 1 + 2 files changed, 1 insertion(+), 384 deletions(-) diff --git a/include/etl/expected.h b/include/etl/expected.h index f2a91997..2c1b96ef 100644 --- a/include/etl/expected.h +++ b/include/etl/expected.h @@ -240,7 +240,6 @@ namespace etl TError error_value; }; -#if ETL_USING_CPP17 template bool operator ==(const etl::unexpected& lhs, const etl::unexpected& rhs) { @@ -265,7 +264,6 @@ namespace etl { } }; -#endif #if ETL_USING_CPP17 inline constexpr unexpect_t unexpect{}; @@ -863,385 +861,3 @@ void swap(etl::unexpected& lhs, etl::unexpected& rhs) } #endif - //******************************************* - /// Equivalence operator. - //******************************************* - template - bool operator ==(const etl::unexpected& lhs, const etl::unexpected& rhs) - { - return lhs.error_value == rhs.error_value; - } - - //******************************************* - /// Swap etl::unexpected. - //******************************************* - template - void swap(etl::unexpected& lhs, etl::unexpected& rhs) - { - lhs.swap(rhs); - } - - //***************************************************************************** - /// unexpect_t - //***************************************************************************** - struct unexpect_t - { - ETL_CONSTEXPR14 explicit unexpect_t() - { - } - }; - -#if ETL_CPP14_SUPPORTED - inline ETL_CONSTEXPR14 unexpect_t unexpect{}; -#endif - - //***************************************************************************** - /// Expected type. - //***************************************************************************** - template - class expected - { - public: - - typename TValue value_type; - typename TError error_type; - typename etl::unexpected unexpected_type; - -#if ETL_CPP11_SUPPORTED - template - using rebind = etl::expected; -#endif - - //******************************************* - /// Default constructor - //******************************************* - ETL_CONSTEXPR14 expected() ETL_NOEXCEPT - : data(TValue()) - { - } - - //******************************************* - /// Copy constructor - //******************************************* - ETL_CONSTEXPR14 expected(const expected& other) ETL_NOEXCEPT - : data(other.data) - { - } - -#if ETL_CPP11_SUPPORTED - //******************************************* - /// Move constructor - //******************************************* - ETL_CONSTEXPR14 expected(expected&& other) ETL_NOEXCEPT - : data(etl::move(other.data)) - { - } -#endif - - template - ETL_CONSTEXPR14 explicit expected(const etl::unexpected& ue) - : data(ue) - { - } - -#if ETL_CPP11_SUPPORTED - template - ETL_CONSTEXPR14 explicit expected(etl::unexpected&& ue) - : data(etl::move(ue)) - { - } -#endif - - ETL_CONSTEXPR14 explicit expected(etl::in_place_t) ETL_NOEXCEPT - : data(TValue()) - { - } - - template - ETL_CONSTEXPR14 explicit expected(etl::in_place_t, Args&&... args) - : data(etl::forward(args)...) - { - } - - template - ETL_CONSTEXPR14 explicit expected(etl::in_place_t, std::initializer_list il, Args&&... args) - : data(il, etl::forward(args)...) - { - } - - template - ETL_CONSTEXPR14 explicit expected(etl::unexpect_t, Args&&... args) - : data(etl::unexpected(args...)) - { - } - - template - ETL_CONSTEXPR14 explicit expected(etl::unexpect_t, std::initializer_list il, Args&&... args) - : data(etl::unexpected(il, args...)) - { - } - - //******************************************* - /// Copy assign from value - //******************************************* - expected& operator =(const TValue& value) - { - data = value; - return *this; - } - - //******************************************* - /// Move assign from value - //******************************************* - expected& operator =(TValue&& value) - { - data = etl::move(value); - return *this; - } - - //******************************************* - /// Copy assign from error - //******************************************* - expected& operator =(const TError& error) - { - data = error; - return *this; - } - - //******************************************* - /// Move assign from error - //******************************************* - expected& operator =(TError&& error) - { - data = etl::move(error); - return *this; - } - -#if ETL_CPP11_SUPPORTED - //******************************************* - /// - //******************************************* - ETL_CONSTEXPR14 T& value() & - { - return etl::get(data); - } - - //******************************************* - /// - //******************************************* - ETL_CONSTEXPR14 const T& value() const& - { - return etl::get(data); - } - - //******************************************* - /// - //******************************************* - ETL_CONSTEXPR14 T&& value() && - { - return etl::move(etl::get(data)); - } - - //******************************************* - /// - //******************************************* - ETL_CONSTEXPR14 const T&& value() const&& - { - return etl::move(etl::get(data)); - } -#else - //******************************************* - /// Returns a const reference to the value. - /// Undefined if the expected does not contain an value. - //******************************************* - ETL_CONSTEXPR14 const TValue& value() const - { - return etl::get(data); - } -#endif - -#if ETL_CPP11_SUPPORTED - //******************************************* - /// - //******************************************* - template - ETL_CONSTEXPR14 TValue value_or(U&& default_value) const& - { - if (has_value()) - { - return value(); - } - else - { - return default_value; - } - } - - //******************************************* - /// - //******************************************* - template - ETL_CONSTEXPR14 TValue value_or(U&& default_value) && - { - if (has_value()) - { - return etl::move(value()); - } - else - { - return etl::move(default_value); - } - } -#else - //******************************************* - /// - //******************************************* - template - TValue value_or(const U& default_value) const - { - if (has_value()) - { - return value(); - } - else - { - return default_value; - } - } -#endif - -#if ETL_CPP11_SUPPORTED - //******************************************* - /// - //******************************************* - ETL_CONSTEXPR14 const TError& error() const& ETL_NOEXCEPT - { - return etl::get(data); - } - - //******************************************* - /// - //******************************************* - ETL_CONSTEXPR14 TError& error() & ETL_NOEXCEPT - { - return etl::get(data); - } - - //******************************************* - /// - //******************************************* - ETL_CONSTEXPR14 const TError&& error() const&& ETL_NOEXCEPT - { - return etl::move(etl::get(data)); - } - - //******************************************* - /// - //******************************************* - ETL_CONSTEXPR14 TError&& error() && ETL_NOEXCEPT - { - return etl::move(etl::get(data)); - } -#else - //******************************************* - /// Returns a const reference to the error. - /// Undefined if the expected does not contain an error. - //******************************************* - ETL_CONSTEXPR14 const TError& error() const - { - return etl::get(data); - } -#endif - -#if ETL_CPP11_SUPPORTED - //******************************************* - /// - //******************************************* - template - ETL_CONSTEXPR14 T& emplace(Args&&... args) ETL_NOEXCEPT - { - data.emplace(args...); - } - - //******************************************* - /// - //******************************************* - template - ETL_CONSTEXPR14 T& emplace(std::initializer_list& il, Args&&... args) ETL_NOEXCEPT - { - data.emplace(il, args...); - } -#endif - - //******************************************* - /// - //******************************************* - TValue* operator ->() - { -#if ETL_IS_DEBUG_BUILD - ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); -#endif - - return etl::addressof(data.get()); - } - - //******************************************* - /// - //******************************************* - const TValue* operator ->() const - { -#if ETL_IS_DEBUG_BUILD - ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); -#endif - - return etl::addressof(data.get()); - } - - //******************************************* - /// - //******************************************* - TValue& operator *() - { -#if ETL_IS_DEBUG_BUILD - ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); -#endif - - return data.get(); - } - - //******************************************* - /// - //******************************************* - const TValue& operator *() const - { -#if ETL_IS_DEBUG_BUILD - ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); -#endif - - return data.get(); - } - - private: - - etl::variant data; - }; - - //***************************************************************************** - /// Specialisation for void value type. - //***************************************************************************** - template - class expected - { - public: - - - - private: - - TError error; - }; -} - - -#endif - diff --git a/test/test_expected.cpp b/test/test_expected.cpp index 3f67f6f8..3e43e04c 100644 --- a/test/test_expected.cpp +++ b/test/test_expected.cpp @@ -185,6 +185,7 @@ namespace TEST(test_constructor_for_result_with_error) { Error input = { "error 1" }; + Unexpected unexpected(input); Expected expected(unexpected); From e3e12ef731b6dd54b0e0b3aad97b224623cd66d9 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 8 Feb 2023 18:49:41 +0100 Subject: [PATCH 43/60] Work in progress --- include/etl/expected.h | 73 +++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 43 deletions(-) diff --git a/include/etl/expected.h b/include/etl/expected.h index 2c1b96ef..013d97d2 100644 --- a/include/etl/expected.h +++ b/include/etl/expected.h @@ -117,19 +117,20 @@ namespace etl //******************************************* /// Construct from argument. //******************************************* - template ::type, etl::unexpected>::value && + template ::type, unexpected>::value && !etl::is_same::type, etl::in_place_t>::value, int>::type> constexpr explicit unexpected(TErr&& e) : error_value(etl::forward(e)) { } + #else //******************************************* /// Construct from argument. //******************************************* template - explicit unexpected(const TErr& e, typename etl::enable_if::type, etl::unexpected>::value && - !etl::is_same::type, etl::in_place_t>::value, int>::type = 0) + explicit unexpected(const TErr& e, typename = typename etl::enable_if::type, unexpected>::value && + !etl::is_same::type, etl::in_place_t>::value, int>::type = 0) : error_value(e) { } @@ -161,7 +162,7 @@ namespace etl /// Assign from etl::unexpected. //******************************************* ETL_CONSTEXPR14 - etl::unexpected& operator =(const etl::unexpected& rhs) + etl::unexpected& operator =(const etl::unexpected& rhs) { ETL_STATIC_ASSERT(etl::is_copy_constructible::value, "Error not copy assignable"); @@ -174,7 +175,7 @@ namespace etl /// Move assign from etl::unexpected. //******************************************* ETL_CONSTEXPR14 - etl::unexpected& operator =(etl::unexpected&& rhs) + etl::unexpected& operator =(etl::unexpected&& rhs) { ETL_STATIC_ASSERT(etl::is_move_constructible::value, "Error not move assignable"); @@ -211,7 +212,7 @@ namespace etl //******************************************* /// Get the error. //******************************************* - constexpr TError&& error() const && noexcept + constexpr TError&& error() const&& noexcept { return etl::move(error_value); } @@ -240,25 +241,10 @@ namespace etl TError error_value; }; - template - bool operator ==(const etl::unexpected& lhs, const etl::unexpected& rhs) - { - return lhs.error_value == rhs.error_value; - } - - //******************************************* - /// Swap etl::unexpected. - //******************************************* - template - void swap(etl::unexpected& lhs, etl::unexpected& rhs) - { - lhs.swap(rhs); - } - //***************************************************************************** /// unexpect_t //***************************************************************************** - struct unexpect_t + struct unexpect_t { ETL_CONSTEXPR14 explicit unexpect_t() { @@ -492,7 +478,7 @@ namespace etl /// //******************************************* ETL_NODISCARD - ETL_CONSTEXPR14 + ETL_CONSTEXPR14 bool has_value() const { return (storage.index() == Value_Type); @@ -502,7 +488,7 @@ namespace etl /// //******************************************* ETL_NODISCARD - ETL_CONSTEXPR14 + ETL_CONSTEXPR14 operator bool() const { return has_value(); @@ -513,7 +499,7 @@ namespace etl //******************************************* template ETL_NODISCARD - ETL_CONSTEXPR14 + ETL_CONSTEXPR14 value_type value_or(U&& default_value) const& { if (has_value()) @@ -548,7 +534,7 @@ namespace etl /// //******************************************* ETL_NODISCARD - ETL_CONSTEXPR14 + ETL_CONSTEXPR14 error_type& error()& ETL_NOEXCEPT { return etl::get(storage); @@ -671,16 +657,16 @@ namespace etl { public: - typedef etl::expected this_type; + typedef etl::expected this_type; typedef void value_type; typedef TError error_type; typedef etl::unexpected unexpected_type; - + //******************************************* /// Default constructor //******************************************* ETL_CONSTEXPR14 - expected() + expected() { } @@ -688,7 +674,7 @@ namespace etl /// Copy construct from unexpected //******************************************* ETL_CONSTEXPR14 - expected(const unexpected_type& ue_) + expected(const unexpected_type& ue_) : storage(ue_.error()) { } @@ -697,7 +683,7 @@ namespace etl /// Move construct from unexpected //******************************************* ETL_CONSTEXPR14 - expected(unexpected_type&& ue_) + expected(unexpected_type&& ue_) : storage(etl::move(ue_.error())) { } @@ -768,8 +754,8 @@ namespace etl /// Returns true if expected has a value //******************************************* ETL_NODISCARD - ETL_CONSTEXPR14 - bool has_value() const + ETL_CONSTEXPR14 + bool has_value() const { return (storage.index() != Error_Type); } @@ -778,8 +764,8 @@ namespace etl /// Returns true if expected has a value //******************************************* ETL_NODISCARD - ETL_CONSTEXPR14 - operator bool() const + ETL_CONSTEXPR14 + operator bool() const { return has_value(); } @@ -789,8 +775,8 @@ namespace etl /// Undefined behaviour if an error has not been set. //******************************************* ETL_NODISCARD - ETL_CONSTEXPR14 - error_type& error()& ETL_NOEXCEPT + ETL_CONSTEXPR14 + error_type& error()& ETL_NOEXCEPT { return etl::get(storage); } @@ -800,8 +786,8 @@ namespace etl /// Undefined behaviour if an error has not been set. //******************************************* ETL_NODISCARD - ETL_CONSTEXPR14 - const error_type& error() const& ETL_NOEXCEPT + ETL_CONSTEXPR14 + const error_type& error() const& ETL_NOEXCEPT { return etl::get(storage); } @@ -811,8 +797,8 @@ namespace etl /// Undefined behaviour if an error has not been set. //******************************************* ETL_NODISCARD - ETL_CONSTEXPR14 - error_type&& error() && ETL_NOEXCEPT + ETL_CONSTEXPR14 + error_type&& error() && ETL_NOEXCEPT { return etl::move(etl::get(storage)); } @@ -822,8 +808,8 @@ namespace etl /// Undefined behaviour if an error has not been set. //******************************************* ETL_NODISCARD - ETL_CONSTEXPR14 - const error_type&& error() const&& ETL_NOEXCEPT + ETL_CONSTEXPR14 + const error_type&& error() const&& ETL_NOEXCEPT { return etl::move(etl::get(storage)); } @@ -861,3 +847,4 @@ void swap(etl::unexpected& lhs, etl::unexpected& rhs) } #endif + From d6a5a359100d956b4f468fb278ad0f85ac5ca5cb Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 8 Feb 2023 20:27:36 +0100 Subject: [PATCH 44/60] Fixed etl::result merge issues --- include/etl/result.h | 119 +------------------------------------------ 1 file changed, 2 insertions(+), 117 deletions(-) diff --git a/include/etl/result.h b/include/etl/result.h index 2b8e0ae1..266cf7c8 100644 --- a/include/etl/result.h +++ b/include/etl/result.h @@ -91,7 +91,7 @@ namespace etl //******************************************* // Move construct from a value //******************************************* - result(TValue&& value) + result(TValue&& value) : data(etl::move(value)) { } @@ -470,125 +470,10 @@ namespace etl } #endif - private: - - etl::optional data; - }; - - //***************************************************************************** - /// Result type. - /// Specialisation for void error type. - //***************************************************************************** - template - class result - { - public: - - //******************************************* - /// Default Constructor - //******************************************* - result() - { - } - - //******************************************* - /// Copy constructor - //******************************************* - result(const result& other) - : data(other.data) - { - } - - //******************************************* - /// Move constructor - //******************************************* - result(result&& other) - : data(etl::move(other.data)) - { - } - - //******************************************* - /// Construct from error - //******************************************* - result(const TValue& value) - : data(value) - { - } - - //******************************************* - /// Move construct from error - //******************************************* - result(TValue&& value) - : data(etl::move(value)) - { - } - - //******************************************* - /// Copy assign from error - //******************************************* - result& operator =(const TValue& value) - { - data = value; - return *this; - } - - //******************************************* - /// Move assign from error - //******************************************* - result& operator =(TValue&& value) - { - data = etl::move(value); - return *this; - } - - //******************************************* - /// true if result contains a value - //******************************************* - bool has_value() const - { - return data.has_value(); - } - - //******************************************* - /// true if result contains a value - //******************************************* - bool is_value() const - { - return has_value(); - } - - //******************************************* - /// true if result contains an error - //******************************************* - bool is_error() const - { - return !has_value(); - } - - //******************************************* - /// Returns a const reference to the error. - /// Undefined if the result does not contain an error. - //******************************************* - const TValue& value() const - { - return data.value(); - } - - //******************************************* - /// Returns an rvalue reference to the error. - /// Undefined if the result does not contain an error. - //******************************************* - TValue&& value() - { - return etl::move(data.value()); - } -#endif - private: etl::optional data; }; } -#endif -#endif +#endif \ No newline at end of file From a1ce449d83e03716492d5414e206a85f17458a0d Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 9 Feb 2023 14:22:14 +0100 Subject: [PATCH 45/60] C++03 compatibility changes --- include/etl/expected.h | 129 +++++++++++++++++++++------ include/etl/private/variant_legacy.h | 8 ++ test/test_expected.cpp | 1 + 3 files changed, 110 insertions(+), 28 deletions(-) diff --git a/include/etl/expected.h b/include/etl/expected.h index 013d97d2..4ac7259a 100644 --- a/include/etl/expected.h +++ b/include/etl/expected.h @@ -129,8 +129,8 @@ namespace etl /// Construct from argument. //******************************************* template - explicit unexpected(const TErr& e, typename = typename etl::enable_if::type, unexpected>::value && - !etl::is_same::type, etl::in_place_t>::value, int>::type = 0) + explicit unexpected(const TErr& e, typename etl::enable_if::type, unexpected>::value && + !etl::is_same::type, etl::in_place_t>::value, int>::type = 0) : error_value(e) { } @@ -188,7 +188,7 @@ namespace etl //******************************************* /// Get the error. //******************************************* - constexpr TError& error() & noexcept + TError& error() & noexcept { return error_value; } @@ -204,7 +204,7 @@ namespace etl //******************************************* /// Get the error. //******************************************* - constexpr TError&& error() && noexcept + TError&& error() && noexcept { return etl::move(error_value); } @@ -270,14 +270,16 @@ namespace etl typedef TError error_type; typedef etl::unexpected unexpected_type; +#if ETL_USING_CPP11 template using rebind = expected; +#endif //******************************************* /// Default constructor //******************************************* ETL_CONSTEXPR14 expected() ETL_NOEXCEPT - : storage(etl::in_place_index, value_type()) + : storage(etl::in_place_index_t(), value_type()) { } @@ -285,17 +287,19 @@ namespace etl /// Constructor //******************************************* ETL_CONSTEXPR14 expected(const value_type& value_) ETL_NOEXCEPT - : storage(etl::in_place_index, value_) + : storage(etl::in_place_index_t(), value_) { } +#if ETL_USING_CPP11 //******************************************* /// Constructor //******************************************* ETL_CONSTEXPR14 expected(value_type&& value_) ETL_NOEXCEPT - : storage(etl::in_place_index, etl::move(value_)) + : storage(etl::in_place_index_t(), etl::move(value_)) { } +#endif //******************************************* /// Copy constructor @@ -305,6 +309,7 @@ namespace etl { } +#if ETL_USING_CPP11 //******************************************* /// Move constructor //******************************************* @@ -312,24 +317,27 @@ namespace etl : storage(etl::move(other.storage)) { } +#endif //******************************************* /// Copy construct from unexpected type. //******************************************* template ETL_CONSTEXPR14 explicit expected(const etl::unexpected& ue) - : storage(etl::in_place_index, ue.error()) + : storage(etl::in_place_index_t(), ue.error()) { } +#if ETL_USING_CPP11 //******************************************* /// Move construct from unexpected type. //******************************************* template ETL_CONSTEXPR14 explicit expected(etl::unexpected&& ue) - : storage(etl::in_place_index, etl::move(ue.error())) + : storage(etl::in_place_index_t(), etl::move(ue.error())) { } +#endif //******************************************* /// Construct with default value type. @@ -339,6 +347,7 @@ namespace etl { } +#if ETL_USING_CPP11 //******************************************* /// Construct value type from arguments. //******************************************* @@ -366,6 +375,7 @@ namespace etl { } +#if ETL_HAS_INITIALIZER_LIST //******************************************* /// Construct error type from initializser_list and arguments. //******************************************* @@ -374,6 +384,8 @@ namespace etl : storage(error_type(il, etl::forward(args)...)) { } +#endif +#endif //******************************************* /// @@ -387,6 +399,7 @@ namespace etl return *this; } +#if ETL_USING_CPP11 //******************************************* /// //******************************************* @@ -397,6 +410,7 @@ namespace etl storage = etl::move(other.storage); return *this; } +#endif //******************************************* /// Copy assign from value @@ -405,10 +419,11 @@ namespace etl { ETL_STATIC_ASSERT(etl::is_copy_constructible::value, "Value not copy assignable"); - storage.emplace(value); + storage.template emplace(value); return *this; } +#if ETL_USING_CPP11 //******************************************* /// Move assign from value //******************************************* @@ -416,9 +431,10 @@ namespace etl { ETL_STATIC_ASSERT(etl::is_move_constructible::value, "Value not move assignable"); - storage.emplace(etl::move(value)); + storage.template emplace(etl::move(value)); return *this; } +#endif //******************************************* /// Copy assign from error @@ -427,10 +443,11 @@ namespace etl { ETL_STATIC_ASSERT(etl::is_copy_constructible::value, "Error not copy assignable"); - storage.emplace(error); + storage.template emplace(error); return *this; } +#if ETL_USING_CPP11 //******************************************* /// Move assign from error //******************************************* @@ -438,12 +455,14 @@ namespace etl { ETL_STATIC_ASSERT(etl::is_move_constructible::value, "Error not move assignable"); - storage.emplace(etl::move(error)); + storage.template emplace(etl::move(error)); return *this; } +#endif +#if ETL_USING_CPP11 //******************************************* - /// + /// Get the value. //******************************************* ETL_CONSTEXPR14 value_type& value()& { @@ -451,7 +470,7 @@ namespace etl } //******************************************* - /// + /// Get the value. //******************************************* ETL_CONSTEXPR14 const value_type& value() const& { @@ -459,7 +478,7 @@ namespace etl } //******************************************* - /// + /// Get the value. //******************************************* ETL_CONSTEXPR14 value_type&& value()&& { @@ -467,12 +486,21 @@ namespace etl } //******************************************* - /// + /// Get the value. //******************************************* ETL_CONSTEXPR14 const value_type&& value() const&& { return etl::move(etl::get(storage)); } +#else + //******************************************* + /// Get the value. + //******************************************* + value_type& value() const + { + return etl::get(storage); + } +#endif //******************************************* /// @@ -494,6 +522,7 @@ namespace etl return has_value(); } +#if ETL_USING_CPP11 //******************************************* /// //******************************************* @@ -587,6 +616,31 @@ namespace etl { storage.emplace(il, args...); } +#else + //******************************************* + /// + //******************************************* + template + value_type value_or(const U& default_value) const + { + if (has_value()) + { + return value(); + } + else + { + return default_value; + } + } + + //******************************************* + /// + //******************************************* + error_type& error() const + { + return etl::get(storage); + } +#endif //******************************************* /// @@ -594,10 +648,10 @@ namespace etl value_type* operator ->() { #if ETL_IS_DEBUG_BUILD - ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); + ETL_ASSERT(storage.index() == Value_Type, ETL_ERROR(expected_invalid)); #endif - return etl::addressof(storage.get()); + return etl::addressof(etl::get(storage)); } //******************************************* @@ -606,10 +660,10 @@ namespace etl const value_type* operator ->() const { #if ETL_IS_DEBUG_BUILD - ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); + ETL_ASSERT(storage.index() == Value_Type, ETL_ERROR(expected_invalid)); #endif - return etl::addressof(storage.get()); + return etl::addressof(etl::get(storage)); } //******************************************* @@ -618,10 +672,10 @@ namespace etl value_type& operator *() { #if ETL_IS_DEBUG_BUILD - ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); + ETL_ASSERT(storage.index() == Value_Type, ETL_ERROR(expected_invalid)); #endif - return storage.get(); + return etl::get(storage); } //******************************************* @@ -630,10 +684,10 @@ namespace etl const value_type& operator *() const { #if ETL_IS_DEBUG_BUILD - ETL_ASSERT(valid, ETL_ERROR(expected_invalid)); + ETL_ASSERT(storage.index() == Value_Type, ETL_ERROR(expected_invalid)); #endif - return storage.get(); + return etl::get(storage); } private: @@ -645,7 +699,7 @@ namespace etl Error_Type }; - using storage_type = etl::variant; + typedef etl::variant storage_type; storage_type storage; }; @@ -679,6 +733,7 @@ namespace etl { } +#if ETL_USING_CPP11 //******************************************* /// Move construct from unexpected //******************************************* @@ -687,6 +742,7 @@ namespace etl : storage(etl::move(ue_.error())) { } +#endif //******************************************* /// Copy construct @@ -697,6 +753,7 @@ namespace etl { } +#if ETL_USING_CPP11 //******************************************* /// Move construct //******************************************* @@ -705,6 +762,7 @@ namespace etl : storage(etl::move(other.storage)) { } +#endif //******************************************* /// Copy assign @@ -717,6 +775,7 @@ namespace etl return *this; } +#if ETL_USING_CPP11 //******************************************* /// Move assign //******************************************* @@ -727,6 +786,7 @@ namespace etl storage = etl::move(other.storage); return *this; } +#endif //******************************************* /// Copy assign from error @@ -735,10 +795,11 @@ namespace etl { ETL_STATIC_ASSERT(etl::is_copy_constructible::value, "Error not copy assignable"); - storage.emplace(error); + storage.template emplace(error); return *this; } +#if ETL_USING_CPP11 //******************************************* /// Move assign from error //******************************************* @@ -746,9 +807,10 @@ namespace etl { ETL_STATIC_ASSERT(etl::is_move_constructible::value, "Error not move assignable"); - storage.emplace(etl::move(error)); + storage.template emplace(etl::move(error)); return *this; } +#endif //******************************************* /// Returns true if expected has a value @@ -770,6 +832,7 @@ namespace etl return has_value(); } +#if ETL_USING_CPP11 //******************************************* /// Returns the error /// Undefined behaviour if an error has not been set. @@ -813,6 +876,16 @@ namespace etl { return etl::move(etl::get(storage)); } +#else + //******************************************* + /// Returns the error + /// Undefined behaviour if an error has not been set. + //******************************************* + error_type& error() const + { + return etl::get(storage); + } +#endif private: diff --git a/include/etl/private/variant_legacy.h b/include/etl/private/variant_legacy.h index 09c1897b..a9d91a7c 100644 --- a/include/etl/private/variant_legacy.h +++ b/include/etl/private/variant_legacy.h @@ -71,6 +71,14 @@ namespace etl }; } + //*************************************************************************** + /// Monostate for variants. + ///\ingroup variant + //*************************************************************************** + struct monostate + { + }; + //*************************************************************************** /// Base exception for the variant class. ///\ingroup variant diff --git a/test/test_expected.cpp b/test/test_expected.cpp index 3e43e04c..b5a44db4 100644 --- a/test/test_expected.cpp +++ b/test/test_expected.cpp @@ -91,6 +91,7 @@ namespace Error& operator =(const std::string e_) { e = e_; + return *this; } operator std::string() const From 36a9d70d7cdabb71b84a4deee7c35bdc8b10a4a3 Mon Sep 17 00:00:00 2001 From: KurtisT Date: Thu, 9 Feb 2023 12:13:14 -0500 Subject: [PATCH 46/60] Feature/span equality operators (#670) * feat: implement equality operator * test: test equality operator * feat: implement not equal operator * test: test not equal operator --------- Co-authored-by: Kurtis Thrush --- include/etl/span.h | 36 +++++++++++++++++++++++++++++++ test/test_span_dynamic_extent.cpp | 28 ++++++++++++++++++++++++ test/test_span_fixed_extent.cpp | 28 ++++++++++++++++++++++++ 3 files changed, 92 insertions(+) diff --git a/include/etl/span.h b/include/etl/span.h index 32f27106..bfd7a4f4 100644 --- a/include/etl/span.h +++ b/include/etl/span.h @@ -345,6 +345,24 @@ namespace etl return pbegin[i]; } + //************************************************************************* + /// Compare two spans for equality. + //************************************************************************* + template , value_type>::value, bool> = true> + ETL_NODISCARD ETL_CONSTEXPR bool operator==(const etl::span& other) const ETL_NOEXCEPT + { + return ((pbegin == other.pbegin) && (Extent == other.size())); + } + + //************************************************************************* + /// Compare two spans for non-equality. + //************************************************************************* + template , value_type>::value, bool> = true> + ETL_NODISCARD ETL_CONSTEXPR bool operator!=(const etl::span& other) const ETL_NOEXCEPT + { + return !(*this == other); + } + //************************************************************************* /// Obtains a span that is a view over the first COUNT elements of this span. //************************************************************************* @@ -731,6 +749,24 @@ namespace etl return pbegin[i]; } + //************************************************************************* + /// Compare two spans for equality. + //************************************************************************* + template , value_type>::value, bool> = true> + ETL_NODISCARD ETL_CONSTEXPR bool operator==(const etl::span& other) const ETL_NOEXCEPT + { + return ((pbegin == other.pbegin) && (pend == other.pend)); + } + + //************************************************************************* + /// Compare two spans for non-equality. + //************************************************************************* + template , value_type>::value, bool> = true> + ETL_NODISCARD ETL_CONSTEXPR bool operator!=(const etl::span& other) const ETL_NOEXCEPT + { + return !(*this == other); + } + //************************************************************************* /// Obtains a span that is a view over the first COUNT elements of this span. //************************************************************************* diff --git a/test/test_span_dynamic_extent.cpp b/test/test_span_dynamic_extent.cpp index 8223fbfd..944b991e 100644 --- a/test/test_span_dynamic_extent.cpp +++ b/test/test_span_dynamic_extent.cpp @@ -970,6 +970,34 @@ namespace } } + //************************************************************************* + TEST(test_operator_equality) + { + etl::array data1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + etl::array data2{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + + View view1{data1}; + View view2{data1}; + View view3{data2}; + + CHECK_TRUE((view1 == view2)); + CHECK_FALSE((view1 == view3)); + } + + //************************************************************************* + TEST(test_operator_not_equal) + { + etl::array data1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + etl::array data2{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + + View view1{data1}; + View view2{data1}; + View view3{data2}; + + CHECK_FALSE((view1 != view2)); + CHECK_TRUE((view1 != view3)); + } + #include "etl/private/diagnostic_pop.h" }; } diff --git a/test/test_span_fixed_extent.cpp b/test/test_span_fixed_extent.cpp index dba32320..82b3a51f 100644 --- a/test/test_span_fixed_extent.cpp +++ b/test/test_span_fixed_extent.cpp @@ -960,6 +960,34 @@ namespace } } + //************************************************************************* + TEST(test_operator_equality) + { + etl::array data1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + etl::array data2{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + + View view1{data1}; + View view2{data1}; + View view3{data2}; + + CHECK_TRUE((view1 == view2)); + CHECK_FALSE((view1 == view3)); + } + + //************************************************************************* + TEST(test_operator_not_equal) + { + etl::array data1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + etl::array data2{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + + View view1{data1}; + View view2{data1}; + View view3{data2}; + + CHECK_FALSE((view1 != view2)); + CHECK_TRUE((view1 != view3)); + } + #include "etl/private/diagnostic_pop.h" }; } From 8491133351a789fba09a22dd5998dd4a62ceb846 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 12 Feb 2023 11:26:03 +0100 Subject: [PATCH 47/60] Work in progress --- include/etl/span.h | 112 +++++++++++++++------- test/test_span_dynamic_extent.cpp | 149 +++++++++++++++++++++++++++--- test/test_span_fixed_extent.cpp | 108 +++++++++++++++++++--- test/vs2019/cpp.hint | 13 +++ 4 files changed, 322 insertions(+), 60 deletions(-) diff --git a/include/etl/span.h b/include/etl/span.h index bfd7a4f4..a84520ad 100644 --- a/include/etl/span.h +++ b/include/etl/span.h @@ -33,6 +33,7 @@ SOFTWARE. #include "platform.h" #include "iterator.h" +#include "algorithm.h" #include "circular_iterator.h" #include "nullptr.h" #include "hash.h" @@ -345,23 +346,24 @@ namespace etl return pbegin[i]; } - //************************************************************************* - /// Compare two spans for equality. - //************************************************************************* - template , value_type>::value, bool> = true> - ETL_NODISCARD ETL_CONSTEXPR bool operator==(const etl::span& other) const ETL_NOEXCEPT - { - return ((pbegin == other.pbegin) && (Extent == other.size())); - } + ////************************************************************************* + ///// Compare two spans for equality. + ////************************************************************************* + //template ::type, value_type>::value, bool>::type = true> + //ETL_NODISCARD ETL_CONSTEXPR bool operator==(const etl::span& other) const ETL_NOEXCEPT + //{ + // return ((begin() == other.begin()) && (Extent == other.size())) || + // etl::equal(begin(), end(), other.begin(), other.end()); + //} - //************************************************************************* - /// Compare two spans for non-equality. - //************************************************************************* - template , value_type>::value, bool> = true> - ETL_NODISCARD ETL_CONSTEXPR bool operator!=(const etl::span& other) const ETL_NOEXCEPT - { - return !(*this == other); - } + ////************************************************************************* + ///// Compare two spans for non-equality. + ////************************************************************************* + //template ::type, value_type>::value, bool>::type = true> + //ETL_NODISCARD ETL_CONSTEXPR bool operator!=(const etl::span& other) const ETL_NOEXCEPT + //{ + // return !(*this == other); + //} //************************************************************************* /// Obtains a span that is a view over the first COUNT elements of this span. @@ -749,23 +751,25 @@ namespace etl return pbegin[i]; } - //************************************************************************* - /// Compare two spans for equality. - //************************************************************************* - template , value_type>::value, bool> = true> - ETL_NODISCARD ETL_CONSTEXPR bool operator==(const etl::span& other) const ETL_NOEXCEPT - { - return ((pbegin == other.pbegin) && (pend == other.pend)); - } + ////************************************************************************* + ///// Compare two spans for equality. + ////************************************************************************* + //template ::type, value_type>::value, bool>::type = true> + //ETL_NODISCARD ETL_CONSTEXPR bool operator==(const etl::span& other) const ETL_NOEXCEPT + //{ + // return (empty() && other.empty()) || + // ((begin() == other.begin()) && (end() == other.end())) || + // etl::equal(begin(), end(), other.begin(), other.end()); + //} - //************************************************************************* - /// Compare two spans for non-equality. - //************************************************************************* - template , value_type>::value, bool> = true> - ETL_NODISCARD ETL_CONSTEXPR bool operator!=(const etl::span& other) const ETL_NOEXCEPT - { - return !(*this == other); - } + ////************************************************************************* + ///// Compare two spans for non-equality. + ////************************************************************************* + //template ::type, value_type>::value, bool>::type = true> + //ETL_NODISCARD ETL_CONSTEXPR bool operator!=(const etl::span& other) const ETL_NOEXCEPT + //{ + // return !(*this == other); + //} //************************************************************************* /// Obtains a span that is a view over the first COUNT elements of this span. @@ -845,6 +849,46 @@ namespace etl pointer pend; }; + //************************************************************************* + /// Compare two spans for equality. + //************************************************************************* + template + ETL_NODISCARD + ETL_CONSTEXPR + typename etl::enable_if::type, typename etl::remove_cv::type>::value, bool>::type + operator ==(const etl::span& lhs, const etl::span& rhs) ETL_NOEXCEPT + { + return (lhs.begin() == rhs.begin()) && (lhs.size() == rhs.size()); + } + + //************************************************************************* + /// Compare two spans for inequality. + //************************************************************************* + template + ETL_NODISCARD + ETL_CONSTEXPR + bool operator !=(const etl::span& lhs, const etl::span& rhs) ETL_NOEXCEPT + { + return !(lhs == rhs); + } + + //************************************************************************* + /// Equality function. + /// Performs a comparision of the range values. + /// Returns true if one of the following are true + /// 1. Both spans are empty. + /// 2. They both point to the same range of data. + /// 3. The values in the two ranges are equal. + //************************************************************************* + template + etl::enable_if_t, etl::remove_cv_t>, bool> + equal(const etl::span& lhs, const etl::span& rhs) + { + return (lhs.empty() && rhs.empty()) || + ((lhs.begin() == rhs.begin()) && (lhs.size() == rhs.size())) || + etl::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); + } + //************************************************************************* /// Template deduction guides. //************************************************************************* @@ -869,7 +913,7 @@ namespace etl span(const etl::array&) -> span; -#if ETL_USING_STL +#if ETL_USING_STL && ETL_USING_CPP11 template span(std::array&) ->span; @@ -890,7 +934,7 @@ namespace etl size_t operator()(const etl::span& view) const { return etl::private_hash::generic_hash(reinterpret_cast(&view[0]), - reinterpret_cast(&view[view.size()])); + reinterpret_cast(&view[view.size()])); } }; #endif diff --git a/test/test_span_dynamic_extent.cpp b/test/test_span_dynamic_extent.cpp index 944b991e..d26178d1 100644 --- a/test/test_span_dynamic_extent.cpp +++ b/test/test_span_dynamic_extent.cpp @@ -973,15 +973,77 @@ namespace //************************************************************************* TEST(test_operator_equality) { - etl::array data1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - etl::array data2{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + etl::array data1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + etl::array data2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 }; + etl::array data4{ 0, 1, 2, 3, 5, 6, 7, 8, 9 }; - View view1{data1}; - View view2{data1}; - View view3{data2}; + int i; - CHECK_TRUE((view1 == view2)); - CHECK_FALSE((view1 == view3)); + View view1{ data1 }; + View view2{ data1 }; + View view3{ data2 }; + View view4{ data3 }; + View view5{ data4 }; + View view6; + View view7; + View view8(&i, &i); + + CHECK_TRUE(etl::equal(view1, view2)); + CHECK_TRUE(etl::equal(view1, view3)); + CHECK_FALSE(etl::equal(view1, view4)); + CHECK_FALSE(etl::equal(view1, view5)); + CHECK_TRUE(etl::equal(view6, view6)); + CHECK_TRUE(etl::equal(view6, view7)); + CHECK_TRUE(etl::equal(view6, view8)); + CHECK_TRUE(etl::equal(view8, view8)); + + CHECK_TRUE(view1 == view2); + CHECK_FALSE(view1 == view3); + CHECK_FALSE(view1 == view4); + CHECK_FALSE(view1 == view5); + CHECK_TRUE(view6 == view6); + CHECK_TRUE(view6 == view7); + CHECK_FALSE(view6 == view8); + CHECK_TRUE(view8 == view8); + } + + //************************************************************************* + TEST(test_operator_equality_one_is_const) + { + etl::array data1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + etl::array data2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 }; + etl::array data4{ 0, 1, 2, 3, 5, 6, 7, 8, 9 }; + + int i; + + View view1{ data1 }; + CView view2{ data1 }; + CView view3{ data2 }; + CView view4{ data3 }; + CView view5{ data4 }; + View view6; + CView view7; + CView view8(&i, &i); + + CHECK_TRUE(etl::equal(view1, view2)); + CHECK_TRUE(etl::equal(view1, view3)); + CHECK_FALSE(etl::equal(view1, view4)); + CHECK_FALSE(etl::equal(view1, view5)); + CHECK_TRUE(etl::equal(view6, view6)); + CHECK_TRUE(etl::equal(view6, view7)); + CHECK_TRUE(etl::equal(view6, view8)); + CHECK_TRUE(etl::equal(view8, view8)); + + CHECK_TRUE(view1 == view2); + CHECK_FALSE(view1 == view3); + CHECK_FALSE(view1 == view4); + CHECK_FALSE(view1 == view5); + CHECK_TRUE(view6 == view6); + CHECK_TRUE(view6 == view7); + CHECK_FALSE(view6 == view8); + CHECK_TRUE(view8 == view8); } //************************************************************************* @@ -989,13 +1051,76 @@ namespace { etl::array data1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; etl::array data2{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 }; + etl::array data4{ 0, 1, 2, 3, 5, 6, 7, 8, 9 }; - View view1{data1}; - View view2{data1}; - View view3{data2}; + int i; - CHECK_FALSE((view1 != view2)); - CHECK_TRUE((view1 != view3)); + View view1{ data1 }; + View view2{ data1 }; + View view3{ data2 }; + View view4{ data3 }; + View view5{ data4 }; + View view6; + View view7; + View view8(&i, &i); + + CHECK_TRUE(etl::equal(view1, view2)); + CHECK_TRUE(etl::equal(view1, view3)); + CHECK_FALSE(etl::equal(view1, view4)); + CHECK_FALSE(etl::equal(view1, view5)); + CHECK_TRUE(etl::equal(view6, view6)); + CHECK_TRUE(etl::equal(view6, view7)); + CHECK_TRUE(etl::equal(view6, view8)); + CHECK_TRUE(etl::equal(view8, view8)); + + CHECK_FALSE(view1 != view2); + CHECK_TRUE(view1 != view3); + CHECK_TRUE(view1 != view4); + CHECK_TRUE(view1 != view5); + CHECK_FALSE(view6 != view6); + CHECK_FALSE(view6 != view7); + CHECK_TRUE(view6 != view8); + CHECK_FALSE(view8 != view8); + } + + //************************************************************************* + TEST(test_operator_not_equal_one_is_const) + { + etl::array data1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + etl::array data2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 }; + etl::array data4{ 0, 1, 2, 3, 5, 6, 7, 8, 9 }; + + int i; + + View view1{ data1 }; + CView view2{ data1 }; + CView view3{ data2 }; + CView view4{ data3 }; + CView view5{ data4 }; + View view6; + View view7; + View view8(&i, &i); + + CHECK_TRUE(etl::equal(view1, view2)); + CHECK_TRUE(etl::equal(view1, view3)); + CHECK_FALSE(etl::equal(view1, view4)); + CHECK_FALSE(etl::equal(view1, view5)); + CHECK_TRUE(etl::equal(view6, view6)); + CHECK_TRUE(etl::equal(view6, view7)); + CHECK_TRUE(etl::equal(view6, view8)); + CHECK_TRUE(etl::equal(view8, view8)); + + CHECK_FALSE(view1 != view1); + CHECK_FALSE(view1 != view2); + CHECK_TRUE(view1 != view3); + CHECK_TRUE(view1 != view4); + CHECK_TRUE(view1 != view5); + CHECK_FALSE(view6 != view6); + CHECK_FALSE(view6 != view7); + CHECK_TRUE(view6 != view8); + CHECK_FALSE(view8 != view8); } #include "etl/private/diagnostic_pop.h" diff --git a/test/test_span_fixed_extent.cpp b/test/test_span_fixed_extent.cpp index 82b3a51f..7e6e327a 100644 --- a/test/test_span_fixed_extent.cpp +++ b/test/test_span_fixed_extent.cpp @@ -963,29 +963,109 @@ namespace //************************************************************************* TEST(test_operator_equality) { - etl::array data1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - etl::array data2{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + etl::array data1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + etl::array data2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 }; - View view1{data1}; - View view2{data1}; - View view3{data2}; + View view1{ data1 }; + View view2{ data1 }; + View view3{ data2 }; + View view4{ data3 }; + View view6; + View view7; - CHECK_TRUE((view1 == view2)); - CHECK_FALSE((view1 == view3)); + CHECK_TRUE(etl::equal(view1, view2)); + CHECK_TRUE(etl::equal(view1, view3)); + CHECK_FALSE(etl::equal(view1, view4)); + CHECK_TRUE(etl::equal(view6, view6)); + CHECK_TRUE(etl::equal(view6, view7)); + + CHECK_TRUE(view1 == view2); + CHECK_FALSE(view1 == view3); + CHECK_FALSE(view1 == view4); + CHECK_TRUE(view6 == view6); + CHECK_TRUE(view6 == view7); + } + + //************************************************************************* + TEST(test_operator_equality_one_is_const) + { + etl::array data1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + etl::array data2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 }; + + View view1{ data1 }; + CView view2{ data1 }; + CView view3{ data2 }; + CView view4{ data3 }; + View view6; + CView view7; + + CHECK_TRUE(etl::equal(view1, view2)); + CHECK_TRUE(etl::equal(view1, view3)); + CHECK_FALSE(etl::equal(view1, view4)); + CHECK_TRUE(etl::equal(view6, view6)); + CHECK_TRUE(etl::equal(view6, view7)); + + CHECK_TRUE(view1 == view2); + CHECK_FALSE(view1 == view3); + CHECK_FALSE(view1 == view4); + CHECK_TRUE(view6 == view6); + CHECK_TRUE(view6 == view7); } //************************************************************************* TEST(test_operator_not_equal) { - etl::array data1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - etl::array data2{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + etl::array data1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + etl::array data2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 }; - View view1{data1}; - View view2{data1}; - View view3{data2}; + View view1{ data1 }; + View view2{ data1 }; + View view3{ data2 }; + View view4{ data3 }; + View view6; + View view7; - CHECK_FALSE((view1 != view2)); - CHECK_TRUE((view1 != view3)); + CHECK_TRUE(etl::equal(view1, view2)); + CHECK_TRUE(etl::equal(view1, view3)); + CHECK_FALSE(etl::equal(view1, view4)); + CHECK_TRUE(etl::equal(view6, view6)); + CHECK_TRUE(etl::equal(view6, view7)); + + CHECK_FALSE(view1 != view2); + CHECK_TRUE(view1 != view3); + CHECK_TRUE(view1 != view4); + CHECK_FALSE(view6 != view6); + CHECK_FALSE(view6 != view7); + } + + //************************************************************************* + TEST(test_operator_not_equal_one_is_const) + { + etl::array data1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + etl::array data2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 }; + + View view1{ data1 }; + CView view2{ data1 }; + CView view3{ data2 }; + CView view4{ data3 }; + View view6; + View view7; + + CHECK_TRUE(etl::equal(view1, view2)); + CHECK_TRUE(etl::equal(view1, view3)); + CHECK_FALSE(etl::equal(view1, view4)); + CHECK_TRUE(etl::equal(view6, view6)); + CHECK_TRUE(etl::equal(view6, view7)); + + CHECK_FALSE(view1 != view2); + CHECK_TRUE(view1 != view3); + CHECK_TRUE(view1 != view4); + CHECK_FALSE(view6 != view6); + CHECK_FALSE(view6 != view7); } #include "etl/private/diagnostic_pop.h" diff --git a/test/vs2019/cpp.hint b/test/vs2019/cpp.hint index 3c9d8d88..0fd4bafc 100644 --- a/test/vs2019/cpp.hint +++ b/test/vs2019/cpp.hint @@ -38,3 +38,16 @@ // such as names of functions and macros. // For more information see https://go.microsoft.com/fwlink/?linkid=865984 #define ETL_NULLPTR +// Hint files help the Visual Studio IDE interpret Visual C++ identifiers +// such as names of functions and macros. +// For more information see https://go.microsoft.com/fwlink/?linkid=865984 +#define ETL_NODISCARD [[nodiscard]] +#define ETL_NODISCARD +// Hint files help the Visual Studio IDE interpret Visual C++ identifiers +// such as names of functions and macros. +// For more information see https://go.microsoft.com/fwlink/?linkid=865984 +#define ETL_CONSTEXPR +// Hint files help the Visual Studio IDE interpret Visual C++ identifiers +// such as names of functions and macros. +// For more information see https://go.microsoft.com/fwlink/?linkid=865984 +#define ETL_NOEXCEPT From 26caa70981eb4a2a07a7f082758d8b5b28abd47e Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 12 Feb 2023 11:44:59 +0100 Subject: [PATCH 48/60] Added M17 CRC --- include/etl/crc.h | 1 + include/etl/crc16_m17.h | 78 ++++++++ include/etl/private/crc_parameters.h | 1 + test/test_crc16_m17.cpp | 263 +++++++++++++++++++++++++++ test/vs2019/etl.vcxproj | 1 + test/vs2019/etl.vcxproj.filters | 3 + 6 files changed, 347 insertions(+) create mode 100644 include/etl/crc16_m17.h create mode 100644 test/test_crc16_m17.cpp diff --git a/include/etl/crc.h b/include/etl/crc.h index db646b65..da8dd0a4 100644 --- a/include/etl/crc.h +++ b/include/etl/crc.h @@ -67,6 +67,7 @@ SOFTWARE. #include "crc16_usb.h" #include "crc16_x25.h" #include "crc16_xmodem.h" +#include "crc16_m17.h" #include "crc32.h" #include "crc32_bzip2.h" diff --git a/include/etl/crc16_m17.h b/include/etl/crc16_m17.h new file mode 100644 index 00000000..5b9f949e --- /dev/null +++ b/include/etl/crc16_m17.h @@ -0,0 +1,78 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2023 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef ETL_CRC16_M17_INCLUDED +#define ETL_CRC16_M17_INCLUDED + +#include "platform.h" +#include "private/crc_implementation.h" + +///\defgroup crc16_m17 16 bit CRC calculation +///\ingroup crc + +namespace etl +{ +#if ETL_USING_CPP11 && !defined(ETL_CRC_FORCE_CPP03_IMPLEMENTATION) + template + using crc16_m17_t = etl::crc_type; +#else + template + class crc16_m17_t : public etl::crc_type + { + public: + + //************************************************************************* + /// Default constructor. + //************************************************************************* + crc16_m17_t() + { + this->reset(); + } + + //************************************************************************* + /// Constructor from range. + /// \param begin Start of the range. + /// \param end End of the range. + //************************************************************************* + template + crc16_m17_t(TIterator begin, const TIterator end) + { + this->reset(); + this->add(begin, end); + } + }; +#endif + + typedef etl::crc16_m17_t<256U> crc16_m17_t256; + typedef etl::crc16_m17_t<16U> crc16_m17_t16; + typedef etl::crc16_m17_t<4U> crc16_m17_t4; + typedef crc16_m17_t256 crc16_m17; +} +#endif diff --git a/include/etl/private/crc_parameters.h b/include/etl/private/crc_parameters.h index 7df70900..8ffb9242 100644 --- a/include/etl/private/crc_parameters.h +++ b/include/etl/private/crc_parameters.h @@ -91,6 +91,7 @@ namespace etl typedef crc_parameters crc16_tms37157_parameters; typedef crc_parameters crc16_a_parameters; typedef crc_parameters crc16_arc_parameters; + typedef crc_parameters crc16_m17_parameters; // 32 bit. typedef crc_parameters crc32_parameters; diff --git a/test/test_crc16_m17.cpp b/test/test_crc16_m17.cpp new file mode 100644 index 00000000..b28d624b --- /dev/null +++ b/test/test_crc16_m17.cpp @@ -0,0 +1,263 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2023 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include "unit_test_framework.h" + +#include +#include +#include +#include + +#include "etl/crc16_m17.h" + +//***************************************************************************** +// The results for these tests were created from https://crccalc.com/ +//***************************************************************************** + +namespace +{ + SUITE(test_crc16_m17) + { + //************************************************************************* + // Table size 256 + //************************************************************************* + TEST(test_crc16_m17) + { + std::string data("123456789"); + + uint16_t crc = etl::crc16_m17(data.begin(), data.end()); + + CHECK_EQUAL(0x772BU, crc); + } + + //************************************************************************* + TEST(test_crc16_m17_add_values) + { + std::string data("123456789"); + + etl::crc16_m17 crc_calculator; + + for (size_t i = 0UL; i < data.size(); ++i) + { + crc_calculator.add(data[i]); + } + + uint16_t crc = crc_calculator; + + CHECK_EQUAL(0x772BU, crc); + } + + //************************************************************************* + TEST(test_crc16_m17_add_range) + { + std::string data("123456789"); + + etl::crc16_m17 crc_calculator; + + crc_calculator.add(data.begin(), data.end()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x772BU, crc); + } + + //************************************************************************* + TEST(test_crc16_m17_add_range_via_iterator) + { + std::string data("123456789"); + + etl::crc16_m17 crc_calculator; + + std::copy(data.begin(), data.end(), crc_calculator.input()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x772BU, crc); + } + + //************************************************************************* + TEST(test_crc16_m17_add_range_endian) + { + std::vector data1 = { 0x01U, 0x02U, 0x03U, 0x04U, 0x05U, 0x06U, 0x07U, 0x08U }; + std::vector data2 = { 0x04030201UL, 0x08070605UL }; + std::vector data3 = { 0x08U, 0x07U, 0x06U, 0x05U, 0x04U, 0x03U, 0x02U, 0x01U }; + + uint16_t crc1 = etl::crc16_m17(data1.begin(), data1.end()); + uint16_t crc2 = etl::crc16_m17((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(crc1, crc2); + + uint16_t crc3 = etl::crc16_m17(data3.rbegin(), data3.rend()); + CHECK_EQUAL(crc1, crc3); + } + + //************************************************************************* + // Table size 16 + //************************************************************************* + TEST(test_crc16_m17_16) + { + std::string data("123456789"); + + uint16_t crc = etl::crc16_m17_t16(data.begin(), data.end()); + + CHECK_EQUAL(0x772BU, crc); + } + + //************************************************************************* + TEST(test_crc16_m17_16_add_values) + { + std::string data("123456789"); + + etl::crc16_m17_t16 crc_calculator; + + for (size_t i = 0UL; i < data.size(); ++i) + { + crc_calculator.add(data[i]); + } + + uint16_t crc = crc_calculator; + + CHECK_EQUAL(0x772BU, crc); + } + + //************************************************************************* + TEST(test_crc16_m17_16_add_range) + { + std::string data("123456789"); + + etl::crc16_m17_t16 crc_calculator; + + crc_calculator.add(data.begin(), data.end()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x772BU, crc); + } + + //************************************************************************* + TEST(test_crc16_m17_16_add_range_via_iterator) + { + std::string data("123456789"); + + etl::crc16_m17_t16 crc_calculator; + + std::copy(data.begin(), data.end(), crc_calculator.input()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x772BU, crc); + } + + //************************************************************************* + TEST(test_crc16_m17_16_add_range_endian) + { + std::vector data1 = { 0x01U, 0x02U, 0x03U, 0x04U, 0x05U, 0x06U, 0x07U, 0x08U }; + std::vector data2 = { 0x04030201UL, 0x08070605UL }; + std::vector data3 = { 0x08U, 0x07U, 0x06U, 0x05U, 0x04U, 0x03U, 0x02U, 0x01U }; + + uint16_t crc1 = etl::crc16_m17_t16(data1.begin(), data1.end()); + uint16_t crc2 = etl::crc16_m17_t16((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(crc1, crc2); + + uint16_t crc3 = etl::crc16_m17_t16(data3.rbegin(), data3.rend()); + CHECK_EQUAL(crc1, crc3); + } + + //************************************************************************* + // Table size 4 + //************************************************************************* + TEST(test_crc16_m17_4) + { + std::string data("123456789"); + + uint16_t crc = etl::crc16_m17_t4(data.begin(), data.end()); + + CHECK_EQUAL(0x772BU, crc); + } + + //************************************************************************* + TEST(test_crc16_m17_4_add_values) + { + std::string data("123456789"); + + etl::crc16_m17_t4 crc_calculator; + + for (size_t i = 0UL; i < data.size(); ++i) + { + crc_calculator.add(data[i]); + } + + uint16_t crc = crc_calculator; + + CHECK_EQUAL(0x772BU, crc); + } + + //************************************************************************* + TEST(test_crc16_m17_4_add_range) + { + std::string data("123456789"); + + etl::crc16_m17_t4 crc_calculator; + + crc_calculator.add(data.begin(), data.end()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x772BU, crc); + } + + //************************************************************************* + TEST(test_crc16_m17_4_add_range_via_iterator) + { + std::string data("123456789"); + + etl::crc16_m17_t4 crc_calculator; + + std::copy(data.begin(), data.end(), crc_calculator.input()); + + uint16_t crc = crc_calculator.value(); + + CHECK_EQUAL(0x772BU, crc); + } + + //************************************************************************* + TEST(test_crc16_m17_4_add_range_endian) + { + std::vector data1 = { 0x01U, 0x02U, 0x03U, 0x04U, 0x05U, 0x06U, 0x07U, 0x08U }; + std::vector data2 = { 0x04030201UL, 0x08070605UL }; + std::vector data3 = { 0x08U, 0x07U, 0x06U, 0x05U, 0x04U, 0x03U, 0x02U, 0x01U }; + + uint16_t crc1 = etl::crc16_m17_t4(data1.begin(), data1.end()); + uint16_t crc2 = etl::crc16_m17_t4((uint8_t*)&data2[0], (uint8_t*)(&data2[0] + data2.size())); + CHECK_EQUAL(crc1, crc2); + + uint16_t crc3 = etl::crc16_m17_t4(data3.rbegin(), data3.rend()); + CHECK_EQUAL(crc1, crc3); + } + }; +} + diff --git a/test/vs2019/etl.vcxproj b/test/vs2019/etl.vcxproj index c855b06b..8d236f99 100644 --- a/test/vs2019/etl.vcxproj +++ b/test/vs2019/etl.vcxproj @@ -11350,6 +11350,7 @@ + diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index e6c75e07..3c5971ca 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -3392,6 +3392,9 @@ Tests\Sanity Checks\Source + + Tests\CRC + From eb3593d2ef111b8a675f426b6275414df200f7ef Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 13 Feb 2023 11:40:36 +0100 Subject: [PATCH 49/60] Added ""_sv string view operators --- include/etl/string.h | 13 +++++++++++++ include/etl/u16string.h | 13 +++++++++++++ include/etl/u32string.h | 13 +++++++++++++ include/etl/wstring.h | 13 +++++++++++++ test/test_string_view.cpp | 21 +++++++++++++++++++++ 5 files changed, 73 insertions(+) diff --git a/include/etl/string.h b/include/etl/string.h index a1415e2e..a84c4d3a 100644 --- a/include/etl/string.h +++ b/include/etl/string.h @@ -43,6 +43,19 @@ SOFTWARE. namespace etl { +#if ETL_USING_CPP11 + inline namespace literals + { + inline namespace string_literals + { + constexpr etl::string_view operator ""_sv(const char* str, size_t length) noexcept + { + return etl::string_view{ str, length }; + } + } + } +#endif + typedef etl::ibasic_string istring; //*************************************************************************** diff --git a/include/etl/u16string.h b/include/etl/u16string.h index 88f5303b..9be06986 100644 --- a/include/etl/u16string.h +++ b/include/etl/u16string.h @@ -41,6 +41,19 @@ SOFTWARE. namespace etl { +#if ETL_USING_CPP11 + inline namespace literals + { + inline namespace string_literals + { + constexpr etl::u16string_view operator ""_sv(const char16_t* str, size_t length) noexcept + { + return etl::u16string_view{ str, length }; + } + } + } +#endif + typedef ibasic_string iu16string; //*************************************************************************** diff --git a/include/etl/u32string.h b/include/etl/u32string.h index 1dda3291..783f4901 100644 --- a/include/etl/u32string.h +++ b/include/etl/u32string.h @@ -41,6 +41,19 @@ SOFTWARE. namespace etl { +#if ETL_USING_CPP11 + inline namespace literals + { + inline namespace string_literals + { + constexpr etl::u32string_view operator ""_sv(const char32_t* str, size_t length) noexcept + { + return etl::u32string_view{ str, length }; + } + } + } +#endif + typedef ibasic_string iu32string; //*************************************************************************** diff --git a/include/etl/wstring.h b/include/etl/wstring.h index cde74be3..22caaae6 100644 --- a/include/etl/wstring.h +++ b/include/etl/wstring.h @@ -41,6 +41,19 @@ SOFTWARE. namespace etl { +#if ETL_USING_CPP11 + inline namespace literals + { + inline namespace string_literals + { + constexpr etl::wstring_view operator ""_sv(const wchar_t* str, size_t length) noexcept + { + return etl::wstring_view{ str, length }; + } + } + } +#endif + typedef ibasic_string iwstring; //*************************************************************************** diff --git a/test/test_string_view.cpp b/test/test_string_view.cpp index 86c9eefc..9cf0e1e7 100644 --- a/test/test_string_view.cpp +++ b/test/test_string_view.cpp @@ -1013,5 +1013,26 @@ namespace CHECK(etl::hash()(u16text) == etl::hash()(u16view)); CHECK(etl::hash()(u32text) == etl::hash()(u32view)); } + + //************************************************************************* + TEST(string_view_literal) + { + typedef etl::string_view View; + typedef etl::wstring_view WView; + typedef etl::u16string_view U16View; + typedef etl::u32string_view U32View; + + using namespace etl::literals::string_literals; + + View view = "Hello World"_sv; + WView wview = L"Hello World"_sv; + U16View u16view = u"Hello World"_sv; + U32View u32view = U"Hello World"_sv; + + CHECK_TRUE((view == View{ "Hello World", etl::strlen("Hello World") })); + CHECK_TRUE((wview == WView{ L"Hello World", etl::strlen(L"Hello World") })); + CHECK_TRUE((u16view == U16View{ u"Hello World", etl::strlen(u"Hello World") })); + CHECK_TRUE((u32view == U32View{ U"Hello World", etl::strlen(U"Hello World") })); + } }; } From 055ce0d442a2869dbf54dbe6be9c1f4c2fed563e Mon Sep 17 00:00:00 2001 From: David Ockey Date: Thu, 16 Feb 2023 02:53:17 -0600 Subject: [PATCH 50/60] Added HFSM-specific start() and reset() (#672) * Added HFSM specific Start and Reset * Added unit tests for HFSM start() and reset() * Updated FSM generator --- include/etl/fsm.h | 4 +- include/etl/generators/fsm_generator.h | 4 +- include/etl/hfsm.h | 35 +++++++ test/test_hfsm.cpp | 132 ++++++++++++++++++++++++- 4 files changed, 168 insertions(+), 7 deletions(-) diff --git a/include/etl/fsm.h b/include/etl/fsm.h index b7f2f915..5c71795d 100644 --- a/include/etl/fsm.h +++ b/include/etl/fsm.h @@ -346,7 +346,7 @@ namespace etl /// Subsequent calls will do nothing. ///\param call_on_enter_state If true will call on_enter_state() for the first state. Default = true. //******************************************* - void start(bool call_on_enter_state = true) + virtual void start(bool call_on_enter_state = true) { // Can only be started once. if (p_state == ETL_NULLPTR) @@ -451,7 +451,7 @@ namespace etl /// Reset the FSM to pre-started state. ///\param call_on_exit_state If true will call on_exit_state() for the current state. Default = false. //******************************************* - void reset(bool call_on_exit_state = false) + virtual void reset(bool call_on_exit_state = false) { if ((p_state != ETL_NULLPTR) && call_on_exit_state) { diff --git a/include/etl/generators/fsm_generator.h b/include/etl/generators/fsm_generator.h index a510de99..c30c8b9c 100644 --- a/include/etl/generators/fsm_generator.h +++ b/include/etl/generators/fsm_generator.h @@ -372,7 +372,7 @@ namespace etl /// Subsequent calls will do nothing. ///\param call_on_enter_state If true will call on_enter_state() for the first state. Default = true. //******************************************* - void start(bool call_on_enter_state = true) + virtual void start(bool call_on_enter_state = true) { // Can only be started once. if (p_state == ETL_NULLPTR) @@ -477,7 +477,7 @@ namespace etl /// Reset the FSM to pre-started state. ///\param call_on_exit_state If true will call on_exit_state() for the current state. Default = false. //******************************************* - void reset(bool call_on_exit_state = false) + virtual void reset(bool call_on_exit_state = false) { if ((p_state != ETL_NULLPTR) && call_on_exit_state) { diff --git a/include/etl/hfsm.h b/include/etl/hfsm.h index 673e2cec..73eee88b 100644 --- a/include/etl/hfsm.h +++ b/include/etl/hfsm.h @@ -50,6 +50,41 @@ namespace etl { } + //******************************************* + /// Starts the HFSM. + /// Can only be called once. + /// Subsequent calls will do nothing. + ///\param call_on_enter_state If true will call on_enter_state() for the first state. Default = true. + //******************************************* + void start(bool call_on_enter_state = true) ETL_OVERRIDE + { + // Can only be started once. + if (p_state == ETL_NULLPTR) + { + p_state = state_list[0]; + ETL_ASSERT(p_state != ETL_NULLPTR, ETL_ERROR(etl::fsm_null_state_exception)); + + if (call_on_enter_state) + { + do_enters(ETL_NULLPTR, p_state, true); + } + } + } + + //******************************************* + /// Reset the HFSM to pre-started state. + ///\param call_on_exit_state If true will call on_exit_state() for the current state. Default = false. + //******************************************* + virtual void reset(bool call_on_exit_state = false) ETL_OVERRIDE + { + if ((p_state != ETL_NULLPTR) && call_on_exit_state) + { + do_exits(ETL_NULLPTR, p_state); + } + + p_state = ETL_NULLPTR; + } + using fsm::receive; //******************************************* diff --git a/test/test_hfsm.cpp b/test/test_hfsm.cpp index 375d1e98..dc1e3459 100644 --- a/test/test_hfsm.cpp +++ b/test/test_hfsm.cpp @@ -33,6 +33,7 @@ SOFTWARE. #include "etl/container.h" #include "etl/packet.h" #include "etl/queue.h" +#include "etl/circular_buffer.h" #include @@ -196,6 +197,9 @@ namespace stoppedCount = 0; isLampOn = false; speed = 0; + + stateEnterHistory.clear(); + stateExitHistory.clear(); } //*********************************** @@ -238,6 +242,10 @@ namespace int stoppedCount; bool isLampOn; int speed; + + // A circular buffer is used so that data overflows won't assert in tests which don't use this data + etl::circular_buffer stateEnterHistory{}; + etl::circular_buffer stateExitHistory{}; }; //*********************************** @@ -271,9 +279,19 @@ namespace //*********************************** etl::fsm_state_id_t on_enter_state() { - get_fsm_context().TurnRunningLampOff(); + auto& context = get_fsm_context(); + context.stateEnterHistory.push(static_cast(get_state_id())); + context.TurnRunningLampOff(); + return No_State_Change; } + + //*********************************** + void on_exit_state() + { + auto& context = get_fsm_context(); + context.stateExitHistory.push(static_cast(get_state_id())); + } }; //*********************************** @@ -301,10 +319,19 @@ namespace //*********************************** etl::fsm_state_id_t on_enter_state() { - get_fsm_context().TurnRunningLampOn(); + auto& context = get_fsm_context(); + context.stateEnterHistory.push(static_cast(get_state_id())); + context.TurnRunningLampOn(); return No_State_Change; } + + //*********************************** + void on_exit_state() + { + auto& context = get_fsm_context(); + context.stateExitHistory.push(static_cast(get_state_id())); + } }; //*********************************** @@ -336,11 +363,21 @@ namespace return No_State_Change; } + //*********************************** etl::fsm_state_id_t on_enter_state() { - ++get_fsm_context().windUpStartCount; + auto& context = get_fsm_context(); + context.stateEnterHistory.push(static_cast(get_state_id())); + ++context.windUpStartCount; return No_State_Change; } + + //*********************************** + void on_exit_state() + { + auto& context = get_fsm_context(); + context.stateExitHistory.push(static_cast(get_state_id())); + } }; //*********************************** @@ -371,6 +408,13 @@ namespace ++get_fsm_context().unknownCount; return No_State_Change; } + + //*********************************** + void on_exit_state() + { + auto& context = get_fsm_context(); + context.stateExitHistory.push(static_cast(get_state_id())); + } }; //*********************************** @@ -852,5 +896,87 @@ namespace CHECK_THROW(mc.set_states(stateList, StateId::Number_Of_States), etl::fsm_state_list_order_exception); } + + //************************************************************************* + TEST(test_hfsm_start_enters) + { + MotorControl mc; + + motorControl.Initialise(stateList, std::size(stateList)); + motorControl.reset(); + motorControl.ClearStatistics(); + + CHECK(!motorControl.is_started()); + + // Start the HFSM (with enters) + motorControl.start(true); + CHECK(motorControl.is_started()); + + // Now in Idle state. + + CHECK_EQUAL(StateId::Idle, int(motorControl.get_state_id())); + CHECK_EQUAL(StateId::Idle, int(motorControl.get_state().get_state_id())); + + CHECK_EQUAL(false, motorControl.isLampOn); + CHECK_EQUAL(0, motorControl.setSpeedCount); + CHECK_EQUAL(0, motorControl.speed); + CHECK_EQUAL(0, motorControl.startCount); + CHECK_EQUAL(0, motorControl.stopCount); + CHECK_EQUAL(0, motorControl.windUpCompleteCount); + CHECK_EQUAL(0, motorControl.windUpStartCount); + CHECK_EQUAL(0, motorControl.stoppedCount); + CHECK_EQUAL(0, motorControl.unknownCount); + + etl::array expectedEnters{StateId::Idle}; + CHECK_EQUAL(expectedEnters.size(), motorControl.stateEnterHistory.size()); + // No enters should have been performed + CHECK(motorControl.stateExitHistory.empty()); + + bool entersCorrect = std::equal(motorControl.stateEnterHistory.begin(), motorControl.stateEnterHistory.end(), expectedEnters.begin()); + CHECK(entersCorrect); + } + + //************************************************************************* + TEST(test_hfsm_reset_exits) + { + MotorControl mc; + + motorControl.Initialise(stateList, std::size(stateList)); + motorControl.reset(); + motorControl.ClearStatistics(); + + CHECK(!motorControl.is_started()); + + // Start the HFSM (with enters) + motorControl.start(false); + CHECK(motorControl.is_started()); + + // Now in Idle state. + + // Send Start event. + motorControl.receive(Start()); + + // Send Timeout event + motorControl.receive(Timeout()); + + // Send SetSpeed event. + motorControl.receive(SetSpeed(100)); + CHECK_EQUAL(StateId::At_Speed, int(motorControl.get_state_id())); + CHECK_EQUAL(StateId::At_Speed, int(motorControl.get_state().get_state_id())); + + // Clean statistics before reset for clean results + motorControl.ClearStatistics(); + + // Reset HFSM (with exits) + motorControl.reset(true); + + etl::array expectedExits{StateId::At_Speed, StateId::Running}; + CHECK_EQUAL(expectedExits.size(), motorControl.stateExitHistory.size()); + // No enters should have been performed + CHECK(motorControl.stateEnterHistory.empty()); + + bool exitsCorrect = std::equal(motorControl.stateExitHistory.begin(), motorControl.stateExitHistory.end(), expectedExits.begin()); + CHECK(exitsCorrect); + } }; } From 2c15062c1baef896222c7fa9a5d95288ff83e8de Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 19 Feb 2023 10:41:43 +0000 Subject: [PATCH 51/60] Added etl::is_aligned, etl::alignment_exception and etl::alignment_error --- include/etl/alignment.h | 63 +++++++++++++++++++++++++++++++++++++++-- test/test_alignment.cpp | 17 +++++++++++ 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/include/etl/alignment.h b/include/etl/alignment.h index a5ccb9af..4b72387e 100644 --- a/include/etl/alignment.h +++ b/include/etl/alignment.h @@ -34,6 +34,8 @@ SOFTWARE. #include "platform.h" #include "type_traits.h" #include "static_assert.h" +#include "error_handler.h" +#include "exception.h" #include @@ -43,12 +45,68 @@ SOFTWARE. namespace etl { + //*************************************************************************** + /// Exception base for alignment + //*************************************************************************** + class alignment_exception : public etl::exception + { + public: + + alignment_exception(string_type reason_, string_type file_name_, numeric_type line_number_) + : exception(reason_, file_name_, line_number_) + { + } + }; + + //*************************************************************************** + /// Memory misalignment exception. + //*************************************************************************** + class alignment_error : public alignment_exception + { + public: + + alignment_error(string_type file_name_, numeric_type line_number_) + : alignment_exception(ETL_ERROR_TEXT("alignment:error", ETL_ALIGNMENT_FILE_ID"A"), file_name_, line_number_) + { + } + }; + + //***************************************************************************** + /// Check that 'p' has 'required_alignment'. + //***************************************************************************** + inline bool is_aligned(void* p, size_t required_alignment) + { + uintptr_t alignment = static_cast(required_alignment); + uintptr_t address = reinterpret_cast(p); + return (address % alignment) == 0U; + } + + //***************************************************************************** + /// Check that 'p' has 'Alignment'. + //***************************************************************************** + template + bool is_aligned(void* p) + { + uintptr_t address = reinterpret_cast(p); + return (address % static_cast(Alignment)) == 0U; + } + + //***************************************************************************** + /// Check that 'p' has the alignment of 'T'. + //***************************************************************************** + template + bool is_aligned(void* p) + { + return is_aligned::value>(p); + } + namespace private_alignment { //*************************************************************************** // Matcher. //*************************************************************************** - template + template class type_with_alignment_matcher; // Matching alignment. @@ -81,7 +139,8 @@ namespace etl //*************************************************************************** // Helper. //*************************************************************************** - template + template class type_with_alignment_helper { public: diff --git a/test/test_alignment.cpp b/test/test_alignment.cpp index c83c8c2e..266ed85c 100644 --- a/test/test_alignment.cpp +++ b/test/test_alignment.cpp @@ -126,5 +126,22 @@ namespace etl::aligned_storage<100, 8>::type data9; f(static_cast(data9)); } + + //************************************************************************* + TEST(test_is_aligned_tests) + { + char alignas(uint32_t) buffer[2U * sizeof(uint32_t)]; + + char* p = buffer; + + CHECK_TRUE(etl::is_aligned(p, std::alignment_of())); + CHECK_TRUE(etl::is_aligned(p)); + CHECK_TRUE(etl::is_aligned(p)); + + ++p; + CHECK_FALSE(etl::is_aligned(p, std::alignment_of())); + CHECK_FALSE(etl::is_aligned(p)); + CHECK_FALSE(etl::is_aligned(p)); + } }; } From 7316c07045c7885ad3fd95b3ef49f591c6494756 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 19 Feb 2023 10:43:13 +0000 Subject: [PATCH 52/60] Added etl::contruct_object_at, etl::get_object_at and etl::destroy_object_at --- include/etl/file_error_numbers.h | 1 + include/etl/memory.h | 97 +++++++++++++++++ test/test_memory.cpp | 174 +++++++++++++++++++++++++++++++ 3 files changed, 272 insertions(+) diff --git a/include/etl/file_error_numbers.h b/include/etl/file_error_numbers.h index 7d6a0e1a..55aaf14b 100644 --- a/include/etl/file_error_numbers.h +++ b/include/etl/file_error_numbers.h @@ -100,5 +100,6 @@ SOFTWARE. #define ETL_BIP_BUFFER_SPSC_ATOMIC_FILE_ID "67" #define ETL_REFERENCE_COUNTED_OBJECT_FILE_ID "68" #define ETL_TO_ARITHMETIC_FILE_ID "69" +#define ETL_ALIGNMENT_FILE_ID "70" #endif diff --git a/include/etl/memory.h b/include/etl/memory.h index 0725d2e6..f81da1db 100644 --- a/include/etl/memory.h +++ b/include/etl/memory.h @@ -2446,6 +2446,103 @@ namespace etl return (result == 0U) ? reinterpret_cast(sb + n) : reinterpret_cast(result); } + +#if ETL_USING_CPP11 + //***************************************************************************** + /// Move construct the container at 'p'. + //***************************************************************************** + template + TObject& construct_object_at(void* p, TObject&& other) + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(is_aligned(p), ETL_ERROR(alignment_error)); +#endif + + return *etl::construct_at(reinterpret_cast::type*>(p), etl::forward(other)); + } + + //***************************************************************************** + /// Construct the container at 'p' from arguments. + //***************************************************************************** + template + TObject& construct_object_at(void* p, TArgs&&... args) + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(is_aligned(p), ETL_ERROR(alignment_error)); +#endif + + return *etl::construct_at(reinterpret_cast(p), etl::forward(args)...); + } +#else + //***************************************************************************** + /// Default construct the container at 'p'. + //***************************************************************************** + template + TObject& construct_object_at(void* p) + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(is_aligned(p), ETL_ERROR(alignment_error)); +#endif + + return *etl::construct_at(reinterpret_cast(p)); + } + + //***************************************************************************** + /// Copy construct the container at 'p'. + //***************************************************************************** + template + TObject& construct_object_at(void* p, const TObject& other) + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(is_aligned(p), ETL_ERROR(alignment_error)); +#endif + + return *etl::construct_at(reinterpret_cast(p), other); + } + + //***************************************************************************** + /// Construct the container at 'p' from argument. + //***************************************************************************** + template + TObject& construct_object_at(void* p, const TArg& arg) + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(is_aligned(p), ETL_ERROR(alignment_error)); +#endif + + return *etl::construct_at(reinterpret_cast(p), arg); + } +#endif + + //***************************************************************************** + /// Get the container at 'p'. + //***************************************************************************** + template + TObject& get_object_at(void* p) + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(is_aligned(p), ETL_ERROR(alignment_error)); +#endif + + TObject& v = *reinterpret_cast(p); + + return v; + } + + //***************************************************************************** + /// Destroy the container at 'p'. + /// For a container that contains a type that is not trivially destructible. + //***************************************************************************** + template + void destroy_object_at(void* p) + { +#if ETL_IS_DEBUG_BUILD + ETL_ASSERT(is_aligned(p), ETL_ERROR(alignment_error)); +#endif + + TObject& v = get_object_at(p); + v.~TObject(); + } } #endif diff --git a/test/test_memory.cpp b/test/test_memory.cpp index 9854f172..fabd6153 100644 --- a/test/test_memory.cpp +++ b/test/test_memory.cpp @@ -1344,5 +1344,179 @@ namespace CHECK(function_was_called); CHECK(ptr.get() == ETL_NULLPTR); } + + //************************************************************************* + struct Flags + { + Flags() + : constructed(false) + , destructed(false) + { + } + + void Clear() + { + constructed = false; + destructed = false; + } + + bool constructed; + bool destructed; + }; + + static Flags flags; + + TEST(test_construct_get_destroy_object_aligned) + { + struct Data + { + Data() + : a(1) + , b(2) + { + flags.constructed = true; + } + + Data(int a_, int b_) + : a(a_) + , b(b_) + { + flags.constructed = true; + } + + ~Data() + { + flags.destructed = true; + } + + int a; + int b; + }; + + alignas(Data) char buffer1[sizeof(Data)]; + char* pbuffer1 = buffer1; + + alignas(Data) char buffer1b[sizeof(Data)]; + char* pbuffer1b = buffer1b; + + alignas(Data) char buffer2[sizeof(Data)]; + char* pbuffer2 = buffer2; + + alignas(Data) char buffer2b[sizeof(Data)]; + char* pbuffer2b = buffer2b; + + alignas(Data) char buffer3[sizeof(Data)]; + char* pbuffer3 = buffer3; + + alignas(Data) char buffer3b[sizeof(Data)]; + char* pbuffer3b = buffer3b; + + flags.Clear(); + Data& rdata1 = etl::construct_object_at(pbuffer1); + CHECK_TRUE(flags.constructed); + CHECK_FALSE(flags.destructed); + CHECK_EQUAL(1, rdata1.a); + CHECK_EQUAL(2, rdata1.b); + + flags.Clear(); + Data data2(3, 4); + Data& rdata2 = etl::construct_object_at(pbuffer2, data2); + CHECK_TRUE(flags.constructed); + CHECK_FALSE(flags.destructed); + CHECK_EQUAL(data2.a, rdata2.a); + CHECK_EQUAL(data2.b, rdata2.b); + + flags.Clear(); + Data& rdata3 = etl::construct_object_at(pbuffer3, 5, 6); + CHECK_TRUE(flags.constructed); + CHECK_FALSE(flags.destructed); + CHECK_EQUAL(5, rdata3.a); + CHECK_EQUAL(6, rdata3.b); + + memcpy(buffer1b, buffer1, sizeof(Data)); + memcpy(buffer2b, buffer2, sizeof(Data)); + memcpy(buffer3b, buffer3, sizeof(Data)); + + flags.Clear(); + Data& rdata1b = etl::get_object_at(pbuffer1b); + CHECK_FALSE(flags.constructed); + CHECK_FALSE(flags.destructed); + CHECK_EQUAL(1, rdata1.a); + CHECK_EQUAL(2, rdata1.b); + + flags.Clear(); + Data& rdata2b = etl::get_object_at(pbuffer2b); + CHECK_FALSE(flags.constructed); + CHECK_FALSE(flags.destructed); + CHECK_EQUAL(data2.a, rdata2.a); + CHECK_EQUAL(data2.b, rdata2.b); + + flags.Clear(); + Data& rdata3b = etl::get_object_at(pbuffer3b); + CHECK_FALSE(flags.constructed); + CHECK_FALSE(flags.destructed); + CHECK_EQUAL(5, rdata3.a); + CHECK_EQUAL(6, rdata3.b); + + flags.Clear(); + etl::destroy_object_at(pbuffer1b); + CHECK_FALSE(flags.constructed); + CHECK_TRUE(flags.destructed); + + flags.Clear(); + etl::destroy_object_at(pbuffer2b); + CHECK_FALSE(flags.constructed); + CHECK_TRUE(flags.destructed); + + flags.Clear(); + etl::destroy_object_at(pbuffer3b); + CHECK_FALSE(flags.constructed); + CHECK_TRUE(flags.destructed); + } + + TEST(test_construct_get_destroy_object_misaligned) + { + struct Data + { + Data() + : a(1) + , b(2) + { + } + + Data(int a_, int b_) + : a(a_) + , b(b_) + { + } + + ~Data() + { + } + + int a; + int b; + }; + + alignas(Data) char buffer1[sizeof(Data)]; + char* pbuffer1 = buffer1 + 1; + + alignas(Data) char buffer2[sizeof(Data)]; + char* pbuffer2 = buffer2 + 1; + + alignas(Data) char buffer3[sizeof(Data)]; + char* pbuffer3 = buffer3 + 1; + + CHECK_THROW(etl::construct_object_at(pbuffer1), etl::alignment_error); + + Data data2(3, 4); + CHECK_THROW(etl::construct_object_at(pbuffer2, data2), etl::alignment_error); + + CHECK_THROW(etl::construct_object_at(pbuffer3, 5, 6), etl::alignment_error); + + CHECK_THROW(etl::get_object_at(pbuffer1), etl::alignment_error); + + CHECK_THROW(etl::destroy_object_at(pbuffer1), etl::alignment_error); + } }; } From a21c4bb2f09bcd1abd672ac8afce59baa9f84c10 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 19 Feb 2023 10:44:54 +0000 Subject: [PATCH 53/60] Removed unnecessary code in etl::vector_ext::repair() --- include/etl/vector.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/etl/vector.h b/include/etl/vector.h index b6ebec27..dde676bb 100644 --- a/include/etl/vector.h +++ b/include/etl/vector.h @@ -1514,9 +1514,6 @@ namespace etl ETL_OVERRIDE #endif { - ETL_ASSERT(etl::is_trivially_copyable::value, ETL_ERROR(etl::vector_incompatible_type)); - - etl::ivector::repair_buffer(this->p_buffer); } }; From db9d93d5e2f5af08c961efb7997b4d7fc64e6345 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 19 Feb 2023 10:45:19 +0000 Subject: [PATCH 54/60] Added repair() to etl::circular_buffer --- include/etl/circular_buffer.h | 57 +++++++++++++++++++++++++++ test/etl_profile.h | 1 + test/test_circular_buffer.cpp | 74 +++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+) diff --git a/include/etl/circular_buffer.h b/include/etl/circular_buffer.h index cdff83b5..fec89f30 100644 --- a/include/etl/circular_buffer.h +++ b/include/etl/circular_buffer.h @@ -70,6 +70,19 @@ namespace etl } }; + //*************************************************************************** + /// Incompatible type exception. + //*************************************************************************** + class circular_buffer_incompatible_type : public circular_buffer_exception + { + public: + + circular_buffer_incompatible_type(string_type file_name_, numeric_type line_number_) + : circular_buffer_exception(ETL_ERROR_TEXT("circular_buffer:type", ETL_CIRCULAR_BUFFER_FILE_ID"B"), file_name_, line_number_) + { + } + }; + //*************************************************************************** /// //*************************************************************************** @@ -962,6 +975,13 @@ namespace etl etl::fill(begin(), end(), value); } +#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE + //************************************************************************* + /// Fix the internal pointers after a low level memory copy. + //************************************************************************* + virtual void repair() = 0; +#endif + //************************************************************************* /// - operator for iterator //************************************************************************* @@ -1037,6 +1057,14 @@ namespace etl } } + //************************************************************************* + /// Fix the internal pointers after a low level memory copy. + //************************************************************************* + void repair_buffer(T* pbuffer_) + { + pbuffer = pbuffer_; + } + pointer pbuffer; private: @@ -1176,6 +1204,22 @@ namespace etl this->clear(); } + //************************************************************************* + /// Fix the internal pointers after a low level memory copy. + //************************************************************************* +#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE + virtual +#endif + void repair() +#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE + ETL_OVERRIDE +#endif + { + ETL_ASSERT(etl::is_trivially_copyable::value, ETL_ERROR(etl::circular_buffer_incompatible_type)); + + etl::icircular_buffer::repair_buffer(buffer); + } + private: /// The uninitialised storage. @@ -1343,6 +1387,19 @@ namespace etl { this->clear(); } + + //************************************************************************* + /// Fix the internal pointers after a low level memory copy. + //************************************************************************* +#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE + virtual +#endif + void repair() +#ifdef ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE + ETL_OVERRIDE +#endif + { + } }; //************************************************************************* diff --git a/test/etl_profile.h b/test/etl_profile.h index ec2e7247..7f2a9eed 100644 --- a/test/etl_profile.h +++ b/test/etl_profile.h @@ -37,6 +37,7 @@ SOFTWARE. #define ETL_ISTRING_REPAIR_ENABLE #define ETL_IVECTOR_REPAIR_ENABLE #define ETL_IDEQUE_REPAIR_ENABLE +#define ETL_ICIRCULAR_BUFFER_REPAIR_ENABLE #define ETL_IN_UNIT_TEST #define ETL_DEBUG_COUNT #define ETL_ARRAY_VIEW_IS_MUTABLE diff --git a/test/test_circular_buffer.cpp b/test/test_circular_buffer.cpp index ae2d3363..d4e6314c 100644 --- a/test/test_circular_buffer.cpp +++ b/test/test_circular_buffer.cpp @@ -990,5 +990,79 @@ namespace bool isEqual = std::equal(blank.begin(), blank.end(), data.begin()); CHECK(isEqual); } + + //************************************************************************* + TEST(test_memcpy_repair) + { + using CB = etl::circular_buffer; + + std::vector input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + CB data(input.begin(), input.end());; + + char buffer[sizeof(CB)]; + + memcpy(&buffer, (const void*)&data, sizeof(data)); + + CB& rdata(*reinterpret_cast(buffer)); + rdata.repair(); + + // Check that the memcpy'd vector is the same. + CHECK_EQUAL(data.size(), rdata.size()); + CHECK(!rdata.empty()); + CHECK(rdata.full()); + + bool is_equal = std::equal(rdata.begin(), + rdata.end(), + data.begin()); + + CHECK(is_equal); + + // Modify the original and check that the memcpy'd vector is not the same. + std::reverse(data.begin(), data.end()); + + is_equal = std::equal(rdata.begin(), + rdata.end(), + data.begin()); + + CHECK(!is_equal); + } + + //************************************************************************* + TEST(test_memcpy_repair_virtual) + { + using CB = etl::circular_buffer; + using ICB = etl::icircular_buffer; + + std::vector input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + CB data(input.begin(), input.end());; + + char buffer[sizeof(CB)]; + + memcpy(&buffer, (const void*)&data, sizeof(data)); + + ICB& rdata(*reinterpret_cast(buffer)); + rdata.repair(); + + // Check that the memcpy'd vector is the same. + CHECK_EQUAL(data.size(), rdata.size()); + CHECK(!rdata.empty()); + CHECK(rdata.full()); + + bool is_equal = std::equal(rdata.begin(), + rdata.end(), + data.begin()); + + CHECK(is_equal); + + // Modify the original and check that the memcpy'd vector is not the same. + std::reverse(data.begin(), data.end()); + + is_equal = std::equal(rdata.begin(), + rdata.end(), + data.begin()); + + CHECK(!is_equal); + } + }; } From f66a29589e9664227b47f1656ef11cd19bee809a Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 19 Feb 2023 12:13:00 +0000 Subject: [PATCH 55/60] Updated sanity check make files --- test/CMakeLists.txt | 1 + test/sanity-check/c++03/CMakeLists.txt | 1 + test/sanity-check/c++11/CMakeLists.txt | 1 + test/sanity-check/c++14/CMakeLists.txt | 1 + test/sanity-check/c++17/CMakeLists.txt | 1 + test/sanity-check/crc16_m17.h.t.cpp | 29 ++++++++++++++++++++++++++ test/test_alignment.cpp | 2 +- test/test_memory.cpp | 12 +++++------ test/vs2019/etl.vcxproj | 28 +++++++++++++++++++++++++ test/vs2019/etl.vcxproj.filters | 3 +++ 10 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 test/sanity-check/crc16_m17.h.t.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index cf1df999..aed36ad8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -59,6 +59,7 @@ add_executable(etl_tests test_crc16_en13757.cpp test_crc16_genibus.cpp test_crc16_kermit.cpp + test_crc16_m17.cpp test_crc16_maxim.cpp test_crc16_mcrf4xx.cpp test_crc16_modbus.cpp diff --git a/test/sanity-check/c++03/CMakeLists.txt b/test/sanity-check/c++03/CMakeLists.txt index 863f49cd..c5545fd9 100644 --- a/test/sanity-check/c++03/CMakeLists.txt +++ b/test/sanity-check/c++03/CMakeLists.txt @@ -88,6 +88,7 @@ target_sources(t98 PRIVATE etl_profile.h ../crc16_en13757.h.t.cpp ../crc16_genibus.h.t.cpp ../crc16_kermit.h.t.cpp + ../crc16_m17.h.t.cpp ../crc16_maxim.h.t.cpp ../crc16_mcrf4xx.h.t.cpp ../crc16_modbus.h.t.cpp diff --git a/test/sanity-check/c++11/CMakeLists.txt b/test/sanity-check/c++11/CMakeLists.txt index 65687b9a..b5c2c4cd 100644 --- a/test/sanity-check/c++11/CMakeLists.txt +++ b/test/sanity-check/c++11/CMakeLists.txt @@ -88,6 +88,7 @@ target_sources(t11 PRIVATE etl_profile.h ../crc16_en13757.h.t.cpp ../crc16_genibus.h.t.cpp ../crc16_kermit.h.t.cpp + ../crc16_m17.h.t.cpp ../crc16_maxim.h.t.cpp ../crc16_mcrf4xx.h.t.cpp ../crc16_modbus.h.t.cpp diff --git a/test/sanity-check/c++14/CMakeLists.txt b/test/sanity-check/c++14/CMakeLists.txt index a0462555..bdabc704 100644 --- a/test/sanity-check/c++14/CMakeLists.txt +++ b/test/sanity-check/c++14/CMakeLists.txt @@ -88,6 +88,7 @@ target_sources(t14 PRIVATE etl_profile.h ../crc16_en13757.h.t.cpp ../crc16_genibus.h.t.cpp ../crc16_kermit.h.t.cpp + ../crc16_m17.h.t.cpp ../crc16_maxim.h.t.cpp ../crc16_mcrf4xx.h.t.cpp ../crc16_modbus.h.t.cpp diff --git a/test/sanity-check/c++17/CMakeLists.txt b/test/sanity-check/c++17/CMakeLists.txt index abaabd55..029d7bf4 100644 --- a/test/sanity-check/c++17/CMakeLists.txt +++ b/test/sanity-check/c++17/CMakeLists.txt @@ -88,6 +88,7 @@ target_sources(t17 PRIVATE etl_profile.h ../crc16_en13757.h.t.cpp ../crc16_genibus.h.t.cpp ../crc16_kermit.h.t.cpp + ../crc16_m17.h.t.cpp ../crc16_maxim.h.t.cpp ../crc16_mcrf4xx.h.t.cpp ../crc16_modbus.h.t.cpp diff --git a/test/sanity-check/crc16_m17.h.t.cpp b/test/sanity-check/crc16_m17.h.t.cpp new file mode 100644 index 00000000..2cbcaa22 --- /dev/null +++ b/test/sanity-check/crc16_m17.h.t.cpp @@ -0,0 +1,29 @@ +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. +https://github.com/ETLCPP/etl +https://www.etlcpp.com + +Copyright(c) 2023 John Wellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#include diff --git a/test/test_alignment.cpp b/test/test_alignment.cpp index 266ed85c..9bd3a721 100644 --- a/test/test_alignment.cpp +++ b/test/test_alignment.cpp @@ -130,7 +130,7 @@ namespace //************************************************************************* TEST(test_is_aligned_tests) { - char alignas(uint32_t) buffer[2U * sizeof(uint32_t)]; + char buffer[2U * sizeof(uint32_t)] alignas(uint32_t); char* p = buffer; diff --git a/test/test_memory.cpp b/test/test_memory.cpp index fabd6153..828b2ca2 100644 --- a/test/test_memory.cpp +++ b/test/test_memory.cpp @@ -1441,22 +1441,22 @@ namespace Data& rdata1b = etl::get_object_at(pbuffer1b); CHECK_FALSE(flags.constructed); CHECK_FALSE(flags.destructed); - CHECK_EQUAL(1, rdata1.a); - CHECK_EQUAL(2, rdata1.b); + CHECK_EQUAL(1, rdata1b.a); + CHECK_EQUAL(2, rdata1b.b); flags.Clear(); Data& rdata2b = etl::get_object_at(pbuffer2b); CHECK_FALSE(flags.constructed); CHECK_FALSE(flags.destructed); - CHECK_EQUAL(data2.a, rdata2.a); - CHECK_EQUAL(data2.b, rdata2.b); + CHECK_EQUAL(data2.a, rdata2b.a); + CHECK_EQUAL(data2.b, rdata2b.b); flags.Clear(); Data& rdata3b = etl::get_object_at(pbuffer3b); CHECK_FALSE(flags.constructed); CHECK_FALSE(flags.destructed); - CHECK_EQUAL(5, rdata3.a); - CHECK_EQUAL(6, rdata3.b); + CHECK_EQUAL(5, rdata3b.a); + CHECK_EQUAL(6, rdata3b.b); flags.Clear(); etl::destroy_object_at(pbuffer1b); diff --git a/test/vs2019/etl.vcxproj b/test/vs2019/etl.vcxproj index 3835e338..f422b800 100644 --- a/test/vs2019/etl.vcxproj +++ b/test/vs2019/etl.vcxproj @@ -4607,6 +4607,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 + true true diff --git a/test/vs2019/etl.vcxproj.filters b/test/vs2019/etl.vcxproj.filters index 82d0c2b4..6473af7e 100644 --- a/test/vs2019/etl.vcxproj.filters +++ b/test/vs2019/etl.vcxproj.filters @@ -3404,6 +3404,9 @@ Tests\Sanity Checks\Source + + Tests\Sanity Checks\Source + From 79d72a1616297f2ca1a6911d53f3ce3cd22763fb Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 20 Feb 2023 11:39:03 +0000 Subject: [PATCH 56/60] Fix alignas syntax --- test/test_alignment.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_alignment.cpp b/test/test_alignment.cpp index 9bd3a721..39e5dc20 100644 --- a/test/test_alignment.cpp +++ b/test/test_alignment.cpp @@ -130,7 +130,7 @@ namespace //************************************************************************* TEST(test_is_aligned_tests) { - char buffer[2U * sizeof(uint32_t)] alignas(uint32_t); + alignas(uint32_t) char buffer[2U * sizeof(uint32_t)]; char* p = buffer; From a89988b8a09758c8441c86c1e4520a94f4bd8285 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Mon, 20 Feb 2023 11:39:29 +0000 Subject: [PATCH 57/60] Fix enable_if syntax --- include/etl/span.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/etl/span.h b/include/etl/span.h index 138af85b..531e68dc 100644 --- a/include/etl/span.h +++ b/include/etl/span.h @@ -881,7 +881,7 @@ namespace etl /// 3. The values in the two ranges are equal. //************************************************************************* template - etl::enable_if_t, etl::remove_cv_t>, bool> + typename etl::enable_if::type, typename etl::remove_cv::type>::value, bool>::type equal(const etl::span& lhs, const etl::span& rhs) { return (lhs.empty() && rhs.empty()) || From 2da1accd190abad2340b367158654deeb538dd72 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 21 Feb 2023 11:52:54 +0000 Subject: [PATCH 58/60] Version updates --- arduino/library-arduino.json | 2 +- arduino/library-arduino.properties | 2 +- include/etl/version.h | 2 +- library.json | 2 +- library.properties | 2 +- version.txt | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arduino/library-arduino.json b/arduino/library-arduino.json index 9130ee02..41574884 100644 --- a/arduino/library-arduino.json +++ b/arduino/library-arduino.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library - Arduino", - "version": "20.35.11", + "version": "20.35.12", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/arduino/library-arduino.properties b/arduino/library-arduino.properties index 6360d9c1..42e91256 100644 --- a/arduino/library-arduino.properties +++ b/arduino/library-arduino.properties @@ -1,5 +1,5 @@ name=Embedded Template Library - Arduino -version=20.35.11 +version=20.35.12 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/include/etl/version.h b/include/etl/version.h index f5272b22..61429066 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 35 -#define ETL_VERSION_PATCH 11 +#define ETL_VERSION_PATCH 12 #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 2bc02502..ae04d750 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "Embedded Template Library", - "version": "20.35.11", + "version": "20.35.12", "authors": { "name": "John Wellbelove", "email": "john.wellbelove@etlcpp.com" diff --git a/library.properties b/library.properties index 8dd949ce..677b2304 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Embedded Template Library -version=20.35.11 +version=20.35.12 author= John Wellbelove maintainer=John Wellbelove license=MIT diff --git a/version.txt b/version.txt index fa556776..7c0f3691 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -20.35.11 +20.35.12 From 4844b54c91a47a9f4725a68418f6896e9c0ffa8b Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 22 Feb 2023 09:36:53 +0000 Subject: [PATCH 59/60] #668 byte_stream changes that add error exceptions have changed previous behaviour --- include/etl/byte_stream.h | 48 --------------------------------------- test/test_byte_stream.cpp | 28 +++++++++++------------ 2 files changed, 14 insertions(+), 62 deletions(-) diff --git a/include/etl/byte_stream.h b/include/etl/byte_stream.h index 2986ff56..4152ff4a 100644 --- a/include/etl/byte_stream.h +++ b/include/etl/byte_stream.h @@ -51,33 +51,6 @@ SOFTWARE. namespace etl { - //*************************************************************************** - /// Exception base for byte streams - //*************************************************************************** - class byte_stream_exception : public etl::exception - { - public: - - byte_stream_exception(string_type reason_, string_type file_name_, numeric_type line_number_) - : exception(reason_, file_name_, line_number_) - { - } - }; - - //*************************************************************************** - ///\ingroup string - /// String empty exception. - //*************************************************************************** - class byte_stream_overflow : public etl::byte_stream_exception - { - public: - - byte_stream_overflow(string_type file_name_, numeric_type line_number_) - : byte_stream_exception(ETL_ERROR_TEXT("byte_stream:overflow", ETL_BYTE_STREAM_FILE_ID"A"), file_name_, line_number_) - { - } - }; - //*************************************************************************** /// Encodes a byte stream. //*************************************************************************** @@ -170,10 +143,6 @@ namespace etl { write_unchecked(value); } - else - { - ETL_ASSERT_FAIL(ETL_ERROR(etl::byte_stream_overflow)); - } return success; } @@ -201,10 +170,6 @@ namespace etl { write_unchecked(value); } - else - { - ETL_ASSERT_FAIL(ETL_ERROR(etl::byte_stream_overflow)); - } return success; } @@ -238,10 +203,6 @@ namespace etl { write_unchecked(range); } - else - { - ETL_ASSERT_FAIL(ETL_ERROR(etl::byte_stream_overflow)); - } return success; } @@ -273,10 +234,6 @@ namespace etl { write_unchecked(start, length); } - else - { - ETL_ASSERT_FAIL(ETL_ERROR(etl::byte_stream_overflow)); - } return success; } @@ -295,10 +252,6 @@ namespace etl { step(n * sizeof(T)); } - else - { - ETL_ASSERT_FAIL(ETL_ERROR(etl::byte_stream_overflow)); - } return success; } @@ -756,7 +709,6 @@ namespace etl } else { - ETL_ASSERT_FAIL(ETL_ERROR(etl::byte_stream_overflow)); return false; } } diff --git a/test/test_byte_stream.cpp b/test/test_byte_stream.cpp index 4f89c3a8..8bd55036 100644 --- a/test/test_byte_stream.cpp +++ b/test/test_byte_stream.cpp @@ -152,8 +152,8 @@ namespace CHECK_EQUAL(sizeof(uint8_t) + sizeof(uint16_t), (std::distance(used_span.begin(), used_span.end()))); CHECK_EQUAL(std::size(storage) - sizeof(uint8_t) - sizeof(uint16_t), (std::distance(free_span.begin(), free_span.end()))); - CHECK(writer.write(uint32_t(0x12345678U))); // 4 more written. - CHECK_THROW(writer.write(uint32_t(0x12345678U)), etl::byte_stream_overflow); // Can't write 4 more. + CHECK(writer.write(uint32_t(0x12345678U))); // 4 more written. + CHECK_FALSE(writer.write(uint32_t(0x12345678U))); // Can't write 4 more. CHECK(!writer.empty()); CHECK(!writer.full()); @@ -186,7 +186,7 @@ namespace CHECK(byte_stream.write(false)); // One too many. - CHECK_THROW(byte_stream.write(true), etl::byte_stream_overflow); + CHECK_FALSE(byte_stream.write(true)); CHECK_ARRAY_EQUAL(result, storage, 8); } @@ -207,7 +207,7 @@ namespace } // One too many. - CHECK_THROW(byte_stream.write(int8_t(0)), etl::byte_stream_overflow); + CHECK_FALSE(byte_stream.write(int8_t(0))); for (size_t i = 0; i < storage.size(); ++i) { @@ -231,7 +231,7 @@ namespace } // One too many. - CHECK_THROW(byte_stream.write(uint8_t(0U)), etl::byte_stream_overflow); + CHECK_FALSE(byte_stream.write(uint8_t(0U))); for (size_t i = 0U; i < storage.size(); ++i) { @@ -255,7 +255,7 @@ namespace CHECK(byte_stream.write(int16_t(0xFFFF))); // One too many. - CHECK_THROW(byte_stream.write(int16_t(0)), etl::byte_stream_overflow); + CHECK_FALSE(byte_stream.write(int16_t(0))); for (size_t i = 0; i < storage.size(); ++i) { @@ -279,7 +279,7 @@ namespace CHECK(byte_stream.write(uint16_t(0xFFFFU))); // One too many. - CHECK_THROW(byte_stream.write(uint16_t(0U)), etl::byte_stream_overflow); + CHECK_FALSE(byte_stream.write(uint16_t(0U))); for (size_t i = 0; i < storage.size(); ++i) { @@ -306,7 +306,7 @@ namespace CHECK(byte_stream.write(int32_t(0xFFFFFFFF))); // One too many. - CHECK_THROW(byte_stream.write(int32_t(0)), etl::byte_stream_overflow); + CHECK_FALSE(byte_stream.write(int32_t(0))); for (size_t i = 0U; i < storage.size(); ++i) { @@ -333,7 +333,7 @@ namespace CHECK(byte_stream.write(uint32_t(0xFFFFFFFFU))); // One too many. - CHECK_THROW(byte_stream.write(uint32_t(0)), etl::byte_stream_overflow); + CHECK_FALSE(byte_stream.write(uint32_t(0))); for (size_t i = 0U; i < storage.size(); ++i) { @@ -360,7 +360,7 @@ namespace CHECK(byte_stream.write(int64_t(0xFFFFFFFFFFFFFFFF))); // One too many. - CHECK_THROW(byte_stream.write(int64_t(0)), etl::byte_stream_overflow); + CHECK_FALSE(byte_stream.write(int64_t(0))); for (size_t i = 0U; i < storage.size(); ++i) { @@ -387,7 +387,7 @@ namespace CHECK(byte_stream.write(uint64_t(0xFFFFFFFFFFFFFFFFU))); // One too many. - CHECK_THROW(byte_stream.write(uint64_t(0)), etl::byte_stream_overflow); + CHECK_FALSE(byte_stream.write(uint64_t(0))); for (size_t i = 0U; i < storage.size(); ++i) { @@ -413,7 +413,7 @@ namespace CHECK(byte_stream.write(int32_t(0x01020304))); CHECK(byte_stream.skip(2)); CHECK(byte_stream.write(int32_t(0x05060708))); - CHECK_THROW(byte_stream.skip(1), etl::byte_stream_overflow); + CHECK_FALSE(byte_stream.skip(1)); for (size_t i = 0U; i < storage.size(); ++i) { @@ -437,7 +437,7 @@ namespace CHECK(result[0] = byte_stream.read()); CHECK(byte_stream.skip(2)); CHECK(result[3] = byte_stream.read()); - CHECK_THROW(byte_stream.skip(2), etl::byte_stream_overflow); + CHECK_FALSE(byte_stream.skip(2)); for (size_t i = 0U; i < result.size(); ++i) { @@ -1242,7 +1242,7 @@ namespace reader.restart(); // Skip five int16_t (too many) - CHECK_THROW(reader.skip(5U), etl::byte_stream_overflow); + CHECK_FALSE(reader.skip(5U)); } //************************************************************************* From 78c547f7ca6fe7b3fc99d13f194504539975c26e Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 23 Feb 2023 09:51:12 +0000 Subject: [PATCH 60/60] Updated release notes --- support/Release notes.txt | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/support/Release notes.txt b/support/Release notes.txt index 6b2f9159..0d11c2ac 100644 --- a/support/Release notes.txt +++ b/support/Release notes.txt @@ -1,6 +1,21 @@ =============================================================================== 20.35.12 -#649 subscript-1 is out of bounds. Changed intrusive_list and intrusive_forward_list iterator constructor parameter from reference to pointer. +#615 Addition of etl::expected +#649 Changed intrusive_list and intrusive_forward_list iterator constructor parameter from reference to pointer. +#667 etl::span copy constructor with original span with fixed extent causes pend iterator to be invalid +#668 byte_stream changes that add error exceptions have changed previous behaviour +#670 span equality operators +#672 HFSM-specific start() and reset() +Fixed span templated copy constructor +Added destination_router_id parameter overrides to receive() virtual functions +Added ""_sv string view operators +Added M17 CRC +Added repair() to etl::circular_buffer +Added etl::contruct_object_at, etl::get_object_at and etl::destroy_object_at +Added etl::is_aligned, etl::alignment_exception and etl::alignment_error +Removed unnecessary code in etl::vector_ext::repair() +Updated sanity check make files +C++03 compatibility improvements =============================================================================== 20.35.11