Itasca C++ Interface
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
farray.h
Go to the documentation of this file.
1 #pragma once
2 
22 //#pragma warning(disable:4244)
23 //#pragma warning(disable:4267)
24 #ifdef __LINUX
25 #include "basetoqt.h"
26 #endif
27 template <class T,uint64 S=32> class FArray {
28 public:
29  using size_type = uint64;
30  using value_type = T;
31  using iterator = T *;
32  using const_iterator = const T *;
33 
35  FArray() : begin_(reinterpret_cast<T *>(arr_.data())), end_(begin_), allocated_(S), size_(0) { }
40  explicit FArray(size_type s,const T &t=T()) : begin_(reinterpret_cast<T *>(arr_.data())), end_(begin_), allocated_(S), size_(0) { checkAllocated(s); end_ = begin_ + s; for (T *b=begin_;b<end_;++b) new(b) T(t); size_ = s; }
42  template <uint64 S2> FArray(const FArray<T,S2> &f) : begin_(reinterpret_cast<T *>(arr_.data())), end_(begin_), allocated_(S), size_(0) { operator=(f); }
44  FArray(const FArray<T,S> &f) : begin_(reinterpret_cast<T *>(arr_.data())), end_(begin_), allocated_(S), size_(0) { operator=(f); }
45  FArray(std::initializer_list<T> l) : begin_(reinterpret_cast<T *>(arr_.data())), end_(begin_), allocated_(S), size_(0) {
46  for (auto it=l.begin();it!=l.end();++it)
47  push_back(*it);
48  }
50  ~FArray() { reset(); }
52  template <uint64 S2> const FArray<T,S> &operator=(const FArray<T,S2> &f) {
53  clear();
54  checkAllocated(f.size());
55  end_ = begin_ + f.size();
56  size_ = f.size();
57  T *bl = begin_;
58  for (auto br=f.begin();bl<end();++bl,++br)
59  new(bl) T(*br);
60  return *this;
61  }
63  const FArray<T,S> &operator=(const FArray<T,S> &f) {
64  clear();
65  checkAllocated(f.size());
66  end_ = begin_ + f.size();
67  size_ = f.size_;
68  T *bl=begin_;
69  for (T *br=f.begin_;bl<end_;++bl,++br)
70  new(bl) T(*br);
71  return *this;
72  }
73 
74  // Accessors
76  size_type size() const { return size_; }
78  size_type stackSize() const { return S; }
81  size_type allocated() const { return allocated_; }
83  bool empty() const { return end_ == begin_; }
86  T * data() { return begin_; }
89  const T * data() const { return begin_; }
91  T & front() { return *begin_; }
93  const T & front() const { return *begin_; }
95  T & back() { return *(end_-1); }
97  const T & back() const { return *(end_-1); }
101  size_type find(const T &t) const {
102  for (size_type i=0;i<size();++i) {
103  if (at(i)==t) return i;
104  }
105  return limits<size_type>::max();
106  }
107 
108  // Manipulators
110  void push_back(const T &t) { checkAllocated(size()+1); new(end_) T(t); ++end_; ++size_; }
114  T *emplace_back() { checkAllocated(size()+1); ++size_; return end_++; }
117  T *emplace_n_back(uint64 n) { checkAllocated(size() + n); T *ret = end_; end_ += n; size_ += n; return ret; }
119  void pop_back() { assert(size()); --end_; end_->~T(); --size_; }
124  void resize(size_type i,const T &t=T()) {
125  if (size()==i) return;
126  if (size()>i) {
127  T *e = end_;
128  end_ = begin_ + i;
129  for (T *p=e-1;p>=end_;--p)
130  p->~T();
131  size_ = i;
132  return;
133  }
134  size_type s = size();
135  checkAllocated(i);
136  end_ = begin_ + i;
137  size_ = i;
138  for (T *p=begin_+s;p<end_;++p)
139  new(p) T(t);
140  }
143  iterator insert(size_type i,const T &t) {
144  i = std::min(size(),i);
145  if (i+1>size()) push_back(t);
146  else {
147  push_back(back());
148  for (iterator p=end_-2;p>begin_+i;--p)
149  *p = *(p-1);
150  *(begin_+i) = t;
151  }
152  return begin_ + i;
153  }
155  void put(size_type i,const T &t) {
156  if (size()<=i) {
157  resize(i);
158  push_back(t);
159  } else
160  at(i) = t;
161  }
163  template <class C> void append(const C &in) { for (auto i=in.begin();i!=in.end();++i) push_back(*i); }
166  iterator insert(iterator it,const T &t) {
167  size_type i = it - begin_;
168  i = std::min(size(),i);
169  if (i+1>size()) push_back(t);
170  else {
171  push_back(back());
172  for (iterator p=end_-2;p>begin_+i;--p)
173  *p = *(p-1);
174  *(begin_+i) = t;
175  }
176  return begin_ + i;
177  }
180  bool remove(size_type i) {
181  if (i>=size()) return false;
182  for (iterator it=begin_+i;it+1<end_;++it)
183  *it = *(it+1);
184  pop_back();
185  return true;
186  }
189  size_type removeAll(const T &t) {
190  size_type ret = 0;
191  for (size_type i=0;i<size();) {
192  if (t==at(i)) {
193  remove(i);
194  ++ret;
195  } else
196  ++i;
197  }
198  return ret;
199  }
202  void clear() {
203  // if type T is not plain old data, call the destructor for each array element;
204  // std::is_pod is deprecated in C++20; can be replaced with is_integral, is_floating_point etc.
205  if (!std::is_pod<T>::value)
206  for (T *b=begin_;b<end_;++b)
207  b->~T();
208  end_ = begin_;
209  size_ = 0;
210  }
213  void clear_no_destruct() { end_ = begin_; size_ = 0; }
217  void reset() {
218  clear();
219  if (begin_!=reinterpret_cast<T *>(arr_.data()))
220  ::free(begin_);
221  end_ = begin_ = reinterpret_cast<T *>(arr_.data());
222  allocated_ = S;
223  }
227  void clip() { if (size()*2<allocated_ && size()>S) changeAllocated(size()); }
228 
229  // Member access functions
232  iterator begin() { return begin_; }
235  const_iterator begin() const { return begin_; }
238  const_iterator constBegin() const { return begin_; }
241  iterator end() { return end_; }
244  const_iterator end() const { return end_; }
247  const_iterator constEnd() const { return end_; }
251  T & at(size_type i) { return begin_[i]; }
255  const T & at(size_type i) const { return begin_[i]; }
259  T & operator[](size_type i) { return at(i); }
263  const T & operator[](size_type i) const { return at(i); }
267  T value(int i,const T &t=T()) const { if (i<0) return t; if (to<size_type>(i)>=size()) return t; return at(i); }
271  T value(quint32 i,const T &t=T()) const { if (to<size_type>(i)>=size()) return t; return at(i); }
275  T value(uint64 i,const T &t=T()) const { if (to<size_type>(i)>=size()) return t; return at(i); }
276 private:
277  void checkAllocated(size_type target) {
278  static const size_type max_increase = 1000000;
279  if (target<=allocated_) return;
280  size_type newsize = std::max<size_type>(allocated_,8);
281  while (newsize<target)
282  newsize += to<size_type>(std::min(max_increase,newsize));
283  changeAllocated(newsize);
284  }
285  void changeAllocated(size_type newSize) {
286  size_type old_size = size();
287  assert(old_size<=newSize);
288  T *newBegin = reinterpret_cast<T *>(arr_.data());
289  if (newSize>S)
290 #ifdef _DEBUG
291  newBegin = reinterpret_cast<T *>(itasca::memory::imalloc(newSize*sizeof(T),__FILE__,__LINE__));
292 #else
293  newBegin = reinterpret_cast<T *>(std::malloc(newSize*sizeof(T)));
294 #endif
295  T *tl = newBegin;
296  for (T *tr=begin_;tr<end_;++tl,++tr) {
297  new(tl) T(*tr);
298  tr->~T();
299  }
300  if (begin_!=reinterpret_cast<T *>(arr_.data()))
301  std::free(begin_);
302  begin_ = newBegin;
303  end_ = begin_ + old_size;
304  allocated_ = newSize;
305  }
306  union { // Note: std::array<> used so you can see contents in debugger (which has been really irritating).
307  T* start_; // Placed in this union so constructors don't get called on creation.
308  std::array<T, S> arr_;
309  };
310  T* begin_ = arr_.data();
311  T* end_ = &begin_;
312  size_type allocated_ = S;
313  size_type size_ = 0;
314 };
316 template <class T> class FArray<T,0> {
317 public:
318  using size_type = uint64;
319  using iterator = T *;
320  using const_iterator = const T *;
321  using value_type = T;
322 
324  FArray() : begin_(0), end_(0), allocated_(0), size_(0) { }
329  FArray(size_type s,const T &t=T()) : begin_(0), end_(begin_), allocated_(0), size_(0) { checkAllocated(s); end_ = begin_ + s; for (T *b=begin_;b<end_;++b) new(b) T(t); size_ = s; }
331  template <uint64 S2> FArray(const FArray<T,S2> &f) : begin_(0), end_(begin_), allocated_(0), size_(0) { operator=(f); }
333  FArray(const FArray<T,0> &f) : begin_(0), end_(begin_), allocated_(0), size_(0) { operator=(f); }
334  FArray(std::initializer_list<T> l) : begin_(0), end_(begin_), allocated_(0), size_(0) {
335  for (auto it=l.begin();it!=l.end();++it)
336  push_back(*it);
337  }
339  ~FArray() { reset(); }
341  template <uint64 S2> const FArray<T,0> &operator=(const FArray<T,S2> &f) {
342  clear();
343  checkAllocated(f.size());
344  end_ = begin_ + f.size();
345  size_ = f.size();
346  T *bl=begin_;
347  for (T *br=f.begin();bl<end();++bl,++br)
348  new(bl) T(*br);
349  return *this;
350  }
352  const FArray<T,0> &operator=(const FArray<T,0> &f) {
353  clear();
354  checkAllocated(f.size());
355  end_ = begin_ + f.size();
356  size_ = f.size_;
357  T *bl=begin_;
358  for (T *br=f.begin_;bl<end_;++bl,++br)
359  new(bl) T(*br);
360  return *this;
361  }
362 
363  // Accessors
365  const size_type &size() const { return size_; }
368  const size_type &allocated() const { return allocated_; }
370  bool empty() const { return end_ == begin_; }
373  T * data() { return begin_; }
376  const T * data() const { return begin_; }
378  T & front() { return *begin_; }
380  const T & front() const { return *begin_; }
382  T & back() { return *(end_-1); }
384  const T & back() const { return *(end_-1); }
385 
386  // Manipulators
388  void push_back(const T &t) { checkAllocated(size()+1); new(end_) T(t); ++end_; ++size_; }
392  T *emplace_back() { checkAllocated(size()+1); ++size_; return end_++; }
395  T *emplace_n_back(uint64 n) { checkAllocated(size() + n); T *ret = end_; end_ += n; size_ += n; return ret; }
397  void pop_back() { assert(size()); --end_; end_->~T(); --size_; }
402  void resize(size_type i,const T &t=T()) {
403  if (size()==i) return;
404  if (size()>i) {
405  T *e = end_;
406  end_ = begin_ + i;
407  for (T *p=e-1;p>=end_;--p)
408  p->~T();
409  size_ = i;
410  return;
411  }
412  auto s = size();
413  checkAllocated(i);
414  end_ = begin_ + i;
415  size_ = i;
416  for (T *p=begin_+s;p<end_;++p)
417  new(p) T(t);
418  }
421  iterator insert(size_type i,const T &t) {
422  i = std::min(size(),i);
423  if (i+1>size()) push_back(t);
424  else {
425  push_back(back());
426  for (iterator p=end_-2;p>begin_+i;--p)
427  *p = *(p-1);
428  *(begin_+i) = t;
429  }
430  return begin_ + i;
431  }
434  iterator insert(iterator it,const T &t) {
435  size_type i = it - begin_;
436  i = std::min(size(),i);
437  if (i+1>size()) push_back(t);
438  else {
439  push_back(back());
440  for (iterator p=end_-2;p>begin_+i;--p)
441  *p = *(p-1);
442  *(begin_+i) = t;
443  }
444  return begin_ + i;
445  }
447  void put(size_type i,const T &t) {
448  if (size()<=i) {
449  resize(i);
450  push_back(t);
451  } else
452  at(i) = t;
453  }
455  template <class C> void append(const C &in) { for (auto i=in.begin();i!=in.end();++i) push_back(*i); }
458  bool remove(size_type i) {
459  if (i>=size()) return false;
460  for (iterator it=begin_+i;it<end_;++it)
461  *it = *(it+1);
462  pop_back();
463  return true;
464  }
467  size_type removeAll(const T &t) {
468  size_type ret = 0;
469  for (size_type i=0;i<size();) {
470  if (t==at(i)) {
471  remove(i);
472  ++ret;
473  } else
474  ++i;
475  }
476  return ret;
477  }
480  void clear() {
481  // if type T is not plain old data, call the destructor for each array element;
482  // std::is_pod is deprecated in C++20; can be replaced with is_integral, is_floating_point etc.
483  if (!std::is_pod<T>::value)
484  for (T *b=begin_;b<end_;++b)
485  b->~T();
486  end_ = begin_;
487  size_ = 0;
488  }
491  void clear_no_destruct() { end_ = begin_; size_ = 0; }
495  void reset() {
496  clear();
497  if (begin_)
498  std::free(begin_);
499  end_ = begin_ = 0;
500  allocated_ = 0;
501  }
505  void clip() { if (size()*2<allocated_) changeAllocated(size()); }
506 
507  // Member access functions
510  iterator begin() { return begin_; }
513  const_iterator begin() const { return begin_; }
516  const_iterator constBegin() const { return begin_; }
519  iterator end() { return end_; }
522  const_iterator end() const { return end_; }
525  const_iterator constEnd() const { return end_; }
529  T & at(size_type i) { return begin_[i]; }
533  const T & at(size_type i) const { return begin_[i]; }
537  T & operator[](size_type i) { return at(i); }
541  const T & operator[](size_type i) const { return at(i); }
545  T value(int i,const T &t=T()) const { if (i<0) return t; if (to<size_type>(i)>=size()) return t; return at(i); }
549  T value(quint32 i,const T &t=T()) const { if (to<size_type>(i)>=size()) return t; return at(i); }
553  T value(uint64 i,const T &t=T()) const { if (to<size_type>(i)>=size()) return t; return at(i); }
554 private:
555  void checkAllocated(size_type target) {
556  if (target<=allocated_) return;
557  size_type newsize = std::max<size_type>(allocated_,8);
558  while (newsize<target)
559  newsize += std::min<size_type>(1000000,newsize);
560  changeAllocated(newsize);
561  }
562  void changeAllocated(size_type newSize) {
563  size_type old_size = size();
564  assert(old_size<=newSize);
565  T *newBegin = 0;
566  if (newSize)
567 #ifdef _DEBUG
568  newBegin = reinterpret_cast<T *>(itasca::memory::imalloc(newSize*sizeof(T),__FILE__,__LINE__));
569 #else
570  newBegin = reinterpret_cast<T *>(std::malloc(newSize*sizeof(T)));
571 #endif
572  T *tl = newBegin;
573  for (T *tr=begin_;tr<end_;++tl,++tr) {
574  new(tl) T(*tr);
575  tr->~T();
576  }
577  std::free(begin_);
578  begin_ = newBegin;
579  end_ = begin_ + old_size;
580  allocated_ = newSize;
581  }
582  T * begin_;
583  T * end_;
584  size_type allocated_;
585  size_type size_;
586 };
587 //#pragma warning(default:4244)
588 //#pragma warning(default:4267)
589 
590 
592 // EoF
const T & back() const
Definition: farray.h:384
void reset()
Definition: farray.h:495
const_iterator begin() const
Definition: farray.h:513
void reset()
Definition: farray.h:217
FArray(size_type s, const T &t=T())
Definition: farray.h:329
T * emplace_back()
Definition: farray.h:392
FArray(size_type s, const T &t=T())
Definition: farray.h:40
const_iterator constBegin() const
Definition: farray.h:516
const T & front() const
Definition: farray.h:93
FArray(const FArray< T, S2 > &f)
Copy constructor, valid for FArrays of the same data type but different stack lengths.
Definition: farray.h:331
iterator insert(iterator it, const T &t)
Definition: farray.h:166
iterator end()
Definition: farray.h:241
T value(quint32 i, const T &t=T()) const
Definition: farray.h:549
void put(size_type i, const T &t)
Adds a value to the array, first making certain it is big enough to hold it.
Definition: farray.h:447
T value(uint64 i, const T &t=T()) const
Definition: farray.h:275
FArray(const FArray< T, S2 > &f)
Copy constructor, valid for FArrays of the same data type but different stack lengths.
Definition: farray.h:42
const_iterator end() const
Definition: farray.h:244
const_iterator end() const
Definition: farray.h:522
bool remove(size_type i)
Definition: farray.h:180
~FArray()
Destructor.
Definition: farray.h:50
const_iterator constEnd() const
Definition: farray.h:247
T value(uint64 i, const T &t=T()) const
Definition: farray.h:553
void clip()
Definition: farray.h:227
void append(const C &in)
Appends the contents of one FArray onto another.
Definition: farray.h:163
iterator insert(size_type i, const T &t)
Definition: farray.h:143
DVect * iterator
Typedef to assist in STL compatibility.
Definition: farray.h:31
const FArray< T, 0 > & operator=(const FArray< T, S2 > &f)
Assignment operator, valid for FArrays of the same data type but different stack lengths.
Definition: farray.h:341
const FArray< T, S > & operator=(const FArray< T, S > &f)
Specialized assignment operator, for the special case of when the stack lengths are the same.
Definition: farray.h:63
const FArray< T, S > & operator=(const FArray< T, S2 > &f)
Assignment operator, valid for FArrays of the same data type but different stack lengths.
Definition: farray.h:52
uint64 size_type
Typedef to assist in STL compatibility.
Definition: farray.h:29
T & at(size_type i)
Definition: farray.h:251
T & operator[](size_type i)
Definition: farray.h:537
FArray(const FArray< T, 0 > &f)
Specialized copy constructor, for the special case of when the stack lengths are the same.
Definition: farray.h:333
const_iterator begin() const
Definition: farray.h:235
T * emplace_n_back(uint64 n)
Definition: farray.h:395
bool remove(size_type i)
Definition: farray.h:458
void clip()
Definition: farray.h:505
T & front()
Definition: farray.h:91
debug checked shorthand for std::numeric_limits<T>::
Definition: limit.h:25
void resize(size_type i, const T &t=T())
Definition: farray.h:402
T value(int i, const T &t=T()) const
Definition: farray.h:267
void clear()
Definition: farray.h:202
iterator insert(iterator it, const T &t)
Definition: farray.h:434
const T * const_iterator
Typedef to assist in STL compatibility.
Definition: farray.h:320
size_type allocated() const
Definition: farray.h:81
void append(const C &in)
Appends the contents of one FArray onto another.
Definition: farray.h:455
T & back()
Definition: farray.h:382
void resize(size_type i, const T &t=T())
Definition: farray.h:124
bool empty() const
Definition: farray.h:370
T * data()
Definition: farray.h:373
const T * data() const
Definition: farray.h:376
size_type size() const
Definition: farray.h:76
T & at(size_type i)
Definition: farray.h:529
T & front()
Definition: farray.h:378
iterator insert(size_type i, const T &t)
Definition: farray.h:421
FArray(const FArray< T, S > &f)
Specialized copy constructor, for the special case of when the stack lengths are the same.
Definition: farray.h:44
iterator end()
Definition: farray.h:519
const T & operator[](size_type i) const
Definition: farray.h:541
FArray()
Default constructor - the array size is zero.
Definition: farray.h:324
T value(quint32 i, const T &t=T()) const
Definition: farray.h:271
const FArray< T, 0 > & operator=(const FArray< T, 0 > &f)
Specialized assignment operator, for the special case of when the stack lengths are the same.
Definition: farray.h:352
const_iterator constEnd() const
Definition: farray.h:525
size_type find(const T &t) const
Definition: farray.h:101
DVect value_type
Typedef to assist in STL compatibility.
Definition: farray.h:30
void pop_back()
Removes the last element in the array. The results are undefined if the array is of zero length.
Definition: farray.h:397
T & back()
Definition: farray.h:95
const T & back() const
Definition: farray.h:97
const DVect * const_iterator
Typedef to assist in STL compatibility.
Definition: farray.h:32
const_iterator constBegin() const
Definition: farray.h:238
size_type removeAll(const T &t)
Definition: farray.h:467
Combines base interface with Qt – allows Qt to interact with other Base types transparently.
An array class that attempts to minimize unnecessary heap access.
Definition: farray.h:27
const T * data() const
Definition: farray.h:89
void push_back(const T &t)
Adds a new element to the end of the array, increasing the array size by one.
Definition: farray.h:110
void pop_back()
Removes the last element in the array. The results are undefined if the array is of zero length.
Definition: farray.h:119
T * emplace_n_back(uint64 n)
Definition: farray.h:117
size_type stackSize() const
Returns the size of the array pre-allocated on the stack.
Definition: farray.h:78
uint64 size_type
Typedef to assist in STL compatibility.
Definition: farray.h:318
const size_type & size() const
Definition: farray.h:365
const T & front() const
Definition: farray.h:380
const T & at(size_type i) const
Definition: farray.h:255
size_type removeAll(const T &t)
Definition: farray.h:189
const T & at(size_type i) const
Definition: farray.h:533
T * emplace_back()
Definition: farray.h:114
T * iterator
Typedef to assist in STL compatibility.
Definition: farray.h:319
void clear_no_destruct()
Definition: farray.h:213
void put(size_type i, const T &t)
Adds a value to the array, first making certain it is big enough to hold it.
Definition: farray.h:155
void clear_no_destruct()
Definition: farray.h:491
T * data()
Definition: farray.h:86
const T & operator[](size_type i) const
Definition: farray.h:263
void clear()
Definition: farray.h:480
FArray()
Default constructor - the array size is zero.
Definition: farray.h:35
void push_back(const T &t)
Adds a new element to the end of the array, increasing the array size by one.
Definition: farray.h:388
T value(int i, const T &t=T()) const
Definition: farray.h:545
bool empty() const
Definition: farray.h:83
Template specialization for S=0 - indication no stack space at all should be made.
Definition: farray.h:316
iterator begin()
Definition: farray.h:510
T & operator[](size_type i)
Definition: farray.h:259
iterator begin()
Definition: farray.h:232
const size_type & allocated() const
Definition: farray.h:368
~FArray()
Destructor.
Definition: farray.h:339