$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Richard Hodges (hodges.r_at_[hidden])
Date: 2024-12-21 07:21:07
Sent from my iPad
> On 20 Dec 2024, at 20:37, Neil Groves via Boost <boost_at_[hidden]> wrote:
> 
> On Thu, 19 Dec 2024 at 15:30, Christian Mazakas via Boost <
> boost_at_[hidden]> wrote:
> 
>> The case against a free function gets a lot stronger once you remember that
>> optional in C++ still supports unchecked accesses with trivial syntax and
>> that
>> the most ergonomic and safe way to actually use it is via something like
>> this:
>> 
>>    users.find(user_id).map([](auto& user) { user.status = deactivated;
>> return user; });
>> 
>> 
> As you know I've tried seeing how far I could get with some work in
> Boost.Range. I appreciate this isn't the solution you are dreaming of.
> 
> 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; });
How is this better than
for(auto&& user : users)
  if(user == user_id)
    deactivate(user);
?
My thoughts on the pipeline code:
- It took a while to figure out what it was doing.
- you canât easily place a breakpoint in it
- itâs only possible with a load of cryptic template expansion
- requires a deep knowledge of not only the language and template but also the helper library.
Whereas the procedural code is:
- absolutely obvious in its intent
- easily debuggable
- implemented using only the language and no template help at all
- trivially teachable
> To me, this looks remarkably similar to your example.
> 
> This works for std::map, std::multimap, std::unordered_map and
> std::unordered_multimap. I find this more readable than the original. Of
> course, this is for one very specific example and I lack support for many
> of the functions that boost::optional has that one may likely wish for when
> using a container that has at most 1 mapped_value per key.
> 
> mapped_values(key) is a Boost.Range adaptor similar to the
> existing "map_values" except that it takes a key parameter and applies
> equal_range to the source range before extracting the mapped_type. I did
> also find the map adaptors in Boost.Range to be unnecessarily fussy about
> const-ness propagation. I had to fix this on my branch to make any
> substantial progress.
> 
> I wondered if reading this example line above if it didn't look quite as
> horrific as perhaps you were imagining?
> 
> One unfortunate aspect of the original snippet is the boost::optional
> choice of the word "map" where we are also working with a concrete "map"
> container.
> 
> There is plenty of work to do if this is of interest to anyone. I would
> want to ensure there was no performance overhead, and currently I'm not
> entirely convinced that my initial implementation that uses the member
> equal_range is optimal. This is an implementation detail, which I would
> work through.
> 
> The value_or ( or front_or ) functionality for non-multi containers can be
> added in a similar manner, and be broadly usable for range algorithms.
> 
> 
> Were this a free function, a user wouldn't be able to create this nice
>> fluent interface
>> that users, by and large, seem to actually like.
>> 
>> 
> For the left-to-right syntax I noticed that there has been a neat looking
> proposal
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2011r0.html
> 
> I'm hoping the left-to-right solution will appear by one or more of
> the active proposals while we make progress coping with the ways we have.
> 
> 
> 
>> - Christian
>> 
>> 
> If this is of any interest to you I'll look at putting some of this into
> the develop branch of Boost.Range. If it is not interesting I shall
> continue on my branch and build a more compelling iteration that I shall
> land later.
> 
> I hope this helps,
> 
> Neil Groves
> 
> _______________________________________________
> Unsubscribe & other changes: http://listarchives.boost.org/mailman/listinfo.cgi/boost