From 62b39548be3d8e07ab06ff9a05b1ff499ed62b40 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sat, 26 Aug 2017 17:25:14 +0300 Subject: [PATCH] Moved next/prior to Boost.Iterator. --- include/boost/next_prior.hpp | 189 ----------------------------------- index.html | 2 +- test/Jamfile.v2 | 2 - test/next_prior_test.cpp | 104 ------------------- utility.htm | 41 +------- 5 files changed, 2 insertions(+), 336 deletions(-) delete mode 100644 include/boost/next_prior.hpp delete mode 100644 test/next_prior_test.cpp diff --git a/include/boost/next_prior.hpp b/include/boost/next_prior.hpp deleted file mode 100644 index 178cf67..0000000 --- a/include/boost/next_prior.hpp +++ /dev/null @@ -1,189 +0,0 @@ -// Boost next_prior.hpp header file ---------------------------------------// - -// (C) Copyright Dave Abrahams and Daniel Walker 1999-2003. -// Copyright (c) Andrey Semashev 2017 -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// 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 -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { - -// Helper functions for classes like bidirectional iterators not supporting -// operator+ and operator- -// -// 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 - -namespace next_prior_detail { - -// The trait attempts to detect if the T type is an iterator. Class-type iterators are assumed -// to have the nested type iterator_category. Strictly speaking, this is not required to be the -// case (e.g. a user can specialize iterator_traits for T without defining T::iterator_category). -// Still, this is a good heuristic in practice, and we can't do anything better anyway. -// Since C++17 we can test for iterator_traits::iterator_category presence instead as it is -// required to be only present for iterators. -template< typename T, typename Void = void > -struct is_iterator -{ - static BOOST_CONSTEXPR_OR_CONST bool value = false; -}; - -template< typename T > -struct is_iterator< - T, - typename enable_if_has_type< -#if !defined(BOOST_NO_CXX17_ITERATOR_TRAITS) - typename std::iterator_traits< T >::iterator_category -#else - typename T::iterator_category -#endif - >::type -> -{ - static BOOST_CONSTEXPR_OR_CONST bool value = true; -}; - -template< typename T > -struct is_iterator< T*, void > -{ - static BOOST_CONSTEXPR_OR_CONST bool value = true; -}; - - -template< typename T, typename Distance, bool HasPlus = has_plus< T, Distance >::value > -struct next_plus_impl; - -template< typename T, typename Distance > -struct next_plus_impl< T, Distance, true > -{ - static T call(T x, Distance n) - { - return x + n; - } -}; - -template< typename T, typename Distance, bool HasPlusAssign = has_plus_assign< T, Distance >::value > -struct next_plus_assign_impl : - public next_plus_impl< T, Distance > -{ -}; - -template< typename T, typename Distance > -struct next_plus_assign_impl< T, Distance, true > -{ - static T call(T x, Distance n) - { - x += n; - return x; - } -}; - -template< typename T, typename Distance, bool IsIterator = is_iterator< T >::value > -struct next_advance_impl : - public next_plus_assign_impl< T, Distance > -{ -}; - -template< typename T, typename Distance > -struct next_advance_impl< T, Distance, true > -{ - static T call(T x, Distance n) - { - boost::iterators::advance(x, n); - return x; - } -}; - - -template< typename T, typename Distance, bool HasMinus = has_minus< T, Distance >::value > -struct prior_minus_impl; - -template< typename T, typename Distance > -struct prior_minus_impl< T, Distance, true > -{ - static T call(T x, Distance n) - { - return x - n; - } -}; - -template< typename T, typename Distance, bool HasMinusAssign = has_minus_assign< T, Distance >::value > -struct prior_minus_assign_impl : - public prior_minus_impl< T, Distance > -{ -}; - -template< typename T, typename Distance > -struct prior_minus_assign_impl< T, Distance, true > -{ - static T call(T x, Distance n) - { - x -= n; - return x; - } -}; - -template< typename T, typename Distance, bool IsIterator = is_iterator< T >::value > -struct prior_advance_impl : - public prior_minus_assign_impl< T, Distance > -{ -}; - -template< typename T, typename Distance > -struct prior_advance_impl< T, Distance, true > -{ - static T call(T x, Distance n) - { - // Avoid negating n to sidestep possible integer overflow - boost::iterators::reverse_iterator< T > rx(x); - boost::iterators::advance(rx, n); - return rx.base(); - } -}; - -} // namespace next_prior_detail - -template -inline T next(T x) { return ++x; } - -template -inline T next(T x, Distance n) -{ - return next_prior_detail::next_advance_impl< T, Distance >::call(x, n); -} - -template -inline T prior(T x) { return --x; } - -template -inline T prior(T x, Distance n) -{ - return next_prior_detail::prior_advance_impl< T, Distance >::call(x, n); -} - -} // namespace boost - -#endif // BOOST_NEXT_PRIOR_HPP_INCLUDED diff --git a/index.html b/index.html index 493be93..689ae95 100644 --- a/index.html +++ b/index.html @@ -25,7 +25,7 @@ in_place_factory
iterator_adaptors
generator iterator adaptors
- next/prior
+ next/prior (moved to the Boost.Iterator library)
noncopyable (moved to the Boost.Core library)
operators
result_of
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 6708c47..22a616a 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -24,8 +24,6 @@ run compressed_pair_test.cpp ../../test/build//boost_test_exec_monitor/sta run iterators_test.cpp ../../test/build//boost_test_exec_monitor/static ; -run next_prior_test.cpp ../../test/build//boost_test_exec_monitor/static ; - run numeric_traits_test.cpp ; run operators_test.cpp ../../test/build//boost_test_exec_monitor/static ; diff --git a/test/next_prior_test.cpp b/test/next_prior_test.cpp deleted file mode 100644 index cd2812f..0000000 --- a/test/next_prior_test.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// 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); -} - -template -bool minus_n_unsigned_test(Iterator first, Iterator last, Distance size) -{ - Iterator i = boost::prior(last, size); - return i == first; -} - -int test_main(int, char*[]) -{ - std::vector x(8); - std::list y(x.begin(), x.end()); - - // Tests with iterators - 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())); - BOOST_REQUIRE(minus_n_unsigned_test(x.begin(), x.end(), x.size())); - BOOST_REQUIRE(minus_n_unsigned_test(y.begin(), y.end(), y.size())); - - BOOST_REQUIRE(plus_one_test(x.rbegin(), x.rend(), y.begin())); - BOOST_REQUIRE(plus_n_test(x.rbegin(), x.rend(), y.begin())); - BOOST_REQUIRE(minus_one_test(x.rbegin(), x.rend(), y.end())); - BOOST_REQUIRE(minus_n_test(x.rbegin(), x.rend(), y.end())); - BOOST_REQUIRE(minus_n_unsigned_test(x.rbegin(), x.rend(), x.size())); - BOOST_REQUIRE(minus_n_unsigned_test(x.rbegin(), x.rend(), y.size())); - - // Tests with integers - BOOST_REQUIRE(boost::next(5) == 6); - BOOST_REQUIRE(boost::next(5, 7) == 12); - BOOST_REQUIRE(boost::prior(5) == 4); - BOOST_REQUIRE(boost::prior(5, 7) == -2); - BOOST_REQUIRE(boost::prior(5, 7u) == -2); - - return 0; -} diff --git a/utility.htm b/utility.htm index 5443bd4..62a81a1 100644 --- a/utility.htm +++ b/utility.htm @@ -17,7 +17,7 @@ Function templates checked_delete() and checked_array_delete() (moved to the Boost.Core library)
  • - Function templates next() and prior()
  • + Function templates next() and prior() (moved to the Boost.Iterator library)
  • Class noncopyable (moved to the Boost.Core library)
  • @@ -28,45 +28,6 @@
  • Other utilities not part of utility.hpp
  • - Function templates next() and prior()

    -

    Certain data types, such as the C++ Standard Library's forward and bidirectional - iterators, do not provide addition and subtraction via operator+() or - operator-().  This means that non-modifying computation of the next or - prior value requires a temporary, even though operator++() or operator--() is - provided.  It also means that writing code like itr+1 inside - a template restricts the iterator category to random access iterators.

    -

    The next() and prior() functions provide a simple way around these problems:

    -
    -
    template <class T>
    -T next(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 next = boost::next(prev, 2);
    -
    -

    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 template result_of

    The class template