From 48c496cd44c6ed2ef590450f61c7a5e184abd190 Mon Sep 17 00:00:00 2001 From: Drew Rife Date: Wed, 13 Mar 2024 05:56:47 -0400 Subject: [PATCH] Implement Constexpr Strong Typedef (#861) * 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 --- include/etl/type_def.h | 34 ++++++++++++-------- test/test_type_def.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 13 deletions(-) diff --git a/include/etl/type_def.h b/include/etl/type_def.h index d16e4cd9c..9b0033135 100644 --- a/include/etl/type_def.h +++ b/include/etl/type_def.h @@ -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; } @@ -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; } diff --git a/test/test_type_def.cpp b/test/test_type_def.cpp index 5cf9203bf..b2f271728 100644 --- a/test/test_type_def.cpp +++ b/test/test_type_def.cpp @@ -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) { @@ -69,6 +84,24 @@ namespace CHECK_EQUAL(i1, i2); } + //************************************************************************* + TEST(test_implicit_constexpr) + { + class type1_t_tag; + typedef etl::type_def type1_t; + + class type2_t_tag; + typedef etl::type_def 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 +117,21 @@ namespace CHECK_EQUAL(t1.get(), t2.get()); } + //************************************************************************* + TEST(test_get_constexpr) + { + class type1_t_tag; + typedef etl::type_def type1_t; + + class type2_t_tag; + typedef etl::type_def type2_t; + + constexpr type1_t t1(1); + constexpr type2_t t2(1); + + CHECK_EQUAL(t1.get(), t2.get()); + } + //************************************************************************* TEST(test_operators) { @@ -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); + } }; }