Boost logo

Boost :

From: Eric Friedman (ebf_at_[hidden])
Date: 2003-10-29 19:24:43


Jaap,

Jaap Suter wrote:
>>>So can I assume Boost.Variant can detect non-throwability and act
>>>accordingly (not do an allocation if not necessary)?
>>
>>Yes, via the type_traits library. Without compiler support, however, you
>>likely will need to specialize the appropriate type_traits templates for
>>your user-defined types.
>
>
> Is it possible to document which type_traits specifically I need to
> specialize. No hurries, and I haven't actually put in any effort to find out
> which ones myself, but it might be nice.

Yes, I will document it.

Just so you know: If has_nothrow_copy<T> evaluates true, variant will
avoid allocation of T. If has_nothrow_constructor evaluates true for any
type in the variant, then allocation will be avoided in all cases.

>>>Brian does bring up another point, which is the order of destruction and
>>>construction. Is this garantueed, or merely a consequence of the current
>>>implementation scheme? Is it possible to make the order of dtor and
>>>(copy-)ctor an explicitly document feature that can be relied upon?
>>
>>It is not guaranteed. For example, since changing from double-storage to
>>temporary heap backup, the order has reversed. I'm not sure what the
>>value of a guaranteed order would be anyhow.
>
> Well, it allows me to do exactly the thing posted in the original message;
> implement a state machine where state entries and exits are implemented
> through ctors and dtors. I can probably think of a few other cases where
> such a defined order can be exploited too.
>
> Personally, I think it makes sense conceptually too. If I use the assignment
> operator on any other class, then in a sense the existing state is destroyed
> first, and then the new state is copied in. I'm not saying that it's
> implemented like that (as no sane person would do), but the similarities are
> there. I think it makes sense to let variant behave the same.

Hmm, I don't want to lock variant into a particular order, since doing
so would exclude a particular set of otherwise-valid implementation
approaches.

[snip]
>>I think this would be better handled with code such as the following:
>>
>> int p = mpl::index_of< my_variant::types, float >::value;
>>
>>Unfortunately, mpl::index_of does not yet exist. Perhaps this is enough
>>motivation for me to finally create it.
>
>
> That makes sense, and I wrote exactly that today actually :). It was
> something like:
>
> template<class Sequence, class Element>
> struct index_of : mpl::distance<
> typename mpl::begin<Sequence>::type,
> typename mpl::find<Sequence, Element>::type
> >::type
> {};
>
> Probably the coding style isn't mpl compatible, but it's just to prove that
> it's an easy enough addition.

Well, that doesn't exactly work if the type is *not* found. But, yes,
your approach is close to what I currently use.

What I had in mind would be to use iter_fold_if, which would allow the
search and the index-counting to occur in just one traversal, and for
the traversal to halt if the type is in fact found. (I don't really know
why iter_fold_if is in the 'aux' namespace of MPL...)

> Anyway, my work lead to the following questions:
>
> 1. I'm using MSVC 7.0, which means I can't use the variant<list<types> >
> method. Is this really not implementable on 7.0, or is it simply too much
> work. I thought of a few ways myself to do it without PTS, but I'm probably
> overlooking something.

Variant construction and assignment simulates overload resolution using
an inheritance hierarchy constructed from a list of types (see
boost/variant/detail/initializer.hpp to see how this is accomplished).

On compilers not supporting using-declarations from dependent (i.e.,
template 'typename' parameter) bases, this can be simulated for a fixed
number of types using the preprocessor. (Again, this is in initializer.hpp.)

A while ago, I tried to implement a is_better_conversion type traits
that would yield describe the result of overload resolution. Working on
the assumption I could get this trait to work, I devised a solution that
would allow nonconformant compilers to work with an arbitrary list of
types. Unfortunately I was never able to get the trait to work (though I
forget the specific details).

I'll try to look back into it.

> 2. Is the 'variant::types' typedef a type that models the mpl::sequence
> concept? I tried running a few algorithms over it, but not everything
> compiled. Therefore, as an temporary solution, I'm now simply defining both
> a vector of types, and a variant of the same types (not using the vector
> because I'm on MSVC). When I need to get the index, I just apply index_of to
> the vector, instead of using variant::types.

It should be a MPL-compatible sequence. Can I get an example of what
code of yours did not work?

Thanks,
Eric


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