|
Geometry : |
Subject: [ggl] pre-/post-increment op on iterators
From: Mateusz Loskot (mateusz)
Date: 2009-04-29 16:52:50
Barend Gehrels wrote:
> Mateusz Loskot wrote:
>> I think it can be solved with a thin iterator adapter that
>> dereferences to segment, instead of to point.
>> The adapter, or a view as called in some situations, should do the job.
>>
>>
> It will probably be something like that. However, it'll need a local
> variable "segment" which is then dereferenced. What if the iterator goes
> next? Is the local variable copied? Didn't do such a thing before.
We definitely don't want to dereference by-value (make a copy of segment
object) but by reference, so we need to cache segment object
created/filled with coordinates read from the adapted vector..
The cache is simply a member variable of adaptor iterator.
Roughly drawing the idea, it could be something like this:
struct segment; // our segment type
template <typename Iterator>
struct segment_iterator
{
typedef Iterator iterator_type;
typedef std::input_iterator_tag iterator_category;
typedef typename std::iterator_traits <Iterator>::difference_type
difference_type;
typedef segment value_type;
typedef segment* pointer;
typedef segment const& reference;
explicit segment_iterator(iterator_type it)
: m_it(it), m_prev(m_it)
{
// move to 2nd point
++m_it;
// TODO: check, somehow, if m_it is not pass the end
// Possibly container which iterator is being
// adapted store only 1 point
}
reference operator*() const
{
// Lazy, so make segment when needed, on dereference not
// on incrementation
// TODO
// 1. make segment from 2 points
m_cache.first = *m_prev;
m_cache.second = *m_it;
// 2. Cache segment as m_segment
return m_cache;
}
pointer operator->() const
{
return &(operator*());
}
segment_iterator& operator++()
{
// TODO: advance position
++m_prev;
++m_it;
return *this;
}
segment_iterator operator++(int)
{
segment_iterator it(*this);
++(*this);
return it;
}
// access iterator being adapted
iterator_type base() { return m_it; }
iterator_type base() const { return m_it; }
private:
segment m_cache;
iterator_type m_it;
iterator_type m_prev;
};
template <typename Iterator>
bool operator==(segment_iterator<Iterator> const& lhs,
segment_iterator<Iterator> const& rhs)
{
return (lhs.base() == rhs.base());
}
template <typename Iterator>
bool operator==(segment_iterator<Iterator> const& lhs,
segment_iterator<Iterator> const& rhs)
{
return (lhs.base() != rhs.base());
}
It seems to make sense to have object generator like make_segment_iterator.
What you think about this idea?
> I'm currently busy in core, multi_core and probably some
> (multi)algorithms...
OK, great!
-- Mateusz Loskot, http://mateusz.loskot.net Charter Member of OSGeo, http://osgeo.org
Geometry list run by mateusz at loskot.net