diff -r 000000000000 -r 6474c204b198 layout/generic/nsQueryFrame.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layout/generic/nsQueryFrame.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,96 @@ +/* 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 "nscore.h" +#include "mozilla/Assertions.h" +#include "mozilla/TypeTraits.h" + +// NOTE: the long lines in this file are intentional to make compiler error +// messages more readable. + +#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 \ + virtual void* QueryFrame(FrameIID id); + +#define NS_QUERYFRAME_HEAD(class) \ + void* class::QueryFrame(FrameIID id) { switch (id) { + +#define NS_QUERYFRAME_ENTRY(class) \ + case class::kFrameIID: { \ + static_assert(mozilla::IsSame::value, \ + #class " must declare itself as a queryframe target"); \ + return static_cast(this); \ + } + +#define NS_QUERYFRAME_ENTRY_CONDITIONAL(class, condition) \ + case class::kFrameIID: \ + if (condition) { \ + static_assert(mozilla::IsSame::value, \ + #class " must declare itself as a queryframe target"); \ + return static_cast(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, +#include "nsFrameIdList.h" +#undef FRAME_ID + + // The PresArena implementation uses this bit to distinguish objects + // allocated by size from objects allocated by type ID (that is, frames + // using AllocateByFrameID, and other objects using AllocateByObjectID). + // It should not collide with any frame ID (above) or Object ID (in + // nsPresArena.h). It is not 0x80000000 to avoid the question of + // whether enumeration constants are signed. + NON_FRAME_MARKER = 0x20000000 + }; + + virtual void* QueryFrame(FrameIID id) = 0; +}; + +class do_QueryFrame +{ +public: + do_QueryFrame(nsQueryFrame *s) : mRawPtr(s) { } + + template + operator Dest*() { + static_assert(mozilla::IsSame::value, + "Dest must declare itself as a queryframe target"); + if (!mRawPtr) + return nullptr; + + return reinterpret_cast(mRawPtr->QueryFrame(Dest::kFrameIID)); + } + +private: + nsQueryFrame *mRawPtr; +}; + +#endif // nsQueryFrame_h