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

📄 funbind.h

📁 又一个c++委托(函数对象)模板类的实现
💻 H
字号:
// Generalized functor implementation helpers. 
// Copyright Aleksei Trunov 2005 
// Use, copy, modify, distribute and sell it for free.

#ifndef _FUNBIND_H_
#define _FUNBIND_H_

#include "Functor.h"

namespace GF {

// ----------------------------------------------------------------------------

template <class TL, class IdsTL, bool include> 
struct Filter2
{
	template <class TL2, int i, class IdsTL2, template <class, int> class Predicate> struct Temp
	{
		typedef typename GU::Select<
			Predicate<typename IdsTL2::Head, i>::value, 
			typename GU::TypeList<typename TL2::Head, typename Temp<typename TL2::Tail, i+1, typename IdsTL2::Tail, Predicate>::Result>,
			typename Temp<typename TL2::Tail, i+1, IdsTL2, Predicate>::Result
		>::Result Result;
	};
	template <class TL2, int i, template <class, int> class Predicate> 
	struct Temp<TL2, i, GU::NullType, Predicate>
	{
		typedef typename GU::Select<include, GU::NullType, TL2>::Result Result;
	};
	template <int i, class IdsTL2, template <class, int> class Predicate> 
	struct Temp<GU::NullType, i, IdsTL2, Predicate>
	{
		typedef GU::NullType Result;
	};
	template <int i, template <class, int> class Predicate> 
	struct Temp<GU::NullType, i, GU::NullType, Predicate>
	{
		typedef GU::NullType Result;
	};
	template <class TL2> struct Temp<TL2, 0, GU::NullType, GU::IsIntType>
	{
		typedef GU::NullType Result;
	};
	template <class TL2> struct Temp<TL2, 0, typename GU::IdsFromTL<TL2>::Type, GU::IsIntType>
	{
		typedef TL2 Result;
	};
	template <class TL2> struct Temp<TL2, 0, GU::NullType, GU::NotIntType>
	{
		typedef TL2 Result;
	};
	template <class TL2> struct Temp<TL2, 0, typename GU::IdsFromTL<TL2>::Type, GU::NotIntType>
	{
		typedef GU::NullType Result;
	};
	typedef typename GU::Select<
		include, 
		typename Temp<TL, 0, IdsTL, GU::IsIntType>::Result,
		typename Temp<TL, 0, IdsTL, GU::NotIntType>::Result
	>::Result Result;
};

template <class TL, class IdsTL> struct BoundTL2
{
	typedef typename Filter2<TL, IdsTL, true>::Result Result;
};
template <class TL, class IdsTL> struct UnboundTL2
{	
	typedef typename Filter2<TL, IdsTL, false>::Result Result;
};

// ----------------------------------------------------------------------------

template <class Incoming, class IdsTL> struct BoundHelper
{
	typedef typename Incoming::TypeListType IncomingTL;
	typedef typename BoundTL2<IncomingTL, IdsTL>::Result BoundTL;
	typedef typename GU::TypeAtNonStrict<BoundTL, 0, GU::NullType>::Result Parm1;
	typedef typename GU::TypeAtNonStrict<BoundTL, 1, GU::NullType>::Result Parm2;
	typedef typename GU::TypeAtNonStrict<BoundTL, 2, GU::NullType>::Result Parm3;
	typedef typename GU::TypeAtNonStrict<BoundTL, 3, GU::NullType>::Result Parm4;
	typedef typename GU::TypeAtNonStrict<BoundTL, 4, GU::NullType>::Result Parm5;
};
template <class Incoming, class IdsTL> struct UnboundHelper
{
	typedef typename Incoming::TypeListType IncomingTL;
	typedef typename UnboundTL2<IncomingTL, IdsTL>::Result UnboundTL;
	typedef typename GU::TypeAtNonStrict<UnboundTL, 0, GU::NullType>::Result Parm1;
	typedef typename GU::TypeAtNonStrict<UnboundTL, 1, GU::NullType>::Result Parm2;
	typedef typename GU::TypeAtNonStrict<UnboundTL, 2, GU::NullType>::Result Parm3;
	typedef typename GU::TypeAtNonStrict<UnboundTL, 3, GU::NullType>::Result Parm4;
	typedef typename GU::TypeAtNonStrict<UnboundTL, 4, GU::NullType>::Result Parm5;
};

template <int i, class BoundPTL, class UnboundPTL, class IdsTL, class TL> struct MergeParmsH
{
	typedef GU::InstantiateH<TL, GU::TupleHolder, i> ResultType;
	struct Bound
	{
		static inline ResultType MergeParms(BoundPTL const& bound, UnboundPTL const& unbound)
		{
			return ResultType(
				static_cast<typename BoundPTL::LeftBase const&>(bound).value, 
				MergeParmsH<i+1, typename BoundPTL::RightBase, UnboundPTL, typename IdsTL::Tail, typename TL::Tail>::MergeParms(static_cast<typename BoundPTL::RightBase const&>(bound), unbound)
			); 
		}
	};
	struct Unbound
	{
		static inline ResultType MergeParms(BoundPTL const& bound, UnboundPTL const& unbound)
		{
			return ResultType(
				static_cast<typename UnboundPTL::LeftBase const&>(unbound).value, 
				MergeParmsH<i+1, BoundPTL, typename UnboundPTL::RightBase, IdsTL, typename TL::Tail>::MergeParms(bound, static_cast<typename UnboundPTL::RightBase const&>(unbound))
			); 
		}
	};
	template <int j, class IdsTL2> struct Predicate { enum { value = IdsTL2::Head::value == j }; };
	template <int j> struct Predicate<j, GU::NullType> { enum { value = false }; };
	static inline ResultType MergeParms(BoundPTL const& bound, UnboundPTL const& unbound)
	{
		return GU::Select<
			Predicate<i, IdsTL>::value,
			Bound,
			Unbound
		>::Result::MergeParms(bound, unbound); 
	}
};
template <int i, class BoundPTL, class UnboundPTL, class IdsTL> 
struct MergeParmsH<i, BoundPTL, UnboundPTL, IdsTL, GU::NullType>
{
	static inline GU::NullType MergeParms(BoundPTL const&, UnboundPTL const&) 
	{ 
		return GU::NullType(); 
	}
};
template <class BoundPTL, class UnboundPTL, class TL> 
struct MergeParmsH<0, BoundPTL, UnboundPTL, GU::NullType, TL>
{
	static inline typename CallParms<TL>::ParmsListType 
	MergeParms(BoundPTL const&/* bound*/, UnboundPTL const& unbound) 
	{ 
		return unbound; 
	}
};

template <class TL, class IdsTL, class BoundPTL, class UnboundPTL> inline 
typename CallParms<TL>::ParmsListType MergeParms(BoundPTL const& bound, UnboundPTL const& unbound)
{
	return MergeParmsH<0, BoundPTL, UnboundPTL, IdsTL, TL>::MergeParms(bound, unbound);
}

template <typename Incoming, typename BoundIdsTL> class Binder
{
public:
	typedef typename Incoming::ResultType ResultType;
	typedef typename Incoming::TypeListType TypeListType;
	typedef typename BoundHelper<Incoming, BoundIdsTL>::BoundTL BoundParamsTL;
	typedef typename UnboundHelper<Incoming, BoundIdsTL>::UnboundTL UnboundParamsTL;
	typedef typename CallParms<BoundParamsTL>::ParmsListType BoundPTL;
	typedef typename CallParms<UnboundParamsTL>::ParmsListType UnboundPTL;
	Binder() : fun_(), bound_() {}
    Binder(Incoming fun, BoundPTL bound) : fun_(fun), bound_(bound) {}
	//typedef Functor<typename Incoming::ResultType, UnboundParamsTL, typename Incoming::Checking, Incoming::size> Outgoing;
	typedef Functor<typename Incoming::ResultType, UnboundParamsTL> Outgoing;
	typedef typename Incoming::ResultType ResultType;
	typedef typename UnboundHelper<Incoming, BoundIdsTL>::Parm1 Parm1;
	typedef typename UnboundHelper<Incoming, BoundIdsTL>::Parm2 Parm2;
	typedef typename UnboundHelper<Incoming, BoundIdsTL>::Parm3 Parm3;
	typedef typename UnboundHelper<Incoming, BoundIdsTL>::Parm4 Parm4;
	typedef typename UnboundHelper<Incoming, BoundIdsTL>::Parm5 Parm5;
	inline ResultType operator()() const 
	{ 
		return fun_(bound_);	// little hand-optimization
		//return fun_(BoundPTL(bound_)); 
		//return fun_(MergeParms<TypeListType, BoundIdsTL>(bound_, CallParms<UnboundParamsTL>::Make())); 
	}
	inline ResultType operator()(Parm1 p1) const 
	{ 
		return fun_(MergeParms<TypeListType, BoundIdsTL>(bound_, CallParms<UnboundParamsTL>::Make(p1))); 
	}
	inline ResultType operator()(Parm1 p1, Parm2 p2) const 
	{ 
		return fun_(MergeParms<TypeListType, BoundIdsTL>(bound_, CallParms<UnboundParamsTL>::Make(p1, p2))); 
	}
	inline ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3) const 
	{ 
		return fun_(MergeParms<TypeListType, BoundIdsTL>(bound_, CallParms<UnboundParamsTL>::Make(p1, p2, p3))); 
	}
	inline ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) const 
	{ 
		return fun_(MergeParms<TypeListType, BoundIdsTL>(bound_, CallParms<UnboundParamsTL>::Make(p1, p2, p3, p4))); 
	}
	inline ResultType operator()(Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5) const 
	{ 
		return fun_(MergeParms<TypeListType, BoundIdsTL>(bound_, CallParms<UnboundParamsTL>::Make(p1, p2, p3, p4, p5))); 
	}
