[libcxx-commits] [PATCH] D129823: [libc++][ranges] Make range algorithms support proxy iterators

Konstantin Varlamov via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Sun Jul 17 22:57:27 PDT 2022


var-const marked an inline comment as done.
var-const added inline comments.


================
Comment at: libcxx/test/std/algorithms/ranges_robust_against_proxy_iterators.compile.pass.cpp:152
+  //test(std::ranges::prev_permutation, in, binary_pred);
+  //test(std::ranges::next_permutation, in, binary_pred);
+}
----------------
huixie90 wrote:
> var-const wrote:
> > huixie90 wrote:
> > > var-const wrote:
> > > > Uninitialized memory algorithms don't work with `ProxyIterator` because it doesn't satisfy `nothrow-input-iterator` that requires the result of dereferencing the iterator to be the same as `iter_reference_t`. I'm not sure if it's possible to write a different valid proxy iterator that would satisfy that constraint but still require special handling in the implementation. @huixie90 What do you think?
> > > The `nothrow-xxx-iterator` explicitly requires `std::same_as<std::remove_cvref_t<std::iter_reference_t<I>>, std::iter_value_t<I>>`, which basically means `value_type& == reference`, which rules out all the proxy iterators. It makes sense for writing to uninitialized memory because we do need the address of `*it` to be something that we can write to (not the proxies). So for most uninitialized algorithms, they are designed not to work with proxies. So we can't test them.
> > > 
> > > However, there are two exceptions. for `uninitialized_copy` and `uninitialized_move`, the inputs and outputs are separate. So in theory the inputs can be `ProxyRange` and the outputs can be a simple array which does model  `nothrow-xxx-iterator` 
> > Thanks a lot for looking into this! It's very helpful. It seems that the following constraint:
> > ```
> >     requires constructible_from<iter_value_t<_OutputIterator>, iter_reference_t<_InputIterator>>
> > ```
> > also prevents proxy iterators from being used with `uninitialized_{copy,move}`?
> hmm. that is strange. 
> let's say the input range is
> ```
> std::array a{1,2,3};
> ProxyRange inputs{a};
> ```
> and output is 
> ```
> std::array<Proxy<int>, 3> out;
> ```
> `iter_value_t<_OutputIterator>` should be `Proxy<int>` and `iter_reference_t<_InputIterator>` should be `Proxy<int&>`
> and `Proxy<int>` should be constructible from `Proxy<int&>`.
> did I miss anything?
`_OutputIterator` would have to be a `nothrow-forward-iterator`, so IIUC its `value_type` cannot be `Proxy`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D129823/new/

https://reviews.llvm.org/D129823



More information about the libcxx-commits mailing list