Add begin() and end() to etl::expected

This commit is contained in:
Roland Reichwein 2026-04-24 18:24:14 +02:00
parent 3e4d41ca57
commit 8e153eece6
2 changed files with 104 additions and 0 deletions

View File

@ -725,6 +725,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>

View File

@ -31,6 +31,7 @@ SOFTWARE.
#include "etl/expected.h"
#include "etl/type_traits.h"
#include <iterator>
#include <string>
#include <vector>
@ -1477,5 +1478,75 @@ 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);
}
}
} // namespace