• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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