Index: glas/structured_vector.hpp =================================================================== RCS file: /cvsroot/glas/glas/glas/Attic/structured_vector.hpp,v retrieving revision 1.1.2.8 diff -r1.1.2.8 structured_vector.hpp 4a5 > #if 0 5a7 > #endif 13a16,56 > namespace IteratorHelpers { > > template > struct generic: public Iterator { > typedef Iterator Base; > template generic(BEGIN b): Base(b) { } > template generic(END e): Base(e) { } > > // Check that this does not incur any problems. (TODO) > > generic(const Base& b): Base(b) { } > > template > bool operator==(const END& e) const { > const generic end(e); > return Base::operator==(end); > } > template > bool operator!=(const END& e) const { > const generic end(e); > return Base::operator!=(end); > } > > // reverse iterators also want comparison with begin. > > template > bool operator==(const BEGIN& b) const { > const generic beg(b); > return Base::operator==(beg); > } > template > bool operator!=(const BEGIN& b) const { > const generic beg(b); > return Base::operator!=(beg); > } > > using Base::operator==; > using Base::operator!=; > }; > } > 31a75,77 > //all_iterator(BEGIN<>&) > //all_iterator(END<>&) > 191a238,263 > // Generic iterators. > // These classes import external iterator definitions into this class, so that > // the notation class::iterator can be used. Inheritance does everything, only > // constructors need to be propagated. > > template > struct iterator: public IteratorHelpers::generic::type> { > typedef IteratorHelpers::generic::type> Base; > template iterator(U t): Base(t) { } > }; > > template > struct const_iterator: public IteratorHelpers::generic::const_type> { > typedef IteratorHelpers::generic::const_type> Base; > template const_iterator(U t): Base(t) { } > }; > > // These function basically just mark the intention of doing a begin/end and forward > // the actual construction of the iterator into the iterator constructor. > > IteratorHelpers::BEGIN begin() { return IteratorHelpers::BEGIN(*this); } > IteratorHelpers::BEGIN begin() const { return IteratorHelpers::BEGIN(*this); } > > IteratorHelpers::END end() { return IteratorHelpers::END(*this); } > IteratorHelpers::END end() const { return IteratorHelpers::END(*this); } > 219a292 > #if 0 240a314 > #endif Index: glas/types.hpp =================================================================== RCS file: /cvsroot/glas/glas/glas/Attic/types.hpp,v retrieving revision 1.1.2.1 diff -r1.1.2.1 types.hpp 6,7c6,74 < struct nz {} ; < struct all {} ; --- > namespace IteratorHelpers { > // Markers used to delay the begin/end computation at iterator construction. > > template > struct BEGIN { > BEGIN(T t): val(t) { } > T val; > }; > > template > struct END { > END(T t):val(t) { } > T val; > }; > } > > struct nz; > > // Here is the real implementation of the nz_iterator. > // For simplicity I just reused the structured_vector::iterator type > // but obviously it is bad to have to different iterators depending on whether > // you use begin() or begin(nz()). This can be easily fixed, but not yet to keep > // the patch as minimal as possible. > > // Here I had to create completely a small iterator because the original > // iterator is just a pointer so I cannot inherit from it. With real iterators, > // most of the stuff (ie everything but the constructors) can go away. > > template > struct nz_iterator { > typename T::nz_iterator iter; > > nz_iterator(IteratorHelpers::BEGIN beg): iter(beg.val.begin(nz())) { } > nz_iterator(IteratorHelpers::END beg): iter(beg.val.end(nz())) { } > > typename T::value_type& operator*() { return *iter; } > const typename T::value_type& operator*() const { return *iter; } > > void operator++() { ++iter; } > > bool operator==(const nz_iterator& it) const { return iter==it.iter; } > bool operator!=(const nz_iterator& it) const { return iter!=it.iter; } > }; > > // nz is not only and empty struct, it contains the information to delagate > // the iterators corresponding to the nz name to the actual implementation. > // Only type and const_type are used currently, but value_type seems relevant also > // and this way, nz::Info can act as a trait. > > struct nz { > template > struct Info { > typedef typename T::value_type value_type; > typedef nz_iterator type; > typedef nz_iterator const_type; > }; > }; > > // Not yet done (it would require to move the definition of all_iterator), > // but you get the idea. > > struct all { > template > struct Info { > //typedef typename T::value_type value_type; > //typedef all_iterator type; > //typedef all_iterator const_type; > }; > } ; Index: test/structured_vector.cpp =================================================================== RCS file: /cvsroot/glas/glas/test/Attic/structured_vector.cpp,v retrieving revision 1.1.2.6 diff -r1.1.2.6 structured_vector.cpp 25a26 > #if 0 36a38,48 > #endif > > { // test generic nz iterator > int j = 0; > vector_type::iterator itw = w.begin(); > for (vector_type::iterator itv=v.begin(); itv!=v.end();++itv,++itw,++j) { > if (a[j]!=*itv) return 6; > if (a[j]!=*itw) return 7; > } > if (itw!=w.end()) return 8; > }