#ifndef _NO_BOUNDARY_ITERATOR_H #define _NO_BOUNDARY_ITERATOR_H #include #include #include "xyz_type.h" struct init_indices { const xyz_type dim; xyz_type cur; init_indices(const xyz_type& d) : dim(d), cur(0,0,0) { } void operator()(lattice_type& lattice) { lattice.idx = cur; if (cur.z < dim.z-1) { ++cur.z; } else { if (cur.y < dim.y-1) { ++cur.y; cur.z = 0; } else { if (cur.x < dim.x-1) { ++cur.x; cur.y = 0; cur.z = 0; } else { cur = 0; } } } } }; template class no_boundary_iterator : public boost::iterator_adaptor, typename std::vector::iterator, boost::use_default, boost::forward_traversal_tag> { xyz_type dimension; //JCR: g++ -Wall... says will b initialized after if not in same order as line 55/56 below & mattered elsewhere xyz_type current; //current as in current event location (not electrical current) public: template no_boundary_iterator( const ITER& iter , const xyz_type& d = xyz_type(0,0,0) ) : no_boundary_iterator::iterator_adaptor_(iter), dimension(d), current(xyz_type(1,1,1))//stopped warning: initialized after instantiated... { if (d != xyz_type(0,0,0)) { std::advance(this->base_reference(), 1 + (dimension.y + 1) * dimension.z); } } private: friend class boost::iterator_core_access; void increment() { if (current.z < dimension.z-2) { ++current.z; ++this->base_reference(); } else { if (current.y < dimension.y-2) { ++current.y; current.z = 1; std::advance(this->base_reference(), 3); } else { if (current.x < dimension.x-2) { ++current.x; current.y = 1; current.z = 1; std::advance(this->base_reference(), 3 + dimension.z * 2); } else { std::advance(this->base_reference(), 2 + (dimension.y + 1) * dimension.z ); } } } } }; //icc: "operands are evaluated in unspecified order"?! template class face_iterator : public boost::iterator_adaptor, typename std::vector::iterator, boost::use_default, boost::forward_traversal_tag> { typename std::vector::iterator beg_iter; int offset, dim1, dim2, step1, step2, curr1, curr2, pad, val ; xyz_type dim; //JCR:g++:order as below matters;xlC:dim's, steps, offset should b initialized using member init. list & boost "different pass-by-value semantics" public: template face_iterator(const ITER& iter, const int face = Xn, const xyz_type& d = xyz_type(0,0,0), const int& p = 0) : face_iterator::iterator_adaptor_(iter), beg_iter(iter), curr1(p), curr2(p), pad(p), val(face), dim(d) { if (dim != xyz_type(0,0,0)) { if (val < Yn) { dim1 = dim.y; step1 = dim.z; } else { dim1 = dim.x; step1 = dim.y*dim.z; } if (val < Zn) { dim2 = dim.z; step2 = 1; } else { dim2 = dim.y; step2 = dim.z; } switch(val) { case Xp: offset = (dim.x-1)*dim.y*dim.z; break; case Yp: offset = (dim.y-1)*dim.z; break; case Zp: offset = dim.z-1; break; default: offset = 0; } std::advance(this->base_reference(), offset + pad*(step1+step2)); } } private: friend class boost::iterator_core_access; void increment() { if (curr2 < dim2 - 1 - pad) { ++curr2; std::advance(this->base_reference(), step2); } else { if (curr1 < dim1 - 1 - pad) { std::advance(this->base_reference(), step1 - (curr2-pad)*step2); ++curr1; curr2 = pad; } else { const int size = dim.x*dim.y*dim.z; std::advance(this->base_reference(), size - (curr2*step2 + curr1*step1 + offset)); } } } }; #endif