AMCAX Kernel 1.0.0.0
SFINAE.hpp File Reference

Defines commonly used SFINAE utils. More...

#include <type_traits>
Include dependency graph for SFINAE.hpp:

Namespaces

namespace  AMCAX
 Namespace of all interface in the AMCAX kernel.
 
namespace  AMCAX::Meshing
 Namespace of all interface in the AMCAX Meshing module.
 

Macros

#define CLASS_HAS_FUNC(ClassName, FuncName)
 Check if a class has specified function. More...
 
#define CLASS_HAS_CONST_FUNC(ClassName, FuncName)
 Check if a class has specified const function. More...
 
#define CLASS_HAS_STATIC_FUNC(ClassName, FuncName)
 check if a class has specified function. More...
 
#define CLASS_HAS_TYPE(ClassName, TypeName)
 check if a class has specified type. More...
 
#define GET_TYPE_OTHERWISE_DEFAULT(ClassName, TypeName, DefaultType, Result)
 Check if a class has specified type then get the type, otherwise get the default type. More...
 
#define GET_TYPE_OTHERWISE_VOID(ClassName, TypeName, Result)    GET_TYPE_OTHERWISE_DEFAULT(ClassName, TypeName, void, Result)
 Check if a class has specified type then get the type, otherwise get the void type. More...
 
#define CLASS_HAS_VALUE(ClassName, ValueName, Result)
 check if a class has specified value. More...
 
#define GET_VALUE_OTHERWISE_DEFAULT(ClassName, ValueType, ValueName, DefaultValue, Result)
 

Detailed Description

Defines commonly used SFINAE utils.

This file is part of AMCAX kernel.

Macro Definition Documentation

◆ CLASS_HAS_CONST_FUNC

#define CLASS_HAS_CONST_FUNC (   ClassName,
  FuncName 
)
Value:
template <typename... Args> \
class SFINAE_##ClassName##_has_##FuncName \
{ \
template <typename C, \
typename = decltype(std::declval<std::add_const_t<C>>() \
.FuncName(std::declval<Args>()...))> \
static std::true_type test(int); \
template <typename C> \
static std::false_type test(...); \
\
public: \
static constexpr bool value = decltype(test<ClassName>(0))::value; \
};

Check if a class has specified const function.

Template Parameters
ArgsParameter types passed to the function.
Note
You need to pass function parameters to this template by yourself.

◆ CLASS_HAS_FUNC

#define CLASS_HAS_FUNC (   ClassName,
  FuncName 
)
Value:
template <typename... Args> \
class SFINAE_##ClassName##_has_##FuncName \
{ \
template <typename C, typename = decltype(std::declval<C>().FuncName( \
std::declval<Args>()...))> \
static std::true_type test(int); \
template <typename C> \
static std::false_type test(...); \
\
public: \
static constexpr bool value = decltype(test<ClassName>(0))::value; \
};

Check if a class has specified function.

Template Parameters
ArgsParameter types passed to the function.
Note
You need to pass function parameters to this template by yourself.

◆ CLASS_HAS_STATIC_FUNC

#define CLASS_HAS_STATIC_FUNC (   ClassName,
  FuncName 
)
Value:
template <typename RetT, typename... Args> \
class SFINAE_##ClassName##_has_##FuncName \
{ \
template <typename F, F> \
struct helper \
{ \
}; \
template <typename C> \
static constexpr std::true_type \
test(helper<RetT (*)(Args...), C::FuncName> *); \
template <typename C> \
static constexpr std::false_type test(...); \
\
public: \
static constexpr bool value = decltype(test<ClassName>(nullptr))::value; \
};

check if a class has specified function.

A non-static member function receives an instance of the class as first parameter. So we need to explicitly declare the function type of "func". "typename F" is the type of function, "F" is the instance of function.

Note
You need to pass return type and paramters type to this template by yourself.

◆ CLASS_HAS_TYPE

#define CLASS_HAS_TYPE (   ClassName,
  TypeName 
)
Value:
class SFINAE_##ClassName##_has_##TypeName \
{ \
template <typename C> \
static constexpr std::true_type test(typename C::TypeName *); \
template <typename C> \
static constexpr std::false_type test(...); \
\
public: \
static constexpr bool value = decltype(test<ClassName>(nullptr))::value; \
};

check if a class has specified type.

◆ CLASS_HAS_VALUE

#define CLASS_HAS_VALUE (   ClassName,
  ValueName,
  Result 
)
Value:
class SFINAE_##ClassName##_has_##ValueName \
{ \
template <typename C> \
static constexpr std::true_type test(typename decltype(C::ValueName) *); \
template <typename C> \
static constexpr std::false_type test(...); \
\
public: \
static constexpr bool value = decltype(test<ClassName>(nullptr))::value; \
}; \
static constexpr bool Result = SFINAE_##ClassName##_has_##ValueName::value;

check if a class has specified value.

◆ GET_TYPE_OTHERWISE_DEFAULT

#define GET_TYPE_OTHERWISE_DEFAULT (   ClassName,
  TypeName,
  DefaultType,
  Result 
)
Value:
class SFINAE_get_##TypeName##_from_##ClassName \
{ \
template <typename C> \
static constexpr auto test(typename C::TypeName *) -> \
typename C::TypeName; \
template <typename C> \
static constexpr auto test(...) -> DefaultType; \
\
public: \
typedef decltype(test<ClassName>(nullptr)) type; \
}; \
using Result = typename SFINAE_get_##TypeName##_from_##ClassName::type;

Check if a class has specified type then get the type, otherwise get the default type.

Parameters
ClassNameThe class where to find type.
TypeNameThe name of the type.
DefaultTypeIf doesn't find the type, the return DefaultType.
ResultFound result will be stored in Result.

◆ GET_TYPE_OTHERWISE_VOID

#define GET_TYPE_OTHERWISE_VOID (   ClassName,
  TypeName,
  Result 
)     GET_TYPE_OTHERWISE_DEFAULT(ClassName, TypeName, void, Result)

Check if a class has specified type then get the type, otherwise get the void type.

Parameters
ClassNameThe class where to find type.
TypeNameThe name of the type.
ResultFound result will be stored in Result.

◆ GET_VALUE_OTHERWISE_DEFAULT

#define GET_VALUE_OTHERWISE_DEFAULT (   ClassName,
  ValueType,
  ValueName,
  DefaultValue,
  Result 
)
Value:
class SFINAE_get_##ValueName##_from_##ClassName \
{ \
template <typename C> \
static constexpr ValueType test(decltype(C::ValueName) *) \
{ \
return C::ValueName; \
} \
template <typename C> \
static constexpr ValueType test(...) \
{ \
return DefaultValue; \
} \
\
public: \
static constexpr ValueType value = test<ClassName>(nullptr); \
}; \
static constexpr ValueType Result = \
SFINAE_get_##ValueName##_from_##ClassName::value;