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 18namespace std { 19 20class type_info 21{ 22public: 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 36class bad_cast 37 : public exception 38{ 39public: 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 46class bad_typeid 47 : public exception 48{ 49public: 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) && !defined(_LIBCPP_NO_VCRUNTIME) 73#include <vcruntime_typeinfo.h> 74#else 75 76#if defined(_LIBCPP_NONUNIQUE_RTTI_BIT) && !defined(_LIBCPP_ABI_MICROSOFT) 77# define _LIBCPP_HAS_NONUNIQUE_TYPEINFO 78#endif 79 80namespace std // purposefully not using versioning namespace 81{ 82 83class _LIBCPP_EXCEPTION_ABI type_info 84{ 85 type_info& operator=(const type_info&); 86 type_info(const type_info&); 87 88#if defined(_LIBCPP_HAS_NONUNIQUE_TYPEINFO) 89 _LIBCPP_INLINE_VISIBILITY 90 int __compare_nonunique_names(const type_info &__arg) const _NOEXCEPT 91 { return __builtin_strcmp(name(), __arg.name()); } 92#endif 93 94#if defined(_LIBCPP_ABI_MICROSOFT) 95 mutable struct { 96 const char *__undecorated_name; 97 const char __decorated_name[1]; 98 } __data; 99 100 int __compare(const type_info &__rhs) const _NOEXCEPT; 101#endif // _LIBCPP_ABI_MICROSOFT 102 103protected: 104#if !defined(_LIBCPP_ABI_MICROSOFT) 105#if defined(_LIBCPP_HAS_NONUNIQUE_TYPEINFO) 106 // A const char* with the non-unique RTTI bit possibly set. 107 uintptr_t __type_name; 108 109 _LIBCPP_INLINE_VISIBILITY 110 explicit type_info(const char* __n) 111 : __type_name(reinterpret_cast<uintptr_t>(__n)) {} 112#else 113 const char *__type_name; 114 115 _LIBCPP_INLINE_VISIBILITY 116 explicit type_info(const char* __n) : __type_name(__n) {} 117#endif 118#endif // ! _LIBCPP_ABI_MICROSOFT 119 120public: 121 _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE 122 virtual ~type_info(); 123 124#if defined(_LIBCPP_ABI_MICROSOFT) 125 const char *name() const _NOEXCEPT; 126 127 _LIBCPP_INLINE_VISIBILITY 128 bool before(const type_info& __arg) const _NOEXCEPT { 129 return __compare(__arg) < 0; 130 } 131 132 size_t hash_code() const _NOEXCEPT; 133 134 _LIBCPP_INLINE_VISIBILITY 135 bool operator==(const type_info& __arg) const _NOEXCEPT { 136 return __compare(__arg) == 0; 137 } 138#else 139#if defined(_LIBCPP_HAS_NONUNIQUE_TYPEINFO) 140 _LIBCPP_INLINE_VISIBILITY 141 const char* name() const _NOEXCEPT 142 { 143 return reinterpret_cast<const char*>(__type_name & 144 ~_LIBCPP_NONUNIQUE_RTTI_BIT); 145 } 146 147 _LIBCPP_INLINE_VISIBILITY 148 bool before(const type_info& __arg) const _NOEXCEPT 149 { 150 if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT)) 151 return __type_name < __arg.__type_name; 152 return __compare_nonunique_names(__arg) < 0; 153 } 154 155 _LIBCPP_INLINE_VISIBILITY 156 size_t hash_code() const _NOEXCEPT 157 { 158 if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT)) 159 return __type_name; 160 161 const char* __ptr = name(); 162 size_t __hash = 5381; 163 while (unsigned char __c = static_cast<unsigned char>(*__ptr++)) 164 __hash = (__hash * 33) ^ __c; 165 return __hash; 166 } 167 168 _LIBCPP_INLINE_VISIBILITY 169 bool operator==(const type_info& __arg) const _NOEXCEPT 170 { 171 if (__type_name == __arg.__type_name) 172 return true; 173 174 if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT)) 175 return false; 176 return __compare_nonunique_names(__arg) == 0; 177 } 178#else 179 _LIBCPP_INLINE_VISIBILITY 180 const char* name() const _NOEXCEPT 181 { return __type_name; } 182 183 _LIBCPP_INLINE_VISIBILITY 184 bool before(const type_info& __arg) const _NOEXCEPT 185 { return __type_name < __arg.__type_name; } 186 187 _LIBCPP_INLINE_VISIBILITY 188 size_t hash_code() const _NOEXCEPT 189 { return reinterpret_cast<size_t>(__type_name); } 190 191 _LIBCPP_INLINE_VISIBILITY 192 bool operator==(const type_info& __arg) const _NOEXCEPT 193 { return __type_name == __arg.__type_name; } 194#endif 195#endif // _LIBCPP_ABI_MICROSOFT 196 197 _LIBCPP_INLINE_VISIBILITY 198 bool operator!=(const type_info& __arg) const _NOEXCEPT 199 { return !operator==(__arg); } 200}; 201 202class _LIBCPP_EXCEPTION_ABI bad_cast 203 : public exception 204{ 205public: 206 bad_cast() _NOEXCEPT; 207 virtual ~bad_cast() _NOEXCEPT; 208 virtual const char* what() const _NOEXCEPT; 209}; 210 211class _LIBCPP_EXCEPTION_ABI bad_typeid 212 : public exception 213{ 214public: 215 bad_typeid() _NOEXCEPT; 216 virtual ~bad_typeid() _NOEXCEPT; 217 virtual const char* what() const _NOEXCEPT; 218}; 219 220} // std 221 222#endif // defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME) 223 224_LIBCPP_BEGIN_NAMESPACE_STD 225_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY 226void __throw_bad_cast() 227{ 228#ifndef _LIBCPP_NO_EXCEPTIONS 229 throw bad_cast(); 230#else 231 _VSTD::abort(); 232#endif 233} 234_LIBCPP_END_NAMESPACE_STD 235 236#endif // __LIBCPP_TYPEINFO 237