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

Side by Side Diff: base/bind_internal.h

Issue 2115533002: Allow binding captureless lambdas into base::Callback by base::Bind (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@05_remove_runnable
Patch Set: +comment and link Created 4 years, 5 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 | « no previous file | base/bind_unittest.cc » ('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 <stddef.h> 8 #include <stddef.h>
9 9
10 #include <tuple> 10 #include <tuple>
(...skipping 28 matching lines...) Expand all
39 // invocation manner for a Functor. This is where function 39 // invocation manner for a Functor. This is where function
40 // signature adapters are applied. 40 // signature adapters are applied.
41 // InvokeHelper<> -- Take a Functor + arguments and actully invokes it. 41 // InvokeHelper<> -- Take a Functor + arguments and actully invokes it.
42 // Handle the differing syntaxes needed for WeakPtr<> 42 // Handle the differing syntaxes needed for WeakPtr<>
43 // support. This is separate from Invoker to avoid creating 43 // support. This is separate from Invoker to avoid creating
44 // multiple version of Invoker<>. 44 // multiple version of Invoker<>.
45 // Invoker<> -- Unwraps the curried parameters and executes the Functor. 45 // Invoker<> -- Unwraps the curried parameters and executes the Functor.
46 // BindState<> -- Stores the curried parameters, and is the main entry point 46 // BindState<> -- Stores the curried parameters, and is the main entry point
47 // into the Bind() system. 47 // into the Bind() system.
48 48
49 template <typename...>
50 struct make_void {
51 using type = void;
52 };
53
54 // A clone of C++17 std::void_t.
55 // Unlike to the original version, we need |make_void| as a helper struct to
Yuta Kitamura 2016/07/01 09:02:33 nit: Remove "to" after "Unlike"
tzik 2016/07/01 09:58:08 Done.
56 // avoid a C++14 defect.
57 // ref: http://en.cppreference.com/w/cpp/types/void_t
58 // ref: http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1558
59 template <typename... Ts>
60 using void_t = typename make_void<Ts...>::type;
61
62 template <typename Lambda, typename Signature = decltype(&Lambda::operator())>
63 struct ExtractLambdaRunTypeImpl;
64
65 template <typename Lambda, typename R, typename... Args>
66 struct ExtractLambdaRunTypeImpl<Lambda, R(Lambda::*)(Args...) const> {
67 using Type = R(Args...);
68 };
69
70 // Evaluated to RunType of the given C++11 lambda expressien type.
Yuta Kitamura 2016/07/01 09:02:33 nit: expressien
tzik 2016/07/01 09:58:08 Done.
71 // Example:
72 // ExtractLambdaRunType<[](int, char*) { return 0.1; }>
73 // is evaluated to
74 // double(int, char*);
75 template <typename Lambda>
76 using ExtractLambdaRunType = typename ExtractLambdaRunTypeImpl<Lambda>::Type;
77
78 // IsCapturelessLambda<Functor> is a std::true_type if |Functor| is a
79 // captureless lambda expression type.
80 // Example:
81 // IsCapturelessLambda<void(*)()>::value is false.
82 //
83 // struct Foo {};
84 // IsCapturelessLambda<void(Foo::*)()>::value is false.
85 //
86 // auto f = []() {};
87 // IsCapturelessLambda<decltype(f)>::value is true.
88 //
89 // int i = 0;
90 // auto g = [i]() {};
91 // IsCapturelessLambda<decltype(g)>::value is false.
92 template <typename Functor, typename SFINAE = void>
93 struct IsCapturelessLambda : std::false_type {};
94
95 template <typename Lambda>
96 struct IsCapturelessLambda<Lambda, void_t<decltype(&Lambda::operator())>>
97 : std::is_convertible<Lambda, ExtractLambdaRunType<Lambda>*> {};
98
49 // HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw 99 // HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw
50 // pointer to a RefCounted type. 100 // pointer to a RefCounted type.
51 // Implementation note: This non-specialized case handles zero-arity case only. 101 // Implementation note: This non-specialized case handles zero-arity case only.
52 // Non-zero-arity cases should be handled by the specialization below. 102 // Non-zero-arity cases should be handled by the specialization below.
53 template <typename... Args> 103 template <typename... Args>
54 struct HasRefCountedTypeAsRawPtr : std::false_type {}; 104 struct HasRefCountedTypeAsRawPtr : std::false_type {};
55 105
56 // Implementation note: Select true_type if the first parameter is a raw pointer 106 // Implementation note: Select true_type if the first parameter is a raw pointer
57 // to a RefCounted type. Otherwise, skip the first parameter and check rest of 107 // to a RefCounted type. Otherwise, skip the first parameter and check rest of
58 // parameters recursively. 108 // parameters recursively.
(...skipping 10 matching lines...) Expand all
69 struct ForceVoidReturn; 119 struct ForceVoidReturn;
70 120
71 template <typename R, typename... Args> 121 template <typename R, typename... Args>
72 struct ForceVoidReturn<R(Args...)> { 122 struct ForceVoidReturn<R(Args...)> {
73 using RunType = void(Args...); 123 using RunType = void(Args...);
74 }; 124 };
75 125
76 // FunctorTraits<> 126 // FunctorTraits<>
77 // 127 //
78 // See description at top of file. 128 // See description at top of file.
79 template <typename Functor> 129 template <typename Functor, typename SFINAE = void>
80 struct FunctorTraits; 130 struct FunctorTraits;
81 131
132 // For captureless lambdas.
133 template <typename Lambda>
134 struct FunctorTraits<
135 Lambda, typename std::enable_if<IsCapturelessLambda<Lambda>::value>::type> {
136 using RunType = ExtractLambdaRunType<Lambda>;
137 static constexpr bool is_method = false;
138 static constexpr bool is_nullable = false;
139
140 template <typename... RunArgs>
141 static typename std::result_of<Lambda(RunArgs&&...)>::type
142 Invoke(const Lambda& lambda, RunArgs&&... args) {
143 return lambda(std::forward<RunArgs>(args)...);
144 }
145 };
146
82 // For functions. 147 // For functions.
83 template <typename R, typename... Args> 148 template <typename R, typename... Args>
84 struct FunctorTraits<R (*)(Args...)> { 149 struct FunctorTraits<R (*)(Args...)> {
85 using RunType = R(Args...); 150 using RunType = R(Args...);
86 static constexpr bool is_method = false; 151 static constexpr bool is_method = false;
152 static constexpr bool is_nullable = true;
87 153
88 template <typename... RunArgs> 154 template <typename... RunArgs>
89 static R Invoke(R (*function)(Args...), RunArgs&&... args) { 155 static R Invoke(R (*function)(Args...), RunArgs&&... args) {
90 return function(std::forward<RunArgs>(args)...); 156 return function(std::forward<RunArgs>(args)...);
91 } 157 }
92 }; 158 };
93 159
94 #if defined(OS_WIN) && !defined(ARCH_CPU_X86_64) 160 #if defined(OS_WIN) && !defined(ARCH_CPU_X86_64)
95 161
96 // For functions. 162 // For functions.
97 template <typename R, typename... Args> 163 template <typename R, typename... Args>
98 struct FunctorTraits<R(__stdcall*)(Args...)> { 164 struct FunctorTraits<R(__stdcall*)(Args...)> {
99 using RunType = R(Args...); 165 using RunType = R(Args...);
100 static constexpr bool is_method = false; 166 static constexpr bool is_method = false;
167 static constexpr bool is_nullable = true;
101 168
102 template <typename... RunArgs> 169 template <typename... RunArgs>
103 static R Invoke(R(__stdcall* function)(Args...), RunArgs&&... args) { 170 static R Invoke(R(__stdcall* function)(Args...), RunArgs&&... args) {
104 return function(std::forward<RunArgs>(args)...); 171 return function(std::forward<RunArgs>(args)...);
105 } 172 }
106 }; 173 };
107 174
108 // For functions. 175 // For functions.
109 template <typename R, typename... Args> 176 template <typename R, typename... Args>
110 struct FunctorTraits<R(__fastcall*)(Args...)> { 177 struct FunctorTraits<R(__fastcall*)(Args...)> {
111 using RunType = R(Args...); 178 using RunType = R(Args...);
112 static constexpr bool is_method = false; 179 static constexpr bool is_method = false;
180 static constexpr bool is_nullable = true;
113 181
114 template <typename... RunArgs> 182 template <typename... RunArgs>
115 static R Invoke(R(__fastcall* function)(Args...), RunArgs&&... args) { 183 static R Invoke(R(__fastcall* function)(Args...), RunArgs&&... args) {
116 return function(std::forward<RunArgs>(args)...); 184 return function(std::forward<RunArgs>(args)...);
117 } 185 }
118 }; 186 };
119 187
120 #endif // defined(OS_WIN) && !defined(ARCH_CPU_X86_64) 188 #endif // defined(OS_WIN) && !defined(ARCH_CPU_X86_64)
121 189
122 // For methods. 190 // For methods.
123 template <typename R, typename Receiver, typename... Args> 191 template <typename R, typename Receiver, typename... Args>
124 struct FunctorTraits<R (Receiver::*)(Args...)> { 192 struct FunctorTraits<R (Receiver::*)(Args...)> {
125 using RunType = R(Receiver*, Args...); 193 using RunType = R(Receiver*, Args...);
126 static constexpr bool is_method = true; 194 static constexpr bool is_method = true;
195 static constexpr bool is_nullable = true;
127 196
128 template <typename ReceiverPtr, typename... RunArgs> 197 template <typename ReceiverPtr, typename... RunArgs>
129 static R Invoke(R (Receiver::*method)(Args...), 198 static R Invoke(R (Receiver::*method)(Args...),
130 ReceiverPtr&& receiver_ptr, 199 ReceiverPtr&& receiver_ptr,
131 RunArgs&&... args) { 200 RunArgs&&... args) {
132 // Clang skips CV qualifier check on a method pointer invocation when the 201 // Clang skips CV qualifier check on a method pointer invocation when the
133 // receiver is a subclass. Store the receiver into a const reference to 202 // receiver is a subclass. Store the receiver into a const reference to
134 // T to ensure the CV check works. 203 // T to ensure the CV check works.
135 // https://llvm.org/bugs/show_bug.cgi?id=27037 204 // https://llvm.org/bugs/show_bug.cgi?id=27037
136 Receiver& receiver = *receiver_ptr; 205 Receiver& receiver = *receiver_ptr;
137 return (receiver.*method)(std::forward<RunArgs>(args)...); 206 return (receiver.*method)(std::forward<RunArgs>(args)...);
138 } 207 }
139 }; 208 };
140 209
141 // For const methods. 210 // For const methods.
142 template <typename R, typename Receiver, typename... Args> 211 template <typename R, typename Receiver, typename... Args>
143 struct FunctorTraits<R (Receiver::*)(Args...) const> { 212 struct FunctorTraits<R (Receiver::*)(Args...) const> {
144 using RunType = R(const Receiver*, Args...); 213 using RunType = R(const Receiver*, Args...);
145 static constexpr bool is_method = true; 214 static constexpr bool is_method = true;
215 static constexpr bool is_nullable = true;
146 216
147 template <typename ReceiverPtr, typename... RunArgs> 217 template <typename ReceiverPtr, typename... RunArgs>
148 static R Invoke(R (Receiver::*method)(Args...) const, 218 static R Invoke(R (Receiver::*method)(Args...) const,
149 ReceiverPtr&& receiver_ptr, 219 ReceiverPtr&& receiver_ptr,
150 RunArgs&&... args) { 220 RunArgs&&... args) {
151 // Clang skips CV qualifier check on a method pointer invocation when the 221 // Clang skips CV qualifier check on a method pointer invocation when the
152 // receiver is a subclass. Store the receiver into a const reference to 222 // receiver is a subclass. Store the receiver into a const reference to
153 // T to ensure the CV check works. 223 // T to ensure the CV check works.
154 // https://llvm.org/bugs/show_bug.cgi?id=27037 224 // https://llvm.org/bugs/show_bug.cgi?id=27037
155 const Receiver& receiver = *receiver_ptr; 225 const Receiver& receiver = *receiver_ptr;
(...skipping 13 matching lines...) Expand all
169 FunctorTraits<T>::Invoke(ignore_result_helper.functor_, 239 FunctorTraits<T>::Invoke(ignore_result_helper.functor_,
170 std::forward<RunArgs>(args)...); 240 std::forward<RunArgs>(args)...);
171 } 241 }
172 }; 242 };
173 243
174 // For Callbacks. 244 // For Callbacks.
175 template <typename R, typename... Args, CopyMode copy_mode> 245 template <typename R, typename... Args, CopyMode copy_mode>
176 struct FunctorTraits<Callback<R(Args...), copy_mode>> { 246 struct FunctorTraits<Callback<R(Args...), copy_mode>> {
177 using RunType = R(Args...); 247 using RunType = R(Args...);
178 static constexpr bool is_method = false; 248 static constexpr bool is_method = false;
249 static constexpr bool is_nullable = true;
179 250
180 template <typename CallbackType, typename... RunArgs> 251 template <typename CallbackType, typename... RunArgs>
181 static R Invoke(CallbackType&& callback, RunArgs&&... args) { 252 static R Invoke(CallbackType&& callback, RunArgs&&... args) {
182 DCHECK(!callback.is_null()); 253 DCHECK(!callback.is_null());
183 return std::forward<CallbackType>(callback).Run( 254 return std::forward<CallbackType>(callback).Run(
184 std::forward<RunArgs>(args)...); 255 std::forward<RunArgs>(args)...);
185 } 256 }
186 }; 257 };
187 258
188 // InvokeHelper<> 259 // InvokeHelper<>
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 // Used to implement MakeUnboundRunType. 345 // Used to implement MakeUnboundRunType.
275 template <typename Functor, typename... BoundArgs> 346 template <typename Functor, typename... BoundArgs>
276 struct MakeUnboundRunTypeImpl { 347 struct MakeUnboundRunTypeImpl {
277 using RunType = 348 using RunType =
278 typename FunctorTraits<typename std::decay<Functor>::type>::RunType; 349 typename FunctorTraits<typename std::decay<Functor>::type>::RunType;
279 using ReturnType = ExtractReturnType<RunType>; 350 using ReturnType = ExtractReturnType<RunType>;
280 using Args = ExtractArgs<RunType>; 351 using Args = ExtractArgs<RunType>;
281 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), Args>; 352 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), Args>;
282 using Type = MakeFunctionType<ReturnType, UnboundArgs>; 353 using Type = MakeFunctionType<ReturnType, UnboundArgs>;
283 }; 354 };
355 template <typename Functor>
356 typename std::enable_if<FunctorTraits<Functor>::is_nullable, bool>::type
357 IsNull(const Functor& functor) {
358 return !functor;
359 }
360
361 template <typename Functor>
362 typename std::enable_if<!FunctorTraits<Functor>::is_nullable, bool>::type
363 IsNull(const Functor&) {
364 return false;
365 }
284 366
285 // BindState<> 367 // BindState<>
286 // 368 //
287 // This stores all the state passed into Bind(). 369 // This stores all the state passed into Bind().
288 template <typename Functor, typename... BoundArgs> 370 template <typename Functor, typename... BoundArgs>
289 struct BindState final : BindStateBase { 371 struct BindState final : BindStateBase {
290 template <typename... ForwardBoundArgs> 372 template <typename... ForwardBoundArgs>
291 explicit BindState(Functor functor, ForwardBoundArgs&&... bound_args) 373 explicit BindState(Functor functor, ForwardBoundArgs&&... bound_args)
292 : BindStateBase(&Destroy), 374 : BindStateBase(&Destroy),
293 functor_(std::move(functor)), 375 functor_(std::move(functor)),
294 bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) { 376 bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) {
295 DCHECK(functor_); 377 DCHECK(!IsNull(functor_));
296 } 378 }
297 379
298 Functor functor_; 380 Functor functor_;
299 std::tuple<BoundArgs...> bound_args_; 381 std::tuple<BoundArgs...> bound_args_;
300 382
301 private: 383 private:
302 ~BindState() {} 384 ~BindState() {}
303 385
304 static void Destroy(BindStateBase* self) { 386 static void Destroy(BindStateBase* self) {
305 delete static_cast<BindState*>(self); 387 delete static_cast<BindState*>(self);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 436
355 // Returns a RunType of bound functor. 437 // Returns a RunType of bound functor.
356 // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C). 438 // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C).
357 template <typename Functor, typename... BoundArgs> 439 template <typename Functor, typename... BoundArgs>
358 using MakeUnboundRunType = 440 using MakeUnboundRunType =
359 typename internal::MakeUnboundRunTypeImpl<Functor, BoundArgs...>::Type; 441 typename internal::MakeUnboundRunTypeImpl<Functor, BoundArgs...>::Type;
360 442
361 } // namespace base 443 } // namespace base
362 444
363 #endif // BASE_BIND_INTERNAL_H_ 445 #endif // BASE_BIND_INTERNAL_H_
OLDNEW
« no previous file with comments | « no previous file | base/bind_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698