7 #ifndef ANDRES_MARRAY_HXX
8 #define ANDRES_MARRAY_HXX
24 #ifdef HAVE_CPP11_INITIALIZER_LISTS
25 #include <initializer_list>
40 template<
class E,
class T>
43 template<
class E,
class T,
class UnaryFunctor>
44 class UnaryViewExpression;
45 template<
class E1,
class T1,
class E2,
class T2,
class BinaryFunctor>
46 class BinaryViewExpression;
47 template<
class E,
class T,
class S,
class BinaryFunctor>
48 class BinaryViewExpressionScalarFirst;
49 template<
class E,
class T,
class S,
class BinaryFunctor>
50 class BinaryViewExpressionScalarSecond;
52 template<
class T,
bool isConst = false,
class A = std::allocator<std::
size_t> >
54 #ifdef HAVE_CPP11_TEMPLATE_ALIASES
57 template<
class T,
bool isConst,
class A = std::allocator<std::
size_t> >
59 template<
class T,
class A = std::allocator<std::
size_t> >
class Marray;
71 namespace marray_detail {
73 template <
bool PREDICATE,
class TRUECASE,
class FALSECASE>
75 template <
class TRUECASE,
class FALSECASE>
76 struct IfBool<true, TRUECASE, FALSECASE>
77 {
typedef TRUECASE type; };
78 template <
class TRUECASE,
class FALSECASE>
79 struct IfBool<false, TRUECASE, FALSECASE>
80 {
typedef FALSECASE type; };
82 template <
class T1,
class T2>
84 {
static const bool type =
false; };
87 {
static const bool type =
true; };
89 template<
class T>
struct TypeTraits
90 {
static const unsigned char position = 255; };
91 template<>
struct TypeTraits<char>
92 {
static const unsigned char position = 0; };
93 template<>
struct TypeTraits<unsigned char>
94 {
static const unsigned char position = 1; };
95 template<>
struct TypeTraits<short>
96 {
static const unsigned char position = 2; };
97 template<>
struct TypeTraits<unsigned short>
98 {
static const unsigned char position = 3; };
99 template<>
struct TypeTraits<int>
100 {
static const unsigned char position = 4; };
101 template<>
struct TypeTraits<unsigned int>
102 {
static const unsigned char position = 5; };
103 template<>
struct TypeTraits<long>
104 {
static const unsigned char position = 6; };
105 template<>
struct TypeTraits<unsigned long>
106 {
static const unsigned char position = 7; };
107 template<>
struct TypeTraits<float>
108 {
static const unsigned char position = 8; };
109 template<>
struct TypeTraits<double>
110 {
static const unsigned char position = 9; };
111 template<>
struct TypeTraits<long double>
112 {
static const unsigned char position = 10; };
113 template<
class A,
class B>
struct PromoteType
114 {
typedef typename IfBool<TypeTraits<A>::position >= TypeTraits<B>::position, A, B>::type type; };
117 template<
class A>
inline void Assert(A assertion) {
118 if(!assertion)
throw std::runtime_error(
"Assertion failed.");
122 template<
class A = std::allocator<std::
size_t> >
class Geometry;
123 template<
class ShapeIterator,
class Str
idesIterator>
124 inline void stridesFromShape(ShapeIterator, ShapeIterator,
128 template<
class Functor,
class T,
class A>
130 template<
class Functor,
class T,
class A>
132 template<
class Functor,
class T1,
class T2,
bool isConst,
class A>
134 template<
class Functor,
class T1,
class A,
class E,
class T2>
138 template<
unsigned short N,
class Functor,
class T,
class A>
139 struct OperateHelperUnary;
140 template<
unsigned short N,
class Functor,
class T1,
class T2,
class A>
141 struct OperateHelperBinaryScalar;
142 template<
unsigned short N,
class Functor,
class T1,
class T2,
143 bool isConst,
class A1,
class A2>
144 struct OperateHelperBinary;
145 template<
bool isConstTo,
class TFrom,
class TTo,
class AFrom,
class ATo>
146 struct AssignmentOperatorHelper;
147 template<
bool isIntegral>
148 struct AccessOperatorHelper;
152 struct Negative {
void operator()(T& x) { x = -x; } };
154 struct PrefixIncrement {
void operator()(T& x) { ++x; } };
156 struct PostfixIncrement {
void operator()(T& x) { x++; } };
158 struct PrefixDecrement {
void operator()(T& x) { --x; } };
160 struct PostfixDecrement {
void operator()(T& x) { x--; } };
163 template<
class T1,
class T2>
164 struct Assign {
void operator()(T1& x,
const T2& y) { x = y; } };
165 template<
class T1,
class T2>
166 struct PlusEqual {
void operator()(T1& x,
const T2& y) { x += y; } };
167 template<
class T1,
class T2>
168 struct MinusEqual {
void operator()(T1& x,
const T2& y) { x -= y; } };
169 template<
class T1,
class T2>
170 struct TimesEqual {
void operator()(T1& x,
const T2& y) { x *= y; } };
171 template<
class T1,
class T2>
172 struct DividedByEqual {
void operator()(T1& x,
const T2& y) { x /= y; } };
176 struct Negate { T operator()(
const T& x)
const {
return -x; } };
179 template<
class T1,
class T2,
class U>
180 struct Plus { U operator()(
const T1& x,
const T2& y)
const {
return x + y; } };
181 template<
class T1,
class T2,
class U>
182 struct Minus { U operator()(
const T1& x,
const T2& y)
const {
return x - y; } };
183 template<
class T1,
class T2,
class U>
184 struct Times { U operator()(
const T1& x,
const T2& y)
const {
return x * y; } };
185 template<
class T1,
class T2,
class U>
186 struct DividedBy { U operator()(
const T1& x,
const T2& y)
const {
return x / y; } };
208 template<
class T,
bool isConst,
class A>
214 typedef typename marray_detail::IfBool<isConst, const T*, T*>::type
pointer;
216 typedef typename marray_detail::IfBool<isConst, const T&, T&>::type
reference;
229 template<
class ShapeIterator>
234 template<
class ShapeIterator,
class Str
ideIterator>
235 View(ShapeIterator, ShapeIterator, StrideIterator,
238 #ifdef HAVE_CPP11_INITIALIZER_LISTS
243 View(std::initializer_list<std::size_t>, std::initializer_list<std::size_t>,
252 template<
class TLocal,
bool isConstLocal,
class ALocal>
254 template<
class E,
class Te>
259 template<
class ShapeIterator>
264 template<
class ShapeIterator,
class Str
ideIterator>
265 void assign(ShapeIterator, ShapeIterator, StrideIterator,
268 #ifdef HAVE_CPP11_INITIALIZER_LISTS
273 void assign(std::initializer_list<std::size_t>,
274 std::initializer_list<std::size_t>,
pointer,
281 const std::size_t
size()
const;
282 const std::size_t
shape(
const std::size_t)
const;
284 const std::size_t*
shapeEnd()
const;
285 const std::size_t
strides(
const std::size_t)
const;
290 template<
class TLocal,
bool isConstLocal,
class ALocal>
296 #ifndef HAVE_CPP11_VARIADIC_TEMPLATES
304 const std::size_t)
const;
306 const std::size_t,
const std::size_t);
308 const std::size_t,
const std::size_t)
const;
310 const std::size_t,
const std::size_t,
const std::size_t,
const std::size_t,
311 const std::size_t,
const std::size_t,
const std::size_t);
313 const std::size_t,
const std::size_t,
const std::size_t,
const std::size_t,
314 const std::size_t,
const std::size_t,
const std::size_t)
const;
318 template<
typename... Args>
320 template<
typename... Args>
323 std::size_t elementAccessHelper(
const std::size_t,
const std::size_t);
324 std::size_t elementAccessHelper(
const std::size_t,
const std::size_t)
const;
325 template<
typename... Args>
326 std::size_t elementAccessHelper(
const std::size_t,
const std::size_t,
328 template<
typename... Args>
329 std::size_t elementAccessHelper(
const std::size_t,
const std::size_t,
330 const Args...)
const;
335 template<
class BaseIterator,
class ShapeIterator>
337 template<
class BaseIterator,
class ShapeIterator>
340 template<
class BaseIterator,
class ShapeIterator>
342 template<
class BaseIterator,
class ShapeIterator>
345 template<
class BaseIterator,
class ShapeIterator>
347 template<
class BaseIterator,
class ShapeIterator>
350 template<
class BaseIterator,
class ShapeIterator>
352 template<
class BaseIterator,
class ShapeIterator>
355 #ifdef HAVE_CPP11_INITIALIZER_LISTS
356 void view(std::initializer_list<std::size_t>,
358 void view(std::initializer_list<std::size_t>,
361 void constView(std::initializer_list<std::size_t>,
363 void constView(std::initializer_list<std::size_t>,
379 template<
class ShapeIterator>
380 void reshape(ShapeIterator, ShapeIterator);
381 template<
class CoordinateIterator>
382 void permute(CoordinateIterator);
383 void transpose(
const std::size_t,
const std::size_t);
385 void shift(
const int);
388 template<
class ShapeIterator>
390 template<
class CoordinateIterator>
398 #ifdef HAVE_CPP11_INITIALIZER_LISTS
399 void reshape(std::initializer_list<std::size_t>);
400 void permute(std::initializer_list<std::size_t>);
407 template<
class CoordinateIterator>
409 template<
class CoordinateIterator>
411 template<
class CoordinateIterator>
414 #ifdef HAVE_CPP11_INITIALIZER_LISTS
425 typedef typename marray_detail::Geometry<A> geometry_type;
429 void updateSimplicity();
430 void testInvariant()
const;
433 const T& operator[](
const std::size_t)
const;
434 T& operator[](
const std::size_t);
438 geometry_type geometry_;
440 template<
class TLocal,
bool isConstLocal,
class ALocal>
442 template<
class TLocal,
class ALocal>
445 template<
bool isConstTo,
class TFrom,
class TTo,
class AFrom,
class ATo>
446 friend struct marray_detail::AssignmentOperatorHelper;
447 friend struct marray_detail::AccessOperatorHelper<true>;
448 friend struct marray_detail::AccessOperatorHelper<false>;
450 template<
class E,
class U>
452 template<
class E,
class U,
class UnaryFunctor>
453 friend class UnaryViewExpression;
454 template<
class E1,
class T1,
class E2,
class T2,
class BinaryFunctor>
455 friend class BinaryViewExpression;
456 template<
class E,
class U,
class S,
class BinaryFunctor>
457 friend class BinaryViewExpressionScalarFirst;
458 template<
class E,
class U,
class S,
class BinaryFunctor>
459 friend class BinaryViewExpressionScalarSecond;
461 template<
class Functor,
class T1,
class Alocal,
class E,
class T2>
471 template<
class T,
bool isConst,
class A>
479 typedef typename marray_detail::IfBool<isConst, const T*, T*>::type
pointer;
480 typedef typename marray_detail::IfBool<isConst, const T&, T&>::type
reference;
483 typedef typename marray_detail::IfBool<isConst, const View<T, true, A>*,
485 typedef typename marray_detail::IfBool<isConst, const View<T, true, A>&,
509 template<
bool isConstLocal>
511 template<
bool isConstLocal>
513 template<
bool isConstLocal>
515 template<
bool isConstLocal>
516 bool operator<(const Iterator<T, isConstLocal, A>&)
const;
517 template<
bool isConstLocal>
519 template<
bool isConstLocal>
520 bool operator<=(const Iterator<T, isConstLocal, A>&)
const;
521 template<
bool isConstLocal>
526 std::size_t
index()
const;
527 template<
class CoordinateIterator>
531 void testInvariant()
const;
537 std::vector<std::size_t> coordinates_;
544 template<
class T,
class A>
546 :
public View<T, false, A>
565 template<
class ShapeIterator>
566 Marray(ShapeIterator, ShapeIterator,
const T& = T(),
569 template<
class ShapeIterator>
573 #ifdef HAVE_CPP11_INITIALIZER_LISTS
574 Marray(std::initializer_list<std::size_t>,
const T& = T(),
579 template<
class E,
class Te>
582 template<
class TLocal,
bool isConstLocal,
class ALocal>
589 template<
class TLocal,
bool isConstLocal,
class ALocal>
591 template<
class E,
class Te>
596 template<
class ShapeIterator>
597 void resize(ShapeIterator, ShapeIterator,
const T& = T());
598 template<
class ShapeIterator>
600 #ifdef HAVE_CPP11_INITIALIZER_LISTS
601 void resize(std::initializer_list<std::size_t>,
const T& = T());
606 typedef typename base::geometry_type geometry_type;
608 void testInvariant()
const;
609 template<
bool SKIP_INITIALIZATION,
class ShapeIterator>
610 void resizeHelper(ShapeIterator, ShapeIterator,
const T& = T());
617 #ifdef HAVE_CPP11_INITIALIZER_LISTS
624 template<
class T,
bool isConst,
class A>
628 std::initializer_list<std::size_t> coordinate,
632 coordinatesToIndex(coordinate.begin(), out);
642 template<
class T,
bool isConst,
class A>
643 template<
class CoordinateIterator>
647 CoordinateIterator it,
653 for(std::size_t j=0; j<this->dimension(); ++j, ++it) {
654 marray_detail::Assert(
MARRAY_NO_ARG_TEST || static_cast<std::size_t>(*it) < shape(j));
655 out +=
static_cast<std::size_t
>(*it) * geometry_.shapeStrides(j);
659 #ifdef HAVE_CPP11_INITIALIZER_LISTS
666 template<
class T,
bool isConst,
class A>
670 std::initializer_list<std::size_t> coordinate,
674 coordinatesToOffset(coordinate.begin(), out);
684 template<
class T,
bool isConst,
class A>
685 template<
class CoordinateIterator>
689 CoordinateIterator it,
695 for(std::size_t j=0; j<this->dimension(); ++j, ++it) {
696 marray_detail::Assert(
MARRAY_NO_ARG_TEST || static_cast<std::size_t>(*it) < shape(j));
697 out +=
static_cast<std::size_t
>(*it) * strides(j);
708 template<
class T,
bool isConst,
class A>
709 template<
class CoordinateIterator>
714 CoordinateIterator outit
721 for(std::size_t j=0; j<this->dimension(); ++j, ++outit) {
722 *outit = std::size_t(index / geometry_.shapeStrides(j));
723 index = index % geometry_.shapeStrides(j);
727 std::size_t j = this->dimension()-1;
730 *outit = std::size_t(index / geometry_.shapeStrides(j));
731 index = index % geometry_.shapeStrides(j);
749 template<
class T,
bool isConst,
class A>
765 for(std::size_t j=0; j<this->dimension(); ++j) {
766 out += geometry_.strides(j) * (index / geometry_.shapeStrides(j));
767 index = index % geometry_.shapeStrides(j);
771 if(this->dimension() == 0) {
776 std::size_t j = this->dimension()-1;
778 out += geometry_.strides(j) * (index / geometry_.shapeStrides(j));
779 index = index % geometry_.shapeStrides(j);
799 template<
class T,
bool isConst,
class A>
806 geometry_(geometry_type(allocator))
812 template<
class T,
bool isConst,
class A>
817 const geometry_type& geometry
830 template<
class T,
bool isConst,
class A>
838 geometry_(geometry_type(0,
defaultOrder, 1,
true, allocator))
847 template<
class T,
bool isConst,
class A>
854 geometry_(in.geometry_)
872 template<
class T,
bool isConst,
class A>
873 template<
class ShapeIterator>
885 geometry_(begin, end, externalCoordinateOrder,
886 internalCoordinateOrder, allocator)
903 template<
class T,
bool isConst,
class A>
904 template<
class ShapeIterator,
class Str
ideIterator>
916 geometry_(begin, end, it, internalCoordinateOrder, allocator)
921 #ifdef HAVE_CPP11_INITIALIZER_LISTS
932 template<
class T,
bool isConst,
class A>
936 std::initializer_list<std::size_t> shape,
940 const allocator_type& allocator
943 geometry_(shape.begin(), shape.end(), externalCoordinateOrder,
944 internalCoordinateOrder, allocator)
957 template<
class T,
bool isConst,
class A>
961 std::initializer_list<std::size_t> shape,
962 std::initializer_list<std::size_t> strides,
965 const allocator_type& allocator
968 geometry_(shape.begin(), shape.end(), strides.begin(),
969 internalCoordinateOrder, allocator)
982 template<
class T,
bool isConst,
class A>
989 geometry_ = geometry_type(allocator);
1006 template<
class T,
bool isConst,
class A>
1007 template<
class ShapeIterator>
1011 ShapeIterator begin,
1022 geometry_ =
typename marray_detail::Geometry<A>(begin, end,
1023 externalCoordinateOrder, internalCoordinateOrder, allocator);
1040 template<
class T,
bool isConst,
class A>
1041 template<
class ShapeIterator,
class Str
ideIterator>
1045 ShapeIterator begin,
1056 geometry_ =
typename marray_detail::Geometry<A>(begin, end,
1057 it, internalCoordinateOrder, allocator);
1062 #ifdef HAVE_CPP11_INITIALIZER_LISTS
1073 template<
class T,
bool isConst,
class A>
1077 std::initializer_list<std::size_t> shape,
1081 const allocator_type& allocator
1084 assign(shape.begin(), shape.end(), data, externalCoordinateOrder,
1085 internalCoordinateOrder, allocator);
1098 template<
class T,
bool isConst,
class A>
1102 std::initializer_list<std::size_t> shape,
1103 std::initializer_list<std::size_t> strides,
1106 const allocator_type& allocator
1109 assign(shape.begin(), shape.end(), strides.begin(), data,
1110 internalCoordinateOrder, allocator);
1121 template<
class T,
bool isConst,
class A>
1123 inline typename View<T, isConst, A>::reference
1124 View<T, isConst, A>::operator()
1129 return marray_detail::AccessOperatorHelper<std::numeric_limits<U>::is_integer>::execute(*
this, u);
1139 template<
class T,
bool isConst,
class A>
1147 return marray_detail::AccessOperatorHelper<std::numeric_limits<U>::is_integer>::execute(*
this, u);
1150 #ifndef HAVE_CPP11_VARIADIC_TEMPLATES
1160 template<
class T,
bool isConst,
class A>
1164 const std::size_t c0,
1165 const std::size_t c1
1169 marray_detail::Assert(
MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 2));
1171 return data_[c0*strides(0) + c1*strides(1)];
1182 template<
class T,
bool isConst,
class A>
1186 const std::size_t c0,
1187 const std::size_t c1
1191 marray_detail::Assert(
MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 2));
1193 return data_[c0*strides(0) + c1*strides(1)];
1205 template<
class T,
bool isConst,
class A>
1209 const std::size_t c0,
1210 const std::size_t c1,
1211 const std::size_t c2
1215 marray_detail::Assert(
MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 3));
1218 return data_[c0*strides(0) + c1*strides(1) + c2*strides(2)];
1230 template<
class T,
bool isConst,
class A>
1234 const std::size_t c0,
1235 const std::size_t c1,
1236 const std::size_t c2
1240 marray_detail::Assert(
MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 3));
1243 return data_[c0*strides(0) + c1*strides(1) + c2*strides(2)];
1256 template<
class T,
bool isConst,
class A>
1260 const std::size_t c0,
1261 const std::size_t c1,
1262 const std::size_t c2,
1263 const std::size_t c3
1267 marray_detail::Assert(
MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 4));
1269 && c2 < shape(2) && c3 < shape(3)));
1270 return data_[c0*strides(0) + c1*strides(1) + c2*strides(2)
1284 template<
class T,
bool isConst,
class A>
1288 const std::size_t c0,
1289 const std::size_t c1,
1290 const std::size_t c2,
1291 const std::size_t c3
1295 marray_detail::Assert(
MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 4));
1297 && c2 < shape(2) && c3 < shape(3)));
1298 return data_[c0*strides(0) + c1*strides(1) + c2*strides(2)
1313 template<
class T,
bool isConst,
class A>
1317 const std::size_t c0,
1318 const std::size_t c1,
1319 const std::size_t c2,
1320 const std::size_t c3,
1321 const std::size_t c4
1325 marray_detail::Assert(
MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 5));
1327 && c2 < shape(2) && c3 < shape(3) && c4 < shape(4)));
1328 return data_[c0*strides(0) + c1*strides(1) + c2*strides(2)
1329 + c3*strides(3) + c4*strides(4)];
1343 template<
class T,
bool isConst,
class A>
1347 const std::size_t c0,
1348 const std::size_t c1,
1349 const std::size_t c2,
1350 const std::size_t c3,
1351 const std::size_t c4
1355 marray_detail::Assert(
MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 5));
1357 && c2 < shape(2) && c3 < shape(3) && c4 < shape(4)));
1358 return data_[c0*strides(0) + c1*strides(1) + c2*strides(2)
1359 + c3*strides(3) + c4*strides(4)];
1379 template<
class T,
bool isConst,
class A>
1383 const std::size_t c0,
1384 const std::size_t c1,
1385 const std::size_t c2,
1386 const std::size_t c3,
1387 const std::size_t c4,
1388 const std::size_t c5,
1389 const std::size_t c6,
1390 const std::size_t c7,
1391 const std::size_t c8,
1392 const std::size_t c9
1396 marray_detail::Assert(
MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 10));
1398 && c2 < shape(2) && c3 < shape(3) && c4 < shape(4)
1399 && c5 < shape(5) && c6 < shape(6) && c7 < shape(7)
1400 && c8 < shape(8) && c9 < shape(9)));
1401 return data_[c0*strides(0) + c1*strides(1) + c2*strides(2)
1402 + c3*strides(3) + c4*strides(4) + c5*strides(5) + c6*strides(6)
1403 + c7*strides(7) + c8*strides(8) + c9*strides(9)];
1422 template<
class T,
bool isConst,
class A>
1426 const std::size_t c0,
1427 const std::size_t c1,
1428 const std::size_t c2,
1429 const std::size_t c3,
1430 const std::size_t c4,
1431 const std::size_t c5,
1432 const std::size_t c6,
1433 const std::size_t c7,
1434 const std::size_t c8,
1435 const std::size_t c9
1439 marray_detail::Assert(
MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 10));
1441 && c2 < shape(2) && c3 < shape(3) && c4 < shape(4)
1442 && c5 < shape(5) && c6 < shape(6) && c7 < shape(7)
1443 && c8 < shape(8) && c9 < shape(9)));
1444 return data_[c0*strides(0) + c1*strides(1) + c2*strides(2)
1445 + c3*strides(3) + c4*strides(4) + c5*strides(5) + c6*strides(6)
1446 + c7*strides(7) + c8*strides(8) + c9*strides(9)];
1451 template<
class T,
bool isConst,
class A>
1455 const std::size_t Dim,
1456 const std::size_t value
1460 return strides(Dim-1) * value;
1463 template<
class T,
bool isConst,
class A>
1465 View<T, isConst, A>::elementAccessHelper
1467 const std::size_t Dim,
1468 const std::size_t value
1472 return strides(Dim-1) * value;
1475 template<
class T,
bool isConst,
class A>
1476 template<
typename... Args>
1478 View<T, isConst, A>::elementAccessHelper
1480 const std::size_t Dim,
1481 const std::size_t value,
1485 marray_detail::Assert(
MARRAY_NO_ARG_TEST || (value < shape(Dim-1-
sizeof...(args)) ) );
1486 return value * strides(Dim-1-
sizeof...(args)) + elementAccessHelper(Dim, args...);
1489 template<
class T,
bool isConst,
class A>
1490 template<
typename... Args>
1492 View<T, isConst, A>::elementAccessHelper
1494 const std::size_t Dim,
1495 const std::size_t value,
1499 marray_detail::Assert(
MARRAY_NO_ARG_TEST || (value < shape(Dim-1-
sizeof...(args)) ) );
1500 return value * strides(Dim-1-
sizeof...(args)) + elementAccessHelper(Dim, args...);
1503 template<
class T,
bool isConst,
class A>
1504 inline typename View<T, isConst, A>::reference
1505 View<T, isConst, A>::operator()
1507 const std::size_t value
1511 if(dimension() == 0) {
1517 indexToOffset(value, offset);
1518 return data_[offset];
1522 template<
class T,
bool isConst,
class A>
1523 inline typename View<T, isConst, A>::reference
1524 View<T, isConst, A>::operator()
1526 const std::size_t value
1530 if(dimension() == 0) {
1536 indexToOffset(value, offset);
1537 return data_[offset];
1541 template<
class T,
bool isConst,
class A>
1542 template<
typename... Args>
1543 inline typename View<T, isConst, A>::reference
1544 View<T, isConst, A>::operator()
1546 const std::size_t value,
1551 marray_detail::Assert(
MARRAY_NO_DEBUG || ( data_ != 0 &&
sizeof...(args)+1 == dimension() ) );
1552 return data_[strides(0)*value + elementAccessHelper(
sizeof...(args)+1, args...) ];
1555 template<
class T,
bool isConst,
class A>
1556 template<
typename... Args>
1557 inline typename View<T, isConst, A>::reference
1558 View<T, isConst, A>::operator()
1560 const std::size_t value,
1565 marray_detail::Assert(
MARRAY_NO_DEBUG || ( data_ != 0 &&
sizeof...(args)+1 == dimension() ) );
1566 return data_[ strides(0) *
static_cast<std::size_t
>(value)
1567 + static_cast<std::size_t>(elementAccessHelper(
sizeof...(args)+1, args...)) ];
1570 #endif // #ifndef HAVE_CPP11_VARIADIC_TEMPLATES
1576 template<
class T,
bool isConst,
class A>
1577 inline const std::size_t
1580 return geometry_.size();
1589 template<
class T,
bool isConst,
class A>
1590 inline const std::size_t
1594 return geometry_.dimension();
1602 template<
class T,
bool isConst,
class A>
1603 inline const std::size_t
1606 const std::size_t dimension
1612 return geometry_.shape(dimension);
1620 template<
class T,
bool isConst,
class A>
1621 inline const std::size_t*
1626 return geometry_.shapeBegin();
1634 template<
class T,
bool isConst,
class A>
1635 inline const std::size_t*
1640 return geometry_.shapeEnd();
1648 template<
class T,
bool isConst,
class A>
1649 inline const std::size_t
1652 const std::size_t dimension
1658 return geometry_.strides(dimension);
1666 template<
class T,
bool isConst,
class A>
1667 inline const std::size_t*
1672 return geometry_.stridesBegin();
1680 template<
class T,
bool isConst,
class A>
1681 inline const std::size_t*
1686 return geometry_.stridesEnd();
1693 template<
class T,
bool isConst,
class A>
1698 return geometry_.coordinateOrder();
1705 template<
class T,
bool isConst,
class A>
1710 return geometry_.isSimple();
1752 template<
class T,
bool isConst,
class A>
1760 marray_detail::AssignmentOperatorHelper<isConst, T, T, A, A>::execute(in, *
this);
1767 template<
class T,
bool isConst,
class A>
1775 marray_detail::AssignmentOperatorHelper<isConst, T, T, A, A>::execute(in, *
this);
1782 template<
class T,
bool isConst,
class A>
1783 template<
class TLocal,
bool isConstLocal,
class ALocal>
1791 marray_detail::AssignmentOperatorHelper<isConst, TLocal, T, ALocal, A>::execute(in, *
this);
1802 template<
class T,
bool isConst,
class A>
1811 for(std::size_t j=0; j<geometry_.size(); ++j) {
1815 else if(dimension() == 1)
1816 marray_detail::OperateHelperBinaryScalar<1, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1817 else if(dimension() == 2)
1818 marray_detail::OperateHelperBinaryScalar<2, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1819 else if(dimension() == 3)
1820 marray_detail::OperateHelperBinaryScalar<3, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1821 else if(dimension() == 4)
1822 marray_detail::OperateHelperBinaryScalar<4, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1823 else if(dimension() == 5)
1824 marray_detail::OperateHelperBinaryScalar<5, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1825 else if(dimension() == 6)
1826 marray_detail::OperateHelperBinaryScalar<6, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1827 else if(dimension() == 7)
1828 marray_detail::OperateHelperBinaryScalar<7, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1829 else if(dimension() == 8)
1830 marray_detail::OperateHelperBinaryScalar<8, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1831 else if(dimension() == 9)
1832 marray_detail::OperateHelperBinaryScalar<9, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1833 else if(dimension() == 10)
1834 marray_detail::OperateHelperBinaryScalar<10, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1843 template<
class T,
bool isConst,
class A>
1844 template<
class E,
class Te>
1851 marray_detail::operate(*
this, expression, marray_detail::Assign<T, Te>());
1863 template<
class T,
bool isConst,
class A>
1864 template<
class BaseIterator,
class ShapeIterator>
1873 view(bit, sit, coordinateOrder(), out);
1886 template<
class T,
bool isConst,
class A>
1887 template<
class BaseIterator,
class ShapeIterator>
1898 std::size_t offset = 0;
1899 coordinatesToOffset(bit, offset);
1900 out.
assign(sit, sit+dimension(), geometry_.stridesBegin(),
1901 data_+offset, internalCoordinateOrder);
1912 template<
class T,
bool isConst,
class A>
1913 template<
class BaseIterator,
class ShapeIterator>
1922 this->view(bit, sit, v);
1936 template<
class T,
bool isConst,
class A>
1937 template<
class BaseIterator,
class ShapeIterator>
1947 this->view(bit, sit, internalCoordinateOrder, v);
1960 template<
class T,
bool isConst,
class A>
1961 template<
class BaseIterator,
class ShapeIterator>
1970 constView(bit, sit, coordinateOrder(), out);
1983 template<
class T,
bool isConst,
class A>
1984 template<
class BaseIterator,
class ShapeIterator>
1995 std::size_t offset = 0;
1996 coordinatesToOffset(bit, offset);
1997 out.
assign(sit, sit+dimension(),
1998 geometry_.stridesBegin(),
1999 static_cast<const T*
>(data_) + offset,
2000 internalCoordinateOrder);
2012 template<
class T,
bool isConst,
class A>
2013 template<
class BaseIterator,
class ShapeIterator>
2022 this->constView(bit, sit, v);
2036 template<
class T,
bool isConst,
class A>
2037 template<
class BaseIterator,
class ShapeIterator>
2047 this->constView(bit, sit, internalCoordinateOrder, v);
2051 #ifdef HAVE_CPP11_INITIALIZER_LISTS
2061 template<
class T,
bool isConst,
class A>
2065 std::initializer_list<std::size_t> b,
2066 std::initializer_list<std::size_t> s,
2071 view(b.begin(), s.begin(), internalCoordinateOrder, out);
2082 template<
class T,
bool isConst,
class A>
2086 std::initializer_list<std::size_t> b,
2087 std::initializer_list<std::size_t> s,
2088 View<T, isConst, A>& out
2091 view(b.begin(), s.begin(), coordinateOrder(), out);
2103 template<
class T,
bool isConst,
class A>
2107 std::initializer_list<std::size_t> b,
2108 std::initializer_list<std::size_t> s,
2110 View<T, true, A>& out
2113 constView(b.begin(), s.begin(), internalCoordinateOrder, out);
2125 template<
class T,
bool isConst,
class A>
2129 std::initializer_list<std::size_t> b,
2130 std::initializer_list<std::size_t> s,
2131 View<T, true, A>& out
2134 constView(b.begin(), s.begin(), coordinateOrder(), out);
2151 template<
class T,
bool isConst,
class A>
2152 template<
class ShapeIterator>
2156 ShapeIterator begin,
2163 std::size_t size = std::accumulate(begin, end, static_cast<std::size_t>(1),
2164 std::multiplies<std::size_t>());
2165 marray_detail::Assert(size == this->size());
2167 assign(begin, end, data_, coordinateOrder(), coordinateOrder());
2184 template<
class T,
bool isConst,
class A>
2185 template<
class ShapeIterator>
2189 ShapeIterator begin,
2198 #ifdef HAVE_CPP11_INITIALIZER_LISTS
2210 template<
class T,
bool isConst,
class A>
2214 std::initializer_list<std::size_t> shape
2217 reshape(shape.begin(), shape.end());
2231 template<
class T,
bool isConst,
class A>
2232 inline View<T, isConst, A>
2235 std::initializer_list<std::size_t> shape
2238 return reshapedView(shape.begin(), shape.end());
2252 template<
class T,
bool isConst,
class A>
2256 const std::size_t dimension,
2257 const std::size_t value
2262 && value < shape(dimension)));
2263 if(this->dimension() == 1) {
2264 View v(&((*
this)(value)));
2265 v.geometry_.coordinateOrder() = coordinateOrder();
2270 v.geometry_.resize(this->dimension()-1);
2271 v.geometry_.coordinateOrder() = coordinateOrder();
2272 v.geometry_.size() = size() / shape(dimension);
2273 for(std::size_t j=0, k=0; j<this->dimension(); ++j) {
2274 if(j != dimension) {
2275 v.geometry_.shape(k) = shape(j);
2276 v.geometry_.strides(k) = strides(j);
2280 marray_detail::stridesFromShape(v.geometry_.shapeBegin(), v.geometry_.shapeEnd(),
2281 v.geometry_.shapeStridesBegin(), v.geometry_.coordinateOrder());
2282 v.data_ = data_ + strides(dimension) * value;
2283 v.updateSimplicity();
2293 template<
class T,
bool isConst,
class A>
2298 if(dimension() != 0) {
2299 std::size_t newDimension = dimension();
2300 for(std::size_t j=0; j<dimension(); ++j) {
2305 if(newDimension != dimension()) {
2306 if(newDimension == 0) {
2307 geometry_.resize(0);
2308 geometry_.size() = 1;
2311 for(std::size_t j=0, k=0; j<geometry_.dimension(); ++j) {
2312 if(geometry_.shape(j) != 1) {
2313 geometry_.shape(k) = geometry_.shape(j);
2314 geometry_.strides(k) = geometry_.strides(j);
2318 geometry_.resize(newDimension);
2319 marray_detail::stridesFromShape(geometry_.shapeBegin(), geometry_.shapeEnd(),
2320 geometry_.shapeStridesBegin(), geometry_.coordinateOrder());
2333 template<
class T,
bool isConst,
class A>
2342 #ifdef HAVE_CPP11_INITIALIZER_LISTS
2351 template<
class T,
bool isConst,
class A>
2355 std::initializer_list<std::size_t> permutation
2358 permute(permutation.begin());
2370 template<
class T,
bool isConst,
class A>
2371 template<
class CoordinateIterator>
2375 CoordinateIterator begin
2380 marray_detail::Assert(dimension() != 0);
2381 std::set<std::size_t> s1, s2;
2382 CoordinateIterator it = begin;
2383 for(std::size_t j=0; j<dimension(); ++j) {
2388 marray_detail::Assert(s1 == s2);
2391 std::vector<std::size_t> newShape = std::vector<std::size_t>(dimension());
2392 std::vector<std::size_t> newStrides = std::vector<std::size_t>(dimension());
2393 for(std::size_t j=0; j<dimension(); ++j) {
2394 newShape[j] = geometry_.shape(static_cast<std::size_t>(*begin));
2395 newStrides[j] = geometry_.strides(static_cast<std::size_t>(*begin));
2398 for(std::size_t j=0; j<dimension(); ++j) {
2399 geometry_.shape(j) = newShape[j];
2400 geometry_.strides(j) = newStrides[j];
2402 marray_detail::stridesFromShape(geometry_.shapeBegin(), geometry_.shapeEnd(),
2403 geometry_.shapeStridesBegin(), geometry_.coordinateOrder());
2417 template<
class T,
bool isConst,
class A>
2418 template<
class CoordinateIterator>
2422 CoordinateIterator begin
2436 template<
class T,
bool isConst,
class A>
2440 const std::size_t c1,
2441 const std::size_t c2
2446 (dimension() != 0 && c1 < dimension() && c2 < dimension()));
2448 std::size_t j1 = c1;
2449 std::size_t j2 = c2;
2454 c = geometry_.shape(j2);
2455 geometry_.shape(j2) = geometry_.shape(j1);
2456 geometry_.shape(j1) = c;
2459 d = geometry_.strides(j2);
2460 geometry_.strides(j2) = geometry_.strides(j1);
2461 geometry_.strides(j1) = d;
2464 marray_detail::stridesFromShape(geometry_.shapeBegin(), geometry_.shapeEnd(),
2465 geometry_.shapeStridesBegin(), geometry_.coordinateOrder());
2476 template<
class T,
bool isConst,
class A>
2481 for(std::size_t j=0; j<dimension()/2; ++j) {
2482 std::size_t k = dimension()-j-1;
2485 std::size_t tmp = geometry_.shape(j);
2486 geometry_.shape(j) = geometry_.shape(k);
2487 geometry_.shape(k) = tmp;
2490 tmp = geometry_.strides(j);
2491 geometry_.strides(j) = geometry_.strides(k);
2492 geometry_.strides(k) = tmp;
2494 marray_detail::stridesFromShape(geometry_.shapeBegin(), geometry_.shapeEnd(),
2495 geometry_.shapeStridesBegin(), geometry_.coordinateOrder());
2508 template<
class T,
bool isConst,
class A>
2512 const std::size_t c1,
2513 const std::size_t c2
2527 template<
class T,
bool isConst,
class A>
2542 template<
class T,
bool isConst,
class A>
2551 if(n <= -static_cast<int>(dimension()) || n >= static_cast<int>(dimension())) {
2552 shift(n % static_cast<int>(dimension()));
2556 shift(n - static_cast<int>(dimension()));
2559 std::vector<std::size_t> p(dimension());
2560 for(std::size_t j=0; j<dimension(); ++j) {
2561 p[j] =
static_cast<std::size_t
>((
static_cast<int>(j) - n)) % dimension();
2574 template<
class T,
bool isConst,
class A>
2592 template<
class T,
bool isConst,
class A>
2605 template<
class T,
bool isConst,
class A>
2618 template<
class T,
bool isConst,
class A>
2631 template<
class T,
bool isConst,
class A>
2645 template<
class T,
bool isConst,
class A>
2657 template<
class T,
bool isConst,
class A>
2669 template<
class T,
bool isConst,
class A>
2681 template<
class T,
bool isConst,
class A>
2694 template<
class T,
bool isConst,
class A>
2700 geometry_.updateSimplicity();
2711 template<
class T,
bool isConst,
class A>
2713 View<T, isConst, A>::operator[]
2715 const std::size_t offset
2719 return data_[offset];
2730 template<
class T,
bool isConst,
class A>
2732 View<T, isConst, A>::operator[]
2734 const std::size_t offset
2737 return data_[offset];
2745 template<
class T,
bool isConst,
class A>
2747 View<T, isConst, A>::testInvariant()
const
2750 if(geometry_.dimension() == 0) {
2751 marray_detail::Assert(geometry_.isSimple() ==
true);
2753 marray_detail::Assert(geometry_.size() == 1);
2757 marray_detail::Assert(data_ != 0);
2760 std::size_t testSize = 1;
2761 for(std::size_t j=0; j<geometry_.dimension(); ++j) {
2762 testSize *= geometry_.shape(j);
2764 marray_detail::Assert(geometry_.size() == testSize);
2768 std::size_t tmp = 1;
2769 for(std::size_t j=0; j<geometry_.dimension(); ++j) {
2770 marray_detail::Assert(geometry_.shapeStrides(geometry_.dimension()-j-1) == tmp);
2771 tmp *= geometry_.shape(geometry_.dimension()-j-1);
2775 std::size_t tmp = 1;
2776 for(std::size_t j=0; j<geometry_.dimension(); ++j) {
2777 marray_detail::Assert(geometry_.shapeStrides(j) == tmp);
2778 tmp *= geometry_.shape(j);
2783 if(geometry_.isSimple()) {
2784 for(std::size_t j=0; j<geometry_.dimension(); ++j) {
2785 marray_detail::Assert(geometry_.strides(j) == geometry_.shapeStrides(j));
2807 template<
class T,
bool isConst,
class A>
2808 template<
class TLocal,
bool isConstLocal,
class ALocal>
2818 if(data_ == 0 || v.data_ == 0) {
2822 const void* dataPointer_ = data_;
2823 const void* vDataPointer_ = v.data_;
2824 const void* maxPointer = & (*this)(this->size()-1);
2825 const void* maxPointerV = & v(v.
size()-1);
2826 if( (dataPointer_ <= vDataPointer_ && vDataPointer_ <= maxPointer)
2827 || (vDataPointer_ <= dataPointer_ && dataPointer_ <= maxPointerV) )
2837 template<
class T,
bool isConst,
class A>
2845 std::ostringstream out(std::ostringstream::out);
2847 if(dimension() == 0) {
2849 out <<
"A = " << (*this)(0) << std::endl;
2851 else if(dimension() == 1) {
2854 for(std::size_t j=0; j<this->size(); ++j) {
2855 out << (*this)(j) <<
", ";
2857 out <<
"\b\b)" << std::endl;
2859 else if(dimension() == 2) {
2862 out <<
"A(r,c) =" << std::endl;
2863 for(std::size_t y=0; y<this->shape(0); ++y) {
2864 for(std::size_t x=0; x<this->shape(1); ++x) {
2865 out << (*this)(y, x) <<
' ';
2871 out <<
"A(c,r) =" << std::endl;
2872 for(std::size_t y=0; y<this->shape(1); ++y) {
2873 for(std::size_t x=0; x<this->shape(0); ++x) {
2874 out << (*this)(x, y) <<
' ';
2882 std::vector<std::size_t> c1(dimension());
2883 std::vector<std::size_t> c2(dimension());
2884 unsigned short q = 2;
2886 q =
static_cast<unsigned char>(dimension() - 3);
2889 it.coordinate(c2.begin());
2890 if(it.index() == 0 || c2[q] != c1[q]) {
2891 if(it.index() != 0) {
2892 out << std::endl << std::endl;
2896 for(std::size_t j=0; j<dimension()-2; ++j) {
2897 out << c2[j] <<
",";
2902 for(std::size_t j=2; j<dimension(); ++j) {
2903 out << c2[j] <<
",";
2910 out <<
") =" << std::endl;
2912 else if(c2[1] != c1[1]) {
2923 if(dimension() == 0) {
2925 out <<
"A = " << (*this)(0) << std::endl;
2929 std::vector<std::size_t> c(dimension());
2932 it.coordinate(c.begin());
2933 for(std::size_t j=0; j<c.size(); ++j) {
2936 out <<
"\b) = " << *it << std::endl;
2946 template<
class T1,
class T2,
bool isConst,
class A>
2954 marray_detail::operate(v, w, marray_detail::PlusEqual<T1, T2>());
2959 template<
class T,
class A>
2960 inline View<T, false, A>&
2966 marray_detail::operate(v, marray_detail::PrefixIncrement<T>());
2971 template<
class T,
class A>
2980 marray_detail::operate(in, marray_detail::PostfixIncrement<T>());
2984 template<
class T1,
class T2,
bool isConst,
class A>
2985 inline View<T1, false, A>&
2992 marray_detail::operate(v, w, marray_detail::MinusEqual<T1, T2>());
2997 template<
class T,
class A>
2998 inline View<T, false, A>&
3004 marray_detail::operate(v, marray_detail::PrefixDecrement<T>());
3009 template<
class T,
class A>
3018 marray_detail::operate(in, marray_detail::PostfixDecrement<T>());
3022 template<
class T1,
class T2,
bool isConst,
class A>
3023 inline View<T1, false, A>&
3030 marray_detail::operate(v, w, marray_detail::TimesEqual<T1, T2>());
3034 template<
class T1,
class T2,
bool isConst,
class A>
3035 inline View<T1, false, A>&
3042 marray_detail::operate(v, w, marray_detail::DividedByEqual<T1, T2>());
3046 template<
class E1,
class T1,
class E2,
class T2>
3047 inline const BinaryViewExpression<E1, T1, E2, T2, marray_detail::Plus<T1, T2, typename marray_detail::PromoteType<T1, T2>::type> >
3054 typedef typename marray_detail::PromoteType<T1, T2>::type promoted_type;
3055 typedef marray_detail::Plus<T1, T2, promoted_type> Functor;
3056 typedef BinaryViewExpression<E1, T1, E2, T2, Functor> return_type;
3057 return return_type(expression1, expression2);
3060 template<
class E,
class T>
3061 inline const ViewExpression<E,T>&
3070 #define MARRAY_UNARY_OPERATOR(datatype, operation, functorname) \
3071 template<class T, class A> \
3072 inline View<T, false, A>& \
3073 operator operation \
3075 View<T, false, A>& v, \
3079 marray_detail::operate(v, static_cast<T>(x), marray_detail:: functorname <T, T>()); \
3083 #define MARRAY_UNARY_OPERATOR_ALL_TYPES(op, functorname) \
3084 MARRAY_UNARY_OPERATOR(char, op, functorname) \
3085 MARRAY_UNARY_OPERATOR(unsigned char, op, functorname) \
3086 MARRAY_UNARY_OPERATOR(short, op, functorname) \
3087 MARRAY_UNARY_OPERATOR(unsigned short, op, functorname) \
3088 MARRAY_UNARY_OPERATOR(int, op, functorname) \
3089 MARRAY_UNARY_OPERATOR(unsigned int, op, functorname) \
3090 MARRAY_UNARY_OPERATOR(long, op, functorname) \
3091 MARRAY_UNARY_OPERATOR(unsigned long, op, functorname) \
3092 MARRAY_UNARY_OPERATOR(float, op, functorname) \
3093 MARRAY_UNARY_OPERATOR(double, op, functorname) \
3094 MARRAY_UNARY_OPERATOR(long double, op, functorname) \
3096 MARRAY_UNARY_OPERATOR_ALL_TYPES(+=, PlusEqual)
3097 MARRAY_UNARY_OPERATOR_ALL_TYPES(-=, MinusEqual)
3098 MARRAY_UNARY_OPERATOR_ALL_TYPES(*=, TimesEqual)
3099 MARRAY_UNARY_OPERATOR_ALL_TYPES(/=, DividedByEqual)
3101 template<class E1, class T1, class E2, class T2>
3102 inline const BinaryViewExpression<E1, T1, E2, T2,
3103 marray_detail::Minus<T1, T2, typename marray_detail::PromoteType<T1, T2>::type> >
3110 return BinaryViewExpression<E1, T1, E2, T2,
3111 marray_detail::Minus<T1, T2,
3112 typename marray_detail::PromoteType<T1, T2>::type> >(
3113 expression1, expression2);
3116 template<
class E,
class T>
3117 inline const UnaryViewExpression<E,T,marray_detail::Negate<T> >
3123 return UnaryViewExpression<E,T,marray_detail::Negate<T> >(
3127 template<
class E1,
class T1,
class E2,
class T2>
3128 inline const BinaryViewExpression<E1, T1, E2, T2,
3129 marray_detail::Times<T1, T2, typename marray_detail::PromoteType<T1, T2>::type> >
3136 return BinaryViewExpression<E1, T1, E2, T2,
3137 marray_detail::Times<T1, T2,
3138 typename marray_detail::PromoteType<T1, T2>::type > >(
3139 expression1, expression2);
3142 template<
class E1,
class T1,
class E2,
class T2>
3143 inline const BinaryViewExpression<E1, T1, E2, T2,
3144 marray_detail::DividedBy<T1, T2, typename marray_detail::PromoteType<T1, T2>::type> >
3151 return BinaryViewExpression<E1, T1, E2, T2,
3152 marray_detail::DividedBy<T1, T2,
3153 typename marray_detail::PromoteType<T1, T2>::type > >(
3154 expression1, expression2);
3157 #define MARRAY_BINARY_OPERATOR(datatype, operation, functorname) \
3158 template<class E, class T> \
3159 inline const BinaryViewExpressionScalarSecond< \
3160 E, T, datatype, marray_detail:: functorname < \
3161 T, datatype, typename marray_detail::PromoteType<T, datatype>::type \
3164 operator operation \
3166 const ViewExpression<E, T>& expression, \
3167 const datatype& scalar \
3170 typedef typename marray_detail::PromoteType<T, datatype>::type \
3172 typedef marray_detail:: functorname <T, datatype, promoted_type> Functor; \
3173 typedef BinaryViewExpressionScalarSecond<E, T, datatype, Functor> \
3175 return expression_type(expression, scalar); \
3178 template<class E, class T> \
3179 inline const BinaryViewExpressionScalarFirst \
3181 E, T, datatype, marray_detail:: functorname < \
3182 datatype, T, typename marray_detail::PromoteType<datatype, T>::type \
3185 operator operation \
3187 const datatype& scalar, \
3188 const ViewExpression<E, T>& expression \
3191 typedef typename marray_detail::PromoteType<T, datatype>::type \
3193 typedef marray_detail:: functorname <datatype, T, promoted_type> Functor; \
3194 typedef BinaryViewExpressionScalarFirst<E, T, datatype, Functor> \
3196 return expression_type(expression, scalar); \
3199 #define MARRAY_BINARY_OPERATOR_ALL_TYPES(op, functorname) \
3200 MARRAY_BINARY_OPERATOR(char, op, functorname) \
3201 MARRAY_BINARY_OPERATOR(unsigned char, op, functorname) \
3202 MARRAY_BINARY_OPERATOR(short, op, functorname) \
3203 MARRAY_BINARY_OPERATOR(unsigned short, op, functorname) \
3204 MARRAY_BINARY_OPERATOR(int, op, functorname) \
3205 MARRAY_BINARY_OPERATOR(unsigned int, op, functorname) \
3206 MARRAY_BINARY_OPERATOR(long, op, functorname) \
3207 MARRAY_BINARY_OPERATOR(unsigned long, op, functorname) \
3208 MARRAY_BINARY_OPERATOR(float, op, functorname) \
3209 MARRAY_BINARY_OPERATOR(double, op, functorname) \
3210 MARRAY_BINARY_OPERATOR(long double, op, functorname) \
3212 MARRAY_BINARY_OPERATOR_ALL_TYPES(+, Plus)
3213 MARRAY_BINARY_OPERATOR_ALL_TYPES(-, Minus)
3214 MARRAY_BINARY_OPERATOR_ALL_TYPES(*, Times)
3215 MARRAY_BINARY_OPERATOR_ALL_TYPES(/, DividedBy)
3227 template<class T, class A>
3229 Marray<T, A>::assign
3234 if(this->data_ != 0) {
3235 dataAllocator_.deallocate(this->data_, this->size());
3238 dataAllocator_ = allocator;
3246 template<
class T,
class A>
3253 dataAllocator_(allocator)
3267 template<
class T,
class A>
3275 : dataAllocator_(allocator)
3277 this->data_ = dataAllocator_.allocate(1);
3278 this->data_[0] = value;
3279 this->geometry_ = geometry_type(0, coordinateOrder, 1,
true, allocator);
3287 template<
class T,
class A>
3293 : dataAllocator_(in.dataAllocator_)
3302 this->data_ = dataAllocator_.allocate(in.
size());
3303 memcpy(this->data_, in.data_, (in.
size())*
sizeof(T));
3305 this->geometry_ = in.geometry_;
3313 template<
class T,
class A>
3314 template<
class TLocal,
bool isConstLocal,
class ALocal>
3327 this->geometry_ = in.geometry_;
3328 for(std::size_t j=0; j<in.
dimension(); ++j) {
3329 this->geometry_.strides(j) = in.geometry_.shapeStrides(j);
3331 this->geometry_.isSimple() =
true;
3334 if(in.
size() == 0) {
3338 this->data_ = dataAllocator_.allocate(in.
size());
3340 if(in.
isSimple() && marray_detail::IsEqual<T, TLocal>::type) {
3341 memcpy(this->data_, in.data_, (in.
size())*
sizeof(T));
3345 for(std::size_t j=0; j<this->size(); ++j, ++it) {
3346 this->data_[j] =
static_cast<T
>(*it);
3358 template<
class T,
class A>
3359 template<
class E,
class Te>
3366 : dataAllocator_(allocator)
3368 this->data_ = dataAllocator_.allocate(expression.
size());
3370 this->geometry_ = geometry_type(0,
3371 static_cast<const E&>(expression).coordinateOrder(),
3372 1,
true, dataAllocator_);
3375 this->geometry_ = geometry_type(
3376 static_cast<const E&>(expression).shapeBegin(),
3377 static_cast<const E&>(expression).shapeEnd(),
3378 static_cast<const E&>(expression).coordinateOrder(),
3379 static_cast<const E&>(expression).coordinateOrder(),
3383 const E& e =
static_cast<const E&
>(expression);
3384 if(e.dimension() == 0) {
3386 this->data_[0] =
static_cast<T
>(e(0));
3390 marray_detail::operate(*
this, e, marray_detail::Assign<T, Te>());
3405 template<
class T,
class A>
3406 template<
class ShapeIterator>
3410 ShapeIterator begin,
3416 : dataAllocator_(allocator)
3418 std::size_t size = std::accumulate(begin, end, static_cast<std::size_t>(1),
3419 std::multiplies<std::size_t>());
3421 base::assign(begin, end, dataAllocator_.allocate(size), coordinateOrder,
3422 coordinateOrder, allocator);
3423 for(std::size_t j=0; j<size; ++j) {
3424 this->data_[j] = value;
3439 template<
class T,
class A>
3440 template<
class ShapeIterator>
3445 ShapeIterator begin,
3450 : dataAllocator_(allocator)
3452 std::size_t size = std::accumulate(begin, end, static_cast<std::size_t>(1),
3453 std::multiplies<std::size_t>());
3455 base::assign(begin, end, dataAllocator_.allocate(size), coordinateOrder,
3456 coordinateOrder, allocator);
3460 #ifdef HAVE_CPP11_INITIALIZER_LISTS
3469 template<
class T,
class A>
3473 std::initializer_list<std::size_t> shape,
3476 const allocator_type& allocator
3479 : dataAllocator_(allocator)
3481 std::size_t
size = std::accumulate(shape.begin(), shape.end(),
3482 static_cast<std::size_t
>(1), std::multiplies<std::size_t>());
3484 base::assign(shape.begin(), shape.end(), dataAllocator_.allocate(size),
3486 std::fill(this->data_, this->data_+size, value);
3493 template<
class T,
class A>
3497 dataAllocator_.deallocate(this->data_, this->size());
3512 template<
class T,
class A>
3528 dataAllocator_.deallocate(this->data_, this->size());
3532 if(this->size() != in.
size()) {
3534 dataAllocator_.deallocate(this->data_, this->size());
3535 this->data_ = dataAllocator_.allocate(in.
size());
3538 memcpy(this->data_, in.data_, in.
size() *
sizeof(T));
3540 this->geometry_ = in.geometry_;
3560 template<
class T,
class A>
3561 template<
class TLocal,
bool isConstLocal,
class ALocal>
3571 if( (
void*)(
this) != (
void*)(&in) ) {
3573 dataAllocator_.deallocate(this->data_, this->size());
3575 this->geometry_ = in.geometry_;
3577 else if(this->overlaps(in)) {
3583 if(this->size() != in.
size()) {
3584 dataAllocator_.deallocate(this->data_, this->size());
3585 this->data_ = dataAllocator_.allocate(in.
size());
3590 for(std::size_t j=0; j<in.
dimension(); ++j) {
3591 this->geometry_.shape(j) = in.geometry_.shape(j);
3592 this->geometry_.shapeStrides(j) = in.geometry_.shapeStrides(j);
3593 this->geometry_.strides(j) = in.geometry_.shapeStrides(j);
3595 this->geometry_.size() = in.
size();
3596 this->geometry_.isSimple() =
true;
3600 if(in.
isSimple() && marray_detail::IsEqual<T, TLocal>::type) {
3601 memcpy(this->data_, in.data_, (in.
size())*
sizeof(T));
3604 marray_detail::OperateHelperBinary<1, marray_detail::Assign<T, TLocal>, T, TLocal, isConstLocal, A, ALocal>::operate(*
this, in, marray_detail::Assign<T, TLocal>(), this->data_, &in(0));
3606 marray_detail::OperateHelperBinary<2, marray_detail::Assign<T, TLocal>, T, TLocal, isConstLocal, A, ALocal>::operate(*
this, in, marray_detail::Assign<T, TLocal>(), this->data_, &in(0));
3608 marray_detail::OperateHelperBinary<3, marray_detail::Assign<T, TLocal>, T, TLocal, isConstLocal, A, ALocal>::operate(*
this, in, marray_detail::Assign<T, TLocal>(), this->data_, &in(0));
3610 marray_detail::OperateHelperBinary<4, marray_detail::Assign<T, TLocal>, T, TLocal, isConstLocal, A, ALocal>::operate(*
this, in, marray_detail::Assign<T, TLocal>(), this->data_, &in(0));
3612 marray_detail::OperateHelperBinary<5, marray_detail::Assign<T, TLocal>, T, TLocal, isConstLocal, A, ALocal>::operate(*
this, in, marray_detail::Assign<T, TLocal>(), this->data_, &in(0));
3614 marray_detail::OperateHelperBinary<6, marray_detail::Assign<T, TLocal>, T, TLocal, isConstLocal, A, ALocal>::operate(*
this, in, marray_detail::Assign<T, TLocal>(), this->data_, &in(0));
3616 marray_detail::OperateHelperBinary<7, marray_detail::Assign<T, TLocal>, T, TLocal, isConstLocal, A, ALocal>::operate(*
this, in, marray_detail::Assign<T, TLocal>(), this->data_, &in(0));
3618 marray_detail::OperateHelperBinary<8, marray_detail::Assign<T, TLocal>, T, TLocal, isConstLocal, A, ALocal>::operate(*
this, in, marray_detail::Assign<T, TLocal>(), this->data_, &in(0));
3620 marray_detail::OperateHelperBinary<9, marray_detail::Assign<T, TLocal>, T, TLocal, isConstLocal, A, ALocal>::operate(*
this, in, marray_detail::Assign<T, TLocal>(), this->data_, &in(0));
3622 marray_detail::OperateHelperBinary<10, marray_detail::Assign<T, TLocal>, T, TLocal, isConstLocal, A, ALocal>::operate(*
this, in, marray_detail::Assign<T, TLocal>(), this->data_, &in(0));
3625 for(std::size_t j=0; j<this->size(); ++j, ++it) {
3626 this->data_[j] =
static_cast<T
>(*it);
3641 template<
class T,
class A>
3649 for(std::size_t j=0; j<this->size(); ++j) {
3650 this->data_[j] = value;
3655 template<
class T,
class A>
3656 template<
class E,
class Te>
3669 if(this->size() != expression.
size()) {
3670 dataAllocator_.deallocate(this->data_, this->size());
3671 this->data_ = dataAllocator_.allocate(expression.
size());
3676 for(std::size_t j=0; j<expression.
dimension(); ++j) {
3677 this->geometry_.shape(j) = expression.
shape(j);
3679 this->geometry_.size() = expression.
size();
3680 this->geometry_.isSimple() =
true;
3682 if(this->geometry_.dimension() != 0) {
3683 marray_detail::stridesFromShape(this->geometry_.shapeBegin(), this->geometry_.shapeEnd(),
3684 this->geometry_.shapeStridesBegin(), this->geometry_.coordinateOrder());
3685 marray_detail::stridesFromShape(this->geometry_.shapeBegin(), this->geometry_.shapeEnd(),
3686 this->geometry_.stridesBegin(), this->geometry_.coordinateOrder());
3690 marray_detail::operate(*
this, expression, marray_detail::Assign<T, Te>());
3695 template<
class T,
class A>
3696 template<
bool SKIP_INITIALIZATION,
class ShapeIterator>
3700 ShapeIterator begin,
3707 std::vector<std::size_t> newShape;
3708 std::size_t newSize = 1;
3709 for(ShapeIterator it = begin; it != end; ++it) {
3710 std::size_t x =
static_cast<std::size_t
>(*it);
3712 newShape.push_back(x);
3716 value_type* newData = dataAllocator_.allocate(newSize);
3717 if(!SKIP_INITIALIZATION) {
3718 for(std::size_t j=0; j<newSize; ++j) {
3723 if(this->data_ != 0) {
3724 if(newSize == 1 || this->dimension() == 0) {
3725 newData[0] = this->data_[0];
3728 std::vector<std::size_t> base1(this->dimension());
3729 std::vector<std::size_t> base2(newShape.size());
3730 std::vector<std::size_t> shape1(this->dimension(), 1);
3731 std::vector<std::size_t> shape2(newShape.size(), 1);
3732 for(std::size_t j=0; j<std::min(this->dimension(), newShape.size()); ++j) {
3733 shape1[j] = std::min(this->shape(j), newShape[j]);
3734 shape2[j] = shape1[j];
3736 View<T, true, A> view1;
3737 this->constView(base1.begin(), shape1.begin(), view1);
3738 View<T, false, A> viewT(newShape.begin(), newShape.end(),
3739 newData, this->coordinateOrder(),
3740 this->coordinateOrder());
3741 View<T, false, A> view2;
3742 viewT.view(base2.begin(), shape2.begin(), view2);
3747 dataAllocator_.deallocate(this->data_, this->size());
3750 base::assign(begin, end, newData, this->geometry_.coordinateOrder(),
3751 this->geometry_.coordinateOrder());
3762 template<
class T,
class A>
3763 template<
class ShapeIterator>
3767 ShapeIterator begin,
3772 resizeHelper<false>(begin, end, value);
3782 template<
class T,
class A>
3783 template<
class ShapeIterator>
3788 ShapeIterator begin,
3792 resizeHelper<true>(begin, end);
3795 #ifdef HAVE_CPP11_INITIALIZER_LISTS
3801 template<
class T,
class A>
3805 std::initializer_list<std::size_t> shape,
3809 resizeHelper<false>(shape.begin(), shape.end(), value);
3817 template<
class T,
class A>
3821 const InitializationSkipping& si,
3822 std::initializer_list<std::size_t> shape
3825 resizeHelper<true>(shape.begin(), shape.end());
3831 template<
class T,
class A>
3833 Marray<T, A>::testInvariant()
const
3835 View<T, false, A>::testInvariant();
3843 template<
class T,
bool isConst,
class A>
3845 Iterator<T, isConst, A>::testInvariant()
const
3849 marray_detail::Assert(coordinates_.size() == 0
3854 if(view_->size() == 0) {
3855 marray_detail::Assert(coordinates_.size() == 0
3860 marray_detail::Assert(index_ >= 0 && index_ <= view_->size());
3861 if(index_ == view_->size()) {
3862 marray_detail::Assert(pointer_ == &((*view_)(view_->size()-1)) + 1);
3865 marray_detail::Assert(pointer_ == &((*view_)(index_)));
3867 if(!view_->isSimple()) {
3868 marray_detail::Assert(coordinates_.size() == view_->dimension());
3869 if(index_ == view_->size()) {
3871 marray_detail::Assert(coordinates_[0] == view_->shape(0));
3872 for(std::size_t j=1; j<coordinates_.size(); ++j) {
3873 marray_detail::Assert(coordinates_[j] == view_->shape(j)-1);
3877 std::size_t d = view_->dimension() - 1;
3878 marray_detail::Assert(coordinates_[d] == view_->shape(d));
3879 for(std::size_t j=0; j<d; ++j) {
3880 marray_detail::Assert(coordinates_[j] == view_->shape(j)-1);
3885 std::vector<std::size_t> testCoord(coordinates_.size());
3886 view_->indexToCoordinates(index_, testCoord.begin());
3887 for(std::size_t j=0; j<coordinates_.size(); ++j) {
3888 marray_detail::Assert(coordinates_[j] == testCoord[j]);
3898 template<
class T,
bool isConst,
class A>
3903 coordinates_(std::vector<std::size_t>())
3913 template<
class T,
bool isConst,
class A>
3917 const std::size_t index
3922 coordinates_(std::vector<std::size_t>(view.
dimension()))
3927 if(view.
size() == 0) {
3933 pointer_ = &view(0) + index;
3936 if(index >= view.
size()) {
3938 coordinates_[0] = view.
shape(0);
3939 for(std::size_t j=1; j<view.
dimension(); ++j) {
3940 coordinates_[j] = view.
shape(j)-1;
3944 std::size_t d = view_->dimension() - 1;
3945 coordinates_[d] = view.
shape(d);
3946 for(std::size_t j=0; j<d; ++j) {
3947 coordinates_[j] = view.
shape(j)-1;
3950 pointer_ = &view(view.
size()-1) + 1;
3954 pointer_ = &view(index);
3966 template<
class T,
bool isConst,
class A>
3970 const std::size_t index
3972 : view_(reinterpret_cast<view_pointer>(&view)),
3975 coordinates_(std::vector<std::size_t>(view.
dimension()))
3981 if(view.
size() == 0) {
3987 pointer_ = &view(0) + index;
3990 if(index >= view.
size()) {
3992 coordinates_[0] = view.
shape(0);
3993 for(std::size_t j=1; j<view.
dimension(); ++j) {
3994 coordinates_[j] = view.
shape(j)-1;
3998 std::size_t d = view_->dimension() - 1;
3999 coordinates_[d] = view.
shape(d);
4000 for(std::size_t j=0; j<d; ++j) {
4001 coordinates_[j] = view.
shape(j)-1;
4004 pointer_ = &view(view.
size()-1) + 1;
4008 pointer_ = &view(index);
4020 template<
class T,
bool isConst,
class A>
4024 const std::size_t index
4026 : view_(reinterpret_cast<view_pointer>(&view)),
4029 coordinates_(std::vector<std::size_t>(view.
dimension()))
4035 if(view.
size() == 0) {
4041 pointer_ = &view(0) + index;
4044 if(index >= view.
size()) {
4046 coordinates_[0] = view.
shape(0);
4047 for(std::size_t j=1; j<view.
dimension(); ++j) {
4048 coordinates_[j] = view.
shape(j)-1;
4052 std::size_t d = view_->dimension() - 1;
4053 coordinates_[d] = view.
shape(d);
4054 for(std::size_t j=0; j<d; ++j) {
4055 coordinates_[j] = view.
shape(j)-1;
4058 pointer_ = &view(view.
size()-1) + 1;
4062 pointer_ = &view(index);
4071 template<
class T,
bool isConst,
class A>
4077 pointer_(
pointer(in.pointer_)),
4079 coordinates_(in.coordinates_)
4086 template<
class T,
bool isConst,
class A>
4090 marray_detail::Assert(
MARRAY_NO_DEBUG || (view_ != 0 && index_ < view_->size()));
4096 template<
class T,
bool isConst,
class A>
4100 marray_detail::Assert(
MARRAY_NO_DEBUG || (view_ != 0 && index_ < view_->size()));
4106 template<
class T,
bool isConst,
class A>
4113 marray_detail::Assert(
MARRAY_NO_DEBUG || (view_ != 0 && x+index_ < view_->size()));
4114 return (*view_)(x+index_);
4117 template<
class T,
bool isConst,
class A>
4125 if(index_ < view_->size()) {
4126 if(index_ + x < view_->size()) {
4128 if(view_->isSimple()) {
4132 pointer_ = &((*view_)(index_));
4133 view_->indexToCoordinates(index_, coordinates_.begin());
4138 index_ = view_->size();
4139 if(view_->isSimple()) {
4140 pointer_ = &(*view_)(0) + view_->size();
4143 pointer_ = (&(*view_)(view_->size()-1)) + 1;
4144 view_->indexToCoordinates(view_->size()-1, coordinates_.begin());
4149 ++coordinates_[view_->dimension()-1];
4158 template<
class T,
bool isConst,
class A>
4166 marray_detail::Assert(
MARRAY_NO_ARG_TEST || static_cast<difference_type>(index_) >= x);
4168 if(view_->isSimple()) {
4172 pointer_ = &((*view_)(index_));
4173 view_->indexToCoordinates(index_, coordinates_.begin());
4181 template<
class T,
bool isConst,
class A>
4186 if(index_ < view_->size()) {
4188 if(view_->isSimple()) {
4192 if(index_ < view_->size()) {
4194 for(std::size_t j=0; j<coordinates_.size(); ++j) {
4195 if(coordinates_[j] == view_->shape(j)-1) {
4196 pointer_ -= view_->strides(j) * coordinates_[j];
4197 coordinates_[j] = 0;
4200 pointer_ += view_->strides(j);
4207 std::size_t j = coordinates_.size() - 1;
4209 if(coordinates_[j] == view_->shape(j)-1) {
4210 pointer_ -= view_->strides(j) * coordinates_[j];
4211 coordinates_[j] = 0;
4214 pointer_ += view_->strides(j);
4229 pointer_ = &((*view_)(view_->size()-1)) + 1;
4234 ++coordinates_[view_->dimension()-1];
4245 template<
class T,
bool isConst,
class A>
4251 if(view_->isSimple()) {
4255 if(index_ == view_->size()) {
4262 --coordinates_[view_->dimension() - 1];
4267 for(std::size_t j=0; j<coordinates_.size(); ++j) {
4268 if(coordinates_[j] == 0) {
4269 coordinates_[j] = view_->shape(j)-1;
4270 pointer_ += view_->strides(j) * coordinates_[j];
4273 pointer_ -= view_->strides(j);
4280 std::size_t j = view_->dimension() - 1;
4282 if(coordinates_[j] == 0) {
4283 coordinates_[j] = view_->shape(j)-1;
4284 pointer_ += view_->strides(j) * coordinates_[j];
4287 pointer_ -= view_->strides(j);
4307 template<
class T,
bool isConst,
class A>
4319 template<
class T,
bool isConst,
class A>
4329 template<
class T,
bool isConst,
class A>
4342 template<
class T,
bool isConst,
class A>
4355 template<
class T,
bool isConst,
class A>
4356 template<
bool isConstLocal>
4368 template<
class T,
bool isConst,
class A>
4369 template<
bool isConstLocal>
4377 marray_detail::Assert(
MARRAY_NO_ARG_TEST || (it.view_ != 0 && (
void*)it.view_ == (
void*)view_));
4378 return index_ == it.index_;
4381 template<
class T,
bool isConst,
class A>
4382 template<
bool isConstLocal>
4392 static_cast<const void*>(it.view_) == static_cast<const void*>(view_));
4393 return index_ != it.index_;
4396 template<
class T,
bool isConst,
class A>
4397 template<
bool isConstLocal>
4406 return(index_ < it.index_);
4409 template<
class T,
bool isConst,
class A>
4410 template<
bool isConstLocal>
4419 return(index_ > it.index_);
4422 template<
class T,
bool isConst,
class A>
4423 template<
bool isConstLocal>
4432 return(index_ <= it.index_);
4435 template<
class T,
bool isConst,
class A>
4436 template<
bool isConstLocal>
4445 return(index_ >= it.index_);
4452 template<
class T,
bool isConst,
class A>
4457 return index_ < view_->size();
4464 template<
class T,
bool isConst,
class A>
4476 template<
class T,
bool isConst,
class A>
4477 template<
class CoordinateIterator>
4481 CoordinateIterator it
4486 if(view_->isSimple()) {
4487 view_->indexToCoordinates(index_, it);
4490 for(std::size_t j=0; j<coordinates_.size(); ++j, ++it) {
4491 *it = coordinates_[j];
4499 template<
class E,
class T>
4506 {
return static_cast<const E&
>(*this).dimension(); }
4508 {
return static_cast<const E&
>(*this).size(); }
4509 const std::size_t
shape(
const std::size_t j)
const
4510 {
return static_cast<const E&
>(*this).shape(j); }
4512 {
return static_cast<const E&
>(*this).shapeBegin(); }
4514 {
return static_cast<const E&
>(*this).shapeEnd(); }
4515 template<
class Tv,
bool isConst,
class A>
4517 {
return static_cast<const E&
>(*this).overlaps(v); }
4519 {
return static_cast<const E&
>(*this).coordinateOrder(); }
4521 {
return static_cast<const E&
>(*this).isSimple(); }
4522 template<
class Accessor>
4524 {
return static_cast<const E&
>(*this)(it); }
4525 const T&
operator()(
const std::size_t c0,
const std::size_t c1)
const
4526 {
return static_cast<const E&
>(*this)(c0, c1); }
4527 const T&
operator()(
const std::size_t c0,
const std::size_t c1,
const std::size_t c2)
const
4528 {
return static_cast<const E&
>(*this)(c0, c1, c2); }
4529 const T&
operator()(
const std::size_t c0,
const std::size_t c1,
const std::size_t c2,
const std::size_t c3)
const
4530 {
return static_cast<const E&
>(*this)(c0, c1, c2, c3); }
4531 const T&
operator()(
const std::size_t c0,
const std::size_t c1,
const std::size_t c2,
const std::size_t c3,
const std::size_t c4)
const
4532 {
return static_cast<const E&
>(*this)(c0, c1, c2, c3, c4); }
4534 {
return static_cast<const E&
>(*this)[offset]; }
4536 {
return static_cast<E&
>(*this); }
4537 operator E
const&()
const
4538 {
return static_cast<const E&
>(*this); }
4541 class ExpressionIterator {
4544 : expression_(expression),
4545 data_(&expression_(0)),
4548 void incrementCoordinate(
const std::size_t coordinateIndex)
4549 { offset_ += expression_.strides(coordinateIndex); }
4550 void resetCoordinate(
const std::size_t coordinateIndex)
4551 { offset_ -= expression_.strides(coordinateIndex)
4553 * (expression_.shape(coordinateIndex) - 1); }
4559 return data_[offset_]; }
4561 const E& expression_;
4563 std::size_t offset_;
4569 template<
class E,
class T,
class UnaryFunctor>
4570 class UnaryViewExpression
4571 :
public ViewExpression<UnaryViewExpression<E, T, UnaryFunctor>, T>
4574 typedef E expression_type;
4575 typedef T value_type;
4577 UnaryViewExpression(
const ViewExpression<E, T>& e)
4579 unaryFunctor_(UnaryFunctor())
4581 const std::size_t dimension()
const
4582 {
return e_.dimension(); }
4583 const std::size_t size()
const
4584 {
return e_.size(); }
4585 const std::size_t shape(
const std::size_t j)
const
4586 {
return e_.shape(j); }
4587 const std::size_t* shapeBegin()
const
4588 {
return e_.shapeBegin(); }
4589 const std::size_t* shapeEnd()
const
4590 {
return e_.shapeEnd(); }
4591 template<
class Tv,
bool isConst,
class A>
4592 bool overlaps(
const View<Tv, isConst, A>& v)
const
4593 {
return e_.overlaps(v); }
4595 {
return e_.coordinateOrder(); }
4596 const bool isSimple()
const
4597 {
return e_.isSimple(); }
4598 template<
class Accessor>
4599 const T operator()(Accessor it)
const
4600 {
return unaryFunctor_(e_(it)); }
4601 const T operator()(
const std::size_t c0,
const std::size_t c1)
const
4602 {
return unaryFunctor_(e_(c0, c1)); }
4603 const T operator()(
const std::size_t c0,
const std::size_t c1,
const std::size_t c2)
const
4604 {
return unaryFunctor_(e_(c0, c1, c2)); }
4605 const T operator()(
const std::size_t c0,
const std::size_t c1,
const std::size_t c2,
const std::size_t c3)
const
4606 {
return unaryFunctor_(e_(c0, c1, c2, c3)); }
4607 const T operator()(
const std::size_t c0,
const std::size_t c1,
const std::size_t c2,
const std::size_t c3,
const std::size_t c4)
const
4608 {
return unaryFunctor_(e_(c0, c1, c2, c3, c4)); }
4609 const T operator[](
const std::size_t offset)
const
4610 {
return unaryFunctor_(e_[offset]); }
4612 class ExpressionIterator {
4614 ExpressionIterator(
const UnaryViewExpression<E, T, UnaryFunctor>& expression)
4615 : unaryFunctor_(expression.unaryFunctor_),
4616 iterator_(expression.e_)
4618 void incrementCoordinate(
const std::size_t coordinateIndex)
4619 { iterator_.incrementCoordinate(coordinateIndex); }
4620 void resetCoordinate(
const std::size_t coordinateIndex)
4621 { iterator_.resetCoordinate(coordinateIndex); }
4623 {
return unaryFunctor_(*iterator_); }
4625 UnaryFunctor unaryFunctor_;
4626 typename E::ExpressionIterator iterator_;
4631 UnaryFunctor unaryFunctor_;
4634 template<
class E1,
class T1,
class E2,
class T2,
class BinaryFunctor>
4635 class BinaryViewExpression
4636 :
public ViewExpression<BinaryViewExpression<E1, T1, E2, T2, BinaryFunctor>,
4637 typename marray_detail::PromoteType<T1, T2>::type>
4640 typedef E1 expression_type_1;
4641 typedef E2 expression_type_2;
4642 typedef T1 value_type_1;
4643 typedef T2 value_type_2;
4644 typedef typename marray_detail::PromoteType<T1, T2>::type value_type;
4645 typedef BinaryFunctor functor_type;
4646 typedef ViewExpression<BinaryViewExpression<E1, T1, E2, T2, BinaryFunctor>,
4649 BinaryViewExpression(
const ViewExpression<E1, T1>& e1,
4650 const ViewExpression<E2, T2>& e2)
4652 binaryFunctor_(BinaryFunctor())
4655 marray_detail::Assert(e1_.size() != 0 && e2_.size() != 0);
4656 marray_detail::Assert(e1_.dimension() == e2_.dimension());
4657 for(std::size_t j=0; j<e1_.dimension(); ++j) {
4658 marray_detail::Assert(e1_.shape(j) == e2_.shape(j));
4662 const std::size_t dimension()
const
4663 {
return e1_.dimension() < e2_.dimension() ? e2_.dimension() : e1_.dimension(); }
4664 const std::size_t size()
const
4665 {
return e1_.size() < e2_.size() ? e2_.size() : e1_.size(); }
4666 const std::size_t shape(
const std::size_t j)
const
4667 {
return e1_.dimension() < e2_.dimension() ? e2_.shape(j) : e1_.shape(j); }
4668 const std::size_t* shapeBegin()
const
4669 {
return e1_.dimension() < e2_.dimension() ? e2_.shapeBegin() : e1_.shapeBegin(); }
4670 const std::size_t* shapeEnd()
const
4671 {
return e1_.dimension() < e2_.dimension() ? e2_.shapeEnd() : e1_.shapeEnd(); }
4672 template<
class Tv,
bool isConst,
class A>
4673 bool overlaps(
const View<Tv, isConst, A>& v)
const
4674 {
return e1_.overlaps(v) || e2_.overlaps(v); }
4676 {
return e1_.coordinateOrder(); }
4677 const bool isSimple()
const
4678 {
return e1_.isSimple() && e2_.isSimple()
4679 && e1_.coordinateOrder() == e2_.coordinateOrder(); }
4680 template<
class Accessor>
4681 const value_type operator()(Accessor it)
const
4682 {
return binaryFunctor_(e1_(it), e2_(it)); }
4683 const value_type operator()(
const std::size_t c0,
const std::size_t c1)
const
4684 {
return binaryFunctor_(e1_(c0, c1), e2_(c0, c1)); }
4685 const value_type operator()(
const std::size_t c0,
const std::size_t c1,
const std::size_t c2)
const
4686 {
return binaryFunctor_(e1_(c0, c1, c2), e2_(c0, c1, c2)); }
4687 const value_type operator()(
const std::size_t c0,
const std::size_t c1,
const std::size_t c2,
const std::size_t c3)
const
4688 {
return binaryFunctor_(e1_(c0, c1, c2, c3), e2_(c0, c1, c2, c3)); }
4689 const value_type operator()(
const std::size_t c0,
const std::size_t c1,
const std::size_t c2,
const std::size_t c3,
const std::size_t c4)
const
4690 {
return binaryFunctor_(e1_(c0, c1, c2, c3, c4), e2_(c0, c1, c2, c3, c4)); }
4691 const value_type operator[](
const std::size_t offset)
const
4692 {
return binaryFunctor_(e1_[offset], e2_[offset]); }
4694 class ExpressionIterator {
4696 ExpressionIterator(
const BinaryViewExpression<E1, T1, E2, T2, BinaryFunctor>& expression)
4697 : binaryFunctor_(expression.binaryFunctor_),
4698 iterator1_(expression.e1_),
4699 iterator2_(expression.e2_)
4701 void incrementCoordinate(
const std::size_t coordinateIndex)
4702 { iterator1_.incrementCoordinate(coordinateIndex);
4703 iterator2_.incrementCoordinate(coordinateIndex); }
4704 void resetCoordinate(
const std::size_t coordinateIndex)
4705 { iterator1_.resetCoordinate(coordinateIndex);
4706 iterator2_.resetCoordinate(coordinateIndex); }
4708 {
return binaryFunctor_(*iterator1_, *iterator2_); }
4710 BinaryFunctor binaryFunctor_;
4711 typename E1::ExpressionIterator iterator1_;
4712 typename E2::ExpressionIterator iterator2_;
4716 const expression_type_1& e1_;
4717 const expression_type_2& e2_;
4718 BinaryFunctor binaryFunctor_;
4721 template<
class E,
class T,
class S,
class BinaryFunctor>
4722 class BinaryViewExpressionScalarFirst
4723 :
public ViewExpression<BinaryViewExpressionScalarFirst<E, T, S, BinaryFunctor>,
4724 typename marray_detail::PromoteType<T, S>::type> {
4726 typedef E expression_type;
4727 typedef T value_type_1;
4728 typedef S scalar_type;
4729 typedef typename marray_detail::PromoteType<T, S>::type value_type;
4730 typedef BinaryFunctor functor_type;
4731 typedef ViewExpression<BinaryViewExpressionScalarFirst<E, T, S, BinaryFunctor>,
4734 BinaryViewExpressionScalarFirst(
const ViewExpression<E, T>& e,
4735 const scalar_type& scalar)
4737 scalar_(scalar), binaryFunctor_(BinaryFunctor())
4739 const std::size_t dimension()
const
4740 {
return e_.dimension(); }
4741 const std::size_t size()
const
4742 {
return e_.size(); }
4743 const std::size_t shape(
const std::size_t j)
const
4744 {
return e_.shape(j); }
4745 const std::size_t* shapeBegin()
const
4746 {
return e_.shapeBegin(); }
4747 const std::size_t* shapeEnd()
const
4748 {
return e_.shapeEnd(); }
4749 template<
class Tv,
bool isConst,
class A>
4750 bool overlaps(
const View<Tv, isConst, A>& v)
const
4751 {
return e_.overlaps(v); }
4753 {
return e_.coordinateOrder(); }
4754 const bool isSimple()
const
4755 {
return e_.isSimple(); }
4756 template<
class Accessor>
4757 const value_type operator()(Accessor it)
const
4758 {
return binaryFunctor_(scalar_, e_(it)); }
4759 const value_type operator()(
const std::size_t c0,
const std::size_t c1)
const
4760 {
return binaryFunctor_(scalar_, e_(c0, c1)); }
4761 const value_type operator()(
const std::size_t c0,
const std::size_t c1,
const std::size_t c2)
const
4762 {
return binaryFunctor_(scalar_, e_(c0, c1, c2)); }
4763 const value_type operator()(
const std::size_t c0,
const std::size_t c1,
const std::size_t c2,
const std::size_t c3)
const
4764 {
return binaryFunctor_(scalar_, e_(c0, c1, c2, c3)); }
4765 const value_type operator()(
const std::size_t c0,
const std::size_t c1,
const std::size_t c2,
const std::size_t c3,
const std::size_t c4)
const
4766 {
return binaryFunctor_(scalar_, e_(c0, c1, c2, c3, c4)); }
4767 const value_type operator[](
const std::size_t offset)
const
4768 {
return binaryFunctor_(scalar_, e_[offset]); }
4770 class ExpressionIterator {
4772 ExpressionIterator(
const BinaryViewExpressionScalarFirst<E, T, S, BinaryFunctor>& expression)
4773 : binaryFunctor_(expression.binaryFunctor_),
4774 scalar_(expression.scalar_),
4775 iterator_(expression.e_)
4777 void incrementCoordinate(
const std::size_t coordinateIndex)
4778 { iterator_.incrementCoordinate(coordinateIndex); }
4779 void resetCoordinate(
const std::size_t coordinateIndex)
4780 { iterator_.resetCoordinate(coordinateIndex); }
4782 {
return binaryFunctor_(scalar_, *iterator_); }
4784 BinaryFunctor binaryFunctor_;
4785 const typename BinaryViewExpressionScalarFirst<E, T, S, BinaryFunctor>::scalar_type& scalar_;
4786 typename E::ExpressionIterator iterator_;
4790 const expression_type& e_;
4791 const scalar_type scalar_;
4792 BinaryFunctor binaryFunctor_;
4795 template<
class E,
class T,
class S,
class BinaryFunctor>
4796 class BinaryViewExpressionScalarSecond
4797 :
public ViewExpression<BinaryViewExpressionScalarSecond<E, T, S, BinaryFunctor>,
4798 typename marray_detail::PromoteType<T, S>::type> {
4800 typedef T value_type_1;
4801 typedef E expression_type;
4802 typedef S scalar_type;
4803 typedef typename marray_detail::PromoteType<T, S>::type value_type;
4804 typedef BinaryFunctor functor_type;
4805 typedef ViewExpression<BinaryViewExpressionScalarSecond<E, T, S, BinaryFunctor>,
4808 BinaryViewExpressionScalarSecond(
const ViewExpression<E, T>& e,
4809 const scalar_type& scalar)
4811 scalar_(scalar), binaryFunctor_(BinaryFunctor())
4813 const std::size_t dimension()
const
4814 {
return e_.dimension(); }
4815 const std::size_t size()
const
4816 {
return e_.size(); }
4817 const std::size_t shape(
const std::size_t j)
const
4818 {
return e_.shape(j); }
4819 const std::size_t* shapeBegin()
const
4820 {
return e_.shapeBegin(); }
4821 const std::size_t* shapeEnd()
const
4822 {
return e_.shapeEnd(); }
4823 template<
class Tv,
bool isConst,
class A>
4824 bool overlaps(
const View<Tv, isConst, A>& v)
const
4825 {
return e_.overlaps(v); }
4827 {
return e_.coordinateOrder(); }
4828 const bool isSimple()
const
4829 {
return e_.isSimple(); }
4830 template<
class Accessor>
4831 const value_type operator()(Accessor it)
const
4832 {
return binaryFunctor_(e_(it), scalar_); }
4833 const value_type operator()(
const std::size_t c0,
const std::size_t c1)
const
4834 {
return binaryFunctor_(e_(c0, c1), scalar_); }
4835 const value_type operator()(
const std::size_t c0,
const std::size_t c1,
const std::size_t c2)
const
4836 {
return binaryFunctor_(e_(c0, c1, c2), scalar_); }
4837 const value_type operator()(
const std::size_t c0,
const std::size_t c1,
const std::size_t c2,
const std::size_t c3)
const
4838 {
return binaryFunctor_(e_(c0, c1, c2, c3), scalar_); }
4839 const value_type operator()(
const std::size_t c0,
const std::size_t c1,
const std::size_t c2,
const std::size_t c3,
const std::size_t c4)
const
4840 {
return binaryFunctor_(e_(c0, c1, c2, c3, c4), scalar_); }
4841 const value_type operator[](
const std::size_t offset)
const
4842 {
return binaryFunctor_(e_[offset], scalar_); }
4844 class ExpressionIterator {
4846 ExpressionIterator(
const BinaryViewExpressionScalarSecond<E, T, S, BinaryFunctor>& expression)
4847 : binaryFunctor_(expression.binaryFunctor_),
4848 scalar_(expression.scalar_),
4849 iterator_(expression.e_)
4851 void incrementCoordinate(
const std::size_t coordinateIndex)
4852 { iterator_.incrementCoordinate(coordinateIndex); }
4853 void resetCoordinate(
const std::size_t coordinateIndex)
4854 { iterator_.resetCoordinate(coordinateIndex); }
4856 {
return binaryFunctor_(*iterator_, scalar_); }
4858 BinaryFunctor binaryFunctor_;
4859 const typename BinaryViewExpressionScalarSecond<E, T, S, BinaryFunctor>::scalar_type& scalar_;
4860 typename E::ExpressionIterator iterator_;
4864 const expression_type& e_;
4865 const scalar_type scalar_;
4866 BinaryFunctor binaryFunctor_;
4873 namespace marray_detail {
4879 typedef typename A::template rebind<std::size_t>::other allocator_type;
4881 Geometry(
const allocator_type& = allocator_type());
4883 const std::size_t = 0,
const bool =
true,
4884 const allocator_type& = allocator_type());
4885 template<
class ShapeIterator>
4886 Geometry(ShapeIterator, ShapeIterator,
4889 const allocator_type& = allocator_type());
4890 template<
class ShapeIterator,
class Str
ideIterator>
4891 Geometry(ShapeIterator, ShapeIterator, StrideIterator,
4893 const allocator_type& = allocator_type());
4894 Geometry(
const Geometry<A>&);
4897 Geometry<A>& operator=(
const Geometry<A>&);
4899 void resize(
const std::size_t dimension);
4900 const std::size_t dimension()
const;
4901 const std::size_t shape(
const std::size_t)
const;
4902 std::size_t& shape(
const std::size_t);
4903 const std::size_t shapeStrides(
const std::size_t)
const;
4904 std::size_t& shapeStrides(
const std::size_t);
4905 const std::size_t strides(
const std::size_t)
const;
4906 std::size_t& strides(
const std::size_t);
4907 const std::size_t* shapeBegin()
const;
4908 std::size_t* shapeBegin();
4909 const std::size_t* shapeEnd()
const;
4910 std::size_t* shapeEnd();
4911 const std::size_t* shapeStridesBegin()
const;
4912 std::size_t* shapeStridesBegin();
4913 const std::size_t* shapeStridesEnd()
const;
4914 std::size_t* shapeStridesEnd();
4915 const std::size_t* stridesBegin()
const;
4916 std::size_t* stridesBegin();
4917 const std::size_t* stridesEnd()
const;
4918 std::size_t* stridesEnd();
4919 const std::size_t size()
const;
4920 std::size_t& size();
4923 const bool isSimple()
const;
4924 void updateSimplicity();
4928 allocator_type allocator_;
4929 std::size_t* shape_;
4930 std::size_t* shapeStrides_;
4933 std::size_t* strides_;
4934 std::size_t dimension_;
4946 Geometry<A>::Geometry
4948 const typename Geometry<A>::allocator_type& allocator
4950 : allocator_(allocator),
4963 Geometry<A>::Geometry
4965 const Geometry<A>& g
4967 : allocator_(g.allocator_),
4968 shape_(g.dimension_==0 ? 0 : allocator_.allocate(g.dimension_*3)),
4969 shapeStrides_(shape_ + g.dimension_),
4970 strides_(shapeStrides_ + g.dimension_),
4971 dimension_(g.dimension_),
4973 coordinateOrder_(g.coordinateOrder_),
4974 isSimple_(g.isSimple_)
4983 memcpy(shape_, g.shape_, (dimension_*3)*
sizeof(std::size_t));
4988 Geometry<A>::Geometry
4990 const std::size_t dimension,
4991 const CoordinateOrder& order,
4992 const std::size_t size,
4993 const bool isSimple,
4994 const typename Geometry<A>::allocator_type& allocator
4996 : allocator_(allocator),
4997 shape_(allocator_.allocate(dimension*3)),
4998 shapeStrides_(shape_+dimension),
4999 strides_(shapeStrides_+dimension),
5000 dimension_(dimension),
5002 coordinateOrder_(order),
5008 template<
class ShapeIterator>
5010 Geometry<A>::Geometry
5012 ShapeIterator begin,
5014 const CoordinateOrder& externalCoordinateOrder,
5015 const CoordinateOrder& internalCoordinateOrder,
5016 const typename Geometry<A>::allocator_type& allocator
5018 : allocator_(allocator),
5019 shape_(allocator_.allocate(std::distance(begin, end) * 3)),
5020 shapeStrides_(shape_ + std::distance(begin, end)),
5021 strides_(shapeStrides_ + std::distance(begin, end)),
5022 dimension_(std::distance(begin, end)),
5024 coordinateOrder_(internalCoordinateOrder),
5027 if(dimension_ != 0) {
5028 isSimple_ = (externalCoordinateOrder == internalCoordinateOrder);
5029 for(std::size_t j=0; j<dimension(); ++j, ++begin) {
5030 const std::size_t s =
static_cast<std::size_t
>(*begin);
5034 stridesFromShape(shapeBegin(), shapeEnd(), stridesBegin(),
5035 externalCoordinateOrder);
5036 stridesFromShape(shapeBegin(), shapeEnd(), shapeStridesBegin(),
5037 internalCoordinateOrder);
5042 template<
class ShapeIterator,
class Str
ideIterator>
5044 Geometry<A>::Geometry
5046 ShapeIterator begin,
5049 const CoordinateOrder& internalCoordinateOrder,
5050 const typename Geometry<A>::allocator_type& allocator
5052 : allocator_(allocator),
5053 shape_(allocator_.allocate(std::distance(begin, end) * 3)),
5054 shapeStrides_(shape_ + std::distance(begin, end)),
5055 strides_(shapeStrides_ + std::distance(begin, end)),
5056 dimension_(std::distance(begin, end)),
5058 coordinateOrder_(internalCoordinateOrder),
5061 if(dimension() != 0) {
5062 for(std::size_t j=0; j<dimension(); ++j, ++begin, ++it) {
5063 const std::size_t s =
static_cast<std::size_t
>(*begin);
5068 stridesFromShape(shapeBegin(), shapeEnd(), shapeStridesBegin(),
5069 internalCoordinateOrder);
5076 Geometry<A>::~Geometry()
5078 allocator_.deallocate(shape_, dimension_*3);
5083 Geometry<A>::operator=
5085 const Geometry<A>& g
5089 if(g.dimension_ != dimension_) {
5090 allocator_.deallocate(shape_, dimension_*3);
5091 dimension_ = g.dimension_;
5092 shape_ = allocator_.allocate(dimension_*3);
5093 shapeStrides_ = shape_+dimension_;
5094 strides_ = shapeStrides_+dimension_;
5095 dimension_ = g.dimension_;
5104 memcpy(shape_, g.shape_, (dimension_*3)*
sizeof(std::size_t));
5106 coordinateOrder_ = g.coordinateOrder_;
5107 isSimple_ = g.isSimple_;
5116 const std::size_t dimension
5119 if(dimension != dimension_) {
5120 std::size_t* newShape = allocator_.allocate(dimension*3);
5121 std::size_t* newShapeStrides = newShape + dimension;
5122 std::size_t* newStrides = newShapeStrides + dimension;
5123 for(std::size_t j=0; j<( (dimension < dimension_) ? dimension : dimension_); ++j) {
5125 newShape[j] = shape(j);
5126 newShapeStrides[j] = shapeStrides(j);
5127 newStrides[j] = strides(j);
5129 allocator_.deallocate(shape_, dimension_*3);
5131 shapeStrides_ = newShapeStrides;
5132 strides_ = newStrides;
5133 dimension_ = dimension;
5138 inline const std::size_t
5139 Geometry<A>::dimension()
const
5145 inline const std::size_t
5146 Geometry<A>::shape(
const std::size_t j)
const
5148 Assert(MARRAY_NO_DEBUG || j<dimension_);
5154 Geometry<A>::shape(
const std::size_t j)
5156 Assert(MARRAY_NO_DEBUG || j<dimension_);
5161 inline const std::size_t
5162 Geometry<A>::shapeStrides
5167 Assert(MARRAY_NO_DEBUG || j<dimension_);
5168 return shapeStrides_[j];
5173 Geometry<A>::shapeStrides
5178 Assert(MARRAY_NO_DEBUG || j<dimension_);
5179 return shapeStrides_[j];
5183 inline const std::size_t
5184 Geometry<A>::strides
5189 Assert(MARRAY_NO_DEBUG || j<dimension_);
5195 Geometry<A>::strides
5200 Assert(MARRAY_NO_DEBUG || j<dimension_);
5205 inline const std::size_t*
5206 Geometry<A>::shapeBegin()
const
5213 Geometry<A>::shapeBegin()
5219 inline const std::size_t*
5220 Geometry<A>::shapeEnd()
const
5222 return shape_ + dimension_;
5227 Geometry<A>::shapeEnd()
5229 return shape_ + dimension_;
5233 inline const std::size_t*
5234 Geometry<A>::shapeStridesBegin()
const
5236 return shapeStrides_;
5241 Geometry<A>::shapeStridesBegin()
5243 return shapeStrides_;
5247 inline const std::size_t*
5248 Geometry<A>::shapeStridesEnd()
const
5250 return shapeStrides_ + dimension_;
5255 Geometry<A>::shapeStridesEnd()
5257 return shapeStrides_ + dimension_;
5261 inline const std::size_t*
5262 Geometry<A>::stridesBegin()
const
5269 Geometry<A>::stridesBegin()
5275 inline const std::size_t*
5276 Geometry<A>::stridesEnd()
const
5278 return strides_ + dimension_;
5283 Geometry<A>::stridesEnd()
5285 return strides_ + dimension_;
5289 inline const std::size_t
5290 Geometry<A>::size()
const
5304 Geometry<A>::coordinateOrder()
const
5306 return coordinateOrder_;
5311 Geometry<A>::coordinateOrder()
5313 return coordinateOrder_;
5318 Geometry<A>::isSimple()
const
5325 Geometry<A>::isSimple()
5332 Geometry<A>::updateSimplicity()
5334 for(std::size_t j=0; j<dimension(); ++j) {
5335 if(shapeStrides(j) != strides(j)) {
5344 template<
class ShapeIterator,
class Str
idesIterator>
5348 ShapeIterator begin,
5350 StridesIterator strideBegin,
5351 const CoordinateOrder& coordinateOrder
5354 Assert(MARRAY_NO_ARG_TEST || std::distance(begin, end) != 0);
5355 std::size_t dimension = std::distance(begin, end);
5356 ShapeIterator shapeIt;
5357 StridesIterator strideIt;
5358 if(coordinateOrder == FirstMajorOrder) {
5359 shapeIt = begin + (dimension-1);
5360 strideIt = strideBegin + (dimension-1);
5362 for(std::size_t j=1; j<dimension; ++j) {
5363 std::size_t tmp = *strideIt;
5365 (*strideIt) = tmp * (*shapeIt);
5371 strideIt = strideBegin;
5373 for(std::size_t j=1; j<dimension; ++j) {
5374 std::size_t tmp = *strideIt;
5376 (*strideIt) = tmp * (*shapeIt);
5382 template<
unsigned short N,
class Functor,
class T,
class A>
5383 struct OperateHelperUnary
5385 static inline void operate
5387 View<T, false, A>& v,
5392 for(std::size_t j=0; j<v.shape(N-1); ++j) {
5393 OperateHelperUnary<N-1, Functor, T, A>::operate(v, f, data);
5394 data += v.strides(N-1);
5396 data -= v.shape(N-1) * v.strides(N-1);
5401 template<
class Functor,
class T,
class A>
5402 struct OperateHelperUnary<0, Functor, T, A>
5404 static inline void operate
5406 View<T, false, A>& v,
5415 template<
unsigned short N,
class Functor,
class T1,
class T2,
class A>
5416 struct OperateHelperBinaryScalar
5418 static inline void operate
5420 View<T1, false, A>& v,
5426 for(std::size_t j=0; j<v.shape(N-1); ++j) {
5427 OperateHelperBinaryScalar<N-1, Functor, T1, T2, A>::operate(
5429 data += v.strides(N-1);
5431 data -= v.shape(N-1) * v.strides(N-1);
5435 template<
class Functor,
class T1,
class T2,
class A>
5436 struct OperateHelperBinaryScalar<0, Functor, T1, T2, A>
5438 static inline void operate
5440 View<T1, false, A>& v,
5450 template<
unsigned short N,
class Functor,
class T1,
class T2,
5451 bool isConst,
class A1,
class A2>
5452 struct OperateHelperBinary
5454 static inline void operate
5456 View<T1, false, A1>& v,
5457 const View<T2, isConst, A2>& w,
5463 for(std::size_t j=0; j<v.shape(N-1); ++j) {
5464 OperateHelperBinary<N-1, Functor, T1, T2, isConst, A1, A2>::operate(
5465 v, w, f, data1, data2);
5466 data1 += v.strides(N-1);
5467 data2 += w.strides(N-1);
5469 data1 -= v.shape(N-1) * v.strides(N-1);
5470 data2 -= w.shape(N-1) * w.strides(N-1);
5474 template<
class Functor,
class T1,
class T2,
bool isConst,
class A1,
class A2>
5475 struct OperateHelperBinary<0, Functor, T1, T2, isConst, A1, A2>
5477 static inline void operate
5479 View<T1, false, A1>& v,
5480 const View<T2, isConst, A2>& w,
5490 template<
class TFrom,
class TTo,
class AFrom,
class ATo>
5491 struct AssignmentOperatorHelper<false, TFrom, TTo, AFrom, ATo>
5502 const View<TFrom, true, AFrom>& from,
5503 View<TTo, false, ATo>& to
5506 typedef typename View<TFrom, true, AFrom>::const_iterator FromIterator;
5507 typedef typename View<TTo, false, ATo>::iterator ToIterator;
5508 if(!MARRAY_NO_ARG_TEST) {
5509 Assert(from.data_ != 0 && from.dimension() == to.dimension());
5510 for(std::size_t j=0; j<from.dimension(); ++j) {
5511 Assert(from.shape(j) == to.shape(j));
5514 if(from.overlaps(to)) {
5515 Marray<TFrom, AFrom> m = from;
5518 else if(from.coordinateOrder() == to.coordinateOrder()
5519 && from.isSimple() && to.isSimple()
5520 && IsEqual<TFrom, TTo>::type) {
5521 memcpy(to.data_, from.data_, (from.size())*
sizeof(TFrom));
5523 else if(from.dimension() == 1)
5524 OperateHelperBinary<1, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5525 else if(from.dimension() == 2)
5526 OperateHelperBinary<2, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5527 else if(from.dimension() == 3)
5528 OperateHelperBinary<3, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5529 else if(from.dimension() == 4)
5530 OperateHelperBinary<4, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5531 else if(from.dimension() == 5)
5532 OperateHelperBinary<5, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5533 else if(from.dimension() == 6)
5534 OperateHelperBinary<6, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5535 else if(from.dimension() == 7)
5536 OperateHelperBinary<7, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5537 else if(from.dimension() == 8)
5538 OperateHelperBinary<8, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5539 else if(from.dimension() == 9)
5540 OperateHelperBinary<9, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5541 else if(from.dimension() == 10)
5542 OperateHelperBinary<10, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5544 FromIterator itFrom = from.begin();
5545 ToIterator itTo = to.begin();
5546 for(; itFrom.hasMore(); ++itFrom, ++itTo) {
5547 *itTo =
static_cast<TTo
>(*itFrom);
5558 const View<TFrom, false, AFrom>& from,
5559 View<TTo, false, ATo>& to
5562 typedef typename View<TFrom, false, AFrom>::const_iterator FromIterator;
5563 typedef typename View<TTo, false, ATo>::iterator ToIterator;
5564 if(static_cast<const void*>(&from) != static_cast<const void*>(&to)) {
5567 Assert(MARRAY_NO_ARG_TEST ||
sizeof(TTo) ==
sizeof(TFrom));
5568 to.data_ =
static_cast<TTo*
>(
static_cast<void*
>(from.data_));
5569 to.geometry_ = from.geometry_;
5572 if(!MARRAY_NO_ARG_TEST) {
5573 Assert(from.data_ != 0 && from.dimension() == to.dimension());
5574 for(std::size_t j=0; j<from.dimension(); ++j) {
5575 Assert(from.shape(j) == to.shape(j));
5578 if(from.overlaps(to)) {
5579 Marray<TFrom, AFrom> m = from;
5582 else if(from.coordinateOrder() == to.coordinateOrder()
5583 && from.isSimple() && to.isSimple()
5584 && IsEqual<TFrom, TTo>::type) {
5585 memcpy(to.data_, from.data_, (from.size())*
sizeof(TFrom));
5587 else if(from.dimension() == 1)
5588 OperateHelperBinary<1, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5589 else if(from.dimension() == 2)
5590 OperateHelperBinary<2, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5591 else if(from.dimension() == 3)
5592 OperateHelperBinary<3, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5593 else if(from.dimension() == 4)
5594 OperateHelperBinary<4, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5595 else if(from.dimension() == 5)
5596 OperateHelperBinary<5, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5597 else if(from.dimension() == 6)
5598 OperateHelperBinary<6, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5599 else if(from.dimension() == 7)
5600 OperateHelperBinary<7, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5601 else if(from.dimension() == 8)
5602 OperateHelperBinary<8, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5603 else if(from.dimension() == 9)
5604 OperateHelperBinary<9, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5605 else if(from.dimension() == 10)
5606 OperateHelperBinary<10, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
5608 FromIterator itFrom = from.begin();
5609 ToIterator itTo = to.begin();
5610 for(; itFrom.hasMore(); ++itFrom, ++itTo) {
5611 *itTo =
static_cast<TTo
>(*itFrom);
5619 template<
class TFrom,
class TTo,
class AFrom,
class ATo>
5620 struct AssignmentOperatorHelper<true, TFrom, TTo, AFrom, ATo>
5623 template<
bool isConstFrom>
5626 const View<TFrom, isConstFrom, AFrom>& from,
5627 View<TTo, true, ATo>& to
5630 Assert(MARRAY_NO_ARG_TEST ||
sizeof(TFrom) ==
sizeof(TTo));
5631 to.data_ =
static_cast<const TTo*
>(
5632 static_cast<const void*
>(from.data_));
5633 to.geometry_ = from.geometry_;
5638 struct AccessOperatorHelper<true>
5641 template<
class T,
class U,
bool isConst,
class A>
5642 static typename View<T, isConst, A>::reference
5643 execute(
const View<T, isConst, A>& v,
const U& index)
5646 Assert(MARRAY_NO_DEBUG || v.data_ != 0);
5647 Assert(MARRAY_NO_DEBUG || v.dimension() != 0 || index == 0);
5649 v.indexToOffset(index, offset);
5650 return v.data_[offset];
5655 struct AccessOperatorHelper<false>
5658 template<
class T,
class U,
bool isConst,
class A>
5659 static typename View<T, isConst, A>::reference
5660 execute(
const View<T, isConst, A>& v, U it)
5663 Assert(MARRAY_NO_DEBUG || v.data_ != 0);
5664 Assert(MARRAY_NO_DEBUG || v.dimension() != 0 || *it == 0);
5666 v.coordinatesToOffset(it, offset);
5667 return v.data_[offset];
5671 template<
class Functor,
class T,
class A>
5675 View<T, false, A>& v,
5681 for(std::size_t j=0; j<v.size(); ++j) {
5685 else if(v.dimension() == 1)
5686 OperateHelperUnary<1, Functor, T, A>::operate(v, f, &v(0));
5687 else if(v.dimension() == 2)
5688 OperateHelperUnary<2, Functor, T, A>::operate(v, f, &v(0));
5689 else if(v.dimension() == 3)
5690 OperateHelperUnary<3, Functor, T, A>::operate(v, f, &v(0));
5691 else if(v.dimension() == 4)
5692 OperateHelperUnary<4, Functor, T, A>::operate(v, f, &v(0));
5693 else if(v.dimension() == 5)
5694 OperateHelperUnary<5, Functor, T, A>::operate(v, f, &v(0));
5695 else if(v.dimension() == 6)
5696 OperateHelperUnary<6, Functor, T, A>::operate(v, f, &v(0));
5697 else if(v.dimension() == 7)
5698 OperateHelperUnary<7, Functor, T, A>::operate(v, f, &v(0));
5699 else if(v.dimension() == 8)
5700 OperateHelperUnary<8, Functor, T, A>::operate(v, f, &v(0));
5701 else if(v.dimension() == 9)
5702 OperateHelperUnary<9, Functor, T, A>::operate(v, f, &v(0));
5703 else if(v.dimension() == 10)
5704 OperateHelperUnary<10, Functor, T, A>::operate(v, f, &v(0));
5706 for(
typename View<T, false, A>::iterator it = v.begin(); it.hasMore(); ++it) {
5712 template<
class Functor,
class T,
class A>
5716 View<T, false, A>& v,
5723 for(std::size_t j=0; j<v.size(); ++j) {
5727 else if(v.dimension() == 1)
5728 OperateHelperBinaryScalar<1, Functor, T, T, A>::operate(v, x, f, &v(0));
5729 else if(v.dimension() == 2)
5730 OperateHelperBinaryScalar<2, Functor, T, T, A>::operate(v, x, f, &v(0));
5731 else if(v.dimension() == 3)
5732 OperateHelperBinaryScalar<3, Functor, T, T, A>::operate(v, x, f, &v(0));
5733 else if(v.dimension() == 4)
5734 OperateHelperBinaryScalar<4, Functor, T, T, A>::operate(v, x, f, &v(0));
5735 else if(v.dimension() == 5)
5736 OperateHelperBinaryScalar<5, Functor, T, T, A>::operate(v, x, f, &v(0));
5737 else if(v.dimension() == 6)
5738 OperateHelperBinaryScalar<6, Functor, T, T, A>::operate(v, x, f, &v(0));
5739 else if(v.dimension() == 7)
5740 OperateHelperBinaryScalar<7, Functor, T, T, A>::operate(v, x, f, &v(0));
5741 else if(v.dimension() == 8)
5742 OperateHelperBinaryScalar<8, Functor, T, T, A>::operate(v, x, f, &v(0));
5743 else if(v.dimension() == 9)
5744 OperateHelperBinaryScalar<9, Functor, T, T, A>::operate(v, x, f, &v(0));
5745 else if(v.dimension() == 10)
5746 OperateHelperBinaryScalar<10, Functor, T, T, A>::operate(v, x, f, &v(0));
5748 for(
typename View<T, false, A>::iterator it = v.begin(); it.hasMore(); ++it) {
5754 template<
class Functor,
class T1,
class T2,
bool isConst,
class A>
5758 View<T1, false, A>& v,
5759 const View<T2, isConst, A>& w,
5763 if(!MARRAY_NO_ARG_TEST) {
5764 Assert(v.size() != 0 && w.size() != 0);
5765 Assert(w.dimension() == 0 || v.dimension() == w.dimension());
5766 if(w.dimension() != 0) {
5767 for(std::size_t j=0; j<v.dimension(); ++j) {
5768 Assert(v.shape(j) == w.shape(j));
5772 if(w.dimension() == 0) {
5776 for(std::size_t j=0; j<v.size(); ++j) {
5780 else if(v.dimension() == 1)
5781 OperateHelperBinaryScalar<1, Functor, T1, T2, A>::operate(v, x, f, &v(0));
5782 else if(v.dimension() == 2)
5783 OperateHelperBinaryScalar<2, Functor, T1, T2, A>::operate(v, x, f, &v(0));
5784 else if(v.dimension() == 3)
5785 OperateHelperBinaryScalar<3, Functor, T1, T2, A>::operate(v, x, f, &v(0));
5786 else if(v.dimension() == 4)
5787 OperateHelperBinaryScalar<4, Functor, T1, T2, A>::operate(v, x, f, &v(0));
5788 else if(v.dimension() == 5)
5789 OperateHelperBinaryScalar<5, Functor, T1, T2, A>::operate(v, x, f, &v(0));
5790 else if(v.dimension() == 6)
5791 OperateHelperBinaryScalar<6, Functor, T1, T2, A>::operate(v, x, f, &v(0));
5792 else if(v.dimension() == 7)
5793 OperateHelperBinaryScalar<7, Functor, T1, T2, A>::operate(v, x, f, &v(0));
5794 else if(v.dimension() == 8)
5795 OperateHelperBinaryScalar<8, Functor, T1, T2, A>::operate(v, x, f, &v(0));
5796 else if(v.dimension() == 9)
5797 OperateHelperBinaryScalar<9, Functor, T1, T2, A>::operate(v, x, f, &v(0));
5798 else if(v.dimension() == 10)
5799 OperateHelperBinaryScalar<10, Functor, T1, T2, A>::operate(v, x, f, &v(0));
5801 for(
typename View<T1, false>::iterator it = v.begin(); it.hasMore(); ++it) {
5812 if(v.coordinateOrder() == w.coordinateOrder()
5813 && v.isSimple() && w.isSimple()) {
5815 const T2* dataW = &w(0);
5816 for(std::size_t j=0; j<v.size(); ++j) {
5817 f(dataV[j], dataW[j]);
5820 else if(v.dimension() == 1)
5821 OperateHelperBinary<1, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
5822 else if(v.dimension() == 2)
5823 OperateHelperBinary<2, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
5824 else if(v.dimension() == 3)
5825 OperateHelperBinary<3, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
5826 else if(v.dimension() == 4)
5827 OperateHelperBinary<4, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
5828 else if(v.dimension() == 5)
5829 OperateHelperBinary<5, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
5830 else if(v.dimension() == 6)
5831 OperateHelperBinary<6, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
5832 else if(v.dimension() == 7)
5833 OperateHelperBinary<7, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
5834 else if(v.dimension() == 8)
5835 OperateHelperBinary<8, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
5836 else if(v.dimension() == 9)
5837 OperateHelperBinary<9, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
5838 else if(v.dimension() == 10)
5839 OperateHelperBinary<10, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
5841 typename View<T1, false>::iterator itV = v.begin();
5842 typename View<T2, isConst>::const_iterator itW = w.begin();
5843 for(; itV.hasMore(); ++itV, ++itW) {
5844 Assert(MARRAY_NO_DEBUG || itW.hasMore());
5847 Assert(MARRAY_NO_DEBUG || !itW.hasMore());
5853 template<
class Functor,
class T1,
class A,
class E,
class T2>
5856 View<T1, false, A>& v,
5857 const ViewExpression<E, T2>& expression,
5861 const E& e = expression;
5862 if(!MARRAY_NO_DEBUG) {
5863 Assert(v.size() != 0 && e.size() != 0);
5864 Assert(e.dimension() == v.dimension());
5865 if(v.dimension() == 0) {
5866 Assert(v.size() == 1 && e.size() == 1);
5869 for(std::size_t j=0; j<v.dimension(); ++j) {
5870 Assert(v.shape(j) == e.shape(j));
5878 else if(v.dimension() == 0) {
5881 else if(v.isSimple() && e.isSimple()
5882 && v.coordinateOrder() == e.coordinateOrder()) {
5883 for(std::size_t j=0; j<v.size(); ++j) {
5889 typename E::ExpressionIterator itE(e);
5890 std::size_t offsetV = 0;
5891 std::vector<std::size_t> coordinate(v.dimension());
5892 std::size_t maxDimension = v.dimension() - 1;
5894 f(v[offsetV], *itE);
5895 for(std::size_t j=0; j<v.dimension(); ++j) {
5896 if(coordinate[j]+1 == v.shape(j)) {
5897 if(j == maxDimension) {
5901 offsetV -= coordinate[j] * v.strides(j);
5902 itE.resetCoordinate(j);
5907 offsetV += v.strides(j);
5908 itE.incrementCoordinate(j);