STL之仿函数,配接器实现

#ifndef __FUNCTIONAL_H
#define __FUNCTIONAL_H
template<class Arg,class Result>
struct unary_function
{
	typedef Arg argument_type;
	typedef Result result_type;
};

template<class Arg1,class Arg2,class Result>
struct binary_function
{

	typedef Arg1 first_argument_type;
	typedef Arg2 second_argument_type;
	typedef Result result_type;
};

template<class T>
struct plus :public binary_function<T, T, T>
{
	T operator()(const T& x, const T& y)const
	{
		return x + y;
	}
};

template<class T>
struct minus :public binary_function<T, T, T>
{
	T operator()(const T& x, const T& y)const
	{
		return x - y;
	}
};

template<class T>
struct multiplies :public binary_function<T, T, T>
{
	T operator()(const T& x, const T& y)const
	{
		return x * y;
	}
};

template<class T>
struct divides :public binary_function<T,T,T>
{
	T operator()(const T& x, const T& y)const
	{
		return x / y;
	}
};

template<class T>
struct modulus :public binary_function<T,T,T>
{
	T operator()(const T& x, const T& y)const
	{
		return x%y;
	}
};

template<class T>
struct negate :public unary_function<T,T>
{
	T operator()(const T& x)const
	{
		return -x;
	}
};

template<class T>
inline T identity_element(plus<T>)
{
	return T(0);
}

template<class T>
inline T identity_element(multiplies<T>)
{
	return T(1);
}

template<class T>
struct equal_to :public binary_function<T, T, bool>
{
	bool operator()(const T& x, const T& y)const
	{
		return x == y;
	}
};

template<class T>
struct not_equal_to :public binary_function<T, T, bool>
{
	bool operator()(const T& x, const T& y)const
	{
		return x != y;
	}
};

template<class T>
struct greater:public binary_function<T, T, bool>
{
	bool operator()(const T& x, const T& y)const
	{
		return x > y;
	}
};

template<class T>
struct greater_equal :public binary_function<T, T, bool>
{
	bool operator()(const T& x, const T& y)const
	{
		return x >= y;
	}
};

template<class T>
struct less :public binary_function<T, T, bool>
{
	bool operator()(const T& x, const T& y)const
	{
		return x < y;
	}
};

template<class T>
struct less_equal :public binary_function<T, T, bool>
{
	bool operator()(const T& x, const T& y)const
	{
		return x <= y;
	}
};

template<class T>
struct logical_and :public binary_function<T, T, bool>
{
	bool operator()(const T& x, const T& y)const
	{
		return x&&y;
	}
};

template<class T>
struct logical_or :public binary_function<T, T, bool>
{
	bool operator()(const T& x, const T& y)const
	{
		return x || y;
	}
};

template<class T>
struct logical_not :public unary_function<T, bool>
{
	bool operator()(const T& x)const
	{
		return !x;
	}
};

template<class T>
struct identity :public unary_function<T, T>
{
	const T& operator()(const T& x)const
	{
		return x;
	}
};

template<class Pair>
struct select1st :public unary_function<Pair, typename Pair::first_type>
{
	const typename Pair::first_type& operator()(const Pair& x)const
	{
		return x.first;
	}
};

template<class Pair>
struct select2nd :public unary_function<Pair, typename Pair::second_type>
{
	const typename Pair::second_type& operator()(const Pair& x)const
	{
		return x.second;
	}
};

template<class Arg1,class Arg2>
struct project1st :public binary_function<Arg1, Arg2, Arg1>
{
	Arg1 operator()(const Arg1& x, const Arg2& y)const
	{
		return x;
	}
};

template<class Arg1,class Arg2>
struct project2nd :public binary_function<Arg1, Arg2, Arg2>
{
	Arg2 operator()(const Arg1& x, const Arg2& y)const
	{
		return y;
	}
};

template<class Predicate>
class unary_negate :public unary_function<typename Predicate::argument_type, bool>
{
protected:
	Predicate pred;
public:
	explicit unary_negate(const Predicate& x) :pred(x){}
	bool operator()(const typename Predicate::argument_type& x)const
	{
		return !pred(x);
	}
};

template<class Predicate>
inline unary_negate<Predicate>& not1(const Predicate& pred)
{
	return unary_negate<Predicate>(pred);
}

