src/Property.h

changeset 88
5def6ff8b466
child 108
6409ece8297c
equal deleted inserted replaced
87:8f65914e7046 88:5def6ff8b466
1 /*
2 Copyright 2012-2014 Santeri Piippo
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 2. Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 3. The name of the author may not be used to endorse or promote products
15 derived from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifndef BOTC_PROPERTY_H
30 #define BOTC_PROPERTY_H
31
32 // =============================================================================
33 //
34 // Identifier names
35 //
36 #define PROPERTY_SET_ACCESSOR(NAME) Set##NAME
37 #define PROPERTY_GET_ACCESSOR(NAME) Get##NAME
38 #define PROPERTY_IS_ACCESSOR(NAME) Is##NAME // for bool types
39 #define PROPERTY_MEMBER_NAME(NAME) m##NAME
40
41 // Names of operations
42 #define PROPERTY_APPEND_OPERATION(NAME) AppendTo##NAME
43 #define PROPERTY_PREPEND_OPERATION(NAME) PrependTo##NAME
44 #define PROPERTY_REPLACE_OPERATION(NAME) ReplaceIn##NAME
45 #define PROPERTY_INCREASE_OPERATION(NAME) Increase##NAME
46 #define PROPERTY_DECREASE_OPERATION(NAME) Decrease##NAME
47 #define PROPERTY_TOGGLE_OPERATION(NAME) Toggle##NAME
48 #define PROPERTY_PUSH_OPERATION(NAME) PushTo##NAME
49 #define PROPERTY_REMOVE_OPERATION(NAME) RemoveFrom##NAME
50 #define PROPERTY_CLEAR_OPERATION(NAME) Clear##NAME
51 #define PROPERTY_COUNT_OPERATION(NAME) Count##NAME
52
53 // Operation definitions
54 // These are the methods of the list type that are called in the operations.
55 #define PROPERTY_APPEND_METHOD_NAME Append // String::Append
56 #define PROPERTY_PREPEND_METHOD_NAME Prepend // String::Prepend
57 #define PROPERTY_REPLACE_METHOD_NAME Replace // String::Replace
58 #define PROPERTY_PUSH_METHOD_NAME Append // List<T>::Append
59 #define PROPERTY_REMOVE_METHOD_NAME Remove // List<T>::Remove
60 #define PROPERTY_CLEAR_METHOD_NAME Clear // List<T>::Clear
61
62 // =============================================================================
63 //
64 // Main PROPERTY macro
65 //
66 #define PROPERTY(ACCESS, TYPE, NAME, OPS, WRITETYPE) \
67 private: \
68 TYPE PROPERTY_MEMBER_NAME(NAME); \
69 \
70 public: \
71 inline TYPE const& PROPERTY_GET_READ_METHOD (NAME, OPS) const \
72 { \
73 return PROPERTY_MEMBER_NAME(NAME); \
74 } \
75 \
76 ACCESS: \
77 PROPERTY_MAKE_WRITE (TYPE, NAME, WRITETYPE) \
78 PROPERTY_DEFINE_OPERATIONS (TYPE, NAME, OPS)
79
80 // =============================================================================
81 //
82 // PROPERTY_GET_READ_METHOD
83 //
84 // This macro uses the OPS argument to construct the name of the actual
85 // macro which returns the name of the get accessor. This is so that the
86 // bool properties get is<NAME>() accessors while non-bools get get<NAME>()
87 //
88 #define PROPERTY_GET_READ_METHOD(NAME, OPS) \
89 PROPERTY_GET_READ_METHOD_##OPS (NAME)
90
91 #define PROPERTY_GET_READ_METHOD_BOOL_OPS(NAME) PROPERTY_IS_ACCESSOR (NAME)()
92 #define PROPERTY_GET_READ_METHOD_NO_OPS(NAME) PROPERTY_GET_ACCESSOR (NAME)()
93 #define PROPERTY_GET_READ_METHOD_STR_OPS(NAME) PROPERTY_GET_ACCESSOR (NAME)()
94 #define PROPERTY_GET_READ_METHOD_NUM_OPS(NAME) PROPERTY_GET_ACCESSOR (NAME)()
95 #define PROPERTY_GET_READ_METHOD_LIST_OPS(NAME) PROPERTY_GET_ACCESSOR (NAME)()
96
97 // =============================================================================
98 //
99 // PROPERTY_MAKE_WRITE
100 //
101 // This macro uses the WRITETYPE argument to construct the set accessor of the
102 // property. If WRITETYPE is STOCK_WRITE, an inline method is defined to just
103 // set the new value of the property. If WRITETYPE is CUSTOM_WRITE, the accessor
104 // is merely declared and is left for the user to define.
105 //
106 #define PROPERTY_MAKE_WRITE(TYPE, NAME, WRITETYPE) \
107 PROPERTY_MAKE_WRITE_##WRITETYPE (TYPE, NAME)
108
109 #define PROPERTY_MAKE_WRITE_STOCK_WRITE(TYPE, NAME) \
110 inline void PROPERTY_SET_ACCESSOR(NAME) (TYPE const& a) \
111 { \
112 PROPERTY_MEMBER_NAME(NAME) = a; \
113 }
114
115 #define PROPERTY_MAKE_WRITE_CUSTOM_WRITE(TYPE, NAME) \
116 void PROPERTY_SET_ACCESSOR(NAME) (TYPE const& NAME); \
117
118 // =============================================================================
119 //
120 // PROPERTY_DEFINE_OPERATIONS
121 //
122 // This macro may expand into methods defining additional operations for the
123 // method.
124
125 #define PROPERTY_DEFINE_OPERATIONS(TYPE, NAME, OPS) \
126 DEFINE_PROPERTY_##OPS (TYPE, NAME)
127
128 // =============================================================================
129 //
130 // DEFINE_PROPERTY_NO_OPS
131 //
132 // Obviously NO_OPS expands into no operations.
133 //
134 #define DEFINE_PROPERTY_NO_OPS(TYPE, NAME)
135
136 // =============================================================================
137 //
138 // DEFINE_PROPERTY_STR_OPS
139 //
140 #define DEFINE_PROPERTY_STR_OPS(TYPE, NAME) \
141 void PROPERTY_APPEND_OPERATION(NAME) (const TYPE& a) \
142 { \
143 TYPE tmp (PROPERTY_MEMBER_NAME(NAME)); \
144 tmp.PROPERTY_APPEND_METHOD_NAME (a); \
145 PROPERTY_SET_ACCESSOR(NAME) (tmp); \
146 } \
147 \
148 void PROPERTY_PREPEND_OPERATION(NAME) (const TYPE& a) \
149 { \
150 TYPE tmp (PROPERTY_MEMBER_NAME(NAME)); \
151 tmp.PROPERTY_PREPEND_METHOD_NAME (a); \
152 PROPERTY_SET_ACCESSOR(NAME) (tmp); \
153 } \
154 \
155 void PROPERTY_REPLACE_OPERATION(NAME) (const TYPE& a, const TYPE& b) \
156 { \
157 TYPE tmp (PROPERTY_MEMBER_NAME(NAME)); \
158 tmp.PROPERTY_REPLACE_METHOD_NAME (a, b); \
159 PROPERTY_SET_ACCESSOR(NAME) (tmp); \
160 }
161
162 // =============================================================================
163 //
164 // DEFINE_PROPERTY_NUM_OPS
165 //
166 #define DEFINE_PROPERTY_NUM_OPS(TYPE, NAME) \
167 inline void PROPERTY_INCREASE_OPERATION(NAME) (TYPE a = 1) \
168 { \
169 PROPERTY_SET_ACCESSOR(NAME) (PROPERTY_MEMBER_NAME(NAME) + a); \
170 } \
171 \
172 inline void PROPERTY_DECREASE_OPERATION(NAME) (TYPE a = 1) \
173 { \
174 PROPERTY_SET_ACCESSOR(NAME) (PROPERTY_MEMBER_NAME(NAME) - a); \
175 }
176
177 // =============================================================================
178 //
179 // DEFINE_PROPERTY_BOOL_OPS
180 //
181 #define DEFINE_PROPERTY_BOOL_OPS(TYPE, NAME) \
182 inline void PROPERTY_TOGGLE_OPERATION(NAME)() \
183 { \
184 PROPERTY_SET_ACCESSOR(NAME) (!PROPERTY_MEMBER_NAME(NAME)); \
185 }
186
187 // =============================================================================
188 //
189 // DEFINE_PROPERTY_LIST_OPS
190 //
191 #define DEFINE_PROPERTY_LIST_OPS(TYPE, NAME) \
192 void PROPERTY_PUSH_OPERATION(NAME) (const TYPE::ValueType& a) \
193 { \
194 PROPERTY_MEMBER_NAME(NAME).PROPERTY_PUSH_METHOD_NAME (a); \
195 } \
196 \
197 void PROPERTY_REMOVE_OPERATION(NAME) (const TYPE::ValueType& a) \
198 { \
199 PROPERTY_MEMBER_NAME(NAME).PROPERTY_REMOVE_METHOD_NAME (a); \
200 } \
201 \
202 inline void PROPERTY_CLEAR_OPERATION(NAME)() \
203 { \
204 PROPERTY_MEMBER_NAME(NAME).PROPERTY_CLEAR_METHOD_NAME(); \
205 } \
206 \
207 public: \
208 inline int PROPERTY_COUNT_OPERATION(NAME)() const \
209 { \
210 return PROPERTY_GET_ACCESSOR (NAME)().Size(); \
211 }
212
213 #endif // BOTC_PROPERTY_H

mercurial