From 18ab6457631100472039d8b49c2d75966a7e08b8 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 15 Oct 2022 14:28:58 +0100 Subject: [PATCH] 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 +