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

📄 hierarchygenerators.h

📁 exmat - The Expression Template Matrix Library,是矩阵运算模板库
💻 H
📖 第 1 页 / 共 2 页
字号:
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
//     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
// Permission to use, copy, modify, distribute and sell this software for any
//     purpose is hereby granted without fee, provided that the above copyright
//     notice appear in all copies and that both that copyright notice and this
//     permission notice appear in supporting documentation.
// The author or Addison-Wesley Longman make no representations about the
//     suitability of this software for any purpose. It is provided "as is"
//     without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////

// Last update: Mar 08, 2003


#ifndef HIERARCHYGENERATORS_INC_
#define HIERARCHYGENERATORS_INC_

#define IS_TYPELIST(TList) TL::Private::IsTypelist<TList>

#include "Typelist.h"
#include "TypeTraits.h"
#include "EmptyType.h"
#include "MSVC6Helpers.h"
namespace Loki
{
////////////////////////////////////////////////////////////////////////////////
// class template GenScatterHierarchy
// Generates a scattered hierarchy starting from a typelist and a template
// Invocation (TList is a typelist, Model is a template of one arg):
// GenScatterHierarchy<TList, Model>
// The generated class inherits all classes generated by instantiating the
// template 'Model' with the types contained in TList
////////////////////////////////////////////////////////////////////////////////
//	VC 6.0 changes:
//	* Unit is no longer a template template parameter.
//	* For every concrete unit-template there must be a normal class containing
//	a nested-template class called In. In should only contain a typedef to the
//	concrete Unit.
//
//	Using the originial library one would write something like this:
//	class Foo {};
//	template <class T> struct TestUnit {};
//	void Func(TestUnit<Foo>);
//	int main()
//	{
//		GenScatterHierarchy<Typelist<Foo, NullType>, TestUnit> obj;
//		Func(obj); // calls Func(TestUnit<Foo>)
//	}
//
//	Using this port the code would become:
//	class Foo {};
//	template <class T> struct TestUnit {};
//	struct TestUnitWrapper 
//	{
//		template <class T> struct In {typedef TestUnit<T> type}; 
//	};
//	void Func(TestUnit<Foo>);
//	int main()
//	{
//		GenScatterHierarchy<Typelist<Foo, NullType>, TestUnitWrapper> obj;
//		Func(obj); // calls Func(TestUnit<Foo>)
//	}
//
//	Not very nice, i know :-(
//
//	See "Metaprogramming VC++ - more of Loki ported" from Mat Marcus
//	(http://lists.boost.org/MailArchives/boost/msg20915.php)
//
//	Update:
//	-------
//	The first version of GenScatterHierarchy did not work with typelists
//	containing equal types. The MSVC 6.0 erroneously complains about 
//	inaccessible base-classes (error C2584).
//	This new version adds Dummy-classes to the left branch of the generated
//	hierarchy to workaround this VC-Bug. 
//	It creates hierarchies like this:
//
//						Holder<int>				NullType
//							\					/
//Holder<int>			GenScatter<int>	GenScatter<NullType>
//		\						\		/
//VC_InaccessibleBase		  InheritFromTo
//		  \							|
//GenScatter<int>	GenScatter<TYPELIST_1(int)>
//			\		/
//          InheritFromTo
//				|
//				|		   
//GenScatter<TYPELIST_2(int, int)>
//
//	Of course this version of GenScatterHierarchy generates a lot more
//	classes (5*n) than Alexandrescu's original implementation (3*n)
//	
	
	template <class TList, class Unit> class GenScatterHierarchy;
namespace Private
{
	
	template <class T, class U>
	struct InheritFromTwo : public T, public U
	{
		inline InheritFromTwo() : T(), U() {}
	};
	
	template <int tag>
	struct GenScatterImpl;

	// Specialization for a general typelist
	template <>
	struct GenScatterImpl<TL::Private::Typelist_ID>
	{
		template <class T, class MetaFunctionWrapper>
		struct In : public GenScatterHierarchy<typename T::Head,MetaFunctionWrapper>
		{
			typedef
			InheritFromTwo	<	VC_InaccessibleBase<GenScatterHierarchy<typename T::Head,
								MetaFunctionWrapper>, typename T::Tail>,
								GenScatterHierarchy<typename T::Tail,
								MetaFunctionWrapper>
							> type;
			typedef VC_InaccessibleBase<GenScatterHierarchy<typename T::Head, MetaFunctionWrapper>,typename T::Tail> LeftBase;
			typedef GenScatterHierarchy<typename T::Tail, MetaFunctionWrapper> RightBase;
		};
	};
	
