OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This file contains utility functions and classes that help the | 5 // This file contains utility functions and classes that help the |
6 // implementation, and management of the Callback objects. | 6 // implementation, and management of the Callback objects. |
7 | 7 |
8 #ifndef BASE_CALLBACK_INTERNAL_H_ | 8 #ifndef BASE_CALLBACK_INTERNAL_H_ |
9 #define BASE_CALLBACK_INTERNAL_H_ | 9 #define BASE_CALLBACK_INTERNAL_H_ |
10 | 10 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 // extract a suitable type for storing and forwarding arguments. | 120 // extract a suitable type for storing and forwarding arguments. |
121 // | 121 // |
122 // In particular, it strips off references, and converts arrays to | 122 // In particular, it strips off references, and converts arrays to |
123 // pointers for storage; and it avoids accidentally trying to create a | 123 // pointers for storage; and it avoids accidentally trying to create a |
124 // "reference of a reference" if the argument is a reference type. | 124 // "reference of a reference" if the argument is a reference type. |
125 // | 125 // |
126 // This array type becomes an issue for storage because we are passing bound | 126 // This array type becomes an issue for storage because we are passing bound |
127 // parameters by const reference. In this case, we end up passing an actual | 127 // parameters by const reference. In this case, we end up passing an actual |
128 // array type in the initializer list which C++ does not allow. This will | 128 // array type in the initializer list which C++ does not allow. This will |
129 // break passing of C-string literals. | 129 // break passing of C-string literals. |
130 template <typename T> | 130 template <typename T, typename = void> |
131 struct CallbackParamTraits | 131 struct CallbackParamTraits |
132 : std::conditional<IsMoveOnlyType<T>::value, | 132 : std::conditional<is_move_only<typename std::decay<T>::type>::value, |
133 CallbackParamTraitsForMoveOnlyType<T>, | 133 CallbackParamTraitsForMoveOnlyType<T>, |
134 CallbackParamTraitsForNonMoveOnlyType<T>>::type { | 134 CallbackParamTraitsForNonMoveOnlyType<T>>::type { |
135 }; | 135 }; |
136 | 136 |
137 template <typename T> | 137 template <typename T> |
| 138 struct CallbackParamTraits< |
| 139 T, |
| 140 typename std::conditional<false, |
| 141 typename std::decay<T>::type::value_type, |
| 142 void>::type> |
| 143 : public std::conditional< |
| 144 base::is_move_only<typename std::decay<T>::type>::value || |
| 145 base::is_move_only< |
| 146 typename std::decay<T>::type::value_type>::value, |
| 147 CallbackParamTraitsForMoveOnlyType<T>, |
| 148 CallbackParamTraitsForNonMoveOnlyType<T>>::type { |
| 149 }; |
| 150 |
| 151 template <typename T> |
138 struct CallbackParamTraitsForNonMoveOnlyType { | 152 struct CallbackParamTraitsForNonMoveOnlyType { |
139 typedef const T& ForwardType; | 153 typedef const T& ForwardType; |
140 typedef T StorageType; | 154 typedef T StorageType; |
141 }; | 155 }; |
142 | 156 |
143 // The Storage should almost be impossible to trigger unless someone manually | 157 // The Storage should almost be impossible to trigger unless someone manually |
144 // specifies type of the bind parameters. However, in case they do, | 158 // specifies type of the bind parameters. However, in case they do, |
145 // this will guard against us accidentally storing a reference parameter. | 159 // this will guard against us accidentally storing a reference parameter. |
146 // | 160 // |
147 // The ForwardType should only be used for unbound arguments. | 161 // The ForwardType should only be used for unbound arguments. |
148 template <typename T> | 162 // template <typename T> |
149 struct CallbackParamTraitsForNonMoveOnlyType<T&> { | 163 // struct CallbackParamTraits<T&> { |
150 typedef T& ForwardType; | 164 // typedef T& ForwardType; |
151 typedef T StorageType; | 165 // typedef T StorageType; |
152 }; | 166 // }; |
153 | 167 |
154 // Note that for array types, we implicitly add a const in the conversion. This | 168 // Note that for array types, we implicitly add a const in the conversion. This |
155 // means that it is not possible to bind array arguments to functions that take | 169 // means that it is not possible to bind array arguments to functions that take |
156 // a non-const pointer. Trying to specialize the template based on a "const | 170 // a non-const pointer. Trying to specialize the template based on a "const |
157 // T[n]" does not seem to match correctly, so we are stuck with this | 171 // T[n]" does not seem to match correctly, so we are stuck with this |
158 // restriction. | 172 // restriction. |
159 template <typename T, size_t n> | 173 template <typename T, size_t n> |
160 struct CallbackParamTraitsForNonMoveOnlyType<T[n]> { | 174 struct CallbackParamTraitsForNonMoveOnlyType<T[n]> { |
161 typedef const T* ForwardType; | 175 typedef const T* ForwardType; |
162 typedef const T* StorageType; | 176 typedef const T* StorageType; |
(...skipping 14 matching lines...) Expand all Loading... |
177 // helper function. When used with Bind(), this signifies transferal of the | 191 // helper function. When used with Bind(), this signifies transferal of the |
178 // object's state to the target function. | 192 // object's state to the target function. |
179 // | 193 // |
180 // For these types, the ForwardType must not be a const reference, or a | 194 // For these types, the ForwardType must not be a const reference, or a |
181 // reference. A const reference is inappropriate, and would break const | 195 // reference. A const reference is inappropriate, and would break const |
182 // correctness, because we are implementing a destructive move. A non-const | 196 // correctness, because we are implementing a destructive move. A non-const |
183 // reference cannot be used with temporaries which means the result of a | 197 // reference cannot be used with temporaries which means the result of a |
184 // function or a cast would not be usable with Callback<> or Bind(). | 198 // function or a cast would not be usable with Callback<> or Bind(). |
185 template <typename T> | 199 template <typename T> |
186 struct CallbackParamTraitsForMoveOnlyType { | 200 struct CallbackParamTraitsForMoveOnlyType { |
187 typedef T ForwardType; | 201 typedef typename std::remove_reference<T>::type&& ForwardType; |
188 typedef T StorageType; | 202 typedef T StorageType; |
189 }; | 203 }; |
190 | 204 |
191 // CallbackForward() is a very limited simulation of C++11's std::forward() | 205 // CallbackForward() is a very limited simulation of C++11's std::forward() |
192 // used by the Callback/Bind system for a set of movable-but-not-copyable | 206 // used by the Callback/Bind system for a set of movable-but-not-copyable |
193 // types. It is needed because forwarding a movable-but-not-copyable | 207 // types. It is needed because forwarding a movable-but-not-copyable |
194 // argument to another function requires us to invoke the proper move | 208 // argument to another function requires us to invoke the proper move |
195 // operator to create a rvalue version of the type. The supported types are | 209 // operator to create a rvalue version of the type. The supported types are |
196 // whitelisted below as overloads of the CallbackForward() function. The | 210 // whitelisted below as overloads of the CallbackForward() function. The |
197 // default template compiles out to be a no-op. | 211 // default template compiles out to be a no-op. |
198 // | 212 // |
199 // In C++11, std::forward would replace all uses of this function. However, it | 213 // In C++11, std::forward would replace all uses of this function. However, it |
200 // is impossible to implement a general std::forward with C++11 due to a lack | 214 // is impossible to implement a general std::forward with C++11 due to a lack |
201 // of rvalue references. | 215 // of rvalue references. |
202 // | 216 // |
203 // In addition to Callback/Bind, this is used by PostTaskAndReplyWithResult to | 217 // In addition to Callback/Bind, this is used by PostTaskAndReplyWithResult to |
204 // simulate std::forward() and forward the result of one Callback as a | 218 // simulate std::forward() and forward the result of one Callback as a |
205 // parameter to another callback. This is to support Callbacks that return | 219 // parameter to another callback. This is to support Callbacks that return |
206 // the movable-but-not-copyable types whitelisted above. | 220 // the movable-but-not-copyable types whitelisted above. |
207 template <typename T> | 221 template <typename T> |
208 typename enable_if<!IsMoveOnlyType<T>::value, T>::type& CallbackForward(T& t) { | 222 typename enable_if<!IsMoveOnlyType<T>::value, T>::type& CallbackForward(T& t) { |
209 return t; | 223 return t; |
210 } | 224 } |
211 | 225 |
212 template <typename T> | 226 template <typename T> |
213 typename enable_if<IsMoveOnlyType<T>::value, T>::type CallbackForward(T& t) { | 227 typename enable_if<IsMoveOnlyType<T>::value, T>::type CallbackForward(T& t) { |
214 return t.Pass(); | 228 return t.Pass(); |
215 } | 229 } |
216 | 230 |
| 231 template <typename T> |
| 232 auto CallbackForward2(T&& t) -> |
| 233 typename CallbackParamTraits<T>::ForwardType { |
| 234 return static_cast<typename CallbackParamTraits<T>::ForwardType>(t); |
| 235 } |
| 236 |
217 } // namespace internal | 237 } // namespace internal |
218 } // namespace base | 238 } // namespace base |
219 | 239 |
220 #endif // BASE_CALLBACK_INTERNAL_H_ | 240 #endif // BASE_CALLBACK_INTERNAL_H_ |
OLD | NEW |