Work-In-Progress

This commit is contained in:
John Wellbelove 2022-10-27 09:52:39 +01:00
parent cea3aea259
commit a1bf74009f
5 changed files with 229 additions and 119 deletions

View File

@ -35,10 +35,56 @@ SOFTWARE.
///\ingroup utilities ///\ingroup utilities
#include "platform.h" #include "platform.h"
#include "exception.h"
#include "error_handler.h"
#include "utility.h" #include "utility.h"
#include "variant.h"
namespace etl 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 <typename TError>
class expected_invalid;
//*******************************************
template<>
class expected_invalid<void> : 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 <typename TError>
class expected_invalid : etl::expected_invalid<void>
{
public:
expected_invalid(string_type file_name_, numeric_type line_number_)
: expected_invalid<void>(file_name_, line_number_)
{
}
};
//*************************************************************************** //***************************************************************************
/// Unexpected type. /// Unexpected type.
/// etl::unexpected represents an unexpected value stored in etl::expected. /// etl::unexpected represents an unexpected value stored in etl::expected.
@ -56,6 +102,7 @@ namespace etl
{ {
} }
#if ETL_CPP11_SUPPORTED
//******************************************* //*******************************************
/// Move constructor. /// Move constructor.
//******************************************* //*******************************************
@ -63,24 +110,25 @@ namespace etl
: error_value(etl::move(other.error_value)) : error_value(etl::move(other.error_value))
{ {
} }
#endif
#if ETL_CPP11_SUPPORTED #if ETL_CPP11_SUPPORTED
//******************************************* //*******************************************
/// Construct from argument. /// Construct from argument.
//******************************************* //*******************************************
template <typename E = TError, typename = typename etl::enable_if<!etl::is_same<typename etl::remove_cvref<Err>::type, etl::unexpected>::value && template <typename TErr = TError, typename = typename etl::enable_if<!etl::is_same<typename etl::remove_cvref<TErr>::type, etl::unexpected>::value &&
!etl::is_same<typename etl::remove_cvref<Err>::type, etl::in_place_t>::value, int>::type> !etl::is_same<typename etl::remove_cvref<TErr>::type, etl::in_place_t>::value, int>::type>
constexpr explicit unexpected(E&& e) constexpr explicit unexpected(TErr&& e)
: error_value(etl::forward<TError>(e)) : error_value(etl::forward<TErr>(e))
{ {
} }
#else #else
//******************************************* //*******************************************
/// Construct from argument. /// Construct from argument.
//******************************************* //*******************************************
template <typename E> template <typename TErr>
explicit unexpected(const E& e, typename etl::enable_if<!etl::is_same<typename etl::remove_cvref<Err>::type, etl::unexpected>::value && explicit unexpected(const TErr& e, typename etl::enable_if<!etl::is_same<typename etl::remove_cvref<TErr>::type, etl::unexpected>::value &&
!etl::is_same<typename etl::remove_cvref<Err>::type, etl::in_place_t>::value, int>::type = 0) !etl::is_same<typename etl::remove_cvref<TErr>::type, etl::in_place_t>::value, int>::type = 0)
: error_value(e) : error_value(e)
{ {
} }
@ -111,7 +159,7 @@ namespace etl
//******************************************* //*******************************************
/// Assign from etl::unexpected. /// Assign from etl::unexpected.
//******************************************* //*******************************************
unexpected& operator =(const etl::unexpected& rhs) unexpected<TError>& operator =(const etl::unexpected<TError>& rhs)
{ {
error_value = rhs.error_value; error_value = rhs.error_value;
} }
@ -120,7 +168,7 @@ namespace etl
//******************************************* //*******************************************
/// Move assign from etl::unexpected. /// Move assign from etl::unexpected.
//******************************************* //*******************************************
unexpected& operator =(etl::unexpected&& rhs) unexpected<TError>& operator =(etl::unexpected<TError>&& rhs)
{ {
error_value = etl::move(rhs.error_value); error_value = etl::move(rhs.error_value);
} }
@ -137,7 +185,7 @@ namespace etl
//******************************************* //*******************************************
/// Swap with another etl::unexpected. /// Swap with another etl::unexpected.
//******************************************* //*******************************************
swap(etl::unexpected& other) void swap(etl::unexpected<TError>& other)
{ {
using ETL_OR_STD::swap; using ETL_OR_STD::swap;
@ -195,13 +243,13 @@ namespace etl
#if ETL_CPP11_SUPPORTED #if ETL_CPP11_SUPPORTED
template <typename U> template <typename U>
using rebind = etl::expected<U, error_type>; using rebind = etl::expected<U, TError>;
#endif #endif
//******************************************* //*******************************************
/// Default constructor /// Default constructor
//******************************************* //*******************************************
ETL_CONSTEXPR14 expected(const expected& other) ETL_NOEXCEPT ETL_CONSTEXPR14 expected() ETL_NOEXCEPT
: data(TValue()) : data(TValue())
{ {
} }
@ -209,7 +257,7 @@ namespace etl
//******************************************* //*******************************************
/// Copy constructor /// Copy constructor
//******************************************* //*******************************************
ETL_CONSTEXPR14 expected(const expected& other) ETL_CONSTEXPR14 expected(const expected& other) ETL_NOEXCEPT
: data(other.data) : data(other.data)
{ {
} }
@ -224,111 +272,49 @@ namespace etl
} }
#endif #endif
template <typename U, typename F>
constexpr explicit() expected(const expected<U, F>& other)
{
}
template <typename U, typename F>
constexpr explicit(expected(expected<U, F>&& other)
{
}
#if ETL_CPP11_SUPPORTED
template <typename U = T>
constexpr explicit expected(U&& v)
{
}
#endif
template <typename F> template <typename F>
constexpr explicit expected(const etl::unexpected<F>& e) ETL_CONSTEXPR14 explicit expected(const etl::unexpected<F>& ue)
: data(ue)
{ {
} }
#if ETL_CPP11_SUPPORTED #if ETL_CPP11_SUPPORTED
template <typename F> template <typename F>
constexpr explicit expected(etl::unexpected<F>&& e) ETL_CONSTEXPR14 explicit expected(etl::unexpected<F>&& ue)
: data(etl::move(ue))
{ {
} }
#endif #endif
constexpr explicit expected(etl::in_place_t) noexcept ETL_CONSTEXPR14 explicit expected(etl::in_place_t) ETL_NOEXCEPT
: data(TValue())
{ {
} }
template <typename... Args> template <typename... Args>
constexpr explicit expected(etl::in_place_t, Args&&... args) ETL_CONSTEXPR14 explicit expected(etl::in_place_t, Args&&... args)
: data(etl::forward<Args>(args)...)
{ {
} }
template <typename U, typename... Args> template <typename U, typename... Args>
constexpr explicit expected(etl::in_place_t, std::initializer_list<U> il, Args&&... args) ETL_CONSTEXPR14 explicit expected(etl::in_place_t, std::initializer_list<U> il, Args&&... args)
: data(il, etl::forward<Args>(args)...)
{ {
} }
template <typename... Args> template <typename... Args>
constexpr explicit expected(etl::unexpect_t, Args&&... args) ETL_CONSTEXPR14 explicit expected(etl::unexpect_t, Args&&... args)
: data(etl::unexpected<TError>(args...))
{ {
} }
template <typename U, typename... Args> template <typename U, typename... Args>
constexpr explicit expected(etl::unexpect_t, std::initializer_list<U> il, Args&&... args) ETL_CONSTEXPR14 explicit expected(etl::unexpect_t, std::initializer_list<U> il, Args&&... args)
: data(etl::unexpected<TError>(il, args...))
{ {
} }
// //*******************************************
// // Construct from a value
// //*******************************************
// expected(const TValue& value)
// : data(value)
// {
// }
//
//#if ETL_CPP11_SUPPORTED
// //*******************************************
// // Move construct from a value
// //*******************************************
// expected(TValue&& value)
// : data(etl::move(value))
// {
// }
//#endif
////*******************************************
///// Construct from error
////*******************************************
//expected(const TError& error)
// : data(error)
//{
//}
////*******************************************
///// Move construct from error
////*******************************************
//expected(TError&& error)
// : data(etl::move(error))
//{
//}
//*******************************************
/// Copy assign
//*******************************************
expected& operator =(const expected& other)
{
data = other.data;
return *this;
}
//*******************************************
/// Move assign
//*******************************************
expected& operator =(expected&& other)
{
data = etl::move(other.data);
return *this;
}
//******************************************* //*******************************************
/// Copy assign from value /// Copy assign from value
//******************************************* //*******************************************
@ -365,6 +351,39 @@ namespace etl
return *this; return *this;
} }
#if ETL_CPP11_SUPPORTED
//*******************************************
///
//*******************************************
ETL_CONSTEXPR14 T& value() &
{
return etl::get<TValue>(data);
}
//*******************************************
///
//*******************************************
ETL_CONSTEXPR14 const T& value() const&
{
return etl::get<TValue>(data);
}
//*******************************************
///
//*******************************************
ETL_CONSTEXPR14 T&& value() &&
{
return etl::move(etl::get<TValue>(data));
}
//*******************************************
///
//*******************************************
ETL_CONSTEXPR14 const T&& value() const&&
{
return etl::move(etl::get<TValue>(data));
}
#else
//******************************************* //*******************************************
/// Returns a const reference to the value. /// Returns a const reference to the value.
/// Undefined if the expected does not contain an value. /// Undefined if the expected does not contain an value.
@ -373,15 +392,7 @@ namespace etl
{ {
return etl::get<TValue>(data); return etl::get<TValue>(data);
} }
#endif
//*******************************************
/// 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<TValue>(etl::move(data)));
}
#if ETL_CPP11_SUPPORTED #if ETL_CPP11_SUPPORTED
//******************************************* //*******************************************
@ -433,6 +444,39 @@ namespace etl
} }
#endif #endif
#if ETL_CPP11_SUPPORTED
//*******************************************
///
//*******************************************
ETL_CONSTEXPR14 const TError& error() const& ETL_NOEXCEPT
{
return etl::get<TError>(data);
}
//*******************************************
///
//*******************************************
ETL_CONSTEXPR14 TError& error() & ETL_NOEXCEPT
{
return etl::get<TError>(data);
}
//*******************************************
///
//*******************************************
ETL_CONSTEXPR14 const TError&& error() const&& ETL_NOEXCEPT
{
return etl::move(etl::get<TError>(data));
}
//*******************************************
///
//*******************************************
ETL_CONSTEXPR14 TError&& error() && ETL_NOEXCEPT
{
return etl::move(etl::get<TError>(data));
}
#else
//******************************************* //*******************************************
/// Returns a const reference to the error. /// Returns a const reference to the error.
/// Undefined if the expected does not contain an error. /// Undefined if the expected does not contain an error.
@ -441,34 +485,82 @@ namespace etl
{ {
return etl::get<TError>(data); return etl::get<TError>(data);
} }
#endif
#if (ETL_CPP11_SUPPORTED) #if ETL_CPP11_SUPPORTED
//******************************************* //*******************************************
/// Returns an rvalue reference to the error. ///
/// Undefined if the expected does not contain an error.
//******************************************* //*******************************************
ETL_CONSTEXPR14 TError&& error() && template <typename... Args>
ETL_CONSTEXPR14 T& emplace(Args&&... args) ETL_NOEXCEPT
{ {
return etl::move(etl::get<TError>(data)); data.emplace(args...);
} }
//******************************************* //*******************************************
/// Returns an rvalue reference to the error. ///
/// Undefined if the expected does not contain an error.
//******************************************* //*******************************************
ETL_CONSTEXPR14 TError&& error() const && template <typename U, typename... Args>
ETL_CONSTEXPR14 T& emplace(std::initializer_list<U>& il, Args&&... args) ETL_NOEXCEPT
{ {
return etl::move(etl::get<TError>(data)); data.emplace(il, args...);
} }
#endif #endif
//*******************************************
///
//*******************************************
TValue* operator ->()
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(valid, ETL_ERROR(expected_invalid));
#endif
return etl::addressof(data.get<TValue>());
}
//*******************************************
///
//*******************************************
const TValue* operator ->() const
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(valid, ETL_ERROR(expected_invalid));
#endif
return etl::addressof(data.get<TValue>());
}
//*******************************************
///
//*******************************************
TValue& operator *()
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(valid, ETL_ERROR(expected_invalid));
#endif
return data.get<TValue>();
}
//*******************************************
///
//*******************************************
const TValue& operator *() const
{
#if ETL_IS_DEBUG_BUILD
ETL_ASSERT(valid, ETL_ERROR(expected_invalid));
#endif
return data.get<TValue>();
}
private: private:
etl::variant<TValue, TError> data; etl::variant<TValue, TError> data;
}; };
//***************************************************************************** //*****************************************************************************
/// Result type.
/// Specialisation for void value type. /// Specialisation for void value type.
//***************************************************************************** //*****************************************************************************
template<typename TError> template<typename TError>

