Add range-based overloads of find*_backward().

This commit is contained in:
Zach Laine
2018-05-12 16:03:41 -05:00
parent 6c68cf8624
commit c5c5d24ff3
4 changed files with 163 additions and 15 deletions

View File

@ -42,26 +42,38 @@ that the member requires.
template<typename BidiIter, typename T>
BidiIter find_backward(BidiIter first, BidiIter last, T const & x);
The function `find_backward` returns an iterator to the last element of
`[first, last)` that is equal to `x`.
template<typename Range, typename T>
boost::range_iterator<Range> find_backward(Range & range, T const & x);
The function `find_backward` returns an iterator to the last element that is
equal to `x` in `[first, last)` or `r`, respectively.
template<typename BidiIter, typename T>
BidiIter find_not_backward(BidiIter first, BidiIter last, T const & x);
The function `find_not_backward` returns an iterator to the last element of
`[first, last)` that is not equal to `x`.
template<typename Range, typename T>
boost::range_iterator<Range> find_not_backward(Range & range, T const & x);
The function `find_not_backward` returns an iterator to the last element that
is not equal to `x` in `[first, last)` or `r`, respectively.
template<typename BidiIter, typename Pred>
BidiIter find_if_backward(BidiIter first, BidiIter last, Pred p);
The function `find_if_backward` returns an iterator to the last element of
`[first, last)` for which `pred` returns `true`.
template<typename Range, typename Pred>
boost::range_iterator<Range> find_if_backward(Range & range, Pred p);
The function `find_if_backward` returns an iterator to the last element for
which `pred` returns `true` in `[first, last)` or `r`, respectively.
template<typename BidiIter, typename Pred>
BidiIter find_if_not_backward(BidiIter first, BidiIter last, Pred p);
The function `find_if_not_backward` returns an iterator to the last element of
`[first, last)` for which `pred` returns `false`.
template<typename Range, typename Pred>
boost::range_iterator<Range> find_if_not_backward(Range & range, Pred p);
The function `find_if_not_backward` returns an iterator to the last element
for which `pred` returns `false` in `[first, last)` or `r`, respectively.
[heading Examples]
@ -90,6 +102,10 @@ All of the variants take their parameters by value and do not depend upon any
global state. Therefore, all the routines in this file provide the strong
exception guarantee.
[heading Notes]
All variants are `constexpr` in C++14 or later.
[endsect]
[/ File equal.qbk

View File

@ -43,10 +43,10 @@ our find condition.
InputIter find_not(InputIter first, Sentinel last, T const & x);
template<typename Range, typename T>
typename boost::range_iterator<Range>::type find_not(Range & r, T const & x);
boost::range_iterator<Range> find_not(Range & r, T const & x);
The function `find_not` returns the first value in the sequence `[first,
last)` that is not equal to `x`.
The function `find_not` returns the first value that is not equal to `x` in
the sequence `[first, last)` or `r`, respectively.
[heading Examples]
@ -72,6 +72,10 @@ Linear.
`find_not` takes its parameters by value and do not depend upon any global
state. Therefore, it provides the strong exception guarantee.
[heading Notes]
`constexpr` in C++14 or later.
[endsect]
[/ File equal.qbk

View File

@ -8,13 +8,17 @@
#define BOOST_ALGORITHM_FIND_BACKWARD_HPP
#include <boost/config.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <utility>
namespace boost { namespace algorithm {
template<typename BidiIter, typename T>
BOOST_CXX14_CONSTEXPR BidiIter find_backward(BidiIter first, BidiIter last, T const & x)
BOOST_CXX14_CONSTEXPR
BidiIter find_backward(BidiIter first, BidiIter last, T const & x)
{
BidiIter it = last;
while (it != first) {
@ -24,8 +28,16 @@ BOOST_CXX14_CONSTEXPR BidiIter find_backward(BidiIter first, BidiIter last, T co
return last;
}
template<typename Range, typename T>
BOOST_CXX14_CONSTEXPR
typename boost::range_iterator<Range>::type find_backward(Range & range, T const & x)
{
return ::boost::algorithm::find_backward(boost::begin(range), boost::end(range), x);
}
template<typename BidiIter, typename T>
BOOST_CXX14_CONSTEXPR BidiIter find_not_backward(BidiIter first, BidiIter last, T const & x)
BOOST_CXX14_CONSTEXPR
BidiIter find_not_backward(BidiIter first, BidiIter last, T const & x)
{
BidiIter it = last;
while (it != first) {
@ -35,8 +47,16 @@ BOOST_CXX14_CONSTEXPR BidiIter find_not_backward(BidiIter first, BidiIter last,
return last;
}
template<typename Range, typename T>
BOOST_CXX14_CONSTEXPR
typename boost::range_iterator<Range>::type find_not_backward(Range & range, T const & x)
{
return ::boost::algorithm::find_not_backward(boost::begin(range), boost::end(range), x);
}
template<typename BidiIter, typename Pred>
BOOST_CXX14_CONSTEXPR BidiIter find_if_backward(BidiIter first, BidiIter last, Pred p)
BOOST_CXX14_CONSTEXPR
BidiIter find_if_backward(BidiIter first, BidiIter last, Pred p)
{
BidiIter it = last;
while (it != first) {
@ -46,8 +66,16 @@ BOOST_CXX14_CONSTEXPR BidiIter find_if_backward(BidiIter first, BidiIter last, P
return last;
}
template<typename Range, typename Pred>
BOOST_CXX14_CONSTEXPR
typename boost::range_iterator<Range>::type find_if_backward(Range & range, Pred p)
{
return ::boost::algorithm::find_if_backward(boost::begin(range), boost::end(range), p);
}
template<typename BidiIter, typename Pred>
BOOST_CXX14_CONSTEXPR BidiIter find_if_not_backward(BidiIter first, BidiIter last, Pred p)
BOOST_CXX14_CONSTEXPR
BidiIter find_if_not_backward(BidiIter first, BidiIter last, Pred p)
{
BidiIter it = last;
while (it != first) {
@ -57,6 +85,13 @@ BOOST_CXX14_CONSTEXPR BidiIter find_if_not_backward(BidiIter first, BidiIter las
return last;
}
template<typename Range, typename Pred>
BOOST_CXX14_CONSTEXPR
typename boost::range_iterator<Range>::type find_if_not_backward(Range & range, Pred p)
{
return ::boost::algorithm::find_if_not_backward(boost::begin(range), boost::end(range), p);
}
}} // namespace boost and algorithm
#endif // BOOST_ALGORITHM_FIND_BACKWARD_HPP

View File

@ -43,12 +43,21 @@ BOOST_CXX14_CONSTEXPR bool check_constexpr_backward()
const int* start = ba::find_backward(from, to, 1); // stops on first
res = (res && start == from);
start = ba::find_backward(in_data, 1); // stops on first
res = (res && start == from);
const int* end = ba::find_backward(from, to, 6); // stops on the end
res = (res && end == to);
end = ba::find_backward(in_data, 6); // stops on the end
res = (res && end == to);
const int* three = ba::find_backward(from, to, 3); // stops on third element
res = (res && three == in_data + 2);
three = ba::find_backward(in_data, 3); // stops on third element
res = (res && three == in_data + 2);
return res;
}
@ -69,6 +78,12 @@ void test_find_backward()
v1.size() - 1);
BOOST_CHECK_EQUAL(
dist(ba::find_backward(v1.begin(), v1.end(), v1.front())), 0);
BOOST_CHECK_EQUAL(dist(ba::find_backward(v1, 0)), v1.size());
BOOST_CHECK_EQUAL(dist(ba::find_backward(v1, 100)), v1.size());
BOOST_CHECK_EQUAL(
dist(ba::find_backward(v1, v1.back())), v1.size() - 1);
BOOST_CHECK_EQUAL(dist(ba::find_backward(v1, v1.front())), 0);
}
// With bidirectional iterators.
@ -87,6 +102,12 @@ void test_find_backward()
l1.size() - 1);
BOOST_CHECK_EQUAL(
dist(ba::find_backward(l1.begin(), l1.end(), l1.front())), 0);
BOOST_CHECK_EQUAL(dist(ba::find_backward(l1, 0)), l1.size());
BOOST_CHECK_EQUAL(dist(ba::find_backward(l1, 100)), l1.size());
BOOST_CHECK_EQUAL(
dist(ba::find_backward(l1, l1.back())), l1.size() - 1);
BOOST_CHECK_EQUAL(dist(ba::find_backward(l1, l1.front())), 0);
}
BOOST_CXX14_CONSTEXPR bool ce_result = check_constexpr_backward();
@ -111,12 +132,21 @@ BOOST_CXX14_CONSTEXPR bool check_constexpr_if_backward()
const int* start = ba::find_if_backward(from, to, equals(1)); // stops on first
res = (res && start == from);
start = ba::find_if_backward(in_data, equals(1)); // stops on first
res = (res && start == from);
const int* end = ba::find_if_backward(from, to, equals(6)); // stops on the end
res = (res && end == to);
end = ba::find_if_backward(in_data, equals(6)); // stops on the end
res = (res && end == to);
const int* three = ba::find_if_backward(from, to, equals(3)); // stops on third element
res = (res && three == in_data + 2);
three = ba::find_if_backward(in_data, equals(3)); // stops on third element
res = (res && three == in_data + 2);
return res;
}
@ -141,6 +171,14 @@ void test_find_if_backward()
dist(
ba::find_if_backward(v1.begin(), v1.end(), equals(v1.front()))),
0);
BOOST_CHECK_EQUAL(dist(ba::find_if_backward(v1, equals(0))), v1.size());
BOOST_CHECK_EQUAL(
dist(ba::find_if_backward(v1, equals(100))), v1.size());
BOOST_CHECK_EQUAL(
dist(ba::find_if_backward(v1, equals(v1.back()))), v1.size() - 1);
BOOST_CHECK_EQUAL(
dist(ba::find_if_backward(v1, equals(v1.front()))), 0);
}
// With bidirectional iterators.
@ -163,6 +201,14 @@ void test_find_if_backward()
dist(
ba::find_if_backward(l1.begin(), l1.end(), equals(l1.front()))),
0);
BOOST_CHECK_EQUAL(dist(ba::find_if_backward(l1, equals(0))), l1.size());
BOOST_CHECK_EQUAL(
dist(ba::find_if_backward(l1, equals(100))), l1.size());
BOOST_CHECK_EQUAL(
dist(ba::find_if_backward(l1, equals(l1.back()))), l1.size() - 1);
BOOST_CHECK_EQUAL(
dist(ba::find_if_backward(l1, equals(l1.front()))), 0);
}
BOOST_CXX14_CONSTEXPR bool ce_result = check_constexpr_if_backward();
@ -187,12 +233,21 @@ BOOST_CXX14_CONSTEXPR bool check_constexpr_if_not_backward()
const int* start = ba::find_if_not_backward(from, to, not_equals(1)); // stops on first
res = (res && start == from);
start = ba::find_if_not_backward(in_data, not_equals(1)); // stops on first
res = (res && start == from);
const int* end = ba::find_if_not_backward(from, to, not_equals(6)); // stops on the end
res = (res && end == to);
end = ba::find_if_not_backward(in_data, not_equals(6)); // stops on the end
res = (res && end == to);
const int* three = ba::find_if_not_backward(from, to, not_equals(3)); // stops on third element
res = (res && three == in_data + 2);
three = ba::find_if_not_backward(in_data, not_equals(3)); // stops on third element
res = (res && three == in_data + 2);
return res;
}
@ -219,6 +274,16 @@ void test_find_if_not_backward()
dist(ba::find_if_not_backward(
v1.begin(), v1.end(), not_equals(v1.front()))),
0);
BOOST_CHECK_EQUAL(
dist(ba::find_if_not_backward(v1, not_equals(0))), v1.size());
BOOST_CHECK_EQUAL(
dist(ba::find_if_not_backward(v1, not_equals(100))), v1.size());
BOOST_CHECK_EQUAL(
dist(ba::find_if_not_backward(v1, not_equals(v1.back()))),
v1.size() - 1);
BOOST_CHECK_EQUAL(
dist(ba::find_if_not_backward(v1, not_equals(v1.front()))), 0);
}
// With bidirectional iterators.
@ -243,6 +308,16 @@ void test_find_if_not_backward()
dist(ba::find_if_not_backward(
l1.begin(), l1.end(), not_equals(l1.front()))),
0);
BOOST_CHECK_EQUAL(
dist(ba::find_if_not_backward(l1, not_equals(0))), l1.size());
BOOST_CHECK_EQUAL(
dist(ba::find_if_not_backward(l1, not_equals(100))), l1.size());
BOOST_CHECK_EQUAL(
dist(ba::find_if_not_backward(l1, not_equals(l1.back()))),
l1.size() - 1);
BOOST_CHECK_EQUAL(
dist(ba::find_if_not_backward(l1, not_equals(l1.front()))), 0);
}
BOOST_CXX14_CONSTEXPR bool ce_result = check_constexpr_if_not_backward();
@ -260,10 +335,16 @@ BOOST_CXX14_CONSTEXPR bool check_constexpr_not_backward()
const int* start = ba::find_not_backward(from, to, 5); // stops on first
res = (res && start == from);
start = ba::find_not_backward(in_data, 5); // stops on first
res = (res && start == from);
const int in_data_2[] = {6, 6, 6, 6, 6};
const int* end = ba::find_not_backward(in_data_2, in_data_2 + 5, 6); // stops on the end
res = (res && end == in_data_2 + 5);
end = ba::find_not_backward(in_data_2, 6); // stops on the end
res = (res && end == in_data_2 + 5);
return res;
}
@ -286,9 +367,15 @@ void test_find_not_backward()
dist(ba::find_not_backward(v1.begin(), v1.end(), 2)),
v1.size() - 1);
BOOST_CHECK_EQUAL(dist(ba::find_not_backward(v1, 1)), 4);
BOOST_CHECK_EQUAL(dist(ba::find_not_backward(v1, 0)), v1.size() - 1);
BOOST_CHECK_EQUAL(dist(ba::find_not_backward(v1, 2)), v1.size() - 1);
v1.resize(5);
BOOST_CHECK_EQUAL(
dist(ba::find_not_backward(v1.begin(), v1.end(), 0)), v1.size());
BOOST_CHECK_EQUAL(dist(ba::find_not_backward(v1, 0)), v1.size());
}
// With bidirectional iterators.
@ -309,9 +396,15 @@ void test_find_not_backward()
dist(ba::find_not_backward(l1.begin(), l1.end(), 2)),
l1.size() - 1);
BOOST_CHECK_EQUAL(dist(ba::find_not_backward(l1, 1)), 4);
BOOST_CHECK_EQUAL(dist(ba::find_not_backward(l1, 0)), l1.size() - 1);
BOOST_CHECK_EQUAL(dist(ba::find_not_backward(l1, 2)), l1.size() - 1);
l1.resize(5);
BOOST_CHECK_EQUAL(
dist(ba::find_not_backward(l1.begin(), l1.end(), 0)), l1.size());
BOOST_CHECK_EQUAL(dist(ba::find_not_backward(l1, 0)), l1.size());
}
BOOST_CXX14_CONSTEXPR bool ce_result = check_constexpr_not_backward();