Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/layout/generic/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 6 kB image not shown  

Quelle  nsQueryFrame.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 nsQueryFrame_h
#define nsQueryFrame_h

#include <type_traits>

#include "nscore.h"
#include "mozilla/Assertions.h"

namespace mozilla {
class ScrollContainerFrame;
}

#define NS_DECL_QUERYFRAME_TARGET(classname)      \
  static const nsQueryFrame::FrameIID kFrameIID = \
      nsQueryFrame::classname##_id;               \
  typedef classname Has_NS_DECL_QUERYFRAME_TARGET;

#define NS_DECL_QUERYFRAME void* QueryFrame(FrameIID id) const override;

#define NS_QUERYFRAME_HEAD(class)               \
  voidclass ::QueryFrame(FrameIID id) const { \
    switch (id) {
#define NS_QUERYFRAME_ENTRY(class)                                    \
  case class ::kFrameIID: {                                           \
    static_assert(                                                    \
        std::is_same_v<classclass ::Has_NS_DECL_QUERYFRAME_TARGET>, \
        #class " must declare itself as a queryframe target");        \
    return const_cast<class*>(static_cast<const class*>(this));       \
  }

#define NS_QUERYFRAME_ENTRY_CONDITIONAL(class, condition)               \
  case class ::kFrameIID:                                               \
    if (condition) {                                                    \
      static_assert(                                                    \
          std::is_same_v<classclass ::Has_NS_DECL_QUERYFRAME_TARGET>, \
          #class " must declare itself as a queryframe target");        \
      return const_cast<class*>(static_cast<const class*>(this));       \
    }                                                                   \
    break;

#define NS_QUERYFRAME_TAIL_INHERITING(class) \
  default:                                   \
    break;                                   \
    }                                        \
    return class ::QueryFrame(id);           \
    }

#define NS_QUERYFRAME_TAIL_INHERITANCE_ROOT                          \
  default:                                                           \
    break;                                                           \
    }                                                                \
    MOZ_ASSERT(id != GetFrameId(),                                   \
               "A frame failed to QueryFrame to its *own type*. "    \
               "It may be missing NS_DECL_QUERYFRAME, or a "         \
               "NS_QUERYFRAME_ENTRY() line with its own type name"); \
    return nullptr;                                                  \
    }

class nsQueryFrame {
 public:
  enum FrameIID {
#define FRAME_ID(classname, ...) classname##_id,
#define ABSTRACT_FRAME_ID(classname) classname##_id,
#include "mozilla/FrameIdList.h"
#undef FRAME_ID
#undef ABSTRACT_FRAME_ID
  };

  // A strict subset of FrameIID above for frame classes that we instantiate.
  enum class ClassID : uint8_t {
#define FRAME_ID(classname, ...) classname##_id,
#define ABSTRACT_FRAME_ID(classname)
#include "mozilla/FrameIdList.h"
#undef FRAME_ID
#undef ABSTRACT_FRAME_ID
  };

  virtual void* QueryFrame(FrameIID id) const = 0;
};

class nsIFrame;

namespace detail {
template <typename Dest, typename = void>
struct FastQueryFrame {
  static constexpr bool kSupported = false;
};

// For final classes we can check the class id.
template <typename Dest>
struct FastQueryFrame<Dest, std::enable_if_t<std::is_final_v<Dest>, void>> {
  static constexpr bool kSupported = true;

  template <typename Src>
  static Dest* QueryFrame(Src* aPtr) {
    return nsQueryFrame::FrameIID(aPtr->GetClassID()) == Dest::kFrameIID
               ? static_cast<Dest*>(aPtr)
               : nullptr;
  }
};

#define IMPL_FAST_QUERYFRAME(Dest_, Check_)                        \
  template <>                                                      \
  struct FastQueryFrame<Dest_, void> {                             \
    static constexpr bool kSupported = true;                       \
    template <typename Src>                                        \
    static Dest_* QueryFrame(Src* aPtr) {                          \
      return aPtr->Check_() ? static_cast<Dest_*>(aPtr) : nullptr; \
    }                                                              \
  }

IMPL_FAST_QUERYFRAME(mozilla::ScrollContainerFrame,
                     IsScrollContainerOrSubclass);

#undef IMPL_FAST_QUERYFRAME
}

template <typename Source>
class do_QueryFrameHelper {
 public:
  explicit do_QueryFrameHelper(Source* s) : mRawPtr(s) {}

  // The return and argument types here are arbitrarily selected so no
  // corresponding member function exists.
  using MatchNullptr = void (*)(doublefloat);
  // Implicit constructor for nullptr, trick borrowed from already_AddRefed.
  MOZ_IMPLICIT do_QueryFrameHelper(MatchNullptr aRawPtr) : mRawPtr(nullptr) {}

  template <typename Dest>
  operator Dest*() {
    static_assert(std::is_same_v<std::remove_const_t<Dest>,
                                 typename Dest::Has_NS_DECL_QUERYFRAME_TARGET>,
                  "Dest must declare itself as a queryframe target");
    if (!mRawPtr) {
      return nullptr;
    }
    if constexpr (::detail::FastQueryFrame<Dest>::kSupported) {
      static_assert(
          std::is_base_of_v<nsIFrame, Source>,
          "We only support fast do_QueryFrame() where the source must be a "
          "derived class of nsIFrame. Consider a two-step do_QueryFrame() "
          "(once to nsIFrame, another to the target) if absolutely needed.");
      Dest* f = ::detail::FastQueryFrame<Dest>::QueryFrame(mRawPtr);
      MOZ_ASSERT(
          f == reinterpret_cast<Dest*>(mRawPtr->QueryFrame(Dest::kFrameIID)),
          "fast and slow paths should give the same result");
      return f;
    }
    if constexpr (std::is_base_of_v<nsIFrame, Source> &&
                  std::is_base_of_v<nsIFrame, Dest>) {
      // For non-final frames we can still optimize the virtual call some of the
      // time.
      if (nsQueryFrame::FrameIID(mRawPtr->GetClassID()) == Dest::kFrameIID) {
        auto* f = static_cast<Dest*>(mRawPtr);
        MOZ_ASSERT(
            f == reinterpret_cast<Dest*>(mRawPtr->QueryFrame(Dest::kFrameIID)),
            "fast and slow paths should give the same result");
        return f;
      }
    }
    return reinterpret_cast<Dest*>(mRawPtr->QueryFrame(Dest::kFrameIID));
  }

 private:
  Source* mRawPtr;
};

template <typename T>
inline do_QueryFrameHelper<T> do_QueryFrame(T* s) {
  return do_QueryFrameHelper<T>(s);
}

#endif  // nsQueryFrame_h

Messung V0.5
C=73 H=96 G=85

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

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