has_member.h:
#ifndef __AOP_SRC_HAS_MEMBER_H__
#define __AOP_SRC_HAS_MEMBER_H__
#include
#define HAS_MEMBER_FUNCTION(member) \
template
struct has_member_##member \
{ \
private: \
template
static auto test(void*) -> decltype(std::declval().member(std::declval
\
template
static std::false_type test(...);\
\
public:\
static const bool value = decltype(test
};
#endif
macros.h:
#ifndef __AOP_MACROS_H__
#define __AOP_MACROS_H__
#define AOP_NAMESPACE_BEGIN namespace aop {
#define AOP_NAMESPACE_END }
#endif
aspect.h:
#ifndef __AOP_SRC_ASPECT_H__
#define __AOP_SRC_ASPECT_H__
#include "has_member.h"
#include "macros.h"
AOP_NAMESPACE_BEGIN
HAS_MEMBER_FUNCTION(Before);
HAS_MEMBER_FUNCTION(After);
template
struct Aspect
{
Aspect(Func&& func) : func_(std::forward
Aspect(const Aspect&) = delete;
Aspect& operator=(const Aspect&) = delete;
template
void InvokeBefore(T&& aspect, Args&&... args)
{
aspect.Before(std::forward
}
void InvokeBefore(...) {}
template
void InvokeAfter(T&& aspect, Args&&... args)
{
aspect.After(std::forward
}
void InvokeAfter(...) {}
template
void Invoke(Args&&... args, T&& aspect)
{
InvokeBefore(std::forward
func_(std::forward
InvokeAfter(std::forward
}
template
void Invoke(Args&&... args, Head&& head, Tail&&... tail)
{
InvokeBefore(std::forward(head), std::forward
Invoke(std::forward
InvokeAfter(std::forward(head), std::forward
}
private:
Func func_;
};
template
using identity_t = typename std::identity
template
void Invoke(Func&& func, Args&&... args)
{
Aspect
asp.Invoke(std::forward
}
template
void InvokeWithAspects(AP&&...ap, Func&& func, Args&&... args)
{
Aspect
asp.Invoke(std::forward
}
AOP_NAMESPACE_END
#endif
test:
// aop.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include
#include
#include
#include "has_member.h"
#include "aspect.h"
using namespace std;
struct TimeElapsedAspect
{
void Before(int i)
{
std::cout << "start timer" << std::endl;
timer = std::chrono::system_clock::now();
}
void After(int i)
{
cout << "time elapsed: " << std::chrono::system_clock::duration(std::chrono::system_clock::now() - timer).count() << endl;
}
private:
std::chrono::system_clock::time_point timer{ std::chrono::system_clock::now() };
};
struct LoggingAspect
{
LoggingAspect()
{
static int id = 0;
std::cout << "LoggingAspect::construct -- id:" << id++ << std::endl;
}
void Before(int i)
{
std::cout << "entering" << std::endl;
}
void After(int i)
{
std::cout << "leaving" << std::endl;
}
};
struct NoBeforeOrAfter
{
NoBeforeOrAfter()
{
static int id = 0;
std::cout << "NoBeforeOrAfter::construct -- id:" << id++ << std::endl;
}
void Before(const std::string&)
{
}
void After(const std::string&)
{
}
};
void foo(int a)
{
cout << "real HT function: " << a << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
aop::Invoke
cout << "-----------------------" << endl;
aop::Invoke
cout << "-----------------------" << endl;
aop::Invoke
cout << "-----------------------" << endl;
LoggingAspect logging;
TimeElapsedAspect timer;
NoBeforeOrAfter no_before_or_after;
aop::InvokeWithAspects
std::forward
std::forward
std::forward
&foo, 1);
system("pause");
return 0;
}