Reputation: 2503
I'm trying to implement a method which returns a boost::filter_iterator pair (begin, end).
I would like this method to be customizable in terms of filtering, but I don't know how I could sort this out since when I typedef the filter iterator range I have to hardcode the predicate I want to use and I cannot choose it depending on the parameter the method receives in input.
I would like to have something like this :
enum FilterType
{
FilterOnState = 0,
FilterOnValue,
FilterOnSize,
FilterOnWhatever...
}
typedef boost::filter_iterator<PredicateStruct, std::list<Object>::iterator> filter_iterator;
std::pair<filter_iterator, filter_iterator> filterObjects(FilterType filterType);
I thought about a possible template solution as well, but I would need the client to access predicates implementation and instance the one suiting his needs before calling the filter, he'd almost do all the job himself : that's why I'd like best the enum based solution.
template<typename P>
std::pair<boost::filter_iterator<P, std::list<Object>::iterator>,
boost::filter_iterator<P, std::list<Object>::iterator>> filterObjects(P& predicate);
Would a predicate "base class" be a possible solution for the enum based implementation ?
Thanks a lot in advance! Giacomo
Upvotes: 2
Views: 2399
Reputation: 131799
Why not simply provide predefined predicates instead of enum values?
struct predef_predicate{
predef_predicate(FilterType f)
: filt(f) {}
template<class T>
bool operator()(T const& v) const{
// filter in whatever way...
}
private:
FilterType filt;
};
namespace { // guard against ODR violations
predef_predicate const filter_state(FilterOnState);
predef_predicate const filter_values(FilterOnValue);
// ...
}
And then, instead of reinventing the wheel, just use Boost.Range's filtered
adaptor.
#include <vector>
#include <iterator>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/algorith/copy.hpp>
int main(){
std::vector<int> v;
// fill v
std::vector<int> filtered;
boost::copy(v | boost::adaptors::filtered(filter_values),
std::back_inserter(filtered));
}
And with C++11, the act of creating a predicate becomes even easier thanks to lambdas.
Upvotes: 2