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

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

Property internal typename

See merge request !225
parents 481ffd7f 83c7408f
Pipeline #11909 passed with stages
in 73 minutes and 38 seconds
......@@ -4,3 +4,5 @@ CMakeLists.txt.user
build*
*.swp
.settings
# ignore mac temporal files
.DS_Store
......@@ -80,13 +80,13 @@ public:
///
/// \param _name Optional textual name for the property.
///
BaseProperty(const std::string& _name = "<unknown>")
: name_(_name), persistent_(false)
BaseProperty(const std::string& _name = "<unknown>", const std::string& _internal_type_name = "<unknown>" )
: name_(_name), internal_type_name_(_internal_type_name), persistent_(false)
{}
/// \brief Copy constructor
BaseProperty(const BaseProperty & _rhs)
: name_( _rhs.name_ ), persistent_( _rhs.persistent_ ) {}
: name_( _rhs.name_ ), internal_type_name_(_rhs.internal_type_name_), persistent_( _rhs.persistent_ ) {}
/// Destructor.
virtual ~BaseProperty() {}
......@@ -119,6 +119,9 @@ public: // named property interface
/// Return the name of the property
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;
public: // I/O support
......@@ -173,6 +176,7 @@ protected:
private:
std::string name_;
std::string internal_type_name_;
bool persistent_;
};
......
......@@ -99,8 +99,10 @@ public:
public:
/// Default constructor
explicit PropertyT(const std::string& _name = "<unknown>")
: BaseProperty(_name)
explicit PropertyT(
const std::string& _name = "<unknown>",
const std::string& _internal_type_name = "<unknown>")
: BaseProperty(_name, _internal_type_name)
{}
/// Copy constructor
......@@ -173,17 +175,17 @@ public: // data access interface
return &data_[0];
}
/// Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!)
vector_type& data_vector() {
return data_;
}
/// Const access to property vector
const vector_type& data_vector() const {
return data_;
}
/// Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!)
vector_type& data_vector() {
return data_;
}
/// Const access to property vector
const vector_type& data_vector() const {
return data_;
}
/// Access the i'th element. No range check is performed!
reference operator[](int _idx)
{
......@@ -230,8 +232,8 @@ public:
public:
explicit PropertyT(const std::string& _name = "<unknown>")
: BaseProperty(_name)
explicit PropertyT(const std::string& _name = "<unknown>", const std::string& _internal_type_name="" )
: BaseProperty(_name, _internal_type_name)
{ }
public: // inherited from BaseProperty
......@@ -337,17 +339,17 @@ public:
public:
/// Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!)
vector_type& data_vector() {
return data_;
}
/// Const access to property vector
const vector_type& data_vector() const {
return data_;
}
/// Get reference to property vector (be careful, improper usage, e.g. resizing, may crash OpenMesh!!!)
vector_type& data_vector() {
return data_;
}
/// Const access to property vector
const vector_type& data_vector() const {
return data_;
}
/// Access the i'th element. No range check is performed!
reference operator[](int _idx)
{
......@@ -394,8 +396,8 @@ public:
public:
explicit PropertyT(const std::string& _name = "<unknown>")
: BaseProperty(_name)
explicit PropertyT(const std::string& _name = "<unknown>", const std::string& _internal_type_name="" )
: BaseProperty(_name, _internal_type_name)
{ }
public: // inherited from BaseProperty
......
......@@ -44,12 +44,8 @@
#ifndef 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/typename.hh>
//-----------------------------------------------------------------------------
namespace OpenMesh
......@@ -104,7 +100,7 @@ public:
int idx=0;
for ( ; p_it!=p_end && *p_it!=nullptr; ++p_it, ++idx ) {};
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);
}
......@@ -117,10 +113,7 @@ public:
{
if (*p_it != nullptr &&
(*p_it)->name() == _name //skip deleted properties
// Skip type check
#ifndef OM_FORCE_STATIC_CAST
&& dynamic_cast<PropertyT<T>*>(properties_[idx]) != nullptr //check type
#endif
&& (*p_it)->internal_type_name() == get_type_name<T>() // new check type
)
{
return BasePropHandleT<T>(idx);
......@@ -146,13 +139,10 @@ public:
{
assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size());
assert(properties_[_h.idx()] != nullptr);
#ifdef OM_FORCE_STATIC_CAST
return *static_cast <PropertyT<T>*> (properties_[_h.idx()]);
#else
PropertyT<T>* p = dynamic_cast<PropertyT<T>*>(properties_[_h.idx()]);
assert( properties_[_h.idx()]->internal_type_name() == get_type_name<T>() );
PropertyT<T> *p = static_cast< PropertyT<T>* > (properties_[_h.idx()]);
assert(p != nullptr);
return *p;
#endif
}
......@@ -160,13 +150,10 @@ public:
{
assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size());
assert(properties_[_h.idx()] != nullptr);
#ifdef OM_FORCE_STATIC_CAST
return *static_cast<PropertyT<T>*>(properties_[_h.idx()]);
#else
PropertyT<T>* p = dynamic_cast<PropertyT<T>*>(properties_[_h.idx()]);
assert( properties_[_h.idx()]->internal_type_name() == get_type_name<T>() );
PropertyT<T> *p = static_cast< PropertyT<T>* > (properties_[_h.idx()]);
assert(p != nullptr);
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