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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
109 enum FunctionThreadAffinity { | 109 enum FunctionThreadAffinity { |
110 CrossThreadAffinity, | 110 CrossThreadAffinity, |
111 SameThreadAffinity | 111 SameThreadAffinity |
112 }; | 112 }; |
113 | 113 |
114 template <typename T> | 114 template <typename T> |
115 class PassedWrapper final { | 115 class PassedWrapper final { |
116 public: | 116 public: |
117 explicit PassedWrapper(T&& scoper) : m_scoper(std::move(scoper)) { } | 117 explicit PassedWrapper(T&& scoper) : m_scoper(std::move(scoper)) { } |
118 PassedWrapper(PassedWrapper&& other) : m_scoper(std::move(other.m_scoper)) {
} | 118 PassedWrapper(PassedWrapper&& other) : m_scoper(std::move(other.m_scoper)) {
} |
119 T moveOut() { return std::move(m_scoper); } | 119 T moveOut() const { return std::move(m_scoper); } |
120 | 120 |
121 private: | 121 private: |
122 T m_scoper; | 122 mutable T m_scoper; |
123 }; | 123 }; |
124 | 124 |
125 template <typename T> | 125 template <typename T> |
126 PassedWrapper<T> passed(T&& value) | 126 PassedWrapper<T> passed(T&& value) |
127 { | 127 { |
128 static_assert(!std::is_reference<T>::value, | 128 static_assert(!std::is_reference<T>::value, |
129 "You must pass an rvalue to passed() so it can be moved. Add std::move()
if necessary."); | 129 "You must pass an rvalue to passed() so it can be moved. Add std::move()
if necessary."); |
130 static_assert(!std::is_const<T>::value, "|value| must not be const so it can
be moved."); | 130 static_assert(!std::is_const<T>::value, "|value| must not be const so it can
be moved."); |
131 return PassedWrapper<T>(std::move(value)); | 131 return PassedWrapper<T>(std::move(value)); |
132 } | 132 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 private: | 212 private: |
213 R(C::*m_function)(Parameters...); | 213 R(C::*m_function)(Parameters...); |
214 }; | 214 }; |
215 | 215 |
216 template <typename T> | 216 template <typename T> |
217 struct ParamStorageTraits { | 217 struct ParamStorageTraits { |
218 typedef T StorageType; | 218 typedef T StorageType; |
219 | 219 |
220 static_assert(!std::is_pointer<T>::value, "Raw pointers are not allowed to b
ind into WTF::Function. Wrap it with either wrapPersistent, wrapWeakPersistent,
wrapCrossThreadPersistent, wrapCrossThreadWeakPersistent, RefPtr or unretained."
); | 220 static_assert(!std::is_pointer<T>::value, "Raw pointers are not allowed to b
ind into WTF::Function. Wrap it with either wrapPersistent, wrapWeakPersistent,
wrapCrossThreadPersistent, wrapCrossThreadWeakPersistent, RefPtr or unretained."
); |
221 static_assert(!IsSubclassOfTemplate<T, blink::Member>::value && !IsSubclassO
fTemplate<T, blink::WeakMember>::value, "Member and WeakMember are not allowed t
o bind into WTF::Function. Wrap it with either wrapPersistent, wrapWeakPersisten
t, wrapCrossThreadPersistent or wrapCrossThreadWeakPersistent."); | 221 static_assert(!IsSubclassOfTemplate<T, blink::Member>::value && !IsSubclassO
fTemplate<T, blink::WeakMember>::value, "Member and WeakMember are not allowed t
o bind into WTF::Function. Wrap it with either wrapPersistent, wrapWeakPersisten
t, wrapCrossThreadPersistent or wrapCrossThreadWeakPersistent."); |
222 | |
223 static StorageType wrap(const T& value) { return value; } // Copy. | |
224 static StorageType wrap(T&& value) { return std::move(value); } | |
225 | |
226 // Don't move out, because the functor may be called multiple times. | |
227 static const T& unwrap(const StorageType& value) { return value; } | |
228 }; | 222 }; |
229 | 223 |
230 template <typename T> | 224 template <typename T> |
231 struct ParamStorageTraits<PassRefPtr<T>> { | 225 struct ParamStorageTraits<PassRefPtr<T>> { |
232 typedef RefPtr<T> StorageType; | 226 typedef RefPtr<T> StorageType; |
233 | |
234 static StorageType wrap(PassRefPtr<T> value) { return value; } | |
235 static T* unwrap(const StorageType& value) { return value.get(); } | |
236 }; | 227 }; |
237 | 228 |
238 template <typename T> | 229 template <typename T> |
239 struct ParamStorageTraits<RefPtr<T>> { | 230 struct ParamStorageTraits<RefPtr<T>> { |
240 typedef RefPtr<T> StorageType; | 231 typedef RefPtr<T> StorageType; |
| 232 }; |
241 | 233 |
242 static StorageType wrap(RefPtr<T> value) { return value.release(); } | 234 template <typename T> |
243 static T* unwrap(const StorageType& value) { return value.get(); } | 235 T* Unwrap(const RefPtr<T>& wrapped) |
244 }; | 236 { |
| 237 return wrapped.get(); |
| 238 } |
245 | 239 |
246 template <typename> class RetainPtr; | 240 template <typename> class RetainPtr; |
247 | 241 |
248 template <typename T> | 242 template <typename T> |
249 struct ParamStorageTraits<RetainPtr<T>> { | 243 struct ParamStorageTraits<RetainPtr<T>> { |
250 typedef RetainPtr<T> StorageType; | 244 typedef RetainPtr<T> StorageType; |
251 | |
252 static StorageType wrap(const RetainPtr<T>& value) { return value; } | |
253 static typename RetainPtr<T>::PtrType unwrap(const StorageType& value) { ret
urn value.get(); } | |
254 }; | 245 }; |
255 | 246 |
256 template <typename T> | 247 template <typename T> |
257 struct ParamStorageTraits<PassedWrapper<T>> { | 248 struct ParamStorageTraits<PassedWrapper<T>> { |
258 typedef PassedWrapper<T> StorageType; | 249 typedef PassedWrapper<T> StorageType; |
| 250 }; |
259 | 251 |
260 static StorageType wrap(PassedWrapper<T>&& value) { return std::move(value);
} | 252 template <typename T> |
261 static T unwrap(StorageType& value) { return value.moveOut(); } | 253 T Unwrap(const PassedWrapper<T>& wrapped) |
262 }; | 254 { |
| 255 return wrapped.moveOut(); |
| 256 } |
263 | 257 |
264 template <typename T, FunctionThreadAffinity threadAffinity> | 258 template <typename T, FunctionThreadAffinity threadAffinity> |
265 struct ParamStorageTraits<UnretainedWrapper<T, threadAffinity>> { | 259 struct ParamStorageTraits<UnretainedWrapper<T, threadAffinity>> { |
266 typedef UnretainedWrapper<T, threadAffinity> StorageType; | 260 typedef UnretainedWrapper<T, threadAffinity> StorageType; |
| 261 }; |
267 | 262 |
268 static StorageType wrap(const UnretainedWrapper<T, threadAffinity>& value) {
return value; } | 263 template <typename T, FunctionThreadAffinity threadAffinity> |
269 static T* unwrap(const StorageType& value) { return value.value(); } | 264 T* Unwrap(const UnretainedWrapper<T, threadAffinity>& wrapped) |
270 }; | 265 { |
| 266 return wrapped.value(); |
| 267 } |
| 268 |
271 | 269 |
272 template<typename, FunctionThreadAffinity threadAffinity = SameThreadAffinity> | 270 template<typename, FunctionThreadAffinity threadAffinity = SameThreadAffinity> |
273 class Function; | 271 class Function; |
274 | 272 |
275 template<FunctionThreadAffinity threadAffinity, typename R, typename... Args> | 273 template<FunctionThreadAffinity threadAffinity, typename R, typename... Args> |
276 class Function<R(Args...), threadAffinity> { | 274 class Function<R(Args...), threadAffinity> { |
277 USING_FAST_MALLOC(Function); | 275 USING_FAST_MALLOC(Function); |
278 WTF_MAKE_NONCOPYABLE(Function); | 276 WTF_MAKE_NONCOPYABLE(Function); |
279 public: | 277 public: |
280 virtual ~Function() { } | 278 virtual ~Function() { } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 // We would like to use StorageTraits<UnboundParameters>... with StorageTrai
ts defined as below in order to obtain | 323 // We would like to use StorageTraits<UnboundParameters>... with StorageTrai
ts defined as below in order to obtain |
326 // storage traits of UnboundParameters, but unfortunately MSVC can't handle
template using declarations correctly. | 324 // storage traits of UnboundParameters, but unfortunately MSVC can't handle
template using declarations correctly. |
327 // So, sadly, we have write down the full type signature in all places where
storage traits are needed. | 325 // So, sadly, we have write down the full type signature in all places where
storage traits are needed. |
328 // | 326 // |
329 // template <typename T> | 327 // template <typename T> |
330 // using StorageTraits = ParamStorageTraits<typename std::decay<T>::type>; | 328 // using StorageTraits = ParamStorageTraits<typename std::decay<T>::type>; |
331 | 329 |
332 // Note that BoundParameters can be const T&, T&& or a mix of these. | 330 // Note that BoundParameters can be const T&, T&& or a mix of these. |
333 explicit PartBoundFunctionImpl(FunctionWrapper functionWrapper, BoundParamet
ers... bound) | 331 explicit PartBoundFunctionImpl(FunctionWrapper functionWrapper, BoundParamet
ers... bound) |
334 : m_functionWrapper(functionWrapper) | 332 : m_functionWrapper(functionWrapper) |
335 , m_bound(ParamStorageTraits<typename std::decay<BoundParameters>::type>
::wrap(std::forward<BoundParameters>(bound))...) | 333 , m_bound(std::forward<BoundParameters>(bound)...) |
336 { | 334 { |
337 } | 335 } |
338 | 336 |
339 ResultType operator()(UnboundParameters... unbound) override | 337 ResultType operator()(UnboundParameters... unbound) override |
340 { | 338 { |
341 // What we really want to do is to call m_functionWrapper(m_bound..., un
bound...), but to do that we need to | 339 // What we really want to do is to call m_functionWrapper(m_bound..., un
bound...), but to do that we need to |
342 // pass a list of indices to a worker function template. | 340 // pass a list of indices to a worker function template. |
343 return callInternal(base::MakeIndexSequence<sizeof...(BoundParameters)>(
), std::forward<UnboundParameters>(unbound)...); | 341 return callInternal(base::MakeIndexSequence<sizeof...(BoundParameters)>(
), std::forward<UnboundParameters>(unbound)...); |
344 } | 342 } |
345 | 343 |
346 private: | 344 private: |
347 template <std::size_t... boundIndices, typename... IncomingUnboundParameters
> | 345 template <std::size_t... boundIndices, typename... IncomingUnboundParameters
> |
348 ResultType callInternal(const base::IndexSequence<boundIndices...>&, Incomin
gUnboundParameters&&... unbound) | 346 ResultType callInternal(const base::IndexSequence<boundIndices...>&, Incomin
gUnboundParameters&&... unbound) |
349 { | 347 { |
350 this->checkThread(); | 348 this->checkThread(); |
351 // Get each element in m_bound, unwrap them, and call the function with
the desired arguments. | 349 // Get each element in m_bound, unwrap them, and call the function with
the desired arguments. |
352 return m_functionWrapper(ParamStorageTraits<typename std::decay<BoundPar
ameters>::type>::unwrap(std::get<boundIndices>(m_bound))..., std::forward<Incomi
ngUnboundParameters>(unbound)...); | 350 using base::internal::Unwrap; |
| 351 return m_functionWrapper(Unwrap(std::get<boundIndices>(m_bound))..., std
::forward<IncomingUnboundParameters>(unbound)...); |
353 } | 352 } |
354 | 353 |
355 FunctionWrapper m_functionWrapper; | 354 FunctionWrapper m_functionWrapper; |
356 std::tuple<typename ParamStorageTraits<typename std::decay<BoundParameters>:
:type>::StorageType...> m_bound; | 355 std::tuple<typename ParamStorageTraits<typename std::decay<BoundParameters>:
:type>::StorageType...> m_bound; |
357 }; | 356 }; |
358 | 357 |
359 template <FunctionThreadAffinity threadAffinity, typename FunctionType, typename
... BoundParameters> | 358 template <FunctionThreadAffinity threadAffinity, typename FunctionType, typename
... BoundParameters> |
360 std::unique_ptr<Function<base::MakeUnboundRunType<FunctionType, BoundParameters.
..>, threadAffinity>> bindInternal(FunctionType function, BoundParameters&&... b
oundParameters) | 359 std::unique_ptr<Function<base::MakeUnboundRunType<FunctionType, BoundParameters.
..>, threadAffinity>> bindInternal(FunctionType function, BoundParameters&&... b
oundParameters) |
361 { | 360 { |
362 // Bound parameters' types are wrapped with std::tuple so we can pass two te
mplate parameter packs (bound | 361 // Bound parameters' types are wrapped with std::tuple so we can pass two te
mplate parameter packs (bound |
(...skipping 22 matching lines...) Expand all Loading... |
385 | 384 |
386 using WTF::passed; | 385 using WTF::passed; |
387 using WTF::unretained; | 386 using WTF::unretained; |
388 using WTF::crossThreadUnretained; | 387 using WTF::crossThreadUnretained; |
389 | 388 |
390 using WTF::Function; | 389 using WTF::Function; |
391 using WTF::SameThreadClosure; | 390 using WTF::SameThreadClosure; |
392 using WTF::CrossThreadClosure; | 391 using WTF::CrossThreadClosure; |
393 | 392 |
394 #endif // WTF_Functional_h | 393 #endif // WTF_Functional_h |
OLD | NEW |