From 2d7e80a89e9c8a245778fe19d537ecfc9819d248 Mon Sep 17 00:00:00 2001 From: rdb Date: Mon, 30 Jul 2018 11:04:20 +0200 Subject: [PATCH] express: add full range of WeakPointerTo ctors and assign ops Matches PointerTo constructors/assignment operators, supporting conversion between related pointer types. Fixes #367 --- panda/src/express/pointerToVoid.I | 7 - panda/src/express/pointerToVoid.h | 4 +- panda/src/express/weakPointerTo.I | 258 ++++++++++++++++++++++++++ panda/src/express/weakPointerTo.h | 60 +++++- panda/src/express/weakPointerToBase.I | 58 ++++-- panda/src/express/weakPointerToBase.h | 8 +- panda/src/express/weakPointerToVoid.I | 7 - panda/src/express/weakPointerToVoid.h | 4 +- 8 files changed, 373 insertions(+), 33 deletions(-) diff --git a/panda/src/express/pointerToVoid.I b/panda/src/express/pointerToVoid.I index c6f981a7fb..8704ce4ce6 100644 --- a/panda/src/express/pointerToVoid.I +++ b/panda/src/express/pointerToVoid.I @@ -11,13 +11,6 @@ * @date 2004-09-27 */ -/** - * - */ -constexpr PointerToVoid:: -PointerToVoid() noexcept : _void_ptr(nullptr) { -} - /** * */ diff --git a/panda/src/express/pointerToVoid.h b/panda/src/express/pointerToVoid.h index 1f5fadd492..e185911eab 100644 --- a/panda/src/express/pointerToVoid.h +++ b/panda/src/express/pointerToVoid.h @@ -32,7 +32,7 @@ */ class EXPCL_PANDA_EXPRESS PointerToVoid : public MemoryBase { protected: - constexpr PointerToVoid() noexcept; + constexpr PointerToVoid() noexcept = default; //INLINE ~PointerToVoid(); private: @@ -63,7 +63,7 @@ protected: // a PointerTo any class that inherits virtually from ReferenceCount. (You // can't downcast past a virtual inheritance level, but you can always // cross-cast from a void pointer.) - AtomicAdjust::Pointer _void_ptr; + AtomicAdjust::Pointer _void_ptr = nullptr; }; #include "pointerToVoid.I" diff --git a/panda/src/express/weakPointerTo.I b/panda/src/express/weakPointerTo.I index c6e570979f..354846807a 100644 --- a/panda/src/express/weakPointerTo.I +++ b/panda/src/express/weakPointerTo.I @@ -39,6 +39,49 @@ WeakPointerTo(const WeakPointerTo ©) : { } +/** + * + */ +template +INLINE WeakPointerTo:: +WeakPointerTo(WeakPointerTo &&from) noexcept : + WeakPointerToBase(std::move(from)) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakPointerTo:: +WeakPointerTo(const WeakPointerTo &r) noexcept : + WeakPointerToBase(r) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakPointerTo:: +WeakPointerTo(const PointerTo &r) noexcept : + WeakPointerToBase(r) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakPointerTo:: +WeakPointerTo(WeakPointerTo &&r) noexcept : + WeakPointerToBase(std::move(r)) +{ +} + /** * */ @@ -152,6 +195,49 @@ operator = (const WeakPointerTo ©) { return *this; } +/** + * + */ +template +INLINE WeakPointerTo &WeakPointerTo:: +operator = (WeakPointerTo &&from) noexcept { + this->reassign(std::move(from)); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakPointerTo &WeakPointerTo:: +operator = (const WeakPointerTo &r) noexcept { + this->reassign(r); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakPointerTo &WeakPointerTo:: +operator = (const PointerTo &r) noexcept { + this->reassign(r); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakPointerTo &WeakPointerTo:: +operator = (WeakPointerTo &&r) noexcept { + this->reassign(std::move(r)); + return *this; +} + /** * */ @@ -202,6 +288,92 @@ WeakConstPointerTo(const WeakConstPointerTo ©) : { } +/** + * + */ +template +INLINE WeakConstPointerTo:: +WeakConstPointerTo(WeakPointerTo &&from) noexcept : + WeakPointerToBase(std::move(from)) +{ +} + +/** + * + */ +template +INLINE WeakConstPointerTo:: +WeakConstPointerTo(WeakConstPointerTo &&from) noexcept : + WeakPointerToBase(std::move(from)) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo:: +WeakConstPointerTo(const WeakPointerTo &r) noexcept : + WeakPointerToBase(r) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo:: +WeakConstPointerTo(const WeakConstPointerTo &r) noexcept : + WeakPointerToBase(r) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo:: +WeakConstPointerTo(const PointerTo &r) noexcept : + WeakPointerToBase(r) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo:: +WeakConstPointerTo(const ConstPointerTo &r) noexcept : + WeakPointerToBase(r) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo:: +WeakConstPointerTo(WeakPointerTo &&r) noexcept : + WeakPointerToBase(std::move(r)) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo:: +WeakConstPointerTo(WeakConstPointerTo &&r) noexcept : + WeakPointerToBase(std::move(r)) +{ +} + /** * */ @@ -332,3 +504,89 @@ operator = (const WeakConstPointerTo ©) { ((WeakConstPointerTo *)this)->reassign(*(const PointerToBase *)©); return *this; } + +/** + * + */ +template +INLINE WeakConstPointerTo &WeakConstPointerTo:: +operator = (WeakPointerTo &&from) noexcept { + this->reassign(std::move(from)); + return *this; +} + +/** + * + */ +template +INLINE WeakConstPointerTo &WeakConstPointerTo:: +operator = (WeakConstPointerTo &&from) noexcept { + this->reassign(std::move(from)); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo &WeakConstPointerTo:: +operator = (const WeakPointerTo &r) noexcept { + this->reassign(r); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo &WeakConstPointerTo:: +operator = (const WeakConstPointerTo &r) noexcept { + this->reassign(r); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo &WeakConstPointerTo:: +operator = (const PointerTo &r) noexcept { + this->reassign(r); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo &WeakConstPointerTo:: +operator = (const ConstPointerTo &r) noexcept { + this->reassign(r); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo &WeakConstPointerTo:: +operator = (WeakPointerTo &&r) noexcept { + this->reassign(std::move(r)); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE WeakConstPointerTo &WeakConstPointerTo:: +operator = (WeakConstPointerTo &&r) noexcept { + this->reassign(std::move(r)); + return *this; +} diff --git a/panda/src/express/weakPointerTo.h b/panda/src/express/weakPointerTo.h index 2e8c6029a5..ee50b0ebc3 100644 --- a/panda/src/express/weakPointerTo.h +++ b/panda/src/express/weakPointerTo.h @@ -30,11 +30,21 @@ class WeakPointerTo : public WeakPointerToBase { public: typedef typename WeakPointerToBase::To To; PUBLISHED: - INLINE WeakPointerTo(To *ptr = nullptr); + constexpr WeakPointerTo() noexcept = default; + INLINE WeakPointerTo(To *ptr); INLINE WeakPointerTo(const PointerTo ©); INLINE WeakPointerTo(const WeakPointerTo ©); public: + INLINE WeakPointerTo(WeakPointerTo &&from) noexcept; + + template + ALWAYS_INLINE WeakPointerTo(const WeakPointerTo &r) noexcept; + template + ALWAYS_INLINE WeakPointerTo(const PointerTo &r) noexcept; + template + ALWAYS_INLINE WeakPointerTo(WeakPointerTo &&r) noexcept; + INLINE To &operator *() const; INLINE To *operator -> () const; // MSVC.NET 2005 insists that we use T *, and not To *, here. @@ -49,6 +59,17 @@ PUBLISHED: INLINE WeakPointerTo &operator = (const PointerTo ©); INLINE WeakPointerTo &operator = (const WeakPointerTo ©); +public: + INLINE WeakPointerTo &operator = (WeakPointerTo &&from) noexcept; + + template + ALWAYS_INLINE WeakPointerTo &operator = (const WeakPointerTo &r) noexcept; + template + ALWAYS_INLINE WeakPointerTo &operator = (const PointerTo &r) noexcept; + template + ALWAYS_INLINE WeakPointerTo &operator = (WeakPointerTo &&r) noexcept; + +PUBLISHED: // This function normally wouldn't need to be redefined here, but we do so // anyway just to help out interrogate (which doesn't seem to want to // automatically export the WeakPointerToBase class). When this works again @@ -66,13 +87,30 @@ class WeakConstPointerTo : public WeakPointerToBase { public: typedef typename WeakPointerToBase::To To; PUBLISHED: - INLINE WeakConstPointerTo(const To *ptr = nullptr); + constexpr WeakConstPointerTo() noexcept = default; + INLINE WeakConstPointerTo(const To *ptr); INLINE WeakConstPointerTo(const PointerTo ©); INLINE WeakConstPointerTo(const ConstPointerTo ©); INLINE WeakConstPointerTo(const WeakPointerTo ©); INLINE WeakConstPointerTo(const WeakConstPointerTo ©); public: + INLINE WeakConstPointerTo(WeakPointerTo &&from) noexcept; + INLINE WeakConstPointerTo(WeakConstPointerTo &&from) noexcept; + + template + ALWAYS_INLINE WeakConstPointerTo(const WeakPointerTo &r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo(const WeakConstPointerTo &r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo(const PointerTo &r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo(const ConstPointerTo &r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo(WeakPointerTo &&r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo(WeakConstPointerTo &&r) noexcept; + INLINE const To &operator *() const; INLINE const To *operator -> () const; INLINE explicit operator const T *() const; @@ -88,6 +126,24 @@ PUBLISHED: INLINE WeakConstPointerTo &operator = (const WeakPointerTo ©); INLINE WeakConstPointerTo &operator = (const WeakConstPointerTo ©); +public: + INLINE WeakConstPointerTo &operator = (WeakPointerTo &&from) noexcept; + INLINE WeakConstPointerTo &operator = (WeakConstPointerTo &&from) noexcept; + + template + ALWAYS_INLINE WeakConstPointerTo &operator = (const WeakPointerTo &r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo &operator = (const WeakConstPointerTo &r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo &operator = (const PointerTo &r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo &operator = (const ConstPointerTo &r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo &operator = (WeakPointerTo &&r) noexcept; + template + ALWAYS_INLINE WeakConstPointerTo &operator = (WeakConstPointerTo &&r) noexcept; + +PUBLISHED: // These functions normally wouldn't need to be redefined here, but we do so // anyway just to help out interrogate (which doesn't seem to want to // automatically export the WeakPointerToBase class). When this works again diff --git a/panda/src/express/weakPointerToBase.I b/panda/src/express/weakPointerToBase.I index 2e537c9639..5410903fdd 100644 --- a/panda/src/express/weakPointerToBase.I +++ b/panda/src/express/weakPointerToBase.I @@ -64,20 +64,27 @@ WeakPointerToBase(const WeakPointerToBase ©) { template INLINE WeakPointerToBase:: WeakPointerToBase(WeakPointerToBase &&from) noexcept { - // Protect against self-move-assignment. - if (from._void_ptr != this->_void_ptr) { - WeakReferenceList *old_ref = (To *)this->_weak_ref; + this->_void_ptr = from._void_ptr; + this->_weak_ref = from._weak_ref; + from._void_ptr = nullptr; + from._weak_ref = nullptr; +} - this->_void_ptr = from._void_ptr; - this->_weak_ref = from._weak_ref; - from._void_ptr = nullptr; - from._weak_ref = nullptr; +/** + * + */ +template +template +INLINE WeakPointerToBase:: +WeakPointerToBase(WeakPointerToBase &&r) noexcept { + // If this next line gives an error, you are trying to convert a WeakPointerTo + // from an incompatible type of another WeakPointerTo. + To *ptr = (Y *)r._void_ptr; - // Now delete the old pointer. - if (old_ref != nullptr && !old_ref->unref()) { - delete old_ref; - } - } + this->_void_ptr = ptr; + this->_weak_ref = r._weak_ref; + r._void_ptr = nullptr; + r._weak_ref = nullptr; } /** @@ -180,6 +187,33 @@ reassign(WeakPointerToBase &&from) noexcept { } } +/** + * Like above, but casts from a compatible pointer type. + */ +template +template +INLINE void WeakPointerToBase:: +reassign(WeakPointerToBase &&from) noexcept { + // Protect against self-move-assignment. + if (from._void_ptr != this->_void_ptr) { + WeakReferenceList *old_ref = (WeakReferenceList *)this->_weak_ref; + + // If there is a compile error on this line, it means you tried to assign + // an incompatible type. + To *new_ptr = (Y *)from._void_ptr; + + this->_void_ptr = new_ptr; + this->_weak_ref = from._weak_ref; + from._void_ptr = nullptr; + from._weak_ref = nullptr; + + // Now delete the old pointer. + if (old_ref != nullptr && !old_ref->unref()) { + delete old_ref; + } + } +} + /** * Ensures that the MemoryUsage record for the pointer has the right type of * object, if we know the type ourselves. diff --git a/panda/src/express/weakPointerToBase.h b/panda/src/express/weakPointerToBase.h index a34b39bdb5..94efd051eb 100644 --- a/panda/src/express/weakPointerToBase.h +++ b/panda/src/express/weakPointerToBase.h @@ -28,16 +28,22 @@ public: typedef T To; protected: - INLINE WeakPointerToBase(To *ptr); + constexpr WeakPointerToBase() noexcept = default; + INLINE explicit WeakPointerToBase(To *ptr); INLINE WeakPointerToBase(const PointerToBase ©); INLINE WeakPointerToBase(const WeakPointerToBase ©); INLINE WeakPointerToBase(WeakPointerToBase &&from) noexcept; + template + INLINE WeakPointerToBase(WeakPointerToBase &&r) noexcept; + INLINE ~WeakPointerToBase(); void reassign(To *ptr); INLINE void reassign(const PointerToBase ©); INLINE void reassign(const WeakPointerToBase ©); INLINE void reassign(WeakPointerToBase &&from) noexcept; + template + INLINE void reassign(WeakPointerToBase &&from) noexcept; INLINE void update_type(To *ptr); diff --git a/panda/src/express/weakPointerToVoid.I b/panda/src/express/weakPointerToVoid.I index 120836510d..187a659fc1 100644 --- a/panda/src/express/weakPointerToVoid.I +++ b/panda/src/express/weakPointerToVoid.I @@ -11,13 +11,6 @@ * @date 2004-09-27 */ -/** - * - */ -INLINE WeakPointerToVoid:: -WeakPointerToVoid() : _weak_ref(nullptr) { -} - /** * Sets a callback that will be made when the pointer is deleted. Does * nothing if this is a null pointer. diff --git a/panda/src/express/weakPointerToVoid.h b/panda/src/express/weakPointerToVoid.h index 56ace2dcb2..3eadfffc4d 100644 --- a/panda/src/express/weakPointerToVoid.h +++ b/panda/src/express/weakPointerToVoid.h @@ -25,7 +25,7 @@ */ class EXPCL_PANDA_EXPRESS WeakPointerToVoid : public PointerToVoid { protected: - INLINE WeakPointerToVoid(); + constexpr WeakPointerToVoid() noexcept = default; public: INLINE void add_callback(WeakPointerCallback *callback) const; @@ -36,7 +36,7 @@ PUBLISHED: INLINE bool is_valid_pointer() const; protected: - mutable WeakReferenceList *_weak_ref; + mutable WeakReferenceList *_weak_ref = nullptr; }; #include "weakPointerToVoid.I"