Chromium Code Reviews| Index: base/function_util.h |
| diff --git a/base/function_util.h b/base/function_util.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1598804aa73e760407413fdef27e505f402becb4 |
| --- /dev/null |
| +++ b/base/function_util.h |
| @@ -0,0 +1,67 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef BASE_FUNCTION_UTIL_H_ |
| +#define BASE_FUNCTION_UTIL_H_ |
| + |
| +#include <utility> |
| + |
| +#include "base/bind.h" |
| +#include "base/callback.h" |
| + |
| +namespace base { |
| + |
| +namespace internal { |
| + |
| +template <typename FuncType, typename Result, typename... Args> |
| +struct FunctionBinderHelper { |
| + 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
|
| + return func(std::forward<Args>(args)...); |
| + } |
| +}; |
| + |
| +template <typename FuncType, typename... Args> |
| +struct FunctionBinderHelper<FuncType, void, Args...> { |
| + static void Run(FuncType func, Args... args) { |
| + func(std::forward<Args>(args)...); |
| + } |
| +}; |
| + |
| +template <typename CallbackType> |
| +struct FunctionBinder {}; |
| + |
| +template <typename ResultType, typename... Args> |
| +struct FunctionBinder<Callback<ResultType(Args...)>> { |
| + template <typename FuncType> |
| + static Callback<ResultType(Args...)> BindFunction(FuncType func) { |
| + return Bind( |
| + &FunctionBinderHelper<FuncType, ResultType, Args...>::Run, func); |
| + } |
| +}; |
| + |
| +} // namespace internal |
| + |
| +// Wraps an arbitrary function as a base::Callback. Note that this requires an |
| +// explicit specification of the target base::Callback type, but the wrapped |
| +// function type can be inferred and thus supports wrapping C++11 lambdas. |
| +// |
| +// For example: |
| +// |
| +// using AddCallback = base::Callback<int(int x, int y)>; |
| +// AddCallback cb = base::WrapLambda<AddCallback>([](int x, int y) { |
| +// return x + y; |
| +// }); |
| +// int z = cb.Run(x, y); |
| +// |
| +// NOTE: Do NOT wrap lambdas which capture references of any kind unless it is |
| +// abundantly clear that this will not lead to subtle bugs, e.g., the wrapped |
| +// callback cannot possibly outlive the captured references. |
| +template <typename CallbackType, typename FuncType> |
| +CallbackType WrapFunction(FuncType func) { |
| + return internal::FunctionBinder<CallbackType>::BindFunction(func); |
| +} |
| + |
| +} // namespace base |
| + |
| +#endif // BASE_FUNCTION_UTIL_H_ |