Boost logo

Boost :

Subject: Re: [boost] [fusion] [intro] ADAPT_STRUCT extensions
From: Christopher Schmidt (mr.chr.schmidt_at_[hidden])
Date: 2010-10-04 17:22:27


Christopher Schmidt schrieb:
> Joel de Guzman schrieb:
>> On 8/17/2010 5:10 AM, Christopher Schmidt wrote:
>>>>> I think simply providing a sequence of proxies is less error-prone than
>>>>> trying to hide it when possible.
>>>>> the example I used in a previous email would then outright fail until
>>>>> support for proxies is added, as opposed to work in one case and
>>>>> fail in
>>>>> another, very similar, case.
>>>>
>>>> Those are very good points. I await for Christopher's reply. I think
>>>> what you gave is a reasonable strategy. I like it.
>>>
>>> I don't agree. The proxy is indeed clumsy, but due to being implicitly
>>> convertible to the underlying type it does its job quite well. In most
>>> use-cases an adapted 'class' does feel just like any other regular
>>> fusion container.
>>> In my opinion, fully exposing the proxy type is not conducive as the
>>> type of interest is always the type encapsulated by the wrapper. The
>>> proxy is just a means to an end.
>>> If the special traits of proxies are ditched, that is if the implicit
>>> conversion ability is removed and the proxy is exposed as the actual
>>> value type, all generic user code will need to handle proxy types
>>> explicitly. Generic user tmp code would probably need hacky mpl-code
>>> that distinguishes fusion proxies from non-proxy value types. Generic
>>> run-time functors would need to be specialized for proxies. That is
>>> prone to errors! With the current design, only very few run-time
>>> functors have to be specialized for proxies at all.
>>
>> Also very good points. I think the proxy should behave similar to
>> Boost ref, as it should expose an implicit conversion to T. This alone
>> will satisfy many code that expects T. As for exposing the proxy as
>> the value type of the sequence, you are right. However, what we can
>> probably do is to be consistent with handling const and non-const
>> and always return a proxy so there is no surprise when code works
>> one way and not the other way.
>
> I agree.
>
>>
>>> Stefan, considering your special use-case: if the proxy's underlying
>>> value type is exposed as the real value type of the sequence, you don't
>>> need to specialize your functor at all. See the attached code -
>>> ref_for_each is an implementation of fusion::for_each that internally
>>> resolves proxy types. Such an approach hides the proxy completely!
>>>
>>> I do not see how fully exposing the proxy leads to simpler or less error
>>> prone code. Therefore I vote for keeping the interface as it is - with
>>> the proxy type being documented and its semantics fully exposed to the
>>> user.
>>> As for the name, I do like ADAPT_EXPR or ADAPT_ADT more than ADAPT_CLASS.
>>
>> My problem with this approach is that you need special algorithms to
>> deal with these proxies. It may not be a bad idea to embrace proxies
>> (and reference wrappers) library wide as intrinsic to our concepts,
>> so that proxies will be totally transparent, but I am not quite sure
>> if it's worth it. It's an additional burden for algorithm writers
>> to deal with.
>
> Well, that is a *lot* of work - and such an approach does not hide the
> proxy completely. The return type of fusion::deref is still a proxy.
>
> I think we should proxify the 'const' return type and rename
> BOOST_FUSION_ADAPT_xxxCLASSxxx to BOOST_FUSION_ADAPT_xxxADTxxx .
> BOOST_FUSION_ADAPT_xxxEXPRxxx breaks ranks as EXPR does not relate to
> the adaptee at all. boost::fusion::extension::class_member_proxy<T>
> should be changed to boost::fusion::extension::adt_attribute_proxy<T,
> B>, with B being a boolean constant that is true for lvalue and false
> for rvalue proxies.
> The drawbacks of proxies should be pointed out explicitly in the
> documentation, including a short abstract that advocates adapting
> abstract data types using fusion's native extension mechanism in order
> to avoid the proxy.

I just committed a preliminary draft of the documentation of
BOOST_FUSION_ADAPT_ADT to the trunk. The actual changes to the code were
committed two weeks ago.
The documentation can be found here:

http://svn.boost.org/svn/boost/trunk/libs/fusion/doc/html/fusion/adapted/adapt_adt.html
http://svn.boost.org/svn/boost/trunk/libs/fusion/doc/html/fusion/notes.html#fusion.notes.adt_attribute_proxy

https://svn.boost.org/trac/boost/browser/trunk/libs/fusion/doc/adapted.qbk
https://svn.boost.org/trac/boost/browser/trunk/libs/fusion/doc/notes.qbk

Feel free to improve the wording in any way ;)
I will have the documentation for the other macros
(BOOST_FUSION_ADAPT_TPL_ADT, BOOST_FUSION_ADAPT_ASSOC_ADT,
BOOST_FUSION_ADAPT_ASSOC_TPL_ADT) committed and merged by Saturday.

The core code of the BOOST_FUSION_ADAPT_xxxADTxxx-macros is in

https://svn.boost.org/trac/boost/browser/trunk/boost/fusion/adapted/adt/detail/adapt_base.hpp#L30

This macro generates the necessary boilerplate, that are the proxy
(fusion::extension::adt_attribute_proxy) specializations, the actual
accessors (specializations of
fusion::extension::access::adt_attribute_access) and the code necessary
to reuse the underlying implementation of regular adapted structs.
I added a get()-function to the proxy. This function may be used in case
the implicit conversion is not feasible. The accessors and the proxy are
disjointed so a user may just 'friend class fusion::extension::access'
without having to deal with the proxy and its template arguments. For
more information, see this post from Stefan.

http://article.gmane.org/gmane.comp.lib.boost.devel/207247

Unfortunately this friending does not work with gcc 3.x as the access
rights of a friend class are (incorrectly) not propagated to its nested
classes.

-Christopher


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