| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2011 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 // ... | 91 // ... |
| 92 // std::unique_ptr<Function<void()>> functor = bind(yourFunction, passed(Arg
ument())); | 92 // std::unique_ptr<Function<void()>> functor = bind(yourFunction, passed(Arg
ument())); |
| 93 // ... | 93 // ... |
| 94 // (*functor)(); | 94 // (*functor)(); |
| 95 // | 95 // |
| 96 // The underlying function must receive the argument wrapped by passed() by rval
ue reference or by value. | 96 // The underlying function must receive the argument wrapped by passed() by rval
ue reference or by value. |
| 97 // | 97 // |
| 98 // Obviously, if you create a functor this way, you shouldn't call the functor t
wice or more; after the second call, | 98 // Obviously, if you create a functor this way, you shouldn't call the functor t
wice or more; after the second call, |
| 99 // the passed argument may be invalid. | 99 // the passed argument may be invalid. |
| 100 | 100 |
| 101 enum FunctionThreadAffinity { |
| 102 CrossThreadAffinity, |
| 103 SameThreadAffinity |
| 104 }; |
| 105 |
| 101 template <typename T> | 106 template <typename T> |
| 102 class PassedWrapper final { | 107 class PassedWrapper final { |
| 103 public: | 108 public: |
| 104 explicit PassedWrapper(T&& scoper) : m_scoper(std::move(scoper)) { } | 109 explicit PassedWrapper(T&& scoper) : m_scoper(std::move(scoper)) { } |
| 105 PassedWrapper(PassedWrapper&& other) : m_scoper(std::move(other.m_scoper)) {
} | 110 PassedWrapper(PassedWrapper&& other) : m_scoper(std::move(other.m_scoper)) {
} |
| 106 T moveOut() { return std::move(m_scoper); } | 111 T moveOut() { return std::move(m_scoper); } |
| 107 | 112 |
| 108 private: | 113 private: |
| 109 T m_scoper; | 114 T m_scoper; |
| 110 }; | 115 }; |
| 111 | 116 |
| 112 template <typename T> | 117 template <typename T> |
| 113 PassedWrapper<T> passed(T&& value) | 118 PassedWrapper<T> passed(T&& value) |
| 114 { | 119 { |
| 115 static_assert(!std::is_reference<T>::value, | 120 static_assert(!std::is_reference<T>::value, |
| 116 "You must pass an rvalue to passed() so it can be moved. Add std::move()
if necessary."); | 121 "You must pass an rvalue to passed() so it can be moved. Add std::move()
if necessary."); |
| 117 static_assert(!std::is_const<T>::value, "|value| must not be const so it can
be moved."); | 122 static_assert(!std::is_const<T>::value, "|value| must not be const so it can
be moved."); |
| 118 return PassedWrapper<T>(std::move(value)); | 123 return PassedWrapper<T>(std::move(value)); |
| 119 } | 124 } |
| 120 | 125 |
| 126 template <typename T, FunctionThreadAffinity threadAffinity> |
| 127 class UnretainedWrapper final { |
| 128 public: |
| 129 explicit UnretainedWrapper(T* ptr) : m_ptr(ptr) { } |
| 130 T* value() const { return m_ptr; } |
| 131 |
| 132 private: |
| 133 T* m_ptr; |
| 134 }; |
| 135 |
| 136 template <typename T> |
| 137 UnretainedWrapper<T, SameThreadAffinity> unretained(T* value) |
| 138 { |
| 139 static_assert(!WTF::IsGarbageCollectedType<T>::value, "unretained() + GCed t
ype is forbidden"); |
| 140 return UnretainedWrapper<T, SameThreadAffinity>(value); |
| 141 } |
| 142 |
| 143 template <typename T> |
| 144 UnretainedWrapper<T, CrossThreadAffinity> crossThreadUnretained(T* value) |
| 145 { |
| 146 static_assert(!WTF::IsGarbageCollectedType<T>::value, "crossThreadUnretained
() + GCed type is forbidden"); |
| 147 return UnretainedWrapper<T, CrossThreadAffinity>(value); |
| 148 } |
| 149 |
| 121 // A FunctionWrapper is a class template that can wrap a function pointer or a m
ember function pointer and | 150 // A FunctionWrapper is a class template that can wrap a function pointer or a m
ember function pointer and |
| 122 // provide a unified interface for calling that function. | 151 // provide a unified interface for calling that function. |
| 123 template <typename> | 152 template <typename> |
| 124 class FunctionWrapper; | 153 class FunctionWrapper; |
| 125 | 154 |
| 126 // Bound static functions: | 155 // Bound static functions: |
| 127 template <typename R, typename... Parameters> | 156 template <typename R, typename... Parameters> |
| 128 class FunctionWrapper<R(*)(Parameters...)> { | 157 class FunctionWrapper<R(*)(Parameters...)> { |
| 129 DISALLOW_NEW(); | 158 DISALLOW_NEW(); |
| 130 public: | 159 public: |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 }; | 253 }; |
| 225 | 254 |
| 226 template <typename T> | 255 template <typename T> |
| 227 struct ParamStorageTraits<PassedWrapper<T>> { | 256 struct ParamStorageTraits<PassedWrapper<T>> { |
| 228 typedef PassedWrapper<T> StorageType; | 257 typedef PassedWrapper<T> StorageType; |
| 229 | 258 |
| 230 static StorageType wrap(PassedWrapper<T>&& value) { return std::move(value);
} | 259 static StorageType wrap(PassedWrapper<T>&& value) { return std::move(value);
} |
| 231 static T unwrap(StorageType& value) { return value.moveOut(); } | 260 static T unwrap(StorageType& value) { return value.moveOut(); } |
| 232 }; | 261 }; |
| 233 | 262 |
| 263 template <typename T, FunctionThreadAffinity threadAffinity> |
| 264 struct ParamStorageTraits<UnretainedWrapper<T, threadAffinity>> { |
| 265 typedef UnretainedWrapper<T, threadAffinity> StorageType; |
| 266 |
| 267 static StorageType wrap(const UnretainedWrapper<T, threadAffinity>& value) {
return value; } |
| 268 static T* unwrap(const StorageType& value) { return value.value(); } |
| 269 }; |
| 270 |
| 234 template<typename T, bool isGarbageCollected> struct PointerParamStorageTraits; | 271 template<typename T, bool isGarbageCollected> struct PointerParamStorageTraits; |
| 235 | 272 |
| 236 template<typename T> | 273 template<typename T> |
| 237 struct PointerParamStorageTraits<T*, false> { | 274 struct PointerParamStorageTraits<T*, false> { |
| 238 STATIC_ONLY(PointerParamStorageTraits); | 275 STATIC_ONLY(PointerParamStorageTraits); |
| 239 using StorageType = T*; | 276 using StorageType = T*; |
| 240 | 277 |
| 241 static StorageType wrap(T* value) { return value; } | 278 static StorageType wrap(T* value) { return value; } |
| 242 static T* unwrap(const StorageType& value) { return value; } | 279 static T* unwrap(const StorageType& value) { return value; } |
| 243 }; | 280 }; |
| 244 | 281 |
| 245 template<typename T> | 282 template<typename T> |
| 246 struct PointerParamStorageTraits<T*, true> { | 283 struct PointerParamStorageTraits<T*, true> { |
| 247 STATIC_ONLY(PointerParamStorageTraits); | 284 STATIC_ONLY(PointerParamStorageTraits); |
| 248 using StorageType = blink::CrossThreadPersistent<T>; | 285 using StorageType = blink::CrossThreadPersistent<T>; |
| 249 | 286 |
| 250 static StorageType wrap(T* value) { return value; } | 287 static StorageType wrap(T* value) { return value; } |
| 251 static T* unwrap(const StorageType& value) { return value.get(); } | 288 static T* unwrap(const StorageType& value) { return value.get(); } |
| 252 }; | 289 }; |
| 253 | 290 |
| 254 template<typename T> | 291 template<typename T> |
| 255 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, IsGarbageCo
llectedType<T>::value> { | 292 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, IsGarbageCo
llectedType<T>::value> { |
| 256 STATIC_ONLY(ParamStorageTraits); | 293 STATIC_ONLY(ParamStorageTraits); |
| 257 }; | 294 }; |
| 258 | 295 |
| 259 enum FunctionThreadAffinity { | |
| 260 CrossThreadAffinity, | |
| 261 SameThreadAffinity | |
| 262 }; | |
| 263 | |
| 264 template<typename, FunctionThreadAffinity threadAffinity = SameThreadAffinity> | 296 template<typename, FunctionThreadAffinity threadAffinity = SameThreadAffinity> |
| 265 class Function; | 297 class Function; |
| 266 | 298 |
| 267 template<FunctionThreadAffinity threadAffinity, typename R, typename... Args> | 299 template<FunctionThreadAffinity threadAffinity, typename R, typename... Args> |
| 268 class Function<R(Args...), threadAffinity> { | 300 class Function<R(Args...), threadAffinity> { |
| 269 USING_FAST_MALLOC(Function); | 301 USING_FAST_MALLOC(Function); |
| 270 WTF_MAKE_NONCOPYABLE(Function); | 302 WTF_MAKE_NONCOPYABLE(Function); |
| 271 public: | 303 public: |
| 272 virtual ~Function() { } | 304 virtual ~Function() { } |
| 273 virtual R operator()(Args... args) = 0; | 305 virtual R operator()(Args... args) = 0; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 std::unique_ptr<Function<base::MakeUnboundRunType<FunctionType, BoundParameters.
..>, SameThreadAffinity>> bind(FunctionType function, BoundParameters&&... bound
Parameters) | 398 std::unique_ptr<Function<base::MakeUnboundRunType<FunctionType, BoundParameters.
..>, SameThreadAffinity>> bind(FunctionType function, BoundParameters&&... bound
Parameters) |
| 367 { | 399 { |
| 368 return bindInternal<SameThreadAffinity>(function, std::forward<BoundParamete
rs>(boundParameters)...); | 400 return bindInternal<SameThreadAffinity>(function, std::forward<BoundParamete
rs>(boundParameters)...); |
| 369 } | 401 } |
| 370 | 402 |
| 371 typedef Function<void(), SameThreadAffinity> SameThreadClosure; | 403 typedef Function<void(), SameThreadAffinity> SameThreadClosure; |
| 372 typedef Function<void(), CrossThreadAffinity> CrossThreadClosure; | 404 typedef Function<void(), CrossThreadAffinity> CrossThreadClosure; |
| 373 | 405 |
| 374 } // namespace WTF | 406 } // namespace WTF |
| 375 | 407 |
| 408 using WTF::bind; |
| 409 |
| 376 using WTF::passed; | 410 using WTF::passed; |
| 411 using WTF::unretained; |
| 412 using WTF::crossThreadUnretained; |
| 413 |
| 377 using WTF::Function; | 414 using WTF::Function; |
| 378 using WTF::bind; | |
| 379 using WTF::SameThreadClosure; | 415 using WTF::SameThreadClosure; |
| 380 using WTF::CrossThreadClosure; | 416 using WTF::CrossThreadClosure; |
| 381 | 417 |
| 382 #endif // WTF_Functional_h | 418 #endif // WTF_Functional_h |
| OLD | NEW |