summaryrefslogtreecommitdiff
path: root/src/core/common/Rtti.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/common/Rtti.cpp')
-rw-r--r--src/core/common/Rtti.cpp51
1 files changed, 37 insertions, 14 deletions
diff --git a/src/core/common/Rtti.cpp b/src/core/common/Rtti.cpp
index eeae41f..0443a8d 100644
--- a/src/core/common/Rtti.cpp
+++ b/src/core/common/Rtti.cpp
@@ -46,27 +46,50 @@ const RttiBase &RttiStore::lookup(const std::type_info &native)
/* Class RttiBase */
-bool RttiBase::isa(const RttiBase &other) const
+void RttiBase::initialize() const
{
- if (&other == this) {
- return true;
- }
- for (auto t : parents) {
- if (t->isa(other)) {
- return true;
+ // Only run this function exactly once -- directly set the initialized flag
+ // to prevent unwanted recursion
+ if (!initialized) {
+ initialized = true;
+
+ // Insert the parent types of the parent types
+ {
+ std::unordered_set<const RttiBase *> origParents = parents;
+ for (const RttiBase *parent : origParents) {
+ parent->initialize();
+ parents.insert(parent->parents.begin(), parent->parents.end());
+ }
+ parents.insert(this);
+ }
+
+ // Insert the aggregated types of the aggregated types
+ {
+ std::unordered_set<const RttiBase *> origAggregatedTypes =
+ aggregatedTypes;
+ for (const RttiBase *aggregatedType : origAggregatedTypes) {
+ aggregatedType->initialize();
+ aggregatedTypes.insert(aggregatedType->aggregatedTypes.begin(),
+ aggregatedType->aggregatedTypes.end());
+ }
}
}
- return false;
+}
+
+bool RttiBase::isa(const RttiBase &other) const
+{
+ initialize();
+ return parents.count(&other) > 0;
+}
+
+bool RttiBase::contains(const RttiBase &other) const
+{
+ initialize();
+ return aggregatedTypes.count(&other) > 0;
}
/* Constant initialization */
const RttiBase RttiTypes::None;
-const RttiBase RttiTypes::Int;
-const RttiBase RttiTypes::Double;
-const RttiBase RttiTypes::String;
-const RttiBase RttiTypes::Array;
-const RttiBase RttiTypes::Map;
-
}