diff options
| author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2014-12-20 00:16:37 +0100 | 
|---|---|---|
| committer | Andreas Stöckel <andreas@somweyr.de> | 2014-12-20 00:16:37 +0100 | 
| commit | 04248309bdedb58be2fe1aa1fad0342ac936b541 (patch) | |
| tree | de8663198fad53b0bbca3b774b1abd1e4c4cbad2 | |
| parent | ee5a821286c48388a900c12b7c03190bed9b1f25 (diff) | |
improved RTTI system
| -rw-r--r-- | src/core/managed/Managed.hpp | 13 | ||||
| -rw-r--r-- | src/core/managed/ManagedType.cpp | 2 | ||||
| -rw-r--r-- | src/core/managed/ManagedType.hpp | 72 | ||||
| -rw-r--r-- | test/core/managed/ManagedTest.cpp | 5 | 
4 files changed, 76 insertions, 16 deletions
| diff --git a/src/core/managed/Managed.hpp b/src/core/managed/Managed.hpp index 4818c3d..cc55ae0 100644 --- a/src/core/managed/Managed.hpp +++ b/src/core/managed/Managed.hpp @@ -114,19 +114,19 @@ public:  	 * @return a reference to the registered ManagedType for this particular  	 * Managed class.  	 */ -	const ManagedType& type() const { -		return ManagedType::typeOf(typeid(*this)); +	const ManagedType &type() const +	{ +		return ManagedType::typeOf(*this);  	}  	/**  	 * Returns true if this Managed instance is of the given ManagedType.  	 *  	 * @param true if the ManagedType registered for this particular Managed -	 * class is  +	 * 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 ManagedType &t) const { return type().isa(t); }  };  /** @@ -512,7 +512,6 @@ public:  	 */  	Managed *getOwner() const { return owner; }  }; -  }  #endif /* _OUSIA_MANAGED_HPP_ */ diff --git a/src/core/managed/ManagedType.cpp b/src/core/managed/ManagedType.cpp index ed4c7da..53e75a3 100644 --- a/src/core/managed/ManagedType.cpp +++ b/src/core/managed/ManagedType.cpp @@ -26,7 +26,7 @@ const ManagedType ManagedType::None;  /* Class ManagedType */ -const ManagedType &ManagedType::typeOf(const std::type_info &nativeType) +const ManagedType &ManagedType::rttiLookup(const std::type_info &nativeType)  {  	auto it = table().find(std::type_index{nativeType});  	if (it == table().end()) { diff --git a/src/core/managed/ManagedType.hpp b/src/core/managed/ManagedType.hpp index f3ed5fd..0a0d445 100644 --- a/src/core/managed/ManagedType.hpp +++ b/src/core/managed/ManagedType.hpp @@ -19,10 +19,12 @@  #ifndef _OUSIA_MANAGED_TYPE_HPP_  #define _OUSIA_MANAGED_TYPE_HPP_ +#include <iostream> +  #include <typeinfo>  #include <typeindex>  #include <unordered_map> -#include <unordered_set> +#include <vector>  namespace ousia { @@ -36,7 +38,8 @@ 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() +	{  		static std::unordered_map<std::type_index, ManagedType *> table;  		return table;  	} @@ -49,7 +52,14 @@ private:  	/**  	 * Set containing references to the parent types.  	 */ -	const std::unordered_set<ManagedType *> parents; +	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:  	/** @@ -58,9 +68,30 @@ public:  	static const ManagedType None;  	/** -	 * Returns the ManagedType for the given type_info structure. +	 * 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.  	 */ -	static const ManagedType &typeOf(const std::type_info &nativeType); +	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" @@ -92,7 +123,7 @@ public:  	 * @param parents is a list of parent types.  	 */  	ManagedType(std::string name, const std::type_info &nativeType, -	            std::unordered_set<ManagedType *> parents) +	            const std::vector<const ManagedType *> &parents)  	    : name(std::move(name)), parents(parents)  	{  		table().emplace(std::make_pair(std::type_index{nativeType}, this)); @@ -105,14 +136,39 @@ public:  	/**  	 * Returns true if this ManagedType instance is the given type or has the -	 *given -	 * type as one of its parents. +	 * 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/test/core/managed/ManagedTest.cpp b/test/core/managed/ManagedTest.cpp index f196770..e286166 100644 --- a/test/core/managed/ManagedTest.cpp +++ b/test/core/managed/ManagedTest.cpp @@ -118,6 +118,11 @@ TEST(Managed, type)  	ASSERT_EQ(&Type3, &m3->type());  	ASSERT_EQ(&Type4, &m4->type());  	ASSERT_EQ(&ManagedType::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));  }  } | 
