1*da0073e9SAndroid Build Coastguard Worker //===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===// 2*da0073e9SAndroid Build Coastguard Worker // 3*da0073e9SAndroid Build Coastguard Worker // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*da0073e9SAndroid Build Coastguard Worker // See https://llvm.org/LICENSE.txt for license information. 5*da0073e9SAndroid Build Coastguard Worker // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*da0073e9SAndroid Build Coastguard Worker // 7*da0073e9SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 8*da0073e9SAndroid Build Coastguard Worker // 9*da0073e9SAndroid Build Coastguard Worker // This file contains some templates that are useful if you are working with the 10*da0073e9SAndroid Build Coastguard Worker // STL at all. 11*da0073e9SAndroid Build Coastguard Worker // 12*da0073e9SAndroid Build Coastguard Worker // No library is required when using these functions. 13*da0073e9SAndroid Build Coastguard Worker // 14*da0073e9SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 15*da0073e9SAndroid Build Coastguard Worker 16*da0073e9SAndroid Build Coastguard Worker // c10: modified from llvm::function_ref 17*da0073e9SAndroid Build Coastguard Worker // c10: added more SFINAE to enable use in overloaded functions 18*da0073e9SAndroid Build Coastguard Worker 19*da0073e9SAndroid Build Coastguard Worker #pragma once 20*da0073e9SAndroid Build Coastguard Worker 21*da0073e9SAndroid Build Coastguard Worker #include <cstdint> 22*da0073e9SAndroid Build Coastguard Worker #include <type_traits> 23*da0073e9SAndroid Build Coastguard Worker #include <utility> 24*da0073e9SAndroid Build Coastguard Worker 25*da0073e9SAndroid Build Coastguard Worker namespace c10 { 26*da0073e9SAndroid Build Coastguard Worker 27*da0073e9SAndroid Build Coastguard Worker /// An efficient, type-erasing, non-owning reference to a callable. This is 28*da0073e9SAndroid Build Coastguard Worker /// intended for use as the type of a function parameter that is not used 29*da0073e9SAndroid Build Coastguard Worker /// after the function in question returns. 30*da0073e9SAndroid Build Coastguard Worker /// 31*da0073e9SAndroid Build Coastguard Worker /// This class does not own the callable, so it is not in general safe to store 32*da0073e9SAndroid Build Coastguard Worker /// a function_ref. 33*da0073e9SAndroid Build Coastguard Worker template <typename Fn> 34*da0073e9SAndroid Build Coastguard Worker class function_ref; 35*da0073e9SAndroid Build Coastguard Worker 36*da0073e9SAndroid Build Coastguard Worker template <typename Ret, typename... Params> 37*da0073e9SAndroid Build Coastguard Worker class function_ref<Ret(Params...)> { 38*da0073e9SAndroid Build Coastguard Worker Ret (*callback)(intptr_t callable, Params... params) = nullptr; 39*da0073e9SAndroid Build Coastguard Worker intptr_t callable{}; 40*da0073e9SAndroid Build Coastguard Worker 41*da0073e9SAndroid Build Coastguard Worker template <typename Callable> callback_fn(intptr_t callable,Params...params)42*da0073e9SAndroid Build Coastguard Worker static Ret callback_fn(intptr_t callable, Params... params) { 43*da0073e9SAndroid Build Coastguard Worker return (*reinterpret_cast<Callable*>(callable))( 44*da0073e9SAndroid Build Coastguard Worker std::forward<Params>(params)...); 45*da0073e9SAndroid Build Coastguard Worker } 46*da0073e9SAndroid Build Coastguard Worker 47*da0073e9SAndroid Build Coastguard Worker public: 48*da0073e9SAndroid Build Coastguard Worker function_ref() = default; function_ref(std::nullptr_t)49*da0073e9SAndroid Build Coastguard Worker function_ref(std::nullptr_t) {} 50*da0073e9SAndroid Build Coastguard Worker 51*da0073e9SAndroid Build Coastguard Worker template <typename Callable> 52*da0073e9SAndroid Build Coastguard Worker function_ref( 53*da0073e9SAndroid Build Coastguard Worker // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) 54*da0073e9SAndroid Build Coastguard Worker Callable&& callable, 55*da0073e9SAndroid Build Coastguard Worker std::enable_if_t< 56*da0073e9SAndroid Build Coastguard Worker !std::is_same_v<std::remove_reference_t<Callable>, function_ref>>* = 57*da0073e9SAndroid Build Coastguard Worker nullptr, 58*da0073e9SAndroid Build Coastguard Worker std::enable_if_t<std::is_convertible_v< 59*da0073e9SAndroid Build Coastguard Worker typename std::invoke_result_t<Callable, Params...>, 60*da0073e9SAndroid Build Coastguard Worker Ret>>* = nullptr) callback(callback_fn<std::remove_reference_t<Callable>>)61*da0073e9SAndroid Build Coastguard Worker : callback(callback_fn<std::remove_reference_t<Callable>>), 62*da0073e9SAndroid Build Coastguard Worker callable(reinterpret_cast<intptr_t>(&callable)) {} 63*da0073e9SAndroid Build Coastguard Worker operator()64*da0073e9SAndroid Build Coastguard Worker Ret operator()(Params... params) const { 65*da0073e9SAndroid Build Coastguard Worker return callback(callable, std::forward<Params>(params)...); 66*da0073e9SAndroid Build Coastguard Worker } 67*da0073e9SAndroid Build Coastguard Worker 68*da0073e9SAndroid Build Coastguard Worker operator bool() const { 69*da0073e9SAndroid Build Coastguard Worker return callback; 70*da0073e9SAndroid Build Coastguard Worker } 71*da0073e9SAndroid Build Coastguard Worker }; 72*da0073e9SAndroid Build Coastguard Worker 73*da0073e9SAndroid Build Coastguard Worker } // namespace c10 74