Merge branch 'hotfix/#819-etl-optional-cannot-return-an-optional-object-of-self-from-member-function' into development

# Conflicts:
#	include/etl/optional.h
This commit is contained in:
John Wellbelove 2024-02-15 11:10:31 +00:00
commit 89eedd4563
2 changed files with 1992 additions and 977 deletions

File diff suppressed because it is too large Load Diff

View File

@ -53,6 +53,28 @@ std::ostream& operator << (std::ostream& os, const etl::optional<Data>& data)
namespace
{
#include "etl/private/diagnostic_unused_function_push.h"
//*************************************************************************
struct NonTrivial
{
constexpr NonTrivial() : a(0) {}
constexpr NonTrivial(int a_) : a(a_) {}
constexpr friend bool operator <(const NonTrivial& lhs, const NonTrivial& rhs)
{
return lhs.a < rhs.a;
}
constexpr friend bool operator ==(const NonTrivial& lhs, const NonTrivial& rhs)
{
return lhs.a == rhs.a;
}
int a;
};
#include "etl/private/diagnostic_pop.h"
SUITE(test_optional)
{
//*************************************************************************
@ -153,10 +175,19 @@ namespace
#include "etl/private/diagnostic_pop.h"
}
//*************************************************************************
TEST(test_nullopt_pod)
{
etl::optional<int> data(etl::nullopt);
data = 1;
data = etl::nullopt;
CHECK(!bool(data));
}
//*************************************************************************
TEST(test_nullopt)
{
etl::optional<Data> data;
etl::optional<Data> data(etl::nullopt);
data = Data("Hello");
data = etl::nullopt;
CHECK(!bool(data));
@ -239,6 +270,40 @@ namespace
CHECK(!(Data("Data2") == data1));
}
#if ETL_USING_CPP20 && ETL_USING_STL
//*************************************************************************
TEST(test_constexpr_equality_non_trivial)
{
constexpr etl::optional<NonTrivial> data1(1);
constexpr etl::optional<NonTrivial> data2(2);
constexpr bool eq1 = (data1 == data2);
constexpr bool eq2 = (data1 == etl::nullopt);
constexpr bool eq3 = (etl::nullopt == data1);
CHECK_FALSE(eq1);
CHECK_FALSE(eq2);
CHECK_FALSE(eq3);
}
#endif
#if ETL_USING_CPP14
//*************************************************************************
TEST(test_constexpr_equality_trivial)
{
constexpr etl::optional<int> data1(1);
constexpr etl::optional<int> data2(2);
constexpr bool eq1 = (data1 == data2);
constexpr bool eq2 = (data1 == etl::nullopt);
constexpr bool eq3 = (etl::nullopt == data1);
CHECK_FALSE(eq1);
CHECK_FALSE(eq2);
CHECK_FALSE(eq3);
}
#endif
//*************************************************************************
TEST(test_inequality)
{
@ -276,6 +341,40 @@ namespace
CHECK(Data("Data2") != data1);
}
#if ETL_USING_CPP20 && ETL_USING_STL
//*************************************************************************
TEST(test_constexpr_inequality_non_trivial)
{
constexpr etl::optional<NonTrivial> data1(1);
constexpr etl::optional<NonTrivial> data2(2);
constexpr bool eq1 = (data1 != data2);
constexpr bool eq2 = (data1 != etl::nullopt);
constexpr bool eq3 = (etl::nullopt != data1);
CHECK_TRUE(eq1);
CHECK_TRUE(eq2);
CHECK_TRUE(eq3);
}
#endif
#if ETL_USING_CPP14
//*************************************************************************
TEST(test_constexpr_inequality_trivial)
{
constexpr etl::optional<int> data1(1);
constexpr etl::optional<int> data2(2);
constexpr bool neq1 = (data1 != data2);
constexpr bool neq2 = (data1 != etl::nullopt);
constexpr bool neq3 = (etl::nullopt != data1);
CHECK_TRUE(neq1);
CHECK_TRUE(neq2);
CHECK_TRUE(neq3);
}
#endif
//*************************************************************************
#include "etl/private/diagnostic_uninitialized_push.h"
TEST(test_less_than)
@ -310,6 +409,45 @@ namespace
}
#include "etl/private/diagnostic_pop.h"
#if ETL_USING_CPP20 && ETL_USING_STL
//*************************************************************************
TEST(test_constexpr_less_than_non_trivial)
{
constexpr etl::optional<NonTrivial> data1(1);
constexpr etl::optional<NonTrivial> data2(2);
constexpr bool lt1 = (data1 < data2);
constexpr bool lt2 = (data2 < data1);
constexpr bool lt3 = (data1 < etl::nullopt);
constexpr bool lt4 = (etl::nullopt < data1);
CHECK_TRUE(lt1);
CHECK_FALSE(lt2);
CHECK_FALSE(lt3);
CHECK_TRUE(lt4);
}
#endif
#if ETL_USING_CPP14
//*************************************************************************
TEST(test_constexpr_less_than_trivial)
{
constexpr etl::optional<int> data1(1);
constexpr etl::optional<int> data2(2);
constexpr bool lt1 = (data1 < data2);
constexpr bool lt2 = (data2 < data1);
constexpr bool lt3 = (data1 < etl::nullopt);
constexpr bool lt4 = (etl::nullopt < data1);
CHECK_TRUE(lt1);
CHECK_FALSE(lt2);
CHECK_FALSE(lt3);
CHECK_TRUE(lt4);
}
#endif
//*************************************************************************
TEST(test_less_than_equal)
{
@ -344,6 +482,44 @@ namespace
CHECK(Data("Data1") <= data1);
}
#if ETL_USING_CPP20 && ETL_USING_STL
//*************************************************************************
TEST(test_constexpr_less_than_equal_non_trivial)
{
constexpr etl::optional<NonTrivial> data1(1);
constexpr etl::optional<NonTrivial> data2(2);
constexpr bool lt1 = (data1 <= data2);
constexpr bool lt2 = (data2 <= data1);
constexpr bool lt3 = (data1 <= etl::nullopt);
constexpr bool lt4 = (etl::nullopt <= data1);
CHECK_TRUE(lt1);
CHECK_FALSE(lt2);
CHECK_FALSE(lt3);
CHECK_TRUE(lt4);
}
#endif
#if ETL_USING_CPP14
//*************************************************************************
TEST(test_constexpr_less_than_equal_trivial)
{
constexpr etl::optional<int> data1(1);
constexpr etl::optional<int> data2(2);
constexpr bool lt1 = (data1 <= data2);
constexpr bool lt2 = (data2 <= data1);
constexpr bool lt3 = (data1 <= etl::nullopt);
constexpr bool lt4 = (etl::nullopt <= data1);
CHECK_TRUE(lt1);
CHECK_FALSE(lt2);
CHECK_FALSE(lt3);
CHECK_TRUE(lt4);
}
#endif
//*************************************************************************
TEST(test_greater_than)
{
@ -376,6 +552,44 @@ namespace
CHECK(!(Data("Data1") > data2));
}
#if ETL_USING_CPP20 && ETL_USING_STL
//*************************************************************************
TEST(test_constexpr_greater_than_non_trivial)
{
constexpr etl::optional<NonTrivial> data1(1);
constexpr etl::optional<NonTrivial> data2(2);
constexpr bool gt1 = (data1 > data2);
constexpr bool gt2 = (data2 > data1);
constexpr bool gt3 = (data1 > etl::nullopt);
constexpr bool gt4 = (etl::nullopt > data1);
CHECK_FALSE(gt1);
CHECK_TRUE(gt2);
CHECK_TRUE(gt3);
CHECK_FALSE(gt4);
}
#endif
#if ETL_USING_CPP14
//*************************************************************************
TEST(test_constexpr_greater_than_trivial)
{
constexpr etl::optional<int> data1(1);
constexpr etl::optional<int> data2(2);
constexpr bool gt1 = (data1 > data2);
constexpr bool gt2 = (data2 > data1);
constexpr bool gt3 = (data1 > etl::nullopt);
constexpr bool gt4 = (etl::nullopt > data1);
CHECK_FALSE(gt1);
CHECK_TRUE(gt2);
CHECK_TRUE(gt3);
CHECK_FALSE(gt4);
}
#endif
//*************************************************************************
TEST(test_greater_than_equal)
{
@ -410,6 +624,44 @@ namespace
CHECK(Data("Data1") >= data1);
}
#if ETL_USING_CPP20 && ETL_USING_STL
//*************************************************************************
TEST(test_constexpr_greater_than_equal_non_trivial)
{
constexpr etl::optional<NonTrivial> data1(1);
constexpr etl::optional<NonTrivial> data2(2);
constexpr bool gte1 = (data1 >= data2);
constexpr bool gte2 = (data2 >= data1);
constexpr bool gte3 = (data1 >= etl::nullopt);
constexpr bool gte4 = (etl::nullopt >= data1);
CHECK_FALSE(gte1);
CHECK_TRUE(gte2);
CHECK_TRUE(gte3);
CHECK_FALSE(gte4);
}
#endif
#if ETL_USING_CPP14
//*************************************************************************
TEST(test_constexpr_greater_than_equal_trivial)
{
constexpr etl::optional<int> data1(1);
constexpr etl::optional<int> data2(2);
constexpr bool gte1 = (data1 >= data2);
constexpr bool gte2 = (data2 >= data1);
constexpr bool gte3 = (data1 >= etl::nullopt);
constexpr bool gte4 = (etl::nullopt >= data1);
CHECK_FALSE(gte1);
CHECK_TRUE(gte2);
CHECK_TRUE(gte3);
CHECK_FALSE(gte4);
}
#endif
//*************************************************************************
TEST(test_container_of_optional)
{
@ -629,6 +881,21 @@ namespace
CHECK_EQUAL(42, (*opt).v);
}
#endif
//*************************************************************************
TEST(test_optional_issue_819)
{
// The code below should compile without error.
class optional_type
{
public:
static etl::optional<optional_type> function()
{
return {};
}
};
}
};
}