template<class Predicate>
class binary_negate
	:public binary_function<typename Predicate::first_argument_type,
	typename Predicate::second_argument_type,
	bool>
{
protected:
	Predicate pred;
public:
	explicit binary_negate(const Predicate& x) :pred(x){}
	bool operator()(const typename Predicate::first_argument_type& x,
		const typename Predicate::second_argument_type& y)const 
	{
		return !pred(x, y);
	}
};

template<class Predicate>
inline binary_negate<Predicate> not2(const Predicate& pred)
{
	return binary_negate<Predicate>(pred);
}

template<class Operation>
class binder1st :public unary_function<typename Operation::second_argument_type,
	typename Operation::result_type>
{
protected:
	Operation op;
	typename Operation::first_argument_type value;
public:
	binder1st(const Operation& x,
		const typename Operation::first_argument_type& y)
		:op(x), value(y){}
	typename Operation::result_type
		operator()(const typename Operation::second_argument_type& x)const
	{
		return op(value, x);
	}
};

template<class Operation,class T>
inline binder1st<Operation> bind1st(const Operation& op, const T& x)
{
	typedef typename Operation::first_argument_type arg1_type;
	return binder1st<Operation>(op, arg1_type(x));
}

template<class Operation>
class binder2nd :public unary_function<typename Operation::first_argument_type,
	typename Operation::result_type>
{
protected:
	Operation op;
	typename Operation::second_argument_type value;
public:
	binder2nd(const Operation& x,
		const typename Operation::second_argument_type& y)
		:op(x), value(y){}
	typename Operation::result_type operator()(const typename Operation::first_argument_type& x)const
	{
		return op(x, value);
	}
};

template<class Operation,class T>
inline binder2nd<Operation> bind2nd(const Operation& op, const T& x)
{
	typedef typename Operation::second_argument_type arg2_type;
	return binder2nd<Operation>(op, arg2_type(x));
}

template<class Operation1,class Operation2>
class unary_compose :
	public unary_function<typename Operation2::argument_type,
	typename Operation1::result_type>
{
protected:
	Operation1 op1;
	Operation2 op2;
public:
	unary_compose(const Operation1& x,const Operation2& y)
		:op1(x), op2(y){}
	typename Operation1::result_type
		operator()(const typename Operation2::argument_type& x)const
	{
		return op1(op2(x));
	}
};

template<class Operation1,class Operation2>
inline unary_compose<Operation1, Operation2> compose1(const Operation1& op1, const Operation2& op2)
{
	return unary_compose<Operation1, Operation2>(op1, op2);
}

template<class Operation1,class Operation2,class Operation3>
class binary_compose
	:public unary_function<typename Operation2::argument_type,
	typename Operation1::result_type>
{
protected:
	Operation1 op1;
	Operation2 op2;
	Operation3 op3;
public:
	binary_compose(const Operation1& x,const Operation2& y,const Operation3& z)
		:op1(x), op2(y), op3(z){}
	typename Operation1::result_type
		operator()(const typename Operation2::argument_type& x)const
	{
		return op1(op2(x), op3(x));
	}
};

template<class Operation1, class Operation2,class Operation3>
inline binary_compose<Operation1,Operation2,Operation3>
compose2(const Operation1& op1, const Operation2& op2, const Operation3& op3)
{
	return binary_compose<Operation1, Operation2, Operation3>(op1, op2, op3);
}

template<class Arg,class Result>
class pointer_to_unary_function :public unary_function<Arg, Result>
{
protected:
	Result(*ptr)(Arg);
public:
	pointer_to_unary_function(){}
	explicit pointer_to_unary_function(Result(*x)(Arg)) :ptr(x){}
	Result operator()(Arg x)const{ return ptr(x); }
};

template<class Arg,class Result>
inline pointer_to_unary_function<Arg, Result> ptr_fun(Result(*x)(Arg))
{
	return pointer_to_unary_function<Arg, Result>(x);
}

template<class Arg1,class Arg2,class Result>
class pointer_to_binary_function
	:public binary_function<Arg1, Arg2, Result>
{
protected:
	Result(*ptr)(Arg1, Arg2);
public:
	pointer_to_binary_function(){}
	explicit pointer_to_binary_function(Result(*x)(Arg1, Arg2)) :ptr(x){}
	Result operator()(Arg1 x, Arg2 y)const
	{
		return ptr(x, y);
	}
};

