mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Add begin() and end() to etl::expected (#1410)
* Print test names at test time (#1343) * Fix operator| conflict with std::ranges (#1395) * Add begin() and end() to etl::expected * Adding error_or() to etl::expected --------- Co-authored-by: John Wellbelove <john.wellbelove@etlcpp.com> Co-authored-by: John Wellbelove <jwellbelove@users.noreply.github.com>
This commit is contained in:
parent
fe7b2da10c
commit
ee0d4740b3
@ -604,6 +604,38 @@ namespace etl
|
||||
return etl::move(etl::get<Error_Type>(storage));
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Get the error or a default value.
|
||||
//*******************************************
|
||||
template <typename G>
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 etl::enable_if_t<etl::is_convertible<G, error_type>::value, error_type> error_or(G&& default_error) const&
|
||||
{
|
||||
if (has_value())
|
||||
{
|
||||
return static_cast<error_type>(etl::forward<G>(default_error));
|
||||
}
|
||||
else
|
||||
{
|
||||
return error();
|
||||
}
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Get the error or a default value.
|
||||
//*******************************************
|
||||
template <typename G>
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 etl::enable_if_t<etl::is_convertible<G, error_type>::value, error_type> error_or(G&& default_error) &&
|
||||
{
|
||||
if (has_value())
|
||||
{
|
||||
return static_cast<error_type>(etl::forward<G>(default_error));
|
||||
}
|
||||
else
|
||||
{
|
||||
return etl::move(error());
|
||||
}
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Swap with another etl::expected.
|
||||
//*******************************************
|
||||
@ -661,6 +693,22 @@ namespace etl
|
||||
{
|
||||
return etl::get<Error_Type>(storage);
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Get the error or a default value.
|
||||
//*******************************************
|
||||
template <typename G>
|
||||
error_type error_or(const G& default_error) const
|
||||
{
|
||||
if (has_value())
|
||||
{
|
||||
return static_cast<error_type>(default_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
return error();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//*******************************************
|
||||
@ -725,6 +773,39 @@ namespace etl
|
||||
}
|
||||
#endif
|
||||
|
||||
//*******************************************
|
||||
/// Returns a pointer to the value if has_value(), otherwise returns nullptr.
|
||||
/// Allows expected to be used as a range of 0 or 1 elements.
|
||||
//*******************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 value_type* begin() ETL_NOEXCEPT
|
||||
{
|
||||
return has_value() ? &etl::get<value_type>(storage) : ETL_NULLPTR;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Returns a pointer past the value if has_value(), otherwise returns nullptr.
|
||||
//*******************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 value_type* end() ETL_NOEXCEPT
|
||||
{
|
||||
return has_value() ? &etl::get<value_type>(storage) + 1 : ETL_NULLPTR;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Returns a const pointer to the value if has_value(), otherwise returns nullptr.
|
||||
//*******************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 const value_type* begin() const ETL_NOEXCEPT
|
||||
{
|
||||
return has_value() ? &etl::get<value_type>(storage) : ETL_NULLPTR;
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Returns a const pointer past the value if has_value(), otherwise returns nullptr.
|
||||
//*******************************************
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 const value_type* end() const ETL_NOEXCEPT
|
||||
{
|
||||
return has_value() ? &etl::get<value_type>(storage) + 1 : ETL_NULLPTR;
|
||||
}
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
template <typename F, typename U = typename etl::remove_cvref< typename etl::invoke_result<F, void, TValue&>::type>::type>
|
||||
auto transform(F&& f) & -> expected<U, TError>
|
||||
@ -1065,6 +1146,38 @@ namespace etl
|
||||
{
|
||||
return etl::move(etl::get<Error_Type>(storage));
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Get the error or a default value.
|
||||
//*******************************************
|
||||
template <typename G>
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 etl::enable_if_t<etl::is_convertible<G, error_type>::value, error_type> error_or(G&& default_error) const&
|
||||
{
|
||||
if (has_value())
|
||||
{
|
||||
return static_cast<error_type>(etl::forward<G>(default_error));
|
||||
}
|
||||
else
|
||||
{
|
||||
return error();
|
||||
}
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Get the error or a default value.
|
||||
//*******************************************
|
||||
template <typename G>
|
||||
ETL_NODISCARD ETL_CONSTEXPR14 etl::enable_if_t<etl::is_convertible<G, error_type>::value, error_type> error_or(G&& default_error) &&
|
||||
{
|
||||
if (has_value())
|
||||
{
|
||||
return static_cast<error_type>(etl::forward<G>(default_error));
|
||||
}
|
||||
else
|
||||
{
|
||||
return etl::move(error());
|
||||
}
|
||||
}
|
||||
#else
|
||||
//*******************************************
|
||||
/// Returns the error
|
||||
@ -1074,6 +1187,22 @@ namespace etl
|
||||
{
|
||||
return etl::get<Error_Type>(storage);
|
||||
}
|
||||
|
||||
//*******************************************
|
||||
/// Get the error or a default value.
|
||||
//*******************************************
|
||||
template <typename G>
|
||||
error_type error_or(const G& default_error) const
|
||||
{
|
||||
if (has_value())
|
||||
{
|
||||
return static_cast<error_type>(default_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
return error();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//*******************************************
|
||||
|
||||
@ -31,6 +31,7 @@ SOFTWARE.
|
||||
#include "etl/expected.h"
|
||||
#include "etl/type_traits.h"
|
||||
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -1477,5 +1478,143 @@ namespace
|
||||
auto with_error_type_check = check_expected_type_helper<void, std::string>(unexpected_out);
|
||||
CHECK_TRUE(with_error_type_check);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_begin_end_with_value)
|
||||
{
|
||||
etl::expected<std::string, Error> exp(std::string("hello"));
|
||||
|
||||
CHECK_TRUE(exp.begin() != exp.end());
|
||||
CHECK_EQUAL(std::distance(exp.begin(), exp.end()), 1);
|
||||
CHECK_EQUAL(*exp.begin(), std::string("hello"));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_begin_end_with_error)
|
||||
{
|
||||
etl::expected<std::string, Error> exp(etl::unexpected<Error>(Error("err")));
|
||||
|
||||
CHECK_TRUE(exp.begin() == exp.end());
|
||||
CHECK_EQUAL(std::distance(exp.begin(), exp.end()), 0);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_begin_end_const_with_value)
|
||||
{
|
||||
const etl::expected<std::string, Error> exp(std::string("world"));
|
||||
|
||||
CHECK_TRUE(exp.begin() != exp.end());
|
||||
CHECK_EQUAL(std::distance(exp.begin(), exp.end()), 1);
|
||||
CHECK_EQUAL(*exp.begin(), std::string("world"));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_begin_end_const_with_error)
|
||||
{
|
||||
const etl::expected<std::string, Error> exp(etl::unexpected<Error>(Error("err")));
|
||||
|
||||
CHECK_TRUE(exp.begin() == exp.end());
|
||||
CHECK_EQUAL(std::distance(exp.begin(), exp.end()), 0);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_range_for_with_value)
|
||||
{
|
||||
etl::expected<int, Error> exp(42);
|
||||
|
||||
int count = 0;
|
||||
int sum = 0;
|
||||
for (auto& v : exp)
|
||||
{
|
||||
++count;
|
||||
sum += v;
|
||||
}
|
||||
|
||||
CHECK_EQUAL(1, count);
|
||||
CHECK_EQUAL(42, sum);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_range_for_with_error)
|
||||
{
|
||||
etl::expected<int, Error> exp(etl::unexpected<Error>(Error("err")));
|
||||
|
||||
int count = 0;
|
||||
for (auto& v : exp)
|
||||
{
|
||||
(void)v;
|
||||
++count;
|
||||
}
|
||||
|
||||
CHECK_EQUAL(0, count);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_error_or_with_value)
|
||||
{
|
||||
etl::expected<int, Error> exp(42);
|
||||
|
||||
Error result = exp.error_or(Error("default"));
|
||||
CHECK_EQUAL("default", result.e);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_error_or_with_error)
|
||||
{
|
||||
etl::expected<int, Error> exp(etl::unexpected<Error>(Error("real_error")));
|
||||
|
||||
Error result = exp.error_or(Error("default"));
|
||||
CHECK_EQUAL("real_error", result.e);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_error_or_const_with_value)
|
||||
{
|
||||
const etl::expected<int, Error> exp(42);
|
||||
|
||||
Error result = exp.error_or(Error("default"));
|
||||
CHECK_EQUAL("default", result.e);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_error_or_const_with_error)
|
||||
{
|
||||
const etl::expected<int, Error> exp(etl::unexpected<Error>(Error("real_error")));
|
||||
|
||||
Error result = exp.error_or(Error("default"));
|
||||
CHECK_EQUAL("real_error", result.e);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_error_or_rvalue_with_value)
|
||||
{
|
||||
Error result = etl::expected<int, Error>(42).error_or(Error("default"));
|
||||
CHECK_EQUAL("default", result.e);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_error_or_rvalue_with_error)
|
||||
{
|
||||
Error result = etl::expected<int, Error>(etl::unexpected<Error>(Error("real_error"))).error_or(Error("default"));
|
||||
CHECK_EQUAL("real_error", result.e);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_error_or_void_value_with_value)
|
||||
{
|
||||
etl::expected<void, Error> exp;
|
||||
|
||||
Error result = exp.error_or(Error("default"));
|
||||
CHECK_EQUAL("default", result.e);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_error_or_void_value_with_error)
|
||||
{
|
||||
etl::expected<void, Error> exp(etl::unexpected<Error>(Error("real_error")));
|
||||
|
||||
Error result = exp.error_or(Error("default"));
|
||||
CHECK_EQUAL("real_error", result.e);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user