-
Notifications
You must be signed in to change notification settings - Fork 532
/
Copy pathfunction_ref.h
122 lines (102 loc) · 3.68 KB
/
function_ref.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
//===- llvm/ADT/STLFunctionalExtras.h - Extras for <functional> -*- 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
//
//===----------------------------------------------------------------------===//
//
// This file contains some extension to <functional>.
//
// No library is required when using these functions.
//
//===----------------------------------------------------------------------===//
// Extra additions to <functional>
//===----------------------------------------------------------------------===//
/// An efficient, type-erasing, non-owning reference to a callable. This is
/// intended for use as the type of a function parameter that is not used
/// after the function in question returns.
///
/// This class does not own the callable, so it is not in general safe to store
/// a FunctionRef.
// torch::executor: modified from llvm::function_ref
// - renamed to FunctionRef
// - removed LLVM_GSL_POINTER and LLVM_LIFETIME_BOUND macro uses
// - use namespaced internal::remove_cvref_t
#pragma once
#include <cstdint>
#include <type_traits>
#include <utility>
namespace executorch {
namespace extension {
namespace pytree {
//===----------------------------------------------------------------------===//
// Features from C++20
//===----------------------------------------------------------------------===//
namespace internal {
template <typename T>
struct remove_cvref {
using type =
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
};
template <typename T>
using remove_cvref_t = typename remove_cvref<T>::type;
} // namespace internal
template <typename Fn>
class FunctionRef;
template <typename Ret, typename... Params>
class FunctionRef<Ret(Params...)> {
Ret (*callback)(intptr_t callable, Params... params) = nullptr;
intptr_t callable;
template <typename Callable>
static Ret callback_fn(intptr_t callable, Params... params) {
return (*reinterpret_cast<Callable*>(callable))(
std::forward<Params>(params)...);
}
public:
FunctionRef() = default;
FunctionRef(std::nullptr_t) {}
template <typename Callable>
FunctionRef(
Callable&& callable,
// This is not the copy-constructor.
std::enable_if_t<!std::is_same<
internal::remove_cvref_t<Callable>,
FunctionRef>::value>* = nullptr,
// Functor must be callable and return a suitable type.
std::enable_if_t<
std::is_void<Ret>::value ||
std::is_convertible<
decltype(std::declval<Callable>()(std::declval<Params>()...)),
Ret>::value>* = nullptr)
: callback(callback_fn<std::remove_reference_t<Callable>>),
callable(reinterpret_cast<intptr_t>(&callable)) {}
Ret operator()(Params... params) const {
return callback(callable, std::forward<Params>(params)...);
}
explicit operator bool() const {
return callback;
}
bool operator==(const FunctionRef<Ret(Params...)>& Other) const {
return callable == Other.callable;
}
};
} // namespace pytree
} // namespace extension
} // namespace executorch
namespace torch {
namespace executor {
namespace pytree {
// TODO(T197294990): Remove these deprecated aliases once all users have moved
// to the new `::executorch` namespaces.
using ::executorch::extension::pytree::FunctionRef;
} // namespace pytree
} // namespace executor
} // namespace torch