102864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko// Copyright 2014 The Chromium OS Authors. All rights reserved.
202864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko// Use of this source code is governed by a BSD-style license that can be
302864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko// found in the LICENSE file.
402864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko
5fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#ifndef LIBBRILLO_BRILLO_BIND_LAMBDA_H_
6fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#define LIBBRILLO_BRILLO_BIND_LAMBDA_H_
702864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko
802864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko#include <base/bind.h>
902864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko
1002864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko////////////////////////////////////////////////////////////////////////////////
1102864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko// This file is an extension to base/bind_internal.h and adds a RunnableAdapter
1202864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko// class specialization that wraps a functor (including lambda objects), so
1302864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko// they can be used in base::Callback/base::Bind constructs.
1402864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko// By including this file you will gain the ability to write expressions like:
1502864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko//    base::Callback<int(int)> callback = base::Bind([](int value) {
1602864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko//      return value * value;
1702864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko//    });
1802864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko////////////////////////////////////////////////////////////////////////////////
1902864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenkonamespace base {
2002864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenkonamespace internal {
2102864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko
2202864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko// LambdaAdapter is a helper class that specializes on different function call
2302864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko// signatures and provides the RunType and Run() method required by
2402864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko// RunnableAdapter<> class.
2502864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenkotemplate <typename Lambda, typename Sig>
2602864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenkoclass LambdaAdapter;
2702864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko
2802864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko// R(...)
2902864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenkotemplate <typename Lambda, typename R, typename... Args>
3002864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenkoclass LambdaAdapter<Lambda, R(Lambda::*)(Args... args)> {
3102864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko public:
3202864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko  typedef R(RunType)(Args...);
33253b5b6d35d47ed6b58b0ca1042b7455b0e2fdb2Chih-Hung Hsieh  explicit LambdaAdapter(Lambda lambda) : lambda_(lambda) {}
344ec4c4d2e4f8ac46ea8e767c1ed88242811a8f4dLuis Hector Chavez  R Run(Args... args) { return lambda_(std::forward<Args>(args)...); }
3502864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko
3602864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko private:
3702864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko  Lambda lambda_;
3802864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko};
3902864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko
4002864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko// R(...) const
4102864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenkotemplate <typename Lambda, typename R, typename... Args>
4202864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenkoclass LambdaAdapter<Lambda, R(Lambda::*)(Args... args) const> {
4302864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko public:
4402864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko  typedef R(RunType)(Args...);
45253b5b6d35d47ed6b58b0ca1042b7455b0e2fdb2Chih-Hung Hsieh  explicit LambdaAdapter(Lambda lambda) : lambda_(lambda) {}
464ec4c4d2e4f8ac46ea8e767c1ed88242811a8f4dLuis Hector Chavez  R Run(Args... args) { return lambda_(std::forward<Args>(args)...); }
4702864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko
4802864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko private:
4902864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko  Lambda lambda_;
5002864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko};
5102864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko
5202864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenkotemplate <typename Lambda>
5305d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenkoclass RunnableAdapter
5405d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko    : public LambdaAdapter<Lambda, decltype(&Lambda::operator())> {
5502864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko public:
5605d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko  explicit RunnableAdapter(Lambda lambda)
5705d29044d14a60775ed6c51c75a414eb0cb50347Alex Vakulenko      : LambdaAdapter<Lambda, decltype(&Lambda::operator())>(lambda) {}
5802864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko};
5902864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko
6002864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko}  // namespace internal
6102864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko}  // namespace base
6202864d90819f2fa91cc3932a3a678e866a3bf89dAlex Vakulenko
63fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#endif  // LIBBRILLO_BRILLO_BIND_LAMBDA_H_
64