1 // Copyright 2016 The PDFium Authors 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 <stddef.h> 9 10 #include <set> 11 12 #include "core/fxcrt/unowned_ptr_exclusion.h" 13 #include "third_party/base/check.h" 14 15 namespace fxcrt { 16 17 class Observable { 18 public: 19 // General-purpose interface for more complicated cleanup. 20 class ObserverIface { 21 public: 22 virtual ~ObserverIface() = default; 23 virtual void OnObservableDestroyed() = 0; 24 }; 25 26 Observable(); 27 Observable(const Observable& that) = delete; 28 Observable& operator=(const Observable& that) = delete; 29 ~Observable(); 30 31 void AddObserver(ObserverIface* pObserver); 32 void RemoveObserver(ObserverIface* pObserver); 33 void NotifyObservers(); 34 35 protected: ActiveObserversForTesting()36 size_t ActiveObserversForTesting() const { return m_Observers.size(); } 37 38 private: 39 std::set<ObserverIface*> m_Observers; 40 }; 41 42 // Simple case of a self-nulling pointer. 43 // Generally, pass ObservedPtr<> by non-const reference since this saves 44 // considerable work compared to pass by value. 45 template <typename T> 46 class ObservedPtr final : public Observable::ObserverIface { 47 public: 48 ObservedPtr() = default; ObservedPtr(T * pObservable)49 explicit ObservedPtr(T* pObservable) : m_pObservable(pObservable) { 50 if (m_pObservable) 51 m_pObservable->AddObserver(this); 52 } ObservedPtr(const ObservedPtr & that)53 ObservedPtr(const ObservedPtr& that) : ObservedPtr(that.Get()) {} ~ObservedPtr()54 ~ObservedPtr() override { 55 if (m_pObservable) 56 m_pObservable->RemoveObserver(this); 57 } 58 void Reset(T* pObservable = nullptr) { 59 if (m_pObservable) 60 m_pObservable->RemoveObserver(this); 61 m_pObservable = pObservable; 62 if (m_pObservable) 63 m_pObservable->AddObserver(this); 64 } OnObservableDestroyed()65 void OnObservableDestroyed() override { 66 DCHECK(m_pObservable); 67 m_pObservable = nullptr; 68 } HasObservable()69 bool HasObservable() const { return !!m_pObservable; } 70 ObservedPtr& operator=(const ObservedPtr& that) { 71 Reset(that.Get()); 72 return *this; 73 } 74 bool operator==(const ObservedPtr& that) const { 75 return m_pObservable == that.m_pObservable; 76 } 77 bool operator!=(const ObservedPtr& that) const { return !(*this == that); } 78 79 template <typename U> 80 bool operator==(const U* that) const { 81 return Get() == that; 82 } 83 84 template <typename U> 85 bool operator!=(const U* that) const { 86 return !(*this == that); 87 } 88 89 explicit operator bool() const { return HasObservable(); } Get()90 T* Get() const { return m_pObservable; } 91 T& operator*() const { return *m_pObservable; } 92 T* operator->() const { return m_pObservable; } 93 94 private: 95 UNOWNED_PTR_EXCLUSION T* m_pObservable = nullptr; 96 }; 97 98 template <typename T, typename U> 99 inline bool operator==(const U* lhs, const ObservedPtr<T>& rhs) { 100 return rhs == lhs; 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 } // namespace fxcrt 109 110 using fxcrt::Observable; 111 using fxcrt::ObservedPtr; 112 113 #endif // CORE_FXCRT_OBSERVED_PTR_H_ 114