Boost logo

Boost :

From: David A. Greene (greened_at_[hidden])
Date: 2002-11-20 15:46:53

Aleksey Gurtovoy wrote:
>>there any way, short of specialization, to determine whether
>>the parameter is a sequence?
> "is_sequence<T>::value", please expect it to appear in the CVS in a day or
> two :).

Oh, fabulous! Just what I ws looking for.

> Given 'is_sequence', it will be as simple as this:
> template< typename T >
> struct as_sequence
> : if_< is_sequence<T>, T, single_view<T> >
> {
> };

Yep, that's what I had in mind. But what is single_view and
what advantage does it have over mpl::vector<T>?

> Actually, as the comments say, that is a default implementation. You can
> override it in two ways - (partially) specialize the primary 'begin/end'
> templates, or specialize 'begin_trait/end_trait' on a sequence tag to
> implement something like this:
> struct my_sequence_tag;
> struct first {
> typedef my_sequence_tag;
> typedef second type;
> };
> struct second {
> typedef my_sequence_tag;
> typedef third type;
> };
> struct third {
> typedef my_sequence_tag;
> typedef boost::mpl::void_ type;
> };

Ok, but what if I don't want to alter first, second and third?
That is, I have some set of classes that define types like this
but they were never originally intended to represent a sequence.
It just happens that I want to maipulate a set of these types
formed by the typedef members they define. See what I'm getting
at? Previously I used template recursion and specialization
to do this but I want to follow the MPL Way(tm). :)

> template<>
> struct begin_traits<my_sequence_tag>
> {
> template< typename Sequence > struct algorithm
> {
> typedef my_iterator<Sequence> type;
> };
> };
> template< typename Tag >
> struct end_traits
> {
> template< typename Sequence > struct algorithm
> {
> typedef my_iterator<void_> type;
> };
> };
> Would it cover your needs?

Mostly, except as I said I don't want to alter the classes if I
don't have to.

>>I thought about designing some kind of wrapper that could
>>be used in specialization:
>>template<typename Node>
>>struct intrusive_list {
>> typedef Node::type type;
>>Then I could partially specialize begin<>/end<> on
>>intrusive_list. Is this a reasonable approach?
> It is, at least from the technical standpoint - 'begin/end' /
> 'begin_trait/end_trait' templates were intended to be specialized; I would
> need some user-level examples of intended usage for the whole thing to be
> able to judge if there is a better way here.

Let me try out some ideas and I'll see what I find.

>>Here's one final puzzle: I have two type vectors that
>>I'd like to merge into one. The trick is that I want
>>to eliminate all duplicates. Since types cannot be
>>ordered (how does one define a less-than operation?)
> This one might be solvable (a challenge! :), but I don't have a solution
> right now.

Well, to accomplish the task below, I really just need to group
identical types together. Then I can just use mpl::unique
to remove the duplicates. So I don't need a full sort, but that's
the obvious solution if it's available.

>>it seems that type vectors cannot be easily sorted.
>>Thus to do a concat/copy while eliminating duplicates
>>would seem to be a very expensive task (search for
>>each candidate in the built-up list before adding it).
>>Any ideas here? I know I'm missing something important.
> Well, it's not an easy one :). For now, I would suggest you to go with the
> algorithm you've outlined above and see if the performance is a showstopper.
> I am sure we'll figure something out, it just needs some amount of thought
> that I am not able to dedicate to it at the moment. Thoughts are welcome!

The above algorithm is certainly fairly easy to write. I'm just
concerned about compile time. I'll do some investigating and
hard thinking about this puzzle.

Thanks for your help, Aleksey, it's very much appreciated.


"Some little people have music in them, but Fats, he was all music,
  and you know how big he was."  --  James P. Johnson

Boost list run by bdawes at, gregod at, cpdaniel at, john at