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

📄 typetraits.h

📁 exmat - The Expression Template Matrix Library,是矩阵运算模板库
💻 H
📖 第 1 页 / 共 2 页
字号:
        struct AdjReference
        {
            template<typename U>
            struct In { typedef U const & Result; };
        };

        template<>
        struct AdjReference<true>
        {
            template<typename U>
            struct In { typedef U Result; };
        };
		struct PointerHelper
		{
			PointerHelper(const volatile void*);
		};


		template <class T>
		NO EnumDetection(T);

		template <class T>
		YES  EnumDetection(...);

		YES IsPointer(PointerHelper);
		NO  IsPointer(...);

		// With the VC 6. Rani Sharoni's approach to detect references unfortunately
		// results in an error C1001: INTERNAL COMPILER-ERROR
		//
		// this reference-detection approach is based on boost's
		// Type-Traits. See: boost::composite_traits.h
		//
		// is_reference_helper1 is a function taking a Type2Type<T> returning
		// a pointer to a function taking a Type2Type<T> returning a T&.
		// This function can only be used if T is not a reference-Type.
		// If T is a reference Type the return type would be
		// a function taking a Type2Type<T> returning a reference to a T-reference.
		// That is illegal, therefore is_reference_helper1(...) is used for
		// references.
		// In order to detect a reference, use the return-type of is_reference_helper1
		// with is_reference_helper2.
		//
		template <class U>
		U&(* IsReferenceHelper1(::Loki::Type2Type<U>) )(::Loki::Type2Type<U>);
		NO	IsReferenceHelper1(...);

		template <class U>
		NO	IsReferenceHelper2(U&(*)(::Loki::Type2Type<U>));
		YES IsReferenceHelper2(...);

		template <class U, class Z>
		YES IsPointer2Member(Z U::*);
		NO	IsPointer2Member(...);

		// this array-detection approach is based on boost's
		// Type-Traits. See: boost::array_traits.hpp
		
		// This function can only be used for non-array-types, because
		// functions can't return arrays.
		template<class U>
		U(* IsArrayTester1(::Loki::Type2Type<U>) )(::Loki::Type2Type<U>);
		char IsArrayTester1(...);

		template<class U>
		NO IsArrayTester2(U(*)(::Loki::Type2Type<U>));
		YES IsArrayTester2(...);

		// Helper functions for function-pointer detection.
		// The code uses the fact, that arrays of functions are not allowed.
		// Of course TypeTraits first makes sure that U is neither void
		// nor a reference.type.
		// The idea for this code is from D Vandevoorde's & N. Josuttis'
		// book "C++ Templates".
		template<class U> 
		NO IsFunctionPtrTester1(U*, U(*)[1] = 0);
		YES IsFunctionPtrTester1(...);
	}

	template <typename T>
    class TypeTraits
    {
	public:
		enum { isVoid = Private::IsVoid<T>::value};
		enum { isStdUnsignedInt =
            TL::IndexOf<Private::StdUnsignedInts, T>::value >= 0 };
        enum { isStdSignedInt =
            TL::IndexOf<Private::StdSignedInts, T>::value >= 0 };
        enum { isStdIntegral = isStdUnsignedInt || isStdSignedInt ||
            TL::IndexOf<Private::StdOtherInts, T>::value >= 0 };
        enum { isStdFloat = TL::IndexOf<Private::StdFloats, T>::value >= 0 };
        enum { isStdArith = isStdIntegral || isStdFloat };
        enum { isStdFundamental = isStdArith || isStdFloat || isVoid };

        enum { isUnsignedInt = isStdUnsignedInt || IsCustomUnsignedInt<T>::value };
        enum { isSignedInt = isStdSignedInt || IsCustomSignedInt<T>::value };
        enum { isIntegral = isStdIntegral || isUnsignedInt || isSignedInt };
        enum { isFloat = isStdFloat || IsCustomFloat<T>::value };
        enum { isArith = isIntegral || isFloat };
        enum { isFundamental = isStdFundamental || isArith || isFloat };

		enum { isArray	= sizeof(Private::YES) 
						== sizeof(Private::IsArrayTester2(
									Private::IsArrayTester1(::Loki::Type2Type<T>()))
							) 
		};
		
		enum { isReference	= sizeof(Private::YES) 
							== sizeof(Private::IsReferenceHelper2(
										Private::IsReferenceHelper1(::Loki::Type2Type<T>()))
								) && !isVoid
		};
		enum { isConst	= Private::IsConstImpl
						<isReference, isArray>::template In<T>::value
        };

        enum { isVolatile = Private::IsVolatileImpl
							<isReference, isArray>::template In<T>::value
        };
	private:
        typedef typename Private::AdjReference<isReference || isVoid>::
		template In<T>::Result AdjType;

		struct is_scalar
        {
        private:
            struct BoolConvert { BoolConvert(bool); };

            static Private::YES check(BoolConvert);
            static Private::NO check(...);

            struct NotScalar {};

            typedef typename Select
            <
                isVoid || isReference || isArray,
                NotScalar, T
            >
            ::Result RetType;

            // changed to RetType& to allow testing of abstract classes
			static RetType& get();

        public:
			enum { value = sizeof(check(get())) == sizeof(Private::YES) };


        }; // is_scalar

    public:
		enum { isScalar = is_scalar::value};
		typedef typename Select
        <
            isScalar || isArray, T, AdjType
        >
        ::Result ParameterType;
	private:
		
		typedef typename Loki::Select
		<
			isScalar,
			T,
			int
		>::Result TestType;
		static TestType MakeT();
		
		enum { isMemberPointerTemp = sizeof(Private::YES) 
									== sizeof(Private::IsPointer2Member(MakeT())) 
		};
	public:
		enum {isPointer = sizeof(Private::YES) 
						== sizeof(Private::IsPointer(MakeT()))};
	private:
		typedef typename Loki::Select
		<
			isVoid || isReference || !isPointer,
			int*,
			T
		>::Result MayBeFuncPtr;
	public:
		// enum types are the only scalar types that can't be initialized
		// with 0.
		// Because we replace all non scalars with int,
		// template <class T>
		// YES EnumDetection(...);
		// will only be selected for enums.
		enum { isEnum = sizeof(Private::YES) 
						== sizeof (Private::EnumDetection<TestType>(0))
         };

		enum { isMemberFunctionPointer =	isScalar && !isArith && !isPointer &&
										!isMemberPointerTemp && !isEnum
		};
		enum { isMemberPointer = isMemberPointerTemp || isMemberFunctionPointer};

		enum { isFunctionPointer = sizeof(Private::YES) 
								== sizeof(
								Private::IsFunctionPtrTester1(MayBeFuncPtr(0)) 
								) && !isMemberPointer
		};
		//
        // We get is_class for free
        // BUG - fails with functions types (ICE) and unknown size array
        // (but works for other incomplete types)
        // (the boost one (Paul Mensonides) is better)
        //
        enum { isClass =
                !isScalar    &&
                !isArray     &&
                !isReference &&
                !isVoid		 &&
				!isEnum
        };
    };

}
#ifdef _MSC_VER
#pragma warning (default: 4800)
#endif

////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// May  10, 2002: ported by Rani Sharoni to VC7 (RTM - 9466)
// Oct	05, 2002: ported by Benjamin Kaufmann to MSVC 6
// Jan	31, 2003: fixed bugs in scalar and array detection.
//					Added isMemberFuncPointer and isEnum. B.K.
//
// Feb	16,	2003: fixed bug in reference-Detection. Renamed isMemberFuncPointer
//					to isMemberFunctionPointer. Added isFunctionPointer, replaced
//					all occurrences of Private::Wrap with Loki::Type2Type and
//					cleaned up the TypeTraits-class.	B.K.					
////////////////////////////////////////////////////////////////////////////////

#endif // TYPETRAITS_INC_

⌨️ 快捷键说明

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