kede
kede

Reputation: 244

Dereference adapter for iterator of pointers

I have a container which is responsible for managing a set of attributes. The class partially looks something like this:

class AttributeSet
{
public:
    // ... interface is irrelevant for my question.

private:
    std::vector<boost::shared_ptr<Attribute> > m_attributes;
};

Attribute is polymorphic so the attributes have to be stored as pointers however they can never be NULL.

I want to use this class with BOOST_FOREACH, like this:

BOOST_FOREACH(const Attribute &attribute, attributeSet)
{
    ...
}

According to BOOST_FOREACH documentation,

The support for STL containers is very general; anything that looks like an STL container counts. If it has nested iterator and const_iterator types and begin() and end() member functions, BOOST_FOREACH will automatically know how to iterate over it.

So I updated my class to look something like this:

class AttributeSet
{
public:
    typedef std::vector<boost::shared_ptr<Attribute> > container;
    typedef container::iterator iterator;
    typedef container::const_iterator const_iterator;

    iterator begin();
    iterator end();

    const_iterator begin() const;
    const_iterator end() const;

private:
    container m_attributes;
};

So now I can do this:

BOOST_FOREACH(const boost::shared_ptr<Attribute> &attribute, attributeSet)
{
    ...
}

This is nice however I don't like that it exposes the attributes as pointers. From the caller side, this is noise and would generate pointless NULL checks.

I have a few ideas on how to correct the problem. For example, something like this would be nice:

class AttributeSet
{
public:
    typedef std::vector<boost::shared_ptr<Attribute> > container;
    typedef iterator_dereference_adapter< container::iterator > iterator;
    typedef iterator_dereference_adapter< container::const_iterator > const_iterator;

    iterator begin() { return iterator(m_attributes.begin()); }
    iterator end() { return iterator(m_attributes.end()); }

    const_iterator begin() const { return const_iterator(m_attributes.begin()); }
    const_iterator end() const { return const_iterator(m_attributes.end()); }

private:
    container m_attributes;
};

The 'iterator_dereference_adapter' class is somewhat self-explanatory. It would wrap an existing iterator of pointers and dereference the pointer values.

So finally, my question...

Before I go off and try to write this adapter, is there something in STL or Boost like this class?

I'm open to other ideas.

Upvotes: 6

Views: 1617

Answers (1)

Casey
Casey

Reputation: 42594

Boost has indirect_iterator which is exactly inteded for wrapping an iterator to pointer type and automatically dereferencing.

Upvotes: 8

Related Questions