Bug 1044658 - 4/6 - remove the need for asWeakPtr, and make asWeakPtr just return 'this' - r=froydnj
authorBenoit Jacob <bjacob@mozilla.com>
Wed, 30 Jul 2014 15:52:04 -0400
changeset 219838 5beea07a9f5f5ba7920d2bf74a87c6b93219d35f
parent 219837 77a2a058bc912c083750a9dd85cf1792e6141ff9
child 219839 8a7cbe9ed925429432adad630a9a138c9649a88d
push id583
push userbhearsum@mozilla.com
push dateMon, 24 Nov 2014 19:04:58 +0000
treeherdermozilla-release@c107e74250f4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1044658
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1044658 - 4/6 - remove the need for asWeakPtr, and make asWeakPtr just return 'this' - r=froydnj
mfbt/WeakPtr.h
--- a/mfbt/WeakPtr.h
+++ b/mfbt/WeakPtr.h
@@ -113,81 +113,111 @@ public:
     return nameBuffer;
   }
 
   size_t typeSize() const { return sizeof(*this); }
 #undef snprintf
 #endif
 
 private:
-  friend class WeakPtr<T>;
-  friend class SupportsWeakPtr<T>;
+  friend class mozilla::SupportsWeakPtr<T>;
 
   void detach() { mPtr = nullptr; }
 
   T* mPtr;
 };
 
 } // namespace detail
 
 template <typename T>
 class SupportsWeakPtr
 {
 public:
-  WeakPtr<T> asWeakPtr()
+
+  const T* asWeakPtr() const
   {
-    if (!weakRef) {
-      weakRef = new detail::WeakReference<T>(static_cast<T*>(this));
-    }
-    return WeakPtr<T>(weakRef);
+     return static_cast<const T*>(this);
   }
 
-  WeakPtr<const T> asWeakPtr() const
+  T* asWeakPtr()
   {
-     WeakPtr<T> p = const_cast<SupportsWeakPtr*>(this)->asWeakPtr();
-     return *reinterpret_cast<WeakPtr<const T>*>(&p);
+     return static_cast<T*>(this);
   }
 
 protected:
   ~SupportsWeakPtr()
   {
     static_assert(IsBaseOf<SupportsWeakPtr<T>, T>::value,
                   "T must derive from SupportsWeakPtr<T>");
-    if (weakRef) {
-      weakRef->detach();
+    if (mSelfReferencingWeakPtr) {
+      mSelfReferencingWeakPtr.mRef->detach();
     }
   }
 
 private:
-  friend class WeakPtr<T>;
+  const WeakPtr<T>& SelfReferencingWeakPtr()
+  {
+    if (!mSelfReferencingWeakPtr) {
+      mSelfReferencingWeakPtr.mRef = new detail::WeakReference<T>(static_cast<T*>(this));
+    }
+    return mSelfReferencingWeakPtr;
+  }
 
-  RefPtr<detail::WeakReference<T>> weakRef;
+  const WeakPtr<const T>& SelfReferencingWeakPtr() const
+  {
+    const WeakPtr<T>& p = const_cast<SupportsWeakPtr*>(this)->SelfReferencingWeakPtr();
+    return reinterpret_cast<const WeakPtr<const T>&>(p);
+  }
+
+  friend class WeakPtr<T>;
+  friend class WeakPtr<const T>;
+
+  WeakPtr<T> mSelfReferencingWeakPtr;
 };
 
 template <typename T>
 class WeakPtr
 {
+  typedef detail::WeakReference<T> WeakReference;
+
 public:
+  WeakPtr& operator=(const WeakPtr& aOther)
+  {
+    mRef = aOther.mRef;
+    return *this;
+  }
+
   WeakPtr(const WeakPtr& aOther)
-    : mRef(aOther.mRef)
-  {}
+  {
+    *this = aOther;
+  }
+
+  WeakPtr& operator=(T* aOther)
+  {
+    return *this = aOther->SelfReferencingWeakPtr();
+  }
+
+  WeakPtr(T* aOther)
+  {
+    *this = aOther;
+  }
 
   // Ensure that mRef is dereferenceable in the uninitialized state.
-  WeakPtr() : mRef(new detail::WeakReference<T>(nullptr)) {}
+  WeakPtr() : mRef(new WeakReference(nullptr)) {}
 
   operator T*() const { return mRef->get(); }
   T& operator*() const { return *mRef->get(); }
 
   T* operator->() const { return mRef->get(); }
 
   T* get() const { return mRef->get(); }
 
 private:
   friend class SupportsWeakPtr<T>;
 
-  explicit WeakPtr(const RefPtr<detail::WeakReference<T>>& aOther) : mRef(aOther) {}
+  explicit WeakPtr(const RefPtr<WeakReference>& aOther) : mRef(aOther) {}
 
-  RefPtr<detail::WeakReference<T>> mRef;
+  RefPtr<WeakReference> mRef;
 };
 
 } // namespace mozilla
 
 #endif /* mozilla_WeakPtr_h */