diff --git a/include/boost/range/algorithm/unique.hpp b/include/boost/range/algorithm/unique.hpp index 9901c24..8017a83 100644 --- a/include/boost/range/algorithm/unique.hpp +++ b/include/boost/range/algorithm/unique.hpp @@ -86,14 +86,14 @@ unique( const ForwardRange& rng ) /// \overload template< class ForwardRange, class BinaryPredicate > inline BOOST_DEDUCED_TYPENAME range_return::type -unique( ForwardRange& rng, BinaryPredicate ) +unique( ForwardRange& rng, BinaryPredicate pred ) { BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); - return ::boost::range::unique(rng); + return ::boost::range::unique(rng, pred); } /// \overload template< class ForwardRange, class BinaryPredicate > -inline BOOST_DEDUCED_TYPENAME range_iterator::type +inline BOOST_DEDUCED_TYPENAME range_return::type unique( const ForwardRange& rng, BinaryPredicate pred ) { BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept )); diff --git a/include/boost/range/config.hpp b/include/boost/range/config.hpp old mode 100755 new mode 100644 index 4e7fb24..cf9e204 --- a/include/boost/range/config.hpp +++ b/include/boost/range/config.hpp @@ -48,6 +48,12 @@ #define BOOST_RANGE_ARRAY_REF() (&boost_range_array) #endif +#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7))) +# define BOOST_RANGE_UNUSED __attribute__((unused)) +#else +# define BOOST_RANGE_UNUSED +#endif + #endif diff --git a/test/adaptor_test/strided.cpp b/test/adaptor_test/strided.cpp index aa80068..b49cfc6 100644 --- a/test/adaptor_test/strided.cpp +++ b/test/adaptor_test/strided.cpp @@ -13,6 +13,7 @@ // #include +#include #include #include @@ -42,9 +43,12 @@ namespace boost Container reference; { - typedef BOOST_DEDUCED_TYPENAME Container::const_iterator iterator_t; - typedef BOOST_DEDUCED_TYPENAME Container::difference_type diff_t; - typedef BOOST_DEDUCED_TYPENAME Container::size_type size_type; + typedef BOOST_DEDUCED_TYPENAME Container::const_iterator + iterator_t BOOST_RANGE_UNUSED; + typedef BOOST_DEDUCED_TYPENAME Container::difference_type + diff_t BOOST_RANGE_UNUSED; + typedef BOOST_DEDUCED_TYPENAME Container::size_type + size_type BOOST_RANGE_UNUSED; iterator_t it = c.begin(); iterator_t last = c.end(); diff --git a/test/algorithm.cpp b/test/algorithm.cpp index 1c0dbc3..2160eaf 100644 --- a/test/algorithm.cpp +++ b/test/algorithm.cpp @@ -35,6 +35,7 @@ #endif #include +#include #include #include #include @@ -107,9 +108,11 @@ void test_random_algorithms(Rng & rng, std::random_access_iterator_tag) { typedef BOOST_DEDUCED_TYPENAME boost::range_iterator::type iterator; typedef BOOST_DEDUCED_TYPENAME boost::range_value::type value_type; - typedef BOOST_DEDUCED_TYPENAME boost::range_size::type size_type; + typedef BOOST_DEDUCED_TYPENAME boost::range_size::type size_type BOOST_RANGE_UNUSED; typedef BOOST_DEDUCED_TYPENAME boost::iterator_category::type iterator_category; + + // just make sure these compile (for now) if(0) { @@ -328,6 +331,8 @@ void test_algorithms(Rng & rng) o = boost::adjacent_difference( rng, boost::begin(out) ); o = boost::adjacent_difference( rng, boost::begin(out), null_op2() ); + + boost::ignore_unused_variable_warning(b); } diff --git a/test/algorithm_test/unique.cpp b/test/algorithm_test/unique.cpp index 880c131..d8eb784 100644 --- a/test/algorithm_test/unique.cpp +++ b/test/algorithm_test/unique.cpp @@ -9,13 +9,15 @@ // For more information, see http://www.boost.org/libs/range/ // #include +#include #include #include #include #include -#include "../test_driver/range_return_test_driver.hpp" +#include +#include "../test_driver/range_overload_test_driver.hpp" #include #include #include @@ -60,6 +62,36 @@ namespace boost_range_test_algorithm_unique } }; + template + struct test_range_overload + { + BOOST_STATIC_CONSTANT( + ::boost::range_return_value, + result_type = ::boost::return_begin_found); + + template + BOOST_DEDUCED_TYPENAME boost::range_return< + Container, result_type + >::type + operator()(Policy& policy, Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_return< + Container,result_type>::type result_t; + + Container cont2(cont); + + result_t result = boost::unique(cont); + + boost::unique(boost::make_iterator_range(cont2)); + + BOOST_CHECK_EQUAL_COLLECTIONS( + cont.begin(), cont.end(), + cont2.begin(), cont2.end()); + + return result; + } + }; + template< class Container > BOOST_DEDUCED_TYPENAME boost::range_iterator::type reference(Container& cont) @@ -67,7 +99,7 @@ namespace boost_range_test_algorithm_unique return std::unique(cont.begin(), cont.end()); } }; - + // test the 'unique' algorithm with a predicate template class unique_pred_test_policy @@ -105,6 +137,34 @@ namespace boost_range_test_algorithm_unique return result; } }; + + template + struct test_range_overload + { + BOOST_STATIC_CONSTANT( + ::boost::range_return_value, + result_type = ::boost::return_begin_found); + + template + BOOST_DEDUCED_TYPENAME boost::range_return::type + operator()(Policy& policy, Container& cont) + { + typedef BOOST_DEDUCED_TYPENAME boost::range_return< + Container,result_type>::type result_t; + + Container cont2(cont); + + result_t result = boost::unique(cont, policy.pred()); + + boost::unique(boost::make_iterator_range(cont2), policy.pred()); + + BOOST_CHECK_EQUAL_COLLECTIONS( + cont.begin(), cont.end(), + cont2.begin(), cont2.end()); + + return result; + } + }; template< class Container > BOOST_DEDUCED_TYPENAME boost::range_iterator::type @@ -121,7 +181,7 @@ namespace boost_range_test_algorithm_unique typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t; - boost::range_test::range_return_test_driver test_driver; + boost::range_test::range_overload_test_driver test_driver; Container cont; @@ -145,6 +205,19 @@ namespace boost_range_test_algorithm_unique test_driver(cont, policy); } + + template + struct equal_div_2 + { + typedef bool result_type; + typedef const T& first_argument_type; + typedef const T& second_argument_type; + + bool operator()(const T& left, const T& right) const + { + return left / 2 == right / 2; + } + }; template void test_unique_impl() @@ -152,17 +225,22 @@ namespace boost_range_test_algorithm_unique test_unique_impl( unique_test_policy(), std::less() - ); + ); test_unique_impl( - unique_pred_test_policy >(), + unique_pred_test_policy >(), std::less() - ); + ); test_unique_impl( - unique_pred_test_policy >(), + unique_pred_test_policy >(), std::greater() - ); + ); + + test_unique_impl( + unique_pred_test_policy >(), + std::less() + ); } void test_unique() diff --git a/test/compile_fail/iterator_range1.cpp b/test/compile_fail/iterator_range1.cpp index eed4ea9..2e5eec3 100644 --- a/test/compile_fail/iterator_range1.cpp +++ b/test/compile_fail/iterator_range1.cpp @@ -16,6 +16,7 @@ namespace iterator_range_test_detail { double source[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 }; boost::iterator_range rng = boost::make_iterator_range(source); + boost::ignore_unused_variable_warning(rng); } } diff --git a/test/test_driver/range_overload_test_driver.hpp b/test/test_driver/range_overload_test_driver.hpp new file mode 100644 index 0000000..e4b2ce7 --- /dev/null +++ b/test/test_driver/range_overload_test_driver.hpp @@ -0,0 +1,74 @@ + // Copyright Neil Groves 2013. Use, modification and + // distribution is subject to 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) + // + // + // For more information, see http://www.boost.org/libs/range/ + // + // Acknowledgments: + // Implemented by Andy in response to Ticket 6888 - unique fix + // + #ifndef BOOST_RANGE_TEST_TEST_DRIVER_RANGE_OVERLOAD_TEST_DRIVER_HPP_INCLUDED + #define BOOST_RANGE_TEST_TEST_DRIVER_RANGE_OVERLOAD_TEST_DRIVER_HPP_INCLUDED + + #include "range_return_test_driver.hpp" + #include + #include + #include + + namespace boost + { + namespace range_test + { + + // A test driver to exercise a test through range_return_test_driver + // plus the overload that determines the return_type by overload + // + // The test driver also contains the code required to check the + // return value correctness. + // + // The TestPolicy needs to implement all those required by + // range_return_test_driver, and additionally + // + // - perform the boost range version of the algorithm that determines + // the return_type by overload + class range_overload_test_driver : range_return_test_driver + { + public: + template< class Container, + class TestPolicy > + void operator()(Container& cont, TestPolicy policy) + { + range_return_test_driver::operator()(cont, policy); + test_range_overload()(cont, policy); + } + + private: + template< class Container, class TestPolicy > + struct test_range_overload + { + void operator()(Container& cont, TestPolicy policy) + { + typedef BOOST_DEDUCED_TYPENAME range_iterator::type iterator_t; + typedef BOOST_DEDUCED_TYPENAME TestPolicy::template test_range_overload test_range_overload_t; + const range_return_value result_type = test_range_overload_t::result_type; + typedef BOOST_DEDUCED_TYPENAME range_return::type range_return_t; + + Container reference(cont); + Container test_cont(cont); + + test_range_overload_t test_range_overload_fn; + range_return_t range_result = test_range_overload_fn(policy, test_cont); + + iterator_t reference_it = policy.reference(reference); + + check_results::test(test_cont, reference, + range_result, reference_it); + } + }; + }; + } + } + + #endif // include guard \ No newline at end of file