Hello list,
I have created a generic iterator template class for arrays that also
doubles as container-wrapper for the array in question. To achieve this
I have based my class on boost::iterator_facade . I have defined all the
neccessary functions as described in the documentation and mostly the
iterators work as intended.
Here's a cut-down version:
#include
#include
#include
template<class Value>
class cArrayIterator : public boost::iterator_facade<
cArrayIterator<Value>
, Value
, boost::random_access_traversal_tag
>
{
private:
struct enabler {};
public:
cArrayIterator()
: first(0),size(0),position(0) {}
cArrayIterator(Value* _first, difference_type _size,
difference_type _position = 0)
: first(_first),size(_size),position(_position) {}
template<class OtherValue>
cArrayIterator(
const cArrayIterator<OtherValue>& other
, typename boost::enable_if<
boost::is_convertible
, enabler
>::type = enabler()
)
:
first(other.first),size(other.size),position(other.position) {}
private:
Value* first;
difference_type position;
difference_type size;
friend class boost::iterator_core_access;
void advance(difference_type n){
position += n;
}
void decrement(){
--position;
}
Value& dereference() const{
return first[position];
}
template<class OtherValue>
difference_type distance_to(const cArrayIterator<OtherValue>& z)
const{
return z.position - this->position;
}
template<class OtherValue>
bool equal(const cArrayIterator<OtherValue>& other) const{
return this->first + this->position == other.first +
other.position;
}
void increment(){
++position;
}
};
I have a big problem though: The project I am working on is quite big
and I intend to replace a particular typedef (currently simply a pointer
to a struct) with this iterator class. There are two kinds of
instructions though that my iterator class currently can't cope with:
1. Initializing a 'pointer' with NULL (in other words, I need a
constructor with one argument of type int, but only in case that
argument's value is 0)
2. Comparing a 'pointer' to NULL (again, comparison to int argument, but
only makes sense for the value 0)
I did add a constructor with only one argument (of type pointer to the
underlying object's type) and could eliminate problem 1. However I feel
it's not quite right, since for my array iterator it doesn't make any
sense to initialize it with just one pointer and no further information
(it requires pointer to first element, position, and size of array), so
in cases where the pointer argument is not NULL this constructor
shouldn't even be available!
Here's the code for the new constructor:
cArrayIterator(Value* _first) // workaround
: first(_first),position(0)
{
if (NULL == _first)
size = 0;
else
size = 1; // not really sensible, but the best I can think
of atm
}
Moreover, I hoped this constructor would also eliminate problem 2 by
implicitely converting the int value of 0 to a NULL iterator, but it
didn't. I tried to provide my own comparison operators, but so far
failed to meet the syntax the compiler would recognize as a fit for a
comparison int to iterator.
This is what I got so far:
template <class Value>
bool operator==(cArrayIterator<const Value> const left,
cArrayIterator<Value> const right)
{
return false;// I'll take care of that once the function gets
actually called :/
}
How do I correctly define a comparison operator that compares a 'NULL
pointer' to a class representing a pointer? Or does iterator_facade
already provide a way to deal with this?
Stefan