1// Copyright 2014 The Chromium OS 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 LIBBRILLO_BRILLO_BIND_LAMBDA_H_
6#define LIBBRILLO_BRILLO_BIND_LAMBDA_H_
7
8#include <base/bind.h>
9
10////////////////////////////////////////////////////////////////////////////////
11// This file is an extension to base/bind_internal.h and adds a RunnableAdapter
12// class specialization that wraps a functor (including lambda objects), so
13// they can be used in base::Callback/base::Bind constructs.
14// By including this file you will gain the ability to write expressions like:
15//    base::Callback<int(int)> callback = base::Bind([](int value) {
16//      return value * value;
17//    });
18////////////////////////////////////////////////////////////////////////////////
19namespace base {
20namespace internal {
21
22// LambdaAdapter is a helper class that specializes on different function call
23// signatures and provides the RunType and Run() method required by
24// RunnableAdapter<> class.
25template <typename Lambda, typename Sig>
26class LambdaAdapter;
27
28// R(...)
29template <typename Lambda, typename R, typename... Args>
30class LambdaAdapter<Lambda, R(Lambda::*)(Args... args)> {
31 public:
32  typedef R(RunType)(Args...);
33  LambdaAdapter(Lambda lambda) : lambda_(lambda) {}
34  R Run(Args... args) { return lambda_(CallbackForward(args)...); }
35
36 private:
37  Lambda lambda_;
38};
39
40// R(...) const
41template <typename Lambda, typename R, typename... Args>
42class LambdaAdapter<Lambda, R(Lambda::*)(Args... args) const> {
43 public:
44  typedef R(RunType)(Args...);
45  LambdaAdapter(Lambda lambda) : lambda_(lambda) {}
46  R Run(Args... args) { return lambda_(CallbackForward(args)...); }
47
48 private:
49  Lambda lambda_;
50};
51
52template <typename Lambda>
53class RunnableAdapter
54    : public LambdaAdapter<Lambda, decltype(&Lambda::operator())> {
55 public:
56  explicit RunnableAdapter(Lambda lambda)
57      : LambdaAdapter<Lambda, decltype(&Lambda::operator())>(lambda) {}
58};
59
60}  // namespace internal
61}  // namespace base
62
63#endif  // LIBBRILLO_BRILLO_BIND_LAMBDA_H_
64