Merge branch 'property-internal-typename' into 'master'
Property internal typename See merge request OpenMesh/OpenMesh!225
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
26
src/OpenMesh/Core/Utils/typename.hh
Normal file
26
src/OpenMesh/Core/Utils/typename.hh
Normal file
@@ -0,0 +1,26 @@
|
||||
#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
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user