From a4bacb5077662b04525e11d5ee67f970375046f4 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 23 Dec 2003 14:59:59 +0000 Subject: [PATCH] Extended next/prior using patch from Daniel Walker (Daniel.Walker-at-bowneglobal.com) [SVN r21382] --- include/boost/next_prior.hpp | 20 +++++++++ test/next_prior_test.cpp | 79 ++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100755 test/next_prior_test.cpp diff --git a/include/boost/next_prior.hpp b/include/boost/next_prior.hpp index d236766..3afeb78 100644 --- a/include/boost/next_prior.hpp +++ b/include/boost/next_prior.hpp @@ -8,9 +8,14 @@ // See http://www.boost.org/libs/utility for documentation. +// Revision History +// 13 Dec 2003 Added next(x, n) and prior(x, n) (Daniel Walker) + #ifndef BOOST_NEXT_PRIOR_HPP_INCLUDED #define BOOST_NEXT_PRIOR_HPP_INCLUDED +#include + namespace boost { // Helper functions for classes like bidirectional iterators not supporting @@ -19,15 +24,30 @@ namespace boost { // Usage: // const std::list::iterator p = get_some_iterator(); // const std::list::iterator prev = boost::prior(p); +// const std::list::iterator next = boost::next(prev, 2); // Contributed by Dave Abrahams template inline T next(T x) { return ++x; } +template +inline T next(T x, Distance n) +{ + std::advance(x, n); + return x; +} + template inline T prior(T x) { return --x; } +template +inline T prior(T x, Distance n) +{ + std::advance(x, -n); + return x; +} + } // namespace boost #endif // BOOST_NEXT_PRIOR_HPP_INCLUDED diff --git a/test/next_prior_test.cpp b/test/next_prior_test.cpp new file mode 100755 index 0000000..ebce472 --- /dev/null +++ b/test/next_prior_test.cpp @@ -0,0 +1,79 @@ +// Boost test program for next() and prior() utilities. + +// Copyright 2003 Daniel Walker. Use, modification, and distribution +// are subject to the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or a copy at +// http://www.boost.org/LICENSE_1_0.txt.) + +// See http://www.boost.org/libs/utility for documentation. + +// Revision History 13 Dec 2003 Initial Version (Daniel Walker) + +// next() and prior() are replacements for operator+ and operator- for +// non-random-access iterators. The semantics of these operators are +// such that after executing j = i + n, std::distance(i, j) equals +// n. Tests are provided to ensure next() has the same +// result. Parallel tests are provided for prior(). The tests call +// next() and prior() several times. next() and prior() are very +// simple functions, though, and it would be very strange if these +// tests were to fail. + +#define BOOST_INCLUDE_MAIN +#include + +#include +#include + +#include + +template +bool plus_one_test(RandomAccessIterator first, RandomAccessIterator last, ForwardIterator first2) +{ + RandomAccessIterator i = first; + ForwardIterator j = first2; + while(i != last) + i = i + 1, j = boost::next(j); + return std::distance(first, i) == std::distance(first2, j); +} + +template +bool plus_n_test(RandomAccessIterator first, RandomAccessIterator last, ForwardIterator first2) +{ + RandomAccessIterator i = first; + ForwardIterator j = first2; + for(int n = 0; i != last; ++n) + i = first + n, j = boost::next(first2, n); + return std::distance(first, i) == std::distance(first2, j); +} + +template +bool minus_one_test(RandomAccessIterator first, RandomAccessIterator last, BidirectionalIterator last2) +{ + RandomAccessIterator i = last; + BidirectionalIterator j = last2; + while(i != first) + i = i - 1, j = boost::prior(j); + return std::distance(i, last) == std::distance(j, last2); +} + +template +bool minus_n_test(RandomAccessIterator first, RandomAccessIterator last, BidirectionalIterator last2) +{ + RandomAccessIterator i = last; + BidirectionalIterator j = last2; + for(int n = 0; i != first; ++n) + i = last - n, j = boost::prior(last2, n); + return std::distance(i, last) == std::distance(j, last2); +} + +int test_main(int, char*[]) +{ + std::vector x(8); + std::list y(x.begin(), x.end()); + + BOOST_REQUIRE(plus_one_test(x.begin(), x.end(), y.begin())); + BOOST_REQUIRE(plus_n_test(x.begin(), x.end(), y.begin())); + BOOST_REQUIRE(minus_one_test(x.begin(), x.end(), y.end())); + BOOST_REQUIRE(minus_n_test(x.begin(), x.end(), y.end())); + return 0; +}