Ticket #6888: unique_fix.diff

File unique_fix.diff, 8.1 KB (added by andy@…, 10 years ago)

Bug fix + test expansion to cover

  • boost/range/algorithm/unique.hpp

     
    8989unique( ForwardRange& rng, BinaryPredicate pred )
    9090{
    9191    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
    92     return ::boost::range::unique<return_begin_found>(rng);
     92    return ::boost::range::unique<return_begin_found>(rng, pred);
    9393}
    9494/// \overload
    9595template< class ForwardRange, class BinaryPredicate >
    96 inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
     96inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange, return_begin_found>::type
    9797unique( const ForwardRange& rng, BinaryPredicate pred )
    9898{
    9999    BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
  • libs/range/test/test_driver/range_overload_test_driver.hpp

     
     1//  Copyright Neil Groves 2009. Use, modification and
     2//  distribution is subject to the Boost Software License, Version
     3//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
     4//  http://www.boost.org/LICENSE_1_0.txt)
     5//
     6//
     7// For more information, see http://www.boost.org/libs/range/
     8//
     9#ifndef BOOST_RANGE_TEST_TEST_DRIVER_RANGE_OVERLOAD_TEST_DRIVER_HPP_INCLUDED
     10#define BOOST_RANGE_TEST_TEST_DRIVER_RANGE_OVERLOAD_TEST_DRIVER_HPP_INCLUDED
     11
     12#include "range_return_test_driver.hpp"
     13#include <boost/assert.hpp>
     14#include <boost/test/test_tools.hpp>
     15#include <boost/test/unit_test.hpp>
     16
     17namespace boost
     18{
     19    namespace range_test
     20    {
     21       
     22        // A test driver to exercise a test through range_return_test_driver
     23        // plus the overload that determines the return_type by overload
     24        //
     25        // The test driver also contains the code required to check the
     26        // return value correctness.
     27        //
     28        // The TestPolicy needs to implement all those required by
     29        // range_return_test_driver, and additionally
     30        //
     31        // - perform the boost range version of the algorithm that determines
     32        //   the return_type by overload
     33        class range_overload_test_driver : range_return_test_driver
     34        {
     35        public:
     36            template< class Container,
     37                      class TestPolicy >
     38            void operator()(Container& cont, TestPolicy policy)
     39            {
     40                range_return_test_driver::operator()(cont, policy);
     41                test_range_overload<Container, TestPolicy>()(cont, policy);
     42            }
     43
     44        private:
     45            template< class Container, class TestPolicy >
     46            struct test_range_overload
     47            {
     48                void operator()(Container& cont, TestPolicy policy)
     49                {
     50                    typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
     51                    typedef BOOST_DEDUCED_TYPENAME TestPolicy::template test_range_overload<Container> test_range_overload_t;
     52                    const range_return_value result_type = test_range_overload_t::result_type;
     53                    typedef BOOST_DEDUCED_TYPENAME range_return<Container, result_type>::type range_return_t;
     54
     55                    Container reference(cont);
     56                    Container test_cont(cont);
     57
     58                    test_range_overload_t test_range_overload_fn;
     59                    range_return_t range_result = test_range_overload_fn(policy, test_cont);
     60
     61                    iterator_t reference_it = policy.reference(reference);
     62
     63                    check_results<result_type>::test(test_cont, reference,
     64                                                     range_result, reference_it);
     65                }
     66            };
     67        };
     68    }
     69}
     70
     71#endif // include guard
  • libs/range/test/algorithm_test/unique.cpp

     
    99// For more information, see http://www.boost.org/libs/range/
    1010//
    1111#include <boost/range/algorithm/unique.hpp>
     12#include <boost/range/detail/range_return.hpp>
    1213
    1314#include <boost/test/test_tools.hpp>
    1415#include <boost/test/unit_test.hpp>
    1516
    1617#include <boost/assign.hpp>
    1718#include <boost/bind.hpp>
    18 #include "../test_driver/range_return_test_driver.hpp"
     19#include <boost/config.hpp>
     20#include "../test_driver/range_overload_test_driver.hpp"
    1921#include <algorithm>
    2022#include <functional>
    2123#include <list>
     
    6163        };
    6264
    6365        template< class Container >
     66        struct test_range_overload
     67        {
     68            BOOST_STATIC_CONSTANT(::boost::range_return_value, result_type = ::boost::return_begin_found);
     69
     70            template< class Policy >
     71            BOOST_DEDUCED_TYPENAME boost::range_return<Container,result_type>::type
     72            operator()(Policy& policy, Container& cont)
     73            {
     74                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,result_type>::type result_t;
     75
     76                Container cont2(cont);
     77
     78                result_t result = boost::unique(cont);
     79
     80                boost::unique(boost::make_iterator_range(cont2));
     81
     82                BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
     83                                               cont2.begin(), cont2.end() );
     84
     85                return result;
     86            }
     87        };
     88
     89        template< class Container >
    6490        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
    6591        reference(Container& cont)
    6692        {
     
    107133        };
    108134
    109135        template< class Container >
     136        struct test_range_overload
     137        {
     138            BOOST_STATIC_CONSTANT(::boost::range_return_value, result_type = ::boost::return_begin_found);
     139
     140            template< class Policy >
     141            BOOST_DEDUCED_TYPENAME boost::range_return<Container,result_type>::type
     142            operator()(Policy& policy, Container& cont)
     143            {
     144                typedef BOOST_DEDUCED_TYPENAME boost::range_return<Container,result_type>::type result_t;
     145
     146                Container cont2(cont);
     147
     148                result_t result = boost::unique(cont, policy.pred());
     149
     150                boost::unique(boost::make_iterator_range(cont2), policy.pred());
     151
     152                BOOST_CHECK_EQUAL_COLLECTIONS( cont.begin(), cont.end(),
     153                                               cont2.begin(), cont2.end() );
     154
     155                return result;
     156            }
     157        };
     158
     159        template< class Container >
    110160        BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
    111161        reference(Container& cont)
    112162        {
     
    121171
    122172        typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
    123173
    124         boost::range_test::range_return_test_driver test_driver;
     174        boost::range_test::range_overload_test_driver test_driver;
    125175
    126176        Container cont;
    127177
     
    146196        test_driver(cont, policy);
    147197    }
    148198
     199    template <class T>
     200    struct greater_by_two
     201    {
     202        bool operator()(const T& left, const T& right) const
     203        {
     204            return left / 2 == right / 2;
     205        }
     206    };
     207
    149208    template<class Container>
    150209    void test_unique_impl()
    151210    {
     
    155214            );
    156215
    157216        test_unique_impl<Container>(
    158             unique_pred_test_policy<std::less<int> >(),
     217            unique_pred_test_policy<std::equal_to<int> >(),
    159218            std::less<int>()
    160219            );
    161 
    162220        test_unique_impl<Container>(
    163             unique_pred_test_policy<std::greater<int> >(),
     221            unique_pred_test_policy<std::equal_to<int> >(),
    164222            std::greater<int>()
    165223            );
     224
     225        test_unique_impl<Container>(
     226            unique_pred_test_policy<greater_by_two<int> >(),
     227            std::less<int>()
     228            );
    166229    }
    167230
    168231    void test_unique()