From a1bf74009f10fc9cefb3d6f57db58bb51076e8a1 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Thu, 27 Oct 2022 09:52:39 +0100 Subject: [PATCH] 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 +