Commit 9279b2a1 authored by Jan Möbius's avatar Jan Möbius
Browse files

Merge branch 'property-internal-typename' into 'master'

Property internal typename

See merge request !225
parents 481ffd7f 83c7408f
...@@ -4,3 +4,5 @@ CMakeLists.txt.user ...@@ -4,3 +4,5 @@ CMakeLists.txt.user
build* build*
*.swp *.swp
.settings .settings
# ignore mac temporal files
.DS_Store
...@@ -80,13 +80,13 @@ public: ...@@ -80,13 +80,13 @@ public:
/// ///
/// \param _name Optional textual name for the property. /// \param _name Optional textual name for the property.
/// ///
BaseProperty(const std::string& _name = "<unknown>") BaseProperty(const std::string& _name = "<unknown>", const std::string& _internal_type_name = "<unknown>" )
: name_(_name), persistent_(false) : name_(_name), internal_type_name_(_internal_type_name), persistent_(false)
{} {}
/// \brief Copy constructor /// \brief Copy constructor
BaseProperty(const BaseProperty & _rhs) BaseProperty(const BaseProperty & _rhs)
: name_( _rhs.name_ ), persistent_( _rhs.persistent_ ) {} : name_( _rhs.name_ ), internal_type_name_(_rhs.internal_type_name_), persistent_( _rhs.persistent_ ) {}
/// Destructor. /// Destructor.
virtual ~BaseProperty() {} virtual ~BaseProperty() {}
...@@ -119,6 +119,9 @@ public: // named property interface ...@@ -119,6 +119,9 @@ public: // named property interface
/// Return the name of the property /// Return the name of the property
const std::string& name() const { return name_; } const std::string& name() const { return name_; }
/// Return internal type name of the property for type safe casting alternative to runtime information
const std::string& internal_type_name() const { return internal_type_name_; }
virtual void stats(std::ostream& _ostr) const; virtual void stats(std::ostream& _ostr) const;
public: // I/O support public: // I/O support
...@@ -173,6 +176,7 @@ protected: ...@@ -173,6 +176,7 @@ protected:
private: private:
std::string name_; std::string name_;
std::string internal_type_name_;
bool persistent_; bool persistent_;
}; };
......
...@@ -99,8 +99,10 @@ public: ...@@ -99,8 +99,10 @@ public:
public: public:
/// Default constructor /// Default constructor
explicit PropertyT(const std::string& _name = "<unknown>") explicit PropertyT(
: BaseProperty(_name) const std::string& _name = "<unknown>",
const std::string& _internal_type_name = "<unknown>")
: BaseProperty(_name, _internal_type_name)
{} {}
/// Copy constructor /// Copy constructor
...@@ -173,17 +175,17 @@ public: // data access interface ...@@ -173,17 +175,17 @@ public: // data access interface
return &data_[0]; return &data_[0];
} }
/// Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!) /// Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!)
vector_type& data_vector() { vector_type& data_vector() {
return data_; return data_;
} }
/// Const access to property vector /// Const access to property vector
const vector_type& data_vector() const { const vector_type& data_vector() const {
return data_; return data_;
} }
/// Access the i'th element. No range check is performed! /// Access the i'th element. No range check is performed!
reference operator[](int _idx) reference operator[](int _idx)
{ {
...@@ -230,8 +232,8 @@ public: ...@@ -230,8 +232,8 @@ public:
public: public:
explicit PropertyT(const std::string& _name = "<unknown>") explicit PropertyT(const std::string& _name = "<unknown>", const std::string& _internal_type_name="" )
: BaseProperty(_name) : BaseProperty(_name, _internal_type_name)
{ } { }
public: // inherited from BaseProperty public: // inherited from BaseProperty
...@@ -337,17 +339,17 @@ public: ...@@ -337,17 +339,17 @@ public:
public: public:
/// Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!) /// Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!)
vector_type& data_vector() { vector_type& data_vector() {
return data_; return data_;
} }
/// Const access to property vector /// Const access to property vector
const vector_type& data_vector() const { const vector_type& data_vector() const {
return data_; return data_;
} }
/// Access the i'th element. No range check is performed! /// Access the i'th element. No range check is performed!
reference operator[](int _idx) reference operator[](int _idx)
{ {
...@@ -394,8 +396,8 @@ public: ...@@ -394,8 +396,8 @@ public:
public: public:
explicit PropertyT(const std::string& _name = "<unknown>") explicit PropertyT(const std::string& _name = "<unknown>", const std::string& _internal_type_name="" )
: BaseProperty(_name) : BaseProperty(_name, _internal_type_name)
{ } { }
public: // inherited from BaseProperty public: // inherited from BaseProperty
......
...@@ -44,12 +44,8 @@ ...@@ -44,12 +44,8 @@
#ifndef OPENMESH_PROPERTYCONTAINER #ifndef OPENMESH_PROPERTYCONTAINER
#define OPENMESH_PROPERTYCONTAINER #define OPENMESH_PROPERTYCONTAINER
// Use static casts when not debugging
#ifdef NDEBUG
#define OM_FORCE_STATIC_CAST
#endif
#include <OpenMesh/Core/Utils/Property.hh> #include <OpenMesh/Core/Utils/Property.hh>
#include <OpenMesh/Core/Utils/typename.hh>
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
namespace OpenMesh namespace OpenMesh
...@@ -104,7 +100,7 @@ public: ...@@ -104,7 +100,7 @@ public:
int idx=0; int idx=0;
for ( ; p_it!=p_end && *p_it!=nullptr; ++p_it, ++idx ) {}; for ( ; p_it!=p_end && *p_it!=nullptr; ++p_it, ++idx ) {};
if (p_it==p_end) properties_.push_back(nullptr); if (p_it==p_end) properties_.push_back(nullptr);
properties_[idx] = new PropertyT<T>(_name); properties_[idx] = new PropertyT<T>(_name, get_type_name<T>() ); // create a new property with requested name and given (system dependent) internal typename
return BasePropHandleT<T>(idx); return BasePropHandleT<T>(idx);
} }
...@@ -117,10 +113,7 @@ public: ...@@ -117,10 +113,7 @@ public:
{ {
if (*p_it != nullptr && if (*p_it != nullptr &&
(*p_it)->name() == _name //skip deleted properties (*p_it)->name() == _name //skip deleted properties
// Skip type check && (*p_it)->internal_type_name() == get_type_name<T>() // new check type
#ifndef OM_FORCE_STATIC_CAST
&& dynamic_cast<PropertyT<T>*>(properties_[idx]) != nullptr //check type
#endif
) )
{ {
return BasePropHandleT<T>(idx); return BasePropHandleT<T>(idx);
...@@ -146,13 +139,10 @@ public: ...@@ -146,13 +139,10 @@ public:
{ {
assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size()); assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size());
assert(properties_[_h.idx()] != nullptr); assert(properties_[_h.idx()] != nullptr);
#ifdef OM_FORCE_STATIC_CAST assert( properties_[_h.idx()]->internal_type_name() == get_type_name<T>() );
return *static_cast <PropertyT<T>*> (properties_[_h.idx()]); PropertyT<T> *p = static_cast< PropertyT<T>* > (properties_[_h.idx()]);
#else
PropertyT<T>* p = dynamic_cast<PropertyT<T>*>(properties_[_h.idx()]);
assert(p != nullptr); assert(p != nullptr);
return *p; return *p;
#endif
} }
...@@ -160,13 +150,10 @@ public: ...@@ -160,13 +150,10 @@ public:
{ {
assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size()); assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size());
assert(properties_[_h.idx()] != nullptr); assert(properties_[_h.idx()] != nullptr);
#ifdef OM_FORCE_STATIC_CAST assert( properties_[_h.idx()]->internal_type_name() == get_type_name<T>() );
return *static_cast<PropertyT<T>*>(properties_[_h.idx()]); PropertyT<T> *p = static_cast< PropertyT<T>* > (properties_[_h.idx()]);
#else
PropertyT<T>* p = dynamic_cast<PropertyT<T>*>(properties_[_h.idx()]);
assert(p != nullptr); assert(p != nullptr);
return *p; return *p;
#endif
} }
......
#pragma once
/// Get an internal name for a type
/// Important, this is depends on compilers and versions, do NOT use in file formats!
/// This provides property type safety when only limited RTTI is available
/// Solution adapted from OpenVolumeMesh
#include <string>
#include <typeinfo>
namespace OpenMesh {
template <typename T>
std::string get_type_name()
{
#ifdef _MSC_VER
// MSVC'S type_name returns only a friendly name with name() method,
// to get a unique name use raw_name() method instead
return typeid(T).raw_name();
#else
// GCC and clang curently return mangled name as name(), there is no raw_name() method
return typeid(T).name();
#endif
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment