15 #include "../config/config.hpp"
58 explicit inline Array(
int asize = 0)
59 :
size(asize) { asize > 0 ?
data.New(asize) :
data.Reset(); }
64 inline Array(T *_data,
int asize)
65 {
data.Wrap(_data, asize,
false);
size = asize; }
72 template <
typename CT>
82 template <
typename CT>
86 inline operator T *() {
return data; }
89 inline operator const T *()
const {
return data; }
121 inline void SetSize(
int nsize);
124 inline void SetSize(
int nsize,
const T &initval);
146 inline int Append(
const T & el);
149 inline int Append(
const T *els,
int nels);
155 inline int Prepend(
const T &el);
159 inline const T &
Last()
const;
162 inline int Union(
const T & el);
165 inline int Find(
const T &el)
const;
199 void Save(std::ostream &
out,
int fmt = 0)
const;
207 void Load(std::istream &in,
int fmt = 0);
211 void Load(
int new_size, std::istream &in)
226 template<
class Compare>
249 inline void Assign(
const T *);
251 template <
typename U>
261 const T *
Read(
bool on_dev =
true)
const
288 if ( LHS.
Size() != RHS.
Size() ) {
return false; }
289 for (
int i=0; i<LHS.
Size(); i++)
291 if ( LHS[i] != RHS[i] ) {
return false; }
299 return !( LHS == RHS );
321 Array2D(
int m,
int n) : array1d(m*n) { M = m; N = n; }
323 void SetSize(
int m,
int n) { array1d.SetSize(m*n); M = m; N = n; }
328 inline const T &
operator()(
int i,
int j)
const;
337 const T *
GetRow(
int i)
const {
return (*
this)[i]; }
353 void Save(std::ostream &
out,
int fmt = 0)
const
356 array1d.Save(out, 1);
365 void Load(std::istream &in,
int fmt = 0)
367 if (fmt == 0) { in >> M >> N; array1d.SetSize(M*N); }
372 void Load(
const char *filename,
int fmt = 0);
376 void Load(
int new_size0,
int new_size1, std::istream &in)
380 { copy.M = M; copy.N = N; array1d.Copy(copy.array1d); }
387 { M = master.M; N = master.N; array1d.MakeRef(master.array1d); }
390 inline void DeleteAll() { M = 0; N = 0; array1d.DeleteAll(); }
407 : array1d(n1*n2*n3) { N2 = n2; N3 = n3; }
410 { array1d.SetSize(n1*n2*n3); N2 = n2; N3 = n3; }
412 inline const T &
operator()(
int i,
int j,
int k)
const;
433 int Append(
const T &item);
436 inline T&
At(
int index)
441 inline const T&
At(
int index)
const
462 template <
typename cA,
typename cT>
483 b_end_idx = std::min(a->size, a->mask+1);
489 MFEM_ASSERT(!
stop,
"invalid use");
492 if (b_end_idx < array->
size)
496 b_end_idx = std::min(
array->size, (b_end_idx|
array->mask) + 1);
543 iterator
begin() {
return size ? iterator(
this) : iterator(
true); }
544 iterator
end() {
return iterator(); }
547 {
return size ? const_iterator(
this) : const_iterator(
true); }
548 const_iterator
cend()
const {
return const_iterator(); }
558 MFEM_ASSERT(index >= 0 && index <
size,
559 "Out of bounds access: " << index <<
", size = " <<
size);
587 data.UseDevice(src.
data.UseDevice());
590 template <
typename T>
template <
typename CT>
595 for (
int i = 0; i <
size; i++) { (*this)[i] = T(src[i]); }
601 const int nsize = std::max(minsize, 2 * data.Capacity());
602 Memory<T> p(nsize, data.GetMemoryType());
604 p.UseDevice(data.UseDevice());
609 template <
typename T>
template <
typename CT>
613 for (
int i = 0; i < size; i++) { (*this)[i] = T(src[i]); }
620 MFEM_ASSERT( nsize>=0,
"Size must be non-negative. It is " << nsize );
621 if (nsize > Capacity())
631 MFEM_ASSERT( nsize>=0,
"Size must be non-negative. It is " << nsize );
634 if (nsize > Capacity())
638 for (
int i = size; i < nsize; i++)
649 MFEM_ASSERT(nsize >= 0,
"invalid new size: " << nsize);
650 if (mt == data.GetMemoryType())
652 if (nsize <= Capacity())
658 const bool use_dev = data.UseDevice();
670 data.UseDevice(use_dev);
676 MFEM_ASSERT( i>=0 && i<size,
677 "Access element " << i <<
" of array, size = " << size );
684 MFEM_ASSERT( i>=0 && i<size,
685 "Access element " << i <<
" of array, size = " << size );
700 const int old_size = size;
702 SetSize(size + nels);
703 for (
int i = 0; i < nels; i++)
705 data[old_size+i] = els[i];
714 for (
int i = size-1; i > 0; i--)
725 MFEM_ASSERT(size > 0,
"Array size is zero: " << size);
732 MFEM_ASSERT(size > 0,
"Array size is zero: " << size);
740 while ((i < size) && (data[i] != el)) { i++; }
751 for (
int i = 0; i < size; i++)
753 if (data[i] == el) {
return i; }
761 const T *begin = data, *end = begin + size;
762 const T* first = std::lower_bound(begin, end, el);
763 if (first == end || !(*first == el)) {
return -1; }
764 return first - begin;
770 for (
int i = 0; i < size; i++)
774 for (i++; i < size; i++)
787 const bool use_dev = data.UseDevice();
791 data.UseDevice(use_dev);
794 template <
typename T>
797 copy.
SetSize(Size(), data.GetMemoryType());
798 data.CopyTo(copy.
data, Size());
799 copy.
data.UseDevice(data.UseDevice());
806 data.Wrap(p, s,
false);
816 data.ClearOwnerFlags();
823 for (
int i = 0; i < sa_size; i++)
825 sa[i] = (*this)[offset+i];
832 for (
int i = 0; i < size; i++)
841 data.CopyFromHost(p, Size());
848 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
849 "Array2D: invalid access of element (" << i <<
',' << j
850 <<
") in array of size (" << array1d.Size()/N <<
',' << N
852 return array1d[i*N+j];
858 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
859 "Array2D: invalid access of element (" << i <<
',' << j
860 <<
") in array of size (" << array1d.Size()/N <<
',' << N
862 return array1d[i*N+j];
868 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
869 "Array2D: invalid access of row " << i <<
" in array with "
870 << array1d.Size()/N <<
" rows.");
871 return &array1d[i*N];
877 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
878 "Array2D: invalid access of row " << i <<
" in array with "
879 << array1d.Size()/N <<
" rows.");
880 return &array1d[i*N];
887 Swap(a.array1d, b.array1d);
895 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
897 "Array3D: invalid access of element ("
898 << i <<
',' << j <<
',' << k <<
") in array of size ("
899 << array1d.Size() / N2 / N3 <<
',' << N2 <<
',' << N3 <<
").");
900 return array1d[(i*N2+j)*N3+k];
906 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
908 "Array3D: invalid access of element ("
909 << i <<
',' << j <<
',' << k <<
") in array of size ("
910 << array1d.Size() / N2 / N3 <<
',' << N2 <<
',' << N3 <<
").");
911 return array1d[(i*N2+j)*N3+k];
919 MFEM_VERIFY(!(block_size & mask),
"block_size must be a power of two.");
922 while ((1 << shift) < block_size) { shift++; }
935 for (
int i = 0; i < blocks.Size(); i++)
937 blocks[i] = (T*)
new char[bsize *
sizeof(T)];
941 for (
int i = 0; i < size; i++)
943 new (&At(i)) T(other[i]);
951 if (size >= blocks.Size() * bsize)
953 T* new_block = (T*)
new char[bsize *
sizeof(T)];
954 blocks.Append(new_block);
963 new (&At(index)) T();
971 new (&At(index)) T(item);
979 std::swap(size, other.
size);
980 std::swap(shift, other.
shift);
981 std::swap(mask, other.
mask);
987 return blocks.Size()*(mask+1)*
sizeof(T) +
988 blocks.MemoryUsage();
994 int bsize = size & mask;
995 for (
int i = blocks.Size(); i != 0; )
997 T *block = blocks[--i];
998 for (
int j = bsize; j != 0; )
1002 delete [] (
char*) block;
T * HostReadWrite()
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), false).
int Size() const
Logical size of the array.
const_iterator(const BlockArray *a)
void Load(std::istream &in, int fmt=0)
Read an Array from the stream in using format fmt. The format fmt can be:
Array(T *_data, int asize)
Memory< T > & GetMemory()
Return a reference to the Memory object used by the Array.
const_iterator cbegin() const
iterator_base< const BlockArray, const T > base
const T * operator()(int i) const
int Capacity() const
Return the current capacity of the BlockArray.
void Load(std::istream &in, int fmt=0)
Read an Array2D from the stream in using format fmt. The format fmt can be:
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
int size
Size of the array.
int Size() const
Return the number of items actually stored.
void Save(std::ostream &out, int fmt=0) const
Save the Array2D to the stream out using the format fmt. The format fmt can be:
void Copy(Array ©) const
Create a copy of the current array.
T * GetData()
Returns the data.
T * Write(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for write access to mem with the mfem::Device MemoryClass, if on_dev = true...
void operator=(const T &a)
void Save(std::ostream &out, int fmt=0) const
Save the Array to the stream out using the format fmt. The format fmt can be:
bool UseDevice() const
Return the device flag of the Memory object used by the Array.
void Sort(Compare cmp)
Sorts the array using the supplied comparison function object.
bool operator==(const iterator &other) const
void MakeRef(const Array2D &master)
Make this Array a reference to 'master'.
void CopyFrom(const Memory &src, int size)
Copy size entries from src to *this.
void Load(int new_size, std::istream &in)
Set the Array size to new_size and read that many entries from the stream in.
const T & At(int index) const
Array(int asize=0)
Creates array of asize elements.
bool operator==(const const_iterator &other) const
void DeleteFirst(const T &el)
Delete the first 'el' entry.
T & operator[](int index)
Access item of the array.
void SetSize(int n1, int n2, int n3)
T Min() const
Find the minimal element in the array, using the comparison operator < for class T.
void DeleteAll()
Delete whole array.
int Append(const Array< T > &els)
Append another array to this array, resize if necessary.
void SetSize(int m, int n)
void Copy(Array2D ©) const
bool OwnsData() const
Return true if the data will be deleted by the array.
const T & operator()(int i, int j) const
const T * GetData() const
Returns the data.
int Append(const T &el)
Append element to array, resize if necessary.
void GetSubArray(int offset, int sa_size, Array< T > &sa) const
T & operator[](int i)
Access element.
void LoseData()
NULL-ifies the data.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
bool operator!=(const Array< T > &LHS, const Array< T > &RHS)
void Assign(const T *)
Copy data from a pointer. Size() elements are copied.
void Sort()
Sorts the array. This requires operator< to be defined for T.
int FindSorted(const T &el) const
Do bisection search for 'el' in a sorted array; return -1 if not found.
void StealData(T **p)
Changes the ownership of the data.
const T * Read(const Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read access to mem with the mfem::Device MemoryClass, if on_dev = true...
int Union(const T &el)
Append element when it is not yet in the array, return index.
Dynamic 2D array using row-major layout.
Memory< T > data
Pointer to data.
void Print(std::ostream &out=mfem::out, int width=4)
Prints array to stream with width elements per row.
void Swap(Array< T > &, Array< T > &)
bool operator==(const Array< T > &LHS, const Array< T > &RHS)
void GrowSize(int minsize)
int IsSorted()
return true if the array is sorted.
BlockArray(int block_size=16 *1024)
MemoryType
Memory types supported by MFEM.
int Find(const T &el) const
Return the first index where 'el' is found; return -1 if not found.
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
const T * operator[](int i) const
void PartialSum()
Partial Sum.
T * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), on_dev).
void DeleteLast()
Delete the last entry.
const T & operator[](int index) const
void MakeDataOwner() const
Make the Array own the data.
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
bool operator!=(const iterator &other) const
const_iterator(bool stop)
void CheckIndex(int index) const
T * ReadWrite(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read+write access to mem with the mfem::Device MemoryClass, if on_dev = true...
bool operator!=(const const_iterator &other) const
Class used by MFEM to store pointers to host and/or device memory.
const_iterator & operator++()
T & Last()
Return the last element in the array.
void Print(std::ostream &out=mfem::out, int width=4) const
Prints array to stream with width elements per row.
iterator_base< BlockArray, T > base
T * Write(bool on_dev=true)
Shortcut for mfem::Write(a.GetMemory(), a.Size(), on_dev).
void MakeRef(T *, int)
Make this Array a reference to a pointer.
Array< T > & operator=(const Array< T > &src)
Assignment operator: deep copy.
const_iterator cend() const
const Memory< T > & GetMemory() const
Return a reference to the Memory object used by the Array, const version.
void DeleteAll()
Delete all dynamically allocated memory, reseting all dimentions to zero.
const T & operator()(int i, int j, int k) const
Array3D(int n1, int n2, int n3)
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
T & At(int index)
Access item of the array.
const T * GetRow(int i) const
int Prepend(const T &el)
Prepend an element to the array, resize if necessary.
int Append()
Allocate and construct a new item in the array, return its index.
void Load(int new_size0, int new_size1, std::istream &in)
Set the Array2D dimensions to new_size0 x new_size1 and read that many entries from the stream in...
void Swap(BlockArray< T > &other)
void GetRow(int i, Array< T > &sa) const
Extract a copy of the i-th row into the Array sa.