1 /* This file is part of Dilay
2  * Copyright © 2015-2018 Alexander Bau
3  * Use and redistribute under the terms of the GNU General Public License
4  */
5 #ifndef DILAY_MACRO
6 #define DILAY_MACRO
7 
8 #include <cassert>
9 #include <memory>
10 
11 // delegators
12 
13 #define SET_SELF this->impl->self = this;
14 
15 #define DELEGATE_COPY_CONSTRUCTOR(from) \
16   from::from (const from& a1)           \
17     : impl (new Impl (*a1.impl))        \
18   {                                     \
19   }
20 
21 #define DELEGATE_COPY_CONSTRUCTOR_SELF(from) \
22   from::from (const from& a1)                \
23     : impl (new Impl (*a1.impl))             \
24   {                                          \
25     SET_SELF                                 \
26   }
27 
28 #define DELEGATE_COPY_CONSTRUCTOR_BASE(from, base) \
29   from::from (const from& a1)                      \
30     : base (a1)                                    \
31     , impl (new Impl (*a1.impl))                   \
32   {                                                \
33     SET_SELF                                       \
34   }
35 
36 #define DELEGATE_MOVE_CONSTRUCTOR(from)      \
37   from::from (from&& a1)                     \
38     : impl (new Impl (std::move (*a1.impl))) \
39   {                                          \
40   }
41 
42 #define DELEGATE_MOVE_CONSTRUCTOR_SELF(from) \
43   from::from (from&& a1)                     \
44     : impl (new Impl (std::move (*a1.impl))) \
45   {                                          \
46     SET_SELF                                 \
47   }
48 
49 #define DELEGATE_MOVE_CONSTRUCTOR_BASE(from, base) \
50   from::from (from&& a1)                           \
51     : base (std::forward<base> (a1))               \
52     , impl (new Impl (std::move (*a1.impl)))       \
53   {                                                \
54     SET_SELF                                       \
55   }
56 
57 #define DELEGATE_ASSIGNMENT_OP(from)               \
58   const from& from::operator= (const from& source) \
59   {                                                \
60     this->impl->operator= (*source.impl);          \
61     return *this;                                  \
62   }
63 
64 #define DELEGATE_MOVE_ASSIGNMENT_OP(from)             \
65   const from& from::operator= (from&& source)         \
66   {                                                   \
67     this->impl->operator= (std::move (*source.impl)); \
68     return *this;                                     \
69   }
70 
71 #define DELEGATE_MOVE_ASSIGNMENT_OP_SELF(from)        \
72   const from& from::operator= (from&& source)         \
73   {                                                   \
74     this->impl->operator= (std::move (*source.impl)); \
75     SET_SELF                                          \
76     return *this;                                     \
77   }
78 
79 #define DELEGATE_DESTRUCTOR(from) \
80   from::~from () {}
81 
82 #define DELEGATE_BIG3_WITHOUT_CONSTRUCTOR(from) \
83   DELEGATE_DESTRUCTOR (from)                    \
84   DELEGATE_MOVE_CONSTRUCTOR (from)
85 
86 #define DELEGATE_BIG3_WITHOUT_CONSTRUCTOR_SELF(from) \
87   DELEGATE_DESTRUCTOR (from)                         \
88   DELEGATE_MOVE_CONSTRUCTOR_SELF (from)
89 
90 #define DELEGATE_BIG4_COPY_WITHOUT_CONSTRUCTOR(from) \
91   DELEGATE_BIG3_WITHOUT_CONSTRUCTOR (from)           \
92   DELEGATE_COPY_CONSTRUCTOR (from)
93 
94 #define DELEGATE_BIG4_COPY_WITHOUT_CONSTRUCTOR_SELF(from) \
95   DELEGATE_BIG3_WITHOUT_CONSTRUCTOR_SELF (from)           \
96   DELEGATE_COPY_CONSTRUCTOR_SELF (from)
97 
98 #define DELEGATE_BIG6_WITHOUT_CONSTRUCTOR(from) \
99   DELEGATE_BIG3_WITHOUT_CONSTRUCTOR (from)      \
100   DELEGATE_MOVE_ASSIGNMENT_OP (from)            \
101   DELEGATE_COPY_CONSTRUCTOR (from)              \
102   DELEGATE_ASSIGNMENT_OP (from)
103 
104 #define DELEGATE_BIG6_WITHOUT_CONSTRUCTOR_SELF(from) \
105   DELEGATE_BIG3_WITHOUT_CONSTRUCTOR_SELF (from)      \
106   DELEGATE_MOVE_ASSIGNMENT_OP_SELF (from)            \
107   DELEGATE_COPY_CONSTRUCTOR_SELF (from)              \
108   DELEGATE_ASSIGNMENT_OP (from)
109 
110 #define DELEGATE_CONSTRUCTOR(from) \
111   from::from ()                    \
112     : impl (new Impl ())           \
113   {                                \
114   }
115 
116 #define DELEGATE1_CONSTRUCTOR(from, t1)       \
117   from::from (t1 a1)                          \
118     : impl (new Impl (std::forward<t1> (a1))) \
119   {                                           \
120   }
121 
122 #define DELEGATE2_CONSTRUCTOR(from, t1, t2)                          \
123   from::from (t1 a1, t2 a2)                                          \
124     : impl (new Impl (std::forward<t1> (a1), std::forward<t2> (a2))) \
125   {                                                                  \
126   }
127 
128 #define DELEGATE3_CONSTRUCTOR(from, t1, t2, t3)                                             \
129   from::from (t1 a1, t2 a2, t3 a3)                                                          \
130     : impl (new Impl (std::forward<t1> (a1), std::forward<t2> (a2), std::forward<t3> (a3))) \
131   {                                                                                         \
132   }
133 
134 #define DELEGATE4_CONSTRUCTOR(from, t1, t2, t3, t4)                                        \
135   from::from (t1 a1, t2 a2, t3 a3, t4 a4)                                                  \
136     : impl (new Impl (std::forward<t1> (a1), std::forward<t2> (a2), std::forward<t3> (a3), \
137                       std::forward<t4> (a4)))                                              \
138   {                                                                                        \
139   }
140 
141 #define DELEGATE5_CONSTRUCTOR(from, t1, t2, t3, t4, t5)                                    \
142   from::from (t1 a1, t2 a2, t3 a3, t4 a4, t5 a5)                                           \
143     : impl (new Impl (std::forward<t1> (a1), std::forward<t2> (a2), std::forward<t3> (a3), \
144                       std::forward<t4> (a4), std::forward<t5> (a5)))                       \
145   {                                                                                        \
146   }
147 
148 #define DELEGATE_CONSTRUCTOR_SELF(from) \
149   from::from ()                         \
150     : impl (new Impl (this))            \
151   {                                     \
152   }
153 
154 #define DELEGATE1_CONSTRUCTOR_SELF(from, t1) \
155   from::from (t1 a1)                         \
156     : impl (new Impl (this, a1))             \
157   {                                          \
158   }
159 
160 #define DELEGATE2_CONSTRUCTOR_SELF(from, t1, t2) \
161   from::from (t1 a1, t2 a2)                      \
162     : impl (new Impl (this, a1, a2))             \
163   {                                              \
164   }
165 
166 #define DELEGATE3_CONSTRUCTOR_SELF(from, t1, t2, t3) \
167   from::from (t1 a1, t2 a2, t3 a3)                   \
168     : impl (new Impl (this, a1, a2, a3))             \
169   {                                                  \
170   }
171 
172 #define DELEGATE4_CONSTRUCTOR_SELF(from, t1, t2, t3, t4) \
173   from::from (t1 a1, t2 a2, t3 a3, t4 a4)                \
174     : impl (new Impl (this, a1, a2, a3, a4))             \
175   {                                                      \
176   }
177 
178 #define DELEGATE5_CONSTRUCTOR_SELF(from, t1, t2, t3, t4, t5) \
179   from::from (t1 a1, t2 a2, t3 a3, t4 a4, t5 a5)             \
180     : impl (new Impl (this, a1, a2, a3, a4, a5))             \
181   {                                                          \
182   }
183 
184 #define DELEGATE_CONSTRUCTOR_BASE(from, params, fromArgs, base, baseArgs) \
185   from::from params : base baseArgs, impl (new Impl fromArgs) {}
186 
187 #define DELEGATE_IMPL(r, from, method, ifaceParams, implArgs) \
188   r from::method ifaceParams { return this->impl->method implArgs; }
189 
190 #define DELEGATE(r, from, method) DELEGATE_IMPL (r, from, method, (), ())
191 
192 #define DELEGATE1(r, from, method, t1) \
193   DELEGATE_IMPL (r, from, method, (t1 a1), (std::forward<t1> (a1)))
194 
195 #define DELEGATE2(r, from, method, t1, t2) \
196   DELEGATE_IMPL (r, from, method, (t1 a1, t2 a2), (std::forward<t1> (a1), std::forward<t2> (a2)))
197 
198 #define DELEGATE3(r, from, method, t1, t2, t3)           \
199   DELEGATE_IMPL (r, from, method, (t1 a1, t2 a2, t3 a3), \
200                  (std::forward<t1> (a1), std::forward<t2> (a2), std::forward<t3> (a3)))
201 
202 #define DELEGATE4(r, from, method, t1, t2, t3, t4) \
203   DELEGATE_IMPL (                                  \
204     r, from, method, (t1 a1, t2 a2, t3 a3, t4 a4), \
205     (std::forward<t1> (a1), std::forward<t2> (a2), std::forward<t3> (a3), std::forward<t4> (a4)))
206 
207 #define DELEGATE5(r, from, method, t1, t2, t3, t4, t5)                                 \
208   DELEGATE_IMPL (r, from, method, (t1 a1, t2 a2, t3 a3, t4 a4, t5 a5),                 \
209                  (std::forward<t1> (a1), std::forward<t2> (a2), std::forward<t3> (a3), \
210                   std::forward<t4> (a4), std::forward<t5> (a5)))
211 
212 #define DELEGATE_CONST(r, from, method) DELEGATE_IMPL (r, from, method, () const, ())
213 
214 #define DELEGATE1_CONST(r, from, method, t1) \
215   DELEGATE_IMPL (r, from, method, (t1 a1) const, (std::forward<t1> (a1)))
216 
217 #define DELEGATE2_CONST(r, from, method, t1, t2)        \
218   DELEGATE_IMPL (r, from, method, (t1 a1, t2 a2) const, \
219                  (std::forward<t1> (a1), std::forward<t2> (a2)))
220 
221 #define DELEGATE3_CONST(r, from, method, t1, t2, t3)           \
222   DELEGATE_IMPL (r, from, method, (t1 a1, t2 a2, t3 a3) const, \
223                  (std::forward<t1> (a1), std::forward<t2> (a2), std::forward<t3> (a3)))
224 
225 #define DELEGATE4_CONST(r, from, method, t1, t2, t3, t4) \
226   DELEGATE_IMPL (                                        \
227     r, from, method, (t1 a1, t2 a2, t3 a3, t4 a4) const, \
228     (std::forward<t1> (a1), std::forward<t2> (a2), std::forward<t3> (a3), std::forward<t4> (a4)))
229 
230 #define DELEGATE5_CONST(r, from, method, t1, t2, t3, t4, t5)                           \
231   DELEGATE_IMPL (r, from, method, (t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) const,           \
232                  (std::forward<t1> (a1), std::forward<t2> (a2), std::forward<t3> (a3), \
233                   std::forward<t4> (a4), std::forward<t5> (a5)))
234 
235 #define DELEGATE_BASE_STATIC(r, from, method, ifaceParams, implArgs) \
236   r from::method ifaceParams { return Impl::method implArgs; }
237 
238 #define DELEGATE_STATIC(r, from, method) DELEGATE_BASE_STATIC (r, from, method, (), ())
239 
240 #define DELEGATE1_STATIC(r, from, method, t1) DELEGATE_BASE_STATIC (r, from, method, (t1 a1), (a1))
241 
242 #define DELEGATE2_STATIC(r, from, method, t1, t2) \
243   DELEGATE_BASE_STATIC (r, from, method, (t1 a1, t2 a2), (a1, a2))
244 
245 #define DELEGATE3_STATIC(r, from, method, t1, t2, t3) \
246   DELEGATE_BASE_STATIC (r, from, method, (t1 a1, t2 a2, t3 a3), (a1, a2, a3))
247 
248 #define DELEGATE4_STATIC(r, from, method, t1, t2, t3, t4) \
249   DELEGATE_BASE_STATIC (r, from, method, (t1 a1, t2 a2, t3 a3, t4 a4), (a1, a2, a3, a4))
250 
251 #define DELEGATE5_STATIC(r, from, method, t1, t2, t3, t4, t5) \
252   DELEGATE_BASE_STATIC (r, from, method, (t1 a1, t2 a2, t3 a3, t4 a4, t5 a5), (a1, a2, a3, a4, a5))
253 
254 #define DELEGATE_IMPL_MEMBER(r, from, method, member, ifaceParams, implArgs) \
255   r from::method ifaceParams { return this->impl->member.method implArgs; }
256 
257 #define DELEGATE_MEMBER(r, from, method, member) \
258   DELEGATE_IMPL_MEMBER (r, from, method, member, (), ())
259 
260 #define DELEGATE1_MEMBER(r, from, method, member, t1) \
261   DELEGATE_IMPL_MEMBER (r, from, method, member, (t1 a1), (std::forward<t1> (a1)))
262 
263 #define DELEGATE2_MEMBER(r, from, method, member, t1, t2)        \
264   DELEGATE_IMPL_MEMBER (r, from, method, member, (t1 a1, t2 a2), \
265                         (std::forward<t1> (a1), std::forward<t2> (a2)))
266 
267 #define DELEGATE3_MEMBER(r, from, method, member, t1, t2, t3)           \
268   DELEGATE_IMPL_MEMBER (r, from, method, member, (t1 a1, t2 a2, t3 a3), \
269                         (std::forward<t1> (a1), std::forward<t2> (a2), std::forward<t3> (a3)))
270 
271 #define DELEGATE4_MEMBER(r, from, method, member, t1, t2, t3, t4) \
272   DELEGATE_IMPL_MEMBER (                                          \
273     r, from, method, member, (t1 a1, t2 a2, t3 a3, t4 a4),        \
274     (std::forward<t1> (a1), std::forward<t2> (a2), std::forward<t3> (a3), std::forward<t4> (a4)))
275 
276 #define DELEGATE5_MEMBER(r, from, method, member, t1, t2, t3, t4, t5)                         \
277   DELEGATE_IMPL_MEMBER (r, from, method, member, (t1 a1, t2 a2, t3 a3, t4 a4, t5 a5),         \
278                         (std::forward<t1> (a1), std::forward<t2> (a2), std::forward<t3> (a3), \
279                          std::forward<t4> (a4), std::forward<t5> (a5)))
280 
281 #define DELEGATE_MEMBER_CONST(r, from, method, member) \
282   DELEGATE_IMPL_MEMBER (r, from, method, member, () const, ())
283 
284 #define DELEGATE1_MEMBER_CONST(r, from, method, member, t1) \
285   DELEGATE_IMPL_MEMBER (r, from, method, member, (t1 a1) const, (std::forward<t1> (a1)))
286 
287 #define DELEGATE2_MEMBER_CONST(r, from, method, member, t1, t2)        \
288   DELEGATE_IMPL_MEMBER (r, from, method, member, (t1 a1, t2 a2) const, \
289                         (std::forward<t1> (a1), std::forward<t2> (a2)))
290 
291 #define DELEGATE3_MEMBER_CONST(r, from, method, member, t1, t2, t3)           \
292   DELEGATE_IMPL_MEMBER (r, from, method, member, (t1 a1, t2 a2, t3 a3) const, \
293                         (std::forward<t1> (a1), std::forward<t2> (a2), std::forward<t3> (a3)))
294 
295 #define DELEGATE4_MEMBER_CONST(r, from, method, member, t1, t2, t3, t4) \
296   DELEGATE_IMPL_MEMBER (                                                \
297     r, from, method, member, (t1 a1, t2 a2, t3 a3, t4 a4) const,        \
298     (std::forward<t1> (a1), std::forward<t2> (a2), std::forward<t3> (a3), std::forward<t4> (a4)))
299 
300 #define DELEGATE5_MEMBER_CONST(r, from, method, member, t1, t2, t3, t4, t5)                   \
301   DELEGATE_IMPL_MEMBER (r, from, method, member, (t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) const,   \
302                         (std::forward<t1> (a1), std::forward<t2> (a2), std::forward<t3> (a3), \
303                          std::forward<t4> (a4), std::forward<t5> (a5)))
304 
305 // big 2 delegators
306 
307 #define DELEGATE_BIG2(from)   \
308   DELEGATE_CONSTRUCTOR (from) \
309   DELEGATE_DESTRUCTOR (from)
310 
311 #define DELEGATE1_BIG2(from, t1)   \
312   DELEGATE1_CONSTRUCTOR (from, t1) \
313   DELEGATE_DESTRUCTOR (from)
314 
315 #define DELEGATE2_BIG2(from, t1, t2)   \
316   DELEGATE2_CONSTRUCTOR (from, t1, t2) \
317   DELEGATE_DESTRUCTOR (from)
318 
319 #define DELEGATE3_BIG2(from, t1, t2, t3)   \
320   DELEGATE3_CONSTRUCTOR (from, t1, t2, t3) \
321   DELEGATE_DESTRUCTOR (from)
322 
323 #define DELEGATE4_BIG2(from, t1, t2, t3, t4)   \
324   DELEGATE4_CONSTRUCTOR (from, t1, t2, t3, t4) \
325   DELEGATE_DESTRUCTOR (from)
326 
327 #define DELEGATE5_BIG2(from, t1, t2, t3, t4, t5)   \
328   DELEGATE5_CONSTRUCTOR (from, t1, t2, t3, t4, t5) \
329   DELEGATE_DESTRUCTOR (from)
330 
331 #define DELEGATE_BIG2_SELF(from)   \
332   DELEGATE_CONSTRUCTOR_SELF (from) \
333   DELEGATE_DESTRUCTOR (from)
334 
335 #define DELEGATE1_BIG2_SELF(from, t1)   \
336   DELEGATE1_CONSTRUCTOR_SELF (from, t1) \
337   DELEGATE_DESTRUCTOR (from)
338 
339 #define DELEGATE2_BIG2_SELF(from, t1, t2)   \
340   DELEGATE2_CONSTRUCTOR_SELF (from, t1, t2) \
341   DELEGATE_DESTRUCTOR (from)
342 
343 #define DELEGATE3_BIG2_SELF(from, t1, t2, t3)   \
344   DELEGATE3_CONSTRUCTOR_SELF (from, t1, t2, t3) \
345   DELEGATE_DESTRUCTOR (from)
346 
347 #define DELEGATE4_BIG2_SELF(from, t1, t2, t3, t4)   \
348   DELEGATE4_CONSTRUCTOR_SELF (from, t1, t2, t3, t4) \
349   DELEGATE_DESTRUCTOR (from)
350 
351 #define DELEGATE5_BIG2_SELF(from, t1, t2, t3, t4, t5)   \
352   DELEGATE5_CONSTRUCTOR_SELF (from, t1, t2, t3, t4, t5) \
353   DELEGATE_DESTRUCTOR (from)
354 
355 #define DELEGATE_BIG2_BASE(from, params, fromArgs, base, baseArgs)   \
356   DELEGATE_CONSTRUCTOR_BASE (from, params, fromArgs, base, baseArgs) \
357   DELEGATE_DESTRUCTOR (from)
358 
359 // big 3 delegators
360 
361 #define DELEGATE_BIG3(from)   \
362   DELEGATE_CONSTRUCTOR (from) \
363   DELEGATE_BIG3_WITHOUT_CONSTRUCTOR (from)
364 
365 #define DELEGATE1_BIG3(from, t1)   \
366   DELEGATE1_CONSTRUCTOR (from, t1) \
367   DELEGATE_BIG3_WITHOUT_CONSTRUCTOR (from)
368 
369 #define DELEGATE2_BIG3(from, t1, t2)   \
370   DELEGATE2_CONSTRUCTOR (from, t1, t2) \
371   DELEGATE_BIG3_WITHOUT_CONSTRUCTOR (from)
372 
373 #define DELEGATE3_BIG3(from, t1, t2, t3)   \
374   DELEGATE3_CONSTRUCTOR (from, t1, t2, t3) \
375   DELEGATE_BIG3_WITHOUT_CONSTRUCTOR (from)
376 
377 #define DELEGATE4_BIG3(from, t1, t2, t3, t4)   \
378   DELEGATE4_CONSTRUCTOR (from, t1, t2, t3, t4) \
379   DELEGATE_BIG3_WITHOUT_CONSTRUCTOR (from)
380 
381 #define DELEGATE5_BIG3(from, t1, t2, t3, t4, t5)   \
382   DELEGATE5_CONSTRUCTOR (from, t1, t2, t3, t4, t5) \
383   DELEGATE_BIG3_WITHOUT_CONSTRUCTOR (from)
384 
385 #define DELEGATE_BIG3_SELF(from)   \
386   DELEGATE_CONSTRUCTOR_SELF (from) \
387   DELEGATE_BIG3_WITHOUT_CONSTRUCTOR_SELF (from)
388 
389 #define DELEGATE1_BIG3_SELF(from, t1)   \
390   DELEGATE1_CONSTRUCTOR_SELF (from, t1) \
391   DELEGATE_BIG3_WITHOUT_CONSTRUCTOR_SELF (from)
392 
393 #define DELEGATE2_BIG3_SELF(from, t1, t2)   \
394   DELEGATE2_CONSTRUCTOR_SELF (from, t1, t2) \
395   DELEGATE_BIG3_WITHOUT_CONSTRUCTOR_SELF (from)
396 
397 #define DELEGATE3_BIG3_SELF(from, t1, t2, t3)   \
398   DELEGATE3_CONSTRUCTOR_SELF (from, t1, t2, t3) \
399   DELEGATE_BIG3_WITHOUT_CONSTRUCTOR_SELF (from)
400 
401 #define DELEGATE4_BIG3_SELF(from, t1, t2, t3, t4)   \
402   DELEGATE4_CONSTRUCTOR_SELF (from, t1, t2, t3, t4) \
403   DELEGATE_BIG3_WITHOUT_CONSTRUCTOR_SELF (from)
404 
405 #define DELEGATE5_BIG3_SELF(from, t1, t2, t3, t4, t5)   \
406   DELEGATE5_CONSTRUCTOR_SELF (from, t1, t2, t3, t4, t5) \
407   DELEGATE_BIG3_WITHOUT_CONSTRUCTOR_SELF (from)
408 
409 #define DELEGATE_BIG3_BASE(from, params, fromArgs, base, baseArgs)   \
410   DELEGATE_CONSTRUCTOR_BASE (from, params, fromArgs, base, baseArgs) \
411   DELEGATE_DESTRUCTOR (from)                                         \
412   DELEGATE_MOVE_CONSTRUCTOR_BASE (from, base)
413 
414 // big 4 delegators
415 
416 #define DELEGATE_BIG4_COPY(from) \
417   DELEGATE_CONSTRUCTOR (from)    \
418   DELEGATE_BIG4_COPY_WITHOUT_CONSTRUCTOR (from)
419 
420 #define DELEGATE1_BIG4_COPY(from, t1) \
421   DELEGATE1_CONSTRUCTOR (from, t1)    \
422   DELEGATE_BIG4_COPY_WITHOUT_CONSTRUCTOR (from)
423 
424 #define DELEGATE2_BIG4_COPY(from, t1, t2) \
425   DELEGATE2_CONSTRUCTOR (from, t1, t2)    \
426   DELEGATE_BIG4_COPY_WITHOUT_CONSTRUCTOR (from)
427 
428 #define DELEGATE3_BIG4_COPY(from, t1, t2, t3) \
429   DELEGATE3_CONSTRUCTOR (from, t1, t2, t3)    \
430   DELEGATE_BIG4_COPY_WITHOUT_CONSTRUCTOR (from)
431 
432 #define DELEGATE4_BIG4_COPY(from, t1, t2, t3, t4) \
433   DELEGATE4_CONSTRUCTOR (from, t1, t2, t3, t4)    \
434   DELEGATE_BIG4_COPY_WITHOUT_CONSTRUCTOR (from)
435 
436 #define DELEGATE5_BIG4_COPY(from, t1, t2, t3, t4, t5) \
437   DELEGATE5_CONSTRUCTOR (from, t1, t2, t3, t4, t5)    \
438   DELEGATE_BIG4_COPY_WITHOUT_CONSTRUCTOR (from)
439 
440 #define DELEGATE_BIG4_COPY_SELF(from) \
441   DELEGATE_CONSTRUCTOR_SELF (from)    \
442   DELEGATE_BIG4_COPY_WITHOUT_CONSTRUCTOR_SELF (from)
443 
444 #define DELEGATE1_BIG4_COPY_SELF(from, t1) \
445   DELEGATE1_CONSTRUCTOR_SELF (from, t1)    \
446   DELEGATE_BIG4_COPY_WITHOUT_CONSTRUCTOR_SELF (from)
447 
448 #define DELEGATE2_BIG4_COPY_SELF(from, t1, t2) \
449   DELEGATE2_CONSTRUCTOR_SELF (from, t1, t2)    \
450   DELEGATE_BIG4_COPY_WITHOUT_CONSTRUCTOR_SELF (from)
451 
452 #define DELEGATE3_BIG4_COPY_SELF(from, t1, t2, t3) \
453   DELEGATE3_CONSTRUCTOR_SELF (from, t1, t2, t3)    \
454   DELEGATE_BIG4_COPY_WITHOUT_CONSTRUCTOR_SELF (from)
455 
456 #define DELEGATE4_BIG4_COPY_SELF(from, t1, t2, t3, t4) \
457   DELEGATE4_CONSTRUCTOR_SELF (from, t1, t2, t3, t4)    \
458   DELEGATE_BIG4_COPY_WITHOUT_CONSTRUCTOR_SELF (from)
459 
460 #define DELEGATE5_BIG4_COPY_SELF(from, t1, t2, t3, t4, t5) \
461   DELEGATE5_CONSTRUCTOR_SELF (from, t1, t2, t3, t4, t5)    \
462   DELEGATE_BIG4_COPY_WITHOUT_CONSTRUCTOR_SELF (from)
463 
464 #define DELEGATE_BIG4_COPY_BASE(from, params, fromArgs, base, baseArgs) \
465   DELEGATE_CONSTRUCTOR_BASE (from, params, fromArgs, base, baseArgs)    \
466   DELEGATE_DESTRUCTOR (from)                                            \
467   DELEGATE_MOVE_CONSTRUCTOR_BASE (from, base)                           \
468   DELEGATE_COPY_CONSTRUCTOR_BASE (from, base)
469 
470 // big 6 delegators
471 
472 #define DELEGATE_BIG6(from)   \
473   DELEGATE_CONSTRUCTOR (from) \
474   DELEGATE_BIG6_WITHOUT_CONSTRUCTOR (from)
475 
476 #define DELEGATE1_BIG6(from, t1)   \
477   DELEGATE1_CONSTRUCTOR (from, t1) \
478   DELEGATE_BIG6_WITHOUT_CONSTRUCTOR (from)
479 
480 #define DELEGATE2_BIG6(from, t1, t2)   \
481   DELEGATE2_CONSTRUCTOR (from, t1, t2) \
482   DELEGATE_BIG6_WITHOUT_CONSTRUCTOR (from)
483 
484 #define DELEGATE3_BIG6(from, t1, t2, t3)   \
485   DELEGATE3_CONSTRUCTOR (from, t1, t2, t3) \
486   DELEGATE_BIG6_WITHOUT_CONSTRUCTOR (from)
487 
488 #define DELEGATE4_BIG6(from, t1, t2, t3, t4)   \
489   DELEGATE4_CONSTRUCTOR (from, t1, t2, t3, t4) \
490   DELEGATE_BIG6_WITHOUT_CONSTRUCTOR (from)
491 
492 #define DELEGATE5_BIG6(from, t1, t2, t3, t4, t5)   \
493   DELEGATE5_CONSTRUCTOR (from, t1, t2, t3, t4, t5) \
494   DELEGATE_BIG6_WITHOUT_CONSTRUCTOR (from)
495 
496 #define DELEGATE_BIG6_SELF(from)   \
497   DELEGATE_CONSTRUCTOR_SELF (from) \
498   DELEGATE_BIG6_WITHOUT_CONSTRUCTOR_SELF (from)
499 
500 #define DELEGATE1_BIG6_SELF(from, t1)   \
501   DELEGATE1_CONSTRUCTOR_SELF (from, t1) \
502   DELEGATE_BIG6_WITHOUT_CONSTRUCTOR_SELF (from)
503 
504 #define DELEGATE2_BIG6_SELF(from, t1, t2)   \
505   DELEGATE2_CONSTRUCTOR_SELF (from, t1, t2) \
506   DELEGATE_BIG6_WITHOUT_CONSTRUCTOR_SELF (from)
507 
508 #define DELEGATE3_BIG6_SELF(from, t1, t2, t3)   \
509   DELEGATE3_CONSTRUCTOR_SELF (from, t1, t2, t3) \
510   DELEGATE_BIG6_WITHOUT_CONSTRUCTOR_SELF (from)
511 
512 #define DELEGATE4_BIG6_SELF(from, t1, t2, t3, t4)   \
513   DELEGATE4_CONSTRUCTOR_SELF (from, t1, t2, t3, t4) \
514   DELEGATE_BIG6_WITHOUT_CONSTRUCTOR_SELF (from)
515 
516 #define DELEGATE5_BIG6_SELF(from, t1, t2, t3, t4, t5)   \
517   DELEGATE5_CONSTRUCTOR_SELF (from, t1, t2, t3, t4, t5) \
518   DELEGATE_BIG6_WITHOUT_CONSTRUCTOR_SELF (from)
519 
520 #define DELEGATE_BIG6_BASE(from, params, fromArgs, base, baseArgs)   \
521   DELEGATE_CONSTRUCTOR_BASE (from, params, fromArgs, base, baseArgs) \
522   DELEGATE_DESTRUCTOR (from)                                         \
523   DELEGATE_COPY_CONSTRUCTOR_BASE (from, base)                        \
524   DELEGATE_MOVE_CONSTRUCTOR_BASE (from, base)                        \
525   DELEGATE_ASSIGNMENT_OP (from)                                      \
526   DELEGATE_MOVE_ASSIGNMENT_OP_SELF (from)
527 
528 // getters/setters
529 
530 #define GETTER_CONST(r, from, member) \
531   r from::member () const { return this->impl->member; }
532 
533 #define GETTER(r, from, member) \
534   r from::member () { return this->impl->member; }
535 
536 #define SETTER(t, from, member) \
537   void from::member (t a) { this->impl->member = a; }
538 
539 #define _MEMBER_GETTER_SETTER(type, name, pass_type)  \
540 public:                                               \
541   pass_type name () const { return this->_##name; }   \
542   void      name (pass_type v) { this->_##name = v; } \
543                                                       \
544 private:                                              \
545   type _##name;
546 
547 #define MEMBER_GETTER_SETTER(type, name) _MEMBER_GETTER_SETTER (type, name, type)
548 
549 #define MEMBER_REF_GETTER_SETTER(type, name) _MEMBER_GETTER_SETTER (type, name, const type&)
550 
551 #define _MEMBER_GETTER_EXPLICIT_SETTER(type, name, pass_type) \
552 public:                                                       \
553   pass_type name () const { return this->_##name; }           \
554   void      name (pass_type v);                               \
555                                                               \
556 private:                                                      \
557   type _##name;
558 
559 #define MEMBER_GETTER_EXPLICIT_SETTER(type, name) _MEMBER_GETTER_EXPLICIT_SETTER (type, name, type)
560 
561 #define MEMBER_REF_GETTER_EXPLICIT_SETTER(type, name) \
562   _MEMBER_GETTER_EXPLICIT_SETTER (type, name, const type&)
563 
564 #define _MEMBER_GETTER(type, name, pass_type)       \
565 public:                                             \
566   pass_type name () const { return this->_##name; } \
567                                                     \
568 private:                                            \
569   type _##name;
570 
571 #define MEMBER_GETTER(type, name) _MEMBER_GETTER (type, name, type)
572 
573 #define MEMBER_REF_GETTER(type, name) _MEMBER_GETTER (type, name, const type&)
574 
575 // safe references
576 
577 #define SAFE_REF(r, method)   \
578   r& method##Ref ()           \
579   {                           \
580     r* ptr = this->method (); \
581     assert (ptr);             \
582     return *ptr;              \
583   }
584 
585 #define SAFE_REF1(r, method, t1) \
586   r& method##Ref (t1 a1)         \
587   {                              \
588     r* ptr = this->method (a1);  \
589     assert (ptr);                \
590     return *ptr;                 \
591   }
592 
593 #define SAFE_REF2(r, method, t1, t2) \
594   r& method##Ref (t1 a1, t2 a2)      \
595   {                                  \
596     r* ptr = this->method (a1, a2);  \
597     assert (ptr);                    \
598     return *ptr;                     \
599   }
600 
601 #define SAFE_REF3(r, method, t1, t2, t3) \
602   r& method##Ref (t1 a1, t2 a2, t3 a3)   \
603   {                                      \
604     r* ptr = this->method (a1, a2, a3);  \
605     assert (ptr);                        \
606     return *ptr;                         \
607   }
608 
609 #define SAFE_REF4(r, method, t1, t2, t3, t4)  \
610   r& method##Ref (t1 a1, t2 a2, t3 a3, t4 a4) \
611   {                                           \
612     r* ptr = this->method (a1, a2, a3, a4);   \
613     assert (ptr);                             \
614     return *ptr;                              \
615   }
616 
617 #define SAFE_REF5(r, method, t1, t2, t3, t4, t5)     \
618   r& method##Ref (t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \
619   {                                                  \
620     r* ptr = this->method (a1, a2, a3, a4, a5);      \
621     assert (ptr);                                    \
622     return *ptr;                                     \
623   }
624 
625 #define SAFE_REF_CONST(r, method) \
626   r& method##Ref () const         \
627   {                               \
628     r* ptr = this->method ();     \
629     assert (ptr);                 \
630     return *ptr;                  \
631   }
632 
633 #define SAFE_REF1_CONST(r, method, t1) \
634   r& method##Ref (t1 a1) const         \
635   {                                    \
636     r* ptr = this->method (a1);        \
637     assert (ptr);                      \
638     return *ptr;                       \
639   }
640 
641 #define SAFE_REF2_CONST(r, method, t1, t2) \
642   r& method##Ref (t1 a1, t2 a2) const      \
643   {                                        \
644     r* ptr = this->method (a1, a2);        \
645     assert (ptr);                          \
646     return *ptr;                           \
647   }
648 
649 #define SAFE_REF3_CONST(r, method, t1, t2, t3) \
650   r& method##Ref (t1 a1, t2 a2, t3 a3) const   \
651   {                                            \
652     r* ptr = this->method (a1, a2, a3);        \
653     assert (ptr);                              \
654     return *ptr;                               \
655   }
656 
657 #define SAFE_REF4_CONST(r, method, t1, t2, t3, t4)  \
658   r& method##Ref (t1 a1, t2 a2, t3 a3, t4 a4) const \
659   {                                                 \
660     r* ptr = this->method (a1, a2, a3, a4);         \
661     assert (ptr);                                   \
662     return *ptr;                                    \
663   }
664 
665 #define SAFE_REF5_CONST(r, method, t1, t2, t3, t4, t5)     \
666   r& method##Ref (t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) const \
667   {                                                        \
668     r* ptr = this->method (a1, a2, a3, a4, a5);            \
669     assert (ptr);                                          \
670     return *ptr;                                           \
671   }
672 
673 // big 2 declarations
674 
675 #define DECLARE_BIG2(t, ...)              \
676   t (__VA_ARGS__);                        \
677   t (const t&) = delete;                  \
678   t (t&&) = delete;                       \
679   const t& operator= (const t&) = delete; \
680   const t& operator= (t&&) = delete;      \
681   ~t ();
682 
683 #define DECLARE_BIG2_VIRTUAL(t, ...)      \
684   t (__VA_ARGS__);                        \
685   t (const t&) = delete;                  \
686   t (t&&) = delete;                       \
687   const t& operator= (const t&) = delete; \
688   const t& operator= (t&&) = delete;      \
689   virtual ~t ();
690 
691 // big 3 declarations
692 
693 #define DECLARE_BIG3(t, ...)              \
694   t (__VA_ARGS__);                        \
695   t (const t&) = delete;                  \
696   t (t&&);                                \
697   const t& operator= (const t&) = delete; \
698   const t& operator= (t&&) = delete;      \
699   ~t ();
700 
701 #define DECLARE_BIG3_VIRTUAL(t, ...)      \
702   t (__VA_ARGS__);                        \
703   t (const t&) = delete;                  \
704   t (t&&);                                \
705   const t& operator= (const t&) = delete; \
706   const t& operator= (t&&) = delete;      \
707   virtual ~t ();
708 
709 // big 4 declarations
710 
711 #define DECLARE_BIG4_COPY(t, ...)         \
712   t (__VA_ARGS__);                        \
713   t (const t&);                           \
714   t (t&&);                                \
715   const t& operator= (const t&) = delete; \
716   const t& operator= (t&&) = delete;      \
717   ~t ();
718 
719 #define DECLARE_BIG4_COPY_VIRTUAL(t, ...) \
720   t (__VA_ARGS__);                        \
721   t (const t&);                           \
722   t (t&&);                                \
723   const t& operator= (const t&) = delete; \
724   const t& operator= (t&&) = delete;      \
725   virtual ~t ();
726 
727 #define DECLARE_BIG4_EXPLICIT_COPY(t, ...) \
728   t (__VA_ARGS__);                         \
729   explicit t (const t&);                   \
730   t (t&&);                                 \
731   const t& operator= (const t&) = delete;  \
732   const t& operator= (t&&) = delete;       \
733   ~t ();
734 
735 #define DECLARE_BIG4_EXPLICIT_COPY_VIRTUAL(t, ...) \
736   t (__VA_ARGS__);                                 \
737   explicit t (const t&);                           \
738   t (t&&);                                         \
739   const t& operator= (const t&) = delete;          \
740   const t& operator= (t&&) = delete;               \
741   virtual ~t ();
742 
743 // big 6 declarations
744 
745 #define DECLARE_BIG6(t, ...)     \
746   t (__VA_ARGS__);               \
747   t (const t&);                  \
748   t (t&&);                       \
749   const t& operator= (const t&); \
750   const t& operator= (t&&);      \
751   ~t ();
752 
753 #define DECLARE_BIG6_VIRTUAL(t, ...) \
754   t (__VA_ARGS__);                   \
755   t (const t&);                      \
756   t (t&&);                           \
757   const t& operator= (const t&);     \
758   const t& operator= (t&&);          \
759   virtual ~t ();
760 
761 // miscellaneous
762 
763 #define DELETE_COPYMOVEASSIGN(t)          \
764   t (const t&) = delete;                  \
765   t (t&&) = delete;                       \
766   const t& operator= (const t&) = delete; \
767   const t& operator= (t&&) = delete;
768 
769 #define DEFAULT_COPYMOVEASSIGN(t)          \
770   t (const t&) = default;                  \
771   t (t&&) = default;                       \
772   const t& operator= (const t&) = default; \
773   const t& operator= (t&&) = default;
774 
775 #define IMPLEMENTATION \
776   struct Impl;         \
777   std::unique_ptr<Impl> impl;
778 
779 #define ESC_PARENS(...) __VA_ARGS__
780 
781 #endif
782