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/Jamfile b/test/Jamfile index 8f72ec7..8604afc 100755 --- a/test/Jamfile +++ b/test/Jamfile @@ -16,25 +16,28 @@ import testing ; # Make tests run by default. DEPENDS all : test ; +local test_monitor = @boost/libs/test/build/boost_test_exec_monitor ; + test-suite utility : [ run ../iterator_traits_test.cpp ] - [ run ../iterators_test.cpp ../../test/build/boost_test_exec_monitor ] + [ run ../iterators_test.cpp $(test_monitor) ] [ compile-fail ../noncopyable_test.cpp ] [ run ../numeric_traits_test.cpp ] - [ run ../operators_test.cpp ../../test/build/boost_test_exec_monitor ] - [ run ../binary_search_test.cpp ../../test/build/boost_test_exec_monitor ] + [ run ../operators_test.cpp $(test_monitor) ] + [ run ../binary_search_test.cpp $(test_monitor) ] [ run ../call_traits_test.cpp : -u ] [ compile-fail ../checked_delete_test.cpp ] - [ run ../compressed_pair_test.cpp ../../test/build/boost_test_exec_monitor : -u ] - [ run ../addressof_test.cpp ../../test/build/boost_test_exec_monitor ] - [ run ../ref_test.cpp ../../test/build/boost_test_exec_monitor ] - [ run ../enable_if_constructors.cpp ../../test/build/boost_test_exec_monitor ] - [ run ../enable_if_dummy_arg_disambiguation.cpp ../../test/build/boost_test_exec_monitor ] - [ run ../enable_if_lazy.cpp ../../test/build/boost_test_exec_monitor ] - [ run ../enable_if_lazy_test.cpp ../../test/build/boost_test_exec_monitor ] - [ run ../enable_if_member_templates.cpp ../../test/build/boost_test_exec_monitor ] - [ run ../enable_if_namespace_disambiguation.cpp ../../test/build/boost_test_exec_monitor ] - [ run ../enable_if_no_disambiguation.cpp ../../test/build/boost_test_exec_monitor ] - [ run ../enable_if_partial_specializations.cpp ../../test/build/boost_test_exec_monitor ] + [ run ../compressed_pair_test.cpp $(test_monitor) : -u ] + [ run ../addressof_test.cpp $(test_monitor) ] + [ run ../ref_test.cpp $(test_monitor) ] + [ run ../enable_if_constructors.cpp $(test_monitor) ] + [ run ../enable_if_dummy_arg_disambiguation.cpp $(test_monitor) ] + [ run ../enable_if_lazy.cpp $(test_monitor) ] + [ run ../enable_if_lazy_test.cpp $(test_monitor) ] + [ run ../enable_if_member_templates.cpp $(test_monitor) ] + [ run ../enable_if_namespace_disambiguation.cpp $(test_monitor) ] + [ run ../enable_if_no_disambiguation.cpp $(test_monitor) ] + [ run ../enable_if_partial_specializations.cpp $(test_monitor) ] + [ run ../next_prior_test.cpp $(test_monitor) ] ; 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; +} diff --git a/utility.htm b/utility.htm index 9f0a6ca..1766d15 100644 --- a/utility.htm +++ b/utility.htm @@ -40,15 +40,33 @@
template <class T>
 T next(T x) { return ++x; }
 
-template <class X>
-T prior(T x) { return --x; }
+template <class T, class Distance> +T next(T x, Distance n) +{ + std::advance(x, n); + return x; +} + +template <class T> +T prior(T x) { return --x; } + +template <class T, class Distance> +T prior(T x, Distance n) +{ + std::advance(x, -n); + return x; +}

Usage is simple:

const std::list<T>::iterator p = get_some_iterator();
-const std::list<T>::iterator prev = boost::prior(p);
+const std::list<T>::iterator prev = boost::prior(p); +const std::list<T>::iterator next = boost::next(prev, 2);
-

Contributed by Dave Abrahams.

+

The distance from the given iterator should be supplied as an absolute value. For + example, the iterator four iterators prior to the given iterator p + may be obtained by prior(p, 4).

+

Contributed by Dave Abrahams. Two-argument versions by Daniel Walker.

Class noncopyable

Class noncopyable is a base class.  Derive your own class from noncopyable when you want to prohibit copy construction @@ -122,7 +140,7 @@ void f() {

See separate documentation.


Revised  01 September, 200323 December, 2003

© Copyright boost.org 1999-2003. Permission to copy, use, modify, sell and distribute