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;
491 int Append(
const T &item);
523 template <
typename cA,
typename cT>
550 MFEM_ASSERT(!
stop,
"invalid use");
553 if (b_end_idx < array->
size)
604 iterator
begin() {
return size ? iterator(
this) : iterator(
true); }
605 iterator
end() {
return iterator(); }
608 {
return size ? const_iterator(
this) : const_iterator(
true); }
609 const_iterator
cend()
const {
return const_iterator(); }
620 "Out of bounds access: " <<
index <<
", size = " <<
size);
648 size > 0 ? data.
New(size, src.data.GetMemoryType()) : data.
Reset();
653 template <
typename T>
template <
typename CT>
657 size > 0 ? data.
New(size) : data.
Reset();
658 for (
int i = 0; i < size; i++) { (*this)[i] = T(src[i]); }
661 template <
typename T>
template <
typename CT,
int N>
664 for (
int i = 0; i < size; i++) { (*this)[i] = T(values[i]); }
670 const int nsize = std::max(minsize, 2 * data.
Capacity());
672 p.CopyFrom(data, size);
678 template <
typename T>
template <
typename CT>
682 for (
int i = 0; i < size; i++) { (*this)[i] = T(src[i]); }
689 MFEM_ASSERT( nsize>=0,
"Size must be non-negative. It is " << nsize );
690 if (nsize > Capacity())
700 MFEM_ASSERT( nsize>=0,
"Size must be non-negative. It is " << nsize );
703 if (nsize > Capacity())
707 for (
int i = size; i < nsize; i++)
718 MFEM_ASSERT(nsize >= 0,
"invalid new size: " << nsize);
721 if (nsize <= Capacity())
745 MFEM_ASSERT( i>=0 && i<size,
746 "Access element " << i <<
" of array, size = " << size );
753 MFEM_ASSERT( i>=0 && i<size,
754 "Access element " << i <<
" of array, size = " << size );
769 const int old_size = size;
771 SetSize(size + nels);
772 for (
int i = 0; i < nels; i++)
774 data[old_size+i] = els[i];
783 for (
int i = size-1; i > 0; i--)
794 MFEM_ASSERT(size > 0,
"Array size is zero: " << size);
801 MFEM_ASSERT(size > 0,
"Array size is zero: " << size);
809 while ((i < size) && (data[i] != el)) { i++; }
820 for (
int i = 0; i < size; i++)
822 if (data[i] == el) {
return i; }
830 const T *begin = data, *end = begin + size;
831 const T* first = std::lower_bound(begin, end, el);
832 if (first == end || !(*first == el)) {
return -1; }
833 return first - begin;
839 for (
int i = 0; i < size; i++)
843 for (i++; i < size; i++)
863 template <
typename T>
867 data.
CopyTo(copy.data, Size());
884 data.
MakeAlias(master.GetMemory(), 0, size);
891 for (
int i = 0; i < sa_size; i++)
893 sa[i] = (*this)[offset+i];
900 for (
int i = 0; i < size; i++)
916 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
917 "Array2D: invalid access of element (" << i <<
',' << j
918 <<
") in array of size (" << array1d.Size()/N <<
',' << N
920 return array1d[i*N+j];
926 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
927 "Array2D: invalid access of element (" << i <<
',' << j
928 <<
") in array of size (" << array1d.Size()/N <<
',' << N
930 return array1d[i*N+j];
936 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
937 "Array2D: invalid access of row " << i <<
" in array with " 938 << array1d.Size()/N <<
" rows.");
939 return &array1d[i*N];
945 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
946 "Array2D: invalid access of row " << i <<
" in array with " 947 << array1d.Size()/N <<
" rows.");
948 return &array1d[i*N];
955 Swap(
a.array1d,
b.array1d);
963 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
965 "Array3D: invalid access of element (" 966 << i <<
',' << j <<
',' << k <<
") in array of size (" 967 << array1d.Size() / N2 / N3 <<
',' << N2 <<
',' << N3 <<
").");
968 return array1d[(i*N2+j)*N3+k];
974 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
976 "Array3D: invalid access of element (" 977 << i <<
',' << j <<
',' << k <<
") in array of size (" 978 << array1d.Size() / N2 / N3 <<
',' << N2 <<
',' << N3 <<
").");
979 return array1d[(i*N2+j)*N3+k];
987 MFEM_VERIFY(!(block_size & mask),
"block_size must be a power of two.");
990 while ((1 << shift) < block_size) { shift++; }
1003 for (
int i = 0; i < blocks.Size(); i++)
1005 blocks[i] = (T*)
new char[bsize *
sizeof(T)];
1009 for (
int i = 0; i < size; i++)
1011 new (&At(i)) T(other[i]);
1015 template<
typename T>
1019 if (size >= blocks.Size() * bsize)
1021 T* new_block = (T*)
new char[bsize *
sizeof(T)];
1022 blocks.Append(new_block);
1027 template<
typename T>
1030 int index = Alloc();
1031 new (&At(
index)) T();
1035 template<
typename T>
1038 int index = Alloc();
1039 new (&At(
index)) T(item);
1043 template<
typename T>
1047 std::swap(size, other.
size);
1048 std::swap(shift, other.
shift);
1049 std::swap(mask, other.
mask);
1052 template<
typename T>
1055 return (mask+1)*
sizeof(T)*blocks.
Size() + blocks.MemoryUsage();
1058 template<
typename T>
1061 int bsize = size & mask;
1062 for (
int i = blocks.Size(); i != 0; )
1064 T *block = blocks[--i];
1065 for (
int j = bsize; j != 0; )
1069 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. ...
void operator=(const T &a)
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.
void MakeAlias(const Memory &base, int offset, int size)
Create a memory object that points inside the memory object base.
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...
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)