From 18ab6457631100472039d8b49c2d75966a7e08b8 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 15 Oct 2022 14:28:58 +0100 Subject: [PATCH 1/5] 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 dd68c7525..d9577b4cb 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 000000000..991625b73 --- /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 2/5] 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 000000000..991625b73 --- /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 3/5] 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 000000000..991625b73 --- /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 4/5] 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 991625b73..252008f2e 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 63d366d51..c855b06b2 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 bb5c004eb..fffd334eb 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 5/5] Work-In-Progress --- include/etl/expected.h | 302 ++++++++++++++++++++----------- 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, 226 insertions(+), 116 deletions(-) diff --git a/include/etl/expected.h b/include/etl/expected.h index 252008f2e..9b8d86e86 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,109 +272,47 @@ 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) - { - } - -// //******************************************* -// // 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) + ETL_CONSTEXPR14 explicit expected(etl::unexpect_t, std::initializer_list il, Args&&... args) + : data(etl::unexpected(il, args...)) { - data = etl::move(other.data); - return *this; } //******************************************* @@ -365,23 +351,48 @@ namespace etl return *this; } +#if ETL_CPP11_SUPPORTED //******************************************* - /// Returns a const reference to the value. - /// Undefined if the expected does not contain an value. + /// //******************************************* - ETL_CONSTEXPR14 const TValue& value() const + ETL_CONSTEXPR14 T& value() & { return etl::get(data); } //******************************************* - /// Returns an rvalue reference to the value. + /// + //******************************************* + 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 TValue&& value() + ETL_CONSTEXPR14 const TValue& value() const { - return etl::move(etl::get(etl::move(data))); + return etl::get(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. + /// + //******************************************* + template + ETL_CONSTEXPR14 T& emplace(Args&&... args) ETL_NOEXCEPT + { + data.emplace(args...); + } + + //******************************************* + /// //******************************************* - ETL_CONSTEXPR14 TError&& error() && + template + ETL_CONSTEXPR14 T& emplace(std::initializer_list& il, Args&&... args) ETL_NOEXCEPT { - return etl::move(etl::get(data)); + data.emplace(il, args...); } +#endif //******************************************* - /// Returns an rvalue reference to the error. - /// Undefined if the expected does not contain an error. + /// //******************************************* - ETL_CONSTEXPR14 TError&& error() const && + TValue* operator ->() { - return etl::move(etl::get(data)); +#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 7d6a0e1a7..b0500c481 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 9370b5368..8de5197a1 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 9d79dbf4e..33653c664 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 fffd334eb..f3bb0187f 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 +