| 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 |