Refactor serial class with templates (#20783)
This commit is contained in:
@@ -314,6 +314,32 @@
|
||||
|
||||
#endif
|
||||
|
||||
// C++11 solution that is standard compliant. <type_traits> is not available on all platform
|
||||
namespace Private {
|
||||
template<bool, typename _Tp = void> struct enable_if { };
|
||||
template<typename _Tp> struct enable_if<true, _Tp> { typedef _Tp type; };
|
||||
}
|
||||
// C++11 solution using SFINAE to detect the existance of a member in a class at compile time.
|
||||
// It creates a HasMember<Type> structure containing 'value' set to true if the member exists
|
||||
#define HAS_MEMBER_IMPL(Member) \
|
||||
namespace Private { \
|
||||
template <typename Type, typename Yes=char, typename No=long> struct HasMember_ ## Member { \
|
||||
template <typename C> static Yes& test( decltype(&C::Member) ) ; \
|
||||
template <typename C> static No& test(...); \
|
||||
enum { value = sizeof(test<Type>(0)) == sizeof(Yes) }; }; \
|
||||
}
|
||||
|
||||
// Call the method if it exists, but do nothing if it does not. The method is detected at compile time.
|
||||
// If the method exists, this is inlined and does not cost anything. Else, an "empty" wrapper is created, returning a default value
|
||||
#define CALL_IF_EXISTS_IMPL(Return, Method, ...) \
|
||||
HAS_MEMBER_IMPL(Method) \
|
||||
namespace Private { \
|
||||
template <typename T, typename ... Args> FORCE_INLINE typename enable_if<HasMember_ ## Method <T>::value, Return>::type Call_ ## Method(T * t, Args... a) { return static_cast<Return>(t->Method(a...)); } \
|
||||
_UNUSED static Return Call_ ## Method(...) { return __VA_ARGS__; } \
|
||||
}
|
||||
#define CALL_IF_EXISTS(Return, That, Method, ...) \
|
||||
static_cast<Return>(Private::Call_ ## Method(That, ##__VA_ARGS__))
|
||||
|
||||
#else
|
||||
|
||||
#define MIN_2(a,b) ((a)<(b)?(a):(b))
|
||||
|
||||
Reference in New Issue
Block a user