Skip to content

Commit

Permalink
Implement Constexpr Strong Typedef (#861)
Browse files Browse the repository at this point in the history
* feat: make type_def constexpr

* test: macro constexpr

* test: implicit constexpr

* test: get constexpr

* refactor: remove constexpr from assignment

* test: comparisons constexpr

* fix: cpp11 support for constexpr get method
  • Loading branch information
drewr95 authored Mar 13, 2024
1 parent b807bad commit 48c496c
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 13 deletions.
34 changes: 21 additions & 13 deletions include/etl/type_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,25 +58,25 @@ namespace etl
typedef TIdType id_type;

//*********************************************************************
type_def()
ETL_CONSTEXPR type_def()
: value(TValue())
{
}

//*********************************************************************
type_def(TValue value_)
ETL_CONSTEXPR type_def(TValue value_)
: value(value_)
{
}

//*********************************************************************
type_def(const type_def& other)
ETL_CONSTEXPR type_def(const type_def& other)
: value(other.value)
{
}

//*********************************************************************
operator TValue() const
ETL_CONSTEXPR operator TValue() const
{
return value;
}
Expand Down Expand Up @@ -238,63 +238,71 @@ namespace etl
}

//*********************************************************************
type_def& operator =(TValue rhs)
ETL_CONSTEXPR type_def& operator =(TValue rhs)
{
value = rhs;
return *this;
}

//*********************************************************************
type_def& operator =(const type_def& rhs)
ETL_CONSTEXPR type_def& operator =(const type_def& rhs)
{
value = rhs.value;
return *this;
}

//*********************************************************************
TValue& get()
ETL_CONSTEXPR TValue& get()
{
return value;
}

#if ETL_USING_CPP14
//*********************************************************************
ETL_CONSTEXPR const TValue& get() const
{
return value;
}
#else
//*********************************************************************
const TValue& get() const
{
return value;
}
#endif // ETL_USING_CPP14

//*********************************************************************
friend bool operator <(const type_def& lhs, const type_def& rhs)
friend ETL_CONSTEXPR bool operator <(const type_def& lhs, const type_def& rhs)
{
return lhs.value < rhs.value;
}

//*********************************************************************
friend bool operator <=(const type_def& lhs, const type_def& rhs)
friend ETL_CONSTEXPR bool operator <=(const type_def& lhs, const type_def& rhs)
{
return lhs.value <= rhs.value;
}

//*********************************************************************
friend bool operator >(const type_def& lhs, const type_def& rhs)
friend ETL_CONSTEXPR bool operator >(const type_def& lhs, const type_def& rhs)
{
return lhs.value > rhs.value;
}

//*********************************************************************
friend bool operator >=(const type_def& lhs, const type_def& rhs)
friend ETL_CONSTEXPR bool operator >=(const type_def& lhs, const type_def& rhs)
{
return lhs.value >= rhs.value;
}

//*********************************************************************
friend bool operator ==(const type_def& lhs, const type_def& rhs)
friend ETL_CONSTEXPR bool operator ==(const type_def& lhs, const type_def& rhs)
{
return lhs.value == rhs.value;
}

//*********************************************************************
friend bool operator !=(const type_def& lhs, const type_def& rhs)
friend ETL_CONSTEXPR bool operator !=(const type_def& lhs, const type_def& rhs)
{
return lhs.value != rhs.value;
}
Expand Down
71 changes: 71 additions & 0 deletions test/test_type_def.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,21 @@ namespace
CHECK_EQUAL(i1, i2);
}

//*************************************************************************
TEST(test_macro_constexpr)
{
ETL_TYPEDEF(uint32_t, type1_t);
ETL_TYPEDEF(uint32_t, type2_t);

constexpr type1_t t1 = type1_t(1);
constexpr type2_t t2 = type2_t(1);

uint32_t i1 = t1.get();
uint32_t i2 = t2.get();

CHECK_EQUAL(i1, i2);
}

//*************************************************************************
TEST(test_implicit)
{
Expand All @@ -69,6 +84,24 @@ namespace
CHECK_EQUAL(i1, i2);
}

//*************************************************************************
TEST(test_implicit_constexpr)
{
class type1_t_tag;
typedef etl::type_def<type1_t_tag, uint32_t> type1_t;

class type2_t_tag;
typedef etl::type_def<type2_t_tag, uint32_t> type2_t;

constexpr type1_t t1 = type1_t(1);
constexpr type2_t t2 = type2_t(1);

uint32_t i1 = t1.get();
uint32_t i2 = t2.get();

CHECK_EQUAL(i1, i2);
}

//*************************************************************************
TEST(test_get)
{
Expand All @@ -84,6 +117,21 @@ namespace
CHECK_EQUAL(t1.get(), t2.get());
}

//*************************************************************************
TEST(test_get_constexpr)
{
class type1_t_tag;
typedef etl::type_def<type1_t_tag, uint32_t> type1_t;

class type2_t_tag;
typedef etl::type_def<type2_t_tag, uint32_t> type2_t;

constexpr type1_t t1(1);
constexpr type2_t t2(1);

CHECK_EQUAL(t1.get(), t2.get());
}

//*************************************************************************
TEST(test_operators)
{
Expand Down Expand Up @@ -141,5 +189,28 @@ namespace
CHECK(!(t1 >= t2));
CHECK(t2 >= t4);
}

//*************************************************************************
TEST(test_comparisons_constexpr)
{
class __type_t__;
typedef etl::type_def<__type_t__, uint32_t> type_t;

constexpr type_t t1(1);
constexpr type_t t2(2);
constexpr type_t t3(t1);
constexpr type_t t4(t2);

CHECK(t1 < t2);
CHECK(!(t2 < t1));
CHECK(t1 <= t2);
CHECK(!(t2 <= t1));
CHECK(t1 <= t3);
CHECK(t2 > t1);
CHECK(!(t1 > t2));
CHECK(t2 >= t1);
CHECK(!(t1 >= t2));
CHECK(t2 >= t4);
}
};
}

0 comments on commit 48c496c

Please sign in to comment.