private:
    Incoming fun_;
    BoundPTL bound_;
};

// ----------------------------------------------------------------------------

template <class Incoming> inline 
typename Binder<Incoming, typename GU::CreateIdsTL<>::Type>::Outgoing
Bind(
	Incoming const& fun
) {
	typedef typename GU::CreateIdsTL<>::Type BoundIdsTL;
	typedef typename Binder<Incoming, BoundIdsTL>::Outgoing Outgoing;
	return Outgoing(Binder<Incoming, BoundIdsTL>(fun, CallParms<typename BoundHelper<Incoming, BoundIdsTL>::BoundTL>::Make()));
}

template <int i1, class Incoming> inline 
typename Binder<Incoming, typename GU::CreateIdsTL<i1>::Type>::Outgoing
Bind(
	Incoming const& fun
	, typename BoundHelper<Incoming, typename GU::CreateTL<GU::Int2Type<i1> >::Type>::Parm1 p1
) {
	typedef typename GU::CreateIdsTL<i1>::Type BoundIdsTL;
	typedef typename Binder<Incoming, BoundIdsTL>::Outgoing Outgoing;
	return Outgoing(Binder<Incoming, BoundIdsTL>(fun, CallParms<typename BoundHelper<Incoming, BoundIdsTL>::BoundTL>::Make(p1)));
}

