All pastes #1823046 Raw Edit

clueless

public text v1 · immutable
#1823046 ·published 2010-03-04 20:08 UTC
rendered paste body
#ifndef RDKFUNCTIONSIMPL_H_#define RDKFUNCTIONSIMPL_H_#include <RDKFunctions>#include <RDKUtility>#include <vector>using std::vector;using std::tuple;namespace RDKNAMESPACE{	template<typename... Args> class rdkArgsI : rdkArgs	{	private:		const vector<const type> types;		tuple<Args...> data;				~rdkArgsI()		{		}			public:		rdkArgsI(Args&&... arguments) : data(std::forward<Args>(arguments)...), types(typeid(Args)...)		{		}				rdkArgsI(tuple<Args...> && arguments) : data(arguments), types(typeid(Args)...)		{		}				size_t arguments() const throw()		{			return sizeof...(Args);		}				const type & operator[](size_t i) const throw(exception)		{			if(i < arguments())				return types[i];			throw rdkOutOfRange;		}				const tuple<Args...> & data get()		{			return data;		}				rdkArgs * pop()		{			if(!arguments())				throw rdkOutOfRange;						rdkArgs * p = new rdkArgsI(pack<sizeof...(Args)-1>(data));			delete this;			return p;		}				rdkArgs * shorten(size_t l) const throw(exception)		{			if(l > arguments())				throw rdkOutOfRange;			else if(l == arguments())				return new rdkArgsI(data);			else			{				rdkArgs * t = new rdkArgI(data);				while(t->arguments() > l)					t = t->pop();				return t;			}		}	};		template<typename... Args> rdkArgs * pack_args(Args&&... a)	{		return new rdkArgsI(std::forward(a)...);	}		template<typename... Args> rdkArgs * pack_args(tuple<Args...> && t)	{		return new rdkArgsI(std::forward(t));	}		template<typename... Args> class rdkFunctionBaseI : rdkFunction	{	protected:		const vector<const type> types;		public:		virtual bool isMemberFunction() const throw()		{			return false;		}				bool callable(rdkArgs * args) const throw()		{			if(args->arguments() < arguments())				return false;						for(size_t i = 0; i < arguments(); i++)				if(args->operator[](i) != operator[](i))					return false;			return true;		}				bool compatible(rdkFunction * rhs) const throw()		{			if(rhs.arguments() < arguments())				return false;						for(size_t i = 0; i < arguments(); i++)				if(rhs->opeartor[](i) != opeartor[](i))					return false;			return true;		}				virtual const type & superClass() const throw(exception)		{			if(isMemberFunction())				return types.front();			else				throw rdkNotAMember;		}				constexpr size_t arguments() const throw()		{			return sizeof...(Args);		}				const type & operator[](size_t i) const throw(exception)		{			if(i < arguments())				return types[i];			throw rdkOutOfRange();		}				virtual void call(const tuple<Args...> &) const = delete;				void operator()(rdkArgs * a) const throw(exception)		{			if(!compatible(a))				throw rdkNotCompatible;						rdkArgsI<Args...> * args = a->shorten(arguments());			if(!args)				throw rdkNotCompatible;						call(args->get());		}	};		template<typename... Args> class rdkFunctionI : rdkFunctionBaseI	{	private:		function<void (Args...)> f;		public:		rdkFunctionI(void (*function)(Args...)) : types(typeid(Args)...), f(function)		{		}				void call(const tuple<Args...> & a) const		{			unpack(f, a...);		}	};		template<typename T, typename... Args> class rdkFunctionMemberI : rdkFunctionBaseI	{	private:		function<void (T*, Args...)> f;		public:		rdkFunctionMemberI(void (T::*function)(Args...)) : types(typeid(T*), typeid(Args)...), f(function)		{		}				bool isMemberFunction() const throw()		{			return true;		}				void call(const tuple<Args...> & a) const		{			unpack(f, a...);		}	};		template<typename... Args> rdkFunction * pack_function(void (*f)(Args...))	{		return new rdkFunctionI(f);	}		template<typename T, typename... Args> rdkFunction * pack_function(void (T::*f)(Args...))	{		return new rdkFunctionMemberI(f);	}}#endif