Although remove_if operates on unary predicate it is not difficult to extend it on any other n arguments predicate.
For example remove with binary predicate can be written this way:
template<class ForwardIt, class BinaryPredicate>
ForwardIt removeif(ForwardIt first, ForwardIt last, BinaryPredicate p) {
ForwardIt result = first;
while ( first != last - 1) {
if ( !p( *first, *( first + 1))) {
*result = *first;
++result;
}
if( first == last - 1) return result;
++first;
}
return result;
}
But you have to fit this to your needs. It all depends how you treat pairs of elements, do you want to remove both of them if predicate returns true or one of them? Only left or only right? etc...
usage:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
bool bp (int left, int right) { return ( left + right == 2); }
/*
*
*/
int main(int argc, char** argv) {
int a[] = { 0, 2, 1, 3, 0, 2, 3, 2, 0, 3, 8};
std::vector<int> v( a, a + 11);
std::copy( v.begin(), v.end(), std::ostream_iterator<int>( std::cout, ","));
std::cout << std::endl;
std::vector<int>::iterator it = removeif( v.begin(), v.end(), bp);
std::copy( v.begin(), v.end(), std::ostream_iterator<int>( std::cout, ","));
v.erase( it, v.end()); std::cout << std::endl;
std::copy( v.begin(), v.end(), std::ostream_iterator<int>( std::cout, ","));
return 0;
}
output:
0,2,1,3,0,2,3,2,0,3,8,
2,1,3,2,3,0,3,2,0,3,8,
2,1,3,2,3,0,3,
This version removes both elements if condition holds.
template<class ForwardIt, class BinaryPredicate>
ForwardIt removeif(ForwardIt first, ForwardIt last, BinaryPredicate p) {
ForwardIt result = first;
while (first != last - 1) {
if (!p(*first, *(first + 1))) {
*result++ = *first++;
*result++ = *first++;
} else {
if (first == last - 1) return result;
++first;
++first;
}
}
return result;
}
0,2,1,3,0,2,3,2,0,3,8,
1,3,3,2,0,3,3,2,0,3,8,
1,3,3,2,0,3,