Skip to content
Snippets Groups Projects
Commit de38fa63 authored by Carsten Gräser's avatar Carsten Gräser
Browse files

[bugfix] Fix operator-> for non-proxy TransformedRangeIterator

In order to support `operator->`, the `TransformedRangeIterator`
uses a `PointerProxy<T>` that stores the result of the transformation.
There are to possible options for the type to be stored:

* `reference = decltype(transform(...))` and
* `value_type` = std::decay_t<reference>`.

So far a `value_type` was stored in the `ProxyType`. This has the
consequence that `operator->` will store a copy of the result,
even if it is an l-value. Hence `(*it).foo(...)` calls `foo()`
on the referenced value while `it->foo(...)` calls it on the copy.
This is not only inefficient, but may also lead to incorrect
behaviour if `foo(...)` is non-const, e.g. `operator=`.

This patch replaces `value_type` by `reference` in the `ProxyType`.
Thus if the transformation returns a value it will still be
copied, while an l-value reference is stored as reference.

To make this work we also have use `add_pointer_t<T>` instead
of `T*` to get a proper pointer if `T` is a reference.
parent 43157797
No related branches found
No related tags found
1 merge request!1389[bugfix] Fix two bugs in TransformedRangeView and TransformedRangeIterator
......@@ -344,7 +344,7 @@ namespace Dune
PointerProxy(ProxyType&& p) : p_(p)
{}
ProxyType* operator->()
std::add_pointer_t<ProxyType> operator->()
{
return &p_;
}
......@@ -375,7 +375,7 @@ namespace Dune
using iterator_category = std::forward_iterator_tag;
using reference = decltype(transform(std::declval<F>(), std::declval<I>()));
using value_type = std::decay_t<reference>;
using pointer = PointerProxy<value_type>;
using pointer = PointerProxy<reference>;
// If we later want to allow standalone TransformedRangeIterators,
// we could customize the FunctionPointer to be a default-constructible,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment