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`.
|
* [*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.
|
* [*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)>`
|
* [*Range Return Type:] `boost::filtered_range<decltype(rng)>`
|
||||||
* [*Returned Range Category:] The minimum of the range category of `rng` and __bidirectional_range__
|
* [*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 >
|
template< class SinglePassRange, class Predicate >
|
||||||
inline filtered_range<Predicate, ForwardRange>
|
inline filtered_range<Predicate, SinglePassRange>
|
||||||
operator|(ForwardRange& r,
|
operator|(SinglePassRange& r,
|
||||||
const filter_holder<Predicate>& f)
|
const filter_holder<Predicate>& f)
|
||||||
{
|
{
|
||||||
BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
|
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<SinglePassRange>));
|
||||||
return filtered_range<Predicate, ForwardRange>( f.val, r );
|
return filtered_range<Predicate, SinglePassRange>( f.val, r );
|
||||||
}
|
}
|
||||||
|
|
||||||
template< class ForwardRange, class Predicate >
|
template< class SinglePassRange, class Predicate >
|
||||||
inline filtered_range<Predicate, const ForwardRange>
|
inline filtered_range<Predicate, const SinglePassRange>
|
||||||
operator|(const ForwardRange& r,
|
operator|(const SinglePassRange& r,
|
||||||
const filter_holder<Predicate>& f )
|
const filter_holder<Predicate>& f )
|
||||||
{
|
{
|
||||||
BOOST_RANGE_CONCEPT_ASSERT((
|
BOOST_RANGE_CONCEPT_ASSERT((
|
||||||
ForwardRangeConcept<const ForwardRange>));
|
SinglePassRangeConcept<const SinglePassRange>));
|
||||||
return filtered_range<Predicate, const ForwardRange>( f.val, r );
|
return filtered_range<Predicate, const SinglePassRange>( f.val, r );
|
||||||
}
|
}
|
||||||
|
|
||||||
} // 'range_detail'
|
} // 'range_detail'
|
||||||
@ -93,23 +93,26 @@ namespace boost
|
|||||||
range_detail::forwarder<range_detail::filter_holder>();
|
range_detail::forwarder<range_detail::filter_holder>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class ForwardRange, class Predicate>
|
template<class SinglePassRange, class Predicate>
|
||||||
inline filtered_range<Predicate, ForwardRange>
|
inline filtered_range<Predicate, SinglePassRange>
|
||||||
filter(ForwardRange& rng, Predicate filter_pred)
|
filter(SinglePassRange& 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)
|
|
||||||
{
|
{
|
||||||
BOOST_RANGE_CONCEPT_ASSERT((
|
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'
|
} // 'adaptors'
|
||||||
|
|
||||||
|
@ -40,10 +40,6 @@ test-suite range :
|
|||||||
[ compile-fail compile_fail/adaptor/copied_concept2.cpp ]
|
[ compile-fail compile_fail/adaptor/copied_concept2.cpp ]
|
||||||
[ compile-fail compile_fail/adaptor/copied_concept3.cpp ]
|
[ compile-fail compile_fail/adaptor/copied_concept3.cpp ]
|
||||||
[ compile-fail compile_fail/adaptor/copied_concept4.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_concept.cpp ]
|
||||||
[ compile-fail compile_fail/adaptor/reversed_concept2.cpp ]
|
[ compile-fail compile_fail/adaptor/reversed_concept2.cpp ]
|
||||||
[ compile-fail compile_fail/adaptor/reversed_concept3.cpp ]
|
[ compile-fail compile_fail/adaptor/reversed_concept3.cpp ]
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
@ -113,12 +114,35 @@ namespace boost
|
|||||||
filtered_test_impl< Container, is_even >();
|
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()
|
void filtered_test()
|
||||||
{
|
{
|
||||||
filtered_test_all_predicates< std::vector< int > >();
|
filtered_test_all_predicates< std::vector< int > >();
|
||||||
filtered_test_all_predicates< std::list< int > >();
|
filtered_test_all_predicates< std::list< int > >();
|
||||||
filtered_test_all_predicates< std::set< int > >();
|
filtered_test_all_predicates< std::set< int > >();
|
||||||
filtered_test_all_predicates< std::multiset< 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