boost.png (6897 bytes)

PrevUpHomeNext

Extending BOOST_FOREACH

If you want to use BOOST_FOREACH to iterate over some new collection type, you must "teach" BOOST_FOREACH how to interact with your type. Since BOOST_FOREACH is built on top of Boost.Range, you must extend Boost.Range in order to extend BOOST_FOREACH.

If your collection type presents a standard container interface, you don't need to do anything to make BOOST_FOREACH work with your type. In other words, if your type has iterator and const_iterator nested typedefs, and begin() and end() member functions, BOOST_FOREACH already knows how to iterate over your type. No further action is required.

Below is an example for extending BOOST_FOREACH to iterate over a type which wraps a std::string.

struct StringWrapper
{
    std::string str;
};

namespace boost
{
    // specialize rannge_iterator and range_const_iterator
    template<>
    struct range_iterator<StringWrapper>
    {
        typedef std::string::iterator type;
    };

    template<>
    struct range_const_iterator<StringWrapper>
    {
        typedef std::string::const_iterator type;
    };

    // Overload begin() and end(), both const and non-const versions
    std::string::iterator begin(StringWrapper & w) { return w.str.begin(); }
    std::string::iterator end(StringWrapper & w) { return w.str.end(); }

    std::string::const_iterator begin(StringWrapper const & w) { return w.str.begin(); }
    std::string::const_iterator end(StringWrapper const & w) { return w.str.end(); }
}

Now that you have taught Boost.Range (and hence BOOST_FOREACH) about your type, you can now use BOOST_FOREACH to iterate over your type.

StringWrapper my_string_wrapper;
BOOST_FOREACH( char ch, my_string_wrapper )
{
    // Woo-hoo!
}

There are some portability issues you should be aware of when extending BOOST_FOREACH. Be sure to check out the Portability section.

Copyright © 2004 Eric Niebler

PrevUpHomeNext