1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/places/nsMaybeWeakPtr.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,105 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef nsMaybeWeakPtr_h_ 1.10 +#define nsMaybeWeakPtr_h_ 1.11 + 1.12 +#include "nsCOMPtr.h" 1.13 +#include "nsWeakReference.h" 1.14 +#include "nsTArray.h" 1.15 +#include "nsCycleCollectionNoteChild.h" 1.16 + 1.17 +// nsMaybeWeakPtr is a helper object to hold a strong-or-weak reference 1.18 +// to the template class. It's pretty minimal, but sufficient. 1.19 + 1.20 +class nsMaybeWeakPtr_base 1.21 +{ 1.22 +protected: 1.23 + // Returns an addref'd pointer to the requested interface 1.24 + void* GetValueAs(const nsIID& iid) const; 1.25 + 1.26 + nsCOMPtr<nsISupports> mPtr; 1.27 +}; 1.28 + 1.29 +template<class T> 1.30 +class nsMaybeWeakPtr : private nsMaybeWeakPtr_base 1.31 +{ 1.32 +public: 1.33 + nsMaybeWeakPtr(nsISupports *ref) { mPtr = ref; } 1.34 + nsMaybeWeakPtr(const nsCOMPtr<nsIWeakReference> &ref) { mPtr = ref; } 1.35 + nsMaybeWeakPtr(const nsCOMPtr<T> &ref) { mPtr = ref; } 1.36 + 1.37 + bool operator==(const nsMaybeWeakPtr<T> &other) const { 1.38 + return mPtr == other.mPtr; 1.39 + } 1.40 + 1.41 + operator const nsCOMPtr<T>() const { return GetValue(); } 1.42 + 1.43 +protected: 1.44 + const nsCOMPtr<T> GetValue() const { 1.45 + return nsCOMPtr<T>(dont_AddRef(static_cast<T*> 1.46 + (GetValueAs(NS_GET_TEMPLATE_IID(T))))); 1.47 + } 1.48 +}; 1.49 + 1.50 +// nsMaybeWeakPtrArray is an array of MaybeWeakPtr objects, that knows how to 1.51 +// grab a weak reference to a given object if requested. It only allows a 1.52 +// given object to appear in the array once. 1.53 + 1.54 +typedef nsTArray< nsMaybeWeakPtr<nsISupports> > isupports_array_type; 1.55 +nsresult NS_AppendWeakElementBase(isupports_array_type *aArray, 1.56 + nsISupports *aElement, bool aWeak); 1.57 +nsresult NS_RemoveWeakElementBase(isupports_array_type *aArray, 1.58 + nsISupports *aElement); 1.59 + 1.60 +template<class T> 1.61 +class nsMaybeWeakPtrArray : public nsTArray< nsMaybeWeakPtr<T> > 1.62 +{ 1.63 +public: 1.64 + nsresult AppendWeakElement(T *aElement, bool aOwnsWeak) 1.65 + { 1.66 + return NS_AppendWeakElementBase( 1.67 + reinterpret_cast<isupports_array_type*>(this), aElement, aOwnsWeak); 1.68 + } 1.69 + 1.70 + nsresult RemoveWeakElement(T *aElement) 1.71 + { 1.72 + return NS_RemoveWeakElementBase( 1.73 + reinterpret_cast<isupports_array_type*>(this), aElement); 1.74 + } 1.75 +}; 1.76 + 1.77 +template <typename T> 1.78 +inline void 1.79 +ImplCycleCollectionUnlink(nsMaybeWeakPtrArray<T>& aField) 1.80 +{ 1.81 + aField.Clear(); 1.82 +} 1.83 + 1.84 +template <typename E> 1.85 +inline void 1.86 +ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, 1.87 + nsMaybeWeakPtrArray<E>& aField, 1.88 + const char* aName, 1.89 + uint32_t aFlags = 0) 1.90 +{ 1.91 + aFlags |= CycleCollectionEdgeNameArrayFlag; 1.92 + size_t length = aField.Length(); 1.93 + for (size_t i = 0; i < length; ++i) { 1.94 + CycleCollectionNoteChild(aCallback, aField[i].get(), aName, aFlags); 1.95 + } 1.96 +} 1.97 + 1.98 +// Call a method on each element in the array, but only if the element is 1.99 +// non-null. 1.100 + 1.101 +#define ENUMERATE_WEAKARRAY(array, type, method) \ 1.102 + for (uint32_t array_idx = 0; array_idx < array.Length(); ++array_idx) { \ 1.103 + const nsCOMPtr<type> &e = array.ElementAt(array_idx); \ 1.104 + if (e) \ 1.105 + e->method; \ 1.106 + } 1.107 + 1.108 +#endif