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