Skip to content

Commit 152581b

Browse files
author
John Wellbelove
committed
Updated type_traits generator
1 parent c133c4d commit 152581b

File tree

2 files changed

+38
-31
lines changed

2 files changed

+38
-31
lines changed

include/etl/generators/type_traits_generator.h

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -725,15 +725,16 @@ namespace etl
725725
{
726726
// Base case
727727
template <typename T, typename = int>
728-
struct is_convertible_to_int : false_type
728+
struct is_convertible_to_int
729+
: false_type
729730
{
730731
};
731732

732733
// Selected if `static_cast<int>(declval<T>())` is a valid statement
733734
// 2nd template argument of base case defaults to int to ensure that this partial specialization is always tried first
734735
template <typename T>
735736
struct is_convertible_to_int<T, decltype(static_cast<int>(declval<T>()))>
736-
: true_type
737+
: true_type
737738
{
738739
};
739740
}
@@ -751,7 +752,29 @@ namespace etl
751752
template <typename T>
752753
inline constexpr bool is_enum_v = etl::is_enum<T>::value;
753754
#endif
755+
#else
756+
namespace private_type_traits
757+
{
758+
// Helper to detect if a type is convertible to an integer
759+
template <typename T>
760+
struct is_convertible_to_int
761+
{
762+
static char test(int); // Match if T is convertible to int
763+
static double test(...); // Fallback for other types
754764

765+
static const bool value = sizeof(test(static_cast<T>(0))) == sizeof(char);
766+
};
767+
}
768+
769+
// Implementation of is_enum
770+
template <typename T>
771+
struct is_enum
772+
{
773+
static const bool value = private_type_traits::is_convertible_to_int<T>::value &&
774+
!is_class<T>::value &&
775+
!is_arithmetic<T>::value &&
776+
!is_reference<T>::value;
777+
};
755778
#endif
756779

757780
//***************************************************************************
@@ -2257,7 +2280,8 @@ typedef integral_constant<bool, true> true_type;
22572280
};
22582281

22592282
template <typename T1, typename T2, typename = void>
2260-
struct common_type_2_impl : decay_conditional_result<const T1&, const T2&>
2283+
struct common_type_2_impl
2284+
: decay_conditional_result<const T1&, const T2&>
22612285
{
22622286
};
22632287

@@ -2354,7 +2378,7 @@ typedef integral_constant<bool, true> true_type;
23542378

23552379
//*********************************************
23562380
// underlying_type
2357-
2381+
#if ETL_USING_BUILTIN_UNDERLYING_TYPE
23582382
// Primary template for etl::underlying_type
23592383
template <typename T, bool = etl::is_enum<T>::value>
23602384
struct underlying_type;
@@ -2367,37 +2391,19 @@ typedef integral_constant<bool, true> true_type;
23672391
ETL_STATIC_ASSERT(etl::is_enum<T>::value, "etl::underlying_type can only be used with enumeration types.");
23682392
};
23692393

2370-
#if ETL_USING_BUILTIN_UNDERLYING_TYPE
23712394
template <typename T>
23722395
struct underlying_type<T, true>
23732396
{
23742397
typedef __underlying_type(T) type;
23752398
};
23762399
#else
2400+
/// Primary template for etl::underlying_type
2401+
/// Users must spelialise this template for their enumerations.
23772402
template <typename T>
2378-
struct underlying_type<T, true>
2403+
struct underlying_type
23792404
{
2380-
private:
2381-
2382-
// Helper union to deduce the underlying type
2383-
union Helper
2384-
{
2385-
T enum_value;
2386-
unsigned char raw[sizeof(T)];
2387-
};
2388-
2389-
public:
2390-
2391-
// The deduced underlying type
2392-
typedef typename etl::conditional<sizeof(Helper) == sizeof(long int),
2393-
long int,
2394-
typename etl::conditional<sizeof(Helper) == sizeof(int),
2395-
int,
2396-
typename etl::conditional<sizeof(Helper) == sizeof(short),
2397-
short,
2398-
typename etl::conditional<sizeof(Helper) == sizeof(char),
2399-
char,
2400-
void>::type>::type>::type>::type type;
2405+
ETL_STATIC_ASSERT(false, "No user defined specialisation of etl::underlying_type for this type");
2406+
typedef char type;
24012407
};
24022408
#endif
24032409

include/etl/type_traits.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -713,15 +713,16 @@ namespace etl
713713
{
714714
// Base case
715715
template <typename T, typename = int>
716-
struct is_convertible_to_int : false_type
716+
struct is_convertible_to_int
717+
: false_type
717718
{
718719
};
719720

720721
// Selected if `static_cast<int>(declval<T>())` is a valid statement
721722
// 2nd template argument of base case defaults to int to ensure that this partial specialization is always tried first
722723
template <typename T>
723724
struct is_convertible_to_int<T, decltype(static_cast<int>(declval<T>()))>
724-
: true_type
725+
: true_type
725726
{
726727
};
727728
}
@@ -2389,6 +2390,8 @@ typedef integral_constant<bool, true> true_type;
23892390
typedef __underlying_type(T) type;
23902391
};
23912392
#else
2393+
/// Primary template for etl::underlying_type
2394+
/// Users must spelialise this template for their enumerations.
23922395
template <typename T>
23932396
struct underlying_type
23942397
{
@@ -2398,8 +2401,6 @@ typedef integral_constant<bool, true> true_type;
23982401
#endif
23992402

24002403
#if ETL_USING_CPP11
2401-
/// Primary template for etl::underlying_type
2402-
/// Users must spelialise this template for their enumerations.
24032404
template <typename T>
24042405
using underlying_type_t = typename underlying_type<T>::type;
24052406
#endif

0 commit comments

Comments
 (0)