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