| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef FLUTTER_FML_MAKE_COPYABLE_H_ |
| #define FLUTTER_FML_MAKE_COPYABLE_H_ |
| |
| #include <utility> |
| |
| #include "flutter/fml/memory/ref_counted.h" |
| #include "flutter/fml/memory/ref_ptr.h" |
| |
| namespace fml { |
| namespace internal { |
| |
| template <typename T> |
| class CopyableLambda { |
| public: |
| explicit CopyableLambda(T func) |
| : impl_(MakeRefCounted<Impl>(std::move(func))) {} |
| |
| template <typename... ArgType> |
| auto operator()(ArgType&&... args) const { |
| return impl_->func_(std::forward<ArgType>(args)...); |
| } |
| |
| private: |
| class Impl : public RefCountedThreadSafe<Impl> { |
| public: |
| explicit Impl(T func) : func_(std::move(func)) {} |
| T func_; |
| }; |
| |
| RefPtr<Impl> impl_; |
| }; |
| |
| } // namespace internal |
| |
| // Provides a wrapper for a move-only lambda that is implictly convertable to an |
| // std::function. |
| // |
| // std::function is copyable, but if a lambda captures an argument with a |
| // move-only type, the lambda itself is not copyable. In order to use the lambda |
| // in places that accept std::functions, we provide a copyable object that wraps |
| // the lambda and is implicitly convertable to an std::function. |
| // |
| // EXAMPLE: |
| // |
| // std::unique_ptr<Foo> foo = ... |
| // std::function<int()> func = |
| // fml::MakeCopyable([bar = std::move(foo)]() { return bar->count(); }); |
| // |
| // Notice that the return type of MakeCopyable is rarely used directly. Instead, |
| // callers typically erase the type by implicitly converting the return value |
| // to an std::function. |
| template <typename T> |
| internal::CopyableLambda<T> MakeCopyable(T lambda) { |
| return internal::CopyableLambda<T>(std::move(lambda)); |
| } |
| |
| } // namespace fml |
| |
| #endif // FLUTTER_FML_MAKE_COPYABLE_H_ |