Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2012 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 // To generate callback.h from callback.h.pump, execute:
     12 // /home/build/google3/third_party/gtest/scripts/pump.py callback.h.pump
     13 
     14 // Callbacks are callable object containers. They can hold a function pointer
     15 // or a function object and behave like a value type. Internally, data is
     16 // reference-counted, making copies and pass-by-value inexpensive.
     17 //
     18 // Callbacks are typed using template arguments.  The format is:
     19 //   CallbackN<ReturnType, ParamType1, ..., ParamTypeN>
     20 // where N is the number of arguments supplied to the callable object.
     21 // Callbacks are invoked using operator(), just like a function or a function
     22 // object. Default-constructed callbacks are "empty," and executing an empty
     23 // callback does nothing. A callback can be made empty by assigning it from
     24 // a default-constructed callback.
     25 //
     26 // Callbacks are similar in purpose to std::function (which isn't available on
     27 // all platforms we support) and a lightweight alternative to sigslots. Since
     28 // they effectively hide the type of the object they call, they're useful in
     29 // breaking dependencies between objects that need to interact with one another.
     30 // Notably, they can hold the results of Bind(), std::bind*, etc, without needing
     31 // to know the resulting object type of those calls.
     32 //
     33 // Sigslots, on the other hand, provide a fuller feature set, such as multiple
     34 // subscriptions to a signal, optional thread-safety, and lifetime tracking of
     35 // slots. When these features are needed, choose sigslots.
     36 //
     37 // Example:
     38 //   int sqr(int x) { return x * x; }
     39 //   struct AddK {
     40 //     int k;
     41 //     int operator()(int x) const { return x + k; }
     42 //   } add_k = {5};
     43 //
     44 //   Callback1<int, int> my_callback;
     45 //   cout << my_callback.empty() << endl;  // true
     46 //
     47 //   my_callback = Callback1<int, int>(&sqr);
     48 //   cout << my_callback.empty() << endl;  // false
     49 //   cout << my_callback(3) << endl;  // 9
     50 //
     51 //   my_callback = Callback1<int, int>(add_k);
     52 //   cout << my_callback(10) << endl;  // 15
     53 //
     54 //   my_callback = Callback1<int, int>();
     55 //   cout << my_callback.empty() << endl;  // true
     56 
     57 #ifndef WEBRTC_BASE_CALLBACK_H_
     58 #define WEBRTC_BASE_CALLBACK_H_
     59 
     60 #include "webrtc/base/refcount.h"
     61 #include "webrtc/base/scoped_ref_ptr.h"
     62 
     63 namespace rtc {
     64 
     65 $var n = 5
     66 $range i 0..n
     67 $for i [[
     68 $range j 1..i
     69 
     70 template <class R$for j [[,
     71           class P$j]]>
     72 class Callback$i {
     73  public:
     74   // Default copy operations are appropriate for this class.
     75   Callback$i() {}
     76   template <class T> Callback$i(const T& functor)
     77       : helper_(new RefCountedObject< HelperImpl<T> >(functor)) {}
     78   R operator()($for j , [[P$j p$j]]) {
     79     if (empty())
     80       return R();
     81     return helper_->Run($for j , [[p$j]]);
     82   }
     83   bool empty() const { return !helper_; }
     84 
     85  private:
     86   struct Helper : RefCountInterface {
     87     virtual ~Helper() {}
     88     virtual R Run($for j , [[P$j p$j]]) = 0;
     89   };
     90   template <class T> struct HelperImpl : Helper {
     91     explicit HelperImpl(const T& functor) : functor_(functor) {}
     92     virtual R Run($for j , [[P$j p$j]]) {
     93       return functor_($for j , [[p$j]]);
     94     }
     95     T functor_;
     96   };
     97   scoped_refptr<Helper> helper_;
     98 };
     99 
    100 ]]
    101 }  // namespace rtc
    102 
    103 #endif  // WEBRTC_BASE_CALLBACK_H_
    104