Home | History | Annotate | Download | only in deps
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef GOOGLE_CACHEINVALIDATION_DEPS_CALLBACK_H_
      6 #define GOOGLE_CACHEINVALIDATION_DEPS_CALLBACK_H_
      7 
      8 #include "base/bind.h"
      9 #include "base/bind_helpers.h"
     10 #include "base/callback.h"
     11 
     12 #define INVALIDATION_CALLBACK1_TYPE(Arg1) ::base::Callback<void(Arg1)>
     13 
     14 // Below are a collection of types and functions that adapt base::Callback's
     15 // pass-by-value semantics to the pointer-based callback system that
     16 // cacheinvalidation needs.
     17 
     18 namespace invalidation {
     19 
     20 typedef ::base::Closure Closure;
     21 
     22 template <class T>
     23 bool IsCallbackRepeatable(const T* callback) {
     24   // The default cacheinvalidation Callbacks may be self-deleting. We don't
     25   // support this behave, so we already return true to indicate that the
     26   // cacheinvalidation implementation should delete our Callbacks.
     27   return true;
     28 }
     29 
     30 namespace internal {
     31 
     32 // Identity<T>::type is a typedef of T. Useful for preventing the
     33 // compiler from inferring the type of an argument in templates.
     34 template <typename T>
     35 struct Identity {
     36   typedef T type;
     37 };
     38 
     39 }  // namespace internal
     40 
     41 // The cacheinvalidation callback system expects to take the callback by
     42 // pointer and handle the ownership semantics itself.  Adapting the
     43 // Chromium Callback system requires returning a dynamically allocated
     44 // copy of the result of Bind().
     45 
     46 inline Closure* NewPermanentCallback(void (*fn)()) {
     47   return new ::base::Closure(::base::Bind(fn));
     48 }
     49 
     50 template <class T1, class T2>
     51 Closure* NewPermanentCallback(
     52     T1* object, void (T2::*method)()) {
     53   return new ::base::Closure(::base::Bind(method, base::Unretained(object)));
     54 }
     55 
     56 template <class T1, class T2, typename Arg1>
     57 ::base::Callback<void(Arg1)>* NewPermanentCallback(
     58     T1* object, void (T2::*method)(Arg1)) {
     59   return new ::base::Callback<void(Arg1)>(
     60       ::base::Bind(method, base::Unretained(object)));
     61 }
     62 
     63 template <class T1, class T2, typename Arg1>
     64 Closure* NewPermanentCallback(
     65     T1* object,
     66     void (T2::*method)(Arg1),
     67     typename internal::Identity<Arg1>::type arg1) {
     68   return new ::base::Closure(::base::Bind(method, base::Unretained(object),
     69                                           arg1));
     70 }
     71 
     72 template <typename Arg1, typename Arg2>
     73 Closure* NewPermanentCallback(
     74     void (*fn)(Arg1, Arg2),
     75     typename internal::Identity<Arg1>::type arg1,
     76     typename internal::Identity<Arg2>::type arg2) {
     77   return new ::base::Closure(::base::Bind(fn, arg1, arg2));
     78 }
     79 
     80 template <class T1, class T2, typename Arg1, typename Arg2>
     81 Closure* NewPermanentCallback(
     82     T1* object,
     83     void (T2::*method)(Arg1, Arg2),
     84     typename internal::Identity<Arg1>::type arg1,
     85     typename internal::Identity<Arg2>::type arg2) {
     86   return new ::base::Closure(::base::Bind(method, base::Unretained(object),
     87                                           arg1, arg2));
     88 }
     89 
     90 template <class T1, class T2, typename Arg1, typename Arg2>
     91 ::base::Callback<void(Arg2)>* NewPermanentCallback(
     92     T1* object,
     93     void (T2::*method)(Arg1, Arg2),
     94     typename internal::Identity<Arg1>::type arg1) {
     95   return new ::base::Callback<void(Arg2)>(
     96       ::base::Bind(method, base::Unretained(object), arg1));
     97 }
     98 
     99 template <class T1, class T2, typename Arg1, typename Arg2, typename Arg3>
    100 Closure* NewPermanentCallback(
    101     T1* object,
    102     void (T2::*method)(Arg1, Arg2, Arg3),
    103     typename internal::Identity<Arg1>::type arg1,
    104     typename internal::Identity<Arg2>::type arg2,
    105     typename internal::Identity<Arg3>::type arg3) {
    106   return new ::base::Closure(::base::Bind(method, base::Unretained(object),
    107                                           arg1, arg2, arg3));
    108 }
    109 
    110 template <class T1, class T2, typename Arg1, typename Arg2, typename Arg3,
    111           typename Arg4>
    112 Closure* NewPermanentCallback(
    113     T1* object,
    114     void (T2::*method)(Arg1, Arg2, Arg3, Arg4),
    115     typename internal::Identity<Arg1>::type arg1,
    116     typename internal::Identity<Arg2>::type arg2,
    117     typename internal::Identity<Arg3>::type arg3,
    118     typename internal::Identity<Arg4>::type arg4) {
    119   return new ::base::Closure(::base::Bind(method, base::Unretained(object),
    120                                           arg1, arg2, arg3, arg4));
    121 }
    122 
    123 // Creates a Closure that runs |callback| on |arg|. The returned Closure owns
    124 // |callback|.
    125 template <typename ArgType>
    126 Closure* NewPermanentCallback(
    127     INVALIDATION_CALLBACK1_TYPE(ArgType)* callback,
    128     typename internal::Identity<ArgType>::type arg) {
    129   return new ::base::Closure(::base::Bind(
    130       &::base::Callback<void(ArgType)>::Run, base::Owned(callback), arg));
    131 }
    132 
    133 }  // namespace invalidation
    134 
    135 #endif  // GOOGLE_CACHEINVALIDATION_DEPS_CALLBACK_H_
    136