Boost logo

Boost :

From: brianjparker_at_[hidden]
Date: 2001-11-04 12:57:23


--- In boost_at_y..., Douglas Gregor <gregod_at_c...> wrote:
> On Saturday 03 November 2001 05:46, you wrote:
>
> 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.

Tags sound like an interesting addition. My original focus in writing
valunion was to allow heterogeneous containers (in particular, the
equivalent to cell arrays in a Matlab-compatible array class I wrote)
and generic functions over them (like visit_valunion()). For such a
generic function, tags wouldn't be of much use (unless they were some
predefined well-known names, like first, second etc :-) ).
 
> 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...

Actually, the original version of valunion didn't use partial
specialisation and was implemented exactly as you describe. I
partially specialised the various cases to improve error messages not
only for switch statements but also for access to undefined members.
But I agree that the resulting code explosion may have become a
little counterproductive. Certainly the partial specialisations could
be removed- they probably don't improve error reporting much anyway.
 
> * 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.

I take your point, but to some extent the template implementation
already forces an ordering on the types i.e. valunion<int, double> is
a different type to valunion<double, int>.
Another possibility would be to use a pointer to a typeinfo structure
for the type field, but I would prefer to keep it simple- I want the
class to be as lightweight and efficient as a built-in union.
   
> * 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?

Yes, they worry me too, they are convenient but I think I will get
rid of them. In the latest version I just uploaded I have added a
safe valunion_cast<>.

I haven't found the conversions to be a problem in practice as the
types I have used have been quite distinct and not interconvertible.
But I must say that valunion is probably the least used class in my
library and I don't have a great deal of real-world experience with
it (but then I tend not to use cell arrays in Matlab either).

> * visit_valunion is great, though I personally would like to be
able to get
> a result back.

Good point. I have just uploaded a new version of valunion in which I
have added a for_each_valunion() function which acts like
std::for_each() but on a container of valunions, and it returns the
passed-in function object so that results can be accumulated and
returned. There is an example in valunion_test.cpp.
 
> 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.

I have uploaded the first pass at the changed files for the boost
type traits library; I called the file "align_of_to_boost.zip".
There was a single header and the html file that needed changing- I
hope my changes are clear.

I will await your comments and/or changes.
,Brian Parker


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