1#pragma once
2
3#include <typeindex>
4#include <c10/core/DispatchKeySet.h>
5#include <c10/macros/Macros.h>
6#include <c10/util/Metaprogramming.h>
7#include <c10/util/Type.h>
8
9namespace c10 {
10namespace impl {
11
12// A CppSignature object holds RTTI information about a C++ function signature at runtime
13// and can compare them or get a debug-printable name.
14class TORCH_API CppSignature final {
15public:
16 CppSignature(const CppSignature&) = default;
17 CppSignature(CppSignature&&) noexcept = default;
18 CppSignature& operator=(const CppSignature&) = default;
19 CppSignature& operator=(CppSignature&&) noexcept = default;
20
21 template<class FuncType>
22 static CppSignature make() {
23 // Normalize functors, lambdas, function pointers, etc. into the plain function type
24 // The first argument of the schema might be of type DispatchKeySet, in which case we remove it.
25 // We do this to guarantee that all CppSignature's for an operator will match, even if they're registered
26 // with different calling conventions.
27 // See Note [Plumbing Keys Through The Dispatcher]
28 using decayed_function_type = typename c10::remove_DispatchKeySet_arg_from_func<std::decay_t<FuncType>>::func_type;
29
30 return CppSignature(std::type_index(typeid(decayed_function_type)));
31 }
32
33 std::string name() const {
34 return c10::demangle(signature_.name());
35 }
36
37 friend bool operator==(const CppSignature& lhs, const CppSignature& rhs) {
38 if (lhs.signature_ == rhs.signature_) {
39 return true;
40 }
41 // Without RTLD_GLOBAL, the type_index comparison could yield false because
42 // they point to different instances of the RTTI data, but the types would
43 // still be the same. Let's check for that case too.
44 // Note that there still is a case where this might not work, i.e. when
45 // linking libraries of different compilers together, they might have
46 // different ways to serialize a type name. That, together with a missing
47 // RTLD_GLOBAL, would still fail this.
48 if (0 == strcmp(lhs.signature_.name(), rhs.signature_.name())) {
49 return true;
50 }
51
52 return false;
53 }
54
55private:
56 explicit CppSignature(std::type_index signature): signature_(std::move(signature)) {}
57 std::type_index signature_;
58};
59
60inline bool operator!=(const CppSignature& lhs, const CppSignature& rhs) {
61 return !(lhs == rhs );
62}
63
64}
65}
66