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