
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.de...
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