Boost logo

Boost :

Subject: Re: [boost] [tuple] Functionals for tuple element access?
From: Eric Niebler (eniebler_at_[hidden])
Date: 2013-02-21 12:37:46


On 13-02-20 01:42 PM, Jan Hudec wrote:
> Hello All,
>
> Doing some heavy template work on collections of pairs and tuples I came
> across the need for functors returning tuple and pair members. So I looked
> whether Boost has anything like that, but couldn't find any.
>
> Now the functors can be written using bind like:
>
> bind(_1, &TupleType::get<3>);
> bind(_1, &PairType::first);
>
> except that requires explicitly mentioning the tuple/pair type. Trying to use
> simply
>
> &boost::tuples::get<3, WHAT?!?!?>
>
> even failed for me as boost::tuples::get is actually a 3-argument template
> based on boost::tuples::cons, which looks like implementation detail I better
> not rely on. Besides bost methods involve pointer-to-{function,member}, which
> might interfere with inlining.
>
> So I think it would be convenient to have functions like this somewhere in
> boost:
>
> template <int N>
> struct getter {
> template <typename X>
> struct result;
>
> template <typename F, typename T>
> struct result<F(T &)> {
> typedef BOOST_DEDUCED_TYPENAME element<N, T>::type &type;
> };
>
> template <typename F, typename T>
> struct result<F(T const &)> {
> typedef BOOST_DEDUCED_TYPENAME element<N, T>::type const &type;
> };
>
> template <typename T>
> BOOST_DEDUCED_TYPENAME element<N, T>::type &
> operator()(T &t) {
> return get<N>(t);
> }
>
> template <typename T>
> BOOST_DEDUCED_TYPENAME element<N, T>::type const &
> operator()(T const &t) {
> return get<N>(t);
> }
> };

There is something like this in Proto, where this kind of thing comes up
now and then. boost/proto/functional/fusion/at.hpp. It works on Fusion
vectors, not tuples, though.

> I would like to ask:
>
> 1. Would there be interest in adding this? Should I polish it up?

Sure.

> 2. What would be good name and place for it (boost::tuples::getter)?
>
> 3. To support pairs, would it be preferred to specialize the N=0 and N=1
> cases (unfortunately I don't see how to handle the result struct without
> copy-paste) or define separate first_getter and second_getter or
> something like that?

Proto has "first" and "second": boost/proto/functional/std/utility.hpp.

> 4. The definition of result with const and non-const reference was enough
> for my uses in boost::transform_value_property_map, but I suspect it does
> not cover all necessary cases (I need non-reference and rvalue reference
> for C++11 too, right?)

In C++11, the nested result template is superfluous.

> My actual use-case was with boost::transform_value_property_map. I needed
> several property maps with the same set of keys, so I created one
> boost::associative_property_map with tuple values and splitted it to maps for
> the items using the above functor.
>
> Obviously nothing of this is needed with C++11 lambdas, but I am stuck
> having to support some obscure platforms like WinCE 4.2 and for it with
> MSVC++9.0.

I, for one, would love to see more algorithms implemented as polymorphic
function objects. They're more useful than function templates.

-- 
Eric Niebler
Boost.org

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk