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 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
230 }; | 259 }; |
231 | 260 |
232 template <typename T> | 261 template <typename T> |
233 struct ParamStorageTraits<PassedWrapper<T>> { | 262 struct ParamStorageTraits<PassedWrapper<T>> { |
234 typedef PassedWrapper<T> StorageType; | 263 typedef PassedWrapper<T> StorageType; |
235 | 264 |
236 static StorageType wrap(PassedWrapper<T>&& value) { return std::move(value); } | 265 static StorageType wrap(PassedWrapper<T>&& value) { return std::move(value); } |
237 static T unwrap(StorageType& value) { return value.moveOut(); } | 266 static T unwrap(StorageType& value) { return value.moveOut(); } |
238 }; | 267 }; |
239 | 268 |
269 template <typename T, FunctionThreadAffinity threadAffinity> | |
270 struct ParamStorageTraits<UnretainedWrapper<T, threadAffinity>> { | |
271 typedef UnretainedWrapper<T, threadAffinity> StorageType; | |
272 | |
273 static StorageType wrap(const UnretainedWrapper<T, threadAffinity>& value) { return value; } | |
274 static T* unwrap(const StorageType& value) { return value.value(); } | |
275 }; | |
276 | |
240 template<typename T, bool isGarbageCollected> struct PointerParamStorageTraits; | 277 template<typename T, bool isGarbageCollected> struct PointerParamStorageTraits; |
241 | 278 |
242 template<typename T> | 279 template<typename T> |
243 struct PointerParamStorageTraits<T*, false> { | 280 struct PointerParamStorageTraits<T*, false> { |
244 STATIC_ONLY(PointerParamStorageTraits); | 281 STATIC_ONLY(PointerParamStorageTraits); |
245 using StorageType = T*; | 282 using StorageType = T*; |
246 | 283 |
247 static StorageType wrap(T* value) { return value; } | 284 static StorageType wrap(T* value) { return value; } |
248 static T* unwrap(const StorageType& value) { return value; } | 285 static T* unwrap(const StorageType& value) { return value; } |
249 }; | 286 }; |
250 | 287 |
251 template<typename T> | 288 template<typename T> |
252 struct PointerParamStorageTraits<T*, true> { | 289 struct PointerParamStorageTraits<T*, true> { |
253 STATIC_ONLY(PointerParamStorageTraits); | 290 STATIC_ONLY(PointerParamStorageTraits); |
254 using StorageType = blink::CrossThreadPersistent<T>; | 291 using StorageType = blink::CrossThreadPersistent<T>; |
255 | 292 |
256 static StorageType wrap(T* value) { return value; } | 293 static StorageType wrap(T* value) { return value; } |
257 static T* unwrap(const StorageType& value) { return value.get(); } | 294 static T* unwrap(const StorageType& value) { return value.get(); } |
258 }; | 295 }; |
259 | 296 |
260 template<typename T> | 297 template<typename T> |
261 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, IsGarbageCo llectedType<T>::value> { | 298 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, IsGarbageCo llectedType<T>::value> { |
262 STATIC_ONLY(ParamStorageTraits); | 299 STATIC_ONLY(ParamStorageTraits); |
263 }; | 300 }; |
264 | 301 |
265 enum FunctionThreadAffinity { | |
266 CrossThreadAffinity, | |
267 SameThreadAffinity | |
268 }; | |
269 | |
270 template<typename, FunctionThreadAffinity threadAffinity = SameThreadAffinity> | 302 template<typename, FunctionThreadAffinity threadAffinity = SameThreadAffinity> |
271 class Function; | 303 class Function; |
272 | 304 |
273 template<FunctionThreadAffinity threadAffinity, typename R, typename... Args> | 305 template<FunctionThreadAffinity threadAffinity, typename R, typename... Args> |
274 class Function<R(Args...), threadAffinity> { | 306 class Function<R(Args...), threadAffinity> { |
275 USING_FAST_MALLOC(Function); | 307 USING_FAST_MALLOC(Function); |
276 WTF_MAKE_NONCOPYABLE(Function); | 308 WTF_MAKE_NONCOPYABLE(Function); |
277 public: | 309 public: |
278 virtual ~Function() { } | 310 virtual ~Function() { } |
279 virtual R operator()(Args... args) = 0; | 311 virtual R operator()(Args... args) = 0; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
370 { | 402 { |
371 return bindInternal<SameThreadAffinity, UnboundParameters...>(function, std: :forward<BoundParameters>(boundParameters)...); | 403 return bindInternal<SameThreadAffinity, UnboundParameters...>(function, std: :forward<BoundParameters>(boundParameters)...); |
372 } | 404 } |
373 | 405 |
374 typedef Function<void(), SameThreadAffinity> SameThreadClosure; | 406 typedef Function<void(), SameThreadAffinity> SameThreadClosure; |
375 typedef Function<void(), CrossThreadAffinity> CrossThreadClosure; | 407 typedef Function<void(), CrossThreadAffinity> CrossThreadClosure; |
376 | 408 |
377 } // namespace WTF | 409 } // namespace WTF |
378 | 410 |
379 using WTF::passed; | 411 using WTF::passed; |
412 using WTF::unretained; | |
413 using WTF::crossThreadUnretained; | |
380 using WTF::Function; | 414 using WTF::Function; |
381 using WTF::bind; | 415 using WTF::bind; |
382 using WTF::SameThreadClosure; | 416 using WTF::SameThreadClosure; |
383 using WTF::CrossThreadClosure; | 417 using WTF::CrossThreadClosure; |
tzik
2016/06/09 09:38:29
Could you sort them?
hiroshige
2016/06/14 12:01:04
I prefer grouping by functionality (unless this li
| |
384 | 418 |
385 #endif // WTF_Functional_h | 419 #endif // WTF_Functional_h |
OLD | NEW |