Boost logo

Proto :

Subject: Re: [proto] expanding Proto's library of callables
From: Thomas Heller (thom.heller_at_[hidden])
Date: 2010-12-28 12:33:04


Eric Niebler wrote:

> On 12/28/2010 11:43 AM, Thomas Heller wrote:
>> Eric Niebler wrote:
>>
>>> On 12/28/2010 5:39 AM, Thomas Heller wrote:
>>>> I just saw that you added functional::at.
>>>> I was wondering about the rationale of your decision to make it a non
>>>> template.
>>>> My gut feeling would have been to have proto::functional::at<N>(seq)
>>>> and not proto::functional::at(seq, N).
>>>
>>> Think of the case of Phoenix placeholders, where in the index is a
>>> parameter:
>>>
>>> when< terminal<placeholder<_> >, _at(_state, _value) >
>>
>> vs:
>>
>> when<terminal<placeholder<_> >, _at<_value>(_state)>
>
> Have you tried that? Callable transforms don't work that way. It would
> have to be:
>
> lazy<at<_value>(_state)>
>
> Blech.

Right ... i keep forgetting about that ...

>>> For the times when the index is not a parameter, you can easily do:
>>>
>>> _at(_state, mpl::int_<N>())
>>
>> vs:
>>
>> _at<mpl::int_<N> >(_state)
>>
>> just wondering ... the second version looks more "natural" and consistent
>
> Still think so?

Nope. Let's have it your way :)

One other thing though ...

    struct at
    {
        BOOST_PROTO_CALLABLE()

        template<typename Sig>
        struct result;

        template<typename This, typename Seq, typename N>
        struct result<This(Seq, N)>
          : fusion::result_of::at<
                typename boost::remove_reference<Seq>::type
              , typename boost::remove_const<typename
boost::remove_reference<N>::type>::type
>
        {};

        template<typename Seq, typename N>
        typename fusion::result_of::at<Seq, N>::type
        operator ()(Seq &seq, N const &
BOOST_PROTO_DISABLE_IF_IS_CONST(Seq)) const
        {
            return fusion::at<N>(seq);
        }

        template<typename Seq, typename N>
        typename fusion::result_of::at<Seq const, N>::type
        operator ()(Seq const &seq, N const &) const
        {
            return fusion::at<N>(seq);
        }
    };

VS:

    struct at
    {
        BOOST_PROTO_CALLABLE()

        template<typename Sig>
        struct result;

        template<typename This, typename Seq, typename N>
        struct result<This(Seq, N)>
            : result<This(Seq const &, N)>
        {};

        template<typename This, typename Seq, typename N>
        struct result<This(Seq &, N)>
          : fusion::result_of::at<
                Seq
              , typename proto::detail::uncvref<N>::type
>
        {};

        template<typename Seq, typename N>
        typename fusion::result_of::at<Seq, N>::type
        operator ()(Seq &seq, N const &
BOOST_PROTO_DISABLE_IF_IS_CONST(Seq)) const
        {
            return fusion::at<N>(seq);
        }

        template<typename Seq, typename N>
        typename fusion::result_of::at<Seq const, N>::type
        operator ()(Seq const &seq, N const &) const
        {
            return fusion::at<N>(seq);
        }
    };

I think the second version instantiates less templates than the first one.


Proto list run by eric at boostpro.com