⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 typetraits.h

📁 高级范型编程
💻 H
字号:
// -*- C++ -*-

//##############################################################################
//The dnc Library
//Copyright (c) 2005 Dreamsoft 赵纯华
//定义Type操作的基础设施
//##############################################################################
//
//Last update: 2005-11-9

#ifndef __DNC_TYPETRAITS_H__
#define __DNC_TYPETRAITS_H__

/** If the compiler can implementation is_base<T> template,then has
 *  DNC_CANCHECKBASE define.
 */
#if !defined(__DMC__) && !defined(DNC_CANCHECKBASE)
#define DNC_CANCHECKBASE
#endif

namespace dnc{
    /**
     *  提供两个尺寸不一样的类型,用于sizeof操作符获得不同的静态整数
     */
    typedef char yes_type;
    struct no_type{
        char padding[8];
    };

    /**
     *  把整数或者一种类型转换成另一种类型,把一个常数或者类型进行强化
     *  @code
     *      //根据整数重载函数
     *      void foo(int2type<0>){
     *      }
     *      void foo(int2type<1>){
     *      }
     *      //根据整数调用函数
     *      void test(){
     *          foo(int2type<0>()); //call foo(int2type<0>)
     *          foo(int2type<1>()); //call foo(int2type<1>)
     *      }
     *
     *      //根据类型重载函数,但是不为类型创建对象
     *      void foo(type2type<MyType>){
     *      }
     *      void foo(type2type<int>){
     *      }
     *      //根据类型调用函数,但是不创建这个类型的对象
     *      void test(){
     *          foo(type2type<MyType>()); //call foo(type2type<MyType>);
     *          foo(type2type<int>());    //call foo(type2type<int>);
     *      }
     *  @endcode
     */
    template <int v>    struct int2type{enum { value = v };};
    template <class T>  struct type2type{typedef T OriginalType;};

    /**
     *  类型选择器,相当于一个三元运算符
     */
	template<bool flag>
	struct selector_helper{
		template<class T,class U>
		struct select{
			typedef T type;
		};
	};
	template<>
	struct selector_helper<false>{
		template<class T,class U>
		struct select{
			typedef U type;
		};
	};
	template <bool flag, typename T, typename U>
    struct selector{
		typedef typename selector_helper<flag>::template select<T,U>::type type;
	};


    /** cv_traits<T> const volatile traits.
     *  多数compiler不能对const和volatile修饰进行模板特化,但是能对被const和
     *  volatile修饰的指针进行特化,这样其实通过简单的转化就能处理任意的类型,所以
     *  把这两种情况放在一起处理.
     *  @param T any C++ type
     *  @return type 没有经过const 和 volatile修饰的类型.
     *  @return is_const Bool value whether T is const.
     *  @return is_volatile Bool value whether T is volatile.
     */
    template <typename T> struct cv_traits{};

    template <typename T>
    struct cv_traits<T*>{
        enum{is_const = false,is_volatile = false};
        typedef T type;
    };

    template <typename T>
    struct cv_traits<const T*>{
        enum{is_const = true,is_volatile = false};
        typedef T type;
    };

    template <typename T>
    struct cv_traits<volatile T*>{
        enum{is_const = false,is_volatile = true};
        typedef T type;
    };

    template <typename T>
    struct cv_traits<const volatile T*>{
        enum{is_const = true,is_volatile = true};
        typedef T type;
    };
    
//------------------------------------------------------------------------------
//判断是否是数组类型
//------------------------------------------------------------------------------
#if 0
	template< typename T > T(* is_array_tester1(type2type<T>) )(type2type<T>);
	char is_array_tester1(...);

	template< typename T> no_type is_array_tester2(T(*)(type2type<T>));
	yes_type is_array_tester2(...);

	template< typename T >
	struct is_array
	{ 
		enum {
			value = 
			sizeof(is_array_tester2(
					is_array_tester1(
					type2type<T>()
					)
			)) == 1
		};
	};
#else
	template<class T> struct is_array{enum{value=false};};
	template<class T> struct is_array<T[]>{enum{value=true};};
#ifndef __DMC__
	template<class T,int C> struct is_array<T[C]>{enum{value=true};};
#endif
    
#endif


    template <typename T> struct is_pointer{
        enum{value=false};
    };
    template <typename T> struct is_pointer<T*>{
        enum{value=true};
    };
    template <typename T> struct is_pointer<const T*>{
        enum{value=true};
    };
    template <typename T> struct is_reference{
        enum{value=false};
    };
    template <typename T> struct is_reference<T&>{
        enum{value=true};
    };
    template <typename T> struct is_reference<const T&>{
        enum{value=true};
    };
    /** template<class T> is_const;
     */
    template <typename T> struct is_const{
        enum{value=cv_traits<T>::is_const};
    };
    /** remove_reference<T>
     */
    template<class T> struct remove_reference{
        typedef T type;
    };
    template<class T> struct remove_reference<T&>{
        typedef T type;
    };
    template<class T> struct remove_pointer{
        typedef T type;
    };
    template<class T> struct remove_pointer<T*>{
        typedef T type;
    };
    template <typename T, bool is_vol>
    struct remove_const_helper{
        typedef T type;
    };

    template <typename T>
    struct remove_const_helper<T, true>{
        typedef T volatile type;
    };
    
    template <typename T>
    struct remove_const{
        typedef typename cv_traits<T*>::type unqualified_type;
        enum{is_volatile = cv_traits<T*>::is_volatile};
        typedef typename remove_const_helper<
                unqualified_type,is_volatile
            >::type type;
    };
//------------------------------------------------------------------------------
//is_integral 判断是否是整数类型
//------------------------------------------------------------------------------
	template<class T> struct is_integral{enum{value=false};};

