31 template<
class E,
class T>
34 template<
class E,
class T,
class UnaryFunctor>
35 class UnaryViewExpression;
36 template<
class E1,
class T1,
class E2,
class T2,
class BinaryFunctor>
37 class BinaryViewExpression;
38 template<
class E,
class T,
class S,
class BinaryFunctor>
39 class BinaryViewExpressionScalarFirst;
40 template<
class E,
class T,
class S,
class BinaryFunctor>
41 class BinaryViewExpressionScalarSecond;
43 template<
class T,
bool isConst = false,
class A = std::allocator<
size_t> >
45 #ifdef HAVE_CPP0X_TEMPLATE_ALIASES
48 template<
class T,
bool isConst,
class A = std::allocator<
size_t> >
50 template<
class T,
class A = std::allocator<
size_t> >
class Vector;
51 template<
class T,
class A = std::allocator<
size_t> >
class Matrix;
52 template<
class T,
class A = std::allocator<
size_t> >
class Marray;
59 const bool MARRAY_NO_DEBUG =
false;
60 const bool MARRAY_NO_ARG_TEST =
false;
64 namespace marray_detail {
66 template <
bool PREDICATE,
class TRUECASE,
class FALSECASE>
68 template <
class TRUECASE,
class FALSECASE>
69 struct IfBool<true, TRUECASE, FALSECASE>
70 {
typedef TRUECASE type; };
71 template <
class TRUECASE,
class FALSECASE>
72 struct IfBool<false, TRUECASE, FALSECASE>
73 {
typedef FALSECASE type; };
75 template <
class T1,
class T2>
77 {
static const bool type =
false; };
80 {
static const bool type =
true; };
82 template<
class T>
struct TypeTraits
83 {
static const unsigned char position = 255; };
84 template<>
struct TypeTraits<char>
85 {
static const unsigned char position = 0; };
86 template<>
struct TypeTraits<unsigned char>
87 {
static const unsigned char position = 1; };
88 template<>
struct TypeTraits<short>
89 {
static const unsigned char position = 2; };
90 template<>
struct TypeTraits<unsigned short>
91 {
static const unsigned char position = 3; };
92 template<>
struct TypeTraits<int>
93 {
static const unsigned char position = 4; };
94 template<>
struct TypeTraits<unsigned int>
95 {
static const unsigned char position = 5; };
96 template<>
struct TypeTraits<long>
97 {
static const unsigned char position = 6; };
98 template<>
struct TypeTraits<unsigned long>
99 {
static const unsigned char position = 7; };
100 template<>
struct TypeTraits<float>
101 {
static const unsigned char position = 8; };
102 template<>
struct TypeTraits<double>
103 {
static const unsigned char position = 9; };
104 template<>
struct TypeTraits<long double>
105 {
static const unsigned char position = 10; };
106 template<
class A,
class B>
struct PromoteType
107 {
typedef typename IfBool<TypeTraits<A>::position >= TypeTraits<B>::position, A, B>::type type; };
110 template<
class A>
inline void Assert(A assertion) {
113 if(!assertion)
throw std::runtime_error(
"Assertion failed.");
118 template<
class A = std::allocator<
size_t> >
class Geometry;
119 template<
class ShapeIterator,
class Str
idesIterator>
120 inline void stridesFromShape(ShapeIterator, ShapeIterator,
124 template<
class Functor,
class T,
class A>
126 template<
class Functor,
class T,
class A>
128 template<
class Functor,
class T1,
class T2,
bool isConst,
class A>
130 template<
class Functor,
class T1,
class A,
class E,
class T2>
134 template<
unsigned short N,
class Functor,
class T,
class A>
135 struct OperateHelperUnary;
136 template<
unsigned short N,
class Functor,
class T1,
class T2,
class A>
137 struct OperateHelperBinaryScalar;
138 template<
unsigned short N,
class Functor,
class T1,
class T2,
139 bool isConst,
class A1,
class A2>
140 struct OperateHelperBinary;
141 template<
bool isConstTo,
class TFrom,
class TTo,
class AFrom,
class ATo>
142 struct AssignmentOperatorHelper;
143 template<
bool isIntegral>
144 struct AccessOperatorHelper;
148 struct Negative {
void operator()(T& x) { x = -x; } };
150 struct PrefixIncrement {
void operator()(T& x) { ++x; } };
152 struct PostfixIncrement {
void operator()(T& x) { x++; } };
154 struct PrefixDecrement {
void operator()(T& x) { --x; } };
156 struct PostfixDecrement {
void operator()(T& x) { x--; } };
159 template<
class T1,
class T2>
160 struct Assign {
void operator()(T1& x,
const T2& y) { x = y; } };
161 template<
class T1,
class T2>
162 struct PlusEqual {
void operator()(T1& x,
const T2& y) { x += y; } };
163 template<
class T1,
class T2>
164 struct MinusEqual {
void operator()(T1& x,
const T2& y) { x -= y; } };
165 template<
class T1,
class T2>
166 struct TimesEqual {
void operator()(T1& x,
const T2& y) { x *= y; } };
167 template<
class T1,
class T2>
168 struct DividedByEqual {
void operator()(T1& x,
const T2& y) { x /= y; } };
172 struct Negate { T operator()(
const T& x)
const {
return -x; } };
175 template<
class T1,
class T2,
class U>
176 struct Plus { U operator()(
const T1& x,
const T2& y)
const {
return x + y; } };
177 template<
class T1,
class T2,
class U>
178 struct Minus { U operator()(
const T1& x,
const T2& y)
const {
return x - y; } };
179 template<
class T1,
class T2,
class U>
180 struct Times { U operator()(
const T1& x,
const T2& y)
const {
return x * y; } };
181 template<
class T1,
class T2,
class U>
182 struct DividedBy { U operator()(
const T1& x,
const T2& y)
const {
return x / y; } };
204 template<
class T,
bool isConst,
class A>
206 :
public ViewExpression<View<T, isConst, A>, T>
211 typedef typename marray_detail::IfBool<isConst, const T*, T*>::type
pointer;
213 typedef typename marray_detail::IfBool<isConst, const T&, T&>::type
reference;
226 template<
class ShapeIterator>
227 View(ShapeIterator, ShapeIterator, pointer,
231 template<
class ShapeIterator,
class Str
ideIterator>
232 View(ShapeIterator, ShapeIterator, StrideIterator,
235 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
236 View(std::initializer_list<size_t>, pointer,
240 View(std::initializer_list<size_t>, std::initializer_list<size_t>,
249 template<
class TLocal,
bool isConstLocal,
class ALocal>
251 template<
class E,
class Te>
256 template<
class ShapeIterator>
257 void assign(ShapeIterator, ShapeIterator, pointer,
261 template<
class ShapeIterator,
class Str
ideIterator>
262 void assign(ShapeIterator, ShapeIterator, StrideIterator,
265 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
266 void assign(std::initializer_list<size_t>, pointer,
270 void assign(std::initializer_list<size_t>,
271 std::initializer_list<size_t>, pointer,
278 const size_t size()
const;
279 const size_t shape(
const size_t)
const;
282 const size_t strides(
const size_t)
const;
287 template<
class TLocal,
bool isConstLocal,
class ALocal>
292 template<
class U> reference
operator()(U)
const;
293 #ifndef HAVE_CPP0X_VARIADIC_TEMPLATES
294 reference
operator()(
const size_t,
const size_t);
295 reference
operator()(
const size_t,
const size_t)
const;
296 reference
operator()(
const size_t,
const size_t,
const size_t);
297 reference
operator()(
const size_t,
const size_t,
const size_t)
const;
298 reference
operator()(
const size_t,
const size_t,
const size_t,
300 reference
operator()(
const size_t,
const size_t,
const size_t,
302 reference
operator()(
const size_t,
const size_t,
const size_t,
303 const size_t,
const size_t);
304 reference
operator()(
const size_t,
const size_t,
const size_t,
305 const size_t,
const size_t)
const;
306 reference
operator()(
const size_t,
const size_t,
const size_t,
307 const size_t,
const size_t,
const size_t,
const size_t,
308 const size_t,
const size_t,
const size_t);
309 reference
operator()(
const size_t,
const size_t,
const size_t,
310 const size_t,
const size_t,
const size_t,
const size_t,
311 const size_t,
const size_t,
const size_t)
const;
315 template<
typename... Args>
316 reference
operator()(
const size_t,
const Args...);
317 template<
typename... Args>
318 reference
operator()(
const size_t,
const Args...)
const;
320 size_t elementAccessHelper(
const size_t,
const size_t);
321 size_t elementAccessHelper(
const size_t,
const size_t)
const;
322 template<
typename... Args>
323 size_t elementAccessHelper(
const size_t,
const size_t,
325 template<
typename... Args>
326 size_t elementAccessHelper(
const size_t,
const size_t,
327 const Args...)
const;
332 template<
class BaseIterator,
class ShapeIterator>
334 template<
class BaseIterator,
class ShapeIterator>
337 template<
class BaseIterator,
class ShapeIterator>
339 template<
class BaseIterator,
class ShapeIterator>
342 template<
class BaseIterator,
class ShapeIterator>
344 template<
class BaseIterator,
class ShapeIterator>
347 template<
class BaseIterator,
class ShapeIterator>
349 template<
class BaseIterator,
class ShapeIterator>
352 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
353 void view(std::initializer_list<size_t>,
355 void view(std::initializer_list<size_t>,
358 void constView(std::initializer_list<size_t>,
360 void constView(std::initializer_list<size_t>,
368 const_iterator
begin()
const;
369 const_iterator
end()
const;
370 reverse_iterator
rbegin();
371 reverse_iterator
rend();
372 const_reverse_iterator
rbegin()
const;
373 const_reverse_iterator
rend()
const;
376 template<
class ShapeIterator>
377 void reshape(ShapeIterator, ShapeIterator);
378 template<
class CoordinateIterator>
379 void permute(CoordinateIterator);
380 void transpose(
const size_t,
const size_t);
382 void shift(
const int);
385 template<
class ShapeIterator>
387 template<
class CoordinateIterator>
395 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
396 void reshape(std::initializer_list<size_t>);
397 void permute(std::initializer_list<size_t>);
404 template<
class CoordinateIterator>
406 template<
class CoordinateIterator>
408 template<
class CoordinateIterator>
411 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
422 typedef typename marray_detail::Geometry<A> geometry_type;
424 View(pointer,
const geometry_type&);
426 void updateSimplicity();
427 void testInvariant()
const;
430 const T& operator[](
const size_t)
const;
431 T& operator[](
const size_t);
435 geometry_type geometry_;
437 template<
class TLocal,
bool isConstLocal,
class ALocal>
439 template<
class TLocal,
class ALocal>
441 template<
class TLocal,
class ALocal>
443 template<
class TLocal,
class ALocal>
446 template<
bool isConstTo,
class TFrom,
class TTo,
class AFrom,
class ATo>
447 friend struct marray_detail::AssignmentOperatorHelper;
448 friend struct marray_detail::AccessOperatorHelper<true>;
449 friend struct marray_detail::AccessOperatorHelper<false>;
451 template<
class E,
class U>
453 template<
class E,
class U,
class UnaryFunctor>
454 friend class UnaryViewExpression;
455 template<
class E1,
class T1,
class E2,
class T2,
class BinaryFunctor>
456 friend class BinaryViewExpression;
457 template<
class E,
class U,
class S,
class BinaryFunctor>
458 friend class BinaryViewExpressionScalarFirst;
459 template<
class E,
class U,
class S,
class BinaryFunctor>
460 friend class BinaryViewExpressionScalarSecond;
462 template<
class Functor,
class T1,
class Alocal,
class E,
class T2>
472 template<
class T,
bool isConst,
class A>
480 typedef typename marray_detail::IfBool<isConst, const T*, T*>::type
pointer;
481 typedef typename marray_detail::IfBool<isConst, const T&, T&>::type
reference;
484 typedef typename marray_detail::IfBool<isConst, const View<T, true, A>*,
486 typedef typename marray_detail::IfBool<isConst, const View<T, true, A>&,
510 template<
bool isConstLocal>
512 template<
bool isConstLocal>
514 template<
bool isConstLocal>
516 template<
bool isConstLocal>
517 bool operator<(const Iterator<T, isConstLocal, A>&)
const;
518 template<
bool isConstLocal>
520 template<
bool isConstLocal>
521 bool operator<=(const Iterator<T, isConstLocal, A>&)
const;
522 template<
bool isConstLocal>
527 size_t index()
const;
528 template<
class CoordinateIterator>
532 void testInvariant()
const;
538 std::vector<size_t> coordinates_;
545 template<
class T,
class A>
547 :
public View<T, false, A>
566 template<
class ShapeIterator>
567 Marray(ShapeIterator, ShapeIterator,
const T& = T(),
570 template<
class ShapeIterator>
574 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
575 Marray(std::initializer_list<size_t>,
const T& = T(),
580 template<
class E,
class Te>
583 template<
class TLocal,
bool isConstLocal,
class ALocal>
590 template<
class TLocal,
bool isConstLocal,
class ALocal>
592 template<
class E,
class Te>
597 template<
class ShapeIterator>
598 void resize(ShapeIterator, ShapeIterator,
const T& = T());
599 template<
class ShapeIterator>
601 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
602 void resize(std::initializer_list<size_t>,
const T& = T());
607 typedef typename base::geometry_type geometry_type;
610 template<
class CoordinateIterator>
611 void permute(CoordinateIterator) {}
612 void transpose(
const size_t,
const size_t) {}
614 void shift(
const int) {}
617 void testInvariant()
const;
618 template<
bool SKIP_INITIALIZATION,
class ShapeIterator>
619 void resizeHelper(ShapeIterator, ShapeIterator,
const T& = T());
621 allocator_type dataAllocator_;
628 template<
class T,
class A>
647 template<
class TLocal,
bool isConstLocal,
class ALocal>
649 Vector(
const size_t,
const T& = T(),
653 template<
class E,
class Te>
656 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
657 Vector(std::initializer_list<T> list,
664 template<
class TLocal,
bool isConstLocal,
class ALocal>
666 template<
class E,
class Te>
675 void resize(
const size_t,
const T& = T());
679 void testInvariant()
const;
683 template<
class T,
class A>
704 template<
class TLocal,
bool isConstLocal,
class ALocal>
706 Matrix(
const size_t,
const size_t,
const T& = T(),
710 const size_t,
const size_t,
713 template<
class E,
class Te>
721 template<
class TLocal,
bool isConstLocal,
class ALocal>
723 template<
class E,
class Te>
727 void reshape(
const size_t,
const size_t);
728 void resize(
const size_t,
const size_t,
const T& = T());
732 void testInvariant()
const;
737 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
738 template<
class T,
bool isConst,
class A>
748 std::initializer_list<size_t> coordinate,
752 coordinatesToIndex(coordinate.begin(), out);
762 template<
class T,
bool isConst,
class A>
763 template<
class CoordinateIterator>
767 CoordinateIterator it,
773 for(
size_t j=0; j<this->dimension(); ++j, ++it) {
774 marray_detail::Assert(MARRAY_NO_ARG_TEST || static_cast<size_t>(*it) < shape(j));
775 out +=
static_cast<size_t>(*it) * geometry_.shapeStrides(j);
779 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
780 template<
class T,
bool isConst,
class A>
790 std::initializer_list<size_t> coordinate,
794 coordinatesToOffset(coordinate.begin(), out);
804 template<
class T,
bool isConst,
class A>
805 template<
class CoordinateIterator>
809 CoordinateIterator it,
815 for(
size_t j=0; j<this->dimension(); ++j, ++it) {
816 marray_detail::Assert(MARRAY_NO_ARG_TEST || static_cast<size_t>(*it) < shape(j));
817 out +=
static_cast<size_t>(*it) * strides(j);
828 template<
class T,
bool isConst,
class A>
829 template<
class CoordinateIterator>
834 CoordinateIterator outit
838 marray_detail::Assert(MARRAY_NO_DEBUG || this->dimension() > 0);
839 marray_detail::Assert(MARRAY_NO_ARG_TEST || index < this->size());
841 for(
size_t j=0; j<this->dimension(); ++j, ++outit) {
842 *outit =
size_t(index / geometry_.shapeStrides(j));
843 index = index % geometry_.shapeStrides(j);
847 size_t j = this->dimension()-1;
850 *outit =
size_t(index / geometry_.shapeStrides(j));
851 index = index % geometry_.shapeStrides(j);
869 template<
class T,
bool isConst,
class A>
878 marray_detail::Assert(MARRAY_NO_ARG_TEST || index < this->size());
885 for(
size_t j=0; j<this->dimension(); ++j) {
886 out += geometry_.strides(j) * (index / geometry_.shapeStrides(j));
887 index = index % geometry_.shapeStrides(j);
891 if(this->dimension() == 0) {
892 marray_detail::Assert(MARRAY_NO_ARG_TEST || index == 0);
896 size_t j = this->dimension()-1;
898 out += geometry_.strides(j) * (index / geometry_.shapeStrides(j));
899 index = index % geometry_.shapeStrides(j);
919 template<
class T,
bool isConst,
class A>
923 const allocator_type& allocator
926 geometry_(geometry_type(allocator))
932 template<
class T,
bool isConst,
class A>
937 const geometry_type& geometry
950 template<
class T,
bool isConst,
class A>
955 const allocator_type& allocator
958 geometry_(geometry_type(0, defaultOrder, 1,
true, allocator))
967 template<
class T,
bool isConst,
class A>
974 geometry_(in.geometry_)
992 template<
class T,
bool isConst,
class A>
993 template<
class ShapeIterator>
1002 const allocator_type& allocator
1005 geometry_(begin, end, externalCoordinateOrder,
1006 internalCoordinateOrder, allocator)
1023 template<
class T,
bool isConst,
class A>
1024 template<
class ShapeIterator,
class Str
ideIterator>
1028 ShapeIterator begin,
1033 const allocator_type& allocator
1036 geometry_(begin, end, it, internalCoordinateOrder, allocator)
1041 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
1042 template<
class T,
bool isConst,
class A>
1056 std::initializer_list<size_t> shape,
1060 const allocator_type& allocator
1063 geometry_(shape.begin(), shape.end(), externalCoordinateOrder,
1064 internalCoordinateOrder, allocator)
1077 template<
class T,
bool isConst,
class A>
1081 std::initializer_list<size_t> shape,
1082 std::initializer_list<size_t> strides,
1085 const allocator_type& allocator
1088 geometry_(shape.begin(), shape.end(), strides.begin(),
1089 internalCoordinateOrder, allocator)
1102 template<
class T,
bool isConst,
class A>
1106 const allocator_type& allocator
1109 geometry_ = geometry_type(allocator);
1126 template<
class T,
bool isConst,
class A>
1127 template<
class ShapeIterator>
1131 ShapeIterator begin,
1136 const allocator_type& allocator
1142 geometry_ =
typename marray_detail::Geometry<A>(begin, end,
1143 externalCoordinateOrder, internalCoordinateOrder, allocator);
1160 template<
class T,
bool isConst,
class A>
1161 template<
class ShapeIterator,
class Str
ideIterator>
1165 ShapeIterator begin,
1170 const allocator_type& allocator
1176 geometry_ =
typename marray_detail::Geometry<A>(begin, end,
1177 it, internalCoordinateOrder, allocator);
1182 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
1183 template<
class T,
bool isConst,
class A>
1197 std::initializer_list<size_t> shape,
1201 const allocator_type& allocator
1204 assign(shape.begin(), shape.end(), data, externalCoordinateOrder,
1205 internalCoordinateOrder, allocator);
1218 template<
class T,
bool isConst,
class A>
1222 std::initializer_list<size_t> shape,
1223 std::initializer_list<size_t> strides,
1226 const allocator_type& allocator
1229 assign(shape.begin(), shape.end(), strides.begin(), data,
1230 internalCoordinateOrder, allocator);
1241 template<
class T,
bool isConst,
class A>
1243 inline typename View<T, isConst, A>::reference
1244 View<T, isConst, A>::operator()
1249 return marray_detail::AccessOperatorHelper<std::numeric_limits<U>::is_integer>::execute(*
this, u);
1259 template<
class T,
bool isConst,
class A>
1267 return marray_detail::AccessOperatorHelper<std::numeric_limits<U>::is_integer>::execute(*
this, u);
1270 #ifndef HAVE_CPP0X_VARIADIC_TEMPLATES
1280 template<
class T,
bool isConst,
class A>
1289 marray_detail::Assert(MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 2));
1290 marray_detail::Assert(MARRAY_NO_ARG_TEST || (c0 < shape(0) && c1 < shape(1)));
1291 return data_[c0*strides(0) + c1*strides(1)];
1302 template<
class T,
bool isConst,
class A>
1311 marray_detail::Assert(MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 2));
1312 marray_detail::Assert(MARRAY_NO_ARG_TEST || (c0 < shape(0) && c1 < shape(1)));
1313 return data_[c0*strides(0) + c1*strides(1)];
1325 template<
class T,
bool isConst,
class A>
1335 marray_detail::Assert(MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 3));
1336 marray_detail::Assert(MARRAY_NO_ARG_TEST || (c0 < shape(0) && c1 < shape(1)
1338 return data_[c0*strides(0) + c1*strides(1) + c2*strides(2)];
1350 template<
class T,
bool isConst,
class A>
1360 marray_detail::Assert(MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 3));
1361 marray_detail::Assert(MARRAY_NO_ARG_TEST || (c0 < shape(0) && c1 < shape(1)
1363 return data_[c0*strides(0) + c1*strides(1) + c2*strides(2)];
1376 template<
class T,
bool isConst,
class A>
1387 marray_detail::Assert(MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 4));
1388 marray_detail::Assert(MARRAY_NO_ARG_TEST || (c0 < shape(0) && c1 < shape(1)
1389 && c2 < shape(2) && c3 < shape(3)));
1390 return data_[c0*strides(0) + c1*strides(1) + c2*strides(2)
1404 template<
class T,
bool isConst,
class A>
1415 marray_detail::Assert(MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 4));
1416 marray_detail::Assert(MARRAY_NO_ARG_TEST || (c0 < shape(0) && c1 < shape(1)
1417 && c2 < shape(2) && c3 < shape(3)));
1418 return data_[c0*strides(0) + c1*strides(1) + c2*strides(2)
1433 template<
class T,
bool isConst,
class A>
1445 marray_detail::Assert(MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 5));
1446 marray_detail::Assert(MARRAY_NO_ARG_TEST || (c0 < shape(0) && c1 < shape(1)
1447 && c2 < shape(2) && c3 < shape(3) && c4 < shape(4)));
1448 return data_[c0*strides(0) + c1*strides(1) + c2*strides(2)
1449 + c3*strides(3) + c4*strides(4)];
1463 template<
class T,
bool isConst,
class A>
1475 marray_detail::Assert(MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 5));
1476 marray_detail::Assert(MARRAY_NO_ARG_TEST || (c0 < shape(0) && c1 < shape(1)
1477 && c2 < shape(2) && c3 < shape(3) && c4 < shape(4)));
1478 return data_[c0*strides(0) + c1*strides(1) + c2*strides(2)
1479 + c3*strides(3) + c4*strides(4)];
1499 template<
class T,
bool isConst,
class A>
1516 marray_detail::Assert(MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 10));
1517 marray_detail::Assert(MARRAY_NO_ARG_TEST || (c0 < shape(0) && c1 < shape(1)
1518 && c2 < shape(2) && c3 < shape(3) && c4 < shape(4)
1519 && c5 < shape(5) && c6 < shape(6) && c7 < shape(7)
1520 && c8 < shape(8) && c9 < shape(9)));
1521 return data_[c0*strides(0) + c1*strides(1) + c2*strides(2)
1522 + c3*strides(3) + c4*strides(4) + c5*strides(5) + c6*strides(6)
1523 + c7*strides(7) + c8*strides(8) + c9*strides(9)];
1542 template<
class T,
bool isConst,
class A>
1559 marray_detail::Assert(MARRAY_NO_DEBUG || (data_ != 0 && dimension() == 10));
1560 marray_detail::Assert(MARRAY_NO_ARG_TEST || (c0 < shape(0) && c1 < shape(1)
1561 && c2 < shape(2) && c3 < shape(3) && c4 < shape(4)
1562 && c5 < shape(5) && c6 < shape(6) && c7 < shape(7)
1563 && c8 < shape(8) && c9 < shape(9)));
1564 return data_[c0*strides(0) + c1*strides(1) + c2*strides(2)
1565 + c3*strides(3) + c4*strides(4) + c5*strides(5) + c6*strides(6)
1566 + c7*strides(7) + c8*strides(8) + c9*strides(9)];
1571 template<
class T,
bool isConst,
class A>
1579 marray_detail::Assert(MARRAY_NO_ARG_TEST || (value < shape(Dim-1) ) );
1580 return strides(Dim-1) * value;
1583 template<
class T,
bool isConst,
class A>
1585 View<T, isConst, A>::elementAccessHelper
1591 marray_detail::Assert(MARRAY_NO_ARG_TEST || (value < shape(Dim-1) ) );
1592 return strides(Dim-1) * value;
1595 template<
class T,
bool isConst,
class A>
1596 template<
typename... Args>
1598 View<T, isConst, A>::elementAccessHelper
1605 marray_detail::Assert(MARRAY_NO_ARG_TEST || (value < shape(Dim-1-
sizeof...(args)) ) );
1606 return value * strides(Dim-1-
sizeof...(args)) + elementAccessHelper(Dim, args...);
1609 template<
class T,
bool isConst,
class A>
1610 template<
typename... Args>
1612 View<T, isConst, A>::elementAccessHelper
1619 marray_detail::Assert(MARRAY_NO_ARG_TEST || (value < shape(Dim-1-
sizeof...(args)) ) );
1620 return value * strides(Dim-1-
sizeof...(args)) + elementAccessHelper(Dim, args...);
1623 template<
class T,
bool isConst,
class A>
1624 inline typename View<T, isConst, A>::reference
1625 View<T, isConst, A>::operator()
1631 if(dimension() == 0) {
1632 marray_detail::Assert(MARRAY_NO_ARG_TEST || value == 0);
1637 indexToOffset(value, offset);
1638 return data_[offset];
1642 template<
class T,
bool isConst,
class A>
1643 inline typename View<T, isConst, A>::reference
1644 View<T, isConst, A>::operator()
1650 if(dimension() == 0) {
1651 marray_detail::Assert(MARRAY_NO_ARG_TEST || value == 0);
1656 indexToOffset(value, offset);
1657 return data_[offset];
1661 template<
class T,
bool isConst,
class A>
1662 template<
typename... Args>
1663 inline typename View<T, isConst, A>::reference
1664 View<T, isConst, A>::operator()
1671 marray_detail::Assert( MARRAY_NO_DEBUG || ( data_ != 0 &&
sizeof...(args)+1 == dimension() ) );
1672 return data_[strides(0)*value + elementAccessHelper(
sizeof...(args)+1, args...) ];
1675 template<
class T,
bool isConst,
class A>
1676 template<
typename... Args>
1677 inline typename View<T, isConst, A>::reference
1678 View<T, isConst, A>::operator()
1685 marray_detail::Assert( MARRAY_NO_DEBUG || ( data_ != 0 &&
sizeof...(args)+1 == dimension() ) );
1686 return data_[ strides(0) *
static_cast<size_t>(value)
1687 + static_cast<size_t>(elementAccessHelper(
sizeof...(args)+1, args...)) ];
1690 #endif // #ifndef HAVE_CPP0X_VARIADIC_TEMPLATES
1696 template<
class T,
bool isConst,
class A>
1700 return geometry_.size();
1709 template<
class T,
bool isConst,
class A>
1713 marray_detail::Assert(MARRAY_NO_DEBUG || this->data_ != 0);
1714 return geometry_.dimension();
1722 template<
class T,
bool isConst,
class A>
1726 const size_t dimension
1730 marray_detail::Assert(MARRAY_NO_DEBUG || data_ != 0);
1731 marray_detail::Assert(MARRAY_NO_ARG_TEST || dimension < this->dimension());
1732 return geometry_.shape(dimension);
1740 template<
class T,
bool isConst,
class A>
1741 inline const size_t*
1745 marray_detail::Assert(MARRAY_NO_DEBUG || data_ != 0);
1746 return geometry_.shapeBegin();
1754 template<
class T,
bool isConst,
class A>
1755 inline const size_t*
1759 marray_detail::Assert(MARRAY_NO_DEBUG || data_ != 0);
1760 return geometry_.shapeEnd();
1768 template<
class T,
bool isConst,
class A>
1772 const size_t dimension
1776 marray_detail::Assert(MARRAY_NO_DEBUG || data_ != 0);
1777 marray_detail::Assert(MARRAY_NO_ARG_TEST || dimension < this->dimension());
1778 return geometry_.strides(dimension);
1786 template<
class T,
bool isConst,
class A>
1787 inline const size_t*
1791 marray_detail::Assert(MARRAY_NO_DEBUG || data_ != 0);
1792 return geometry_.stridesBegin();
1800 template<
class T,
bool isConst,
class A>
1801 inline const size_t*
1805 marray_detail::Assert(MARRAY_NO_DEBUG || data_ != 0);
1806 return geometry_.stridesEnd();
1813 template<
class T,
bool isConst,
class A>
1818 return geometry_.coordinateOrder();
1825 template<
class T,
bool isConst,
class A>
1830 return geometry_.isSimple();
1872 template<
class T,
bool isConst,
class A>
1880 marray_detail::AssignmentOperatorHelper<isConst, T, T, A, A>::execute(in, *
this);
1887 template<
class T,
bool isConst,
class A>
1889 View<T, isConst, A>::operator=
1895 marray_detail::AssignmentOperatorHelper<isConst, T, T, A, A>::execute(in, *
this);
1902 template<
class T,
bool isConst,
class A>
1903 template<
class TLocal,
bool isConstLocal,
class ALocal>
1905 View<T, isConst, A>::operator=
1911 marray_detail::AssignmentOperatorHelper<isConst, TLocal, T, ALocal, A>::execute(in, *
this);
1922 template<
class T,
bool isConst,
class A>
1924 View<T, isConst, A>::operator=
1929 marray_detail::Assert(MARRAY_NO_DEBUG || data_ != 0);
1931 for(
size_t j=0; j<geometry_.size(); ++j) {
1935 else if(dimension() == 1)
1936 marray_detail::OperateHelperBinaryScalar<1, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1937 else if(dimension() == 2)
1938 marray_detail::OperateHelperBinaryScalar<2, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1939 else if(dimension() == 3)
1940 marray_detail::OperateHelperBinaryScalar<3, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1941 else if(dimension() == 4)
1942 marray_detail::OperateHelperBinaryScalar<4, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1943 else if(dimension() == 5)
1944 marray_detail::OperateHelperBinaryScalar<5, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1945 else if(dimension() == 6)
1946 marray_detail::OperateHelperBinaryScalar<6, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1947 else if(dimension() == 7)
1948 marray_detail::OperateHelperBinaryScalar<7, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1949 else if(dimension() == 8)
1950 marray_detail::OperateHelperBinaryScalar<8, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1951 else if(dimension() == 9)
1952 marray_detail::OperateHelperBinaryScalar<9, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1953 else if(dimension() == 10)
1954 marray_detail::OperateHelperBinaryScalar<10, marray_detail::Assign<T, T>, T, T, A>::operate(*
this, value, marray_detail::Assign<T, T>(), data_);
1956 for(iterator it = begin(); it.hasMore(); ++it) {
1963 template<
class T,
bool isConst,
class A>
1964 template<
class E,
class Te>
1966 View<T, isConst, A>::operator=
1971 marray_detail::operate(*
this, expression, marray_detail::Assign<T, Te>());
1983 template<
class T,
bool isConst,
class A>
1984 template<
class BaseIterator,
class ShapeIterator>
1993 view(bit, sit, coordinateOrder(), out);
2006 template<
class T,
bool isConst,
class A>
2007 template<
class BaseIterator,
class ShapeIterator>
2019 coordinatesToOffset(bit, offset);
2020 out.assign(sit, sit+dimension(), geometry_.stridesBegin(),
2021 data_+offset, internalCoordinateOrder);
2032 template<
class T,
bool isConst,
class A>
2033 template<
class BaseIterator,
class ShapeIterator>
2042 this->view(bit, sit, v);
2056 template<
class T,
bool isConst,
class A>
2057 template<
class BaseIterator,
class ShapeIterator>
2067 this->view(bit, sit, internalCoordinateOrder, v);
2080 template<
class T,
bool isConst,
class A>
2081 template<
class BaseIterator,
class ShapeIterator>
2090 constView(bit, sit, coordinateOrder(), out);
2103 template<
class T,
bool isConst,
class A>
2104 template<
class BaseIterator,
class ShapeIterator>
2116 coordinatesToOffset(bit, offset);
2117 out.assign(sit, sit+dimension(),
2118 geometry_.stridesBegin(),
2119 static_cast<const T*
>(data_) + offset,
2120 internalCoordinateOrder);
2132 template<
class T,
bool isConst,
class A>
2133 template<
class BaseIterator,
class ShapeIterator>
2142 this->constView(bit, sit, v);
2156 template<
class T,
bool isConst,
class A>
2157 template<
class BaseIterator,
class ShapeIterator>
2167 this->constView(bit, sit, internalCoordinateOrder, v);
2171 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
2172 template<
class T,
bool isConst,
class A>
2185 std::initializer_list<size_t> b,
2186 std::initializer_list<size_t> s,
2191 view(b.begin(), s.begin(), internalCoordinateOrder, out);
2202 template<
class T,
bool isConst,
class A>
2206 std::initializer_list<size_t> b,
2207 std::initializer_list<size_t> s,
2208 View<T, isConst, A>& out
2211 view(b.begin(), s.begin(), coordinateOrder(), out);
2223 template<
class T,
bool isConst,
class A>
2227 std::initializer_list<size_t> b,
2228 std::initializer_list<size_t> s,
2230 View<T, true, A>& out
2233 constView(b.begin(), s.begin(), internalCoordinateOrder, out);
2245 template<
class T,
bool isConst,
class A>
2249 std::initializer_list<size_t> b,
2250 std::initializer_list<size_t> s,
2251 View<T, true, A>& out
2254 constView(b.begin(), s.begin(), coordinateOrder(), out);
2271 template<
class T,
bool isConst,
class A>
2272 template<
class ShapeIterator>
2276 ShapeIterator begin,
2281 marray_detail::Assert(MARRAY_NO_DEBUG || isSimple());
2282 if(!MARRAY_NO_ARG_TEST) {
2283 size_t size = std::accumulate(begin, end, 1, std::multiplies<size_t>());
2284 marray_detail::Assert(size == this->size());
2286 assign(begin, end, data_, coordinateOrder(), coordinateOrder());
2303 template<
class T,
bool isConst,
class A>
2304 template<
class ShapeIterator>
2308 ShapeIterator begin,
2313 out.reshape(begin, end);
2317 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
2318 template<
class T,
bool isConst,
class A>
2333 std::initializer_list<size_t> shape
2336 reshape(shape.begin(), shape.end());
2350 template<
class T,
bool isConst,
class A>
2351 inline View<T, isConst, A>
2354 std::initializer_list<size_t> shape
2357 return reshapedView(shape.begin(), shape.end());
2371 template<
class T,
bool isConst,
class A>
2375 const size_t dimension,
2380 marray_detail::Assert(MARRAY_NO_ARG_TEST || (dimension < this->dimension()
2381 && value < shape(dimension)));
2382 if(this->dimension() == 1) {
2383 View v(&((*
this)(value)));
2384 v.geometry_.coordinateOrder() = coordinateOrder();
2389 v.geometry_.resize(this->dimension()-1);
2390 v.geometry_.coordinateOrder() = coordinateOrder();
2391 v.geometry_.size() = size() / shape(dimension);
2392 for(
size_t j=0, k=0; j<this->dimension(); ++j) {
2393 if(j != dimension) {
2394 v.geometry_.shape(k) = shape(j);
2395 v.geometry_.strides(k) = strides(j);
2399 marray_detail::stridesFromShape(v.geometry_.shapeBegin(), v.geometry_.shapeEnd(),
2400 v.geometry_.shapeStridesBegin(), v.geometry_.coordinateOrder());
2401 v.data_ = data_ + strides(dimension) * value;
2402 v.updateSimplicity();
2412 template<
class T,
bool isConst,
class A>
2417 if(dimension() != 0) {
2418 size_t newDimension = dimension();
2419 for(
size_t j=0; j<dimension(); ++j) {
2424 if(newDimension != dimension()) {
2425 if(newDimension == 0) {
2426 geometry_.resize(0);
2427 geometry_.size() = 1;
2430 for(
size_t j=0, k=0; j<geometry_.dimension(); ++j) {
2431 if(geometry_.shape(j) != 1) {
2432 geometry_.shape(k) = geometry_.shape(j);
2433 geometry_.strides(k) = geometry_.strides(j);
2437 geometry_.resize(newDimension);
2438 marray_detail::stridesFromShape(geometry_.shapeBegin(), geometry_.shapeEnd(),
2439 geometry_.shapeStridesBegin(), geometry_.coordinateOrder());
2452 template<
class T,
bool isConst,
class A>
2461 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
2462 template<
class T,
bool isConst,
class A>
2474 std::initializer_list<size_t> permutation
2477 permute(permutation.begin());
2489 template<
class T,
bool isConst,
class A>
2490 template<
class CoordinateIterator>
2494 CoordinateIterator begin
2498 if(!MARRAY_NO_ARG_TEST) {
2499 marray_detail::Assert(dimension() != 0);
2500 std::set<size_t> s1, s2;
2501 CoordinateIterator it = begin;
2502 for(
size_t j=0; j<dimension(); ++j) {
2507 marray_detail::Assert(s1 == s2);
2510 std::vector<size_t> newShape = std::vector<size_t>(dimension());
2511 std::vector<size_t> newStrides = std::vector<size_t>(dimension());
2512 for(
size_t j=0; j<dimension(); ++j) {
2513 newShape[j] = geometry_.shape(static_cast<size_t>(*begin));
2514 newStrides[j] = geometry_.strides(static_cast<size_t>(*begin));
2517 for(
size_t j=0; j<dimension(); ++j) {
2518 geometry_.shape(j) = newShape[j];
2519 geometry_.strides(j) = newStrides[j];
2521 marray_detail::stridesFromShape(geometry_.shapeBegin(), geometry_.shapeEnd(),
2522 geometry_.shapeStridesBegin(), geometry_.coordinateOrder());
2536 template<
class T,
bool isConst,
class A>
2537 template<
class CoordinateIterator>
2541 CoordinateIterator begin
2555 template<
class T,
bool isConst,
class A>
2564 marray_detail::Assert(MARRAY_NO_ARG_TEST ||
2565 (dimension() != 0 && c1 < dimension() && c2 < dimension()));
2573 c = geometry_.shape(j2);
2574 geometry_.shape(j2) = geometry_.shape(j1);
2575 geometry_.shape(j1) = c;
2578 d = geometry_.strides(j2);
2579 geometry_.strides(j2) = geometry_.strides(j1);
2580 geometry_.strides(j1) = d;
2583 marray_detail::stridesFromShape(geometry_.shapeBegin(), geometry_.shapeEnd(),
2584 geometry_.shapeStridesBegin(), geometry_.coordinateOrder());
2595 template<
class T,
bool isConst,
class A>
2600 for(
size_t j=0; j<dimension()/2; ++j) {
2601 size_t k = dimension()-j-1;
2604 size_t tmp = geometry_.shape(j);
2605 geometry_.shape(j) = geometry_.shape(k);
2606 geometry_.shape(k) = tmp;
2609 tmp = geometry_.strides(j);
2610 geometry_.strides(j) = geometry_.strides(k);
2611 geometry_.strides(k) = tmp;
2613 marray_detail::stridesFromShape(geometry_.shapeBegin(), geometry_.shapeEnd(),
2614 geometry_.shapeStridesBegin(), geometry_.coordinateOrder());
2628 template<
class T,
bool isConst,
class A>
2637 out.transpose(c1, c2);
2647 template<
class T,
bool isConst,
class A>
2662 template<
class T,
bool isConst,
class A>
2670 marray_detail::Assert(MARRAY_NO_DEBUG || dimension() != 0);
2671 if(n <= -static_cast<int>(dimension()) || n >= static_cast<int>(dimension())) {
2672 shift(n % static_cast<int>(dimension()));
2676 shift(n - static_cast<int>(dimension()));
2679 std::vector<size_t> p(dimension());
2680 for(
size_t j=0; j<dimension(); ++j) {
2681 p[j] =
static_cast<size_t>((
static_cast<int>(j) - n)) % dimension();
2694 template<
class T,
bool isConst,
class A>
2712 template<
class T,
bool isConst,
class A>
2725 template<
class T,
bool isConst,
class A>
2738 template<
class T,
bool isConst,
class A>
2751 template<
class T,
bool isConst,
class A>
2765 template<
class T,
bool isConst,
class A>
2769 return reverse_iterator(end());
2777 template<
class T,
bool isConst,
class A>
2781 return reverse_iterator(begin());
2789 template<
class T,
bool isConst,
class A>
2793 return const_reverse_iterator(end());
2801 template<
class T,
bool isConst,
class A>
2805 return const_reverse_iterator(begin());
2814 template<
class T,
bool isConst,
class A>
2820 geometry_.updateSimplicity();
2831 template<
class T,
bool isConst,
class A>
2833 View<T, isConst, A>::operator[]
2839 return data_[offset];
2850 template<
class T,
bool isConst,
class A>
2852 View<T, isConst, A>::operator[]
2857 return data_[offset];
2865 template<
class T,
bool isConst,
class A>
2867 View<T, isConst, A>::testInvariant()
const
2869 if(!MARRAY_NO_DEBUG) {
2870 if(geometry_.dimension() == 0) {
2871 marray_detail::Assert(geometry_.isSimple() ==
true);
2873 marray_detail::Assert(geometry_.size() == 1);
2877 marray_detail::Assert(data_ != 0);
2880 size_t testSize = 1;
2881 for(
size_t j=0; j<geometry_.dimension(); ++j) {
2882 testSize *= geometry_.shape(j);
2884 marray_detail::Assert(geometry_.size() == testSize);
2889 for(
size_t j=0; j<geometry_.dimension(); ++j) {
2890 marray_detail::Assert(geometry_.shapeStrides(geometry_.dimension()-j-1) == tmp);
2891 tmp *= geometry_.shape(geometry_.dimension()-j-1);
2896 for(
size_t j=0; j<geometry_.dimension(); ++j) {
2897 marray_detail::Assert(geometry_.shapeStrides(j) == tmp);
2898 tmp *= geometry_.shape(j);
2903 if(geometry_.isSimple()) {
2904 for(
size_t j=0; j<geometry_.dimension(); ++j) {
2905 marray_detail::Assert(geometry_.strides(j) == geometry_.shapeStrides(j));
2927 template<
class T,
bool isConst,
class A>
2928 template<
class TLocal,
bool isConstLocal,
class ALocal>
2935 if(!MARRAY_NO_ARG_TEST) {
2938 if(data_ == 0 || v.data_ == 0) {
2942 const void* dataPointer_ = data_;
2943 const void* vDataPointer_ = v.data_;
2944 const void* maxPointer = & (*this)(this->size()-1);
2945 const void* maxPointerV = & v(v.size()-1);
2946 if( (dataPointer_ <= vDataPointer_ && vDataPointer_ <= maxPointer)
2947 || (vDataPointer_ <= dataPointer_ && dataPointer_ <= maxPointerV) )
2957 template<
class T,
bool isConst,
class A>
2965 std::ostringstream out(std::ostringstream::out);
2967 if(dimension() == 0) {
2969 out <<
"A = " << (*this)(0) << std::endl;
2971 else if(dimension() == 1) {
2974 for(
size_t j=0; j<this->size(); ++j) {
2975 out << (*this)(j) <<
", ";
2977 out <<
"\b\b)" << std::endl;
2979 else if(dimension() == 2) {
2982 out <<
"A(r,c) =" << std::endl;
2983 for(
size_t y=0; y<this->shape(0); ++y) {
2984 for(
size_t x=0; x<this->shape(1); ++x) {
2985 out << (*this)(y, x) <<
' ';
2991 out <<
"A(c,r) =" << std::endl;
2992 for(
size_t y=0; y<this->shape(1); ++y) {
2993 for(
size_t x=0; x<this->shape(0); ++x) {
2994 out << (*this)(x, y) <<
' ';
3002 std::vector<size_t> c1(dimension());
3003 std::vector<size_t> c2(dimension());
3004 unsigned short q = 2;
3008 for(const_iterator it = this->begin(); it.hasMore(); ++it) {
3009 it.coordinate(c2.begin());
3010 if(it.index() == 0 || c2[q] != c1[q]) {
3011 if(it.index() != 0) {
3012 out << std::endl << std::endl;
3016 for(
size_t j=0; j<dimension()-2; ++j) {
3017 out << c2[j] <<
",";
3022 for(
size_t j=2; j<dimension(); ++j) {
3023 out << c2[j] <<
",";
3030 out <<
") =" << std::endl;
3032 else if(c2[1] != c1[1]) {
3043 if(dimension() == 0) {
3045 out <<
"A = " << (*this)(0) << std::endl;
3049 std::vector<size_t> c(dimension());
3050 for(const_iterator it = this->begin(); it.hasMore(); ++it) {
3052 it.coordinate(c.begin());
3053 for(
size_t j=0; j<c.size(); ++j) {
3056 out <<
"\b) = " << *it << std::endl;
3066 template<
class T1,
class T2,
bool isConst,
class A>
3070 View<T1, false, A>& v,
3074 marray_detail::operate(v, w, marray_detail::PlusEqual<T1, T2>());
3079 template<
class T,
class A>
3080 inline View<T, false, A>&
3086 marray_detail::operate(v, marray_detail::PrefixIncrement<T>());
3091 template<
class T,
class A>
3100 marray_detail::operate(in, marray_detail::PostfixIncrement<T>());
3104 template<
class T1,
class T2,
bool isConst,
class A>
3105 inline View<T1, false, A>&
3108 View<T1, false, A>& v,
3112 marray_detail::operate(v, w, marray_detail::MinusEqual<T1, T2>());
3117 template<
class T,
class A>
3118 inline View<T, false, A>&
3124 marray_detail::operate(v, marray_detail::PrefixDecrement<T>());
3129 template<
class T,
class A>
3138 marray_detail::operate(in, marray_detail::PostfixDecrement<T>());
3142 template<
class T1,
class T2,
bool isConst,
class A>
3143 inline View<T1, false, A>&
3146 View<T1, false, A>& v,
3150 marray_detail::operate(v, w, marray_detail::TimesEqual<T1, T2>());
3154 template<
class T1,
class T2,
bool isConst,
class A>
3155 inline View<T1, false, A>&
3158 View<T1, false, A>& v,
3162 marray_detail::operate(v, w, marray_detail::DividedByEqual<T1, T2>());
3166 template<
class E1,
class T1,
class E2,
class T2>
3167 inline const BinaryViewExpression<E1, T1, E2, T2, marray_detail::Plus<T1, T2, typename marray_detail::PromoteType<T1, T2>::type> >
3174 typedef typename marray_detail::PromoteType<T1, T2>::type promoted_type;
3175 typedef marray_detail::Plus<T1, T2, promoted_type> Functor;
3176 typedef BinaryViewExpression<E1, T1, E2, T2, Functor> return_type;
3177 return return_type(expression1, expression2);
3180 template<
class E,
class T>
3181 inline const ViewExpression<E,T>&
3190 #define MARRAY_UNARY_OPERATOR(datatype, operation, functorname) \
3191 template<class T, class A> \
3192 inline View<T, false, A>& \
3193 operator operation \
3195 View<T, false, A>& v, \
3199 marray_detail::operate(v, static_cast<T>(x), marray_detail:: functorname <T, T>()); \
3203 #define MARRAY_UNARY_OPERATOR_ALL_TYPES(op, functorname) \
3204 MARRAY_UNARY_OPERATOR(char, op, functorname) \
3205 MARRAY_UNARY_OPERATOR(unsigned char, op, functorname) \
3206 MARRAY_UNARY_OPERATOR(short, op, functorname) \
3207 MARRAY_UNARY_OPERATOR(unsigned short, op, functorname) \
3208 MARRAY_UNARY_OPERATOR(int, op, functorname) \
3209 MARRAY_UNARY_OPERATOR(unsigned int, op, functorname) \
3210 MARRAY_UNARY_OPERATOR(long, op, functorname) \
3211 MARRAY_UNARY_OPERATOR(unsigned long, op, functorname) \
3212 MARRAY_UNARY_OPERATOR(float, op, functorname) \
3213 MARRAY_UNARY_OPERATOR(double, op, functorname) \
3214 MARRAY_UNARY_OPERATOR(long double, op, functorname) \
3221 template<class E1, class T1, class E2, class T2>
3222 inline const BinaryViewExpression<E1, T1, E2, T2,
3223 marray_detail::Minus<T1, T2, typename marray_detail::PromoteType<T1, T2>::type> >
3230 return BinaryViewExpression<E1, T1, E2, T2,
3231 marray_detail::Minus<T1, T2,
3232 typename marray_detail::PromoteType<T1, T2>::type> >(
3233 expression1, expression2);
3236 template<
class E,
class T>
3237 inline const UnaryViewExpression<E,T,marray_detail::Negate<T> >
3243 return UnaryViewExpression<E,T,marray_detail::Negate<T> >(
3247 template<
class E1,
class T1,
class E2,
class T2>
3248 inline const BinaryViewExpression<E1, T1, E2, T2,
3249 marray_detail::Times<T1, T2, typename marray_detail::PromoteType<T1, T2>::type> >
3256 return BinaryViewExpression<E1, T1, E2, T2,
3257 marray_detail::Times<T1, T2,
3258 typename marray_detail::PromoteType<T1, T2>::type > >(
3259 expression1, expression2);
3262 template<
class E1,
class T1,
class E2,
class T2>
3263 inline const BinaryViewExpression<E1, T1, E2, T2,
3264 marray_detail::DividedBy<T1, T2, typename marray_detail::PromoteType<T1, T2>::type> >
3271 return BinaryViewExpression<E1, T1, E2, T2,
3272 marray_detail::DividedBy<T1, T2,
3273 typename marray_detail::PromoteType<T1, T2>::type > >(
3274 expression1, expression2);
3277 #define MARRAY_BINARY_OPERATOR(datatype, operation, functorname) \
3278 template<class E, class T> \
3279 inline const BinaryViewExpressionScalarSecond< \
3280 E, T, datatype, marray_detail:: functorname < \
3281 T, datatype, typename marray_detail::PromoteType<T, datatype>::type \
3284 operator operation \
3286 const ViewExpression<E, T>& expression, \
3287 const datatype& scalar \
3290 typedef typename marray_detail::PromoteType<T, datatype>::type \
3292 typedef marray_detail:: functorname <T, datatype, promoted_type> Functor; \
3293 typedef BinaryViewExpressionScalarSecond<E, T, datatype, Functor> \
3295 return expression_type(expression, scalar); \
3298 template<class E, class T> \
3299 inline const BinaryViewExpressionScalarFirst \
3301 E, T, datatype, marray_detail:: functorname < \
3302 datatype, T, typename marray_detail::PromoteType<datatype, T>::type \
3305 operator operation \
3307 const datatype& scalar, \
3308 const ViewExpression<E, T>& expression \
3311 typedef typename marray_detail::PromoteType<T, datatype>::type \
3313 typedef marray_detail:: functorname <datatype, T, promoted_type> Functor; \
3314 typedef BinaryViewExpressionScalarFirst<E, T, datatype, Functor> \
3316 return expression_type(expression, scalar); \
3319 #define MARRAY_BINARY_OPERATOR_ALL_TYPES(op, functorname) \
3320 MARRAY_BINARY_OPERATOR(char, op, functorname) \
3321 MARRAY_BINARY_OPERATOR(unsigned char, op, functorname) \
3322 MARRAY_BINARY_OPERATOR(short, op, functorname) \
3323 MARRAY_BINARY_OPERATOR(unsigned short, op, functorname) \
3324 MARRAY_BINARY_OPERATOR(int, op, functorname) \
3325 MARRAY_BINARY_OPERATOR(unsigned int, op, functorname) \
3326 MARRAY_BINARY_OPERATOR(long, op, functorname) \
3327 MARRAY_BINARY_OPERATOR(unsigned long, op, functorname) \
3328 MARRAY_BINARY_OPERATOR(float, op, functorname) \
3329 MARRAY_BINARY_OPERATOR(double, op, functorname) \
3330 MARRAY_BINARY_OPERATOR(long double, op, functorname) \
3347 template<class T, class A>
3351 const allocator_type& allocator
3354 if(this->data_ != 0) {
3355 dataAllocator_.deallocate(this->data_, this->size());
3358 dataAllocator_ = allocator;
3366 template<
class T,
class A>
3370 const allocator_type& allocator
3373 dataAllocator_(allocator)
3387 template<
class T,
class A>
3393 const allocator_type& allocator
3395 : dataAllocator_(allocator)
3397 this->data_ = dataAllocator_.allocate(1);
3398 this->data_[0] = value;
3399 this->geometry_ = geometry_type(0, coordinateOrder, 1,
true, allocator);
3407 template<
class T,
class A>
3413 : dataAllocator_(in.dataAllocator_)
3415 if(!MARRAY_NO_ARG_TEST) {
3422 this->data_ = dataAllocator_.allocate(in.
size());
3423 memcpy(this->data_, in.data_, (in.
size())*
sizeof(T));
3425 this->geometry_ = in.geometry_;
3433 template<
class T,
class A>
3434 template<
class TLocal,
bool isConstLocal,
class ALocal>
3442 if(!MARRAY_NO_ARG_TEST) {
3447 this->geometry_ = in.geometry_;
3448 for(
size_t j=0; j<in.dimension(); ++j) {
3449 this->geometry_.strides(j) = in.geometry_.shapeStrides(j);
3451 this->geometry_.isSimple() =
true;
3454 if(in.size() == 0) {
3458 this->data_ = dataAllocator_.allocate(in.size());
3460 if(in.isSimple() && marray_detail::IsEqual<T, TLocal>::type) {
3461 memcpy(this->data_, in.data_, (in.size())*
sizeof(T));
3465 for(
size_t j=0; j<this->size(); ++j, ++it) {
3466 this->data_[j] =
static_cast<T
>(*it);
3478 template<
class T,
class A>
3479 template<
class E,
class Te>
3484 const allocator_type& allocator
3486 : dataAllocator_(allocator)
3488 this->data_ = dataAllocator_.allocate(expression.
size());
3490 this->geometry_ = geometry_type(0,
3491 static_cast<const E&>(expression).coordinateOrder(),
3492 1,
true, dataAllocator_);
3495 this->geometry_ = geometry_type(
3496 static_cast<const E&>(expression).shapeBegin(),
3497 static_cast<const E&>(expression).shapeEnd(),
3498 static_cast<const E&>(expression).coordinateOrder(),
3499 static_cast<const E&>(expression).coordinateOrder(),
3503 const E& e =
static_cast<const E&
>(expression);
3504 if(e.dimension() == 0) {
3505 marray_detail::Assert(MARRAY_NO_ARG_TEST || e.size() < 2);
3506 this->data_[0] =
static_cast<T
>(e(0));
3509 marray_detail::Assert(MARRAY_NO_ARG_TEST || e.size() != 0);
3510 marray_detail::operate(*
this, e, marray_detail::Assign<T, Te>());
3525 template<
class T,
class A>
3526 template<
class ShapeIterator>
3530 ShapeIterator begin,
3534 const allocator_type& allocator
3536 : dataAllocator_(allocator)
3538 size_t size = std::accumulate(begin, end, static_cast<size_t>(1), std::multiplies<size_t>());
3539 marray_detail::Assert(MARRAY_NO_ARG_TEST || size != 0);
3540 base::assign(begin, end, dataAllocator_.allocate(size), coordinateOrder,
3541 coordinateOrder, allocator);
3542 for(
size_t j=0; j<size; ++j) {
3543 this->data_[j] = value;
3558 template<
class T,
class A>
3559 template<
class ShapeIterator>
3564 ShapeIterator begin,
3567 const allocator_type& allocator
3569 : dataAllocator_(allocator)
3571 size_t size = std::accumulate(begin, end, 1, std::multiplies<size_t>());
3572 marray_detail::Assert(MARRAY_NO_ARG_TEST || size != 0);
3573 base::assign(begin, end, dataAllocator_.allocate(size), coordinateOrder,
3574 coordinateOrder, allocator);
3578 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
3579 template<
class T,
class A>
3591 std::initializer_list<size_t> shape,
3594 const allocator_type& allocator
3597 : dataAllocator_(allocator)
3599 size_t size = std::accumulate(shape.begin(), shape.end(),
3600 1, std::multiplies<size_t>());
3601 marray_detail::Assert(MARRAY_NO_ARG_TEST || size != 0);
3602 base::assign(shape.begin(), shape.end(), dataAllocator_.allocate(size),
3604 for(
size_t j=0; j<
size; ++j) {
3605 this->data_[j] = value;
3613 template<
class T,
class A>
3617 dataAllocator_.deallocate(this->data_, this->size());
3632 template<
class T,
class A>
3641 if(!MARRAY_NO_ARG_TEST) {
3648 dataAllocator_.deallocate(this->data_, this->size());
3652 if(this->size() != in.size()) {
3654 dataAllocator_.deallocate(this->data_, this->size());
3655 this->data_ = dataAllocator_.allocate(in.size());
3658 memcpy(this->data_, in.data_, in.size() *
sizeof(T));
3660 this->geometry_ = in.geometry_;
3680 template<
class T,
class A>
3681 template<
class TLocal,
bool isConstLocal,
class ALocal>
3683 Marray<T, A>::operator=
3688 if(!MARRAY_NO_ARG_TEST) {
3691 if( (
void*)(
this) != (
void*)(&in) ) {
3693 dataAllocator_.deallocate(this->data_, this->size());
3695 this->geometry_ = in.geometry_;
3697 else if(this->overlaps(in)) {
3703 if(this->size() != in.size()) {
3704 dataAllocator_.deallocate(this->data_, this->size());
3705 this->data_ = dataAllocator_.allocate(in.size());
3709 this->geometry_.
resize(in.dimension());
3710 for(
size_t j=0; j<in.dimension(); ++j) {
3711 this->geometry_.shape(j) = in.geometry_.shape(j);
3712 this->geometry_.shapeStrides(j) = in.geometry_.shapeStrides(j);
3713 this->geometry_.strides(j) = in.geometry_.shapeStrides(j);
3715 this->geometry_.size() = in.size();
3716 this->geometry_.isSimple() =
true;
3717 this->geometry_.coordinateOrder() = in.coordinateOrder();
3720 if(in.isSimple() && marray_detail::IsEqual<T, TLocal>::type) {
3721 memcpy(this->data_, in.data_, (in.size())*
sizeof(T));
3723 else if(in.dimension() == 1)
3724 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));
3725 else if(in.dimension() == 2)
3726 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));
3727 else if(in.dimension() == 3)
3728 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));
3729 else if(in.dimension() == 4)
3730 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));
3731 else if(in.dimension() == 5)
3732 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));
3733 else if(in.dimension() == 6)
3734 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));
3735 else if(in.dimension() == 7)
3736 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));
3737 else if(in.dimension() == 8)
3738 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));
3739 else if(in.dimension() == 9)
3740 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));
3741 else if(in.dimension() == 10)
3742 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));
3745 for(
size_t j=0; j<this->size(); ++j, ++it) {
3746 this->data_[j] =
static_cast<T
>(*it);
3761 template<
class T,
class A>
3763 Marray<T, A>::operator=
3768 marray_detail::Assert(MARRAY_NO_DEBUG || this->data_ != 0);
3769 for(
size_t j=0; j<this->size(); ++j) {
3770 this->data_[j] = value;
3775 template<
class T,
class A>
3776 template<
class E,
class Te>
3778 Marray<T, A>::operator=
3789 if(this->size() != expression.
size()) {
3790 dataAllocator_.deallocate(this->data_, this->size());
3791 this->data_ = dataAllocator_.allocate(expression.
size());
3796 for(
size_t j=0; j<expression.
dimension(); ++j) {
3797 this->geometry_.shape(j) = expression.
shape(j);
3799 this->geometry_.size() = expression.
size();
3800 this->geometry_.isSimple() =
true;
3802 if(this->geometry_.dimension() != 0) {
3803 marray_detail::stridesFromShape(this->geometry_.shapeBegin(), this->geometry_.shapeEnd(),
3804 this->geometry_.shapeStridesBegin(), this->geometry_.coordinateOrder());
3805 marray_detail::stridesFromShape(this->geometry_.shapeBegin(), this->geometry_.shapeEnd(),
3806 this->geometry_.stridesBegin(), this->geometry_.coordinateOrder());
3810 marray_detail::operate(*
this, expression, marray_detail::Assign<T, Te>());
3815 template<
class T,
class A>
3816 template<
bool SKIP_INITIALIZATION,
class ShapeIterator>
3820 ShapeIterator begin,
3827 std::vector<size_t> newShape;
3829 for(ShapeIterator it = begin; it != end; ++it) {
3830 size_t x =
static_cast<size_t>(*it);
3831 marray_detail::Assert(MARRAY_NO_ARG_TEST || x > 0);
3832 newShape.push_back(x);
3836 value_type* newData = dataAllocator_.allocate(newSize);
3837 if(!SKIP_INITIALIZATION) {
3838 for(
size_t j=0; j<newSize; ++j) {
3843 if(this->data_ != 0) {
3844 if(newSize == 1 || this->dimension() == 0) {
3845 newData[0] = this->data_[0];
3848 std::vector<size_t> base1(this->dimension());
3849 std::vector<size_t> base2(newShape.size());
3850 std::vector<size_t> shape1(this->dimension(), 1);
3851 std::vector<size_t> shape2(newShape.size(), 1);
3852 for(
size_t j=0; j<std::min(this->dimension(), newShape.size()); ++j) {
3853 shape1[j] = std::min(this->shape(j), newShape[j]);
3854 shape2[j] = shape1[j];
3856 View<T, true, A> view1;
3857 this->constView(base1.begin(), shape1.begin(), view1);
3858 View<T, false, A> viewT(newShape.begin(), newShape.end(),
3859 newData, this->coordinateOrder(),
3860 this->coordinateOrder());
3861 View<T, false, A> view2;
3862 viewT.view(base2.begin(), shape2.begin(), view2);
3867 dataAllocator_.deallocate(this->data_, this->size());
3870 base::assign(begin, end, newData, this->geometry_.coordinateOrder(),
3871 this->geometry_.coordinateOrder());
3882 template<
class T,
class A>
3883 template<
class ShapeIterator>
3887 ShapeIterator begin,
3892 if(std::distance(begin,end)==0) {
3893 if(this->size()>0) {
3903 resizeHelper<false>(begin, end, value);
3914 template<
class T,
class A>
3915 template<
class ShapeIterator>
3920 ShapeIterator begin,
3924 resizeHelper<true>(begin, end);
3927 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
3928 template<
class T,
class A>
3937 std::initializer_list<size_t> shape,
3941 resizeHelper<false>(shape.begin(), shape.end(), value);
3949 template<
class T,
class A>
3953 const InitializationSkipping& si,
3954 std::initializer_list<size_t> shape
3957 resizeHelper<true>(shape.begin(), shape.end());
3963 template<
class T,
class A>
3965 Marray<T, A>::testInvariant()
const
3967 View<T, false, A>::testInvariant();
3968 marray_detail::Assert(MARRAY_NO_DEBUG || this->geometry_.isSimple());
3975 template<
class T,
bool isConst,
class A>
3977 Iterator<T, isConst, A>::testInvariant()
const
3979 if(!MARRAY_NO_DEBUG) {
3981 marray_detail::Assert(coordinates_.size() == 0
3986 if(view_->size() == 0) {
3987 marray_detail::Assert(coordinates_.size() == 0
3992 marray_detail::Assert(index_ <= view_->size());
3993 if(index_ == view_->size()) {
3994 marray_detail::Assert(pointer_ == &((*view_)(view_->size()-1)) + 1);
3997 marray_detail::Assert(pointer_ == &((*view_)(index_)));
3999 if(!view_->isSimple()) {
4000 marray_detail::Assert(coordinates_.size() == view_->dimension());
4001 if(index_ == view_->size()) {
4003 marray_detail::Assert(coordinates_[0] == view_->shape(0));
4004 for(
size_t j=1; j<coordinates_.size(); ++j) {
4005 marray_detail::Assert(coordinates_[j] == view_->shape(j)-1);
4009 size_t d = view_->dimension() - 1;
4010 marray_detail::Assert(coordinates_[d] == view_->shape(d));
4011 for(
size_t j=0; j<d; ++j) {
4012 marray_detail::Assert(coordinates_[j] == view_->shape(j)-1);
4017 std::vector<size_t> testCoord(coordinates_.size());
4018 view_->indexToCoordinates(index_, testCoord.begin());
4019 for(
size_t j=0; j<coordinates_.size(); ++j) {
4020 marray_detail::Assert(coordinates_[j] == testCoord[j]);
4030 template<
class T,
bool isConst,
class A>
4045 template<
class T,
bool isConst,
class A>
4054 coordinates_(std::vector<size_t>(view.dimension()))
4059 if(view.size() == 0) {
4060 marray_detail::Assert(MARRAY_NO_ARG_TEST || index == 0);
4063 if(view.isSimple()) {
4064 marray_detail::Assert(MARRAY_NO_ARG_TEST || index <= view.size());
4065 pointer_ = &view(0) + index;
4068 if(index >= view.size()) {
4070 coordinates_[0] = view.shape(0);
4071 for(
size_t j=1; j<view.dimension(); ++j) {
4072 coordinates_[j] = view.shape(j)-1;
4076 size_t d = view_->dimension() - 1;
4077 coordinates_[d] = view.shape(d);
4078 for(
size_t j=0; j<d; ++j) {
4079 coordinates_[j] = view.shape(j)-1;
4082 pointer_ = &view(view.size()-1) + 1;
4085 view.indexToCoordinates(index, coordinates_.begin());
4086 pointer_ = &view(index);
4098 template<
class T,
bool isConst,
class A>
4104 : view_(reinterpret_cast<view_pointer>(&view)),
4107 coordinates_(std::vector<size_t>(view.
dimension()))
4113 if(view.
size() == 0) {
4114 marray_detail::Assert(MARRAY_NO_ARG_TEST || index == 0);
4118 marray_detail::Assert(MARRAY_NO_ARG_TEST || index <= view.
size());
4119 pointer_ = &view(0) + index;
4122 if(index >= view.
size()) {
4124 coordinates_[0] = view.
shape(0);
4125 for(
size_t j=1; j<view.
dimension(); ++j) {
4126 coordinates_[j] = view.
shape(j)-1;
4130 size_t d = view_->dimension() - 1;
4131 coordinates_[d] = view.
shape(d);
4132 for(
size_t j=0; j<d; ++j) {
4133 coordinates_[j] = view.
shape(j)-1;
4136 pointer_ = &view(view.
size()-1) + 1;
4140 pointer_ = &view(index);
4152 template<
class T,
bool isConst,
class A>
4158 : view_(reinterpret_cast<view_pointer>(&view)),
4161 coordinates_(std::vector<size_t>(view.
dimension()))
4167 if(view.
size() == 0) {
4168 marray_detail::Assert(MARRAY_NO_ARG_TEST || index == 0);
4172 marray_detail::Assert(MARRAY_NO_ARG_TEST || index <= view.
size());
4173 pointer_ = &view(0) + index;
4176 if(index >= view.
size()) {
4178 coordinates_[0] = view.
shape(0);
4179 for(
size_t j=1; j<view.
dimension(); ++j) {
4180 coordinates_[j] = view.
shape(j)-1;
4184 size_t d = view_->dimension() - 1;
4185 coordinates_[d] = view.
shape(d);
4186 for(
size_t j=0; j<d; ++j) {
4187 coordinates_[j] = view.
shape(j)-1;
4190 pointer_ = &view(view.
size()-1) + 1;
4194 pointer_ = &view(index);
4203 template<
class T,
bool isConst,
class A>
4209 pointer_(pointer(in.pointer_)),
4211 coordinates_(in.coordinates_)
4218 template<
class T,
bool isConst,
class A>
4222 marray_detail::Assert(MARRAY_NO_DEBUG || (view_ != 0 && index_ < view_->size()));
4228 template<
class T,
bool isConst,
class A>
4232 marray_detail::Assert(MARRAY_NO_DEBUG || (view_ != 0 && index_ < view_->size()));
4238 template<
class T,
bool isConst,
class A>
4245 marray_detail::Assert(MARRAY_NO_DEBUG || (view_ != 0 && x+index_ < view_->size()));
4246 return (*view_)(x+index_);
4249 template<
class T,
bool isConst,
class A>
4256 marray_detail::Assert(MARRAY_NO_DEBUG || view_ != 0);
4257 if(index_ < view_->size()) {
4258 if(index_ + x < view_->size()) {
4260 if(view_->isSimple()) {
4264 pointer_ = &((*view_)(index_));
4265 view_->indexToCoordinates(index_, coordinates_.begin());
4270 index_ = view_->size();
4271 if(view_->isSimple()) {
4272 pointer_ = &(*view_)(0) + view_->size();
4275 pointer_ = (&(*view_)(view_->size()-1)) + 1;
4276 view_->indexToCoordinates(view_->size()-1, coordinates_.begin());
4281 ++coordinates_[view_->dimension()-1];
4290 template<
class T,
bool isConst,
class A>
4292 Iterator<T, isConst, A>::operator-=
4297 marray_detail::Assert(MARRAY_NO_DEBUG || view_ != 0);
4298 marray_detail::Assert(MARRAY_NO_ARG_TEST || static_cast<difference_type>(index_) >= x);
4300 if(view_->isSimple()) {
4304 pointer_ = &((*view_)(index_));
4305 view_->indexToCoordinates(index_, coordinates_.begin());
4313 template<
class T,
bool isConst,
class A>
4317 marray_detail::Assert(MARRAY_NO_DEBUG || view_ != 0);
4318 if(index_ < view_->size()) {
4320 if(view_->isSimple()) {
4324 if(index_ < view_->size()) {
4326 for(
size_t j=0; j<coordinates_.size(); ++j) {
4327 if(coordinates_[j] == view_->shape(j)-1) {
4328 pointer_ -= view_->strides(j) * coordinates_[j];
4329 coordinates_[j] = 0;
4332 pointer_ += view_->strides(j);
4339 size_t j = coordinates_.size() - 1;
4341 if(coordinates_[j] == view_->shape(j)-1) {
4342 pointer_ -= view_->strides(j) * coordinates_[j];
4343 coordinates_[j] = 0;
4346 pointer_ += view_->strides(j);
4361 pointer_ = &((*view_)(view_->size()-1)) + 1;
4366 ++coordinates_[view_->dimension()-1];
4377 template<
class T,
bool isConst,
class A>
4381 marray_detail::Assert(MARRAY_NO_DEBUG || (view_ != 0 && index_ > 0));
4383 if(view_->isSimple()) {
4387 if(index_ == view_->size()) {
4394 --coordinates_[view_->dimension() - 1];
4399 for(
size_t j=0; j<coordinates_.size(); ++j) {
4400 if(coordinates_[j] == 0) {
4401 coordinates_[j] = view_->shape(j)-1;
4402 pointer_ += view_->strides(j) * coordinates_[j];
4405 pointer_ -= view_->strides(j);
4412 size_t j = view_->dimension() - 1;
4414 if(coordinates_[j] == 0) {
4415 coordinates_[j] = view_->shape(j)-1;
4416 pointer_ += view_->strides(j) * coordinates_[j];
4419 pointer_ -= view_->strides(j);
4439 template<
class T,
bool isConst,
class A>
4443 marray_detail::Assert(MARRAY_NO_DEBUG || view_ != 0);
4451 template<
class T,
bool isConst,
class A>
4455 marray_detail::Assert(MARRAY_NO_DEBUG || (view_ != 0 && index_ > 0));
4461 template<
class T,
bool isConst,
class A>
4463 Iterator<T, isConst, A>::operator+
4468 marray_detail::Assert(MARRAY_NO_DEBUG || view_ != 0);
4474 template<
class T,
bool isConst,
class A>
4476 Iterator<T, isConst, A>::operator-
4481 marray_detail::Assert(MARRAY_NO_DEBUG || view_ != 0);
4487 template<
class T,
bool isConst,
class A>
4488 template<
bool isConstLocal>
4490 Iterator<T, isConst, A>::operator-
4495 marray_detail::Assert(MARRAY_NO_DEBUG || view_ != 0);
4496 marray_detail::Assert(MARRAY_NO_ARG_TEST || it.view_ != 0);
4500 template<
class T,
bool isConst,
class A>
4501 template<
bool isConstLocal>
4503 Iterator<T, isConst, A>::operator==
4508 marray_detail::Assert(MARRAY_NO_DEBUG || view_ != 0);
4509 marray_detail::Assert(MARRAY_NO_ARG_TEST || (it.view_ != 0 && (
void*)it.view_ == (
void*)view_));
4510 return index_ == it.index_;
4513 template<
class T,
bool isConst,
class A>
4514 template<
bool isConstLocal>
4516 Iterator<T, isConst, A>::operator!=
4521 marray_detail::Assert(MARRAY_NO_DEBUG || view_ != 0);
4522 marray_detail::Assert(MARRAY_NO_ARG_TEST || it.view_ != 0);
4523 marray_detail::Assert(MARRAY_NO_ARG_TEST ||
4524 static_cast<const void*>(it.view_) == static_cast<const void*>(view_));
4525 return index_ != it.index_;
4528 template<
class T,
bool isConst,
class A>
4529 template<
bool isConstLocal>
4531 Iterator<T, isConst, A>::operator<
4536 marray_detail::Assert(MARRAY_NO_DEBUG || view_ != 0);
4537 marray_detail::Assert(MARRAY_NO_ARG_TEST || (it.view_ != 0 && it.view_ == view_));
4538 return(index_ < it.index_);
4541 template<
class T,
bool isConst,
class A>
4542 template<
bool isConstLocal>
4544 Iterator<T, isConst, A>::operator>
4549 marray_detail::Assert(MARRAY_NO_DEBUG || view_ != 0);
4550 marray_detail::Assert(MARRAY_NO_ARG_TEST || (it.view_ != 0 && it.view_ == view_));
4551 return(index_ > it.index_);
4554 template<
class T,
bool isConst,
class A>
4555 template<
bool isConstLocal>
4557 Iterator<T, isConst, A>::operator<=
4562 marray_detail::Assert(MARRAY_NO_DEBUG || view_ != 0);
4563 marray_detail::Assert(MARRAY_NO_ARG_TEST || (it.view_ != 0 && it.view_ == view_));
4564 return(index_ <= it.index_);
4567 template<
class T,
bool isConst,
class A>
4568 template<
bool isConstLocal>
4570 Iterator<T, isConst, A>::operator>=
4575 marray_detail::Assert(MARRAY_NO_DEBUG || view_ != 0);
4576 marray_detail::Assert(MARRAY_NO_ARG_TEST || (it.view_ != 0 && it.view_ == view_));
4577 return(index_ >= it.index_);
4584 template<
class T,
bool isConst,
class A>
4588 marray_detail::Assert(MARRAY_NO_DEBUG || view_ != 0);
4589 return index_ < view_->size();
4596 template<
class T,
bool isConst,
class A>
4608 template<
class T,
bool isConst,
class A>
4609 template<
class CoordinateIterator>
4613 CoordinateIterator it
4616 marray_detail::Assert(MARRAY_NO_DEBUG || view_ != 0);
4617 marray_detail::Assert(MARRAY_NO_ARG_TEST || index_ < view_->size());
4618 if(view_->isSimple()) {
4619 view_->indexToCoordinates(index_, it);
4622 for(
size_t j=0; j<coordinates_.size(); ++j, ++it) {
4623 *it = coordinates_[j];
4634 template<
class T,
class A>
4638 const allocator_type& allocator
4649 template<
class T,
class A>
4650 template<
class TLocal,
bool isConstLocal,
class ALocal>
4658 marray_detail::Assert(MARRAY_NO_ARG_TEST ||
4660 || (in.dimension() == 0 && in.size() == 1)
4661 || in.dimension() == 1
4663 this->geometry_.size() = in.size();
4664 this->geometry_.coordinateOrder() = in.coordinateOrder();
4666 this->geometry_.resize(1);
4667 this->geometry_.shape(0) = in.size();
4668 this->geometry_.shapeStrides(0) = 1;
4669 this->geometry_.strides(0) = 1;
4670 this->data_ = this->dataAllocator_.allocate(this->size());
4671 if(in.dimension() == 0) {
4672 this->data_[0] =
static_cast<T
>(in(0));
4675 if(in.isSimple() && marray_detail::IsEqual<T, TLocal>::type) {
4676 memcpy(this->data_, in.data_, (this->size())*
sizeof(T));
4679 for(
size_t j=0; j<in.size(); ++j) {
4680 this->data_[j] =
static_cast<T
>(in(j));
4694 template<
class T,
class A>
4700 const allocator_type& allocator
4705 size_t shape[1] = {size};
4706 this->data_ = this->dataAllocator_.allocate(size);
4707 base::base::assign(&shape[0], &shape[1], this->data_);
4708 for(
size_t j=0; j<size; ++j) {
4709 this->data_[j] = value;
4721 template<
class T,
class A>
4727 const allocator_type& allocator
4732 size_t shape[1] = {size};
4733 this->data_ = this->dataAllocator_.allocate(size);
4734 base::base::assign(&shape[0], &shape[1], this->data_);
4744 template<
class T,
class A>
4745 template<
class E,
class Te>
4750 const allocator_type& allocator
4752 : base(expression, allocator)
4754 marray_detail::Assert(MARRAY_NO_ARG_TEST || expression.
dimension() == 1);
4755 marray_detail::Assert(MARRAY_NO_ARG_TEST || expression.
size() > 0);
4759 #ifdef HAVE_CPP0X_INITIALIZER_LISTS
4760 template<
class T,
class A>
4769 std::initializer_list<T> list,
4770 const allocator_type& allocator
4774 if(list.size() != 0) {
4775 size_t shape[1] = {list.size()};
4776 this->data_ = this->dataAllocator_.allocate(list.size());
4777 base::base::assign(&shape[0], &shape[1], this->data_);
4779 for(
const T *p = list.begin(); p != list.end(); ++p, ++j) {
4780 this->data_[j] = *p;
4793 template<
class T,
class A>
4794 inline Vector<T, A>&
4795 Vector<T, A>::operator=
4800 marray_detail::Assert(MARRAY_NO_DEBUG || this->data_ != 0);
4801 for(
size_t j=0; j<this->size(); ++j) {
4802 this->data_[j] = value;
4813 template<
class T,
class A>
4815 Vector<T, A>::operator=
4821 base::operator=(in);
4832 template<
class T,
class A>
4833 template<
class TLocal,
bool isConstLocal,
class ALocal>
4835 Vector<T, A>::operator=
4841 marray_detail::Assert(MARRAY_NO_ARG_TEST ||
4843 (in.dimension() == 0 && in.size() == 1) ||
4844 in.dimension() == 1);
4845 if(in.geometry_.dimension() == 0 && in.geometry_.size() == 1) {
4847 if(this->size() != 1) {
4848 this->dataAllocator_.deallocate(this->data_, this->size());
4849 this->data_ = this->dataAllocator_.allocate(1);
4851 this->data_[0] =
static_cast<T
>(in(0));
4852 this->geometry_.resize(1);
4853 this->geometry_.shape(0) = 1;
4854 this->geometry_.shapeStrides(0) = 1;
4855 this->geometry_.strides(0) = 1;
4856 this->geometry_.size() = 1;
4857 this->geometry_.isSimple() =
true;
4858 this->geometry_.coordinateOrder() = in.coordinateOrder();
4861 base::operator=(in);
4871 template<
class T,
class A>
4872 template<
class E,
class Te>
4874 Vector<T, A>::operator=
4879 marray_detail::Assert(MARRAY_NO_ARG_TEST || expression.
dimension() == 1);
4880 marray_detail::Assert(MARRAY_NO_ARG_TEST || expression.
size() > 0);
4881 base::operator=(expression);
4894 template<
class T,
class A>
4901 marray_detail::Assert(size == this->size());
4909 template<
class T,
class A>
4921 size_t shape[1] = {size};
4922 base::resize(&shape[0], &shape[1], value);
4932 template<
class T,
class A>
4944 size_t shape[1] = {size};
4945 base::resize(is, &shape[0], &shape[1]);
4952 template<
class T,
class A>
4954 Vector<T, A>::operator[]
4960 return this->operator()(index);
4965 template<
class T,
class A>
4967 Vector<T, A>::operator[]
4973 return this->operator()(index);
4978 template<
class T,
class A>
4983 marray_detail::Assert(MARRAY_NO_DEBUG || this->data_ == 0 ||
4984 (this->geometry_.isSimple() && this->geometry_.dimension() == 1));
4993 template<
class T,
class A>
4997 const allocator_type& allocator
5008 template<
class T,
class A>
5009 template<
class TLocal,
bool isConstLocal,
class ALocal>
5017 marray_detail::Assert(MARRAY_NO_ARG_TEST ||
5019 (in.dimension() == 0 && in.size() == 1) ||
5020 in.dimension() == 2);
5021 this->geometry_.size() = in.size();
5022 this->geometry_.coordinateOrder() = in.coordinateOrder();
5024 this->geometry_.resize(2);
5025 if(in.dimension() == 0) {
5026 this->geometry_.shape(0) = 1;
5027 this->geometry_.shape(1) = 1;
5028 this->geometry_.shapeStrides(0) = 1;
5029 this->geometry_.shapeStrides(1) = 1;
5030 this->geometry_.strides(0) = 1;
5031 this->geometry_.strides(1) = 1;
5032 this->data_ = this->dataAllocator_.allocate(1);
5033 this->data_[0] =
static_cast<T
>(in(0));
5036 this->geometry_.shape(0) = in.shape(0);
5037 this->geometry_.shape(1) = in.shape(1);
5038 this->geometry_.shapeStrides(0) = in.geometry_.shapeStrides(0);
5039 this->geometry_.shapeStrides(1) = in.geometry_.shapeStrides(1);
5040 this->geometry_.strides(0) = in.geometry_.shapeStrides(0);
5041 this->geometry_.strides(1) = in.geometry_.shapeStrides(1);
5042 this->data_ = this->dataAllocator_.allocate(this->size());
5043 if(in.isSimple() && marray_detail::IsEqual<T, TLocal>::type) {
5044 memcpy(this->data_, in.data_, (this->size())*
sizeof(T));
5047 for(
size_t j=0; j<in.size(); ++j) {
5048 this->data_[j] =
static_cast<T
>(in(j));
5065 template<
class T,
class A>
5073 const allocator_type& allocator
5077 if(n1 > 0 && n2 > 0) {
5078 size_t shape[2] = {n1, n2};
5079 T* data = this->dataAllocator_.allocate(n1 * n2);
5080 base::base::assign(&shape[0], &shape[2], data,
5081 coordinateOrder, coordinateOrder);
5082 for(
size_t j=0; j<this->size(); ++j) {
5083 this->data_[j] = value;
5099 template<
class T,
class A>
5107 const allocator_type& allocator
5111 if(n1 > 0 && n2 > 0) {
5112 size_t shape[2] = {n1, n2};
5113 this->data_ = this->dataAllocator_.allocate(n1 * n2);
5114 base::base::assign(&shape[0], &shape[2], this->data_,
5115 coordinateOrder, coordinateOrder);
5125 template<
class T,
class A>
5126 template<
class E,
class Te>
5131 const allocator_type& allocator
5133 : base(expression, allocator)
5135 marray_detail::Assert(MARRAY_NO_ARG_TEST || expression.
dimension() == 2);
5136 marray_detail::Assert(MARRAY_NO_ARG_TEST || expression.
size() > 0);
5146 template<
class T,
class A>
5153 marray_detail::Assert(MARRAY_NO_DEBUG || this->data_ != 0);
5154 for(
size_t j=0; j<this->size(); ++j) {
5155 this->data_[j] = value;
5164 template<
class T,
class A>
5166 Matrix<T, A>::operator=
5172 base::operator=(in);
5181 template<
class T,
class A>
5182 template<
class TLocal,
bool isConstLocal,
class ALocal>
5184 Matrix<T, A>::operator=
5189 marray_detail::Assert(MARRAY_NO_ARG_TEST ||
5191 (in.dimension() == 0 && in.size() == 1) ||
5192 in.dimension() == 2);
5193 if(in.dimension() == 0 && in.size() == 1) {
5195 if(this->size() != 1) {
5196 this->dataAllocator_.deallocate(this->data_, this->size());
5197 this->data_ = this->dataAllocator_.allocate(1);
5199 this->data_[0] =
static_cast<T
>(in(0));
5200 this->geometry_.
resize(2);
5201 this->geometry_.shape(0) = 1;
5202 this->geometry_.shape(1) = 1;
5203 this->geometry_.shapeStrides(0) = 1;
5204 this->geometry_.shapeStrides(1) = 1;
5205 this->geometry_.strides(0) = 1;
5206 this->geometry_.strides(1) = 1;
5207 this->geometry_.size() = 1;
5208 this->geometry_.isSimple() =
true;
5209 this->geometry_.coordinateOrder() = in.coordinateOrder();
5212 base::operator=(in);
5222 template<
class T,
class A>
5223 template<
class E,
class Te>
5225 Matrix<T, A>::operator=
5230 marray_detail::Assert(MARRAY_NO_ARG_TEST || expression.
dimension() == 2);
5231 marray_detail::Assert(MARRAY_NO_ARG_TEST || expression.
size() > 0);
5232 base::operator=(expression);
5242 template<
class T,
class A>
5251 if(n1 == 0 || n2 == 0) {
5255 size_t shape[2] = {n1, n2};
5256 base::resize(&shape[0], &shape[2], value);
5267 template<
class T,
class A>
5276 if(n1 == 0 || n2 == 0) {
5280 size_t shape[2] = {n1, n2};
5281 base::resize(is, &shape[0], &shape[2]);
5293 template<
class T,
class A>
5301 marray_detail::Assert(MARRAY_NO_ARG_TEST || (n2 > 0 && n1 > 0));
5302 size_t shape[2] = {n1, n2};
5303 base::reshape(&shape[0], &shape[2]);
5309 template<
class T,
class A>
5314 marray_detail::Assert(MARRAY_NO_DEBUG || this->data_ == 0 ||
5315 (this->geometry_.isSimple() && this->geometry_.dimension() == 2));
5320 template<
class E,
class T>
5321 class ViewExpression {
5327 {
return static_cast<const E&
>(*this).dimension(); }
5329 {
return static_cast<const E&
>(*this).size(); }
5330 const size_t shape(
const size_t j)
const
5331 {
return static_cast<const E&
>(*this).shape(j); }
5333 {
return static_cast<const E&
>(*this).shapeBegin(); }
5335 {
return static_cast<const E&
>(*this).shapeEnd(); }
5336 template<
class Tv,
bool isConst,
class A>
5338 {
return static_cast<const E&
>(*this).overlaps(v); }
5340 {
return static_cast<const E&
>(*this).coordinateOrder(); }
5342 {
return static_cast<const E&
>(*this).isSimple(); }
5343 template<
class Accessor>
5345 {
return static_cast<const E&
>(*this)(it); }
5347 {
return static_cast<const E&
>(*this)(c0, c1); }
5348 const T&
operator()(
const size_t c0,
const size_t c1,
const size_t c2)
const
5349 {
return static_cast<const E&
>(*this)(c0, c1, c2); }
5350 const T&
operator()(
const size_t c0,
const size_t c1,
const size_t c2,
const size_t c3)
const
5351 {
return static_cast<const E&
>(*this)(c0, c1, c2, c3); }
5352 const T&
operator()(
const size_t c0,
const size_t c1,
const size_t c2,
const size_t c3,
const size_t c4)
const
5353 {
return static_cast<const E&
>(*this)(c0, c1, c2, c3, c4); }
5355 {
return static_cast<const E&
>(*this)[offset]; }
5357 {
return static_cast<E&
>(*this); }
5358 operator E
const&()
const
5359 {
return static_cast<const E&
>(*this); }
5362 class ExpressionIterator {
5365 : expression_(expression),
5366 data_(&expression_(0)),
5369 void incrementCoordinate(
const size_t coordinateIndex)
5370 { offset_ += expression_.strides(coordinateIndex); }
5371 void resetCoordinate(
const size_t coordinateIndex)
5372 { offset_ -= expression_.strides(coordinateIndex)
5374 * (expression_.shape(coordinateIndex) - 1); }
5380 return data_[offset_]; }
5382 const E& expression_;
5390 template<
class E,
class T,
class UnaryFunctor>
5391 class UnaryViewExpression
5392 :
public ViewExpression<UnaryViewExpression<E, T, UnaryFunctor>, T>
5395 typedef E expression_type;
5396 typedef T value_type;
5398 UnaryViewExpression(
const ViewExpression<E, T>& e)
5400 unaryFunctor_(UnaryFunctor())
5402 const size_t dimension()
const
5403 {
return e_.dimension(); }
5404 const size_t size()
const
5405 {
return e_.size(); }
5406 const size_t shape(
const size_t j)
const
5407 {
return e_.shape(j); }
5408 const size_t* shapeBegin()
const
5409 {
return e_.shapeBegin(); }
5410 const size_t* shapeEnd()
const
5411 {
return e_.shapeEnd(); }
5412 template<
class Tv,
bool isConst,
class A>
5413 bool overlaps(
const View<Tv, isConst, A>& v)
const
5414 {
return e_.overlaps(v); }
5416 {
return e_.coordinateOrder(); }
5417 const bool isSimple()
const
5418 {
return e_.isSimple(); }
5419 template<
class Accessor>
5420 const T operator()(Accessor it)
const
5421 {
return unaryFunctor_(e_(it)); }
5422 const T operator()(
const size_t c0,
const size_t c1)
const
5423 {
return unaryFunctor_(e_(c0, c1)); }
5424 const T operator()(
const size_t c0,
const size_t c1,
const size_t c2)
const
5425 {
return unaryFunctor_(e_(c0, c1, c2)); }
5426 const T operator()(
const size_t c0,
const size_t c1,
const size_t c2,
const size_t c3)
const
5427 {
return unaryFunctor_(e_(c0, c1, c2, c3)); }
5428 const T operator()(
const size_t c0,
const size_t c1,
const size_t c2,
const size_t c3,
const size_t c4)
const
5429 {
return unaryFunctor_(e_(c0, c1, c2, c3, c4)); }
5430 const T operator[](
const size_t offset)
const
5431 {
return unaryFunctor_(e_[offset]); }
5433 class ExpressionIterator {
5435 ExpressionIterator(
const UnaryViewExpression<E, T, UnaryFunctor>& expression)
5436 : unaryFunctor_(expression.unaryFunctor_),
5437 iterator_(expression.e_)
5439 void incrementCoordinate(
const size_t coordinateIndex)
5440 { iterator_.incrementCoordinate(coordinateIndex); }
5441 void resetCoordinate(
const size_t coordinateIndex)
5442 { iterator_.resetCoordinate(coordinateIndex); }
5444 {
return unaryFunctor_(*iterator_); }
5446 UnaryFunctor unaryFunctor_;
5447 typename E::ExpressionIterator iterator_;
5452 UnaryFunctor unaryFunctor_;
5455 template<
class E1,
class T1,
class E2,
class T2,
class BinaryFunctor>
5456 class BinaryViewExpression
5457 :
public ViewExpression<BinaryViewExpression<E1, T1, E2, T2, BinaryFunctor>,
5458 typename marray_detail::PromoteType<T1, T2>::type>
5461 typedef E1 expression_type_1;
5462 typedef E2 expression_type_2;
5463 typedef T1 value_type_1;
5464 typedef T2 value_type_2;
5465 typedef typename marray_detail::PromoteType<T1, T2>::type value_type;
5466 typedef BinaryFunctor functor_type;
5467 typedef ViewExpression<BinaryViewExpression<E1, T1, E2, T2, BinaryFunctor>,
5470 BinaryViewExpression(
const ViewExpression<E1, T1>& e1,
5471 const ViewExpression<E2, T2>& e2)
5473 binaryFunctor_(BinaryFunctor())
5475 if(!MARRAY_NO_DEBUG) {
5476 marray_detail::Assert(e1_.size() != 0 && e2_.size() != 0);
5477 marray_detail::Assert(e1_.dimension() == e2_.dimension());
5478 for(
size_t j=0; j<e1_.dimension(); ++j) {
5479 marray_detail::Assert(e1_.shape(j) == e2_.shape(j));
5483 const size_t dimension()
const
5484 {
return e1_.dimension() < e2_.dimension() ? e2_.dimension() : e1_.dimension(); }
5485 const size_t size()
const
5486 {
return e1_.size() < e2_.size() ? e2_.size() : e1_.size(); }
5487 const size_t shape(
const size_t j)
const
5488 {
return e1_.dimension() < e2_.dimension() ? e2_.shape(j) : e1_.shape(j); }
5489 const size_t* shapeBegin()
const
5490 {
return e1_.dimension() < e2_.dimension() ? e2_.shapeBegin() : e1_.shapeBegin(); }
5491 const size_t* shapeEnd()
const
5492 {
return e1_.dimension() < e2_.dimension() ? e2_.shapeEnd() : e1_.shapeEnd(); }
5493 template<
class Tv,
bool isConst,
class A>
5494 bool overlaps(
const View<Tv, isConst, A>& v)
const
5495 {
return e1_.overlaps(v) || e2_.overlaps(v); }
5497 {
return e1_.coordinateOrder(); }
5498 const bool isSimple()
const
5499 {
return e1_.isSimple() && e2_.isSimple()
5500 && e1_.coordinateOrder() == e2_.coordinateOrder(); }
5501 template<
class Accessor>
5502 const value_type operator()(Accessor it)
const
5503 {
return binaryFunctor_(e1_(it), e2_(it)); }
5504 const value_type operator()(
const size_t c0,
const size_t c1)
const
5505 {
return binaryFunctor_(e1_(c0, c1), e2_(c0, c1)); }
5506 const value_type operator()(
const size_t c0,
const size_t c1,
const size_t c2)
const
5507 {
return binaryFunctor_(e1_(c0, c1, c2), e2_(c0, c1, c2)); }
5508 const value_type operator()(
const size_t c0,
const size_t c1,
const size_t c2,
const size_t c3)
const
5509 {
return binaryFunctor_(e1_(c0, c1, c2, c3), e2_(c0, c1, c2, c3)); }
5510 const value_type operator()(
const size_t c0,
const size_t c1,
const size_t c2,
const size_t c3,
const size_t c4)
const
5511 {
return binaryFunctor_(e1_(c0, c1, c2, c3, c4), e2_(c0, c1, c2, c3, c4)); }
5512 const value_type operator[](
const size_t offset)
const
5513 {
return binaryFunctor_(e1_[offset], e2_[offset]); }
5515 class ExpressionIterator {
5517 ExpressionIterator(
const BinaryViewExpression<E1, T1, E2, T2, BinaryFunctor>& expression)
5518 : binaryFunctor_(expression.binaryFunctor_),
5519 iterator1_(expression.e1_),
5520 iterator2_(expression.e2_)
5522 void incrementCoordinate(
const size_t coordinateIndex)
5523 { iterator1_.incrementCoordinate(coordinateIndex);
5524 iterator2_.incrementCoordinate(coordinateIndex); }
5525 void resetCoordinate(
const size_t coordinateIndex)
5526 { iterator1_.resetCoordinate(coordinateIndex);
5527 iterator2_.resetCoordinate(coordinateIndex); }
5529 {
return binaryFunctor_(*iterator1_, *iterator2_); }
5531 BinaryFunctor binaryFunctor_;
5532 typename E1::ExpressionIterator iterator1_;
5533 typename E2::ExpressionIterator iterator2_;
5537 const expression_type_1& e1_;
5538 const expression_type_2& e2_;
5539 BinaryFunctor binaryFunctor_;
5542 template<
class E,
class T,
class S,
class BinaryFunctor>
5543 class BinaryViewExpressionScalarFirst
5544 :
public ViewExpression<BinaryViewExpressionScalarFirst<E, T, S, BinaryFunctor>,
5545 typename marray_detail::PromoteType<T, S>::type> {
5547 typedef E expression_type;
5548 typedef T value_type_1;
5549 typedef S scalar_type;
5550 typedef typename marray_detail::PromoteType<T, S>::type value_type;
5551 typedef BinaryFunctor functor_type;
5552 typedef ViewExpression<BinaryViewExpressionScalarFirst<E, T, S, BinaryFunctor>,
5555 BinaryViewExpressionScalarFirst(
const ViewExpression<E, T>& e,
5556 const scalar_type& scalar)
5558 scalar_(scalar), binaryFunctor_(BinaryFunctor())
5560 const size_t dimension()
const
5561 {
return e_.dimension(); }
5562 const size_t size()
const
5563 {
return e_.size(); }
5564 const size_t shape(
const size_t j)
const
5565 {
return e_.shape(j); }
5566 const size_t* shapeBegin()
const
5567 {
return e_.shapeBegin(); }
5568 const size_t* shapeEnd()
const
5569 {
return e_.shapeEnd(); }
5570 template<
class Tv,
bool isConst,
class A>
5571 bool overlaps(
const View<Tv, isConst, A>& v)
const
5572 {
return e_.overlaps(v); }
5574 {
return e_.coordinateOrder(); }
5575 const bool isSimple()
const
5576 {
return e_.isSimple(); }
5577 template<
class Accessor>
5578 const value_type operator()(Accessor it)
const
5579 {
return binaryFunctor_(scalar_, e_(it)); }
5580 const value_type operator()(
const size_t c0,
const size_t c1)
const
5581 {
return binaryFunctor_(scalar_, e_(c0, c1)); }
5582 const value_type operator()(
const size_t c0,
const size_t c1,
const size_t c2)
const
5583 {
return binaryFunctor_(scalar_, e_(c0, c1, c2)); }
5584 const value_type operator()(
const size_t c0,
const size_t c1,
const size_t c2,
const size_t c3)
const
5585 {
return binaryFunctor_(scalar_, e_(c0, c1, c2, c3)); }
5586 const value_type operator()(
const size_t c0,
const size_t c1,
const size_t c2,
const size_t c3,
const size_t c4)
const
5587 {
return binaryFunctor_(scalar_, e_(c0, c1, c2, c3, c4)); }
5588 const value_type operator[](
const size_t offset)
const
5589 {
return binaryFunctor_(scalar_, e_[offset]); }
5591 class ExpressionIterator {
5593 ExpressionIterator(
const BinaryViewExpressionScalarFirst<E, T, S, BinaryFunctor>& expression)
5594 : binaryFunctor_(expression.binaryFunctor_),
5595 scalar_(expression.scalar_),
5596 iterator_(expression.e_)
5598 void incrementCoordinate(
const size_t coordinateIndex)
5599 { iterator_.incrementCoordinate(coordinateIndex); }
5600 void resetCoordinate(
const size_t coordinateIndex)
5601 { iterator_.resetCoordinate(coordinateIndex); }
5603 {
return binaryFunctor_(scalar_, *iterator_); }
5605 BinaryFunctor binaryFunctor_;
5606 const typename BinaryViewExpressionScalarFirst<E, T, S, BinaryFunctor>::scalar_type& scalar_;
5607 typename E::ExpressionIterator iterator_;
5611 const expression_type& e_;
5612 const scalar_type scalar_;
5613 BinaryFunctor binaryFunctor_;
5616 template<
class E,
class T,
class S,
class BinaryFunctor>
5617 class BinaryViewExpressionScalarSecond
5618 :
public ViewExpression<BinaryViewExpressionScalarSecond<E, T, S, BinaryFunctor>,
5619 typename marray_detail::PromoteType<T, S>::type> {
5621 typedef T value_type_1;
5622 typedef E expression_type;
5623 typedef S scalar_type;
5624 typedef typename marray_detail::PromoteType<T, S>::type value_type;
5625 typedef BinaryFunctor functor_type;
5626 typedef ViewExpression<BinaryViewExpressionScalarSecond<E, T, S, BinaryFunctor>,
5629 BinaryViewExpressionScalarSecond(
const ViewExpression<E, T>& e,
5630 const scalar_type& scalar)
5632 scalar_(scalar), binaryFunctor_(BinaryFunctor())
5634 const size_t dimension()
const
5635 {
return e_.dimension(); }
5636 const size_t size()
const
5637 {
return e_.size(); }
5638 const size_t shape(
const size_t j)
const
5639 {
return e_.shape(j); }
5640 const size_t* shapeBegin()
const
5641 {
return e_.shapeBegin(); }
5642 const size_t* shapeEnd()
const
5643 {
return e_.shapeEnd(); }
5644 template<
class Tv,
bool isConst,
class A>
5645 bool overlaps(
const View<Tv, isConst, A>& v)
const
5646 {
return e_.overlaps(v); }
5648 {
return e_.coordinateOrder(); }
5649 const bool isSimple()
const
5650 {
return e_.isSimple(); }
5651 template<
class Accessor>
5652 const value_type operator()(Accessor it)
const
5653 {
return binaryFunctor_(e_(it), scalar_); }
5654 const value_type operator()(
const size_t c0,
const size_t c1)
const
5655 {
return binaryFunctor_(e_(c0, c1), scalar_); }
5656 const value_type operator()(
const size_t c0,
const size_t c1,
const size_t c2)
const
5657 {
return binaryFunctor_(e_(c0, c1, c2), scalar_); }
5658 const value_type operator()(
const size_t c0,
const size_t c1,
const size_t c2,
const size_t c3)
const
5659 {
return binaryFunctor_(e_(c0, c1, c2, c3), scalar_); }
5660 const value_type operator()(
const size_t c0,
const size_t c1,
const size_t c2,
const size_t c3,
const size_t c4)
const
5661 {
return binaryFunctor_(e_(c0, c1, c2, c3, c4), scalar_); }
5662 const value_type operator[](
const size_t offset)
const
5663 {
return binaryFunctor_(e_[offset], scalar_); }
5665 class ExpressionIterator {
5667 ExpressionIterator(
const BinaryViewExpressionScalarSecond<E, T, S, BinaryFunctor>& expression)
5668 : binaryFunctor_(expression.binaryFunctor_),
5669 scalar_(expression.scalar_),
5670 iterator_(expression.e_)
5672 void incrementCoordinate(
const size_t coordinateIndex)
5673 { iterator_.incrementCoordinate(coordinateIndex); }
5674 void resetCoordinate(
const size_t coordinateIndex)
5675 { iterator_.resetCoordinate(coordinateIndex); }
5677 {
return binaryFunctor_(*iterator_, scalar_); }
5679 BinaryFunctor binaryFunctor_;
5680 const typename BinaryViewExpressionScalarSecond<E, T, S, BinaryFunctor>::scalar_type& scalar_;
5681 typename E::ExpressionIterator iterator_;
5685 const expression_type& e_;
5686 const scalar_type scalar_;
5687 BinaryFunctor binaryFunctor_;
5694 namespace marray_detail {
5700 typedef typename A::template rebind<size_t>::other allocator_type;
5702 Geometry(
const allocator_type& = allocator_type());
5704 const size_t = 0,
const bool =
true,
5705 const allocator_type& = allocator_type());
5706 template<
class ShapeIterator>
5707 Geometry(ShapeIterator, ShapeIterator,
5710 const allocator_type& = allocator_type());
5711 template<
class ShapeIterator,
class Str
ideIterator>
5712 Geometry(ShapeIterator, ShapeIterator, StrideIterator,
5714 const allocator_type& = allocator_type());
5715 Geometry(
const Geometry<A>&);
5718 Geometry<A>& operator=(
const Geometry<A>&);
5720 void resize(
const size_t dimension);
5721 const size_t dimension()
const;
5722 const size_t shape(
const size_t)
const;
5723 size_t& shape(
const size_t);
5724 const size_t shapeStrides(
const size_t)
const;
5725 size_t& shapeStrides(
const size_t);
5726 const size_t strides(
const size_t)
const;
5727 size_t& strides(
const size_t);
5728 const size_t* shapeBegin()
const;
5729 size_t* shapeBegin();
5730 const size_t* shapeEnd()
const;
5732 const size_t* shapeStridesBegin()
const;
5733 size_t* shapeStridesBegin();
5734 const size_t* shapeStridesEnd()
const;
5735 size_t* shapeStridesEnd();
5736 const size_t* stridesBegin()
const;
5737 size_t* stridesBegin();
5738 const size_t* stridesEnd()
const;
5739 size_t* stridesEnd();
5740 const size_t size()
const;
5744 const bool isSimple()
const;
5745 void updateSimplicity();
5749 allocator_type allocator_;
5751 size_t* shapeStrides_;
5767 Geometry<A>::Geometry
5769 const typename Geometry<A>::allocator_type& allocator
5771 : allocator_(allocator),
5777 coordinateOrder_(defaultOrder),
5784 Geometry<A>::Geometry
5786 const Geometry<A>& g
5788 : allocator_(g.allocator_),
5789 shape_(g.dimension_==0 ? 0 : allocator_.allocate(g.dimension_*3)),
5790 shapeStrides_(shape_ + g.dimension_),
5791 strides_(shapeStrides_ + g.dimension_),
5792 dimension_(g.dimension_),
5794 coordinateOrder_(g.coordinateOrder_),
5795 isSimple_(g.isSimple_)
5804 memcpy(shape_, g.shape_, (dimension_*3)*
sizeof(
size_t));
5809 Geometry<A>::Geometry
5811 const size_t dimension,
5814 const bool isSimple,
5815 const typename Geometry<A>::allocator_type& allocator
5817 : allocator_(allocator),
5818 shape_(allocator_.allocate(dimension*3)),
5819 shapeStrides_(shape_+dimension),
5820 strides_(shapeStrides_+dimension),
5821 dimension_(dimension),
5823 coordinateOrder_(order),
5829 template<
class ShapeIterator>
5831 Geometry<A>::Geometry
5833 ShapeIterator begin,
5837 const typename Geometry<A>::allocator_type& allocator
5839 : allocator_(allocator),
5840 shape_(allocator_.allocate(
std::distance(begin, end) * 3)),
5841 shapeStrides_(shape_ +
std::distance(begin, end)),
5842 strides_(shapeStrides_ +
std::distance(begin, end)),
5843 dimension_(
std::distance(begin, end)),
5845 coordinateOrder_(internalCoordinateOrder),
5848 if(dimension_ != 0) {
5849 isSimple_ = (externalCoordinateOrder == internalCoordinateOrder);
5850 for(
size_t j=0; j<dimension(); ++j, ++begin) {
5851 const size_t s =
static_cast<size_t>(*begin);
5855 stridesFromShape(shapeBegin(), shapeEnd(), stridesBegin(),
5856 externalCoordinateOrder);
5857 stridesFromShape(shapeBegin(), shapeEnd(), shapeStridesBegin(),
5858 internalCoordinateOrder);
5863 template<
class ShapeIterator,
class Str
ideIterator>
5865 Geometry<A>::Geometry
5867 ShapeIterator begin,
5871 const typename Geometry<A>::allocator_type& allocator
5873 : allocator_(allocator),
5874 shape_(allocator_.allocate(
std::distance(begin, end) * 3)),
5875 shapeStrides_(shape_ +
std::distance(begin, end)),
5876 strides_(shapeStrides_ +
std::distance(begin, end)),
5877 dimension_(
std::distance(begin, end)),
5879 coordinateOrder_(internalCoordinateOrder),
5882 if(dimension() != 0) {
5883 for(
size_t j=0; j<dimension(); ++j, ++begin, ++it) {
5884 const size_t s =
static_cast<size_t>(*begin);
5889 stridesFromShape(shapeBegin(), shapeEnd(), shapeStridesBegin(),
5890 internalCoordinateOrder);
5897 Geometry<A>::~Geometry()
5899 allocator_.deallocate(shape_, dimension_*3);
5904 Geometry<A>::operator=
5906 const Geometry<A>& g
5910 if(g.dimension_ != dimension_) {
5911 allocator_.deallocate(shape_, dimension_*3);
5912 dimension_ = g.dimension_;
5913 shape_ = allocator_.allocate(dimension_*3);
5914 shapeStrides_ = shape_+dimension_;
5915 strides_ = shapeStrides_+dimension_;
5916 dimension_ = g.dimension_;
5925 memcpy(shape_, g.shape_, (dimension_*3)*
sizeof(
size_t));
5927 coordinateOrder_ = g.coordinateOrder_;
5928 isSimple_ = g.isSimple_;
5937 const size_t dimension
5940 if(dimension != dimension_) {
5941 size_t* newShape = allocator_.allocate(dimension*3);
5942 size_t* newShapeStrides = newShape + dimension;
5943 size_t* newStrides = newShapeStrides + dimension;
5944 for(
size_t j=0; j<( (dimension < dimension_) ? dimension : dimension_); ++j) {
5946 newShape[j] = shape(j);
5947 newShapeStrides[j] = shapeStrides(j);
5948 newStrides[j] = strides(j);
5950 allocator_.deallocate(shape_, dimension_*3);
5952 shapeStrides_ = newShapeStrides;
5953 strides_ = newStrides;
5954 dimension_ = dimension;
5960 Geometry<A>::dimension()
const
5967 Geometry<A>::shape(
const size_t j)
const
5969 Assert(MARRAY_NO_DEBUG || j<dimension_);
5975 Geometry<A>::shape(
const size_t j)
5977 Assert(MARRAY_NO_DEBUG || j<dimension_);
5983 Geometry<A>::shapeStrides
5988 Assert(MARRAY_NO_DEBUG || j<dimension_);
5989 return shapeStrides_[j];
5994 Geometry<A>::shapeStrides
5999 Assert(MARRAY_NO_DEBUG || j<dimension_);
6000 return shapeStrides_[j];
6005 Geometry<A>::strides
6010 Assert(MARRAY_NO_DEBUG || j<dimension_);
6016 Geometry<A>::strides
6021 Assert(MARRAY_NO_DEBUG || j<dimension_);
6026 inline const size_t*
6027 Geometry<A>::shapeBegin()
const
6034 Geometry<A>::shapeBegin()
6040 inline const size_t*
6041 Geometry<A>::shapeEnd()
const
6043 return shape_ + dimension_;
6048 Geometry<A>::shapeEnd()
6050 return shape_ + dimension_;
6054 inline const size_t*
6055 Geometry<A>::shapeStridesBegin()
const
6057 return shapeStrides_;
6062 Geometry<A>::shapeStridesBegin()
6064 return shapeStrides_;
6068 inline const size_t*
6069 Geometry<A>::shapeStridesEnd()
const
6071 return shapeStrides_ + dimension_;
6076 Geometry<A>::shapeStridesEnd()
6078 return shapeStrides_ + dimension_;
6082 inline const size_t*
6083 Geometry<A>::stridesBegin()
const
6090 Geometry<A>::stridesBegin()
6096 inline const size_t*
6097 Geometry<A>::stridesEnd()
const
6099 return strides_ + dimension_;
6104 Geometry<A>::stridesEnd()
6106 return strides_ + dimension_;
6111 Geometry<A>::size()
const
6125 Geometry<A>::coordinateOrder()
const
6127 return coordinateOrder_;
6132 Geometry<A>::coordinateOrder()
6134 return coordinateOrder_;
6139 Geometry<A>::isSimple()
const
6146 Geometry<A>::isSimple()
6153 Geometry<A>::updateSimplicity()
6155 for(
size_t j=0; j<dimension(); ++j) {
6156 if(shapeStrides(j) != strides(j)) {
6165 template<
class ShapeIterator,
class Str
idesIterator>
6169 ShapeIterator begin,
6171 StridesIterator strideBegin,
6175 Assert(MARRAY_NO_ARG_TEST || std::distance(begin, end) != 0);
6176 size_t dimension = std::distance(begin, end);
6177 ShapeIterator shapeIt;
6178 StridesIterator strideIt;
6180 shapeIt = begin + (dimension-1);
6181 strideIt = strideBegin + (dimension-1);
6183 for(
size_t j=1; j<dimension; ++j) {
6184 size_t tmp = *strideIt;
6186 (*strideIt) = tmp * (*shapeIt);
6192 strideIt = strideBegin;
6194 for(
size_t j=1; j<dimension; ++j) {
6195 size_t tmp = *strideIt;
6197 (*strideIt) = tmp * (*shapeIt);
6203 template<
unsigned short N,
class Functor,
class T,
class A>
6204 struct OperateHelperUnary
6206 static inline void operate
6208 View<T, false, A>& v,
6213 for(
size_t j=0; j<v.shape(N-1); ++j) {
6214 OperateHelperUnary<N-1, Functor, T, A>::operate(v, f, data);
6215 data += v.strides(N-1);
6217 data -= v.shape(N-1) * v.strides(N-1);
6222 template<
class Functor,
class T,
class A>
6223 struct OperateHelperUnary<0, Functor, T, A>
6225 static inline void operate
6227 View<T, false, A>& v,
6236 template<
unsigned short N,
class Functor,
class T1,
class T2,
class A>
6237 struct OperateHelperBinaryScalar
6239 static inline void operate
6241 View<T1, false, A>& v,
6247 for(
size_t j=0; j<v.shape(N-1); ++j) {
6248 OperateHelperBinaryScalar<N-1, Functor, T1, T2, A>::operate(
6250 data += v.strides(N-1);
6252 data -= v.shape(N-1) * v.strides(N-1);
6256 template<
class Functor,
class T1,
class T2,
class A>
6257 struct OperateHelperBinaryScalar<0, Functor, T1, T2, A>
6259 static inline void operate
6261 View<T1, false, A>& v,
6271 template<
unsigned short N,
class Functor,
class T1,
class T2,
6272 bool isConst,
class A1,
class A2>
6273 struct OperateHelperBinary
6275 static inline void operate
6277 View<T1, false, A1>& v,
6278 const View<T2, isConst, A2>& w,
6284 for(
size_t j=0; j<v.shape(N-1); ++j) {
6285 OperateHelperBinary<N-1, Functor, T1, T2, isConst, A1, A2>::operate(
6286 v, w, f, data1, data2);
6287 data1 += v.strides(N-1);
6288 data2 += w.strides(N-1);
6290 data1 -= v.shape(N-1) * v.strides(N-1);
6291 data2 -= w.shape(N-1) * w.strides(N-1);
6295 template<
class Functor,
class T1,
class T2,
bool isConst,
class A1,
class A2>
6296 struct OperateHelperBinary<0, Functor, T1, T2, isConst, A1, A2>
6298 static inline void operate
6300 View<T1, false, A1>& v,
6301 const View<T2, isConst, A2>& w,
6311 template<
class TFrom,
class TTo,
class AFrom,
class ATo>
6312 struct AssignmentOperatorHelper<false, TFrom, TTo, AFrom, ATo>
6323 const View<TFrom, true, AFrom>& from,
6324 View<TTo, false, ATo>& to
6327 typedef typename View<TFrom, true, AFrom>::const_iterator FromIterator;
6328 typedef typename View<TTo, false, ATo>::iterator ToIterator;
6329 if(!MARRAY_NO_ARG_TEST) {
6330 Assert(from.data_ != 0 && from.dimension() == to.dimension());
6331 for(
size_t j=0; j<from.dimension(); ++j) {
6332 Assert(from.shape(j) == to.shape(j));
6335 if(from.overlaps(to)) {
6336 Marray<TFrom, AFrom> m = from;
6339 else if(from.coordinateOrder() == to.coordinateOrder()
6340 && from.isSimple() && to.isSimple()
6341 && IsEqual<TFrom, TTo>::type) {
6342 memcpy(to.data_, from.data_, (from.size())*
sizeof(TFrom));
6344 else if(from.dimension() == 1)
6345 OperateHelperBinary<1, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6346 else if(from.dimension() == 2)
6347 OperateHelperBinary<2, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6348 else if(from.dimension() == 3)
6349 OperateHelperBinary<3, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6350 else if(from.dimension() == 4)
6351 OperateHelperBinary<4, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6352 else if(from.dimension() == 5)
6353 OperateHelperBinary<5, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6354 else if(from.dimension() == 6)
6355 OperateHelperBinary<6, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6356 else if(from.dimension() == 7)
6357 OperateHelperBinary<7, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6358 else if(from.dimension() == 8)
6359 OperateHelperBinary<8, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6360 else if(from.dimension() == 9)
6361 OperateHelperBinary<9, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6362 else if(from.dimension() == 10)
6363 OperateHelperBinary<10, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6365 FromIterator itFrom = from.begin();
6366 ToIterator itTo = to.begin();
6367 for(; itFrom.hasMore(); ++itFrom, ++itTo) {
6368 *itTo =
static_cast<TTo
>(*itFrom);
6379 const View<TFrom, false, AFrom>& from,
6380 View<TTo, false, ATo>& to
6383 typedef typename View<TFrom, false, AFrom>::const_iterator FromIterator;
6384 typedef typename View<TTo, false, ATo>::iterator ToIterator;
6385 if(static_cast<const void*>(&from) != static_cast<const void*>(&to)) {
6388 Assert(MARRAY_NO_ARG_TEST ||
sizeof(TTo) ==
sizeof(TFrom));
6389 to.data_ =
static_cast<TTo*
>(
static_cast<void*
>(from.data_));
6390 to.geometry_ = from.geometry_;
6393 if(!MARRAY_NO_ARG_TEST) {
6394 Assert(from.data_ != 0 && from.dimension() == to.dimension());
6395 for(
size_t j=0; j<from.dimension(); ++j) {
6396 Assert(from.shape(j) == to.shape(j));
6399 if(from.overlaps(to)) {
6400 Marray<TFrom, AFrom> m = from;
6403 else if(from.coordinateOrder() == to.coordinateOrder()
6404 && from.isSimple() && to.isSimple()
6405 && IsEqual<TFrom, TTo>::type) {
6406 memcpy(to.data_, from.data_, (from.size())*
sizeof(TFrom));
6408 else if(from.dimension() == 1)
6409 OperateHelperBinary<1, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6410 else if(from.dimension() == 2)
6411 OperateHelperBinary<2, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6412 else if(from.dimension() == 3)
6413 OperateHelperBinary<3, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6414 else if(from.dimension() == 4)
6415 OperateHelperBinary<4, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6416 else if(from.dimension() == 5)
6417 OperateHelperBinary<5, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6418 else if(from.dimension() == 6)
6419 OperateHelperBinary<6, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6420 else if(from.dimension() == 7)
6421 OperateHelperBinary<7, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6422 else if(from.dimension() == 8)
6423 OperateHelperBinary<8, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6424 else if(from.dimension() == 9)
6425 OperateHelperBinary<9, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6426 else if(from.dimension() == 10)
6427 OperateHelperBinary<10, Assign<TTo, TFrom>, TTo, TFrom,
true, ATo, AFrom>::operate(to, from, Assign<TTo, TFrom>(), &to(0), &from(0));
6429 FromIterator itFrom = from.begin();
6430 ToIterator itTo = to.begin();
6431 for(; itFrom.hasMore(); ++itFrom, ++itTo) {
6432 *itTo =
static_cast<TTo
>(*itFrom);
6440 template<
class TFrom,
class TTo,
class AFrom,
class ATo>
6441 struct AssignmentOperatorHelper<true, TFrom, TTo, AFrom, ATo>
6444 template<
bool isConstFrom>
6447 const View<TFrom, isConstFrom, AFrom>& from,
6448 View<TTo, true, ATo>& to
6451 Assert(MARRAY_NO_ARG_TEST ||
sizeof(TFrom) ==
sizeof(TTo));
6452 to.data_ =
static_cast<const TTo*
>(
6453 static_cast<const void*
>(from.data_));
6454 to.geometry_ = from.geometry_;
6459 struct AccessOperatorHelper<true>
6462 template<
class T,
class U,
bool isConst,
class A>
6463 static typename View<T, isConst, A>::reference
6464 execute(
const View<T, isConst, A>& v,
const U& index)
6467 Assert(MARRAY_NO_DEBUG || v.data_ != 0);
6468 Assert(MARRAY_NO_DEBUG || v.dimension() != 0 || index == 0);
6470 v.indexToOffset(index, offset);
6471 return v.data_[offset];
6476 struct AccessOperatorHelper<false>
6479 template<
class T,
class U,
bool isConst,
class A>
6480 static typename View<T, isConst, A>::reference
6481 execute(
const View<T, isConst, A>& v, U it)
6484 Assert(MARRAY_NO_DEBUG || v.data_ != 0 );
6485 Assert(MARRAY_NO_DEBUG || v.dimension() != 0 || *it == 0);
6487 v.coordinatesToOffset(it, offset);
6488 return v.data_[offset];
6492 template<
class Functor,
class T,
class A>
6496 View<T, false, A>& v,
6502 for(
size_t j=0; j<v.size(); ++j) {
6506 else if(v.dimension() == 1)
6507 OperateHelperUnary<1, Functor, T, A>::operate(v, f, &v(0));
6508 else if(v.dimension() == 2)
6509 OperateHelperUnary<2, Functor, T, A>::operate(v, f, &v(0));
6510 else if(v.dimension() == 3)
6511 OperateHelperUnary<3, Functor, T, A>::operate(v, f, &v(0));
6512 else if(v.dimension() == 4)
6513 OperateHelperUnary<4, Functor, T, A>::operate(v, f, &v(0));
6514 else if(v.dimension() == 5)
6515 OperateHelperUnary<5, Functor, T, A>::operate(v, f, &v(0));
6516 else if(v.dimension() == 6)
6517 OperateHelperUnary<6, Functor, T, A>::operate(v, f, &v(0));
6518 else if(v.dimension() == 7)
6519 OperateHelperUnary<7, Functor, T, A>::operate(v, f, &v(0));
6520 else if(v.dimension() == 8)
6521 OperateHelperUnary<8, Functor, T, A>::operate(v, f, &v(0));
6522 else if(v.dimension() == 9)
6523 OperateHelperUnary<9, Functor, T, A>::operate(v, f, &v(0));
6524 else if(v.dimension() == 10)
6525 OperateHelperUnary<10, Functor, T, A>::operate(v, f, &v(0));
6533 template<
class Functor,
class T,
class A>
6537 View<T, false, A>& v,
6544 for(
size_t j=0; j<v.size(); ++j) {
6548 else if(v.dimension() == 1)
6549 OperateHelperBinaryScalar<1, Functor, T, T, A>::operate(v, x, f, &v(0));
6550 else if(v.dimension() == 2)
6551 OperateHelperBinaryScalar<2, Functor, T, T, A>::operate(v, x, f, &v(0));
6552 else if(v.dimension() == 3)
6553 OperateHelperBinaryScalar<3, Functor, T, T, A>::operate(v, x, f, &v(0));
6554 else if(v.dimension() == 4)
6555 OperateHelperBinaryScalar<4, Functor, T, T, A>::operate(v, x, f, &v(0));
6556 else if(v.dimension() == 5)
6557 OperateHelperBinaryScalar<5, Functor, T, T, A>::operate(v, x, f, &v(0));
6558 else if(v.dimension() == 6)
6559 OperateHelperBinaryScalar<6, Functor, T, T, A>::operate(v, x, f, &v(0));
6560 else if(v.dimension() == 7)
6561 OperateHelperBinaryScalar<7, Functor, T, T, A>::operate(v, x, f, &v(0));
6562 else if(v.dimension() == 8)
6563 OperateHelperBinaryScalar<8, Functor, T, T, A>::operate(v, x, f, &v(0));
6564 else if(v.dimension() == 9)
6565 OperateHelperBinaryScalar<9, Functor, T, T, A>::operate(v, x, f, &v(0));
6566 else if(v.dimension() == 10)
6567 OperateHelperBinaryScalar<10, Functor, T, T, A>::operate(v, x, f, &v(0));
6575 template<
class Functor,
class T1,
class T2,
bool isConst,
class A>
6579 View<T1, false, A>& v,
6580 const View<T2, isConst, A>& w,
6584 if(!MARRAY_NO_ARG_TEST) {
6585 Assert(v.size() != 0 && w.size() != 0);
6586 Assert(w.dimension() == 0 || v.dimension() == w.dimension());
6587 if(w.dimension() != 0) {
6588 for(
size_t j=0; j<v.dimension(); ++j) {
6589 Assert(v.shape(j) == w.shape(j));
6593 if(w.dimension() == 0) {
6597 for(
size_t j=0; j<v.size(); ++j) {
6601 else if(v.dimension() == 1)
6602 OperateHelperBinaryScalar<1, Functor, T1, T2, A>::operate(v, x, f, &v(0));
6603 else if(v.dimension() == 2)
6604 OperateHelperBinaryScalar<2, Functor, T1, T2, A>::operate(v, x, f, &v(0));
6605 else if(v.dimension() == 3)
6606 OperateHelperBinaryScalar<3, Functor, T1, T2, A>::operate(v, x, f, &v(0));
6607 else if(v.dimension() == 4)
6608 OperateHelperBinaryScalar<4, Functor, T1, T2, A>::operate(v, x, f, &v(0));
6609 else if(v.dimension() == 5)
6610 OperateHelperBinaryScalar<5, Functor, T1, T2, A>::operate(v, x, f, &v(0));
6611 else if(v.dimension() == 6)
6612 OperateHelperBinaryScalar<6, Functor, T1, T2, A>::operate(v, x, f, &v(0));
6613 else if(v.dimension() == 7)
6614 OperateHelperBinaryScalar<7, Functor, T1, T2, A>::operate(v, x, f, &v(0));
6615 else if(v.dimension() == 8)
6616 OperateHelperBinaryScalar<8, Functor, T1, T2, A>::operate(v, x, f, &v(0));
6617 else if(v.dimension() == 9)
6618 OperateHelperBinaryScalar<9, Functor, T1, T2, A>::operate(v, x, f, &v(0));
6619 else if(v.dimension() == 10)
6620 OperateHelperBinaryScalar<10, Functor, T1, T2, A>::operate(v, x, f, &v(0));
6622 for(
typename View<T1, false>::iterator it = v.begin(); it.hasMore(); ++it) {
6633 if(v.coordinateOrder() == w.coordinateOrder()
6634 && v.isSimple() && w.isSimple()) {
6636 const T2* dataW = &w(0);
6637 for(
size_t j=0; j<v.size(); ++j) {
6638 f(dataV[j], dataW[j]);
6641 else if(v.dimension() == 1)
6642 OperateHelperBinary<1, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
6643 else if(v.dimension() == 2)
6644 OperateHelperBinary<2, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
6645 else if(v.dimension() == 3)
6646 OperateHelperBinary<3, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
6647 else if(v.dimension() == 4)
6648 OperateHelperBinary<4, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
6649 else if(v.dimension() == 5)
6650 OperateHelperBinary<5, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
6651 else if(v.dimension() == 6)
6652 OperateHelperBinary<6, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
6653 else if(v.dimension() == 7)
6654 OperateHelperBinary<7, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
6655 else if(v.dimension() == 8)
6656 OperateHelperBinary<8, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
6657 else if(v.dimension() == 9)
6658 OperateHelperBinary<9, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
6659 else if(v.dimension() == 10)
6660 OperateHelperBinary<10, Functor, T1, T2, isConst, A, A>::operate(v, w, f, &v(0), &w(0));
6662 typename View<T1, false>::iterator itV = v.begin();
6663 typename View<T2, isConst>::const_iterator itW = w.begin();
6664 for(; itV.hasMore(); ++itV, ++itW) {
6665 Assert(MARRAY_NO_DEBUG || itW.hasMore());
6668 Assert(MARRAY_NO_DEBUG || !itW.hasMore());
6674 template<
class Functor,
class T1,
class A,
class E,
class T2>
6677 View<T1, false, A>& v,
6678 const ViewExpression<E, T2>& expression,
6682 const E& e = expression;
6683 if(!MARRAY_NO_DEBUG) {
6684 Assert(v.size() != 0 && e.size() != 0);
6685 Assert(e.dimension() == v.dimension());
6686 if(v.dimension() == 0) {
6687 Assert(v.size() == 1 && e.size() == 1);
6690 for(
size_t j=0; j<v.dimension(); ++j) {
6691 Assert(v.shape(j) == e.shape(j));
6699 else if(v.dimension() == 0) {
6702 else if(v.isSimple() && e.isSimple()
6703 && v.coordinateOrder() == e.coordinateOrder()) {
6704 for(
size_t j=0; j<v.size(); ++j) {
6710 typename E::ExpressionIterator itE(e);
6712 std::vector<size_t> coordinate(v.dimension());
6713 size_t maxDimension = v.dimension() - 1;
6715 f(v[offsetV], *itE);
6716 for(
size_t j=0; j<v.dimension(); ++j) {
6717 if(coordinate[j]+1 == v.shape(j)) {
6718 if(j == maxDimension) {
6722 offsetV -= coordinate[j] * v.strides(j);
6723 itE.resetCoordinate(j);
6728 offsetV += v.strides(j);
6729 itE.incrementCoordinate(j);
6743 #endif // #ifndef MARRAY_HXX
View< T, isConst, A > & operator=(const T &)
Assignment.
void assign(const allocator_type &=allocator_type())
Clear Marray.
View< T, isConst, A > squeezedView() const
Get a View where all singleton dimensions have been removed by setting their coordinates to zero...
const size_t * stridesBegin() const
Get a constant iterator to the beginning of the strides vector.
base::const_pointer const_pointer
static const bool Const
Flag to be used with the template parameter isConst of View and Iterator.
const T & const_reference
base::const_reverse_iterator const_reverse_iterator
const T & operator()(const size_t c0, const size_t c1, const size_t c2) const
STL-compliant random access iterator for View and Marray.
static const CoordinateOrder defaultOrder
Default order of coordinate tuples.
A::template rebind< value_type >::other allocator_type
Marray(const allocator_type &=allocator_type())
Empty constructor.
Runtime-flexible multi-dimensional views and arrays.
base::reverse_iterator reverse_iterator
void view(BaseIterator, ShapeIterator, View< T, isConst, A > &) const
Get a sub-view with the same coordinate order.
const size_t * shapeEnd() const
Iterator< T, isConst, A > iterator
Iterator< T, true, A > const_iterator
void permute(CoordinateIterator)
Permute dimensions.
base::value_type value_type
iterator end()
Get the end-iterator.
Flag to indicate initialization skipping.
const size_t shape(const size_t) const
Get the shape in one dimension.
Marray< T, A > & operator=(const T &)
Assignment.
const T & operator()(Accessor it) const
void reshape(const size_t)
Reshape.
marray_detail::IfBool< isConst, const T &, T & >::type reference
void indexToCoordinates(size_t, CoordinateIterator) const
Compute the coordinate sequence that corresponds to an index.
reverse_iterator rbegin()
Get a reserve iterator to the beginning.
Iterator< T, isConst, A > & operator-=(const difference_type &)
Iterator< T, isConst, A > operator+(const difference_type &) const
base::reverse_iterator reverse_iterator
View< T, isConst, A > shiftedView(const int) const
Get a View which dimensions cycle shifted.
Array-Interface to an interval of memory.
const bool isSimple() const
void coordinatesToIndex(CoordinateIterator, size_t &) const
Compute the index that corresponds to a sequence of coordinates.
void resize(const size_t, const size_t, const T &=T())
Resize (existing entries are preserved, new entries are initialized).
std::random_access_iterator_tag iterator_category
Matrix< T, A > & operator=(const T &)
Assignment.
base::const_pointer const_pointer
base::const_iterator const_iterator
Matrix(const allocator_type &=allocator_type())
Empty constructor.
const size_t * shapeBegin() const
const bool MARRAY_NO_DEBUG
General assertion testing enabled.
void indexToOffset(size_t, size_t &) const
Compute the offset that corresponds to an index.
void reshape(const size_t, const size_t)
Reshape.
#define MARRAY_BINARY_OPERATOR_ALL_TYPES(op, functorname)
base::reference reference
iterator begin()
Get an iterator to the beginning.
base::value_type value_type
#define MARRAY_UNARY_OPERATOR_ALL_TYPES(op, functorname)
bool overlaps(const View< TLocal, isConstLocal, ALocal > &) const
Check whether two Views overlap.
const CoordinateOrder & coordinateOrder() const
base::allocator_type allocator_type
bool operator>(const Iterator< T, isConstLocal, A > &) const
void coordinatesToOffset(CoordinateIterator, size_t &) const
Compute the offset that corresponds to a sequence of coordinates.
size_t index() const
Get the corresponding index in the View.
Iterator< T, isConst, A > & operator--()
Prefix decrement.
base::const_reverse_iterator const_reverse_iterator
const BinaryViewExpression< E1, T1, E2, T2, marray_detail::Times< T1, T2, typename marray_detail::PromoteType< T1, T2 >::type > > operator*(const ViewExpression< E1, T1 > &expression1, const ViewExpression< E2, T2 > &expression2)
std::string asString(const StringStyle &=MatrixStyle) const
Output as string.
std::ptrdiff_t difference_type
void constView(BaseIterator, ShapeIterator, View< T, true, A > &) const
Get a sub-view to constant data with the same coordinate order.
const size_t dimension() const
Get the dimension.
A::template rebind< value_type >::other allocator_type
marray_detail::IfBool< isConst, const T *, T * >::type pointer
const bool MARRAY_NO_ARG_TEST
Argument testing enabled.
void reshape(ShapeIterator, ShapeIterator)
Reshape the View.
View< T, isConst, A > boundView(const size_t, const size_t=0) const
Get a View where one coordinate is bound to a value.
const T & operator()(const size_t c0, const size_t c1, const size_t c2, const size_t c3, const size_t c4) const
ViewExpression< View< T, isConst, A >, T > base
base::const_iterator const_iterator
bool operator!=(const Iterator< T, isConstLocal, A > &) const
Vector(const allocator_type &=allocator_type())
Empty constructor.
marray_detail::IfBool< isConst, const View< T, true, A > *, View< T, false, A > * >::type view_pointer
const size_t strides(const size_t) const
Get the strides in one dimension.
View< T, isConst, A > permutedView(CoordinateIterator) const
Get a View with permuted dimensions.
void coordinate(CoordinateIterator) const
Get the corresponding coordinate sequence in the View.
base::const_reverse_iterator const_reverse_iterator
const size_t size() const
Get the number of data items.
marray_detail::IfBool< isConst, const T &, T & >::type reference
bool hasMore() const
Fast alternative to comparing with the end iterator.
void shift(const int)
Cycle shift dimensions.
const T & operator()(const size_t c0, const size_t c1) const
reference operator*() const
De-reference.
base::reference reference
void transpose()
Reverse dimensions.
const size_t shape(const size_t j) const
base::const_reference const_reference
const size_t dimension() const
std::reverse_iterator< const_iterator > const_reverse_iterator
bool overlaps(const View< Tv, isConst, A > &v) const
marray_detail::IfBool< isConst, const T *, T * >::type pointer
base::allocator_type allocator_type
marray_detail::IfBool< isConst, const View< T, true, A > &, View< T, false, A > & >::type view_reference
void squeeze()
Remove singleton dimensions by setting their coordinates to zero.
std::reverse_iterator< iterator > reverse_iterator
void resize(const size_t, const T &=T())
Resize (existing entries are preserved, new entries are initialized).
base::reference reference
Runtime-flexible multi-dimensional array.
pointer operator->() const
Pointer.
base::value_type value_type
const size_t * stridesEnd() const
Get a constant iterator to the end of the strides vector.
const size_t size() const
const T & operator[](const size_t offset) const
const bool isSimple() const
Determine whether the shape strides equal the strides of the View.
base::const_iterator const_iterator
View< T, isConst, A > transposedView() const
Get a View with dimensions reversed.
Vector< T, A > & operator=(const T &)
Assignment.
static const bool Mutable
Flag to be used with the template parameter isConst of View and Iterator.
reverse_iterator rend()
Get the reverse end-iterator.
base::const_pointer const_pointer
base::reverse_iterator reverse_iterator
Iterator< T, isConst, A > & operator+=(const difference_type &)
Iterator< T, isConst, A > operator-(const difference_type &) const
Iterator< T, isConst, A > & operator++()
Prefix increment.
static const InitializationSkipping SkipInitialization
Flag to indicate initialization skipping.
reference operator()(U)
Reference data.
const size_t * shapeEnd() const
Get a constant iterator to the end of the shape vector.
base::const_reference const_reference
View< T, isConst, A > reshapedView(ShapeIterator, ShapeIterator) const
Get a reshaped View.
const size_t * shapeBegin() const
Get a constant iterator to the beginning of the shape vector.
const CoordinateOrder & coordinateOrder() const
Get the coordinate order used for scalar indexing and iterators.
T & operator[](const size_t)
Element access.
void resize(ShapeIterator, ShapeIterator, const T &=T())
Resize (existing entries are preserved, new entries are initialized).
reference operator[](const size_t) const
Element access.
Iterator()
Empty constructor.
bool operator==(const Iterator< T, isConstLocal, A > &) const
bool operator>=(const Iterator< T, isConstLocal, A > &) const
base::const_reference const_reference
const T & operator()(const size_t c0, const size_t c1, const size_t c2, const size_t c3) const
void assign(const allocator_type &=allocator_type())
Clear View.