I assume that a bit mask is stored in a container (to support bit masks with more than sizeof(uintmax_t)
bits on your system). In this case the essence of solution is:
std::remove_copy_if(v.begin(), v.end(), std::back_inserter(out),
!*boost::lambda::var(pred)++);
Where v
- an input vector; out
- a vector to store results; pred
- an iterator over a bit mask.
If you'd like to avoid boost::lambda
then it is easily simulated:
template <class InputIterator, class OutputIterator, class PredicateIterator>
void copy_if(InputIterator first, InputIterator last, OutputIterator result,
PredicateIterator pred) {
for ( ; first != last; ++first)
if (*pred++)
*result++ = *first;
}
It can be used as follows (using the same notation as in the above example):
copy_if(v.begin(), v.end(), std::back_inserter(out), pred);
Or the same using a predicate:
template <class Iterator>
class Pred {
Iterator it;
public:
Pred(Iterator it_) : it(it_) {}
template <class T>
bool operator ()(T /* ignore argument */) { return !*it++; }
};
template <class Iterator>
Pred<Iterator> iterator2predicate(Iterator it) {
return Pred<Iterator>(it);
}
That can be used as follows:
std::remove_copy_if(v.begin(), v.end(), std::back_inserter(out),
iterator2predicate(pred));
Example (using boost::lambda
, but it is easy to replace it by the above two other options):
/** g++ -Wall -Ipath/to/boost -o filter_array filter_array.cpp */
#include <algorithm>
#include <iostream>
#include <iterator> // back_inserter()
#include <vector>
#include <boost/lambda/lambda.hpp>
#define LEN(array) (sizeof(array) / sizeof(*(array)))
#define P(v) { std::for_each(v.begin(), v.end(), \
std::cout << boost::lambda::_1 << " "); \
std::cout << std::endl; }
int main() {
int a[] = {123, 345, 678, 890, 555,};
const size_t n = LEN(a);
bool bits[][n] = {
1, 0, 1, 0, 0,
0, 0, 1, 1, 0,
0, 0, 0, 0, 1,
};
typedef std::vector<int> Array;
Array v(a, a + n);
P(v);
for (size_t i = 0; i < LEN(bits); ++i) {
Array out;
std::vector<bool> b(bits[i], bits[i] + LEN(bits[i]));
std::vector<bool>::const_iterator pred = b.begin();
P(b);
std::remove_copy_if(v.begin(), v.end(), std::back_inserter(out),
!*boost::lambda::var(pred)++);
P(out);
}
}
Output:
123 345 678 890 555
1 0 1 0 0
123 678
0 0 1 1 0
678 890
0 0 0 0 1
555