
Boost : 
From: Bjorn.Karlsson_at_[hidden]
Date: 20040223 04:44:17
> From: Daniel Frey [mailto:daniel.frey_at_[hidden]]
>
> // A strange way to retrieve my_container.begin():
> boost::prior( my_container.end(), my_container.size() );
>
> Is that legal? The second template parameter of boost::prior
> is deduced
> to an unsigned(!) type, which IMHO means that n is
> undefined, right? Do
> we need to fix this?
It's both legal and well defined, but perhaps not very intuitive...
For unary minus, the negative of an unsigned is computed as 2^nv (where n
is the number of bits in the type yielded by performing integral promotion
on the operand and v is the value of the operand [5.3.1/7]). The resulting
type is the promoted operand; this means that unsigned char and unsigned
short will typically work as expected with boost::prior (those types can be
promoted to int on most [all?] platforms), whereas unsigned int and unsigned
long will always return a positive value (because here, the resulting type
of integral promotion is the type of the operand, and the result of the
unary  operator is therefore 2^nv).
So, the effect of this is that the example above is valid, but the resulting
iterator is pasttheend, typically way too far to ever be seen again...and
the name 'prior' thus becomes misleading for certain types.
> or shall we document that it's illegal/undefined to call
> boost::prior()
> with an unsigned second parameter?
I think Dave's suggestion of using reverse_iterator would be cool; that also
adds a good reason for using boost::prior rather than std::advance for
decrementing.
Something like this should work:
template <class T, class Distance>
inline T prior(T x, Distance n)
{
return next(std::reverse_iterator<T>(x),n).base();
}
(Daniel, good work spotting this issue!)
Bjorn Karlsson
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk