Boost logo

Boost :

From: Gennaro Prota (gennaro_prota_at_[hidden])
Date: 2004-05-22 03:25:03


On Sun, 16 May 2004 10:40:52 -0400, David Abrahams
<dave_at_[hidden]> wrote:

>So, should I just remove it?

Well, not because it isn't implementable. Admittedly, it isn't the
most useful thing in the world either, so I don't have a strong
opinion about its inclusion ;)

>Looking back at that thread, I'm
>surprised I included it in this header because I don't think I ever
>really understood what you were saying.
>
>I don't think there's an alternative to using the comma operator that
>will work both when dst_type is a dependent type in a template and
>when it is not dependent, because of differences in the need for
>"typename".

Good point. Then we could attack the expression part of static_cast.
What about using the conditional operator? I don't know how that
interacts with broken compilers, though. If you like it, I could
provide the tests.

//------------------------------------------------------------

#include <cstddef>

namespace boost {

template< typename T>
struct identity
{
    typedef T type;
};

// The use of identity creates a non-deduced form, so that the
// explicit template argument must be supplied
template <typename T>
inline T implicit_cast (typename identity<T>::type x) {
    return x;
}

} // namespace boost

// Macro for when you need a constant expression.
// Note that 'expr' appears three times but is
// evaluated (at most) once.
#define BOOST_IMPLICIT_CAST(dest_type, expr) \
  (static_cast<dest_type>( \
                 sizeof(boost::implicit_cast<dest_type>(expr)) ? \
                 (expr) : (expr) \
                ) \
  )

//------------------------------------------------------------
// Examples:

template <typename T>
struct X
{
    typedef T type;
};

// integral constant expressions
template <typename T>
void f(T arg) {

 // dest_type is dependent
 int x [ BOOST_IMPLICIT_CAST(typename X<T>::type, 'A') ];
 
 // dest_type is non-dependent
 int y [ BOOST_IMPLICIT_CAST(int, 'B') ];

}

// constant-expressions for the purpose of non-local static object
initialization

// (a) null pointer value (of type char*)
static void * pc = BOOST_IMPLICIT_CAST(void*, (char*)(0) );

// (b) null member pointer value
struct X2 { void f(int) {} };
static void (X2::*pm)(int) = BOOST_IMPLICIT_CAST( void (X2::*)(int),
0);

// (c) arithmetic constant expression
static int n = BOOST_IMPLICIT_CAST(int, 1.0);

// (d) address constant expression
static const void * pso = BOOST_IMPLICIT_CAST(const void*, (const
char*) (1 +
&"hello"));

// (e) reference constant expression
static char c = 'x';
static int n2 = BOOST_IMPLICIT_CAST(int, c);

// these should fail
#ifdef TEST_FAILURES

struct B {};
struct D : B {};
D d;
B & ref = d;

enum my_enum { value1, value2 };

void g()
{
  BOOST_IMPLICIT_CAST(void, 1);
  BOOST_IMPLICIT_CAST(D&, ref);
  BOOST_IMPLICIT_CAST(my_enum, 1);
  
}

#endif

int main()
{
    f(1);
    f(8UL);
}

Genny.


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