Developer Documentation
OpenVolumeMeshProperty.hh
1 /*===========================================================================*\
2  * *
3  * OpenVolumeMesh *
4  * Copyright (C) 2011 by Computer Graphics Group, RWTH Aachen *
5  * www.openvolumemesh.org *
6  * *
7  *---------------------------------------------------------------------------*
8  * This file is part of OpenVolumeMesh. *
9  * *
10  * OpenVolumeMesh is free software: you can redistribute it and/or modify *
11  * it under the terms of the GNU Lesser General Public License as *
12  * published by the Free Software Foundation, either version 3 of *
13  * the License, or (at your option) any later version with the *
14  * following exceptions: *
15  * *
16  * If other files instantiate templates or use macros *
17  * or inline functions from this file, or you compile this file and *
18  * link it with other files to produce an executable, this file does *
19  * not by itself cause the resulting executable to be covered by the *
20  * GNU Lesser General Public License. This exception does not however *
21  * invalidate any other reasons why the executable file might be *
22  * covered by the GNU Lesser General Public License. *
23  * *
24  * OpenVolumeMesh is distributed in the hope that it will be useful, *
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27  * GNU Lesser General Public License for more details. *
28  * *
29  * You should have received a copy of the GNU LesserGeneral Public *
30  * License along with OpenVolumeMesh. If not, *
31  * see <http://www.gnu.org/licenses/>. *
32  * *
33 \*===========================================================================*/
34 
35 #pragma once
36 
37 //== INCLUDES =================================================================
38 
39 #include <cassert>
40 #include <istream>
41 #include <ostream>
42 #include <numeric>
43 #include <string>
44 #include <vector>
45 
46 #include "OpenVolumeMeshBaseProperty.hh"
47 
48 #include "Serializers.hh"
49 
50 namespace OpenVolumeMesh {
51 
52 //== CLASS DEFINITION =========================================================
53 
61 template<class T>
62 class OpenVolumeMeshPropertyT: public OpenVolumeMeshBaseProperty {
63 public:
64 
65  template <class PropT, class Entity> friend class PropertyPtr;
66 
67  typedef T Value;
68  typedef typename std::vector<T> vector_type;
69  typedef T value_type;
70  typedef typename vector_type::reference reference;
71  typedef typename vector_type::const_reference const_reference;
72 
73 public:
74 
75  explicit OpenVolumeMeshPropertyT(
76  const std::string& _name,
77  const std::string& _internal_type_name,
78  const T &_def = T())
79  : OpenVolumeMeshBaseProperty(_name, _internal_type_name),
80  def_(_def)
81  {}
82 
83 
84  OpenVolumeMeshPropertyT(const OpenVolumeMeshPropertyT& _rhs) = default;
85 
86 public:
87  // inherited from OpenVolumeMeshBaseProperty
88  void reserve(size_t _n) override{
89  data_.reserve(_n);
90  }
91  void resize(size_t _n) override {
92  data_.resize(_n, def_);
93  }
94  size_t size() const override {
95  return data_.size();
96  }
97  void clear() override {
98  data_.clear();
99  vector_type().swap(data_);
100  }
101  void push_back() override {
102  data_.push_back(def_);
103  }
104  void swap(size_t _i0, size_t _i1) override {
105  std::swap(data_[_i0], data_[_i1]);
106  }
107 
108  virtual void copy(size_t _src_idx, size_t _dst_idx) {
109  data_[_dst_idx] = data_[_src_idx];
110  }
111  void delete_element(size_t _idx) override {
112  data_.erase(data_.begin() + static_cast<long>(_idx));
113  }
114 
115 public:
116 
117  size_t n_elements() const override {
118  return data_.size();
119  }
120  size_t element_size() const override {
121  return sizeof(T);
122  }
123 
124 
125 #ifndef DOXY_IGNORE_THIS
126  struct plus {
127  size_t operator ()(size_t _b, const T& /*_v*/) {
128  return _b + sizeof(T);
129  }
130  };
131 #endif
132 
133  size_t size_of() const override {
136  return std::accumulate(data_.begin(), data_.end(), size_t(0), plus());
137  }
138 
139  size_t size_of(size_t _n_elem) const override {
140  return this->OpenVolumeMeshBaseProperty::size_of(_n_elem);
141  }
142 
143  // Function to serialize a property
144  void serialize(std::ostream& _ostr) const override {
145  for(typename vector_type::const_iterator it = data_.begin();
146  it != data_.end(); ++it) {
147  OpenVolumeMesh::serialize(_ostr, *it) << std::endl;
148  }
149  }
150 
151  // Function to deserialize a property
152  void deserialize(std::istream& _istr) override {
153  for(unsigned int i = 0; i < n_elements(); ++i) {
154  OpenVolumeMesh::deserialize(_istr, data_[i]);
155  }
156  }
157 
158 public:
159  // data access interface
160 
162  const T* data() const {
163 
164  if (data_.empty())
165  return 0;
166 
167  return &data_[0];
168  }
169 
171  vector_type& data_vector() {
172 
173  return data_;
174  }
175 
177  reference operator[](size_t _idx) {
178  assert(_idx < data_.size());
179  return data_[_idx];
180  }
181 
183  const_reference operator[](size_t _idx) const {
184  assert(_idx < data_.size());
185  return data_[_idx];
186  }
187 
189  OpenVolumeMeshPropertyT<T>* clone() const override {
191  return p;
192  }
193 
194  typename vector_type::const_iterator begin() const { return data_.begin(); }
195 
196  typename vector_type::iterator begin() { return data_.begin(); }
197 
198  typename vector_type::const_iterator end() const { return data_.end(); }
199 
200  typename vector_type::iterator end() { return data_.end(); }
201 
202 protected:
203 
205  void delete_multiple_entries(const std::vector<bool>& _tags) override {
206 
207  assert(_tags.size() == data_.size());
208  vector_type new_data;
209  typename vector_type::iterator d_it = data_.begin();
210  std::vector<bool>::const_iterator t_it = _tags.begin();
211  std::vector<bool>::const_iterator t_end = _tags.end();
212  for(; t_it != t_end; ++t_it, ++d_it) {
213  if(!*t_it) {
214  new_data.push_back(*d_it);
215  }
216  }
217  data_.swap(new_data);
218  }
219 
220 private:
221 
222  vector_type data_;
223 
224  const T def_;
225 };
226 
227 
228 //-----------------------------------------------------------------------------
229 // Property specialization for bool type.
230 //-----------------------------------------------------------------------------
231 
232 template<>
233 inline void OpenVolumeMeshPropertyT<bool>::swap(size_t _i0, size_t _i1)
234 {
235  // std::vector<bool>::swap(reference x, reference y) exists, but
236  // on libstdc++ with _GLIBCXX_DEBUG it doesn't compile
237  // (2018-02-26, libstdc++ 8.2.0)
238 
239  auto tmp = data_[_i0];
240  data_[_i0] = data_[_i1];
241  data_[_i1] = tmp;
242 }
243 
244 template<>
245 inline size_t OpenVolumeMeshPropertyT<bool>::size_of(size_t _n_elem) const
246 {
247  return _n_elem / 8 + ((_n_elem % 8) != 0);
248 }
249 
250 template<>
252 {
253  return size_of(n_elements());
254 }
255 
256 template<>
258 {
260 }
261 
262 template<>
263 inline void OpenVolumeMeshPropertyT<bool>::deserialize(std::istream& _istr)
264 {
265  for(unsigned int i = 0; i < n_elements(); ++i) {
266  value_type val;
267  OpenVolumeMesh::deserialize(_istr, val);
268  data_[i] = val;
269  }
270 }
271 
272 
273 //-----------------------------------------------------------------------------
274 // Property specialization for std::string type.
275 //-----------------------------------------------------------------------------
276 template<>
278 {
280 }
281 
282 template<>
284 {
285  return sizeof(data_);
286 }
287 
288 template<>
290 {
292 }
293 
294 
295 //-----------------------------------------------------------------------------
296 
297 } // Namespace OpenVolumeMesh
298 
void clear() override
Clear all elements and free memory.
size_t n_elements() const override
Number of elements in property.
void delete_element(size_t _idx) override
Erase an element of the vector.
void reserve(size_t _n) override
Reserve memory for n elements.
void swap(size_t _i0, size_t _i1) override
Let two elements swap their storage place.
OpenVolumeMeshPropertyT< T > * clone() const override
Make a copy of self.
size_t size() const override
Return underlying container size.
Default property class for any type T.
vector_type & data_vector()
Get reference to property vector (be careful, improper usage, e.g. resizing, may crash) ...
size_t size_of(size_t _n_elem) const override
size_t size_of() const override
Return size of property in bytes.
void resize(size_t _n) override
Resize storage to hold n elements.
void delete_multiple_entries(const std::vector< bool > &_tags) override
Delete multiple entries in list.
reference operator[](size_t _idx)
Access the i&#39;th element. No range check is performed!
size_t element_size() const override
Size of one element in bytes or UnknownSize if not known.
void push_back() override
Extend the number of elements by one.
virtual size_t size_of() const
Return size of property in bytes.
static const size_t UnknownSize
Indicates an error when a size is returned by a member.
const_reference operator[](size_t _idx) const
Const access to the i&#39;th element. No range check is performed!
const T * data() const
Get pointer to array (does not work for T==bool)