Skip to content

Instantly share code, notes, and snippets.

@taskie
Last active August 29, 2015 14:19
Show Gist options
  • Save taskie/2f92a70a18735b56d63d to your computer and use it in GitHub Desktop.
Save taskie/2f92a70a18735b56d63d to your computer and use it in GitHub Desktop.
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4317.pdf
#include <iterator>
namespace n4317
{
namespace internal
{
template <typename RanIter, typename Dist>
void advance_helper(RanIter & i, RanIter e, Dist n, std::random_access_iterator_tag)
{
auto maxd = e - i;
if ((n > 0 && maxd < n) || (n < 0 && maxd > n)) i = e;
else i += n;
}
template <typename InpIter, typename Dist>
void advance_helper(InpIter & i, InpIter e, Dist n, std::input_iterator_tag)
{
for (; 0 < n && i != e; --n) ++i;
}
template <typename BiIter, typename Dist>
void advance_helper(BiIter & i, BiIter e, Dist n, std::bidirectional_iterator_tag)
{
for (; 0 < n && i != e; --n) ++i;
for (; n < 0 && i != e; ++n) --i;
}
}
template <typename Iter>
void advance(Iter & i, Iter e, typename std::iterator_traits<Iter>::difference_type n)
{
typedef typename std::iterator_traits<Iter>::iterator_category Cat;
internal::advance_helper(i, e, n, Cat{});
}
template <typename Iter>
Iter next(Iter i, Iter e, typename std::iterator_traits<Iter>::difference_type n = 1)
{
advance(i, e, n);
return i;
}
template <typename Iter>
Iter prev(Iter i, Iter e, typename std::iterator_traits<Iter>::difference_type n = 1)
{
advance(i, e, -n);
return i;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment