blob: 889c55fe310a5b99b798c393f92a5620c11b7a75 [file] [log] [blame]
// Copyright 2018 The Chromium OS 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 DIAGNOSTICS_DPSL_INTERNAL_CALLBACK_UTILS_H_
#define DIAGNOSTICS_DPSL_INTERNAL_CALLBACK_UTILS_H_
#include <functional>
#include <utility>
#include <base/bind.h>
#include <base/callback.h>
#include <base/location.h>
#include <base/memory/ref_counted.h>
#include <base/task_runner.h>
#include <base/threading/thread_task_runner_handle.h>
#include <grpcpp/grpcpp.h>
namespace diagnostics {
// A function that transforms base::Callback into std::function
template <typename ReturnType, typename... ArgType>
inline std::function<ReturnType(ArgType...)> MakeStdFunctionFromCallback(
base::Callback<ReturnType(ArgType...)> callback) {
return [callback](ArgType&&... args) {
return callback.Run(std::forward<ArgType>(args)...);
};
}
// A function that transforms base::Callback into std::function, and
// automatically adds grpc::Status::OK
template <typename ReturnType, typename... ArgType>
inline std::function<ReturnType(ArgType...)> MakeStdFunctionFromCallbackGrpc(
base::Callback<ReturnType(grpc::Status, ArgType...)> callback) {
return [callback](ArgType&&... args) {
return callback.Run(grpc::Status::OK, std::forward<ArgType>(args)...);
};
}
namespace internal {
template <typename ReturnType, typename... ArgTypes>
inline ReturnType RunStdFunctionWithArgs(
std::function<ReturnType(ArgTypes...)> function, ArgTypes... args) {
return function(std::forward<ArgTypes>(args)...);
}
template <typename ReturnType, typename... ArgTypes>
inline ReturnType RunStdFunctionWithArgsGrpc(
std::function<ReturnType(ArgTypes...)> function,
grpc::Status status,
ArgTypes... args) {
return function(std::forward<ArgTypes>(args)...);
}
} // namespace internal
// Transforms std::function into base::Callback.
template <typename ReturnType, typename... ArgTypes>
inline base::Callback<ReturnType(ArgTypes...)> MakeCallbackFromStdFunction(
std::function<ReturnType(ArgTypes...)> function) {
return base::Bind(&internal::RunStdFunctionWithArgs<ReturnType, ArgTypes...>,
base::Passed(std::move(function)));
}
// Transforms std::function into base::Callback, and ignores grpc::Status
template <typename ReturnType, typename... ArgTypes>
inline base::Callback<ReturnType(grpc::Status, ArgTypes...)>
MakeCallbackFromStdFunctionGrpc(
std::function<ReturnType(ArgTypes...)> function) {
return base::Bind(
&internal::RunStdFunctionWithArgsGrpc<ReturnType, ArgTypes...>,
base::Passed(std::move(function)));
}
namespace internal {
template <typename... ArgTypes>
inline void RunCallbackOnTaskRunner(scoped_refptr<base::TaskRunner> task_runner,
const base::Location& location,
base::Callback<void(ArgTypes...)> callback,
ArgTypes... args) {
task_runner->PostTask(location, base::Bind(std::move(callback),
base::Passed(std::move(args))...));
}
} // namespace internal
// Returns a callback that remembers the current task runner and, when called,
// posts |callback| to it (with all arguments forwarded).
template <typename... ArgTypes>
inline base::Callback<void(ArgTypes...)> MakeOriginTaskRunnerPostingCallback(
const base::Location& location,
base::Callback<void(ArgTypes...)> callback) {
return base::Bind(&internal::RunCallbackOnTaskRunner<ArgTypes...>,
base::ThreadTaskRunnerHandle::Get(), location,
std::move(callback));
}
} // namespace diagnostics
#endif // DIAGNOSTICS_DPSL_INTERNAL_CALLBACK_UTILS_H_