express: add full range of WeakPointerTo ctors and assign ops

Matches PointerTo constructors/assignment operators, supporting conversion between related pointer types.

Fixes #367
This commit is contained in:
rdb 2018-07-30 11:04:20 +02:00
parent f12bc29d6d
commit 2d7e80a89e
8 changed files with 373 additions and 33 deletions

View File

@ -11,13 +11,6 @@
* @date 2004-09-27 * @date 2004-09-27
*/ */
/**
*
*/
constexpr PointerToVoid::
PointerToVoid() noexcept : _void_ptr(nullptr) {
}
/** /**
* *
*/ */

View File

@ -32,7 +32,7 @@
*/ */
class EXPCL_PANDA_EXPRESS PointerToVoid : public MemoryBase { class EXPCL_PANDA_EXPRESS PointerToVoid : public MemoryBase {
protected: protected:
constexpr PointerToVoid() noexcept; constexpr PointerToVoid() noexcept = default;
//INLINE ~PointerToVoid(); //INLINE ~PointerToVoid();
private: private:
@ -63,7 +63,7 @@ protected:
// a PointerTo any class that inherits virtually from ReferenceCount. (You // a PointerTo any class that inherits virtually from ReferenceCount. (You
// can't downcast past a virtual inheritance level, but you can always // can't downcast past a virtual inheritance level, but you can always
// cross-cast from a void pointer.) // cross-cast from a void pointer.)
AtomicAdjust::Pointer _void_ptr; AtomicAdjust::Pointer _void_ptr = nullptr;
}; };
#include "pointerToVoid.I" #include "pointerToVoid.I"

View File

