c++ 面向切面变成 aop 通用模板

#ifndef AOP_h
#define AOP_h
#define HAS_MEMBER(member)\
templatestruct has_member_##member\
{\
private:\
		template static auto Check(int) -> decltype(std::declval().member(std::declval()...), std::true_type()); \
	template static std::false_type Check(...);\
public:\
	enum{value = std::is_same(0)), std::true_type>::value};\
};\

HAS_MEMBER(Foo)
HAS_MEMBER(Before)
HAS_MEMBER(After)
 
template
struct Aspect  
{
	Aspect(Func&& f) : m_func(std::forward(f))
	{
	}

	template
	typename std::enable_if::value&&has_member_After::value>::type Invoke(Args&&... args, T&& aspect)
	{
		aspect.Before(std::forward(args)...);//核心逻辑之前的切面逻辑
		m_func(std::forward(args)...);//核心逻辑
		aspect.After(std::forward(args)...);//核心逻辑之后的切面逻辑
	}

	template
	typename std::enable_if::value&&!has_member_After::value>::type Invoke(Args&&... args, T&& aspect)
	{
		aspect.Before(std::forward(args)...);//核心逻辑之前的切面逻辑
		m_func(std::forward(args)...);//核心逻辑
	}

	template
	typename std::enable_if::value&&has_member_After::value>::type Invoke(Args&&... args, T&& aspect)
	{
		m_func(std::forward(args)...);//核心逻辑
		aspect.After(std::forward(args)...);//核心逻辑之后的切面逻辑
	}

	template
	void Invoke(Args&&... args, Head&&headAspect, Tail&&... tailAspect)
	{
		headAspect.Before(std::forward(args)...);
		Invoke(std::forward(args)..., std::forward(tailAspect)...);
		headAspect.After(std::forward(args)...);
	}

private:
	Func m_func; //被织入的函数
};
template using identity_t = T;

//AOP的辅助函数,简化调用
template
void Invoke(Func&&f, Args&&... args)
{
	Aspect asp(std::forward(f));
	asp.Invoke(std::forward(args)..., identity_t()...);
}

#endif // !AOP_h

你可能感兴趣的:(c++,架构)