Boost logo

Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2002-07-20 09:47:06


On Friday 19 July 2002 10:23 pm, Eric Friedman wrote:
> (1) Variant-to-variant conversion.
>
> "Strict" conversion requires each of the source variant's bounded types to
> be unambiguously convertible to one of the destination variant's bounded
> types; "Non-strict" requires only the source variant's runtime value to be
> convertible to one of the destination variant's bounded types, throwing an
> exception if the conversion does not exist or is ambiguous.
>
> Which should be the default conversion method (strict being safer,
> non-strict more useful), and should both methods be supplied?

Nonstrict conversion breaks the static guarantees that variant is so good at
keeping. I think strict conversion must be available and should be the
default behavior. I'd think that nonstrict conversion should be omitted from
the library: if it is necessary for a particular situation, we should force
the user to enumerate all the cases in a visitor so they _know_ when they
aren't handling a case.

> (2) Default construction of variant types/"emptiness" of variant values.
>
> Should variant default construct the first type specified in its bounds or
> should it initialize to an 'empty' state (like boost::any)?
>
> The former is arbitrary (though arbitrariness may be documented). But the
> latter, while elegant, may introduce greater complexity in user code (i.e.,
> can a variant be "emptied" once it is non-empty? under what conditions must
> the user check against variant::empty()? and so on).

The latter breaks static completeness-of-decoding guarantees, because it is no
longer sufficient to list all of the type cases in the visitor (you must also
have an "empty" case, and that's a real annoyance if you never intend to use
it).

The decision to default-construct the first type is arbitrary, but the
DefaultConstructible requirement is only there if the user uses the variant
default constructor, so I don't think it's a big loss for such a huge gain in
static type safety.

> Currently variant::empty() is provided only for type signature
> compatilibity with boost::any and always returns a true value. Is the
> concept of an empty variant an important or useful one?

Shouldn't that always return a false value?

> (3) Algorithmic complexity of variant visitation.
>
> O(1) is possible but introduces need for some thread-safety primitives and
> (minimal) space overhead; O(N) is achievable via cascading if statements.
>
> On one hand it is unlikely N (i.e. the number of bounded types) will grow
> large, and so the question seems moot; on the other hand, there may be uses
> for variant that have not yet been imagined -- and which may leverage N
> that is large.
>
> What should be required of a conforming variant implementation?

O(1) vs. O(N) is overly simple, unfortunately :(. The major operation in the
O(1) is a call through a function pointer, whereas the O(N) is N conditional
jumps (the calls can all be inlined). I think we'll need some experiments to
find out what 'N' is for the tradeoff to occur. However, I suspect that the
complexity guarantee could be left out.

> (4) Non-member variant functionality, e.g., type_switch, extract<T>,
> try_convert (for non-strict variant-to-variant conversion), etc.
>
> Should these facilities be treated as separate libraries from
> Boost.Variant, as they are not variant-specific? How would such an approach
> be handled if variant were accepted into Boost?

extract<T> can be added at any time, so it might as well come along with
variant.

type_switch should probably be a separate library, because it could include
several libraries and be rather large. At this point, I think we should look
toward getting Variant up to the formal review stage.

try_convert could come with the library

I essentially would favor small, noncontroversial changes to go in with the
library, whereas larger changes that might prompt a lot of discuss should be
separate libraries (so they don't detract from the main purpose of the
library). extract<T> and try_convert are quite small, so they should be
coupled with variant; type_switch is a lot larger and we have yet to discuss
exact features for it.

        Doug


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