13e519524SHoward Hinnant// -*- C++ -*- 2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===// 33e519524SHoward Hinnant// 457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information. 657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 73e519524SHoward Hinnant// 83e519524SHoward Hinnant//===----------------------------------------------------------------------===// 93e519524SHoward Hinnant 103e519524SHoward Hinnant#ifndef __LIBCPP_TYPEINFO 113e519524SHoward Hinnant#define __LIBCPP_TYPEINFO 123e519524SHoward Hinnant 133e519524SHoward Hinnant/* 143e519524SHoward Hinnant 153e519524SHoward Hinnant typeinfo synopsis 163e519524SHoward Hinnant 173e519524SHoward Hinnantnamespace std { 183e519524SHoward Hinnant 193e519524SHoward Hinnantclass type_info 203e519524SHoward Hinnant{ 213e519524SHoward Hinnantpublic: 223e519524SHoward Hinnant virtual ~type_info(); 233e519524SHoward Hinnant 24fafca58cSHoward Hinnant bool operator==(const type_info& rhs) const noexcept; 25fafca58cSHoward Hinnant bool operator!=(const type_info& rhs) const noexcept; 263e519524SHoward Hinnant 27fafca58cSHoward Hinnant bool before(const type_info& rhs) const noexcept; 28fafca58cSHoward Hinnant size_t hash_code() const noexcept; 29fafca58cSHoward Hinnant const char* name() const noexcept; 303e519524SHoward Hinnant 313e519524SHoward Hinnant type_info(const type_info& rhs) = delete; 323e519524SHoward Hinnant type_info& operator=(const type_info& rhs) = delete; 333e519524SHoward Hinnant}; 343e519524SHoward Hinnant 353e519524SHoward Hinnantclass bad_cast 363e519524SHoward Hinnant : public exception 373e519524SHoward Hinnant{ 383e519524SHoward Hinnantpublic: 39fafca58cSHoward Hinnant bad_cast() noexcept; 40fafca58cSHoward Hinnant bad_cast(const bad_cast&) noexcept; 41fafca58cSHoward Hinnant bad_cast& operator=(const bad_cast&) noexcept; 42fafca58cSHoward Hinnant virtual const char* what() const noexcept; 433e519524SHoward Hinnant}; 443e519524SHoward Hinnant 453e519524SHoward Hinnantclass bad_typeid 463e519524SHoward Hinnant : public exception 473e519524SHoward Hinnant{ 483e519524SHoward Hinnantpublic: 49fafca58cSHoward Hinnant bad_typeid() noexcept; 50fafca58cSHoward Hinnant bad_typeid(const bad_typeid&) noexcept; 51fafca58cSHoward Hinnant bad_typeid& operator=(const bad_typeid&) noexcept; 52fafca58cSHoward Hinnant virtual const char* what() const noexcept; 533e519524SHoward Hinnant}; 543e519524SHoward Hinnant 553e519524SHoward Hinnant} // std 563e519524SHoward Hinnant 573e519524SHoward Hinnant*/ 583e519524SHoward Hinnant 59*385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler 602eadbc86SLouis Dionne#include <__availability> 61bfbd73f8SArthur O'Dwyer#include <__config> 623e519524SHoward Hinnant#include <cstddef> 630090e657STim Northover#include <cstdint> 64bfbd73f8SArthur O'Dwyer#include <exception> 65e337fb07SEric Fiselier#include <type_traits> 66bfbd73f8SArthur O'Dwyer 67b683ec20SEric Fiselier#ifdef _LIBCPP_NO_EXCEPTIONS 68b683ec20SEric Fiselier#include <cstdlib> 69b683ec20SEric Fiselier#endif 703e519524SHoward Hinnant 71073458b1SHoward Hinnant#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 723e519524SHoward Hinnant# pragma GCC system_header 73073458b1SHoward Hinnant#endif 743e519524SHoward Hinnant 75e69290dcSEric Fiselier#if defined(_LIBCPP_ABI_VCRUNTIME) 761634c15eSPeter Collingbourne#include <vcruntime_typeinfo.h> 771634c15eSPeter Collingbourne#else 781634c15eSPeter Collingbourne 793e519524SHoward Hinnantnamespace std // purposefully not using versioning namespace 803e519524SHoward Hinnant{ 813e519524SHoward Hinnant 822405bd68SEric Fiselier 836b653fc7SLouis Dionne#if defined(_LIBCPP_ABI_MICROSOFT) 846b653fc7SLouis Dionne 85111e0cbeSNick Kledzikclass _LIBCPP_EXCEPTION_ABI type_info 863e519524SHoward Hinnant{ 873e519524SHoward Hinnant type_info& operator=(const type_info&); 883e519524SHoward Hinnant type_info(const type_info&); 89f6ac5650SEric Fiselier 90e7b38cdcSSaleem Abdulrasool mutable struct { 91e7b38cdcSSaleem Abdulrasool const char *__undecorated_name; 92e7b38cdcSSaleem Abdulrasool const char __decorated_name[1]; 93e7b38cdcSSaleem Abdulrasool } __data; 94e7b38cdcSSaleem Abdulrasool 95c3f5cc8eSShoaib Meenai int __compare(const type_info &__rhs) const _NOEXCEPT; 963e519524SHoward Hinnant 973e519524SHoward Hinnantpublic: 98e9c66ad9SMehdi Amini _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE 993e519524SHoward Hinnant virtual ~type_info(); 1003e519524SHoward Hinnant 101e7b38cdcSSaleem Abdulrasool const char *name() const _NOEXCEPT; 102e7b38cdcSSaleem Abdulrasool 103e7b38cdcSSaleem Abdulrasool _LIBCPP_INLINE_VISIBILITY 104e7b38cdcSSaleem Abdulrasool bool before(const type_info& __arg) const _NOEXCEPT { 105e7b38cdcSSaleem Abdulrasool return __compare(__arg) < 0; 106e7b38cdcSSaleem Abdulrasool } 107e7b38cdcSSaleem Abdulrasool 108e7b38cdcSSaleem Abdulrasool size_t hash_code() const _NOEXCEPT; 109e7b38cdcSSaleem Abdulrasool 110e7b38cdcSSaleem Abdulrasool _LIBCPP_INLINE_VISIBILITY 111e7b38cdcSSaleem Abdulrasool bool operator==(const type_info& __arg) const _NOEXCEPT { 112e7b38cdcSSaleem Abdulrasool return __compare(__arg) == 0; 113e7b38cdcSSaleem Abdulrasool } 1146b653fc7SLouis Dionne 1156b653fc7SLouis Dionne _LIBCPP_INLINE_VISIBILITY 1166b653fc7SLouis Dionne bool operator!=(const type_info& __arg) const _NOEXCEPT 1176b653fc7SLouis Dionne { return !operator==(__arg); } 1186b653fc7SLouis Dionne}; 1196b653fc7SLouis Dionne 1202405bd68SEric Fiselier#else // !defined(_LIBCPP_ABI_MICROSOFT) 1216b653fc7SLouis Dionne 1222405bd68SEric Fiselier// ========================================================================== // 1232405bd68SEric Fiselier// Implementations 1242405bd68SEric Fiselier// ========================================================================== // 1252405bd68SEric Fiselier// ------------------------------------------------------------------------- // 1262405bd68SEric Fiselier// Unique 127d0fcdcd2SLouis Dionne// (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION = 1) 1282405bd68SEric Fiselier// ------------------------------------------------------------------------- // 1292405bd68SEric Fiselier// This implementation of type_info assumes a unique copy of the RTTI for a 13017095dc8SLouis Dionne// given type inside a program. This is a valid assumption when abiding to the 1312405bd68SEric Fiselier// Itanium ABI (http://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-components). 1322405bd68SEric Fiselier// Under this assumption, we can always compare the addresses of the type names 1332405bd68SEric Fiselier// to implement equality-comparison of type_infos instead of having to perform 1342405bd68SEric Fiselier// a deep string comparison. 1352405bd68SEric Fiselier// -------------------------------------------------------------------------- // 1362405bd68SEric Fiselier// NonUnique 137d0fcdcd2SLouis Dionne// (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION = 2) 1382405bd68SEric Fiselier// -------------------------------------------------------------------------- // 1392405bd68SEric Fiselier// This implementation of type_info does not assume there is always a unique 1402405bd68SEric Fiselier// copy of the RTTI for a given type inside a program. For various reasons 1412405bd68SEric Fiselier// the linker may have failed to merge every copy of a types RTTI 1422405bd68SEric Fiselier// (For example: -Bsymbolic or llvm.org/PR37398). Under this assumption, two 1432405bd68SEric Fiselier// type_infos are equal if their addresses are equal or if a deep string 1442405bd68SEric Fiselier// comparison is equal. 1452405bd68SEric Fiselier// -------------------------------------------------------------------------- // 1462405bd68SEric Fiselier// NonUniqueARMRTTIBit 147be00e889SLouis Dionne// (_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION = 3) 1482405bd68SEric Fiselier// -------------------------------------------------------------------------- // 1492405bd68SEric Fiselier// This implementation is specific to ARM64 on Apple platforms. 1502405bd68SEric Fiselier// 15117095dc8SLouis Dionne// This implementation of type_info does not assume always a unique copy of 15217095dc8SLouis Dionne// the RTTI for a given type inside a program. When constructing the type_info, 15317095dc8SLouis Dionne// the compiler packs the pointer to the type name into a uintptr_t and reserves 15417095dc8SLouis Dionne// the high bit of that pointer, which is assumed to be free for use under that 15517095dc8SLouis Dionne// ABI. If that high bit is set, that specific copy of the RTTI can't be assumed 15617095dc8SLouis Dionne// to be unique within the program. If the high bit is unset, then the RTTI can 15717095dc8SLouis Dionne// be assumed to be unique within the program. 15817095dc8SLouis Dionne// 15917095dc8SLouis Dionne// When comparing type_infos, if both RTTIs can be assumed to be unique, it 16017095dc8SLouis Dionne// suffices to compare their addresses. If both the RTTIs can't be assumed to 16117095dc8SLouis Dionne// be unique, we must perform a deep string comparison of the type names. 16217095dc8SLouis Dionne// However, if one of the RTTIs is guaranteed unique and the other one isn't, 16317095dc8SLouis Dionne// then both RTTIs are necessarily not to be considered equal. 16417095dc8SLouis Dionne// 16517095dc8SLouis Dionne// The intent of this design is to remove the need for weak symbols. Specifically, 16617095dc8SLouis Dionne// if a type would normally have a default-visibility RTTI emitted as a weak 16717095dc8SLouis Dionne// symbol, it is given hidden visibility instead and the non-unique bit is set. 16817095dc8SLouis Dionne// Otherwise, types declared with hidden visibility are always considered to have 16917095dc8SLouis Dionne// a unique RTTI: the RTTI is emitted with linkonce_odr linkage and is assumed 17017095dc8SLouis Dionne// to be deduplicated by the linker within the linked image. Across linked image 17117095dc8SLouis Dionne// boundaries, such types are thus considered different types. 1726b653fc7SLouis Dionne 173be00e889SLouis Dionne// This value can be overriden in the __config_site. When it's not overriden, 174be00e889SLouis Dionne// we pick a default implementation based on the platform here. 175be00e889SLouis Dionne#ifndef _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 176be00e889SLouis Dionne 177be00e889SLouis Dionne // Windows binaries can't merge typeinfos, so use the NonUnique implementation. 178be00e889SLouis Dionne# ifdef _LIBCPP_OBJECT_FORMAT_COFF 179be00e889SLouis Dionne# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 2 180be00e889SLouis Dionne 181be00e889SLouis Dionne // On arm64 on Apple platforms, use the special NonUniqueARMRTTIBit implementation. 182be00e889SLouis Dionne# elif defined(__APPLE__) && defined(__LP64__) && !defined(__x86_64__) 183be00e889SLouis Dionne# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 3 184be00e889SLouis Dionne 185be00e889SLouis Dionne // On all other platforms, assume the Itanium C++ ABI and use the Unique implementation. 186be00e889SLouis Dionne# else 187be00e889SLouis Dionne# define _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 1 188be00e889SLouis Dionne# endif 189be00e889SLouis Dionne#endif 190be00e889SLouis Dionne 1912405bd68SEric Fiselierstruct __type_info_implementations { 1922405bd68SEric Fiselier struct __string_impl_base { 1932405bd68SEric Fiselier typedef const char* __type_name_t; 1942405bd68SEric Fiselier _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE 1952405bd68SEric Fiselier _LIBCPP_CONSTEXPR static const char* __type_name_to_string(__type_name_t __v) _NOEXCEPT { 1962405bd68SEric Fiselier return __v; 1979075622dSSaleem Abdulrasool } 1982405bd68SEric Fiselier _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE 1992405bd68SEric Fiselier _LIBCPP_CONSTEXPR static __type_name_t __string_to_type_name(const char* __v) _NOEXCEPT { 2002405bd68SEric Fiselier return __v; 2019075622dSSaleem Abdulrasool } 2022405bd68SEric Fiselier }; 2030090e657STim Northover 2042405bd68SEric Fiselier struct __unique_impl : __string_impl_base { 2052405bd68SEric Fiselier _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE 2062405bd68SEric Fiselier static size_t __hash(__type_name_t __v) _NOEXCEPT { 2072405bd68SEric Fiselier return reinterpret_cast<size_t>(__v); 2082405bd68SEric Fiselier } 2092405bd68SEric Fiselier _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE 2102405bd68SEric Fiselier static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { 2112405bd68SEric Fiselier return __lhs == __rhs; 2122405bd68SEric Fiselier } 2132405bd68SEric Fiselier _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE 2142405bd68SEric Fiselier static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { 2152405bd68SEric Fiselier return __lhs < __rhs; 2162405bd68SEric Fiselier } 2172405bd68SEric Fiselier }; 2189075622dSSaleem Abdulrasool 2192405bd68SEric Fiselier struct __non_unique_impl : __string_impl_base { 2202405bd68SEric Fiselier _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE 2212405bd68SEric Fiselier static size_t __hash(__type_name_t __ptr) _NOEXCEPT { 2220090e657STim Northover size_t __hash = 5381; 2230090e657STim Northover while (unsigned char __c = static_cast<unsigned char>(*__ptr++)) 2240090e657STim Northover __hash = (__hash * 33) ^ __c; 2259075622dSSaleem Abdulrasool return __hash; 2269075622dSSaleem Abdulrasool } 2272405bd68SEric Fiselier _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE 2282405bd68SEric Fiselier static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { 2292405bd68SEric Fiselier return __lhs == __rhs || __builtin_strcmp(__lhs, __rhs) == 0; 2309075622dSSaleem Abdulrasool } 2312405bd68SEric Fiselier _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE 2322405bd68SEric Fiselier static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { 2332405bd68SEric Fiselier return __builtin_strcmp(__lhs, __rhs) < 0; 2342405bd68SEric Fiselier } 2356b653fc7SLouis Dionne }; 2366b653fc7SLouis Dionne 2372405bd68SEric Fiselier struct __non_unique_arm_rtti_bit_impl { 2382405bd68SEric Fiselier typedef uintptr_t __type_name_t; 2396b653fc7SLouis Dionne 2402405bd68SEric Fiselier _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE 2412405bd68SEric Fiselier static const char* __type_name_to_string(__type_name_t __v) _NOEXCEPT { 2422405bd68SEric Fiselier return reinterpret_cast<const char*>(__v & 2432405bd68SEric Fiselier ~__non_unique_rtti_bit::value); 2442405bd68SEric Fiselier } 2452405bd68SEric Fiselier _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE 2462405bd68SEric Fiselier static __type_name_t __string_to_type_name(const char* __v) _NOEXCEPT { 2472405bd68SEric Fiselier return reinterpret_cast<__type_name_t>(__v); 2482405bd68SEric Fiselier } 2492405bd68SEric Fiselier 2502405bd68SEric Fiselier _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE 2512405bd68SEric Fiselier static size_t __hash(__type_name_t __v) _NOEXCEPT { 2522405bd68SEric Fiselier if (__is_type_name_unique(__v)) 2538d5c0b87SJonathan Crowther return __v; 2542405bd68SEric Fiselier return __non_unique_impl::__hash(__type_name_to_string(__v)); 2552405bd68SEric Fiselier } 2562405bd68SEric Fiselier _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE 2572405bd68SEric Fiselier static bool __eq(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { 2582405bd68SEric Fiselier if (__lhs == __rhs) 2592405bd68SEric Fiselier return true; 26017095dc8SLouis Dionne if (__is_type_name_unique(__lhs) || __is_type_name_unique(__rhs)) 26117095dc8SLouis Dionne // Either both are unique and have a different address, or one of them 26217095dc8SLouis Dionne // is unique and the other one isn't. In both cases they are unequal. 2632405bd68SEric Fiselier return false; 2642405bd68SEric Fiselier return __builtin_strcmp(__type_name_to_string(__lhs), __type_name_to_string(__rhs)) == 0; 2652405bd68SEric Fiselier } 2662405bd68SEric Fiselier _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE 2672405bd68SEric Fiselier static bool __lt(__type_name_t __lhs, __type_name_t __rhs) _NOEXCEPT { 26817095dc8SLouis Dionne if (__is_type_name_unique(__lhs) || __is_type_name_unique(__rhs)) 2692405bd68SEric Fiselier return __lhs < __rhs; 2702405bd68SEric Fiselier return __builtin_strcmp(__type_name_to_string(__lhs), __type_name_to_string(__rhs)) < 0; 2712405bd68SEric Fiselier } 2722405bd68SEric Fiselier 2732405bd68SEric Fiselier private: 27482705e7dSEric Fiselier // The unique bit is the top bit. It is expected that __type_name_t is 64 bits when 27582705e7dSEric Fiselier // this implementation is actually used. 276d586f92cSArthur O'Dwyer typedef integral_constant<__type_name_t, 27782705e7dSEric Fiselier (1ULL << ((__CHAR_BIT__ * sizeof(__type_name_t)) - 1))> __non_unique_rtti_bit; 2782405bd68SEric Fiselier 2792405bd68SEric Fiselier _LIBCPP_INLINE_VISIBILITY 2802405bd68SEric Fiselier static bool __is_type_name_unique(__type_name_t __lhs) _NOEXCEPT { 2812405bd68SEric Fiselier return !(__lhs & __non_unique_rtti_bit::value); 2822405bd68SEric Fiselier } 2832405bd68SEric Fiselier }; 2842405bd68SEric Fiselier 2852405bd68SEric Fiselier typedef 286be00e889SLouis Dionne#if _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 1 2872405bd68SEric Fiselier __unique_impl 288d0fcdcd2SLouis Dionne#elif _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 2 289d0fcdcd2SLouis Dionne __non_unique_impl 290be00e889SLouis Dionne#elif _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION == 3 291be00e889SLouis Dionne __non_unique_arm_rtti_bit_impl 2922405bd68SEric Fiselier#else 293d0fcdcd2SLouis Dionne# error invalid configuration for _LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION 2942405bd68SEric Fiselier#endif 2952405bd68SEric Fiselier __impl; 2962405bd68SEric Fiselier}; 2972405bd68SEric Fiselier 2986b653fc7SLouis Dionneclass _LIBCPP_EXCEPTION_ABI type_info 2996b653fc7SLouis Dionne{ 3006b653fc7SLouis Dionne type_info& operator=(const type_info&); 3016b653fc7SLouis Dionne type_info(const type_info&); 3026b653fc7SLouis Dionne 3036b653fc7SLouis Dionne protected: 3042405bd68SEric Fiselier typedef __type_info_implementations::__impl __impl; 3052405bd68SEric Fiselier 3062405bd68SEric Fiselier __impl::__type_name_t __type_name; 3076b653fc7SLouis Dionne 3086b653fc7SLouis Dionne _LIBCPP_INLINE_VISIBILITY 3092405bd68SEric Fiselier explicit type_info(const char* __n) 3102405bd68SEric Fiselier : __type_name(__impl::__string_to_type_name(__n)) {} 3116b653fc7SLouis Dionne 3126b653fc7SLouis Dionnepublic: 3136b653fc7SLouis Dionne _LIBCPP_AVAILABILITY_TYPEINFO_VTABLE 3146b653fc7SLouis Dionne virtual ~type_info(); 3156b653fc7SLouis Dionne 3169075622dSSaleem Abdulrasool _LIBCPP_INLINE_VISIBILITY 3179075622dSSaleem Abdulrasool const char* name() const _NOEXCEPT 3182405bd68SEric Fiselier { 3192405bd68SEric Fiselier return __impl::__type_name_to_string(__type_name); 3202405bd68SEric Fiselier } 3219075622dSSaleem Abdulrasool 3229075622dSSaleem Abdulrasool _LIBCPP_INLINE_VISIBILITY 3239075622dSSaleem Abdulrasool bool before(const type_info& __arg) const _NOEXCEPT 3242405bd68SEric Fiselier { 3252405bd68SEric Fiselier return __impl::__lt(__type_name, __arg.__type_name); 3262405bd68SEric Fiselier } 3279075622dSSaleem Abdulrasool 3289075622dSSaleem Abdulrasool _LIBCPP_INLINE_VISIBILITY 3299075622dSSaleem Abdulrasool size_t hash_code() const _NOEXCEPT 3302405bd68SEric Fiselier { 3312405bd68SEric Fiselier return __impl::__hash(__type_name); 3322405bd68SEric Fiselier } 3339075622dSSaleem Abdulrasool 3349075622dSSaleem Abdulrasool _LIBCPP_INLINE_VISIBILITY 3359075622dSSaleem Abdulrasool bool operator==(const type_info& __arg) const _NOEXCEPT 3362405bd68SEric Fiselier { 3372405bd68SEric Fiselier return __impl::__eq(__type_name, __arg.__type_name); 3382405bd68SEric Fiselier } 3399075622dSSaleem Abdulrasool 340789847ddSHoward Hinnant _LIBCPP_INLINE_VISIBILITY 341fafca58cSHoward Hinnant bool operator!=(const type_info& __arg) const _NOEXCEPT 3423e519524SHoward Hinnant { return !operator==(__arg); } 3433e519524SHoward Hinnant}; 3442405bd68SEric Fiselier#endif // defined(_LIBCPP_ABI_MICROSOFT) 3456b653fc7SLouis Dionne 346111e0cbeSNick Kledzikclass _LIBCPP_EXCEPTION_ABI bad_cast 3473e519524SHoward Hinnant : public exception 3483e519524SHoward Hinnant{ 3493e519524SHoward Hinnant public: 350fafca58cSHoward Hinnant bad_cast() _NOEXCEPT; 351585a3cc3SDimitry Andric bad_cast(const bad_cast&) _NOEXCEPT = default; 352fafca58cSHoward Hinnant virtual ~bad_cast() _NOEXCEPT; 353fafca58cSHoward Hinnant virtual const char* what() const _NOEXCEPT; 3543e519524SHoward Hinnant}; 3553e519524SHoward Hinnant 356111e0cbeSNick Kledzikclass _LIBCPP_EXCEPTION_ABI bad_typeid 3573e519524SHoward Hinnant : public exception 3583e519524SHoward Hinnant{ 3593e519524SHoward Hinnant public: 360fafca58cSHoward Hinnant bad_typeid() _NOEXCEPT; 361fafca58cSHoward Hinnant virtual ~bad_typeid() _NOEXCEPT; 362fafca58cSHoward Hinnant virtual const char* what() const _NOEXCEPT; 3633e519524SHoward Hinnant}; 3643e519524SHoward Hinnant 365d2b0df35SNikolas Klauser} // namespace std 3663e519524SHoward Hinnant 367e69290dcSEric Fiselier#endif // defined(_LIBCPP_ABI_VCRUNTIME) 3681634c15eSPeter Collingbourne 369d437fa5cSMarshall Clow_LIBCPP_BEGIN_NAMESPACE_STD 370dc7200b4SLouis Dionne_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY 371d437fa5cSMarshall Clowvoid __throw_bad_cast() 372d437fa5cSMarshall Clow{ 373d437fa5cSMarshall Clow#ifndef _LIBCPP_NO_EXCEPTIONS 374d437fa5cSMarshall Clow throw bad_cast(); 375d437fa5cSMarshall Clow#else 376d437fa5cSMarshall Clow _VSTD::abort(); 377d437fa5cSMarshall Clow#endif 378d437fa5cSMarshall Clow} 379d437fa5cSMarshall Clow_LIBCPP_END_NAMESPACE_STD 380d437fa5cSMarshall Clow 3813e519524SHoward Hinnant#endif // __LIBCPP_TYPEINFO 382