From 22dc6b27c55b58f124315c23a99ce4730d242255 Mon Sep 17 00:00:00 2001 From: Tigran Khachatryan <39616689+tigran2008@users.noreply.github.com> Date: Fri, 19 Jul 2024 20:20:44 +0400 Subject: [PATCH] Add an etl::nullptr_t type to (#924) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add an etl::nullptr_t type * etlcpp/etl issue #921 (etl::unique_ptr reset): add etl::unique_ptr(...)::reset(ETL_NULLPTR) Remove default argument for the normal reset method of etl::unique_ptr (sorry, didn't notice 😬) Silence the unused argument warning Fix operator =(nullptr) Replace the nullptr_t enum with a class which acts more similar to C++11 nullptr * Add member pointer support and delete the addressof operator * "Delete" etl::addressof(ETL_NULLPTR) * Ensure compatibility with C++98 * ACTUALLY ensure compatibility with C++98 I'm stupid :/ * Correct definition according to cppreference --- include/etl/memory.h | 40 +++++++++------------------------ include/etl/nullptr.h | 24 ++++++++++++++++++-- include/etl/private/addressof.h | 3 ++- 3 files changed, 35 insertions(+), 32 deletions(-) diff --git a/include/etl/memory.h b/include/etl/memory.h index 1abcf6380..692b102ec 100644 --- a/include/etl/memory.h +++ b/include/etl/memory.h @@ -1395,8 +1395,8 @@ namespace etl //********************************* void reset(pointer p_ = pointer()) ETL_NOEXCEPT { - assert(p_ != p); - + assert(p_ == ETL_NULLPTR || p_ != p); + pointer value = p; p = p_; @@ -1420,29 +1420,16 @@ namespace etl return (p != ETL_NULLPTR); } -#if ETL_USING_STL && ETL_USING_CPP11 //********************************* - unique_ptr& operator =(std::nullptr_t) ETL_NOEXCEPT + unique_ptr& operator =(etl::nullptr_t) ETL_NOEXCEPT { if (p) { - reset(nullptr); + reset(ETL_NULLPTR); } return *this; } -#else - //********************************* - unique_ptr& operator =(void*) ETL_NOEXCEPT - { - if (p) - { - reset(NULL); - } - - return *this; - } -#endif #if ETL_USING_CPP11 //********************************* @@ -1622,6 +1609,11 @@ namespace etl } } + void reset(etl::nullptr_t = ETL_NULLPTR) ETL_NOEXCEPT + { + reset(pointer()); + } + //********************************* void swap(unique_ptr& v) ETL_NOEXCEPT { @@ -1636,23 +1628,13 @@ namespace etl return (p != ETL_NULLPTR); } -#if ETL_USING_STL && ETL_USING_CPP11 - //********************************* - unique_ptr& operator =(std::nullptr_t) ETL_NOEXCEPT - { - reset(nullptr); - - return *this; - } -#else //********************************* - unique_ptr& operator =(void*) ETL_NOEXCEPT + unique_ptr& operator =(etl::nullptr_t) ETL_NOEXCEPT { - reset(NULL); + reset(ETL_NULLPTR); return *this; } -#endif #if ETL_USING_CPP11 //********************************* diff --git a/include/etl/nullptr.h b/include/etl/nullptr.h index 8d2e99512..df52ea80f 100644 --- a/include/etl/nullptr.h +++ b/include/etl/nullptr.h @@ -35,13 +35,33 @@ SOFTWARE. #include +namespace etl +{ #if ETL_CPP11_NOT_SUPPORTED - // Use the old style C++ NULL definition. - #define ETL_NULLPTR 0 + class nullptr_t + { + public: + template + inline operator T*() const { return 0; } + + template + inline operator T C::* () const { return 0; } + + inline bool operator==(nullptr_t) const { return true; } + inline bool operator!=(nullptr_t) const { return false; } + private: + void operator&() const ETL_DELETE; // cannot take the address of ETL_NULLPTR + }; + + static const nullptr_t _nullptr = nullptr_t(); + + #define ETL_NULLPTR (etl::_nullptr) #else // Use the new style nullptr. + typedef decltype(nullptr) nullptr_t; #define ETL_NULLPTR nullptr #endif +} #endif diff --git a/include/etl/private/addressof.h b/include/etl/private/addressof.h index 67fc8d2f6..fc864e0cd 100644 --- a/include/etl/private/addressof.h +++ b/include/etl/private/addressof.h @@ -32,6 +32,7 @@ SOFTWARE. #define ETL_ADDRESSOF_INCLUDED #include "../platform.h" +#include "../type_traits.h" #if defined(ETL_IN_UNIT_TEST) || ETL_USING_STL #include @@ -48,7 +49,7 @@ namespace etl ///\ingroup memory //***************************************************************************** template - ETL_CONSTEXPR17 T* addressof(T& t) + ETL_CONSTEXPR17 typename etl::enable_if::value, T>::type* addressof(T& t) { #if ETL_USING_STL && ETL_USING_CPP11 return std::addressof(t);