Roll trace-viewer to 5b0446a2.
[chromium-blink-merge.git] / base / callback_list.h
blob5b911fd4867e1bec80ce002c57fd5d58b129247b
1 // This file was GENERATED by command:
2 // pump.py callback_list.h.pump
3 // DO NOT EDIT BY HAND!!!
6 // Copyright 2013 The Chromium Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE file.
10 #ifndef BASE_CALLBACK_LIST_H_
11 #define BASE_CALLBACK_LIST_H_
13 #include <list>
15 #include "base/basictypes.h"
16 #include "base/callback.h"
17 #include "base/callback_internal.h"
18 #include "base/compiler_specific.h"
19 #include "base/logging.h"
20 #include "base/memory/scoped_ptr.h"
22 // OVERVIEW:
24 // A container for a list of callbacks. Unlike a normal STL vector or list,
25 // this container can be modified during iteration without invalidating the
26 // iterator. It safely handles the case of a callback removing itself
27 // or another callback from the list while callbacks are being run.
29 // TYPICAL USAGE:
31 // class MyWidget {
32 // public:
33 // ...
35 // typedef base::Callback<void(const Foo&)> OnFooCallback;
37 // scoped_ptr<base::CallbackList<void(const Foo&)>::Subscription>
38 // RegisterCallback(const OnFooCallback& cb) {
39 // return callback_list_.Add(cb);
40 // }
42 // private:
43 // void NotifyFoo(const Foo& foo) {
44 // callback_list_.Notify(foo);
45 // }
47 // base::CallbackList<void(const Foo&)> callback_list_;
49 // DISALLOW_COPY_AND_ASSIGN(MyWidget);
50 // };
53 // class MyWidgetListener {
54 // public:
55 // MyWidgetListener::MyWidgetListener() {
56 // foo_subscription_ = MyWidget::GetCurrent()->RegisterCallback(
57 // base::Bind(&MyWidgetListener::OnFoo, this)));
58 // }
60 // MyWidgetListener::~MyWidgetListener() {
61 // // Subscription gets deleted automatically and will deregister
62 // // the callback in the process.
63 // }
65 // private:
66 // void OnFoo(const Foo& foo) {
67 // // Do something.
68 // }
70 // scoped_ptr<base::CallbackList<void(const Foo&)>::Subscription>
71 // foo_subscription_;
73 // DISALLOW_COPY_AND_ASSIGN(MyWidgetListener);
74 // };
76 namespace base {
78 namespace internal {
80 template <typename CallbackType>
81 class CallbackListBase {
82 public:
83 class Subscription {
84 public:
85 Subscription(CallbackListBase<CallbackType>* list,
86 typename std::list<CallbackType>::iterator iter)
87 : list_(list),
88 iter_(iter) {
91 ~Subscription() {
92 if (list_->active_iterator_count_) {
93 iter_->Reset();
94 } else {
95 list_->callbacks_.erase(iter_);
96 if (!list_->removal_callback_.is_null())
97 list_->removal_callback_.Run();
101 private:
102 CallbackListBase<CallbackType>* list_;
103 typename std::list<CallbackType>::iterator iter_;
105 DISALLOW_COPY_AND_ASSIGN(Subscription);
108 // Add a callback to the list. The callback will remain registered until the
109 // returned Subscription is destroyed, which must occur before the
110 // CallbackList is destroyed.
111 scoped_ptr<Subscription> Add(const CallbackType& cb) WARN_UNUSED_RESULT {
112 DCHECK(!cb.is_null());
113 return scoped_ptr<Subscription>(
114 new Subscription(this, callbacks_.insert(callbacks_.end(), cb)));
117 // Sets a callback which will be run when a subscription list is changed.
118 void set_removal_callback(const Closure& callback) {
119 removal_callback_ = callback;
122 // Returns true if there are no subscriptions. This is only valid to call when
123 // not looping through the list.
124 bool empty() {
125 DCHECK_EQ(0, active_iterator_count_);
126 return callbacks_.empty();
129 protected:
130 // An iterator class that can be used to access the list of callbacks.
131 class Iterator {
132 public:
133 explicit Iterator(CallbackListBase<CallbackType>* list)
134 : list_(list),
135 list_iter_(list_->callbacks_.begin()) {
136 ++list_->active_iterator_count_;
139 Iterator(const Iterator& iter)
140 : list_(iter.list_),
141 list_iter_(iter.list_iter_) {
142 ++list_->active_iterator_count_;
145 ~Iterator() {
146 if (list_ && --list_->active_iterator_count_ == 0) {
147 list_->Compact();
151 CallbackType* GetNext() {
152 while ((list_iter_ != list_->callbacks_.end()) && list_iter_->is_null())
153 ++list_iter_;
155 CallbackType* cb = NULL;
156 if (list_iter_ != list_->callbacks_.end()) {
157 cb = &(*list_iter_);
158 ++list_iter_;
160 return cb;
163 private:
164 CallbackListBase<CallbackType>* list_;
165 typename std::list<CallbackType>::iterator list_iter_;
168 CallbackListBase() : active_iterator_count_(0) {}
170 ~CallbackListBase() {
171 DCHECK_EQ(0, active_iterator_count_);
172 DCHECK_EQ(0U, callbacks_.size());
175 // Returns an instance of a CallbackListBase::Iterator which can be used
176 // to run callbacks.
177 Iterator GetIterator() {
178 return Iterator(this);
181 // Compact the list: remove any entries which were NULLed out during
182 // iteration.
183 void Compact() {
184 typename std::list<CallbackType>::iterator it = callbacks_.begin();
185 bool updated = false;
186 while (it != callbacks_.end()) {
187 if ((*it).is_null()) {
188 updated = true;
189 it = callbacks_.erase(it);
190 } else {
191 ++it;
194 if (updated && !removal_callback_.is_null())
195 removal_callback_.Run();
199 private:
200 std::list<CallbackType> callbacks_;
201 int active_iterator_count_;
202 Closure removal_callback_;
204 DISALLOW_COPY_AND_ASSIGN(CallbackListBase);
207 } // namespace internal
209 template <typename Sig> class CallbackList;
211 template <>
212 class CallbackList<void(void)>
213 : public internal::CallbackListBase<Callback<void(void)> > {
214 public:
215 typedef Callback<void(void)> CallbackType;
217 CallbackList() {}
219 void Notify() {
220 internal::CallbackListBase<CallbackType>::Iterator it =
221 this->GetIterator();
222 CallbackType* cb;
223 while ((cb = it.GetNext()) != NULL) {
224 cb->Run();
228 private:
229 DISALLOW_COPY_AND_ASSIGN(CallbackList);
232 template <typename A1>
233 class CallbackList<void(A1)>
234 : public internal::CallbackListBase<Callback<void(A1)> > {
235 public:
236 typedef Callback<void(A1)> CallbackType;
238 CallbackList() {}
240 void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1) {
241 typename internal::CallbackListBase<CallbackType>::Iterator it =
242 this->GetIterator();
243 CallbackType* cb;
244 while ((cb = it.GetNext()) != NULL) {
245 cb->Run(a1);
249 private:
250 DISALLOW_COPY_AND_ASSIGN(CallbackList);
253 template <typename A1, typename A2>
254 class CallbackList<void(A1, A2)>
255 : public internal::CallbackListBase<Callback<void(A1, A2)> > {
256 public:
257 typedef Callback<void(A1, A2)> CallbackType;
259 CallbackList() {}
261 void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
262 typename internal::CallbackParamTraits<A2>::ForwardType a2) {
263 typename internal::CallbackListBase<CallbackType>::Iterator it =
264 this->GetIterator();
265 CallbackType* cb;
266 while ((cb = it.GetNext()) != NULL) {
267 cb->Run(a1, a2);
271 private:
272 DISALLOW_COPY_AND_ASSIGN(CallbackList);
275 template <typename A1, typename A2, typename A3>
276 class CallbackList<void(A1, A2, A3)>
277 : public internal::CallbackListBase<Callback<void(A1, A2, A3)> > {
278 public:
279 typedef Callback<void(A1, A2, A3)> CallbackType;
281 CallbackList() {}
283 void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
284 typename internal::CallbackParamTraits<A2>::ForwardType a2,
285 typename internal::CallbackParamTraits<A3>::ForwardType a3) {
286 typename internal::CallbackListBase<CallbackType>::Iterator it =
287 this->GetIterator();
288 CallbackType* cb;
289 while ((cb = it.GetNext()) != NULL) {
290 cb->Run(a1, a2, a3);
294 private:
295 DISALLOW_COPY_AND_ASSIGN(CallbackList);
298 template <typename A1, typename A2, typename A3, typename A4>
299 class CallbackList<void(A1, A2, A3, A4)>
300 : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4)> > {
301 public:
302 typedef Callback<void(A1, A2, A3, A4)> CallbackType;
304 CallbackList() {}
306 void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
307 typename internal::CallbackParamTraits<A2>::ForwardType a2,
308 typename internal::CallbackParamTraits<A3>::ForwardType a3,
309 typename internal::CallbackParamTraits<A4>::ForwardType a4) {
310 typename internal::CallbackListBase<CallbackType>::Iterator it =
311 this->GetIterator();
312 CallbackType* cb;
313 while ((cb = it.GetNext()) != NULL) {
314 cb->Run(a1, a2, a3, a4);
318 private:
319 DISALLOW_COPY_AND_ASSIGN(CallbackList);
322 template <typename A1, typename A2, typename A3, typename A4, typename A5>
323 class CallbackList<void(A1, A2, A3, A4, A5)>
324 : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4, A5)> > {
325 public:
326 typedef Callback<void(A1, A2, A3, A4, A5)> CallbackType;
328 CallbackList() {}
330 void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
331 typename internal::CallbackParamTraits<A2>::ForwardType a2,
332 typename internal::CallbackParamTraits<A3>::ForwardType a3,
333 typename internal::CallbackParamTraits<A4>::ForwardType a4,
334 typename internal::CallbackParamTraits<A5>::ForwardType a5) {
335 typename internal::CallbackListBase<CallbackType>::Iterator it =
336 this->GetIterator();
337 CallbackType* cb;
338 while ((cb = it.GetNext()) != NULL) {
339 cb->Run(a1, a2, a3, a4, a5);
343 private:
344 DISALLOW_COPY_AND_ASSIGN(CallbackList);
347 template <typename A1, typename A2, typename A3, typename A4, typename A5,
348 typename A6>
349 class CallbackList<void(A1, A2, A3, A4, A5, A6)>
350 : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4, A5,
351 A6)> > {
352 public:
353 typedef Callback<void(A1, A2, A3, A4, A5, A6)> CallbackType;
355 CallbackList() {}
357 void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
358 typename internal::CallbackParamTraits<A2>::ForwardType a2,
359 typename internal::CallbackParamTraits<A3>::ForwardType a3,
360 typename internal::CallbackParamTraits<A4>::ForwardType a4,
361 typename internal::CallbackParamTraits<A5>::ForwardType a5,
362 typename internal::CallbackParamTraits<A6>::ForwardType a6) {
363 typename internal::CallbackListBase<CallbackType>::Iterator it =
364 this->GetIterator();
365 CallbackType* cb;
366 while ((cb = it.GetNext()) != NULL) {
367 cb->Run(a1, a2, a3, a4, a5, a6);
371 private:
372 DISALLOW_COPY_AND_ASSIGN(CallbackList);
375 template <typename A1, typename A2, typename A3, typename A4, typename A5,
376 typename A6, typename A7>
377 class CallbackList<void(A1, A2, A3, A4, A5, A6, A7)>
378 : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4, A5, A6,
379 A7)> > {
380 public:
381 typedef Callback<void(A1, A2, A3, A4, A5, A6, A7)> CallbackType;
383 CallbackList() {}
385 void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
386 typename internal::CallbackParamTraits<A2>::ForwardType a2,
387 typename internal::CallbackParamTraits<A3>::ForwardType a3,
388 typename internal::CallbackParamTraits<A4>::ForwardType a4,
389 typename internal::CallbackParamTraits<A5>::ForwardType a5,
390 typename internal::CallbackParamTraits<A6>::ForwardType a6,
391 typename internal::CallbackParamTraits<A7>::ForwardType a7) {
392 typename internal::CallbackListBase<CallbackType>::Iterator it =
393 this->GetIterator();
394 CallbackType* cb;
395 while ((cb = it.GetNext()) != NULL) {
396 cb->Run(a1, a2, a3, a4, a5, a6, a7);
400 private:
401 DISALLOW_COPY_AND_ASSIGN(CallbackList);
404 } // namespace base
406 #endif // BASE_CALLBACK_LIST_H_