Domi
Multi-dimensional, distributed data structures
Loading...
Searching...
No Matches
Domi_MDArray.hpp
1// @HEADER
2// ***********************************************************************
3//
4// Domi: Multi-dimensional Distributed Linear Algebra Services
5// Copyright (2014) Sandia Corporation
6//
7// Under the terms of Contract DE-AC04-94AL85000 with Sandia
8// Corporation, the U.S. Government retains certain rights in this
9// software.
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//
18// 2. Redistributions in binary form must reproduce the above copyright
19// notice, this list of conditions and the following disclaimer in the
20// documentation and/or other materials provided with the distribution.
21//
22// 3. Neither the name of the Corporation nor the names of the
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Questions? Contact William F. Spotz (wfspotz@sandia.gov)
39//
40// ***********************************************************************
41// @HEADER
42
43#ifndef DOMI_MDARRAY_HPP
44#define DOMI_MDARRAY_HPP
45
46// Standard includes
47#include <cstdarg>
48
49// Teuchos includes
50#include "Teuchos_Array.hpp"
51
52// Domi includes
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"
58
59namespace Domi
60{
61
62// I put these non-member template functions here for the same reason
63// that Ross did the same thing for the Teuchos::Array class. See
64// Teuchos_Array.hpp for details.
65template< typename T > class MDArray;
66
71template< typename T >
72bool operator==(const MDArray< T > & a1,
73 const MDArray< T > & a2);
74
80template< typename T >
81bool operator==(const MDArray< T > & a1,
82 const MDArrayView< T > & a2);
83
89template< typename T >
91 const MDArray< T > & a2);
92
97template< typename T >
98bool operator!=(const MDArray< T > & a1,
99 const MDArray< T > & a2);
100
105template< typename T >
106bool operator!=(const MDArray< T > & a1,
107 const MDArrayView< T > & a2);
108
114template< typename T >
116 const MDArray< T > & a2);
117
122template< typename T >
123void swap(MDArray< T > & a1, MDArray< T > & a2);
124
285template< typename T >
287{
288public:
289
292
294 typedef T value_type;
295
297 typedef T* pointer;
298
300 typedef const T* const_pointer;
301
303 typedef T& reference;
304
306 typedef const T& const_reference;
307
309
312
317 inline MDArray();
318
326 inline MDArray(const Teuchos::ArrayView< dim_type > & dims);
327
342 inline MDArray(const Teuchos::ArrayView< dim_type > & dims,
343 const T & value,
344 const Layout layout = DEFAULT_ORDER);
345
360 inline MDArray(const Teuchos::ArrayView< dim_type > & dims,
361 const Layout layout,
362 const T & value = value_type());
363
368 inline MDArray(const MDArray< T > & source);
369
374 MDArray(const MDArrayView< T > & source);
375
378 ~MDArray();
379
381
384
387 inline int numDims() const;
388
391 inline const Teuchos::Array< dim_type > & dimensions() const;
392
398 inline dim_type dimension(int axis) const;
399
402 inline size_type size() const;
403
406 inline const Teuchos::Array< size_type > & strides() const;
407
410 inline const Teuchos::Array< T > & array() const;
411
414 inline const Layout layout() const;
415
417
420
421 friend class MDIterator< MDArray< T > >;
422 friend class MDIterator< MDArray< const T > >;
423 friend class MDRevIterator< MDArray< T > >;
424 friend class MDRevIterator< MDArray< const T > >;
425
430
433 iterator begin();
434
437 iterator end();
438
441 const_iterator begin() const;
442
445 const_iterator end() const;
446
449 const_iterator cbegin() const;
450
453 const_iterator cend() const;
454
458
462
466
470
472
475
480
484 const MDArrayView< T > mdArrayView() const;
485
490
495
496#ifndef SWIG
500 inline operator MDArrayView< T >() const;
501
505 inline operator MDArrayView< const T >() const;
506#endif
507
509
512
522 MDArrayView< T > operator[](dim_type i);
523
533 const MDArrayView< T > operator[](dim_type i) const;
534
545
555 const MDArrayView< T > operator[](Slice s) const;
556
560
563 inline const MDArrayView< T > operator()() const;
564
566
570
579 inline T & operator()(dim_type i);
580
591 inline T & operator()(dim_type i, dim_type j);
592
605 inline T & operator()(dim_type i, dim_type j, dim_type k);
606
621 inline T & operator()(dim_type i, dim_type j, dim_type k, dim_type m);
622
639 inline T & operator()(dim_type i, dim_type j, dim_type k, dim_type m,
640 dim_type n);
641
663 inline T & operator()(dim_type i, dim_type j, dim_type k, dim_type m,
664 dim_type n, dim_type p, ...);
665
674 inline const T & operator()(dim_type i) const;
675
686 inline const T & operator()(dim_type i, dim_type j) const;
687
700 inline const T & operator()(dim_type i, dim_type j, dim_type k) const;
701
716 inline const T & operator()(dim_type i, dim_type j, dim_type k,
717 dim_type m) const;
718
735 inline const T & operator()(dim_type i, dim_type j, dim_type k,
736 dim_type m, dim_type n) const;
737
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;
761
763
766
771 void assign(const T & value);
772
781 T & at(dim_type i, ...);
782
791 const T & at(dim_type i, ...) const;
792
795 inline size_type capacity() const;
796
799 void clear();
800
803 inline bool empty() const;
804
807 inline size_type max_size() const;
808
813 void resize(const Teuchos::ArrayView< dim_type > & dims);
814
817 void swap(MDArray<T> & a);
818
822 inline static bool hasBoundsChecking();
823
826 std::string toString() const;
827
831 inline const T * getRawPtr() const;
832
836 inline T * getRawPtr();
837
839
840 // These operators are declared as friends so that the compiler will
841 // do automatic type conversion.
842
845
848 template< typename T2 >
849 friend bool operator==(const MDArray< T2 > & a1,
850 const MDArray< T2 > & a2);
851
854 template< typename T2 >
855 friend bool operator==(const MDArray< T2 > & a1,
856 const MDArrayView< T2 > & a2);
857
860 template< typename T2 >
861 friend bool operator==(const MDArrayView< T2 > & a1,
862 const MDArray< T2 > & a2);
863
866 template< typename T2 >
867 friend bool operator!=(const MDArray< T2 > & a1,
868 const MDArray< T2 > & a2);
869
872 template< typename T2 >
873 friend bool operator!=(const MDArray< T2 > & a1,
874 const MDArrayView< T2 > & a2);
875
878 template< typename T2 >
879 friend bool operator!=(const MDArrayView< T2 > & a1,
880 const MDArray< T2 > & a2);
881
884 template< typename T2 >
885 friend std::ostream & operator<<(std::ostream & os,
886 const MDArray< T2 > & a);
887
890 template< typename T2 >
891 friend void swap(MDArray< T2 > & a1,
892 MDArray< T2 > & a2);
893
895
896private:
897 Teuchos::Array< dim_type > _dimensions;
898 Teuchos::Array< size_type > _strides;
899 Teuchos::Array< T > _array;
900 Layout _layout;
901 pointer _ptr;
902
903 // Used for array bounds checking
904 void assertAxis(int axis) const;
905
906 // Used for array bounds checking
907 void assertIndex(dim_type i, int axis) const;
908};
909
911// Implementations //
913
914template< typename T >
916 _dimensions(Teuchos::tuple< dim_type >(0)),
917 _strides(Teuchos::tuple< size_type >(1)),
918 _array(),
919 _layout(DEFAULT_ORDER),
920 _ptr()
921{
922}
923
925
926template< typename T >
927MDArray< T >::MDArray(const Teuchos::ArrayView< dim_type > & dims) :
928 _dimensions(dims),
929 _strides(computeStrides< size_type, dim_type >(dims, DEFAULT_ORDER)),
930 _array(computeSize(dims)),
931 _layout(DEFAULT_ORDER),
932 _ptr(_array.getRawPtr())
933{
934}
935
937
938template< typename T >
939MDArray< T >::MDArray(const Teuchos::ArrayView< dim_type > & dims,
940 const T & value,
941 const Layout layout) :
942 _dimensions(dims),
943 _strides(computeStrides< size_type, dim_type >(dims, layout)),
944 _array(computeSize(dims), value),
945 _layout(layout),
946 _ptr(_array.getRawPtr())
947{
948}
949
951
952template< typename T >
953MDArray< T >::MDArray(const Teuchos::ArrayView< dim_type > & dims,
954 const Layout layout,
955 const T & value) :
956 _dimensions(dims),
957 _strides(computeStrides< size_type, dim_type >(dims, layout)),
958 _array(computeSize(dims), value),
959 _layout(layout),
960 _ptr(_array.getRawPtr())
961{
962}
963
965
966template< typename T >
968 _dimensions(source._dimensions),
969 _strides(source._strides),
970 _array(source._array),
971 _layout(source._layout),
972 _ptr(_array.getRawPtr())
973{
974}
975
977
978template< typename T >
980 _dimensions(source.dimensions()),
981 _strides(computeStrides< size_type, dim_type >(source.dimensions(),
982 source.layout())),
983 _array(computeSize(source.dimensions())),
984 _layout(source.layout()),
985 _ptr(_array.getRawPtr())
986{
987 // Copy the values from the MDArrayView to the MDArray
988 iterator thisit = begin();
989 typename MDArrayView< T >::const_iterator srcit = source.cbegin();
990 for ( ; srcit != source.cend(); ++thisit, ++srcit)
991 {
992 *thisit = *srcit;
993 }
994}
995
997
998template< typename T >
1000{
1001}
1002
1004
1005template< typename T >
1006int
1008{
1009 return _dimensions.size();
1010}
1011
1013
1014template< typename T >
1015const Teuchos::Array< dim_type > &
1017{
1018 return _dimensions;
1019}
1020
1022
1023template< typename T >
1024dim_type
1026{
1027#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1028 assertAxis(axis);
1029#endif
1030 return _dimensions[axis];
1031}
1032
1034
1035template< typename T >
1036size_type
1038{
1039 return _array.size();
1040}
1041
1043
1044template< typename T >
1045const Teuchos::Array< size_type > &
1047{
1048 return _strides;
1049}
1050
1052
1053template< typename T >
1054const Teuchos::Array< T > &
1056{
1057 return _array;
1058}
1059
1061
1062template< typename T >
1063const Layout
1065{
1066 return _layout;
1067}
1068
1070
1071template< typename T >
1074{
1075 return iterator(*this);
1076}
1077
1079
1080template< typename T >
1083{
1084 // Return the iterator corresponding to the last element
1085 return iterator(*this, true);
1086}
1087
1089
1090template< typename T >
1093{
1094 return const_iterator(*this);
1095}
1096
1098
1099template< typename T >
1102{
1103 // Return the iterator corresponding to the last element
1104 return const_iterator(*this, true);
1105}
1106
1108
1109template< typename T >
1112{
1113 return const_iterator(*this);
1114}
1115
1117
1118template< typename T >
1121{
1122 // Return the iterator corresponding to the last element
1123 return const_iterator(*this, true);
1124}
1125
1127
1128template< typename T >
1131{
1132 return reverse_iterator(*this);
1133}
1134
1136
1137template< typename T >
1140{
1141 // Return the reverse_iterator corresponding to the last element
1142 return reverse_iterator(*this, true);
1143}
1144
1146
1147template< typename T >
1150{
1151 return const_reverse_iterator(*this);
1152}
1153
1155
1156template< typename T >
1159{
1160 // Return the reverse_iterator corresponding to the last element
1161 return const_reverse_iterator(*this, true);
1162}
1163
1165
1166template< typename T >
1169{
1170 return MDArrayView< T >(_array(), _dimensions, _layout);
1171}
1172
1174
1175template< typename T >
1176const MDArrayView< T >
1178{
1179 Teuchos::ArrayView< T > array(const_cast< T* >(_array.getRawPtr()),
1180 _array.size());
1181 Teuchos::Array< dim_type > dims(_dimensions);
1182 return MDArrayView< T >(array, dims(), _layout);
1183}
1184
1186
1187template< typename T >
1190{
1191 return MDArrayView< const T >(_array, _dimensions(), _layout);
1192}
1193
1195
1196template< typename T >
1199{
1200 return MDArrayView< const T >(_array, _dimensions(), _layout);
1201}
1202
1204
1205#ifndef SWIG
1206template< typename T >
1208{
1209 return mdArrayView();
1210}
1211
1213
1214template< typename T >
1216{
1217 return mdArrayViewConst();
1218}
1219#endif
1220
1222
1223template< typename T >
1226{
1227 // Note: array bounds checking, if active, will be performed by the
1228 // MDArrayView class
1229 return mdArrayView()[i];
1230}
1231
1233
1234template< typename T >
1235const MDArrayView< T >
1237{
1238 // Note: array bounds checking, if active, will be performed by the
1239 // MDArrayView class
1240 return mdArrayView()[i];
1241}
1242
1244
1245template< typename T >
1248{
1249 // Note: Slices produce safe indexes
1250 return mdArrayView()[s];
1251}
1252
1254
1255template< typename T >
1256const MDArrayView< T >
1258{
1259 // Note: Slices produce safe indexes
1260 return mdArrayView()[s];
1261}
1262
1264
1265template< typename T >
1268{
1269 return mdArrayView();
1270}
1271
1273
1274template< typename T >
1275const MDArrayView< T >
1277{
1278 return mdArrayView();
1279}
1280
1282
1283template< typename T >
1284T &
1286{
1287#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1288 TEUCHOS_TEST_FOR_EXCEPTION(
1289 (_dimensions.size() != 1), RangeError,
1290 "Attempt to access " << _dimensions.size() << "D array with 1 index"
1291 );
1292 assertIndex(i, 0);
1293#endif
1294 return _ptr[i * _strides[0]];
1295}
1296
1298
1299template< typename T >
1300T &
1302 dim_type j)
1303{
1304#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1305 TEUCHOS_TEST_FOR_EXCEPTION(
1306 (_dimensions.size() != 2), RangeError,
1307 "Attempt to access " << _dimensions.size() << "D array with 2 indexes"
1308 );
1309 assertIndex(i, 0);
1310 assertIndex(j, 1);
1311#endif
1312 return _ptr[i * _strides[0] + j * _strides[1]];
1313}
1314
1316
1317template< typename T >
1318T &
1320 dim_type j,
1321 dim_type k)
1322{
1323#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1324 TEUCHOS_TEST_FOR_EXCEPTION(
1325 (_dimensions.size() != 3), RangeError,
1326 "Attempt to access " << _dimensions.size() << "D array with 3 indexes"
1327 );
1328 assertIndex(i, 0);
1329 assertIndex(j, 1);
1330 assertIndex(k, 2);
1331#endif
1332 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2]];
1333}
1334
1336
1337template< typename T >
1338T &
1340 dim_type j,
1341 dim_type k,
1342 dim_type m)
1343{
1344#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1345 TEUCHOS_TEST_FOR_EXCEPTION(
1346 (_dimensions.size() != 4), RangeError,
1347 "Attempt to access " << _dimensions.size() << "D array with 4 indexes"
1348 );
1349 assertIndex(i, 0);
1350 assertIndex(j, 1);
1351 assertIndex(k, 2);
1352 assertIndex(m, 3);
1353#endif
1354 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2] +
1355 m * _strides[3]];
1356}
1357
1359
1360template< typename T >
1361T &
1363 dim_type j,
1364 dim_type k,
1365 dim_type m,
1366 dim_type n)
1367{
1368#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1369 TEUCHOS_TEST_FOR_EXCEPTION(
1370 (_dimensions.size() != 5), RangeError,
1371 "Attempt to access " << _dimensions.size() << "D array with 5 indexes"
1372 );
1373 assertIndex(i, 0);
1374 assertIndex(j, 1);
1375 assertIndex(k, 2);
1376 assertIndex(m, 3);
1377 assertIndex(n, 4);
1378#endif
1379 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2] +
1380 m * _strides[3] + n * _strides[4]];
1381}
1382
1384
1385template< typename T >
1386T &
1388 dim_type j,
1389 dim_type k,
1390 dim_type m,
1391 dim_type n,
1392 dim_type p,
1393 ...)
1394{
1395#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1396 TEUCHOS_TEST_FOR_EXCEPTION(
1397 (_dimensions.size() < 6), RangeError,
1398 "Attempt to access " << _dimensions.size() << "D array with too many indexes"
1399 );
1400 assertIndex(i, 0);
1401 assertIndex(j, 1);
1402 assertIndex(k, 2);
1403 assertIndex(m, 3);
1404 assertIndex(n, 4);
1405 assertIndex(p, 5);
1406#endif
1407 va_list 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++)
1412 {
1413 dim_type q = va_arg(indexes, dim_type);
1414#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1415 assertIndex(q, axis);
1416#endif
1417 offset += q * _strides[axis];
1418 }
1419 va_end(indexes);
1420 return _ptr[offset];
1421}
1422
1424
1425template< typename T >
1426const T &
1428{
1429#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1430 TEUCHOS_TEST_FOR_EXCEPTION(
1431 (_dimensions.size() != 1), RangeError,
1432 "Attempt to access " << _dimensions.size() << "D array with 1 index"
1433 );
1434 assertIndex(i, 0);
1435#endif
1436 return _ptr[i * _strides[0]];
1437}
1438
1440
1441template< typename T >
1442const T &
1444 dim_type j) const
1445{
1446#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1447 TEUCHOS_TEST_FOR_EXCEPTION(
1448 (_dimensions.size() != 2), RangeError,
1449 "Attempt to access " << _dimensions.size() << "D array with 2 indexes"
1450 );
1451 assertIndex(i, 0);
1452 assertIndex(j, 1);
1453#endif
1454 return _ptr[i * _strides[0] + j * _strides[1]];
1455}
1456
1458
1459template< typename T >
1460const T &
1462 dim_type j,
1463 dim_type k) const
1464{
1465#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1466 TEUCHOS_TEST_FOR_EXCEPTION(
1467 (_dimensions.size() != 3), RangeError,
1468 "Attempt to access " << _dimensions.size() << "D array with 3 indexes"
1469 );
1470 assertIndex(i, 0);
1471 assertIndex(j, 1);
1472 assertIndex(k, 2);
1473#endif
1474 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2]];
1475}
1476
1478
1479template< typename T >
1480const T &
1482 dim_type j,
1483 dim_type k,
1484 dim_type m) const
1485{
1486#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1487 TEUCHOS_TEST_FOR_EXCEPTION(
1488 (_dimensions.size() != 4), RangeError,
1489 "Attempt to access " << _dimensions.size() << "D array with 4 indexes"
1490 );
1491 assertIndex(i, 0);
1492 assertIndex(j, 1);
1493 assertIndex(k, 2);
1494 assertIndex(m, 3);
1495#endif
1496 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2] +
1497 m * _strides[3]];
1498}
1499
1501
1502template< typename T >
1503const T &
1505 dim_type j,
1506 dim_type k,
1507 dim_type m,
1508 dim_type n) const
1509{
1510#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1511 TEUCHOS_TEST_FOR_EXCEPTION(
1512 (_dimensions.size() != 5), RangeError,
1513 "Attempt to access " << _dimensions.size() << "D array with 5 indexes"
1514 );
1515 assertIndex(i, 0);
1516 assertIndex(j, 1);
1517 assertIndex(k, 2);
1518 assertIndex(m, 3);
1519 assertIndex(n, 4);
1520#endif
1521 return _ptr[i * _strides[0] + j * _strides[1] + k * _strides[2] +
1522 m * _strides[3] + n * _strides[4]];
1523}
1524
1526
1527template< typename T >
1528const T &
1530 dim_type j,
1531 dim_type k,
1532 dim_type m,
1533 dim_type n,
1534 dim_type p,
1535 ...) const
1536{
1537#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1538 TEUCHOS_TEST_FOR_EXCEPTION(
1539 (_dimensions.size() < 6), RangeError,
1540 "Attempt to access " << _dimensions.size() << "D array with too many indexes"
1541 );
1542 assertIndex(i, 0);
1543 assertIndex(j, 1);
1544 assertIndex(k, 2);
1545 assertIndex(m, 3);
1546 assertIndex(n, 4);
1547 assertIndex(p, 5);
1548#endif
1549 va_list 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++)
1554 {
1555 dim_type q = va_arg(indexes, dim_type);
1556#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1557 assertIndex(q, axis);
1558#endif
1559 offset += q * _strides[axis];
1560 }
1561 va_end(indexes);
1562 return _ptr[offset];
1563}
1564
1566
1567template< typename T >
1568void
1569MDArray< T >::assign(const T & value)
1570{
1571 for (iterator it = begin(); it != end(); ++it)
1572 *it = value;
1573}
1574
1576
1577template< typename T >
1578T &
1579MDArray< T >::at(dim_type i, ...)
1580{
1581 assertIndex(i, 0);
1582 va_list indexes;
1583 size_type offset = i * _strides[0];
1584 va_start(indexes, i);
1585 for (int axis = 1; axis < _dimensions.size(); axis++)
1586 {
1587 dim_type j = va_arg(indexes, dim_type);
1588 assertIndex(j, axis);
1589 offset += j * _strides[axis];
1590 }
1591 va_end(indexes);
1592 return _ptr[offset];
1593}
1594
1596
1597template< typename T >
1598const T &
1599MDArray< T >::at(dim_type i, ...) const
1600{
1601 assertIndex(i, 0);
1602 va_list indexes;
1603 size_type offset = i * _strides[0];
1604 va_start(indexes, i);
1605 for (int axis = 1; axis < _dimensions.size(); axis++)
1606 {
1607 dim_type j = va_arg(indexes, dim_type);
1608 assertIndex(j, axis);
1609 offset += j * _strides[axis];
1610 }
1611 va_end(indexes);
1612 return _ptr[offset];
1613}
1614
1616
1617template< typename T >
1618size_type
1620{
1621 return _array.capacity();
1622}
1623
1625
1626template< typename T >
1627void
1629{
1630 _dimensions.resize(1);
1631 _dimensions[0] = 0;
1632 _strides.resize(1);
1633 _strides[0] = 1;
1634 _array.clear();
1635 _ptr = _array.getRawPtr();
1636}
1637
1639
1640template< typename T >
1641bool
1643{
1644 return _array.empty();
1645}
1646
1648
1649template< typename T >
1650size_type
1652{
1653 return _array.max_size();
1654}
1655
1657
1658template< typename T >
1659void
1660MDArray< T >::resize(const Teuchos::ArrayView< dim_type > & dims)
1661{
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();
1666}
1667
1669
1670template< typename T >
1671void
1673{
1674 // Use Teuchos::swap() to swap the dimensions, strides and
1675 // underlying array
1676 Teuchos::swap(_dimensions, a._dimensions);
1677 Teuchos::swap(_strides, a._strides );
1678 Teuchos::swap(_array, a._array );
1679 // Perform a raw swap of the storage order
1680 Layout tmp = _layout;
1681 _layout = a._layout;
1682 a._layout = tmp;
1683 // Make sure the pointers are correct
1684 _ptr = _array.getRawPtr();
1685 a._ptr = a._array.getRawPtr();
1686}
1687
1689
1690template< typename T >
1691bool
1693{
1694#ifdef HAVE_DOMI_ARRAY_BOUNDSCHECK
1695 return true;
1696#else
1697 return false;
1698#endif
1699}
1700
1702
1703template< typename T >
1704std::string
1706{
1707 return mdArrayView().toString();
1708}
1709
1711
1712template< typename T >
1713const T *
1715{
1716 return _array.getRawPtr();
1717}
1718
1720
1721template< typename T >
1722T *
1724{
1725 return _array.getRawPtr();
1726}
1727
1729
1730template< typename T >
1731bool operator==(const MDArray< T > & a1, const MDArray< T > & a2)
1732{
1733 return (a1() == a2());
1734}
1735
1737
1738template< typename T >
1739bool operator==(const MDArray< T > & a1, const MDArrayView< T > & a2)
1740{
1741 return (a1() == a2);
1742}
1743
1745
1746template< typename T >
1747bool operator==(const MDArrayView< T > & a1, const MDArray< T > & a2)
1748{
1749 return (a1 == a2());
1750}
1751
1753
1754template< typename T >
1755bool operator!=(const MDArray< T > & a1, const MDArray< T > & a2)
1756{
1757 return not (a1 == a2);
1758}
1759
1761
1762template< typename T >
1763bool operator!=(const MDArray< T > & a1, const MDArrayView< T > & a2)
1764{
1765 return (a1() != a2);
1766}
1767
1769
1770template< typename T >
1771bool operator!=(const MDArrayView< T > & a1, const MDArray< T > & a2)
1772{
1773 return (a1 != a2());
1774}
1775
1777
1778template< typename T >
1779std::ostream & operator<<(std::ostream & os, const MDArray< T > & a)
1780{
1781 os << a.toString();
1782 return os;
1783}
1784
1786
1787template< typename T >
1788void swap(MDArray< T > & a1, MDArray< T > & a2)
1789{
1790 a1.swap(a2);
1791}
1792
1794// Private implementations //
1796
1797template< typename T >
1798void
1799MDArray< T >::assertAxis(int axis) const
1800{
1801 TEUCHOS_TEST_FOR_EXCEPTION(
1802 !(0 <= axis && axis < _dimensions.size()),
1803 RangeError,
1804 "MDArray<T>::assertAxis(axis=" << axis << "): out of range "
1805 << "axis in [0, " << _dimensions.size() << ")"
1806 );
1807}
1808
1810
1811template< typename T >
1812void
1813MDArray< T >::assertIndex(dim_type i, int axis) const
1814{
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] << ")"
1819 );
1820}
1821
1822} // end namespace Domi
1823
1824#endif
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

Generated for Domi by doxygen 1.9.6