
On Fri, 20 Dec 2024 at 20:04, Peter Dimov via Boost
Neil Groves wrote:
I have working on a private branch (without new member functions in any associative container):
users | mapped_values(user_id) | invoke([](user_type& user) { user.status = deactivated; });
To me, this looks remarkably similar to your example.
That's the best I can do using the standard ranges: https://godbolt.org/z/WMrzszMGP
But it's not the same as the original example, because it doesn't return the found user.
It is true that my example didn't the same type as the original but incorrect to state that it didn't return the found user. It isn't clear that it does but it does by returning the equal_range(key) | map_value. It returns the range it was given by the invoke adapter, and so it does return the user in the range of 1. I started with this because I'm working on a layer of the most general (that work with multi- containers and well as the single value containers) and working toward the specific which I believe I can achieve without problems layering on top of the general solutions and optimizing in places.
There might be a way to say something like `| views::front` that will make the pipeline return .front(), but I don't know what it is.
I proposed something very similar to this in my earlier, far too lengthy, waffle. What I was thinking was that we could have front_or and when empty provide another value. This with some syntactic sugar can produce the value_or / ref_or functionality. I think layering this on the range solution should work nicely, and I believe is able to be done with optimizations that make the 0..1 ranges zero overhead. I have not demonstrated this yet. I intuit that performance ought to be superior using 0..1 ranges vs optional, but until I have benchmarks I can only say it is my intuition. I would never enforce the absence of optional, but I intend to be able to avoid optional for many of the use-cases for correctness and performance. You can say `| views::take(1)` but that's still a range.
`| views::to
>` would work if it worked, but I don't think it does.
.. .but it could. I'm happy to make chagnes were necessary to get what we want. I'm not totally sold on the optional idea. I prefer the range to fn idiom for it's elimination of the dereferencing of a nullopt. The return of a default value (which may or may not be the same type as the mapped_type) seems to offer an option-free approach to the common use-case where one wishes to select a default alternative value when it is missing. It also leaves the door open to returning an optional for when that makes sense. I believe I can do all of these things. If people want it. I shall build this. Of course, Boost.Range is not state-of-the-art and there could potentially be work to do if we want simliar things in the standard ranges. I don't see any reason the considerably superior standard ranges cannot do this as well or better. However Peter I know how clever and experienced you are and so I wonder if you have spotted trouble ahead that I am missing? Regards, Neil Groves