MFEM  v3.1
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
array.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 #ifndef MFEM_ARRAY
13 #define MFEM_ARRAY
14 
15 #include "../config/config.hpp"
16 #include "error.hpp"
17 
18 #include <iostream>
19 #include <cstdlib>
20 #include <cstring>
21 #include <algorithm>
22 
23 namespace mfem
24 {
25 
27 class BaseArray
28 {
29 protected:
31  void *data;
33  int size;
35  int allocsize;
38  int inc;
39 
40  BaseArray() { }
42  BaseArray(int asize, int ainc, int elmentsize);
44  ~BaseArray();
48  void GrowSize(int minsize, int elementsize);
49 };
50 
51 template <class T>
52 class Array;
53 
54 template <class T>
55 void Swap(Array<T> &, Array<T> &);
56 
65 template <class T>
66 class Array : public BaseArray
67 {
68 public:
69  friend void Swap<T>(Array<T> &, Array<T> &);
70 
72  explicit inline Array(int asize = 0, int ainc = 0)
73  : BaseArray(asize, ainc, sizeof (T)) { }
74 
78  inline Array(T *_data, int asize, int ainc = 0)
79  { data = _data; size = asize; allocsize = -asize; inc = ainc; }
80 
82  inline ~Array() { }
83 
85  inline operator T *() { return (T *)data; }
86 
88  inline operator const T *() const { return (const T *)data; }
89 
91  inline T *GetData() { return (T *)data; }
93  inline const T *GetData() const { return (T *)data; }
94 
96  inline bool OwnsData() const { return (allocsize > 0); }
97 
99  inline void StealData(T **p)
100  { *p = (T*)data; data = 0; size = allocsize = 0; }
101 
103  inline void LoseData() { data = 0; size = allocsize = 0; }
104 
106  void MakeDataOwner() { allocsize = abs(allocsize); }
107 
109  inline int Size() const { return size; }
110 
112  inline void SetSize(int nsize);
113 
115  inline void SetSize(int nsize, const T &initval);
116 
119  inline int Capacity() const { return abs(allocsize); }
120 
122  inline void Reserve(int capacity)
123  { if (capacity > abs(allocsize)) { GrowSize(capacity, sizeof(T)); } }
124 
126  inline T & operator[](int i);
127 
129  inline const T &operator[](int i) const;
130 
132  inline int Append(const T & el);
133 
135  inline int Append(const Array<T> &els);
136 
138  inline int Prepend(const T &el);
139 
141  inline T &Last();
142  inline const T &Last() const;
143 
145  inline int Union(const T & el);
146 
148  inline int Find(const T &el) const;
149 
151  inline void DeleteLast() { if (size > 0) { size--; } }
152 
154  inline void DeleteFirst(const T &el);
155 
157  inline void DeleteAll();
158 
160  inline void Copy(Array &copy) const
161  {
162  copy.SetSize(Size());
163  memcpy(copy.GetData(), data, Size()*sizeof(T));
164  }
165 
167  inline void MakeRef(T *, int);
168 
170  inline void MakeRef(const Array &master);
171 
172  inline void GetSubArray(int offset, int sa_size, Array<T> &sa);
173 
175  void Print(std::ostream &out = std::cout, int width = 4);
176 
178  void Save(std::ostream &out);
179 
182  T Max() const;
183 
186  T Min() const;
187 
189  void Sort() { std::sort((T*) data, (T*) data + size); }
190 
193  void Unique()
194  {
195  T* end = std::unique((T*) data, (T*) data + size);
196  SetSize(end - (T*) data);
197  }
198 
200  int IsSorted();
201 
203  void PartialSum();
204 
206  T Sum();
207 
208  inline void operator=(const T &a);
209 
211  inline void Assign(const T *);
212 
213  long MemoryUsage() const { return Capacity() * sizeof(T); }
214 
215 private:
219  Array(const Array<T> &);
220 };
221 
222 template <class T>
223 inline bool operator==(const Array<T> &LHS, const Array<T> &RHS)
224 {
225  if ( LHS.Size() != RHS.Size() ) { return false; }
226  for (int i=0; i<LHS.Size(); i++)
227  if ( LHS[i] != RHS[i] ) { return false; }
228  return true;
229 }
230 
231 template <class T>
232 inline bool operator!=(const Array<T> &LHS, const Array<T> &RHS)
233 {
234  return !( LHS == RHS );
235 }
236 
237 template <class T>
238 class Array2D;
239 
240 template <class T>
241 void Swap(Array2D<T> &, Array2D<T> &);
242 
243 template <class T>
244 class Array2D
245 {
246 private:
247  friend void Swap<T>(Array2D<T> &, Array2D<T> &);
248 
249  Array<T> array1d;
250  int N;
251 
252 public:
253  Array2D() { N = 0; }
254  Array2D(int m, int n) : array1d(m*n) { N = n; }
255 
256  void SetSize(int m, int n) { array1d.SetSize(m*n); N = n; }
257 
258  int NumRows() const { return array1d.Size()/N; }
259  int NumCols() const { return N; }
260 
261  inline const T &operator()(int i, int j) const;
262  inline T &operator()(int i, int j);
263 
264  inline const T *operator[](int i) const;
265  inline T *operator[](int i);
266 
267  const T *operator()(int i) const { return (*this)[i]; }
268  T *operator()(int i) { return (*this)[i]; }
269 
270  const T *GetRow(int i) const { return (*this)[i]; }
271  T *GetRow(int i) { return (*this)[i]; }
272 
273  void Copy(Array2D &copy) const
274  { copy.N = N; array1d.Copy(copy.array1d); }
275 
276  inline void operator=(const T &a)
277  { array1d = a; }
278 
280  inline void MakeRef(const Array2D &master)
281  { N = master.N; array1d.MakeRef(master.array1d);}
282 };
283 
284 
285 template <class T>
286 class Array3D
287 {
288 private:
289  Array<T> array1d;
290  int N2, N3;
291 
292 public:
293  Array3D() { N2 = N3 = 0; }
294  Array3D(int n1, int n2, int n3)
295  : array1d(n1*n2*n3) { N2 = n2; N3 = n3; }
296 
297  void SetSize(int n1, int n2, int n3)
298  { array1d.SetSize(n1*n2*n3); N2 = n2; N3 = n3; }
299 
300  inline const T &operator()(int i, int j, int k) const;
301  inline T &operator()(int i, int j, int k);
302 };
303 
304 
305 template <class T>
306 inline void Swap(T &a, T &b)
307 {
308  T c = a;
309  a = b;
310  b = c;
311 }
312 
313 template <class T>
314 inline void Swap(Array<T> &a, Array<T> &b)
315 {
316  Swap(a.data, b.data);
317  Swap(a.size, b.size);
318  Swap(a.allocsize, b.allocsize);
319  Swap(a.inc, b.inc);
320 }
321 
322 template <class T>
323 inline void Array<T>::SetSize(int nsize)
324 {
325  MFEM_ASSERT( nsize>=0, "Size must be non-negative. It is " << nsize );
326  if (nsize > abs(allocsize))
327  {
328  GrowSize(nsize, sizeof(T));
329  }
330  size = nsize;
331 }
332 
333 template <class T>
334 inline void Array<T>::SetSize(int nsize, const T &initval)
335 {
336  MFEM_ASSERT( nsize>=0, "Size must be non-negative. It is " << nsize );
337  if (nsize > size)
338  {
339  if (nsize > abs(allocsize))
340  {
341  GrowSize(nsize, sizeof(T));
342  }
343  for (int i = size; i < nsize; i++)
344  {
345  ((T*)data)[i] = initval;
346  }
347  }
348  size = nsize;
349 }
350 
351 template <class T>
352 inline T &Array<T>::operator[](int i)
353 {
354  MFEM_ASSERT( i>=0 && i<size,
355  "Access element " << i << " of array, size = " << size );
356  return ((T*)data)[i];
357 }
358 
359 template <class T>
360 inline const T &Array<T>::operator[](int i) const
361 {
362  MFEM_ASSERT( i>=0 && i<size,
363  "Access element " << i << " of array, size = " << size );
364  return ((T*)data)[i];
365 }
366 
367 template <class T>
368 inline int Array<T>::Append(const T &el)
369 {
370  SetSize(size+1);
371  ((T*)data)[size-1] = el;
372  return size;
373 }
374 
375 template <class T>
376 inline int Array<T>::Append(const Array<T> & els)
377 {
378  int old_size = size;
379 
380  SetSize(size + els.Size());
381  for (int i = 0; i < els.Size(); i++)
382  {
383  ((T*)data)[old_size+i] = els[i];
384  }
385  return size;
386 }
387 
388 
389 template <class T>
390 inline int Array<T>::Prepend(const T &el)
391 {
392  SetSize(size+1);
393  for (int i = size-1; i > 0; i--)
394  {
395  ((T*)data)[i] = ((T*)data)[i-1];
396  }
397  ((T*)data)[0] = el;
398  return size;
399 }
400 
401 
402 template <class T>
403 inline T &Array<T>::Last()
404 {
405  MFEM_ASSERT(size > 0, "Array size is zero: " << size);
406  return ((T*)data)[size-1];
407 }
408 
409 template <class T>
410 inline const T &Array<T>::Last() const
411 {
412  MFEM_ASSERT(size > 0, "Array size is zero: " << size);
413  return ((T*)data)[size-1];
414 }
415 
416 template <class T>
417 inline int Array<T>::Union(const T &el)
418 {
419  int i = 0;
420  while ((i < size) && (((T*)data)[i] != el)) { i++; }
421  if (i == size)
422  {
423  Append(el);
424  }
425  return i;
426 }
427 
428 template <class T>
429 inline int Array<T>::Find(const T &el) const
430 {
431  for (int i = 0; i < size; i++)
432  if (((T*)data)[i] == el)
433  {
434  return i;
435  }
436  return -1;
437 }
438 
439 template <class T>
440 inline void Array<T>::DeleteFirst(const T &el)
441 {
442  for (int i = 0; i < size; i++)
443  if (((T*)data)[i] == el)
444  {
445  for (i++; i < size; i++)
446  {
447  ((T*)data)[i-1] = ((T*)data)[i];
448  }
449  size--;
450  return;
451  }
452 }
453 
454 template <class T>
455 inline void Array<T>::DeleteAll()
456 {
457  if (allocsize > 0)
458  {
459  delete [] (char*)data;
460  }
461  data = NULL;
462  size = allocsize = 0;
463 }
464 
465 template <class T>
466 inline void Array<T>::MakeRef(T *p, int s)
467 {
468  if (allocsize > 0)
469  {
470  delete [] (char*)data;
471  }
472  data = p;
473  size = s;
474  allocsize = -s;
475 }
476 
477 template <class T>
478 inline void Array<T>::MakeRef(const Array &master)
479 {
480  if (allocsize > 0)
481  {
482  delete [] (char*)data;
483  }
484  data = master.data;
485  size = master.size;
486  allocsize = -abs(master.allocsize);
487  inc = master.inc;
488 }
489 
490 template <class T>
491 inline void Array<T>::GetSubArray(int offset, int sa_size, Array<T> &sa)
492 {
493  sa.SetSize(sa_size);
494  for (int i = 0; i < sa_size; i++)
495  {
496  sa[i] = (*this)[offset+i];
497  }
498 }
499 
500 template <class T>
501 inline void Array<T>::operator=(const T &a)
502 {
503  for (int i = 0; i < size; i++)
504  {
505  ((T*)data)[i] = a;
506  }
507 }
508 
509 template <class T>
510 inline void Array<T>::Assign(const T *p)
511 {
512  memcpy(data, p, Size()*sizeof(T));
513 }
514 
515 
516 template <class T>
517 inline const T &Array2D<T>::operator()(int i, int j) const
518 {
519  MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
520  "Array2D: invalid access of element (" << i << ',' << j
521  << ") in array of size (" << array1d.Size()/N << ',' << N
522  << ")." );
523  return array1d[i*N+j];
524 }
525 
526 template <class T>
527 inline T &Array2D<T>::operator()(int i, int j)
528 {
529  MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
530  "Array2D: invalid access of element (" << i << ',' << j
531  << ") in array of size (" << array1d.Size()/N << ',' << N
532  << ")." );
533  return array1d[i*N+j];
534 }
535 
536 template <class T>
537 inline const T *Array2D<T>::operator[](int i) const
538 {
539  MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
540  "Array2D: invalid access of row " << i << " in array with "
541  << array1d.Size()/N << " rows.");
542  return &array1d[i*N];
543 }
544 
545 template <class T>
546 inline T *Array2D<T>::operator[](int i)
547 {
548  MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
549  "Array2D: invalid access of row " << i << " in array with "
550  << array1d.Size()/N << " rows.");
551  return &array1d[i*N];
552 }
553 
554 
555 template <class T>
556 inline void Swap(Array2D<T> &a, Array2D<T> &b)
557 {
558  Swap(a.array1d, b.array1d);
559  Swap(a.N, b.N);
560 }
561 
562 
563 template <class T>
564 inline const T &Array3D<T>::operator()(int i, int j, int k) const
565 {
566  MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
567  && k >= 0 && k < N3,
568  "Array3D: invalid access of element ("
569  << i << ',' << j << ',' << k << ") in array of size ("
570  << array1d.Size() / N2 / N3 << ',' << N2 << ',' << N3 << ").");
571  return array1d[(i*N2+j)*N3+k];
572 }
573 
574 template <class T>
575 inline T &Array3D<T>::operator()(int i, int j, int k)
576 {
577  MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
578  && k >= 0 && k < N3,
579  "Array3D: invalid access of element ("
580  << i << ',' << j << ',' << k << ") in array of size ("
581  << array1d.Size() / N2 / N3 << ',' << N2 << ',' << N3 << ").");
582  return array1d[(i*N2+j)*N3+k];
583 }
584 
585 }
586 
587 #endif
int Size() const
Logical size of the array.
Definition: array.hpp:109
void Unique()
Definition: array.hpp:193
int NumCols() const
Definition: array.hpp:259
~BaseArray()
Free the allocated memory.
Definition: array.cpp:35
const T * operator()(int i) const
Definition: array.hpp:267
void * data
Pointer to data.
Definition: array.hpp:31
Array(T *_data, int asize, int ainc=0)
Definition: array.hpp:78
T * GetRow(int i)
Definition: array.hpp:271
Base class for array container.
Definition: array.hpp:27
void Copy(Array &copy) const
Create a copy of the current array.
Definition: array.hpp:160
T * GetData()
Returns the data.
Definition: array.hpp:91
T * operator()(int i)
Definition: array.hpp:268
void operator=(const T &a)
Definition: array.hpp:276
void operator=(const T &a)
Definition: array.hpp:501
T Sum()
Sum all entries.
Definition: array.cpp:133
void MakeRef(const Array2D &master)
Make this Array a reference to &#39;master&#39;.
Definition: array.hpp:280
void DeleteFirst(const T &el)
Delete the first &#39;el&#39; entry.
Definition: array.hpp:440
void SetSize(int n1, int n2, int n3)
Definition: array.hpp:297
T Min() const
Definition: array.cpp:105
void DeleteAll()
Delete whole array.
Definition: array.hpp:455
void GrowSize(int minsize, int elementsize)
Definition: array.cpp:43
~Array()
Destructor.
Definition: array.hpp:82
void GetSubArray(int offset, int sa_size, Array< T > &sa)
Definition: array.hpp:491
int size
Size of the array.
Definition: array.hpp:33
void SetSize(int m, int n)
Definition: array.hpp:256
void Copy(Array2D &copy) const
Definition: array.hpp:273
bool OwnsData() const
Return true if the data will be deleted by the array.
Definition: array.hpp:96
const T & operator()(int i, int j) const
Definition: array.hpp:517
const T * GetData() const
Returns the data.
Definition: array.hpp:93
int Append(const T &el)
Append element to array, resize if necessary.
Definition: array.hpp:368
T & operator[](int i)
Access element.
Definition: array.hpp:352
void LoseData()
NULL-ifies the data.
Definition: array.hpp:103
T Max() const
Definition: array.cpp:90
void MakeDataOwner()
Make the Array own the data.
Definition: array.hpp:106
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
Definition: array.hpp:122
bool operator!=(const Array< T > &LHS, const Array< T > &RHS)
Definition: array.hpp:232
void Assign(const T *)
Copy data from a pointer. Size() elements are copied.
Definition: array.hpp:510
long MemoryUsage() const
Definition: array.hpp:213
void Sort()
Sorts the array. This requires operator&lt; to be defined for T.
Definition: array.hpp:189
int allocsize
Size of the allocated memory.
Definition: array.hpp:35
void StealData(T **p)
Changes the ownership of the the data.
Definition: array.hpp:99
int Union(const T &el)
Append element when it is not yet in the array, return index.
Definition: array.hpp:417
void Print(std::ostream &out=std::cout, int width=4)
Prints array to stream with width elements per row.
Definition: array.cpp:63
void Swap(Array< T > &, Array< T > &)
Definition: array.hpp:314
bool operator==(const Array< T > &LHS, const Array< T > &RHS)
Definition: array.hpp:223
int IsSorted()
return true if the array is sorted.
Definition: array.cpp:145
int Find(const T &el) const
Return the first index where &#39;el&#39; is found; return -1 if not found.
Definition: array.hpp:429
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Definition: array.hpp:323
const T * operator[](int i) const
Definition: array.hpp:537
void PartialSum()
Partial Sum.
Definition: array.cpp:121
void Save(std::ostream &out)
Prints array to stream out.
Definition: array.cpp:80
void DeleteLast()
Delete the last entry.
Definition: array.hpp:151
Array2D(int m, int n)
Definition: array.hpp:254
int Capacity() const
Definition: array.hpp:119
T & Last()
Return the last element in the array.
Definition: array.hpp:403
void MakeRef(T *, int)
Make this Array a reference to a pointer.
Definition: array.hpp:466
const T & operator()(int i, int j, int k) const
Definition: array.hpp:564
Array3D(int n1, int n2, int n3)
Definition: array.hpp:294
Array(int asize=0, int ainc=0)
Creates array of asize elements.
Definition: array.hpp:72
const T * GetRow(int i) const
Definition: array.hpp:270
int NumRows() const
Definition: array.hpp:258
int Prepend(const T &el)
Prepend an element to the array, resize if necessary.
Definition: array.hpp:390