template <int i1, int i2, class Incoming> inline 
typename Binder<Incoming, typename GU::CreateIdsTL<i1, i2>::Type>::Outgoing
Bind(
	Incoming const& fun
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2>::Type>::Parm1 p1
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2>::Type>::Parm2 p2
) {
	typedef typename GU::CreateIdsTL<i1, i2>::Type BoundIdsTL;
	typedef typename Binder<Incoming, BoundIdsTL>::Outgoing Outgoing;
	return Outgoing(Binder<Incoming, BoundIdsTL>(fun, CallParms<typename BoundHelper<Incoming, BoundIdsTL>::BoundTL>::Make(p1, p2)));
}

template <int i1, int i2, int i3, class Incoming> inline 
typename Binder<Incoming, typename GU::CreateIdsTL<i1, i2, i3>::Type>::Outgoing
Bind(
	Incoming const& fun
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3>::Type>::Parm1 p1
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3>::Type>::Parm2 p2
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3>::Type>::Parm3 p3
) {
	typedef typename GU::CreateIdsTL<i1, i2, i3>::Type BoundIdsTL;
	typedef typename Binder<Incoming, BoundIdsTL>::Outgoing Outgoing;
	return Outgoing(Binder<Incoming, BoundIdsTL>(fun, CallParms<typename BoundHelper<Incoming, BoundIdsTL>::BoundTL>::Make(p1, p2, p3)));
}

