1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 #ifndef SUPPORT_TYPE_ID_H 10 #define SUPPORT_TYPE_ID_H 11 12 #include <functional> 13 #include <typeinfo> 14 #include <string> 15 #include <cstdio> 16 #include <cassert> 17 18 #include "test_macros.h" 19 #include "demangle.h" 20 21 #if TEST_STD_VER < 11 22 #error This header requires C++11 or greater 23 #endif 24 25 // TypeID - Represent a unique identifier for a type. TypeID allows equality 26 // comparisons between different types. 27 struct TypeID { 28 friend bool operator==(TypeID const& LHS, TypeID const& RHS) 29 {return LHS.m_id == RHS.m_id; } 30 friend bool operator!=(TypeID const& LHS, TypeID const& RHS) 31 {return LHS.m_id != RHS.m_id; } 32 33 std::string name() const { 34 return demangle(m_id); 35 } 36 37 void dump() const { 38 std::string s = name(); 39 std::printf("TypeID: %s\n", s.c_str()); 40 } 41 42 private: 43 explicit constexpr TypeID(const char* xid) : m_id(xid) {} 44 45 TypeID(const TypeID&) = delete; 46 TypeID& operator=(TypeID const&) = delete; 47 48 const char* const m_id; 49 template <class T> friend TypeID const& makeTypeIDImp(); 50 }; 51 52 // makeTypeID - Return the TypeID for the specified type 'T'. 53 template <class T> 54 inline TypeID const& makeTypeIDImp() { 55 static const TypeID id(typeid(T).name()); 56 return id; 57 } 58 59 template <class T> 60 struct TypeWrapper {}; 61 62 template <class T> 63 inline TypeID const& makeTypeID() { 64 return makeTypeIDImp<TypeWrapper<T>>(); 65 } 66 67 template <class ...Args> 68 struct ArgumentListID {}; 69 70 // makeArgumentID - Create and return a unique identifier for a given set 71 // of arguments. 72 template <class ...Args> 73 inline TypeID const& makeArgumentID() { 74 return makeTypeIDImp<ArgumentListID<Args...>>(); 75 } 76 77 78 // COMPARE_TYPEID(...) is a utility macro for generating diagnostics when 79 // two typeid's are expected to be equal 80 #define COMPARE_TYPEID(LHS, RHS) CompareTypeIDVerbose(#LHS, LHS, #RHS, RHS) 81 82 inline bool CompareTypeIDVerbose(const char* LHSString, TypeID const* LHS, 83 const char* RHSString, TypeID const* RHS) { 84 if (*LHS == *RHS) 85 return true; 86 std::printf("TypeID's not equal:\n"); 87 std::printf("%s: %s\n----------\n%s: %s\n", 88 LHSString, LHS->name().c_str(), 89 RHSString, RHS->name().c_str()); 90 return false; 91 } 92 93 #endif // SUPPORT_TYPE_ID_H 94