chromium / subspace

A concept-centered standard library for C++20, enabling safer and more reliable products and a more modern feel for C++ code.; Also home of Subdoc the code-documentation generator.
https://suslib.cc
Apache License 2.0
89 stars 15 forks source link

Put moved() onto IteratorOverRange and make it unsafe #382

Closed danakj closed 1 year ago

danakj commented 1 year ago

moved() will move from the references in the range, which leaves behing moved-from objects which can cause bugs and Undefined Behaviour. It is up to the caller to clear those elements from the range or destroy the range after using moved(). This type of global analysis requires careful code review and is thus unsafe.

Subspace collections don't need the moved() function, as you can consume the collection (move from it) to make the iterator, which will then own the elements and yield them by value, moving them from the iterator.

We do not use std::borrowed_range here because it returns the wrong default. It returns false for types it does not know about, but those types (like llvm::ArrayRef for instance) may not own the elements they provide a range over, and moving from them is invalid. Even if borrowed_range could be made accurate though, the requirement for the caller of moved() to clean things up after makes the operation unsafe.