C
c.m.
Hi,
I'm implementing a multidimensional array class and I want to let the
user call algorithms like std::sort along any dimension. As an example,
users shall be able to sort a 2D array along the columns as well as the
rows.
So in most cases the elements to be sorted will not be laid out
contiguously in memory. To work around this, the O'Reilly C++ Cookbook
introduces the StrideIterator Template that adapts another iterator.
Here's the gist of it:
StrideIterator(RandomAccessIterator iterToAdapt, difference_type step) :
adaptedIter(iterToAdapt),
step(step)
{
}
self& operator++()
{
adaptedIter += step;
return *this;
}
The trouble with this is the one-past-the-last-element semantics for
specifying the end of a sequence. The last ++iter call would make the
underlying pointer point outside the array. According to 5.7.5 of the
standard, the behaviour of the += step addition is undefined in that
case. With VC2008 it fails an assertion when adapting a
std::vector::iterator.
Is there an elegant way to make this work? Obviously, one could put an
if (underlyingArray.end() - adaptedIter < step) {
adaptedIter = underlyingArray.end();
return;
}
into operator++ to "clamp" the iterator to one-past-the-last-element but
from a performance point-of-view, having a conditional in there is not
an attractive solution.
Thanks,
Chris
I'm implementing a multidimensional array class and I want to let the
user call algorithms like std::sort along any dimension. As an example,
users shall be able to sort a 2D array along the columns as well as the
rows.
So in most cases the elements to be sorted will not be laid out
contiguously in memory. To work around this, the O'Reilly C++ Cookbook
introduces the StrideIterator Template that adapts another iterator.
Here's the gist of it:
StrideIterator(RandomAccessIterator iterToAdapt, difference_type step) :
adaptedIter(iterToAdapt),
step(step)
{
}
self& operator++()
{
adaptedIter += step;
return *this;
}
The trouble with this is the one-past-the-last-element semantics for
specifying the end of a sequence. The last ++iter call would make the
underlying pointer point outside the array. According to 5.7.5 of the
standard, the behaviour of the += step addition is undefined in that
case. With VC2008 it fails an assertion when adapting a
std::vector::iterator.
Is there an elegant way to make this work? Obviously, one could put an
if (underlyingArray.end() - adaptedIter < step) {
adaptedIter = underlyingArray.end();
return;
}
into operator++ to "clamp" the iterator to one-past-the-last-element but
from a performance point-of-view, having a conditional in there is not
an attractive solution.
Thanks,
Chris