Boost logo

Boost :

From: Gennaro Prota (gennaro_prota_at_[hidden])
Date: 2003-02-19 06:24:31


On Tue, 18 Feb 2003 19:14:50 +0200, "Rani Sharoni"
<rani_sharoni_at_[hidden]> wrote:

>This is very nice technique. Just notice that you also need to handle void,
>functions and arrays types.
>
>Abstract classes, functions and array types will fail the completion on the
>burn conversion operator since they are not allowed as returns types.

Yeah. The code was just to give the idea, which I could have expressed
in English if it wasn't that my English is even worse than my C++ :-)

>IMHO the main achievement of your technique is that, unlike techniques that
>use conversion constructor to burn user defined conversion, its works for
>incomplete classes (EDG and GCC complain when trying to pass lvalue of
>incomplete class to function that take ellipsis as an argument).

Yes. Attempting lvalue-to-rvalue conversion of an expression of
incomplete type makes the program ill-formed.

>Here is a possible is_enum implementation using your technique:
>
>
>template<typename T> struct convertible { operator T&() const; };
>
>template<typename T>
>struct is_enum2
>{
> static yes test(int);
> static no test(...);
>
> struct not_enum {};
>
> typedef typename select_type< is_fundamental<T>::value ||
>is_reference<T>::value, not_enum, convertible<T> >::type T2;
>
> static T2& make();
>};
>
>
>
>template<typename T>
>struct is_enum
>{
> enum { value = sizeof(is_enum2<T>::test(is_enum2<T>::make())) ==
>sizeof(yes) } ;
>};

Nice :-) BTW, you can avoid the select_type machinery:

  template <typename T>
  struct Burn {
    operator T&() const;
  };

  // fire-prevention
  template <typename T>
  Burn<T> ref(T*);
  template <typename T>
  char* ref(...);

  // outside the is_enum<> template
  // to help gcc
  //
  yes is_enum_checker (unsigned long);
  no is_enum_checker (...);

  template <typename T>
  struct is_enum {

   static const bool value =
         !is_integral<T>::value
      && !is_floating<T>::value
      && sizeof(yes) == sizeof( is_enum_checker (ref<T>(0)) );
  };

But this simple stuff is already enough to knock out a lot of
compilers :-/

BTW, I've seen how complex boost::is_reference is. Why so? What
compiler(s) cause(s) most problems?

Genny.


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