OLD | NEW |
(Empty) | |
| 1 $$ This is a pump file for generating file templates. Pump is a python |
| 2 $$ script that is part of the Google Test suite of utilities. Description |
| 3 $$ can be found here: |
| 4 $$ |
| 5 $$ http://code.google.com/p/googletest/wiki/PumpManual |
| 6 $$ |
| 7 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 8 // Use of this source code is governed by a BSD-style license that can be |
| 9 // found in the LICENSE file. |
| 10 |
| 11 #ifndef BASE_PREBIND_H_ |
| 12 #define BASE_PREBIND_H_ |
| 13 |
| 14 #include "base/uber_callback.h" |
| 15 |
| 16 namespace base { |
| 17 |
| 18 namespace internal { |
| 19 // These classes are argument wrappers that affect the refcounting, and storage |
| 20 // semantics for prebound arguments. |
| 21 |
| 22 template <typename T> |
| 23 class UnretainedWrapper { |
| 24 public: |
| 25 explicit UnretainedWrapper(T* o) : obj_(o) {} |
| 26 T* get() { return obj_; } |
| 27 private: |
| 28 T* obj_; |
| 29 }; |
| 30 |
| 31 template <typename T> |
| 32 class ConstRefWrapper { |
| 33 public: |
| 34 explicit ConstRefWrapper(const T& o) : ptr_(&o) {} |
| 35 const T* get() { return ptr_; } |
| 36 private: |
| 37 const T* ptr_; |
| 38 }; |
| 39 |
| 40 // Unwrap for the wrappers above. |
| 41 template <typename T> |
| 42 T Unwrap(T o) { return o; } |
| 43 |
| 44 template <typename T> |
| 45 T* Unwrap(UnretainedWrapper<T> unretained) { return unretained.get(); } |
| 46 |
| 47 template <typename T> |
| 48 const T* Unwrap(ConstRefWrapper<T> const_ref) { return const_ref.get(); } |
| 49 |
| 50 // Optional Refcounting. |
| 51 |
| 52 template <bool ref, typename O> |
| 53 struct MaybeRefcount; |
| 54 |
| 55 template <typename O> |
| 56 struct MaybeRefcount<false, O> { |
| 57 static void AddRef(const O&) {} |
| 58 static void Release(const O&) {} |
| 59 }; |
| 60 |
| 61 template <typename O> |
| 62 struct MaybeRefcount<true, UnretainedWrapper<O> > { |
| 63 static void AddRef(const UnretainedWrapper<O>&) {} |
| 64 static void Release(const UnretainedWrapper<O>&) {} |
| 65 }; |
| 66 |
| 67 template <typename O> |
| 68 struct MaybeRefcount<true, ConstRefWrapper<O> > { |
| 69 static void AddRef(ConstRefWrapper<O> o) { o.get()->AddRef(); } |
| 70 static void Release(ConstRefWrapper<O> o) { o.get()->Release(); } |
| 71 }; |
| 72 |
| 73 template <typename O> |
| 74 struct MaybeRefcount<true, O* > { |
| 75 static void AddRef(O* o) { o->AddRef(); } |
| 76 static void Release(O* o) { o->Release(); } |
| 77 }; |
| 78 |
| 79 // The method by which a function is invoked is determined by 3 different |
| 80 // dimensions: |
| 81 // |
| 82 // 1) The type of function (normal, method, const-method) |
| 83 // 2) The arity of the function |
| 84 // 3) The number of bound parameters. |
| 85 // |
| 86 // The FunctionTraitsN classes unwrap the function signature type to |
| 87 // specialize based on the first two dimensions. The N in FunctionTraitsN |
| 88 // specifies the 3rd dimension. |
| 89 |
| 90 $var MAX_ARITY = 6 |
| 91 |
| 92 $range PREBOUND 1..MAX_ARITY |
| 93 $for PREBOUND [[ |
| 94 |
| 95 template <typename StorageType, typename Sig> |
| 96 struct FunctionTraits$(PREBOUND); |
| 97 |
| 98 $range ARITY 1..MAX_ARITY |
| 99 $for ARITY [[ |
| 100 |
| 101 $var UNBOUND = ARITY - PREBOUND |
| 102 $if UNBOUND >= 0 [[ |
| 103 |
| 104 $$ Variables for function traits generation. |
| 105 $range ARG 1..ARITY |
| 106 $range BOUND_ARG 1..PREBOUND |
| 107 $range UNBOUND_ARG (ARITY - UNBOUND + 1)..ARITY |
| 108 |
| 109 $$ Variables for method traits generation. We are always short one arity since |
| 110 $$ the first bound parameter is the object. |
| 111 $var M_ARITY = ARITY - 1 |
| 112 $range M_ARG 1..M_ARITY |
| 113 $range M_BOUND_ARG 2..PREBOUND |
| 114 $range M_UNBOUND_ARG (M_ARITY - UNBOUND + 1)..M_ARITY |
| 115 |
| 116 // Function: Arity $(ARITY) -> $(UNBOUND). |
| 117 template <typename StorageType, typename R, $for ARG , [[typename X$(ARG)]]> |
| 118 struct FunctionTraits$(PREBOUND)<StorageType, R(*)($for ARG , [[X$(ARG)]])> { |
| 119 static const bool kShouldRef = false; |
| 120 static R DoInvoke(InvokerStorageBase* base[[]] |
| 121 $if UNBOUND != 0 [[, ]] $for UNBOUND_ARG , [[X$(UNBOUND_ARG) x$(UNBOUND_ARG)]])
{ |
| 122 StorageType* invoker = static_cast<StorageType*>(base); |
| 123 return invoker->f_($for BOUND_ARG , [[Unwrap(invoker->p$(BOUND_ARG)_)]][[]] |
| 124 $if UNBOUND > 0 [[, ]] $for UNBOUND_ARG , [[x$(UNBOUND_ARG)]]); |
| 125 } |
| 126 }; |
| 127 |
| 128 // Method: Arity $(M_ARITY) -> $(UNBOUND). |
| 129 template <typename StorageType, typename R, typename T[[]] |
| 130 $if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]> |
| 131 struct FunctionTraits$(PREBOUND)<StorageType, R(T::*)($for M_ARG , [[X$(M_ARG)]]
)> { |
| 132 static const bool kShouldRef = true; |
| 133 static R DoInvoke(InvokerStorageBase* base[[]] |
| 134 $if UNBOUND > 0 [[, ]] $for M_UNBOUND_ARG , [[X$(M_UNBOUND_ARG) x$(M_UNBOUND_ARG
)]]) { |
| 135 StorageType* invoker = static_cast<StorageType*>(base); |
| 136 return (Unwrap(invoker->p1_)->*invoker->f_)([[]] |
| 137 $for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]] |
| 138 $if UNBOUND > 0 [[$if PREBOUND > 1 [[, ]]]][[]] |
| 139 $for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]); |
| 140 } |
| 141 }; |
| 142 |
| 143 // Const Method: Arity $(M_ARITY) -> $(UNBOUND). |
| 144 template <typename StorageType, typename R, typename T[[]] |
| 145 $if M_ARITY > 0[[, ]] $for M_ARG , [[typename X$(M_ARG)]]> |
| 146 struct FunctionTraits$(PREBOUND)<StorageType, R(T::*)($for M_ARG , [[X$(M_ARG)]]
) const> { |
| 147 static const bool kShouldRef = true; |
| 148 static R DoInvoke(InvokerStorageBase* base[[]] |
| 149 $if UNBOUND > 0 [[, ]] $for M_UNBOUND_ARG , [[X$(M_UNBOUND_ARG) x$(M_UNBOUND_ARG
)]]) { |
| 150 StorageType* invoker = static_cast<StorageType*>(base); |
| 151 return (Unwrap(invoker->p1_)->*invoker->f_)([[]] |
| 152 $for M_BOUND_ARG , [[Unwrap(invoker->p$(M_BOUND_ARG)_)]][[]] |
| 153 $if UNBOUND > 0 [[$if PREBOUND > 1 [[, ]]]][[]] |
| 154 $for M_UNBOUND_ARG , [[x$(M_UNBOUND_ARG)]]); |
| 155 } |
| 156 }; |
| 157 |
| 158 ]] $$ if UNBOUND |
| 159 ]] $$ for ARITY |
| 160 ]] $$ for PREBOUND |
| 161 |
| 162 |
| 163 // These are the actual storage classes for the invokers. |
| 164 |
| 165 $for PREBOUND [[ |
| 166 $range BOUND_ARG 1..PREBOUND |
| 167 |
| 168 template <typename Sig, $for BOUND_ARG , [[typename P$(BOUND_ARG)]]> |
| 169 class InvokerStorage$(PREBOUND) : public InvokerStorageBase { |
| 170 public: |
| 171 typedef InvokerStorage$(PREBOUND) StorageType; |
| 172 typedef FunctionTraits$(PREBOUND)<StorageType, Sig> FunctionTraits; |
| 173 |
| 174 InvokerStorage$(PREBOUND)(Sig f, [[]] |
| 175 $for BOUND_ARG , [[const P$(BOUND_ARG)& p$(BOUND_ARG)]]) |
| 176 : f_(f), $for BOUND_ARG , [[p$(BOUND_ARG)_(p$(BOUND_ARG))]] { |
| 177 MaybeRefcount<FunctionTraits::kShouldRef, P1>::AddRef(p1_); |
| 178 } |
| 179 |
| 180 virtual ~InvokerStorage$(PREBOUND)() { |
| 181 MaybeRefcount<FunctionTraits::kShouldRef, P1>::Release(p1_); |
| 182 } |
| 183 |
| 184 Sig f_; |
| 185 |
| 186 $for BOUND_ARG [[ |
| 187 P$(BOUND_ARG) p$(BOUND_ARG)_; |
| 188 |
| 189 ]] |
| 190 }; |
| 191 |
| 192 ]] $$ for PREBOUND |
| 193 |
| 194 } // namespace internal |
| 195 |
| 196 |
| 197 $for PREBOUND [[ |
| 198 $range BOUND_ARG 1..PREBOUND |
| 199 |
| 200 template <typename Sig, $for BOUND_ARG , [[typename P$(BOUND_ARG)]]> |
| 201 InvokerStorageHolder<internal::InvokerStorage$(PREBOUND)<Sig, [[]] |
| 202 $for BOUND_ARG , [[P$(BOUND_ARG)]]> > |
| 203 Prebind(Sig f, $for BOUND_ARG , [[const P$(BOUND_ARG)& p$(BOUND_ARG)]]) { |
| 204 return MakeInvokerStorageHolder( |
| 205 new internal::InvokerStorage$(PREBOUND)<Sig, [[]] |
| 206 $for BOUND_ARG , [[P$(BOUND_ARG)]]>( |
| 207 f, [[]] $for BOUND_ARG , [[p$(BOUND_ARG)]])); |
| 208 } |
| 209 |
| 210 ]] $$ for PREBOUND |
| 211 |
| 212 template <typename T> |
| 213 inline internal::UnretainedWrapper<T> Unretained(T* o) { |
| 214 return internal::UnretainedWrapper<T>(o); |
| 215 } |
| 216 |
| 217 template <typename T> |
| 218 inline internal::ConstRefWrapper<T> ConstRef(const T& o) { |
| 219 return internal::ConstRefWrapper<T>(o); |
| 220 } |
| 221 |
| 222 |
| 223 } // namespace base |
| 224 |
| 225 #endif // BASE_PREBIND_H_ |
OLD | NEW |