View File

@ -100,5 +100,5 @@ SOFTWARE.
#define ETL_BIP_BUFFER_SPSC_ATOMIC_FILE_ID "67" #define ETL_BIP_BUFFER_SPSC_ATOMIC_FILE_ID "67"
#define ETL_REFERENCE_COUNTED_OBJECT_FILE_ID "68" #define ETL_REFERENCE_COUNTED_OBJECT_FILE_ID "68"
#define ETL_TO_ARITHMETIC_FILE_ID "69" #define ETL_TO_ARITHMETIC_FILE_ID "69"
#define ETL_EXPECTED_FILE_ID "70"
#endif #endif

View File

@ -91,7 +91,7 @@ namespace etl
public: public:
optional_invalid(string_type file_name_, numeric_type line_number_) 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. /// An optional type.
/// If the optional type is not initialised then a type is not constructed. /// If the optional type is not initialised then a type is not constructed.
/// See http://en.cppreference.com/w/cpp/utility/optional /// See http://en.cppreference.com/w/cpp/utility/optional
///\tparam The type to store. ///\tparam T The type to store.
///\ingroup utilities ///\ingroup utilities
//***************************************************************************** //*****************************************************************************
template <typename T, bool is_pod = etl::is_pod<T>::value> template <typename T, bool is_pod = etl::is_pod<T>::value>
@ -516,6 +516,8 @@ namespace etl
//***************************************************************************** //*****************************************************************************
/// For POD types. /// For POD types.
///\tparam T The type to store.
///\ingroup utilities
//***************************************************************************** //*****************************************************************************
template <typename T> template <typename T>
class optional<T, true> class optional<T, true>

