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