Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Fix/closing iterator returns reference to temp #488
This PR addresses an issue with both closing_iterator and ever_circling_range_iterator where they can return a reference to a temporary object. This happens when using a range where Range::reference is a value type (in my particular case, I hit this with boost::transformed_range). This happens because neither of them were honoring the range's reference type, they were assuming it was 'value_type const&'.
The first commit adds the tests, both of which fail with a SEGFAULT, and the second commit fixes the iterators.
Built and tested on Ubuntu 16.04 with gcc 5.4:
Note that transformed range is SinglePassRange, not RandomAccesRange which is required by the library (see Linestring and Ring concepts). It's because as you noticed non-real-reference has to be returned and the standard allows only InputIterator to do that. AFAIR
With that said I think the code should work in practice so I'm ok with the change. But if you want to be more complete you could go through the code and see if the iterators you just modified are used as intended. So please let me know if you'd like to have this PR merged at this point or work on it more.
Thanks @awulkiew , I'm aware that in general you need a RandomAccessRange, but in my particular case I was using closeable_view directly and ran into this, along the lines of:
Easy enough to work around, but there didn't seem to be any good reason it shouldn't work :)
I did scan through to look for anything obvious that was using closing_iterator (either directly or indirectly) and most of it looked OK, but there were some places that were passing a range wrapped with closeable_view (or normalized_view) that could be a problem depending on what the callee does with it. the only place I could find that's definitely a problem was in in algorithms/detail/relate/linear_areal.hpp in the calculate_from_inside() method, it stores a reference to the result of range::at(rng, index) where rng is a normalized_view (that derives from closeable_view).
So, I think merge the PR as is. I think it's fair to say the majority of the library requires a RandomAccessRange with occasional bits (like closeable_view) that can work SinglePassRange.