ryanhaining / cppitertools

Implementation of python itertools and builtin iteration functions for C++17
https://twitter.com/cppitertools
BSD 2-Clause "Simplified" License
1.37k stars 115 forks source link

Filtering `iter::product` #17

Closed iliocatallo closed 10 years ago

iliocatallo commented 10 years ago

Hi,

with respect to #16, I was trying to filter out the upper right corner of the matrix using iter::filter. Here's the showcase code:

int main() {

    auto range = iter::product(iter::range(10), iter::range(5));

    for (auto&& ij: iter::filter([](std::tuple<unsigned, unsigned> const& c) {return std::get<0>(c) >= std::get<1>(c);}, range))
        std::cout << std::get<0>(ij) << "," << std::get<1>(ij) << std::endl;
}

Unfortunately, this does not compile. Clang reads:

error: indirection requires pointer operand ('const iterator_type<iter::Productor<iter::Range<int>, iter::Range<int> > &>' (aka 'const iter::Productor<iter::Range<int>, iter::Range<int> >::Iterator') invalid)
                        return *this->sub_iter;

Same error if I replace iter::filter with boost::adaptors::filtered, so I presume the error should be in iter::Producter.

Thanks.

ryanhaining commented 10 years ago

This looks like a constness issue with range::Iterator::operator*(); (not being marked const of course). For this limited case it might work just as well to make the range operator* a const member, but that doesn't generalize well. This hints at a bigger issue I suspected would need addressing eventually. It seems that time has come today!

On Tue, Sep 23, 2014 at 3:13 AM, iliocatallo notifications@github.com wrote:

Hi,

with respect to #16 https://github.com/ryanhaining/cppitertools/issues/16, I was trying to filter out the upper right corner of the matrix using iter::filter. Here's the showcase code:

int main() {

auto range = iter::product(iter::range(10), iter::range(5));

for (auto&& ij: iter::filter([](std::tuple<unsigned, unsigned> const& c) {return std::get<0>(c) >= std::get<1>(c);}, range))
    std::cout << std::get<0>(ij) << "," << std::get<1>(ij) << std::endl;

Unfortunately, this does not compile. Clang reads:

error: indirection requires pointer operand ('const iterator_typeiter::Productor<iter::Range<int, iter::Range > &>' (aka 'const iter::Productoriter::Range<int, iter::Range >::Iterator') invalid) return *this->sub_iter;

Same error if I replace iter::filter with boost::adaptors::filtered, so I presume the error should be in iter::Producter.

Thanks.

— Reply to this email directly or view it on GitHub https://github.com/ryanhaining/cppitertools/issues/17.

ryanhaining commented 10 years ago

nevermind. this is gonna run deeper than expected.

ryanhaining commented 10 years ago

fixed with d0438877e6998a829dcd03619189de602ce3b371