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 HandleT> friend class PropertyPtr;
66 
67  typedef T Value;
68  typedef 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  OpenVolumeMeshPropertyT(const std::string& _name = "<unknown>", const T &_def = T()) :
77  def_(_def) {
78  }
79 
80 
81  OpenVolumeMeshPropertyT(const OpenVolumeMeshPropertyT& _rhs) = default;
82 
83 public:
84  // inherited from OpenVolumeMeshBaseProperty
85  virtual void reserve(size_t _n) {
86  data_.reserve(_n);
87  }
88  virtual void resize(size_t _n) {
89  data_.resize(_n, def_);
90  }
91  virtual void clear() {
92  data_.clear();
93  vector_type().swap(data_);
94  }
95  virtual void push_back() {
96  data_.push_back(def_);
97  }
98  virtual void swap(size_t _i0, size_t _i1) {
99  std::swap(data_[_i0], data_[_i1]);
100  }
101 
102 
103  virtual void copy(size_t _src_idx, size_t _dst_idx) {
104  data_[_dst_idx] = data_[_src_idx];
105  }
106  void delete_element(size_t _idx) {
107  data_.erase(data_.begin() + _idx);
108  }
109 
110 public:
111 
112  virtual size_t n_elements() const {
113  return data_.size();
114  }
115  virtual size_t element_size() const {
116  return sizeof(T);
117  }
118 
119 
120 #ifndef DOXY_IGNORE_THIS
121  struct plus {
122  size_t operator ()(size_t _b, const T& /*_v*/) {
123  return _b + sizeof(T);
124  }
125  };
126 #endif
127 
128  virtual size_t size_of() const {
131  return std::accumulate(data_.begin(), data_.end(), size_t(0), plus());
132  }
133 
134  virtual size_t size_of(size_t _n_elem) const {
135  return this->OpenVolumeMeshBaseProperty::size_of(_n_elem);
136  }
137 
138  // Function to serialize a property
139  virtual void serialize(std::ostream& _ostr) const {
140  for(typename vector_type::const_iterator it = data_.begin();
141  it != data_.end(); ++it) {
142  OpenVolumeMesh::serialize(_ostr, *it) << std::endl;
143  }
144  }
145 
146  // Function to deserialize a property
147  virtual void deserialize(std::istream& _istr) {
148  for(unsigned int i = 0; i < n_elements(); ++i) {
149  OpenVolumeMesh::deserialize(_istr, data_[i]);
150  }
151  }
152 
153 public:
154  // data access interface
155 
157  const T* data() const {
158 
159  if (data_.empty())
160  return 0;
161 
162  return &data_[0];
163  }
164 
166  vector_type& data_vector() {
167 
168  return data_;
169  }
170 
172  reference operator[](size_t _idx) {
173  assert(_idx < data_.size());
174  return data_[_idx];
175  }
176 
178  const_reference operator[](size_t _idx) const {
179  assert(_idx < data_.size());
180  return data_[_idx];
181  }
182 
186  return p;
187  }
188 
189  typename vector_type::const_iterator begin() const { return data_.begin(); }
190 
191  typename vector_type::iterator begin() { return data_.begin(); }
192 
193  typename vector_type::const_iterator end() const { return data_.end(); }
194 
195  typename vector_type::iterator end() { return data_.end(); }
196 
197 protected:
198 
200  virtual void delete_multiple_entries(const std::vector<bool>& _tags) {
201 
202  assert(_tags.size() == data_.size());
203  vector_type new_data;
204  typename vector_type::iterator d_it = data_.begin();
205  std::vector<bool>::const_iterator t_it = _tags.begin();
206  std::vector<bool>::const_iterator t_end = _tags.end();
207  for(; t_it != t_end; ++t_it, ++d_it) {
208  if(!*t_it) {
209  new_data.push_back(*d_it);
210  }
211  }
212  data_.swap(new_data);
213  }
214 
215 private:
216 
217  vector_type data_;
218 
219  const T def_;
220 };
221 
222 
223 //-----------------------------------------------------------------------------
224 // Property specialization for bool type.
225 //-----------------------------------------------------------------------------
226 
227 template<>
228 inline void OpenVolumeMeshPropertyT<bool>::swap(size_t _i0, size_t _i1)
229 {
230  // std::vector<bool>::swap(reference x, reference y) exists, but
231  // on libstdc++ with _GLIBCXX_DEBUG it doesn't compile
232  // (2018-02-26, libstdc++ 8.2.0)
233 
234  auto tmp = data_[_i0];
235  data_[_i0] = data_[_i1];
236  data_[_i1] = tmp;;
237 }
238 
239 template<>
240 inline size_t OpenVolumeMeshPropertyT<bool>::size_of(size_t _n_elem) const
241 {
242  return _n_elem / 8 + ((_n_elem % 8) != 0);
243 }
244 
245 template<>
247 {
248  return size_of(n_elements());
249 }
250 
251 template<>
253 {
255 }
256 
257 template<>
258 inline void OpenVolumeMeshPropertyT<bool>::deserialize(std::istream& _istr)
259 {
260  for(unsigned int i = 0; i < n_elements(); ++i) {
261  value_type val;
262  OpenVolumeMesh::deserialize(_istr, val);
263  data_[i] = val;
264  }
265 }
266 
267 
268 //-----------------------------------------------------------------------------
269 // Property specialization for std::string type.
270 //-----------------------------------------------------------------------------
271 template<>
273 {
275 }
276 
277 template<>
279 {
280  return sizeof(data_);
281 }
282 
283 template<>
285 {
287 }
288 
289 
290 //-----------------------------------------------------------------------------
291 
292 } // Namespace OpenVolumeMesh
293 
const T * data() const
Get pointer to array (does not work for T==bool)
virtual void clear()
Clear all elements and free memory.
virtual size_t element_size() const
Size of one element in bytes or UnknownSize if not known.
void delete_element(size_t _idx)
Erase an element of the vector.
virtual size_t n_elements() const
Number of elements in property.
virtual void delete_multiple_entries(const std::vector< bool > &_tags)
Delete multiple entries in list.
OpenVolumeMeshPropertyT< T > * clone() const
Make a copy of self.
virtual void swap(size_t _i0, size_t _i1)
Let two elements swap their storage place.
Default property class for any type T.
const_reference operator[](size_t _idx) const
Const access to the i&#39;th element. No range check is performed!
vector_type & data_vector()
Get reference to property vector (be careful, improper usage, e.g. resizing, may crash) ...
reference operator[](size_t _idx)
Access the i&#39;th element. No range check is performed!
virtual size_t size_of(size_t _n_elem) const
static const size_t UnknownSize
Indicates an error when a size is returned by a member.
virtual size_t size_of() const
Return size of property in bytes.
virtual void reserve(size_t _n)
Reserve memory for n elements.
virtual void push_back()
Extend the number of elements by one.
virtual void resize(size_t _n)
Resize storage to hold n elements.
virtual size_t size_of() const
Return size of property in bytes.