ROSE  0.11.50.0
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  bool operator==(const Callbacks &other) {
30  return callbacks_.size() == other.callbacks_.size() &&
31  std::equal(callbacks_.begin(), callbacks_.end(), other.callbacks_.begin());
32  }
33 
34  Callbacks& append(const Callback &callback) {
35  callbacks_.push_back(callback);
36  return *this;
37  }
38 
39  Callbacks& append(const Callbacks &other) {
40  callbacks_.insert(callbacks_.end(), other.callbacks_.begin(), other.callbacks_.end());
41  return *this;
42  }
43 
44  Callbacks& prepend(const Callback &callback) {
45  callbacks_.push_front(callback);
46  return *this;
47  }
48 
49  Callback& prepend(const Callbacks &other) {
50  callbacks_.insert(callbacks_.begin(), other.callbacks_.begin(), other.callbacks_.end());
51  return *this;
52  }
53 
54  Callbacks& eraseFirst(const Callback &callback) {
55  for (typename CbList::iterator iter=callbacks_.begin(); iter!=callbacks_.end(); ++iter) {
56  if (*iter == callback) {
57  callbacks_.erase(iter);
58  break;
59  }
60  }
61  return *this;
62  }
63 
64  Callbacks& eraseLast(const Callback &callback) {
65  for (typename CbList::reverse_iterator reverseIter=callbacks_.rbegin(); reverseIter!=callbacks_.rend(); ++reverseIter) {
66  if (*reverseIter == callback) {
67  typename CbList::iterator forwardIter = (++reverseIter).base();
68  callbacks_.erase(forwardIter);
69  break;
70  }
71  }
72  return *this;
73  }
74 
75  Callbacks& eraseMatching(const Callback &callback) {
76  typename CbList::iterator iter = callbacks_.begin();
77  while (iter!=callbacks_.end()) {
78  if (*iter == callback) {
79  typename CbList::iterator toErase = iter++;
80  callbacks_.erase(toErase); // std::list iterators are stable over erasure
81  } else {
82  ++iter;
83  }
84  }
85  }
86 
87  template<class CB, class Args>
88  bool applyCallback(CB *callback, bool chained, Args &args) const {
89  return (*callback)(chained, args);
90  }
91 
92  template<class CB, class Args>
93  bool applyCallback(const SharedPointer<CB> &callback, bool chained, Args &args) const {
94  return (*callback)(chained, args);
95  }
96 
97 #if __cplusplus >= 201103ul
98  template<class CB, class Args>
99  bool applyCallback(const std::shared_ptr<CB> &callback, bool chained, Args &args) const {
100  return (*callback)(chained, args);
101  }
102 #endif
103 
104  template<class CB, class Args>
105  bool applyCallback(CB &callback, bool chained, Args &args) const {
106  return callback(chained, args);
107  }
108 
109  template<class Arguments>
110  bool apply(bool chained, const Arguments &arguments) const {
111  for (typename CbList::const_iterator iter=callbacks_.begin(); iter!=callbacks_.end(); ++iter)
112  chained = applyCallback(*iter, chained, arguments);
113  return chained;
114  }
115 
116  template<class Arguments>
117  bool apply(bool chained, Arguments &arguments) const {
118  for (typename CbList::const_iterator iter=callbacks_.begin(); iter!=callbacks_.end(); ++iter)
119  chained = applyCallback(*iter, chained, arguments);
120  return chained;
121  }
122 };
123 
124 template<class Callback>
126  Callbacks<Callback> &callbacks_;
127  Callback callback_;
128 public:
129  TemporaryCallback(Callbacks<Callback> &callbacks, const Callback &callback)
130  : callbacks_(callbacks), callback_(callback) {
131  callbacks_.append(callback);
132  }
133 
134  ~TemporaryCallback() {
135  callbacks_.eraseLast(callback_);
136  }
137 };
138 
139 } // namespace
140 
141 #endif
Reference-counting intrusive smart pointer.
Definition: SharedPointer.h:68
Name space for the entire library.
Definition: FeasiblePath.h:787