template <int i1, int i2, int i3, int i4, class Incoming> inline 
typename Binder<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4>::Type>::Outgoing
Bind(
	Incoming const& fun
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4>::Type>::Parm1 p1
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4>::Type>::Parm2 p2
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4>::Type>::Parm3 p3
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4>::Type>::Parm4 p4
) {
	typedef typename GU::CreateIdsTL<i1, i2, i3, i4>::Type BoundIdsTL;
	typedef typename Binder<Incoming, BoundIdsTL>::Outgoing Outgoing;
	return Outgoing(Binder<Incoming, BoundIdsTL>(fun, CallParms<typename BoundHelper<Incoming, BoundIdsTL>::BoundTL>::Make(p1, p2, p3, p4)));
}

template <int i1, int i2, int i3, int i4, int i5, class Incoming> inline 
typename Binder<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5>::Type>::Outgoing
Bind(
	Incoming const& fun
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5>::Type>::Parm1 p1
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5>::Type>::Parm2 p2
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5>::Type>::Parm3 p3
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5>::Type>::Parm4 p4
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5>::Type>::Parm5 p5
) {
	typedef typename GU::CreateIdsTL<i1, i2, i3, i4, i5>::Type BoundIdsTL;
	typedef typename Binder<Incoming, BoundIdsTL>::Outgoing Outgoing;
	return Outgoing(Binder<Incoming, BoundIdsTL>(fun, CallParms<typename BoundHelper<Incoming, BoundIdsTL>::BoundTL>::Make(p1, p2, p3, p4, p5)));
}

template <int i1, int i2, int i3, int i4, int i5, int i6, class Incoming> inline 
typename Binder<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5, i6>::Type>::Outgoing
Bind(
	Incoming const& fun
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5, i6>::Type>::Parm1 p1
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5, i6>::Type>::Parm2 p2
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5, i6>::Type>::Parm3 p3
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5, i6>::Type>::Parm4 p4
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5, i6>::Type>::Parm5 p5
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5, i6>::Type>::Parm5 p6
) {
	typedef typename GU::CreateIdsTL<i1, i2, i3, i4, i5, i6>::Type BoundIdsTL;
	typedef typename Binder<Incoming, BoundIdsTL>::Outgoing Outgoing;
	return Outgoing(Binder<Incoming, BoundIdsTL>(fun, CallParms<typename BoundHelper<Incoming, BoundIdsTL>::BoundTL>::Make(p1, p2, p3, p4, p5, p6)));
}

template <int i1, int i2, int i3, int i4, int i5, int i6, int i7, class Incoming> inline 
typename Binder<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5, i6, i7>::Type>::Outgoing
Bind(
	Incoming const& fun
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5, i6, i7>::Type>::Parm1 p1
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5, i6, i7>::Type>::Parm2 p2
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5, i6, i7>::Type>::Parm3 p3
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5, i6, i7>::Type>::Parm4 p4
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5, i6, i7>::Type>::Parm5 p5
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5, i6, i7>::Type>::Parm5 p6
	, typename BoundHelper<Incoming, typename GU::CreateIdsTL<i1, i2, i3, i4, i5, i6, i7>::Type>::Parm5 p7
) {
	typedef typename GU::CreateIdsTL<i1, i2, i3, i4, i5, i6, i7>::Type BoundIdsTL;
	typedef typename Binder<Incoming, BoundIdsTL>::Outgoing Outgoing;
	return Outgoing(Binder<Incoming, BoundIdsTL>(fun, CallParms<typename BoundHelper<Incoming, BoundIdsTL>::BoundTL>::Make(p1, p2, p3, p4, p5, p6, p7)));
}

}

#endif // _FUNBIND_H_

⌨️ 快捷键说明

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