$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Gennaro Prota (gennaro_prota_at_[hidden])
Date: 2003-02-17 15:03:21
On Mon, 17 Feb 2003 10:02:58 +0100, Daniel Frey
<daniel.frey_at_[hidden]> wrote:
>I started to implement my own type-traits to see if I can do it and to
>learn something. While doing so, my design lead me to some dependencies:
>is_enum needed is_class
Daniel, my apologies in advance if this is just a stupid comment. I'm
again jumping in without actually following the thread (not enough
time), however if I had to implement is_enum the first property that I
would try exploiting is the built-in convertibility (of an rvalue) to
integral types. If you immediately burn the one user-defined
conversion allowed in any implicit conversion sequence there's no need
to exclude classes, I think. The basic idea is:
 template <typename T>
 struct is_integral {
  static const bool value = false;
 };
 #define THIS_IS_INTEGRAL(t)            \
  template <> struct is_integral<t> {   \
    static const bool value = true;     \
  }                                     \
                                   /**/
 template <typename T>
 struct is_floating {
  static const bool value = false;
 };
 #define THIS_IS_FLOATING(t)            \
   template<> struct is_floating<t> {   \
      static const bool value = true;   \
  }
              ...
    /* add cv-qualified specs here */
              ...
                                 /**/
 THIS_IS_INTEGRAL(bool);
 THIS_IS_INTEGRAL(char);
 THIS_IS_INTEGRAL(wchar_t);
 THIS_IS_INTEGRAL(signed char);
 THIS_IS_INTEGRAL(short);
 THIS_IS_INTEGRAL(int);
 THIS_IS_INTEGRAL(long);
 THIS_IS_INTEGRAL(unsigned char);
 THIS_IS_INTEGRAL(unsigned short);
 THIS_IS_INTEGRAL(unsigned int);
 THIS_IS_INTEGRAL(unsigned long);
 THIS_IS_FLOATING(float);
 THIS_IS_FLOATING(double);
 THIS_IS_FLOATING(long double);
 template <typename T>
 struct is_enum {
  struct Burn {
   operator T() const;
 };
 typedef char yes;
 typedef char(&no)[2];
 static yes is_it(unsigned long);
 static no  is_it(...);
 
 template <typename U>
 static no check_rvalue(U&);
 static yes  check_rvalue(...);
 static T get_T();
 static const bool value =
    !is_integral<T>::value
          &&
    !is_floating<T>::value
          &&
    sizeof(yes) == sizeof( is_it( Burn() ) )
          &&
    sizeof(yes)  == sizeof( check_rvalue( get_T() ) )
  ;
 };
The above is absolutely untested and off the top of my head so take it
with great great prudence :-) It was just to say that, if I'm not
mistaken, is_enum doesn't need is_class. Maybe.
Genny.