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*
|
build*
|
||||||
*.swp
|
*.swp
|
||||||
.settings
|
.settings
|
||||||
|
# ignore mac temporal files
|
||||||
|
.DS_Store
|
||||||
|
|||||||
@@ -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
|
|||||||
/// 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:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
std::string name_;
|
std::string name_;
|
||||||
|
std::string internal_type_name_;
|
||||||
bool persistent_;
|
bool persistent_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|||||||
|
|
||||||
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:
|
|||||||
|
|
||||||
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:
|
|||||||
|
|
||||||
|
|
||||||
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:
|
|||||||
|
|
||||||
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 @@
|
|||||||
#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:
|
|||||||
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:
|
|||||||
{
|
{
|
||||||
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:
|
|||||||
{
|
{
|
||||||
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:
|
|||||||
{
|
{
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
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