forked from boostorg/range
Ticket 10988 - Filtered adaptor should only require SinglePassRange.
This commit is contained in:
@ -12,9 +12,9 @@
|
||||
]
|
||||
|
||||
* [*Precondition:] The `value_type` of the range is convertible to the argument type of `pred`.
|
||||
* [*Postcondition:] For all adjacent elements `[x]` in the returned range, `pred(x)` is `true`.
|
||||
* [*Postcondition:] For all elements `[x]` in the returned range, `pred(x)` is `true`.
|
||||
* [*Throws:] Whatever the copy constructor of `pred` might throw.
|
||||
* [*Range Category:] __forward_range__
|
||||
* [*Range Category:] __singlepass_range__
|
||||
* [*Range Return Type:] `boost::filtered_range<decltype(rng)>`
|
||||
* [*Returned Range Category:] The minimum of the range category of `rng` and __bidirectional_range__
|
||||
|
||||
|
@ -56,23 +56,23 @@ namespace boost
|
||||
{ }
|
||||
};
|
||||
|
||||
template< class ForwardRange, class Predicate >
|
||||
inline filtered_range<Predicate, ForwardRange>
|
||||
operator|(ForwardRange& r,
|
||||
template< class SinglePassRange, class Predicate >
|
||||
inline filtered_range<Predicate, SinglePassRange>
|
||||
operator|(SinglePassRange& r,
|
||||
const filter_holder<Predicate>& f)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||
return filtered_range<Predicate, ForwardRange>( f.val, r );
|
||||
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange>));
|
||||
return filtered_range<Predicate, SinglePassRange>( f.val, r );
|
||||
}
|
||||
|
||||
template< class ForwardRange, class Predicate >
|
||||
inline filtered_range<Predicate, const ForwardRange>
|
||||
operator|(const ForwardRange& r,
|
||||
template< class SinglePassRange, class Predicate >
|
||||
inline filtered_range<Predicate, const SinglePassRange>
|
||||
operator|(const SinglePassRange& r,
|
||||
const filter_holder<Predicate>& f )
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((
|
||||
ForwardRangeConcept<const ForwardRange>));
|
||||
return filtered_range<Predicate, const ForwardRange>( f.val, r );
|
||||
SinglePassRangeConcept<const SinglePassRange>));
|
||||
return filtered_range<Predicate, const SinglePassRange>( f.val, r );
|
||||
}
|
||||
|
||||
} // 'range_detail'
|
||||
@ -93,23 +93,26 @@ namespace boost
|
||||
range_detail::forwarder<range_detail::filter_holder>();
|
||||
}
|
||||
|
||||
template<class ForwardRange, class Predicate>
|
||||
inline filtered_range<Predicate, ForwardRange>
|
||||
filter(ForwardRange& rng, Predicate filter_pred)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
||||
|
||||
return range_detail::filtered_range<Predicate, ForwardRange>( filter_pred, rng );
|
||||
}
|
||||
|
||||
template<class ForwardRange, class Predicate>
|
||||
inline filtered_range<Predicate, const ForwardRange>
|
||||
filter(const ForwardRange& rng, Predicate filter_pred)
|
||||
template<class SinglePassRange, class Predicate>
|
||||
inline filtered_range<Predicate, SinglePassRange>
|
||||
filter(SinglePassRange& rng, Predicate filter_pred)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((
|
||||
ForwardRangeConcept<const ForwardRange>));
|
||||
SinglePassRangeConcept<SinglePassRange>));
|
||||
|
||||
return range_detail::filtered_range<Predicate, const ForwardRange>( filter_pred, rng );
|
||||
return range_detail::filtered_range<
|
||||
Predicate, SinglePassRange>( filter_pred, rng );
|
||||
}
|
||||
|
||||
template<class SinglePassRange, class Predicate>
|
||||
inline filtered_range<Predicate, const SinglePassRange>
|
||||
filter(const SinglePassRange& rng, Predicate filter_pred)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((
|
||||
SinglePassRangeConcept<const SinglePassRange>));
|
||||
|
||||
return range_detail::filtered_range<
|
||||
Predicate, const SinglePassRange>( filter_pred, rng );
|
||||
}
|
||||
} // 'adaptors'
|
||||
|
||||
|
@ -40,10 +40,6 @@ test-suite range :
|
||||
[ compile-fail compile_fail/adaptor/copied_concept2.cpp ]
|
||||
[ compile-fail compile_fail/adaptor/copied_concept3.cpp ]
|
||||
[ compile-fail compile_fail/adaptor/copied_concept4.cpp ]
|
||||
[ compile-fail compile_fail/adaptor/filtered_concept.cpp ]
|
||||
[ compile-fail compile_fail/adaptor/filtered_concept2.cpp ]
|
||||
[ compile-fail compile_fail/adaptor/filtered_concept3.cpp ]
|
||||
[ compile-fail compile_fail/adaptor/filtered_concept4.cpp ]
|
||||
[ compile-fail compile_fail/adaptor/reversed_concept.cpp ]
|
||||
[ compile-fail compile_fail/adaptor/reversed_concept2.cpp ]
|
||||
[ compile-fail compile_fail/adaptor/reversed_concept3.cpp ]
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@ -113,12 +114,35 @@ namespace boost
|
||||
filtered_test_impl< Container, is_even >();
|
||||
}
|
||||
|
||||
void ticket_10988_single_pass()
|
||||
{
|
||||
std::vector<int> v;
|
||||
std::string str("0 1 2 3 4 5");
|
||||
std::istringstream in(str);
|
||||
|
||||
boost::push_back(v,
|
||||
boost::make_iterator_range(
|
||||
std::istream_iterator<int>(in),
|
||||
std::istream_iterator<int>())
|
||||
| boost::adaptors::filtered(is_even()));
|
||||
|
||||
std::vector<int> reference;
|
||||
for (int i = 0; i < 6; i += 2)
|
||||
{
|
||||
reference.push_back(i);
|
||||
}
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(
|
||||
reference.begin(), reference.end(),
|
||||
v.begin(), v.end());
|
||||
}
|
||||
|
||||
void filtered_test()
|
||||
{
|
||||
filtered_test_all_predicates< std::vector< int > >();
|
||||
filtered_test_all_predicates< std::list< int > >();
|
||||
filtered_test_all_predicates< std::set< int > >();
|
||||
filtered_test_all_predicates< std::multiset< int > >();
|
||||
ticket_10988_single_pass();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,38 +0,0 @@
|
||||
// Boost.Range library
|
||||
//
|
||||
// Copyright Neil Groves 2014. 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
|
||||
//
|
||||
|
||||
#include "mock_range.hpp"
|
||||
#include <boost/range/adaptor/filtered.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct always_true
|
||||
{
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator()(int) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int main(int, const char**)
|
||||
{
|
||||
using boost::range::unit_test::mock_range;
|
||||
using boost::adaptors::filtered;
|
||||
|
||||
// This next line should fail when Boost.Range concept checking is
|
||||
// enabled since the filtered adaptor takes at least a ForwardRange.
|
||||
return (mock_range<boost::single_pass_traversal_tag>() |
|
||||
filtered(always_true())).front();
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
// Boost.Range library
|
||||
//
|
||||
// Copyright Neil Groves 2014. 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
|
||||
//
|
||||
|
||||
#include "mock_range.hpp"
|
||||
#include <boost/range/adaptor/filtered.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct always_true
|
||||
{
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator()(int) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int main(int, const char**)
|
||||
{
|
||||
using boost::range::unit_test::mock_const_range;
|
||||
using boost::adaptors::filtered;
|
||||
|
||||
// This next line should fail when Boost.Range concept checking is
|
||||
// enabled since the filtered adaptor takes at least a ForwardRange.
|
||||
return (mock_const_range<boost::single_pass_traversal_tag>() |
|
||||
filtered(always_true())).front();
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
// Boost.Range library
|
||||
//
|
||||
// Copyright Neil Groves 2014. 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
|
||||
//
|
||||
|
||||
#include "mock_range.hpp"
|
||||
#include <boost/range/adaptor/filtered.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct always_true
|
||||
{
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator()(int) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int main(int, const char**)
|
||||
{
|
||||
using boost::range::unit_test::mock_range;
|
||||
|
||||
// This next line should fail when Boost.Range concept checking is
|
||||
// enabled since the filtered adaptor takes at least a ForwardRange.
|
||||
return boost::adaptors::filter(
|
||||
mock_range<boost::single_pass_traversal_tag>(),
|
||||
always_true()).front();
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
// Boost.Range library
|
||||
//
|
||||
// Copyright Neil Groves 2014. 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
|
||||
//
|
||||
|
||||
#include "mock_range.hpp"
|
||||
#include <boost/range/adaptor/filtered.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct always_true
|
||||
{
|
||||
typedef bool result_type;
|
||||
|
||||
bool operator()(int) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
int main(int, const char**)
|
||||
{
|
||||
using boost::range::unit_test::mock_const_range;
|
||||
|
||||
// This next line should fail when Boost.Range concept checking is
|
||||
// enabled since the filtered adaptor takes at least a ForwardRange.
|
||||
return boost::adaptors::filter(
|
||||
mock_const_range<boost::single_pass_traversal_tag>(),
|
||||
always_true()).front();
|
||||
}
|
Reference in New Issue
Block a user