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)57internal::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