Aleph-w  1.5a.2
Biblioteca general de algoritmos y estructuras de datos
 Todo Clases Archivos Funciones Variables 'typedefs' Enumeraciones Amigas Grupos Páginas
tpl_memArray.H
1 # ifndef TPL_MEMARRAY_H
2 # define TPL_MEMARRAY_H
3 
4 # include <utility>
5 
6 # include <stdlib.h>
7 # include <math.h>
8 # include <stdexcept>
9 # include <nana.h>
10 
11 # include <ahDry.H>
12 
13 namespace Aleph
14 {
15 
16  template <typename T>
17 class MemArray
18 {
19 protected:
20 
21  T * ptr;
22  size_t dim;
23  size_t n;
24  size_t contract_threshold;
25 
26  void allocate()
27  {
28  ptr = new T [dim];
29  contract_threshold = dim / 4;
30  }
31 
32  // return true if expansion is done
33  bool expand(const size_t first = 0)
34  {
35  if (n < dim)
36  return false;
37 
38  const size_t newsz = dim << 1; // 2*dim
39  T * new_ptr = new T [newsz];
40  for (int i = 0; i < dim; ++i)
41  std::swap(ptr[(i + first) % dim ], new_ptr[i]);
42  delete [] ptr;
43  ptr = new_ptr;
44  dim = newsz;
45  contract_threshold = dim/4;
46 
47  return true;
48  }
49 
50  // return true if contraction is done
51  bool contract(const size_t first = 0)
52  {
53  if (n > contract_threshold)
54  return false;
55 
56  const size_t newsz = dim >> 1; // dim/2
57 
58  T * new_ptr = new T [newsz];
59 
60  for (int i = 0; i < newsz; ++i)
61  std::swap(ptr[(first + i) % dim], new_ptr[i]);
62 
63  for (int i = newsz; i < dim; ++i)
64  ptr[i].~T();
65 
66  delete [] ptr;
67  ptr = new_ptr;
68  dim = newsz;
69  contract_threshold = dim/4;
70 
71  return true;
72  }
73 
74  // if dim == 2^k returns dim; else next two power 2^k > dim
75  static size_t init_dim(const size_t dim)
76  {
77  if (dim == 0 or ((dim > 0) and (dim & (dim - 1)) == 0))
78  return dim;
79 
80  return 1 << (int) (log2(dim) + 1);
81  }
82 
83 public:
84 
86  const size_t & capacity() const { return dim; }
87 
88  const size_t & size() const { return n; }
89 
90  bool is_empty() const { return n == 0; }
91 
104  MemArray(size_t __dim = 8)
105  : ptr(NULL), dim(init_dim(__dim)), n(0)
106  {
107  allocate();
108  }
109 
110  ~MemArray()
111  {
112  if (ptr != NULL)
113  {
114  delete [] ptr;
115  ptr = NULL;
116  }
117  }
118 
119  void swap(MemArray & a)
120  {
121  std::swap(ptr, a.ptr);
122  std::swap(dim, a.dim);
123  std::swap(n, a.n);
124  std::swap(contract_threshold, a.contract_threshold);
125  }
126 
127  MemArray(const MemArray & a)
128  : ptr(NULL), dim(a.dim), n(a.n)
129  {
130  allocate();
131  for (int i = 0; i < dim; ++i)
132  ptr[i] = a.ptr[i];
133  }
134 
135  MemArray(MemArray && a)
136  : ptr(NULL), dim(0), n(0), contract_threshold(0)
137  {
138  swap(a);
139  }
140 
141  MemArray & operator = (const MemArray & a)
142  {
143  if (this == &a)
144  return *this;
145 
146  T * newptr = new T [a.n]; // allocate new array
147  for (int i = 0; i < a.n; ++i) // copy items to new array
148  newptr[i] = a.ptr[i];
149 
150  delete [] ptr;
151  ptr = newptr;
152  dim = a.dim;
153  n = a.n;
154 
155  return *this;
156  }
157 
158  MemArray & operator = (MemArray && a)
159  {
160  swap(a);
161  return *this;
162  }
163 
164  void empty()
165  {
166  n = 0;
167  if (dim == 1)
168  return;
169 
170  contract();
171  }
172 
174  T & put(const T & item)
175  {
176  expand();
177 
178  T & ret = ptr[n++] = item;
179  return ret;
180  }
181 
182  T & put(T && item)
183  {
184  expand();
185 
186  T & ret = ptr[n++] = std::move(item);
187  return ret;
188  }
189 
190  T & put(const size_t i, const T & item)
191  {
192  if (i >= dim)
193  throw std::range_error("index out of range");
194 
195  return ptr[i] = item;
196  }
197 
198  T & put(const size_t i, T && item)
199  {
200  if (i >= dim)
201  throw std::range_error("index out of range");
202 
203  return ptr[i] = std::move(item);
204  }
205 
207  void putn(const size_t more)
208  {
209  n += more;
210  expand();
211  }
212 
214  T get(int i = 1)
215  {
216  int idx = n - i;
217  if (idx < 0)
218  throw std::underflow_error("Deleted more entries than capacity");
219 
220  n = idx;
221  T ret = std::move(ptr[n]);
222 
223  contract();
224 
225  return ret;
226  }
227 
228  T & last() { return ptr[n - 1]; }
229 
230  T & first() { return ptr[0]; }
231 
232  T & access(const size_t i)
233  {
234  return ptr[i];
235  }
236 
237  const T & last() const { return ptr[n - 1]; }
238 
239  const T & first() const { return ptr[0]; }
240 
241  const T & access(const size_t i) const
242  {
243  return ptr[i];
244  }
245 
247  T & operator [] (const size_t i)
248  {
249  return ptr[i];
250  }
251 
252  const T & operator [] (const size_t i) const
253  {
254  if (i >= n)
255  throw std::range_error("access out of range");
256 
257  return ptr[i];
258  }
259 
260  T & operator () (const size_t i)
261  {
262  I(i < dim);
263  return ptr[i];
264  }
265 
266  const T & operator () (const size_t i) const
267  {
268  I(i < dim);
269  return ptr[i];
270  }
271 
272  template <class Operation>
273  bool traverse(Operation & operation)
274  {
275  for (int i = 0; i < n; i++)
276  if (not operation(ptr[i]))
277  return false;
278 
279  return true;
280  }
281 
282  template <class Operation>
283  bool traverse(Operation & operation) const
284  {
285  return const_cast<MemArray*>(this)->traverse(operation);
286  }
287 
288  template <class Operation>
289  bool traverse(Operation && operation = Operation()) const
290  {
291  return traverse<Operation>(operation);
292  }
293 
294  template <class Operation>
295  bool traverse(Operation && operation = Operation())
296  {
297  return traverse<Operation>(operation);
298  }
299 
300  Functional_Methods(T);
301 };
302 
303 
304 } // end namespace Aleph
305 
306 # endif // TPL_MEMARRAY_H
Definition: tpl_memArray.H:17
const size_t & capacity() const
Retorna la capacidad del arreglo.
Definition: tpl_memArray.H:86
void putn(const size_t more)
inserta entradas para el arreglo.
Definition: tpl_memArray.H:207
T & put(const T &item)
Coloca item al final de arreglo. Se expande si se alcanza el final.
Definition: tpl_memArray.H:174
MemArray(size_t __dim=8)
Definition: tpl_memArray.H:104
T & operator[](const size_t i)
acceso a la i-ésima entrada válida
Definition: tpl_memArray.H:247

Leandro Rabindranath León