34void Swap(Array<T> &, Array<T> &);
57 static_assert(std::is_trivial<T>::value,
"type T must be trivial");
70 explicit inline Array(
int asize)
71 :
size(asize) { asize > 0 ?
data.New(asize) :
data.Reset(); }
75 :
size(asize) { asize > 0 ?
data.New(asize, mt) :
data.Reset(mt); }
83 inline Array(T *data_,
int asize,
bool own_data =
false)
84 {
data.Wrap(data_, asize, own_data);
size = asize; }
91 template <
typename CT>
95 template <
typename CT,
int N>
96 explicit inline Array(
const CT (&values)[N]);
108 template <
typename CT>
112 inline operator T *() {
return data; }
115 inline operator const T *()
const {
return data; }
150 inline void SetSize(
int nsize,
const T &initval);
175 inline int Append(
const T *els,
int nels);
193 inline int Find(
const T &el)
const;
214 inline void MakeRef(T *data_,
int size_,
bool own_data =
false);
237 void Save(std::ostream &
out,
int fmt = 0)
const;
245 void Load(std::istream &in,
int fmt = 0);
249 void Load(
int new_size, std::istream &in)
264 template<
class Compare>
291 template <
typename U>
297 template <
typename U>
317 const T *
Read(
bool on_dev =
true)
const
344 if ( LHS.
Size() != RHS.
Size() ) {
return false; }
345 for (
int i=0; i<LHS.
Size(); i++)
347 if ( LHS[i] != RHS[i] ) {
return false; }
355 return !( LHS == RHS );
360template <
typename T>
const T &
AsConst(
const T &
a) {
return a; }
367void Swap(Array2D<T> &, Array2D<T> &);
381 Array2D(
int m,
int n) : array1d(m*n) { M = m; N = n; }
399 const T *
GetRow(
int i)
const {
return (*
this)[i]; }
415 void Save(std::ostream &os,
int fmt = 0)
const
427 void Load(std::istream &in,
int fmt = 0)
429 if (fmt == 0) { in >> M >> N; array1d.
SetSize(M*N); }
434 void Load(
const char *filename,
int fmt = 0);
438 void Load(
int new_size0,
int new_size1, std::istream &in)
442 { copy.M = M; copy.N = N; array1d.
Copy(copy.array1d); }
451 { M = master.M; N = master.N; array1d.
MakeRef(master.array1d); }
471 : array1d(n1*n2*n3) { N2 = n2; N3 = n3; }
474 { array1d.
SetSize(n1*n2*n3); N2 = n2; N3 = n3; }
533 template <
typename cA,
typename cT>
560 MFEM_ASSERT(!
stop,
"invalid use");
572 MFEM_ASSERT(
b_end_idx == array->size,
"invalid use");
630 "Out of bounds access: " <<
index <<
", size = " <<
size);
660 data.UseDevice(src.
data.UseDevice());
663template <
typename T>
template <
typename CT>
668 for (
int i = 0; i <
size; i++) { (*this)[i] = T(src[i]); }
671template <
typename T>
template <
typename CT,
int N>
674 for (
int i = 0; i <
size; i++) { (*this)[i] = T(values[i]); }
680 const int nsize = std::max(minsize, 2 * data.
Capacity());
682 p.CopyFrom(data, size);
688template <
typename T>
template <
typename CT>
692 for (
int i = 0; i < size; i++) { (*this)[i] = T(src[i]); }
699 MFEM_ASSERT( nsize>=0,
"Size must be non-negative. It is " << nsize );
700 if (nsize > Capacity())
710 MFEM_ASSERT( nsize>=0,
"Size must be non-negative. It is " << nsize );
713 if (nsize > Capacity())
717 for (
int i = size; i < nsize; i++)
728 MFEM_ASSERT(nsize >= 0,
"invalid new size: " << nsize);
731 if (nsize <= Capacity())
755 MFEM_ASSERT( i>=0 && i<size,
756 "Access element " << i <<
" of array, size = " << size );
763 MFEM_ASSERT( i>=0 && i<size,
764 "Access element " << i <<
" of array, size = " << size );
779 const int old_size = size;
781 SetSize(size + nels);
782 for (
int i = 0; i < nels; i++)
784 data[old_size+i] = els[i];
793 for (
int i = size-1; i > 0; i--)
804 MFEM_ASSERT(size > 0,
"Array size is zero: " << size);
811 MFEM_ASSERT(size > 0,
"Array size is zero: " << size);
819 while ((i < size) && (data[i] != el)) { i++; }
830 for (
int i = 0; i < size; i++)
832 if (data[i] == el) {
return i; }
840 const T *begin = data, *end = begin + size;
841 const T* first = std::lower_bound(begin, end, el);
842 if (first == end || !(*first == el)) {
return -1; }
843 return first - begin;
849 for (
int i = 0; i < size; i++)
853 for (i++; i < size; i++)
885 data.
Wrap(data_, size_, own_data);
893 data.
Wrap(data_, size_, mt, own_data);
909 for (
int i = 0; i < sa_size; i++)
911 sa[i] = (*this)[offset+i];
918 for (
int i = 0; i < size; i++)
934 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
935 "Array2D: invalid access of element (" << i <<
',' << j
936 <<
") in array of size (" << array1d.Size()/N <<
',' << N
938 return array1d[i*N+j];
944 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
945 "Array2D: invalid access of element (" << i <<
',' << j
946 <<
") in array of size (" << array1d.Size()/N <<
',' << N
948 return array1d[i*N+j];
954 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
955 "Array2D: invalid access of row " << i <<
" in array with "
956 << array1d.Size()/N <<
" rows.");
957 return &array1d[i*N];
963 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
964 "Array2D: invalid access of row " << i <<
" in array with "
965 << array1d.Size()/N <<
" rows.");
966 return &array1d[i*N];
973 Swap(
a.array1d,
b.array1d);
981 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
983 "Array3D: invalid access of element ("
984 << i <<
',' << j <<
',' << k <<
") in array of size ("
985 << array1d.Size() / N2 / N3 <<
',' << N2 <<
',' << N3 <<
").");
986 return array1d[(i*N2+j)*N3+k];
992 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
994 "Array3D: invalid access of element ("
995 << i <<
',' << j <<
',' << k <<
") in array of size ("
996 << array1d.Size() / N2 / N3 <<
',' << N2 <<
',' << N3 <<
").");
997 return array1d[(i*N2+j)*N3+k];
1004 mask = block_size-1;
1005 MFEM_VERIFY(!(block_size & mask),
"block_size must be a power of two.");
1008 while ((1 << shift) < block_size) { shift++; }
1017 shift = other.
shift;
1021 for (
int i = 0; i < blocks.Size(); i++)
1023 blocks[i] = (T*)
new char[bsize *
sizeof(T)];
1027 for (
int i = 0; i < size; i++)
1029 new (&At(i)) T(other[i]);
1037 if (size >= blocks.Size() * bsize)
1039 T* new_block = (T*)
new char[bsize *
sizeof(T)];
1040 blocks.Append(new_block);
1048 int index = Alloc();
1049 new (&At(
index)) T();
1056 int index = Alloc();
1057 new (&At(
index)) T(item);
1065 std::swap(size, other.
size);
1066 std::swap(shift, other.
shift);
1067 std::swap(mask, other.
mask);
1073 return (mask+1)*
sizeof(T)*blocks.Size() + blocks.MemoryUsage();
1079 int bsize = size & mask;
1080 for (
int i = blocks.Size(); i != 0; )
1082 T *block = blocks[--i];
1083 for (
int j = bsize; j != 0; )
1087 delete [] (
char*) block;
Dynamic 2D array using row-major layout.
void DeleteAll()
Delete all dynamically allocated memory, resetting all dimensions to zero.
const T * operator[](int i) const
friend void Swap(Array2D< T > &, Array2D< T > &)
void Copy(Array2D ©) const
Array2D(const Array2D &)=default
void Save(std::ostream &os, int fmt=0) const
Save the Array2D to the stream out using the format fmt. The format fmt can be:
const T & operator()(int i, int j) const
const T * GetRow(int i) const
void Load(std::istream &in, int fmt=0)
Read an Array2D from the stream in using format fmt. The format fmt can be:
T & operator()(int i, int j)
void Print(std::ostream &out=mfem::out, int width=4)
Prints array to stream with width elements per row.
void operator=(const T &a)
void GetRow(int i, Array< T > &sa) const
Extract a copy of the i-th row into the Array sa.
const T * operator()(int i) const
Array2D & operator=(const Array2D &a)=default
void MakeRef(const Array2D &master)
Make this Array a reference to 'master'.
void SetSize(int m, int n)
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.
const T & operator()(int i, int j, int k) const
Array3D(int n1, int n2, int n3)
void SetSize(int n1, int n2, int n3)
void operator=(const T &a)
T & operator()(int i, int j, int k)
Memory< T > & GetMemory()
Return a reference to the Memory object used by the Array.
const T & Last() const
Return the last element in the array.
void Sort(Compare cmp)
Sorts the array in ascending order using the supplied comparison function object.
void DeleteFirst(const T &el)
Delete the first entry with value == 'el'.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void Load(std::istream &in, int fmt=0)
Read an Array from the stream in using format fmt. The format fmt can be:
int FindSorted(const T &el) const
Do bisection search for 'el' in a sorted array; return -1 if not found.
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
void MakeRef(const Array &master)
Make this Array a reference to 'master'.
friend void Swap(Array< T > &, Array< T > &)
void GetSubArray(int offset, int sa_size, Array< T > &sa) const
Copy sub array starting from offset out to the provided sa.
int size
Size of the array.
int Union(const T &el)
Append element when it is not yet in the array, return index.
void Sort()
Sorts the array in ascending order. This requires operator< to be defined for T.
T & operator[](int i)
Reference access to the ith element.
void MakeDataOwner() const
Make the Array own the data.
T Sum()
Return the sum of all the array entries using the '+'' operator for class 'T'.
void Assign(const T *)
Copy data from a pointer. 'Size()' elements are copied.
void CopyFrom(const U *src)
Copy from src into this array. Copies enough entries to fill the Capacity size of this array....
Array< T > & operator=(const Array< T > &src)
Assignment operator: deep copy from 'src'.
T * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), on_dev).
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
void StealData(T **p)
Changes the ownership of the data.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Prepend(const T &el)
Prepend an 'el' to the array, resize if necessary.
T Min() const
Find the minimal element in the array, using the comparison operator < for class T.
void LoseData()
NULL-ifies the data.
int Size() const
Return the logical size of the array.
const T * begin() const
STL-like begin. Returns const pointer to the first element of the array.
void PartialSum()
Fill the entries of the array with the cumulative sum of the entries.
Memory< T > data
Pointer to data.
bool UseDevice() const
Return the device flag of the Memory object used by the Array.
const T * end() const
STL-like end. Returns const pointer after the last element of the array.
void operator=(const T &a)
Set all entries of the array to the provided constant.
Array(MemoryType mt)
Creates an empty array with a given MemoryType.
int Append(const T *els, int nels)
Append another array to this array, resize if necessary.
int IsSorted() const
Return 1 if the array is sorted from lowest to highest. Otherwise return 0.
int Append(const Array< T > &els)
Append another array to this array, resize if necessary.
void MakeRef(T *data_, int size_, bool own_data=false)
Make this Array a reference to a pointer.
Array(int asize, MemoryType mt)
Creates array of asize elements with a given MemoryType.
Array(const Array< CT > &src)
Copy constructor (deep copy) from 'src', an Array of convertible type.
void DeleteAll()
Delete the whole array.
T * Write(bool on_dev=true)
Shortcut for mfem::Write(a.GetMemory(), a.Size(), on_dev).
int Find(const T &el) const
Return the first index where 'el' is found; return -1 if not found.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
T * GetData()
Returns the data.
const T * GetData() const
Returns the data.
const Memory< T > & GetMemory() const
Return a reference to the Memory object used by the Array, const version.
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:
void Copy(Array ©) const
Create a copy of the internal array to the provided copy.
Array(Array< T > &&src)
Move constructor ("steals" data from 'src')
Array(const Array &src)
Copy constructor: deep copy from src.
bool OwnsData() const
Return true if the data will be deleted by the Array.
void Unique()
Removes duplicities from a sorted array. This requires operator== to be defined for T.
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
T * HostReadWrite()
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), false).
T * end()
STL-like end. Returns pointer after the last element of the array.
Array()
Creates an empty array.
Array(T *data_, int asize, bool own_data=false)
Creates array using an externally allocated host pointer data_ to asize elements. If own_data is true...
T * begin()
STL-like begin. Returns pointer to the first element of the array.
void Print(std::ostream &out=mfem::out, int width=4) const
Prints array to stream with width elements per row.
const T & operator[](int i) const
Const reference access to the ith element.
Array & operator=(const Array< CT > &src)
Assignment operator (deep copy) from src, an Array of convertible type.
std::size_t MemoryUsage() const
Returns the number of bytes allocated for the array including any reserve.
Array(const CT(&values)[N])
Deep copy from a braced init-list of convertible type.
void MakeRef(T *data_, int size, MemoryType mt, bool own_data)
Make this Array a reference to a pointer.
Array(int asize)
Creates array of asize elements.
void CopyTo(U *dest)
STL-like copyTo dest from begin to end.
void SetSize(int nsize, MemoryType mt)
Resize the array to size nsize using MemoryType mt. Note that unlike the other versions of SetSize(),...
void GrowSize(int minsize)
void DeleteLast()
Delete the last entry of the array.
void SetSize(int nsize, const T &initval)
Same as SetSize(int) plus initialize new entries with 'initval'.
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
T & Last()
Return the last element in the array.
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_iterator(bool stop)
const_iterator(const BlockArray *a)
const_iterator & operator++()
iterator_base< const BlockArray, const T > base
bool operator!=(const const_iterator &other) const
bool operator==(const const_iterator &other) const
bool operator==(const iterator &other) const
bool operator!=(const iterator &other) const
iterator_base< BlockArray, T > base
void DeleteAll()
Destroy all items, set size to zero.
BlockArray(const BlockArray< T > &other)
const T & At(int index) const
int Capacity() const
Return the current capacity of the BlockArray.
std::size_t MemoryUsage() const
const_iterator cend() const
BlockArray & operator=(const BlockArray &)=delete
T & At(int index)
Access item of the array.
const T & operator[](int index) const
void CheckIndex(int index) const
void Swap(BlockArray< T > &other)
int Append()
Allocate and construct a new item in the array, return its index.
const_iterator cbegin() const
T & operator[](int index)
Access item of the array.
int Append(const T &item)
Allocate and copy-construct a new item in the array, return its index.
int Size() const
Return the number of items actually stored.
BlockArray(int block_size=16 *1024)
Class used by MFEM to store pointers to host and/or device memory.
int Capacity() const
Return the size of the allocated memory.
void CopyFromHost(const T *src, int size)
Copy size entries from the host pointer src to *this.
void MakeAlias(const Memory &base, int offset, int size)
Create a memory object that points inside the memory object base.
bool UseDevice() const
Read the internal device flag.
MemoryType GetMemoryType() const
Return a MemoryType that is currently valid. If both the host and the device pointers are currently v...
void Reset()
Reset the memory to be empty, ensuring that Delete() will be a no-op.
void Wrap(T *ptr, int size, bool own)
Wrap an externally allocated host pointer, ptr with the current host memory type returned by MemoryMa...
void Delete()
Delete the owned pointers and reset the Memory object.
void CopyTo(Memory &dest, int size) const
Copy size entries from *this to dest.
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
int index(int i, int j, int nx, int ny)
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's DeviceMemoryClass, if on_dev = true,...
void Swap(Array< T > &, Array< T > &)
T * Write(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for write access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true,...
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
bool operator!=(const Array< T > &LHS, const Array< T > &RHS)
T * ReadWrite(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read+write access to mem with the mfem::Device's DeviceMemoryClass,...
bool operator==(const Array< T > &LHS, const Array< T > &RHS)
const T & AsConst(const T &a)
Utility function similar to std::as_const in c++17.
MemoryType
Memory types supported by MFEM.
real_t p(const Vector &x, real_t t)