📄 typet.hpp
字号:
/* The following code example is taken from the book * "C++ Templates - The Complete Guide" * by David Vandevoorde and Nicolai M. Josuttis, Addison-Wesley, 2002 * * (C) Copyright David Vandevoorde and Nicolai M. Josuttis 2002. * Permission to copy, use, modify, sell and distribute this software * is granted provided this copyright notice appears in all copies. * This software is provided "as is" without express or implied * warranty, and with no claim as to its suitability for any purpose. */#ifndef TYPET_HPP#define TYPET_HPP// define IsFundaT<>/********************************** * type1.hpp: **********************************/// primary template: in general T is no fundamental typetemplate <typename T>class IsFundaT { public: enum { Yes = 0, No = 1};};// macro to specialize for fundamental types#define MK_FUNDA_TYPE(T) \ template<> class IsFundaT<T> { \ public: \ enum { 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_EXISTSMK_FUNDA_TYPE(float)MK_FUNDA_TYPE(double)MK_FUNDA_TYPE(long double)#undef MK_FUNDA_TYPE/**** end of type1.hpp ****/// define primary template CompoundT<> (first version)//#include "type2.hpp"// define primary template CompoundT<> (second version)/********************************** * type6.hpp: **********************************/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 };};// same for void volatile and void const volatile//...template<typename T>class CompoundT { // primary template public: enum { IsPtrT = 0, IsRefT = 0, IsArrayT = 0, IsFuncT = IsFunctionT<T>::Yes, IsPtrMemT = 0 }; typedef T BaseT; typedef T BottomT; typedef CompoundT<void> ClassT;};/**** end of type6.hpp ****/// define CompoundT<> specializations/********************************** * type3.hpp: **********************************/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;};/**** end of type3.hpp ****//********************************** * type4.hpp: **********************************/#include <stddef.h>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;};/**** end of type4.hpp ****//********************************** * type5.hpp: **********************************/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;};//.../**** end of type5.hpp ****/// define IsEnumT<>/********************************** * type7.hpp: **********************************/struct SizeOverOne { char c[2]; };template<typename T, bool convert_possible = !CompoundT<T>::IsFuncT && !CompoundT<T>::IsArrayT>class ConsumeUDC { public: operator T() const;};// conversion to function types is not possibletemplate <typename T>class ConsumeUDC<T, false> {};// conversion to void type is not possibletemplate <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 intchar enum_check(float);char enum_check(double);char enum_check(long double);SizeOverOne enum_check(...); // catch alltemplate<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 };};/**** end of type7.hpp ****/// define IsClassT<>/********************************** * type8.hpp: **********************************/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 };};/**** end of type8.hpp ****/// define template that handles all in one styletemplate <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 };};#endif // TYPET_HPP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -