From 435cf124ce3eb66f822a5b3eb1e4e4836bcc8131 Mon Sep 17 00:00:00 2001 From: Martin Heistermann Date: Thu, 23 May 2019 17:15:15 +0200 Subject: [PATCH] Properties: Store and compare type names instead of relying on dynamic_cast --- src/OpenVolumeMesh/Core/BaseProperty.hh | 10 ++------ .../Core/OpenVolumeMeshBaseProperty.hh | 25 ++++++++++--------- .../Core/OpenVolumeMeshProperty.hh | 13 ++++++---- src/OpenVolumeMesh/Core/PropertyDefines.hh | 2 +- .../Core/PropertyDefinesT_impl.hh | 4 +-- src/OpenVolumeMesh/Core/PropertyPtr.hh | 1 + .../Core/ResourceManagerT_impl.hh | 17 +++++++------ src/OpenVolumeMesh/Core/TypeName.hh | 21 ++++++++++++++++ 8 files changed, 57 insertions(+), 36 deletions(-) create mode 100644 src/OpenVolumeMesh/Core/TypeName.hh diff --git a/src/OpenVolumeMesh/Core/BaseProperty.hh b/src/OpenVolumeMesh/Core/BaseProperty.hh index 5e117e6..984e94b 100644 --- a/src/OpenVolumeMesh/Core/BaseProperty.hh +++ b/src/OpenVolumeMesh/Core/BaseProperty.hh @@ -32,14 +32,6 @@ * * \*===========================================================================*/ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * $LastChangedBy$ * - * * -\*===========================================================================*/ - #ifndef BASEPROPERTY_HH_ #define BASEPROPERTY_HH_ @@ -93,6 +85,8 @@ public: protected: + virtual const std::string &internal_type_name() const = 0; + /// Copy data from other property. `other` MUST point to an object with the same type as `this`! /// Currently no type check is performed. virtual void assign_values_from(const BaseProperty *other) = 0; diff --git a/src/OpenVolumeMesh/Core/OpenVolumeMeshBaseProperty.hh b/src/OpenVolumeMesh/Core/OpenVolumeMeshBaseProperty.hh index 0a2117c..51e3b48 100644 --- a/src/OpenVolumeMesh/Core/OpenVolumeMeshBaseProperty.hh +++ b/src/OpenVolumeMesh/Core/OpenVolumeMeshBaseProperty.hh @@ -32,15 +32,6 @@ * * \*===========================================================================*/ -/*===========================================================================*\ - * * - * $Revision$ * - * $Date$ * - * $LastChangedBy$ * - * * -\*===========================================================================*/ - - #ifndef OPENVOLUMEMESHBASEPROPERTY_HH #define OPENVOLUMEMESHBASEPROPERTY_HH @@ -71,9 +62,14 @@ public: public: - explicit OpenVolumeMeshBaseProperty(const std::string& _name = "") : - name_(_name), persistent_(false), handle_(-1) { - } + explicit OpenVolumeMeshBaseProperty( + const std::string& _name = "", + const std::string& _internal_type_name = "") + : name_(_name), + internal_type_name_(_internal_type_name), + persistent_(false), + handle_(-1) + {} OpenVolumeMeshBaseProperty(const OpenVolumeMeshBaseProperty& _rhs) = default; @@ -107,6 +103,10 @@ public: return name_; } + const std::string& internal_type_name() const { + return internal_type_name_; + } + // Function to serialize a property virtual void serialize(std::ostream& /*_ostr*/) const {} @@ -148,6 +148,7 @@ protected: private: std::string name_; + std::string internal_type_name_; bool persistent_; diff --git a/src/OpenVolumeMesh/Core/OpenVolumeMeshProperty.hh b/src/OpenVolumeMesh/Core/OpenVolumeMeshProperty.hh index 736f03f..f5f90d7 100644 --- a/src/OpenVolumeMesh/Core/OpenVolumeMeshProperty.hh +++ b/src/OpenVolumeMesh/Core/OpenVolumeMeshProperty.hh @@ -62,7 +62,7 @@ template class OpenVolumeMeshPropertyT: public OpenVolumeMeshBaseProperty { public: - template friend class PropertyPtr; + template friend class PropertyPtr; typedef T Value; typedef std::vector vector_type; @@ -72,10 +72,13 @@ public: public: - OpenVolumeMeshPropertyT(const std::string& _name = "", const T &_def = T()) : - OpenVolumeMeshBaseProperty(_name), - def_(_def) { - } + explicit OpenVolumeMeshPropertyT( + const std::string& _name = "", + const std::string& _internal_type_name = "", + const T &_def = T()) + : OpenVolumeMeshBaseProperty(_name, _internal_type_name), + def_(_def) + {} OpenVolumeMeshPropertyT(const OpenVolumeMeshPropertyT& _rhs) = default; diff --git a/src/OpenVolumeMesh/Core/PropertyDefines.hh b/src/OpenVolumeMesh/Core/PropertyDefines.hh index cd14c5f..aae0762 100644 --- a/src/OpenVolumeMesh/Core/PropertyDefines.hh +++ b/src/OpenVolumeMesh/Core/PropertyDefines.hh @@ -89,7 +89,7 @@ public: : PropertyTT(std::move(mesh->template request_property(_name, _def))) {} using PropertyHandleT = OpenVolumeMesh::PropHandleT; - PropertyTT(const std::string& _name, ResourceManager& _resMan, PropertyHandleT _handle, const T _def = T()); + PropertyTT(const std::string& _name, const std::string& _internal_type_name, ResourceManager& _resMan, PropertyHandleT _handle, const T _def = T()); virtual ~PropertyTT() = default; virtual BaseProperty* clone(ResourceManager &_resMan, OpenVolumeMeshHandle _handle) const; virtual const std::string entityType() const { return entityTypeName(); } diff --git a/src/OpenVolumeMesh/Core/PropertyDefinesT_impl.hh b/src/OpenVolumeMesh/Core/PropertyDefinesT_impl.hh index edb35dd..d7e83d4 100644 --- a/src/OpenVolumeMesh/Core/PropertyDefinesT_impl.hh +++ b/src/OpenVolumeMesh/Core/PropertyDefinesT_impl.hh @@ -42,8 +42,8 @@ namespace OpenVolumeMesh { template -PropertyTT::PropertyTT(const std::string& _name, ResourceManager& _resMan, PropertyHandleT _handle, const T _def) : - PropertyPtr, Entity>(new OpenVolumeMeshPropertyT(_name, _def), _resMan, _handle) { +PropertyTT::PropertyTT(const std::string& _name, const std::string& _internal_type_name, ResourceManager& _resMan, PropertyHandleT _handle, const T _def) : + PropertyPtr, Entity>(new OpenVolumeMeshPropertyT(_name, _internal_type_name, _def), _resMan, _handle) { } diff --git a/src/OpenVolumeMesh/Core/PropertyPtr.hh b/src/OpenVolumeMesh/Core/PropertyPtr.hh index ff9feff..d162485 100644 --- a/src/OpenVolumeMesh/Core/PropertyPtr.hh +++ b/src/OpenVolumeMesh/Core/PropertyPtr.hh @@ -114,6 +114,7 @@ public: virtual bool anonymous() const { return ptr::shared_ptr::get()->name().empty(); } protected: + virtual const std::string &internal_type_name() const { return ptr::shared_ptr::get()->internal_type_name(); } void assign_values_from(const BaseProperty *other) override; void move_values_from(BaseProperty *other) override; diff --git a/src/OpenVolumeMesh/Core/ResourceManagerT_impl.hh b/src/OpenVolumeMesh/Core/ResourceManagerT_impl.hh index 75d44d4..5c9a603 100644 --- a/src/OpenVolumeMesh/Core/ResourceManagerT_impl.hh +++ b/src/OpenVolumeMesh/Core/ResourceManagerT_impl.hh @@ -44,9 +44,11 @@ #include "ResourceManager.hh" #include "PropertyDefines.hh" +#include "TypeName.hh" namespace OpenVolumeMesh { + template VertexPropertyT ResourceManager::request_vertex_property(const std::string& _name, const T _def) { @@ -90,25 +92,24 @@ MeshPropertyT ResourceManager::request_mesh_property(const std::string& _name } template -PropT ResourceManager::internal_request_property(StdVecT& _vec, const std::string& _name, size_t _size, const T _def) { +PropT ResourceManager::internal_request_property(StdVecT& _vec, const std::string& _name, size_t _size, const T _def) +{ + auto type_name = get_type_name(); if(!_name.empty()) { for(typename StdVecT::iterator it = _vec.begin(); it != _vec.end(); ++it) { - if((*it)->name() == _name) { -#if OVM_FORCE_STATIC_CAST + if((*it)->name() == _name + && (*it)->internal_type_name() == type_name) + { return *static_cast(*it); -#else - PropT* prop = dynamic_cast(*it); - if(prop != NULL) return *prop; -#endif } } } HandleT handle((int)_vec.size()); - PropT* prop = new PropT(_name, *this, handle, _def); + PropT* prop = new PropT(_name, type_name, *this, handle, _def); prop->resize(_size); // Store property pointer diff --git a/src/OpenVolumeMesh/Core/TypeName.hh b/src/OpenVolumeMesh/Core/TypeName.hh new file mode 100644 index 0000000..058edef --- /dev/null +++ b/src/OpenVolumeMesh/Core/TypeName.hh @@ -0,0 +1,21 @@ +#include +#include + +/// Get an internal name for a type. Important: this differs between +/// compilers and versions, do NOT use in file formats! +/// We need this in order to provide property type safety when +/// only limited RTTI support is available. +template +std::string get_type_name() +{ +#ifdef _MSC_VER + // MSVC's type_name only returns a friendly name with .name(), + // get the more unique mangled name using .raw_name(): + return typeid(T).raw_name(); +#else + // GCC and clang currently return the mangled name as .name(), + // there is no .raw_name() + return typeid(T).name(); +#endif +} + -- GitLab