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
65#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
66#pragma GCC system_header
67#endif
68
69namespace std  // purposefully not using versioning namespace
70{
71
72class _LIBCPP_EXCEPTION_ABI type_info
73{
74    type_info& operator=(const type_info&);
75    type_info(const type_info&);
76protected:
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
92public:
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
148class _LIBCPP_EXCEPTION_ABI bad_cast
149    : public exception
150{
151public:
152    bad_cast() _NOEXCEPT;
153    virtual ~bad_cast() _NOEXCEPT;
154    virtual const char* what() const _NOEXCEPT;
155};
156
157class _LIBCPP_EXCEPTION_ABI bad_typeid
158    : public exception
159{
160public:
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