15 #include "../config/config.hpp" 25 #include <type_traits> 34 void 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); }
80 inline Array(T *data_,
int asize)
81 {
data.Wrap(data_, asize,
false);
size = asize; }
88 template <
typename CT>
92 template <
typename CT,
int N>
93 explicit inline Array(
const CT (&values)[N]);
105 template <
typename CT>
109 inline operator T *() {
return data; }
112 inline operator const T *()
const {
return data; }
144 inline void SetSize(
int nsize);
147 inline void SetSize(
int nsize,
const T &initval);
169 inline int Append(
const T & el);
172 inline int Append(
const T *els,
int nels);
178 inline int Prepend(
const T &el);
184 inline const T &
Last()
const;
187 inline int Union(
const T & el);
190 inline int Find(
const T &el)
const;
227 void Save(std::ostream &
out,
int fmt = 0)
const;
235 void Load(std::istream &in,
int fmt = 0);
239 void Load(
int new_size, std::istream &in)
254 template<
class Compare>
278 inline void Assign(
const T *);
281 template <
typename U>
287 template <
typename U>
307 const T *
Read(
bool on_dev =
true)
const 334 if ( LHS.Size() != RHS.Size() ) {
return false; }
335 for (
int i=0; i<LHS.Size(); i++)
337 if ( LHS[i] != RHS[i] ) {
return false; }
345 return !( LHS == RHS );
350 template <
typename T>
const T &
AsConst(
const T &
a) {
return a; }
371 Array2D(
int m,
int n) : array1d(m*n) { M = m; N = n; }
375 void SetSize(
int m,
int n) { array1d.SetSize(m*n); M = m; N = n; }
380 inline const T &
operator()(
int i,
int j)
const;
389 const T *
GetRow(
int i)
const {
return (*
this)[i]; }
405 void Save(std::ostream &os,
int fmt = 0)
const 417 void Load(std::istream &in,
int fmt = 0)
419 if (fmt == 0) { in >> M >> N; array1d.SetSize(M*N); }
424 void Load(
const char *filename,
int fmt = 0);
428 void Load(
int new_size0,
int new_size1, std::istream &in)
432 { copy.M = M; copy.N = N; array1d.Copy(copy.array1d); }
441 { M = master.M; N = master.N; array1d.MakeRef(master.array1d); }
444 inline void DeleteAll() { M = 0; N = 0; array1d.DeleteAll(); }
461 : array1d(n1*n2*n3) { N2 = n2; N3 = n3; }
464 { array1d.SetSize(n1*n2*n3); N2 = n2; N3 = n3; }
466 inline const T &
operator()(
int i,
int j,
int k)
const;
488 int Append(
const T &item);
520 template <
typename cA,
typename cT>
547 MFEM_ASSERT(!
stop,
"invalid use");
550 if (b_end_idx < array->
size)
601 iterator
begin() {
return size ? iterator(
this) : iterator(
true); }
602 iterator
end() {
return iterator(); }
605 {
return size ? const_iterator(
this) : const_iterator(
true); }
606 const_iterator
cend()
const {
return const_iterator(); }
617 "Out of bounds access: " <<
index <<
", size = " <<
size);
645 size > 0 ? data.
New(size, src.data.GetMemoryType()) : data.
Reset();
650 template <
typename T>
template <
typename CT>
654 size > 0 ? data.
New(size) : data.
Reset();
655 for (
int i = 0; i < size; i++) { (*this)[i] = T(src[i]); }
658 template <
typename T>
template <
typename CT,
int N>
661 for (
int i = 0; i < size; i++) { (*this)[i] = T(values[i]); }
667 const int nsize = std::max(minsize, 2 * data.
Capacity());
669 p.CopyFrom(data, size);
675 template <
typename T>
template <
typename CT>
679 for (
int i = 0; i < size; i++) { (*this)[i] = T(src[i]); }
686 MFEM_ASSERT( nsize>=0,
"Size must be non-negative. It is " << nsize );
687 if (nsize > Capacity())
697 MFEM_ASSERT( nsize>=0,
"Size must be non-negative. It is " << nsize );
700 if (nsize > Capacity())
704 for (
int i = size; i < nsize; i++)
715 MFEM_ASSERT(nsize >= 0,
"invalid new size: " << nsize);
718 if (nsize <= Capacity())
742 MFEM_ASSERT( i>=0 && i<size,
743 "Access element " << i <<
" of array, size = " << size );
750 MFEM_ASSERT( i>=0 && i<size,
751 "Access element " << i <<
" of array, size = " << size );
766 const int old_size = size;
768 SetSize(size + nels);
769 for (
int i = 0; i < nels; i++)
771 data[old_size+i] = els[i];
780 for (
int i = size-1; i > 0; i--)
791 MFEM_ASSERT(size > 0,
"Array size is zero: " << size);
798 MFEM_ASSERT(size > 0,
"Array size is zero: " << size);
806 while ((i < size) && (data[i] != el)) { i++; }
817 for (
int i = 0; i < size; i++)
819 if (data[i] == el) {
return i; }
827 const T *begin = data, *end = begin + size;
828 const T* first = std::lower_bound(begin, end, el);
829 if (first == end || !(*first == el)) {
return -1; }
830 return first - begin;
836 for (
int i = 0; i < size; i++)
840 for (i++; i < size; i++)
860 template <
typename T>
864 data.
CopyTo(copy.data, Size());
889 for (
int i = 0; i < sa_size; i++)
891 sa[i] = (*this)[offset+i];
898 for (
int i = 0; i < size; i++)
914 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
915 "Array2D: invalid access of element (" << i <<
',' << j
916 <<
") in array of size (" << array1d.Size()/N <<
',' << N
918 return array1d[i*N+j];
924 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
925 "Array2D: invalid access of element (" << i <<
',' << j
926 <<
") in array of size (" << array1d.Size()/N <<
',' << N
928 return array1d[i*N+j];
934 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
935 "Array2D: invalid access of row " << i <<
" in array with " 936 << array1d.Size()/N <<
" rows.");
937 return &array1d[i*N];
943 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
944 "Array2D: invalid access of row " << i <<
" in array with " 945 << array1d.Size()/N <<
" rows.");
946 return &array1d[i*N];
953 Swap(
a.array1d,
b.array1d);
961 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
963 "Array3D: invalid access of element (" 964 << i <<
',' << j <<
',' << k <<
") in array of size (" 965 << array1d.Size() / N2 / N3 <<
',' << N2 <<
',' << N3 <<
").");
966 return array1d[(i*N2+j)*N3+k];
972 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
974 "Array3D: invalid access of element (" 975 << i <<
',' << j <<
',' << k <<
") in array of size (" 976 << array1d.Size() / N2 / N3 <<
',' << N2 <<
',' << N3 <<
").");
977 return array1d[(i*N2+j)*N3+k];
985 MFEM_VERIFY(!(block_size & mask),
"block_size must be a power of two.");
988 while ((1 << shift) < block_size) { shift++; }
1001 for (
int i = 0; i < blocks.Size(); i++)
1003 blocks[i] = (T*)
new char[bsize *
sizeof(T)];
1007 for (
int i = 0; i < size; i++)
1009 new (&At(i)) T(other[i]);
1013 template<
typename T>
1017 if (size >= blocks.Size() * bsize)
1019 T* new_block = (T*)
new char[bsize *
sizeof(T)];
1020 blocks.Append(new_block);
1025 template<
typename T>
1028 int index = Alloc();
1029 new (&At(
index)) T();
1033 template<
typename T>
1036 int index = Alloc();
1037 new (&At(
index)) T(item);
1041 template<
typename T>
1045 std::swap(size, other.
size);
1046 std::swap(shift, other.
shift);
1047 std::swap(mask, other.
mask);
1050 template<
typename T>
1053 return (mask+1)*
sizeof(T)*blocks.
Size() + blocks.MemoryUsage();
1056 template<
typename T>
1059 int bsize = size & mask;
1060 for (
int i = blocks.Size(); i != 0; )
1062 T *block = blocks[--i];
1063 for (
int j = bsize; j != 0; )
1067 delete [] (
char*) block;
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
T Min() const
Find the minimal element in the array, using the comparison operator < for class T.
T * HostReadWrite()
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), false).
int Size() const
Return the number of items actually stored.
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:
friend void Swap(Array< T > &, Array< T > &)
void Unique()
Removes duplicities from a sorted array. This requires operator== to be defined for T...
Memory< T > & GetMemory()
Return a reference to the Memory object used by the Array.
T * end()
STL-like end. Returns pointer after the last element of the array.
Array(int asize, MemoryType mt)
Creates array of asize elements with a given MemoryType.
iterator_base< const BlockArray, const T > base
bool operator==(const iterator &other) const
void Delete()
Delete the owned pointers and reset the Memory object.
void Load(std::istream &in, int fmt=0)
Read an Array2D from the stream in using format fmt. The format fmt can be:
int size
Size of the array.
void Copy(Array2D ©) const
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's DeviceMemoryClass, if on_dev = true...
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void operator=(const T &a)
bool OwnsData() const
Return true if the data will be deleted by the array.
Array(int asize)
Creates array of asize elements.
void Sort(Compare cmp)
Sorts the array in ascending order using the supplied comparison function object. ...
T Sum()
Return the sum of all the array entries using the '+'' operator for class 'T'.
void GetRow(int i, Array< T > &sa) const
Extract a copy of the i-th row into the Array sa.
std::size_t MemoryUsage() 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_iterator cend() const
void DeleteFirst(const T &el)
Delete the first entry with value == 'el'.
T & operator[](int index)
Access item of the array.
void SetSize(int n1, int n2, int n3)
Array(Array< T > &&src)
Move constructor ("steals" data from 'src')
const Memory< T > & GetMemory() const
Return a reference to the Memory object used by the Array, const version.
void DeleteAll()
Delete the whole array.
int Append(const Array< T > &els)
Append another array to this array, resize if necessary.
void CopyTo(U *dest)
STL-like copyTo dest from begin to end.
void MakeDataOwner() const
Make the Array own the data.
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 SetSize(int m, int n)
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 CopyFromHost(const T *src, int size)
Copy size entries from the host pointer src to *this.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
void DeleteAll()
Destroy all items, set size to zero.
T & operator[](int i)
Reference access to the ith element.
int Capacity() const
Return the current capacity of the BlockArray.
int Find(const T &el) const
Return the first index where 'el' is found; return -1 if not found.
void LoseData()
NULL-ifies the data.
BlockArray & operator=(const BlockArray &)=delete
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:
void CheckIndex(int index) const
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
void CopyFrom(const U *src)
Copy from src into this array. Copies enough entries to fill the Capacity size of this array...
bool operator!=(const Array< T > &LHS, const Array< T > &RHS)
T * begin()
STL-like begin. Returns pointer to the first element of the array.
void Assign(const T *)
Copy data from a pointer. 'Size()' elements are copied.
bool UseDevice() const
Return the device flag of the Memory object used by the Array.
void Print(std::ostream &out=mfem::out, int width=4) const
Prints array to stream with width elements per row.
void Sort()
Sorts the array in ascending order. This requires operator< to be defined for T.
int Capacity() const
Return the size of the allocated memory.
void StealData(T **p)
Changes the ownership of the data.
void GetSubArray(int offset, int sa_size, Array< T > &sa) const
Copy sub array starting from offset out to the provided sa.
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...
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
int FindSorted(const T &el) const
Do bisection search for 'el' in a sorted array; return -1 if not found.
const T * operator[](int i) const
void Reset()
Reset the memory to be empty, ensuring that Delete() will be a no-op.
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 > &)
double p(const Vector &x, double t)
bool operator==(const Array< T > &LHS, const Array< T > &RHS)
void GrowSize(int minsize)
bool operator==(const const_iterator &other) const
int IsSorted()
Return 1 if the array is sorted from lowest to highest. Otherwise return 0.
Array(T *data_, int asize)
Creates array using an existing c-array of asize elements; allocsize is set to -asize to indicate tha...
BlockArray(int block_size=16 *1024)
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
MemoryType
Memory types supported by MFEM.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
void PartialSum()
Fill the entries of the array with the cumulative sum of the entries.
T * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), on_dev).
void DeleteLast()
Delete the last entry of the array.
const_iterator cbegin() const
Array(MemoryType mt)
Creates an empty array with a given MemoryType.
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
lvalue_t & Assign(lvalue_t &a, const rvalue_t &b)
const_iterator(bool stop)
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, if on_dev = true, or the mfem::Device's HostMemoryClass, otherwise.
bool operator!=(const const_iterator &other) const
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
void ClearOwnerFlags() const
Clear the ownership flags for the host and device pointers, as well as any internal data allocated by...
Array()
Creates an empty array.
int index(int i, int j, int nx, int ny)
void Copy(Array ©) const
Create a copy of the internal array to the provided copy.
bool operator!=(const iterator &other) const
Class used by MFEM to store pointers to host and/or device memory.
const T & operator()(int i, int j, int k) const
void Swap(T &a, T &b)
inlines ///
int Size() const
Return the logical size of the array.
const_iterator & operator++()
T & Last()
Return the last element in the array.
void CopyTo(Memory &dest, int size) const
Copy size entries from *this to dest.
std::size_t MemoryUsage() const
Returns the number of bytes allocated for the array including any reserve.
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 from 'src'.
const T & operator()(int i, int j) const
bool UseDevice() const
Read the internal device flag.
void DeleteAll()
Delete all dynamically allocated memory, resetting all dimensions to zero.
Array3D(int n1, int n2, int n3)
const T * GetRow(int i) const
T & At(int index)
Access item of the array.
const T & AsConst(const T &a)
Utility function similar to std::as_const in c++17.
MemoryType GetMemoryType() const
Return a MemoryType that is currently valid. If both the host and the device pointers are currently v...
int Prepend(const T &el)
Prepend an 'el' 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)