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 9 namespace c10 { 10 namespace 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. 14 class TORCH_API CppSignature final { 15 public: 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> make()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 name()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 55 private: CppSignature(std::type_index signature)56 explicit CppSignature(std::type_index signature): signature_(std::move(signature)) {} 57 std::type_index signature_; 58 }; 59 60 inline bool operator!=(const CppSignature& lhs, const CppSignature& rhs) { 61 return !(lhs == rhs ); 62 } 63 64 } 65 } 66