1 // -*- C++ -*- 2 //===-------------------------- typeinfo ----------------------------------===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is dual licensed under the MIT and the University of Illinois Open 7 // Source Licenses. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 11 #ifndef __LIBCPP_TYPEINFO 12 #define __LIBCPP_TYPEINFO 13 14 /* 15 16 typeinfo synopsis 17 18 namespace std { 19 20 class type_info 21 { 22 public: 23 virtual ~type_info(); 24 25 bool operator==(const type_info& rhs) const noexcept; 26 bool operator!=(const type_info& rhs) const noexcept; 27 28 bool before(const type_info& rhs) const noexcept; 29 size_t hash_code() const noexcept; 30 const char* name() const noexcept; 31 32 type_info(const type_info& rhs) = delete; 33 type_info& operator=(const type_info& rhs) = delete; 34 }; 35 36 class bad_cast 37 : public exception 38 { 39 public: 40 bad_cast() noexcept; 41 bad_cast(const bad_cast&) noexcept; 42 bad_cast& operator=(const bad_cast&) noexcept; 43 virtual const char* what() const noexcept; 44 }; 45 46 class bad_typeid 47 : public exception 48 { 49 public: 50 bad_typeid() noexcept; 51 bad_typeid(const bad_typeid&) noexcept; 52 bad_typeid& operator=(const bad_typeid&) noexcept; 53 virtual const char* what() const noexcept; 54 }; 55 56 } // std 57 58 */ 59 60 #include <__config> 61 #include <exception> 62 #include <cstddef> 63 #include <cstdint> 64 65 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 66 #pragma GCC system_header 67 #endif 68 69 namespace std // purposefully not using versioning namespace 70 { 71 72 class _LIBCPP_EXCEPTION_ABI type_info 73 { 74 type_info& operator=(const type_info&); 75 type_info(const type_info&); 76 protected: 77 #ifndef _LIBCPP_NONUNIQUE_RTTI_BIT 78 const char* __type_name; 79 #else 80 // A const char* with the non-unique RTTI bit possibly set. 81 uintptr_t __type_name; 82 #endif 83 84 _LIBCPP_INLINE_VISIBILITY 85 explicit type_info(const char* __n) 86 #ifndef _LIBCPP_NONUNIQUE_RTTI_BIT 87 : __type_name(__n) {} 88 #else 89 : __type_name(reinterpret_cast<uintptr_t>(__n)) {} 90 #endif 91 92 public: 93 virtual ~type_info(); 94 95 _LIBCPP_INLINE_VISIBILITY 96 const char* name() const _NOEXCEPT 97 #ifndef _LIBCPP_NONUNIQUE_RTTI_BIT 98 {return __type_name;} 99 #else 100 {return reinterpret_cast<const char*>(__type_name & ~_LIBCPP_NONUNIQUE_RTTI_BIT);} 101 #endif 102 103 _LIBCPP_INLINE_VISIBILITY 104 bool before(const type_info& __arg) const _NOEXCEPT 105 #ifndef _LIBCPP_NONUNIQUE_RTTI_BIT 106 {return __type_name < __arg.__type_name;} 107 #else 108 {if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT)) 109 return __type_name < __arg.__type_name; 110 return __compare_nonunique_names(__arg) < 0;} 111 #endif 112 113 _LIBCPP_INLINE_VISIBILITY 114 size_t hash_code() const _NOEXCEPT 115 #ifndef _LIBCPP_NONUNIQUE_RTTI_BIT 116 {return *reinterpret_cast<const size_t*>(&__type_name);} 117 #else 118 {if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT)) return __type_name; 119 const char *__ptr = name(); 120 size_t __hash = 5381; 121 while (unsigned char __c = static_cast<unsigned char>(*__ptr++)) 122 __hash = (__hash * 33) ^ __c; 123 return __hash;} 124 #endif 125 126 _LIBCPP_INLINE_VISIBILITY 127 bool operator==(const type_info& __arg) const _NOEXCEPT 128 #ifndef _LIBCPP_NONUNIQUE_RTTI_BIT 129 {return __type_name == __arg.__type_name;} 130 #else 131 {if (__type_name == __arg.__type_name) return true; 132 if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT)) 133 return false; 134 return __compare_nonunique_names(__arg) == 0;} 135 #endif 136 _LIBCPP_INLINE_VISIBILITY 137 bool operator!=(const type_info& __arg) const _NOEXCEPT 138 {return !operator==(__arg);} 139 140 #ifdef _LIBCPP_NONUNIQUE_RTTI_BIT 141 private: 142 _LIBCPP_INLINE_VISIBILITY 143 int __compare_nonunique_names(const type_info &__arg) const _NOEXCEPT 144 {return __builtin_strcmp(name(), __arg.name());} 145 #endif 146 }; 147 148 class _LIBCPP_EXCEPTION_ABI bad_cast 149 : public exception 150 { 151 public: 152 bad_cast() _NOEXCEPT; 153 virtual ~bad_cast() _NOEXCEPT; 154 virtual const char* what() const _NOEXCEPT; 155 }; 156 157 class _LIBCPP_EXCEPTION_ABI bad_typeid 158 : public exception 159 { 160 public: 161 bad_typeid() _NOEXCEPT; 162 virtual ~bad_typeid() _NOEXCEPT; 163 virtual const char* what() const _NOEXCEPT; 164 }; 165 166 } // std 167 168 #endif // __LIBCPP_TYPEINFO 169