Boost logo

Boost :

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.


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