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