From 651a869d4f9479dd3dfdd0293305a60b8c8d0e1c Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Tue, 24 Jun 2014 01:05:32 +0400 Subject: [PATCH 1/4] Reworked next() and prior() taking the distance arguments. The new version should provide the expected behavior in the case (prior(v.end(), v.size()) == v.begin()). It should also work with integers now, as was originally intended by David Abrahams. Added tests to verify these new use cases. --- include/boost/next_prior.hpp | 122 +++++++++++++++++++++++++++++++++-- test/next_prior_test.cpp | 18 ++++++ 2 files changed, 136 insertions(+), 4 deletions(-) diff --git a/include/boost/next_prior.hpp b/include/boost/next_prior.hpp index e1d2e42..7854ec4 100644 --- a/include/boost/next_prior.hpp +++ b/include/boost/next_prior.hpp @@ -13,6 +13,17 @@ #define BOOST_NEXT_PRIOR_HPP_INCLUDED #include +#if defined(_MSC_VER) && _MSC_VER <= 1310 +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include namespace boost { @@ -26,14 +37,118 @@ namespace boost { // Contributed by Dave Abrahams +namespace next_prior_detail { + +template< typename T, typename Distance, bool HasPlus = has_plus< T, Distance >::value > +struct next_impl2 +{ + static T call(T x, Distance n) + { + std::advance(x, n); + return x; + } +}; + +template< typename T, typename Distance > +struct next_impl2< 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_impl1 : + public next_impl2< T, Distance > +{ +}; + +template< typename T, typename Distance > +struct next_impl1< T, Distance, true > +{ + static T call(T x, Distance n) + { + x += n; + return x; + } +}; + + +template< + typename T, + typename Distance, + typename PromotedDistance = typename integral_promotion< Distance >::type, +#if !defined(_MSC_VER) || _MSC_VER > 1310 + bool IsUInt = is_unsigned< PromotedDistance >::value +#else + // MSVC 7.1 has problems with applying is_unsigned to non-integral types + bool IsUInt = mpl::and_< is_integral< PromotedDistance >, is_unsigned< PromotedDistance > >::value +#endif +> +struct prior_impl3 +{ + static T call(T x, Distance n) + { + std::advance(x, -n); + return x; + } +}; + +template< typename T, typename Distance, typename PromotedDistance > +struct prior_impl3< T, Distance, PromotedDistance, true > +{ + static T call(T x, Distance n) + { + typedef typename make_signed< PromotedDistance >::type signed_distance; + std::advance(x, -static_cast< signed_distance >(static_cast< PromotedDistance >(n))); + return x; + } +}; + + +template< typename T, typename Distance, bool HasMinus = has_minus< T, Distance >::value > +struct prior_impl2 : + public prior_impl3< T, Distance > +{ +}; + +template< typename T, typename Distance > +struct prior_impl2< 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_impl1 : + public prior_impl2< T, Distance > +{ +}; + +template< typename T, typename Distance > +struct prior_impl1< T, Distance, true > +{ + static T call(T x, Distance n) + { + x -= n; + return x; + } +}; + +} // namespace next_prior_detail + template inline T next(T x) { return ++x; } template inline T next(T x, Distance n) { - std::advance(x, n); - return x; + return next_prior_detail::next_impl1< T, Distance >::call(x, n); } template @@ -42,8 +157,7 @@ inline T prior(T x) { return --x; } template inline T prior(T x, Distance n) { - std::advance(x, -n); - return x; + return next_prior_detail::prior_impl1< T, Distance >::call(x, n); } } // namespace boost diff --git a/test/next_prior_test.cpp b/test/next_prior_test.cpp index ebce472..4f9b01a 100644 --- a/test/next_prior_test.cpp +++ b/test/next_prior_test.cpp @@ -66,14 +66,32 @@ bool minus_n_test(RandomAccessIterator first, RandomAccessIterator last, Bidirec 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())); + + // 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; } From 520dff92707da4f912ddad129736dded443b036c Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 30 Jun 2014 22:57:48 +0100 Subject: [PATCH 2/4] Add a redirect for the compressed pair docs. --- compressed_pair.htm | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 compressed_pair.htm diff --git a/compressed_pair.htm b/compressed_pair.htm new file mode 100644 index 0000000..0b99bf7 --- /dev/null +++ b/compressed_pair.htm @@ -0,0 +1,16 @@ + + + + + + + + +Automatic redirection failed, please go to +doc/html/compressed_pair.html + + From 45226031325a60d7e9740601afa18e06c8907390 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Mon, 18 Aug 2014 15:12:15 +0100 Subject: [PATCH 3/4] Add metadata file. --- meta/libraries.json | 131 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 meta/libraries.json diff --git a/meta/libraries.json b/meta/libraries.json new file mode 100644 index 0000000..9215b0a --- /dev/null +++ b/meta/libraries.json @@ -0,0 +1,131 @@ +[ + { + "key": "utility", + "name": "Utility", + "authors": [ + "Dave Abrahams and others" + ], + "description": "Class noncopyable plus checked_delete(), checked_array_delete(), next(), prior() function templates, plus base-from-member idiom.", + "documentation": "utility.htm", + "category": [ + "Algorithms", + "Function-objects", + "Memory", + "Miscellaneous", + "Patterns" + ] + }, + { + "key": "utility/call_traits", + "name": "Call Traits", + "authors": [ + "John Maddock, Howard Hinnant, et al" + ], + "description": "Defines types for passing parameters.", + "documentation": "call_traits.htm", + "category": [ + "Generic" + ] + }, + { + "key": "utility/compressed_pair", + "name": "Compressed Pair", + "authors": [ + "John Maddock, Howard Hinnant, et al" + ], + "description": "Empty member optimization.", + "documentation": "compressed_pair.htm", + "category": [ + "Data", + "Patterns" + ] + }, + { + "key": "utility/enable_if", + "name": "Enable If", + "authors": [ + "Jaakko J\u00e4rvi", + "Jeremiah Willcock", + "Andrew Lumsdaine" + ], + "description": "Selective inclusion of function template overloads.", + "documentation": "enable_if.html", + "category": [ + "Generic" + ], + "maintainers": [ + "Jaakko Jarvi ", + "Jeremiah Willcock " + ] + }, + { + "key": "utility/identity_type", + "name": "Identity Type", + "authors": [ + "Lorenzo Caminiti" + ], + "description": "Wrap types within round parenthesis so they can always be passed as macro parameters.", + "documentation": "identity_type/", + "category": [ + "Preprocessor" + ], + "maintainers": [ + "Lorenzo Caminiti " + ] + }, + { + "key": "utility/in_place_factories", + "name": "In Place Factory, Typed In Place Factory", + "authors": [ + "Fernando Cacciola" + ], + "description": "Generic in-place construction of contained objects with a variadic argument-list.", + "documentation": "in_place_factories.html", + "category": [ + "Generic" + ] + }, + { + "key": "utility/operators", + "name": "Operators", + "authors": [ + "Dave Abrahams", + "Jeremy Siek" + ], + "description": "Templates ease arithmetic classes and iterators.", + "documentation": "operators.htm", + "category": [ + "Generic", + "Iterators", + "Math" + ], + "maintainers": [ + "Daniel Frey " + ] + }, + { + "key": "utility/result_of", + "name": "Result Of", + "description": "Determines the type of a function call expression.", + "documentation": "utility.htm#result_of", + "category": [ + "Function-objects" + ], + "authors": "", + "maintainers": [ + "Daniel Walker " + ] + }, + { + "key": "utility/value_initialized", + "name": "Value Initialized", + "authors": [ + "Fernando Cacciola" + ], + "description": "Wrapper for uniform-syntax value initialization, based on the original idea of David Abrahams.", + "documentation": "value_init.htm", + "category": [ + "Miscellaneous" + ] + } +] From 492fd7f091c73494fb0062de586adc792f97c141 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Mon, 18 Aug 2014 18:57:40 +0400 Subject: [PATCH 4/4] Moved enable_if to Boost.Core. --- meta/libraries.json | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/meta/libraries.json b/meta/libraries.json index 9215b0a..5674daf 100644 --- a/meta/libraries.json +++ b/meta/libraries.json @@ -40,24 +40,6 @@ "Patterns" ] }, - { - "key": "utility/enable_if", - "name": "Enable If", - "authors": [ - "Jaakko J\u00e4rvi", - "Jeremiah Willcock", - "Andrew Lumsdaine" - ], - "description": "Selective inclusion of function template overloads.", - "documentation": "enable_if.html", - "category": [ - "Generic" - ], - "maintainers": [ - "Jaakko Jarvi ", - "Jeremiah Willcock " - ] - }, { "key": "utility/identity_type", "name": "Identity Type",