17 */ |
17 */ |
18 |
18 |
19 #ifndef LDFORGE_PROPERTY_H |
19 #ifndef LDFORGE_PROPERTY_H |
20 #define LDFORGE_PROPERTY_H |
20 #define LDFORGE_PROPERTY_H |
21 |
21 |
22 #define PROPERTY( ACCESS, TYPE, NAME, OPS, WRITETYPE ) \ |
22 // ============================================================================= |
23 private: \ |
23 // |
24 TYPE m_##NAME; \ |
24 // Identifier names |
25 \ |
25 // |
26 public: \ |
26 #define PROPERTY_SET_ACCESSOR(NAME) set##NAME |
27 inline TYPE const& GET_READ_METHOD( NAME, OPS ) const \ |
27 #define PROPERTY_GET_ACCESSOR(NAME) get##NAME |
28 { \ |
28 #define PROPERTY_IS_ACCESSOR(NAME) is##NAME // for bool types |
29 return m_##NAME; \ |
29 #define PROPERTY_MEMBER_NAME(NAME) m_##NAME |
30 } \ |
30 |
31 \ |
31 // Names of operations |
32 ACCESS: \ |
32 #define PROPERTY_APPEND_OPERATION(NAME) appendTo##NAME |
33 DEFINE_WRITE_METHOD_##WRITETYPE( TYPE, NAME ) \ |
33 #define PROPERTY_PREPEND_OPERATION(NAME) prependTo##NAME |
34 DEFINE_PROPERTY_##OPS( TYPE, NAME ) |
34 #define PROPERTY_REPLACE_OPERATION(NAME) replaceIn##NAME |
35 |
35 #define PROPERTY_INCREASE_OPERATION(NAME) increase##NAME |
36 #define GET_READ_METHOD( NAME, OPS ) \ |
36 #define PROPERTY_DECREASE_OPERATION(NAME) decrease##NAME |
37 GET_READ_METHOD_##OPS( NAME ) |
37 #define PROPERTY_TOGGLE_OPERATION(NAME) toggle##NAME |
38 |
38 #define PROPERTY_PUSH_OPERATION(NAME) pushTo##NAME |
39 #define GET_READ_METHOD_BOOL_OPS( NAME ) is##NAME() |
39 #define PROPERTY_REMOVE_OPERATION(NAME) removeFrom##NAME |
40 #define GET_READ_METHOD_NO_OPS( NAME ) get##NAME() |
40 #define PROPERTY_CLEAR_OPERATION(NAME) clear##NAME |
41 #define GET_READ_METHOD_STR_OPS( NAME ) get##NAME() |
41 #define PROPERTY_COUNT_OPERATION(NAME) count##NAME |
42 #define GET_READ_METHOD_NUM_OPS( NAME ) get##NAME() |
42 |
43 #define GET_READ_METHOD_LIST_OPS( NAME ) get##NAME() |
43 // Operation definitions |
44 |
44 // These are the methods of the list type that are called in the operations. |
45 #define DEFINE_WRITE_METHOD_STOCK_WRITE( TYPE, NAME ) \ |
45 #define PROPERTY_APPEND_METHOD_NAME append // QString::append |
46 inline void set##NAME( TYPE const& NAME##_ ) \ |
46 #define PROPERTY_PREPEND_METHOD_NAME prepend // QString::prepend |
47 { \ |
47 #define PROPERTY_REPLACE_METHOD_NAME replace // QString::replace |
48 m_##NAME = NAME##_; \ |
48 #define PROPERTY_PUSH_METHOD_NAME append // QList<T>::append |
49 } |
49 #define PROPERTY_REMOVE_METHOD_NAME removeOne // QList<T>::removeOne |
50 |
50 #define PROPERTY_CLEAR_METHOD_NAME clear // QList<T>::clear |
51 #define DEFINE_WRITE_METHOD_CUSTOM_WRITE( TYPE, NAME ) \ |
51 |
52 void set##NAME( TYPE const& NAME##_ ); \ |
52 // ============================================================================= |
53 |
53 // |
54 #define DEFINE_WITH_CB( NAME ) void NAME##Changed(); |
54 // Main PROPERTY macro |
55 #define DEFINE_NO_CB( NAME ) |
55 // |
56 |
56 #define PROPERTY(ACCESS, TYPE, NAME, OPS, WRITETYPE) \ |
57 #define DEFINE_PROPERTY_NO_OPS( TYPE, NAME ) |
57 private: \ |
58 |
58 TYPE PROPERTY_MEMBER_NAME(NAME); \ |
59 #define DEFINE_PROPERTY_STR_OPS( TYPE, NAME ) \ |
59 \ |
60 void appendTo##NAME( TYPE a ) \ |
60 public: \ |
61 { \ |
61 inline TYPE const& PROPERTY_GET_READ_METHOD (NAME, OPS) const \ |
62 TYPE tmp( m_##NAME ); \ |
62 { \ |
63 tmp.append( a ); \ |
63 return PROPERTY_MEMBER_NAME(NAME); \ |
64 set##NAME( tmp ); \ |
64 } \ |
65 } \ |
65 \ |
66 \ |
66 ACCESS: \ |
67 void prependTo##NAME( TYPE a ) \ |
67 PROPERTY_MAKE_WRITE (TYPE, NAME, WRITETYPE) \ |
68 { \ |
68 PROPERTY_DEFINE_OPERATIONS (TYPE, NAME, OPS) |
69 TYPE tmp( m_##NAME ); \ |
69 |
70 tmp.prepend( a ); \ |
70 // ============================================================================= |
71 set##NAME( tmp ); \ |
71 // |
72 } \ |
72 // PROPERTY_GET_READ_METHOD |
73 \ |
73 // |
74 void replaceIn##NAME( TYPE a, TYPE b ) \ |
74 // This macro uses the OPS argument to construct the name of the actual |
75 { \ |
75 // macro which returns the name of the get accessor. This is so that the |
76 TYPE tmp( m_##NAME ); \ |
76 // bool properties get is<NAME>() accessors while non-bools get get<NAME>() |
77 tmp.replace( a, b ); \ |
77 // |
78 set##NAME( tmp ); \ |
78 #define PROPERTY_GET_READ_METHOD(NAME, OPS) \ |
79 } |
79 PROPERTY_GET_READ_METHOD_##OPS (NAME) |
80 |
80 |
81 #define DEFINE_PROPERTY_NUM_OPS( TYPE, NAME ) \ |
81 #define PROPERTY_GET_READ_METHOD_BOOL_OPS(NAME) PROPERTY_IS_ACCESSOR (NAME)() |
82 inline void increase##NAME( TYPE a = 1 ) \ |
82 #define PROPERTY_GET_READ_METHOD_NO_OPS(NAME) PROPERTY_GET_ACCESSOR (NAME)() |
83 { \ |
83 #define PROPERTY_GET_READ_METHOD_STR_OPS(NAME) PROPERTY_GET_ACCESSOR (NAME)() |
84 set##NAME( m_##NAME + a ); \ |
84 #define PROPERTY_GET_READ_METHOD_NUM_OPS(NAME) PROPERTY_GET_ACCESSOR (NAME)() |
85 } \ |
85 #define PROPERTY_GET_READ_METHOD_LIST_OPS(NAME) PROPERTY_GET_ACCESSOR (NAME)() |
86 \ |
86 |
87 inline void decrease##NAME( TYPE a = 1 ) \ |
87 // ============================================================================= |
88 { \ |
88 // |
89 set##NAME( m_##NAME - a ); \ |
89 // PROPERTY_MAKE_WRITE |
90 } |
90 // |
91 |
91 // This macro uses the WRITETYPE argument to construct the set accessor of the |
92 #define DEFINE_PROPERTY_BOOL_OPS( TYPE, NAME ) \ |
92 // property. If WRITETYPE is STOCK_WRITE, an inline method is defined to just |
93 inline void toggle##NAME() \ |
93 // set the new value of the property. If WRITETYPE is CUSTOM_WRITE, the accessor |
94 { \ |
94 // is merely declared and is left for the user to define. |
95 set##NAME( !m_##NAME ); \ |
95 // |
96 } |
96 #define PROPERTY_MAKE_WRITE(TYPE, NAME, WRITETYPE) \ |
97 |
97 PROPERTY_MAKE_WRITE_##WRITETYPE (TYPE, NAME) |
98 #define DEFINE_PROPERTY_LIST_OPS( TYPE, NAME ) \ |
98 |
99 void pushTo##NAME( const TYPE::value_type& a ) \ |
99 #define PROPERTY_MAKE_WRITE_STOCK_WRITE(TYPE, NAME) \ |
100 { \ |
100 inline void set##NAME (TYPE const& new##NAME) \ |
101 TYPE tmp( m_##NAME ); \ |
101 { \ |
102 tmp.push_back( a ); \ |
102 PROPERTY_MEMBER_NAME(NAME) = new##NAME; \ |
103 set##NAME( tmp ); \ |
103 } |
104 } \ |
104 |
105 \ |
105 #define PROPERTY_MAKE_WRITE_CUSTOM_WRITE(TYPE, NAME) \ |
106 void removeFrom##NAME( const TYPE::value_type& a ) \ |
106 void set##NAME (TYPE const& new##NAME); \ |
107 { \ |
107 |
108 TYPE tmp( m_##NAME ); \ |
108 // ============================================================================= |
109 tmp.removeOne( a ); \ |
109 // |
110 set##NAME( tmp ); \ |
110 // PROPERTY_DEFINE_OPERATIONS |
111 } \ |
111 // |
112 \ |
112 // This macro may expand into methods defining additional operations for the |
113 inline void clear##NAME() \ |
113 // method. |
114 { \ |
114 |
115 set##NAME( TYPE() ); \ |
115 #define PROPERTY_DEFINE_OPERATIONS(TYPE, NAME, OPS) \ |
116 } \ |
116 DEFINE_PROPERTY_##OPS (TYPE, NAME) |
117 \ |
117 |
118 public: \ |
118 // ============================================================================= |
119 inline int count##NAME() \ |
119 // |
120 { \ |
120 // DEFINE_PROPERTY_NO_OPS |
121 return get##NAME().size(); \ |
121 // |
|
122 // Obviously NO_OPS expands into no operations. |
|
123 // |
|
124 #define DEFINE_PROPERTY_NO_OPS(TYPE, NAME) |
|
125 |
|
126 // ============================================================================= |
|
127 // |
|
128 // DEFINE_PROPERTY_STR_OPS |
|
129 // |
|
130 #define DEFINE_PROPERTY_STR_OPS(TYPE, NAME) \ |
|
131 void PROPERTY_APPEND_OPERATION(NAME) (const TYPE& a) \ |
|
132 { \ |
|
133 TYPE tmp (PROPERTY_MEMBER_NAME(NAME)); \ |
|
134 tmp.PROPERTY_APPEND_METHOD_NAME (a); \ |
|
135 set##NAME (tmp); \ |
|
136 } \ |
|
137 \ |
|
138 void PROPERTY_PREPEND_OPERATION(NAME) (const TYPE& a) \ |
|
139 { \ |
|
140 TYPE tmp (PROPERTY_MEMBER_NAME(NAME)); \ |
|
141 tmp.PROPERTY_PREPEND_METHOD_NAME (a); \ |
|
142 set##NAME (tmp); \ |
|
143 } \ |
|
144 \ |
|
145 void PROPERTY_REPLACE_OPERATION(NAME) (const TYPE& a, const TYPE& b) \ |
|
146 { \ |
|
147 TYPE tmp (PROPERTY_MEMBER_NAME(NAME)); \ |
|
148 tmp.PROPERTY_REPLACE_METHOD_NAME (a, b); \ |
|
149 set##NAME (tmp); \ |
|
150 } |
|
151 |
|
152 // ============================================================================= |
|
153 // |
|
154 // DEFINE_PROPERTY_NUM_OPS |
|
155 // |
|
156 #define DEFINE_PROPERTY_NUM_OPS(TYPE, NAME) \ |
|
157 inline void PROPERTY_INCREASE_OPERATION(NAME) (TYPE a = 1) \ |
|
158 { \ |
|
159 set##NAME (PROPERTY_MEMBER_NAME(NAME) + a); \ |
|
160 } \ |
|
161 \ |
|
162 inline void PROPERTY_DECREASE_OPERATION(NAME) (TYPE a = 1) \ |
|
163 { \ |
|
164 set##NAME (PROPERTY_MEMBER_NAME(NAME) - a); \ |
|
165 } |
|
166 |
|
167 // ============================================================================= |
|
168 // |
|
169 // DEFINE_PROPERTY_BOOL_OPS |
|
170 // |
|
171 #define DEFINE_PROPERTY_BOOL_OPS(TYPE, NAME) \ |
|
172 inline void PROPERTY_TOGGLE_OPERATION(NAME)() \ |
|
173 { \ |
|
174 set##NAME (!PROPERTY_MEMBER_NAME(NAME)); \ |
|
175 } |
|
176 |
|
177 // ============================================================================= |
|
178 // |
|
179 // DEFINE_PROPERTY_LIST_OPS |
|
180 // |
|
181 #define DEFINE_PROPERTY_LIST_OPS(TYPE, NAME) \ |
|
182 void PROPERTY_PUSH_OPERATION(NAME) (const TYPE::value_type& a) \ |
|
183 { \ |
|
184 PROPERTY_MEMBER_NAME(NAME).PROPERTY_PUSH_METHOD_NAME (a); \ |
|
185 } \ |
|
186 \ |
|
187 void PROPERTY_REMOVE_OPERATION(NAME) (const TYPE::value_type& a) \ |
|
188 { \ |
|
189 PROPERTY_MEMBER_NAME(NAME).PROPERTY_REMOVE_METHOD_NAME (a); \ |
|
190 } \ |
|
191 \ |
|
192 inline void PROPERTY_CLEAR_OPERATION(NAME)() \ |
|
193 { \ |
|
194 PROPERTY_MEMBER_NAME(NAME).PROPERTY_CLEAR_METHOD_NAME(); \ |
|
195 } \ |
|
196 \ |
|
197 public: \ |
|
198 inline int PROPERTY_COUNT_OPERATION(NAME)() const \ |
|
199 { \ |
|
200 return PROPERTY_GET_ACCESSOR (NAME)().size(); \ |
122 } |
201 } |
123 |
202 |
124 #endif // LDFORGE_PROPERTY_H |
203 #endif // LDFORGE_PROPERTY_H |