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