diff -r 000000000000 -r 6474c204b198 toolkit/components/places/nsMaybeWeakPtr.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolkit/components/places/nsMaybeWeakPtr.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,105 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsMaybeWeakPtr_h_ +#define nsMaybeWeakPtr_h_ + +#include "nsCOMPtr.h" +#include "nsWeakReference.h" +#include "nsTArray.h" +#include "nsCycleCollectionNoteChild.h" + +// nsMaybeWeakPtr is a helper object to hold a strong-or-weak reference +// to the template class. It's pretty minimal, but sufficient. + +class nsMaybeWeakPtr_base +{ +protected: + // Returns an addref'd pointer to the requested interface + void* GetValueAs(const nsIID& iid) const; + + nsCOMPtr mPtr; +}; + +template +class nsMaybeWeakPtr : private nsMaybeWeakPtr_base +{ +public: + nsMaybeWeakPtr(nsISupports *ref) { mPtr = ref; } + nsMaybeWeakPtr(const nsCOMPtr &ref) { mPtr = ref; } + nsMaybeWeakPtr(const nsCOMPtr &ref) { mPtr = ref; } + + bool operator==(const nsMaybeWeakPtr &other) const { + return mPtr == other.mPtr; + } + + operator const nsCOMPtr() const { return GetValue(); } + +protected: + const nsCOMPtr GetValue() const { + return nsCOMPtr(dont_AddRef(static_cast + (GetValueAs(NS_GET_TEMPLATE_IID(T))))); + } +}; + +// nsMaybeWeakPtrArray is an array of MaybeWeakPtr objects, that knows how to +// grab a weak reference to a given object if requested. It only allows a +// given object to appear in the array once. + +typedef nsTArray< nsMaybeWeakPtr > isupports_array_type; +nsresult NS_AppendWeakElementBase(isupports_array_type *aArray, + nsISupports *aElement, bool aWeak); +nsresult NS_RemoveWeakElementBase(isupports_array_type *aArray, + nsISupports *aElement); + +template +class nsMaybeWeakPtrArray : public nsTArray< nsMaybeWeakPtr > +{ +public: + nsresult AppendWeakElement(T *aElement, bool aOwnsWeak) + { + return NS_AppendWeakElementBase( + reinterpret_cast(this), aElement, aOwnsWeak); + } + + nsresult RemoveWeakElement(T *aElement) + { + return NS_RemoveWeakElementBase( + reinterpret_cast(this), aElement); + } +}; + +template +inline void +ImplCycleCollectionUnlink(nsMaybeWeakPtrArray& aField) +{ + aField.Clear(); +} + +template +inline void +ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, + nsMaybeWeakPtrArray& aField, + const char* aName, + uint32_t aFlags = 0) +{ + aFlags |= CycleCollectionEdgeNameArrayFlag; + size_t length = aField.Length(); + for (size_t i = 0; i < length; ++i) { + CycleCollectionNoteChild(aCallback, aField[i].get(), aName, aFlags); + } +} + +// Call a method on each element in the array, but only if the element is +// non-null. + +#define ENUMERATE_WEAKARRAY(array, type, method) \ + for (uint32_t array_idx = 0; array_idx < array.Length(); ++array_idx) { \ + const nsCOMPtr &e = array.ElementAt(array_idx); \ + if (e) \ + e->method; \ + } + +#endif