$include_dir="/home/hyper-archives/geometry/include"; include("$include_dir/msg-header.inc") ?>
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