rendered paste body#ifndef SYNTH_H#define SYNTH_H#include <iostream>template <typename T> class IsFundaT { public: enum Fundamenal { Yes = 0, No = 1}; }; // macro to specialize for fundamental types #define MK_FUNDA_TYPE(T) \ template<> class IsFundaT<T> { \ public: \ enum Fundamenal { Yes = 1, No = 0 }; \ };MK_FUNDA_TYPE(void) MK_FUNDA_TYPE(bool) MK_FUNDA_TYPE(char) MK_FUNDA_TYPE(signed char) MK_FUNDA_TYPE(unsigned char) MK_FUNDA_TYPE(wchar_t) MK_FUNDA_TYPE(signed short) MK_FUNDA_TYPE(unsigned short) MK_FUNDA_TYPE(signed int) MK_FUNDA_TYPE(unsigned int) MK_FUNDA_TYPE(signed long) MK_FUNDA_TYPE(unsigned long) #if LONGLONG_EXISTS MK_FUNDA_TYPE(signed long long) MK_FUNDA_TYPE(unsigned long long) #endif // LONGLONG_EXISTS MK_FUNDA_TYPE(float) MK_FUNDA_TYPE(double) MK_FUNDA_TYPE(long double) #undef MK_FUNDA_TYPE template <typename T> void fundamental_test (T const& t) { if (IsFundaT<T>::Yes) { std::cout << "T is fundamental type" << std::endl; } else { std::cout << "T is no fundamental type" << std::endl; } } template<typename T> class CompoundT { // primary template public: enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0, IsFuncT = 0, IsPtrMemT = 0 }; typedef T BaseT; typedef T BottomT; typedef CompoundT<void> ClassT; }; template<typename T> class CompoundT<T&> { // partial specialization for references public: enum { IsPtrT = 0, IsRefT = 1, IsArrayT = 0, IsFuncT = 0, IsPtrMemT = 0 }; typedef T BaseT; typedef typename CompoundT<T>::BottomT BottomT; typedef CompoundT<void> ClassT; }; template<typename T> class CompoundT<T*> { // partial specialization for pointers public: enum { IsPtrT = 1, IsRefT = 0, IsArrayT = 0, IsFuncT = 0, IsPtrMemT = 0 }; typedef T BaseT; typedef typename CompoundT<T>::BottomT BottomT; typedef CompoundT<void> ClassT; }; template<typename T, size_t N> class CompoundT <T[N]> { // partial specialization for arrays public: enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 1, IsFuncT = 0, IsPtrMemT = 0 }; typedef T BaseT; typedef typename CompoundT<T>::BottomT BottomT; typedef CompoundT<void> ClassT; }; template<typename T> class CompoundT <T[]> { // partial specialization for empty arrays public: enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 1, IsFuncT = 0, IsPtrMemT = 0 }; typedef T BaseT; typedef typename CompoundT<T>::BottomT BottomT; typedef CompoundT<void> ClassT; }; template<typename T, typename C> class CompoundT <T C::*> { // partial specialization for pointer-to-members public: enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0, IsFuncT = 0, IsPtrMemT = 1 }; typedef T BaseT; typedef typename CompoundT<T>::BottomT BottomT; typedef C ClassT; }; template<typename R> class CompoundT<R()> { public: enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0, IsFuncT = 1, IsPtrMemT = 0 }; typedef R BaseT(); typedef R BottomT(); typedef CompoundT<void> ClassT; }; template<typename R, typename P1> class CompoundT<R(P1)> { public: enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0, IsFuncT = 1, IsPtrMemT = 0 }; typedef R BaseT(P1); typedef R BottomT(P1); typedef CompoundT<void> ClassT; }; template<typename R, typename P1> class CompoundT<R(P1, ...)> { public: enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0, IsFuncT = 1, IsPtrMemT = 0 }; typedef R BaseT(P1); typedef R BottomT(P1); typedef CompoundT<void> ClassT; }; template<typename T> class IsFunctionT { private: typedef char One; typedef struct { char a[2]; } Two; template<typename U> static One test(...); template<typename U> static Two test(U (*)[1]); public: enum { Yes = sizeof(IsFunctionT<T>::test<T>(0)) == 1 }; enum { No = !Yes }; }; template<typename T> class IsFunctionT<T&> { public: enum { Yes = 0 }; enum { No = !Yes }; }; template<> class IsFunctionT<void> { public: enum { Yes = 0 }; enum { No = !Yes }; }; template<> class IsFunctionT<void const> { public: enum { Yes = 0 }; enum { No = !Yes }; }; struct SizeOverOne { char c[2]; }; template<typename T, bool convert_possible = !CompoundT<T>::IsFuncT && !CompoundT<T>::IsArrayT> class ConsumeUDC { public: operator T() const; };template <typename T> class ConsumeUDC<T, false> { }; template <bool convert_possible> class ConsumeUDC<void, convert_possible> { }; char enum_check(bool); char enum_check(char); char enum_check(signed char); char enum_check(unsigned char); char enum_check(wchar_t); char enum_check(signed short); char enum_check(unsigned short); char enum_check(signed int); char enum_check(unsigned int); char enum_check(signed long); char enum_check(unsigned long); #if LONGLONG_EXISTS char enum_check(signed long long); char enum_check(unsigned long long); #endif // LONGLONG_EXISTS // avoid accidental conversions from float to int char enum_check(float); char enum_check(double); char enum_check(long double); SizeOverOne enum_check(...); // catch all template<typename T> class IsEnumT { public: enum { Yes = IsFundaT<T>::No && !CompoundT<T>::IsRefT && !CompoundT<T>::IsPtrT && !CompoundT<T>::IsPtrMemT && sizeof(enum_check(ConsumeUDC<T>()))==1 }; enum { No = !Yes }; }; template<typename T> class IsClassT { public: enum { Yes = IsFundaT<T>::No && IsEnumT<T>::No && !CompoundT<T>::IsPtrT && !CompoundT<T>::IsRefT && !CompoundT<T>::IsArrayT && !CompoundT<T>::IsPtrMemT && !CompoundT<T>::IsFuncT }; enum { No = !Yes }; }; template <typename T> class TypeT { public: enum { IsFundaT = IsFundaT<T>::Yes, IsPtrT = CompoundT<T>::IsPtrT, IsRefT = CompoundT<T>::IsRefT, IsArrayT = CompoundT<T>::IsArrayT, IsFuncT = CompoundT<T>::IsFuncT, IsPtrMemT = CompoundT<T>::IsPtrMemT, IsEnumT = IsEnumT<T>::Yes, IsClassT = IsClassT<T>::Yes }; }; template <typename T> void check() { if (TypeT<T>::IsFundaT) { std::cout << " IsFundaT "; } if (TypeT<T>::IsPtrT) { std::cout << " IsPtrT "; } if (TypeT<T>::IsRefT) { std::cout << " IsRefT "; } if (TypeT<T>::IsArrayT) { std::cout << " IsArrayT "; } if (TypeT<T>::IsFuncT) { std::cout << " IsFuncT "; } if (TypeT<T>::IsPtrMemT) { std::cout << " IsPtrMemT "; } if (TypeT<T>::IsEnumT) { std::cout << " IsEnumT "; } if (TypeT<T>::IsClassT) { std::cout << " IsClassT "; } std::cout << std::endl; } // check by passing type as function call argument template <typename T> void checkT (T) { check<T>(); // for pointer types check type of what they refer to if (TypeT<T>::IsPtrT || TypeT<T>::IsPtrMemT) { check<typename CompoundT<T>::BaseT>(); } } void test_synth(){ fundamental_test(Vector<float,3>()); fundamental_test(int()); std::cout << "int:" << std::endl; check<int>(); std::cout << "int&:" << std::endl; check<int&>(); std::cout << "char[42]:" << std::endl; check<char[42]>(); std::cout << "MyClass:" << std::endl; check<Vector<int,3>>(); std::cout << "ptr to enum:" << std::endl; E* ptr = 0; checkT(ptr); std::cout << "42:" << std::endl; checkT(42); std::cout << "test_synth()():" << std::endl; checkT(test_synth); /* std::cout << "memptr to array:" << std::endl; char (MyClass::* memptr) [] = 0; checkT(memptr); */}#endif // SYNTH_H