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 28 matching lines...) Expand all Loading... | |
39 | 39 |
40 namespace blink { | 40 namespace blink { |
41 template <typename T> | 41 template <typename T> |
42 class Member; | 42 class Member; |
43 template <typename T> | 43 template <typename T> |
44 class WeakMember; | 44 class WeakMember; |
45 } | 45 } |
46 | 46 |
47 namespace WTF { | 47 namespace WTF { |
48 | 48 |
49 // Functional.h provides a very simple way to bind a function pointer and argume nts together into a function object | 49 // Functional.h provides a very simple way to bind a function pointer and |
50 // that can be stored, copied and invoked, similar to how boost::bind and std::b ind in C++11. | 50 // arguments together into a function object that can be stored, copied and |
51 // invoked, similar to boost::bind and std::bind in C++11. | |
51 | 52 |
52 // Thread Safety: | 53 // Thread Safety: |
53 // | 54 // |
54 // WTF::bind() and WTF::Closure should be used for same-thread closures | 55 // WTF::bind() and WTF::Closure should be used for same-thread closures |
55 // only, i.e. the closures must be created, executed and destructed on | 56 // only, i.e. the closures must be created, executed and destructed on |
56 // the same thread. | 57 // the same thread. |
57 // Use crossThreadBind() and CrossThreadClosure if the function/task is called | 58 // Use crossThreadBind() and CrossThreadClosure if the function/task is called |
58 // or destructed on a (potentially) different thread from the current thread. | 59 // or destructed on a (potentially) different thread from the current thread. |
59 | 60 |
60 // WTF::bind() and move semantics | 61 // WTF::bind() and move semantics |
61 // ============================== | 62 // ============================== |
62 // | 63 // |
63 // For unbound parameters (arguments supplied later on the bound functor directl y), there are two ways to pass movable | 64 // For unbound parameters (arguments supplied later on the bound functor |
64 // arguments: | 65 // directly), there are two ways to pass movable arguments: |
65 // | 66 // |
66 // 1) Pass by rvalue reference. | 67 // 1) Pass by rvalue reference. |
67 // | 68 // |
68 // void yourFunction(Argument&& argument) { ... } | 69 // void yourFunction(Argument&& argument) { ... } |
69 // std::unique_ptr<Function<void(Argument&&)>> functor = bind<Argumen t&&>(yourFunction); | 70 // std::unique_ptr<Function<void(Argument&&)>> functor = |
71 // bind<Argument&&>(yourFunction); | |
70 // | 72 // |
71 // 2) Pass by value. | 73 // 2) Pass by value. |
72 // | 74 // |
73 // void yourFunction(Argument argument) { ... } | 75 // void yourFunction(Argument argument) { ... } |
74 // std::unique_ptr<Function<void(Argument)>> functor = bind<Argument> (yourFunction); | 76 // std::unique_ptr<Function<void(Argument)>> functor = |
77 // bind<Argument>(yourFunction); | |
75 // | 78 // |
76 // Note that with the latter there will be *two* move constructions happening, b ecause there needs to be at least one | 79 // Note that with the latter there will be *two* move constructions happening, |
77 // intermediary function call taking an argument of type "Argument" (i.e. passed by value). The former case does not | 80 // because there needs to be at least one intermediary function call taking an |
81 // argument of type "Argument" (i.e. passed by value). The former case does not | |
78 // require any move constructions inbetween. | 82 // require any move constructions inbetween. |
79 // | 83 // |
80 // For bound parameters (arguments supplied on the creation of a functor), you c an move your argument into the internal | 84 // For bound parameters (arguments supplied on the creation of a functor), you |
81 // storage of the functor by supplying an rvalue to that argument (this is done in wrap() of ParamStorageTraits). | 85 // can move your argument into the internal storage of the functor by supplying |
82 // However, to make the functor be able to get called multiple times, the stored object does not get moved out | 86 // an rvalue to that argument (this is done in wrap() of ParamStorageTraits). |
83 // automatically when the underlying function is actually invoked. If you want t o make an argument "auto-passed", | 87 // However, to make the functor be able to get called multiple times, the |
84 // you can do so by wrapping your bound argument with passed() function, as show n below: | 88 // stored object does not get moved out automatically when the underlying |
89 // function is actually invoked. If you want to make an argument "auto-passed", | |
90 // you can do so by wrapping your bound argument with passed() function, as | |
91 // shown below: | |
85 // | 92 // |
86 // void yourFunction(Argument argument) | 93 // void yourFunction(Argument argument) |
87 // { | 94 // { |
88 // // |argument| is passed from the internal storage of functor. | 95 // // |argument| is passed from the internal storage of functor. |
89 // ... | 96 // ... |
90 // } | 97 // } |
91 // | 98 // |
92 // ... | 99 // ... |
93 // std::unique_ptr<Function<void()>> functor = bind(yourFunction, passed(Arg ument())); | 100 // std::unique_ptr<Function<void()>> functor = bind(yourFunction, |
101 // passed(Argument())); | |
dcheng
2016/10/01 19:58:17
Nit: indent
Nico
2016/10/02 00:49:28
Done.
| |
94 // ... | 102 // ... |
95 // (*functor)(); | 103 // (*functor)(); |
96 // | 104 // |
97 // The underlying function must receive the argument wrapped by passed() by rval ue reference or by value. | 105 // The underlying function must receive the argument wrapped by passed() by |
106 // rvalue reference or by value. | |
98 // | 107 // |
99 // Obviously, if you create a functor this way, you shouldn't call the functor t wice or more; after the second call, | 108 // Obviously, if you create a functor this way, you shouldn't call the functor |
100 // the passed argument may be invalid. | 109 // twice or more; after the second call, the passed argument may be invalid. |
101 | 110 |
102 enum FunctionThreadAffinity { CrossThreadAffinity, SameThreadAffinity }; | 111 enum FunctionThreadAffinity { CrossThreadAffinity, SameThreadAffinity }; |
103 | 112 |
104 template <typename T> | 113 template <typename T> |
105 class PassedWrapper final { | 114 class PassedWrapper final { |
106 public: | 115 public: |
107 explicit PassedWrapper(T&& scoper) : m_scoper(std::move(scoper)) {} | 116 explicit PassedWrapper(T&& scoper) : m_scoper(std::move(scoper)) {} |
108 PassedWrapper(PassedWrapper&& other) : m_scoper(std::move(other.m_scoper)) {} | 117 PassedWrapper(PassedWrapper&& other) : m_scoper(std::move(other.m_scoper)) {} |
109 T moveOut() const { return std::move(m_scoper); } | 118 T moveOut() const { return std::move(m_scoper); } |
110 | 119 |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
282 } // namespace base | 291 } // namespace base |
283 | 292 |
284 using WTF::passed; | 293 using WTF::passed; |
285 using WTF::unretained; | 294 using WTF::unretained; |
286 using WTF::crossThreadUnretained; | 295 using WTF::crossThreadUnretained; |
287 | 296 |
288 using WTF::Function; | 297 using WTF::Function; |
289 using WTF::CrossThreadClosure; | 298 using WTF::CrossThreadClosure; |
290 | 299 |
291 #endif // WTF_Functional_h | 300 #endif // WTF_Functional_h |
OLD | NEW |