	// Specialization for a typelist with only one element
	template <>
	struct GenScatterImpl<TL::Private::AtomList_ID>
	{
		template <class T, class MetaFunctionWrapper>
		struct In : public GenScatterHierarchy<typename T::Head,MetaFunctionWrapper>
		{
			// for the last Holder-class no dummy class is needed.
			typedef
			InheritFromTwo	<	GenScatterHierarchy<typename T::Head,
								MetaFunctionWrapper>,
								GenScatterHierarchy<NullType,
								MetaFunctionWrapper>
							> type;
			typedef GenScatterHierarchy<typename T::Head, MetaFunctionWrapper> LeftBase;
			typedef GenScatterHierarchy<NullType, MetaFunctionWrapper> RightBase;
		};
	};
	// Specialization for a single type
	template <>
	struct GenScatterImpl<TL::Private::NoneList_ID>
	{
		template <class AtomicType, class MetaFunctionWrapper>
		struct In
		{
			typedef typename
			ApplyInnerType<MetaFunctionWrapper, AtomicType>::type type;
			typedef type LeftBase;
			typedef EmptyType RightBase;
			//typedef AtomicType::THIS_SELECTED bla;
		};

	};

	// Specialization for NullType
	template <>
	struct GenScatterImpl<TL::Private::NullType_ID>
	{
		template <class NullTypeList, class MetaFunctionWrapper>
		struct In
		{
			typedef EmptyType type;
			typedef type LeftBase;
			typedef type RightBase;
		};
	};
} // end namespace Private
	
	template <class T, class Unit>
	class GenScatterHierarchy : public Private::GenScatterImpl
	<
		IS_TYPELIST(T)::type_id
	>::template In<T, Unit>::type
	{
	public:
		typedef typename Select
		<
			TL::Private::IsTypelist<T>::value, T, void
		>::Result TList;
		
		typedef typename Private::GenScatterImpl
		<
			IS_TYPELIST(T)::type_id
		>::template In<T, Unit>::LeftBase LeftBase;
		typedef typename Private::GenScatterImpl
		<
			IS_TYPELIST(T)::type_id
		>::template In<T, Unit>::RightBase RightBase;
		
		template <typename U> struct Rebind
		{
			typedef ApplyInnerType<Unit, U>::type Result;
		};
	};
	
////////////////////////////////////////////////////////////////////////////////
// function template Field
// Accesses a field in an object of a type generated with GenScatterHierarchy
// Invocation (obj is an object of a type H generated with GenScatterHierarchy,
//     T is a type in the typelist used to generate H):
// Field<T>(obj)
// returns a reference to Unit<T>, where Unit is the template used to generate H
////////////////////////////////////////////////////////////////////////////////
	template <class T, class TList, class UnitWrapper>
	typename ApplyInnerType<UnitWrapper, T>::type&
	Field(GenScatterHierarchy<TList, UnitWrapper>& obj,Type2Type<T>* = (Type2Type<T>*)0)
	{
		return obj;
	}

	template <class T, class TList, class UnitWrapper>
	const typename ApplyInnerType<UnitWrapper, T>::type&
	Field(const GenScatterHierarchy<TList, UnitWrapper>& obj, Type2Type<T>* = (Type2Type<T>*)0)
	{
		return obj;
	}

	

////////////////////////////////////////////////////////////////////////////////
// function template TupleUnit
// The building block of tuples
////////////////////////////////////////////////////////////////////////////////

    template <class T>
    struct TupleUnit
    {
        T value_;
        operator T&() { return value_; }
        operator const T&() const { return value_; }
    };

////////////////////////////////////////////////////////////////////////////////
// class template Tuple
// Implements a tuple class that holds a number of values and provides field
//     access to them via the Field function (below)
////////////////////////////////////////////////////////////////////////////////
	namespace Private
	{
		struct TupleUnitWrapper
		{
			template <class T>
			struct In
			{
				typedef TupleUnit<T> type;
			};
		};
	}
    template <class TList>
	struct Tuple : public GenScatterHierarchy<TList, Private::TupleUnitWrapper>
    {
    };

⌨️ 快捷键说明

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