libstdc++: Fix iterator caching inside range adaptors [PR100479]
authorPatrick Palka <ppalka@redhat.com>
Mon, 24 May 2021 19:24:44 +0000 (15:24 -0400)
committerPatrick Palka <ppalka@redhat.com>
Mon, 24 May 2021 19:24:44 +0000 (15:24 -0400)
commit46ed811bcb4b86a81ef3d78ea8cfffc6cd043144
tree4b7829c60803aa3e33be3cc9ebd61e2630fb93db
parent6fdc59f196c3e1b4aeeb8a0407d4eb40645c5251
libstdc++: Fix iterator caching inside range adaptors [PR100479]

This fixes two issues with our iterator caching as described in detail
in the PR.  Since we recently added the __non_propagating_cache class
template as part of r12-336 for P2328, this patch just rewrites the
problematic _CachedPosition partial specialization in terms of this
class template.

For the offset partial specialization, it's safe to propagate the cached
offset on copy/move, but we should still invalidate the cached offset in
the source object on move.

libstdc++-v3/ChangeLog:

PR libstdc++/100479
* include/std/ranges (__detail::__non_propagating_cache): Move
definition up to before that of _CachedPosition.  Make base
class _Optional_base protected instead of private.  Add const
overload for operator*.
(__detail::_CachedPosition): Rewrite the partial specialization
for forward ranges as a derived class of __non_propagating_cache.
Remove the size constraint on the partial specialization for
random access ranges.  Add copy/move/copy-assignment/move-assignment
members to the offset partial specialization for random
access ranges that propagate the cached value but additionally
invalidate it in the source object on move.
* testsuite/std/ranges/adaptors/100479.cc: New test.
libstdc++-v3/include/std/ranges
libstdc++-v3/testsuite/std/ranges/adaptors/100479.cc [new file with mode: 0644]