nsHtml5StreamParserPtr.h (7063B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef nsHtml5StreamParserPtr_h 7 #define nsHtml5StreamParserPtr_h 8 9 #include "nsHtml5StreamParser.h" 10 #include "nsHtml5StreamParserReleaser.h" 11 #include "nsThreadUtils.h" 12 #include "mozilla/dom/DocGroup.h" 13 14 /** 15 * Like nsRefPtr except release is proxied to the main 16 * thread. Mostly copied from nsRefPtr. 17 */ 18 class nsHtml5StreamParserPtr { 19 private: 20 void assign_with_AddRef(nsHtml5StreamParser* rawPtr) { 21 if (rawPtr) rawPtr->AddRef(); 22 assign_assuming_AddRef(rawPtr); 23 } 24 void** begin_assignment() { 25 assign_assuming_AddRef(0); 26 return reinterpret_cast<void**>(&mRawPtr); 27 } 28 void assign_assuming_AddRef(nsHtml5StreamParser* newPtr) { 29 nsHtml5StreamParser* oldPtr = mRawPtr; 30 mRawPtr = newPtr; 31 if (oldPtr) release(oldPtr); 32 } 33 void release(nsHtml5StreamParser* aPtr) { 34 nsCOMPtr<nsIRunnable> releaser = new nsHtml5StreamParserReleaser(aPtr); 35 if (NS_FAILED(aPtr->DispatchToMain(releaser.forget()))) { 36 NS_WARNING("Failed to dispatch releaser event."); 37 } 38 } 39 40 private: 41 nsHtml5StreamParser* mRawPtr; 42 43 public: 44 ~nsHtml5StreamParserPtr() { 45 if (mRawPtr) release(mRawPtr); 46 } 47 // Constructors 48 nsHtml5StreamParserPtr() 49 : mRawPtr(0) 50 // default constructor 51 {} 52 nsHtml5StreamParserPtr(const nsHtml5StreamParserPtr& aSmartPtr) 53 : mRawPtr(aSmartPtr.mRawPtr) 54 // copy-constructor 55 { 56 if (mRawPtr) mRawPtr->AddRef(); 57 } 58 explicit nsHtml5StreamParserPtr(nsHtml5StreamParser* aRawPtr) 59 : mRawPtr(aRawPtr) 60 // construct from a raw pointer (of the right type) 61 { 62 if (mRawPtr) mRawPtr->AddRef(); 63 } 64 // Assignment operators 65 nsHtml5StreamParserPtr& operator=(const nsHtml5StreamParserPtr& rhs) 66 // copy assignment operator 67 { 68 assign_with_AddRef(rhs.mRawPtr); 69 return *this; 70 } 71 nsHtml5StreamParserPtr& operator=(nsHtml5StreamParser* rhs) 72 // assign from a raw pointer (of the right type) 73 { 74 assign_with_AddRef(rhs); 75 return *this; 76 } 77 // Other pointer operators 78 void swap(nsHtml5StreamParserPtr& rhs) 79 // ...exchange ownership with |rhs|; can save a pair of refcount operations 80 { 81 nsHtml5StreamParser* temp = rhs.mRawPtr; 82 rhs.mRawPtr = mRawPtr; 83 mRawPtr = temp; 84 } 85 void swap(nsHtml5StreamParser*& rhs) 86 // ...exchange ownership with |rhs|; can save a pair of refcount operations 87 { 88 nsHtml5StreamParser* temp = rhs; 89 rhs = mRawPtr; 90 mRawPtr = temp; 91 } 92 template <typename I> 93 void forget(I** rhs) 94 // Set the target of rhs to the value of mRawPtr and null out mRawPtr. 95 // Useful to avoid unnecessary AddRef/Release pairs with "out" 96 // parameters where rhs bay be a T** or an I** where I is a base class 97 // of T. 98 { 99 NS_ASSERTION(rhs, "Null pointer passed to forget!"); 100 *rhs = mRawPtr; 101 mRawPtr = 0; 102 } 103 nsHtml5StreamParser* get() const 104 /* 105 Prefer the implicit conversion provided automatically by |operator 106 nsHtml5StreamParser*() const|. Use |get()| to resolve ambiguity or to get a 107 castable pointer. 108 */ 109 { 110 return const_cast<nsHtml5StreamParser*>(mRawPtr); 111 } 112 operator nsHtml5StreamParser*() const 113 /* 114 ...makes an |nsHtml5StreamParserPtr| act like its underlying raw 115 pointer type whenever it is used in a context where a raw pointer is 116 expected. It is this operator that makes an |nsHtml5StreamParserPtr| 117 substitutable for a raw pointer. Prefer the implicit use of this operator 118 to calling |get()|, except where necessary to resolve ambiguity. 119 */ 120 { 121 return get(); 122 } 123 nsHtml5StreamParser* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN { 124 MOZ_ASSERT(mRawPtr != 0, 125 "You can't dereference a NULL nsHtml5StreamParserPtr with " 126 "operator->()."); 127 return get(); 128 } 129 nsHtml5StreamParserPtr* get_address() 130 // This is not intended to be used by clients. See |address_of| 131 // below. 132 { 133 return this; 134 } 135 const nsHtml5StreamParserPtr* get_address() const 136 // This is not intended to be used by clients. See |address_of| 137 // below. 138 { 139 return this; 140 } 141 142 public: 143 nsHtml5StreamParser& operator*() const { 144 MOZ_ASSERT(mRawPtr != 0, 145 "You can't dereference a NULL nsHtml5StreamParserPtr with " 146 "operator*()."); 147 return *get(); 148 } 149 nsHtml5StreamParser** StartAssignment() { 150 #ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT 151 return reinterpret_cast<nsHtml5StreamParser**>(begin_assignment()); 152 #else 153 assign_assuming_AddRef(0); 154 return reinterpret_cast<nsHtml5StreamParser**>(&mRawPtr); 155 #endif 156 } 157 }; 158 159 inline nsHtml5StreamParserPtr* address_of(nsHtml5StreamParserPtr& aPtr) { 160 return aPtr.get_address(); 161 } 162 163 inline const nsHtml5StreamParserPtr* address_of( 164 const nsHtml5StreamParserPtr& aPtr) { 165 return aPtr.get_address(); 166 } 167 168 class nsHtml5StreamParserPtrGetterAddRefs 169 /* 170 ... 171 This class is designed to be used for anonymous temporary objects in the 172 argument list of calls that return COM interface pointers, e.g., 173 nsHtml5StreamParserPtr<IFoo> fooP; 174 ...->GetAddRefedPointer(getter_AddRefs(fooP)) 175 DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_AddRefs()| 176 instead. When initialized with a |nsHtml5StreamParserPtr|, as in the example 177 above, it returns a |void**|, a |T**|, or an |nsISupports**| as needed, that 178 the outer call (|GetAddRefedPointer| in this case) can fill in. This type 179 should be a nested class inside |nsHtml5StreamParserPtr<T>|. 180 */ 181 { 182 public: 183 explicit nsHtml5StreamParserPtrGetterAddRefs( 184 nsHtml5StreamParserPtr& aSmartPtr) 185 : mTargetSmartPtr(aSmartPtr) { 186 // nothing else to do 187 } 188 operator void**() { 189 return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment()); 190 } 191 operator nsHtml5StreamParser**() { return mTargetSmartPtr.StartAssignment(); } 192 nsHtml5StreamParser*& operator*() { 193 return *(mTargetSmartPtr.StartAssignment()); 194 } 195 196 private: 197 nsHtml5StreamParserPtr& mTargetSmartPtr; 198 }; 199 200 inline nsHtml5StreamParserPtrGetterAddRefs getter_AddRefs( 201 nsHtml5StreamParserPtr& aSmartPtr) 202 /* 203 Used around a |nsHtml5StreamParserPtr| when 204 ...makes the class |nsHtml5StreamParserPtrGetterAddRefs| invisible. 205 */ 206 { 207 return nsHtml5StreamParserPtrGetterAddRefs(aSmartPtr); 208 } 209 210 // Comparing an |nsHtml5StreamParserPtr| to |0| 211 212 inline bool operator==(const nsHtml5StreamParserPtr& lhs, decltype(nullptr)) { 213 return lhs.get() == nullptr; 214 } 215 216 inline bool operator==(decltype(nullptr), const nsHtml5StreamParserPtr& rhs) { 217 return nullptr == rhs.get(); 218 } 219 220 inline bool operator!=(const nsHtml5StreamParserPtr& lhs, decltype(nullptr)) { 221 return lhs.get() != nullptr; 222 } 223 224 inline bool operator!=(decltype(nullptr), const nsHtml5StreamParserPtr& rhs) { 225 return nullptr != rhs.get(); 226 } 227 228 #endif // !defined(nsHtml5StreamParserPtr_h)