1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
/*
Ousía
Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file Rtti.hpp
*
* Classes used for storing runtime type information (RTTI). RTTI is used to
* lookup objects in the object graph of a certain type and to attach
* information that should be accessible to the script engine.
*
* @author Andreas Stöckel (astoecke@techfak.uni-bielefeld.de)
*/
#ifndef _OUSIA_MANAGED_RTTI_HPP_
#define _OUSIA_MANAGED_RTTI_HPP_
#include <typeinfo>
#include <typeindex>
#include <unordered_map>
#include <vector>
namespace ousia {
class RttiBase;
/**
* Helper class used to globally store and access the runtime type information.
*/
class RttiStore {
private:
/**
* Function used internally to access the static map storing all registered
* native types and their corresponding type information.
*/
static std::unordered_map<std::type_index, const RttiBase *> &table();
public:
/**
* Registers the given pointer to the RttiBase class in the RTTI table. Does
* not override information for already registered types.
*
* @param native is a reference at the native type information provided
* by the compiler.
* @param rtti is a pointer pointing at the type information that should be
* stored for this type.
*/
static void store(const std::type_info &native, const RttiBase *rtti);
/**
* Looks up the type information stored for the given native type
* information.
*/
static const RttiBase &lookup(const std::type_info &native);
};
/**
* The Rtti class allows for attaching data to native types that can be accessed
* at runtime. This type information can e.g. be retrieved using the "type"
* method of the Managed class. This system is used for attaching human readable
* names, parent types and script engine functionality. Use the Rtti class for
* convenient registration of type information.
*/
class RttiBase {
private:
/**
* Set containing references to the parent types.
*/
const std::vector<const RttiBase *> parents;
public:
/**
* Rtti of no particular type.
*/
static const RttiBase None;
/**
* Human readable name associated with the type.
*/
const std::string name;
/**
* Default constructor. Creates a Rtti instance with name "unknown"
* and no parents.
*/
RttiBase() : name("unknown") {}
/**
* Creates a new RttiBase instance and registers it in the global type
* table. Use the Rtti class for more convinient registration of type
* information.
*
* @param name is the name of the type.
* @param native is a reference at the native type information provided by
* the compiler.
* @param parents is a list of parent types.
*/
RttiBase(std::string name, const std::type_info &native,
std::vector<const RttiBase *> parents =
std::vector<const RttiBase *>{})
: parents(std::move(parents)), name(std::move(name))
{
RttiStore::store(native, this);
}
/**
* Returns true if this Rtti instance is the given type or has the
* given type as one of its parents.
*
* @param other is the other type for which the relation to this type
* should be checked.
*/
bool isa(const RttiBase &other) const;
};
/**
* The Rtti class allows for attaching data to native types that can be accessed
* at runtime. This type information can e.g. be retrieved using the "type"
* method of the Managed class. This system is used for attaching human
* readable names, parent types and script engine functionality.
*
* @tparam T is the class for which the type information should be registered.
*/
template <class T>
class Rtti : public RttiBase {
public:
/**
* Creates a new RttiBase instance and registers it in the global type
* table.
*
* @param name is the name of the type.
* @param parents is a list of parent types.
*/
Rtti(std::string name, const std::vector<const RttiBase *> &parents =
std::vector<const RttiBase *>{})
: RttiBase(name, typeid(T), parents)
{
}
};
/**
* Function that can be used to retrieve the RTTI information of a Managed
* object.
*
* @tparam T is the C++ type for which the type information should be returned.
*/
template <typename T>
inline const RttiBase &typeOf()
{
return RttiStore::lookup(typeid(T));
}
/**
* Function that can be used to retrieve the RTTI information of a Managed
* object.
*
* @tparam T is the C++ type for which the type information should be returned.
* @param obj is a dummy object for which the type information should be
* returned.
*/
template <typename T>
inline const RttiBase &typeOf(const T &obj)
{
return RttiStore::lookup(typeid(obj));
}
}
#endif /* _OUSIA_MANAGED_RTTI_HPP_ */
|