// -*- c++ -*- // // $COPYRIGHT$ // //================================================================== #ifndef MTL_SPARSE_ITERATOR_H #define MTL_SPARSE_ITERATOR_H #include "mtl/mtl_iterator.h" namespace mtl { using std::random_access_iterator_tag; using std::output_iterator_tag; using std::advance; using std::distance; template struct choose { template static inline self add(Iterator i, int, int n, self*) { std::advance(i, n); return self(i); } template static inline self sub(Iterator i, int n, self*) { std::advance(i, -n); return self(i); } template static inline int diff(const self& x, const self& y) { return distance(x.iter, y.iter); } template static inline void init(Iterator& iter, int& pos, const Iterator& /*start*/, const Iterator& finish) { iter = finish; pos = -1; } template static inline bool lessthan(const self& x, const self& y) { return x.iter < y.iter; } template static inline bool notequal(const self& x, const self& y) { return x.iter != y.iter; } template static inline Iterator convert(const Iterator& iter, int) { return iter; } template static inline int index(Iterator iter, int) { return (*iter).index; } template static inline void inc(Iterator& iter, int&) { ++iter; } template static inline void dec(Iterator& iter, int&) { --iter; } template static inline Val& deref(Iterator iter, int, Val*) { return (*iter).value; } template inline void add_assign(Iterator& iter, int&, int n) { advance(iter,n); } template inline void sub_assign(Iterator& iter, int&, int n) { advance(iter,n); } }; template <> struct choose { template static inline self add(Iterator iter, int pos, int n, self*) { return self(iter, pos + n); } template static inline self sub(Iterator iter, int pos, int n, self*) { return self(iter, pos - n); } template static inline int diff(const self& x, const self& y) { return x.pos - y.pos; } template static inline void init(Iterator& iter, int& pos, const Iterator& start, const Iterator& finish) { iter = start; pos = finish - start; } template static inline bool lessthan(const self& x, const self& y) { return x.iter < y.iter; } template static inline bool notequal(const self& x, const self& y) { return x.iter != y.iter; } template static inline Iterator convert(const Iterator& iter, int pos) { return iter + pos; } template static inline int index(Iterator iter, int pos) { return (*(iter + pos)).index; } template static inline void inc(Iterator&, int& pos) { ++pos; } template static inline void dec(Iterator&, int& pos) { --pos; } template static inline Val& deref(const Iterator& iter, int pos, Val*) { return (*(iter + pos)).value; } template static inline void add_assign(Iterator&, int& pos, int n) { pos += n; } template static inline void sub_assign(Iterator&, int& pos, int n) { pos -= n; } }; template class const_sparse_iterator; //: Sparse Vector Iterator // // This iterators is used to implement the sparse1D adaptor. The base // iterator returns a entry1 (an index-value pair) and this iterator // makes it look like we are just dealing with the value for // dereference, while the index() method return the index. // //!category: iterators, adaptors //!component: type //!tparam: Iterator - the underlying iterator type //!tparam: T - the value type template class sparse_iterator { typedef sparse_iterator self; typedef typename std::iterator_traits::iterator_category cat; public: typedef std::bidirectional_iterator_tag iterator_category; typedef T value_type; typedef int difference_type; typedef T& reference; typedef T* pointer; public: inline sparse_iterator() { } inline sparse_iterator(const sparse_iterator& x) : iter(x.iter), pos(x.pos) { } inline sparse_iterator(const Iterator& iter_, int p = 0) : iter(iter_), pos(p) { } inline sparse_iterator(const Iterator& start, const Iterator& finish) { choose::init(iter, pos, start, finish); } inline operator Iterator() const { return choose::convert(iter, pos); } inline int index() const { return choose::index(iter, pos); } inline bool operator!=(const self& x) const { return choose::notequal(*this, x); } inline bool operator<(const self& x) const { return choose::lessthan(*this, x); } inline reference operator*() const { return choose::deref(iter, pos, pointer()); } #if 0 inline int operator-(const self& x) const { return choose::diff(*this, x); } #endif inline self& operator++() { choose::inc(iter, pos); return *this; } inline self operator++(int) { self tmp = *this; choose::inc(iter, pos); return tmp; } inline self& operator--() { choose::dec(iter, pos); return *this; } #if 0 inline self& operator+=(int n) { choose::add_assign(iter, pos, n); return *this; } inline self& operator-=(int n) { choose::sub_assign(iter, pos, n); return *this; } #endif inline Iterator base() const { return choose::convert(iter, pos); } #if 0 inline self operator+(int n) const { return choose::add(iter, pos, n, this); } inline self operator-(int n) const { return choose::sub(iter, pos, n, this); } #endif public: /* VC++ workaround */ Iterator iter; int pos; }; template inline bool operator==(const sparse_iterator& a, const sparse_iterator& b) { return a.base() == b.base(); } template class const_sparse_iterator { typedef const_sparse_iterator self; typedef typename std::iterator_traits::iterator_category cat; public: typedef cat iterator_category; typedef T value_type; typedef int difference_type; typedef const T& reference; typedef T* pointer; public: inline const_sparse_iterator() { } inline const_sparse_iterator(const const_sparse_iterator& x) : iter(x.iter), pos(x.pos) { } inline const_sparse_iterator(const Iterator& iter_, int p = 0) : iter(iter_), pos(p) { } inline const_sparse_iterator(const Iterator& start, const Iterator& finish) { choose::init(iter, pos, start, finish); } template inline const_sparse_iterator(const sparse_iterator& si) : iter(si.iter), pos(si.pos) { } inline operator Iterator() const { return choose::convert(iter, pos); } inline int index() const { return choose::index(iter, pos); } inline bool operator!=(const self& x) const { return choose::notequal(*this, x); } inline bool operator<(const self& x) const { return choose::lessthan(*this, x); } inline reference operator*() const { return choose::deref(iter, pos, pointer()); } inline int operator-(const self& x) const { return choose::diff(*this, x); } inline self& operator++() { choose::inc(iter, pos); return *this; } inline self operator++(int) { self tmp = *this; choose::inc(iter, pos); return tmp; } inline self& operator--() { choose::dec(iter, pos); return *this; } inline self& operator+=(int n) { choose::add_assign(iter, pos, n); return *this; } inline self& operator-=(int n) { choose::sub_assign(iter, pos, n); return *this; } inline Iterator base() const { return choose::convert(iter, pos); } inline self operator+(int n) const { return choose::add(iter, pos, n, this); } inline self operator-(int n) const { return choose::sub(iter, pos, n, this); } public: /* VC++ workaround */ Iterator iter; int pos; }; template inline bool operator==(const const_sparse_iterator& a, const const_sparse_iterator& b) { return a.base() == b.base(); } } /* namespace mtl */ #endif