Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2004-12-02 10:04:26


David Abrahams wrote:
> David Abrahams wrote:
>
>> Still no dice for vc7.1, though.
>
>
> Hum, that was too easy:

Well, there are still some unhandled corner cases. Maybe someone more
clever than I can figure out how to manage them. I'm thinking these may
require the Rani Sharoni trick from is_base_and_derived, but since I
don't really understand it, I'll admit I'm just speculating. I doubt
there's a cure for the one vc7.1 failure, but I could of course be wrong.

The other failures I'm labelling as "corner cases" because they only
fail on oddball cases like "(volatile x)x()" or rvalue expressions with
private copy ctors, or ones that can't be evaluated anyway. If there's
no copy ctor that takes an "x volatile" argument, you can't return one
from a function.

#include <boost/static_assert.hpp>

typedef char yes;
typedef char (&no)[2];

template <class T>
yes is_nonconst_rvalue(T const&, ...);

template <class T>
no is_nonconst_rvalue(T&, int);

struct foo
{
#ifndef BOOST_MSVC
     template<typename U>
     operator U() const;

     template<typename V>
     operator V& () volatile const;
#else
     template<typename U>
     operator U();

     template<typename V>
     operator V& () const volatile;
#endif

     static foo const instance;
     static bool select;
};

#define IS_RVALUE(x)
                 \
     (sizeof(is_nonconst_rvalue((foo::select ? foo::instance : (x)), 0))
== sizeof(yes))

int rvalue();
int const_rvalue();
int& lvalue();
int const& const_lvalue();

int volatile volatile_rvalue();
int const volatile const_volatile_rvalue();
int volatile& volatile_lvalue();
int const volatile& const_volatile_lvalue();

BOOST_STATIC_ASSERT(IS_RVALUE(rvalue()));
BOOST_STATIC_ASSERT(IS_RVALUE(const_rvalue()));
BOOST_STATIC_ASSERT(!IS_RVALUE(lvalue()));
BOOST_STATIC_ASSERT(!IS_RVALUE(const_lvalue()));

BOOST_STATIC_ASSERT(IS_RVALUE(volatile_rvalue()));
BOOST_STATIC_ASSERT(IS_RVALUE(const_volatile_rvalue()));
BOOST_STATIC_ASSERT(!IS_RVALUE(volatile_lvalue()));
BOOST_STATIC_ASSERT(!IS_RVALUE(const_volatile_lvalue()));

struct x { ~x(); };

x rvaluex();
x const_rvaluex();
x& lvaluex();
x const& const_lvaluex();

x volatile volatile_rvaluex();
x const volatile const_volatile_rvaluex();
x volatile& volatile_lvaluex();
x const volatile& const_volatile_lvaluex();

BOOST_STATIC_ASSERT(IS_RVALUE(rvaluex()));
BOOST_STATIC_ASSERT(IS_RVALUE(const_rvaluex()));
BOOST_STATIC_ASSERT(!IS_RVALUE(lvaluex()));
BOOST_STATIC_ASSERT(!IS_RVALUE(const_lvaluex()));

// foo.cpp:76: error: No match for 'x(volatile x)'
// foo.cpp:59: error: candidates are: x::x()
// foo.cpp:59: error: x::x(const x &)
BOOST_STATIC_ASSERT(IS_RVALUE(volatile_rvaluex()));

// foo.cpp:77: error: No match for 'x(const volatile x)'
// foo.cpp:59: error: candidates are: x::x()
// foo.cpp:59: error: x::x(const x &)
BOOST_STATIC_ASSERT(IS_RVALUE(const_volatile_rvaluex()));

BOOST_STATIC_ASSERT(IS_RVALUE((volatile x)x()));

BOOST_STATIC_ASSERT(!IS_RVALUE(volatile_lvaluex()));
BOOST_STATIC_ASSERT(!IS_RVALUE(const_volatile_lvaluex()));

-- 
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

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