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 #ifdef _LIBCPP_NO_EXCEPTIONS 65 #include <cstdlib> 66 #endif 67 68 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 69 #pragma GCC system_header 70 #endif 71 72 #if defined(_LIBCPP_ABI_MICROSOFT) 73 #include <vcruntime_typeinfo.h> 74 #elif defined(_LIBCPP_NONUNIQUE_RTTI_BIT) 75 #define _LIBCPP_HAS_NONUNIQUE_TYPEINFO 76 #else 77 #define _LIBCPP_HAS_UNIQUE_TYPEINFO 78 #endif 79 80 namespace std // purposefully not using versioning namespace 81 { 82 83 #if !defined(_LIBCPP_ABI_MICROSOFT) 84 class _LIBCPP_EXCEPTION_ABI type_info 85 { 86 type_info& operator=(const type_info&); 87 type_info(const type_info&); 88 89 #if defined(_LIBCPP_HAS_NONUNIQUE_TYPEINFO) 90 _LIBCPP_INLINE_VISIBILITY 91 int __compare_nonunique_names(const type_info &__arg) const _NOEXCEPT 92 { return __builtin_strcmp(name(), __arg.name()); } 93 #endif 94 95 protected: 96 #if defined(_LIBCPP_HAS_NONUNIQUE_TYPEINFO) 97 // A const char* with the non-unique RTTI bit possibly set. 98 uintptr_t __type_name; 99 100 _LIBCPP_INLINE_VISIBILITY 101 explicit type_info(const char* __n) 102 : __type_name(reinterpret_cast<uintptr_t>(__n)) {} 103 #else 104 const char *__type_name; 105 106 _LIBCPP_INLINE_VISIBILITY 107 explicit type_info(const char* __n) : __type_name(__n) {} 108 #endif 109 110 public: 111 _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE 112 virtual ~type_info(); 113 114 #if defined(_LIBCPP_HAS_NONUNIQUE_TYPEINFO) 115 _LIBCPP_INLINE_VISIBILITY 116 const char* name() const _NOEXCEPT 117 { 118 return reinterpret_cast<const char*>(__type_name & 119 ~_LIBCPP_NONUNIQUE_RTTI_BIT); 120 } 121 122 _LIBCPP_INLINE_VISIBILITY 123 bool before(const type_info& __arg) const _NOEXCEPT 124 { 125 if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT)) 126 return __type_name < __arg.__type_name; 127 return __compare_nonunique_names(__arg) < 0; 128 } 129 130 _LIBCPP_INLINE_VISIBILITY 131 size_t hash_code() const _NOEXCEPT 132 { 133 if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT)) 134 return __type_name; 135 136 const char* __ptr = name(); 137 size_t __hash = 5381; 138 while (unsigned char __c = static_cast<unsigned char>(*__ptr++)) 139 __hash = (__hash * 33) ^ __c; 140 return __hash; 141 } 142 143 _LIBCPP_INLINE_VISIBILITY 144 bool operator==(const type_info& __arg) const _NOEXCEPT 145 { 146 if (__type_name == __arg.__type_name) 147 return true; 148 149 if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT)) 150 return false; 151 return __compare_nonunique_names(__arg) == 0; 152 } 153 #else 154 _LIBCPP_INLINE_VISIBILITY 155 const char* name() const _NOEXCEPT 156 { return __type_name; } 157 158 _LIBCPP_INLINE_VISIBILITY 159 bool before(const type_info& __arg) const _NOEXCEPT 160 { return __type_name < __arg.__type_name; } 161 162 _LIBCPP_INLINE_VISIBILITY 163 size_t hash_code() const _NOEXCEPT 164 { return reinterpret_cast<size_t>(__type_name); } 165 166 _LIBCPP_INLINE_VISIBILITY 167 bool operator==(const type_info& __arg) const _NOEXCEPT 168 { return __type_name == __arg.__type_name; } 169 #endif 170 171 _LIBCPP_INLINE_VISIBILITY 172 bool operator!=(const type_info& __arg) const _NOEXCEPT 173 { return !operator==(__arg); } 174 }; 175 176 class _LIBCPP_EXCEPTION_ABI bad_cast 177 : public exception 178 { 179 public: 180 bad_cast() _NOEXCEPT; 181 virtual ~bad_cast() _NOEXCEPT; 182 virtual const char* what() const _NOEXCEPT; 183 }; 184 185 class _LIBCPP_EXCEPTION_ABI bad_typeid 186 : public exception 187 { 188 public: 189 bad_typeid() _NOEXCEPT; 190 virtual ~bad_typeid() _NOEXCEPT; 191 virtual const char* what() const _NOEXCEPT; 192 }; 193 194 #endif // !_LIBCPP_ABI_MICROSOFT 195 196 } // std 197 198 _LIBCPP_BEGIN_NAMESPACE_STD 199 _LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE 200 void __throw_bad_cast() 201 { 202 #ifndef _LIBCPP_NO_EXCEPTIONS 203 throw bad_cast(); 204 #else 205 _VSTD::abort(); 206 #endif 207 } 208 _LIBCPP_END_NAMESPACE_STD 209 210 #endif // __LIBCPP_TYPEINFO 211