Use Boost.Iterator to advance iterators.

By using Boost.Iterator we rely on the separate traversal category instead of
the standard iterator category to advance iterators efficiently. For instance,
this allows to advance transform iterators over a random access sequence
in constant time, despite that they are formally input iterators.

Also, std::reverse_iterator formally requires at least bidirectional iterator
as the underlying iterator type. Transform iterators from the example above
don't qualify, so potentially std::reverse_iterator could fail to compile.
This commit is contained in:
Andrey Semashev 2017-07-12 21:08:13 +03:00
parent 5bc9e47688
commit e25d85446e

View File

@ -22,6 +22,8 @@
#include <boost/type_traits/has_plus_assign.hpp> #include <boost/type_traits/has_plus_assign.hpp>
#include <boost/type_traits/has_minus.hpp> #include <boost/type_traits/has_minus.hpp>
#include <boost/type_traits/has_minus_assign.hpp> #include <boost/type_traits/has_minus_assign.hpp>
#include <boost/iterator/advance.hpp>
#include <boost/iterator/reverse_iterator.hpp>
namespace boost { namespace boost {
@ -101,7 +103,7 @@ struct next_advance_impl< T, Distance, true >
{ {
static T call(T x, Distance n) static T call(T x, Distance n)
{ {
std::advance(x, n); boost::iterators::advance(x, n);
return x; return x;
} }
}; };
@ -147,8 +149,8 @@ struct prior_advance_impl< T, Distance, true >
static T call(T x, Distance n) static T call(T x, Distance n)
{ {
// Avoid negating n to sidestep possible integer overflow // Avoid negating n to sidestep possible integer overflow
std::reverse_iterator< T > rx(x); boost::iterators::reverse_iterator< T > rx(x);
std::advance(rx, n); boost::iterators::advance(rx, n);
return rx.base(); return rx.base();
} }
}; };