MFEM  v3.2
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 
192  template<class Compare>
193  void Sort(Compare cmp) { std::sort((T*) data, (T*) data + size, cmp); }
194 
197  void Unique()
198  {
199  T* end = std::unique((T*) data, (T*) data + size);
200  SetSize(end - (T*) data);
201  }
202 
204  int IsSorted();
205 
207  void PartialSum();
208 
210  T Sum();
211 
212  inline void operator=(const T &a);
213 
215  inline void Assign(const T *);
216 
217  // STL-like begin/end
218  inline T* begin() const { return (T*) data; }
219  inline T* end() const { return (T*) data + size; }
220 
221  long MemoryUsage() const { return Capacity() * sizeof(T); }
222 
223 private:
227  Array(const Array<T> &);
228 };
229 
230 template <class T>
231 inline bool operator==(const Array<T> &LHS, const Array<T> &RHS)
232 {
233  if ( LHS.Size() != RHS.Size() ) { return false; }
234  for (int i=0; i<LHS.Size(); i++)
235  if ( LHS[i] != RHS[i] ) { return false; }
236  return true;
237 }
238 
239 template <class T>
240 inline bool operator!=(const Array<T> &LHS, const Array<T> &RHS)
241 {
242  return !( LHS == RHS );
243 }
244 
245 template <class T>
246 class Array2D;
247 
248 template <class T>
249 void Swap(Array2D<T> &, Array2D<T> &);
250 
251 template <class T>
252 class Array2D
253 {
254 private:
255  friend void Swap<T>(Array2D<T> &, Array2D<T> &);
256 
257  Array<T> array1d;
258  int N;
259 
260 public:
261  Array2D() { N = 0; }
262  Array2D(int m, int n) : array1d(m*n) { N = n; }
263 
264  void SetSize(int m, int n) { array1d.SetSize(m*n); N = n; }
265 
266  int NumRows() const { return array1d.Size()/N; }
267  int NumCols() const { return N; }
268 
269  inline const T &operator()(int i, int j) const;
270  inline T &operator()(int i, int j);
271 
272  inline const T *operator[](int i) const;
273  inline T *operator[](int i);
274 
275  const T *operator()(int i) const { return (*this)[i]; }
276  T *operator()(int i) { return (*this)[i]; }
277 
278  const T *GetRow(int i) const { return (*this)[i]; }
279  T *GetRow(int i) { return (*this)[i]; }
280 
281  void Copy(Array2D &copy) const
282  { copy.N = N; array1d.Copy(copy.array1d); }
283 
284  inline void operator=(const T &a)
285  { array1d = a; }
286 
288  inline void MakeRef(const Array2D &master)
289  { N = master.N; array1d.MakeRef(master.array1d);}
290 };
291 
292 
293 template <class T>
294 class Array3D
295 {
296 private:
297  Array<T> array1d;
298  int N2, N3;
299 
300 public:
301  Array3D() { N2 = N3 = 0; }
302  Array3D(int n1, int n2, int n3)
303  : array1d(n1*n2*n3) { N2 = n2; N3 = n3; }
304 
305  void SetSize(int n1, int n2, int n3)
306  { array1d.SetSize(n1*n2*n3); N2 = n2; N3 = n3; }
307 
308  inline const T &operator()(int i, int j, int k) const;
309  inline T &operator()(int i, int j, int k);
310 };
311 
312 
313 template <class T>
314 inline void Swap(T &a, T &b)
315 {
316  T c = a;
317  a = b;
318  b = c;
319 }
320 
321 template <class T>
322 inline void Swap(Array<T> &a, Array<T> &b)
323 {
324  Swap(a.data, b.data);
325  Swap(a.size, b.size);
326  Swap(a.allocsize, b.allocsize);
327  Swap(a.inc, b.inc);
328 }
329 
330 template <class T>
331 inline void Array<T>::SetSize(int nsize)
332 {
333  MFEM_ASSERT( nsize>=0, "Size must be non-negative. It is " << nsize );
334  if (nsize > abs(allocsize))
335  {
336  GrowSize(nsize, sizeof(T));
337  }
338  size = nsize;
339 }
340 
341 template <class T>
342 inline void Array<T>::SetSize(int nsize, const T &initval)
343 {
344  MFEM_ASSERT( nsize>=0, "Size must be non-negative. It is " << nsize );
345  if (nsize > size)
346  {
347  if (nsize > abs(allocsize))
348  {
349  GrowSize(nsize, sizeof(T));
350  }
351  for (int i = size; i < nsize; i++)
352  {
353  ((T*)data)[i] = initval;
354  }
355  }
356  size = nsize;
357 }
358 
359 template <class T>
360 inline T &Array<T>::operator[](int i)
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 const T &Array<T>::operator[](int i) const
369 {
370  MFEM_ASSERT( i>=0 && i<size,
371  "Access element " << i << " of array, size = " << size );
372  return ((T*)data)[i];
373 }
374 
375 template <class T>
376 inline int Array<T>::Append(const T &el)
377 {
378  SetSize(size+1);
379  ((T*)data)[size-1] = el;
380  return size;
381 }
382 
383 template <class T>
384 inline int Array<T>::Append(const Array<T> & els)
385 {
386  int old_size = size;
387 
388  SetSize(size + els.Size());
389  for (int i = 0; i < els.Size(); i++)
390  {
391  ((T*)data)[old_size+i] = els[i];
392  }
393  return size;
394 }
395 
396 
397 template <class T>
398 inline int Array<T>::Prepend(const T &el)
399 {
400  SetSize(size+1);
401  for (int i = size-1; i > 0; i--)
402  {
403  ((T*)data)[i] = ((T*)data)[i-1];
404  }
405  ((T*)data)[0] = el;
406  return size;
407 }
408 
409 
410 template <class T>
411 inline T &Array<T>::Last()
412 {
413  MFEM_ASSERT(size > 0, "Array size is zero: " << size);
414  return ((T*)data)[size-1];
415 }
416 
417 template <class T>
418 inline const T &Array<T>::Last() const
419 {
420  MFEM_ASSERT(size > 0, "Array size is zero: " << size);
421  return ((T*)data)[size-1];
422 }
423 
424 template <class T>
425 inline int Array<T>::Union(const T &el)
426 {
427  int i = 0;
428  while ((i < size) && (((T*)data)[i] != el)) { i++; }
429  if (i == size)
430  {
431  Append(el);
432  }
433  return i;
434 }
435 
436 template <class T>
437 inline int Array<T>::Find(const T &el) const
438 {
439  for (int i = 0; i < size; i++)
440  if (((T*)data)[i] == el)
441  {
442  return i;
443  }
444  return -1;
445 }
446 
447 template <class T>
448 inline void Array<T>::DeleteFirst(const T &el)
449 {
450  for (int i = 0; i < size; i++)
451  if (((T*)data)[i] == el)
452  {
453  for (i++; i < size; i++)
454  {
455  ((T*)data)[i-1] = ((T*)data)[i];
456  }
457  size--;
458  return;
459  }
460 }
461 
462 template <class T>
463 inline void Array<T>::DeleteAll()
464 {
465  if (allocsize > 0)
466  {
467  delete [] (char*)data;
468  }
469  data = NULL;
470  size = allocsize = 0;
471 }
472 
473 template <class T>
474 inline void Array<T>::MakeRef(T *p, int s)
475 {
476  if (allocsize > 0)
477  {
478  delete [] (char*)data;
479  }
480  data = p;
481  size = s;
482  allocsize = -s;
483 }
484 
485 template <class T>
486 inline void Array<T>::MakeRef(const Array &master)
487 {
488  if (allocsize > 0)
489  {
490  delete [] (char*)data;
491  }
492  data = master.data;
493  size = master.size;
494  allocsize = -abs(master.allocsize);
495  inc = master.inc;
496 }
497 
498 template <class T>
499 inline void Array<T>::GetSubArray(int offset, int sa_size, Array<T> &sa)
500 {
501  sa.SetSize(sa_size);
502  for (int i = 0; i < sa_size; i++)
503  {
504  sa[i] = (*this)[offset+i];
505  }
506 }
507 
508 template <class T>
509 inline void Array<T>::operator=(const T &a)
510 {
511  for (int i = 0; i < size; i++)
512  {
513  ((T*)data)[i] = a;
514  }
515 }
516 
517 template <class T>
518 inline void Array<T>::Assign(const T *p)
519 {
520  memcpy(data, p, Size()*sizeof(T));
521 }
522 
523 
524 template <class T>
525 inline const T &Array2D<T>::operator()(int i, int j) const
526 {
527  MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
528  "Array2D: invalid access of element (" << i << ',' << j
529  << ") in array of size (" << array1d.Size()/N << ',' << N
530  << ")." );
531  return array1d[i*N+j];
532 }
533 
534 template <class T>
535 inline T &Array2D<T>::operator()(int i, int j)
536 {
537  MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
538  "Array2D: invalid access of element (" << i << ',' << j
539  << ") in array of size (" << array1d.Size()/N << ',' << N
540  << ")." );
541  return array1d[i*N+j];
542 }
543 
544 template <class T>
545 inline const T *Array2D<T>::operator[](int i) const
546 {
547  MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
548  "Array2D: invalid access of row " << i << " in array with "
549  << array1d.Size()/N << " rows.");
550  return &array1d[i*N];
551 }
552 
553 template <class T>
554 inline T *Array2D<T>::operator[](int i)
555 {
556  MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
557  "Array2D: invalid access of row " << i << " in array with "
558  << array1d.Size()/N << " rows.");
559  return &array1d[i*N];
560 }
561 
562 
563 template <class T>
564 inline void Swap(Array2D<T> &a, Array2D<T> &b)
565 {
566  Swap(a.array1d, b.array1d);
567  Swap(a.N, b.N);
568 }
569 
570 
571 template <class T>
572 inline const T &Array3D<T>::operator()(int i, int j, int k) const
573 {
574  MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
575  && k >= 0 && k < N3,
576  "Array3D: invalid access of element ("
577  << i << ',' << j << ',' << k << ") in array of size ("
578  << array1d.Size() / N2 / N3 << ',' << N2 << ',' << N3 << ").");
579  return array1d[(i*N2+j)*N3+k];
580 }
581 
582 template <class T>
583 inline T &Array3D<T>::operator()(int i, int j, int k)
584 {
585  MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
586  && k >= 0 && k < N3,
587  "Array3D: invalid access of element ("
588  << i << ',' << j << ',' << k << ") in array of size ("
589  << array1d.Size() / N2 / N3 << ',' << N2 << ',' << N3 << ").");
590  return array1d[(i*N2+j)*N3+k];
591 }
592 
593 }
594 
595 #endif
int Size() const
Logical size of the array.
Definition: array.hpp:109
void Unique()
Definition: array.hpp:197
int NumCols() const
Definition: array.hpp:267
~BaseArray()
Free the allocated memory.
Definition: array.cpp:35
const T * operator()(int i) const
Definition: array.hpp:275
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:279
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:276
void operator=(const T &a)
Definition: array.hpp:284
void Sort(Compare cmp)
Sorts the array using the supplied comparison function object.
Definition: array.hpp:193
void operator=(const T &a)
Definition: array.hpp:509
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:288
T * end() const
Definition: array.hpp:219
T * begin() const
Definition: array.hpp:218
void DeleteFirst(const T &el)
Delete the first &#39;el&#39; entry.
Definition: array.hpp:448
void SetSize(int n1, int n2, int n3)
Definition: array.hpp:305
T Min() const
Definition: array.cpp:105
void DeleteAll()
Delete whole array.
Definition: array.hpp:463
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:499
int size
Size of the array.
Definition: array.hpp:33
void SetSize(int m, int n)
Definition: array.hpp:264
void Copy(Array2D &copy) const
Definition: array.hpp:281
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:525
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:376
T & operator[](int i)
Access element.
Definition: array.hpp:360
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:240
void Assign(const T *)
Copy data from a pointer. Size() elements are copied.
Definition: array.hpp:518
long MemoryUsage() const
Definition: array.hpp:221
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 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:425
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:322
bool operator==(const Array< T > &LHS, const Array< T > &RHS)
Definition: array.hpp:231
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:437
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Definition: array.hpp:331
const T * operator[](int i) const
Definition: array.hpp:545
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:262
int Capacity() const
Definition: array.hpp:119
T & Last()
Return the last element in the array.
Definition: array.hpp:411
void MakeRef(T *, int)
Make this Array a reference to a pointer.
Definition: array.hpp:474
const T & operator()(int i, int j, int k) const
Definition: array.hpp:572
Array3D(int n1, int n2, int n3)
Definition: array.hpp:302
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:278
int NumRows() const
Definition: array.hpp:266
int Prepend(const T &el)
Prepend an element to the array, resize if necessary.
Definition: array.hpp:398