Home | History | Annotate | Download | only in v1
      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)
     73 #if defined(_LIBCPP_NONUNIQUE_RTTI_BIT)
     74 #define _LIBCPP_HAS_NONUNIQUE_TYPEINFO
     75 #else
     76 #define _LIBCPP_HAS_UNIQUE_TYPEINFO
     77 #endif
     78 #endif
     79 
     80 namespace std  // purposefully not using versioning namespace
     81 {
     82 
     83 class _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 
    103 protected:
    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 
    120 public:
    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 
    202 class _LIBCPP_EXCEPTION_ABI bad_cast
    203     : public exception
    204 {
    205 public:
    206     bad_cast() _NOEXCEPT;
    207     virtual ~bad_cast() _NOEXCEPT;
    208     virtual const char* what() const _NOEXCEPT;
    209 };
    210 
    211 class _LIBCPP_EXCEPTION_ABI bad_typeid
    212     : public exception
    213 {
    214 public:
    215     bad_typeid() _NOEXCEPT;
    216     virtual ~bad_typeid() _NOEXCEPT;
    217     virtual const char* what() const _NOEXCEPT;
    218 };
    219 
    220 }  // std
    221 
    222 _LIBCPP_BEGIN_NAMESPACE_STD
    223 _LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
    224 void __throw_bad_cast()
    225 {
    226 #ifndef _LIBCPP_NO_EXCEPTIONS
    227     throw bad_cast();
    228 #else
    229 	_VSTD::abort();
    230 #endif
    231 }
    232 _LIBCPP_END_NAMESPACE_STD
    233 
    234 #endif  // __LIBCPP_TYPEINFO
    235