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     virtual ~type_info();
    112 
    113 #if defined(_LIBCPP_HAS_NONUNIQUE_TYPEINFO)
    114     _LIBCPP_INLINE_VISIBILITY
    115     const char* name() const _NOEXCEPT
    116     {
    117       return reinterpret_cast<const char*>(__type_name &
    118                                            ~_LIBCPP_NONUNIQUE_RTTI_BIT);
    119     }
    120 
    121     _LIBCPP_INLINE_VISIBILITY
    122     bool before(const type_info& __arg) const _NOEXCEPT
    123     {
    124       if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))
    125         return __type_name < __arg.__type_name;
    126       return __compare_nonunique_names(__arg) < 0;
    127     }
    128 
    129     _LIBCPP_INLINE_VISIBILITY
    130     size_t hash_code() const _NOEXCEPT
    131     {
    132       if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT))
    133         return __type_name;
    134 
    135       const char* __ptr = name();
    136       size_t __hash = 5381;
    137       while (unsigned char __c = static_cast<unsigned char>(*__ptr++))
    138         __hash = (__hash * 33) ^ __c;
    139       return __hash;
    140     }
    141 
    142     _LIBCPP_INLINE_VISIBILITY
    143     bool operator==(const type_info& __arg) const _NOEXCEPT
    144     {
    145       if (__type_name == __arg.__type_name)
    146         return true;
    147 
    148       if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))
    149         return false;
    150       return __compare_nonunique_names(__arg) == 0;
    151     }
    152 #else
    153     _LIBCPP_INLINE_VISIBILITY
    154     const char* name() const _NOEXCEPT
    155     { return __type_name; }
    156 
    157     _LIBCPP_INLINE_VISIBILITY
    158     bool before(const type_info& __arg) const _NOEXCEPT
    159     { return __type_name < __arg.__type_name; }
    160 
    161     _LIBCPP_INLINE_VISIBILITY
    162     size_t hash_code() const _NOEXCEPT
    163     { return reinterpret_cast<size_t>(__type_name); }
    164 
    165     _LIBCPP_INLINE_VISIBILITY
    166     bool operator==(const type_info& __arg) const _NOEXCEPT
    167     { return __type_name == __arg.__type_name; }
    168 #endif
    169 
    170     _LIBCPP_INLINE_VISIBILITY
    171     bool operator!=(const type_info& __arg) const _NOEXCEPT
    172     { return !operator==(__arg); }
    173 };
    174 
    175 class _LIBCPP_EXCEPTION_ABI bad_cast
    176     : public exception
    177 {
    178 public:
    179     bad_cast() _NOEXCEPT;
    180     virtual ~bad_cast() _NOEXCEPT;
    181     virtual const char* what() const _NOEXCEPT;
    182 };
    183 
    184 class _LIBCPP_EXCEPTION_ABI bad_typeid
    185     : public exception
    186 {
    187 public:
    188     bad_typeid() _NOEXCEPT;
    189     virtual ~bad_typeid() _NOEXCEPT;
    190     virtual const char* what() const _NOEXCEPT;
    191 };
    192 
    193 #endif // !_LIBCPP_ABI_MICROSOFT
    194 
    195 }  // std
    196 
    197 _LIBCPP_BEGIN_NAMESPACE_STD
    198 _LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
    199 void __throw_bad_cast()
    200 {
    201 #ifndef _LIBCPP_NO_EXCEPTIONS
    202     throw bad_cast();
    203 #else
    204 	_VSTD::abort();
    205 #endif
    206 }
    207 _LIBCPP_END_NAMESPACE_STD
    208 
    209 #endif  // __LIBCPP_TYPEINFO
    210