tags:

views:

93

answers:

2

How to check (without Boost or other nonstandard lib) if type passed to template is an enum type?
Thanks.

+2  A: 

http://www.boost.org/doc/libs/1_44_0/libs/type_traits/doc/html/boost_typetraits/reference/is_enum.html

I appreciate you want total portability and not to use boost. If you find that impractical, you might still prefer to use a simple ifdef and the following: MSDN has a similar facility on the front page of google results for c++ is_enum. On recent GNU compilers, try your luck with using std::tr1::is_enum;

Even if you don't want to use boost, you could examine it for the technique used in determination. Looks complex enough to be exclusion of all other possibilities :-/.

Tony
@Tony I've updated my question
There is nothing we can do
Actually, is_enum should be used with care. Some compilers don't support it correctly. See the latest version of boost: http://www.boost.org/doc/libs/1_44_0/libs/type_traits/doc/html/boost_typetraits/reference/is_enum.html
Cătălin Pitiș
@Cătălin: "broken under Borland C++ Builder 5, and for the Metrowerks compiler prior to version 8" isn't likely to bother too many people (poor old Borland).
Tony
@A-ha: to do it without Boost, open the Boost source and copy-paste. They have a habit of thinking hard and reviewing thoroughly, you probably won't find a better implementation.
Potatoswatter
@Tony: You're right. However, I still see Visual Studio 6 required in some projects, so why not MW 8 or BC 5? About the same generation :)
Cătălin Pitiș
@Potatoswatter it's not about finding better implementation. I want to learn how it is done. That's all.
There is nothing we can do
+1  A: 

Looking at http://www.boost.org/doc/libs/1_44_0/boost/type_traits/is_enum.hpp,

If this evaluates to true:

::boost::type_traits::ice_or<
           ::boost::is_arithmetic<T>::value
         , ::boost::is_reference<T>::value
         , ::boost::is_function<T>::value
         , is_class_or_union<T>::value
         , is_array<T>::value
      >::value

Then this base template is selected:

// Don't evaluate convertibility to int_convertible unless the type
// is non-arithmetic. This suppresses warnings with GCC.
template <bool is_typename_arithmetic_or_reference = true>
struct is_enum_helper
{
    template <typename T> struct type
    {
        BOOST_STATIC_CONSTANT(bool, value = false);
    };
};

Otherwise check if it's convertible to int:

template <>
struct is_enum_helper<false>
{
    template <typename T> struct type
       : ::boost::is_convertible<typename boost::add_reference<T>::type,::boost::detail::int_convertible>
    {
    };
};

If you want to do it as well as Boost, you'll have to define all those other traits. <type_traits> is like that.

Potatoswatter