Allow implicit conversion from Ref<T> to T&
[WebKit-https.git] / Source / WTF / wtf / Ref.h
index 73414ff..e3f34dc 100644 (file)
 #ifndef WTF_Ref_h
 #define WTF_Ref_h
 
-#include <wtf/Compiler.h>
+#include <wtf/GetPtr.h>
+#include <wtf/Noncopyable.h>
 
 namespace WTF {
 
+template<typename T> class PassRef;
+
 template<typename T> class Ref {
+    WTF_MAKE_NONCOPYABLE(Ref)
 public:
     Ref(T& object) : m_ptr(&object) { m_ptr->ref(); }
+    template<typename U> Ref(PassRef<U> reference) : m_ptr(&reference.leakRef()) { }
+
+    ~Ref() { m_ptr->deref(); }
+
     Ref& operator=(T& object)
     {
         object.ref();
@@ -40,8 +48,12 @@ public:
         m_ptr = &object;
         return *this;
     }
-
-    ~Ref() { m_ptr->deref(); }
+    template<typename U> Ref& operator=(PassRef<U> reference)
+    {
+        m_ptr->deref();
+        m_ptr = &reference.leakRef();
+        return *this;
+    }
 
     const T* operator->() const { return m_ptr; }
     T* operator->() { return m_ptr; }
@@ -49,13 +61,28 @@ public:
     const T& get() const { return *m_ptr; }
     T& get() { return *m_ptr; }
 
-private:
-    Ref(const Ref&);
-    Ref& operator=(const Ref<T>&);
+    operator T&() { return *m_ptr; }
+    operator const T&() const { return *m_ptr; }
+
+    template<typename U> PassRef<T> replace(PassRef<U>) WARN_UNUSED_RETURN;
 
+private:
     T* m_ptr;
 };
 
+template<typename T> template<typename U> inline PassRef<T> Ref<T>::replace(PassRef<U> reference)
+{
+    auto oldReference = adoptRef(*m_ptr);
+    m_ptr = &reference.leakRef();
+    return oldReference;
+}
+
+template <typename T>
+struct GetPtrHelper<Ref<T>> {
+    typedef T* PtrType;
+    static T* getPtr(const Ref<T>& p) { return const_cast<T*>(&p.get()); }
+};
+
 } // namespace WTF
 
 using WTF::Ref;