Merge branch 'pull-request/#861-Implement-Constexpr-Strong-Typedef' into development

This commit is contained in:
John Wellbelove 2024-03-17 13:57:17 +00:00
commit 84dd8ceca3
2 changed files with 335 additions and 231 deletions

View File

@ -35,274 +35,262 @@ SOFTWARE.
namespace etl
{
#define ETL_TYPEDEF(T, name) class name##_tag; typedef etl::type_def<name##_tag, T> name
#define ETL_TYPEDEF(T, name) class name##_tag; typedef etl::type_def<name##_tag, T> name
//*************************************************************************
/// A template type to define strong typedefs.
/// Usage:
///\code
/// // Short form.
/// ETL_TYPEDEF(int, mytype);
///
/// // Long form.
/// class mytype_t_tag;
/// typedef etl::type_def<mytype_t_tag, int> mytype_t_tag;
///\endcode
//*************************************************************************
template <typename TIdType, typename TValue>
class type_def
//*************************************************************************
/// A template type to define strong typedefs.
/// Usage:
///\code
/// // Short form.
/// ETL_TYPEDEF(int, mytype);
///
/// // Long form.
/// class mytype_t_tag;
/// typedef etl::type_def<mytype_t_tag, int> mytype_t_tag;
///\endcode
//*************************************************************************
template <typename TIdType, typename TValue>
class type_def
{
public:
typedef TValue value_type;
typedef TIdType id_type;
//*********************************************************************
ETL_CONSTEXPR type_def()
: value(TValue())
{
public:
}
typedef TValue value_type;
typedef TIdType id_type;
//*********************************************************************
ETL_CONSTEXPR type_def(TValue value_)
: value(value_)
{
}
//*********************************************************************
type_def()
: value(TValue())
{
}
//*********************************************************************
ETL_CONSTEXPR type_def(const type_def& other)
: value(other.value)
{
}
//*********************************************************************
type_def(TValue value_)
: value(value_)
{
}
//*********************************************************************
ETL_CONSTEXPR operator TValue() const
{
return value;
}
//*********************************************************************
type_def(const type_def& other)
: value(other.value)
{
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator ++()
{
++value;
return *this;
}
//*********************************************************************
operator TValue() const
{
return value;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def operator ++(int)
{
type_def temp(*this);
type_def::operator ++();
return temp;
}
//*********************************************************************
type_def& operator ++()
{
++value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator --()
{
--value;
return *this;
}
//*********************************************************************
type_def operator ++(int)
{
type_def temp(*this);
type_def::operator ++();
return temp;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def operator --(int)
{
type_def temp(*this);
type_def::operator --();
return temp;
}
//*********************************************************************
type_def& operator --()
{
--value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator +=(TValue rhs)
{
value += rhs;
return *this;
}
//*********************************************************************
type_def operator --(int)
{
type_def temp(*this);
type_def::operator --();
return temp;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator +=(const type_def& rhs)
{
value += rhs.value;
return *this;
}
//*********************************************************************
type_def& operator +=(TValue rhs)
{
value += rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator -=(TValue rhs)
{
value -= rhs;
return *this;
}
//*********************************************************************
type_def& operator +=(const type_def& rhs)
{
value += rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator -=(const type_def& rhs)
{
value -= rhs.value;
return *this;
}
//*********************************************************************
type_def& operator -=(TValue rhs)
{
value -= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator *=(TValue rhs)
{
value *= rhs;
return *this;
}
//*********************************************************************
type_def& operator -=(const type_def& rhs)
{
value -= rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator *=(const type_def& rhs)
{
value *= rhs.value;
return *this;
}
//*********************************************************************
type_def& operator *=(TValue rhs)
{
value *= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator /=(TValue rhs)
{
value /= rhs;
return *this;
}
//*********************************************************************
type_def& operator *=(const type_def& rhs)
{
value *= rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator /=(const type_def& rhs)
{
value /= rhs.value;
return *this;
}
//*********************************************************************
type_def& operator /=(TValue rhs)
{
value /= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator %=(TValue rhs)
{
value %= rhs;
return *this;
}
//*********************************************************************
type_def& operator /=(const type_def& rhs)
{
value /= rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator %=(const type_def& rhs)
{
value %= rhs.value;
return *this;
}
//*********************************************************************
type_def& operator %=(TValue rhs)
{
value %= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator &=(TValue rhs)
{
value &= rhs;
return *this;
}
//*********************************************************************
type_def& operator %=(const type_def& rhs)
{
value %= rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator &=(const type_def& rhs)
{
value &= rhs.value;
return *this;
}
//*********************************************************************
type_def& operator &=(TValue rhs)
{
value &= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator |=(TValue rhs)
{
value |= rhs;
return *this;
}
//*********************************************************************
type_def& operator &=(const type_def& rhs)
{
value &= rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator |=(const type_def& rhs)
{
value |= rhs.value;
return *this;
}
//*********************************************************************
type_def& operator |=(TValue rhs)
{
value |= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator ^=(TValue rhs)
{
value ^= rhs;
return *this;
}
//*********************************************************************
type_def& operator |=(const type_def& rhs)
{
value |= rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator ^=(const type_def& rhs)
{
value ^= rhs.value;
return *this;
}
//*********************************************************************
type_def& operator ^=(TValue rhs)
{
value ^= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator <<=(TValue rhs)
{
value <<= rhs;
return *this;
}
//*********************************************************************
type_def& operator ^=(const type_def& rhs)
{
value ^= rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator >>=(TValue rhs)
{
value >>= rhs;
return *this;
}
//*********************************************************************
type_def& operator <<=(TValue rhs)
{
value <<= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator =(TValue rhs)
{
value = rhs;
return *this;
}
//*********************************************************************
type_def& operator >>=(TValue rhs)
{
value >>= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator =(const type_def& rhs)
{
value = rhs.value;
return *this;
}
//*********************************************************************
type_def& operator =(TValue rhs)
{
value = rhs;
return *this;
}
//*********************************************************************
TValue& get()
{
return value;
}
//*********************************************************************
type_def& operator =(const type_def& rhs)
{
value = rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR const TValue& get() const
{
return value;
}
//*********************************************************************
TValue& get()
{
return value;
}
//*********************************************************************
friend ETL_CONSTEXPR bool operator >(const type_def& lhs, const type_def& rhs)
{
return lhs.value > rhs.value;
}
//*********************************************************************
const TValue& get() const
{
return value;
}
//*********************************************************************
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)
{
return lhs.value < rhs.value;
}
//*********************************************************************
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)
{
return lhs.value <= rhs.value;
}
//*********************************************************************
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)
{
return lhs.value > rhs.value;
}
private:
//*********************************************************************
friend 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)
{
return lhs.value == rhs.value;
}
//*********************************************************************
friend bool operator !=(const type_def& lhs, const type_def& rhs)
{
return lhs.value != rhs.value;
}
private:
TValue value;
};
TValue value;
};
}
#endif

View File

@ -32,6 +32,8 @@ SOFTWARE.
#include "etl/type_def.h"
#include "etl/type_traits.h"
namespace
{
SUITE(test_type_def)
@ -51,6 +53,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)
{
@ -69,6 +86,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)
{
@ -84,6 +119,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)
{
@ -141,5 +191,71 @@ 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 bool eq = t1 == t1;
constexpr bool neq = t1 == t2;
constexpr bool lt = t1 < t2;
constexpr bool nlt = t2 < t1;
constexpr bool lte = t1 <= t2;
constexpr bool nlte = t2 <= t1;
constexpr bool gt = t1 > t2;
constexpr bool ngt = t2 > t1;
constexpr bool gte = t1 >= t2;
constexpr bool ngte = t2 >= t1;
CHECK_TRUE(eq);
CHECK_FALSE(neq);
CHECK_TRUE(lt);
CHECK_FALSE(nlt);
CHECK_TRUE(lte);
CHECK_FALSE(nlte);
CHECK_FALSE(gt);
CHECK_TRUE(ngt);
CHECK_FALSE(gte);
CHECK_TRUE(ngte);
}
//*************************************************************************
ETL_TYPEDEF(int32_t, arithmetic_type_t);
constexpr arithmetic_type_t CreatePlus()
{
arithmetic_type_t value = 0;
++value;
value++;
value += 1;
return value;
}
constexpr arithmetic_type_t CreateMinus()
{
arithmetic_type_t value = 0;
--value;
value--;
value -= 1;
return value;
}
TEST(test_arithmetic_constexpr)
{
constexpr arithmetic_type_t value_plus = CreatePlus();
constexpr arithmetic_type_t value_minus = CreateMinus();
CHECK_EQUAL(3, value_plus.get());
CHECK_EQUAL(-3, value_minus.get());
}
};
}