Boost logo

Boost :

From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2002-10-16 04:32:17


Presented below:

    #include "boost/static_assert.hpp"
    #include "boost/config.hpp"

    typedef char (&yes_tag)[1];
    typedef char (&no_tag)[2];

    template< typename T > yes_tag is_class_helper(void (T::*)(void));
    template< typename T > no_tag is_class_helper(...);

    template < typename T > struct is_union_inherit : T {};
    template< typename T > yes_tag is_union_class_helper(T*);
    template< typename T > no_tag is_union_class_helper(...);

    template< typename T >
    struct is_union
    {
        BOOST_STATIC_CONSTANT(bool
            , value =
                    sizeof(is_union_class_helper<T>(
                          static_cast< is_union_inherit<T>* >(0)
                        )) == sizeof(no_tag)
                &&
                    sizeof(is_class_helper<T>(0)) == sizeof(yes_tag)
            );
    };

    union U {};
    class C {};
    struct S {};

    BOOST_STATIC_ASSERT(is_union<U>::value);
    BOOST_STATIC_ASSERT(!is_union<C>::value);
    BOOST_STATIC_ASSERT(!is_union<S>::value);
    BOOST_STATIC_ASSERT(!is_union<int>::value);

Works with Intel C++ 6.0. The only catch is that it doesn't work with
incomplete types.

On a related note, it seems to me that the current semantics of
'boost::is_class' trait:

<docs quote>
    "Evaluates to true only if T is of class/struct type."
</>

does not match the standard - section 9 clearly states that union is a class
too.

Aleksey


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