43#ifndef DOMI_MDARRAY_HPP
44#define DOMI_MDARRAY_HPP
50#include "Teuchos_Array.hpp"
53#include "Domi_ConfigDefs.hpp"
54#include "Domi_Utils.hpp"
55#include "Domi_MDIterator.hpp"
56#include "Domi_MDRevIterator.hpp"
57#include "Domi_MDArrayView.hpp"
65template<
typename T >
class MDArray;
72bool operator==(
const MDArray< T > & a1,
73 const MDArray< T > & a2);
105template<
typename T >
114template<
typename T >
122template<
typename T >
285template<
typename T >
326 inline MDArray(
const Teuchos::ArrayView< dim_type > & dims);
342 inline MDArray(
const Teuchos::ArrayView< dim_type > & dims,
344 const Layout
layout = DEFAULT_ORDER);
360 inline MDArray(
const Teuchos::ArrayView< dim_type > & dims,
391 inline const Teuchos::Array< dim_type > &
dimensions()
const;
398 inline dim_type
dimension(
int axis)
const;
402 inline size_type
size()
const;
406 inline const Teuchos::Array< size_type > &
strides()
const;
410 inline const Teuchos::Array< T > &
array()
const;
414 inline const Layout
layout()
const;
591 inline T &
operator()(dim_type i, dim_type j);
605 inline T &
operator()(dim_type i, dim_type j, dim_type k);
621 inline T &
operator()(dim_type i, dim_type j, dim_type k, dim_type m);
639 inline T &
operator()(dim_type i, dim_type j, dim_type k, dim_type m,
663 inline T &
operator()(dim_type i, dim_type j, dim_type k, dim_type m,
664 dim_type n, dim_type p, ...);
674 inline const T &
operator()(dim_type i)
const;
686 inline const T &
operator()(dim_type i, dim_type j)
const;
700 inline const T &
operator()(dim_type i, dim_type j, dim_type k)
const;
716 inline const T &
operator()(dim_type i, dim_type j, dim_type k,
735 inline const T &
operator()(dim_type i, dim_type j, dim_type k,
736 dim_type m, dim_type n)
const;
759 inline const T &
operator()(dim_type i, dim_type j, dim_type k,
760 dim_type m, dim_type n, dim_type p, ...)
const;
771 void assign(
const T & value);
781 T &
at(dim_type i, ...);
791 const T &
at(dim_type i, ...)
const;
803 inline bool empty()
const;
813 void resize(
const Teuchos::ArrayView< dim_type > & dims);
848 template<
typename T2 >
854 template<
typename T2 >
860 template<
typename T2 >
866 template<
typename T2 >
872 template<
typename T2 >
878 template<
typename T2 >
884 template<
typename T2 >
890 template<
typename T2 >
897 Teuchos::Array< dim_type > _dimensions;
898 Teuchos::Array< size_type > _strides;
899 Teuchos::Array< T > _array;
904 void assertAxis(
int axis)
const;
907 void assertIndex(dim_type i,
int axis)
const;
914template<
typename T >
916 _dimensions(Teuchos::tuple< dim_type >(0)),
917 _strides(Teuchos::tuple< size_type >(1)),
919 _layout(DEFAULT_ORDER),
926template<
typename T >
929 _strides(computeStrides< size_type, dim_type >(dims, DEFAULT_ORDER)),
930 _array(computeSize(dims)),
931 _layout(DEFAULT_ORDER),
932 _ptr(_array.getRawPtr())
938template<
typename T >
941 const Layout layout) :
943 _strides(computeStrides< size_type, dim_type >(dims, layout)),
944 _array(computeSize(dims), value),
946 _ptr(_array.getRawPtr())
952template<
typename T >
957 _strides(computeStrides< size_type, dim_type >(dims, layout)),
958 _array(computeSize(dims), value),
960 _ptr(_array.getRawPtr())
966template<
typename T >
968 _dimensions(source._dimensions),
969 _strides(source._strides),
970 _array(source._array),
971 _layout(source._layout),
972 _ptr(_array.getRawPtr())
978template<
typename T >
980 _dimensions(source.dimensions()),
981 _strides(computeStrides< size_type, dim_type >(source.dimensions(),
983 _array(computeSize(source.dimensions())),
984 _layout(source.layout()),
985 _ptr(_array.getRawPtr())
990 for ( ; srcit != source.
cend(); ++thisit, ++srcit)
998template<
typename T >
1005template<
typename T >
1009 return _dimensions.size();
1014template<
typename T >
1015const Teuchos::Array< dim_type > &
1023template<
typename T >
1027#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1030 return _dimensions[axis];
1035template<
typename T >
1039 return _array.size();
1044template<
typename T >
1045const Teuchos::Array< size_type > &
1053template<
typename T >
1054const Teuchos::Array< T > &
1062template<
typename T >
1071template<
typename T >
1080template<
typename T >
1090template<
typename T >
1099template<
typename T >
1109template<
typename T >
1118template<
typename T >
1128template<
typename T >
1137template<
typename T >
1147template<
typename T >
1156template<
typename T >
1166template<
typename T >
1175template<
typename T >
1179 Teuchos::ArrayView< T > array(
const_cast< T*
>(_array.getRawPtr()),
1181 Teuchos::Array< dim_type > dims(_dimensions);
1187template<
typename T >
1196template<
typename T >
1206template<
typename T >
1209 return mdArrayView();
1214template<
typename T >
1217 return mdArrayViewConst();
1223template<
typename T >
1229 return mdArrayView()[i];
1234template<
typename T >
1240 return mdArrayView()[i];
1245template<
typename T >
1250 return mdArrayView()[s];
1255template<
typename T >
1260 return mdArrayView()[s];
1265template<
typename T >
1269 return mdArrayView();
1274template<
typename T >
1278 return mdArrayView();
1283template<
typename T >
1287#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1288 TEUCHOS_TEST_FOR_EXCEPTION(
1290 "Attempt to access " << _dimensions.size() <<
"D array with 1 index"
1294 return _ptr[i * _strides[0]];
1299template<
typename T >
1304#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1305 TEUCHOS_TEST_FOR_EXCEPTION(
1307 "Attempt to access " << _dimensions.size() <<
"D array with 2 indexes"
1312 return _ptr[i * _strides[0] + j * _strides[1]];
1317template<
typename T >
1323#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1324 TEUCHOS_TEST_FOR_EXCEPTION(
1326 "Attempt to access " << _dimensions.size() <<
"D array with 3 indexes"
1332 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2]];
1337template<
typename T >
1344#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1345 TEUCHOS_TEST_FOR_EXCEPTION(
1347 "Attempt to access " << _dimensions.size() <<
"D array with 4 indexes"
1354 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2] +
1360template<
typename T >
1368#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1369 TEUCHOS_TEST_FOR_EXCEPTION(
1371 "Attempt to access " << _dimensions.size() <<
"D array with 5 indexes"
1379 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2] +
1380 m * _strides[3] + n * _strides[4]];
1385template<
typename T >
1395#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1396 TEUCHOS_TEST_FOR_EXCEPTION(
1398 "Attempt to access " << _dimensions.size() <<
"D array with too many indexes"
1408 size_type offset = i * _strides[0] + j * _strides[1] + k * _strides[2] +
1409 m * _strides[3] + n * _strides[4] + p * _strides[5];
1410 va_start(indexes, p);
1411 for (
int axis = 6; axis < _dimensions.size(); axis++)
1413 dim_type q = va_arg(indexes, dim_type);
1414#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1415 assertIndex(q, axis);
1417 offset += q * _strides[axis];
1420 return _ptr[offset];
1425template<
typename T >
1429#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1430 TEUCHOS_TEST_FOR_EXCEPTION(
1432 "Attempt to access " << _dimensions.size() <<
"D array with 1 index"
1436 return _ptr[i * _strides[0]];
1441template<
typename T >
1446#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1447 TEUCHOS_TEST_FOR_EXCEPTION(
1449 "Attempt to access " << _dimensions.size() <<
"D array with 2 indexes"
1454 return _ptr[i * _strides[0] + j * _strides[1]];
1459template<
typename T >
1465#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1466 TEUCHOS_TEST_FOR_EXCEPTION(
1468 "Attempt to access " << _dimensions.size() <<
"D array with 3 indexes"
1474 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2]];
1479template<
typename T >
1486#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1487 TEUCHOS_TEST_FOR_EXCEPTION(
1489 "Attempt to access " << _dimensions.size() <<
"D array with 4 indexes"
1496 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2] +
1502template<
typename T >
1510#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1511 TEUCHOS_TEST_FOR_EXCEPTION(
1513 "Attempt to access " << _dimensions.size() <<
"D array with 5 indexes"
1521 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2] +
1522 m * _strides[3] + n * _strides[4]];
1527template<
typename T >
1537#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1538 TEUCHOS_TEST_FOR_EXCEPTION(
1540 "Attempt to access " << _dimensions.size() <<
"D array with too many indexes"
1550 size_type offset = i * _strides[0] + j * _strides[1] + k * _strides[2] +
1551 m * _strides[3] + n * _strides[4] + p * _strides[5];
1552 va_start(indexes, p);
1553 for (
int axis = 6; axis < _dimensions.size(); axis++)
1555 dim_type q = va_arg(indexes, dim_type);
1556#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1557 assertIndex(q, axis);
1559 offset += q * _strides[axis];
1562 return _ptr[offset];
1567template<
typename T >
1571 for (
iterator it = begin(); it != end(); ++it)
1577template<
typename T >
1583 size_type offset = i * _strides[0];
1584 va_start(indexes, i);
1585 for (
int axis = 1; axis < _dimensions.size(); axis++)
1587 dim_type j = va_arg(indexes, dim_type);
1588 assertIndex(j, axis);
1589 offset += j * _strides[axis];
1592 return _ptr[offset];
1597template<
typename T >
1603 size_type offset = i * _strides[0];
1604 va_start(indexes, i);
1605 for (
int axis = 1; axis < _dimensions.size(); axis++)
1607 dim_type j = va_arg(indexes, dim_type);
1608 assertIndex(j, axis);
1609 offset += j * _strides[axis];
1612 return _ptr[offset];
1617template<
typename T >
1621 return _array.capacity();
1626template<
typename T >
1630 _dimensions.resize(1);
1635 _ptr = _array.getRawPtr();
1640template<
typename T >
1644 return _array.empty();
1649template<
typename T >
1653 return _array.max_size();
1658template<
typename T >
1662 _dimensions.assign(dims.begin(), dims.end());
1663 _strides = computeStrides< size_type, dim_type >(dims, _layout);
1664 _array.resize(computeSize(dims));
1665 _ptr = _array.getRawPtr();
1670template<
typename T >
1676 Teuchos::swap(_dimensions, a._dimensions);
1677 Teuchos::swap(_strides, a._strides );
1678 Teuchos::swap(_array, a._array );
1680 Layout tmp = _layout;
1681 _layout = a._layout;
1684 _ptr = _array.getRawPtr();
1685 a._ptr = a._array.getRawPtr();
1690template<
typename T >
1694#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1703template<
typename T >
1707 return mdArrayView().toString();
1712template<
typename T >
1716 return _array.getRawPtr();
1721template<
typename T >
1725 return _array.getRawPtr();
1730template<
typename T >
1733 return (a1() == a2());
1738template<
typename T >
1741 return (a1() == a2);
1746template<
typename T >
1749 return (a1 == a2());
1754template<
typename T >
1757 return not (a1 == a2);
1762template<
typename T >
1765 return (a1() != a2);
1770template<
typename T >
1773 return (a1 != a2());
1778template<
typename T >
1779std::ostream & operator<<(std::ostream & os,
const MDArray< T > & a)
1787template<
typename T >
1797template<
typename T >
1801 TEUCHOS_TEST_FOR_EXCEPTION(
1802 !(0 <= axis && axis < _dimensions.size()),
1804 "MDArray<T>::assertAxis(axis=" << axis <<
"): out of range "
1805 <<
"axis in [0, " << _dimensions.size() <<
")"
1811template<
typename T >
1813MDArray< T >::assertIndex(dim_type i,
int axis)
const
1815 TEUCHOS_TEST_FOR_EXCEPTION(
1816 !(0 <= i && i < _dimensions[axis]), RangeError,
1817 "MDArray<T>::assertIndex(i=" << i <<
",axis=" << axis <<
"): out of range "
1818 <<
"i in [0, " << _dimensions[axis] <<
")"
Memory-safe templated multi-dimensional array class.
Definition: Domi_MDArray.hpp:287
reverse_iterator rbegin()
Return the beginning reverse_iterator.
Definition: Domi_MDArray.hpp:1130
const Teuchos::Array< size_type > & strides() const
Return the indexing strides.
Definition: Domi_MDArray.hpp:1046
size_type max_size() const
Return the maximum allowable size for the MDArray
Definition: Domi_MDArray.hpp:1651
const Teuchos::Array< dim_type > & dimensions() const
Return an array of dimensions.
Definition: Domi_MDArray.hpp:1016
const T * const_pointer
Const pointer type.
Definition: Domi_MDArray.hpp:300
const Teuchos::Array< T > & array() const
Return the underlying Teuchos::Array
Definition: Domi_MDArray.hpp:1055
T & reference
Reference type.
Definition: Domi_MDArray.hpp:303
T & at(dim_type i,...)
Non-const single element access method with bounds checking.
Definition: Domi_MDArray.hpp:1579
const T & const_reference
Const reference type.
Definition: Domi_MDArray.hpp:306
T * pointer
Pointer type.
Definition: Domi_MDArray.hpp:297
friend bool operator!=(const MDArray< T2 > &a1, const MDArrayView< T2 > &a2)
MDArray/MDArrayView inequality operator.
MDArrayView< T > operator[](dim_type i)
Sub-array access operator. The returned MDArrayView object will have one fewer dimensions than the ca...
Definition: Domi_MDArray.hpp:1225
const T * getRawPtr() const
Return a const raw pointer to the beginning of the MDArray or NULL if unsized.
Definition: Domi_MDArray.hpp:1714
friend std::ostream & operator<<(std::ostream &os, const MDArray< T2 > &a)
Stream output operator.
static bool hasBoundsChecking()
Return true if MDArray has been compiled with bounds checking on.
Definition: Domi_MDArray.hpp:1692
friend bool operator==(const MDArray< T2 > &a1, const MDArrayView< T2 > &a2)
MDArray/MDArrayView equality operator.
std::string toString() const
Convert the MDArray to a string representation.
Definition: Domi_MDArray.hpp:1705
const Layout layout() const
Return the storage order.
Definition: Domi_MDArray.hpp:1064
void clear()
Clear the MDArray
Definition: Domi_MDArray.hpp:1628
void swap(MDArray< T > &a)
Swap this MDArray with the given MDArray
Definition: Domi_MDArray.hpp:1672
const_reverse_iterator crend() const
Return the ending const_reverse_iterator.
Definition: Domi_MDArray.hpp:1158
friend bool operator!=(const MDArray< T2 > &a1, const MDArray< T2 > &a2)
Inequality operator.
MDArray()
Default constructor.
Definition: Domi_MDArray.hpp:915
friend bool operator==(const MDArray< T2 > &a1, const MDArray< T2 > &a2)
Equality operator.
void resize(const Teuchos::ArrayView< dim_type > &dims)
Resize the MDArray based on the given dimensions.
Definition: Domi_MDArray.hpp:1660
friend bool operator!=(const MDArrayView< T2 > &a1, const MDArray< T2 > &a2)
MDArrayView/MDArray inequality operator.
void assign(const T &value)
Assign a value to all elements of the MDArray
Definition: Domi_MDArray.hpp:1569
const_iterator cbegin() const
Return the beginning const_iterator.
Definition: Domi_MDArray.hpp:1111
reverse_iterator rend()
Return the ending reverse_iterator.
Definition: Domi_MDArray.hpp:1139
size_type size() const
Return the total size of the MDArray
Definition: Domi_MDArray.hpp:1037
const_reverse_iterator crbegin() const
Return the beginning const_reverse_iterator.
Definition: Domi_MDArray.hpp:1149
MDArrayView< T > operator()()
Conversion to non-const MDArrayView
Definition: Domi_MDArray.hpp:1267
friend bool operator==(const MDArrayView< T2 > &a1, const MDArray< T2 > &a2)
MDArrayView/MDArray equality operator.
int numDims() const
Return the number of dimensions.
Definition: Domi_MDArray.hpp:1007
dim_type dimension(int axis) const
Return the dimension of the given axis.
Definition: Domi_MDArray.hpp:1025
size_type capacity() const
Return the capacity of the underlying Teuchos::Array
Definition: Domi_MDArray.hpp:1619
bool empty() const
Return whether the MDArray is empty.
Definition: Domi_MDArray.hpp:1642
T value_type
Value type.
Definition: Domi_MDArray.hpp:294
iterator end()
Return the ending iterator.
Definition: Domi_MDArray.hpp:1082
iterator begin()
Return the beginning iterator.
Definition: Domi_MDArray.hpp:1073
const_iterator cend() const
Return the ending const_iterator.
Definition: Domi_MDArray.hpp:1120
friend void swap(MDArray< T2 > &a1, MDArray< T2 > &a2)
Swap function.
MDArrayView< T > mdArrayView()
Perform an explicit conversion to a non-const MDArrayView<T>
Definition: Domi_MDArray.hpp:1168
~MDArray()
Destructor.
Definition: Domi_MDArray.hpp:999
MDArrayView< const T > mdArrayViewConst()
Perform an explicit conversion to a non-const MDArrayView<const T>
Definition: Domi_MDArray.hpp:1189
Memory-safe templated multi-dimensional array view class.
Definition: Domi_MDArrayView.hpp:115
bool operator==(const MDArrayView< T > &a1, const MDArray< T > &a2)
MDArrayView/MDArray equality operator.
Definition: Domi_MDArray.hpp:1747
bool operator!=(const MDArrayView< T > &a1, const MDArray< T > &a2)
MDArrayView/MDArray inequality operator.
Definition: Domi_MDArray.hpp:1771
const_iterator cend() const
Return the ending const_iterator.
Definition: Domi_MDArrayView.hpp:1007
const_iterator cbegin() const
Return the beginning const_iterator.
Definition: Domi_MDArrayView.hpp:998
bool operator==(const MDArray< T > &a1, const MDArrayView< T > &a2)
MDArray/MDArrayView equality operator.
Definition: Domi_MDArray.hpp:1739
Iterator class suitable for multi-dimensional arrays.
Definition: Domi_MDIterator.hpp:102
Reverse iterator class suitable for multi-dimensional arrays.
Definition: Domi_MDRevIterator.hpp:100
Range Error exception type.
Definition: Domi_Exceptions.hpp:66
A Slice contains a start, stop, and step index, describing a subset of an ordered container.
Definition: Domi_Slice.hpp:138