G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsProperty.h
1 #pragma once
2 
3 //== INCLUDES =================================================================
4 
5 
6 #include <vector>
7 #include <string>
8 #include <algorithm>
9 #include <typeinfo>
10 
11 
12 //== NAMESPACE ================================================================
13 
14 
15 namespace gismo {
16 
17 
18 //== CLASS DEFINITION =========================================================
19 
20 
21 class Base_property_array
22 {
23 public:
24 
26  Base_property_array(const std::string& name) : name_(name) {}
27 
29  virtual ~Base_property_array() {}
30 
32  virtual void reserve(size_t n) = 0;
33 
35  virtual void resize(size_t n) = 0;
36 
38  virtual void free_memory() = 0;
39 
41  virtual void push_back() = 0;
42 
44  virtual void swap(size_t i0, size_t i1) = 0;
45 
47  virtual Base_property_array* clone () const = 0;
48 
50  virtual const std::type_info& type() = 0;
51 
53  const std::string& name() const { return name_; }
54 
56  void rename(std::string newname)
57  { name_ = give(newname) ; }
58 
59 protected:
60 
61  std::string name_;
62 };
63 
64 
65 
66 //== CLASS DEFINITION =========================================================
67 
68 
69 template <class T>
70 class gsProperty_array : public Base_property_array
71 {
72 public:
73 
74  typedef T value_type;
75  typedef std::vector<value_type> vector_type;
76  typedef typename vector_type::reference reference;
77  typedef typename vector_type::const_reference const_reference;
78 
79  gsProperty_array(const std::string& name, T t=T()) :
80  Base_property_array(name), value_(give(t)) {}
81 
82 public: // virtual interface of Base_property_array
83 
84  virtual void reserve(size_t n)
85  {
86  data_.reserve(n);
87  }
88 
89  virtual void resize(size_t n)
90  {
91  data_.resize(n, value_);
92  }
93 
94  virtual void push_back()
95  {
96  data_.push_back(value_);
97  }
98 
99  virtual void free_memory()
100  {
101  vector_type(data_).swap(data_);
102  }
103 
104  virtual void swap(size_t i0, size_t i1)
105  {
106  T d(data_[i0]);
107  data_[i0]=data_[i1];
108  data_[i1]=d;
109  }
110 
111  virtual Base_property_array* clone() const
112  {
113  gsProperty_array<T>* p = new gsProperty_array<T>(name_, value_);
114  p->data_ = data_;
115  return p;
116  }
117 
118  virtual const std::type_info& type() { return typeid(T); }
119 
120 
121 public:
122 
124  const T* data() const
125  {
126  return &data_[0];
127  }
128 
129 
131  std::vector<T>& vector()
132  {
133  return data_;
134  }
135 
136 
138  reference operator[](int _idx)
139  {
140  assert( size_t(_idx) < data_.size() );
141  return data_[_idx];
142  }
143 
145  const_reference operator[](int _idx) const
146  {
147  assert( size_t(_idx) < data_.size());
148  return data_[_idx];
149  }
150 
151 
152 
153 private:
154  vector_type data_;
155  value_type value_;
156 };
157 
158 
159 // specialization for bool properties
160 template <>
161 inline const bool*
162 gsProperty_array<bool>::data() const
163 {
164  assert(false);
165  return NULL;
166 }
167 
168 
169 
170 //== CLASS DEFINITION =========================================================
171 
172 
173 template <class T>
174 class gsProperty
175 {
176 public:
177 
178  typedef typename gsProperty_array<T>::reference reference;
179  typedef typename gsProperty_array<T>::const_reference const_reference;
180 
181  friend class gsProperty_container;
182  friend class gsSurfMesh;
183 
184 
185 public:
186 
187  gsProperty(gsProperty_array<T>* p=NULL) : parray_(p) {}
188 
189  void reset()
190  {
191  parray_ = NULL;
192  }
193 
194  operator bool() const
195  {
196  return parray_ != NULL;
197  }
198 
199  reference operator[](int i)
200  {
201  assert(parray_ != NULL);
202  return (*parray_)[i];
203  }
204 
205  const_reference operator[](int i) const
206  {
207  assert(parray_ != NULL);
208  return (*parray_)[i];
209  }
210 
211  const T* data() const
212  {
213  assert(parray_ != NULL);
214  return parray_->data();
215  }
216 
217 
218  std::vector<T>& vector()
219  {
220  assert(parray_ != NULL);
221  return parray_->vector();
222  }
223 
224 
225 private:
226 
227  gsProperty_array<T>& array()
228  {
229  assert(parray_ != NULL);
230  return *parray_;
231  }
232 
233  const gsProperty_array<T>& array() const
234  {
235  assert(parray_ != NULL);
236  return *parray_;
237  }
238 
239 
240 private:
241  gsProperty_array<T>* parray_;
242 };
243 
244 
245 
246 //== CLASS DEFINITION =========================================================
247 
248 
249 class gsProperty_container
250 {
251 public:
252 
253  // default constructor
254  gsProperty_container() : size_(0) {}
255 
256  // destructor (deletes all property arrays)
257  virtual ~gsProperty_container() { clear(); }
258 
259  // copy constructor: performs deep copy of property arrays
260  gsProperty_container(const gsProperty_container& _rhs) { operator=(_rhs); }
261 
262  // assignment: performs deep copy of property arrays
263  gsProperty_container& operator=(const gsProperty_container& _rhs)
264  {
265  if (this != &_rhs)
266  {
267  clear();
268  parrays_.resize(_rhs.n_properties());
269  size_ = _rhs.size();
270  for (unsigned int i=0; i<parrays_.size(); ++i)
271  parrays_[i] = _rhs.parrays_[i]->clone();
272  }
273  return *this;
274  }
275 
276  // returns the current size of the property arrays
277  size_t size() const { return size_; }
278 
279  // returns the number of property arrays
280  size_t n_properties() const { return parrays_.size(); }
281 
282  // returns a vector of all property names
283  std::vector<std::string> properties() const
284  {
285  std::vector<std::string> names;
286  for (unsigned int i=0; i<parrays_.size(); ++i)
287  names.push_back(parrays_[i]->name());
288  return names;
289  }
290 
291 
292  // add a property with name \c name and default value \c t
293  template <class T> gsProperty<T> add(const std::string& name, T t=T())
294  {
295  // if a property with this name already exists, return an invalid property
296  for (unsigned int i=0; i<parrays_.size(); ++i)
297  {
298  if (parrays_[i]->name() == name)
299  {
300  std::cerr << "[gsProperty_container] A property with name \""
301  << name << "\" already exists. Returning invalid property.\n";
302  return gsProperty<T>();
303  }
304  }
305 
306  // otherwise add the property
307 // #pragma GCC diagnostic push
308 // #pragma GCC diagnostic ignored "-Wuninitialized"
309  gsProperty_array<T>* p = new gsProperty_array<T>(name, give(t));//warn unin.
310 // #pragma GCC diagnostic pop
311 // #pragma GCC diagnostic pop //restores cmdline options
312  p->resize(size_);
313  parrays_.push_back(p);
314  return gsProperty<T>(p);
315  }
316 
317 
318  // get a property by its name. returns invalid property if it does not exist.
319  template <class T> gsProperty<T> get(const std::string& name) const
320  {
321  for (unsigned int i=0; i<parrays_.size(); ++i)
322  if (parrays_[i]->name() == name)
323  return gsProperty<T>(dynamic_cast<gsProperty_array<T>*>(parrays_[i]));
324  return gsProperty<T>();
325  }
326 
327 
328  // returns a property if it exists, otherwise it creates it first.
329  template <class T> gsProperty<T> get_or_add(const std::string& name, const T t=T())
330  {
331  gsProperty<T> p = get<T>(name);
332  if (!p) p = add<T>(name, give(t));
333  return p;
334  }
335 
336  // Returns true if a property labeled \a name exists.
337  bool has(const std::string& name) const
338  {
339  for (unsigned int i=0; i<parrays_.size(); ++i)
340  if (parrays_[i]->name() == name)
341  return true;
342  return false;
343  }
344 
345  // get the type of property by its name. returns typeid(void) if
346  // it does not exist.
347  const std::type_info& get_type(const std::string& name)
348  {
349  for (unsigned int i=0; i<parrays_.size(); ++i)
350  if (parrays_[i]->name() == name)
351  return parrays_[i]->type();
352  return typeid(void);
353  }
354 
355  // Returns true if a property labeled \a name exists.
356  void swap(const std::string& name1, const std::string& name2) const
357  {
358  std::pair<int,int> spair(-1,-1);
359  for (unsigned int i=0; i<parrays_.size(); ++i)
360  {
361  if (parrays_[i]->name() == name1)
362  spair.first = i;
363  if (parrays_[i]->name() == name2)
364  spair.second = i;
365  }
366  GISMO_ASSERT(spair.first!=-1 && spair.second!=-1,"error");
367  parrays_[spair.first ]->rename(name2);
368  parrays_[spair.second]->rename(name1);
369  }
370 
371  // rename a property (the name should not exist already)
372  template <class T> void rename(gsProperty<T>& h, std::string newname)
373  {
374  GISMO_ASSERT( !has(newname), "There is already a property with this name.");
375  h.parray_->rename(give(newname));
376  }
377 
378  // delete a property
379  template <class T> void remove(gsProperty<T>& h)
380  {
381  std::vector<Base_property_array*>::iterator
382  it=parrays_.begin(),
383  end=parrays_.end();
384  for (; it!=end; ++it)
385  {
386  if (*it == h.parray_)
387  {
388  delete *it;
389  parrays_.erase(it);
390  h.reset();
391  break;
392  }
393  }
394  }
395 
396  // delete all properties
397  void clear()
398  {
399  for (unsigned int i=0; i<parrays_.size(); ++i)
400  delete parrays_[i];
401  parrays_.clear();
402  size_ = 0;
403  }
404 
405 
406  // reserve memory for n entries in all arrays
407  void reserve(size_t n) const
408  {
409  for (unsigned int i=0; i<parrays_.size(); ++i)
410  parrays_[i]->reserve(n);
411  }
412 
413  // resize all arrays to size n
414  void resize(size_t n)
415  {
416  for (unsigned int i=0; i<parrays_.size(); ++i)
417  parrays_[i]->resize(n);
418  size_ = n;
419  }
420 
421  // free unused space in all arrays
422  void free_memory() const
423  {
424  for (unsigned int i=0; i<parrays_.size(); ++i)
425  parrays_[i]->free_memory();
426  }
427 
428  // add a new element to each vector
429  void push_back()
430  {
431  for (unsigned int i=0; i<parrays_.size(); ++i)
432  parrays_[i]->push_back();
433  ++size_;
434  }
435 
436  // swap elements i0 and i1 in all arrays
437  void swap(size_t i0, size_t i1) const
438  {
439  for (unsigned int i=0; i<parrays_.size(); ++i)
440  parrays_[i]->swap(i0, i1);
441  }
442 
443 
444 private:
445  std::vector<Base_property_array*> parrays_;
446  size_t size_;
447 };
448 
449 
450 //=============================================================================
451 } // namespace gismo
S give(S &x)
Definition: gsMemory.h:266
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89