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
18namespace std {
19
20class type_info
21{
22public:
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
36class bad_cast
37    : public exception
38{
39public:
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
46class bad_typeid
47    : public exception
48{
49public:
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
72namespace std  // purposefully not using versioning namespace
73{
74
75class _LIBCPP_EXCEPTION_ABI type_info
76{
77    type_info& operator=(const type_info&);
78    type_info(const type_info&);
79
80    typedef size_t _LIBCPP_MAY_ALIAS _ASizeT; // Avoid strict-aliasing issues.
81
82protected:
83#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
84    const char* __type_name;
85#else
86    // A const char* with the non-unique RTTI bit possibly set.
87    uintptr_t __type_name;
88#endif
89
90    _LIBCPP_INLINE_VISIBILITY
91    explicit type_info(const char* __n)
92#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
93        : __type_name(__n) {}
94#else
95        : __type_name(reinterpret_cast<uintptr_t>(__n)) {}
96#endif
97
98public:
99    virtual ~type_info();
100
101    _LIBCPP_INLINE_VISIBILITY
102    const char* name() const _NOEXCEPT
103#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
104        {return __type_name;}
105#else
106        {return reinterpret_cast<const char*>(__type_name & ~_LIBCPP_NONUNIQUE_RTTI_BIT);}
107#endif
108
109    _LIBCPP_INLINE_VISIBILITY
110    bool before(const type_info& __arg) const _NOEXCEPT
111#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
112        {return __type_name < __arg.__type_name;}
113#else
114        {if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))
115           return __type_name < __arg.__type_name;
116         return __compare_nonunique_names(__arg) < 0;}
117#endif
118
119    _LIBCPP_INLINE_VISIBILITY
120    size_t hash_code() const _NOEXCEPT
121#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
122        {return *reinterpret_cast<const _ASizeT *>(&__type_name);}
123#else
124        {if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT)) return __type_name;
125         const char *__ptr = name();
126         size_t __hash = 5381;
127         while (unsigned char __c = static_cast<unsigned char>(*__ptr++))
128           __hash = (__hash * 33) ^ __c;
129         return __hash;}
130#endif
131
132    _LIBCPP_INLINE_VISIBILITY
133    bool operator==(const type_info& __arg) const _NOEXCEPT
134#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
135        {return __type_name == __arg.__type_name;}
136#else
137        {if (__type_name == __arg.__type_name) return true;
138         if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))
139           return false;
140         return __compare_nonunique_names(__arg) == 0;}
141#endif
142    _LIBCPP_INLINE_VISIBILITY
143    bool operator!=(const type_info& __arg) const _NOEXCEPT
144        {return !operator==(__arg);}
145
146#ifdef _LIBCPP_NONUNIQUE_RTTI_BIT
147  private:
148    _LIBCPP_INLINE_VISIBILITY
149    int __compare_nonunique_names(const type_info &__arg) const _NOEXCEPT
150        {return __builtin_strcmp(name(), __arg.name());}
151#endif
152};
153
154class _LIBCPP_EXCEPTION_ABI bad_cast
155    : public exception
156{
157public:
158    bad_cast() _NOEXCEPT;
159    virtual ~bad_cast() _NOEXCEPT;
160    virtual const char* what() const _NOEXCEPT;
161};
162
163class _LIBCPP_EXCEPTION_ABI bad_typeid
164    : public exception
165{
166public:
167    bad_typeid() _NOEXCEPT;
168    virtual ~bad_typeid() _NOEXCEPT;
169    virtual const char* what() const _NOEXCEPT;
170};
171
172}  // std
173
174_LIBCPP_BEGIN_NAMESPACE_STD
175_LIBCPP_NORETURN inline _LIBCPP_ALWAYS_INLINE
176void __throw_bad_cast()
177{
178#ifndef _LIBCPP_NO_EXCEPTIONS
179    throw bad_cast();
180#else
181	_VSTD::abort();
182#endif
183}
184_LIBCPP_END_NAMESPACE_STD
185
186#endif  // __LIBCPP_TYPEINFO
187