Boost logo

Boost :

From: Rani Sharoni (rani_sharoni_at_[hidden])
Date: 2003-02-18 12:14:50


Gennaro Prota wrote:
> 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:

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.

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).

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) } ;
};

I compiled the above code (using the appropriate is_fundamental and
is_reference) with Comeau 4.3.0.1, GCC3.2 and EDG.

You can probably use a similar approach to implement yet another is_class
(not void, reference and doesn't have an implicit standard conversion to
bool).

Cheers,

Rani


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