Line data Source code
1 : /* This Source Code Form is subject to the terms of the Mozilla Public
2 : * License, v. 2.0. If a copy of the MPL was not distributed with this
3 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 :
5 : #ifndef nsQueryFrame_h
6 : #define nsQueryFrame_h
7 :
8 : #include "nscore.h"
9 : #include "mozilla/Assertions.h"
10 : #include "mozilla/TypeTraits.h"
11 :
12 : // NOTE: the long lines in this file are intentional to make compiler error
13 : // messages more readable.
14 :
15 : #define NS_DECL_QUERYFRAME_TARGET(classname) \
16 : static const nsQueryFrame::FrameIID kFrameIID = nsQueryFrame::classname##_id; \
17 : typedef classname Has_NS_DECL_QUERYFRAME_TARGET;
18 :
19 : #define NS_DECL_QUERYFRAME \
20 : void* QueryFrame(FrameIID id) override;
21 :
22 : #define NS_QUERYFRAME_HEAD(class) \
23 : void* class::QueryFrame(FrameIID id) { switch (id) {
24 :
25 : #define NS_QUERYFRAME_ENTRY(class) \
26 : case class::kFrameIID: { \
27 : static_assert(mozilla::IsSame<class, class::Has_NS_DECL_QUERYFRAME_TARGET>::value, \
28 : #class " must declare itself as a queryframe target"); \
29 : return static_cast<class*>(this); \
30 : }
31 :
32 : #define NS_QUERYFRAME_ENTRY_CONDITIONAL(class, condition) \
33 : case class::kFrameIID: \
34 : if (condition) { \
35 : static_assert(mozilla::IsSame<class, class::Has_NS_DECL_QUERYFRAME_TARGET>::value, \
36 : #class " must declare itself as a queryframe target"); \
37 : return static_cast<class*>(this); \
38 : } \
39 : break;
40 :
41 : #define NS_QUERYFRAME_TAIL_INHERITING(class) \
42 : default: break; \
43 : } \
44 : return class::QueryFrame(id); \
45 : }
46 :
47 : #define NS_QUERYFRAME_TAIL_INHERITANCE_ROOT \
48 : default: break; \
49 : } \
50 : MOZ_ASSERT(id != GetFrameId(), \
51 : "A frame failed to QueryFrame to its *own type*. " \
52 : "It may be missing NS_DECL_QUERYFRAME, or a " \
53 : "NS_QUERYFRAME_ENTRY() line with its own type name"); \
54 : return nullptr; \
55 : }
56 :
57 866 : class nsQueryFrame
58 : {
59 : public:
60 : enum FrameIID {
61 : #define FRAME_ID(classname, ...) classname##_id,
62 : #define ABSTRACT_FRAME_ID(classname) classname##_id,
63 : #include "nsFrameIdList.h"
64 : #undef FRAME_ID
65 : #undef ABSTRACT_FRAME_ID
66 :
67 : // This marker allows mozilla::ArenaObjectID to "extend" this enum
68 : // with additional sequential values for use in nsPresArena and
69 : // nsIPresShell::{Allocate,Free}ByObjectId
70 : NON_FRAME_MARKER
71 : };
72 :
73 : // A strict subset of FrameIID above for frame classes that we instantiate.
74 : enum class ClassID : uint8_t {
75 : #define FRAME_ID(classname, ...) classname##_id,
76 : #define ABSTRACT_FRAME_ID(classname)
77 : #include "nsFrameIdList.h"
78 : #undef FRAME_ID
79 : #undef ABSTRACT_FRAME_ID
80 : };
81 :
82 : virtual void* QueryFrame(FrameIID id) = 0;
83 : };
84 :
85 : class do_QueryFrame
86 : {
87 : public:
88 11569 : explicit do_QueryFrame(nsQueryFrame *s) : mRawPtr(s) { }
89 :
90 : // The return and argument types here are arbitrarily selected so no
91 : // corresponding member function exists.
92 : typedef void (do_QueryFrame::* MatchNullptr)(double, float);
93 : // Implicit constructor for nullptr, trick borrowed from already_AddRefed.
94 0 : MOZ_IMPLICIT do_QueryFrame(MatchNullptr aRawPtr) : mRawPtr(nullptr) {}
95 :
96 : template<class Dest>
97 11569 : operator Dest*() {
98 : static_assert(mozilla::IsSame<Dest, typename Dest::Has_NS_DECL_QUERYFRAME_TARGET>::value,
99 : "Dest must declare itself as a queryframe target");
100 11569 : if (!mRawPtr)
101 624 : return nullptr;
102 :
103 10945 : return reinterpret_cast<Dest*>(mRawPtr->QueryFrame(Dest::kFrameIID));
104 : }
105 :
106 : private:
107 : nsQueryFrame *mRawPtr;
108 : };
109 :
110 : #endif // nsQueryFrame_h
|