#ifndef TYPE_TRAITS_H
#define TYPE_TRAITS_H
template <typename T>
struct TypeTraits
{
private:
struct NullType {};
template <typename U> struct UnConst
{
typedef U Result;
};
template <typename U> struct UnConst<const U>
{
typedef U Result;
};
template <typename U> struct ReferenceTraits
{
enum {IsReference = 0};
typedef U ReferencedType;
};
template <typename U> struct ReferenceTraits<U&>
{
enum {IsReference = 1};
typedef U ReferencedType;
};
template <typename U> struct PointerTraits
{
enum {IsPointer = 0};
typedef U PointeeType;
};
template <typename U> struct PointerTraits<U *>
{
enum {IsPointer = 1};
typedef U PointeeType;
};
template <typename U> struct FunctionPtrTraits
{
enum {IsFunctionPointer = 0};
};
template <typename U>
struct FunctionPtrTraits <U (*) (void)>
{
enum {IsFunctionPointer = 1};
enum {nArgs = 0};
typedef U ReturnType;
};
template <typename U, typename V1>
struct FunctionPtrTraits <U (*) (V1)>
{
enum {IsFunctionPointer = 1};
enum {nArgs = 1};
typedef U ReturnType;
typedef V1 Arg1Type;
};
template <typename U, typename V1, typename V2>
struct FunctionPtrTraits <U (*) (V1,V2)>
{
enum {IsFunctionPointer = 1};
enum {nArgs = 2};
typedef U ReturnType;
typedef V1 Arg1Type;
typedef V2 Arg2Type;
};
template <typename U, typename V1, typename V2,
typename V3>
struct FunctionPtrTraits <U (*) (V1,V2,V3)>
{
enum {IsFunctionPointer = 1};
enum {nArgs = 3};
typedef U ReturnType;
typedef V1 Arg1Type;
typedef V2 Arg2Type;
typedef V3 Arg3Type;
};
template <typename U, typename V1, typename V2,
typename V3, typename V4>
struct FunctionPtrTraits <U (*) (V1,V2,V3,V4)>
{
enum {IsFunctionPointer = 1};
enum {nArgs = 4};
typedef U ReturnType;
typedef V1 Arg1Type;
typedef V2 Arg2Type;
typedef V3 Arg3Type;
typedef V4 Arg4Type;
};
template <typename U, typename V1, typename V2,
typename V3, typename V4,
typename V5>
struct FunctionPtrTraits <U (*) (V1,V2,V3,V4,V5)>
{
enum {IsFunctionPointer = 1};
enum {nArgs = 5};
typedef U ReturnType;
typedef V1 Arg1Type;
typedef V2 Arg2Type;
typedef V3 Arg3Type;
typedef V4 Arg4Type;
typedef V5 Arg5Type;
};
template <typename U, typename V1, typename V2,
typename V3, typename V4,
typename V5, typename V6>
struct FunctionPtrTraits <U (*) (V1,V2,V3,V4,V5,V6)>
{
enum {IsFunctionPointer = 1};
enum {nArgs = 6};
typedef U ReturnType;
typedef V1 Arg1Type;
typedef V2 Arg2Type;
typedef V3 Arg3Type;
typedef V4 Arg4Type;
typedef V5 Arg5Type;
typedef V6 Arg6Type;
};
template <typename U> struct PtrToMemberTraits
{
enum {IsPointerToMember = 0};
};
template <typename U, typename V>
struct PtrToMemberTraits <U (V::*) (void)>
{
enum {IsPointerToMember = 1};
enum {nArgs = 0};
typedef U ReturnType;
};
template <typename U, typename V>
struct PtrToMemberTraits <U (V::*) (void) const>
{
enum {IsPointerToMember = 1};
enum {nArgs = 0};
typedef U ReturnType;
};
template <typename U, typename V,typename W1>
struct PtrToMemberTraits <U (V::*) (W1)>
{
enum {IsPointerToMember = 1};
enum {nArgs = 1};
typedef U ReturnType;
typedef W1 Arg1Type;
};
template <typename U, typename V,typename W1>
struct PtrToMemberTraits <U (V::*) (W1) const>
{
enum {IsPointerToMember = 1};
enum {nArgs = 1};
typedef U ReturnType;
typedef W1 Arg1Type;
};
template <typename U, typename V,typename W1, typename W2>
struct PtrToMemberTraits <U (V::*) (W1,W2)>
{
enum {IsPointerToMember = 1};
enum {nArgs = 2};
typedef U ReturnType;
typedef W1 Arg1Type;
typedef W2 Arg2Type;
};
template <typename U, typename V,typename W1, typename W2>
struct PtrToMemberTraits <U (V::*) (W1,W2) const>
{
enum {IsPointerToMember = 1};
enum {nArgs = 2};
typedef U ReturnType;
typedef W1 Arg1Type;
typedef W2 Arg2Type;
};
template <typename U, typename V,
typename W1, typename W2,
typename W3>
struct PtrToMemberTraits <U (V::*) (W1,W2,W3)>
{
enum {IsPointerToMember = 1};
enum {nArgs = 3};
typedef U ReturnType;
typedef W1 Arg1Type;
typedef W2 Arg2Type;
typedef W3 Arg3Type;
};
template <typename U, typename V,
typename W1, typename W2,
typename W3>
struct PtrToMemberTraits <U (V::*) (W1,W2,W3) const>
{
enum {IsPointerToMember = 1};
enum {nArgs = 3};
typedef U ReturnType;
typedef W1 Arg1Type;
typedef W2 Arg2Type;
typedef W3 Arg3Type;
};
template <typename U, typename V,
typename W1, typename W2,
typename W3, typename W4>
struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4)>
{
enum {IsPointerToMember = 1};
enum {nArgs = 4};
typedef U ReturnType;
typedef W1 Arg1Type;
typedef W2 Arg2Type;
typedef W3 Arg3Type;
typedef W4 Arg4Type;
};
template <typename U, typename V,
typename W1, typename W2,
typename W3, typename W4>
struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4) const>
{
enum {IsPointerToMember = 1};
enum {nArgs = 4};
typedef U ReturnType;
typedef W1 Arg1Type;
typedef W2 Arg2Type;
typedef W3 Arg3Type;
typedef W4 Arg4Type;
};
template <typename U, typename V,
typename W1, typename W2,
typename W3, typename W4,
typename W5>
struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4,W5)>
{
enum {IsPointerToMember = 1};
enum {nArgs = 5};
typedef U ReturnType;
typedef W1 Arg1Type;
typedef W2 Arg2Type;
typedef W3 Arg3Type;
typedef W4 Arg4Type;
typedef W5 Arg5Type;
};
template <typename U, typename V,
typename W1, typename W2,
typename W3, typename W4,
typename W5>
struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4,W5) const>
{
enum {IsPointerToMember = 1};
enum {nArgs = 5};
typedef U ReturnType;
typedef W1 Arg1Type;
typedef W2 Arg2Type;
typedef W3 Arg3Type;
typedef W4 Arg4Type;
typedef W5 Arg5Type;
};
template <typename U, typename V,
typename W1, typename W2,
typename W3, typename W4,
typename W5, typename W6>
struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4,W5,W6)>
{
enum {IsPointerToMember = 1};
enum {nArgs = 6};
typedef U ReturnType;
typedef W1 Arg1Type;
typedef W2 Arg2Type;
typedef W3 Arg3Type;
typedef W4 Arg4Type;
typedef W5 Arg5Type;
typedef W6 Arg6Type;
};
template <typename U, typename V,
typename W1, typename W2,
typename W3, typename W4,
typename W5, typename W6>
struct PtrToMemberTraits <U (V::*) (W1,W2,W3,W4,W5,W6) const>
{
enum {IsPointerToMember = 1};
enum {nArgs = 6};
typedef U ReturnType;
typedef W1 Arg1Type;
typedef W2 Arg2Type;
typedef W3 Arg3Type;
typedef W4 Arg4Type;
typedef W5 Arg5Type;
typedef W6 Arg6Type;
};
public:
typedef typename UnConst<T>::Result NonConstType;
typedef typename ReferenceTraits<T>::ReferencedType ReferencedType;
typedef typename PointerTraits<T>::PointeeType PointeeType;
enum {IsPointerToMember = PtrToMemberTraits<T>::IsPointerToMember};
enum {IsPointer = PointerTraits<T>::IsPointer};
enum {IsReference = ReferenceTraits<T>::IsReference};
enum {IsFunctionPointer = FunctionPtrTraits<T>::IsFunctionPointer};
typedef PtrToMemberTraits<T> PointerToMemberTraits;
typedef FunctionPtrTraits<T> FunctionPointerTraits;
};
#endif /* TYPE_TRAITS_H */