diff --git a/common/nullptr.hh b/common/nullptr.hh new file mode 100644 index 0000000000000000000000000000000000000000..de6ddbd167fc4b29bdba34526af70dcc2b71003b --- /dev/null +++ b/common/nullptr.hh @@ -0,0 +1,29 @@ +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +#ifndef DUNE_NULLPTR_HH +#define DUNE_NULLPTR_HH + +#if ! HAVE_NULLPTR + +/** + \brief Fallback implementation of nullptr + + see C++ proposal + http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf + */ +const // this is a const object... +class nullptr_t { // of type nullptr_t +public: + template<class T> // convertible to any type + operator T*() const // of null non-member + { return 0; } // pointer... + template<class C, class T> // or any type of null + operator T C::*() const // member pointer... + { return 0; } +private: + void operator&() const; // whose address can't be taken +} nullptr = {}; // and whose name is nullptr + +#endif // HAVE_NULLPTR + +#endif // DUNE_NULLPTR_HH diff --git a/common/test/Makefile.am b/common/test/Makefile.am index 76c1ff1f379871646623082351a2f52dd6f38650..897c7a2c092a119fff94ba96d44e328636167e75 100644 --- a/common/test/Makefile.am +++ b/common/test/Makefile.am @@ -5,7 +5,7 @@ TESTPROGS = parsetest test-stack arraylisttest smartpointertest \ poolallocatortest settest gcdlcmtest streamtest \ bigunsignedinttest mpihelpertest singletontest mpicollcomm \ utilitytest lrutest \ - smallobject \ + smallobject nullptr-test \ testfassign1 testfassign2 testfassign3 \ testfassign4 \ testfassign_fail1 testfassign_fail2 testfassign_fail3 \ @@ -14,7 +14,7 @@ TESTPROGS = parsetest test-stack arraylisttest smartpointertest \ # which tests to run COMPILE_XFAIL=$(DUNE_COMMON_ROOT)/bin/xfail-compile-tests -COMPILE_XFAIL_TESTS = static_assert_test +COMPILE_XFAIL_TESTS = nullptr-test-fail static_assert_test compile_XFAIL: for i in $(COMPILE_XFAIL_TESTS); do \ @@ -40,6 +40,10 @@ AM_LDFLAGS = $(LOCAL_LIBS) # define the programs smallobject_SOURCES = smallobject.cc +nullptr_test_SOURCES = nullptr-test.cc nullptr-test2.cc +nullptr_test_fail_SOURCES = nullptr-test.cc +nullptr_test_fail_CPPFLAGS = -DFAIL + static_assert_test_SOURCES = static_assert_test.cc bigunsignedinttest_SOURCES=bigunsignedinttest.cc diff --git a/common/test/nullptr-test.cc b/common/test/nullptr-test.cc new file mode 100644 index 0000000000000000000000000000000000000000..92f4bf99bbe7f9a2d9d0a327d4c9396e29fe9409 --- /dev/null +++ b/common/test/nullptr-test.cc @@ -0,0 +1,35 @@ +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +#include <config.h> + +#include <dune/common/nullptr.hh> + +void basic_tests() +{ + typedef nullptr_t NULLPTR_T; + char* ch = nullptr; // ch has the null pointer value + char* ch2 = 0; // ch2 has the null pointer value +#ifdef FAIL + int n = nullptr; // error +#endif + int n2 = 0; // n2 is zero + if( ch == 0 ) ; // evaluates to true + if( ch == nullptr ) ; // evaluates to true + if( ch ) ; // evaluates to false + if( n2 == 0 ) ; // evaluates to true + ch = ch2; +#ifdef FAIL + if( n2 == nullptr ) ; // error + if( nullptr ) ; // error, no conversion to bool + if( nullptr == 0 ) ; // error + // arithmetic + nullptr = 0; // error, nullptr is not an lvalue + nullptr + 2; // error +#endif +} + +int main() +{ + basic_tests(); + return 0; +} diff --git a/common/test/nullptr-test2.cc b/common/test/nullptr-test2.cc new file mode 100644 index 0000000000000000000000000000000000000000..2c7b4cb1a68494e8109d1472b744366d8ad7f730 --- /dev/null +++ b/common/test/nullptr-test2.cc @@ -0,0 +1,5 @@ +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +#include <config.h> + +#include <dune/common/nullptr.hh> diff --git a/m4/dune_common.m4 b/m4/dune_common.m4 index d56f74cde550b4c411ba971069984d5c7a5d842c..75405c2e6ce85677cc45085dbf9853fee384ab28 100644 --- a/m4/dune_common.m4 +++ b/m4/dune_common.m4 @@ -11,6 +11,7 @@ AC_DEFUN([DUNE_COMMON_CHECKS], AC_REQUIRE([DUNE_CHECK_COMPILER]) AC_REQUIRE([GXX0X]) AC_REQUIRE([STATIC_ASSERT_CHECK]) + AC_REQUIRE([NULLPTR_CHECK]) AC_REQUIRE([DUNE_LINKCXX]) AC_REQUIRE([DUNE_CHECKDEPRECATED]) AC_REQUIRE([DUNE_SET_MINIMAL_DEBUG_LEVEL]) diff --git a/m4/static_assert.m4 b/m4/static_assert.m4 index 213f34b7e0c4ecbb674fdb7c7e89025fd10110a8..a9ccfa6ef6ae3b1cbfbc729c14369a449d721095 100644 --- a/m4/static_assert.m4 +++ b/m4/static_assert.m4 @@ -33,3 +33,21 @@ AC_DEFUN([STATIC_ASSERT_CHECK],[ fi AC_LANG_POP ]) + +AC_DEFUN([NULLPTR_CHECK],[ + AC_REQUIRE([AC_PROG_CXX]) + AC_REQUIRE([GXX0X]) + AC_LANG_PUSH([C++]) + AC_MSG_CHECKING([whether nullptr is supported]) + AC_TRY_COMPILE([],[typedef nullptr_t peng; + char* ch = nullptr; + ], [ + HAVE_NULLPTR=yes + AC_MSG_RESULT(yes)], [ + HAVE_NULLPTR=no + AC_MSG_RESULT(no)]) + if test "x$HAVE_NULLPTR" = xyes; then + AC_DEFINE(HAVE_NULLPTR, 1, [Define to 1 if nullptr is supported]) + fi + AC_LANG_POP +])