• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Flutter 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 FLUTTER_FML_MAKE_COPYABLE_H_
6 #define FLUTTER_FML_MAKE_COPYABLE_H_
7 
8 #include <utility>
9 
10 #include "flutter/fml/memory/ref_counted.h"
11 #include "flutter/fml/memory/ref_ptr.h"
12 
13 namespace fml {
14 namespace internal {
15 
16 template <typename T>
17 class CopyableLambda {
18  public:
CopyableLambda(T func)19   explicit CopyableLambda(T func)
20       : impl_(MakeRefCounted<Impl>(std::move(func))) {}
21 
22   template <typename... ArgType>
operator()23   auto operator()(ArgType&&... args) const {
24     return impl_->func_(std::forward<ArgType>(args)...);
25   }
26 
27  private:
28   class Impl : public RefCountedThreadSafe<Impl> {
29    public:
Impl(T func)30     explicit Impl(T func) : func_(std::move(func)) {}
31     T func_;
32   };
33 
34   RefPtr<Impl> impl_;
35 };
36 
37 }  // namespace internal
38 
39 // Provides a wrapper for a move-only lambda that is implictly convertable to an
40 // std::function.
41 //
42 // std::function is copyable, but if a lambda captures an argument with a
43 // move-only type, the lambda itself is not copyable. In order to use the lambda
44 // in places that accept std::functions, we provide a copyable object that wraps
45 // the lambda and is implicitly convertable to an std::function.
46 //
47 // EXAMPLE:
48 //
49 // std::unique_ptr<Foo> foo = ...
50 // std::function<int()> func =
51 //     fml::MakeCopyable([bar = std::move(foo)]() { return bar->count(); });
52 //
53 // Notice that the return type of MakeCopyable is rarely used directly. Instead,
54 // callers typically erase the type by implicitly converting the return value
55 // to an std::function.
56 template <typename T>
MakeCopyable(T lambda)57 internal::CopyableLambda<T> MakeCopyable(T lambda) {
58   return internal::CopyableLambda<T>(std::move(lambda));
59 }
60 
61 }  // namespace fml
62 
63 #endif  // FLUTTER_FML_MAKE_COPYABLE_H_
64