forked from boostorg/range
[boost][range] - fix for ticket 6888 - unique predicate overloads
[SVN r85686]
This commit is contained in:
committed by
Nathan Ridge
parent
fbc0057432
commit
3d3dea1411
@ -86,14 +86,14 @@ unique( const ForwardRange& rng )
|
|||||||
/// \overload
|
/// \overload
|
||||||
template< class ForwardRange, class BinaryPredicate >
|
template< class ForwardRange, class BinaryPredicate >
|
||||||
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange, return_begin_found>::type
|
inline BOOST_DEDUCED_TYPENAME range_return<ForwardRange, return_begin_found>::type
|
||||||
unique( ForwardRange& rng, BinaryPredicate )
|
unique( ForwardRange& rng, BinaryPredicate pred )
|
||||||
{
|
{
|
||||||
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<ForwardRange> ));
|
||||||
return ::boost::range::unique<return_begin_found>(rng);
|
return ::boost::range::unique<return_begin_found>(rng, pred);
|
||||||
}
|
}
|
||||||
/// \overload
|
/// \overload
|
||||||
template< class ForwardRange, class BinaryPredicate >
|
template< class ForwardRange, class BinaryPredicate >
|
||||||
inline BOOST_DEDUCED_TYPENAME range_iterator<const ForwardRange>::type
|
inline BOOST_DEDUCED_TYPENAME range_return<const ForwardRange, return_begin_found>::type
|
||||||
unique( const ForwardRange& rng, BinaryPredicate pred )
|
unique( const ForwardRange& rng, BinaryPredicate pred )
|
||||||
{
|
{
|
||||||
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
BOOST_RANGE_CONCEPT_ASSERT(( ForwardRangeConcept<const ForwardRange> ));
|
||||||
|
6
include/boost/range/config.hpp
Executable file → Normal file
6
include/boost/range/config.hpp
Executable file → Normal file
@ -48,6 +48,12 @@
|
|||||||
#define BOOST_RANGE_ARRAY_REF() (&boost_range_array)
|
#define BOOST_RANGE_ARRAY_REF() (&boost_range_array)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)))
|
||||||
|
# define BOOST_RANGE_UNUSED __attribute__((unused))
|
||||||
|
#else
|
||||||
|
# define BOOST_RANGE_UNUSED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
//
|
//
|
||||||
#include <boost/range/adaptor/strided.hpp>
|
#include <boost/range/adaptor/strided.hpp>
|
||||||
|
|
||||||
|
#include <boost/config.hpp>
|
||||||
#include <boost/test/test_tools.hpp>
|
#include <boost/test/test_tools.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
@ -42,9 +43,12 @@ namespace boost
|
|||||||
Container reference;
|
Container reference;
|
||||||
|
|
||||||
{
|
{
|
||||||
typedef BOOST_DEDUCED_TYPENAME Container::const_iterator iterator_t;
|
typedef BOOST_DEDUCED_TYPENAME Container::const_iterator
|
||||||
typedef BOOST_DEDUCED_TYPENAME Container::difference_type diff_t;
|
iterator_t BOOST_RANGE_UNUSED;
|
||||||
typedef BOOST_DEDUCED_TYPENAME Container::size_type size_type;
|
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 it = c.begin();
|
||||||
|
|
||||||
iterator_t last = c.end();
|
iterator_t last = c.end();
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/assign.hpp>
|
#include <boost/assign.hpp>
|
||||||
|
#include <boost/config.hpp>
|
||||||
#include <boost/array.hpp>
|
#include <boost/array.hpp>
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/range/numeric.hpp>
|
#include <boost/range/numeric.hpp>
|
||||||
@ -107,9 +108,11 @@ void test_random_algorithms(Rng & rng, std::random_access_iterator_tag)
|
|||||||
{
|
{
|
||||||
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Rng>::type iterator;
|
typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<Rng>::type iterator;
|
||||||
typedef BOOST_DEDUCED_TYPENAME boost::range_value<Rng>::type value_type;
|
typedef BOOST_DEDUCED_TYPENAME boost::range_value<Rng>::type value_type;
|
||||||
typedef BOOST_DEDUCED_TYPENAME boost::range_size<Rng>::type size_type;
|
typedef BOOST_DEDUCED_TYPENAME boost::range_size<Rng>::type size_type BOOST_RANGE_UNUSED;
|
||||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_category<iterator>::type iterator_category;
|
typedef BOOST_DEDUCED_TYPENAME boost::iterator_category<iterator>::type iterator_category;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// just make sure these compile (for now)
|
// just make sure these compile (for now)
|
||||||
if(0)
|
if(0)
|
||||||
{
|
{
|
||||||
@ -329,6 +332,8 @@ void test_algorithms(Rng & rng)
|
|||||||
o = boost::adjacent_difference( rng, boost::begin(out),
|
o = boost::adjacent_difference( rng, boost::begin(out),
|
||||||
null_op2() );
|
null_op2() );
|
||||||
|
|
||||||
|
boost::ignore_unused_variable_warning(b);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// test the algorithms that require a random-access range
|
// test the algorithms that require a random-access range
|
||||||
|
@ -9,13 +9,15 @@
|
|||||||
// For more information, see http://www.boost.org/libs/range/
|
// For more information, see http://www.boost.org/libs/range/
|
||||||
//
|
//
|
||||||
#include <boost/range/algorithm/unique.hpp>
|
#include <boost/range/algorithm/unique.hpp>
|
||||||
|
#include <boost/range/detail/range_return.hpp>
|
||||||
|
|
||||||
#include <boost/test/test_tools.hpp>
|
#include <boost/test/test_tools.hpp>
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
#include <boost/assign.hpp>
|
#include <boost/assign.hpp>
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include "../test_driver/range_return_test_driver.hpp"
|
#include <boost/config.hpp>
|
||||||
|
#include "../test_driver/range_overload_test_driver.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <list>
|
#include <list>
|
||||||
@ -60,6 +62,36 @@ namespace boost_range_test_algorithm_unique
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Container>
|
||||||
|
struct test_range_overload
|
||||||
|
{
|
||||||
|
BOOST_STATIC_CONSTANT(
|
||||||
|
::boost::range_return_value,
|
||||||
|
result_type = ::boost::return_begin_found);
|
||||||
|
|
||||||
|
template<typename Policy>
|
||||||
|
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 >
|
template< class Container >
|
||||||
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
|
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
|
||||||
reference(Container& cont)
|
reference(Container& cont)
|
||||||
@ -106,6 +138,34 @@ namespace boost_range_test_algorithm_unique
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename Container>
|
||||||
|
struct test_range_overload
|
||||||
|
{
|
||||||
|
BOOST_STATIC_CONSTANT(
|
||||||
|
::boost::range_return_value,
|
||||||
|
result_type = ::boost::return_begin_found);
|
||||||
|
|
||||||
|
template<typename Policy>
|
||||||
|
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, 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 >
|
template< class Container >
|
||||||
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
|
BOOST_DEDUCED_TYPENAME boost::range_iterator<Container>::type
|
||||||
reference(Container& cont)
|
reference(Container& cont)
|
||||||
@ -121,7 +181,7 @@ namespace boost_range_test_algorithm_unique
|
|||||||
|
|
||||||
typedef BOOST_DEDUCED_TYPENAME Container::value_type value_t;
|
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;
|
Container cont;
|
||||||
|
|
||||||
@ -146,6 +206,19 @@ namespace boost_range_test_algorithm_unique
|
|||||||
test_driver(cont, policy);
|
test_driver(cont, policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
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<class Container>
|
template<class Container>
|
||||||
void test_unique_impl()
|
void test_unique_impl()
|
||||||
{
|
{
|
||||||
@ -155,14 +228,19 @@ namespace boost_range_test_algorithm_unique
|
|||||||
);
|
);
|
||||||
|
|
||||||
test_unique_impl<Container>(
|
test_unique_impl<Container>(
|
||||||
unique_pred_test_policy<std::less<int> >(),
|
unique_pred_test_policy<std::equal_to<int> >(),
|
||||||
std::less<int>()
|
std::less<int>()
|
||||||
);
|
);
|
||||||
|
|
||||||
test_unique_impl<Container>(
|
test_unique_impl<Container>(
|
||||||
unique_pred_test_policy<std::greater<int> >(),
|
unique_pred_test_policy<std::equal_to<int> >(),
|
||||||
std::greater<int>()
|
std::greater<int>()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test_unique_impl<Container>(
|
||||||
|
unique_pred_test_policy<equal_div_2<int> >(),
|
||||||
|
std::less<int>()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_unique()
|
void test_unique()
|
||||||
|
@ -16,6 +16,7 @@ namespace iterator_range_test_detail
|
|||||||
{
|
{
|
||||||
double source[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
|
double source[] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
|
||||||
boost::iterator_range<float*> rng = boost::make_iterator_range(source);
|
boost::iterator_range<float*> rng = boost::make_iterator_range(source);
|
||||||
|
boost::ignore_unused_variable_warning(rng);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
74
test/test_driver/range_overload_test_driver.hpp
Normal file
74
test/test_driver/range_overload_test_driver.hpp
Normal file
@ -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 <boost/assert.hpp>
|
||||||
|
#include <boost/test/test_tools.hpp>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
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<Container, TestPolicy>()(cont, policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
template< class Container, class TestPolicy >
|
||||||
|
struct test_range_overload
|
||||||
|
{
|
||||||
|
void operator()(Container& cont, TestPolicy policy)
|
||||||
|
{
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME range_iterator<Container>::type iterator_t;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME TestPolicy::template test_range_overload<Container> test_range_overload_t;
|
||||||
|
const range_return_value result_type = test_range_overload_t::result_type;
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME range_return<Container, result_type>::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<result_type>::test(test_cont, reference,
|
||||||
|
range_result, reference_it);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // include guard
|
Reference in New Issue
Block a user