|
Boost : |
From: Douglas Gregor (gregod_at_[hidden])
Date: 2001-11-03 19:46:49
On Saturday 03 November 2001 05:46, you wrote:
> Hmmm, good point. I actually envisaged a very minor change to the
> standard whereby class types would be allowed in union definitions to
> get the correct alignment, but the semantics of unions would be
> otherwise unchanged.
>
> I hadn't actually thought through the destructor issue, but words
> could be added to the standard that class type members must be
> explicitly constructed and destructed by the user and the behaviour
> is undefined otherwise (i.e. unions don't get a compiler-generated
> destructor); though maybe that would be too subtle and a source of
> bugs.
My inclination is that this sort of change would not go over well with the
committee, because it just makes a type-unsafe language feature applicable in
many more type-unsafe ways.
> Certainly, a full discriminated union class should be a library
> class.
>
> In fact, the valunion class I submitted in bjp_utilities28102001.zip
> is such a class and was one of the original motivations for my
> wanting to add alignment_traits<>::align_t to boost.
>
> (BTW, The syntax for valunion is-
>
> boost::valunion<AddExpression, MulExpression, Variable> vu;
>
> vu = AddExpression();
> assert(vu.type == 1);
> AddExpression a = static_cast<AddExpression>(vu);
> (or AddExpression a = vu.get<1>(); // in latest version only)
>
> I called it valunion in analogy with valarray- I originally created
> it to give Matlab-like cell array functionality to such an array
> class.
> )
In a previous discussion regarding the addition of a discriminated union-like
type, John Skaller requested that a variant type be tagged. So with the
little snippet I gave, if we have tagged<Add, AddExpression>, AddExpression
is the type of a possible value named Add. It's analagous to a non-static
class member: Add is the name, AddExpression is the type. So vu.get<Add>()
would return a reference to an AddExpression. The point of tags is that some
extra information can be encoded into the tpe. For instance, both Add and Mul
tags could have the same underlying type std::pair<Expression, Expression>.
I would expect, of course, that for any implementation:
boost::variant<T1, T2, T3>
would be equivalent to:
boost::variant<tagged<T1, T1>, tagged<T2, T2>, tagged<T3, T3> >
so a tagged variant's functionality is a strict superset of an untagged
variant's functionality.
I've finally gotten the chance to take a look at valunion, and of course I've
got a few comments.
* Partial specialization is unfortunately missing for a lot of Boost users
and developers. Looking through the source, it seems that it isn't overly
complicated to remove the uses of partial specialization within valunion.
Essentially, null_t would be replaced with something like:
template<int N> struct useless {};
And valunion becomes:
template<typename A, typename B=useless<2>, typename C = useless<3>,
...>
class valunion { /* ... */ };
Indeed, it might even help to remove partial specialization because it
would eliminate a lot of code duplication (reduction in parse time).
Finally, having only a single definition of valunion would make it easier
to extend to the Boost Preprocessor library, when that becomes
available...
Granted, I do understand your argument that the compiler can often give
better error messages in switch statements when partial specialization is
used. But I've got a different syntax for switch statements that solves
the problem more generally...
* I'm not sure I like the use of the "type" field to determine the current
type. It's great for use in a switch statement, but it relies on the ordering
of the arguments, which seems to go against the notion of a structure that
isn't a tuple.
* The user-defined conversions to each type scare me somewhat because they
are easily abused. Have you found them to be abused often in practice?
* visit_valunion is great, though I personally would like to be able to get
a result back.
More later...
> Yes, so we should make this concrete and create a patch for the
> boost type traits library and email it to the type traits library
> maintainer (I believe this is John Maddock ). I will upload a first
> pass today under the name "alignment_traits_ext.zip". If you could
> look at it sometime (no hurry), and perhaps add your preferred
> align_t computation method in a conditionally compiled block, then we
> can compare the possibilities and create a final submission.
Sounds good.
Doug
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk