Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ranges::views::cache1 moves from the cache on read. #1766

Open
MPJansen opened this issue Feb 3, 2023 · 0 comments
Open

ranges::views::cache1 moves from the cache on read. #1766

MPJansen opened this issue Feb 3, 2023 · 0 comments

Comments

@MPJansen
Copy link

MPJansen commented Feb 3, 2023

Hi!
Thank you so much for providing this excellent library.

While trying to avoid a known behavior of transform-filter pairs as described here I ran into an issue with views::cache1.

The code looks like

auto pipeline = ranges::views::transform(
   [](auto object) {
     return object;
    }) 
  | ranges::views::cache1
  | ranges::views::filter(
    [](auto object /*const auto& object*/) { <-- A
      return object.has_value(); // <-- B -- object is ok here
   }) //
  | ranges::views::transform(
    [](auto object) {
      // <-- C -- object is moved from/unititialized here
    });

using this pipeline result in an uninitialized object on line C. Removing the cache1 fixes this but result in the first transform being executed twice per element.
Turning the argument on line A into a const reference also fixes the problem, but I am unsure why and think it is undesirable.

Inspecting the implementation of cache1 I found the following:

range_value_t<Rng> && read() const
{
    if(parent_->dirty_)
    {
        parent_->update_(*current_);
        parent_->dirty_ = false;
    }
    return std::move(*parent_->cache_);
}

It seems that the read function of cache1's cursor actually moves from the cache, which seemingly defeats the purpose of having one.
Therefore if filter has a value-type argument it moves from the cache but leaves the dirty_ flag false. the next read of this iterator then reads from an uninitialized cache.

I think this might be a bug in the implementation, but am unsure.

Kind regards,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant