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

📄 typelist.h

📁 exmat - The Expression Template Matrix Library,是矩阵运算模板库
💻 H
📖 第 1 页 / 共 3 页
字号:

			enum
			{
				NoneList_ID = 0,
				Typelist_ID = 1,
				AtomList_ID	= 2,
				NullType_ID = 4

			};
////////////////////////////////////////////////////////////////////////////////
// class template IsTypelist
// detects if type is Typelist (including Nulltype)
// Invocation :
// IsTypelist<T>::value
////////////////////////////////////////////////////////////////////////////////
			template<typename T>
			struct IsTypelist
			{
			private:
				typedef TypeTag<1>::X List;
				typedef TypeTag<2>::X AtomList;
				typedef TypeTag<3>::X NullList;
				typedef TypeTag<4>::X NoList;

				// VC 6.0 does not allow overloads
				// for check(Type2Type< Typelist<Head, Tail> >)
				// and check(Type2Type<NullType>);
				// so we must use to different functions
				template<class Head, class Tail>
				static TypeTag<1>::X	check(Type2Type< Typelist<Head, Tail> >);
				static TypeTag<4>::X	check(...);

				template <class U>
				static TypeTag<2>::X	check2(Type2Type< Typelist<U, NullType> >);
				static TypeTag<4>::X	check2(...);

				static TypeTag<3>::X	check3(Type2Type<NullType>);
				static TypeTag<4>::X	check3(...);

			public:
				enum
				{
					temp1	= sizeof(check(Type2Type<T>())) == sizeof(TypeTag<1>::X) ? Typelist_ID : NoneList_ID,
					temp2	= sizeof(check2(Type2Type<T>())) == sizeof(TypeTag<2>::X) ? AtomList_ID : NoneList_ID,
					temp4	= temp2 ? Typelist_ID :NoneList_ID,
					temp3	= sizeof(check3(Type2Type<T>())) == sizeof(TypeTag<3>::X) ? NullType_ID : NoneList_ID,
					value	= temp1 || temp2 || temp3,
					type_id	= (temp1 ^ temp4) | temp2 | temp3
				};
				typedef typename Select
				<
					type_id == Typelist_ID || type_id == AtomList_ID,
					Typelist_tag,
					typename Select<type_id == NullType_ID, NullType_tag, NoneList_tag>::Result
				>
				::Result type_tag;
			};

		}	// end of namespace Private
////////////////////////////////////////////////////////////////////////////////
// class template MakeTypelist
// Takes a number of arguments equal to its numeric suffix
// The arguments are type names.
// MakeTypeList<T1, T2, ...>::Result
// returns a typelist that is of T1, T2, ...
////////////////////////////////////////////////////////////////////////////////
// MakeTypeList-Template from Rani Sharoni's VC 7 port.
		template
		<	typename T1  = NullType, typename T2  = NullType, typename T3  = NullType,
			typename T4  = NullType, typename T5  = NullType, typename T6  = NullType,
			typename T7  = NullType, typename T8  = NullType, typename T9  = NullType,
			typename T10 = NullType, typename T11 = NullType, typename T12 = NullType,
			typename T13 = NullType, typename T14 = NullType, typename T15 = NullType,
			typename T16 = NullType, typename T17 = NullType, typename T18 = NullType
		>
		struct MakeTypelist
		{
			private:
				typedef typename MakeTypelist
				<
				T2 , T3 , T4 ,
				T5 , T6 , T7 ,
				T8 , T9 , T10,
				T11, T12, T13,
				T14, T15, T16,
				T17, T18
				>
				::Result TailResult;

			public:
				typedef Typelist<T1, TailResult> Result;
		};

		template<>
		struct MakeTypelist
		<
			NullType, NullType, NullType,
			NullType, NullType, NullType,
			NullType, NullType, NullType,
			NullType, NullType, NullType,
			NullType, NullType, NullType,
			NullType, NullType, NullType
		>
		{
			typedef NullType Result;
		};

////////////////////////////////////////////////////////////////////////////////
// class template Length
// Computes the length of a typelist
// Invocation (TList is a typelist):
// Length<TList>::value
// returns a compile-time constant containing the length of TList, not counting
// the end terminator (which by convention is NullType)
////////////////////////////////////////////////////////////////////////////////
		template <class TList>
		struct Length
		{
			private:
				ASSERT_TYPELIST(TList);
				typedef typename TList::Head Head;
				typedef typename TList::Tail Tail;
			public:

			enum {value = 1 + Length<Tail>::value};
		};

		// explicit specialization for an empty list.
		// this is the border case for the recursive length-calculation
		template <>
		struct Length<NullType>
		{
			enum {value = 0};
		};


////////////////////////////////////////////////////////////////////////////////
// class template TypeAt
// Finds the type at a given index in a typelist
// Invocation (TList is a typelist and index is a compile-time integral
//     constant):
// TypeAt<TList, index>::Result
// returns the type in position 'index' in TList
// If you pass an out-of-bounds index, the result is a compile-time error
////////////////////////////////////////////////////////////////////////////////
namespace Private
{
	// The type at Index i is the type at i-1 of the List's Tail
	template <unsigned int Index>
	struct TypeAtImpl
	{
		template <class TList>
		struct In
		{
			ASSERT_TYPELIST(TList);
			typedef typename TList::Head Head;
			typedef typename TList::Tail Tail;
			typedef typename TypeAtImpl<Index-1>::template In<Tail>::Result Result;
		};

	};
	// the border case is represented by an explicit specialization
	// The type at Index 0 is the type of the head.
	template <>
	struct TypeAtImpl<0>
	{
		template <class TList>
		struct In
		{
			ASSERT_TYPELIST(TList);
			typedef typename TList::Head Head;
			typedef Head Result;
		};
	};
}	// end of namespace Private

	template <class TList, unsigned int Index>
	struct TypeAt
	{
		typedef typename Private::TypeAtImpl<Index>::template In<TList>::Result Result ;
	};

////////////////////////////////////////////////////////////////////////////////
// class template TypeAtNonStrict
// Finds the type at a given index in a typelist
// Invocations (TList is a typelist and index is a compile-time integral
//     constant):
// a) TypeAt<TList, index>::Result
// returns the type in position 'index' in TList, or NullType if index is
//     out-of-bounds
// b) TypeAt<TList, index, D>::Result
// returns the type in position 'index' in TList, or D if index is out-of-bounds
////////////////////////////////////////////////////////////////////////////////
	template <class TList, unsigned int i, class DefType = NullType>
	struct TypeAtNonStrict;
namespace Private
{
	// if TList is not NullType, check if Index is 0.
	// if Index is 0, the result is TList::Head
	// if Index is > 0, the result is the result of appliying TypeAtNonStrict
	// to the list's and Index-1
	template <class TList>
	struct TypeAtNonStrictImpl
	{
		template <class DefType, unsigned int Index>
		struct In
		{
			ASSERT_TYPELIST(TList);
			typedef typename Select
			<
				Index == 0,				// The condition
				typename TList::Head,	// true-case
				typename TypeAtNonStrict<typename TList::Tail, Index-1, DefType>::Result
			>::Result Result;
		};
	};

	// if TList is NullType the result is *always* the specified DefaultType.
	template <>
	struct TypeAtNonStrictImpl<NullType>
	{
		template <class DefType, unsigned int Index>
		struct In
		{
			typedef DefType Result;
		};
	};

}	// end of namespace Private
	template <class TList, unsigned int i, class DefType>
	struct TypeAtNonStrict
	{
		typedef typename
		Private::TypeAtNonStrictImpl<TList>::template In<DefType, i>::Result Result;
	};

////////////////////////////////////////////////////////////////////////////////
// class template IndexOf
// Finds the index of a type in a typelist
// Invocation (TList is a typelist and T is a type):
// IndexOf<TList, T>::value
// returns the position of T in TList, or -1 if T is not found in TList
////////////////////////////////////////////////////////////////////////////////
	template <class TList, class T>
	struct IndexOf;
