G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
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
15namespace gismo {
16
17
18//== CLASS DEFINITION =========================================================
19
20
21class Base_property_array
22{
23public:
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
59protected:
60
61 std::string name_;
62};
63
64
65
66//== CLASS DEFINITION =========================================================
67
68
69template <class T>
70class gsProperty_array : public Base_property_array
71{
72public:
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
82public: // 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
121public:
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
153private:
154 vector_type data_;
155 value_type value_;
156};
157
158
159// specialization for bool properties
160template <>
161inline const bool*
162gsProperty_array<bool>::data() const
163{
164 assert(false);
165 return NULL;
166}
167
168
169
170//== CLASS DEFINITION =========================================================
171
172
173template <class T>
174class gsProperty
175{
176public:
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
185public:
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
225private:
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
240private:
241 gsProperty_array<T>* parray_;
242};
243
244
245
246//== CLASS DEFINITION =========================================================
247
248
249class gsProperty_container
250{
251public:
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
444private:
445 std::vector<Base_property_array*> parrays_;
446 size_t size_;
447};
448
449
450//=============================================================================
451} // namespace gismo
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
The G+Smo namespace, containing all definitions for the library.
S give(S &x)
Definition gsMemory.h:266