1 // Written in the D programming language.
2 
3 /**
4  * Interface to C++ <typeinfo>
5  *
6  * Copyright: Copyright (c) 2016 D Language Foundation
7  * License:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
8  * Authors:   $(HTTP digitalmars.com, Walter Bright)
9  * Source:    $(DRUNTIMESRC core/stdcpp/_typeinfo.d)
10  */
11 
12 module core.stdcpp.typeinfo;
13 
14 import core.attribute : weak;
15 
16 version (CppRuntime_DigitalMars)
17 {
18     import core.stdcpp.exception;
19 
20     extern (C++, "std"):
21 
22     class type_info
23     {
24     @nogc:
25         void* pdata;
26 
27     public:
28         //virtual ~this();
29         void dtor() { }     // reserve slot in vtbl[]
30 
31         //bool operator==(const type_info rhs) const;
32         //bool operator!=(const type_info rhs) const;
33         final bool before(const type_info rhs) const nothrow;
34         final const(char)* name() const nothrow;
35     protected:
36         //type_info();
37     private:
38         //this(const type_info rhs);
39         //type_info operator=(const type_info rhs);
40     }
41 
42     class bad_cast : exception
43     {
44     @nogc:
45         extern(D) this() nothrow { }
46         extern(D) this(const bad_cast) nothrow { }
47         //bad_cast operator=(const bad_cast) nothrow { return this; }
48         //virtual ~this() nothrow;
49         override const(char)* what() const nothrow;
50     }
51 
52     class bad_typeid : exception
53     {
54     @nogc:
55         extern(D) this() nothrow { }
56         extern(D) this(const bad_typeid) nothrow { }
57         //bad_typeid operator=(const bad_typeid) nothrow { return this; }
58         //virtual ~this() nothrow;
59         override const (char)* what() const nothrow;
60     }
61 }
62 else version (CppRuntime_Microsoft)
63 {
64     import core.stdcpp.exception;
65 
66     extern (C++, "std"):
67 
68     struct __type_info_node
69     {
70         void* _MemPtr;
71         __type_info_node* _Next;
72     }
73 
74     extern __gshared __type_info_node __type_info_root_node;
75 
76     class type_info
77     {
78     @nogc:
79         @weak ~this() nothrow {}
80         //bool operator==(const type_info rhs) const;
81         //bool operator!=(const type_info rhs) const;
82         final bool before(const type_info rhs) const nothrow;
83         final const(char)* name(__type_info_node* p = &__type_info_root_node) const nothrow;
84 
85     private:
86         void* pdata;
87         char[1] _name;
88         //type_info operator=(const type_info rhs);
89     }
90 
91     class bad_cast : exception
92     {
93     @nogc:
94         extern(D) this(const(char)* msg = "bad cast") nothrow { super(msg); }
95         //virtual ~this();
96     }
97 
98     class bad_typeid : exception
99     {
100     @nogc:
101         extern(D) this(const(char)* msg = "bad typeid") nothrow { super(msg); }
102         //virtual ~this();
103     }
104 }
105 else version (CppRuntime_Gcc)
106 {
107     import core.stdcpp.exception;
108 
109     extern (C++, "__cxxabiv1")
110     {
111         extern(C++, class) struct __class_type_info;
112     }
113 
114     extern (C++, "std"):
115 
116     abstract class type_info
117     {
118     @nogc:
119         @weak ~this() {}
120         @weak final const(char)* name() const nothrow
121         {
122             return _name[0] == '*' ? _name + 1 : _name;
123         }
124         @weak final bool before(const type_info _arg) const nothrow
125         {
126             import core.stdc.string : strcmp;
127             return (_name[0] == '*' && _arg._name[0] == '*')
128                 ? _name < _arg._name
129                 : strcmp(_name, _arg._name) < 0;
130         }
131         //bool operator==(const type_info) const;
132         bool __is_pointer_p() const;
133         bool __is_function_p() const;
134         bool __do_catch(const type_info, void**, uint) const;
135         bool __do_upcast(const __class_type_info*, void**) const;
136 
137     protected:
138         const(char)* _name;
139 
140         extern(D) this(const(char)* name) { _name = name; }
141     }
142 
143     class bad_cast : exception
144     {
145     @nogc:
146         extern(D) this() nothrow {}
147         //~this();
148         @weak override const(char)* what() const nothrow { return "bad cast"; }
149     }
150 
151     class bad_typeid : exception
152     {
153     @nogc:
154         extern(D) this() nothrow {}
155         //~this();
156         @weak override const(char)* what() const nothrow { return "bad typeid"; }
157     }
158 }
159 else version (CppRuntime_Clang)
160 {
161     import core.stdcpp.exception;
162 
163     extern (C++, "std"):
164 
165     abstract class type_info
166     {
167     @nogc:
168         @weak ~this() {}
169         @weak final const(char)* name() const nothrow
170         {
171             return __type_name;
172         }
173         @weak final bool before(const type_info __arg) const nothrow
174         {
175             return __type_name < __arg.__type_name;
176         }
177         //bool operator==(const type_info) const;
178 
179     protected:
180         const(char)* __type_name;
181 
182         extern(D) this(const(char)* __n) { __type_name = __n; }
183     }
184 
185     class bad_cast : exception
186     {
187     @nogc:
188         extern(D) this() nothrow {}
189         //~this();
190         @weak override const(char)* what() const nothrow { return "bad cast"; }
191     }
192 
193     class bad_typeid : exception
194     {
195     @nogc:
196         extern(D) this() nothrow {}
197         //~this();
198         @weak override const(char)* what() const nothrow { return "bad typeid"; }
199     }
200 }
201 else
202     static assert(0, "Missing std::type_info binding for this platform");