namespace Private
{
	// If TList is a typelist and TList::Head is T, then the Index is 0
	// If TList::Head is not T, compute the result of IndexOf applied to
	// TList's tail and T into a temporary value temp.
	// If temp is -1, then value is -1
	// Else value is 1 + temp
	template <class TList>
	struct IndexOfImpl
	{
		template <class T>
		struct In
		{
			ASSERT_TYPELIST(TList);
			typedef typename TList::Head Head;
			typedef typename TList::Tail Tail;
			private:
				enum {temp = IsEqualType<T, Head>::value != 0 ? 0
							: IndexOf<Tail, T>::temp};

			public:
				enum {value = temp == -1 ? -1 : 1 + temp};
		};
	};

	// T cannot be in an empty list.
	// Therefore return -1 to indicate Not-In-List
	template <>
	struct IndexOfImpl<NullType>
	{
		template <class T>
		struct In
		{
			enum {value = -1};
		};
	};

}	// end of namespace Private

	// The primary IndexOfImpl-Template is always one step ahead.
	// Therefore if T is in list, we need to subtract one from the result.
	template <class TList, class T>
	struct IndexOf
	{
		enum {temp = Private::IndexOfImpl<TList>::template In<T>::value};
		enum {value = temp == -1 ? -1 : temp - 1};
	};
////////////////////////////////////////////////////////////////////////////////
// class template Append
// Appends a type or a typelist to another
// Invocation (TList is a typelist and T is either a type or a typelist):
// Append<TList, T>::Result
// returns a typelist that is TList followed by T and NullType-terminated
////////////////////////////////////////////////////////////////////////////////
	template <class TList, class T>
	struct Append;

namespace Private
{
	template <class TList>
	struct AppendImpl
	{	// if TList is not NullType the result
		// is a typelist having TList::Head as its Head and
		// and the result of appending T to TList::Tail as its tail.
		ASSERT_TYPELIST(TList);
		template <class T>
		struct In
		{
			typedef Typelist<typename TList::Head,
				typename Append<typename TList::Tail, T>::Result> Result;
		};

	};

	template <>
	struct AppendImpl<NullType>
	{	// if TList is NullType, check if T is NullType, a single type
		// or a typelist
		// If TList is NullType and T is NullType
		// the result is NullType, too
		//
		// If TList is NullType and T is not NullType.
		// Check if T is a Typelist
		//
		// if TList is NullType and T is a typelist the result is T
		// if TList is NullType and T is not a typelist
		// the result is a typelist containing only T
		template <class T>
		struct In
		{
			typedef typename Select
			<
				IsEqualType<T, NullType>::value,	// is T == Nulltype?
				NullType,							// yes
				typename Select						// no. check if T is a Typelist
				<
					IsTypelist<T>::value,			// is T a typelist?
					T,								// yes
					Typelist<T, NullType>			// no
				>::Result
			>::Result Result;
		};
	};

}	// end of namespace Private

	template <class TList, class T>
	struct Append
	{
		typedef typename Private::AppendImpl<TList>::template In<T>::Result Result;
	};

////////////////////////////////////////////////////////////////////////////////
// class template Erase
// Erases the first occurence, if any, of a type in a typelist
// Invocation (TList is a typelist and T is a type):
// Erase<TList, T>::Result
// returns a typelist that is TList without the first occurence of T
////////////////////////////////////////////////////////////////////////////////
	template <class TList, class T>
	struct Erase;
namespace Private
{
	template <class TList>
	struct EraseImpl
	{	// TList is not NullType.
		// Check if TList::Head is equal to T
		// if T is the same as TList::Head, then the Result is TList::Tail
		//
		// if TList is not NullType and TList::Head is not equal to T,
		// then the Result is a Typelist having TList::Head as its Head
		// and the result of applying Erase to the tail of list as its
		// tail.
		template <class T>
		struct In
		{
			ASSERT_TYPELIST(TList);
			typedef typename TList::Head Head;
			typedef typename TList::Tail Tail;
			typedef typename Select
			<
				IsEqualType<Head, T>::value,	// is T equal to Head?
				Tail,							// Yes. Result is tail
				Typelist<typename TList::Head,	// No. recurse
				typename Erase<typename TList::Tail, T>::Result>
			>::Result Result;

		};
	};

	// if TList is NullType the result is NullType.
	template <>
	struct EraseImpl<NullType>
	{
		template <class T>
		struct In

⌨️ 快捷键说明

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