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
*/
/**
*
*/
constexpr PointerToVoid::
PointerToVoid() noexcept : _void_ptr(nullptr) {
}
/**
*
*/

View File

@ -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"

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;
}
/**
*
*/
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);
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:
typedef typename WeakPointerToBase<T>::To To;
PUBLISHED:
INLINE WeakPointerTo(To *ptr = nullptr);
constexpr WeakPointerTo() noexcept = default;
INLINE WeakPointerTo(To *ptr);
INLINE WeakPointerTo(const PointerTo<T> &copy);
INLINE WeakPointerTo(const WeakPointerTo<T> &copy);
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;
// 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 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
// 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<T> {
public:
typedef typename WeakPointerToBase<T>::To To;
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 ConstPointerTo<T> &copy);
INLINE WeakConstPointerTo(const WeakPointerTo<T> &copy);
INLINE WeakConstPointerTo(const WeakConstPointerTo<T> &copy);
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 explicit operator const T *() const;
@ -88,6 +126,24 @@ PUBLISHED:
INLINE WeakConstPointerTo<T> &operator = (const WeakPointerTo<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
// anyway just to help out interrogate (which doesn't seem to want to
// automatically export the WeakPointerToBase class). When this works again

View File

@ -64,20 +64,27 @@ WeakPointerToBase(const WeakPointerToBase<T> &copy) {
template<class T>
INLINE WeakPointerToBase<T>::
WeakPointerToBase(WeakPointerToBase<T> &&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;
}
// Now delete the old pointer.
if (old_ref != nullptr && !old_ref->unref()) {
delete old_ref;
}
}
/**
*
*/
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;
this->_void_ptr = ptr;
this->_weak_ref = r._weak_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
* object, if we know the type ourselves.

View File

@ -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<T> &copy);
INLINE WeakPointerToBase(const WeakPointerToBase<T> &copy);
INLINE WeakPointerToBase(WeakPointerToBase<T> &&from) noexcept;
template<class Y>
INLINE WeakPointerToBase(WeakPointerToBase<Y> &&r) noexcept;
INLINE ~WeakPointerToBase();
void reassign(To *ptr);
INLINE void reassign(const PointerToBase<To> &copy);
INLINE void reassign(const WeakPointerToBase<To> &copy);
INLINE void reassign(WeakPointerToBase<To> &&from) noexcept;
template<class Y>
INLINE void reassign(WeakPointerToBase<Y> &&from) noexcept;
INLINE void update_type(To *ptr);

View File

@ -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.

View File

@ -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"