1// This file was GENERATED by command:
2//     pump.py callback_list.h.pump
3// DO NOT EDIT BY HAND!!!
4
5
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.
9
10#ifndef BASE_CALLBACK_LIST_H_
11#define BASE_CALLBACK_LIST_H_
12
13#include <list>
14
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"
21
22// OVERVIEW:
23//
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.
28//
29// TYPICAL USAGE:
30//
31// class MyWidget {
32//  public:
33//   ...
34//
35//   typedef base::Callback<void(const Foo&)> OnFooCallback;
36//
37//   scoped_ptr<base::CallbackList<void(const Foo&)>::Subscription>
38//   RegisterCallback(const OnFooCallback& cb) {
39//     return callback_list_.Add(cb);
40//   }
41//
42//  private:
43//   void NotifyFoo(const Foo& foo) {
44//      callback_list_.Notify(foo);
45//   }
46//
47//   base::CallbackList<void(const Foo&)> callback_list_;
48//
49//   DISALLOW_COPY_AND_ASSIGN(MyWidget);
50// };
51//
52//
53// class MyWidgetListener {
54//  public:
55//   MyWidgetListener::MyWidgetListener() {
56//     foo_subscription_ = MyWidget::GetCurrent()->RegisterCallback(
57//             base::Bind(&MyWidgetListener::OnFoo, this)));
58//   }
59//
60//   MyWidgetListener::~MyWidgetListener() {
61//      // Subscription gets deleted automatically and will deregister
62//      // the callback in the process.
63//   }
64//
65//  private:
66//   void OnFoo(const Foo& foo) {
67//     // Do something.
68//   }
69//
70//   scoped_ptr<base::CallbackList<void(const Foo&)>::Subscription>
71//       foo_subscription_;
72//
73//   DISALLOW_COPY_AND_ASSIGN(MyWidgetListener);
74// };
75
76namespace base {
77
78namespace internal {
79
80template <typename CallbackType>
81class 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) {
89    }
90
91    ~Subscription() {
92      if (list_->active_iterator_count_)
93        iter_->Reset();
94      else
95        list_->callbacks_.erase(iter_);
96    }
97
98   private:
99    CallbackListBase<CallbackType>* list_;
100    typename std::list<CallbackType>::iterator iter_;
101
102    DISALLOW_COPY_AND_ASSIGN(Subscription);
103  };
104
105  // Add a callback to the list. The callback will remain registered until the
106  // returned Subscription is destroyed, which must occur before the
107  // CallbackList is destroyed.
108  scoped_ptr<Subscription> Add(const CallbackType& cb) WARN_UNUSED_RESULT {
109    DCHECK(!cb.is_null());
110    return scoped_ptr<Subscription>(
111        new Subscription(this, callbacks_.insert(callbacks_.end(), cb)));
112  }
113
114 protected:
115  // An iterator class that can be used to access the list of callbacks.
116  class Iterator {
117   public:
118    explicit Iterator(CallbackListBase<CallbackType>* list)
119        : list_(list),
120          list_iter_(list_->callbacks_.begin()) {
121      ++list_->active_iterator_count_;
122    }
123
124    Iterator(const Iterator& iter)
125        : list_(iter.list_),
126          list_iter_(iter.list_iter_) {
127      ++list_->active_iterator_count_;
128    }
129
130    ~Iterator() {
131      if (list_ && --list_->active_iterator_count_ == 0) {
132        list_->Compact();
133      }
134    }
135
136    CallbackType* GetNext() {
137      while ((list_iter_ != list_->callbacks_.end()) && list_iter_->is_null())
138        ++list_iter_;
139
140      CallbackType* cb = NULL;
141      if (list_iter_ != list_->callbacks_.end()) {
142        cb = &(*list_iter_);
143        ++list_iter_;
144      }
145      return cb;
146    }
147
148   private:
149    CallbackListBase<CallbackType>* list_;
150    typename std::list<CallbackType>::iterator list_iter_;
151  };
152
153  CallbackListBase() : active_iterator_count_(0) {}
154
155  ~CallbackListBase() {
156    DCHECK_EQ(0, active_iterator_count_);
157    DCHECK_EQ(0U, callbacks_.size());
158  }
159
160  // Returns an instance of a CallbackListBase::Iterator which can be used
161  // to run callbacks.
162  Iterator GetIterator() {
163    return Iterator(this);
164  }
165
166  // Compact the list: remove any entries which were NULLed out during
167  // iteration.
168  void Compact() {
169    typename std::list<CallbackType>::iterator it = callbacks_.begin();
170    while (it != callbacks_.end()) {
171      if ((*it).is_null())
172        it = callbacks_.erase(it);
173      else
174        ++it;
175    }
176  }
177
178 private:
179  std::list<CallbackType> callbacks_;
180  int active_iterator_count_;
181
182  DISALLOW_COPY_AND_ASSIGN(CallbackListBase);
183};
184
185}  // namespace internal
186
187template <typename Sig> class CallbackList;
188
189template <>
190class CallbackList<void(void)>
191    : public internal::CallbackListBase<Callback<void(void)> > {
192 public:
193  typedef Callback<void(void)> CallbackType;
194
195  CallbackList() {}
196
197  void Notify() {
198    internal::CallbackListBase<CallbackType>::Iterator it =
199        this->GetIterator();
200    CallbackType* cb;
201    while ((cb = it.GetNext()) != NULL) {
202      cb->Run();
203    }
204  }
205
206 private:
207  DISALLOW_COPY_AND_ASSIGN(CallbackList);
208};
209
210template <typename A1>
211class CallbackList<void(A1)>
212    : public internal::CallbackListBase<Callback<void(A1)> > {
213 public:
214  typedef Callback<void(A1)> CallbackType;
215
216  CallbackList() {}
217
218  void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1) {
219    typename internal::CallbackListBase<CallbackType>::Iterator it =
220        this->GetIterator();
221    CallbackType* cb;
222    while ((cb = it.GetNext()) != NULL) {
223      cb->Run(a1);
224    }
225  }
226
227 private:
228  DISALLOW_COPY_AND_ASSIGN(CallbackList);
229};
230
231template <typename A1, typename A2>
232class CallbackList<void(A1, A2)>
233    : public internal::CallbackListBase<Callback<void(A1, A2)> > {
234 public:
235  typedef Callback<void(A1, A2)> CallbackType;
236
237  CallbackList() {}
238
239  void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
240              typename internal::CallbackParamTraits<A2>::ForwardType a2) {
241    typename internal::CallbackListBase<CallbackType>::Iterator it =
242        this->GetIterator();
243    CallbackType* cb;
244    while ((cb = it.GetNext()) != NULL) {
245      cb->Run(a1, a2);
246    }
247  }
248
249 private:
250  DISALLOW_COPY_AND_ASSIGN(CallbackList);
251};
252
253template <typename A1, typename A2, typename A3>
254class CallbackList<void(A1, A2, A3)>
255    : public internal::CallbackListBase<Callback<void(A1, A2, A3)> > {
256 public:
257  typedef Callback<void(A1, A2, A3)> CallbackType;
258
259  CallbackList() {}
260
261  void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
262              typename internal::CallbackParamTraits<A2>::ForwardType a2,
263              typename internal::CallbackParamTraits<A3>::ForwardType a3) {
264    typename internal::CallbackListBase<CallbackType>::Iterator it =
265        this->GetIterator();
266    CallbackType* cb;
267    while ((cb = it.GetNext()) != NULL) {
268      cb->Run(a1, a2, a3);
269    }
270  }
271
272 private:
273  DISALLOW_COPY_AND_ASSIGN(CallbackList);
274};
275
276template <typename A1, typename A2, typename A3, typename A4>
277class CallbackList<void(A1, A2, A3, A4)>
278    : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4)> > {
279 public:
280  typedef Callback<void(A1, A2, A3, A4)> CallbackType;
281
282  CallbackList() {}
283
284  void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
285              typename internal::CallbackParamTraits<A2>::ForwardType a2,
286              typename internal::CallbackParamTraits<A3>::ForwardType a3,
287              typename internal::CallbackParamTraits<A4>::ForwardType a4) {
288    typename internal::CallbackListBase<CallbackType>::Iterator it =
289        this->GetIterator();
290    CallbackType* cb;
291    while ((cb = it.GetNext()) != NULL) {
292      cb->Run(a1, a2, a3, a4);
293    }
294  }
295
296 private:
297  DISALLOW_COPY_AND_ASSIGN(CallbackList);
298};
299
300template <typename A1, typename A2, typename A3, typename A4, typename A5>
301class CallbackList<void(A1, A2, A3, A4, A5)>
302    : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4, A5)> > {
303 public:
304  typedef Callback<void(A1, A2, A3, A4, A5)> CallbackType;
305
306  CallbackList() {}
307
308  void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
309              typename internal::CallbackParamTraits<A2>::ForwardType a2,
310              typename internal::CallbackParamTraits<A3>::ForwardType a3,
311              typename internal::CallbackParamTraits<A4>::ForwardType a4,
312              typename internal::CallbackParamTraits<A5>::ForwardType a5) {
313    typename internal::CallbackListBase<CallbackType>::Iterator it =
314        this->GetIterator();
315    CallbackType* cb;
316    while ((cb = it.GetNext()) != NULL) {
317      cb->Run(a1, a2, a3, a4, a5);
318    }
319  }
320
321 private:
322  DISALLOW_COPY_AND_ASSIGN(CallbackList);
323};
324
325template <typename A1, typename A2, typename A3, typename A4, typename A5,
326    typename A6>
327class CallbackList<void(A1, A2, A3, A4, A5, A6)>
328    : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4, A5,
329        A6)> > {
330 public:
331  typedef Callback<void(A1, A2, A3, A4, A5, A6)> CallbackType;
332
333  CallbackList() {}
334
335  void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
336              typename internal::CallbackParamTraits<A2>::ForwardType a2,
337              typename internal::CallbackParamTraits<A3>::ForwardType a3,
338              typename internal::CallbackParamTraits<A4>::ForwardType a4,
339              typename internal::CallbackParamTraits<A5>::ForwardType a5,
340              typename internal::CallbackParamTraits<A6>::ForwardType a6) {
341    typename internal::CallbackListBase<CallbackType>::Iterator it =
342        this->GetIterator();
343    CallbackType* cb;
344    while ((cb = it.GetNext()) != NULL) {
345      cb->Run(a1, a2, a3, a4, a5, a6);
346    }
347  }
348
349 private:
350  DISALLOW_COPY_AND_ASSIGN(CallbackList);
351};
352
353template <typename A1, typename A2, typename A3, typename A4, typename A5,
354    typename A6, typename A7>
355class CallbackList<void(A1, A2, A3, A4, A5, A6, A7)>
356    : public internal::CallbackListBase<Callback<void(A1, A2, A3, A4, A5, A6,
357        A7)> > {
358 public:
359  typedef Callback<void(A1, A2, A3, A4, A5, A6, A7)> CallbackType;
360
361  CallbackList() {}
362
363  void Notify(typename internal::CallbackParamTraits<A1>::ForwardType a1,
364              typename internal::CallbackParamTraits<A2>::ForwardType a2,
365              typename internal::CallbackParamTraits<A3>::ForwardType a3,
366              typename internal::CallbackParamTraits<A4>::ForwardType a4,
367              typename internal::CallbackParamTraits<A5>::ForwardType a5,
368              typename internal::CallbackParamTraits<A6>::ForwardType a6,
369              typename internal::CallbackParamTraits<A7>::ForwardType a7) {
370    typename internal::CallbackListBase<CallbackType>::Iterator it =
371        this->GetIterator();
372    CallbackType* cb;
373    while ((cb = it.GetNext()) != NULL) {
374      cb->Run(a1, a2, a3, a4, a5, a6, a7);
375    }
376  }
377
378 private:
379  DISALLOW_COPY_AND_ASSIGN(CallbackList);
380};
381
382}  // namespace base
383
384#endif  // BASE_CALLBACK_LIST_H_
385