@ -39,6 +39,49 @@ WeakPointerTo(const WeakPointerTo<T> &copy) :
{ {
} }
/**
*
*/
template<class T>
INLINE WeakPointerTo<T>::
WeakPointerTo(WeakPointerTo<T> &&from) noexcept :
WeakPointerToBase<T>(std::move(from))
{
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakPointerTo<T>::
WeakPointerTo(const WeakPointerTo<Y> &r) noexcept :
WeakPointerToBase<T>(r)
{
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakPointerTo<T>::
WeakPointerTo(const PointerTo<Y> &r) noexcept :
WeakPointerToBase<T>(r)
{
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakPointerTo<T>::
WeakPointerTo(WeakPointerTo<Y> &&r) noexcept :
WeakPointerToBase<T>(std::move(r))
{
}
/** /**
* *
*/ */
@ -152,6 +195,49 @@ operator = (const WeakPointerTo<T> &copy) {
return *this; return *this;
} }
/**
*
*/
template<class T>
INLINE WeakPointerTo<T> &WeakPointerTo<T>::
operator = (WeakPointerTo<T> &&from) noexcept {
this->reassign(std::move(from));
return *this;
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakPointerTo<T> &WeakPointerTo<T>::
operator = (const WeakPointerTo<Y> &r) noexcept {
this->reassign(r);
return *this;
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakPointerTo<T> &WeakPointerTo<T>::
operator = (const PointerTo<Y> &r) noexcept {
this->reassign(r);
return *this;
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakPointerTo<T> &WeakPointerTo<T>::
operator = (WeakPointerTo<Y> &&r) noexcept {
this->reassign(std::move(r));
return *this;
}
/** /**
* *
*/ */
@ -202,6 +288,92 @@ WeakConstPointerTo(const WeakConstPointerTo<T> &copy) :
{ {
} }
/**
*
*/
template<class T>
INLINE WeakConstPointerTo<T>::
WeakConstPointerTo(WeakPointerTo<T> &&from) noexcept :
WeakPointerToBase<T>(std::move(from))
{
}
/**
*
*/
template<class T>
INLINE WeakConstPointerTo<T>::
WeakConstPointerTo(WeakConstPointerTo<T> &&from) noexcept :
WeakPointerToBase<T>(std::move(from))
{
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T>::
WeakConstPointerTo(const WeakPointerTo<Y> &r) noexcept :
WeakPointerToBase<T>(r)
{
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T>::
WeakConstPointerTo(const WeakConstPointerTo<Y> &r) noexcept :
WeakPointerToBase<T>(r)
{
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T>::
WeakConstPointerTo(const PointerTo<Y> &r) noexcept :
WeakPointerToBase<T>(r)
{
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T>::
WeakConstPointerTo(const ConstPointerTo<Y> &r) noexcept :
WeakPointerToBase<T>(r)
{
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T>::
WeakConstPointerTo(WeakPointerTo<Y> &&r) noexcept :
WeakPointerToBase<T>(std::move(r))
{
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T>::
WeakConstPointerTo(WeakConstPointerTo<Y> &&r) noexcept :
WeakPointerToBase<T>(std::move(r))
{
}
/** /**
* *
*/ */
@ -332,3 +504,89 @@ operator = (const WeakConstPointerTo<T> &copy) {
((WeakConstPointerTo<T> *)this)->reassign(*(const PointerToBase<T> *)&copy); ((WeakConstPointerTo<T> *)this)->reassign(*(const PointerToBase<T> *)&copy);
return *this; return *this;
} }
/**
*
*/
template<class T>
INLINE WeakConstPointerTo<T> &WeakConstPointerTo<T>::
operator = (WeakPointerTo<T> &&from) noexcept {
this->reassign(std::move(from));
return *this;
}
/**
*
*/
template<class T>
INLINE WeakConstPointerTo<T> &WeakConstPointerTo<T>::
operator = (WeakConstPointerTo<T> &&from) noexcept {
this->reassign(std::move(from));
return *this;
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T> &WeakConstPointerTo<T>::
operator = (const WeakPointerTo<Y> &r) noexcept {
this->reassign(r);
return *this;
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T> &WeakConstPointerTo<T>::
operator = (const WeakConstPointerTo<Y> &r) noexcept {
this->reassign(r);
return *this;
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T> &WeakConstPointerTo<T>::
operator = (const PointerTo<Y> &r) noexcept {
this->reassign(r);
return *this;
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T> &WeakConstPointerTo<T>::
operator = (const ConstPointerTo<Y> &r) noexcept {
this->reassign(r);
return *this;
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T> &WeakConstPointerTo<T>::
operator = (WeakPointerTo<Y> &&r) noexcept {
this->reassign(std::move(r));
return *this;
}
/**
*
*/
template<class T>
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T> &WeakConstPointerTo<T>::
operator = (WeakConstPointerTo<Y> &&r) noexcept {
this->reassign(std::move(r));
return *this;
}

View File

@ -30,11 +30,21 @@ class WeakPointerTo : public WeakPointerToBase<T> {
public: public:
typedef typename WeakPointerToBase<T>::To To; typedef typename WeakPointerToBase<T>::To To;
PUBLISHED: PUBLISHED:
INLINE WeakPointerTo(To *ptr = nullptr); constexpr WeakPointerTo() noexcept = default;
INLINE WeakPointerTo(To *ptr);
INLINE WeakPointerTo(const PointerTo<T> &copy); INLINE WeakPointerTo(const PointerTo<T> &copy);
INLINE WeakPointerTo(const WeakPointerTo<T> &copy); INLINE WeakPointerTo(const WeakPointerTo<T> &copy);
public: public:
INLINE WeakPointerTo(WeakPointerTo<T> &&from) noexcept;
template<class Y>
ALWAYS_INLINE WeakPointerTo(const WeakPointerTo<Y> &r) noexcept;
template<class Y>
ALWAYS_INLINE WeakPointerTo(const PointerTo<Y> &r) noexcept;
template<class Y>
ALWAYS_INLINE WeakPointerTo(WeakPointerTo<Y> &&r) noexcept;
INLINE To &operator *() const; INLINE To &operator *() const;
INLINE To *operator -> () const; INLINE To *operator -> () const;
// MSVC.NET 2005 insists that we use T *, and not To *, here. // MSVC.NET 2005 insists that we use T *, and not To *, here.
@ -49,6 +59,17 @@ PUBLISHED:
INLINE WeakPointerTo<T> &operator = (const PointerTo<T> &copy); INLINE WeakPointerTo<T> &operator = (const PointerTo<T> &copy);
INLINE WeakPointerTo<T> &operator = (const WeakPointerTo<T> &copy); INLINE WeakPointerTo<T> &operator = (const WeakPointerTo<T> &copy);
public:
INLINE WeakPointerTo<T> &operator = (WeakPointerTo<T> &&from) noexcept;
template<class Y>
ALWAYS_INLINE WeakPointerTo<T> &operator = (const WeakPointerTo<Y> &r) noexcept;
template<class Y>
ALWAYS_INLINE WeakPointerTo<T> &operator = (const PointerTo<Y> &r) noexcept;
template<class Y>
ALWAYS_INLINE WeakPointerTo<T> &operator = (WeakPointerTo<Y> &&r) noexcept;
PUBLISHED:
// This function normally wouldn't need to be redefined here, but we do so // 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 // anyway just to help out interrogate (which doesn't seem to want to
// automatically export the WeakPointerToBase class). When this works again // automatically export the WeakPointerToBase class). When this works again
@ -66,13 +87,30 @@ class WeakConstPointerTo : public WeakPointerToBase<T> {
public: public:
typedef typename WeakPointerToBase<T>::To To; typedef typename WeakPointerToBase<T>::To To;
PUBLISHED: PUBLISHED:
INLINE WeakConstPointerTo(const To *ptr = nullptr); constexpr WeakConstPointerTo() noexcept = default;
INLINE WeakConstPointerTo(const To *ptr);
INLINE WeakConstPointerTo(const PointerTo<T> &copy); INLINE WeakConstPointerTo(const PointerTo<T> &copy);
INLINE WeakConstPointerTo(const ConstPointerTo<T> &copy); INLINE WeakConstPointerTo(const ConstPointerTo<T> &copy);
INLINE WeakConstPointerTo(const WeakPointerTo<T> &copy); INLINE WeakConstPointerTo(const WeakPointerTo<T> &copy);
INLINE WeakConstPointerTo(const WeakConstPointerTo<T> &copy); INLINE WeakConstPointerTo(const WeakConstPointerTo<T> &copy);
public: public:
INLINE WeakConstPointerTo(WeakPointerTo<T> &&from) noexcept;
INLINE WeakConstPointerTo(WeakConstPointerTo<T> &&from) noexcept;
template<class Y>
ALWAYS_INLINE WeakConstPointerTo(const WeakPointerTo<Y> &r) noexcept;
template<class Y>
ALWAYS_INLINE WeakConstPointerTo(const WeakConstPointerTo<Y> &r) noexcept;
template<class Y>
ALWAYS_INLINE WeakConstPointerTo(const PointerTo<Y> &r) noexcept;
template<class Y>
ALWAYS_INLINE WeakConstPointerTo(const ConstPointerTo<Y> &r) noexcept;
template<class Y>
ALWAYS_INLINE WeakConstPointerTo(WeakPointerTo<Y> &&r) noexcept;
template<class Y>
ALWAYS_INLINE WeakConstPointerTo(WeakConstPointerTo<Y> &&r) noexcept;
INLINE const To &operator *() const; INLINE const To &operator *() const;
INLINE const To *operator -> () const; INLINE const To *operator -> () const;
INLINE explicit operator const T *() const; INLINE explicit operator const T *() const;
@ -88,6 +126,24 @@ PUBLISHED:
INLINE WeakConstPointerTo<T> &operator = (const WeakPointerTo<T> &copy); INLINE WeakConstPointerTo<T> &operator = (const WeakPointerTo<T> &copy);
INLINE WeakConstPointerTo<T> &operator = (const WeakConstPointerTo<T> &copy); INLINE WeakConstPointerTo<T> &operator = (const WeakConstPointerTo<T> &copy);
public:
INLINE WeakConstPointerTo<T> &operator = (WeakPointerTo<T> &&from) noexcept;
INLINE WeakConstPointerTo<T> &operator = (WeakConstPointerTo<T> &&from) noexcept;
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T> &operator = (const WeakPointerTo<Y> &r) noexcept;
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T> &operator = (const WeakConstPointerTo<Y> &r) noexcept;
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T> &operator = (const PointerTo<Y> &r) noexcept;
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T> &operator = (const ConstPointerTo<Y> &r) noexcept;
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T> &operator = (WeakPointerTo<Y> &&r) noexcept;
template<class Y>
ALWAYS_INLINE WeakConstPointerTo<T> &operator = (WeakConstPointerTo<Y> &&r) noexcept;
PUBLISHED:
// These functions normally wouldn't need to be redefined here, but we do so // 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 // anyway just to help out interrogate (which doesn't seem to want to
// automatically export the WeakPointerToBase class). When this works again // automatically export the WeakPointerToBase class). When this works again

View File

@ -64,20 +64,27 @@ WeakPointerToBase(const WeakPointerToBase<T> &copy) {
template<class T> template<class T>
INLINE WeakPointerToBase<T>:: INLINE WeakPointerToBase<T>::
WeakPointerToBase(WeakPointerToBase<T> &&from) noexcept { WeakPointerToBase(WeakPointerToBase<T> &&from) noexcept {
// Protect against self-move-assignment. this->_void_ptr = from._void_ptr;
if (from._void_ptr != this->_void_ptr) { this->_weak_ref = from._weak_ref;
WeakReferenceList *old_ref = (To *)this->_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<class T>
template<class Y>
INLINE WeakPointerToBase<T>::
WeakPointerToBase(WeakPointerToBase<Y> &&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. this->_void_ptr = ptr;
if (old_ref != nullptr && !old_ref->unref()) { this->_weak_ref = r._weak_ref;
delete old_ref; r._void_ptr = nullptr;
} r._weak_ref = nullptr;
}
} }
/** /**
@ -180,6 +187,33 @@ reassign(WeakPointerToBase<To> &&from) noexcept {
} }
} }
/**
* Like above, but casts from a compatible pointer type.
*/
template<class T>
template<class Y>
INLINE void WeakPointerToBase<T>::
reassign(WeakPointerToBase<Y> &&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 * Ensures that the MemoryUsage record for the pointer has the right type of
* object, if we know the type ourselves. * object, if we know the type ourselves.

View File

@ -28,16 +28,22 @@ public:
typedef T To; typedef T To;
protected: protected:
INLINE WeakPointerToBase(To *ptr); constexpr WeakPointerToBase() noexcept = default;
INLINE explicit WeakPointerToBase(To *ptr);
INLINE WeakPointerToBase(const PointerToBase<T> &copy); INLINE WeakPointerToBase(const PointerToBase<T> &copy);
INLINE WeakPointerToBase(const WeakPointerToBase<T> &copy); INLINE WeakPointerToBase(const WeakPointerToBase<T> &copy);
INLINE WeakPointerToBase(WeakPointerToBase<T> &&from) noexcept; INLINE WeakPointerToBase(WeakPointerToBase<T> &&from) noexcept;
template<class Y>
INLINE WeakPointerToBase(WeakPointerToBase<Y> &&r) noexcept;
INLINE ~WeakPointerToBase(); INLINE ~WeakPointerToBase();
void reassign(To *ptr); void reassign(To *ptr);
INLINE void reassign(const PointerToBase<To> &copy); INLINE void reassign(const PointerToBase<To> &copy);
INLINE void reassign(const WeakPointerToBase<To> &copy); INLINE void reassign(const WeakPointerToBase<To> &copy);
INLINE void reassign(WeakPointerToBase<To> &&from) noexcept; INLINE void reassign(WeakPointerToBase<To> &&from) noexcept;
template<class Y>
INLINE void reassign(WeakPointerToBase<Y> &&from) noexcept;
INLINE void update_type(To *ptr); INLINE void update_type(To *ptr);

View File

@ -11,13 +11,6 @@
* @date 2004-09-27 * @date 2004-09-27
*/ */
/**
*
*/
INLINE WeakPointerToVoid::
WeakPointerToVoid() : _weak_ref(nullptr) {
}
/** /**
* Sets a callback that will be made when the pointer is deleted. Does * Sets a callback that will be made when the pointer is deleted. Does
* nothing if this is a null pointer. * nothing if this is a null pointer.

View File

@ -25,7 +25,7 @@
*/ */
class EXPCL_PANDA_EXPRESS WeakPointerToVoid : public PointerToVoid { class EXPCL_PANDA_EXPRESS WeakPointerToVoid : public PointerToVoid {
protected: protected:
INLINE WeakPointerToVoid(); constexpr WeakPointerToVoid() noexcept = default;
public: public:
INLINE void add_callback(WeakPointerCallback *callback) const; INLINE void add_callback(WeakPointerCallback *callback) const;
@ -36,7 +36,7 @@ PUBLISHED:
INLINE bool is_valid_pointer() const; INLINE bool is_valid_pointer() const;
protected: protected:
mutable WeakReferenceList *_weak_ref; mutable WeakReferenceList *_weak_ref = nullptr;
}; };
#include "weakPointerToVoid.I" #include "weakPointerToVoid.I"