|
Boost : |
Subject: Re: [boost] [config] Macro for null pointer
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2012-11-27 18:35:44
On Sun, Nov 18, 2012 at 2:03 PM, Jeffrey Lee Hellrung, Jr. <
jeffrey.hellrung_at_[hidden]> wrote:
> On Sun, Nov 18, 2012 at 7:22 AM, Edward Diener <eldiener_at_[hidden]>wrote:
>
>> On 11/16/2012 12:32 AM, Jeffrey Lee Hellrung, Jr. wrote:
>>
>>> On Thu, Nov 15, 2012 at 7:04 PM, Edward Diener <eldiener_at_[hidden]>
>>> **wrote:
>>>
>>> I have found something like this to be helpful, when working with
>>>> multiple
>>>> compilers:
>>>>
>>>> #include <boost/config.hpp>
>>>> #if defined(BOOST_NO_NULLPTR)
>>>> #define BOOST_XXX_NULLPTR 0
>>>> #else
>>>> #define BOOST_XXX_NULLPTR nullptr
>>>> #endif
>>>>
>>>> where XXX is some local name for my own use. And then use
>>>> BOOST_XXX_NULLPTR in places where a null pointer is needed.
>>>>
>>>> Would this be a candidate for a BOOST_NULLPTR macro in the config
>>>> library
>>>> instead ?
>>>>
>>>>
>>> Might it be better to just offer a (albeit imperfect) nullptr emulation
>>> if
>>> not supplied by the compiler? For example, [1].
>>>
>>> - Jeff
>>>
>>> [1] http://en.wikibooks.org/wiki/**More_C%2B%2B_Idioms/nullptr
>>>
>>
>> I agree that you are right.
>>
>> If the nullptr emulation has less problems than using 0 it would seem
>> worthwhile. That appears to be easily the case. Both are of course
>> imperfect but it appears that a nullptr emulation is far less imperfect.
>> The question then is who is going to do it and support it, given that it
>> will most probably be obsolete in the near future as more compilers
>> implement features of C++11. Unless someone steps up to do it ( and I am
>> not that person due to, for one, already being behind in getting TTI into
>> Boost ) it will not be done and then using 0 is at least a second best
>> solution.
>>
>> In my own current use of nullptr in cross-compiler code for Boost using 0
>> is adequate for my means in the few instances where I am using nullptr. So
>> my suggestion in my OP is adequate for me right now but may well not be
>> adequate for others or for future usage on compilers which do not support
>> nullptr.
>>
>
> I'll post something this week and if it's ultimately decided to be
> included in, e.g., boost/utility, I don't have a problem supporting it.
>
First go at it:
/*** BEGIN NULLPTR DEFINITION ***/
#include <boost/config.hpp>
#ifndef BOOST_NO_NULLPTR
#include <cstddef>
namespace boost
{
typedef std::nullptr_t nullptr_t;
} // namespace boost
#else // #ifndef BOOST_NO_NULLPTR
#include <ostream>
namespace boost
{
struct nullptr_t
{
template< class T >
operator T * () const
{ return static_cast< T * >(0); }
template< class T, class C >
operator T C:: * () const
{ return static_cast< T C:: * >(0); }
#ifndef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
explicit operator bool () { return false; }
#else // #ifndef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
private:
struct _boost_explicit_operator_bool_struct { };
typedef int
(_boost_explicit_operator_bool_struct::*_boost_explicit_operator_bool_result_type);
public:
operator _boost_explicit_operator_bool_result_type () const { return 0; }
#endif // #ifndef BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
// Must be public in order for nullptr_t to be POD.
void * _boost_nullptr_sizeof;
#ifndef BOOST_NO_DELETED_FUNCTIONS
void operator & () const = delete;
#else // #ifndef BOOST_NO_DELETED_FUNCTIONS
private: void operator & () const;
#endif // #ifndef BOOST_NO_DELETED_FUNCTIONS
};
boost::nullptr_t const nullptr = { 0 };
inline bool operator==(boost::nullptr_t, boost::nullptr_t) { return true; }
inline bool operator!=(boost::nullptr_t, boost::nullptr_t) { return false; }
inline std::ostream &
operator<<(std::ostream & o, boost::nullptr_t)
{ return o << static_cast< void * >(0); }
} // namespace boost
using boost::nullptr;
#endif // #ifndef BOOST_NO_NULLPTR
/*** END NULLPTR DEFINITION ***/
#include <cassert>
#include <boost/implicit_cast.hpp>
#include <boost/static_assert.hpp>
struct X { };
int main(int argc, char * argv[])
{
BOOST_STATIC_ASSERT( sizeof( nullptr ) == sizeof( void * ) );
assert(!static_cast< bool >(nullptr));
assert(!nullptr);
assert(boost::implicit_cast< void * >(nullptr) == 0);
assert(boost::implicit_cast< int * >(nullptr) == 0);
assert(boost::implicit_cast< int X::* >(nullptr) == 0);
//assert(nullptr == static_cast< void * >(0));
//assert(nullptr != &argc);
return 0;
}
Unfortunately, the assertions that are commented out in main trigger an ICE
on MSVC9 (yeah, big surprise); it's possible I did something wrong, but in
the event that I didn't, if we can find a workaround to get such
expressions to work, that'd be great (I tried explicitly defining
operator== and operator!= out-of-line, and that didn't help).
Also, I only tested this on MSVC9 (for now).
Comments?
- Jeff
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk