forked from loveyacper/ananas
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDelegate.h
89 lines (71 loc) · 1.82 KB
/
Delegate.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#ifndef BERT_DELEGATE_H
#define BERT_DELEGATE_H
#include <functional>
#include <list>
///@file Delegate.h
///@brief A delegate class like C#
namespace ananas {
template <typename T>
class Delegate;
///@brief A delegate class like C# delegate
/// Usage
///@code
/// //三个函数的定义
/// void Inc(int& n) { ++n; }
/// void Print(int& n) { cout << n << endl; }
///
/// class Test {
/// public:
/// void MInc(int& n) { ++n; }
/// };
///
/// //测试委托
/// int n = 0;
/// ananas::Delegate<void (int& )> cb;
/// cb += Inc;
/// cb += Print;
/// cb(n); // 先执行Inc,再执行print打印1
///
/// Test obj;
/// cb += std::bind(&Test::MInc, &obj, std::placeholders::_1); //也可以注册成员函数
/// //注册lambda也没问题,只要签名一致
/// cb += [](int& b) { ++b; };
///@endcode
template <typename... Args>
class Delegate<void (Args...)> {
public:
typedef Delegate<void (Args...)> Self;
Delegate() = default;
Delegate(const Self& ) = delete;
Self& operator= (const Self& ) = delete;
template <typename F>
Delegate(F&& f) {
connect(std::forward<F>(f));
}
Delegate(Self&& other) :
funcs_(std::move(other.funcs_)) {
}
template <typename F>
Self& operator+=(F&& f) {
connect(std::forward<F>(f));
return *this;
}
template<typename... ARGS>
void operator()(ARGS&&... args) {
call(std::forward<ARGS>(args)...);
}
private:
std::list<std::function<void (Args ...)> > funcs_;
template <typename F>
void connect(F&& f) {
funcs_.emplace_back(std::forward<F>(f));
}
template <typename... ARGS>
void call(ARGS&&... args) {
// But what if rvalue args?
for (const auto& f : funcs_)
f(std::forward<ARGS>(args)...);
}
};
} // end namespace ananas
#endif