36#ifndef MULTI_HANDLE_HXX
37#define MULTI_HANDLE_HXX
39#include "multi_fwd.hxx"
40#include "metaprogramming.hxx"
41#include "multi_shape.hxx"
45template <
unsigned TARGET_INDEX,
class Handle,
unsigned int INDEX=Handle::index>
46struct CoupledHandleCast;
48template <
unsigned int TARGET_INDEX,
class Handle>
49typename CoupledHandleCast<TARGET_INDEX, Handle>::reference
52template <
unsigned int TARGET_INDEX,
class Handle>
53typename CoupledHandleCast<TARGET_INDEX, Handle>::const_reference
54get(Handle
const & handle);
63template <
class T,
class NEXT>
68 typedef NEXT base_type;
71 static const int index = NEXT::index + 1;
72 static const unsigned int dimensions = NEXT::dimensions;
77 typedef T & reference;
79 typedef typename base_type::shape_type shape_type;
87 template <
class NEXT1>
96 pointer_(
const_cast<pointer
>(p)),
100 template <
class Str
ide>
103 pointer_(
const_cast<pointer
>(v.data())),
106 vigra_precondition(v.shape() ==
this->shape(),
"createCoupledIterator(): shape mismatch.");
109 inline void incDim(
int dim)
111 pointer_ += strides_[dim];
112 base_type::incDim(dim);
115 inline void decDim(
int dim)
117 pointer_ -= strides_[dim];
118 base_type::decDim(dim);
123 pointer_ += d*strides_[dim];
124 base_type::addDim(dim, d);
127 inline void add(shape_type
const & d)
129 pointer_ += dot(d, strides_);
133 template<
int DIMENSION>
134 inline void increment()
136 pointer_ += strides_[DIMENSION];
140 template<
int DIMENSION>
141 inline void decrement()
143 pointer_ -= strides_[DIMENSION];
148 template<
int DIMENSION>
151 pointer_ +=
offset*strides_[DIMENSION];
155 template<
int DIMENSION>
158 pointer_ -=
offset*strides_[DIMENSION];
162 void restrictToSubarray(shape_type
const & start, shape_type
const & end)
164 pointer_ += dot(start, strides_);
165 base_type::restrictToSubarray(start, end);
169 reference operator*()
199 shape_type
const & strides()
const
210 template <
unsigned int TARGET_INDEX>
211 typename CoupledHandleCast<TARGET_INDEX, CoupledHandle, index>::reference
217 template <
unsigned int TARGET_INDEX>
218 typename CoupledHandleCast<TARGET_INDEX, CoupledHandle, index>::const_reference
227 pointer_ =
const_cast<pointer
>(p);
240 static const unsigned int index = 0;
241 static const unsigned int dimensions = N;
244 typedef value_type
const * pointer;
245 typedef value_type
const * const_pointer;
246 typedef value_type
const & reference;
247 typedef value_type
const & const_reference;
248 typedef value_type shape_type;
257 CoupledHandle(value_type
const & shape)
265 shape_(shape.begin()),
269 inline void incDim(
int dim)
274 inline void decDim(
int dim)
284 inline void add(shape_type
const & d)
289 template<
int DIMENSION>
290 inline void increment()
295 template<
int DIMENSION>
296 inline void decrement()
302 template<
int DIMENSION>
305 point_[DIMENSION] += offset;
308 template<
int DIMENSION>
311 point_[DIMENSION] -= offset;
314 void restrictToSubarray(shape_type
const & start, shape_type
const & end)
316 point_ = shape_type();
317 shape_ = end - start;
321 inline void incrementIndex()
326 inline void decrementIndex()
333 scanOrderIndex_ += offset;
338 scanOrderIndex_ -= offset;
344 return scanOrderIndex_;
348 const_reference point()
const
354 const_reference shape()
const
359 const_reference operator*()
const
364 const_pointer operator->()
const
369 const_pointer ptr()
const
374 unsigned int borderType()
const
376 return detail::BorderTypeImpl<N>::exec(point_, shape_);
379 template <
unsigned int TARGET_INDEX>
380 typename CoupledHandleCast<TARGET_INDEX, CoupledHandle, index>::reference
386 template <
unsigned int TARGET_INDEX>
387 typename CoupledHandleCast<TARGET_INDEX, CoupledHandle, index>::const_reference
394 void internal_reset(value_type
const & point)
399 value_type point_, shape_;
404template <
class T,
class NEXT>
405class CoupledHandle<Multiband<T>, NEXT>
409 typedef NEXT base_type;
410 typedef CoupledHandle<Multiband<T>, NEXT> self_type;
412 static const unsigned int index = NEXT::index + 1;
413 static const unsigned int dimensions = NEXT::dimensions;
415 typedef MultiArrayView<1, T, StridedArrayTag> value_type;
416 typedef value_type * pointer;
417 typedef value_type
const * const_pointer;
418 typedef value_type & reference;
419 typedef value_type
const & const_reference;
420 typedef typename base_type::shape_type shape_type;
428 template <
class NEXT1>
429 CoupledHandle(CoupledHandle<Multiband<T>, NEXT1>
const & h, NEXT
const & next)
435 CoupledHandle(const_reference p, shape_type
const & strides, NEXT
const & next)
441 template <
class Str
ide>
442 CoupledHandle(MultiArrayView<dimensions+1, Multiband<T>, Stride>
const & v, NEXT
const & next)
444 view_(v.bindInner(shape_type())),
445 strides_(v.bindOuter(0).stride())
447 vigra_precondition(v.bindOuter(0).shape() == this->shape(),
"createCoupledIterator(): shape mismatch.");
450 inline void incDim(
int dim)
452 view_.unsafePtr() += strides_[dim];
453 base_type::incDim(dim);
456 inline void decDim(
int dim)
458 view_.unsafePtr() -= strides_[dim];
459 base_type::decDim(dim);
464 view_.unsafePtr() += d*strides_[dim];
465 base_type::addDim(dim, d);
468 inline void add(shape_type
const & d)
470 view_.unsafePtr() +=
dot(d, strides_);
474 template<
int DIMENSION>
475 inline void increment()
477 view_.unsafePtr() += strides_[DIMENSION];
478 base_type::template increment<DIMENSION>();
481 template<
int DIMENSION>
482 inline void decrement()
484 view_.unsafePtr() -= strides_[DIMENSION];
485 base_type::template decrement<DIMENSION>();
489 template<
int DIMENSION>
492 view_.unsafePtr() += offset*strides_[DIMENSION];
493 base_type::template increment<DIMENSION>(offset);
496 template<
int DIMENSION>
499 view_.unsafePtr() -= offset*strides_[DIMENSION];
500 base_type::template decrement<DIMENSION>(offset);
503 void restrictToSubarray(shape_type
const & start, shape_type
const & end)
505 view_.unsafePtr() +=
dot(start, strides_);
506 base_type::restrictToSubarray(start, end);
510 reference operator*()
515 const_reference operator*()
const
525 const_pointer operator->()
const
535 const_pointer ptr()
const
540 shape_type
const & strides()
const
545 MultiArrayView<dimensions+1, Multiband<T> >
548 typedef MultiArrayView<dimensions+1, T> View;
549 typename View::difference_type vshape(SkipInitialization), vstride(SkipInitialization);
550 vshape.template subarray<0, dimensions>() = this->shape();
551 vstride.template subarray<0, dimensions>() = strides();
552 vshape[dimensions] = view_.shape(0);
553 vstride[dimensions] = view_.stride(0);
554 return View(vshape, vstride, view_.data() -
dot(this->point(), strides())).multiband();
557 template <
unsigned int TARGET_INDEX>
558 typename CoupledHandleCast<TARGET_INDEX, CoupledHandle, index>::reference
564 template <
unsigned int TARGET_INDEX>
565 typename CoupledHandleCast<TARGET_INDEX, CoupledHandle, index>::const_reference
572 void internal_reset(U
const &)
574 vigra_fail(
"CoupledHandle<Multiband<T>>::internal_reset(): not implemented.");
582template <
unsigned int N,
class T>
583class IteratorChunkHandle
586 typedef ChunkedArray<N, T> array_type;
589 IteratorChunkHandle()
594 IteratorChunkHandle(shape_type
const & offset)
599 IteratorChunkHandle(IteratorChunkHandle
const & other)
600 : offset_(other.offset_),
604 IteratorChunkHandle & operator=(IteratorChunkHandle
const & other)
606 offset_ = other.offset_;
612 SharedChunkHandle<N, T> * chunk_;
624template <
class U,
class NEXT>
625class CoupledHandle<ChunkedMemory<U>, NEXT>
627 public IteratorChunkHandle<NEXT::dimensions, typename UnqualifiedType<U>::type>
630 typedef typename UnqualifiedType<U>::type T;
631 typedef NEXT base_type;
632 typedef IteratorChunkHandle<NEXT::dimensions, T> base_type2;
633 typedef CoupledHandle<ChunkedMemory<U>, NEXT> self_type;
635 static const unsigned int index = NEXT::index + 1;
636 static const unsigned int dimensions = NEXT::dimensions;
638 typedef typename IfBool<UnqualifiedType<U>::isConst,
639 ChunkedArrayBase<dimensions, T>
const,
640 ChunkedArrayBase<dimensions, T> >::type array_type;
641 typedef detail::ChunkShape<dimensions, T> chunk_shape;
642 typedef T value_type;
644 typedef value_type
const * const_pointer;
645 typedef U & reference;
646 typedef value_type
const & const_reference;
647 typedef typename base_type::shape_type shape_type;
658 CoupledHandle(CoupledHandle
const & other)
661 pointer_(other.pointer_),
662 strides_(other.strides_),
663 upper_bound_(other.upper_bound_),
667 pointer_ = array_->chunkForIterator(point(), strides_, upper_bound_,
this);
670 CoupledHandle(array_type
const & array, NEXT
const & next)
674 array_(const_cast<array_type*>(&array))
677 pointer_ = array_->chunkForIterator(point(), strides_, upper_bound_,
this);
684 array_->unrefChunk(
this);
687 CoupledHandle & operator=(CoupledHandle
const & other)
693 array_->unrefChunk(
this);
694 base_type::operator=(other);
695 base_type2::operator=(other);
696 array_ = other.array_;
699 pointer_ = array_->chunkForIterator(point(), strides_, upper_bound_,
this);
703 pointer_ = other.pointer_;
704 strides_ = other.strides_;
705 upper_bound_ = other.upper_bound_;
711 using base_type::point;
712 using base_type::shape;
714 inline void incDim(
int dim)
716 base_type::incDim(dim);
717 pointer_ += strides_[dim];
718 if(point()[dim] == upper_bound_[dim])
721 pointer_ = array_->chunkForIterator(point(), strides_, upper_bound_,
this);
725 inline void decDim(
int dim)
727 base_type::decDim(dim);
728 pointer_ -= strides_[dim];
729 if(point()[dim] < upper_bound_[dim] - array_->chunk_shape_[dim])
732 pointer_ = array_->chunkForIterator(point(), strides_, upper_bound_,
this);
738 base_type::addDim(dim, d);
739 if(point()[dim] < shape()[dim] && point()[dim] >= 0)
740 pointer_ = array_->chunkForIterator(point(), strides_, upper_bound_,
this);
743 inline void add(shape_type
const & d)
746 pointer_ = array_->chunkForIterator(point(), strides_, upper_bound_,
this);
749 template<
int DIMENSION>
750 inline void increment()
753 base_type::template increment<DIMENSION>();
754 pointer_ += strides_[DIMENSION];
755 if(point()[DIMENSION] == upper_bound_[DIMENSION])
757 if(point()[DIMENSION] > shape()[DIMENSION])
760 vigra_invariant(
false,
"CoupledHandle<ChunkedMemory<T>>: internal error.");
762 pointer_ = array_->chunkForIterator(point(), strides_, upper_bound_,
this);
766 template<
int DIMENSION>
767 inline void decrement()
770 base_type::template decrement<DIMENSION>();
771 pointer_ -= strides_[DIMENSION];
772 if(point()[DIMENSION] < upper_bound_[DIMENSION] - array_->chunk_shape_[DIMENSION])
774 if(point()[DIMENSION] < -1)
777 vigra_invariant(
false,
"CoupledHandle<ChunkedMemory<T>>: internal error.");
779 pointer_ = array_->chunkForIterator(point(), strides_, upper_bound_,
this);
783 template<
int DIMENSION>
786 addDim(DIMENSION, d);
789 template<
int DIMENSION>
792 addDim(DIMENSION, -d);
795 void restrictToSubarray(shape_type
const & start, shape_type
const & end)
797 base_type::restrictToSubarray(start, end);
798 this->offset_ += start;
799 pointer_ = array_->chunkForIterator(point(), strides_, upper_bound_,
this);
803 reference operator*()
808 const_reference operator*()
const
818 const_pointer operator->()
const
828 const_pointer ptr()
const
839 template <
unsigned int TARGET_INDEX>
840 typename CoupledHandleCast<TARGET_INDEX, CoupledHandle, index>::reference
846 template <
unsigned int TARGET_INDEX>
847 typename CoupledHandleCast<TARGET_INDEX, CoupledHandle, index>::const_reference
854 void internal_reset(V
const &)
856 vigra_fail(
"CoupledHandle<ChunkedMemory<T>>::internal_reset(): not implemented.");
860 shape_type strides_, upper_bound_;
865template <
unsigned TARGET_INDEX>
866struct Error__CoupledHandle_index_out_of_range;
870template <
unsigned TARGET_INDEX,
class Handle,
bool isVal
id,
unsigned int INDEX=Handle::index>
871struct CoupledHandleCastImpl
873 typedef typename CoupledHandleCastImpl<TARGET_INDEX, typename Handle::base_type, isValid>::type type;
874 typedef typename type::value_type value_type;
875 typedef typename type::reference reference;
876 typedef typename type::const_reference const_reference;
879template <
unsigned TARGET_INDEX,
class Handle,
unsigned int INDEX>
880struct CoupledHandleCastImpl<TARGET_INDEX, Handle, false, INDEX>
882 typedef Error__CoupledHandle_index_out_of_range<TARGET_INDEX> type;
883 typedef Error__CoupledHandle_index_out_of_range<TARGET_INDEX> value_type;
884 typedef Error__CoupledHandle_index_out_of_range<TARGET_INDEX> reference;
885 typedef Error__CoupledHandle_index_out_of_range<TARGET_INDEX> const_reference;
888template <
unsigned TARGET_INDEX,
class Handle>
889struct CoupledHandleCastImpl<TARGET_INDEX, Handle, true, TARGET_INDEX>
892 typedef typename type::value_type value_type;
893 typedef typename type::reference reference;
894 typedef typename type::const_reference const_reference;
899template <
unsigned TARGET_INDEX,
class Handle,
unsigned int INDEX>
900struct CoupledHandleCast
901:
public detail::CoupledHandleCastImpl<TARGET_INDEX, Handle, (TARGET_INDEX <= INDEX), INDEX>
904template <unsigned int TARGET_INDEX, class Handle>
906typename CoupledHandleCast<TARGET_INDEX, Handle>::type &
912template <unsigned int TARGET_INDEX, class Handle>
914typename CoupledHandleCast<TARGET_INDEX, Handle>::type const &
915cast(Handle const & handle)
922template <unsigned int TARGET_INDEX, class Handle>
924typename CoupledHandleCast<TARGET_INDEX, Handle>::reference
927 return *cast<TARGET_INDEX>(handle);
932template <unsigned int TARGET_INDEX, class Handle>
934typename CoupledHandleCast<TARGET_INDEX, Handle>::const_reference
935get(Handle const & handle)
937 return *cast<TARGET_INDEX>(handle);
942template <unsigned int N, class List>
943struct ComposeCoupledHandle;
945template <unsigned int N, class T, class TAIL>
946struct ComposeCoupledHandle<N, TypeList<T, TAIL> >
948 typedef typename ComposeCoupledHandle<N, TAIL>::type BaseType;
949 typedef typename MultiArrayShape<N>::type shape_type;
950 typedef CoupledHandle<T, BaseType> type;
953 type exec(MultiArrayView<N, T, S> const & m,
954 shape_type const & start, shape_type const & end,
955 BaseType const & base)
957 return type(m.subarray(start, end).data(), m.stride(), base);
961 type exec(MultiArrayView<N, T, S> const & m, BaseType const & base)
963 return type(m.data(), m.stride(), base);
967template <unsigned int N>
968struct ComposeCoupledHandle<N, void>
970 typedef typename MultiArrayShape<N>::type shape_type;
971 typedef CoupledHandle<shape_type, void> type;
973 type exec(shape_type const & shape)
978 type exec(shape_type const & start, shape_type const & end)
980 return type(end-start);
985template <unsigned int N, class T1=void, class T2=void, class T3=void, class T4=void, class T5=void>
986struct CoupledHandleType
989 typedef typename MakeTypeList<T5, T4, T3, T2, T1>::type TypeList;
990 typedef typename ComposeCoupledHandle<N, TypeList>::type type;
993template <unsigned int N, class T1, class T2, class T3, class T4, class T5>
994struct CoupledHandleType<N, Multiband<T1>, T2, T3, T4, T5>
997 typedef typename MakeTypeList<T5, T4, T3, T2, Multiband<T1> >::type TypeList;
998 typedef typename ComposeCoupledHandle<N-1, TypeList>::type type;
1002template <class A, class B>
1003struct ZipCoupledHandles;
1005template <class A, class Head, class Tail>
1006struct ZipCoupledHandles<A, CoupledHandle<Head, Tail> >
1008 typedef typename ZipCoupledHandles<A, Tail>::type Next;
1009 typedef CoupledHandle<Head, Next> type;
1011 static type construct(A const & a, CoupledHandle<Head, Tail> const & h)
1013 return type(h, ZipCoupledHandles<A, Tail>::construct(a, (Tail const &)h));
1017template <class A, class Shape>
1018struct ZipCoupledHandles<A, CoupledHandle<Shape, void> >
1022 static type construct(A const & a, CoupledHandle<Shape, void> const &)
1036template <class Handle, unsigned int INDEX=Handle::index>
1037struct CoupledHandleTraits
1039 typedef Handle value_type;
1040 typedef Handle & reference;
1041 typedef Handle const & const_reference;
1042 typedef Handle * pointer;
1043 typedef Handle const * const_pointer;
1045 static reference dereference(Handle & h)
1050 static const_reference dereference(Handle const & h)
1056template <class Handle>
1057struct CoupledHandleTraits<Handle, 0>
1059 typedef typename Handle::value_type value_type;
1060 typedef typename Handle::reference reference;
1061 typedef typename Handle::const_reference const_reference;
1062 typedef typename Handle::pointer pointer;
1063 typedef typename Handle::const_pointer const_pointer;
1065 static reference dereference(Handle & h)
1070 static const_reference dereference(Handle const & h)
1076template <class Handle>
1077struct CoupledHandleTraits<Handle, 1>
1079 typedef typename Handle::value_type value_type;
1080 typedef typename Handle::reference reference;
1081 typedef typename Handle::const_reference const_reference;
1082 typedef typename Handle::pointer pointer;
1083 typedef typename Handle::const_pointer const_pointer;
1085 static reference dereference(Handle & h)
1090 static const_reference dereference(Handle const & h)
Definition multi_handle.hxx:66
TinyVector< MultiArrayIndex, N > type
Definition multi_shape.hxx:272
Class for a single RGB value.
Definition rgbvalue.hxx:128
Class for fixed size vectors.
Definition tinyvector.hxx:1008
LookupTag< TAG, A >::result_type get(A const &a)
Definition accumulator.hxx:2942
NormTraits< T >::SquaredNormType dot(const MultiArrayView< 2, T, C1 > &x, const MultiArrayView< 2, T, C2 > &y)
Definition matrix.hxx:1342
std::ptrdiff_t MultiArrayIndex
Definition multi_fwd.hxx:60