Browse Source

express: fix a few compile errors with certain WeakPointerTo uses

Fixes #367
rdb 7 years ago
parent
commit
fe1bfef5c0
2 changed files with 55 additions and 0 deletions
  1. 48 0
      panda/src/express/weakPointerToBase.I
  2. 7 0
      panda/src/express/weakPointerToBase.h

+ 48 - 0
panda/src/express/weakPointerToBase.I

@@ -72,6 +72,26 @@ WeakPointerToBase(WeakPointerToBase<T> &&from) noexcept {
   from._weak_ref = nullptr;
 }
 
+/**
+ * Copies a weak pointer from a cast-convertible weak pointer type.
+ */
+template<class T>
+template<class Y>
+INLINE WeakPointerToBase<T>::
+WeakPointerToBase(const WeakPointerToBase<Y> &r) {
+  // 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;
+
+  WeakReferenceList *weak_ref = r._weak_ref;
+  if (weak_ref != nullptr) {
+    _weak_ref = weak_ref;
+    weak_ref->ref();
+  }
+}
+
 /**
  * Moves a weak pointer from a cast-convertible weak pointer type.
  */
@@ -190,6 +210,34 @@ 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(const WeakPointerToBase<Y> &copy) {
+  // If there is a compile error on this line, it means you tried to assign
+  // an incompatible type.
+  To *new_ptr = (Y *)copy._void_ptr;
+
+  if (new_ptr != (To *)_void_ptr) {
+    WeakReferenceList *old_ref = (WeakReferenceList *)_weak_ref;
+    WeakReferenceList *new_ref = copy._weak_ref;
+    _void_ptr = new_ptr;
+    _weak_ref = new_ref;
+
+    if (new_ref != nullptr) {
+      new_ref->ref();
+    }
+
+    // Now remove the old reference.
+    if (old_ref != nullptr && !old_ref->unref()) {
+      delete old_ref;
+    }
+  }
+}
+
 /**
  * Like above, but casts from a compatible pointer type.
  */

+ 7 - 0
panda/src/express/weakPointerToBase.h

@@ -34,6 +34,8 @@ protected:
   INLINE WeakPointerToBase(const WeakPointerToBase<T> &copy);
   INLINE WeakPointerToBase(WeakPointerToBase<T> &&from) noexcept;
   template<class Y>
+  INLINE WeakPointerToBase(const WeakPointerToBase<Y> &r);
+  template<class Y>
   INLINE WeakPointerToBase(WeakPointerToBase<Y> &&r) noexcept;
 
   INLINE ~WeakPointerToBase();
@@ -43,6 +45,8 @@ protected:
   INLINE void reassign(const WeakPointerToBase<To> &copy);
   INLINE void reassign(WeakPointerToBase<To> &&from) noexcept;
   template<class Y>
+  INLINE void reassign(const WeakPointerToBase<Y> &copy);
+  template<class Y>
   INLINE void reassign(WeakPointerToBase<Y> &&from) noexcept;
 
   INLINE void update_type(To *ptr);
@@ -96,6 +100,9 @@ public:
   template<class Y>
   INLINE bool owner_before(const PointerToBase<Y> &other) const noexcept;
 
+  // This is needed to be able to access the privates of other instantiations.
+  template<typename Y> friend class WeakPointerToBase;
+
 PUBLISHED:
   INLINE void clear();
   INLINE void refresh() const;