ROSE  0.9.9.109
Callbacks.h
1 // WARNING: Changes to this file must be contributed back to Sawyer or else they will
2 // be clobbered by the next update from Sawyer. The Sawyer repository is at
3 // https://github.com/matzke1/sawyer.
4 
5 
6 
7 
8 #ifndef Sawyer_Callbacks_H
9 #define Sawyer_Callbacks_H
10 
11 #include <Sawyer/Sawyer.h>
12 #include <Sawyer/SharedPointer.h>
13 #include <list>
14 
15 namespace Sawyer {
16 
17 // FIXME[Robb Matzke 2014-08-13]: documentation
18 template<class Callback>
19 class Callbacks {
20 private:
21  typedef std::list<Callback> CbList;
22  CbList callbacks_;
23 
24 public:
25  bool isEmpty() const {
26  return callbacks_.empty();
27  }
28 
29  Callbacks& append(const Callback &callback) {
30  callbacks_.push_back(callback);
31  return *this;
32  }
33 
34  Callbacks& append(const Callbacks &other) {
35  callbacks_.insert(callbacks_.end(), other.callbacks_.begin(), other.callbacks_.end());
36  return *this;
37  }
38 
39  Callbacks& prepend(const Callback &callback) {
40  callbacks_.push_front(callback);
41  return *this;
42  }
43 
44  Callback& prepend(const Callbacks &other) {
45  callbacks_.insert(callbacks_.begin(), other.callbacks_.begin(), other.callbacks_.end());
46  return *this;
47  }
48 
49  Callbacks& eraseFirst(const Callback &callback) {
50  for (typename CbList::iterator iter=callbacks_.begin(); iter!=callbacks_.end(); ++iter) {
51  if (*iter == callback) {
52  callbacks_.erase(iter);
53  break;
54  }
55  }
56  return *this;
57  }
58 
59  Callbacks& eraseLast(const Callback &callback) {
60  for (typename CbList::reverse_iterator reverseIter=callbacks_.rbegin(); reverseIter!=callbacks_.rend(); ++reverseIter) {
61  if (*reverseIter == callback) {
62  typename CbList::iterator forwardIter = (++reverseIter).base();
63  callbacks_.erase(forwardIter);
64  break;
65  }
66  }
67  return *this;
68  }
69 
70  Callbacks& eraseMatching(const Callback &callback) {
71  typename CbList::iterator iter = callbacks_.begin();
72  while (iter!=callbacks_.end()) {
73  if (*iter == callback) {
74  typename CbList::iterator toErase = iter++;
75  callbacks_.erase(toErase); // std::list iterators are stable over erasure
76  } else {
77  ++iter;
78  }
79  }
80  }
81 
82  template<class CB, class Args>
83  bool applyCallback(CB *callback, bool chained, const Args &args) const {
84  return (*callback)(chained, args);
85  }
86 
87  template<class CB, class Args>
88  bool applyCallback(const SharedPointer<CB> &callback, bool chained, const Args &args) const {
89  return (*callback)(chained, args);
90  }
91 
92  template<class CB, class Args>
93  bool applyCallback(CB &callback, bool chained, const Args &args) const {
94  return callback(chained, args);
95  }
96 
97  template<class Arguments>
98  bool apply(bool chained, const Arguments &arguments) const {
99  for (typename CbList::const_iterator iter=callbacks_.begin(); iter!=callbacks_.end(); ++iter)
100  chained = applyCallback(*iter, chained, arguments);
101  return chained;
102  }
103 };
104 
105 template<class Callback>
107  Callbacks<Callback> &callbacks_;
108  Callback callback_;
109 public:
110  TemporaryCallback(Callbacks<Callback> &callbacks, const Callback &callback)
111  : callbacks_(callbacks), callback_(callback) {
112  callbacks_.append(callback);
113  }
114 
115  ~TemporaryCallback() {
116  callbacks_.eraseLast(callback_);
117  }
118 };
119 
120 } // namespace
121 
122 #endif
Reference-counting smart pointer.
Definition: SharedPointer.h:34
Name space for the entire library.
Definition: Access.h:11