mardi 14 janvier 2020

C++ filtration using lazy iterator 2

I have written this code to print out 17.5, 25.0

template<typename Iterator, typename Callable>
struct FilteringIterator : Iterator {
    using OriginalIterator = Iterator; // required for accessing the used Iterator type from other locations

    Iterator m_end;
    Callable callable;

    FilteringIterator(Iterator m_begin, Iterator m_end, Callable callable) : Iterator{m_begin}, m_end{m_end}, callable{callable} { }
    Iterator& get_orig_iter() { return ((Iterator&)*this); }
    double operator*() {
        while (true) {
            if (get_orig_iter() != m_end) {
                if(callable(*get_orig_iter()) == 1) {
                    return *get_orig_iter();
                } else {
                    get_orig_iter()++;
                }
            } else {
                break;
            }
        }
        if(callable(*get_orig_iter()) == 1) {
            return *get_orig_iter();
        } 
        return *get_orig_iter();
    }
};

auto filter = [](auto action) {
    return [=](auto& container) {
        using Container = std::decay_t<decltype(container)>;
        using Iterator = typename Container::iterator;
        using IteratorX = FilteringIterator<Iterator, decltype(action)>;
        return Range{IteratorX{container.begin(), container.end(), action}, IteratorX{container.end(), container.end(), action}};
    };
};

I need a lazy iterator that will traverse over a range and filter it lazily. For example,

auto v = std::vector<double>{};
auto odd_gen = views::odds();

for(int i=0; i<5; ++i)
    v.push_back(odd_gen() * 2.5);
// v contains {2.5, 7.5, 12.5, 17.5, 22.5} here

new_line();
for(auto a : v | filter(greater_than(15))) // filter is applied lazily as the range is traversed
    std::cout << a  << std::endl;

// print { 17.5, 22.5} here

     new_line();
for(auto a : v | filter(less_than(15))) // filter is applied lazily as the range is traversed
    std::cout << a << std::endl; 

// prints 2.5, 7.5 and 12.5

but now, I want it to print out 2.5, 7.5, 12.5 but i couldn't manage to do that. What can I do?

Aucun commentaire:

Enregistrer un commentaire