template<class Arg1,class Arg2,class Result>
inline pointer_to_binary_function<Arg1, Arg2, Result> ptr_fun(Result(*x)(Arg1, Arg2))
{
	return pointer_to_binary_function<Arg1, Arg2, Result>(x);
}

template<class S,class T>
class mem_fun_t :public unary_function<T*, S>
{
public:
	explicit mem_fun_t(S(T::*f)()) :f(pf){}
	S operator()(T* p){ return (p->*f)(); }
private:
	S(T::*f)();
};

template<class S,class T>
class const_mem_fun_t :public unary_function<T*, S>
{
public:
	explicit const_mem_fun_t(S(T::*pf)()const) :f(pf){}
	S operator()(const T* p)const{ return (p->*f)(); }
private:
	S(T::*f)()const;
};

template<class S,class T>
class mem_fun_ref_t :public unary_function<T, S>
{
public:
	explicit mem_fun_ref_t(S(T::*pf)()) :f(pf){}
	S operator()(T& r)const{ return (r.*f)(); }
private:
	S(T::*f)();
};

template<class S,class T>
class const_mem_fun_ref_t :public unary_function<T, S>
{
public:
	explicit const_mem_fun_ref_t(S(T::*pf)()const) :f(pf){}
	S operator()(const T& r)const{ return (r.*f)(); }
private:
	S(T::*f)()const;
};

template<class S,class T,class A>
class mem_fun1_t :public binary_function<T*, A, S>
{
public:
	explicit mem_fun1_t(S(T::*pf)(A)) :f(pf){}
	S operator()(T* p, A x)const{ return (p->*f)(x); }
private:
	S(T::*f)(A);
};

template<class S,class T,class A>
class const_mem_fun1_t :public binary_function<T*, A, S>
{
public:
	explicit const_mem_fun1_t(S(T::*pf)(A)const) :f(pf){}
	S operator()(const T* p, A x)const{ return (p->*f)(x); }
private:
	S(T::*f)(A)const;
};

template<class S,class T,class A>
class mem_fun1_ref_t :public binary_function<T, A, S>
{
public:
	explicit mem_fun1_ref_t(S(T::*pf)(A)) :f(pf){}
	S operator()(T& r, A x)const{ return (r.*f)(x); }
private:
	S(T::*f)(A);
};

template<class S, class T, class A>
class const_mem_fun1_ref_t :public binary_function<T, A, S>
{
public:
	explicit const_mem_fun1_ref_t(S(T::*pf)(A)const) :f(pf){}
	S operator()(const T& r, A x)const{ return (r.*f)(x); }
private:
	S(T::*f)(A)const;
};

template<class S,class T>
inline mem_fun_t<S, T> mem_fun(S(T::*f)())
{
	return mem_fun_t<S, T>(f);
}

template<class S,class T>
inline const_mem_fun_t<S, T> mem_fun(S(T::*f)()const)
{
	return const_mem_fun_t<S, T>(f);
}

template<class S,class T>
inline mem_fun_ref_t<S, T> mem_fun_ref(S(T::*f)())
{
	return mem_fun_ref_t<S, T>(f);
}

template<class S,class T>
inline const_mem_fun_ref_t<S, T> mem_fun_ref(S(T::*f)()const)
{
	return const_mem_fun_ref_t<S, T>(f);
}

template<class S,class T,class A>
inline mem_fun1_t<S, T, A> mem_fun1(S(T::*f)(A))
{
	return mem_fun1_t<S, T, A>(f);
}

template<class S,class T,class A>
inline const_mem_fun1_t<S, T, A> mem_fun1(S(T::*f)(A)const)
{
	return const_mem_fun1_t<S, T, A>(f);
}

template<class S,class T,class A>
inline mem_fun1_ref_t<S, T, A> mem_fun1_ref(S(T::*f)(A))
{
	return mem_fun1_ref_t<S, T, A>(f);
}

template<class S,class T,class A>
inline const_mem_fun1_ref_t<S, T, A> mem_fun1_ref(S(T::*f)(A))
{
	return const_mem_fun1_ref_t<S, T, A>(f);
}

#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值