ROSE 0.11.145.147
callbacks.h
1#ifndef ROSE_Callbacks_H
2#define ROSE_Callbacks_H
3#include <Rose/Constants.h>
4
5#include <boost/thread/locks.hpp>
6#include <boost/thread/mutex.hpp>
7#include <list>
8
9namespace Rose {
10
12namespace Callbacks {
13
19
82template<class T>
83class List {
84public:
85 typedef T CallbackType;
86 typedef std::list<CallbackType*> CBList;
88private:
89 mutable boost::mutex mutex_;
90 CBList list;
91
92public:
93 List() {}
94
95 List(const List &other) {
96 boost::lock_guard<boost::mutex> lock(other.mutex_);
97 list = other.list;
98 }
99
100 explicit List(CallbackType *callback) {
101 append(callback);
102 }
103
107 size_t size() const {
108 boost::lock_guard<boost::mutex> lock(mutex_);
109 return list.size();
110 }
111
117 bool empty() const {
118 boost::lock_guard<boost::mutex> lock(mutex_);
119 return list.empty();
120 }
121
129 assert(cb!=NULL);
130 boost::lock_guard<boost::mutex> lock(mutex_);
131 list.push_back(cb);
132 return *this;
133 }
134
142 assert(cb!=NULL);
143 boost::lock_guard<boost::mutex> lock(mutex_);
144 list.push_front(cb);
145 return *this;
146 }
147
155 List& after(CallbackType *relative_to, CallbackType *cb, size_t nreplacements = UNLIMITED) {
156 assert(cb!=NULL);
157 boost::lock_guard<boost::mutex> lock(mutex_);
158 for (typename CBList::iterator li=list.begin(); li!=list.end() && nreplacements>0; ++li) {
159 if (*li==relative_to) {
160 li = list.insert(++li, cb);
161 --nreplacements;
162 }
163 }
164 return *this;
165 }
166
172 List& before(CallbackType *relative_to, CallbackType *cb, size_t nreplacements = UNLIMITED) {
173 assert(cb!=NULL);
174 boost::lock_guard<boost::mutex> lock(mutex_);
175 for (typename CBList::iterator li=list.begin(); li!=list.end() && nreplacements>0; ++li) {
176 if (*li==relative_to) {
177 li = list.insert(li, cb);
178 ++li;
179 --nreplacements;
180 }
181 }
182 return *this;
183 }
184
193 List& replace(CallbackType *old_cb, CallbackType *new_cb, size_t nreplacements = UNLIMITED, Direction dir = FORWARD) {
194 assert(new_cb!=NULL);
195 boost::lock_guard<boost::mutex> lock(mutex_);
196 if (FORWARD==dir) {
197 for (typename CBList::iterator li=list.begin(); li!=list.end() && nreplacements>0; ++li) {
198 if (*li==old_cb) {
199 *li = new_cb;
200 --nreplacements;
201 }
202 }
203 } else {
204 for (typename CBList::reverse_iterator li=list.rbegin(); li!=list.rend() && nreplacements>0; ++li) {
205 if (*li==old_cb) {
206 *li = new_cb;
207 --nreplacements;
208 }
209 }
210 }
211 return *this;
212 }
213
222 boost::lock_guard<boost::mutex> lock(mutex_);
223 if (FORWARD==dir) {
224 for (typename CBList::iterator li=list.begin(); li!=list.end(); ++li) {
225 if (*li==cb) {
226 list.erase(li);
227 return true;
228 }
229 }
230 } else {
231 for (typename CBList::reverse_iterator li=list.rbegin(); li!=list.rend(); ++li) {
232 if (*li==cb) {
233 list.erase((++li).base());
234 return true;
235 }
236 }
237 }
238 return false;
239 }
240
246 boost::lock_guard<boost::mutex> lock(mutex_);
247 list.clear();
248 return *this;
249 }
250
254 std::list<CallbackType*> callbacks() const {
255 boost::lock_guard<boost::mutex> lock(mutex_);
256 return list;
257 }
258
271 template<class ArgumentType>
272 bool apply(bool b, const ArgumentType &args, Direction dir=FORWARD) const {
273 CBList list = callbacks(); /* copy, so callbacks can safely modify this object's list */
274 if (FORWARD==dir) {
275 for (typename CBList::iterator li=list.begin(); li!=list.end(); ++li) {
276 b = (**li)(b, args);
277 }
278 } else {
279 for (typename CBList::reverse_iterator li=list.rbegin(); li!=list.rend(); ++li) {
280 b = (**li)(b, args);
281 }
282 }
283 return b;
284 }
285};
286
287} // namespace
288} // namespace
289
290#endif /* ROSE_callbacks_H */
List of callback functors.
Definition callbacks.h:83
List & replace(CallbackType *old_cb, CallbackType *new_cb, size_t nreplacements=UNLIMITED, Direction dir=FORWARD)
Replace one callback with another.
Definition callbacks.h:193
List & clear()
Remove all callbacks from list without destroying them.
Definition callbacks.h:245
List & prepend(CallbackType *cb)
Prepend callback to beginning of list without copying it.
Definition callbacks.h:141
bool erase(CallbackType *cb, Direction dir=FORWARD)
Remove a callback from a list without destroying it.
Definition callbacks.h:221
std::list< CallbackType * > CBList
Standard vector of functor pointers.
Definition callbacks.h:86
size_t size() const
Returns the number of callbacks in the list.
Definition callbacks.h:107
bool apply(bool b, const ArgumentType &args, Direction dir=FORWARD) const
Invokes all functors in the callback list.
Definition callbacks.h:272
bool empty() const
Predicate to test whether the list is empty.
Definition callbacks.h:117
T CallbackType
Functor class.
Definition callbacks.h:85
List & append(CallbackType *cb)
Append a functor to the end of the list without copying it.
Definition callbacks.h:128
List & after(CallbackType *relative_to, CallbackType *cb, size_t nreplacements=UNLIMITED)
Insert a callback after another.
Definition callbacks.h:155
List & before(CallbackType *relative_to, CallbackType *cb, size_t nreplacements=UNLIMITED)
Insert a callback before another.
Definition callbacks.h:172
std::list< CallbackType * > callbacks() const
Returns a copy of the underlying STL vector of functors.
Definition callbacks.h:254
Direction
Direction of callback list traversal.
Definition callbacks.h:15
@ BACKWARD
Traverse the list from back to front.
Definition callbacks.h:17
@ FORWARD
Traverse the list from front to back.
Definition callbacks.h:16
The ROSE library.
const size_t UNLIMITED
Effectively unlimited size.
Definition Constants.h:19