Boost logo

Boost :

Subject: Re: [boost] [config] Macro for null pointer
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2012-11-28 11:33:25


On Tue, Nov 27, 2012 at 11:05 PM, Andrey Semashev <andrey.semashev_at_[hidden]
> wrote:

> On Wed, Nov 28, 2012 at 3:35 AM, Jeffrey Lee Hellrung, Jr.
> <jeffrey.hellrung_at_[hidden]> wrote:
> >
> > First go at it:
> >
> > /*** BEGIN NULLPTR DEFINITION ***/
> >
> > #include <boost/config.hpp>
> >
> > #ifndef BOOST_NO_NULLPTR
>
> I believe, the actual macros for C++11 features start with
> BOOST_NO_CXX11_ (e.g. BOOST_NO_CXX11_NULLPTR). The ones without CXX11
> are deprecated.
>

Right, I just hadn't installed 1.52.0 yet; this macro transition seemed to
be only halfway done in 1.51.0.

> #include <cstddef>
> >
> > namespace boost
> > {
> >
> > typedef std::nullptr_t nullptr_t;
> >
> > } // namespace boost
> >
> > #else // #ifndef BOOST_NO_NULLPTR
> >
> > #include <ostream>
>
> <iosfwd>, please.
>

Ah, need to overload on basic_ostream for that to work, of course.

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

I guess this could be simplified slightly with just

typedef (nullptr_t::*_boost_explicit_operator_bool_result_type);

>
> > #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); }
>
> I think, this is better:
>
> template< typename CharT, typename TraitsT >
> inline std::basic_ostream< CharT, TraitsT >& operator<<
> (std::basic_ostream< CharT, TraitsT >& strm, boost::nullptr_t)
> {
> o << static_cast< void * >(0);
> return o;
> }
>
> It will also not require basic_ostream to be defined.
>

Right.

> > } // 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).
>
> Will it help if you also define templated comparison operators with
> pointers?
>

You mean

template< class T >
inline bool operator==(boost::nullptr_t, T * const p) { return 0 == p; }

? Yeah, no dice.

- Jeff


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