Boost logo

Boost :

From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2002-11-25 02:38:38


David A. Greene wrote:
> > "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.

It's there!

Doesn't work with Borland and GCC 2.95 (3.2 is OK), though, currently, as it
relies on 'has_begin' and 'has_tag' traits, and there is no known way to
implement these on those two compilers.

>
> > 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

A sequence adapter, like, for example, 'filer_view' -
http://www.mywikinet.com/mpl/ref/Reference/filter_view.html.

> and what advantage does it have over mpl::vector<T>?

Simplicity, lightweightness, and conceptual cleanness :).

> > 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.

Is the sequence always the same? E.g. do you always operate on 'first',
'second', and 'third', or sometimes it's 'second' and 'third' only, or even
the 'third' only?

If the former, then you only need to specialize 'begin/end' for the 'first'
type, and you are done:

    template< typename T >
    struct intrusive_iter
    {
        typedef T type;
        typedef intrusive_iter<typename T::type> next;
    };

    template<>
    struct intrusive_iter<void_>
    {
    };

    template<>
    struct begin<first>
    {
        typedef intrusive_iter<first> type;
    };

    template<>
    struct end<first>
    {
        typedef intrusive_iter<void_> type;
    };

If not, then wrapping it into 'intrusive_list' is probably the best we can
do:

    template< typename T >
    struct intrusive_list
    {
        typedef intrusive_iter<T> begin;
        typedef intrusive_iter<void_> end;
    };

    template< typename T >
    struct begin< intrusive_list<T> >
    {
        typedef intrusive_iter<first> type;
    };

    template< typename T >
    struct end< intrusive_list<T> >
    {
        typedef intrusive_iter<void_> type;
    };

    fold< intrusive_list<first>, ... >::type res1;
    fold< intrusive_list<second>, ... >::type res2;

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

You are welcome!

Aleksey


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