37 #ifndef VIGRA_MULTI_ARRAY_HXX
38 #define VIGRA_MULTI_ARRAY_HXX
42 #include "accessor.hxx"
43 #include "tinyvector.hxx"
44 #include "rgbvalue.hxx"
45 #include "basicimageview.hxx"
46 #include "imageiterator.hxx"
47 #include "numerictraits.hxx"
48 #include "multi_iterator.hxx"
49 #include "metaprogramming.hxx"
50 #include "mathutil.hxx"
53 #ifdef VIGRA_CHECK_BOUNDS
54 #define VIGRA_ASSERT_INSIDE(diff) \
55 vigra_precondition(this->isInside(diff), "Index out of bounds")
57 #define VIGRA_ASSERT_INSIDE(diff)
75 template <
unsigned int N>
76 inline TinyVector <MultiArrayIndex, N>
77 defaultStride(
const TinyVector <MultiArrayIndex, N> &shape)
79 TinyVector <MultiArrayIndex, N> ret;
81 for (
int i = 1; i < (int)N; ++i)
82 ret [i] = ret [i-1] * shape [i-1];
99 struct ScanOrderToOffset
104 const TinyVector <MultiArrayIndex, N> & stride)
106 return stride[N-K] * (d % shape[N-K]) +
107 ScanOrderToOffset<K-1>::exec(d / shape[N-K], shape, stride);
112 struct ScanOrderToOffset<1>
117 const TinyVector <MultiArrayIndex, N> & stride)
119 return stride[N-1] * d;
124 struct ScanOrderToCoordinate
129 TinyVector <MultiArrayIndex, N> & result)
131 result[N-K] = (d % shape[N-K]);
132 ScanOrderToCoordinate<K-1>::exec(d / shape[N-K], shape, result);
137 struct ScanOrderToCoordinate<1>
142 TinyVector <MultiArrayIndex, N> & result)
149 struct CoordinateToScanOrder
153 exec(
const TinyVector <MultiArrayIndex, N> &shape,
154 const TinyVector <MultiArrayIndex, N> & coordinate)
156 return coordinate[N-K] + shape[N-K] * CoordinateToScanOrder<K-1>::exec(shape, coordinate);
161 struct CoordinateToScanOrder<1>
165 exec(
const TinyVector <MultiArrayIndex, N> & ,
166 const TinyVector <MultiArrayIndex, N> & coordinate)
168 return coordinate[N-1];
174 struct CoordinatesToOffest
178 exec(
const TinyVector <MultiArrayIndex, N> & stride,
MultiArrayIndex x)
180 return stride[0] * x;
186 return stride[0] * x + stride[1] * y;
191 struct CoordinatesToOffest<UnstridedArrayTag>
203 return x + stride[1] * y;
222 template <
unsigned int N>
225 typedef UnstridedArrayTag type;
229 struct MaybeStrided <0>
231 typedef StridedArrayTag type;
249 struct MultiIteratorChooser
253 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
274 struct MultiIteratorChooser <StridedArrayTag>
276 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
279 typedef StridedMultiIterator <N, T, REFERENCE, POINTER> type;
297 struct MultiIteratorChooser <UnstridedArrayTag>
299 template <
unsigned int N,
class T,
class REFERENCE,
class POINTER>
302 typedef MultiIterator <N, T, REFERENCE, POINTER> type;
312 template <
class DestIterator,
class Shape,
class T>
314 initMultiArrayData(DestIterator d, Shape
const & shape, T
const & init, MetaInt<0>)
316 DestIterator dend = d + shape[0];
323 template <
class DestIterator,
class Shape,
class T,
int N>
325 initMultiArrayData(DestIterator d, Shape
const & shape, T
const & init, MetaInt<N>)
327 DestIterator dend = d + shape[N];
330 initMultiArrayData(d.begin(), shape, init, MetaInt<N-1>());
334 #define VIGRA_COPY_MULTI_ARRAY_DATA(name, op) \
335 template <class SrcIterator, class Shape, class DestIterator> \
337 name##MultiArrayData(SrcIterator s, Shape const & shape, DestIterator d, MetaInt<0>) \
339 SrcIterator send = s + shape[0]; \
340 for(; s < send; ++s, ++d) \
342 *d op detail::RequiresExplicitCast<typename DestIterator::value_type>::cast(*s); \
346 template <class SrcIterator, class Shape, class DestIterator, int N> \
348 name##MultiArrayData(SrcIterator s, Shape const & shape, DestIterator d, MetaInt<N>) \
350 SrcIterator send = s + shape[N]; \
351 for(; s < send; ++s, ++d) \
353 name##MultiArrayData(s.begin(), shape, d.begin(), MetaInt<N-1>()); \
357 template <class DestIterator, class Shape, class T> \
359 name##ScalarMultiArrayData(DestIterator d, Shape const & shape, T const & init, MetaInt<0>) \
361 DestIterator dend = d + shape[0]; \
362 for(; d < dend; ++d) \
364 *d op detail::RequiresExplicitCast<typename DestIterator::value_type>::cast(init); \
368 template <class DestIterator, class Shape, class T, int N> \
370 name##ScalarMultiArrayData(DestIterator d, Shape const & shape, T const & init, MetaInt<N>) \
372 DestIterator dend = d + shape[N]; \
373 for(; d < dend; ++d) \
375 name##ScalarMultiArrayData(d.begin(), shape, init, MetaInt<N-1>()); \
379 VIGRA_COPY_MULTI_ARRAY_DATA(copy, =)
380 VIGRA_COPY_MULTI_ARRAY_DATA(copyAdd, +=)
381 VIGRA_COPY_MULTI_ARRAY_DATA(copySub, -=)
382 VIGRA_COPY_MULTI_ARRAY_DATA(copyMul, *=)
383 VIGRA_COPY_MULTI_ARRAY_DATA(copyDiv, /=)
385 #undef VIGRA_COPY_MULTI_ARRAY_DATA
387 template <
class SrcIterator,
class Shape,
class T,
class ALLOC>
389 uninitializedCopyMultiArrayData(SrcIterator s, Shape
const & shape, T * & d, ALLOC & a, MetaInt<0>)
391 SrcIterator send = s + shape[0];
392 for(; s < send; ++s, ++d)
394 a.construct(d, static_cast<T const &>(*s));
398 template <
class SrcIterator,
class Shape,
class T,
class ALLOC,
int N>
400 uninitializedCopyMultiArrayData(SrcIterator s, Shape
const & shape, T * & d, ALLOC & a, MetaInt<N>)
402 SrcIterator send = s + shape[N];
405 uninitializedCopyMultiArrayData(s.begin(), shape, d, a, MetaInt<N-1>());
409 template <
class SrcIterator,
class Shape,
class T>
411 normMaxOfMultiArray(SrcIterator s, Shape
const & shape, T & result, MetaInt<0>)
413 SrcIterator send = s + shape[0];
422 template <
class SrcIterator,
class Shape,
class T,
int N>
424 normMaxOfMultiArray(SrcIterator s, Shape
const & shape, T & result, MetaInt<N>)
426 SrcIterator send = s + shape[N];
429 normMaxOfMultiArray(s.begin(), shape, result, MetaInt<N-1>());
434 struct MultiArrayL1Functor
437 T operator()(U t)
const
442 struct MultiArrayL2Functor
445 T operator()(U t)
const
450 struct MultiArrayScaledL2Functor
454 MultiArrayScaledL2Functor(T s)
459 T operator()(U t)
const
463 template <
class SrcIterator,
class Shape,
class Functor,
class T>
465 sumOverMultiArray(SrcIterator s, Shape
const & shape, Functor f, T & result, MetaInt<0>)
467 SrcIterator send = s + shape[0];
474 template <
class SrcIterator,
class Shape,
class Functor,
class T,
int N>
476 sumOverMultiArray(SrcIterator s, Shape
const & shape, Functor f, T & result, MetaInt<N>)
478 SrcIterator send = s + shape[N];
481 sumOverMultiArray(s.begin(), shape, f, result, MetaInt<N-1>());
485 template <
class SrcIterator,
class Shape,
class DestIterator>
487 equalityOfMultiArrays(SrcIterator s, Shape
const & shape, DestIterator d, MetaInt<0>)
489 SrcIterator send = s + shape[0];
490 for(; s < send; ++s, ++d)
498 template <
class SrcIterator,
class Shape,
class DestIterator,
int N>
500 equalityOfMultiArrays(SrcIterator s, Shape
const & shape, DestIterator d, MetaInt<N>)
502 SrcIterator send = s + shape[N];
503 for(; s < send; ++s, ++d)
505 if(!equalityOfMultiArrays(s.begin(), shape, d.begin(), MetaInt<N-1>()))
512 template <
class SrcIterator,
class Shape,
class DestIterator>
514 swapDataImpl(SrcIterator s, Shape
const & shape, DestIterator d, MetaInt<0>)
516 SrcIterator send = s + shape[0];
517 for(; s < send; ++s, ++d)
521 template <
class SrcIterator,
class Shape,
class DestIterator,
int N>
523 swapDataImpl(SrcIterator s, Shape
const & shape, DestIterator d, MetaInt<N>)
525 SrcIterator send = s + shape[N];
526 for(; s < send; ++s, ++d)
527 swapDataImpl(s.begin(), shape, d.begin(), MetaInt<N-1>());
539 template <
unsigned int N,
class T,
class C = Unstr
idedArrayTag>
540 class MultiArrayView;
541 template <
unsigned int N,
class T,
class A = std::allocator<T> >
550 template <
unsigned int N,
class T,
class C>
551 struct NormTraits<MultiArrayView<N, T, C> >
553 typedef MultiArrayView<N, T, C> Type;
554 typedef typename NormTraits<T>::SquaredNormType SquaredNormType;
555 typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult NormType;
558 template <
unsigned int N,
class T,
class A>
559 struct NormTraits<MultiArray<N, T, A> >
560 :
public NormTraits<MultiArrayView<N, T, UnstridedArrayTag> >
562 typedef NormTraits<MultiArrayView<N, T, UnstridedArrayTag> > BaseType;
563 typedef MultiArray<N, T, A> Type;
564 typedef typename BaseType::SquaredNormType SquaredNormType;
565 typedef typename BaseType::NormType NormType;
599 template <
unsigned int N,
class T,
class C>
647 typedef typename vigra::detail::MultiIteratorChooser <
648 C>::template Traverser <actual_dimension, T, T &, T *>::type
traverser;
652 typedef typename vigra::detail::MultiIteratorChooser <
653 C>::template Traverser <actual_dimension, T, T const &, T const *>::type
const_traverser;
665 typedef typename difference_type::value_type diff_zero_t;
680 template <
class U,
class CN>
683 template <
class U,
class CN>
689 template <
class U,
class CN>
701 : m_shape (diff_zero_t(0)), m_stride (diff_zero_t(0)), m_ptr (0)
708 m_stride (detail::defaultStride <
MultiArrayView<N,T>::actual_dimension> (shape)),
718 const difference_type &
stride,
740 template<
class U,
class C1>
743 vigra_precondition(this->
shape() == rhs.
shape(),
744 "MultiArrayView::operator=() size mismatch.");
752 template<
class U,
class C1>
758 template<
class U,
class C1>
764 template<
class U,
class C1>
770 template<
class U,
class C1>
777 detail::copyAddScalarMultiArrayData(
traverser_begin(),
shape(), rhs, MetaInt<actual_dimension-1>());
785 detail::copySubScalarMultiArrayData(
traverser_begin(),
shape(), rhs, MetaInt<actual_dimension-1>());
793 detail::copyMulScalarMultiArrayData(
traverser_begin(),
shape(), rhs, MetaInt<actual_dimension-1>());
801 detail::copyDivScalarMultiArrayData(
traverser_begin(),
shape(), rhs, MetaInt<actual_dimension-1>());
809 VIGRA_ASSERT_INSIDE(d);
810 return m_ptr [
dot (d, m_stride)];
817 VIGRA_ASSERT_INSIDE(d);
818 return m_ptr [
dot (d, m_stride)];
823 template <
unsigned int M>
842 return m_ptr [detail::ScanOrderToOffset<actual_dimension>::exec(d, m_shape, m_stride)];
858 return m_ptr [detail::ScanOrderToOffset<actual_dimension>::exec(d, m_shape, m_stride)];
865 difference_type result;
866 detail::ScanOrderToCoordinate<actual_dimension>::exec(d, m_shape, result);
874 return detail::CoordinateToScanOrder<actual_dimension>::exec(m_shape, d);
882 return m_ptr [detail::CoordinatesToOffest<C>::exec(m_stride, x)];
887 reference
operator() (difference_type_1 x, difference_type_1 y)
890 return m_ptr [detail::CoordinatesToOffest<C>::exec(m_stride, x, y)];
895 reference
operator() (difference_type_1 x, difference_type_1 y, difference_type_1 z)
898 return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z];
903 reference
operator() (difference_type_1 x, difference_type_1 y,
904 difference_type_1 z, difference_type_1 u)
907 return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_stride[3]*u];
912 reference
operator() (difference_type_1 x, difference_type_1 y, difference_type_1 z,
913 difference_type_1 u, difference_type_1 v)
916 return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_stride[3]*u + m_stride[4]*v];
924 return m_ptr [detail::CoordinatesToOffest<C>::exec(m_stride, x)];
929 const_reference
operator() (difference_type_1 x, difference_type_1 y)
const
932 return m_ptr [detail::CoordinatesToOffest<C>::exec(m_stride, x, y)];
937 const_reference
operator() (difference_type_1 x, difference_type_1 y, difference_type_1 z)
const
940 return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z];
945 const_reference
operator() (difference_type_1 x, difference_type_1 y,
946 difference_type_1 z, difference_type_1 u)
const
949 return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_stride[3]*u];
954 const_reference
operator() (difference_type_1 x, difference_type_1 y, difference_type_1 z,
955 difference_type_1 u, difference_type_1 v)
const
958 return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_stride[3]*u + m_stride[4]*v];
966 detail::copyScalarMultiArrayData(
traverser_begin(),
shape(), init, MetaInt<actual_dimension-1>());
982 template <
class U,
class CN>
1002 template <
class T2,
class C2>
1022 template <
unsigned int M>
1039 template <
unsigned int M>
1060 template <
unsigned int M>
1062 bind (difference_type_1 d)
const;
1111 bindAt (difference_type_1 m, difference_type_1 d)
const;
1159 const difference_type &q)
const
1161 const difference_type_1 offset =
dot (m_stride, p);
1174 difference_type shape =
m_shape;
1175 for (
unsigned int i = 0; i < actual_dimension; ++i)
1198 difference_type
shape(m_shape.begin(), difference_type::ReverseCopy),
1199 stride(m_stride.begin(), difference_type::ReverseCopy);
1254 difference_type_1 ret = m_shape[0];
1255 for(
int i = 1; i < actual_dimension; ++i)
1277 difference_type_1
size (difference_type_1 n)
const
1285 difference_type_1
shape (difference_type_1 n)
const
1301 return m_stride [n];
1306 template <
class U,
class C1>
1317 template <
class U,
class C1>
1327 for(
int d=0; d<actual_dimension; ++d)
1328 if(p[d] < 0 || p[d] >=
shape(d))
1335 typename NormTraits<MultiArrayView>::SquaredNormType
squaredNorm()
const
1337 typedef typename NormTraits<MultiArrayView>::SquaredNormType SquaredNormType;
1338 SquaredNormType res = NumericTraits<SquaredNormType>::zero();
1339 detail::sumOverMultiArray(
traverser_begin(),
shape(), detail::MultiArrayL2Functor<SquaredNormType>(),
1340 res, MetaInt<actual_dimension-1>());
1357 typename NormTraits<MultiArrayView>::NormType
norm(
int type = 2,
bool useSquaredNorm =
true)
const;
1381 traverser ret (m_ptr, m_stride.begin (), m_shape.begin ());
1390 const_traverser ret (m_ptr, m_stride.begin (), m_shape.begin ());
1400 traverser ret (m_ptr, m_stride.begin (), m_shape.begin ());
1401 ret += m_shape [actual_dimension-1];
1411 const_traverser ret (m_ptr, m_stride.begin (), m_shape.begin ());
1412 ret += m_shape [actual_dimension-1];
1422 template <
unsigned int N,
class T,
class C>
1423 MultiArrayView<N, T, C> &
1424 MultiArrayView <N, T, C>::operator=(MultiArrayView<N, T, C>
const & rhs)
1428 vigra_precondition(this->
shape() == rhs.shape() ||
m_ptr == 0,
1429 "MultiArrayView::operator=(MultiArrayView const &) size mismatch - use MultiArrayView::reset().");
1437 this->copyImpl(rhs);
1441 template <
unsigned int N,
class T,
class C>
1444 MultiArrayView <N, T, C>::arraysOverlap(
const MultiArrayView <N, T, CN>& rhs)
const
1446 vigra_precondition (shape () == rhs.shape (),
1447 "MultiArrayView::arraysOverlap(): shape mismatch.");
1450 typename MultiArrayView <N, T, CN>::const_pointer
1451 rhs_first_element = rhs.data(),
1452 rhs_last_element = rhs_first_element +
dot(rhs.shape() -
difference_type(1), rhs.stride());
1453 return !(last_element < rhs_first_element || rhs_last_element < first_element);
1456 template <
unsigned int N,
class T,
class C>
1457 template <
class U,
class CN>
1459 MultiArrayView <N, T, C>::copyImpl(
const MultiArrayView <N, U, CN>& rhs)
1461 if(!arraysOverlap(rhs))
1464 detail::copyMultiArrayData(rhs.traverser_begin(),
shape(),
traverser_begin(), MetaInt<actual_dimension-1>());
1470 MultiArray<N, T> tmp(rhs);
1471 detail::copyMultiArrayData(tmp.traverser_begin(),
shape(),
traverser_begin(), MetaInt<actual_dimension-1>());
1475 #define VIGRA_MULTI_ARRY_COMPUTED_ASSIGNMENT(name, op) \
1476 template <unsigned int N, class T, class C> \
1477 template<class U, class C1> \
1478 MultiArrayView<N, T, C> & \
1479 MultiArrayView <N, T, C>::operator op(MultiArrayView<N, U, C1> const & rhs) \
1481 vigra_precondition(this->shape() == rhs.shape(), "MultiArrayView::operator" #op "() size mismatch."); \
1482 if(!arraysOverlap(rhs)) \
1484 detail::name##MultiArrayData(rhs.traverser_begin(), shape(), traverser_begin(), MetaInt<actual_dimension-1>()); \
1488 MultiArray<N, T> tmp(rhs); \
1489 detail::name##MultiArrayData(tmp.traverser_begin(), shape(), traverser_begin(), MetaInt<actual_dimension-1>()); \
1494 VIGRA_MULTI_ARRY_COMPUTED_ASSIGNMENT(copyAdd, +=)
1495 VIGRA_MULTI_ARRY_COMPUTED_ASSIGNMENT(copySub, -=)
1496 VIGRA_MULTI_ARRY_COMPUTED_ASSIGNMENT(copyMul, *=)
1497 VIGRA_MULTI_ARRY_COMPUTED_ASSIGNMENT(copyDiv, /=)
1499 #undef VIGRA_MULTI_ARRY_COMPUTED_ASSIGNMENT
1501 template <
unsigned int N,
class T,
class C>
1502 template <
class U,
class CN>
1504 MultiArrayView <N, T, C>::swapDataImpl(MultiArrayView <N, U, CN> rhs)
1506 vigra_precondition (shape () == rhs.shape (),
1507 "MultiArrayView::swapData(): shape mismatch.");
1512 typename MultiArrayView <N, U, CN>::const_pointer
1513 rhs_first_element = rhs.data(),
1514 rhs_last_element = rhs_first_element +
dot(rhs.shape() -
difference_type(1), rhs.stride());
1515 if(last_element < rhs_first_element || rhs_last_element < first_element)
1518 detail::swapDataImpl(
traverser_begin(),
shape(), rhs.traverser_begin(), MetaInt<actual_dimension-1>());
1524 MultiArray<N, T> tmp(*
this);
1530 template <
unsigned int N,
class T,
class C>
1531 MultiArrayView <N, T, StridedArrayTag>
1535 for (
unsigned int i = 0; i < actual_dimension; ++i)
1542 "MultiArrayView::permuteDimensions(): every dimension must occur exactly once.");
1546 template <
unsigned int N,
class T,
class C>
1551 for(
unsigned int k=0; k<N; ++k)
1553 for(
unsigned int k=0; k<N-1; ++k)
1555 unsigned int smallest = k;
1556 for(
unsigned int j=k+1; j<N; ++j)
1564 std::swap(permutation[k], permutation[smallest]);
1568 for(
unsigned int k=0; k<N; ++k)
1569 ordering[permutation[k]] = k;
1573 template <
unsigned int N,
class T,
class C>
1579 permutation[ordering[k]] = k;
1583 template <
unsigned int N,
class T,
class C>
1589 permutation[ordering[N-1-k]] = k;
1593 template <
unsigned int N,
class T,
class C>
1594 template <
unsigned int M>
1601 static const int NNew = (N-M == 0) ? 1 : N-M;
1605 inner_shape [0] = 1;
1606 inner_stride [0] = 0;
1613 return MultiArrayView <N-M, T, C> (inner_shape, inner_stride, ptr);
1616 template <
unsigned int N,
class T,
class C>
1617 template <
unsigned int M>
1624 static const int NNew = (N-M == 0) ? 1 : N-M;
1628 outer_shape [0] = 1;
1629 outer_stride [0] = 0;
1637 (outer_shape, outer_stride, ptr);
1640 template <
unsigned int N,
class T,
class C>
1641 template <
unsigned int M>
1645 static const int NNew = (N-1 == 0) ? 1 : N-1;
1657 shape.
begin () + M);
1660 stride.
begin () + M);
1666 template <
unsigned int N,
class T,
class C>
1670 static const int NNew = (N-1 == 0) ? 1 : N-1;
1674 inner_shape [0] = 1;
1675 inner_stride [0] = 0;
1686 template <
unsigned int N,
class T,
class C>
1690 static const int NNew = (N-1 == 0) ? 1 : N-1;
1694 outer_shape [0] = 1;
1695 outer_stride [0] = 0;
1706 template <
unsigned int N,
class T,
class C>
1710 vigra_precondition (
1711 n < static_cast <int> (N),
1712 "MultiArrayView <N, T, C>::bindAt(): dimension out of range.");
1713 static const int NNew = (N-1 == 0) ? 1 : N-1;
1725 shape.
begin () + n);
1728 stride.
begin () + n);
1734 template <
unsigned int N,
class T,
class C>
1738 vigra_precondition (
1739 0 <= i && i <= static_cast <difference_type_1> (N),
1740 "MultiArrayView <N, T, C>::insertSingletonDimension(): index out of range.");
1752 template <
unsigned int N,
class T,
class C>
1753 typename NormTraits<MultiArrayView <N, T, C> >::NormType
1756 typedef typename NormTraits<MultiArrayView>::NormType NormType;
1762 NormType res = NumericTraits<NormType>::zero();
1768 NormType res = NumericTraits<NormType>::zero();
1770 res, MetaInt<actual_dimension-1>());
1781 NormType normMax = NumericTraits<NormType>::zero();
1782 detail::normMaxOfMultiArray(
traverser_begin(),
shape(), normMax, MetaInt<actual_dimension-1>());
1783 if(normMax == NumericTraits<NormType>::zero())
1785 NormType res = NumericTraits<NormType>::zero();
1786 detail::sumOverMultiArray(
traverser_begin(),
shape(), detail::MultiArrayScaledL2Functor<NormType>(normMax),
1787 res, MetaInt<actual_dimension-1>());
1788 return sqrt(res)*normMax;
1792 vigra_precondition(
false,
"MultiArrayView::norm(): Unknown norm type.");
1793 return NumericTraits<NormType>::zero();
1804 template <
unsigned int N,
class T,
class C>
1805 inline typename NormTraits<MultiArrayView <N, T, C> >::SquaredNormType
1811 template <
unsigned int N,
class T,
class C>
1812 inline typename NormTraits<MultiArrayView <N, T, C> >::NormType
1813 norm(MultiArrayView <N, T, C>
const & a)
1847 template <
unsigned int N,
class T,
class A >
1900 typedef typename vigra::detail::MultiIteratorChooser <
1906 typedef typename vigra::detail::MultiIteratorChooser <
1920 typedef typename difference_type::value_type diff_zero_t;
1940 template <
class U,
class C>
1947 template <
class U,
class C>
1968 allocator_type
const & alloc = allocator_type());
1973 allocator_type
const & alloc = allocator_type());
1978 allocator_type
const & alloc = allocator_type());
1984 m_alloc (rhs.m_alloc)
1991 template <
class U,
class C>
1993 allocator_type
const & alloc = allocator_type());
2003 this->copyOrReshape(rhs);
2012 template <
class U,
class C>
2015 this->copyOrReshape(rhs);
2022 template <
class U,
class C>
2032 template <
class U,
class C>
2042 template <
class U,
class C>
2052 template <
class U,
class C>
2114 reshape (shape, NumericTraits <T>::zero ());
2135 return this->
data();
2149 return this->
data();
2167 template <
unsigned int N,
class T,
class A>
2183 template <
unsigned int N,
class T,
class A>
2199 template <
unsigned int N,
class T,
class A>
2215 template <
unsigned int N,
class T,
class A>
2216 template <
class U,
class C>
2220 detail::defaultStride <MultiArrayView<N,T>::actual_dimension>(rhs.shape()),
2224 allocate (this->
m_ptr, rhs);
2227 template <
unsigned int N,
class T,
class A>
2228 template <
class U,
class C>
2232 if (this->
shape() == rhs.shape())
2241 template <
unsigned int N,
class T,
class A>
2249 else if(new_shape == this->
shape())
2251 this->
init(initial);
2255 difference_type new_stride = detail::defaultStride <MultiArrayView<N,T>::actual_dimension> (new_shape);
2258 allocate (new_ptr, new_size, initial);
2260 this->
m_ptr = new_ptr;
2267 template <
unsigned int N,
class T,
class A>
2273 std::swap(this->
m_shape, other.m_shape);
2274 std::swap(this->
m_stride, other.m_stride);
2275 std::swap(this->
m_ptr, other.m_ptr);
2276 std::swap(this->m_alloc, other.m_alloc);
2279 template <
unsigned int N,
class T,
class A>
2283 ptr = m_alloc.
allocate ((
typename A::size_type)s);
2286 for (i = 0; i < s; ++i)
2287 m_alloc.construct (ptr + i, init);
2291 m_alloc.destroy (ptr + j);
2292 m_alloc.deallocate (ptr, (
typename A::size_type)s);
2297 template <
unsigned int N,
class T,
class A>
2302 ptr = m_alloc.
allocate ((
typename A::size_type)s);
2305 for (i = 0; i < s; ++i, ++
init)
2306 m_alloc.construct (ptr + i, *init);
2310 m_alloc.destroy (ptr + j);
2311 m_alloc.deallocate (ptr, (
typename A::size_type)s);
2316 template <
unsigned int N,
class T,
class A>
2317 template <
class U,
class C>
2321 ptr = m_alloc.allocate ((
typename A::size_type)s);
2324 detail::uninitializedCopyMultiArrayData(init.traverser_begin(), init.shape(),
2325 p, m_alloc, MetaInt<actual_dimension-1>());
2328 for (
pointer pp = ptr; pp < p; ++pp)
2329 m_alloc.destroy (pp);
2330 m_alloc.deallocate (ptr, (
typename A::size_type)s);
2335 template <
unsigned int N,
class T,
class A>
2341 m_alloc.destroy (ptr + i);
2342 m_alloc.
deallocate (ptr, (
typename A::size_type)s);
2352 template <
unsigned int N,
class T,
class C>
2353 inline triple<typename MultiArrayView<N,T,C>::const_traverser,
2358 return triple<typename MultiArrayView<N,T,C>::const_traverser,
2366 template <
unsigned int N,
class T,
class C,
class Accessor>
2367 inline triple<typename MultiArrayView<N,T,C>::const_traverser,
2368 typename MultiArrayView<N,T,C>::difference_type,
2370 srcMultiArrayRange( MultiArrayView<N,T,C>
const & array, Accessor a )
2372 return triple<typename MultiArrayView<N,T,C>::const_traverser,
2373 typename MultiArrayView<N,T,C>::difference_type,
2375 ( array.traverser_begin(),
2380 template <
unsigned int N,
class T,
class C>
2381 inline pair<typename MultiArrayView<N,T,C>::const_traverser,
2382 typename AccessorTraits<T>::default_const_accessor >
2383 srcMultiArray( MultiArrayView<N,T,C>
const & array )
2385 return pair<typename MultiArrayView<N,T,C>::const_traverser,
2386 typename AccessorTraits<T>::default_const_accessor >
2387 ( array.traverser_begin(),
2388 typename AccessorTraits<T>::default_const_accessor() );
2391 template <
unsigned int N,
class T,
class C,
class Accessor>
2392 inline pair<typename MultiArrayView<N,T,C>::const_traverser,
2394 srcMultiArray( MultiArrayView<N,T,C>
const & array, Accessor a )
2396 return pair<typename MultiArrayView<N,T,C>::const_traverser,
2398 ( array.traverser_begin(), a );
2401 template <
unsigned int N,
class T,
class C>
2402 inline triple<typename MultiArrayView<N,T,C>::traverser,
2403 typename MultiArrayView<N,T,C>::difference_type,
2404 typename AccessorTraits<T>::default_accessor >
2405 destMultiArrayRange( MultiArrayView<N,T,C> & array )
2407 return triple<typename MultiArrayView<N,T,C>::traverser,
2408 typename MultiArrayView<N,T,C>::difference_type,
2409 typename AccessorTraits<T>::default_accessor >
2410 ( array.traverser_begin(),
2412 typename AccessorTraits<T>::default_accessor() );
2415 template <
unsigned int N,
class T,
class C,
class Accessor>
2416 inline triple<typename MultiArrayView<N,T,C>::traverser,
2417 typename MultiArrayView<N,T,C>::difference_type,
2419 destMultiArrayRange( MultiArrayView<N,T,C> & array, Accessor a )
2421 return triple<typename MultiArrayView<N,T,C>::traverser,
2422 typename MultiArrayView<N,T,C>::difference_type,
2424 ( array.traverser_begin(),
2429 template <
unsigned int N,
class T,
class C>
2430 inline pair<typename MultiArrayView<N,T,C>::traverser,
2431 typename AccessorTraits<T>::default_accessor >
2432 destMultiArray( MultiArrayView<N,T,C> & array )
2434 return pair<typename MultiArrayView<N,T,C>::traverser,
2435 typename AccessorTraits<T>::default_accessor >
2436 ( array.traverser_begin(),
2437 typename AccessorTraits<T>::default_accessor() );
2440 template <
unsigned int N,
class T,
class C,
class Accessor>
2441 inline pair<typename MultiArrayView<N,T,C>::traverser,
2443 destMultiArray( MultiArrayView<N,T,C> & array, Accessor a )
2445 return pair<typename MultiArrayView<N,T,C>::traverser,
2447 ( array.traverser_begin(), a );
2452 template <
class PixelType,
class Accessor>
2453 inline triple<ConstStridedImageIterator<PixelType>,
2454 ConstStridedImageIterator<PixelType>, Accessor>
2455 srcImageRange(
const MultiArrayView<2, PixelType, StridedArrayTag> & img, Accessor a)
2457 ConstStridedImageIterator<PixelType>
2458 ul(img.data(), 1, img.stride(0), img.stride(1));
2459 return triple<ConstStridedImageIterator<PixelType>,
2460 ConstStridedImageIterator<PixelType>,
2462 ul, ul + Size2D(img.shape(0), img.shape(1)), a);
2465 template <
class PixelType,
class Accessor>
2466 inline pair<ConstStridedImageIterator<PixelType>, Accessor>
2467 srcImage(
const MultiArrayView<2, PixelType, StridedArrayTag> & img, Accessor a)
2469 ConstStridedImageIterator<PixelType>
2470 ul(img.data(), 1, img.stride(0), img.stride(1));
2471 return pair<ConstStridedImageIterator<PixelType>, Accessor>
2475 template <
class PixelType,
class Accessor>
2476 inline triple<StridedImageIterator<PixelType>,
2477 StridedImageIterator<PixelType>, Accessor>
2478 destImageRange(MultiArrayView<2, PixelType, StridedArrayTag> & img, Accessor a)
2480 StridedImageIterator<PixelType>
2481 ul(img.data(), 1, img.stride(0), img.stride(1));
2482 return triple<StridedImageIterator<PixelType>,
2483 StridedImageIterator<PixelType>,
2485 ul, ul + Size2D(img.shape(0), img.shape(1)), a);
2488 template <
class PixelType,
class Accessor>
2489 inline pair<StridedImageIterator<PixelType>, Accessor>
2490 destImage(MultiArrayView<2, PixelType, StridedArrayTag> & img, Accessor a)
2492 StridedImageIterator<PixelType>
2493 ul(img.data(), 1, img.stride(0), img.stride(1));
2494 return pair<StridedImageIterator<PixelType>, Accessor>
2498 template <
class PixelType,
class Accessor>
2499 inline pair<StridedImageIterator<PixelType>, Accessor>
2500 maskImage(MultiArrayView<2, PixelType, StridedArrayTag> & img, Accessor a)
2502 StridedImageIterator<PixelType>
2503 ul(img.data(), 1, img.stride(0), img.stride(1));
2504 return pair<StridedImageIterator<PixelType>, Accessor>
2510 template <
class PixelType>
2511 inline triple<ConstStridedImageIterator<PixelType>,
2512 ConstStridedImageIterator<PixelType>,
2513 typename AccessorTraits<PixelType>::default_const_accessor>
2514 srcImageRange(MultiArrayView<2, PixelType, StridedArrayTag>
const & img)
2516 ConstStridedImageIterator<PixelType>
2517 ul(img.data(), 1, img.stride(0), img.stride(1));
2518 typedef typename AccessorTraits<PixelType>::default_const_accessor Accessor;
2519 return triple<ConstStridedImageIterator<PixelType>,
2520 ConstStridedImageIterator<PixelType>,
2522 (ul, ul + Size2D(img.shape(0), img.shape(1)), Accessor());
2525 template <
class PixelType>
2526 inline triple<ConstImageIterator<PixelType>,
2527 ConstImageIterator<PixelType>,
2528 typename AccessorTraits<PixelType>::default_const_accessor>
2529 srcImageRange(MultiArrayView<2, PixelType, UnstridedArrayTag>
const & img)
2531 ConstImageIterator<PixelType>
2532 ul(img.data(), img.stride(1));
2533 typedef typename AccessorTraits<PixelType>::default_const_accessor Accessor;
2534 return triple<ConstImageIterator<PixelType>,
2535 ConstImageIterator<PixelType>,
2537 (ul, ul + Size2D(img.shape(0), img.shape(1)), Accessor());
2540 template <
class PixelType>
2541 inline pair< ConstStridedImageIterator<PixelType>,
2542 typename AccessorTraits<PixelType>::default_const_accessor>
2543 srcImage(MultiArrayView<2, PixelType, StridedArrayTag>
const & img)
2545 ConstStridedImageIterator<PixelType>
2546 ul(img.data(), 1, img.stride(0), img.stride(1));
2547 typedef typename AccessorTraits<PixelType>::default_const_accessor Accessor;
2548 return pair<ConstStridedImageIterator<PixelType>,
2553 template <
class PixelType>
2554 inline pair< ConstImageIterator<PixelType>,
2555 typename AccessorTraits<PixelType>::default_const_accessor>
2556 srcImage(MultiArrayView<2, PixelType, UnstridedArrayTag>
const & img)
2558 ConstImageIterator<PixelType>
2559 ul(img.data(), img.stride(1));
2560 typedef typename AccessorTraits<PixelType>::default_const_accessor Accessor;
2561 return pair<ConstImageIterator<PixelType>,
2566 template <
class PixelType>
2567 inline triple< StridedImageIterator<PixelType>,
2568 StridedImageIterator<PixelType>,
2569 typename AccessorTraits<PixelType>::default_accessor>
2570 destImageRange(MultiArrayView<2, PixelType, StridedArrayTag> & img)
2572 StridedImageIterator<PixelType>
2573 ul(img.data(), 1, img.stride(0), img.stride(1));
2574 typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
2575 return triple<StridedImageIterator<PixelType>,
2576 StridedImageIterator<PixelType>,
2578 (ul, ul + Size2D(img.shape(0), img.shape(1)), Accessor());
2581 template <
class PixelType>
2582 inline triple< ImageIterator<PixelType>,
2583 ImageIterator<PixelType>,
2584 typename AccessorTraits<PixelType>::default_accessor>
2585 destImageRange(MultiArrayView<2, PixelType, UnstridedArrayTag> & img)
2587 ImageIterator<PixelType>
2588 ul(img.data(), img.stride(1));
2589 typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
2590 return triple<ImageIterator<PixelType>,
2591 ImageIterator<PixelType>,
2593 (ul, ul + Size2D(img.shape(0), img.shape(1)), Accessor());
2596 template <
class PixelType>
2597 inline pair< StridedImageIterator<PixelType>,
2598 typename AccessorTraits<PixelType>::default_accessor>
2599 destImage(MultiArrayView<2, PixelType, StridedArrayTag> & img)
2601 StridedImageIterator<PixelType>
2602 ul(img.data(), 1, img.stride(0), img.stride(1));
2603 typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
2604 return pair<StridedImageIterator<PixelType>, Accessor>
2608 template <
class PixelType>
2609 inline pair< ImageIterator<PixelType>,
2610 typename AccessorTraits<PixelType>::default_accessor>
2611 destImage(MultiArrayView<2, PixelType, UnstridedArrayTag> & img)
2613 ImageIterator<PixelType> ul(img.data(), img.stride(1));
2614 typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
2615 return pair<ImageIterator<PixelType>, Accessor>(ul, Accessor());
2618 template <
class PixelType>
2619 inline pair< ConstStridedImageIterator<PixelType>,
2620 typename AccessorTraits<PixelType>::default_accessor>
2621 maskImage(MultiArrayView<2, PixelType, StridedArrayTag>
const & img)
2623 ConstStridedImageIterator<PixelType>
2624 ul(img.data(), 1, img.stride(0), img.stride(1));
2625 typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
2626 return pair<ConstStridedImageIterator<PixelType>, Accessor>
2630 template <
class PixelType>
2631 inline pair< ConstImageIterator<PixelType>,
2632 typename AccessorTraits<PixelType>::default_accessor>
2633 maskImage(MultiArrayView<2, PixelType, UnstridedArrayTag>
const & img)
2635 ConstImageIterator<PixelType>
2636 ul(img.data(), img.stride(1));
2637 typedef typename AccessorTraits<PixelType>::default_accessor Accessor;
2638 return pair<ConstImageIterator<PixelType>, Accessor>
2691 BasicImageView <RGBValue<T> >
2694 vigra_precondition (
2695 array.
shape (0) == 3,
"makeRGBImageView(): array.shape(0) must be 3.");
2704 #undef VIGRA_ASSERT_INSIDE
2705 #endif // VIGRA_MULTI_ARRAY_HXX