7 #ifndef ARRAYSTRUCTS_INCL_H_INCLUDED
8 #define ARRAYSTRUCTS_INCL_H_INCLUDED
13 template <
class T>
void ConcatenateVector(std::vector<T> &vecRoot,
const std::vector<T> &vecConcat)
15 vecRoot.insert(vecRoot.end(), vecConcat.begin(), vecConcat.end());
18 template <
class T>
bool CompareDisp(T &mesh1, T &mesh2)
21 std::stringstream ss1, ss2;
22 auto old_buf = std::cout.rdbuf(ss1.rdbuf());
25 std::cout.rdbuf(ss2.rdbuf());
27 std::cout.rdbuf(old_buf);
29 compFlag = ss1.str().compare(ss2.str()) == 0;
33 template <
class T>
void DisplayVector(std::vector<T> vec)
35 PrintVector(vec, std::cout);
37 template <
class T>
void PrintVector(std::vector<T> vec, std::ostream &streamout)
39 streamout << int(vec.size()) <<
" - ";
40 for (
int i = 0; i < int(vec.size()); ++i)
42 streamout << vec[i] <<
" ";
47 template <
class T>
void DisplayVectorStatistics(std::vector<T> vec)
49 std::cout << int(vec.size()) <<
" - ";
50 std::cout << *min_element(vec.begin(), vec.end()) <<
" " << *max_element(vec.begin(), vec.end()) <<
" ";
56 std::cout << s <<
" " << double(s) / double(vec.size());
60 template <
class T,
class R>
61 R ConcatenateVectorField(
const ArrayStruct<T> &arrayIn, R T::*mp,
const std::vector<int> &subList)
65 auto itVecInt = surfInds.begin();
67 for (ii = 0; ii < int(subList.size()); ++ii)
69 surfInds.insert(itVecInt, (arrayIn(subList[ii])->*mp).begin(), (arrayIn(subList[ii])->*mp).end());
70 itVecInt = surfInds.end();
76 template <
class T,
class R>
77 std::vector<R> ConcatenateScalarField(
const ArrayStruct<T> &arrayIn, R T::*mp,
const std::vector<int> &subList)
79 std::vector<R> surfInds;
81 surfInds.reserve(subList.size());
82 for (ii = 0; ii < int(subList.size()); ++ii)
84 surfInds.push_back((arrayIn(subList[ii])->*mp));
90 template <
class T,
class R> R ConcatenateVectorField(
const ArrayStruct<T> &arrayIn, R T::*mp,
int rStart,
int rEnd)
94 auto itVecInt = surfInds.begin();
96 for (ii = rStart; ii < rEnd; ++ii)
98 surfInds.insert(itVecInt, (arrayIn(ii)->*mp).begin(), (arrayIn(ii)->*mp).end());
99 itVecInt = surfInds.end();
105 template <
class T,
class R>
106 std::vector<R> ConcatenateScalarField(
const ArrayStruct<T> &arrayIn, R T::*mp,
int rStart,
int rEnd)
108 std::vector<R> surfInds;
110 surfInds.reserve((rStart - rEnd) > 0 ? (rStart - rEnd) : 0);
111 for (ii = rStart; ii < rEnd; ++ii)
113 surfInds.push_back((arrayIn(ii)->*mp));
119 template <
class T,
class R,
class U,
class V>
120 void OperArrayStructMethod(
const ArrayStruct<T> &arrayIn,
const std::vector<int> &subList, R T::*mp, U &out, V oper)
124 for (ii = 0; ii < int(subList.size()); ++ii)
126 out = oper(out, (arrayIn(subList[ii])->*mp)());
131 template <
class T,
class R> std::vector<R> ReturnDataEqualRange(T key,
const std::unordered_multimap<T, R> &hashTable)
133 std::vector<R> subList;
136 auto range = hashTable.equal_range(key);
137 for (
auto it = range.first; it != range.second; ++it)
139 subList.push_back(it->second);
144 template <
class T,
class R>
145 void ReturnDataEqualRange(T key,
const std::unordered_multimap<T, R> &hashTable, std::vector<R> &subList)
149 auto range = hashTable.equal_range(key);
150 for (
auto it = range.first; it != range.second; ++it)
152 subList.push_back(it->second);
155 template <
typename T>
inline void sort(std::vector<T> &vec)
157 sort(vec.begin(), vec.end());
159 template <
typename T>
inline void unique(std::vector<T> &vec)
161 auto itVecInt = std::unique(vec.begin(), vec.end());
162 vec.resize(std::distance(vec.begin(), itVecInt));
180 template <
typename T>
181 inline void set_intersection(std::vector<T> &targVec,
const std::vector<T> &vec1,
const std::vector<T> &vec2,
185 typename std::vector<T>::iterator it;
186 targVec.assign(vec1.size(), tempType);
191 it = set_intersection(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), targVec.begin());
193 targVec.resize(it - targVec.begin());
202 template <
class T>
int TestTemplate_ArrayStruct()
206 std::vector<int> testSub = {2, 5, 10, 7};
207 std::vector<int> delInd = {1, 2};
216 stackT.assign(5, singleT);
217 stackT.PopulateIndices();
219 stackT2.PopulateIndices();
221 errTest = CompareDisp(stackT, stackT2);
224 std::cerr <<
"Error Displays were not the same (Stage 1)" << std::endl;
230 errTest = CompareDisp(stackT, stackT2);
233 std::cerr <<
"Error Displays were not the same - assignement not "
238 errFlag += TestReadiness(stackT,
" after assignement",
false,
false);
241 stackT.PrepareForUse();
242 stackT2.PrepareForUse();
243 errFlag += TestReadiness(stackT,
" after PrepareForUse",
true,
true);
248 testSub = stackT.find_list(testSub);
249 errFlag += TestReadiness(stackT,
" after find",
true,
true);
251 if (i != 2 || j != rsvs3d::constants::__notfound)
253 std::cerr <<
"FIND did not Succesfully identify the indices" << std::endl;
256 if (testSub[2] != 2 || testSub[3] != rsvs3d::constants::__notfound)
258 std::cerr <<
"FIND_LISTS did not Succesfully identify the "
267 errFlag += TestReadiness(stackT,
" after [] assignement",
false,
false);
272 std::cerr <<
"FIND did not throw an error at the unsafe access" << std::endl;
276 catch (std::exception
const &ex)
278 std::cout <<
"Previous Call should have thrown the following "
281 std::cout <<
"Warning: reading from potentially obsolete unordered_map" << std::endl;
286 stackT.PrepareForUse();
287 errFlag += TestReadiness(stackT,
" after PrepareForUse (2nd Time Time)",
true,
true);
289 stackT.Concatenate(stackT2);
290 errFlag += TestReadiness(stackT,
" after Concatenate",
false,
false);
292 stackT.PrepareForUse();
293 errFlag += TestReadiness(stackT,
" after PrepareForUse (3nd Time Time)",
true,
true);
295 stackT.PopulateIndices();
296 errFlag += TestReadiness(stackT,
" after PopulateIndices",
false,
true);
298 stackT.PrepareForUse();
299 errFlag += TestReadiness(stackT,
" after PrepareForUse (4th Time Time)",
true,
true);
302 fidw = fopen(
"../TESTOUT/testarray.dat",
"w");
306 errFlag += TestReadiness(stackT,
" Write out",
true,
true);
308 fidr = fopen(
"../TESTOUT/testarray.dat",
"r");
313 stackT3.PrepareForUse();
314 errTest = CompareDisp(stackT, stackT3);
317 std::cerr <<
"Error Displays were not the same after write read" << std::endl;
323 std::cout <<
"Error: Could not open file to read test arraystructures." << std::endl;
329 std::cout <<
"Error: Could not open file to write test arraystructures." << std::endl;
334 errTest = CompareDisp(stackT, stackT2);
337 std::cerr <<
"Error Displays were not the same after full assignement" << std::endl;
341 errFlag += TestReadiness(stackT,
" Disp",
true,
true);
343 stackT.elems.erase(stackT.elems.begin(), ++(++stackT.elems.begin()));
346 stackT2.remove(delInd);
348 errTest = CompareDisp(stackT, stackT2);
353 std::cerr <<
"Error Displays were not the same erase" << std::endl;
357 catch (std::exception
const &ex)
359 std::cerr <<
"Exception: " << ex.what() << std::endl;
365 template <
class T>
int TestReadiness(T &stackT,
const char *txt,
bool errTarg,
bool errTargCheck)
373 errTest = stackT.isready();
374 if (!(errTest == errTarg))
376 std::cerr <<
"stackT wrongly marked as " << (errTarg ?
"not" :
"") <<
" ready (isready()) " << txt << std::endl;
379 errTest = stackT.checkready();
380 if (!(errTest == errTargCheck))
382 std::cerr <<
"stackT wrongly marked as " << (errTarg ?
"not" :
"") <<
" ready (checkready())" << txt
396 std::cerr <<
"warning: Potentially unsafe reading of max index"
397 " - execute PrepareForUse() before access"
399 std::cerr <<
" in " << __PRETTY_FUNCTION__ << std::endl;
407 if (isHash == 0 && !noWarn)
409 std::cerr <<
"Warning: reading from potentially obsolete unordered_map ";
410 std::cerr << std::endl <<
" in " << __PRETTY_FUNCTION__ << std::endl;
411 std::cerr <<
" To avoid this message perform read operations on"
412 " ArrayStruct<T> using the () operator"
415 auto search = hashTable.find(key);
417 if (search == hashTable.end())
419 return (rsvs3d::constants::__notfound);
423 key2 = elems[search->second].index;
426 std::cerr <<
" Error in " << __PRETTY_FUNCTION__ << std::endl;
430 return (search->second);
435 std::vector<int> returnSub = key;
437 for (ii = 0; ii < int(key.size()); ++ii)
439 returnSub[ii] = this->find(key[ii], noWarn);
447 fprintf(fid,
"%i %i \n",
int(this->size()),
int(isInMesh));
448 for (ii = 0; ii < int(this->size()); ++ii)
450 elems[ii].write(fid);
456 fscanf(fid,
"%i %i ", &n, &ii);
459 for (ii = 0; ii < n; ++ii)
469 readyforuse = ((isHash == 1) & (isSetMI == 1));
472 while ((i < this->size()) & readyforuse)
474 readyforuse = readyforuse & elems[i].isready(isInMesh);
479 return (readyforuse);
490 std::cout <<
"Array of size " << this->size() << std::endl;
491 for (
int ii = 0; unsigned_int(ii) < elems.size(); ii++)
493 std::cout <<
"Array " << ii <<
" ";
496 std::cout <<
"Array Dat: isHash " << isHash <<
"; isSetMI " << isSetMI <<
"; isInMesh " << isInMesh << std::endl;
500 std::cout <<
"Array of size " << this->size() << std::endl;
501 for (
int ii = iStart; iEnd < elems.size(); ii++)
503 std::cout <<
"Array " << ii <<
" ";
506 std::cout <<
"Array Dat: isHash " << isHash <<
"; isSetMI " << isSetMI <<
"; isInMesh " << isInMesh << std::endl;
511 std::cout <<
"Array of size " << this->size() <<
" displaying subset of size " << subs.size() << std::endl;
512 for (ii = 0; unsigned_int(ii) < subs.size(); ii++)
514 std::cout <<
"Array " << subs[ii] <<
" ";
515 elems[subs[ii]].disp();
531 if (!hashTable.empty())
535 hashTable.reserve(elems.size());
536 for (
int i = 0; i < int(elems.size()); ++i)
538 hashTable.emplace(elems[i].Key(), i);
547 for (
int i = 0; i < int(elems.size()); ++i)
549 elems[i].TightenConnectivity();
558 int n = elems.size();
560 for (
int ii = n - 1; - 1 < ii; --ii)
562 if (maxIndex < this->elems[ii].index)
564 maxIndex = elems[ii].index;
582 int nCurr, nNew, nTot, ii;
583 nCurr = this->size();
588 for (ii = 0; ii < nNew; ii++)
590 elems.push_back(other.elems[ii]);
601 int n = elems.size();
603 for (
int ii = 0; ii < n; ++ii)
605 elems[ii].index = ii + 1;
615 int n = elems.size();
616 for (
int ii = 0; ii < n; ++ii)
618 elems[ii].ChangeIndices(nVert, nEdge, nSurf, nVolu);
627 for (
int ii = 0; ii < this->size(); ++ii)
629 this->elems[ii].PrepareForUse();
647 delHash.vec = delInd;
648 delHash.GenerateHash();
650 elems.erase(std::remove_if(elems.begin(), elems.end(), delHash), elems.end());
666 return (
int(elems.size()));
670 return (
int(elems.capacity()));
674 elems.assign(n, newelem);
681 elems.push_back(newelem);
683 maxIndex = newelem.index > maxIndex ? newelem.index : maxIndex;
684 hashTable.emplace(newelem.Key(), elems.size() - 1);
703 HashVector(vec, hashTable);
708 return (FindSub(key, hashTable));
712 return (ReturnDataEqualRange(key, hashTable));
717 return (hashTable.count(key));
722 std::vector<int> subOut;
723 subOut.reserve(key.size());
724 for (
int i = 0; i < int(key.size()); ++i)
726 subOut.push_back(hashTable.count(key[i]));
732 template <
class T,
class Q,
class R>
735 return (FindSubList(key, vec, hashTable));
740 return (FindSub(key.Key(), hashTable) != rsvs3d::constants::__notfound);
745 return (FindSub(key.Key(), hashTable) != rsvs3d::constants::__notfound);
751 HashVector(vec, hashTable, targ);
755 template <
class T>
int FindSub(
const T &key,
const std::unordered_multimap<T, int> &hashTable)
757 auto search = hashTable.find(key);
759 if (search == hashTable.end())
761 return (rsvs3d::constants::__notfound);
764 return (search->second);
768 std::vector<int> FindSubList(
const std::vector<T> &keyFind,
const std::vector<T> &keyList,
769 std::unordered_multimap<T, int> &hashTable)
771 std::vector<int> returnSub;
774 returnSub.reserve(
int(keyFind.size()));
776 if (hashTable.empty())
778 HashVector(keyList, hashTable);
781 for (ii = 0; ii < int(keyFind.size()); ++ii)
783 returnSub.push_back(FindSub(keyFind[ii], hashTable));
785 if (returnSub[ii] >= 0)
787 if (keyList[returnSub[ii]] != keyFind[ii])
798 std::vector<int> FindSubList(
const std::vector<T> &keyFind,
const std::vector<T> &keyList,
799 const std::unordered_multimap<T, int> &hashTable)
801 std::vector<int> returnSub;
804 returnSub.reserve(
int(keyFind.size()));
806 if (hashTable.empty() && keyList.size() > 0 && keyFind.size() > 0)
811 for (ii = 0; ii < int(keyFind.size()); ++ii)
813 returnSub.push_back(FindSub(keyFind[ii], hashTable));
815 if (returnSub[ii] >= 0)
817 if (keyList[returnSub[ii]] != keyFind[ii])
827 template <
class T,
class Q>
828 void HashVector(
const std::vector<T> &elems, std::unordered_multimap<T, Q> &hashTable,
const std::vector<Q> &targElems)
833 hashTable.reserve(elems.size());
834 if (targElems.size() == 0)
836 for (
int i = 0; i < int(elems.size()); ++i)
838 hashTable.emplace(elems[i], i);
841 else if (targElems.size() == elems.size())
843 for (
int i = 0; i < int(elems.size()); ++i)
845 hashTable.emplace(elems[i], targElems[i]);
855 template <
template <
class Q,
class R>
class T,
class Q,
class R>
void EraseKeyPair(T<Q, R> hashTable, Q key, R pos)
857 typename T<Q, R>::iterator it;
858 it = hashTable.find(key);
859 while (it->second != pos && it->first == key)
864 if (it->second == pos && it->first == key)
870 std::cerr <<
"Error: Key value std::pair not found and could not be removed " << std::endl;
871 std::cerr <<
" key " << key <<
" pos " << pos << std::endl;
872 std::cerr <<
" in function:" << __PRETTY_FUNCTION__ << std::endl;
Provide std::vector container with hashed index mapping.
Provides the error and warning system used by the RSVS3D project.
#define RSVS3D_ERROR_ARGUMENT(M)
Throw a invalid_argument.