Skip to content

Commit 14b1fe1

Browse files
committed
Support etl::underlying_type with compiler builtin
1 parent e1b263a commit 14b1fe1

File tree

4 files changed

+121
-1
lines changed

4 files changed

+121
-1
lines changed

include/etl/generators/type_traits_generator.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2302,6 +2302,41 @@ typedef integral_constant<bool, true> true_type;
23022302
using type_identity_t = typename type_identity<T>::type;
23032303
#endif
23042304

2305+
#if ETL_USING_BUILTIN_UNDERLYING_TYPE
2306+
namespace private_type_traits
2307+
{
2308+
template <typename T, bool = is_enum<T>::value>
2309+
struct __underlying_type_impl;
2310+
2311+
template <typename T>
2312+
struct __underlying_type_impl<T, false>
2313+
{
2314+
};
2315+
2316+
template <typename T>
2317+
struct __underlying_type_impl<T, true>
2318+
{
2319+
using type = __underlying_type(T);
2320+
};
2321+
}
2322+
2323+
template <typename T>
2324+
struct underlying_type : private_type_traits::__underlying_type_impl<T, is_enum<T>::value>
2325+
{
2326+
};
2327+
2328+
#if ETL_USING_CPP11
2329+
template <typename T>
2330+
using underlying_type_t = typename underlying_type<T>::type;
2331+
2332+
template <typename T>
2333+
ETL_CONSTEXPR underlying_type_t<T> to_underlying(T val) ETL_NOEXCEPT
2334+
{
2335+
return static_cast<underlying_type_t<T>>(val);
2336+
}
2337+
#endif
2338+
#endif
2339+
23052340
#if ETL_USING_CPP11
23062341
//*********************************************
23072342
// has_duplicates

include/etl/profiles/determine_builtin_support.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ SOFTWARE.
5151
#if !defined(ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE)
5252
#define ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE 1
5353
#endif
54+
55+
#if !defined(ETL_USING_BUILTIN_UNDERLYING_TYPE)
56+
#define ETL_USING_BUILTIN_UNDERLYING_TYPE 1
57+
#endif
5458
#endif
5559

5660
#if defined(__has_builtin) // Use __has_builtin to check for existence of builtin functions?
@@ -73,6 +77,10 @@ SOFTWARE.
7377
#if !defined(ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE)
7478
#define ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE (__has_builtin(__has_trivial_copy) || __has_builtin(__is_trivially_copyable))
7579
#endif
80+
81+
#if !defined(ETL_USING_BUILTIN_UNDERLYING_TYPE)
82+
#define ETL_USING_BUILTIN_UNDERLYING_TYPE __has_builtin(__underlying_type)
83+
#endif
7684
#endif
7785

7886
// The default. Set to 0, if not already set.
@@ -96,6 +104,10 @@ SOFTWARE.
96104
#define ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE 0
97105
#endif
98106

107+
#if !defined(ETL_USING_BUILTIN_UNDERLYING_TYPE)
108+
#define ETL_USING_BUILTIN_UNDERLYING_TYPE 0
109+
#endif
110+
99111
namespace etl
100112
{
101113
namespace traits

include/etl/type_traits.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2295,6 +2295,41 @@ typedef integral_constant<bool, true> true_type;
22952295
using type_identity_t = typename type_identity<T>::type;
22962296
#endif
22972297

2298+
#if ETL_USING_BUILTIN_UNDERLYING_TYPE
2299+
namespace private_type_traits
2300+
{
2301+
template <typename T, bool = is_enum<T>::value>
2302+
struct __underlying_type_impl;
2303+
2304+
template <typename T>
2305+
struct __underlying_type_impl<T, false>
2306+
{
2307+
};
2308+
2309+
template <typename T>
2310+
struct __underlying_type_impl<T, true>
2311+
{
2312+
using type = __underlying_type(T);
2313+
};
2314+
}
2315+
2316+
template <typename T>
2317+
struct underlying_type : private_type_traits::__underlying_type_impl<T, is_enum<T>::value>
2318+
{
2319+
};
2320+
2321+
#if ETL_USING_CPP11
2322+
template <typename T>
2323+
using underlying_type_t = typename underlying_type<T>::type;
2324+
2325+
template <typename T>
2326+
ETL_CONSTEXPR underlying_type_t<T> to_underlying(T val) ETL_NOEXCEPT
2327+
{
2328+
return static_cast<underlying_type_t<T>>(val);
2329+
}
2330+
#endif
2331+
#endif
2332+
22982333
#if ETL_USING_CPP11
22992334
//*********************************************
23002335
// has_duplicates

test/test_type_traits.cpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1329,11 +1329,49 @@ namespace
13291329
}
13301330

13311331
//*************************************************************************
1332-
TEST(test_type_identity)
1332+
TEST(test_type_identity)
13331333
{
13341334
CHECK_CLOSE(type_identity_test_add(1.5f, 2), 3.5f, 0.01f);
13351335
}
13361336

1337+
//*************************************************************************
1338+
TEST(test_underlying_type)
1339+
{
1340+
enum enum0_t : char
1341+
{
1342+
};
1343+
1344+
enum enum1_t : uint32_t
1345+
{
1346+
};
1347+
1348+
enum class enum2_t : short
1349+
{
1350+
};
1351+
1352+
enum class enum3_t : size_t
1353+
{
1354+
};
1355+
1356+
using enum4_t = enum1_t;
1357+
using enum5_t = std::add_const<enum2_t>::type;
1358+
1359+
CHECK_TRUE((std::is_same<etl::underlying_type<enum0_t>::type, char>::value));
1360+
CHECK_TRUE((std::is_same<etl::underlying_type<enum1_t>::type, uint32_t>::value));
1361+
CHECK_TRUE((std::is_same<etl::underlying_type<enum2_t>::type, short>::value));
1362+
CHECK_TRUE((std::is_same<etl::underlying_type<enum3_t>::type, size_t>::value));
1363+
CHECK_TRUE((std::is_same<etl::underlying_type<enum4_t>::type, uint32_t>::value));
1364+
CHECK_TRUE((std::is_same<etl::underlying_type<enum5_t>::type, short>::value));
1365+
#if ETL_USING_CPP11
1366+
CHECK_TRUE((std::is_same<etl::underlying_type_t<enum0_t>, char>::value));
1367+
CHECK_TRUE((std::is_same<etl::underlying_type_t<enum1_t>, uint32_t>::value));
1368+
CHECK_TRUE((std::is_same<etl::underlying_type_t<enum2_t>, short>::value));
1369+
CHECK_TRUE((std::is_same<etl::underlying_type_t<enum3_t>, size_t>::value));
1370+
CHECK_TRUE((std::is_same<etl::underlying_type_t<enum4_t>, uint32_t>::value));
1371+
CHECK_TRUE((std::is_same<etl::underlying_type_t<enum5_t>, short>::value));
1372+
#endif
1373+
}
1374+
13371375
//*************************************************************************
13381376
TEST(test_has_duplicates)
13391377
{

0 commit comments

Comments
 (0)