/* 对不能萃取自定义class是否有trivial default ctor、assignment operator、trivial dtor的大部分编译器 可在本文件中实现该自定义class的__type_traits特化版本。 一个class什么时候会有自己的non-trivial构造析构赋值拷贝函数呢? 当class内存在指针并对它进行动态分配,即会产生浅拷贝问题,所以需要non-trivial-xxx */ //////////////////////////////////////////////////////////////////////////////// /*一个type_traits应用 template <class _ForwardIter, class _Size, class _Tp> inline _ForwardIter __uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, const _Tp& __x, __true_type) { return fill_n(__first, __n, __x); } template <class _ForwardIter, class _Size, class _Tp> _ForwardIter __uninitialized_fill_n_aux(_ForwardIter __first, _Size __n, const _Tp& __x, __false_type) { _ForwardIter __cur = __first; __STL_TRY { for ( ; __n > 0; --__n, ++__cur) _Construct(&*__cur, __x); return __cur; } __STL_UNWIND(_Destroy(__first, __cur)); } template <class _ForwardIter, class _Size, class _Tp, class _Tp1> inline _ForwardIter __uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x, _Tp1*) { typedef typename __type_traits<_Tp1>::is_POD_type _Is_POD; return __uninitialized_fill_n_aux(__first, __n, __x, _Is_POD()); } template <class _ForwardIter, class _Size, class _Tp> inline _ForwardIter uninitialized_fill_n(_ForwardIter __first, _Size __n, const _Tp& __x) { return __uninitialized_fill_n(__first, __n, __x, __VALUE_TYPE(__first)); } */ //////////////////////////////////////////////////////////////////////////////// #ifndef __TYPE_TRAITS_H #define __TYPE_TRAITS_H #ifndef __STL_CONFIG_H #include <stl_config.h> #endif // 这个头文件提供了一个框架, 允许编译器在编译期根据类型属性派发函数的机制 // 这个框架对于编写模板代码非常有用 // 例如, 当我们需要拷贝一个未知类型的array, 它能帮助我们得知这个未知类型 // 是否具有一个trivial copy constructor, 以帮助我们决定memcpy()或memmove()是否能使用 // __type_traits模板类提供了一些列的typedefs, 其值是__true_type或者__false_type // __type_traits模板类可以接受任何类型的参数 // 模板类中的typedefs可以通过以下手段获取其正确值 // 1. general instantiation, 对于所有类型都要有保守值 // 2. 经过特化的版本 // 3. 一些编译器(例如Silicon Graphics N32 and N64 compilers) // 会自动给所有类型提供合适的特化版本 // // 例子: // Copy an array of elements which have non-trivial copy constructors // template <class T> void copy(T* source,T* destination,int n,__false_type); // Copy an array of elements which have trivial copy constructors. Use memcpy. // template <class T> void copy(T* source,T* destination,int n,__true_type); // // Copy an array of any type by using the most efficient copy mechanism // template <class T> inline void copy(T* source,T* destination,int n) // { // copy(source,destination,n, // typename __type_traits<T>::has_trivial_copy_constructor()); // } //定义struct而非bool用于参数推断 struct __true_type { }; struct __false_type { }; template <class _Tp> struct __type_traits { typedef __true_type this_dummy_member_must_be_first; // 不要移除这个成员 // 它通知能自动特化__type_traits的编译器, 现在这个__type_traits template是特化的 // 这是为了确保万一编译器使用了__type_traits而与此处无任何关联的模板时 // 一切也能顺利运作 // 以下条款应当被遵守, 因为编译器有可能自动生成类型的特化版本 // - 你可以重新安排的成员次序 // - 你可以移除你想移除的成员 // - 一定不可以修改下列成员名称, 却没有修改编译器中的相应名称 // - 新加入的成员被当作一般成员, 除非编译器提供特殊支持 typedef __false_type has_trivial_default_constructor; typedef __false_type has_trivial_copy_constructor; typedef __false_type has_trivial_assignment_operator; typedef __false_type has_trivial_destructor; typedef __false_type is_POD_type; }; //POD :plain old data,可以那么理解,就是以前的c语言里面的类型和struct,或者class定义里面单单只是数据,不涉及其他的指针操作,
//也就是说可以通过memcpy拷贝就可以完成复制的 // Provide some specializations. This is harmless for compilers that // have built-in __types_traits support, and essential for compilers // that don't. //对基本类型都提供特化版本,每个成员都是__true_type,所以这些类型都可以用最快速的方式(memcpy,memmove)来拷贝或赋值 #ifndef __STL_NO_BOOL __STL_TEMPLATE_NULL struct __type_traits<bool> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #endif /* __STL_NO_BOOL */ __STL_TEMPLATE_NULL struct __type_traits<char> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<signed char> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned char> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #ifdef __STL_HAS_WCHAR_T __STL_TEMPLATE_NULL struct __type_traits<wchar_t> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #endif /* __STL_HAS_WCHAR_T */ __STL_TEMPLATE_NULL struct __type_traits<short> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned short> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<int> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned int> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<long> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned long> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #ifdef __STL_LONG_LONG __STL_TEMPLATE_NULL struct __type_traits<long long> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned long long> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #endif /* __STL_LONG_LONG */ __STL_TEMPLATE_NULL struct __type_traits<float> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<double> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<long double> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION template <class _Tp> struct __type_traits<_Tp*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #else /* __STL_CLASS_PARTIAL_SPECIALIZATION */ __STL_TEMPLATE_NULL struct __type_traits<char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<signed char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<unsigned char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<const char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<const signed char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; __STL_TEMPLATE_NULL struct __type_traits<const unsigned char*> { typedef __true_type has_trivial_default_constructor; typedef __true_type has_trivial_copy_constructor; typedef __true_type has_trivial_assignment_operator; typedef __true_type has_trivial_destructor; typedef __true_type is_POD_type; }; #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */ // The following could be written in terms of numeric_limits. // We're doing it separately to reduce the number of dependencies. //把所有是整数的类型用特化版本__true_type,否则用__false_type,然后在具体应用中调用重载函数特定版本 template <class _Tp> struct _Is_integer { typedef __false_type _Integral; }; #ifndef __STL_NO_BOOL __STL_TEMPLATE_NULL struct _Is_integer<bool> { typedef __true_type _Integral; }; #endif /* __STL_NO_BOOL */ __STL_TEMPLATE_NULL struct _Is_integer<char> { typedef __true_type _Integral; }; __STL_TEMPLATE_NULL struct _Is_integer<signed char> { typedef __true_type _Integral; }; __STL_TEMPLATE_NULL struct _Is_integer<unsigned char> { typedef __true_type _Integral; }; #ifdef __STL_HAS_WCHAR_T __STL_TEMPLATE_NULL struct _Is_integer<wchar_t> { typedef __true_type _Integral; }; #endif /* __STL_HAS_WCHAR_T */ __STL_TEMPLATE_NULL struct _Is_integer<short> { typedef __true_type _Integral; }; __STL_TEMPLATE_NULL struct _Is_integer<unsigned short> { typedef __true_type _Integral; }; __STL_TEMPLATE_NULL struct _Is_integer<int> { typedef __true_type _Integral; }; __STL_TEMPLATE_NULL struct _Is_integer<unsigned int> { typedef __true_type _Integral; }; __STL_TEMPLATE_NULL struct _Is_integer<long> { typedef __true_type _Integral; }; __STL_TEMPLATE_NULL struct _Is_integer<unsigned long> { typedef __true_type _Integral; }; #ifdef __STL_LONG_LONG __STL_TEMPLATE_NULL struct _Is_integer<long long> { typedef __true_type _Integral; }; __STL_TEMPLATE_NULL struct _Is_integer<unsigned long long> { typedef __true_type _Integral; }; #endif /* __STL_LONG_LONG */ #endif /* __TYPE_TRAITS_H */