//===- FunctionExtras.h - Function type erasure utilities -------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file /// This file provides a collection of function (or more generally, callable) /// type erasure utilities supplementing those provided by the standard library /// in `<function>`. /// /// It provides `unique_function`, which works like `std::function` but supports /// move-only callable objects and const-qualification. /// /// Future plans: /// - Add a `function` that provides ref-qualified support, which doesn't work /// with `std::function`. /// - Provide support for specifying multiple signatures to type erase callable /// objects with an overload set, such as those produced by generic lambdas. /// - Expand to include a copyable utility that directly replaces std::function /// but brings the above improvements. /// /// Note that LLVM's utilities are greatly simplified by not supporting /// allocators. /// /// If the standard library ever begins to provide comparable facilities we can /// consider switching to those. /// //===----------------------------------------------------------------------===// #ifndef LLVM_ADT_FUNCTIONEXTRAS_H #define LLVM_ADT_FUNCTIONEXTRAS_H #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/STLForwardCompat.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/MemAlloc.h" #include "llvm/Support/type_traits.h" #include <cstring> #include <memory> #include <type_traits> namespace llvm { /// unique_function is a type-erasing functor similar to std::function. /// /// It can hold move-only function objects, like lambdas capturing unique_ptrs. /// Accordingly, it is movable but not copyable. /// /// It supports const-qualification: /// - unique_function<int() const> has a const operator(). /// It can only hold functions which themselves have a const operator(). /// - unique_function<int()> has a non-const operator(). /// It can hold functions with a non-const operator(), like mutable lambdas. template <typename FunctionT> class unique_function; namespace detail { EnableIfTrivial; EnableUnlessSameType; EnableIfCallable; template <typename ReturnT, typename... ParamTs> class UniqueFunctionBase { … }; template <typename R, typename... P> template <typename CallableT, typename CalledAsT, typename Enable> typename UniqueFunctionBase<R, P...>::NonTrivialCallbacks UniqueFunctionBase< R, P...>::CallbacksHolder<CallableT, CalledAsT, Enable>::Callbacks = …; template <typename R, typename... P> template <typename CallableT, typename CalledAsT> typename UniqueFunctionBase<R, P...>::TrivialCallback UniqueFunctionBase<R, P...>::CallbacksHolder< CallableT, CalledAsT, EnableIfTrivial<CallableT>>::Callbacks{ … }; } // namespace detail unique_function<R (P...)>; unique_function<R (P...) const>; } // end namespace llvm #endif // LLVM_ADT_FUNCTIONEXTRAS_H