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

Quelle  WinOLELock.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 mozilla_widget_WinOLELock_h_
#define mozilla_widget_WinOLELock_h_

#include <type_traits>
#include <minwindef.h>
#include <winbase.h>
#include "mozilla/Assertions.h"

namespace details {
// implementation of `is_complete_type_v` borrowed from Raymond Chen:
//  https://devblogs.microsoft.com/oldnewthing/20190711-00/?p=102682
template <typename, typename = void>
constexpr bool is_complete_type_v = false;
template <typename T>
constexpr bool is_complete_type_v<T, std::void_t<decltype(sizeof(T))>> = true;

// The Windows SDK typically declares handle types to be of type "pointer to
// incomplete struct type"; this is broadly a good choice, but implies that we
// need to take additional steps to avoid declaring operator* or operator-> for
// smart pointers thereto.
template <typename T>
constexpr bool is_dereferenceable_v =
    std::is_pointer_v<T> && is_complete_type_v<std::remove_pointer_t<T>>;

template <typename T>
constexpr bool is_arrowable_v =
    std::is_pointer_v<T> && is_complete_type_v<std::remove_pointer_t<T>> &&
    std::is_class_v<std::remove_pointer_t<T>>;

// SFINAE mixins for ScopedOLELock, below.
template <typename Derived, typename T, bool = is_dereferenceable_v<T>,
          bool = is_arrowable_v<T>>
struct OLELockMixin {};

template <typename D, typename T>
struct OLELockMixin<D, T, true, false> {
  auto operator*() const -> std::remove_pointer_t<T>& {
    T ptr = static_cast<D const*>(this)->get();
    MOZ_ASSERT(ptr);
    return *ptr;
  }
};

template <typename D, typename T>
struct OLELockMixin<D, T, true, true> : OLELockMixin<D, T, true, false> {
  auto operator->() const -> T {
    T ptr = static_cast<D const*>(this)->get();
    MOZ_ASSERT(ptr);
    return ptr;
  }
};
}  // namespace details

// RAII scoped-handle object for ::GlobalLock()ed data -- which, in practice,
// means data associated with either the clipboard or with drag-and-drop.
//
// T must be of pointer, handle, or array type.
template <class T>
class ScopedOLELock;

// Handle/pointer implementation of ScopedHGLock.
template <class T>
class ScopedOLELock : public details::OLELockMixin<ScopedOLELock<T>, T> {
 public:
  explicit ScopedOLELock(HGLOBAL glob) : mGlobal(glob) {
    static_assert(std::is_pointer_v<T>);
    mData = static_cast<T>(::GlobalLock(mGlobal));
  }
  ~ScopedOLELock() { ::GlobalUnlock(mGlobal); }

  auto operator=(ScopedOLELock const&) = delete;
  ScopedOLELock(ScopedOLELock const&) = delete;

  explicit operator bool() const { return bool(mData); }

  auto get() const -> T { return mData; }

  // operator* and operator-> are also SFINAE'd in, when usable.
  // TODO(C++20): inline them here.

 private:
  HGLOBAL mGlobal;
  T mData;
};

template <class U>
class ScopedOLELock<U[]> {
 public:
  explicit ScopedOLELock(HGLOBAL glob) : mGlobal(glob) {
    static_assert(details::is_complete_type_v<U>);
    mData = static_cast<U*>(::GlobalLock(mGlobal));

    auto const [quot, rem] = std::lldiv(GlobalSize(mGlobal), sizeof(U));
    mExtent = quot;
    NS_WARNING_ASSERTION(
        rem == 0,
        "size of alleged array is not a multiple of the array element size");
  }
  ~ScopedOLELock() { ::GlobalUnlock(mGlobal); }

  auto operator=(ScopedOLELock const&) = delete;
  ScopedOLELock(ScopedOLELock const&) = delete;

  explicit operator bool() const { return bool(mData); }

  auto get() const -> U* { return mData; }

  // STL-style, for range-based iteration and so forth
  auto begin() const -> U* { return mData; }
  auto end() const -> U* { return mData + mExtent; }
  auto size() const -> size_t { return mExtent; }

  auto operator[](size_t index) const {
    MOZ_ASSERT(index < mExtent);
    return mData[index];
  }

 private:
  HGLOBAL mGlobal;
  U* mData;
  size_t mExtent;
};

// RAII scoped-handle object for _locally-created_ ::GlobalLock()ed data.
//
// T must be of POD type. A specialication for runtime-bounded array types is
// provided below.
template <typename T>
class ScopedOLEMemory {
  static_assert(alignof(T) <= 8,
                "GlobalAlloc only aligns to 8-byte boundaries");

  // This could be weakened if needed, but not eliminated: the destructor must
  // be trivial.
  static_assert(std::is_pod_v<T>, "type must be POD");

 public:
  explicit ScopedOLEMemory()
      : mHandle(::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(T))) {}
  ~ScopedOLEMemory() {
    // documented as `_Frees_ptr_opt_`, so we don't need to check for NULL
    ::GlobalFree(mHandle);
  }

  ScopedOLELock<T*> lock() const { return ScopedOLELock<T*>(mHandle); }

  explicit operator bool() const { return bool(mHandle); }

  HGLOBAL forget() {
    HGLOBAL r{mHandle};
    mHandle = nullptr;
    return r;
  }

 private:
  HGLOBAL mHandle;
};

template <typename U>
class ScopedOLEMemory<U[]> {
  static_assert(alignof(U) <= 8,
                "GlobalAlloc only aligns to 8-byte boundaries");
  // This could be weakened if needed, but not eliminated: the destructor must
  // be trivial.
  static_assert(std::is_pod_v<U>, "type must be POD");

 public:
  explicit ScopedOLEMemory(size_t n)
      : mHandle(::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(U) * n)),
        mExtent(n) {}
  ~ScopedOLEMemory() { ::GlobalFree(mHandle); }

  ScopedOLELock<U[]> lock() const { return ScopedOLELock<U[]>(mHandle); }

  explicit operator bool() const { return bool(mHandle); }

  HGLOBAL forget() {
    HGLOBAL r{mHandle};
    mHandle = nullptr;
    return r;
  }

 private:
  HGLOBAL mHandle;
  size_t mExtent;
};

#endif  // mozilla_widget_WinOLELock_h_

Messung V0.5 in Prozent
C=94 H=98 G=95

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet am  2026-09-28) ¤

*© 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.