Boost logo

Boost Users :

From: Jean-Pierre Bergamin (james_at_[hidden])
Date: 2008-04-12 12:40:08


Hello everyone

Imagine a class "numbers" that contains some values and methods like
getEvenValues(), getOddValues(), getValuesLarger100() etc. Those methods
return an iterator range of filter_iterators. In the the code I posted
below, I'd have to define a different iterator_range of filter_iterator
types for all the different methods (numbers::EvenFilterRange,
numbers::OddFilterRange etc.). Is there some way to "hide" the type of
the predicate used in a filter_iterator, so that it would be possible to
have a generic "NumberRange" type for the return values of all methods?
Something like:

class numbers {
    typedef NumberRange ????;
    NumberRange getEvenValues() const;
    NumberRange getOddValues() const;
    NumberRange getValuesLarger100() const;
}

Thanks for your hints

James

/*********************************************/
#include <vector>
#include <iostream>

#include <boost/iterator/filter_iterator.hpp>
#include <boost/iterator/counting_iterator.hpp>
#include <boost/range/iterator_range.hpp>

using namespace std;
using namespace boost;

/*********************************************/
template<typename T>
struct is_even {
    bool operator()(const T &t) {
        return t % 2 == 0;
    }
};

template<typename T>
struct is_odd {
    bool operator()(const T &t) {
        return t % 2 != 0;
    }
};

/*********************************************/
class numbers {
public:
    typedef vector<int> NumberContainer;
    typedef NumberContainer::const_iterator NumberIter;
    typedef iterator_range<
        filter_iterator<
            is_even<numbers::NumberContainer::value_type>,
            NumberIter>
> EvenFilterRange;

    numbers() {
        copy(
            counting_iterator<NumberContainer::value_type>(0),
            counting_iterator<NumberContainer::value_type>(100),
            back_inserter(m_vec)
        );
    }

    template<typename Pred>
    iterator_range<filter_iterator<Pred, NumberIter> > getValues(const
Pred &pred) {
        return make_iterator_range(
            make_filter_iterator(pred, m_vec.begin(), m_vec.end()),
            make_filter_iterator(pred, m_vec.end(), m_vec.end())
        );
    }
  
    EvenFilterRange getEvenValues() {
        typedef is_even<numbers::NumberContainer::value_type> PredType;
        PredType is_even_predicate;
        return getValues(is_even_predicate);
    };

private:
  
    NumberContainer m_vec;
};

/*********************************************/

template<typename T>
struct print_number {
    void operator()(const T &t) {
        cout << "Number: " << t << endl;
    }
};

/*********************************************/

int main()
{
    numbers n;
    numbers::EvenFilterRange even_filter_range = n.getEvenValues();
    print_number<numbers::NumberContainer::value_type> printer;
    for_each(begin(even_filter_range), end(even_filter_range), printer);
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net