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