Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: base/callback_internal.h

Issue 1644603003: Do Perfect Forwarding from base::Bind to BindState storage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« base/bind_internal.h ('K') | « base/bind_internal.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 struct CallbackParamTraitsForMoveOnlyType; 122 struct CallbackParamTraitsForMoveOnlyType;
123 123
124 template <typename> 124 template <typename>
125 struct CallbackParamTraitsForNonMoveOnlyType; 125 struct CallbackParamTraitsForNonMoveOnlyType;
126 126
127 // TODO(tzik): Use a default parameter once MSVS supports variadic templates 127 // TODO(tzik): Use a default parameter once MSVS supports variadic templates
128 // with default values. 128 // with default values.
129 // http://connect.microsoft.com/VisualStudio/feedbackdetail/view/957801/compilat ion-error-with-variadic-templates 129 // http://connect.microsoft.com/VisualStudio/feedbackdetail/view/957801/compilat ion-error-with-variadic-templates
130 // 130 //
131 // This is a typetraits object that's used to take an argument type, and 131 // This is a typetraits object that's used to take an argument type, and
132 // extract a suitable type for storing and forwarding arguments. 132 // extract a suitable type for storing and forwarding arguments.
danakj 2016/01/28 23:01:00 Comment is out of date now
tzik 2016/02/01 15:00:16 Done.
133 // 133 //
134 // In particular, it strips off references, and converts arrays to 134 // In particular, it strips off references, and converts arrays to
135 // pointers for storage; and it avoids accidentally trying to create a 135 // pointers for storage; and it avoids accidentally trying to create a
danakj 2016/01/28 23:01:00 And here
tzik 2016/02/01 15:00:16 Done.
136 // "reference of a reference" if the argument is a reference type. 136 // "reference of a reference" if the argument is a reference type.
137 // 137 //
138 // This array type becomes an issue for storage because we are passing bound 138 // This array type becomes an issue for storage because we are passing bound
139 // parameters by const reference. In this case, we end up passing an actual 139 // parameters by const reference. In this case, we end up passing an actual
140 // array type in the initializer list which C++ does not allow. This will 140 // array type in the initializer list which C++ does not allow. This will
141 // break passing of C-string literals. 141 // break passing of C-string literals.
142 template <typename T> 142 template <typename T>
143 struct CallbackParamTraits 143 struct CallbackParamTraits
144 : std::conditional<IsMoveOnlyType<T>::value, 144 : std::conditional<IsMoveOnlyType<T>::value,
145 CallbackParamTraitsForMoveOnlyType<T>, 145 CallbackParamTraitsForMoveOnlyType<T>,
146 CallbackParamTraitsForNonMoveOnlyType<T>>::type { 146 CallbackParamTraitsForNonMoveOnlyType<T>>::type {
147 }; 147 };
148 148
149 template <typename T> 149 template <typename T>
150 struct CallbackParamTraitsForNonMoveOnlyType { 150 struct CallbackParamTraitsForNonMoveOnlyType {
151 using ForwardType = const T&; 151 using ForwardType = const T&;
152 using StorageType = T;
153 }; 152 };
154 153
155 // The Storage should almost be impossible to trigger unless someone manually 154 // The Storage should almost be impossible to trigger unless someone manually
156 // specifies type of the bind parameters. However, in case they do, 155 // specifies type of the bind parameters. However, in case they do,
157 // this will guard against us accidentally storing a reference parameter. 156 // this will guard against us accidentally storing a reference parameter.
158 // 157 //
159 // The ForwardType should only be used for unbound arguments. 158 // The ForwardType should only be used for unbound arguments.
160 template <typename T> 159 template <typename T>
161 struct CallbackParamTraitsForNonMoveOnlyType<T&> { 160 struct CallbackParamTraitsForNonMoveOnlyType<T&> {
danakj 2016/01/28 23:01:00 Do we still need this specialization?
tzik 2016/02/01 15:00:16 Done.
162 using ForwardType = T&; 161 using ForwardType = T&;
163 using StorageType = T;
164 }; 162 };
165 163
166 // Note that for array types, we implicitly add a const in the conversion. This 164 // Note that for array types, we implicitly add a const in the conversion. This
167 // means that it is not possible to bind array arguments to functions that take 165 // means that it is not possible to bind array arguments to functions that take
168 // a non-const pointer. Trying to specialize the template based on a "const 166 // a non-const pointer. Trying to specialize the template based on a "const
169 // T[n]" does not seem to match correctly, so we are stuck with this 167 // T[n]" does not seem to match correctly, so we are stuck with this
170 // restriction. 168 // restriction.
171 template <typename T, size_t n> 169 template <typename T, size_t n>
172 struct CallbackParamTraitsForNonMoveOnlyType<T[n]> { 170 struct CallbackParamTraitsForNonMoveOnlyType<T[n]> {
173 using ForwardType = const T*; 171 using ForwardType = const T*;
174 using StorageType = const T*;
175 }; 172 };
176 173
177 // See comment for CallbackParamTraits<T[n]>. 174 // See comment for CallbackParamTraits<T[n]>.
178 template <typename T> 175 template <typename T>
179 struct CallbackParamTraitsForNonMoveOnlyType<T[]> { 176 struct CallbackParamTraitsForNonMoveOnlyType<T[]> {
180 using ForwardType = const T*; 177 using ForwardType = const T*;
181 using StorageType = const T*;
182 }; 178 };
183 179
184 // Parameter traits for movable-but-not-copyable scopers. 180 // Parameter traits for movable-but-not-copyable scopers.
185 // 181 //
186 // Callback<>/Bind() understands movable-but-not-copyable semantics where 182 // Callback<>/Bind() understands movable-but-not-copyable semantics where
187 // the type cannot be copied but can still have its state destructively 183 // the type cannot be copied but can still have its state destructively
188 // transferred (aka. moved) to another instance of the same type by calling a 184 // transferred (aka. moved) to another instance of the same type by calling a
189 // helper function. When used with Bind(), this signifies transferal of the 185 // helper function. When used with Bind(), this signifies transferal of the
190 // object's state to the target function. 186 // object's state to the target function.
191 // 187 //
192 // For these types, the ForwardType must not be a const reference, or a 188 // For these types, the ForwardType must not be a const reference, or a
193 // reference. A const reference is inappropriate, and would break const 189 // reference. A const reference is inappropriate, and would break const
194 // correctness, because we are implementing a destructive move. A non-const 190 // correctness, because we are implementing a destructive move. A non-const
195 // reference cannot be used with temporaries which means the result of a 191 // reference cannot be used with temporaries which means the result of a
196 // function or a cast would not be usable with Callback<> or Bind(). 192 // function or a cast would not be usable with Callback<> or Bind().
197 template <typename T> 193 template <typename T>
198 struct CallbackParamTraitsForMoveOnlyType { 194 struct CallbackParamTraitsForMoveOnlyType {
199 using ForwardType = T; 195 using ForwardType = T;
200 using StorageType = T;
201 }; 196 };
202 197
203 // CallbackForward() is a very limited simulation of C++11's std::forward() 198 // CallbackForward() is a very limited simulation of C++11's std::forward()
204 // used by the Callback/Bind system for a set of movable-but-not-copyable 199 // used by the Callback/Bind system for a set of movable-but-not-copyable
205 // types. It is needed because forwarding a movable-but-not-copyable 200 // types. It is needed because forwarding a movable-but-not-copyable
206 // argument to another function requires us to invoke the proper move 201 // argument to another function requires us to invoke the proper move
207 // operator to create a rvalue version of the type. The supported types are 202 // operator to create a rvalue version of the type. The supported types are
208 // whitelisted below as overloads of the CallbackForward() function. The 203 // whitelisted below as overloads of the CallbackForward() function. The
209 // default template compiles out to be a no-op. 204 // default template compiles out to be a no-op.
210 // 205 //
(...skipping 14 matching lines...) Expand all
225 template <typename T> 220 template <typename T>
226 typename std::enable_if<IsMoveOnlyType<T>::value, T>::type CallbackForward( 221 typename std::enable_if<IsMoveOnlyType<T>::value, T>::type CallbackForward(
227 T& t) { 222 T& t) {
228 return std::move(t); 223 return std::move(t);
229 } 224 }
230 225
231 } // namespace internal 226 } // namespace internal
232 } // namespace base 227 } // namespace base
233 228
234 #endif // BASE_CALLBACK_INTERNAL_H_ 229 #endif // BASE_CALLBACK_INTERNAL_H_
OLDNEW
« base/bind_internal.h ('K') | « base/bind_internal.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698