Boost logo

Boost :

Subject: Re: [boost] [variant] Please vote for behavior (Was: Basic rvalue and C++11 features seupport)
From: Larry Evans (cppljevans_at_[hidden])
Date: 2013-01-24 18:00:51


On 01/24/13 16:16, Larry Evans wrote:
> On 01/24/13 13:56, Larry Evans wrote:
>> On 01/21/13 17:51, Hartmut Kaiser wrote:
>>>> On 1/22/13 3:57 AM, Antony Polukhin wrote:
>>>>> I've got some nice idea from discussion: nullable variant. If many
>>>>> people use or want to use a variant with a type, that represents empty
>>>>> state, we can create a separate nullable variant class. I think that
>>>>> nullable variant can be implemented more efficient that the current
>>>>> variant. For example we can simplify copy/move constructors and
>>>>> assignment operators, guarantee fast noexcept default construction,
>>>>> simplify metaprogamming and reduce compilation times. Maybe someone
>>>>> want to implement it?
>>>>
>>>> I like it! If you implement it, I'll be your first user :-) I don't really
>>>> care much about this "never empty" guarantee and I think it's not really
>>>> worth the trouble.
>>>
>>> I'd prefer to have a nullable variant as well. If not that, then I would
>>> like to support II: Set operand.p_ to NULL, add BOOST_ASSERT in get
>>> operations.
>>>
>>
>> OR have get<T> return recursive_wrapper<T> and then the user
>> would have to check whether it's nulled. This avoids the
>> need for BOOST_ASSERT; however it does violate the contract:
>>
>> This "never-empty" property insulates the user from the possibility of
>> undefined variant content and the significant additional
>> complexity-of-use attendant with such a possibility.
>>
>> mentioned here:
>>
>> http://www.boost.org/doc/libs/1_52_0/doc/html/variant/design.html#variant.design.never-empty
>>
>> however, setting operator.p_ to NULL does the same but makes
>> it harder for the user to detect since the user would have to
>> use a try/catch to test it, IIUC.
>>
>> -regards,
>> Larry
>>
> However, if you're allowing recursive_wrapper<T>::get_pointer() to
> return 0, why not just put the recursive_wrapper closer to where
> the recursion actually occurs? After all, a null pointer is
> one way to signal the end of a recursive data structure.
>
> IOW, something like the first attachment.
>
> The current way of doing the same is the 2nd attachment.
> This current way puts recursive_wrapper as one of the
> variant's bounded types; however, the 1st attachment
> shows it used as a member of one of the bounded types.
> That seems more like the way its normally done.
> After all, the domain equation for the simplest recursive
> type is:
>
> List<T> = Null + T*List<T>
>
> which is closer to what the 1st attachment has, except,
> instead of T*List<T> it has:
>
> fusion::vector<T,recursive_wrapper<List<T> >
>
> and instead lf Null it has:
>
> boost::blank.
>
> In contrast, the 2nd attachment is more like:
>
> List<T> = Null + recursive_wrapper<T*List<T> >
>
> The Null + T*recursive_wrapper<List<T> > seems
> closer to how the actual recursion is implemented.
>
> -regards,
> Larry
>
OOPS, allowing recursive_wrapper<T>::get_pointer() == 0
violates the domain equation:

  List<T> = Null + T*List<T>

because with a null recursive_wrapper, there are 3 possible
states:

  List<T> = Null + T*List<T> + List<T>*==0

where List<T>*==0 means a null pointer to a List<T>.

The only way I can see to solve that problem is to
disallow recursive_wrapper<T>::get_pinter() == 0 and,
when moving from a List<T>, set the moved from state
to Null, AFAICT.

-Larry


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