rsvs3D  0.0.0
Codes for the c++ implementation of the 3D RSVS
arraystructures.hpp
Go to the documentation of this file.
1 
10 //===============================================
11 // Include Guards
12 #ifndef ARRAYSTRUCTS_H_INCLUDED
13 #define ARRAYSTRUCTS_H_INCLUDED
14 
15 //===============================================
16 // Levels of debuging Guards
17 #ifdef DEBUGLVL2 // All Debugging calls
18 #define DEBUGLVL1
19 #define TEST_RANGE // deprecated
20 #define TEST_ARRAYSTRUCT
21 
22 #endif
23 
24 #ifdef DEBUGLVL1 // Debugging of new features.
25 #ifndef SAFE_ACCESS
26 #define SAFE_ACCESS
27 #endif
28 #endif
29 
30 //=================================
31 // forward declared dependencies
32 // class foo; //when you only need a pointer not the actual object
33 // and to avoid circular dependencies
34 
35 //=================================
36 // included dependencies
37 #ifdef DBG_MEMLEAK
38 #define _CRTDBG_MAP_ALLOC
39 #include <crtdbg.h>
40 #include <stdlib.h>
41 #endif // DBG_MEMLEAK
42 
43 #include <algorithm>
44 #include <cstdlib>
45 #include <functional>
46 #include <iostream>
47 #include <sstream>
48 #include <stdexcept>
49 #include <string>
50 #include <unordered_map>
51 #include <vector>
52 #if defined(USE_BOOST) && defined(USE_STACKTRACE)
53 #include <boost/stacktrace.hpp>
54 namespace stacktrace = boost::stacktrace;
55 #endif
56 
57 #include "warning.hpp"
58 
59 //==================================
60 // Code
61 // NOTE: function in a class definition are IMPLICITELY INLINED
62 // ie replaced by their code at compile time
63 
64 namespace rsvs3d
65 {
66 namespace constants
67 {
68 static const int __notfound = -1;
69 static const int __failure = -1;
70 static const int __success = 0;
71 } // namespace constants
72 namespace logicals
73 {
74 inline bool __isfound(int f)
75 {
76  return f != constants::__notfound;
77 }
78 } // namespace logicals
79 } // namespace rsvs3d
80 
81 template <class T> class ArrayStruct;
82 template <class T, class Q, class R = int> class HashedVector;
83 template <class T> class SnakStruct;
84 
85 typedef unsigned int unsigned_int;
86 
87 // Forward declared templated functions
88 template <class T> int TestTemplate_ArrayStruct();
89 bool CompareFuncOut(std::function<void()> func1, std::function<void()> func2);
90 template <typename T> inline void sort(std::vector<T> &vec);
91 template <typename T> inline void unique(std::vector<T> &vec);
92 // template <typename T> inline void set_intersection(std::vector<T>
93 // &targVec,std::vector<T> &vec1,std::vector<T> &vec2,bool isSort=true);
94 template <typename T>
95 inline void set_intersection(std::vector<T> &targVec, const std::vector<T> &vec1, const std::vector<T> &vec2,
96  bool isSort);
97 template <class T>
98 std::vector<int> FindSubList(const std::vector<T> &keyFind, const std::vector<T> &keyList,
99  std::unordered_multimap<T, int> &hashTable);
100 template <class T>
101 std::vector<int> FindSubList(const std::vector<T> &keyFind, const std::vector<T> &keyList,
102  const std::unordered_multimap<T, int> &hashTable);
103 template <class T, class Q>
104 void HashVector(const std::vector<T> &elems, std::unordered_multimap<T, Q> &hashTable,
105  const std::vector<Q> &targElems = {});
106 template <class T> int FindSub(const T &key, const std::unordered_multimap<T, int> &hashTable);
107 template <class T> void ConcatenateVector(std::vector<T> &vecRoot, const std::vector<T> &vecConcat);
108 template <class T, class R> std::vector<R> ReturnDataEqualRange(T key, const std::unordered_multimap<T, R> &hashTable);
109 template <class T, class R>
110 void ReturnDataEqualRange(T key, const std::unordered_multimap<T, R> &hashTable, std::vector<R> &subList);
111 
112 // Templates
113 template <class T> class ArrayStruct
114 {
115  protected:
116  int maxIndex;
117  int isHash = 0;
118  int isSetMI = 0;
119  bool readyforuse = false;
120  bool isInMesh = false; // used to change behaviour if not in a mesh.
121 
122  std::vector<T> elems; // std::vector of elements (structures)
123  std::unordered_multimap<int, int> hashTable; // Hash Table of indexed elements
124  void ForceArrayReady();
125  void SetLastIndex()
126  {
127  isSetMI = 1;
128  maxIndex = elems.back().index;
129  };
130 
131  public:
132  friend class mesh;
133  friend class snake;
134  friend class surf;
135  friend int TestTemplate_ArrayStruct<T>();
136 
137  void disp() const;
138  void disp(const std::vector<int> &subs) const;
139  void disp(int iStart, int iEnd) const;
140  int find(int key, bool noWarn = false) const;
141  std::vector<int> find_list(const std::vector<int> &key, bool noWarn = false) const;
142  inline int GetMaxIndex() const;
143  inline void Init(int n);
144  bool isready() const
145  {
146  return (readyforuse);
147  };
148  bool checkready();
149  void Concatenate(const ArrayStruct<T> &other);
150  void PopulateIndices();
151  void SetMaxIndex();
152  void HashArray();
153  void PrepareForUse();
154  void ChangeIndices(int nVert, int nEdge, int nSurf, int nVolu);
155  void write(FILE *fid) const;
156  void read(FILE *fid);
157  void remove(std::vector<int> delInd);
158  void TightenConnectivity();
159  // methods needed from std::vector
160  inline int size() const;
161  inline int capacity() const;
162  inline void assign(int n, T &newelem);
163  inline void push_back(T &newelem);
164  inline void reserve(int n);
165  inline void clear();
166  // Operators
167  void issafeaccess(const int a)
168  {
169 #ifdef SAFE_ACCESS // adds a check in debug mode
170  if ((unsigned_int(a) >= elems.size()) || (0 > a))
171  {
172  std::cerr << "Error in " << __PRETTY_FUNCTION__ << std::endl;
173 #ifdef USE_STACKTRACE
174  std::cerr << stacktrace::stacktrace() << std::endl;
175 #endif
176  std::cerr << "Attempt to access position " << a << " in std::vector of size " << elems.size() << std::endl;
177  // dbg::fail(__PRETTY_FUNCTION__,"index out of range");
178  RSVS3D_ERROR_RANGE(" Index is out of range");
179  }
180 #endif // SAFE_ACCESS
181  }
182 
183  const T *operator()(const int a) const
184  {
185  // () Operator returns a constant pointer to the corresponding elems.
186  // Cannot be used on the left hand side and can't be used to edit data in
187  // elems
188 #ifdef SAFE_ACCESS // adds a check in debug mode
189  if ((unsigned_int(a) >= elems.size()) || (0 > a))
190  {
191  std::cerr << "Error in " << __PRETTY_FUNCTION__ << std::endl;
192 #ifdef USE_STACKTRACE
193  std::cerr << stacktrace::stacktrace() << std::endl;
194 #endif
195  std::cerr << "Attempt to access position " << a << " in std::vector of size " << elems.size() << std::endl;
196  // dbg::fail(__PRETTY_FUNCTION__,"index out of range");
197  RSVS3D_ERROR_RANGE(" Index is out of range");
198  }
199 #endif // SAFE_ACCESS
200  return (&(elems[a]));
201  }
202  const T *isearch(const int b) const
203  {
204  // () Operator returns a constant pointer to the corresponding elems.
205  // Cannot be used on the left hand side and can't be used to edit data in
206  // elems
207  int a = this->find(b);
208 #ifdef SAFE_ACCESS // adds a check in debug mode
209  if ((unsigned_int(a) >= elems.size()) || (0 > a))
210  {
211  std::cerr << "Error in " << __PRETTY_FUNCTION__ << std::endl;
212 #ifdef USE_STACKTRACE
213  std::cerr << stacktrace::stacktrace() << std::endl;
214 #endif
215  std::cerr << "Attempt to access index " << b << " at position " << a << " in std::vector of size "
216  << elems.size() << std::endl;
217  // dbg::fail(__PRETTY_FUNCTION__,"index out of range");
218  RSVS3D_ERROR_RANGE(" Index is out of range");
219  }
220 #endif // SAFE_ACCESS
221  return (&(elems[a]));
222  }
223 
224  T &operator[](const int a)
225  {
226  // [] Operator returns a reference to the corresponding elems.
227 #ifdef SAFE_ACCESS // adds a check in debug mode
228  if ((unsigned_int(a) >= elems.size()) | (0 > a))
229  {
230  std::cerr << "Error in " << __PRETTY_FUNCTION__ << std::endl;
231 #ifdef USE_STACKTRACE
232  std::cerr << stacktrace::stacktrace() << std::endl;
233 #endif
234  std::cerr << "Attempt to access position " << a << " in std::vector of size " << elems.size() << std::endl;
235  // dbg::fail(__PRETTY_FUNCTION__,"index out of range");
236  RSVS3D_ERROR_RANGE("Index is out of range");
237  }
238 #endif // SAFE_ACCESS
239  isHash = 0;
240  isSetMI = 0;
241  readyforuse = false;
242  return (elems[a]);
243  }
244 };
245 
246 template <class T> class SnakStruct : public ArrayStruct<T>
247 {
248  protected:
249  using ArrayStruct<T>::elems;
251 
252  std::unordered_multimap<int, int> hashParent;
253  int isHashParent = 0;
254 
255  public:
256  friend class snake;
257 
258  // inline int KeyParent(int a) const ;
259  int findparent(int key) const;
260  void findsiblings(int key, std::vector<int> &siblings) const;
261  int countparent(int key) const
262  {
263  return (hashParent.count(key));
264  };
265  void HashParent();
266  void DeHashParent(const int pos);
267  bool memberIsHashParent(const int pos) const;
268  inline void Init(int n);
269  // Functions that need modification
270  inline void push_back(T &newelem);
271  inline void clear();
272  bool checkready();
273  void ForceArrayReady();
274  void PrepareForUse();
275  void Concatenate(const SnakStruct<T> &other);
276  void remove(const std::vector<int> &sub);
277  T &operator[](const int a)
278  {
279  isHashParent = 0;
280  return (ArrayStruct<T>::operator[](a));
281  }
282 };
283 
284 template <class T> class ModiftrackArray : public ArrayStruct<T>
285 {
286  protected:
287  using ArrayStruct<T>::elems;
288  friend class mesh;
289  friend class snake;
290 
291  public:
292  void SetNoModif();
293  void ReturnModifInd(std::vector<int> &vecind);
294  void ReturnModifLog(std::vector<bool> &modiflog);
295  T &operator[](const int a)
296  {
297 #ifdef SAFE_ACCESS
299 #endif
300  elems[a].isModif = true;
301  return (ArrayStruct<T>::operator[](a));
302  }
303 };
304 
305 template <class T, class Q, class R> class HashedVector
306 { // container for
307  public:
308  std::vector<T> vec;
309  std::unordered_multimap<T, R> hashTable;
310  bool isHash = true;
311 
312  inline void GenerateHash();
313  inline int find(const T key) const;
314  inline std::vector<int> findall(const T key) const;
315  inline int count(const T key) const;
316  std::vector<int> count(const std::vector<T> &key) const;
317  inline std::vector<int> find_list(const std::vector<T> &key) const;
318  bool operator()(const Q &key) const;
319  inline bool IsInVec(const Q &key) const;
320  T &operator[](const int a)
321  {
322  return this->vec[a];
323  }
324  const T &operator[](const int a) const
325  {
326  return this->vec[a];
327  }
328 
329  void reserve(const size_t a)
330  {
331  this->vec.reserve(a);
332  this->hashTable.reserve(a);
333  }
334  void assign(const size_t a, const T &elm)
335  {
336  this->vec.assign(a, elm);
337  this->isHash = false;
338  }
339  void push_back(const T &elm)
340  {
341  this->vec.push_back(elm);
342  R t = this->vec.size() - 1;
343  this->hashTable.emplace(elm, t);
344  }
345  void clear()
346  {
347  this->vec.clear();
348  this->isHash = true;
349  this->hashTable.clear();
350  }
351  size_t size() const
352  {
353  return this->vec.size();
354  }
355 };
356 
357 template <class T, class Q, class R> class HashedMap : public HashedVector<T, Q, R>
358 {
359  public:
363 
364  std::vector<R> targ;
365  inline void GenerateHash();
366 };
367 
368 template <class T, class Q, class R, class S> class HashedVectorPair : public HashedVector<T, Q, R>
369 {
370  S defaultVal = S(0);
371 
372  public:
376  std::vector<S> targ;
377 
378  S &operator()(const T &elm)
379  {
380  int pos = this->HashedVector<T, Q, R>::find(elm);
381  if (pos == rsvs3d::constants::__notfound)
382  {
383  this->push_back(elm, S(0));
384  pos = this->size() - 1;
385  }
386  return this->targ[pos];
387  }
388  const S &operator()(const T &elm) const
389  {
390  int pos = this->HashedVector<T, Q, R>::find(elm);
391  if (pos == rsvs3d::constants::__notfound)
392  {
393  return this->defaultVal;
394  }
395  return this->targ[pos];
396  }
397  void reserve(const size_t a)
398  {
400  this->vec.reserve(a);
401  }
402  void assign(const size_t a, const T &elmVec, const S &elmTarg)
403  {
404  this->HashedVector<T, Q, R>::assign(a, elmVec);
405  this->targ.assign(a, elmTarg);
406  }
407  void push_back(const T &elmVec, const S &elmTarg)
408  {
409  this->HashedVector<T, Q, R>::push_back(elmVec);
410  this->targ.push_back(elmTarg);
411  }
412  void clear()
413  {
415  this->targ.clear();
416  }
417 };
418 
419 template <class T, class Q, class R = int> class HashedVectorSafe : protected HashedVector<T, Q, R>
420 { // container for
421  protected:
425 
426  public:
434 
435  void operator=(const std::vector<T> &a)
436  {
437  vec = a;
438  isHash = false;
439  }
440  void operator=(const HashedVector<T, Q> &a)
441  {
442  vec = a.vec;
443  isHash = a.isHash;
444  hashTable = a.hashTable;
445  }
446  T &operator[](const int a)
447  {
448  // [] Operator returns a reference to the corresponding elems.
449 #ifdef SAFE_ACCESS // adds a check in debug mode
450  if ((unsigned_int(a) >= vec.size()) | (0 > a))
451  {
452  std::cerr << "Error in " << __PRETTY_FUNCTION__ << std::endl;
453  RSVS3D_ERROR_RANGE(" : Index is out of range");
454  }
455 #endif // SAFE_ACCESS
456  isHash = 0;
457  return (vec[a]);
458  }
459  const T &operator[](const int a) const
460  {
461  // [] Operator returns a reference to the corresponding elems.
462 #ifdef SAFE_ACCESS // adds a check in debug mode
463  if ((unsigned_int(a) >= vec.size()) | (0 > a))
464  {
465  std::cerr << "Error in " << __PRETTY_FUNCTION__ << std::endl;
466  RSVS3D_ERROR_RANGE(" : Index is out of range");
467  }
468 #endif // SAFE_ACCESS
469  return (vec[a]);
470  }
471  const T &isearch(const int b) const
472  {
473  // () Operator returns a constant pointer to the corresponding elems.
474  // Cannot be used on the left hand side and can't be used to edit data in
475  // elems
476  int a = this->find(b);
477 #ifdef SAFE_ACCESS // adds a check in debug mode
478  if ((unsigned_int(a) >= vec.size()) | (0 > a))
479  {
480  std::cerr << "Error in " << __PRETTY_FUNCTION__ << std::endl;
481  RSVS3D_ERROR_RANGE(" : Index is out of range");
482  }
483 #endif // SAFE_ACCESS
484  return (&(vec[a]));
485  }
486 };
487 
488 // Base class
489 
491 { // Abstract class to ensure interface is correct
492  public:
493  int index = 0;
494  bool isBorder = false;
495 
496  virtual void disp() const = 0;
497  virtual int Key() const = 0;
498  virtual void ChangeIndices(int nVert, int nEdge, int nSurf, int nVolu) = 0;
499  virtual void PrepareForUse() = 0;
500  virtual bool isready(bool isInMesh) const = 0;
501  virtual void read(FILE *fid) = 0;
502  virtual void write(FILE *fid) const = 0;
503  virtual void TightenConnectivity() = 0;
504  // virtual operator=( meshpart* other)=0 ;
505 };
506 
507 class snakpart
508 { // required functions for parts of snake
509  public:
510  virtual int KeyParent() const = 0;
511 };
512 
514 { // required functions for parts of snake
515  protected:
516  bool isModif = true;
517 
518  public:
519  bool returnIsModif() const
520  {
521  return (isModif);
522  }
523 };
524 
525 // functions
526 template <class T> bool CompareDisp(T *mesh1, T *mesh2);
527 template <class T> int TestReadiness(T &stackT, const char *txt, bool errTarg, bool errTargCheck);
528 template <class T> void DisplayVector(std::vector<T> vec);
529 template <class T> void DisplayVectorStatistics(std::vector<T> vec);
530 template <class T> void PrintVector(std::vector<T> vec, std::ostream &streamout);
531 
532 template <class T, class R>
533 R ConcatenateVectorField(const ArrayStruct<T> &arrayIn, R T::*mp, const std::vector<int> &subList);
534 template <class T, class R>
535 std::vector<R> ConcatenateScalarField(const ArrayStruct<T> &arrayIn, R T::*mp, const std::vector<int> &subList);
536 template <class T, class R> R ConcatenateVectorField(const ArrayStruct<T> &arrayIn, R T::*mp, int rStart, int rEnd);
537 
538 template <class T, class R>
539 std::vector<R> ConcatenateScalarField(const ArrayStruct<T> &arrayIn, R T::*mp, int rStart, int rEnd);
540 
541 template <class T, class R, class U, class V>
542 void OperArrayStructMethod(const ArrayStruct<T> &arrayIn, const std::vector<int> &subList, R T::*mp, U &out, V oper);
543 template <template <class Q, class R> class T, class Q, class R> void EraseKeyPair(T<Q, R> hashTable, Q key, R pos);
544 
545 // test functions
546 
547 // template <class T> bool CompareDisp(T *mesh1,T *mesh2);
548 // bool CompareFuncOut(function<void()> mesh1, function<void()> mesh2);
549 
550 #include "arraystructures_incl.cpp"
551 #include "snakstruct_incl.cpp"
552 
553 #endif // ARRAYSTRUCTS_H_INCLUDED
554 
555 // Regexp to add std everywhere
556 // ([^:])((exception|cerr|endl|cout|vector|unordered_multimap|string|stringstream)[^a-zA-Z0-9_])
557 // \1std::\2
Class for mesh handling.
Definition: mesh.hpp:592
Definition: snake.hpp:83
Class for surface object in a mesh.
Definition: mesh.hpp:267
Namespace for general purpose tools of the RSVS project.
Definition: snake.cpp:1464
File for the implementation of the class template SnakStruct this .cpp file is INCLUDED as part of ar...
Provides the error and warning system used by the RSVS3D project.
#define RSVS3D_ERROR_RANGE(M)
Throw a range_error.
Definition: warning.hpp:173