00001 #ifndef __vector_Iterator_HPP
00002 #define __vector_Iterator_HPP "Created 21.05.2006 12:12:12 by werner"
00003
00004 #include <eagle/FixedArray.hpp>
00005 #include "VVector.hpp"
00006 #include "Index.hpp"
00007 #include <typeinfo>
00008 #include "HyperslabParameters.hpp"
00009
00010 #include <memcore/memcore.h>
00011
00012 namespace Fiber
00013 {
00014 using std::type_info;
00015 using Eagle::FixedArray;
00016
00017 typedef Eagle::Mult Mult;
00018 typedef Eagle::Div Div;
00019 typedef Eagle::Add Add;
00020 typedef Eagle::Sub Sub;
00021
00022 template <int Configuration> struct RangeFailureAction;
00023
00024 template <>
00025 struct RangeFailureAction<0> : std::exception
00026 {
00027 static void check(const char*funcname, index_t i, index_t max_i)
00028 {}
00029
00030 override const char*what() const throw()
00031 {
00032 return "Range check error";
00033 }
00034 };
00035
00036 template <>
00037 struct RangeFailureAction<1> : std::exception
00038 {
00039 static void check(const char*funcname, index_t i, index_t max_i)
00040 {
00041
00042
00043 if (i>=max_i)
00044 {
00045 std::cout << "RangeFailueAction<1>: ERROR " << funcname << ":" << i << " of " << max_i << " accessed!" << std::endl;
00046 assert(i<max_i);
00047 }
00048 }
00049
00050 override const char*what() const throw()
00051 {
00052 return "Range check error";
00053 }
00054 };
00055
00056 struct RangeException : std::exception
00057 {
00058 RangeException(const char*func, index_t i, index_t max_i)
00059 {}
00060
00061 override const char*what() const throw()
00062 {
00063 return "Range check error";
00064 }
00065 };
00066
00067 template <>
00068 struct RangeFailureAction<2> : std::exception
00069 {
00070 static void check(const char*funcname, index_t i, index_t max_i)
00071 {
00072 if (i>=max_i)
00073 {
00074 throw RangeException(funcname, i, max_i);
00075 }
00076 }
00077
00078 override const char*what() const throw()
00079 {
00080 return "Range check error";
00081 }
00082 };
00083
00084 template <>
00085 struct RangeFailureAction<3>
00086 {
00087 static void check(const char*funcname, index_t i, index_t max_i)
00088 {
00089 if (i>=max_i)
00090 {
00091 std::cerr << "RangeFailueAction<3>: ERROR " << funcname << ":" << i << " of " << max_i << " accessed!" << std::endl;
00092 throw RangeException(funcname, i, max_i);
00093 }
00094 }
00095
00096 override const char*what() const throw()
00097 {
00098 return "Range check error";
00099 }
00100 };
00101
00102
00103 #ifndef FIBER_VECTOR_RANGE_FAILURE_ACTION
00104 #ifdef NDEBUG
00105 #define FIBER_VECTOR_RANGE_FAILURE_ACTION 0
00106 #else
00107 #define FIBER_VECTOR_RANGE_FAILURE_ACTION 1
00108 #endif
00109 #endif
00110
00111 typedef RangeFailureAction<FIBER_VECTOR_RANGE_FAILURE_ACTION> DefaultRangeFailureAction;
00112
00113 template <class T>
00114 class Iterator;
00115
00116 template <int Components, class T>
00117 class Iterator<FixedArray<T, Components> >;
00118
00119
00135 template <class T>
00136 class ElementIterator : public HyperslabParameters
00137 {
00138 private:
00140 T*data;
00141
00142 protected:
00143 using HyperslabParameters::length;
00144 using HyperslabParameters::stride;
00145 using HyperslabParameters::offset;
00146 using HyperslabParameters::shift;
00147 using HyperslabParameters::cropped;
00148
00149 void incPtr(index_t what)
00150 {
00151 data += what;
00152 }
00153
00154 public:
00155 typedef Eagle::MetaInfo<T> info_t;
00156 typedef typename info_t::element_t element_info_t;
00157
00161 ElementIterator(index_t Length, T*Data, index_t Stride, index_t Offset)
00162 : HyperslabParameters(Length, Stride, Offset)
00163 , data(Data)
00164 {}
00165
00167 ElementIterator(const ElementIterator&It)
00168 : HyperslabParameters(It)
00169 , data (It.data)
00170 {}
00171
00173 ElementIterator(const HyperslabParameters&It, T*newData)
00174 : HyperslabParameters(It)
00175 , data (newData)
00176 {}
00177
00179 ElementIterator(index_t i, const ElementIterator&It, const Add&)
00180 : HyperslabParameters(i, It)
00181 , data (It.data)
00182 {}
00183
00184
00186 void SetNewData(T*newData, index_t newLength) throw()
00187 {
00188 data = newData;
00189 length = newLength;
00190
00191 if( stride == 1 )
00192 {
00193 offset = length;
00194
00195
00196
00197 }
00198 else
00199 {
00200 offset = 0;
00201
00202
00203
00204
00205
00206 }
00207 }
00208
00211 T*ptr(int c=0) const
00212 {
00213 if (!data)
00214 return 0;
00215
00216 return data+c*offset;
00217 }
00218
00230 T&operator()(index_t i, int c) const
00231 {
00232 index_t index = getIndex(i,c);
00233
00234
00235
00236
00237 DefaultRangeFailureAction::check(__func__, index, getLength() );
00238 DefaultRangeFailureAction::check(__func__, i , count() );
00239
00240
00241 return data[index];
00242 }
00243
00248 operator bool() const
00249 {
00250 return data!=0;
00251 }
00252
00253
00254 #if defined(_IOSTREAM_) || defined(_GLIBCXX_OSTREAM) || defined(_CPP_IOSTREAM) || defined(__SGI_STL_IOSTREAM)
00255 #define ITERATOR_OSTREAM
00256 friend std::ostream&operator<<(std::ostream&os, const ElementIterator&It)
00257 {
00258 os << '(' << It.shift << " + i)*" << It.stride << " + c*" << It.offset
00259 << " ; " << It.length << " elements of type "
00260 << typeid (T).name() << ", " << It.count() << " iterable.\n"
00261 ;
00262 return os;
00263 }
00264 #endif
00265
00266 };
00267
00268
00272 template <class T>
00273 class IteratorBase : public ElementIterator<T>
00274 {
00275 protected:
00276 using ElementIterator<T>::length;
00277 using ElementIterator<T>::stride;
00278 using ElementIterator<T>::offset;
00279 using ElementIterator<T>::shift;
00280 using ElementIterator<T>::cropped;
00281
00282 public:
00283 using ElementIterator<T>::getLength;
00284 using ElementIterator<T>::count;
00285 using ElementIterator<T>::ptr;
00286 using ElementIterator<T>::getStride;
00287 using ElementIterator<T>::getOffset;
00288 using ElementIterator<T>::operator();
00289
00290 IteratorBase(index_t Length, T*d, index_t Stride, index_t Offset)
00291 : ElementIterator<T>(Length, d, Stride, Offset)
00292 {}
00293
00294 IteratorBase(const IteratorBase&IB)
00295 : ElementIterator<T>(IB)
00296 {}
00297
00299 IteratorBase(const HyperslabParameters&IB, T*d)
00300 : ElementIterator<T>(IB,d)
00301 {}
00302
00303 IteratorBase(index_t ishift, const IteratorBase&P, const Add&)
00304 : ElementIterator<T>(ishift, P, Add() )
00305 {}
00306 };
00307
00308
00309 template <class T>
00310 class Iterator;
00311
00312 template <int C, class T>
00313 class Iterator<FixedArray<T, C> >;
00314
00315 template <class T, int C>
00316 class FixedArrayTrait
00317 {
00318 public: typedef FixedArray<T, C> array_t;
00319 };
00320
00321 template <class T>
00322 class FixedArrayTrait<T,1>
00323 {
00324 public: typedef T array_t;
00325 };
00326
00327
00328 template <class Type>
00329 struct ElementryArrayTrait
00330 {
00331 typedef Eagle::MetaInfo<Type> FI;
00332 typedef typename FixedArrayTrait<typename FI::element_t, FI::MULTIPLICITY>::array_t basetype_t;
00333 };
00334
00348 template <class T>
00349 class Iterator : public IteratorBase<T>
00350 {
00351 protected:
00352 using IteratorBase<T>::length;
00353 using IteratorBase<T>::stride;
00354 using IteratorBase<T>::offset;
00355 using IteratorBase<T>::shift;
00356 using IteratorBase<T>::cropped;
00357
00358 public:
00359 typedef IteratorBase<T> Base_t;
00360
00361 using IteratorBase<T>::getLength;
00362 using IteratorBase<T>::count;
00363 using IteratorBase<T>::ptr;
00364 using IteratorBase<T>::getStride;
00365 using IteratorBase<T>::getOffset;
00366 using IteratorBase<T>::operator();
00367
00368 typedef T value_t;
00369
00370 typedef Eagle::MetaInfo<value_t> FI;
00371 typedef typename FI::element_t component_t;
00372 typedef typename ElementryArrayTrait<T>::basetype_t array_t;
00373
00375 Iterator(index_t howmany, T*Ptr)
00376 : IteratorBase<T>(howmany, Ptr, 1, howmany)
00377 {}
00378
00379 #if 0 // better not allow this constructor, should force using first version
00380
00381 Iterator(T*Ptr, index_t howmany)
00382 : IteratorBase<T>(howmany, Ptr, 1, howmany)
00383 {}
00384 #endif
00385
00387 Iterator(const HyperslabParameters&P, T*Ptr)
00388 : IteratorBase<T>(P, Ptr)
00389 {}
00390
00392 Iterator(const Iterator&P)
00393 : IteratorBase<T>(P)
00394 {}
00395
00397 Iterator(const Iterator&P, int)
00398 : IteratorBase<T>(P)
00399 {}
00400
00404 template <int Components>
00405 Iterator(index_t howmany, FixedArray<T, Components>*Ptr, int component)
00406 : IteratorBase<T>(howmany*Components,
00407 Ptr?Ptr->ptr(component):0,
00408 sizeof(FixedArray<T, Components>)/sizeof(T),
00409 0)
00410 {
00411 assert(component<Components);
00412 }
00413
00414 template <int Components>
00415 Iterator(const Iterator<FixedArray<T, Components> >&It, int component)
00416 : IteratorBase<T>(It.count()*Components,
00417 It?It.ptr():0,
00418 sizeof(Eagle::FixedArray<T, Components>)/sizeof(T),
00419 0)
00420 {
00421 assert(component<Components);
00422 if (It.isSeparatedCompound() )
00423 {
00425
00426 index_t nElements = It.getLength() / Components;
00427 this->stride = 1;
00428 this->offset = nElements;
00429 this->length = nElements;
00430 this->incPtr( nElements );
00431 this->shift = It.getShift();
00432 this->cropped= It.getCropped();
00433 }
00434 else
00435 {
00437
00438 this->incPtr( component );
00439 this->stride = sizeof(Eagle::FixedArray<T, Components>)/sizeof(T);
00440 this->offset = 0;
00441 this->shift = It.getShift();
00442 this->length = It.getLength();
00443 this->cropped= It.getCropped();
00444 }
00445 }
00446
00447
00454 template <int Components>
00455 Iterator(index_t Length, Eagle::VVector<Components, T>*Ptr, int component)
00456 : IteratorBase<T>(Length*Components,
00457 Ptr?Ptr->ptr(component):0,
00458 sizeof(Eagle::VVector<Components, T>)/sizeof(T),
00459 0)
00460 {
00461 assert(component<Components);
00462 }
00463
00465 Iterator(index_t ishift, const Iterator&P, const Add&)
00466 : IteratorBase<T>(ishift, P, Add() )
00467 {
00468
00469
00470 }
00471
00473 Iterator<array_t> getArrayIterator() const;
00474
00476 Iterator<component_t> getComponent(int n) const;
00477
00478 friend Iterator operator+(const Iterator&P, uint32_t i)
00479 {
00480 return Iterator(i, P, Add() );
00481 }
00482
00483 friend Iterator operator+(uint32_t i, const Iterator&P)
00484 {
00485 return Iterator(i, P, Add() );
00486 }
00487
00488 friend Iterator operator+(const Iterator&P, uint64_t i)
00489 {
00490 return Iterator(i, P, Add() );
00491 }
00492
00493 friend Iterator operator+(uint64_t i, const Iterator&P)
00494 {
00495 return Iterator(i, P, Add() );
00496 }
00497
00498
00499
00500 friend Iterator operator+(const Iterator&P, int32_t i)
00501 {
00502 return Iterator(i, P, Add() );
00503 }
00504
00505 friend Iterator operator+(int32_t i, const Iterator&P)
00506 {
00507 return Iterator(i, P, Add() );
00508 }
00509
00510 friend Iterator operator+(const Iterator&P, int64_t i)
00511 {
00512 return Iterator(i, P, Add() );
00513 }
00514
00515 friend Iterator operator+(int64_t i, const Iterator&P)
00516 {
00517 return Iterator(i, P, Add() );
00518 }
00519
00520 #if 0
00521 friend Iterator operator+(const Iterator&P, long long i)
00522 {
00523 return Iterator(i, P, Add() );
00524 }
00525
00526 friend Iterator operator+(long long i, const Iterator&P)
00527 {
00528 return Iterator(i, P, Add() );
00529 }
00530 #endif
00531
00533 typedef T& reference_t;
00534
00536 T&operator[](index_t i) const
00537 {
00538 return (*this)(i,0);
00539 }
00540
00542 const T&getValue(index_t i) const
00543 {
00544 return (*this)(i,0);
00545 }
00546
00548 void set(const T&Value)
00549 {
00550 for(index_t i=0; i<count(); i++)
00551 {
00552 (*this)(i,0) = Value;
00553 }
00554 }
00555 };
00556
00557
00558 #if 0
00559 template <class T>
00560 class constViewPtr<const T> : public ViewPtrBase<const T, 1>
00561 {
00562
00563
00564
00565 public:
00566 using ViewPtrBase<T, 1>::data;
00567 using ViewPtrBase<T, 1>::stride;
00568 using ViewPtrBase<T, 1>::offset;
00569
00570 typedef T value_t;
00571
00573 ViewPtr(const T*ptr)
00574 : ViewPtrBase<const T, 1>(ptr, 1, 0)
00575 {}
00576
00578 ViewPtr(const ViewPtr&P)
00579 : ViewPtrBase<const T, 1>(P.data, P.stride, P.offset)
00580 {}
00581
00585 template <int Components>
00586 ViewPtr(const FixedArray<Components, T>*ptr, int component)
00587 : ViewPtrBase<const T, 1>(ptr->ptr(0),
00588 sizeof(FixedArray<Components, T>)/sizeof(T) ,
00589 component)
00590 {
00591 assert(component<Components);
00592 }
00593
00594
00598 template <int Components>
00599 ViewPtr(const VVector<Components, T>*ptr, int component)
00600 : ViewPtrBase<const T,1>(ptr->ptr(0),
00601 stride(sizeof(VVector<Components, T>)/sizeof(T) ),
00602 component)
00603 {}
00604
00605
00609 ViewPtr(const ViewPtr&P, index_t ElementShift)
00610 : ViewPtrBase<const T,1>(P.data + P.stride*ElementShift, P.stride, P.offset)
00611
00612 {}
00613
00619 void setOffset(int o)
00620 {
00621 offset = o;
00622 }
00623
00624 const T&operator[](index_t i) const
00625 {
00626 return data[i*stride + offset];
00627 }
00628 };
00629 #endif
00630
00631
00644 template <class Iterator>
00645 class ElementProxy
00646 {
00647 typedef typename Iterator::array_t array_t;
00648 enum { Components = Iterator::Components };
00649 typedef typename Iterator::element_value_t element_value_t;
00650
00651 const Iterator&owner;
00652 index_t idx;
00653
00654 public:
00660 ElementProxy(const Iterator&Owner, index_t Idx)
00661 : owner(Owner), idx(Idx)
00662 {}
00663
00668 operator array_t() const
00669 {
00670 array_t retval;
00671 for(int c=0; c<Components; c++)
00672 {
00673 retval[c] = owner.getComponent(idx,c);
00674 }
00675 return retval;
00676 }
00677
00679 ElementProxy&operator=(const array_t&v)
00680 {
00681 for(int c=0; c<Components; c++)
00682 {
00683 owner.getComponent(idx,c) = v[c];
00684 }
00685 return *this;
00686 }
00687
00688
00690 ElementProxy&operator=(const ElementProxy&in)
00691 {
00692 for(int c=0; c<Components; c++)
00693 {
00694 owner.getComponent(idx,c) = in.owner.getComponent( in.idx, c);
00695 }
00696 return *this;
00697 }
00698
00699 typedef element_value_t value_type;
00700 enum { SIZE = Components };
00701
00706 Eagle::Assignment<ElementProxy, 0> operator=(const element_value_t&x)
00707 {
00708 return Eagle::Assignment<ElementProxy, 0>(*this, x);
00709 }
00710
00711
00713 ElementProxy&operator+=(const array_t&v)
00714 {
00715 for(int c=0; c<Components; c++)
00716 {
00717 owner.getComponent(idx,c) += v[c];
00718 }
00719 return *this;
00720 }
00721
00723 ElementProxy&operator-=(const array_t&v)
00724 {
00725 for(int c=0; c<Components; c++)
00726 {
00727 owner.getComponent(idx,c) -= v[c];
00728 }
00729 return *this;
00730 }
00731
00733 element_value_t&operator[](int c) const
00734 {
00735 return owner.getComponent(idx,c);
00736 }
00737 };
00738
00739
00740
00754 template <int C, class T>
00755 class Iterator<Eagle::FixedArray<T, C> > : public IteratorBase<T>
00756 {
00757 public:
00758 using IteratorBase<T>::ptr;
00759 using IteratorBase<T>::getStride;
00760 using IteratorBase<T>::getOffset;
00761 using IteratorBase<T>::getLength;
00762 using IteratorBase<T>::count;
00763 using IteratorBase<T>::operator();
00764
00766 enum { Components = C };
00767
00769 typedef FixedArray<T, Components> array_t;
00770
00772 typedef T element_value_t;
00773
00775 typedef Iterator<array_t> Iterator_t;
00776
00778 typedef ElementProxy<Iterator_t> Proxy;
00779
00785 Iterator<FixedArray<T, C> >(index_t Length, FixedArray<T, C>*Ptr)
00786 : IteratorBase<T>(Length*C, Ptr ? Ptr->ptr(0) : 0,
00787 C,
00788 1)
00789 {}
00790
00797 Iterator<FixedArray<T, C> >(index_t size, T*Ptr)
00798 : IteratorBase<T>(size*C, Ptr, 1, size)
00799 {}
00800
00804 Iterator<FixedArray<T, C> >(index_t ishift, const Iterator&P, const Add&)
00805 : IteratorBase<T>(ishift, P, Add() )
00806 {
00807
00808
00809
00810 }
00811
00812
00813
00814
00815
00816
00817
00818
00819 friend Iterator<FixedArray<T, C> > operator+(const Iterator<FixedArray<T, C> >&P, int32_t i)
00820 {
00821 return Iterator<FixedArray<T,C> >(i, P, Add() );
00822 }
00823
00824 friend Iterator<FixedArray<T,C> > operator+(int32_t i, const Iterator<FixedArray<T,C> >&P)
00825 {
00826 return Iterator<FixedArray<T,C> >(i, P, Add() );
00827 }
00828
00829
00830 friend Iterator<FixedArray<T,C> > operator+(const Iterator<FixedArray<T,C> >&P, int64_t i)
00831 {
00832 return Iterator<FixedArray<T,C> >(i, P, Add() );
00833 }
00834
00835 friend Iterator<FixedArray<T,C> > operator+(int64_t i, const Iterator<FixedArray<T,C> >&P)
00836 {
00837 return Iterator<FixedArray<T,C> >(i, P, Add() );
00838 }
00839
00840
00841
00842 friend Iterator<FixedArray<T, C> > operator+(const Iterator<FixedArray<T, C> >&P, uint32_t i)
00843 {
00844 return Iterator<FixedArray<T,C> >(i, P, Add() );
00845 }
00846
00847 friend Iterator<FixedArray<T,C> > operator+(uint32_t i, const Iterator<FixedArray<T,C> >&P)
00848 {
00849 return Iterator<FixedArray<T,C> >(i, P, Add() );
00850 }
00851
00852 friend Iterator<FixedArray<T,C> > operator+(const Iterator<FixedArray<T,C> >&P, uint64_t i)
00853 {
00854 return Iterator<FixedArray<T,C> >(i, P, Add() );
00855 }
00856
00857 friend Iterator<FixedArray<T,C> > operator+(uint64_t i, const Iterator<FixedArray<T,C> >&P)
00858 {
00859 return Iterator<FixedArray<T,C> >(i, P, Add() );
00860 }
00861
00862 #if 0
00863 friend Iterator<FixedArray<T,C> > operator+(const Iterator<FixedArray<T,C> >&P, long long i)
00864 {
00865 return Iterator<FixedArray<T,C> >(i, P, Add() );
00866 }
00867
00868 friend Iterator<FixedArray<T,C> > operator+(long long i, const Iterator<FixedArray<T,C> >&P)
00869 {
00870 return Iterator<FixedArray<T,C> >(i, P, Add() );
00871 }
00872 #endif
00873
00874 Iterator<T> getComponent(int i) const
00875 {
00876 return Iterator<T>(*this, i);
00877 }
00878
00879
00880 T&getComponent(index_t i, int c) const
00881 {
00882 assert(c<Components);
00883 return (*this)(i,c);
00884 }
00885
00886 typedef Proxy reference_t;
00887
00889 Proxy operator[](index_t i) const
00890 {
00891 return Proxy(*this, i);
00892 }
00893
00895 array_t getValue(index_t i) const
00896 {
00897 array_t retval;
00898 for(int c=0; c<Components; c++)
00899 {
00900 retval[c] = getComponent(i,c);
00901 }
00902 return retval;
00903 }
00904 };
00905
00916 template <class VectorType>
00917 inline Iterator<typename FixedArrayTrait<typename Eagle::MetaInfo<VectorType>::element_t, Eagle::MetaInfo<VectorType>::MULTIPLICITY>::array_t >
00918 farray_iterator( const Iterator<VectorType>&V )
00919 {
00920 typedef Eagle::MetaInfo<VectorType> FI;
00921
00922 typedef typename FixedArrayTrait<typename FI::element_t, FI::MULTIPLICITY>::array_t array_t;
00923
00924 array_t*data = V.ptr();
00925
00926 Iterator<array_t> retval( V.getLength(), data );
00927 retval.setCount( V.count() );
00928 return retval;
00929 }
00930
00936 template <class Type>
00937 inline Iterator<Type> array_iterator(const Iterator<Type>&It)
00938 {
00939 return It;
00940 }
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950 template <class Type>
00951 inline Iterator<Type> array_iterator(const Iterator<FixedArray<Type, 1> >&It)
00952 {
00953 Type*data = It.ptr();
00954
00955 Iterator<Type> retval( It.getLength(), data );
00956 retval.setCount( It.count() );
00957 return retval;
00958 }
00959
00960
00961
00962 template <int N, class Type>
00963 inline Iterator<Eagle::Vector<Type,N> > vector_iterator(const Iterator<Eagle::VVector<N, Type> >&It)
00964 {
00965 return Iterator<Eagle::Vector<Type,N> >( It, &It.ptr()->vec() );
00966 }
00967
00968 template <class T>
00969 inline Iterator<typename Iterator<T>::array_t> Iterator<T>::getArrayIterator() const
00970 {
00971
00972 return array_iterator( farray_iterator( *this ) );
00973 }
00974
00975 template <class T>
00976 inline Iterator<typename Iterator<T>::component_t> Iterator<T>::getComponent(int i) const
00977 {
00978 return Iterator<typename Iterator<T>::component_t>( getArrayIterator(), i);
00979 }
00980
00981
00982
00983
00984 }
00985
00986 #endif