From 678ec0f3fbc878a7a663d08b0f82d9257f190606 Mon Sep 17 00:00:00 2001 From: Kevin Bracey Date: Wed, 10 Jul 2019 12:45:59 +0300 Subject: [PATCH] SharedPtr: add move operations Optimise SharedPtr by giving it move constructor and assignment operator. --- platform/SharedPtr.h | 73 +++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 18 deletions(-) diff --git a/platform/SharedPtr.h b/platform/SharedPtr.h index edaa8198b3e..ae6d7794653 100644 --- a/platform/SharedPtr.h +++ b/platform/SharedPtr.h @@ -71,7 +71,7 @@ class SharedPtr { * @brief Create empty SharedPtr not pointing to anything. * @details Used for variable declaration. */ - SharedPtr(): _ptr(NULL), _counter(NULL) + constexpr SharedPtr(): _ptr(), _counter() { } @@ -79,12 +79,11 @@ class SharedPtr { * @brief Create new SharedPtr * @param ptr Pointer to take control over */ - SharedPtr(T *ptr): _ptr(ptr), _counter(NULL) + SharedPtr(T *ptr): _ptr(ptr), _counter() { // Allocate counter on the heap, so it can be shared - if (_ptr != NULL) { - _counter = new uint32_t; - *_counter = 1; + if (_ptr != nullptr) { + _counter = new uint32_t(1); } } @@ -106,13 +105,25 @@ class SharedPtr { SharedPtr(const SharedPtr &source): _ptr(source._ptr), _counter(source._counter) { // Increment reference counter - if (_ptr != NULL) { + if (_ptr != nullptr) { core_util_atomic_incr_u32(_counter, 1); } } /** - * @brief Assignment operator. + * @brief Move constructor. + * @details Create new SharedPtr from other SharedPtr by + * moving pointer to original object and pointer to counter. + * @param source Object being copied from. + */ + SharedPtr(SharedPtr &&source): _ptr(source._ptr), _counter(source._counter) + { + source._ptr = nullptr; + source._counter = nullptr; + } + + /** + * @brief Copy assignment operator. * @details Cleanup previous reference and assign new pointer and counter. * @param source Object being assigned from. * @return Object being assigned. @@ -128,7 +139,7 @@ class SharedPtr { _counter = source.get_counter(); // Increment new counter - if (_ptr != NULL) { + if (_ptr != nullptr) { core_util_atomic_incr_u32(_counter, 1); } } @@ -136,6 +147,29 @@ class SharedPtr { return *this; } + /** + * @brief Move assignment operator. + * @details Cleanup previous reference and assign new pointer and counter. + * @param source Object being assigned from. + * @return Object being assigned. + */ + SharedPtr operator=(SharedPtr &&source) + { + if (this != &source) { + // Clean up by decrementing counter + decrement_counter(); + + // Assign new values + _ptr = source._ptr; + _counter = source._counter; + + source._ptr = nullptr; + source._counter = nullptr; + } + + return *this; + } + /** * @brief Replaces the managed pointer with a new unmanaged pointer. * @param[in] ptr the new raw pointer to manage. @@ -146,21 +180,24 @@ class SharedPtr { decrement_counter(); _ptr = ptr; - if (ptr != NULL) { + if (ptr != nullptr) { // Allocate counter on the heap, so it can be shared - _counter = new uint32_t; - *_counter = 1; + _counter = new uint32_t(1); } else { - _counter = NULL; + _counter = nullptr; } } /** - * @brief Replace the managed pointer with a NULL pointer. + * @brief Replace the managed pointer with a null pointer. */ void reset() { - reset(NULL); + // Clean up by decrementing counter + decrement_counter(); + + _ptr = nullptr; + _counter = nullptr; } /** @@ -179,7 +216,7 @@ class SharedPtr { */ uint32_t use_count() const { - if (_ptr != NULL) { + if (_ptr != nullptr) { return core_util_atomic_load_u32(_counter); } else { return 0; @@ -206,11 +243,11 @@ class SharedPtr { /** * @brief Boolean conversion operator. - * @return Whether or not the pointer is NULL. + * @return Whether or not the pointer is null. */ operator bool() const { - return (_ptr != NULL); + return _ptr != nullptr; } private: @@ -231,7 +268,7 @@ class SharedPtr { */ void decrement_counter() { - if (_ptr != NULL) { + if (_ptr != nullptr) { if (core_util_atomic_decr_u32(_counter, 1) == 0) { delete _counter; delete _ptr;