Boost logo

Boost Users :

From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2005-02-01 22:08:34


Martin Pasdzierny writes:
> Stepping forward in dealing with a mpl::vector_c of enums I found it
> hard to determine the correct expression to 'mpl::find' an element
> within such a vector. The code below compiles with gcc 3.3.3 and
> shows 5 different approaches, but only version 4,5 really find the
> correct iterator. Version 1,2,3 return iterators pointing to the
> vectors end. It would be helpful if someone more familiar with
> MPL's concepts could give some explanation, particularly about the
> aspects:
>
> - Is there a solution using mpl::find instead of mpl::find_if

Yes (assuming that the sequence you are searching in satisfies
Integral Sequence Wrapper requirements):

    typedef vector_c<int,X,Y> v;
    typedef find< v, integral_c<int,c> >::type iter;
                                ^^^

> If not, why the difference between finding elements in
> mpl::vector and mpl::vector_c ?

'find' uses *type equality* ('boost::is_same') to determine whether
the elements are the same, and from standpoint of the C++ compiler,
all these

    integral_c<MY_ENUM,c>
    integral_c<int,c>
    int_<c>

have different types, so you have to be precise in specifying what
exactly you are looking for. The 'find' snippet above is guaranteed to
work because all Integral Sequence Wrappers classes are required to
be wrappers around
seqn<integral_c<T,c1>,integral_c<T,c2>, ... integral_c<T,cn> >
(see http://www.boost.org/libs/mpl/doc/refmanual/integral-sequence-wrapper.html).

Note that unless you have control over how your sequences of integral
constants are constructed, the approach is fragile:

    typedef vector_c<int,X,Y> v1;
    typedef find< v1, integral_c<int,X> >::type iter1; // OK

    typedef push_back< my_vector_c, int_<Z> >::type v2;
    // ^^^^^^^
    typedef find< v1, integral_c<int,Z> >::type iter2; // Nothing found!

The current recommendation for generic code working with integral
constants is to always use explicit 'equal_to' comparison. If you find
this too verbose, you might consider writing a helper metafunction
that would wrap this up for you, e.g.:

    template< typename Seq, typename Seq::value_type N >
    struct find_c
        : find_if< Seq, equal_to<_1, integral_c<typename Seq::value_type,N> >
    {
    };

    typedef find_c< v1, Z >::type iter2; // Works

> - What is the difference between using integral wrappers:
> boost::mpl::integral_c<MY_ENUM,c> >
> boost::mpl::int_<c>

See the above.

> - And still the question from the previous posting:
> Can I (should I) tell mpl::vector_c I'm using my own enum type
> and not plain int ?

Not at the moment, see my earlier reply.

HTH,

-- 
Aleksey Gurtovoy
MetaCommunications Engineering

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net