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

Merge branch 'prop-partial-specialisation' into 'master'

Properties: use partial template specialization.

See merge request !53
parents 9ec8ccad a1adaf49
Pipeline #8873 passed with stage
in 4 minutes and 12 seconds
...@@ -75,9 +75,7 @@ public: ...@@ -75,9 +75,7 @@ public:
name_(_name), persistent_(false), handle_(-1) { name_(_name), persistent_(false), handle_(-1) {
} }
OpenVolumeMeshBaseProperty(const OpenVolumeMeshBaseProperty& _rhs) : OpenVolumeMeshBaseProperty(const OpenVolumeMeshBaseProperty& _rhs) = default;
name_(_rhs.name_), persistent_(_rhs.persistent_), handle_(_rhs.handle_.idx()) {
}
virtual ~OpenVolumeMeshBaseProperty() {} virtual ~OpenVolumeMeshBaseProperty() {}
......
...@@ -72,18 +72,13 @@ public: ...@@ -72,18 +72,13 @@ public:
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), OpenVolumeMeshBaseProperty(_name),
def_(_def) { def_(_def) {
} }
/// Copy constructor
OpenVolumeMeshPropertyT(const OpenVolumeMeshPropertyT& _rhs) : OpenVolumeMeshPropertyT(const OpenVolumeMeshPropertyT& _rhs) = default;
OpenVolumeMeshBaseProperty(_rhs),
data_(_rhs.data_),
def_(_rhs.def_) {
}
public: public:
// inherited from OpenVolumeMeshBaseProperty // inherited from OpenVolumeMeshBaseProperty
...@@ -101,8 +96,10 @@ public: ...@@ -101,8 +96,10 @@ public:
data_.push_back(def_); data_.push_back(def_);
} }
virtual void swap(size_t _i0, size_t _i1) { virtual void swap(size_t _i0, size_t _i1) {
std::swap(data_[_i0], data_[_i1]); std::swap(data_[_i0], data_[_i1]);
} }
virtual void copy(size_t _src_idx, size_t _dst_idx) { virtual void copy(size_t _src_idx, size_t _dst_idx) {
data_[_dst_idx] = data_[_src_idx]; data_[_dst_idx] = data_[_src_idx];
} }
...@@ -116,8 +113,9 @@ public: ...@@ -116,8 +113,9 @@ public:
return data_.size(); return data_.size();
} }
virtual size_t element_size() const { virtual size_t element_size() const {
return sizeof(T); return sizeof(T);
} }
#ifndef DOXY_IGNORE_THIS #ifndef DOXY_IGNORE_THIS
struct plus { struct plus {
...@@ -127,11 +125,11 @@ public: ...@@ -127,11 +125,11 @@ public:
}; };
#endif #endif
virtual size_t size_of() const { virtual size_t size_of() const {
if (element_size() != OpenVolumeMeshBaseProperty::UnknownSize) if (element_size() != OpenVolumeMeshBaseProperty::UnknownSize)
return this->OpenVolumeMeshBaseProperty::size_of(n_elements()); return this->OpenVolumeMeshBaseProperty::size_of(n_elements());
return std::accumulate(data_.begin(), data_.end(), size_t(0), plus()); return std::accumulate(data_.begin(), data_.end(), size_t(0), plus());
} }
virtual size_t size_of(size_t _n_elem) const { virtual size_t size_of(size_t _n_elem) const {
return this->OpenVolumeMeshBaseProperty::size_of(_n_elem); return this->OpenVolumeMeshBaseProperty::size_of(_n_elem);
...@@ -221,293 +219,75 @@ private: ...@@ -221,293 +219,75 @@ private:
const T def_; const T def_;
}; };
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Property specialization for bool type.
//-----------------------------------------------------------------------------
/**
* Property specialization for bool type.
*/
template<> template<>
class OpenVolumeMeshPropertyT<bool> : public OpenVolumeMeshBaseProperty { inline void OpenVolumeMeshPropertyT<bool>::swap(size_t _i0, size_t _i1)
public: {
// std::vector<bool>::swap(reference x, reference y) exists, but
template <class PropT, class HandleT> friend class PropertyPtr; // on libstdc++ with _GLIBCXX_DEBUG it doesn't compile
// (2018-02-26, libstdc++ 8.2.0)
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];
}
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 {
return OpenVolumeMeshBaseProperty::UnknownSize;
}
virtual size_t 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;
}
}
// Function to deserialize a property
virtual void 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(); } auto tmp = data_[_i0];
data_[_i0] = data_[_i1];
data_[_i1] = tmp;;
}
vector_type::const_iterator end() const { return data_.end(); } template<>
inline size_t OpenVolumeMeshPropertyT<bool>::size_of(size_t _n_elem) const
vector_type::iterator end() { return data_.end(); } {
return _n_elem / 8 + ((_n_elem % 8) != 0);
}
protected: template<>
inline size_t OpenVolumeMeshPropertyT<bool>::size_of() const
{
return size_of(n_elements());
}
/// Delete multiple entries in list template<>
virtual void delete_multiple_entries(const std::vector<bool>& _tags) { inline size_t OpenVolumeMeshPropertyT<bool>::element_size() const
{
return OpenVolumeMeshBaseProperty::UnknownSize;
}
assert(_tags.size() == data_.size()); template<>
vector_type new_data; inline void OpenVolumeMeshPropertyT<bool>::deserialize(std::istream& _istr)
vector_type::iterator d_it = data_.begin(); {
std::vector<bool>::const_iterator t_it = _tags.begin(); for(unsigned int i = 0; i < n_elements(); ++i) {
std::vector<bool>::const_iterator t_end = _tags.end(); value_type val;
for(; t_it != t_end; ++t_it, ++d_it) { OpenVolumeMesh::deserialize(_istr, val);
if(!*t_it) { data_[i] = val;
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<> template<>
class OpenVolumeMeshPropertyT<std::string> : public OpenVolumeMeshBaseProperty { inline size_t OpenVolumeMeshPropertyT<std::string>::size_of(size_t) const
public: {
return OpenVolumeMeshBaseProperty::UnknownSize;
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 = "") : template<>
OpenVolumeMeshBaseProperty(_name), inline size_t OpenVolumeMeshPropertyT<std::string>::size_of() const
def_(_def) { {
} return sizeof(data_);
}
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 {
return OpenVolumeMeshBaseProperty::UnknownSize;
}
virtual size_t size_of() const {
return sizeof(data_);
}
virtual size_t size_of(size_t /* _n_elem */) 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: template<>
inline size_t OpenVolumeMeshPropertyT<std::string>::element_size() const
{
return OpenVolumeMeshBaseProperty::UnknownSize;
}
vector_type data_;
const std::string def_; //-----------------------------------------------------------------------------
};
} // Namespace OpenVolumeMesh } // 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