1 // Copyright 2016 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #ifndef CORE_FXCRT_WEAK_PTR_H_ 8 #define CORE_FXCRT_WEAK_PTR_H_ 9 10 #include <cstddef> 11 #include <memory> 12 #include <utility> 13 14 #include "core/fxcrt/fx_system.h" 15 #include "core/fxcrt/retain_ptr.h" 16 17 namespace fxcrt { 18 19 template <class T, class D = std::default_delete<T>> 20 class WeakPtr { 21 public: 22 WeakPtr() = default; WeakPtr(const WeakPtr & that)23 WeakPtr(const WeakPtr& that) : m_pHandle(that.m_pHandle) {} WeakPtr(WeakPtr && that)24 WeakPtr(WeakPtr&& that) noexcept { Swap(that); } WeakPtr(std::unique_ptr<T,D> pObj)25 explicit WeakPtr(std::unique_ptr<T, D> pObj) 26 : m_pHandle(new Handle(std::move(pObj))) {} 27 28 // Deliberately implicit to allow passing nullptr. 29 // NOLINTNEXTLINE(runtime/explicit) WeakPtr(std::nullptr_t arg)30 WeakPtr(std::nullptr_t arg) {} 31 32 explicit operator bool() const { return m_pHandle && !!m_pHandle->Get(); } HasOneRef()33 bool HasOneRef() const { return m_pHandle && m_pHandle->HasOneRef(); } 34 T* operator->() { return m_pHandle->Get(); } 35 const T* operator->() const { return m_pHandle->Get(); } 36 WeakPtr& operator=(const WeakPtr& that) { 37 m_pHandle = that.m_pHandle; 38 return *this; 39 } 40 bool operator==(const WeakPtr& that) const { 41 return m_pHandle == that.m_pHandle; 42 } 43 bool operator!=(const WeakPtr& that) const { return !(*this == that); } 44 Get()45 T* Get() const { return m_pHandle ? m_pHandle->Get() : nullptr; } DeleteObject()46 void DeleteObject() { 47 if (m_pHandle) { 48 m_pHandle->Clear(); 49 m_pHandle.Reset(); 50 } 51 } Reset()52 void Reset() { m_pHandle.Reset(); } Reset(std::unique_ptr<T,D> pObj)53 void Reset(std::unique_ptr<T, D> pObj) { 54 m_pHandle.Reset(new Handle(std::move(pObj))); 55 } Swap(WeakPtr & that)56 void Swap(WeakPtr& that) { m_pHandle.Swap(that.m_pHandle); } 57 58 private: 59 class Handle { 60 public: Handle(std::unique_ptr<T,D> ptr)61 explicit Handle(std::unique_ptr<T, D> ptr) 62 : m_nCount(0), m_pObj(std::move(ptr)) {} Reset(std::unique_ptr<T,D> ptr)63 void Reset(std::unique_ptr<T, D> ptr) { m_pObj = std::move(ptr); } Clear()64 void Clear() { // Now you're all weak ptrs ... 65 m_pObj.reset(); // unique_ptr nulls first before invoking delete. 66 } Get()67 T* Get() const { return m_pObj.get(); } Retain()68 T* Retain() { 69 ++m_nCount; 70 return m_pObj.get(); 71 } Release()72 void Release() { 73 if (--m_nCount == 0) 74 delete this; 75 } HasOneRef()76 bool HasOneRef() const { return m_nCount == 1; } 77 78 private: 79 ~Handle() = default; 80 81 intptr_t m_nCount; 82 std::unique_ptr<T, D> m_pObj; 83 }; 84 85 RetainPtr<Handle> m_pHandle; 86 }; 87 88 } // namespace fxcrt 89 90 using fxcrt::WeakPtr; 91 92 #endif // CORE_FXCRT_WEAK_PTR_H_ 93