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

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
« no previous file with comments | « 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 forwarding arguments.
133 //
134 // In particular, it strips off references, and converts arrays to
135 // pointers for storage; and it avoids accidentally trying to create a
136 // "reference of a reference" if the argument is a reference type.
137 //
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
140 // array type in the initializer list which C++ does not allow. This will
141 // break passing of C-string literals.
142 template <typename T> 133 template <typename T>
143 struct CallbackParamTraits 134 struct CallbackParamTraits
144 : std::conditional<IsMoveOnlyType<T>::value, 135 : std::conditional<IsMoveOnlyType<T>::value,
145 CallbackParamTraitsForMoveOnlyType<T>, 136 CallbackParamTraitsForMoveOnlyType<T>,
146 CallbackParamTraitsForNonMoveOnlyType<T>>::type { 137 CallbackParamTraitsForNonMoveOnlyType<T>>::type {
147 }; 138 };
148 139
149 template <typename T> 140 template <typename T>
150 struct CallbackParamTraitsForNonMoveOnlyType { 141 struct CallbackParamTraitsForNonMoveOnlyType {
151 using ForwardType = const T&; 142 using ForwardType = const T&;
152 using StorageType = T;
153 };
154
155 // The Storage should almost be impossible to trigger unless someone manually
156 // specifies type of the bind parameters. However, in case they do,
157 // this will guard against us accidentally storing a reference parameter.
158 //
159 // The ForwardType should only be used for unbound arguments.
160 template <typename T>
161 struct CallbackParamTraitsForNonMoveOnlyType<T&> {
162 using ForwardType = T&;
163 using StorageType = T;
164 }; 143 };
165 144
166 // Note that for array types, we implicitly add a const in the conversion. This 145 // 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 146 // 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 147 // 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 148 // T[n]" does not seem to match correctly, so we are stuck with this
170 // restriction. 149 // restriction.
171 template <typename T, size_t n> 150 template <typename T, size_t n>
172 struct CallbackParamTraitsForNonMoveOnlyType<T[n]> { 151 struct CallbackParamTraitsForNonMoveOnlyType<T[n]> {
173 using ForwardType = const T*; 152 using ForwardType = const T*;
174 using StorageType = const T*;
175 }; 153 };
176 154
177 // See comment for CallbackParamTraits<T[n]>. 155 // See comment for CallbackParamTraits<T[n]>.
178 template <typename T> 156 template <typename T>
179 struct CallbackParamTraitsForNonMoveOnlyType<T[]> { 157 struct CallbackParamTraitsForNonMoveOnlyType<T[]> {
180 using ForwardType = const T*; 158 using ForwardType = const T*;
181 using StorageType = const T*;
182 }; 159 };
183 160
184 // Parameter traits for movable-but-not-copyable scopers. 161 // Parameter traits for movable-but-not-copyable scopers.
185 // 162 //
186 // Callback<>/Bind() understands movable-but-not-copyable semantics where 163 // Callback<>/Bind() understands movable-but-not-copyable semantics where
187 // the type cannot be copied but can still have its state destructively 164 // 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 165 // 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 166 // helper function. When used with Bind(), this signifies transferal of the
190 // object's state to the target function. 167 // object's state to the target function.
191 // 168 //
192 // For these types, the ForwardType must not be a const reference, or a 169 // For these types, the ForwardType must not be a const reference, or a
193 // reference. A const reference is inappropriate, and would break const 170 // reference. A const reference is inappropriate, and would break const
194 // correctness, because we are implementing a destructive move. A non-const 171 // correctness, because we are implementing a destructive move. A non-const
195 // reference cannot be used with temporaries which means the result of a 172 // 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(). 173 // function or a cast would not be usable with Callback<> or Bind().
197 template <typename T> 174 template <typename T>
198 struct CallbackParamTraitsForMoveOnlyType { 175 struct CallbackParamTraitsForMoveOnlyType {
199 using ForwardType = T; 176 using ForwardType = T;
200 using StorageType = T;
201 }; 177 };
202 178
203 // CallbackForward() is a very limited simulation of C++11's std::forward() 179 // 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 180 // 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 181 // types. It is needed because forwarding a movable-but-not-copyable
206 // argument to another function requires us to invoke the proper move 182 // 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 183 // operator to create a rvalue version of the type. The supported types are
208 // whitelisted below as overloads of the CallbackForward() function. The 184 // whitelisted below as overloads of the CallbackForward() function. The
209 // default template compiles out to be a no-op. 185 // default template compiles out to be a no-op.
210 // 186 //
(...skipping 14 matching lines...) Expand all
225 template <typename T> 201 template <typename T>
226 typename std::enable_if<IsMoveOnlyType<T>::value, T>::type CallbackForward( 202 typename std::enable_if<IsMoveOnlyType<T>::value, T>::type CallbackForward(
227 T& t) { 203 T& t) {
228 return std::move(t); 204 return std::move(t);
229 } 205 }
230 206
231 } // namespace internal 207 } // namespace internal
232 } // namespace base 208 } // namespace base
233 209
234 #endif // BASE_CALLBACK_INTERNAL_H_ 210 #endif // BASE_CALLBACK_INTERNAL_H_
OLDNEW
« no previous file with comments | « base/bind_internal.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698