Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/xpcom/base/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 6 kB image not shown  

Quelle  nsMaybeWeakPtr.h

  Sprache: C
 

/* 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 "mozilla/Try.h"
#include "mozilla/Variant.h"
#include "nsCOMPtr.h"
#include "nsIWeakReferenceUtils.h"
#include "nsTArray.h"
#include "nsCycleCollectionNoteChild.h"
#include "xpcpublic.h"

// nsMaybeWeakPtr is a helper object to hold a strong-or-weak reference
// to the template class.  It's pretty minimal, but sufficient.

template <class T>
class nsMaybeWeakPtr {
 public:
  nsMaybeWeakPtr() : mPtr(mozilla::VariantType<nsCOMPtr<T>>{}, nullptr) {}
  explicit nsMaybeWeakPtr(std::nullptr_t)
      : mPtr(mozilla::VariantType<nsCOMPtr<T>>{}, nullptr) {}
  explicit nsMaybeWeakPtr(T* aRef)
      : mPtr(mozilla::VariantType<nsCOMPtr<T>>{}, aRef) {}
  explicit nsMaybeWeakPtr(const nsWeakPtr& aRef)
      : mPtr(mozilla::VariantType<nsWeakPtr>{}, aRef) {
    MOZ_ASSERT(AsWeak(), "null nsWeakPtr pointer passed to nsMaybeWeakPtr");
  }

  bool IsStrong() const { return mPtr.template is<nsCOMPtr<T>>(); }

  bool IsWeak() const { return mPtr.template is<nsWeakPtr>(); }

  nsMaybeWeakPtr& operator=(std::nullptr_t) {
    mPtr.template emplace<nsCOMPtr<T>>(nullptr);
    return *this;
  }

  nsMaybeWeakPtr<T>& operator=(T* aRef) {
    mPtr.template emplace<nsCOMPtr<T>>(aRef);
    return *this;
  }

  nsMaybeWeakPtr<T>& operator=(const nsWeakPtr& aRef) {
    mPtr.template emplace<nsWeakPtr>(aRef);
    return *this;
  }

  bool operator==(const nsMaybeWeakPtr<T>& aOther) const {
    return mPtr == aOther.mPtr;
  }

  bool operator==(T* const& aStrong) const {
    return IsStrong() && AsStrong() == aStrong;
  }

  bool operator==(const nsWeakPtr& aWeak) const {
    return IsWeak() && AsWeak() == aWeak;
  }

  already_AddRefed<T> GetValue() const {
    return IsWeak() ? GetWeakReferent() : nsCOMPtr<T>{AsStrong()}.forget();
  }

  friend inline void ImplCycleCollectionTraverse(
      nsCycleCollectionTraversalCallback& aCallback,
      const nsMaybeWeakPtr& aField, const char* aName, uint32_t aFlags = 0) {
    if (aField.IsStrong()) {
      CycleCollectionNoteChild(aCallback, aField.AsStrong().get(), aName,
                               aFlags);
    }
  }

 protected:
  const nsCOMPtr<T>& AsStrong() const {
    return mPtr.template as<nsCOMPtr<T>>();
  }

  const nsWeakPtr& AsWeak() const { return mPtr.template as<nsWeakPtr>(); }

 private:
  already_AddRefed<T> GetWeakReferent() const {
    MOZ_ASSERT(AsWeak());
    nsresult rv;
    nsCOMPtr<T> ref = do_QueryReferent(AsWeak(), &rv);
    NS_WARNING_ASSERTION(NS_SUCCEEDED(rv) || rv == NS_ERROR_NULL_POINTER,
                         "QueryReferent failed with non-null pointer");
    return ref.forget();
  }

  mozilla::Variant<nsCOMPtr<T>, nsWeakPtr> mPtr;
};

// 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.

template <class T>
class nsMaybeWeakPtrArray : public CopyableTArray<nsMaybeWeakPtr<T>> {
  using MaybeWeakArray = nsTArray<nsMaybeWeakPtr<T>>;

  nsresult SetMaybeWeakPtr(nsMaybeWeakPtr<T>& aRef, T* aElement,
                           bool aOwnsWeak) {
    nsresult rv = NS_OK;

    if (aOwnsWeak) {
      aRef = do_GetWeakReference(aElement, &rv);
    } else {
      aRef = aElement;
    }

    return rv;
  }

 public:
  nsresult AppendWeakElement(T* aElement, bool aOwnsWeak) {
    nsMaybeWeakPtr<T> ref;
    MOZ_TRY(SetMaybeWeakPtr(ref, aElement, aOwnsWeak));

#if (defined(MOZ_DIAGNOSTIC_ASSERT_ENABLED) && !defined(MOZ_THUNDERBIRD))
    // Checking for duplicates is expensive, so we enforce callers to avoid
    // this with a diagnostic assertion. See bug 2000788 for Thunderbird.
    if (IsAssertOnDoubleAdd()) {
      if (MaybeWeakArray::Contains(aElement)) {
        xpc_DumpJSStack(true, true, false);
        MOZ_DIAGNOSTIC_ASSERT(false"Element already in array.");
      }
    }
#endif

    MaybeWeakArray::AppendElement(ref);
    return NS_OK;
  }

  nsresult AppendWeakElementUnlessExists(T* aElement, bool aOwnsWeak) {
    nsMaybeWeakPtr<T> ref;
    MOZ_TRY(SetMaybeWeakPtr(ref, aElement, aOwnsWeak));

    if (MaybeWeakArray::Contains(ref)) {
      return NS_ERROR_INVALID_ARG;
    }

    MaybeWeakArray::AppendElement(ref);
    return NS_OK;
  }

  nsresult RemoveWeakElement(T* aElement) {
    if (MaybeWeakArray::RemoveElement(aElement)) {
      return NS_OK;
    }

    // Don't use do_GetWeakReference; it should only be called if we know
    // the object supports weak references.
    nsCOMPtr<nsISupportsWeakReference> supWeakRef = do_QueryInterface(aElement);
    if (!supWeakRef) {
      return NS_ERROR_INVALID_ARG;
    }

    nsCOMPtr<nsIWeakReference> weakRef;
    nsresult rv = supWeakRef->GetWeakReference(getter_AddRefs(weakRef));
    NS_ENSURE_SUCCESS(rv, rv);

    if (MaybeWeakArray::RemoveElement(weakRef)) {
      return NS_OK;
    }

    return NS_ERROR_INVALID_ARG;
  }

  friend inline void ImplCycleCollectionUnlink(nsMaybeWeakPtrArray& aField) {
    aField.Clear();
  }

  friend inline void ImplCycleCollectionTraverse(
      nsCycleCollectionTraversalCallback& aCallback,
      nsMaybeWeakPtrArray& aField, const char* aName, uint32_t aFlags = 0) {
    aFlags |= CycleCollectionEdgeNameArrayFlag;
    for (auto& e : aField) {
      ImplCycleCollectionTraverse(aCallback, e, aName, aFlags);
    }
  }

 private:
#if (defined(MOZ_DIAGNOSTIC_ASSERT_ENABLED) && !defined(MOZ_THUNDERBIRD))
  // Until we have bug 2005466, a plain diagnostic assert would only yield us
  // unactionable crash reports from official Nightly builds in case JS was
  // adding an observer (which is common enough). But we want developers using
  // non-DEBUG builds to catch this locally and on CI when testing.
  static inline bool IsAssertOnDoubleAdd() {
#  if defined(DEBUG) || defined(FUZZING)
    return true;
#  else
    return xpc::IsInAutomation();
#  endif
  }
#endif
};

// 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<type>& e = (array).ElementAt(array_idx).GetValue();      \
    if (e) e->method;                                                       \
  }

#endif

Messung V0.5 in Prozent
C=96 H=96 G=95

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.