summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2014-12-20 15:51:00 +0100
committerAndreas Stöckel <andreas@somweyr.de>2014-12-20 15:51:00 +0100
commita7567d08e4d5869833069ec7211785af350aea88 (patch)
tree120971129563f9e5f054ea5bb740fcbf8f473936
parent87233da76c01ebead18a26f01ffb4e20dffe3214 (diff)
Renamed ManagedType class to Rtti to make naming less confusing, implemented easier to use Rtti clas
-rw-r--r--CMakeLists.txt11
-rw-r--r--src/core/managed/Managed.hpp18
-rw-r--r--src/core/managed/ManagedType.hpp175
-rw-r--r--src/core/managed/Rtti.cpp (renamed from src/core/managed/ManagedType.cpp)32
-rw-r--r--src/core/managed/Rtti.hpp183
-rw-r--r--src/core/model/Typesystem.cpp14
-rw-r--r--test/core/managed/ManagedTest.cpp35
-rw-r--r--test/core/managed/RttiTest.cpp63
8 files changed, 299 insertions, 232 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4cc06d6..371ffca 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,12 +32,17 @@ OPTION(BUILD_DOCUMENTATION "Create and install the HTML based API documentation
# Enable C++11 and all warnings
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic-errors -std=c++11")
-# Include boost (filesystem) expat and mozjs-24 via PkgConfig
+# Include expat and mozjs-24 via PkgConfig
FIND_PACKAGE(PkgConfig REQUIRED)
PKG_CHECK_MODULES(MOZJS REQUIRED mozjs-24)
PKG_CHECK_MODULES(EXPAT REQUIRED expat)
+
+# Include required Boost components using the Boost cmake package
FIND_PACKAGE(Boost COMPONENTS system filesystem REQUIRED)
+# Set utf8cpp include path
+SET(UTF8CPP_INCLUDE_DIR "lib/utf8")
+
################################################################################
# Inclusion of doxygen #
################################################################################
@@ -87,6 +92,7 @@ INCLUDE_DIRECTORIES(
${MOZJS_INCLUDE_DIRS}
${EXPAT_INCLUDE_DIRS}
${Boost_INCLUDE_DIR}
+ ${UTF8CPP_INCLUDE_DIR}
)
# Link directories
@@ -112,8 +118,8 @@ ADD_LIBRARY(ousia_core
src/core/common/Variant
src/core/common/VariantReader
src/core/managed/Managed
- src/core/managed/ManagedType
src/core/managed/Manager
+ src/core/managed/Rtti
src/core/model/Document
src/core/model/Domain
src/core/model/Typesystem
@@ -184,6 +190,7 @@ IF(TEST)
test/core/managed/ManagedContainerTest
test/core/managed/ManagedTest
test/core/managed/ManagerTest
+ test/core/managed/RttiTest
test/core/model/DomainTest
test/core/model/DocumentTest
test/core/model/TypesystemTest
diff --git a/src/core/managed/Managed.hpp b/src/core/managed/Managed.hpp
index cc55ae0..8582702 100644
--- a/src/core/managed/Managed.hpp
+++ b/src/core/managed/Managed.hpp
@@ -19,7 +19,7 @@
#ifndef _OUSIA_MANAGED_HPP_
#define _OUSIA_MANAGED_HPP_
-#include "ManagedType.hpp"
+#include "Rtti.hpp"
#include "Manager.hpp"
namespace ousia {
@@ -108,25 +108,25 @@ public:
bool deleteData(const std::string &key);
/**
- * Returns the ManagedType instance registered for instances of the type
- * of this Managed instance.
+ * Returns the RttiBase instance registered for instances of the type of
+ * this Managed instance.
*
- * @return a reference to the registered ManagedType for this particular
+ * @return a reference to the registered RttiBase for this particular
* Managed class.
*/
- const ManagedType &type() const
+ const RttiBase &type() const
{
- return ManagedType::typeOf(*this);
+ return typeOf(*this);
}
/**
- * Returns true if this Managed instance is of the given ManagedType.
+ * Returns true if this Managed instance is of the given RttiBase.
*
- * @param true if the ManagedType registered for this particular Managed
+ * @param true if the RttiBase registered for this particular Managed
* class is of the given type or one of the registered parent types is of
* the given type.
*/
- bool isa(const ManagedType &t) const { return type().isa(t); }
+ bool isa(const RttiBase &t) const { return type().isa(t); }
};
/**
diff --git a/src/core/managed/ManagedType.hpp b/src/core/managed/ManagedType.hpp
deleted file mode 100644
index 0a0d445..0000000
--- a/src/core/managed/ManagedType.hpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- 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/>.
-*/
-
-#ifndef _OUSIA_MANAGED_TYPE_HPP_
-#define _OUSIA_MANAGED_TYPE_HPP_
-
-#include <iostream>
-
-#include <typeinfo>
-#include <typeindex>
-#include <unordered_map>
-#include <vector>
-
-namespace ousia {
-
-/**
- * The ManagedType is used to register type information that can be retrieved
- * using the "type" method of the Managed class.
- */
-class ManagedType {
-private:
- /**
- * Used internally to store all registered native types and their
- * corresponding type information.
- */
- static std::unordered_map<std::type_index, ManagedType *> &table()
- {
- static std::unordered_map<std::type_index, ManagedType *> table;
- return table;
- }
-
- /**
- * Name of the type -- for messages and debug output.
- */
- const std::string name;
-
- /**
- * Set containing references to the parent types.
- */
- const std::vector<const ManagedType *> parents;
-
- /**
- * Returns the ManagedType for the given type_info structure.
- *
- * @param nativeType is a pointer at the C++ RTTI information.
- */
- static const ManagedType &rttiLookup(const std::type_info &nativeType);
-
-public:
- /**
- * ManagedType of no particular type.
- */
- static const ManagedType None;
-
- /**
- * Returns the ManagedType for the given native type.
- *
- * @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>
- static const ManagedType &typeOf(const T &obj)
- {
- return rttiLookup(typeid(obj));
- }
-
- /**
- * Returns the ManagedType for the given native type.
- *
- * @tparam T is the C++ type for which the type information should be
- * returned.
- */
- template <typename T>
- static const ManagedType &typeOf()
- {
- return rttiLookup(typeid(T));
- }
-
- /**
- * Default constructor. Creates a ManagedType instance with name "unknown"
- * and no parents.
- */
- ManagedType() : name("unknown") {}
-
- /**
- * Creates a new ManagedType instance and registers it in the global type
- * table.
- *
- * @param name is the name of the type.
- * @param nativeType is the underlying C++ class the type should be attached
- * to.
- */
- ManagedType(std::string name, const std::type_info &nativeType)
- : name(std::move(name))
- {
- table().emplace(std::make_pair(std::type_index{nativeType}, this));
- }
-
- /**
- * Creates a new ManagedType instance and registers it in the global type
- * table.
- *
- * @param name is the name of the type.
- * @param nativeType is the underlying C++ class the type should be attached
- * to.
- * @param parents is a list of parent types.
- */
- ManagedType(std::string name, const std::type_info &nativeType,
- const std::vector<const ManagedType *> &parents)
- : name(std::move(name)), parents(parents)
- {
- table().emplace(std::make_pair(std::type_index{nativeType}, this));
- }
-
- /**
- * Returns the name of this type.
- */
- std::string getName() const { return name; }
-
- /**
- * Returns true if this ManagedType 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 ManagedType &other) const;
-};
-
-/**
- * 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 ManagedType &typeOf()
-{
- return ManagedType::typeOf<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 ManagedType &typeOf(const T &obj)
-{
- return ManagedType::typeOf(obj);
-}
-}
-
-#endif /* _OUSIA_MANAGED_TYPE_HPP_ */
-
diff --git a/src/core/managed/ManagedType.cpp b/src/core/managed/Rtti.cpp
index 53e75a3..eade524 100644
--- a/src/core/managed/ManagedType.cpp
+++ b/src/core/managed/Rtti.cpp
@@ -16,27 +16,39 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ManagedType.hpp"
+#include "Rtti.hpp"
namespace ousia {
-/* Instantiation of static variables */
+/* Class RttiStore */
-const ManagedType ManagedType::None;
+std::unordered_map<std::type_index, const RttiBase *> &RttiStore::table()
+{
+ static std::unordered_map<std::type_index, const RttiBase *> table;
+ return table;
+}
-/* Class ManagedType */
+void RttiStore::store(const std::type_info &native, const RttiBase *rtti)
+{
+ table().emplace(std::type_index{native}, rtti);
+}
-const ManagedType &ManagedType::rttiLookup(const std::type_info &nativeType)
+const RttiBase &RttiStore::lookup(const std::type_info &native)
{
- auto it = table().find(std::type_index{nativeType});
- if (it == table().end()) {
- return None;
+ const auto &tbl = table();
+ auto it = tbl.find(std::type_index{native});
+ if (it == tbl.end()) {
+ return RttiBase::None;
} else {
return *(it->second);
}
}
-bool ManagedType::isa(const ManagedType &other) const
+/* Class RttiBase */
+
+const RttiBase RttiBase::None;
+
+bool RttiBase::isa(const RttiBase &other) const
{
if (&other == this) {
return true;
@@ -48,5 +60,7 @@ bool ManagedType::isa(const ManagedType &other) const
}
return false;
}
+
+
}
diff --git a/src/core/managed/Rtti.hpp b/src/core/managed/Rtti.hpp
new file mode 100644
index 0000000..f53fd9b
--- /dev/null
+++ b/src/core/managed/Rtti.hpp
@@ -0,0 +1,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_ */
+
diff --git a/src/core/model/Typesystem.cpp b/src/core/model/Typesystem.cpp
index 3fc8465..724bf0e 100644
--- a/src/core/model/Typesystem.cpp
+++ b/src/core/model/Typesystem.cpp
@@ -76,13 +76,13 @@ EnumType EnumType::createValidated(Manager &mgr, std::string name,
/* RTTI type registrations */
-const ManagedType Type_T("Type", typeid(Type));
-const ManagedType StringType_T("StringType", typeid(StringType), {&Type_T});
-const ManagedType IntType_T("IntType", typeid(IntType), {&Type_T});
-const ManagedType DoubleType_T("DoubleType", typeid(DoubleType), {&Type_T});
-const ManagedType BoolType_T("BoolType", typeid(BoolType), {&Type_T});
-const ManagedType EnumType_T("EnumType", typeid(EnumType), {&Type_T});
-const ManagedType StructType_T("StructType", typeid(EnumType), {&Type_T});
+const Rtti<Type> Type_T("Type");
+const Rtti<StringType> StringType_T("StringType", {&Type_T});
+const Rtti<IntType> IntType_T("IntType", {&Type_T});
+const Rtti<DoubleType> DoubleType_T("DoubleType", {&Type_T});
+const Rtti<BoolType> BoolType_T("BoolType", {&Type_T});
+const Rtti<EnumType> EnumType_T("EnumType", {&Type_T});
+const Rtti<StructType> StructType_T("StructType", {&Type_T});
}
}
diff --git a/test/core/managed/ManagedTest.cpp b/test/core/managed/ManagedTest.cpp
index e286166..c88cf7a 100644
--- a/test/core/managed/ManagedTest.cpp
+++ b/test/core/managed/ManagedTest.cpp
@@ -75,33 +75,10 @@ class TypeTestManaged5 : public Managed {
using Managed::Managed;
};
-ManagedType Type1("Type1", typeid(TypeTestManaged1));
-ManagedType Type2("Type2", typeid(TypeTestManaged2));
-ManagedType Type3("Type3", typeid(TypeTestManaged3), {&Type1});
-ManagedType Type4("Type2", typeid(TypeTestManaged4), {&Type3, &Type2});
-
-TEST(ManagedType, isa)
-{
- ASSERT_TRUE(Type1.isa(Type1));
- ASSERT_FALSE(Type1.isa(Type2));
- ASSERT_FALSE(Type1.isa(Type3));
- ASSERT_FALSE(Type1.isa(Type4));
-
- ASSERT_FALSE(Type2.isa(Type1));
- ASSERT_TRUE(Type2.isa(Type2));
- ASSERT_FALSE(Type2.isa(Type3));
- ASSERT_FALSE(Type2.isa(Type4));
-
- ASSERT_TRUE(Type3.isa(Type1));
- ASSERT_FALSE(Type3.isa(Type2));
- ASSERT_TRUE(Type3.isa(Type3));
- ASSERT_FALSE(Type3.isa(Type4));
-
- ASSERT_TRUE(Type4.isa(Type1));
- ASSERT_TRUE(Type4.isa(Type2));
- ASSERT_TRUE(Type4.isa(Type3));
- ASSERT_TRUE(Type4.isa(Type4));
-}
+static const Rtti<TypeTestManaged1> Type1("Type1");
+static const Rtti<TypeTestManaged2> Type2("Type2");
+static const Rtti<TypeTestManaged3> Type3("Type3", {&Type1});
+static const Rtti<TypeTestManaged4> Type4("Type4", {&Type3, &Type2});
TEST(Managed, type)
{
@@ -117,10 +94,8 @@ TEST(Managed, type)
ASSERT_EQ(&Type2, &m2->type());
ASSERT_EQ(&Type3, &m3->type());
ASSERT_EQ(&Type4, &m4->type());
- ASSERT_EQ(&ManagedType::None, &m5->type());
+ ASSERT_EQ(&RttiBase::None, &m5->type());
- ASSERT_EQ(&Type1, &ManagedType::typeOf(*m1));
- ASSERT_EQ(&Type1, &ManagedType::typeOf<TypeTestManaged1>());
ASSERT_EQ(&Type1, &typeOf<TypeTestManaged1>());
ASSERT_EQ(&Type1, &typeOf(*m1));
}
diff --git a/test/core/managed/RttiTest.cpp b/test/core/managed/RttiTest.cpp
new file mode 100644
index 0000000..091bdea
--- /dev/null
+++ b/test/core/managed/RttiTest.cpp
@@ -0,0 +1,63 @@
+/*
+ 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/>.
+*/
+
+#include <array>
+#include <string>
+#include <iostream>
+
+#include <gtest/gtest.h>
+
+#include <core/managed/Rtti.hpp>
+
+namespace ousia {
+
+class RttiTestClass1 {};
+class RttiTestClass2 {};
+class RttiTestClass3 {};
+class RttiTestClass4 {};
+
+static const Rtti<RttiTestClass1> Type1("Type1");
+static const Rtti<RttiTestClass2> Type2("Type2");
+static const Rtti<RttiTestClass3> Type3("Type3", {&Type1});
+static const Rtti<RttiTestClass4> Type4("Type4", {&Type3, &Type2});
+
+TEST(Rtti, isa)
+{
+ ASSERT_TRUE(Type1.isa(Type1));
+ ASSERT_FALSE(Type1.isa(Type2));
+ ASSERT_FALSE(Type1.isa(Type3));
+ ASSERT_FALSE(Type1.isa(Type4));
+
+ ASSERT_FALSE(Type2.isa(Type1));
+ ASSERT_TRUE(Type2.isa(Type2));
+ ASSERT_FALSE(Type2.isa(Type3));
+ ASSERT_FALSE(Type2.isa(Type4));
+
+ ASSERT_TRUE(Type3.isa(Type1));
+ ASSERT_FALSE(Type3.isa(Type2));
+ ASSERT_TRUE(Type3.isa(Type3));
+ ASSERT_FALSE(Type3.isa(Type4));
+
+ ASSERT_TRUE(Type4.isa(Type1));
+ ASSERT_TRUE(Type4.isa(Type2));
+ ASSERT_TRUE(Type4.isa(Type3));
+ ASSERT_TRUE(Type4.isa(Type4));
+}
+
+}
+