Itasca C++ Interface
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
flatarray.h
1 #pragma once
2 
3 template <class T> class FlatArray {
4 public:
5  typedef quint64 size_type;
6  typedef T * iterator;
7  typedef const T *const_iterator;
8 
10  FlatArray() { }
11  FlatArray(size_type s,double fac=1.3) : defaultStorage_(s), multFac_(fac) { checkAllocated(s); }
12  FlatArray(const FlatArray<T> &f) { operator=(f); }
13  FlatArray(std::initializer_list<T> l) {
14  for (auto it=l.begin();it!=l.end();++it)
15  push_back(*it);
16  }
17  ~FlatArray() { defaultStorage_=0; reset(); }
18  const FlatArray<T> &operator=(const FlatArray<T> &f) {
19  clear();
20  defaultStorage_ = f.defaultStorage_;
21  checkAllocated(f.size());
22  end_ = begin_ + f.size();
23  size_ = f.size();
24  T *bl=begin_;
25  for (T *br=f.begin();bl<end();++bl,++br)
26  new(bl) T(*br);
27  return *this;
28  }
29  const size_type &size() const { return size_; }
30  const size_type &allocated() const { return allocated_; }
31  bool empty() const { return end_ == begin_; }
32  T * data() { return begin_; }
33  const T * data() const { return begin_; }
34  T & front() { return *begin_; }
35  const T & front() const { return *begin_; }
36  T & back() { return *(end_-1); }
37  const T & back() const { return *(end_-1); }
38 
39  void push_back(const T &t) { checkAllocated(size()+1); new(end_) T(t); ++end_; ++size_; }
40  T *emplace_back() { checkAllocated(size()+1); ++size_; return end_++; }
41  void pop_back() { assert(size()); --end_; end_->~T(); --size_; }
42  void resize(size_type i,const T &t=T()) {
43  if (size()==i) return;
44  if (size()>i) {
45  T *e = end_;
46  end_ = begin_ + i;
47  for (T *p=e-1;p>=end_;--p)
48  p->~T();
49  size_ = i;
50  return;
51  }
52  auto s = size();
53  checkAllocated(i);
54  end_ = begin_ + i;
55  size_ = i;
56  for (T *p=begin_+s;p<end_;++p)
57  new(p) T(t);
58  }
59  size_type removeReplaceLast(size_type i) {
60  if (i>=size()) return -1;
61  auto last = end_-1;
62  iterator it = &begin_[i];
63  (*it) = *last;
64  pop_back();
65  return size();
66  }
67  size_type removeReplaceLastClip(size_type i) {
68  if (i>=size()) return -1;
69  auto last = end_-1;
70  iterator it = &begin_[i];
71  (*it) = *last;
72  pop_back();
73  clip();
74  return size();
75  }
76 
77  bool remove(size_type i) {
78  if (i>=size()) return false;
79  for (iterator it=begin_+i;it<end_;++it)
80  *it = *(it+1);
81  pop_back();
82  return true;
83  }
84 
85  size_type removeAll(const T &t) {
86  size_type ret = 0;
87  for (size_type i=0;i<size();) {
88  if (t==at(i)) {
89  remove(i);
90  ++ret;
91  } else
92  ++i;
93  }
94  return ret;
95  }
96 
97  void clear() {
98  if (!std::is_pod<T>::value)
99  for (T *b=begin_;b<end_;++b)
100  b->~T();
101  end_ = begin_;
102  size_ = 0;
103  }
104 
105  void reset() {
106  clear();
107  if (defaultStorage_ != allocated_) {
108  if (begin_)
109  std::free(begin_);
110  end_ = begin_ = 0;
111  allocated_ = 0;
112  if (defaultStorage_)
113  changeAllocated(defaultStorage_);
114  }
115  }
116 
117  void clip() { if (size()*multFac_<allocated_) changeAllocated(size()*multFac_); }
118  iterator begin() { return begin_; }
119  const_iterator begin() const { return begin_; }
120  const_iterator constBegin() const { return begin_; }
121  iterator end() { return end_; }
122  const_iterator end() const { return end_; }
123  const_iterator constEnd() const { return end_; }
124  T & at(size_type i) { return begin_[i]; }
125  const T & at(size_type i) const { return begin_[i]; }
126  T & operator[](size_type i) { return at(i); }
127  const T & operator[](size_type i) const { return at(i); }
128 private:
129  void checkAllocated(size_type target) {
130  if (target<=allocated_) return;
131  // How many should be allocated?
132  size_type oldSize = std::max<size_type>(allocated_,defaultStorage_);
133  size_type newsize = multFac_*std::max<size_type>(target,oldSize);
134  changeAllocated(newsize);
135  }
136  void changeAllocated(size_type newSize) {
137  size_type old_size = size();
138  assert(old_size<=newSize);
139  T *newBegin = 0;
140  if (newSize)
141 #ifdef _DEBUG
142  newBegin = reinterpret_cast<T *>(itasca::memory::imalloc(newSize*sizeof(T),__FILE__,__LINE__));
143 #else
144  newBegin = reinterpret_cast<T *>(std::malloc(newSize*sizeof(T)));
145 #endif
146  T *tl = newBegin;
147  for (T *tr=begin_;tr<end_;++tl,++tr) {
148  new(tl) T(*tr);
149  tr->~T();
150  }
151  std::free(begin_);
152  begin_ = newBegin;
153  end_ = begin_ + old_size;
154  allocated_ = newSize;
155  }
156  T * begin_ = 0;
157  T * end_= 0;
158  size_type allocated_ = 0;
159  size_type size_ = 0;
160  size_type defaultStorage_ = 1000;
161  double multFac_ = 1.3;
162 };
163 
164 template <class T> class FlatArrayVec : public std::vector<T> {
165 public:
166  typedef quint64 size_type;
167  FlatArrayVec() { }
168  FlatArrayVec(size_type s,double =1.3) : defaultStorage_(s) { this->reserve(defaultStorage_); }
169  FlatArrayVec(const FlatArrayVec<T> &f) { operator=(f); }
170  FlatArrayVec(std::initializer_list<T> l) {
171  for (auto it=l.begin();it!=l.end();++it)
172  push_back(*it);
173  }
174  ~FlatArrayVec() { defaultStorage_=0; reset(); }
175  const FlatArrayVec<T> &operator=(const FlatArrayVec<T> &f) {
176  defaultStorage_ = f.defaultStorage_;
177  this->clear();
178  reserve(f.capacity());
179  assign(f.begin(),f.end());
180  return *this;
181  }
182  const size_type &allocated() const { return this->capacity(); }
183  size_type removeReplaceLast(size_type i) {
184  if (i>=this->size()) return -1;
185  std::swap(this->at(i),this->back());
186  this->pop_back();
187  return this->size();
188  }
189  size_type removeReplaceLastClip(size_type i) {
190  size_type ret = removeReplaceLast(i);
191  this->shrink_to_fit();
192  return ret;
193  }
194 
195  bool remove(size_type i) {
196  if (i>=this->size()) return false;
197  this->erase(i);
198  return true;
199  }
200  size_type removeAll(const T &t) {
201  size_type ret = 0;
202  for (size_type i=0;i<this->size();) {
203  if (t==this->at(i)) {
204  remove(i);
205  ++ret;
206  } else
207  ++i;
208  }
209  return ret;
210  }
211  void reset() {
212  this->clear();
213  if (defaultStorage_ != this->capacity()) {
214  this->resize(defaultStorage_);
215  this->shrink_to_fit();
216  this->clear();
217  }
218  }
219  void clip() { this->shrink_to_fit(); }
220 private:
221  size_type defaultStorage_ = 1000;
222 };
223 // EoF
Definition: flatarray.h:164
T * iterator
Typedef to assist in STL compatibility.
Definition: flatarray.h:6
FlatArray()
Default constructor - the array size is zero.
Definition: flatarray.h:10
Definition: flatarray.h:3
quint64 size_type
Typedef to assist in STL compatibility.
Definition: flatarray.h:5
const T * const_iterator
Typedef to assist in STL compatibility.
Definition: flatarray.h:7