Chromium Code Reviews| 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 |