OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This defines a set of argument wrappers and related factory methods that | 5 // This defines a set of argument wrappers and related factory methods that |
6 // can be used specify the refcounting and reference semantics of arguments | 6 // can be used specify the refcounting and reference semantics of arguments |
7 // that are bound by the Bind() function in base/bind.h. | 7 // that are bound by the Bind() function in base/bind.h. |
8 // | 8 // |
9 // The public functions are base::Unretained() and base::ConstRef(). | 9 // The public functions are base::Unretained() and base::ConstRef(). |
10 // Unretained() allows Bind() to bind a non-refcounted class. | 10 // Unretained() allows Bind() to bind a non-refcounted class. |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 template <bool IsClasstype, typename T> | 154 template <bool IsClasstype, typename T> |
155 struct UnsafeBindtoRefCountedArgHelper : false_type { | 155 struct UnsafeBindtoRefCountedArgHelper : false_type { |
156 }; | 156 }; |
157 | 157 |
158 template <typename T> | 158 template <typename T> |
159 struct UnsafeBindtoRefCountedArgHelper<true, T> | 159 struct UnsafeBindtoRefCountedArgHelper<true, T> |
160 : integral_constant<bool, SupportsAddRefAndRelease<T>::value> { | 160 : integral_constant<bool, SupportsAddRefAndRelease<T>::value> { |
161 }; | 161 }; |
162 | 162 |
163 template <typename T> | 163 template <typename T> |
164 struct UnsafeBindtoRefCountedArg | 164 struct UnsafeBindtoRefCountedArg : false_type { |
| 165 }; |
| 166 |
| 167 template <typename T> |
| 168 struct UnsafeBindtoRefCountedArg<T*> |
165 : UnsafeBindtoRefCountedArgHelper<is_class<T>::value, T> { | 169 : UnsafeBindtoRefCountedArgHelper<is_class<T>::value, T> { |
166 }; | 170 }; |
167 | 171 |
168 | 172 |
169 template <typename T> | 173 template <typename T> |
170 class UnretainedWrapper { | 174 class UnretainedWrapper { |
171 public: | 175 public: |
172 explicit UnretainedWrapper(T* o) : obj_(o) {} | 176 explicit UnretainedWrapper(T* o) : obj_(o) {} |
173 T* get() { return obj_; } | 177 T* get() { return obj_; } |
174 private: | 178 private: |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 static void AddRef(T* o) { o->AddRef(); } | 230 static void AddRef(T* o) { o->AddRef(); } |
227 static void Release(T* o) { o->Release(); } | 231 static void Release(T* o) { o->Release(); } |
228 }; | 232 }; |
229 | 233 |
230 template <typename T> | 234 template <typename T> |
231 struct MaybeRefcount<base::true_type, const T*> { | 235 struct MaybeRefcount<base::true_type, const T*> { |
232 static void AddRef(const T* o) { o->AddRef(); } | 236 static void AddRef(const T* o) { o->AddRef(); } |
233 static void Release(const T* o) { o->Release(); } | 237 static void Release(const T* o) { o->Release(); } |
234 }; | 238 }; |
235 | 239 |
236 | |
237 // This is a typetraits object that's used to convert an argument type into a | |
238 // type suitable for storage. In particular, it strips off references, and | |
239 // converts arrays to pointers. | |
240 // | |
241 // This array type becomes an issue because we are passing bound parameters by | |
242 // const reference. In this case, we end up passing an actual array type in the | |
243 // initializer list which C++ does not allow. This will break passing of | |
244 // C-string literals. | |
245 template <typename T> | |
246 struct BindType { | |
247 typedef T StorageType; | |
248 }; | |
249 | |
250 // This should almost be impossible to trigger unless someone manually | |
251 // specifies type of the bind parameters. However, in case they do, | |
252 // this will guard against us accidentally storing a reference parameter. | |
253 template <typename T> | |
254 struct BindType<T&> { | |
255 typedef T StorageType; | |
256 }; | |
257 | |
258 // Note that for array types, we implicitly add a const in the conversion. This | |
259 // means that it is not possible to bind array arguments to functions that take | |
260 // a non-const pointer. Trying to specialize the template based on a "const | |
261 // T[n]" does not seem to match correctly, so we are stuck with this | |
262 // restriction. | |
263 template <typename T, size_t n> | |
264 struct BindType<T[n]> { | |
265 typedef const T* StorageType; | |
266 }; | |
267 | |
268 template <typename T> | |
269 struct BindType<T[]> { | |
270 typedef const T* StorageType; | |
271 }; | |
272 | |
273 } // namespace internal | 240 } // namespace internal |
274 | 241 |
275 template <typename T> | 242 template <typename T> |
276 inline internal::UnretainedWrapper<T> Unretained(T* o) { | 243 inline internal::UnretainedWrapper<T> Unretained(T* o) { |
277 return internal::UnretainedWrapper<T>(o); | 244 return internal::UnretainedWrapper<T>(o); |
278 } | 245 } |
279 | 246 |
280 template <typename T> | 247 template <typename T> |
281 inline internal::ConstRefWrapper<T> ConstRef(const T& o) { | 248 inline internal::ConstRefWrapper<T> ConstRef(const T& o) { |
282 return internal::ConstRefWrapper<T>(o); | 249 return internal::ConstRefWrapper<T>(o); |
283 } | 250 } |
284 | 251 |
285 } // namespace base | 252 } // namespace base |
286 | 253 |
287 #endif // BASE_BIND_HELPERS_H_ | 254 #endif // BASE_BIND_HELPERS_H_ |
OLD | NEW |