From 97bdec1f62fd80ea79e11c8d7c7e42c060c4c543 Mon Sep 17 00:00:00 2001 From: zcy <290198252@qq.com> Date: Sun, 24 Apr 2022 01:33:12 +0800 Subject: [PATCH] add AOP pattern --- general/src/pattern/aspect.hpp | 72 +++++++++++ test/src/test_cpu_usage/test_cpu_usage.cpp | 144 +++++++++++++++++++++ 2 files changed, 216 insertions(+) create mode 100644 general/src/pattern/aspect.hpp diff --git a/general/src/pattern/aspect.hpp b/general/src/pattern/aspect.hpp new file mode 100644 index 0000000..b2fcaaf --- /dev/null +++ b/general/src/pattern/aspect.hpp @@ -0,0 +1,72 @@ +#include + + +#define HAS_MEMBER(member) \ +template \ +struct 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}; \ +}; \ + + +template +struct Aspect +{ + //forward or move 是一样的 + 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 +void invoke(Func&& f, Args&&...args) +{ + Aspect asp(std::forward(f)); + asp.invoke(std::forward(args)..., Ap()...); +} + diff --git a/test/src/test_cpu_usage/test_cpu_usage.cpp b/test/src/test_cpu_usage/test_cpu_usage.cpp index 0bf14cc..aa67c77 100644 --- a/test/src/test_cpu_usage/test_cpu_usage.cpp +++ b/test/src/test_cpu_usage/test_cpu_usage.cpp @@ -5,6 +5,150 @@ #include using namespace std; +#define HAS_MEMBER(member) \ +template \ +struct 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(before) +HAS_MEMBER(after) + +template +struct Aspect +{ + //forward or move 是一样的 + 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 +void invoke(Func&& f, Args&&...args) +{ + Aspect asp(std::forward(f)); + asp.invoke(std::forward(args)..., Ap()...); +} + +struct AA +{ + void before(int i) + { + cout << "before AA:" << i << endl; + } + void after(int i) + { + cout << "after AA:" << i << endl; + } +}; + +struct CC +{ + void before(int i) + { + cout << "before CC:" << i << endl; + } + void after(int i) + { + cout << "after CC:" << i << endl; + } +}; + +struct BB +{ + void before() + { + cout << "before BB" << endl; + } + void after() + { + cout << "after BB" << endl; + } +}; + +struct DD +{ + void before() + { + cout << "before DD" << endl; + } + void after() + { + cout << "after DD" << endl; + } +}; + +void gt() +{ + cout << "gt functional" << endl; +} + +void ht(int i) +{ + cout << "ht functional:" << i << endl; +} + +void test() +{ + //织入普通函数 + std::function f = std::bind(&ht, std::placeholders::_1); + invoke(f, 1); + + cout << "------------------------" << endl; + //织入普通函数 + invoke(>); + cout << "------------------------" << endl; + invoke(&ht, 1); +} + + int main(int argc, char **argv) { CProcessMonitor usage1(26644);