1 // Copyright 2015 The Weave 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 LIBWEAVE_SRC_BIND_LAMBDA_H_
6 #define LIBWEAVE_SRC_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 ////////////////////////////////////////////////////////////////////////////////
19 namespace base {
20 namespace 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.
25 template <typename Lambda, typename Sig>
26 class LambdaAdapter;
27 
28 // R(...)
29 template <typename Lambda, typename R, typename... Args>
30 class LambdaAdapter<Lambda, R (Lambda::*)(Args... args)> {
31  public:
32   typedef R(RunType)(Args...);
LambdaAdapter(Lambda lambda)33   LambdaAdapter(Lambda lambda) : lambda_(lambda) {}
Run(Args...args)34   R Run(Args... args) { return lambda_(CallbackForward(args)...); }
35 
36  private:
37   Lambda lambda_;
38 };
39 
40 // R(...) const
41 template <typename Lambda, typename R, typename... Args>
42 class LambdaAdapter<Lambda, R (Lambda::*)(Args... args) const> {
43  public:
44   typedef R(RunType)(Args...);
LambdaAdapter(Lambda lambda)45   LambdaAdapter(Lambda lambda) : lambda_(lambda) {}
Run(Args...args)46   R Run(Args... args) { return lambda_(CallbackForward(args)...); }
47 
48  private:
49   Lambda lambda_;
50 };
51 
52 template <typename Lambda>
53 class RunnableAdapter
54     : public LambdaAdapter<Lambda, decltype(&Lambda::operator())> {
55  public:
RunnableAdapter(Lambda lambda)56   explicit RunnableAdapter(Lambda lambda)
57       : LambdaAdapter<Lambda, decltype(&Lambda::operator())>(lambda) {}
58 };
59 
60 }  // namespace internal
61 }  // namespace base
62 
63 #endif  // LIBWEAVE_SRC_BIND_LAMBDA_H_
64