35#ifndef NEKTAR_LIB_UTILITIES_BASIC_UTILS_SHARED_ARRAY_HPP
36#define NEKTAR_LIB_UTILITIES_BASIC_UTILS_SHARED_ARRAY_HPP
44#include <boost/multi_array.hpp>
57template <
typename Dim,
typename DataType>
class Array;
61template <
typename DataType>
class Array<
OneD, const DataType>
67 void (*m_callback)(
void *);
87 m_pythonInfo(nullptr),
89 m_size(0), m_capacity(0), m_data(nullptr), m_count(nullptr),
103 m_pythonInfo(nullptr),
105 m_size(dim1Size), m_capacity(dim1Size), m_data(nullptr),
106 m_count(nullptr), m_offset(0)
124 m_pythonInfo(nullptr),
126 m_size(dim1Size), m_capacity(dim1Size), m_data(nullptr),
127 m_count(nullptr), m_offset(0)
144 m_pythonInfo(nullptr),
146 m_size(dim1Size), m_capacity(dim1Size), m_data(nullptr),
147 m_count(nullptr), m_offset(0)
163 m_pythonInfo(nullptr),
165 m_size(dim1Size), m_capacity(dim1Size), m_data(nullptr),
166 m_count(nullptr), m_offset(0)
174 m_data, m_capacity, data);
196 m_pythonInfo(rhs.m_pythonInfo),
198 m_size(dim1Size), m_capacity(rhs.m_capacity), m_data(rhs.m_data),
199 m_count(rhs.m_count), m_offset(rhs.m_offset)
201 if (m_count !=
nullptr)
206 larger than input array size.");
215 Array(size_type dim1Size, DataType *data,
void *memory_pointer,
216 void (*python_decrement)(
void *))
217 : m_size(dim1Size), m_capacity(dim1Size), m_data(data),
218 m_count(nullptr), m_offset(0)
220 m_count =
new size_type();
223 m_pythonInfo =
new PythonInfo *();
224 *m_pythonInfo =
new PythonInfo();
225 (*m_pythonInfo)->m_callback = python_decrement;
226 (*m_pythonInfo)->m_pyObject = memory_pointer;
234 m_pythonInfo(rhs.m_pythonInfo),
236 m_size(rhs.m_size), m_capacity(rhs.m_capacity), m_data(rhs.m_data),
237 m_count(rhs.m_count), m_offset(rhs.m_offset)
239 if (m_count !=
nullptr)
247#if __GNUC__ == 12 && __GNUC_MINOR__ == 2
248#pragma GCC diagnostic push
249#pragma GCC diagnostic ignored "-Wuse-after-free"
253 if (m_count ==
nullptr)
262 if (*m_pythonInfo ==
nullptr)
269 (*m_pythonInfo)->m_callback((*m_pythonInfo)->m_pyObject);
270 delete *m_pythonInfo;
274 m_pythonInfo =
nullptr;
291 if (m_count !=
nullptr)
296 if (m_count !=
nullptr && *m_count == 0)
299 if (*m_pythonInfo ==
nullptr)
304 else if ((*rhs.m_pythonInfo) !=
nullptr &&
305 (*m_pythonInfo)->m_pyObject !=
306 (*rhs.m_pythonInfo)->m_pyObject)
308 (*m_pythonInfo)->m_callback((*m_pythonInfo)->m_pyObject);
309 delete *m_pythonInfo;
313 m_pythonInfo =
nullptr;
326 if (m_count !=
nullptr)
333 m_pythonInfo = rhs.m_pythonInfo;
337#if __GNUC__ == 12 && __GNUC_MINOR__ == 2
338#pragma GCC diagnostic pop
343 return m_data + m_offset;
347 return m_data + m_offset + m_size;
353 std::string(
"Element ") + std::to_string(i) +
354 std::string(
" requested in an array of size ") +
355 std::to_string(m_size));
356 return *(m_data + i + m_offset);
362 return m_data + m_offset;
368 return m_data + m_offset;
388 WARNINGL1(
false,
"member function num_elements() is deprecated, "
389 "use size() instead.");
415 const element *end = start + m_size;
420 return (rhs_start >= start && rhs_start <= end) ||
421 (rhs_end >= start && rhs_end <= end);
427 return *m_pythonInfo !=
nullptr;
430 void ToPythonArray(
void *memory_pointer,
void (*python_decrement)(
void *))
432 *m_pythonInfo =
new PythonInfo();
433 (*m_pythonInfo)->m_callback = python_decrement;
434 (*m_pythonInfo)->m_pyObject = memory_pointer;
448 template <
typename T>
452 template <
typename T>
458 PythonInfo **m_pythonInfo;
485 m_pythonInfo =
new PythonInfo *();
486 *m_pythonInfo =
nullptr;
490 template <
typename T>
495 result.m_offset += offset;
496 result.m_size = rhs.m_size - offset;
502template <
typename DataType>
class Array<
TwoD, const DataType>
510 typedef typename ArrayType::index
index;
528 m_data->num_elements());
535 m_data->data(), m_data->num_elements(), initValue);
542 m_data->data(), m_data->num_elements(), data);
558 return m_data->begin();
562 return m_data->end();
570 return m_data->data();
574 return m_data->data();
578 return m_data->num_dimensions();
582 return m_data->shape();
587 return m_data->num_elements();
593 WARNINGL1(
false,
"member function num_elements() is deprecated, "
594 "use size() instead.");
595 return m_data->num_elements();
600 return m_data->shape()[0];
604 return m_data->shape()[1];
625template <
typename DataType>
679 Array(size_type dim1Size, DataType *data,
void *memory_pointer,
680 void (*python_decrement)(
void *))
681 : BaseType(dim1Size, data, memory_pointer, python_decrement)
685 void ToPythonArray(
void *memory_pointer,
void (*python_decrement)(
void *))
687 BaseType::ToPythonArray(memory_pointer, python_decrement);
693 BaseType::operator=(rhs);
712 return this->m_data + this->m_offset;
718 return this->m_data + this->m_offset + this->m_size;
721 using BaseType::operator[];
725 std::string(
"Element ") + std::to_string(i) +
726 std::string(
" requested in an array of size ") +
727 std::to_string(this->size()));
734 return this->m_data + this->m_offset;
737 using BaseType::data;
740 return this->m_data + this->m_offset;
745 template <
typename T1,
typename T3>
friend class NekMatrix;
752 ASSERTL1(newSize <= this->m_capacity,
753 "Can't change an array size to something larger than its "
755 this->m_size = newSize;
762template <
typename DataType>
783 :
BaseType(dim1Size, dim2Size, initValue)
788 :
BaseType(dim1Size, dim2Size, data)
798 BaseType::operator=(rhs);
802 using BaseType::begin;
805 return this->m_data->begin();
811 return this->m_data->end();
814 using BaseType::operator[];
817 return (*this->m_data)[i];
823 return this->m_data->data();
826 using BaseType::data;
829 return this->m_data->data();
837inline bool IsEqualImpl(
const T &lhs,
const T &rhs, std::false_type)
844inline bool IsEqualImpl(
const T &lhs,
const T &rhs, std::true_type)
849template <
typename T>
inline bool IsEqual(
const T &lhs,
const T &rhs)
851 return IsEqualImpl(lhs, rhs, std::is_floating_point<T>());
854template <
typename T1,
typename T2>
857 if (lhs.size() != rhs.size())
862 if (lhs.data() == rhs.data())
879template <
typename T1,
typename T2>
882 return !(lhs == rhs);
885template <
typename DataType>
893template <
typename DataType>
901template <
typename ConstDataType,
typename DataType>
905 if (dest.
size() != source.size())
910 std::copy(source.data(), source.data() + source.size(), dest.
data());
913template <
typename ConstDataType,
typename DataType>
918 if (dest.
size() != n)
951template <
typename T1,
typename T2>
954 if ((lhs.GetRows() != rhs.GetRows()) ||
955 (lhs.GetColumns() != rhs.GetColumns()))
960 if (lhs.data() == rhs.data())
970 if (!
IsEqual(lhs[i][j], rhs[i][j]))
980template <
typename T1,
typename T2>
983 return !(lhs == rhs);
986namespace LibUtilities
#define WARNINGL1(condition, msg)
#define ASSERTL0(condition, msg)
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
reference operator[](size_type i)
Array(size_type dim1Size, const Array< OneD, DataType > &rhs)
BaseType::reference reference
Array(size_type dim1Size, const DataType *data)
Array(size_type dim1Size)
Array(const Array< OneD, const DataType > &rhs)
static Array< OneD, DataType > CreateWithOffset(const Array< OneD, DataType > &rhs, unsigned int offset)
BaseType::element element
Array< OneD, constDataType >::const_iterator begin() const
BaseType::size_type size_type
BaseType::iterator iterator
Array(const Array< OneD, DataType > &rhs)
Array< OneD, const DataType > BaseType
Array(size_type dim1Size, DataType *data, const ArrayWrapperType wrap=eArrayCopy)
Array(size_type dim1Size, const DataType &initValue)
Array(size_type dim1Size, const Array< OneD, const DataType > &rhs)
Array< OneD, DataType > & operator=(const Array< OneD, DataType > &rhs)
void ChangeSize(size_type newSize)
1D Array of constant elements with garbage collection and bounds checking.
const DataType & const_reference
friend Array< OneD, T > operator+(const Array< OneD, T > &lhs, typename Array< OneD, T >::size_type offset)
Creates an array with a specified offset.
Array(size_type dim1Size, const Array< OneD, const DataType > &rhs)
Creates a 1D array that references rhs.
size_type GetCount() const
Returns the array's reference counter.
void CreateStorage(size_type size)
Array(size_type dim1Size, const DataType *data)
Creates a 1D array a copies data into it.
const_iterator end() const
Array()
Creates an empty array.
const_iterator begin() const
bool Overlaps(const Array< OneD, const DataType > &rhs) const
Returns true is this array and rhs overlap.
Array(size_type dim1Size)
Creates an array of size dim1Size.
Array(size_type dim1Size, DataType *data, const ArrayWrapperType wrap=eArrayCopy)
Create a 1D array that wrap around a given pointer.
size_type num_elements() const
Returns the array's size. Deprecated.
friend Array< OneD, T > operator+(typename Array< OneD, T >::size_type offset, const Array< OneD, T > &rhs)
const_reference operator[](size_type i) const
Array< OneD, const DataType > & operator=(const Array< OneD, const DataType > &rhs)
Creates a reference to rhs.
const element * get() const
Returns a c-style pointer to the underlying array.
size_type capacity() const
Returns the array's capacity.
Array(const Array< OneD, const DataType > &rhs)
Creates a reference to rhs.
size_type size() const
Returns the array's size.
size_type num_dimensions() const
Returns 1.
static Array< OneD, T > CreateWithOffset(const Array< OneD, T > &rhs, size_type offset)
size_type GetOffset() const
Returns the array's offset.
const DataType * const_iterator
Array(size_type dim1Size, const DataType &initValue)
Creates a 1D array with each element initialized to an initial value.
const element * data() const
Returns a c-style pointer to the underlying array.
BaseType::iterator iterator
Array(const Array< TwoD, DataType > &rhs)
Array(size_type dim1Size, size_type dim2Size, const DataType *data)
BaseType::reference reference
reference operator[](index i)
Array(size_type dim1Size, size_type dim2Size)
Array(size_type dim1Size, size_type dim2Size, const DataType &initValue)
BaseType::size_type size_type
Array< TwoD, DataType > & operator=(const Array< TwoD, DataType > &rhs)
BaseType::element element
Array< TwoD, const DataType > BaseType
2D array with garbage collection and bounds checking.
size_type num_elements() const
const element * get() const
Array< TwoD, const DataType > & operator=(const Array< TwoD, const DataType > &rhs)
const element * data() const
Array(size_type dim1Size, size_type dim2Size, const DataType &initValue)
ArrayType::size_type size_type
Array(size_type dim1Size, size_type dim2Size, const DataType *data)
const_iterator end() const
ArrayType::const_reference const_reference
size_type num_dimensions() const
const size_type * shape() const
ArrayType::element element
Array(size_type dim1Size, size_type dim2Size)
Constructs a 2 dimensional array. The elements of the array are not initialized.
ArrayType::iterator iterator
std::shared_ptr< ArrayType > m_data
ArrayType::const_iterator const_iterator
boost::multi_array_ref< DataType, 2 > ArrayType
size_type GetRows() const
Array(const Array< TwoD, const DataType > &rhs)
ArrayType::reference reference
const_iterator begin() const
const_reference operator[](index i) const
size_type GetColumns() const
static DataType * RawAllocate(size_t NumberOfElements)
Allocates a chunk of raw, uninitialized memory, capable of holding NumberOfElements objects.
static void RawDeallocate(DataType *array, size_t NumberOfElements)
Deallocates memory allocated from RawAllocate.
static std::vector< unsigned int > NullUnsignedIntVector
static std::vector< std::vector< NekDouble > > NullVectorNekDoubleVector
static std::vector< NekDouble > NullNekDoubleVector
bool IsRealEqual(T1 &&lhs, T2 &&rhs, const unsigned int factor=NekConstants::kNekFloatCompFact)
compare reals of same type with relative tolerance
bool operator==(const Array< OneD, T1 > &lhs, const Array< OneD, T2 > &rhs)
static Array< OneD, int > NullInt1DArray
Array< OneD, DataType > operator+(const Array< OneD, DataType > &lhs, typename Array< OneD, DataType >::size_type offset)
static Array< OneD, Array< OneD, NekDouble > > NullNekDoubleArrayOfArray
bool IsEqual(const T &lhs, const T &rhs)
static Array< OneD, Array< OneD, Array< OneD, NekDouble > > > NullNekDoubleTensorOfArray3D
bool IsEqualImpl(const T &lhs, const T &rhs, std::false_type)
void CopyArrayN(const Array< OneD, ConstDataType > &source, Array< OneD, DataType > &dest, typename Array< OneD, DataType >::size_type n)
static Array< OneD, NekDouble > NullNekDouble1DArray
std::shared_ptr< boost::multi_array_ref< DataType, Dim::Value > > CreateStorage(const ExtentListType &extent)
bool operator!=(const Array< OneD, T1 > &lhs, const Array< OneD, T2 > &rhs)
void CopyArray(const Array< OneD, ConstDataType > &source, Array< OneD, DataType > &dest)