Re: [boost] [STLInterfaces] only three operations?
On Mon, Dec 9, 2019 at 12:55 PM Andrzej Krzemienski <akrzemi1@gmail.com> wrote:
pon., 9 gru 2019 o 17:32 Zach Laine <whatwasthataddress@gmail.com> napisaĆ(a):
Same with the iterator in the flight map:
https://github.com/tzlaine/flat_map/blob/master/implementation/flat_map#L266
According to C++17 requirements this shouldn't have been a random_access_iterator.
Also, std::ranges::sort() will not work with it. But this is not directly related to `iterator_interface`
I don't know why you think that. ranges::sort() is designed to work with std::random_access_iterator, which is designed explicitly to support proxy iterators. Casey and Eric have assured me that this "just works". Do you know of a reason why it does not? If so, you've spotted a defect, and we should file an LWG issue immediately.
Not sure if it is a defect. An iterator that returns a proxy as ::reference can be a valid random_access_iterator. However, std::ranges::sort(), apart from a random_access_iterator requirement, has one more requirement: sortable<>: (http://eel.is/c++draft/sort) which boils down to indirectly_writable ( http://eel.is/c++draft/iterator.concept.writable). This last concepts puts severe restrictions on proxy types. For instance you should be able to assign to them when they are const-qualified. So a type like std::tuple<> of references will not work. But you will be able to design a sufficiently bizarre proxy type that will work with std::ranges::sort(), So in a way it will work with *some* reference proxies.
Ok, I just realized this somehow drifted off-list. Re-adding the list... This is the definition of indirectly_writable: template<class Out, class T> concept indirectly_writable = requires(Out&& o, T&& t) { *o = std::forward<T>(t); // not required to be equality-preserving *std::forward<Out>(o) = std::forward<T>(t); // not required to be equality-preserving const_cast<const iter_reference_t<Out>&&>(*o) = std::forward<T>(t); // not required to be equality-preserving const_cast<const iter_reference_t<Out>&&>(*std::forward<Out>(o)) = std::forward<T>(t); // not required to be equality-preserving }; All you need to make this work is a reference type for which all those are well-formed. If you pick std::tuple, it all just works. If you pick std::pair, only the first two expressions in the requires expression work. You can easily define UDTs for which this concept works too, of course. Zach
participants (1)
-
Zach Laine