diff --git a/panda/src/express/pointerTo.I b/panda/src/express/pointerTo.I index e0f8c85046..8c7aa38a4e 100644 --- a/panda/src/express/pointerTo.I +++ b/panda/src/express/pointerTo.I @@ -39,6 +39,41 @@ PointerTo(PointerTo &&from) noexcept : { } +#ifndef CPPPARSER +/** + * + */ +template +template +ALWAYS_INLINE PointerTo:: +PointerTo(Y *ptr) noexcept : + PointerToBase(ptr) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE PointerTo:: +PointerTo(const PointerTo &r) noexcept : + PointerToBase(r.p()) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE PointerTo:: +PointerTo(PointerTo &&r) noexcept : + PointerToBase(std::move(r)) +{ +} +#endif // !CPPPARSER + /** * */ @@ -49,6 +84,30 @@ operator = (PointerTo &&from) noexcept { return *this; } +#ifndef CPPPARSER +/** + * + */ +template +template +ALWAYS_INLINE PointerTo &PointerTo:: +operator = (const PointerTo &r) noexcept { + this->reassign(r.p()); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE PointerTo &PointerTo:: +operator = (PointerTo &&r) noexcept { + this->reassign(std::move(r)); + return *this; +} +#endif // !CPPPARSER + /** * */ @@ -172,6 +231,63 @@ ConstPointerTo(ConstPointerTo &&from) noexcept : { } +#ifndef CPPPARSER +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo:: +ConstPointerTo(const Y *ptr) noexcept : + PointerToBase((Y *)ptr) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo:: +ConstPointerTo(const PointerTo &r) noexcept : + PointerToBase(r.p()) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo:: +ConstPointerTo(const ConstPointerTo &r) noexcept : + PointerToBase((Y *)r.p()) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo:: +ConstPointerTo(PointerTo &&r) noexcept : + PointerToBase(std::move(r)) +{ +} + +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo:: +ConstPointerTo(ConstPointerTo &&r) noexcept : + PointerToBase(std::move(r)) +{ +} +#endif // !CPPPARSER + /** * */ @@ -192,6 +308,52 @@ operator = (ConstPointerTo &&from) noexcept { return *this; } +#ifndef CPPPARSER +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo &ConstPointerTo:: +operator = (const PointerTo &r) noexcept { + this->reassign(r.p()); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo &ConstPointerTo:: +operator = (const ConstPointerTo &r) noexcept { + this->reassign((Y *)r.p()); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo &ConstPointerTo:: +operator = (PointerTo &&r) noexcept { + this->reassign(std::move(r)); + return *this; +} + +/** + * + */ +template +template +ALWAYS_INLINE ConstPointerTo &ConstPointerTo:: +operator = (ConstPointerTo &&r) noexcept { + this->reassign(std::move(r)); + return *this; +} +#endif // !CPPPARSER + /** * */ diff --git a/panda/src/express/pointerTo.h b/panda/src/express/pointerTo.h index 1f9704c3f3..e9250a2f8a 100644 --- a/panda/src/express/pointerTo.h +++ b/panda/src/express/pointerTo.h @@ -77,8 +77,21 @@ PUBLISHED: public: INLINE PointerTo(PointerTo &&from) noexcept; + + template + ALWAYS_INLINE explicit PointerTo(Y *ptr) noexcept; + template + ALWAYS_INLINE PointerTo(const PointerTo &r) noexcept; + template + ALWAYS_INLINE PointerTo(PointerTo &&r) noexcept; + INLINE PointerTo &operator = (PointerTo &&from) noexcept; + template + ALWAYS_INLINE PointerTo &operator = (const PointerTo &r) noexcept; + template + ALWAYS_INLINE PointerTo &operator = (PointerTo &&r) noexcept; + constexpr To &operator *() const noexcept; constexpr To *operator -> () const noexcept; // MSVC.NET 2005 insists that we use T *, and not To *, here. @@ -141,9 +154,30 @@ PUBLISHED: public: INLINE ConstPointerTo(PointerTo &&from) noexcept; INLINE ConstPointerTo(ConstPointerTo &&from) noexcept; + + template + ALWAYS_INLINE explicit ConstPointerTo(const Y *ptr) noexcept; + template + ALWAYS_INLINE ConstPointerTo(const PointerTo &r) noexcept; + template + ALWAYS_INLINE ConstPointerTo(const ConstPointerTo &r) noexcept; + template + ALWAYS_INLINE ConstPointerTo(PointerTo &&r) noexcept; + template + ALWAYS_INLINE ConstPointerTo(ConstPointerTo &&r) noexcept; + INLINE ConstPointerTo &operator = (PointerTo &&from) noexcept; INLINE ConstPointerTo &operator = (ConstPointerTo &&from) noexcept; + template + ALWAYS_INLINE ConstPointerTo &operator = (const PointerTo &r) noexcept; + template + ALWAYS_INLINE ConstPointerTo &operator = (const ConstPointerTo &r) noexcept; + template + ALWAYS_INLINE ConstPointerTo &operator = (PointerTo &&r) noexcept; + template + ALWAYS_INLINE ConstPointerTo &operator = (ConstPointerTo &&r) noexcept; + constexpr const To &operator *() const noexcept; constexpr const To *operator -> () const noexcept; constexpr operator const T *() const noexcept; diff --git a/panda/src/express/pointerToBase.I b/panda/src/express/pointerToBase.I index e6e749f1f4..819e16efec 100644 --- a/panda/src/express/pointerToBase.I +++ b/panda/src/express/pointerToBase.I @@ -44,11 +44,24 @@ PointerToBase(const PointerToBase ©) { */ template INLINE PointerToBase:: -~PointerToBase() { - if (_void_ptr != nullptr) { - unref_delete((To *)_void_ptr); - _void_ptr = nullptr; - } +PointerToBase(PointerToBase &&from) noexcept { + _void_ptr = from._void_ptr; + from._void_ptr = nullptr; +} + +/** + * + */ +template +template +INLINE PointerToBase:: +PointerToBase(PointerToBase &&r) noexcept { + // If this next line gives an error, you are trying to convert a PointerTo + // from an incompatible type of another PointerTo. + To *ptr = (Y *)r._void_ptr; + + this->_void_ptr = ptr; + r._void_ptr = nullptr; } /** @@ -56,9 +69,11 @@ INLINE PointerToBase:: */ template INLINE PointerToBase:: -PointerToBase(PointerToBase &&from) noexcept { - _void_ptr = from._void_ptr; - from._void_ptr = nullptr; +~PointerToBase() { + if (_void_ptr != nullptr) { + unref_delete((To *)_void_ptr); + _void_ptr = nullptr; + } } /** @@ -84,6 +99,31 @@ reassign(PointerToBase &&from) noexcept { } } +/** + * Like above, but casts from a compatible pointer type. + */ +template +template +INLINE void PointerToBase:: +reassign(PointerToBase &&from) noexcept { + // Protect against self-move-assignment. + if (from._void_ptr != this->_void_ptr) { + To *old_ptr = (To *)this->_void_ptr; + + // 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; + from._void_ptr = nullptr; + + // Now delete the old pointer. + if (old_ptr != nullptr) { + unref_delete(old_ptr); + } + } +} + /** * This is the main work of the PointerTo family. When the pointer is * reassigned, decrement the old reference count and increment the new one. diff --git a/panda/src/express/pointerToBase.h b/panda/src/express/pointerToBase.h index 057a465454..959574aba7 100644 --- a/panda/src/express/pointerToBase.h +++ b/panda/src/express/pointerToBase.h @@ -35,17 +35,25 @@ protected: INLINE PointerToBase(To *ptr); INLINE PointerToBase(const PointerToBase ©); INLINE PointerToBase(PointerToBase &&from) noexcept; + template + INLINE PointerToBase(PointerToBase &&r) noexcept; + INLINE ~PointerToBase(); INLINE void reassign(To *ptr); INLINE void reassign(const PointerToBase ©); INLINE void reassign(PointerToBase &&from) noexcept; + template + INLINE void reassign(PointerToBase &&from) noexcept; INLINE void update_type(To *ptr); // No assignment or retrieval functions are declared in PointerToBase, // because we will have to specialize on const vs. non-const later. + // This is needed to be able to access the privates of other instantiations. + template friend class PointerToBase; + PUBLISHED: ALWAYS_INLINE void clear();