| 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 | 53 |
| 54 // WTF::bind() and move semantics | 54 // WTF::bind() and move semantics |
| 55 // ============================== | 55 // ============================== |
| 56 // | 56 // |
| 57 // For unbound parameters (arguments supplied later on the bound functor directl
y), there are two ways to pass movable | 57 // For unbound parameters (arguments supplied later on the bound functor directl
y), there are two ways to pass movable |
| 58 // arguments: | 58 // arguments: |
| 59 // | 59 // |
| 60 // 1) Pass by rvalue reference. | 60 // 1) Pass by rvalue reference. |
| 61 // | 61 // |
| 62 // void yourFunction(Argument&& argument) { ... } | 62 // void yourFunction(Argument&& argument) { ... } |
| 63 // OwnPtr<Function<void(Argument&&)>> functor = bind<Argument&&>(your
Function); | 63 // std::unique_ptr<Function<void(Argument&&)>> functor = bind<Argumen
t&&>(yourFunction); |
| 64 // | 64 // |
| 65 // 2) Pass by value. | 65 // 2) Pass by value. |
| 66 // | 66 // |
| 67 // void yourFunction(Argument argument) { ... } | 67 // void yourFunction(Argument argument) { ... } |
| 68 // OwnPtr<Function<void(Argument)>> functor = bind<Argument>(yourFunc
tion); | 68 // std::unique_ptr<Function<void(Argument)>> functor = bind<Argument>
(yourFunction); |
| 69 // | 69 // |
| 70 // Note that with the latter there will be *two* move constructions happening, b
ecause there needs to be at least one | 70 // Note that with the latter there will be *two* move constructions happening, b
ecause there needs to be at least one |
| 71 // intermediary function call taking an argument of type "Argument" (i.e. passed
by value). The former case does not | 71 // intermediary function call taking an argument of type "Argument" (i.e. passed
by value). The former case does not |
| 72 // require any move constructions inbetween. | 72 // require any move constructions inbetween. |
| 73 // | 73 // |
| 74 // For bound parameters (arguments supplied on the creation of a functor), you c
an move your argument into the internal | 74 // For bound parameters (arguments supplied on the creation of a functor), you c
an move your argument into the internal |
| 75 // storage of the functor by supplying an rvalue to that argument (this is done
in wrap() of ParamStorageTraits). | 75 // storage of the functor by supplying an rvalue to that argument (this is done
in wrap() of ParamStorageTraits). |
| 76 // However, to make the functor be able to get called multiple times, the stored
object does not get moved out | 76 // However, to make the functor be able to get called multiple times, the stored
object does not get moved out |
| 77 // automatically when the underlying function is actually invoked. If you want t
o make an argument "auto-passed", | 77 // automatically when the underlying function is actually invoked. If you want t
o make an argument "auto-passed", |
| 78 // you can do so by wrapping your bound argument with passed() function, as show
n below: | 78 // you can do so by wrapping your bound argument with passed() function, as show
n below: |
| 79 // | 79 // |
| 80 // void yourFunction(Argument argument) | 80 // void yourFunction(Argument argument) |
| 81 // { | 81 // { |
| 82 // // |argument| is passed from the internal storage of functor. | 82 // // |argument| is passed from the internal storage of functor. |
| 83 // ... | 83 // ... |
| 84 // } | 84 // } |
| 85 // | 85 // |
| 86 // ... | 86 // ... |
| 87 // OwnPtr<Function<void()>> functor = bind(yourFunction, passed(Argument()))
; | 87 // std::unique_ptr<Function<void()>> functor = bind(yourFunction, passed(Arg
ument())); |
| 88 // ... | 88 // ... |
| 89 // (*functor)(); | 89 // (*functor)(); |
| 90 // | 90 // |
| 91 // The underlying function must receive the argument wrapped by passed() by rval
ue reference or by value. | 91 // The underlying function must receive the argument wrapped by passed() by rval
ue reference or by value. |
| 92 // | 92 // |
| 93 // Obviously, if you create a functor this way, you shouldn't call the functor t
wice or more; after the second call, | 93 // Obviously, if you create a functor this way, you shouldn't call the functor t
wice or more; after the second call, |
| 94 // the passed argument may be invalid. | 94 // the passed argument may be invalid. |
| 95 | 95 |
| 96 template <typename T> | 96 template <typename T> |
| 97 class PassedWrapper final { | 97 class PassedWrapper final { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 return (c->*m_function)(std::forward<IncomingParameters>(parameters)...)
; | 159 return (c->*m_function)(std::forward<IncomingParameters>(parameters)...)
; |
| 160 } | 160 } |
| 161 | 161 |
| 162 template <typename... IncomingParameters> | 162 template <typename... IncomingParameters> |
| 163 R operator()(const PassOwnPtr<C>& c, IncomingParameters&&... parameters) | 163 R operator()(const PassOwnPtr<C>& c, IncomingParameters&&... parameters) |
| 164 { | 164 { |
| 165 return (c.get()->*m_function)(std::forward<IncomingParameters>(parameter
s)...); | 165 return (c.get()->*m_function)(std::forward<IncomingParameters>(parameter
s)...); |
| 166 } | 166 } |
| 167 | 167 |
| 168 template <typename... IncomingParameters> | 168 template <typename... IncomingParameters> |
| 169 R operator()(const std::unique_ptr<C>& c, IncomingParameters&&... parameters
) |
| 170 { |
| 171 return (c.get()->*m_function)(std::forward<IncomingParameters>(parameter
s)...); |
| 172 } |
| 173 |
| 174 template <typename... IncomingParameters> |
| 169 R operator()(const WeakPtr<C>& c, IncomingParameters&&... parameters) | 175 R operator()(const WeakPtr<C>& c, IncomingParameters&&... parameters) |
| 170 { | 176 { |
| 171 C* obj = c.get(); | 177 C* obj = c.get(); |
| 172 if (!obj) | 178 if (!obj) |
| 173 return R(); | 179 return R(); |
| 174 return (obj->*m_function)(std::forward<IncomingParameters>(parameters)..
.); | 180 return (obj->*m_function)(std::forward<IncomingParameters>(parameters)..
.); |
| 175 } | 181 } |
| 176 | 182 |
| 177 private: | 183 private: |
| 178 R(C::*m_function)(Parameters...); | 184 R(C::*m_function)(Parameters...); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 | 343 |
| 338 } // namespace WTF | 344 } // namespace WTF |
| 339 | 345 |
| 340 using WTF::passed; | 346 using WTF::passed; |
| 341 using WTF::Function; | 347 using WTF::Function; |
| 342 using WTF::bind; | 348 using WTF::bind; |
| 343 using WTF::SameThreadClosure; | 349 using WTF::SameThreadClosure; |
| 344 using WTF::CrossThreadClosure; | 350 using WTF::CrossThreadClosure; |
| 345 | 351 |
| 346 #endif // WTF_Functional_h | 352 #endif // WTF_Functional_h |
| OLD | NEW |