View File

@ -49,7 +49,7 @@ namespace etl
/// Result type. /// Result type.
//***************************************************************************** //*****************************************************************************
template <typename TValue, typename TError> template <typename TValue, typename TError>
class result class ETL_DEPRECATED result
{ {
public: public:
@ -66,6 +66,7 @@ namespace etl
{ {
} }
#if ETL_CPP11_SUPPORTED
//******************************************* //*******************************************
/// Move constructor /// Move constructor
//******************************************* //*******************************************
@ -73,6 +74,7 @@ namespace etl
: data(etl::move(other.data)) : data(etl::move(other.data))
{ {
} }
#endif
//******************************************* //*******************************************
// Construct from a value // Construct from a value
@ -85,7 +87,7 @@ namespace etl
//******************************************* //*******************************************
// Move construct from a value // Move construct from a value
//******************************************* //*******************************************
result(TValue&& value) result(TValue&& value)
: data(etl::move(value)) : data(etl::move(value))
{ {
} }
@ -101,10 +103,12 @@ namespace etl
//******************************************* //*******************************************
/// Move construct from error /// Move construct from error
//******************************************* //*******************************************
#if ETL_CPP11_SUPPORTED
result(TError&& error) result(TError&& error)
: data(etl::move(error)) : data(etl::move(error))
{ {
} }
#endif
//******************************************* //*******************************************
/// Copy assign /// Copy assign
@ -136,11 +140,13 @@ namespace etl
//******************************************* //*******************************************
/// Move assign from value /// Move assign from value
//******************************************* //*******************************************
#if ETL_CPP11_SUPPORTED
result& operator =(TValue&& value) result& operator =(TValue&& value)
{ {
data = etl::move(value); data = etl::move(value);
return *this; return *this;
} }
#endif
//******************************************* //*******************************************
/// Copy assign from error /// Copy assign from error
@ -154,11 +160,13 @@ namespace etl
//******************************************* //*******************************************
/// Move assign from error /// Move assign from error
//******************************************* //*******************************************
#if ETL_CPP11_SUPPORTED
result& operator =(TError&& error) result& operator =(TError&& error)
{ {
data = etl::move(error); data = etl::move(error);
return *this; return *this;
} }
#endif
//******************************************* //*******************************************
/// <b>true</b> if result contains a value /// <b>true</b> if result contains a value
@ -215,10 +223,12 @@ namespace etl
/// Returns an rvalue reference to the error. /// Returns an rvalue reference to the error.
/// Undefined if the result does not contain an error. /// Undefined if the result does not contain an error.
//******************************************* //*******************************************
#if ETL_CPP11_SUPPORTED
TError&& error() TError&& error()
{ {
return etl::move(etl::get<TError>(etl::move(data))); return etl::move(etl::get<TError>(etl::move(data)));
} }
#endif
private: private:
@ -269,10 +279,12 @@ namespace etl
//******************************************* //*******************************************
/// Move construct from error /// Move construct from error
//******************************************* //*******************************************
#if ETL_CPP11_SUPPORTED
result(TError&& err_) result(TError&& err_)
: err(etl::move(err_)) : err(etl::move(err_))
{ {
} }
#endif
//******************************************* //*******************************************
/// Copy assign from error /// Copy assign from error
@ -286,11 +298,13 @@ namespace etl
//******************************************* //*******************************************
/// Move assign from error /// Move assign from error
//******************************************* //*******************************************
#if ETL_CPP11_SUPPORTED
result& operator =(TError&& err_) result& operator =(TError&& err_)
{ {
err = etl::move(err_); err = etl::move(err_);
return *this; return *this;
} }
#endif
//******************************************* //*******************************************
/// <b>true</b> if result contains a value /// <b>true</b> if result contains a value
@ -321,10 +335,12 @@ namespace etl
/// Returns an rvalue reference to the error. /// Returns an rvalue reference to the error.
/// Undefined if the result does not contain an error. /// Undefined if the result does not contain an error.
//******************************************* //*******************************************
#if ETL_CPP11_SUPPORTED
TError&& error() TError&& error()
{ {
return etl::move(err); return etl::move(err);
} }
#endif
private: private:

View File

@ -345,9 +345,6 @@
<ClInclude Include="..\..\include\etl\io_port.h"> <ClInclude Include="..\..\include\etl\io_port.h">
<Filter>ETL\Utilities</Filter> <Filter>ETL\Utilities</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\include\etl\optional.h">
<Filter>ETL\Containers</Filter>
</ClInclude>
<ClInclude Include="..\..\include\etl\set.h"> <ClInclude Include="..\..\include\etl\set.h">
<Filter>ETL\Containers</Filter> <Filter>ETL\Containers</Filter>
</ClInclude> </ClInclude>
@ -1344,6 +1341,9 @@
<ClInclude Include="..\..\include\etl\expected.h"> <ClInclude Include="..\..\include\etl\expected.h">
<Filter>ETL\Utilities</Filter> <Filter>ETL\Utilities</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\include\etl\optional.h">
<Filter>ETL\Utilities</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\test_string_char.cpp"> <ClCompile Include="..\test_string_char.cpp">
@ -2192,9 +2192,6 @@
<ClCompile Include="..\test_random.cpp"> <ClCompile Include="..\test_random.cpp">
<Filter>Tests\Maths</Filter> <Filter>Tests\Maths</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\test_optional.cpp">
<Filter>Tests\Containers</Filter>
</ClCompile>
<ClCompile Include="..\test_error_handler.cpp"> <ClCompile Include="..\test_error_handler.cpp">
<Filter>Tests\Errors</Filter> <Filter>Tests\Errors</Filter>
</ClCompile> </ClCompile>
@ -3392,6 +3389,9 @@
<ClCompile Include="..\sanity-check\to_arithmetic.h.t.cpp"> <ClCompile Include="..\sanity-check\to_arithmetic.h.t.cpp">
<Filter>Tests\Sanity Checks\Source</Filter> <Filter>Tests\Sanity Checks\Source</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\test_optional.cpp">
<Filter>Tests\Misc</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\library.properties"> <None Include="..\..\library.properties">