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