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