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 #ifndef CORE_FXCRT_OBSERVED_PTR_H_ 6 #define CORE_FXCRT_OBSERVED_PTR_H_ 7 8 #include <set> 9 10 #include "core/fxcrt/fx_system.h" 11 #include "third_party/base/stl_util.h" 12 13 namespace fxcrt { 14 15 class Observable { 16 public: 17 // General-purpose interface for more complicated cleanup. 18 class ObserverIface { 19 public: 20 virtual ~ObserverIface() = default; 21 virtual void OnObservableDestroyed() = 0; 22 }; 23 24 Observable(); 25 Observable(const Observable& that) = delete; 26 ~Observable(); AddObserver(ObserverIface * pObserver)27 void AddObserver(ObserverIface* pObserver) { 28 ASSERT(!pdfium::ContainsKey(m_Observers, pObserver)); 29 m_Observers.insert(pObserver); 30 } RemoveObserver(ObserverIface * pObserver)31 void RemoveObserver(ObserverIface* pObserver) { 32 ASSERT(pdfium::ContainsKey(m_Observers, pObserver)); 33 m_Observers.erase(pObserver); 34 } NotifyObservers()35 void NotifyObservers() { 36 for (auto* pObserver : m_Observers) 37 pObserver->OnObservableDestroyed(); 38 m_Observers.clear(); 39 } 40 Observable& operator=(const Observable& that) = delete; 41 42 protected: ActiveObserversForTesting()43 size_t ActiveObserversForTesting() const { return m_Observers.size(); } 44 45 private: 46 std::set<ObserverIface*> m_Observers; 47 }; 48 49 // Simple case of a self-nulling pointer. 50 template <typename T> 51 class ObservedPtr final : public Observable::ObserverIface { 52 public: 53 ObservedPtr() = default; ObservedPtr(T * pObservable)54 explicit ObservedPtr(T* pObservable) : m_pObservable(pObservable) { 55 if (m_pObservable) 56 m_pObservable->AddObserver(this); 57 } ObservedPtr(const ObservedPtr & that)58 ObservedPtr(const ObservedPtr& that) : ObservedPtr(that.Get()) {} ~ObservedPtr()59 ~ObservedPtr() override { 60 if (m_pObservable) 61 m_pObservable->RemoveObserver(this); 62 } 63 void Reset(T* pObservable = nullptr) { 64 if (m_pObservable) 65 m_pObservable->RemoveObserver(this); 66 m_pObservable = pObservable; 67 if (m_pObservable) 68 m_pObservable->AddObserver(this); 69 } OnObservableDestroyed()70 void OnObservableDestroyed() override { 71 ASSERT(m_pObservable); 72 m_pObservable = nullptr; 73 } HasObservable()74 bool HasObservable() const { return !!m_pObservable; } 75 ObservedPtr& operator=(const ObservedPtr& that) { 76 Reset(that.Get()); 77 return *this; 78 } 79 bool operator==(const ObservedPtr& that) const { 80 return m_pObservable == that.m_pObservable; 81 } 82 bool operator!=(const ObservedPtr& that) const { return !(*this == that); } 83 84 template <typename U> 85 bool operator==(const U* that) const { 86 return Get() == that; 87 } 88 89 template <typename U> 90 bool operator!=(const U* that) const { 91 return !(*this == that); 92 } 93 94 explicit operator bool() const { return HasObservable(); } Get()95 T* Get() const { return m_pObservable; } 96 T& operator*() const { return *m_pObservable; } 97 T* operator->() const { return m_pObservable; } 98 99 private: 100 T* m_pObservable = nullptr; 101 }; 102 103 template <typename T, typename U> 104 inline bool operator==(const U* lhs, const ObservedPtr<T>& rhs) { 105 return rhs == lhs; 106 } 107 108 template <typename T, typename U> 109 inline bool operator!=(const U* lhs, const ObservedPtr<T>& rhs) { 110 return rhs != lhs; 111 } 112 113 } // namespace fxcrt 114 115 using fxcrt::Observable; 116 using fxcrt::ObservedPtr; 117 118 #endif // CORE_FXCRT_OBSERVED_PTR_H_ 119