1227825Stheraven// -*- C++ -*-
2227825Stheraven//===-------------------------- typeinfo ----------------------------------===//
3227825Stheraven//
4227825Stheraven//                     The LLVM Compiler Infrastructure
5227825Stheraven//
6227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open
7227825Stheraven// Source Licenses. See LICENSE.TXT for details.
8227825Stheraven//
9227825Stheraven//===----------------------------------------------------------------------===//
10227825Stheraven
11227825Stheraven#ifndef __LIBCPP_TYPEINFO
12227825Stheraven#define __LIBCPP_TYPEINFO
13227825Stheraven
14227825Stheraven/*
15227825Stheraven
16227825Stheraven    typeinfo synopsis
17227825Stheraven
18227825Stheravennamespace std {
19227825Stheraven
20227825Stheravenclass type_info
21227825Stheraven{
22227825Stheravenpublic:
23227825Stheraven    virtual ~type_info();
24227825Stheraven
25227825Stheraven    bool operator==(const type_info& rhs) const noexcept;
26227825Stheraven    bool operator!=(const type_info& rhs) const noexcept;
27227825Stheraven
28227825Stheraven    bool before(const type_info& rhs) const noexcept;
29227825Stheraven    size_t hash_code() const noexcept;
30227825Stheraven    const char* name() const noexcept;
31227825Stheraven
32227825Stheraven    type_info(const type_info& rhs) = delete;
33227825Stheraven    type_info& operator=(const type_info& rhs) = delete;
34227825Stheraven};
35227825Stheraven
36227825Stheravenclass bad_cast
37227825Stheraven    : public exception
38227825Stheraven{
39227825Stheravenpublic:
40227825Stheraven    bad_cast() noexcept;
41227825Stheraven    bad_cast(const bad_cast&) noexcept;
42227825Stheraven    bad_cast& operator=(const bad_cast&) noexcept;
43227825Stheraven    virtual const char* what() const noexcept;
44227825Stheraven};
45227825Stheraven
46227825Stheravenclass bad_typeid
47227825Stheraven    : public exception
48227825Stheraven{
49227825Stheravenpublic:
50227825Stheraven    bad_typeid() noexcept;
51227825Stheraven    bad_typeid(const bad_typeid&) noexcept;
52227825Stheraven    bad_typeid& operator=(const bad_typeid&) noexcept;
53227825Stheraven    virtual const char* what() const noexcept;
54227825Stheraven};
55227825Stheraven
56227825Stheraven}  // std
57227825Stheraven
58227825Stheraven*/
59227825Stheraven
60227825Stheraven#include <__config>
61227825Stheraven#include <exception>
62227825Stheraven#include <cstddef>
63278724Sdim#include <cstdint>
64227825Stheraven
65227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
66227825Stheraven#pragma GCC system_header
67227825Stheraven#endif
68227825Stheraven
69227825Stheravennamespace std  // purposefully not using versioning namespace
70227825Stheraven{
71227825Stheraven
72227825Stheravenclass _LIBCPP_EXCEPTION_ABI type_info
73227825Stheraven{
74227825Stheraven    type_info& operator=(const type_info&);
75227825Stheraven    type_info(const type_info&);
76227825Stheravenprotected:
77278724Sdim#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
78227825Stheraven    const char* __type_name;
79278724Sdim#else
80278724Sdim    // A const char* with the non-unique RTTI bit possibly set.
81278724Sdim    uintptr_t __type_name;
82278724Sdim#endif
83227825Stheraven
84227825Stheraven    _LIBCPP_INLINE_VISIBILITY
85227825Stheraven    explicit type_info(const char* __n)
86278724Sdim#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
87227825Stheraven        : __type_name(__n) {}
88278724Sdim#else
89278724Sdim        : __type_name(reinterpret_cast<uintptr_t>(__n)) {}
90278724Sdim#endif
91227825Stheraven
92227825Stheravenpublic:
93227825Stheraven    virtual ~type_info();
94227825Stheraven
95227825Stheraven    _LIBCPP_INLINE_VISIBILITY
96278724Sdim    const char* name() const _NOEXCEPT
97278724Sdim#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
98278724Sdim        {return __type_name;}
99278724Sdim#else
100278724Sdim        {return reinterpret_cast<const char*>(__type_name & ~_LIBCPP_NONUNIQUE_RTTI_BIT);}
101278724Sdim#endif
102227825Stheraven
103227825Stheraven    _LIBCPP_INLINE_VISIBILITY
104227825Stheraven    bool before(const type_info& __arg) const _NOEXCEPT
105278724Sdim#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
106227825Stheraven        {return __type_name < __arg.__type_name;}
107278724Sdim#else
108278724Sdim        {if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))
109278724Sdim           return __type_name < __arg.__type_name;
110278724Sdim         return __compare_nonunique_names(__arg) < 0;}
111278724Sdim#endif
112278724Sdim
113227825Stheraven    _LIBCPP_INLINE_VISIBILITY
114227825Stheraven    size_t hash_code() const _NOEXCEPT
115278724Sdim#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
116227825Stheraven        {return *reinterpret_cast<const size_t*>(&__type_name);}
117278724Sdim#else
118278724Sdim        {if (!(__type_name & _LIBCPP_NONUNIQUE_RTTI_BIT)) return __type_name;
119278724Sdim         const char *__ptr = name();
120278724Sdim         size_t __hash = 5381;
121278724Sdim         while (unsigned char __c = static_cast<unsigned char>(*__ptr++))
122278724Sdim           __hash = (__hash * 33) ^ __c;
123278724Sdim         return __hash;}
124278724Sdim#endif
125227825Stheraven
126227825Stheraven    _LIBCPP_INLINE_VISIBILITY
127227825Stheraven    bool operator==(const type_info& __arg) const _NOEXCEPT
128278724Sdim#ifndef _LIBCPP_NONUNIQUE_RTTI_BIT
129227825Stheraven        {return __type_name == __arg.__type_name;}
130278724Sdim#else
131278724Sdim        {if (__type_name == __arg.__type_name) return true;
132278724Sdim         if (!((__type_name & __arg.__type_name) & _LIBCPP_NONUNIQUE_RTTI_BIT))
133278724Sdim           return false;
134278724Sdim         return __compare_nonunique_names(__arg) == 0;}
135278724Sdim#endif
136227825Stheraven    _LIBCPP_INLINE_VISIBILITY
137227825Stheraven    bool operator!=(const type_info& __arg) const _NOEXCEPT
138227825Stheraven        {return !operator==(__arg);}
139227825Stheraven
140278724Sdim#ifdef _LIBCPP_NONUNIQUE_RTTI_BIT
141278724Sdim  private:
142278724Sdim    _LIBCPP_INLINE_VISIBILITY
143278724Sdim    int __compare_nonunique_names(const type_info &__arg) const _NOEXCEPT
144278724Sdim        {return __builtin_strcmp(name(), __arg.name());}
145278724Sdim#endif
146227825Stheraven};
147227825Stheraven
148227825Stheravenclass _LIBCPP_EXCEPTION_ABI bad_cast
149227825Stheraven    : public exception
150227825Stheraven{
151227825Stheravenpublic:
152227825Stheraven    bad_cast() _NOEXCEPT;
153227825Stheraven    virtual ~bad_cast() _NOEXCEPT;
154227825Stheraven    virtual const char* what() const _NOEXCEPT;
155227825Stheraven};
156227825Stheraven
157227825Stheravenclass _LIBCPP_EXCEPTION_ABI bad_typeid
158227825Stheraven    : public exception
159227825Stheraven{
160227825Stheravenpublic:
161227825Stheraven    bad_typeid() _NOEXCEPT;
162227825Stheraven    virtual ~bad_typeid() _NOEXCEPT;
163227825Stheraven    virtual const char* what() const _NOEXCEPT;
164227825Stheraven};
165227825Stheraven
166227825Stheraven}  // std
167227825Stheraven
168227825Stheraven#endif  // __LIBCPP_TYPEINFO
169