AliceVision
Photogrammetric Computer Vision Framework
StaticVector.hpp
1 // This file is part of the AliceVision project.
2 // Copyright (c) 2017 AliceVision contributors.
3 // This Source Code Form is subject to the terms of the Mozilla Public License,
4 // v. 2.0. If a copy of the MPL was not distributed with this file,
5 // You can obtain one at https://mozilla.org/MPL/2.0/.
6 
7 #pragma once
8 
9 #include <aliceVision/system/Logger.hpp>
10 
11 #include <algorithm>
12 #include <assert.h>
13 #include <cstdlib>
14 #include <filesystem>
15 #include <sstream>
16 #include <vector>
17 #include <zlib.h>
18 #include <iostream>
19 #include <stdexcept>
20 
21 namespace aliceVision {
22 
23 template<class T>
25 {
26  std::vector<T> _data;
27 
28  typedef typename std::vector<T>::iterator Iterator;
29  typedef typename std::vector<T>::const_iterator ConstIterator;
30  typedef typename std::vector<T>::reference Reference;
31  typedef typename std::vector<T>::const_reference ConstReference;
32 
33  public:
34  StaticVector() {}
35 
36  StaticVector(int n)
37  : _data(n)
38  {}
39 
40  StaticVector(int n, const T& value)
41  : _data(n, value)
42  {}
43 
44  const T& operator[](int index) const { return _data[index]; }
45 
46  T& operator[](int index) { return _data[index]; }
47 
48  void clear() { _data.clear(); }
49 
50  Iterator begin() { return _data.begin(); }
51  Iterator end() { return _data.end(); }
52 
53  ConstIterator begin() const { return _data.begin(); }
54  ConstIterator end() const { return _data.end(); }
55 
56  Reference front() { return _data.front(); }
57  ConstReference front() const { return _data.front(); }
58 
59  Reference back() { return _data.back(); }
60  ConstReference back() const { return _data.back(); }
61 
62  const std::vector<T>& getData() const { return _data; }
63  std::vector<T>& getDataWritable() { return _data; }
64  int size() const { return _data.size(); }
65  bool empty() const { return _data.empty(); }
66  size_t capacity() const { return _data.capacity(); }
67  void reserve(int n) { _data.reserve(n); }
68  void resize(int n) { _data.resize(n); }
69  void resize(int n, T value) { _data.resize(n, value); }
70  void resize_with(int n, const T& val) { _data.resize(n, val); }
71  void swap(StaticVector& other) { _data.swap(other._data); }
72  void assign(int n, T value) { _data.assign(n, value); }
73 
74  void shrink_to_fit() { _data.shrink_to_fit(); }
75 
76  void reserveAddIfNeeded(int nplanned, int ntoallocated)
77  {
78  if (size() + nplanned > capacity())
79  {
80  reserveAdd(nplanned + ntoallocated);
81  }
82  }
83 
84  void reserveAdd(int ntoallocated) { _data.reserve(capacity() + ntoallocated); }
85 
86  void push_back(const T& val) { _data.push_back(val); }
87 
88  void push_front(const T& val) { _data.insert(_data.begin(), val); }
89 
90  void push_back_arr(StaticVector<T>* arr) { _data.insert(_data.end(), arr->getData().begin(), arr->getData().end()); }
91 
92  void push_back_arr(StaticVector<T>& arr) { _data.insert(_data.end(), arr.getData().begin(), arr.getData().end()); }
93 
94  void remove(int i) { _data.erase(_data.begin() + i); }
95 
96  int push_back_distinct(const T& val)
97  {
98  int id = indexOf(val);
99  if (id == -1)
100  _data.push_back(val);
101  return id;
102  }
103 
104  T pop()
105  {
106  T val = _data.back();
107  _data.pop_back();
108  return val;
109  }
110 
111  int indexOf(const T& value) const
112  {
113  const auto it = std::find(_data.begin(), _data.end(), value);
114  return it != _data.end() ? std::distance(_data.begin(), it) : -1;
115  }
116 
117  int indexOfSorted(const T& value) const { return indexOf(value); }
118 
119  int indexOfNearestSorted(const T& value) const
120  {
121  // Retrieve the first element >= value in _data
122  auto it = std::lower_bound(_data.begin(), _data.end(), value);
123  if (it == _data.end())
124  return -1;
125  // If we're between two values...
126  if (it != _data.begin())
127  {
128  // ...select the index of the closest value between it (>= value) and prevIt (< value)
129  auto prevIt = std::prev(it);
130  it = (value - *prevIt) < (*it - value) ? prevIt : it;
131  }
132  return std::distance(_data.begin(), it);
133  }
134 
135  int minValId() const
136  {
137  if (_data.empty())
138  return -1;
139  return std::distance(_data.begin(), std::min_element(_data.begin(), _data.end()));
140  }
141 
142  int maxValId() const
143  {
144  if (_data.empty())
145  return -1;
146  return std::distance(_data.begin(), std::max_element(_data.begin(), _data.end()));
147  }
148 };
149 
150 // TODO: to remove
151 // Avoid the problematic case of std::vector<bool>::operator[]
153 
154 template<class T>
155 int sizeOfStaticVector(const StaticVector<T>* a)
156 {
157  if (a == nullptr)
158  return 0;
159  return a->size();
160 }
161 
162 template<class T>
163 int sizeOfStaticVector(const StaticVector<T>& a)
164 {
165  if (a.empty())
166  return 0;
167  return a.size();
168 }
169 
170 template<class T>
171 int indexOf(T* arr, int n, const T& what)
172 {
173  int isthereindex = -1;
174 
175  int i = 0;
176  while ((i < n) && (isthereindex == -1))
177  {
178  if (arr[i] == what)
179  {
180  isthereindex = i;
181  };
182  i++;
183  };
184 
185  return isthereindex;
186 }
187 
188 template<class T>
189 void saveArrayOfArraysToFile(const std::string& fileName, StaticVector<StaticVector<T>*>* aa)
190 {
191  ALICEVISION_LOG_DEBUG("[IO] saveArrayOfArraysToFile: " << fileName);
192  FILE* f = fopen(fileName.c_str(), "wb");
193  int n = aa->size();
194  fwrite(&n, sizeof(int), 1, f);
195  for (int i = 0; i < n; i++)
196  {
197  int m = 0;
198  StaticVector<T>* a = (*aa)[i];
199  if (a == NULL)
200  {
201  fwrite(&m, sizeof(int), 1, f);
202  }
203  else
204  {
205  m = a->size();
206  fwrite(&m, sizeof(int), 1, f);
207  if (m > 0)
208  {
209  fwrite(&(*a)[0], sizeof(T), m, f);
210  };
211  };
212  };
213  fclose(f);
214 }
215 
216 template<class T>
217 void saveArrayOfArraysToFile(const std::string fileName, StaticVector<StaticVector<T>>& aa)
218 {
219  ALICEVISION_LOG_DEBUG("[IO] saveArrayOfArraysToFile: " << fileName);
220  FILE* f = fopen(fileName.c_str(), "wb");
221  int n = aa.size();
222  fwrite(&n, sizeof(int), 1, f);
223  for (int i = 0; i < n; i++)
224  {
225  int m = 0;
226  StaticVector<T>& a = aa[i];
227  if (a.empty())
228  {
229  fwrite(&m, sizeof(int), 1, f);
230  }
231  else
232  {
233  m = a.size();
234  fwrite(&m, sizeof(int), 1, f);
235  if (m > 0)
236  {
237  fwrite(&a[0], sizeof(T), m, f);
238  };
239  };
240  };
241  fclose(f);
242 }
243 
244 template<class T>
245 StaticVector<StaticVector<T>*>* loadArrayOfArraysFromFile(const std::string& fileName)
246 {
247  ALICEVISION_LOG_DEBUG("[IO] loadArrayOfArraysFromFile: " << fileName);
248  FILE* f = fopen(fileName.c_str(), "rb");
249  if (f == nullptr)
250  {
251  ALICEVISION_THROW_ERROR("[IO] loadArrayOfArraysFromFile: can't open file " << fileName);
252  }
253 
254  int n = 0;
255  size_t retval = fread(&n, sizeof(int), 1, f);
256  if (retval != 1)
257  {
258  fclose(f);
259  ALICEVISION_THROW_ERROR("[IO] loadArrayOfArraysFromFile: can't read outer array size");
260  }
261  StaticVector<StaticVector<T>*>* aa = new StaticVector<StaticVector<T>*>();
262  aa->reserve(n);
263  aa->resize_with(n, NULL);
264  for (int i = 0; i < n; i++)
265  {
266  int m = 0;
267  retval = fread(&m, sizeof(int), 1, f);
268  if (retval != 1)
269  {
270  fclose(f);
271  ALICEVISION_THROW_ERROR("[IO] loadArrayOfArraysFromFile: can't read inner array size");
272  }
273  if (m > 0)
274  {
275  StaticVector<T>* a = new StaticVector<T>();
276  a->resize(m);
277  retval = fread(&(*a)[0], sizeof(T), m, f);
278  if (retval != m)
279  {
280  fclose(f);
281  ALICEVISION_THROW_ERROR("[IO] loadArrayOfArraysFromFile: can't read vector element");
282  }
283  (*aa)[i] = a;
284  };
285  };
286  fclose(f);
287 
288  return aa;
289 }
290 
291 template<class T>
292 void loadArrayOfArraysFromFile(StaticVector<StaticVector<T>>& out_aa, const std::string& fileName)
293 {
294  ALICEVISION_LOG_DEBUG("[IO] loadArrayOfArraysFromFile: " << fileName);
295  FILE* f = fopen(fileName.c_str(), "rb");
296  if (f == nullptr)
297  {
298  ALICEVISION_THROW_ERROR("[IO] loadArrayOfArraysFromFile: can't open file " << fileName);
299  }
300 
301  int n = 0;
302  size_t retval = fread(&n, sizeof(int), 1, f);
303  if (retval != 1)
304  {
305  fclose(f);
306  ALICEVISION_THROW_ERROR("[IO] loadArrayOfArraysFromFile: can't read outer array size");
307  }
308 
309  out_aa.reserve(n);
310  out_aa.resize(n);
311  for (int i = 0; i < n; i++)
312  {
313  int m = 0;
314  retval = fread(&m, sizeof(int), 1, f);
315  if (retval != 1)
316  {
317  fclose(f);
318  ALICEVISION_THROW_ERROR("[IO] loadArrayOfArraysFromFile: can't read inner array size");
319  }
320  if (m > 0)
321  {
322  StaticVector<T>& a = out_aa[i];
323  a.resize(m);
324  retval = fread(&a[0], sizeof(T), m, f);
325  if (retval != m)
326  {
327  fclose(f);
328  ALICEVISION_THROW_ERROR("[IO] loadArrayOfArraysFromFile: can't read vector element");
329  }
330  };
331  };
332  fclose(f);
333 }
334 
335 template<class T>
336 void saveArrayToFile(const std::string& fileName, const StaticVector<T>& a, bool docompress = true)
337 {
338  saveArrayToFile(fileName, &a, docompress);
339 }
340 
341 template<class T>
342 void saveArrayToFile(const std::string& fileName, const StaticVector<T>* a, bool docompress = true)
343 {
344  ALICEVISION_LOG_DEBUG("[IO] saveArrayToFile: " << fileName);
345 
346  std::filesystem::path filepath = fileName;
347  std::filesystem::create_directories(filepath.parent_path());
348 
349  if (!a)
350  {
351  ALICEVISION_LOG_DEBUG("[IO] saveArrayToFile called with NULL static vector");
352  return;
353  }
354 
355  if (a->empty())
356  {
357  ALICEVISION_LOG_WARNING("[IO] saveArrayToFile called with 0-sized static vector");
358  return;
359  }
360 
361  if ((docompress == false) || (a->size() < 1000))
362  {
363  FILE* f = fopen(fileName.c_str(), "wb");
364  if (f == NULL)
365  {
366  ALICEVISION_THROW_ERROR("[IO] file " << fileName << " could not be opened, msg: " << strerror(errno));
367  }
368  int n = a->size();
369  if (n == 0)
370  {
371  fclose(f);
372  return;
373  }
374  int items = fwrite(&n, sizeof(int), 1, f);
375  if (items < 1 && ferror(f) != 0)
376  {
377  fclose(f);
378  ALICEVISION_THROW_ERROR("[IO] failed to write 1 int to " << fileName << ", msg: " << strerror(errno));
379  }
380  items = fwrite(&(*a)[0], sizeof(T), n, f);
381  if (items < n && ferror(f) != 0)
382  {
383  fclose(f);
384  ALICEVISION_THROW_ERROR("[IO] failed to write n items to " << fileName << ", msg: " << strerror(errno));
385  }
386  fclose(f);
387  }
388  else
389  {
390  /* ===========================================================================
391  //from zlib - compress.c
392  Compresses the source buffer into the destination buffer. The level
393  parameter has the same meaning as in deflateInit. sourceLen is the byte
394  length of the source buffer. Upon entry, destLen is the total size of the
395  destination buffer, which must be at least 0.1% larger than sourceLen plus
396  12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
397 
398  compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
399  memory, Z_BUF_ERROR if there was not enough room in the output buffer,
400  Z_STREAM_ERROR if the level parameter is invalid.
401  */
402 
403  // uLong comprLen = sizeof(T)*a->size();
404  uLong comprLen = uLong((double)(sizeof(T) * a->size()) * 1.02) + 12;
405  Byte* compr = (Byte*)calloc((uInt)comprLen, 1);
406  int err = compress(compr, &comprLen, (const Bytef*)(&(*a)[0]), sizeof(T) * a->size());
407 
408  if (err != Z_OK)
409  {
410  ALICEVISION_LOG_ERROR("compress error " << err << " : " << (sizeof(T) * a->size()) << " -> " << comprLen << ", n " << a->size());
411 
412  FILE* f = fopen(fileName.c_str(), "wb");
413  if (f == NULL)
414  {
415  free(compr);
416  ALICEVISION_THROW_ERROR("[IO] file " << fileName << " could not be opened, msg: " << strerror(errno));
417  }
418  int n = a->size();
419  if (n > 0)
420  {
421  int items = fwrite(&n, sizeof(int), 1, f);
422  if (items < 1 && ferror(f) != 0)
423  {
424  fclose(f);
425  free(compr);
426  ALICEVISION_THROW_ERROR("[IO] failed to write 1 int to " << fileName << ", msg: " << strerror(errno));
427  }
428  items = fwrite(&(*a)[0], sizeof(T), n, f);
429  if (items < 1 && ferror(f) != 0)
430  {
431  fclose(f);
432  free(compr);
433  ALICEVISION_THROW_ERROR("[IO] failed to write " << n << " items to " << fileName << ", msg: " << strerror(errno));
434  }
435  }
436  fclose(f);
437  }
438  else
439  {
440  FILE* f = fopen(fileName.c_str(), "wb");
441  if (f == NULL)
442  {
443  free(compr);
444  ALICEVISION_THROW_ERROR("[IO] file " << fileName << " could not be opened, msg: " << strerror(errno));
445  }
446  int n = -1;
447  int items = fwrite(&n, sizeof(int), 1, f);
448  if (items < 1 && ferror(f) != 0)
449  {
450  fclose(f);
451  free(compr);
452  ALICEVISION_THROW_ERROR("[IO] failed to write 1 int to " << fileName << ", msg: " << strerror(errno));
453  }
454  n = a->size();
455  items = fwrite(&n, sizeof(int), 1, f);
456  if (items < 1 && ferror(f) != 0)
457  {
458  fclose(f);
459  free(compr);
460  ALICEVISION_THROW_ERROR("[IO] failed to write 1 int to " << fileName << ", msg: " << strerror(errno));
461  }
462  items = fwrite(&comprLen, sizeof(uLong), 1, f);
463  if (items < 1 && ferror(f) != 0)
464  {
465  fclose(f);
466  free(compr);
467  ALICEVISION_THROW_ERROR("[IO] failed to write 1 uLong to " << fileName << ", msg: " << strerror(errno));
468  }
469  items = fwrite(compr, sizeof(Byte), comprLen, f);
470  if (items < 1 && ferror(f) != 0)
471  {
472  fclose(f);
473  free(compr);
474  ALICEVISION_THROW_ERROR("[IO] failed to write " << comprLen << " items to " << fileName << ", msg: " << strerror(errno));
475  }
476  fclose(f);
477  };
478 
479  free(compr);
480  };
481 }
482 
483 template<class T>
484 StaticVector<T>* loadArrayFromFile(const std::string& fileName, bool printfWarning = false)
485 {
486  ALICEVISION_LOG_DEBUG("[IO] loadArrayFromFile: " << fileName);
487 
488  FILE* f = fopen(fileName.c_str(), "rb");
489  if (f == NULL)
490  {
491  ALICEVISION_THROW_ERROR("loadArrayFromFile : can't open file " << fileName);
492  }
493  else
494  {
495  int n = 0;
496  size_t retval = fread(&n, sizeof(int), 1, f);
497  if (retval != 1)
498  {
499  fclose(f);
500  ALICEVISION_THROW_ERROR("[IO] loadArrayFromFile: can't read array size (1) from " << fileName);
501  }
502  StaticVector<T>* a = NULL;
503 
504  if (n == -1)
505  {
506  retval = fread(&n, sizeof(int), 1, f);
507  if (retval != 1)
508  {
509  fclose(f);
510  ALICEVISION_THROW_ERROR("[IO] loadArrayFromFile: can't read array size (2)");
511  }
512  a = new StaticVector<T>();
513  a->resize(n);
514 
515  uLong comprLen;
516  retval = fread(&comprLen, sizeof(uLong), 1, f);
517  if (retval != 1)
518  {
519  delete a;
520  fclose(f);
521  ALICEVISION_THROW_ERROR("[IO] loadArrayFromFile: can't read ulong elem size");
522  }
523  Byte* compr = (Byte*)calloc((uInt)comprLen, 1);
524  retval = fread(compr, sizeof(Byte), comprLen, f);
525  if (retval != comprLen)
526  {
527  delete a;
528  fclose(f);
529  ALICEVISION_THROW_ERROR("[IO] loadArrayFromFile: can't read blob");
530  }
531 
532  uLong uncomprLen = sizeof(T) * n;
533  int err = uncompress((Bytef*)(&(*a)[0]), &uncomprLen, compr, comprLen);
534 
535  if (err != Z_OK)
536  {
537  delete a;
538  fclose(f);
539  ALICEVISION_THROW_ERROR("uncompress error " << err << " : " << (sizeof(T) * n) << " -> " << uncomprLen << ", n " << n);
540  }
541 
542  if (uncomprLen != sizeof(T) * n)
543  {
544  delete a;
545  fclose(f);
546  ALICEVISION_THROW_ERROR("loadArrayFromFile: uncompression failed uncomprLen!=sizeof(T)*n");
547  }
548 
549  free(compr);
550  }
551  else
552  {
553  a = new StaticVector<T>();
554  a->resize(n);
555  size_t retval = fread(&(*a)[0], sizeof(T), n, f);
556  if (retval != n)
557  {
558  delete a;
559  fclose(f);
560  ALICEVISION_THROW_ERROR("[IO] loadArrayFromFile: can't read n elements");
561  }
562  }
563 
564  fclose(f);
565 
566  return a;
567  }
568 }
569 
570 template<class T>
571 bool loadArrayFromFile(StaticVector<T>& out, const std::string& fileName, bool printfWarning = false)
572 {
573  ALICEVISION_LOG_DEBUG("[IO] loadArrayFromFile: " << fileName);
574 
575  FILE* f = fopen(fileName.c_str(), "rb");
576  if (f == NULL)
577  {
578  throw std::runtime_error("loadArrayFromFile : can't open file " + fileName);
579  }
580  else
581  {
582  int n = 0;
583  size_t retval = fread(&n, sizeof(int), 1, f);
584  if (retval != 1)
585  ALICEVISION_LOG_WARNING("[IO] loadArrayFromFile: can't read array size (1) from " << fileName);
586  out.clear();
587 
588  if (n == -1)
589  {
590  retval = fread(&n, sizeof(int), 1, f);
591  if (retval != 1)
592  ALICEVISION_LOG_WARNING("[IO] loadArrayFromFile: can't read array size (2)");
593  out.resize(n);
594 
595  uLong comprLen;
596  retval = fread(&comprLen, sizeof(uLong), 1, f);
597  if (retval != 1)
598  ALICEVISION_LOG_WARNING("[IO] loadArrayFromFile: can't read ulong elem size");
599  Byte* compr = (Byte*)calloc((uInt)comprLen, 1);
600  retval = fread(compr, sizeof(Byte), comprLen, f);
601  if (retval != comprLen)
602  ALICEVISION_LOG_WARNING("[IO] loadArrayFromFile: can't read blob");
603 
604  uLong uncomprLen = sizeof(T) * n;
605  int err = uncompress((Bytef*)out.getDataWritable().data(), &uncomprLen, compr, comprLen);
606 
607  if (err != Z_OK)
608  {
609  ALICEVISION_LOG_ERROR("uncompress error " << err << " : " << (sizeof(T) * n) << " -> " << uncomprLen << ", n " << n);
610  }
611 
612  if (uncomprLen != sizeof(T) * n)
613  {
614  fclose(f);
615  throw std::runtime_error("loadArrayFromFile: uncompression failed uncomprLen!=sizeof(T)*n");
616  }
617 
618  free(compr);
619  }
620  else
621  {
622  out.resize(n);
623  size_t retval = fread(out.getDataWritable().data(), sizeof(T), n, f);
624  if (retval != n)
625  ALICEVISION_LOG_WARNING("[IO] loadArrayFromFile: can't read n elements");
626  }
627 
628  fclose(f);
629 
630  return true;
631  }
632 }
633 
634 template<class T>
635 void loadArrayFromFileIntoArray(StaticVector<T>* a, const std::string& fileName, bool printfWarning = false)
636 {
637  ALICEVISION_LOG_DEBUG("[IO] loadArrayFromFileIntoArray: " << fileName);
638 
639  FILE* f = fopen(fileName.c_str(), "rb");
640  if (f == NULL)
641  {
642  ALICEVISION_THROW_ERROR("loadArrayFromFileIntoArray: can not open file: " << fileName);
643  }
644  int n = 0;
645  fread(&n, sizeof(int), 1, f);
646 
647  if (n == -1)
648  {
649  fread(&n, sizeof(int), 1, f);
650  if (a->size() != n)
651  {
652  fclose(f);
653  ALICEVISION_THROW_ERROR("loadArrayFromFileIntoArray: expected length " << a->size() << " loaded length " << n);
654  }
655 
656  uLong comprLen;
657  fread(&comprLen, sizeof(uLong), 1, f);
658  Byte* compr = (Byte*)calloc((uInt)comprLen, 1);
659  fread(compr, sizeof(Byte), comprLen, f);
660 
661  uLong uncomprLen = sizeof(T) * n;
662  int err = uncompress((Bytef*)(&(*a)[0]), &uncomprLen, compr, comprLen);
663 
664  if (err != Z_OK)
665  {
666  fclose(f);
667  ALICEVISION_THROW_ERROR("uncompress error " << err << " : " << (sizeof(T) * n) << " -> " << uncomprLen << ", n " << n);
668  }
669 
670  if (uncomprLen != sizeof(T) * n)
671  {
672  fclose(f);
673  ALICEVISION_THROW_ERROR("loadArrayFromFileIntoArray: uncompression failed uncomprLen!=sizeof(T)*n");
674  }
675 
676  free(compr);
677  }
678  else
679  {
680  if (a->size() != n)
681  {
682  fclose(f);
683  ALICEVISION_THROW_ERROR("loadArrayFromFileIntoArray: expected length " << a->size() << " loaded length " << n);
684  }
685  fread(&(*a)[0], sizeof(T), n, f);
686  }
687 
688  fclose(f);
689 }
690 
691 int getArrayLengthFromFile(const std::string& fileName);
692 
693 template<class T>
694 void deleteAllPointers(StaticVector<T*>& vec)
695 {
696  for (int i = 0; i < vec.size(); ++i)
697  {
698  if (vec[i] != NULL)
699  {
700  delete (vec[i]);
701  vec[i] = NULL;
702  }
703  }
704 }
705 
706 template<class T>
707 void deleteArrayOfArrays(StaticVector<StaticVector<T>*>** aa)
708 {
709  for (int i = 0; i < (*aa)->size(); i++)
710  {
711  if ((*(*aa))[i] != NULL)
712  {
713  delete ((*(*aa))[i]);
714  (*(*aa))[i] = NULL;
715  }
716  }
717  delete (*aa);
718 }
719 
720 template<class T>
721 void deleteArrayOfArrays(StaticVector<StaticVector<T>*>& aa)
722 {
723  for (int i = 0; i < aa.size(); i++)
724  {
725  if (aa[i] != NULL)
726  {
727  delete aa[i];
728  aa[i] = NULL;
729  };
730  };
731  aa.clear();
732 }
733 
734 template<class T>
735 StaticVector<StaticVector<T>*>* cloneArrayOfArrays(StaticVector<StaticVector<T>*>* inAOA)
736 {
737  StaticVector<StaticVector<T>*>* outAOA = new StaticVector<StaticVector<T>*>();
738  outAOA->reserve(inAOA->size());
739  // copy
740  for (int i = 0; i < inAOA->size(); i++)
741  {
742  if ((*inAOA)[i] == NULL)
743  {
744  outAOA->push_back(NULL);
745  }
746  else
747  {
748  StaticVector<T>* outA = new StaticVector<T>();
749  outA->reserve((*inAOA)[i]->size());
750  outA->push_back_arr((*inAOA)[i]);
751  outAOA->push_back(outA);
752  };
753  };
754 
755  return outAOA;
756 }
757 
758 } // namespace aliceVision
aliceVision
Definition: checkerDetector.cpp:32
aliceVision::StaticVector
Definition: StaticVector.hpp:24