Boost logo

Boost :

From: Ion Gaztañaga (igaztanaga_at_[hidden])
Date: 2006-04-09 10:59:12


Hi to all,

  Trying to simplify containers' code in Boost.Interprocess, I've seen
that an iterator that simulates a range of values from a single value is
useful to implement functions taking a value and a count in containers:

template<class T, class A>
class vector
{
    //...
    void insert (iterator position, size_type n, const T& x);
    void assign (size_type n, const T& x);
};

My intention was to reuse the code for "insert" and "assign" taking
iterators to avoid nearly duplicating the code (which is quite complex
in vector, deque and basic_string). This way, I've created
an iterator called "range_from_ref_iterator" that can be used to
implement the "insert" function taking a value and a count like this:

void insert (iterator position, size_type n, const T& x)
{
    this->insert(position
                ,range_from_ref_iterator<const T>(x, n)
                ,range_from_ref_iterator<const T>());
}

This iterator is a random access traversal iterator, that I only would
use as read iterator but I'm not sure if it would fill write iterator
requirements.

The code to implement the iterator:

template <class T, class Difference = std::ptrdiff_t>
class range_from_ref_iterator
    : public boost::iterator_facade
          < range_from_ref_iterator<T>
          , T
          , boost::random_access_traversal_tag
          , T &
          , Difference>
{
    typedef boost::iterator_facade
          < range_from_ref_iterator<T>
          , T
          , boost::random_access_traversal_tag> super_t;

    typedef range_from_ref_iterator<T> this_type;

    //Give access to private core functions
    friend class boost::iterator_core_access;

    public:
    explicit range_from_ref_iterator(T &ref, Difference range_size)
       : m_ptr(&ref), m_num(range_size){}

    //This constructor creates a "end" iterator
    range_from_ref_iterator()
       : m_ptr(0), m_num(0){}

    private:
    T * m_ptr;
    Difference m_num;

    void increment()
    { --m_num; }

    void decrement()
    { ++m_num; }

    bool equal(const this_type &other) const
    { return m_num == other.m_num; }

    T & dereference() const
    { return *m_ptr; }

    void advance(Difference n)
    { m_num -= n; }

    Difference distance_to(const this_type &other)const
    { return m_num - other.m_num; }
};

Do you think this iterator is a good addition to boost iterator library?
Obviously it can be more refined. It could take the external value by
reference or store a copy depending on the type. But I think it can be
useful. I'm open to write the documentation following Boost.Iterator
style if this iterator is considered useful (I'm open also to let others
do the hard work, of course). Comments?

Regards,

Ion


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk