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 
     65 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
     66 #pragma GCC system_header
     67 #endif
     68 
     69 namespace std  // purposefully not using versioning namespace
     70 {
     71 
     72 class _LIBCPP_EXCEPTION_ABI type_info
     73 {
     74     type_info& operator=(const type_info&);
     75     type_info(const type_info&);
     76 protected:
     77 #ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
     78     const char* __type_name;
     79 #else
     80     // A const char* with the non-unique RTTI bit possibly set.
     81     uintptr_t __type_name;
     82 #endif
     83 
     84     _LIBCPP_INLINE_VISIBILITY
     85     explicit type_info(const char* __n)
     86 #ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
     87         : __type_name(__n) {}
     88 #else
     89         : __type_name(reinterpret_cast<uintptr_t>(__n)) {}
     90 #endif
     91 
     92 public:
     93     virtual ~type_info();
     94 
     95     _LIBCPP_INLINE_VISIBILITY
     96     const char* name() const _NOEXCEPT
     97 #ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
     98         {return __type_name;}
     99 #else
    100         {return reinterpret_cast<const char*>(__type_name & ~_LIBCPP_NONUNIQUE_RTTI_BIT);}
    101 #endif
    102 
    103     _LIBCPP_INLINE_VISIBILITY
    104     bool before(const type_info& __arg) const _NOEXCEPT
    105 #ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
    106         {return __type_name < __arg.__type_name;}
    107 #else
    108         {if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))
    109            return __type_name < __arg.__type_name;
    110          return __compare_nonunique_names(__arg) < 0;}
    111 #endif
    112 
    113     _LIBCPP_INLINE_VISIBILITY
    114     size_t hash_code() const _NOEXCEPT
    115 #ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
    116         {return *reinterpret_cast<const size_t*>(&__type_name);}
    117 #else
    118         {if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT)) return __type_name;
    119          const char *__ptr = name();
    120          size_t __hash = 5381;
    121          while (unsigned char __c = static_cast<unsigned char>(*__ptr++))
    122            __hash = (__hash * 33) ^ __c;
    123          return __hash;}
    124 #endif
    125 
    126     _LIBCPP_INLINE_VISIBILITY
    127     bool operator==(const type_info& __arg) const _NOEXCEPT
    128 #ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
    129         {return __type_name == __arg.__type_name;}
    130 #else
    131         {if (__type_name == __arg.__type_name) return true;
    132          if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))
    133            return false;
    134          return __compare_nonunique_names(__arg) == 0;}
    135 #endif
    136     _LIBCPP_INLINE_VISIBILITY
    137     bool operator!=(const type_info& __arg) const _NOEXCEPT
    138         {return !operator==(__arg);}
    139 
    140 #ifdef _LIBCPP_NONUNIQUE_RTTI_BIT
    141   private:
    142     _LIBCPP_INLINE_VISIBILITY
    143     int __compare_nonunique_names(const type_info &__arg) const _NOEXCEPT
    144         {return __builtin_strcmp(name(), __arg.name());}
    145 #endif
    146 };
    147 
    148 class _LIBCPP_EXCEPTION_ABI bad_cast
    149     : public exception
    150 {
    151 public:
    152     bad_cast() _NOEXCEPT;
    153     virtual ~bad_cast() _NOEXCEPT;
    154     virtual const char* what() const _NOEXCEPT;
    155 };
    156 
    157 class _LIBCPP_EXCEPTION_ABI bad_typeid
    158     : public exception
    159 {
    160 public:
    161     bad_typeid() _NOEXCEPT;
    162     virtual ~bad_typeid() _NOEXCEPT;
    163     virtual const char* what() const _NOEXCEPT;
    164 };
    165 
    166 }  // std
    167 
    168 #endif  // __LIBCPP_TYPEINFO
    169