Konstruktive Kritik erwünscht



  • Ich habe eine generische multidispatcher Klasse, basierend auf automatisch generierten if-else Abfragen geschrieben. Jeder darf sie in seinen freien Projekten benutzen, wenn er folgende Angaben macht:

    (Ich hoffe das kommt nicht falsch rüber oder widerspricht dem footer, aber jeder der schon mal lange an was gearbeitet hat und es dann veröffentlichte wird mich verstehen [hoffe ich])
    Was ich wissen möchte geht eigentlich schon aus dem Titel hervor: was würdet ihr ändern/verbessern?

    Hier der code:
    mer_typelist.h

    #include <boost/preprocessor/list/for_each.hpp>
    #include <boost/preprocessor/list/adt.hpp>
    #include <boost/preprocessor/array/data.hpp>
    #include <boost/preprocessor/array/size.hpp>
    #include <boost/preprocessor/tuple/to_list.hpp>
    #include <boost/preprocessor/seq/to_tuple.hpp>
    #include <boost/preprocessor/seq/size.hpp>
    
    #define MER_TYPELIST_FROM_BOOST_PP_LIST_LITTLE_HELPER(R,DATA,ELEM)\
    	Loki::Typelist<ELEM,
    
    #define MER_TYPELIST_FROM_BOOST_PP_LIST_LITTLE_HELPER_2(R,DATA,ELEM)\
    	DATA\
    
    #define MER_TYPELIST_FROM_BOOST_PP_LIST(LIST)\
    	Loki::Typelist<BOOST_PP_LIST_FIRST(LIST),BOOST_PP_LIST_FOR_EACH(MER_TYPELIST_FROM_BOOST_PP_LIST_LITTLE_HELPER,_,BOOST_PP_LIST_REST(LIST)) Loki::NullType BOOST_PP_LIST_FOR_EACH(MER_TYPELIST_FROM_BOOST_PP_LIST_LITTLE_HELPER_2,>,BOOST_PP_LIST_REST(LIST))>
    
    #define MER_TYPELIST_FROM_BOOST_PP_ARRAY(ARRAY)\
    	MER_TYPELIST_FROM_BOOST_PP_LIST(BOOST_PP_TUPLE_TO_LIST(BOOST_PP_ARRAY_SIZE(ARRAY),BOOST_PP_ARRAY_DATA(ARRAY)))
    
    #define MER_TYPELIST_FROM_BOOST_PP_TUPLE(SIZE,TUPLE)\
    	MER_TYPELIST_FROM_BOOST_PP_LIST(BOOST_PP_TUPLE_TO_LIST(SIZE,TUPLE))
    
    #define MER_TYPELIST_FROM_BOOST_PP_SEQ(SEQ)\
    	MER_TYPELIST_FROM_BOOST_PP_LIST(BOOST_PP_TUPLE_TO_LIST(BOOST_PP_SEQ_SIZE(SEQ),BOOST_PP_SEQ_TO_TUPLE(SEQ)))
    
    namespace mer
    {
    	namespace TL
    	{
    		template<class Tlist,unsigned i>
    		struct list_at
    		{
    			typedef typename list_at<typename Tlist::Tail,(i-1)>::result result;
    		};
    
    		template<class Tlist>
    		struct list_at<Tlist,0>
    		{
    			typedef Tlist result;
    		};
    
    		template<class Tlist, unsigned index>
    		struct erase_list_at
    		{
    			typedef Loki::Typelist<typename Tlist::Head,typename erase_list_at<typename Tlist::Tail,index-1>::result> result;
    		};
    
    		template<class Tlist>
    		struct erase_list_at<Tlist,0>
    		{
    			typedef Loki::NullType result;
    		};
    
    		template<class Tlist,unsigned i>
    		struct erase_at
    		{
    			typedef Loki::Typelist<typename Tlist::Head,typename erase_at<typename Tlist::Tail,i-1>::result> result;
    		};
    
    		template<class Tlist>
    		struct erase_at<Tlist,0>
    		{
    			typedef typename Tlist::Tail result;
    		};
    
    		template<class Tlist>
    		struct change_to_refernce_type
    		{
    			typedef Loki::Typelist<typename Loki::TypeTraits<typename Tlist::Head>::ReferredType&,typename change_to_refernce_type<typename Tlist::Tail>::result> result;
    		};
    
    		template<>
    		struct change_to_refernce_type<Loki::NullType>
    		{
    			typedef Loki::NullType result;
    		};
    
    		template<class Tlist>
    		struct change_to_non_refernce_type
    		{
    			typedef Loki::Typelist<typename Loki::TypeTraits<typename Tlist::Head>::ReferredType,typename change_to_non_refernce_type<typename Tlist::Tail>::result> result;
    		};
    
    		template<>
    		struct change_to_non_refernce_type<Loki::NullType>
    		{
    			typedef Loki::NullType result;
    		};
    
    		template<class Tlist>
    		struct last_type
    		{
    			typedef typename last_type<typename Tlist::Tail>::result result;
    		};
    
    		template<class T>
    		struct last_type<TYPELIST_1(T)>
    		{
    			typedef T result;
    		};
    
    		template<class Tlist>
    		struct erase_last
    		{
    			typedef Loki::Typelist<typename Tlist::Head,typename erase_last<typename Tlist::Tail>::result> result;
    			typename erase_last<typename Tlist::Tail>::erased erased;
    		};
    
    		template<class T>
    		struct erase_last<TYPELIST_1(T)>
    		{
    			typedef Loki::NullType result;
    			typedef T erased;
    		};
    	};
    }
    

    modern_ellipse.h:

    #define MER_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_LIST_OF_ARGUMENTS_LITTLE_HELPER(R,D,I,E)\
    	,mer::detail::modern_ellipse_<mer::TL::list_at<D,(I+1)>::result>(E
    
    #define MER_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_LIST_OF_ARGUMENTS_LITTLE_HELPER_2(R,DATA,ELEM)	)\
    
    #define MER_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_LIST_OF_ARGUMENTS(TLIST,LIST)\
    	mer::modern_ellipse<mer::TL::list_at<TLIST,0>::result>(BOOST_PP_LIST_FIRST(LIST)\
    	BOOST_PP_LIST_FOR_EACH_I(MER_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_LIST_OF_ARGUMENTS_LITTLE_HELPER,TLIST,BOOST_PP_LIST_REST(LIST))\
    	BOOST_PP_LIST_FOR_EACH(MER_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_LIST_OF_ARGUMENTS_LITTLE_HELPER_2,_,LIST)
    
    #define MER_NAMED_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_LIST_OF_ARGUMENTS(TLIST,LIST,NAME)\
    	mer::modern_ellipse<mer::TL::list_at<TLIST,0>::result> NAME (BOOST_PP_LIST_FIRST(LIST)\
    	BOOST_PP_LIST_FOR_EACH_I(MER_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_LIST_OF_ARGUMENTS_LITTLE_HELPER,TLIST,BOOST_PP_LIST_REST(LIST))\
    	BOOST_PP_LIST_FOR_EACH(MER_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_LIST_OF_ARGUMENTS_LITTLE_HELPER_2,_,LIST)
    
    #define MER_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_ARRAY_OF_ARGUMENTS(TLIST,ARRAY)\
    	MER_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_LIST_OF_ARGUMENTS(TLIST,BOOST_PP_TUPLE_TO_LIST(BOOST_PP_ARRAY_SIZE(ARRAY),BOOST_PP_ARRAY_DATA(ARRAY)))
    
    #define MER_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_SEQ_OF_ARGUMENTS(TLIST,SEQ)\
    	MER_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_LIST_OF_ARGUMENTS(TLIST,BOOST_PP_TUPLE_TO_LIST(BOOST_PP_SEQ_SIZE(SEQ),BOOST_PP_SEQ_TO_TUPLE(SEQ)))
    
    #define MER_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_TUPLE_OF_ARGUMENTS(TLIST,SIZE,TUPLE)\
    	MER_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_LIST_OF_ARGUMENTS(TLIST,BOOST_PP_TUPLE_TO_LIST(SIZE,TUPLE))
    
    #define MER_NAMED_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_ARRAY_OF_ARGUMENTS(TLIST,ARRAY,NAME)\
    	MER_NAMED_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_LIST_OF_ARGUMENTS(TLIST,BOOST_PP_TUPLE_TO_LIST(BOOST_PP_ARRAY_SIZE(ARRAY),BOOST_PP_ARRAY_DATA(ARRAY)),NAME)
    
    #define MER_NAMED_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_SEQ_OF_ARGUMENTS(TLIST,SEQ,NAME)\
    	MER_NAMED_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_LIST_OF_ARGUMENTS(TLIST,BOOST_PP_TUPLE_TO_LIST(BOOST_PP_SEQ_SIZE(SEQ),BOOST_PP_SEQ_TO_TUPLE(SEQ)),NAME)
    
    #define MER_NAMED_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_TUPLE_OF_ARGUMENTS(TLIST,SIZE,TUPLE,NAME)\
    	MER_NAMED_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_LIST_OF_ARGUMENTS(TLIST,BOOST_PP_TUPLE_TO_LIST(SIZE,TUPLE),NAME)
    
    namespace mer
    {
    	namespace detail
    	{
    		template<class Tlist>
    		struct modern_ellipse_
    		{
    			typedef typename Tlist::Head head_type;
    			head_type head;
    			typedef typename Tlist::Tail tlist_tail_type;
    			typedef modern_ellipse_<typename Tlist::Tail> tail_type;
    			tail_type tail;
    			modern_ellipse_(head_type head_,tail_type& tail_)
    				:head(head_),tail(tail_){};
    			modern_ellipse_(modern_ellipse_<typename TL::erase_at<Tlist,Loki::TL::Length<Tlist>::value-1>::result>& me,typename Loki::TL::TypeAt<Tlist,Loki::TL::Length<Tlist>::value-1>::Result a)
    			:head(me.head),tail(me.tail,a){};
    		};
    
    		template<class T,class U>
    		struct modern_ellipse_<TYPELIST_2(T,U)>
    		{
    			typedef T head_type;
    			head_type head;
    			typedef modern_ellipse_<TYPELIST_1(U)> tail_type;
    			tail_type tail;
    			typedef TYPELIST_1(U) tlist_tail_type;
    			modern_ellipse_(head_type head_,tail_type& tail_)
    				:head(head_),tail(tail_){};
    			modern_ellipse_(modern_ellipse_<TYPELIST_1(T)>& me,U a)
    				:head(me.head),tail(detail::modern_ellipse_<TYPELIST_1(U)>(a)){};
    		};
    
    		template<class T>
    		struct modern_ellipse_<TYPELIST_1(T)>
    		{
    			typedef T head_type;	
    			head_type head;
    			typedef Loki::NullType tail_type;
    			typedef Loki::NullType tlist_tail_type;
    			modern_ellipse_(head_type head_)
    				:head(head_){};
    		};
    	};
    
    	template<class Tlist>
    	struct modern_ellipse
    	{
    		typedef Tlist type_list;
    		enum{size=::Loki::TL::Length<Tlist>::value};
    		typedef typename Tlist::Head head_type;
    		head_type head;
    		typedef typename Tlist::Tail tlist_tail_type;
    		typedef detail::modern_ellipse_<typename Tlist::Tail> tail_type;
    		tail_type tail;
    		modern_ellipse(head_type head_,tail_type& tail_)
    			:head(head_),tail(tail_){};
    		modern_ellipse(modern_ellipse<typename TL::erase_at<Tlist,Loki::TL::Length<Tlist>::value-1>::result>& me,typename Loki::TL::TypeAt<Tlist,Loki::TL::Length<Tlist>::value-1>::Result a)
    			:head(me.head),tail(me.tail,a){};
    	};
    
    	template<class T,class U>
    	struct modern_ellipse<TYPELIST_2(T,U)>
    	{
    		typedef TYPELIST_2(T,U) type_list;
    		enum{size=Loki::TL::Length<type_list>::value};
    		typedef typename type_list::Head head_type;
    		head_type head;
    		typedef detail::modern_ellipse_<typename type_list::Tail> tail_type;
    		tail_type tail;
    		typedef typename type_list::Tail tlist_tail_type;
    		modern_ellipse(head_type head_,tail_type& tail_)
    			:head(head_),tail(tail_){};
    		modern_ellipse(modern_ellipse<TYPELIST_1(T)>& me,U a)
    			:head(me.head),tail(detail::modern_ellipse_<TYPELIST_1(U)>(a)){};
    	};
    
    	template<class T>
    	struct modern_ellipse<Loki::Typelist<T,Loki::NullType> >
    	{
    		typedef Loki::Typelist<T,Loki::NullType> type_list;
    		enum{size=1};
    		typedef T head_type;
    		head_type head;
    		typedef Loki::NullType tail_type;
    		typedef Loki::NullType tlist_tail_type;
    		modern_ellipse(head_type head_)
    				:head(head_){};
    	};
    
    	namespace ME
    	{		
    		namespace detail
    		{
                template<class T>
    			struct partial;
    
    			template<class Tlist>
    			struct partial<modern_ellipse<Tlist> >
    			{
    				template<class Ftor>
    				static void for_each(modern_ellipse<Tlist>& me,Ftor& f)
    				{
    					f(me.head);
    					partial<typename modern_ellipse<Tlist>::tail_type>::for_each(me.tail,f);
    				};
    			};
    
    			template<class Tlist>
    			struct partial<::mer::detail::modern_ellipse_<Tlist> >
    			{
    				template<class Ftor>
    				static void for_each(::mer::detail::modern_ellipse_<Tlist>& me,Ftor& f)
    				{
    					f(me.head);
    					partial<typename ::mer::detail::modern_ellipse_<Tlist>::tail_type>::for_each(me.tail,f);
    				};
    			};
    
    			template<class T>
    			struct partial<modern_ellipse<Loki::Typelist<T,Loki::NullType> > >
    			{
    				template<class Ftor>
    				static void for_each(modern_ellipse<Loki::Typelist<T,Loki::NullType> >&me,Ftor& f)
    				{
    					f(me.head);
    				};
    			};
    
    			template<class T>
    			struct partial<::mer::detail::modern_ellipse_<Loki::Typelist<T,Loki::NullType> > >
    			{
    				template<class Ftor>
    				static void for_each(::mer::detail::modern_ellipse_<Loki::Typelist<T,Loki::NullType> >&me,Ftor& f)
    				{
    					f(me.head);
    				};
    			};
    		};
    
    		template<class Ftor,class Tlist>
    		void for_each(modern_ellipse<Tlist>& me,Ftor& f)
    		{
    			detail::partial<modern_ellipse<Tlist> >::for_each(me,f);
    		};
    
    		template<class T,unsigned i>
    		struct index;
    
    		template<class Tlist,unsigned i>
    		struct index<modern_ellipse<Tlist>,i>
    		{
    			static typename Loki::TL::TypeAt<Tlist,i>::Result value_at(modern_ellipse<Tlist>& me)
    			{
    				return index<typename modern_ellipse<Tlist>::tail_type,i-1>::value_at(me.tail);
    			};
    		};
    
    		template<class Tlist,unsigned i>
    		struct index<::mer::detail::modern_ellipse_<Tlist>,i>
    		{
    			static typename Loki::TL::TypeAt<Tlist,i>::Result value_at(::mer::detail::modern_ellipse_<Tlist>& me)
    			{
    				return index<typename detail::modern_ellipse_<Tlist>::tail_type,i-1>::value_at(me.tail);
    			};
    		};
    
    		template<class Tlist>
    		struct index<modern_ellipse<Tlist>,0>
    		{
    			static typename Loki::TL::TypeAt<Tlist,0>::Result value_at(modern_ellipse<Tlist>& me)
    			{
    				return me.head;
    			};
    		};
    
    		template<class Tlist>
    		struct index<::mer::detail::modern_ellipse_<Tlist>,0>
    		{
    			static typename Loki::TL::TypeAt<Tlist,0>::Result value_at(::mer::detail::modern_ellipse_<Tlist>& me)
    			{
    				return me.head;
    			};
    		};
    	};
    };
    

    static_dispatcher.h:

    namespace mer
    {
    	template
    	<
    		class Executor,                    //typ des Funktors der nach erfolgreichem dispatching aufgerufen wird
                                                                //sollte operator() für alle kombinationen eines möglichen dispatchings überladen (s.Bsp)
    		template<class,class>class Error,  //type des Funktors, der nach fehlgeschlagenem dispatching aufgerufen wird
                                                                //sollte operator() definieren, der eine mer::modern_ellipse<derersteparameter>& und eine mer::modern_ellipse<derzeiteparameter>& erwartet
                                                                //das linke Argument enthält die bereits dispatchten Werte, das Rechte nur nicht umgewandelte Argumente
                                                                //ist der erste template-Paramter TYPELIST_1(Loki::EmptyType), so ist bereits das erste dispatching Fehlgeschlagen
                                                                //Das Argument, für das das dispatching fehlschlug, befindet sich an erster Stelle der 2. mer::modern_ellipse
    		class Bases,                        //Loki::NullType terminierte Typliste, die die Basisiklassen der zu dispatchenden Klassen enthält
    		class Types,                        //Loki::NullType terminierte Typliste aus Loki::NullType terminierten Typlisten, die die konkreten Klassen enthaltlten
                                                                 //sollte nach Basisklassen sortiert in de gleichen Reihenfolge vorliegen wie Bases
    		class Result_type=void              //Rückgabetyp von Functor::operator()
    	>
    	class static_dispatcher
    	{
    	private:
    		template<class E,template<class,class>class Er,class B,class T,class RT>
    		friend class static_dispatcher;
    		typedef typename Loki::TL::DerivedToFront<typename Loki::TL::NoDuplicates<typename TL::change_to_non_refernce_type<typename Types::Head>::result>::Result>::Result types;
    		typedef typename types::Head head;
    		typedef typename types::Tail tail;
    		template<class L_list>
    		static Result_type go_
    		(
    			modern_ellipse<L_list>& me1,
    			detail::modern_ellipse_<typename mer::TL::list_at<typename TL::change_to_refernce_type<Bases>::result,Loki::TL::Length<L_list>::value>::result>& me2,
    			Executor& exec
    		)
    		{
    			if(head* ph=dynamic_cast<head*>(&me2.head))	//Übereinstimmung gefunden
    			{
    				return static_dispatcher				//zur nächsten Ebene springen
    					<Executor,Error,typename TL::change_to_refernce_type<Bases>::result,typename Types::Tail,Result_type>
    					::go_<Loki::TL::Append<L_list,head&>::Result>(modern_ellipse<Loki::TL::Append<L_list,head&>::Result>(me1,*ph),me2.tail,exec);
    			}
    			else										//keine Übereinstimmung gefunden
    			{
    				return static_dispatcher				//nächsten Typ testen
    					<Executor,Error,typename TL::change_to_refernce_type<Bases>::result,Loki::Typelist<tail,typename Types::Tail>,Result_type>
    					::go_<L_list>(me1,me2,exec);
    			};
    		};
    	public:
    		static Result_type go(modern_ellipse<typename TL::change_to_refernce_type<Bases>::result>& me, Executor& exec)
    		{
    			if(head* ph=dynamic_cast<head*>(&me.head))	//Übereinstimmung gefunden
    			{
    				return static_dispatcher				//zur nächsten Ebene springen
    					<Executor,Error,typename TL::change_to_refernce_type<Bases>::result,typename Types::Tail,Result_type>
    					::go_(modern_ellipse<TYPELIST_1(head&)>(*ph),detail::modern_ellipse_<typename typename TL::change_to_refernce_type<Bases>::result::Tail>(me.tail),exec);
    			}
    			else										//keine Übereinstimmung gefunden
    			{
    				return static_dispatcher				//nächsten Typ testen
    					<Executor,Error,typename TL::change_to_refernce_type<Bases>::result,Loki::Typelist<tail,typename Types::Tail>,Result_type>
    					::go(me,exec);
    			};
    		};
    	};
    
    	//Fehlerbehandlung 1:
    	template
    	<
    		class Executor,
    		template<class,class>class Error,
    		class Bases,
    		class S_types,
    		class Result_type
    	>
    	class static_dispatcher<Executor,Error,Bases,Loki::Typelist<Loki::NullType,S_types>,Result_type>
    	{
    	private:
    		template<class E,template<class,class>class Er,class B,class T,class R>
    		friend class static_dispatcher;
    		template<class L_list>
    		static Result_type go_
    		(
    			modern_ellipse<L_list>& me1,
    			detail::modern_ellipse_<typename mer::TL::list_at<typename TL::change_to_refernce_type<Bases>::result,Loki::TL::Length<L_list>::value>::result>& me2,
    			Executor& exec
    		)
    		{
    			return Error<L_list,typename mer::TL::list_at<typename TL::change_to_refernce_type<Bases>::result,Loki::TL::Length<L_list>::value>::result>()(me1,modern_ellipse<typename mer::TL::list_at<typename TL::change_to_refernce_type<Bases>::result,Loki::TL::Length<L_list>::value>::result>(me2.head,me2.tail));
    		};
    	public:
    		static Result_type go(modern_ellipse<typename TL::change_to_refernce_type<Bases>::result>& me, Executor& exec)
    		{
    			return Error<TYPELIST_1(Loki::EmptyType),typename TL::change_to_refernce_type<Bases>::result>()(modern_ellipse<TYPELIST_1(Loki::EmptyType)>(Loki::EmptyType()),me);
    		};
    	};
    
    	//letzte Ebene:
    	template
    	<
    		class Executor,
    		template<class,class>class Error,
    		class Bases,
    		class Types_rhs,
    		class Result_type
    	>
    	class static_dispatcher<Executor,Error,Bases,TYPELIST_1(Types_rhs),Result_type>
    	{
    	private:
    		template<class E,template<class,class>class Er,class B,class T,class RT>
    		friend class static_dispatcher;
    		typedef typename Loki::TL::DerivedToFront<typename Loki::TL::NoDuplicates<typename TL::change_to_non_refernce_type<Types_rhs>::result>::Result>::Result types_rhs;
    		typedef typename types_rhs::Head head;
    		typedef typename types_rhs::Tail tail;
    		template<class L_list>
    		static Result_type go_
    		(
    			modern_ellipse<L_list>& me1,
    			detail::modern_ellipse_<typename mer::TL::list_at<typename TL::change_to_refernce_type<Bases>::result,Loki::TL::Length<L_list>::value>::result>& me2,
    			Executor& exec
    		)
    		{
    			if(head* ph=dynamic_cast<head*>(&me2.head))	//Übereinstimmung gefunden
    			{											//Aufruf des Executors
    				return exec(modern_ellipse<typename Loki::TL::Append<L_list,head&>::Result>(me1,*ph));
    			}
    			else										//keine Übereinstimmung gefunden
    			{
    				return static_dispatcher				//nächsten Typ testen
    					<Executor,Error,typename TL::change_to_refernce_type<Bases>::result,TYPELIST_1(typename types_rhs::Tail),Result_type>
    					::go_<L_list>(me1,me2,exec);
    			};
    		};
    	public:
    		static Result_type go(modern_ellipse<typename TL::change_to_refernce_type<Bases>::result>& me, Executor& exec)
    		{
    			if(head* ph=dynamic_cast<head*>(&me.head))	//Übereinstimmung gefunden
    			{
    				return exec(modern_ellipse<TYPELIST_1(head&)>(*ph));//Aufruf des Executors
    			}
    			else										//keine Übereinstimmung gefunden
    			{
    				return static_dispatcher				//nächsten Typ testen
    					<Executor,Error,typename TL::change_to_refernce_type<Bases>::result,TYPELIST_1(typename types_rhs::Tail),Result_type>
    					::go(me,exec);
    			};
    		};
    	};
    
    	//Fehlerbehandlung 2:
    	template
    	<
    		class Executor,
    		template<class,class>class Error,
    		class Bases,
    		class Result_type
    	>
    	class static_dispatcher<Executor,Error,Bases,TYPELIST_1(Loki::NullType),Result_type>
    	{
    	private:
    		template<class E,template<class,class>class Er,class B,class T,class RT>
    		friend class static_dispatcher;
    		template<class L_list>
    		static Result_type go_
    		(
    			modern_ellipse<L_list>& me1,
    			detail::modern_ellipse_<typename mer::TL::list_at<typename TL::change_to_refernce_type<Bases>::result,Loki::TL::Length<L_list>::value>::result>& me2,
    			Executor& exec
    		)
    		{
    			return Error<L_list,TYPELIST_1(typename TL::last_type<typename TL::change_to_refernce_type<Bases>::result>::result)>()(me1,modern_ellipse<TYPELIST_1(typename TL::last_type<TL::change_to_refernce_type<Bases>::result>::result)>(me2.head));
    		};
    	public:
    		static Result_type go(modern_ellipse<typename TL::change_to_refernce_type<Bases>::result>& me, Executor& exec)
    		{
    			return Error<TYPELIST_1(Loki::EmptyType),typename TL::change_to_refernce_type<Bases>::result>()(modern_ellipse<TYPELIST_1(Loki::EmptyType)>(Loki::EmptyType()),me);
    		};
    	};
    };
    

    main:

    #include "static_dispatcher.h"
    class objekt
    {
    public:
    	virtual string what(){return "objekt";};
    };
    
    class raumstation
    	:public objekt
    {
    public:
    	virtual string what(){return "raumstation";};
    };
    
    class raumschiff
    	:public objekt
    {
    public:
    	virtual string what(){return "raumschiff";};
    };
    
    class satellit
    	:public objekt
    {
    public:
    	virtual string what(){return "satellit";};
    };
    
    struct executor
    {
    	//triple-dispatching
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumstation&,raumstation&,raumstation&)>&)
    	{
    		cout<<"triple_dispatcher(raumstation&, raumstation&, raumstation&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumstation&,raumstation&,raumschiff&)>&)
    	{
    		cout<<"triple_dispatcher(raumstation&, raumstation&, raumschiff&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumstation&,raumstation&,satellit&)>&)
    	{
    		cout<<"triple_dispatcher(raumstation&, raumstation&, satellit&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumstation&,raumschiff&,raumstation&)>&)
    	{
    		cout<<"triple_dispatcher(raumstation&, raumschiff&, raumstation&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumstation&,raumschiff&,raumschiff&)>&)
    	{
    		cout<<"triple_dispatcher(raumstation&, raumschiff&, raumschiff&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumstation&,raumschiff&,satellit&)>&)
    	{
    		cout<<"triple_dispatcher(raumstation&, raumschiff&, satellit&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumstation&,satellit&,raumstation&)>&)
    	{
    		cout<<"triple_dispatcher(raumstation&, satellit&, raumstation&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumstation&,satellit&,raumschiff&)>&)
    	{
    		cout<<"triple_dispatcher(raumstation&, satellit&, raumschiff&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumstation&,satellit&,satellit&)>&)
    	{
    		cout<<"triple_dispatcher(raumstation&, satellit&, satellit&)"<<endl;
    	};
    
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumschiff&,raumstation&,raumstation&)>&)
    	{
    		cout<<"triple_dispatcher(raumschiff&, raumstation&, raumstation&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumschiff&,raumstation&,raumschiff&)>&)
    	{
    		cout<<"triple_dispatcher(raumschiff&, raumstation&, raumschiff&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumschiff&,raumstation&,satellit&)>&)
    	{
    		cout<<"triple_dispatcher(raumschiff&, raumstation&, satellit&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumschiff&,raumschiff&,raumstation&)>&)
    	{
    		cout<<"triple_dispatcher(raumschiff&, raumschiff&, raumstation&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumschiff&,raumschiff&,raumschiff&)>&)
    	{
    		cout<<"triple_dispatcher(raumschiff&, raumschiff&, raumschiff&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumschiff&,raumschiff&,satellit&)>&)
    	{
    		cout<<"triple_dispatcher(raumschiff&, raumschiff&, satellit&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumschiff&,satellit&,raumstation&)>&)
    	{
    		cout<<"triple_dispatcher(raumschiff&, satellit&, raumstation&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumschiff&,satellit&,raumschiff&)>&)
    	{
    		cout<<"triple_dispatcher(raumschiff&, satellit&, raumschiff&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(raumschiff&,satellit&,satellit&)>&)
    	{
    		cout<<"triple_dispatcher(raumschiff&, satellit&, satellit&)"<<endl;
    	};
    
    	void operator()(mer::modern_ellipse<TYPELIST_3(satellit&,raumstation&,raumstation&)>&)
    	{
    		cout<<"triple_dispatcher(satellit&, raumstation&, raumstation&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(satellit&,raumstation&,raumschiff&)>&)
    	{
    		cout<<"triple_dispatcher(satellit&, raumstation&, raumschiff&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(satellit&,raumstation&,satellit&)>&)
    	{
    		cout<<"triple_dispatcher(satellit&, raumstation&, satellit&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(satellit&,raumschiff&,raumstation&)>&)
    	{
    		cout<<"triple_dispatcher(satellit&, raumschiff&, raumstation&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(satellit&,raumschiff&,raumschiff&)>&)
    	{
    		cout<<"triple_dispatcher(satellit&, raumschiff&, raumschiff&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(satellit&,raumschiff&,satellit&)>&)
    	{
    		cout<<"triple_dispatcher(satellit&, raumschiff&, satellit&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(satellit&,satellit&,raumstation&)>&)
    	{
    		cout<<"triple_dispatcher(satellit&, satellit&, raumstation&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(satellit&,satellit&,raumschiff&)>&)
    	{
    		cout<<"triple_dispatcher(satellit&, satellit&, raumschiff&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_3(satellit&,satellit&,satellit&)>&)
    	{
    		cout<<"triple_dispatcher(satellit&, satellit&, satellit&)"<<endl;
    	};
    
    	//double-dispatching
    	void operator()(mer::modern_ellipse<TYPELIST_2(raumstation&,raumstation&)>&)
    	{
    		cout<<"triple_dispatcher(raumstation&, raumstation&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_2(raumstation&,raumschiff&)>&)
    	{
    		cout<<"triple_dispatcher(raumstation&, raumschiff&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_2(raumstation&,satellit&)>&)
    	{
    		cout<<"triple_dispatcher(raumstation&, satellit&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_2(raumschiff&,raumstation&)>&)
    	{
    		cout<<"triple_dispatcher(raumschiff&, raumstation&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_2(raumschiff&,raumschiff&)>&)
    	{
    		cout<<"triple_dispatcher(raumschiff&, raumschiff&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_2(raumschiff&,satellit&)>&)
    	{
    		cout<<"triple_dispatcher(raumschiff&, satellit&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_2(satellit&,raumstation&)>&)
    	{
    		cout<<"triple_dispatcher(satellit&, raumstation&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_2(satellit&,raumschiff&)>&)
    	{
    		cout<<"triple_dispatcher(satellit&, raumschiff&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_2(satellit&,satellit&)>&)
    	{
    		cout<<"triple_dispatcher(satellit&, satellit&)"<<endl;
    	};
    
    	//single-dispatching
    	void operator()(mer::modern_ellipse<TYPELIST_1(satellit&)>&)
    	{
    		cout<<"triple_dispatcher(satellit&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_1(raumschiff&)>&)
    	{
    		cout<<"triple_dispatcher(raumschiff&)"<<endl;
    	};
    	void operator()(mer::modern_ellipse<TYPELIST_1(raumstation&)>&)
    	{
    		cout<<"triple_dispatcher(raumstation&)"<<endl;
    	};
    };
    
    template<class L_list,class R_list>
    struct error
    {
    	void operator()(mer::modern_ellipse<L_list>&,mer::modern_ellipse<R_list>&)
    	{
    		cout<<"Unbekanntes Objekt gefunden!"<<endl;
    	};
    };
    
    int main()
    {
    	objekt* pra1=new raumstation;
    	objekt* pra2=new raumstation;
    	objekt* pra3=new raumstation;
    	objekt* pr1=new raumschiff;
    	objekt* pr2=new raumschiff;
    	objekt* pr3=new raumschiff;
    	objekt* ps1=new satellit;
    	objekt* ps2=new satellit;
    	objekt* ps3=new satellit;
    
    	typedef mer::static_dispatcher<executor,error,TYPELIST_3(objekt,objekt&,objekt&),
    		TYPELIST_3
    		(
    			TYPELIST_5(raumschiff,raumstation&,raumschiff,satellit,raumstation&),
    			TYPELIST_3(raumstation,raumschiff&,satellit&),
    			TYPELIST_3(raumstation&,raumschiff,satellit)
    		),void> m_disp;
    	typedef TYPELIST_3(objekt&,objekt&,objekt&) ml;
    	MER_NAMED_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_SEQ_OF_ARGUMENTS
    		(ml,(*ps1)(*pr2)(*pra3),me);
    
    	//typedef mer::static_dispatcher<executor,error,TYPELIST_2(objekt,objekt&),
    	//	TYPELIST_2
    	//	(
    	//		TYPELIST_3(raumstation,raumschiff&,satellit&),
    	//		TYPELIST_3(raumstation&,raumschiff,satellit)
    	//	),void> m_disp;
    	//typedef TYPELIST_2(objekt&,objekt&) ml;
    	//MER_NAMED_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_SEQ_OF_ARGUMENTS
    	//	(ml,(*ps1)(*pra3),me);
    
    	//typedef mer::static_dispatcher<executor,error,TYPELIST_1(objekt&),
    	//	TYPELIST_1
    	//	(
    	//		TYPELIST_3(raumstation&,raumschiff,satellit)
    	//	),void> m_disp;
    	//typedef TYPELIST_1(objekt&) ml;
    	//MER_NAMED_M_ELLIPSE_FROM_MER_TYPELIST_AND_BOOST_PP_SEQ_OF_ARGUMENTS
    	//	(ml,(*ps1),me);
    
    	m_disp::go(me,executor());
    
    	delete pra1;
    	delete pra2;
    	delete pra3;
    	delete pr1;
    	delete pr2;
    	delete pr3;
    	delete ps1;
    	delete ps2;
    	delete ps3;
    	cin.get();
    	return 0;
    };
    

    Außerdem habe ich eine globale include_datei (Wovon man vmtl. net alles braucht, hab ich halt im Laufe der Zeit mal benutzt und nicht wieder rausgenommen):

    #include <iostream>
    #include <string>
    #include <vector>
    
    #include <Typelist.h>
    #include <TypeTraits.h>
    #include <EmptyType.h>
    
    #include <mer_typelist.h>
    
    #include <boost/preprocessor/list/for_each.hpp>
    #include <boost/preprocessor/list/adt.hpp>
    #include <boost/preprocessor/array/data.hpp>
    #include <boost/preprocessor/array/size.hpp>
    #include <boost/preprocessor/tuple/to_list.hpp>
    #include <boost/preprocessor/seq/to_tuple.hpp>
    #include <boost/preprocessor/seq/size.hpp>
    #include <boost/preprocessor/punctuation/comma.hpp>
    

    Wie man sieht baut der code von der Struktur her auf dem static_dispatcher aus der Loki-Bibliothek auf, da aber bis auf die Namen der Funktionen und der Verwendung von Typlisten nichts mehr davon übrig ist, habe ich darauf verzichtet, Andrei Alexandrescus copyright anzugeben.

    Es würde mich freuen wenn sich jemand die Mühe machen und sich den code näher anschauen oder ein paar tests durchführen würde.
    :xmas1: :xmas2:



  • projekteforum?



  • Wenns im falschen Forum ist kanns ja verschoben werden, aber das hatten wir doch schon oft, z.B.: http://www.c-plusplus.net/forum/viewtopic.php?t=90564&highlight=konstruktive+kritik

    Kann ja nicht sein, das niemand eine Meinung dazu hat. Also bitte, sagt was dazu.



  • Dazu wird hier mit Sicherheit keiner was sagen.



  • Humer schrieb:

    Dazu wird hier mit Sicherheit keiner was sagen.

    Du bist also "keiner". Schön. Ich hoffe es finden sich noch ein paar andere. Danke trotzdem für diesen überaus geistreichen Beitrag.
    (Mensch, wir sind zivilisierte Menschen, du wirst doch wenigstens ne Begründung liefern können?)



  • Das checkt hier sowieso fast keiner. Und die die es vielleicht tun könnten, nehmen sich mit Sicherheit nicht die Zeit dazu.



  • ness schrieb:

    Ich habe eine generische multidispatcher Klasse, basierend auf automatisch generierten if-else Abfragen geschrieben.

    naja, dann mache ich lieber sowas:

    map<string, handler> m;
    
    m[ typeid(klasse1).name() + typeid(klasse2).name() ] = handler;
    

    usw.



  • DrGreenthumb schrieb:

    naja, dann mache ich lieber sowas:

    C/C++ Code:
    map<string, handler> m;

    m[ typeid(klasse1).name() + typeid(klasse2).name() ] = handler;

    usw.

    Das nehm ich dann automatisiert als nächstes in Angriff (Erst mal die index-basierte Variante...) 😃
    /edit: Du weißt dass nicht garantiert wird, dass typeid(...).name() im Verlauf des Programmes gleich bleibt?
    /nochmaledit: Manuell stell ich mir da übrigens schon triple-dispatching kompliziert vor...

    Humer schrieb:

    Das checkt hier sowieso fast keiner. Und die die es vielleicht tun könnten, nehmen sich mit Sicherheit nicht die Zeit dazu.

    a)Es geht doch gar nicht nur um die implementation. Mir geht es auch darum ob jemand was zum Design zu sagen hat oder offensichtliche Anfängerfehler enthalten sind.
    Das ist die erste brauchbare Klasse die ich zur vollendung gebracht habe!

    b)Aussprüche ala das Versteh ich eh nicht hasse ich. Das darf ich mir täglich in der Schule anhören, wo ich mehr oder weniger als "wunderkind" bekannt bin. Und das ist ganz gewiss nicht Witzig.

    c)Woher willst du wissen das sich niemand Zeit nimmt? (OK, so unbrechtigt ist der Einwand nun auch wieder nicht...)



  • BITTE! Es kann doch nicht sein, das niemand was dazu sagen möchte? 😞



  • ness schrieb:

    BITTE! Es kann doch nicht sein, das niemand was dazu sagen möchte? 😞

    Humer hat irgendwie Recht 😕

    Ach ja, nimm mal "!Ein Anfänger!" aus deiner Signatur 🙄 😃 😉



  • Der Thread ist gerade mal 4 Stunden alt, und du hast ihn schon zweimal gebumped? Ein bisschen ungeduldig, nicht?

    Wahrscheinlich schau ich's mir irgendwann mal an, aber das ist bei diesem Umfang eine längerfristige Sache.



  • Warum? Es entspricht doch der Wahrheit? Ich hab mich am 16.07.2004 angemeldet, das ist etwa 3 Tage nachdem ich mit volkards Tut angefangen hab. C++ lerne ich also seit ca. 5 Monaten. Hm... irgendwie doch länger als mir vorkommt... Was du vor dir siehst ist die erste vollendete sinnvolle Klasse von mir. OK, ich machs weg, jetzt wo ich drüber nachdenk...
    @Ringding: Ja, das wär net. Und, ja, ungeduldig. (sehr 😃 )



  • ich hab mir das ganze erstmal so angeschaut:

    was ich so auf den ersten blick sehe, ist ein einfacher double dispatching algorithmus, der die üblichen schwächen aufweist: zu viel code, zu schlecht wartbar, und mit linearer suchzeit(+dynamic cast en masse). dazu kommt noch, dass ohne entsprechende docu die template parameter für den static dispatcher selber unüberblickbar sind



  • Ich sag ja, er baut auf statisch generierten if-else Anweisungen auf, also nur eine automatisierung der rohen, fehlerträchtigen standard-implementierung. Wie meinst du das mit dem primitiven algorhithmus? Bekannt wären mir nurnoch dynamische Strukturnen, das habe ich auch noch vor...
    Zu der Sache der Wartbarkeit: ja damit hast du recht, aber wie das ändern?
    Übrigens: Das ist KEIN double-dispatching Algorithmus, sondern eine generalisierung des multidispatching (Daher auch die partielle Spezialisierung für die letzte Ebene)
    /edit für otzes Edit: Ja, dafür muss ein Stück doku her... (morgen)



  • @ness: wenn du positive kritik willst, darfste net so angeben. Wenn du natürlich fertig gemacht werden willst, nur weiter so! 😉



  • @life: Einerseits nützt positive Kritik nat. wenig... 😃 Aber vmtl. hast du Recht... *immerwiederfeststellwiekompliziertdieweltdochist*



  • ich bezweifel irgendwie, dass du hier konstruktive kritik bekommen wirst oo



  • ness, wie wäre es mal wenn du was sinnvolles programmierst?



  • ness geh damit lieber auch auf sourceforge oder codeguru wenn du willst das sich ein paar leute dein ganzes projekt anschaun obwohl das hier sicher auch manche machen wenn sie halt Zeit haben 🙂

    wegem dem projekt selbst, ich finde die makros am anfang nicht so elegant
    etwas unübersichtlich sonst aber was ich so beim Überfliegen gesehen hab (also nur mal das Konstrukt) sieht gut aus auch das codestyling

    #c++ @ freenode.net



  • was kann man damit anfangen? braucht man das? 😕 😮


Anmelden zum Antworten