Boost logo

Boost :

From: Stjepan Rajko (stipe_at_[hidden])
Date: 2007-08-15 15:38:25


Hello,

I have found the following little snippet of code quite useful (it is
modeled closely after enable_if, but it enables if the given type has
been defined, kind of like enable_if + HAS_XXX but simpler and more
general). I am curious whether you think this functionality is useful
in general, whether the implementation is OK, and whether you think it
might be useful to add it to the Utility library (if the functionality
is not somewhere else in boost already):

    // if T is a valid type enable_if_defined result is Result,
otherwise specialization failure
    template<typename T, typename Result=void>
    struct enable_if_defined
    {
        typedef Result type;
    };

    struct void_;

    // if we need to test for multiple types, we can use all_of
    template<typename T0=void_, typename T1=void_, typename T2=void_,
        typename T3=void_, typename T4=void_, typename T5=void_>
    struct all_of
    {
    };

Some examples of how I've been using it:

/// Example 1: specialize a template if the type has a trait:

template<typename T, typename Enable=void>
struct producer_category_of
{
};

// if T has the producer_category trait, use it to specify producer_category_of
template<typename T>
struct producer_category_of<T,
typename detail::enable_if_defined<typename T::producer_category >::type >
{
    typedef typename T::producer_category type;
};

/// Example 2: specialize a type if the type has a couple of
metafunctions defined for it:

template<typename T, typename Enable=void>
struct is_producer
    : public boost::false_type {};

// If T has both producer_category_of and producer_type_of specified,
it is_producer
template<typename T>
struct is_producer<T,
        typename detail::enable_if_defined<detail::all_of<
            typename producer_category_of<T>::type,
            typename produced_type_of<T>::type
> >::type >
    : public boost::true_type {};

There is some overlap between the proposed enable_if_defined with the
existing enable_if in combination with mpl's HAS_XXX.

Advantages of enable_if_defined:

* unlike enable_if+HAS_XXX, there is no need to define a separate
metafunction for each trait to be tested
* enable_if_defined can be used to test any type expression that will
work with SFINAE

Disadvantages of enable_if_defined:

* there is no corresponding disable_if_defined
* can't be directly used with MPL - if you need a boolean metafunction
corresponding to an enable_if_defined, then you do need to define one.
* probably not compatible with as many compilers as enable_if+HAS_XXX

Any feedback welcome - if this is not a good approach please tell me
why so I can stop using it.

Thanks,

Stjepan


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