The Boost iterator_adaptor
can greatly simplify your code. The documentation has e.g. this example for a linked list iterator
template <class Value>
class node_iter
: public boost::iterator_adaptor<
node_iter<Value> // Derived
, Value* // Base
, boost::use_default // Value
, boost::forward_traversal_tag // CategoryOrTraversal
>
{
private:
struct enabler {}; // a private type avoids misuse
public:
node_iter()
: node_iter::iterator_adaptor_(0) {}
explicit node_iter(Value* p)
: node_iter::iterator_adaptor_(p) {}
template <class OtherValue>
node_iter(
node_iter<OtherValue> const& other
, typename boost::enable_if<
boost::is_convertible<OtherValue*,Value*>
, enabler
>::type = enabler()
)
: node_iter::iterator_adaptor_(other.base()) {}
private:
friend class boost::iterator_core_access;
void increment() { this->base_reference() = this->base()->next(); }
};
Note that the example only provides a default constructor, a constructor taking a node pointer, a generalized copy constructor that only accepts elements that can be converted to a node pointer, and an increment function. The increment function is an implementation detail that is shared by both operator++()
and operator++(int)
.
All the other boiler-plate is automatically being generated by deriving from boost::iterator_adaptor
. That includes all the nested typedef
that you could also get from deriving from std::iterator
, as well as all the overloaded operators (++, *, ->, ==, !=, advance) and anything else to make it a fully Standard conforming iterator.
By passing a Value const*
and using a typedef
you can define a const_iterator
that reuses all your code with the appropriate modifications. Studying the example now will save you enormously down the road.