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

Side by Side Diff: base/callback_internal.h

Issue 1781843003: Remove CallbackParamTraits and CallbackForward (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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_win.h ('k') | base/callback_list.h » ('j') | 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
11 #include <stddef.h>
12 #include <memory>
13 #include <type_traits>
14 #include <vector>
15
16 #include "base/atomic_ref_count.h" 11 #include "base/atomic_ref_count.h"
17 #include "base/base_export.h" 12 #include "base/base_export.h"
18 #include "base/callback_forward.h" 13 #include "base/callback_forward.h"
19 #include "base/macros.h" 14 #include "base/macros.h"
20 #include "base/memory/ref_counted.h" 15 #include "base/memory/ref_counted.h"
21 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/scoped_ptr.h"
22 17
23 namespace base { 18 namespace base {
24 namespace internal { 19 namespace internal {
25 template <CopyMode copy_mode> 20 template <CopyMode copy_mode>
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 CallbackBase& operator=(CallbackBase&& c); 105 CallbackBase& operator=(CallbackBase&& c);
111 protected: 106 protected:
112 explicit CallbackBase(BindStateBase* bind_state) 107 explicit CallbackBase(BindStateBase* bind_state)
113 : CallbackBase<CopyMode::MoveOnly>(bind_state) {} 108 : CallbackBase<CopyMode::MoveOnly>(bind_state) {}
114 ~CallbackBase() {} 109 ~CallbackBase() {}
115 }; 110 };
116 111
117 extern template class CallbackBase<CopyMode::MoveOnly>; 112 extern template class CallbackBase<CopyMode::MoveOnly>;
118 extern template class CallbackBase<CopyMode::Copyable>; 113 extern template class CallbackBase<CopyMode::Copyable>;
119 114
120 // A helper template to determine if given type is non-const move-only-type,
121 // i.e. if a value of the given type should be passed via std::move() in a
122 // destructive way. Types are considered to be move-only if they have a
123 // sentinel MoveOnlyTypeForCPP03 member: a class typically gets this from using
124 // the DISALLOW_COPY_AND_ASSIGN_WITH_MOVE_FOR_BIND macro.
125 // It would be easy to generalize this trait to all move-only types... but this
126 // confuses template deduction in VS2013 with certain types such as
127 // std::unique_ptr.
128 // TODO(dcheng): Revisit this when Windows switches to VS2015 by default.
129
130 template <typename T> struct IsMoveOnlyType {
131 // Types YesType and NoType are guaranteed such that sizeof(YesType) <
132 // sizeof(NoType).
133 using YesType = char;
134 struct NoType { YesType dummy[2]; };
135
136 template <typename U>
137 static YesType Test(const typename U::MoveOnlyTypeForCPP03*);
138
139 template <typename U>
140 static NoType Test(...);
141
142 static const bool value = sizeof((Test<T>(0))) == sizeof(YesType) &&
143 !std::is_const<T>::value;
144 };
145
146 // Specialization of IsMoveOnlyType so that std::unique_ptr is still considered
147 // move-only, even without the sentinel member.
148 template <typename T, typename D>
149 struct IsMoveOnlyType<std::unique_ptr<T, D>> : std::true_type {};
150
151 // Specialization of std::vector, so that it's considered move-only if the
152 // element type is move-only. Allocator is explicitly ignored when determining
153 // move-only status of the std::vector.
154 template <typename T, typename Allocator>
155 struct IsMoveOnlyType<std::vector<T, Allocator>> : IsMoveOnlyType<T> {};
156
157 template <typename>
158 struct CallbackParamTraitsForMoveOnlyType;
159
160 template <typename>
161 struct CallbackParamTraitsForNonMoveOnlyType;
162
163 // TODO(tzik): Use a default parameter once MSVS supports variadic templates
164 // with default values.
165 // http://connect.microsoft.com/VisualStudio/feedbackdetail/view/957801/compilat ion-error-with-variadic-templates
166 //
167 // This is a typetraits object that's used to take an argument type, and
168 // extract a suitable type for forwarding arguments.
169 template <typename T>
170 struct CallbackParamTraits
171 : std::conditional<IsMoveOnlyType<T>::value,
172 CallbackParamTraitsForMoveOnlyType<T>,
173 CallbackParamTraitsForNonMoveOnlyType<T>>::type {
174 };
175
176 template <typename T>
177 struct CallbackParamTraitsForNonMoveOnlyType {
178 using ForwardType = const T&;
179 };
180
181 // Note that for array types, we implicitly add a const in the conversion. This
182 // means that it is not possible to bind array arguments to functions that take
183 // a non-const pointer. Trying to specialize the template based on a "const
184 // T[n]" does not seem to match correctly, so we are stuck with this
185 // restriction.
186 template <typename T, size_t n>
187 struct CallbackParamTraitsForNonMoveOnlyType<T[n]> {
188 using ForwardType = const T*;
189 };
190
191 // See comment for CallbackParamTraits<T[n]>.
192 template <typename T>
193 struct CallbackParamTraitsForNonMoveOnlyType<T[]> {
194 using ForwardType = const T*;
195 };
196
197 // Parameter traits for movable-but-not-copyable scopers.
198 //
199 // Callback<>/Bind() understands movable-but-not-copyable semantics where
200 // the type cannot be copied but can still have its state destructively
201 // transferred (aka. moved) to another instance of the same type by calling a
202 // helper function. When used with Bind(), this signifies transferal of the
203 // object's state to the target function.
204 //
205 // For these types, the ForwardType must not be a const reference, or a
206 // reference. A const reference is inappropriate, and would break const
207 // correctness, because we are implementing a destructive move. A non-const
208 // reference cannot be used with temporaries which means the result of a
209 // function or a cast would not be usable with Callback<> or Bind().
210 template <typename T>
211 struct CallbackParamTraitsForMoveOnlyType {
212 using ForwardType = T;
213 };
214
215 // CallbackForward() is a very limited simulation of C++11's std::forward()
216 // used by the Callback/Bind system for a set of movable-but-not-copyable
217 // types. It is needed because forwarding a movable-but-not-copyable
218 // argument to another function requires us to invoke the proper move
219 // operator to create a rvalue version of the type. The supported types are
220 // whitelisted below as overloads of the CallbackForward() function. The
221 // default template compiles out to be a no-op.
222 //
223 // In C++11, std::forward would replace all uses of this function. However, it
224 // is impossible to implement a general std::forward without C++11 due to a lack
225 // of rvalue references.
226 //
227 // In addition to Callback/Bind, this is used by PostTaskAndReplyWithResult to
228 // simulate std::forward() and forward the result of one Callback as a
229 // parameter to another callback. This is to support Callbacks that return
230 // the movable-but-not-copyable types whitelisted above.
231 template <typename T>
232 typename std::enable_if<!IsMoveOnlyType<T>::value, T>::type& CallbackForward(
Nico 2016/03/10 21:54:50 Don't we lose this protection now? Or does std::fo
tzik 2016/03/14 08:49:42 Do you mean a protection to prevent moving non-mov
233 T& t) {
234 return t;
235 }
236
237 template <typename T>
238 typename std::enable_if<IsMoveOnlyType<T>::value, T>::type CallbackForward(
239 T& t) {
240 return std::move(t);
241 }
242
243 } // namespace internal 115 } // namespace internal
244 } // namespace base 116 } // namespace base
245 117
246 #endif // BASE_CALLBACK_INTERNAL_H_ 118 #endif // BASE_CALLBACK_INTERNAL_H_
OLDNEW
« no previous file with comments | « base/bind_internal_win.h ('k') | base/callback_list.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698