Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:09

0001 //===- llvm/ADT/STLFunctionalExtras.h - Extras for <functional> -*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file contains some extension to <functional>.
0010 //
0011 // No library is required when using these functions.
0012 //
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_ADT_STLFUNCTIONALEXTRAS_H
0016 #define LLVM_ADT_STLFUNCTIONALEXTRAS_H
0017 
0018 #include "llvm/ADT/STLForwardCompat.h"
0019 #include "llvm/Support/Compiler.h"
0020 
0021 #include <cstdint>
0022 #include <type_traits>
0023 #include <utility>
0024 
0025 namespace llvm {
0026 
0027 //===----------------------------------------------------------------------===//
0028 //     Extra additions to <functional>
0029 //===----------------------------------------------------------------------===//
0030 
0031 /// An efficient, type-erasing, non-owning reference to a callable. This is
0032 /// intended for use as the type of a function parameter that is not used
0033 /// after the function in question returns.
0034 ///
0035 /// This class does not own the callable, so it is not in general safe to store
0036 /// a function_ref.
0037 template<typename Fn> class function_ref;
0038 
0039 template <typename Ret, typename... Params>
0040 class LLVM_GSL_POINTER function_ref<Ret(Params...)> {
0041   Ret (*callback)(intptr_t callable, Params ...params) = nullptr;
0042   intptr_t callable;
0043 
0044   template<typename Callable>
0045   static Ret callback_fn(intptr_t callable, Params ...params) {
0046     return (*reinterpret_cast<Callable*>(callable))(
0047         std::forward<Params>(params)...);
0048   }
0049 
0050 public:
0051   function_ref() = default;
0052   function_ref(std::nullptr_t) {}
0053 
0054   template <typename Callable>
0055   function_ref(
0056       Callable &&callable LLVM_LIFETIME_BOUND,
0057       // This is not the copy-constructor.
0058       std::enable_if_t<!std::is_same<remove_cvref_t<Callable>,
0059                                      function_ref>::value> * = nullptr,
0060       // Functor must be callable and return a suitable type.
0061       std::enable_if_t<std::is_void<Ret>::value ||
0062                        std::is_convertible<decltype(std::declval<Callable>()(
0063                                                std::declval<Params>()...)),
0064                                            Ret>::value> * = nullptr)
0065       : callback(callback_fn<std::remove_reference_t<Callable>>),
0066         callable(reinterpret_cast<intptr_t>(&callable)) {}
0067 
0068   Ret operator()(Params ...params) const {
0069     return callback(callable, std::forward<Params>(params)...);
0070   }
0071 
0072   explicit operator bool() const { return callback; }
0073 
0074   bool operator==(const function_ref<Ret(Params...)> &Other) const {
0075     return callable == Other.callable;
0076   }
0077 };
0078 
0079 } // end namespace llvm
0080 
0081 #endif // LLVM_ADT_STLFUNCTIONALEXTRAS_H