Boost logo

Boost :

Subject: Re: [boost] [config] Macro for null pointer
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2012-11-28 02:05:52


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.

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

<iosfwd>, please.

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

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.

> } // 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?


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