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

Side by Side Diff: base/bind_internal.h

Issue 1498973002: WIP: base::Bind for rvalue references. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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_helpers.h ('k') | base/bind_internal_win.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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 #ifndef BASE_BIND_INTERNAL_H_ 5 #ifndef BASE_BIND_INTERNAL_H_
6 #define BASE_BIND_INTERNAL_H_ 6 #define BASE_BIND_INTERNAL_H_
7 7
8 #include <type_traits> 8 #include <type_traits>
9 9
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 101
102 // BindsArrayToFirstArg selects true_type when |is_method| is true and the first 102 // BindsArrayToFirstArg selects true_type when |is_method| is true and the first
103 // item of |Args| is an array type. 103 // item of |Args| is an array type.
104 // Implementation note: This non-specialized case handles !is_method case and 104 // Implementation note: This non-specialized case handles !is_method case and
105 // zero-arity case only. Other cases should be handled by the specialization 105 // zero-arity case only. Other cases should be handled by the specialization
106 // below. 106 // below.
107 template <bool is_method, typename... Args> 107 template <bool is_method, typename... Args>
108 struct BindsArrayToFirstArg : false_type {}; 108 struct BindsArrayToFirstArg : false_type {};
109 109
110 template <typename T, typename... Args> 110 template <typename T, typename... Args>
111 struct BindsArrayToFirstArg<true, T, Args...> : is_array<T> {}; 111 struct BindsArrayToFirstArg<true, T, Args...>
112 : is_array<typename std::remove_reference<T>::type> {};
112 113
113 // HasRefCountedParamAsRawPtr is the same to HasRefCountedTypeAsRawPtr except 114 // HasRefCountedParamAsRawPtr is the same to HasRefCountedTypeAsRawPtr except
114 // when |is_method| is true HasRefCountedParamAsRawPtr skips the first argument. 115 // when |is_method| is true HasRefCountedParamAsRawPtr skips the first argument.
115 // Implementation note: This non-specialized case handles !is_method case and 116 // Implementation note: This non-specialized case handles !is_method case and
116 // zero-arity case only. Other cases should be handled by the specialization 117 // zero-arity case only. Other cases should be handled by the specialization
117 // below. 118 // below.
118 template <bool is_method, typename... Args> 119 template <bool is_method, typename... Args>
119 struct HasRefCountedParamAsRawPtr : HasRefCountedTypeAsRawPtr<Args...> {}; 120 struct HasRefCountedParamAsRawPtr : HasRefCountedTypeAsRawPtr<Args...> {};
120 121
121 template <typename T, typename... Args> 122 template <typename T, typename... Args>
(...skipping 26 matching lines...) Expand all
148 // Function. 149 // Function.
149 template <typename R, typename... Args> 150 template <typename R, typename... Args>
150 class RunnableAdapter<R(*)(Args...)> { 151 class RunnableAdapter<R(*)(Args...)> {
151 public: 152 public:
152 typedef R (RunType)(Args...); 153 typedef R (RunType)(Args...);
153 154
154 explicit RunnableAdapter(R(*function)(Args...)) 155 explicit RunnableAdapter(R(*function)(Args...))
155 : function_(function) { 156 : function_(function) {
156 } 157 }
157 158
158 R Run(typename CallbackParamTraits<Args>::ForwardType... args) { 159 template <typename... RunArgs>
159 return function_(CallbackForward(args)...); 160 R Run(RunArgs&&... args) {
161 return function_(std::forward<RunArgs>(args)...);
160 } 162 }
161 163
162 private: 164 private:
163 R (*function_)(Args...); 165 R (*function_)(Args...);
164 }; 166 };
165 167
166 // Method. 168 // Method.
167 template <typename R, typename T, typename... Args> 169 template <typename R, typename T, typename... Args>
168 class RunnableAdapter<R(T::*)(Args...)> { 170 class RunnableAdapter<R(T::*)(Args...)> {
169 public: 171 public:
170 typedef R (RunType)(T*, Args...); 172 typedef R (RunType)(T*, Args...);
171 typedef true_type IsMethod; 173 typedef true_type IsMethod;
172 174
173 explicit RunnableAdapter(R(T::*method)(Args...)) 175 explicit RunnableAdapter(R(T::*method)(Args...))
174 : method_(method) { 176 : method_(method) {
175 } 177 }
176 178
177 R Run(T* object, typename CallbackParamTraits<Args>::ForwardType... args) { 179 template <typename... RunArgs>
178 return (object->*method_)(CallbackForward(args)...); 180 R Run(T* object, RunArgs&&... args) {
181 return (object->*method_)(std::forward<RunArgs>(args)...);
179 } 182 }
180 183
181 private: 184 private:
182 R (T::*method_)(Args...); 185 R (T::*method_)(Args...);
183 }; 186 };
184 187
185 // Const Method. 188 // Const Method.
186 template <typename R, typename T, typename... Args> 189 template <typename R, typename T, typename... Args>
187 class RunnableAdapter<R(T::*)(Args...) const> { 190 class RunnableAdapter<R(T::*)(Args...) const> {
188 public: 191 public:
189 typedef R (RunType)(const T*, Args...); 192 typedef R (RunType)(const T*, Args...);
190 typedef true_type IsMethod; 193 typedef true_type IsMethod;
191 194
192 explicit RunnableAdapter(R(T::*method)(Args...) const) 195 explicit RunnableAdapter(R(T::*method)(Args...) const)
193 : method_(method) { 196 : method_(method) {
194 } 197 }
195 198
199 template <typename... RunArgs>
196 R Run(const T* object, 200 R Run(const T* object,
197 typename CallbackParamTraits<Args>::ForwardType... args) { 201 RunArgs&&... args) {
198 return (object->*method_)(CallbackForward(args)...); 202 return (object->*method_)(std::forward<RunArgs>(args)...);
199 } 203 }
200 204
201 private: 205 private:
202 R (T::*method_)(Args...) const; 206 R (T::*method_)(Args...) const;
203 }; 207 };
204 208
205 209
206 // ForceVoidReturn<> 210 // ForceVoidReturn<>
207 // 211 //
208 // Set of templates that support forcing the function return type to void. 212 // Set of templates that support forcing the function return type to void.
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 // from the invocation call. 281 // from the invocation call.
278 // 282 //
279 // WeakCalls similarly need special syntax that is applied to the first 283 // WeakCalls similarly need special syntax that is applied to the first
280 // argument to check if they should no-op themselves. 284 // argument to check if they should no-op themselves.
281 template <bool IsWeakCall, typename ReturnType, typename Runnable, 285 template <bool IsWeakCall, typename ReturnType, typename Runnable,
282 typename ArgsType> 286 typename ArgsType>
283 struct InvokeHelper; 287 struct InvokeHelper;
284 288
285 template <typename ReturnType, typename Runnable, typename... Args> 289 template <typename ReturnType, typename Runnable, typename... Args>
286 struct InvokeHelper<false, ReturnType, Runnable, TypeList<Args...>> { 290 struct InvokeHelper<false, ReturnType, Runnable, TypeList<Args...>> {
287 static ReturnType MakeItSo(Runnable runnable, Args... args) { 291 template <typename... RunArgs>
288 return runnable.Run(CallbackForward(args)...); 292 static ReturnType MakeItSo(Runnable runnable, RunArgs&&... args) {
293 return runnable.Run(std::forward<RunArgs>(args)...);
289 } 294 }
290 }; 295 };
291 296
292 template <typename Runnable, typename... Args> 297 template <typename Runnable, typename... Args>
293 struct InvokeHelper<false, void, Runnable, TypeList<Args...>> { 298 struct InvokeHelper<false, void, Runnable, TypeList<Args...>> {
294 static void MakeItSo(Runnable runnable, Args... args) { 299 template <typename... RunArgs>
295 runnable.Run(CallbackForward(args)...); 300 static void MakeItSo(Runnable runnable, RunArgs&&... args) {
301 runnable.Run(std::forward<RunArgs>(args)...);
296 } 302 }
297 }; 303 };
298 304
299 template <typename Runnable, typename BoundWeakPtr, typename... Args> 305 template <typename Runnable, typename BoundWeakPtr, typename... Args>
300 struct InvokeHelper<true, void, Runnable, TypeList<BoundWeakPtr, Args...>> { 306 struct InvokeHelper<true, void, Runnable, TypeList<BoundWeakPtr, Args...>> {
301 static void MakeItSo(Runnable runnable, BoundWeakPtr weak_ptr, Args... args) { 307 template <typename... RunArgs>
308 static void MakeItSo(Runnable runnable,
309 BoundWeakPtr weak_ptr,
310 RunArgs&&... args) {
302 if (!weak_ptr.get()) { 311 if (!weak_ptr.get()) {
303 return; 312 return;
304 } 313 }
305 runnable.Run(weak_ptr.get(), CallbackForward(args)...); 314 runnable.Run(weak_ptr.get(), std::forward<RunArgs>(args)...);
306 } 315 }
307 }; 316 };
308 317
309 #if !defined(_MSC_VER) 318 #if !defined(_MSC_VER)
310 319
311 template <typename ReturnType, typename Runnable, typename ArgsType> 320 template <typename ReturnType, typename Runnable, typename ArgsType>
312 struct InvokeHelper<true, ReturnType, Runnable, ArgsType> { 321 struct InvokeHelper<true, ReturnType, Runnable, ArgsType> {
313 // WeakCalls are only supported for functions with a void return type. 322 // WeakCalls are only supported for functions with a void return type.
314 // Otherwise, the function result would be undefined if the the WeakPtr<> 323 // Otherwise, the function result would be undefined if the the WeakPtr<>
315 // is invalidated. 324 // is invalidated.
(...skipping 14 matching lines...) Expand all
330 template <size_t... bound_indices, 339 template <size_t... bound_indices,
331 typename StorageType, 340 typename StorageType,
332 typename... Unwrappers, 341 typename... Unwrappers,
333 typename InvokeHelperType, 342 typename InvokeHelperType,
334 typename R, 343 typename R,
335 typename... UnboundForwardArgs> 344 typename... UnboundForwardArgs>
336 struct Invoker<IndexSequence<bound_indices...>, 345 struct Invoker<IndexSequence<bound_indices...>,
337 StorageType, TypeList<Unwrappers...>, 346 StorageType, TypeList<Unwrappers...>,
338 InvokeHelperType, R(UnboundForwardArgs...)> { 347 InvokeHelperType, R(UnboundForwardArgs...)> {
339 static R Run(BindStateBase* base, 348 static R Run(BindStateBase* base,
340 UnboundForwardArgs... unbound_args) { 349 typename CallbackParamTraits<
350 UnboundForwardArgs>::ForwardType... unbound_args) {
341 StorageType* storage = static_cast<StorageType*>(base); 351 StorageType* storage = static_cast<StorageType*>(base);
342 // Local references to make debugger stepping easier. If in a debugger, 352 // Local references to make debugger stepping easier. If in a debugger,
343 // you really want to warp ahead and step through the 353 // you really want to warp ahead and step through the
344 // InvokeHelper<>::MakeItSo() call below. 354 // InvokeHelper<>::MakeItSo() call below.
345 return InvokeHelperType::MakeItSo( 355 return InvokeHelperType::MakeItSo(
346 storage->runnable_, 356 storage->runnable_,
347 Unwrappers::Unwrap(get<bound_indices>(storage->bound_args_))..., 357 Unwrappers::Unwrap(get<bound_indices>(storage->bound_args_))...,
348 CallbackForward(unbound_args)...); 358 CallbackForward2(unbound_args)...);
349 } 359 }
350 }; 360 };
351 361
352
353 // BindState<> 362 // BindState<>
354 // 363 //
355 // This stores all the state passed into Bind() and is also where most 364 // This stores all the state passed into Bind() and is also where most
356 // of the template resolution magic occurs. 365 // of the template resolution magic occurs.
357 // 366 //
358 // Runnable is the functor we are binding arguments to. 367 // Runnable is the functor we are binding arguments to.
359 // RunType is type of the Run() function that the Invoker<> should use. 368 // RunType is type of the Run() function that the Invoker<> should use.
360 // Normally, this is the same as the RunType of the Runnable, but it can 369 // Normally, this is the same as the RunType of the Runnable, but it can
361 // be different if an adapter like IgnoreResult() has been used. 370 // be different if an adapter like IgnoreResult() has been used.
362 // 371 //
(...skipping 12 matching lines...) Expand all
375 using StorageType = BindState<Runnable, R(Args...), TypeList<BoundArgs...>>; 384 using StorageType = BindState<Runnable, R(Args...), TypeList<BoundArgs...>>;
376 using RunnableType = Runnable; 385 using RunnableType = Runnable;
377 386
378 // true_type if Runnable is a method invocation and the first bound argument 387 // true_type if Runnable is a method invocation and the first bound argument
379 // is a WeakPtr. 388 // is a WeakPtr.
380 using IsWeakCall = 389 using IsWeakCall =
381 IsWeakMethod<HasIsMethodTag<Runnable>::value, BoundArgs...>; 390 IsWeakMethod<HasIsMethodTag<Runnable>::value, BoundArgs...>;
382 391
383 using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>; 392 using BoundIndices = MakeIndexSequence<sizeof...(BoundArgs)>;
384 using Unwrappers = TypeList<UnwrapTraits<BoundArgs>...>; 393 using Unwrappers = TypeList<UnwrapTraits<BoundArgs>...>;
385 using UnboundForwardArgs = DropTypeListItem< 394 using UnboundForwardArgs =
386 sizeof...(BoundArgs), 395 DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>;
387 TypeList<typename CallbackParamTraits<Args>::ForwardType...>>;
388 using UnboundForwardRunType = MakeFunctionType<R, UnboundForwardArgs>; 396 using UnboundForwardRunType = MakeFunctionType<R, UnboundForwardArgs>;
389 397
390 using InvokeHelperArgs = ConcatTypeLists< 398 using InvokeHelperArgs = ConcatTypeLists<
391 TypeList<typename UnwrapTraits<BoundArgs>::ForwardType...>, 399 TypeList<typename UnwrapTraits<BoundArgs>::ForwardType...>,
392 UnboundForwardArgs>; 400 UnboundForwardArgs>;
393 using InvokeHelperType = 401 using InvokeHelperType =
394 InvokeHelper<IsWeakCall::value, R, Runnable, InvokeHelperArgs>; 402 InvokeHelper<IsWeakCall::value, R, Runnable, InvokeHelperArgs>;
395 403
396 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>; 404 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), TypeList<Args...>>;
397 405
398 public: 406 public:
399 using InvokerType = Invoker<BoundIndices, StorageType, Unwrappers, 407 using InvokerType = Invoker<BoundIndices, StorageType, Unwrappers,
400 InvokeHelperType, UnboundForwardRunType>; 408 InvokeHelperType, UnboundForwardRunType>;
401 using UnboundRunType = MakeFunctionType<R, UnboundArgs>; 409 using UnboundRunType = MakeFunctionType<R, UnboundArgs>;
402 410
403 BindState(const Runnable& runnable, const BoundArgs&... bound_args) 411 template <typename... PassedBoundArgs>
412 BindState(const Runnable& runnable, PassedBoundArgs&&... bound_args)
404 : BindStateBase(&Destroy), 413 : BindStateBase(&Destroy),
405 runnable_(runnable), 414 runnable_(runnable),
406 ref_(bound_args...), 415 ref_(bound_args...),
407 bound_args_(bound_args...) {} 416 bound_args_(std::forward<PassedBoundArgs>(bound_args)...) {}
408 417
409 RunnableType runnable_; 418 RunnableType runnable_;
410 MaybeScopedRefPtr<HasIsMethodTag<Runnable>::value, BoundArgs...> ref_; 419 MaybeScopedRefPtr<HasIsMethodTag<Runnable>::value, BoundArgs...> ref_;
411 Tuple<BoundArgs...> bound_args_; 420 std::tuple<BoundArgs...> bound_args_;
412 421
413 private: 422 private:
414 ~BindState() {} 423 ~BindState() {}
415 424
416 static void Destroy(BindStateBase* self) { 425 static void Destroy(BindStateBase* self) {
417 delete static_cast<BindState*>(self); 426 delete static_cast<BindState*>(self);
418 } 427 }
419 }; 428 };
420 429
421 } // namespace internal 430 } // namespace internal
422 } // namespace base 431 } // namespace base
423 432
424 #endif // BASE_BIND_INTERNAL_H_ 433 #endif // BASE_BIND_INTERNAL_H_
OLDNEW
« no previous file with comments | « base/bind_helpers.h ('k') | base/bind_internal_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698