	template<> struct is_integral<unsigned char>{enum{value=true};};
	template<> struct is_integral<unsigned short>{enum{value=true};};
	template<> struct is_integral<unsigned int>{enum{value=true};};
	template<> struct is_integral<unsigned long>{enum{value=true};};
#ifdef DNC_HASLONGLONG
	template<> struct is_integral<unsigned long long>{enum{value=true};};
#endif
    template<> struct is_integral<signed char>{enum{value=true};};
	template<> struct is_integral<signed short>{enum{value=true};};
	template<> struct is_integral<signed int>{enum{value=true};};
	template<> struct is_integral<signed long>{enum{value=true};};
#ifdef DNC_HASLONGLONG
	template<> struct is_integral<long long>{enum{value=true};};
#endif
	template<> struct is_integral<bool>{enum{value=true};};
	template<> struct is_integral<char>{enum{value=true};};
#ifdef DNC_HASWCHAR
	template<> struct is_integral<wchar_t>{enum{value=true};};
#endif

//------------------------------------------------------------------------------
//is_float 判断是否是浮点数类型
//------------------------------------------------------------------------------
	template<class T> struct is_float{enum{value=false};};
	template<> struct is_float<float>{enum{value=true};};
	template<> struct is_float<double>{enum{value=true};};
	template<> struct is_float<long double>{enum{value=true};};

//------------------------------------------------------------------------------
//判断是否是算数类型
//------------------------------------------------------------------------------
	template<class T> struct is_arithmetic
	{enum{value=is_integral<T>::value||is_float<T>::value};};



//------------------------------------------------------------------------------
//判断是否是void类型
//------------------------------------------------------------------------------
	template<typename T> struct is_void{enum{value=false};};
	template<> struct is_void<void> {enum{value=true};};

//------------------------------------------------------------------------------
//判断是否是class或者union或者struct
//------------------------------------------------------------------------------
	template <typename T>
	struct is_class{
        template <class U> static yes_type is_class_or_union_tester(void(U::*)(void));
		template <class U> static no_type  is_class_or_union_tester(...);
		enum{value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(yes_type)};
	};

//------------------------------------------------------------------------------
//判断From是否能转换成To
//------------------------------------------------------------------------------
	template <class From, class To>
    struct is_convertible{
	private:
		static no_type	is_convertible_tester(...);
		static yes_type is_convertible_tester(To);
	public:
		enum{value = sizeof(is_convertible_tester(From())) == sizeof(yes_type)};
	};
//------------------------------------------------------------------------------
//判断T和U是否是同一种类型
//------------------------------------------------------------------------------
	template <class T, class U>
	struct is_same{
	private:
		static yes_type is_same_tester(T**, T**);
		static no_type  is_same_tester(...);
	public:
		enum{value = 
			sizeof(yes_type) == sizeof(is_same_tester((T**)0,(U**)0)) && 
			sizeof(T) == sizeof(U)
		};
	};
//------------------------------------------------------------------------------
//判断是否是枚举类型
//------------------------------------------------------------------------------
	template<bool flag,class T>
	struct is_enum_helper{
        static no_type	 is_enum_tester(...);
        static yes_type is_enum_tester(int);
        enum{value = sizeof(is_enum_tester(T())) == sizeof(yes_type)};
	};
	template<class T>
	struct is_enum_helper<true,T>{
        enum{value=false};
	};
	template<typename T>
	struct is_enum{
		enum{
            value=is_enum_helper<
                is_integral<T>::value||
                is_float<T>::value||
                is_void<T>::value||
                is_array<T>::value||
                is_class<T>::value||
                is_pointer<T>::value||
                is_reference<T>::value,T>::value
           };
	};
//------------------------------------------------------------------------------
//remove const and volatile modifier
//------------------------------------------------------------------------------
	template<class T>
	struct remove_cv{
		typedef typename cv_traits<T*>::type type;
	};
//------------------------------------------------------------------------------
//判断B是否是D的基类
//------------------------------------------------------------------------------
#ifdef DNC_CANCHECKBASE
    template <typename B, typename D>
    struct bd_helper{
        template <typename T>
        static yes_type check(D const volatile *, T);
        static no_type  check(B const volatile *, int);
    };
    template<typename B, typename D>
    struct is_base_impl2{
        struct Host{
            operator D const volatile *();
            operator B const volatile *() const;
        };
        enum{value = sizeof(bd_helper<B,D>::check(Host(), 0)) ==
                 sizeof(yes_type)};
    };    
#else
    //broken version
    template<typename B, typename D>
    struct is_base_impl2{
        enum{value = is_convertible<D*,B*>::value};
    };
#endif
    template <typename B, typename D>
    struct is_base_impl3{
        enum{value = false};
    };

    template <bool ic1, bool ic2, bool iss>
    struct is_base_select{
        template <class T, class U>
        struct rebind
        {
            typedef is_base_impl3<T,U> type;
        };
    };

    template <>
    struct is_base_select<true,true,false>{
        template <class T, class U>
        struct rebind
        {
            typedef is_base_impl2<T,U> type;
        };
    };

    template <typename B, typename D>
    struct is_base{
        typedef typename cv_traits<B*>::type ncvB;
        typedef typename cv_traits<D*>::type ncvD;
        enum{
            b_is_class = is_class<B>::value,
                d_is_class = is_class<D>::value,
                bd_is_same = is_same<B,D>::value
                };
        typedef is_base_select<
            b_is_class,
            d_is_class,
            bd_is_same> binder_selector;
        typedef typename binder_selector::template rebind<ncvB,ncvD> binder;
        typedef typename binder::type bound_type;

        enum{value = bound_type::value};
    };
}
#endif //__DNC_TYPETRAITS_H__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -