Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/ipc/glue/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 5 kB image not shown  

Quelle  SideVariant.h   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 mozilla_ipc_SidedVariant_h
#define mozilla_ipc_SidedVariant_h

#include <variant>
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "ipc/IPCMessageUtils.h"

namespace mozilla {
namespace ipc {

/**
 * Helper type used by IPDL structs and unions to hold actor pointers with a
 * dynamic side.
 *
 * When sent over IPC, ParentSide will be used for send/recv on parent actors,
 * and ChildSide will be used for send/recv on child actors.
 */

template <typename ParentSide, typename ChildSide>
struct SideVariant {
 public:
  SideVariant() = default;
  template <typename U,
            std::enable_if_t<std::is_convertible_v<U&&, ParentSide>, int> = 0>
  MOZ_IMPLICIT SideVariant(U&& aParent) : mParent(std::forward<U>(aParent)) {}
  template <typename U,
            std::enable_if_t<std::is_convertible_v<U&&, ChildSide>, int> = 0>
  MOZ_IMPLICIT SideVariant(U&& aChild) : mChild(std::forward<U>(aChild)) {}
  MOZ_IMPLICIT SideVariant(std::nullptr_t) {}

  MOZ_IMPLICIT SideVariant& operator=(ParentSide aParent) {
    mParent = aParent;
    mChild = nullptr;
    return *this;
  }
  MOZ_IMPLICIT SideVariant& operator=(ChildSide aChild) {
    mChild = aChild;
    mParent = nullptr;
    return *this;
  }
  MOZ_IMPLICIT SideVariant& operator=(std::nullptr_t) {
    mChild = nullptr;
    mParent = nullptr;
    return *this;
  }

  MOZ_IMPLICIT operator bool() const { return mParent || mChild; }

  bool IsNull() const { return !operator bool(); }
  bool IsParent() const { return mParent; }
  bool IsChild() const { return mChild; }

  ParentSide AsParent() const {
    MOZ_ASSERT(IsNull() || IsParent());
    return mParent;
  }
  ChildSide AsChild() const {
    MOZ_ASSERT(IsNull() || IsChild());
    return mChild;
  }

 private:
  // As the values are both pointers, this is the same size as a variant would
  // be, but has less risk of type confusion, and supports an overall `nullptr`
  // value which is neither parent nor child.
  ParentSide mParent = nullptr;
  ChildSide mChild = nullptr;
};

}  // namespace ipc

// NotNull specialization to expose AsChild and AsParent on the NotNull itself
// avoiding unnecessary unwrapping.
template <typename ParentSide, typename ChildSide>
class NotNull<mozilla::ipc::SideVariant<ParentSide, ChildSide>> {
  template <typename U>
  friend constexpr NotNull<U> WrapNotNull(U aBasePtr);
  template <typename U>
  friend constexpr NotNull<U> WrapNotNullUnchecked(U aBasePtr);
  template <typename U>
  friend class NotNull;

  using BasePtr = mozilla::ipc::SideVariant<ParentSide, ChildSide>;

  BasePtr mBasePtr;

  // This constructor is only used by WrapNotNull() and MakeNotNull<U>().
  template <typename U>
  constexpr explicit NotNull(U aBasePtr) : mBasePtr(aBasePtr) {}

 public:
  // Disallow default construction.
  NotNull() = delete;

  // Construct/assign from another NotNull with a compatible base pointer type.
  template <typename U, typename = std::enable_if_t<
                            std::is_convertible_v<const U&, BasePtr>>>
  constexpr MOZ_IMPLICIT NotNull(const NotNull<U>& aOther)
      : mBasePtr(aOther.get()) {
    static_assert(sizeof(BasePtr) == sizeof(NotNull<BasePtr>),
                  "NotNull must have zero space overhead.");
    static_assert(offsetof(NotNull<BasePtr>, mBasePtr) == 0,
                  "mBasePtr must have zero offset.");
  }

  template <typename U,
            typename = std::enable_if_t<std::is_convertible_v<U&&, BasePtr>>>
  constexpr MOZ_IMPLICIT NotNull(MovingNotNull<U>&& aOther)
      : mBasePtr(NotNull{std::move(aOther)}) {}

  // Disallow null checks, which are unnecessary for this type.
  explicit operator bool() const = delete;

  // Explicit conversion to a base pointer. Use only to resolve ambiguity or to
  // get a castable pointer.
  constexpr const BasePtr& get() const { return mBasePtr; }

  // Implicit conversion to a base pointer. Preferable to get().
  constexpr operator const BasePtr&() const { return get(); }

  bool IsParent() const { return get().IsParent(); }
  bool IsChild() const { return get().IsChild(); }

  NotNull<ParentSide> AsParent() const { return WrapNotNull(get().AsParent()); }
  NotNull<ChildSide> AsChild() const { return WrapNotNull(get().AsChild()); }
};

}  // namespace mozilla

namespace IPC {

template <typename ParentSide, typename ChildSide>
struct ParamTraits<mozilla::ipc::SideVariant<ParentSide, ChildSide>> {
  typedef mozilla::ipc::SideVariant<ParentSide, ChildSide> paramType;

  static void Write(IPC::MessageWriter* aWriter, const paramType& aParam) {
    if (!aWriter->GetActor()) {
      aWriter->FatalError("actor required to serialize this type");
      return;
    }

    if (aWriter->GetActor()->GetSide() == mozilla::ipc::ParentSide) {
      if (aParam && !aParam.IsParent()) {
        aWriter->FatalError("invalid side");
        return;
      }
      WriteParam(aWriter, aParam.AsParent());
    } else {
      if (aParam && !aParam.IsChild()) {
        aWriter->FatalError("invalid side");
        return;
      }
      WriteParam(aWriter, aParam.AsChild());
    }
  }

  static ReadResult<paramType> Read(IPC::MessageReader* aReader) {
    if (!aReader->GetActor()) {
      aReader->FatalError("actor required to deserialize this type");
      return {};
    }

    if (aReader->GetActor()->GetSide() == mozilla::ipc::ParentSide) {
      auto parentSide = ReadParam<ParentSide>(aReader);
      if (!parentSide) {
        return {};
      }
      return std::move(*parentSide);
    }
    auto childSide = ReadParam<ChildSide>(aReader);
    if (!childSide) {
      return {};
    }
    return std::move(*childSide);
  }
};

}  // namespace IPC

#endif  // mozilla_ipc_SidedVariant_h

Messung V0.5
C=97 H=95 G=95

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

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.