Commit aebc2089 authored by Martin Heistermann's avatar Martin Heistermann
Browse files

Properties: use partial template specialization.

Avoid a lot of code duplication.

Also change constructor _def param to a const&, which was only in
the std::string specialization before, but makes sense everywhere.
parent 9ec8ccad
Pipeline #8871 failed with stage
in 2 minutes and 52 seconds
......@@ -75,9 +75,7 @@ public:
name_(_name), persistent_(false), handle_(-1) {
}
OpenVolumeMeshBaseProperty(const OpenVolumeMeshBaseProperty& _rhs) :
name_(_rhs.name_), persistent_(_rhs.persistent_), handle_(_rhs.handle_.idx()) {
}
OpenVolumeMeshBaseProperty(const OpenVolumeMeshBaseProperty& _rhs) = default;
virtual ~OpenVolumeMeshBaseProperty() {}
......
......@@ -72,18 +72,13 @@ public:
public:
/// Default constructor
OpenVolumeMeshPropertyT(const std::string& _name = "<unknown>", const T _def = T()) :
OpenVolumeMeshPropertyT(const std::string& _name = "<unknown>", const T &_def = T()) :
OpenVolumeMeshBaseProperty(_name),
def_(_def) {
}
/// Copy constructor
OpenVolumeMeshPropertyT(const OpenVolumeMeshPropertyT& _rhs) :
OpenVolumeMeshBaseProperty(_rhs),
data_(_rhs.data_),
def_(_rhs.def_) {
}
OpenVolumeMeshPropertyT(const OpenVolumeMeshPropertyT& _rhs) = default;
public:
// inherited from OpenVolumeMeshBaseProperty
......@@ -103,6 +98,8 @@ public:
virtual void swap(size_t _i0, size_t _i1) {
std::swap(data_[_i0], data_[_i1]);
}
virtual void copy(size_t _src_idx, size_t _dst_idx) {
data_[_dst_idx] = data_[_src_idx];
}
......@@ -119,6 +116,7 @@ public:
return sizeof(T);
}
#ifndef DOXY_IGNORE_THIS
struct plus {
size_t operator ()(size_t _b, const T& /*_v*/) {
......@@ -221,293 +219,69 @@ private:
const T def_;
};
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Property specialization for bool type.
//-----------------------------------------------------------------------------
/**
* Property specialization for bool type.
*/
template<>
class OpenVolumeMeshPropertyT<bool> : public OpenVolumeMeshBaseProperty {
public:
template <class PropT, class HandleT> friend class PropertyPtr;
typedef std::vector<bool> vector_type;
typedef bool value_type;
typedef vector_type::reference reference;
typedef vector_type::const_reference const_reference;
public:
OpenVolumeMeshPropertyT(const std::string& _name = "<unknown>", const bool _def = bool()) :
OpenVolumeMeshBaseProperty(_name),
def_(_def) {
}
public:
// inherited from OpenVolumeMeshBaseProperty
virtual void reserve(size_t _n) {
data_.reserve(_n);
}
virtual void resize(size_t _n) {
data_.resize(_n, def_);
}
virtual void clear() {
data_.clear();
vector_type().swap(data_);
}
virtual void push_back() {
data_.push_back(def_);
}
virtual void swap(size_t _i0, size_t _i1) {
bool t(data_[_i0]);
data_[_i0] = data_[_i1];
data_[_i1] = t;
}
virtual void copy(size_t _src_idx, size_t _dst_idx) {
data_[_dst_idx] = data_[_src_idx];
}
inline void OpenVolumeMeshPropertyT<bool>::swap(size_t _i0, size_t _i1)
{
data_.swap(data_[_i0], data_[_i1]);
}
void delete_element(size_t _idx) {
data_.erase(data_.begin() + _idx);
}
public:
template<>
inline size_t OpenVolumeMeshPropertyT<bool>::size_of(size_t _n_elem) const
{
return _n_elem / 8 + ((_n_elem % 8) != 0);
}
virtual size_t n_elements() const {
return data_.size();
}
virtual size_t element_size() const {
return OpenVolumeMeshBaseProperty::UnknownSize;
}
virtual size_t size_of() const {
template<>
inline size_t OpenVolumeMeshPropertyT<bool>::size_of() const
{
return size_of(n_elements());
}
virtual size_t size_of(size_t _n_elem) const {
return _n_elem / 8 + ((_n_elem % 8) != 0);
}
}
// Function to serialize a property
virtual void serialize(std::ostream& _ostr) const {
for(vector_type::const_iterator it = data_.begin();
it != data_.end(); ++it) {
OpenVolumeMesh::serialize(_ostr, *it) << std::endl;
}
}
template<>
inline size_t OpenVolumeMeshPropertyT<bool>::element_size() const
{
return OpenVolumeMeshBaseProperty::UnknownSize;
}
// Function to deserialize a property
virtual void deserialize(std::istream& _istr) {
template<>
inline void OpenVolumeMeshPropertyT<bool>::deserialize(std::istream& _istr)
{
for(unsigned int i = 0; i < n_elements(); ++i) {
value_type val;
OpenVolumeMesh::deserialize(_istr, val);
data_[i] = val;
}
}
public:
/// Access the i'th element. No range check is performed!
reference operator[](size_t _idx) {
assert(_idx < data_.size());
return data_[_idx];
}
/// Const access to the i'th element. No range check is performed!
const_reference operator[](size_t _idx) const {
assert(_idx < data_.size());
return data_[_idx];
}
/// Make a copy of self.
OpenVolumeMeshPropertyT<bool>* clone() const {
OpenVolumeMeshPropertyT<bool>* p = new OpenVolumeMeshPropertyT<bool> (
*this);
return p;
}
vector_type::const_iterator begin() const { return data_.begin(); }
}
vector_type::iterator begin() { return data_.begin(); }
vector_type::const_iterator end() const { return data_.end(); }
vector_type::iterator end() { return data_.end(); }
protected:
/// Delete multiple entries in list
virtual void delete_multiple_entries(const std::vector<bool>& _tags) {
assert(_tags.size() == data_.size());
vector_type new_data;
vector_type::iterator d_it = data_.begin();
std::vector<bool>::const_iterator t_it = _tags.begin();
std::vector<bool>::const_iterator t_end = _tags.end();
for(; t_it != t_end; ++t_it, ++d_it) {
if(!*t_it) {
new_data.push_back(*d_it);
}
}
data_.swap(new_data);
}
private:
vector_type data_;
const bool def_;
};
//-----------------------------------------------------------------------------
/**
* Property specialization for std::string type.
*/
// Property specialization for std::string type.
//-----------------------------------------------------------------------------
template<>
class OpenVolumeMeshPropertyT<std::string> : public OpenVolumeMeshBaseProperty {
public:
template <class PropT, class HandleT> friend class PropertyPtr;
typedef std::string Value;
typedef std::vector<std::string> vector_type;
typedef std::string value_type;
typedef vector_type::reference reference;
typedef vector_type::const_reference const_reference;
public:
OpenVolumeMeshPropertyT(const std::string& _name = "<unknown>", const std::string& _def = "") :
OpenVolumeMeshBaseProperty(_name),
def_(_def) {
}
public:
// inherited from OpenVolumeMeshBaseProperty
virtual void reserve(size_t _n) {
data_.reserve(_n);
}
virtual void resize(size_t _n) {
data_.resize(_n, def_);
}
virtual void clear() {
data_.clear();
vector_type().swap(data_);
}
virtual void push_back() {
data_.push_back(def_);
}
virtual void swap(size_t _i0, size_t _i1) {
std::swap(data_[_i0], data_[_i1]);
}
virtual void copy(size_t _src_idx, size_t _dst_idx) {
data_[_dst_idx] = data_[_src_idx];
}
virtual void delete_element(size_t _idx) {
data_.erase(data_.begin() + _idx);
}
public:
virtual size_t n_elements() const {
return data_.size();
}
virtual size_t element_size() const {
inline size_t OpenVolumeMeshPropertyT<std::string>::size_of(size_t) const
{
return OpenVolumeMeshBaseProperty::UnknownSize;
}
virtual size_t size_of() const {
}
template<>
inline size_t OpenVolumeMeshPropertyT<std::string>::size_of() const
{
return sizeof(data_);
}
}
virtual size_t size_of(size_t /* _n_elem */) const {
template<>
inline size_t OpenVolumeMeshPropertyT<std::string>::element_size() const
{
return OpenVolumeMeshBaseProperty::UnknownSize;
}
virtual void stats(std::ostream& _ostr) const {
for(vector_type::const_iterator it = data_.begin();
it != data_.end(); ++it) {
_ostr << *it << " ";
}
}
// Function to serialize a property
virtual void serialize(std::ostream& _ostr) const {
for(vector_type::const_iterator it = data_.begin();
it != data_.end(); ++it) {
OpenVolumeMesh::serialize(_ostr, *it) << std::endl;
}
}
// Function to deserialize a property
virtual void deserialize(std::istream& _istr) {
for(unsigned int i = 0; i < n_elements(); ++i) {
OpenVolumeMesh::deserialize(_istr, data_[i]);
}
}
public:
const value_type* data() const {
if (data_.empty())
return 0;
return (value_type*) &data_[0];
}
/// Access the i'th element. No range check is performed!
reference operator[](size_t _idx) {
assert(_idx < data_.size());
return ((value_type*) &data_[0])[_idx];
}
/// Const access the i'th element. No range check is performed!
const_reference operator[](size_t _idx) const {
assert(_idx < data_.size());
return ((value_type*) &data_[0])[_idx];
}
}
OpenVolumeMeshPropertyT<value_type>* clone() const {
OpenVolumeMeshPropertyT<value_type>* p = new OpenVolumeMeshPropertyT<
value_type> (*this);
return p;
}
vector_type::const_iterator begin() const { return data_.begin(); }
vector_type::iterator begin() { return data_.begin(); }
vector_type::const_iterator end() const { return data_.end(); }
vector_type::iterator end() { return data_.end(); }
protected:
/// Delete multiple entries in list
virtual void delete_multiple_entries(const std::vector<bool>& _tags) {
assert(_tags.size() == data_.size());
vector_type new_data;
vector_type::iterator d_it = data_.begin();
std::vector<bool>::const_iterator t_it = _tags.begin();
std::vector<bool>::const_iterator t_end = _tags.end();
for(; t_it != t_end; ++t_it, ++d_it) {
if(!*t_it) {
new_data.push_back(*d_it);
}
}
data_.swap(new_data);
}
private:
vector_type data_;
const std::string def_;
};
//-----------------------------------------------------------------------------
} // Namespace OpenVolumeMesh
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