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

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: rebase 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 the original version, we need |make_void| as a helper struct to avoid
56 // 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 Callable,
63 typename Signature = decltype(&Callable::operator())>
64 struct ExtractCallableRunTypeImpl;
65
66 template <typename Callable, typename R, typename... Args>
67 struct ExtractCallableRunTypeImpl<Callable, R(Callable::*)(Args...) const> {
68 using Type = R(Args...);
69 };
70
71 // Evaluated to RunType of the given callable type.
72 // Example:
73 // auto f = [](int, char*) { return 0.1; };
74 // ExtractCallableRunType<decltype(f)>
75 // is evaluated to
76 // double(int, char*);
77 template <typename Callable>
78 using ExtractCallableRunType =
79 typename ExtractCallableRunTypeImpl<Callable>::Type;
80
81 // IsConvertibleToRunType<Functor> is std::true_type if |Functor| has operator()
82 // and convertible to the corresponding function pointer. Otherwise, it's
83 // std::false_type.
84 // Example:
85 // IsConvertibleToRunType<void(*)()>::value is false.
86 //
87 // struct Foo {};
88 // IsConvertibleToRunType<void(Foo::*)()>::value is false.
89 //
90 // auto f = []() {};
91 // IsConvertibleToRunType<decltype(f)>::value is true.
92 //
93 // int i = 0;
94 // auto g = [i]() {};
95 // IsConvertibleToRunType<decltype(g)>::value is false.
96 template <typename Functor, typename SFINAE = void>
97 struct IsConvertibleToRunType : std::false_type {};
98
99 template <typename Callable>
100 struct IsConvertibleToRunType<Callable, void_t<decltype(&Callable::operator())>>
101 : std::is_convertible<Callable, ExtractCallableRunType<Callable>*> {};
102
49 // HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw 103 // HasRefCountedTypeAsRawPtr selects true_type when any of the |Args| is a raw
50 // pointer to a RefCounted type. 104 // pointer to a RefCounted type.
51 // Implementation note: This non-specialized case handles zero-arity case only. 105 // Implementation note: This non-specialized case handles zero-arity case only.
52 // Non-zero-arity cases should be handled by the specialization below. 106 // Non-zero-arity cases should be handled by the specialization below.
53 template <typename... Args> 107 template <typename... Args>
54 struct HasRefCountedTypeAsRawPtr : std::false_type {}; 108 struct HasRefCountedTypeAsRawPtr : std::false_type {};
55 109
56 // Implementation note: Select true_type if the first parameter is a raw pointer 110 // 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 111 // to a RefCounted type. Otherwise, skip the first parameter and check rest of
58 // parameters recursively. 112 // parameters recursively.
(...skipping 10 matching lines...) Expand all
69 struct ForceVoidReturn; 123 struct ForceVoidReturn;
70 124
71 template <typename R, typename... Args> 125 template <typename R, typename... Args>
72 struct ForceVoidReturn<R(Args...)> { 126 struct ForceVoidReturn<R(Args...)> {
73 using RunType = void(Args...); 127 using RunType = void(Args...);
74 }; 128 };
75 129
76 // FunctorTraits<> 130 // FunctorTraits<>
77 // 131 //
78 // See description at top of file. 132 // See description at top of file.
133 template <typename Functor, typename SFINAE = void>
134 struct FunctorTraits;
135
136 // For a callable type that is convertible to the corresponding function type.
137 // This specialization is intended to allow binding captureless lambdas by
138 // base::Bind(), based on the fact that captureless lambdas can be convertible
139 // to the function type while capturing lambdas can't.
79 template <typename Functor> 140 template <typename Functor>
80 struct FunctorTraits; 141 struct FunctorTraits<
142 Functor,
143 typename std::enable_if<IsConvertibleToRunType<Functor>::value>::type> {
144 using RunType = ExtractCallableRunType<Functor>;
145 static constexpr bool is_method = false;
146 static constexpr bool is_nullable = false;
147
148 template <typename... RunArgs>
149 static ExtractReturnType<RunType>
150 Invoke(const Functor& functor, RunArgs&&... args) {
151 return functor(std::forward<RunArgs>(args)...);
152 }
153 };
81 154
82 // For functions. 155 // For functions.
83 template <typename R, typename... Args> 156 template <typename R, typename... Args>
84 struct FunctorTraits<R (*)(Args...)> { 157 struct FunctorTraits<R (*)(Args...)> {
85 using RunType = R(Args...); 158 using RunType = R(Args...);
86 static constexpr bool is_method = false; 159 static constexpr bool is_method = false;
160 static constexpr bool is_nullable = true;
87 161
88 template <typename... RunArgs> 162 template <typename... RunArgs>
89 static R Invoke(R (*function)(Args...), RunArgs&&... args) { 163 static R Invoke(R (*function)(Args...), RunArgs&&... args) {
90 return function(std::forward<RunArgs>(args)...); 164 return function(std::forward<RunArgs>(args)...);
91 } 165 }
92 }; 166 };
93 167
94 #if defined(OS_WIN) && !defined(ARCH_CPU_X86_64) 168 #if defined(OS_WIN) && !defined(ARCH_CPU_X86_64)
95 169
96 // For functions. 170 // For functions.
97 template <typename R, typename... Args> 171 template <typename R, typename... Args>
98 struct FunctorTraits<R(__stdcall*)(Args...)> { 172 struct FunctorTraits<R(__stdcall*)(Args...)> {
99 using RunType = R(Args...); 173 using RunType = R(Args...);
100 static constexpr bool is_method = false; 174 static constexpr bool is_method = false;
175 static constexpr bool is_nullable = true;
101 176
102 template <typename... RunArgs> 177 template <typename... RunArgs>
103 static R Invoke(R(__stdcall* function)(Args...), RunArgs&&... args) { 178 static R Invoke(R(__stdcall* function)(Args...), RunArgs&&... args) {
104 return function(std::forward<RunArgs>(args)...); 179 return function(std::forward<RunArgs>(args)...);
105 } 180 }
106 }; 181 };
107 182
108 // For functions. 183 // For functions.
109 template <typename R, typename... Args> 184 template <typename R, typename... Args>
110 struct FunctorTraits<R(__fastcall*)(Args...)> { 185 struct FunctorTraits<R(__fastcall*)(Args...)> {
111 using RunType = R(Args...); 186 using RunType = R(Args...);
112 static constexpr bool is_method = false; 187 static constexpr bool is_method = false;
188 static constexpr bool is_nullable = true;
113 189
114 template <typename... RunArgs> 190 template <typename... RunArgs>
115 static R Invoke(R(__fastcall* function)(Args...), RunArgs&&... args) { 191 static R Invoke(R(__fastcall* function)(Args...), RunArgs&&... args) {
116 return function(std::forward<RunArgs>(args)...); 192 return function(std::forward<RunArgs>(args)...);
117 } 193 }
118 }; 194 };
119 195
120 #endif // defined(OS_WIN) && !defined(ARCH_CPU_X86_64) 196 #endif // defined(OS_WIN) && !defined(ARCH_CPU_X86_64)
121 197
122 // For methods. 198 // For methods.
123 template <typename R, typename Receiver, typename... Args> 199 template <typename R, typename Receiver, typename... Args>
124 struct FunctorTraits<R (Receiver::*)(Args...)> { 200 struct FunctorTraits<R (Receiver::*)(Args...)> {
125 using RunType = R(Receiver*, Args...); 201 using RunType = R(Receiver*, Args...);
126 static constexpr bool is_method = true; 202 static constexpr bool is_method = true;
203 static constexpr bool is_nullable = true;
127 204
128 template <typename ReceiverPtr, typename... RunArgs> 205 template <typename ReceiverPtr, typename... RunArgs>
129 static R Invoke(R (Receiver::*method)(Args...), 206 static R Invoke(R (Receiver::*method)(Args...),
130 ReceiverPtr&& receiver_ptr, 207 ReceiverPtr&& receiver_ptr,
131 RunArgs&&... args) { 208 RunArgs&&... args) {
132 // Clang skips CV qualifier check on a method pointer invocation when the 209 // 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 210 // receiver is a subclass. Store the receiver into a const reference to
134 // T to ensure the CV check works. 211 // T to ensure the CV check works.
135 // https://llvm.org/bugs/show_bug.cgi?id=27037 212 // https://llvm.org/bugs/show_bug.cgi?id=27037
136 Receiver& receiver = *receiver_ptr; 213 Receiver& receiver = *receiver_ptr;
137 return (receiver.*method)(std::forward<RunArgs>(args)...); 214 return (receiver.*method)(std::forward<RunArgs>(args)...);
138 } 215 }
139 }; 216 };
140 217
141 // For const methods. 218 // For const methods.
142 template <typename R, typename Receiver, typename... Args> 219 template <typename R, typename Receiver, typename... Args>
143 struct FunctorTraits<R (Receiver::*)(Args...) const> { 220 struct FunctorTraits<R (Receiver::*)(Args...) const> {
144 using RunType = R(const Receiver*, Args...); 221 using RunType = R(const Receiver*, Args...);
145 static constexpr bool is_method = true; 222 static constexpr bool is_method = true;
223 static constexpr bool is_nullable = true;
146 224
147 template <typename ReceiverPtr, typename... RunArgs> 225 template <typename ReceiverPtr, typename... RunArgs>
148 static R Invoke(R (Receiver::*method)(Args...) const, 226 static R Invoke(R (Receiver::*method)(Args...) const,
149 ReceiverPtr&& receiver_ptr, 227 ReceiverPtr&& receiver_ptr,
150 RunArgs&&... args) { 228 RunArgs&&... args) {
151 // Clang skips CV qualifier check on a method pointer invocation when the 229 // 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 230 // receiver is a subclass. Store the receiver into a const reference to
153 // T to ensure the CV check works. 231 // T to ensure the CV check works.
154 // https://llvm.org/bugs/show_bug.cgi?id=27037 232 // https://llvm.org/bugs/show_bug.cgi?id=27037
155 const Receiver& receiver = *receiver_ptr; 233 const Receiver& receiver = *receiver_ptr;
(...skipping 13 matching lines...) Expand all
169 FunctorTraits<T>::Invoke(ignore_result_helper.functor_, 247 FunctorTraits<T>::Invoke(ignore_result_helper.functor_,
170 std::forward<RunArgs>(args)...); 248 std::forward<RunArgs>(args)...);
171 } 249 }
172 }; 250 };
173 251
174 // For Callbacks. 252 // For Callbacks.
175 template <typename R, typename... Args, CopyMode copy_mode> 253 template <typename R, typename... Args, CopyMode copy_mode>
176 struct FunctorTraits<Callback<R(Args...), copy_mode>> { 254 struct FunctorTraits<Callback<R(Args...), copy_mode>> {
177 using RunType = R(Args...); 255 using RunType = R(Args...);
178 static constexpr bool is_method = false; 256 static constexpr bool is_method = false;
257 static constexpr bool is_nullable = true;
179 258
180 template <typename CallbackType, typename... RunArgs> 259 template <typename CallbackType, typename... RunArgs>
181 static R Invoke(CallbackType&& callback, RunArgs&&... args) { 260 static R Invoke(CallbackType&& callback, RunArgs&&... args) {
182 DCHECK(!callback.is_null()); 261 DCHECK(!callback.is_null());
183 return std::forward<CallbackType>(callback).Run( 262 return std::forward<CallbackType>(callback).Run(
184 std::forward<RunArgs>(args)...); 263 std::forward<RunArgs>(args)...);
185 } 264 }
186 }; 265 };
187 266
188 // InvokeHelper<> 267 // InvokeHelper<>
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 // Used to implement MakeUnboundRunType. 353 // Used to implement MakeUnboundRunType.
275 template <typename Functor, typename... BoundArgs> 354 template <typename Functor, typename... BoundArgs>
276 struct MakeUnboundRunTypeImpl { 355 struct MakeUnboundRunTypeImpl {
277 using RunType = 356 using RunType =
278 typename FunctorTraits<typename std::decay<Functor>::type>::RunType; 357 typename FunctorTraits<typename std::decay<Functor>::type>::RunType;
279 using ReturnType = ExtractReturnType<RunType>; 358 using ReturnType = ExtractReturnType<RunType>;
280 using Args = ExtractArgs<RunType>; 359 using Args = ExtractArgs<RunType>;
281 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), Args>; 360 using UnboundArgs = DropTypeListItem<sizeof...(BoundArgs), Args>;
282 using Type = MakeFunctionType<ReturnType, UnboundArgs>; 361 using Type = MakeFunctionType<ReturnType, UnboundArgs>;
283 }; 362 };
363 template <typename Functor>
364 typename std::enable_if<FunctorTraits<Functor>::is_nullable, bool>::type
365 IsNull(const Functor& functor) {
366 return !functor;
367 }
368
369 template <typename Functor>
370 typename std::enable_if<!FunctorTraits<Functor>::is_nullable, bool>::type
371 IsNull(const Functor&) {
372 return false;
373 }
284 374
285 // BindState<> 375 // BindState<>
286 // 376 //
287 // This stores all the state passed into Bind(). 377 // This stores all the state passed into Bind().
288 template <typename Functor, typename... BoundArgs> 378 template <typename Functor, typename... BoundArgs>
289 struct BindState final : BindStateBase { 379 struct BindState final : BindStateBase {
290 template <typename... ForwardBoundArgs> 380 template <typename... ForwardBoundArgs>
291 explicit BindState(Functor functor, ForwardBoundArgs&&... bound_args) 381 explicit BindState(Functor functor, ForwardBoundArgs&&... bound_args)
292 : BindStateBase(&Destroy), 382 : BindStateBase(&Destroy),
293 functor_(std::move(functor)), 383 functor_(std::move(functor)),
294 bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) { 384 bound_args_(std::forward<ForwardBoundArgs>(bound_args)...) {
295 DCHECK(functor_); 385 DCHECK(!IsNull(functor_));
296 } 386 }
297 387
298 Functor functor_; 388 Functor functor_;
299 std::tuple<BoundArgs...> bound_args_; 389 std::tuple<BoundArgs...> bound_args_;
300 390
301 private: 391 private:
302 ~BindState() {} 392 ~BindState() {}
303 393
304 static void Destroy(BindStateBase* self) { 394 static void Destroy(BindStateBase* self) {
305 delete static_cast<BindState*>(self); 395 delete static_cast<BindState*>(self);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 444
355 // Returns a RunType of bound functor. 445 // Returns a RunType of bound functor.
356 // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C). 446 // E.g. MakeUnboundRunType<R(A, B, C), A, B> is evaluated to R(C).
357 template <typename Functor, typename... BoundArgs> 447 template <typename Functor, typename... BoundArgs>
358 using MakeUnboundRunType = 448 using MakeUnboundRunType =
359 typename internal::MakeUnboundRunTypeImpl<Functor, BoundArgs...>::Type; 449 typename internal::MakeUnboundRunTypeImpl<Functor, BoundArgs...>::Type;
360 450
361 } // namespace base 451 } // namespace base
362 452
363 #endif // BASE_BIND_INTERNAL_H_ 453 #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