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 |