Boost logo

Boost :

From: Keith MacDonald (boost_at_[hidden])
Date: 2003-09-30 09:48:25


Hi Thomas,

Thanks for explaining the differences between iterator_adaptor and
iterator_facade. Clearly, for a new container class, I should have used
iterator_facade, so have rewritten my test accordingly.

I couldn't have begun to tackle the problem without your advice, but even
then I battled with obscure compiler error messages for a long time, before
I got it working. Would you mind taking a critical look at the finished
class (below), to make sure I got it right?

One query I have about the implementation of iterator_facade is why the
iterator -> const_iterator conversion constructors, and the equal and
distance_to members take value, rather than reference parameters. There's
no penalty for basic types, but there is for structs.

Thanks,
Keith MacDonald

[code]

// cont3.h

#include <boost/iterator/iterator_facade.hpp>

class container3
{
public:
    // Iteration:
    class iterator;
    class const_iterator;

    // Read-only iterator:
    typedef boost::iterator_facade< const_iterator,
                                    unsigned char const,
                                    boost::readable_lvalue_iterator_tag,
                                    boost::random_access_traversal_tag
> boost_const_iterator;

    class const_iterator
        : public boost_const_iterator
    {
    public:

        const_iterator()
            { m_pData = NULL; }

        const_iterator(pointer p)
            { m_pData = p; }

        const_iterator(iterator it)
            { m_pData = it.m_pData; }

        friend class iterator;
        friend class boost::iterator_core_access;

    private:
        // Required interface
        reference dereference() const
            { return *m_pData; }

        void increment()
            { ++m_pData; }

        void decrement()
            { --m_pData; }

        bool equal(const_iterator it) const
            { return m_pData == it.m_pData; }

        void advance(difference_type n)
            { m_pData += n; }

        difference_type distance_to(const_iterator it) const
            { return it.m_pData - m_pData; }

    protected:
        pointer m_pData;
    };

    // Read-write iterator:
    typedef boost::iterator_facade< iterator,
                                    unsigned char,
                                    boost::writable_lvalue_iterator_tag,
                                    boost::random_access_traversal_tag
> boost_iterator;

    class iterator
        : public boost_iterator
    {
    public:

        iterator()
            { m_pData = NULL; }

        iterator(pointer p)
            { m_pData = p; }

        iterator(const_iterator it)
            { m_pData = const_cast<pointer>(it.m_pData); }

        friend class const_iterator;
        friend class boost::iterator_core_access;

    private:
        // Required interface
        reference dereference() const
            { return *m_pData; }

        void increment()
            { ++m_pData; }

        void decrement()
            { --m_pData; }

        bool equal(iterator it) const
            { return m_pData == it.m_pData; }

        void advance(difference_type n)
            { m_pData += n; }

        difference_type distance_to(iterator it) const
            { return it.m_pData - m_pData; }

    protected:
        pointer m_pData;
    };

public:
    // The container interface:

    container3()
    {
        for (int i = 0; i < sizeof(m_buf); ++i)
            m_buf[i] = i;
    }

    const_iterator begin() const
        { return const_iterator(m_buf); }

    const_iterator end() const
        { return const_iterator(m_buf + sizeof(m_buf)); }

    iterator begin()
        { return iterator(m_buf); }

    iterator end()
        { return iterator(m_buf + sizeof(m_buf)); }

private:
    unsigned char m_buf[256];
};

[/code]

"Thomas Witt" <witt_at_[hidden]> wrote in message
news:3F786AA6.9040803_at_acm.org...
>
> Hi Keith,
>
> I'll try to explain where the boost iterator library fits into this
> picture. The boost iterator library aka iterator adaptor provides
> facilities to ease the implementation of new iterators and the adaption
> of existing ones.
>
> If you need to create a new iterator that's state is not already an
> iterator or is sufficiently iterator like iterator_facade is the way to
> go. iterator_facade provides the full blown iterator interfaces, taking
> care of all the nitty gritty details. iterator_facade forwards all calls
> to the iterator interface to up to six core operations that need to be
> implemented in the user's class. The actual number of core operations
> needed depends on the iterator category.
>
<snip>
>
> HTH
>
> Thomas
>
>
> _______________________________________________
> Unsubscribe & other changes:
http://lists.boost.org/mailman/listinfo.cgi/boost
>


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