Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef BASE_FUNCTION_UTIL_H_ | |
| 6 #define BASE_FUNCTION_UTIL_H_ | |
| 7 | |
| 8 #include <utility> | |
| 9 | |
| 10 #include "base/bind.h" | |
| 11 #include "base/callback.h" | |
| 12 | |
| 13 namespace base { | |
| 14 | |
| 15 namespace internal { | |
| 16 | |
| 17 template <typename FuncType, typename Result, typename... Args> | |
| 18 struct FunctionBinderHelper { | |
| 19 static Result Run(FuncType func, Args... args) { | |
|
yzshen1
2016/06/22 23:05:54
Do we need Args&&... (here and below)?
Ken Rockot(use gerrit already)
2016/06/22 23:14:43
This wouldn't work - we can't for example base::Bi
| |
| 20 return func(std::forward<Args>(args)...); | |
| 21 } | |
| 22 }; | |
| 23 | |
| 24 template <typename FuncType, typename... Args> | |
| 25 struct FunctionBinderHelper<FuncType, void, Args...> { | |
| 26 static void Run(FuncType func, Args... args) { | |
| 27 func(std::forward<Args>(args)...); | |
| 28 } | |
| 29 }; | |
| 30 | |
| 31 template <typename CallbackType> | |
| 32 struct FunctionBinder {}; | |
| 33 | |
| 34 template <typename ResultType, typename... Args> | |
| 35 struct FunctionBinder<Callback<ResultType(Args...)>> { | |
| 36 template <typename FuncType> | |
| 37 static Callback<ResultType(Args...)> BindFunction(FuncType func) { | |
| 38 return Bind( | |
| 39 &FunctionBinderHelper<FuncType, ResultType, Args...>::Run, func); | |
| 40 } | |
| 41 }; | |
| 42 | |
| 43 } // namespace internal | |
| 44 | |
| 45 // Wraps an arbitrary function as a base::Callback. Note that this requires an | |
| 46 // explicit specification of the target base::Callback type, but the wrapped | |
| 47 // function type can be inferred and thus supports wrapping C++11 lambdas. | |
| 48 // | |
| 49 // For example: | |
| 50 // | |
| 51 // using AddCallback = base::Callback<int(int x, int y)>; | |
| 52 // AddCallback cb = base::WrapLambda<AddCallback>([](int x, int y) { | |
| 53 // return x + y; | |
| 54 // }); | |
| 55 // int z = cb.Run(x, y); | |
| 56 // | |
| 57 // NOTE: Do NOT wrap lambdas which capture references of any kind unless it is | |
| 58 // abundantly clear that this will not lead to subtle bugs, e.g., the wrapped | |
| 59 // callback cannot possibly outlive the captured references. | |
| 60 template <typename CallbackType, typename FuncType> | |
| 61 CallbackType WrapFunction(FuncType func) { | |
| 62 return internal::FunctionBinder<CallbackType>::BindFunction(func); | |
| 63 } | |
| 64 | |
| 65 } // namespace base | |
| 66 | |
| 67 #endif // BASE_FUNCTION_UTIL_H_ | |
| OLD | NEW |