Added all arithmetic operators to type_def

This commit is contained in:
John Wellbelove 2025-05-05 18:01:29 +01:00
parent 22391aa750
commit 394b1110fb
3 changed files with 495 additions and 54 deletions

View File

@ -32,10 +32,12 @@ SOFTWARE.
#define ETL_TYPE_DEF_INCLUDED
#include "platform.h"
#include "type_traits.h"
namespace etl
{
#define ETL_TYPEDEF(T, name) class name##_tag; typedef etl::type_def<name##_tag, T> name
#define ETL_USING(name, T) class name##_tag; typedef etl::type_def<name##_tag, T> name
//*************************************************************************
/// A template type to define strong typedefs.
@ -43,10 +45,12 @@ namespace etl
///\code
/// // Short form.
/// ETL_TYPEDEF(int, mytype);
/// or
/// ETL_USING(mytype, int);
///
/// // Long form.
/// class mytype_t_tag;
/// typedef etl::type_def<mytype_t_tag, int> mytype_t_tag;
/// typedef etl::type_def<mytype_t_tag, int> mytype;
///\endcode
//*************************************************************************
template <typename TIdType, typename TValue>
@ -54,16 +58,19 @@ namespace etl
{
public:
typedef TValue type;
typedef TValue value_type;
typedef TIdType id_type;
//*********************************************************************
#if ETL_USING_CPP11
ETL_CONSTEXPR type_def() = default;
#endif
ETL_CONSTEXPR type_def()
: value(TValue())
{
}
//*********************************************************************
ETL_CONSTEXPR type_def(TValue value_)
template <typename T, typename = typename etl::enable_if<etl::is_convertible<T, TValue>::value, void>::type>
ETL_CONSTEXPR type_def(T value_)
: value(value_)
{
}
@ -110,21 +117,28 @@ namespace etl
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator +=(TValue rhs)
template <typename T>
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def&>::type
operator +=(T rhs)
{
value += rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator +=(const type_def& rhs)
ETL_CONSTEXPR14
type_def& operator +=(const type_def& rhs)
{
value += rhs.value;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator -=(TValue rhs)
template <typename T>
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def&>::type
operator -=(T rhs)
{
value -= rhs;
return *this;
@ -138,7 +152,10 @@ namespace etl
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator *=(TValue rhs)
template <typename T>
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def&>::type
operator *=(T rhs)
{
value *= rhs;
return *this;
@ -152,7 +169,10 @@ namespace etl
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator /=(TValue rhs)
template <typename T>
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def&>::type
operator /=(T rhs)
{
value /= rhs;
return *this;
@ -166,7 +186,10 @@ namespace etl
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator %=(TValue rhs)
template <typename T>
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def&>::type
operator %=(T rhs)
{
value %= rhs;
return *this;
@ -180,7 +203,10 @@ namespace etl
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator &=(TValue rhs)
template <typename T>
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def&>::type
operator &=(T rhs)
{
value &= rhs;
return *this;
@ -194,7 +220,10 @@ namespace etl
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator |=(TValue rhs)
template <typename T>
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def&>::type
operator |=(T rhs)
{
value |= rhs;
return *this;
@ -208,7 +237,10 @@ namespace etl
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator ^=(TValue rhs)
template <typename T>
ETL_CONSTEXPR14
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def&>::type
operator ^=(T rhs)
{
value ^= rhs;
return *this;
@ -222,26 +254,19 @@ namespace etl
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator <<=(TValue rhs)
ETL_CONSTEXPR14 type_def& operator <<=(int rhs)
{
value <<= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator >>=(TValue rhs)
ETL_CONSTEXPR14 type_def& operator >>=(int rhs)
{
value >>= rhs;
return *this;
}
//*********************************************************************
ETL_CONSTEXPR14 type_def& operator =(TValue rhs)
{
value = rhs;
return *this;
}
//*********************************************************************
#if ETL_USING_CPP11
ETL_CONSTEXPR14 type_def& operator =(const type_def& rhs) = default;
@ -259,24 +284,378 @@ namespace etl
return value;
}
//*********************************************************************
// + operator
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def>::type
operator +(const type_def& lhs, T rhs)
{
return type_def(lhs.value + rhs);
}
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR type_def operator +(T lhs, const type_def& rhs)
{
return type_def(lhs + rhs.value);
}
//*********************************************************************
friend ETL_CONSTEXPR type_def operator +(const type_def& lhs, const type_def& rhs)
{
return type_def(lhs.value + rhs.value);
}
//*********************************************************************
// - operator
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def>::type
operator -(const type_def& lhs, T rhs)
{
return type_def(lhs.value - rhs);
}
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def>::type
operator -(T lhs, const type_def& rhs)
{
return type_def(lhs - rhs.value);
}
//*********************************************************************
friend ETL_CONSTEXPR type_def operator -(const type_def& lhs, const type_def& rhs)
{
return type_def(lhs.value - rhs.value);
}
//*********************************************************************
// * operator
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def>::type
operator *(const type_def& lhs, T rhs)
{
return type_def(lhs.value * rhs);
}
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def>::type
operator *(T lhs, const type_def& rhs)
{
return type_def(lhs * rhs.value);
}
//*********************************************************************
friend ETL_CONSTEXPR type_def operator *(const type_def& lhs, const type_def& rhs)
{
return type_def(lhs.value * rhs.value);
}
//*********************************************************************
// / operator
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def>::type
operator /(const type_def& lhs, T rhs)
{
return type_def(lhs.value / rhs);
}
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def>::type
operator /(T lhs, const type_def& rhs)
{
return type_def(lhs / rhs.value);
}
//*********************************************************************
friend ETL_CONSTEXPR type_def operator /(const type_def& lhs, const type_def& rhs)
{
return type_def(lhs.value / rhs.value);
}
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def>::type
operator %(const type_def& lhs, T rhs)
{
return type_def(lhs.value % rhs);
}
//*********************************************************************
// % operator
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def>::type
operator %(T lhs, const type_def& rhs)
{
return type_def(lhs % rhs.value);
}
//*********************************************************************
friend ETL_CONSTEXPR type_def operator %(const type_def& lhs, const type_def& rhs)
{
return type_def(lhs.value % rhs.value);
}
//*********************************************************************
// & operator
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def>::type
operator &(const type_def& lhs, T rhs)
{
return type_def(lhs.value & rhs);
}
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def>::type
operator &(T lhs, const type_def& rhs)
{
return type_def(lhs & rhs.value);
}
//*********************************************************************
friend ETL_CONSTEXPR type_def operator &(const type_def& lhs, const type_def& rhs)
{
return type_def(lhs.value & rhs.value);
}
//*********************************************************************
// | operator
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def>::type
operator |(const type_def& lhs, T rhs)
{
return type_def(lhs.value | rhs);
}
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def>::type
operator |(T lhs, const type_def& rhs)
{
return type_def(lhs | rhs.value);
}
//*********************************************************************
friend ETL_CONSTEXPR type_def operator |(const type_def& lhs, const type_def& rhs)
{
return type_def(lhs.value | rhs.value);
}
//*********************************************************************
// ^ operator
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def>::type
operator ^(const type_def& lhs, T rhs)
{
return type_def(lhs.value ^ rhs);
}
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, type_def>::type
operator ^(T lhs, const type_def& rhs)
{
return type_def(lhs ^ rhs.value);
}
//*********************************************************************
friend ETL_CONSTEXPR type_def operator ^(const type_def& lhs, const type_def& rhs)
{
return type_def(lhs.value ^ rhs.value);
}
//*********************************************************************
// << operator
//*********************************************************************
friend ETL_CONSTEXPR type_def operator <<(const type_def& lhs, int rhs)
{
return type_def(lhs.value << rhs);
}
//*********************************************************************
// >> operator
//*********************************************************************
friend ETL_CONSTEXPR type_def operator >>(const type_def& lhs, int rhs)
{
return type_def(lhs.value >> rhs);
}
//*********************************************************************
// < operator
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, bool>::type
operator <(const type_def& lhs, T rhs)
{
return lhs.value < rhs;
}
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, bool>::type
operator <(T lhs, const type_def& rhs)
{
return lhs < rhs.value;
}
//*********************************************************************
friend ETL_CONSTEXPR bool operator <(const type_def& lhs, const type_def& rhs)
{
return lhs.value < rhs.value;
}
//*********************************************************************
// <= operator
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, bool>::type
operator <=(const type_def& lhs, T rhs)
{
return lhs.value <= rhs;
}
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, bool>::type
operator <=(T lhs, const type_def& rhs)
{
return lhs <= rhs.value;
}
//*********************************************************************
friend ETL_CONSTEXPR bool operator <=(const type_def& lhs, const type_def& rhs)
{
return lhs.value <= rhs.value;
}
//*********************************************************************
// > operator
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, bool>::type
operator >(const type_def& lhs, T rhs)
{
return lhs.value > rhs;
}
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, bool>::type
operator >(T lhs, const type_def& rhs)
{
return lhs > rhs.value;
}
//*********************************************************************
friend ETL_CONSTEXPR bool operator >(const type_def& lhs, const type_def& rhs)
{
return lhs.value > rhs.value;
}
//*********************************************************************
// >= operator
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, bool>::type
operator >=(const type_def& lhs, T rhs)
{
return lhs.value >= rhs;
}
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, bool>::type
operator >=(T lhs, const type_def& rhs)
{
return lhs >= rhs.value;
}
//*********************************************************************
friend ETL_CONSTEXPR bool operator >=(const type_def& lhs, const type_def& rhs)
{
return lhs.value >= rhs.value;
}
//*********************************************************************
// == operator
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, bool>::type
operator ==(const type_def& lhs, T rhs)
{
return lhs.value == rhs;
}
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, bool>::type
operator ==(T lhs, const type_def& rhs)
{
return lhs == rhs.value;
}
//*********************************************************************
friend ETL_CONSTEXPR bool operator ==(const type_def& lhs, const type_def& rhs)
{
return lhs.value == rhs.value;
}
//*********************************************************************
// != operator
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, bool>::type
operator !=(const type_def& lhs, T rhs)
{
return lhs.value != rhs;
}
//*********************************************************************
template <typename T>
friend ETL_CONSTEXPR
typename etl::enable_if<etl::is_convertible<T, TValue>::value, bool>::type
operator !=(T lhs, const type_def& rhs)
{
return lhs != rhs.value;
}
//*********************************************************************
friend ETL_CONSTEXPR bool operator !=(const type_def& lhs, const type_def& rhs)
{

View File

@ -32,20 +32,37 @@ SOFTWARE.
#include "etl/type_def.h"
#include "etl/type_traits.h"
namespace
{
const char One = 1;
const char Two = 2;
SUITE(test_type_def)
{
//*************************************************************************
TEST(test_macro)
TEST(test_macro_ETL_TYPEDEF)
{
ETL_TYPEDEF(uint32_t, type1_t);
ETL_TYPEDEF(uint32_t, type2_t);
type1_t t1 = type1_t(1);
type2_t t2 = type2_t(1);
type1_t t1 = type1_t(One);
type2_t t2 = type2_t(One);
uint32_t i1 = t1.get();
uint32_t i2 = t2.get();
CHECK_EQUAL(i1, i2);
CHECK_TRUE(std::is_trivially_copyable<type1_t>::value);
}
//*************************************************************************
TEST(test_macro_ETL_USING)
{
ETL_USING(type1_t, uint32_t);
ETL_USING(type2_t, uint32_t);
type1_t t1 = type1_t(One);
type2_t t2 = type2_t(One);
uint32_t i1 = t1.get();
uint32_t i2 = t2.get();
@ -60,8 +77,8 @@ namespace
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);
constexpr type1_t t1 = type1_t(One);
constexpr type2_t t2 = type2_t(One);
uint32_t i1 = t1.get();
uint32_t i2 = t2.get();
@ -78,8 +95,8 @@ namespace
class type2_t_tag;
typedef etl::type_def<type2_t_tag, uint32_t> type2_t;
type1_t t1 = type1_t(1);
type2_t t2 = type2_t(1);
type1_t t1 = type1_t(One);
type2_t t2 = type2_t(One);
uint32_t i1 = t1.get();
uint32_t i2 = t2.get();
@ -96,8 +113,8 @@ namespace
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);
constexpr type1_t t1 = type1_t(One);
constexpr type2_t t2 = type2_t(One);
uint32_t i1 = t1.get();
uint32_t i2 = t2.get();
@ -114,8 +131,8 @@ namespace
class type2_t_tag;
typedef etl::type_def<type2_t_tag, uint32_t> type2_t;
type1_t t1(1);
type2_t t2(1);
type1_t t1(One);
type2_t t2(One);
CHECK_EQUAL(t1.get(), t2.get());
}
@ -129,14 +146,14 @@ namespace
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);
constexpr type1_t t1(One);
constexpr type2_t t2(One);
CHECK_EQUAL(t1.get(), t2.get());
}
//*************************************************************************
TEST(test_operators)
TEST(test_unary_operators)
{
class __type_t__;
typedef etl::type_def<__type_t__, uint32_t> type_t;
@ -148,14 +165,14 @@ namespace
CHECK_EQUAL(i++, uint32_t(t++));
CHECK_EQUAL(--i, uint32_t(--t));
CHECK_EQUAL(i--, uint32_t(t--));
CHECK_EQUAL(i += 2, uint32_t(t += 2));
CHECK_EQUAL(i += 2, uint32_t(t += type_t(2)));
CHECK_EQUAL(i -= 2, uint32_t(t -= 2));
CHECK_EQUAL(i -= 2, uint32_t(t -= type_t(2)));
CHECK_EQUAL(i *= 2, uint32_t(t *= 2));
CHECK_EQUAL(i *= 2, uint32_t(t *= type_t(2)));
CHECK_EQUAL(i /= 2, uint32_t(t /= 2));
CHECK_EQUAL(i /= 2, uint32_t(t /= type_t(2)));
CHECK_EQUAL(i += Two, uint32_t(t += Two));
CHECK_EQUAL(i += Two, uint32_t(t += type_t(Two)));
CHECK_EQUAL(i -= Two, uint32_t(t -= Two));
CHECK_EQUAL(i -= Two, uint32_t(t -= type_t(Two)));
CHECK_EQUAL(i *= Two, uint32_t(t *= Two));
CHECK_EQUAL(i *= Two, uint32_t(t *= type_t(Two)));
CHECK_EQUAL(i /= Two, uint32_t(t /= Two));
CHECK_EQUAL(i /= Two, uint32_t(t /= type_t(Two)));
CHECK_EQUAL(i &= 0xFF00U, uint32_t(t &= 0xFF00U));
CHECK_EQUAL(i &= 0xFF00U, uint32_t(t &= type_t(0xFF00U)));
CHECK_EQUAL(i |= 0x003DU, uint32_t(t |= 0x003DU));
@ -170,6 +187,52 @@ namespace
CHECK_EQUAL(0x1234U, uint32_t(t));
}
//*************************************************************************
TEST(test_binary_operators)
{
class __type_t__;
using type_t = etl::type_def<__type_t__, uint32_t> ;
uint32_t i1 = 0x5A3DUL;
uint32_t i2 = 0xB47AUL;
type_t t1(0x5A3DUL);
type_t t2(0xB47AUL);
CHECK_EQUAL(i1 + Two, t1 + Two);
CHECK_EQUAL(Two + i1, Two + t1);
CHECK_EQUAL(i1 + i2, t1 + t2);
CHECK_EQUAL(i1 - Two, t1 - Two);
CHECK_EQUAL(i2 - i1, i2 - t1);
CHECK_EQUAL(i2 - i1, t2 - t1);
CHECK_EQUAL(i1 * Two, t1 * Two);
CHECK_EQUAL(Two * i1, Two * t1);
CHECK_EQUAL(i1 * i2, t1 * t2);
CHECK_EQUAL(i1 / Two, t1 / Two);
CHECK_EQUAL(i2 / i1, i2 / t1);
CHECK_EQUAL(i2 / i1, t2 / t1);
CHECK_EQUAL(uint32_t(0xFF00) & i1, uint32_t(0xFF00) & t1);
CHECK_EQUAL(i1 & uint32_t(0xFF00), t1 & uint32_t(0xFF00));
CHECK_EQUAL(uint32_t(0xFF00) & i1, type_t(0xFF00UL) & t1);
CHECK_EQUAL(uint32_t(0x003D) | i1, uint32_t(0x003D) | t1);
CHECK_EQUAL(i1 | uint32_t(0x003D), t1 | uint32_t(0x003D));
CHECK_EQUAL(uint32_t(0x003D) | i1, type_t(0x003DUL) | t1);
CHECK_EQUAL(uint32_t(0xAA55) ^ i1, uint32_t(0xAA55) ^ t1);
CHECK_EQUAL(i1 ^ uint32_t(0xAA55), t1 ^ uint32_t(0xAA55));
CHECK_EQUAL(uint32_t(0xAA55) ^ i1, type_t(0xAA55UL) ^ t1);
CHECK_EQUAL(i1 << 2, t1 << 2);
CHECK_EQUAL(i1 >> 2, t1 >> 2);
CHECK_EQUAL(i1 % uint32_t(23), t1 % uint32_t(23));
CHECK_EQUAL(uint32_t(23) % i1, uint32_t(23) % t1);
}
//*************************************************************************
TEST(test_comparisons)
{
@ -177,7 +240,7 @@ namespace
typedef etl::type_def<__type_t__, uint32_t> type_t;
type_t t1(1);
type_t t2(2);
type_t t2(Two);
type_t t3(t1);
type_t t4(t2);
@ -200,7 +263,7 @@ namespace
typedef etl::type_def<__type_t__, uint32_t> type_t;
constexpr type_t t1(1);
constexpr type_t t2(2);
constexpr type_t t2(Two);
constexpr bool eq = t1 == t1;
constexpr bool neq = t1 == t2;

View File

@ -748,18 +748,17 @@ namespace
enum1_t e1 = enum1_t::b2;
enum2_t e2 = enum2_t::c0;
CHECK_TRUE(etl::is_same<int8_t, etl::underlying_type_t<enum0_t>>::value);
CHECK_TRUE(etl::is_same<unsigned char, etl::underlying_type_t<enum1_t>>::value);
CHECK_TRUE(etl::is_same<int32_t, etl::underlying_type_t<enum2_t>>::value);
CHECK_TRUE((etl::is_same<int8_t, etl::underlying_type_t<enum0_t>>::value));
CHECK_TRUE((etl::is_same<unsigned char, etl::underlying_type_t<enum1_t>>::value));
CHECK_TRUE((etl::is_same<int32_t, etl::underlying_type_t<enum2_t>>::value));
CHECK_EQUAL(etl::to_underlying(e0), 't');
CHECK_EQUAL(etl::to_underlying(e1), 5);
CHECK_EQUAL(etl::to_underlying(e2), -2);
CHECK_EQUAL(etl::to_underlying(e3), 2);
CHECK_EQUAL(etl::to_underlying(enum0_t::a0), 'e');
CHECK_EQUAL(etl::to_underlying(enum0_t::a2), 'l');
CHECK_EQUAL(etl::to_underlying(enum0_t::a3), '3');
CHECK_EQUAL(etl::to_underlying(enum3_t::b1), 3);
CHECK_EQUAL(etl::to_underlying(enum1_t::b1), 3);
CHECK_EQUAL(etl::to_underlying(enum2_t::c1), 100);
}
#endif