1 /*
2  *  Copyright (c) 2016, Facebook, Inc.
3  *  All rights reserved.
4  *
5  *  This source code is licensed under the BSD-style license found in the
6  *  LICENSE file in the root directory of this source tree. An additional grant
7  *  of patent rights can be found in the PATENTS file in the same directory.
8  */
9 
10 #ifndef FATAL_INCLUDE_fatal_preprocessor_h
11 #define FATAL_INCLUDE_fatal_preprocessor_h
12 
13 #include <fatal/portability.h>
14 
15 namespace fatal {
16 
17 /////////////////
18 // source_info //
19 /////////////////
20 
21 #define FATAL_SOURCE_INFO() \
22   ::fatal::source_info(__FILE__, __LINE__)
23 
24 struct source_info {
25 
26 FATAL_DIAGNOSTIC_PUSH
27 FATAL_GCC_DIAGNOSTIC_IGNORED_SHADOW_IF_BROKEN
28 
source_infosource_info29   source_info(char const *file, unsigned long line):
30     file_(basename(file)),
31     line_(line)
32   {}
33 
34 FATAL_DIAGNOSTIC_POP
35 
filesource_info36   char const *file() const { return file_; }
linesource_info37   unsigned long line() const { return line_; }
38 
basenamesource_info39   static char const *basename(char const *path) {
40     for (auto i = path; *i; ++i) {
41       if (*i == '/') {
42         path = i + 1;
43       }
44     }
45     return path;
46   }
47 
48   template <typename Out>
printsource_info49   Out &print(Out &out) const {
50     out << file_ << ':' << line_;
51     return out;
52   }
53 
54 private:
55   char const *const file_;
56   unsigned long const line_;
57 };
58 
59 template <typename Out>
60 Out &operator <<(Out &out, source_info source) {
61   return source.print(out);
62 }
63 
64 /////////////////
65 // FATAL_EMPTY //
66 /////////////////
67 
68 /**
69  * TODO: DOCUMENT
70  *
71  * @author: Marcelo Juchem <marcelo@fb.com>
72  */
73 #define FATAL_EMPTY()
74 
75 //////////////////
76 // FATAL_IGNORE //
77 //////////////////
78 
79 /**
80  * TODO: DOCUMENT
81  *
82  * @author: Marcelo Juchem <marcelo@fb.com>
83  */
84 #define FATAL_IGNORE(...)
85 
86 ////////////////////
87 // FATAL_IDENTITY //
88 ////////////////////
89 
90 /**
91  * TODO: DOCUMENT
92  *
93  * @author: Marcelo Juchem <marcelo@fb.com>
94  */
95 #define FATAL_IDENTITY(...) \
96   __VA_ARGS__
97 
98 /////////////////
99 // FATAL_COMMA //
100 /////////////////
101 
102 /**
103  * TODO: DOCUMENT
104  *
105  * @author: Marcelo Juchem <marcelo@fb.com>
106  */
107 #define FATAL_COMMA(...) \
108   ,
109 
110 /////////////////////
111 // FATAL_SEMICOLON //
112 /////////////////////
113 
114 /**
115  * TODO: DOCUMENT
116  *
117  * @author: Marcelo Juchem <marcelo@fb.com>
118  */
119 #define FATAL_SEMICOLON(...) \
120   ;
121 
122 ///////////////
123 // FATAL_CAT //
124 ///////////////
125 
126 /**
127  * TODO: DOCUMENT
128  *
129  * @author: Marcelo Juchem <marcelo@fb.com>
130  */
131 #define FATAL_CAT(LHS, ...) \
132   FATAL_IMPL_CAT(LHS, __VA_ARGS__)
133 
134 #define FATAL_IMPL_CAT(LHS, ...) \
135   LHS ## __VA_ARGS__
136 
137 ///////////////
138 // FATAL_NOT //
139 ///////////////
140 
141 /**
142  * TODO: DOCUMENT
143  *
144  * @author: Marcelo Juchem <marcelo@fb.com>
145  */
146 #define FATAL_NOT(...) \
147   FATAL_IMPL_NOT(FATAL_CAT(FATAL_IMPL_NOT_SWITCH_, __VA_ARGS__)())
148 
149 #define FATAL_IMPL_NOT(...) \
150   FATAL_ARG_2(__VA_ARGS__, 0)
151 
152 #define FATAL_IMPL_NOT_SWITCH_() \
153   FATAL_IMPL_NOT_WHEN_FALSE()
154 
155 #define FATAL_IMPL_NOT_SWITCH_0(...) \
156   FATAL_IMPL_NOT_WHEN_FALSE()
157 
158 #define FATAL_IMPL_NOT_WHEN_FALSE() \
159   ~, 1
160 
161 ////////////////
162 // FATAL_BOOL //
163 ////////////////
164 
165 /**
166  * TODO: DOCUMENT
167  *
168  * @author: Marcelo Juchem <marcelo@fb.com>
169  */
170 #define FATAL_BOOL(...) \
171   FATAL_NOT(FATAL_NOT(__VA_ARGS__))
172 
173 ////////////////////////////
174 // FATAL_IS_PARENTHESIZED //
175 ////////////////////////////
176 
177 /**
178  * TODO: DOCUMENT
179  *
180  * @author: Marcelo Juchem <marcelo@fb.com>
181  */
182 #define FATAL_IS_PARENTHESIZED(...) \
183   FATAL_IMPL_IS_PARENTHESIZED(FATAL_IMPL_IS_PARENTHESIZED_WHEN_TRUE __VA_ARGS__)
184 
185 #define FATAL_IMPL_IS_PARENTHESIZED(...) \
186   FATAL_NOT(FATAL_ARG_1(__VA_ARGS__))
187 
188 #define FATAL_IMPL_IS_PARENTHESIZED_WHEN_TRUE(...) \
189   0
190 
191 //////////////////////////
192 // FATAL_UNPARENTHESIZE //
193 //////////////////////////
194 
195 /**
196  * TODO: DOCUMENT
197  *
198  * @author: Marcelo Juchem <marcelo@fb.com>
199  */
200 #define FATAL_UNPARENTHESIZE(...) \
201   FATAL_CONDITIONAL_INTERNAL_UNPARENTHESIZE( \
202     FATAL_IS_PARENTHESIZED(__VA_ARGS__) \
203   )( \
204     FATAL_IDENTITY __VA_ARGS__ \
205   )(__VA_ARGS__)
206 
207 ////////////////
208 // FATAL_CALL //
209 ////////////////
210 
211 /**
212  * TODO: DOCUMENT AND TEST
213  *
214  * @author: Marcelo Juchem <marcelo@fb.com>
215  */
216 #define FATAL_CALL(Fn, ...) \
217   FATAL_IDENTITY(Fn)(__VA_ARGS__)
218 
219 ///////////////////////
220 // FATAL_TUPLE_APPLY //
221 ///////////////////////
222 
223 /**
224  * TODO: DOCUMENT AND TEST
225  *
226  * @author: Marcelo Juchem <marcelo@fb.com>
227  */
228 #define FATAL_TUPLE_APPLY(Fn, Arg, ...) \
229   FATAL_IMPL_TUPLE_APPLY(Fn, Arg, FATAL_UNPARENTHESIZE(__VA_ARGS__))
230 
231 #define FATAL_IMPL_TUPLE_APPLY(Fn, ...) \
232   Fn(__VA_ARGS__)
233 
234 ///////////////////////
235 // FATAL_TUPLE_GET_1 //
236 ///////////////////////
237 
238 /**
239  * TODO: DOCUMENT AND TEST
240  *
241  * @author: Marcelo Juchem <marcelo@fb.com>
242  */
243 #define FATAL_TUPLE_GET_1(...) \
244   FATAL_IMPL_TUPLE_GET(FATAL_ARG_1, FATAL_UNPARENTHESIZE(__VA_ARGS__))
245 
246 #define FATAL_TUPLE_GET_2(...) \
247   FATAL_IMPL_TUPLE_GET(FATAL_ARG_2, FATAL_UNPARENTHESIZE(__VA_ARGS__))
248 
249 #define FATAL_TUPLE_GET_3(...) \
250   FATAL_IMPL_TUPLE_GET(FATAL_ARG_3, FATAL_UNPARENTHESIZE(__VA_ARGS__))
251 
252 #define FATAL_TUPLE_GET_4(...) \
253   FATAL_IMPL_TUPLE_GET(FATAL_ARG_4, FATAL_UNPARENTHESIZE(__VA_ARGS__))
254 
255 #define FATAL_TUPLE_GET_5(...) \
256   FATAL_IMPL_TUPLE_GET(FATAL_ARG_5, FATAL_UNPARENTHESIZE(__VA_ARGS__))
257 
258 #define FATAL_TUPLE_GET_6(...) \
259   FATAL_IMPL_TUPLE_GET(FATAL_ARG_6, FATAL_UNPARENTHESIZE(__VA_ARGS__))
260 
261 #define FATAL_TUPLE_GET_7(...) \
262   FATAL_IMPL_TUPLE_GET(FATAL_ARG_7, FATAL_UNPARENTHESIZE(__VA_ARGS__))
263 
264 #define FATAL_TUPLE_GET_8(...) \
265   FATAL_IMPL_TUPLE_GET(FATAL_ARG_8, FATAL_UNPARENTHESIZE(__VA_ARGS__))
266 
267 #define FATAL_TUPLE_GET_9(...) \
268   FATAL_IMPL_TUPLE_GET(FATAL_ARG_9, FATAL_UNPARENTHESIZE(__VA_ARGS__))
269 
270 #define FATAL_IMPL_TUPLE_GET(Fn, ...) \
271   Fn(__VA_ARGS__)
272 
273 /////////////////
274 // FATAL_ARG_n //
275 /////////////////
276 
277 /**
278  * TODO: DOCUMENT
279  *
280  * @author: Marcelo Juchem <marcelo@fb.com>
281  */
282 #define FATAL_ARG_1(x1, ...) x1
283 
284 #define FATAL_ARG_2(x1, x2, ...) x2
285 
286 #define FATAL_ARG_3(x1, x2, x3, ...) x3
287 
288 #define FATAL_ARG_4(x1, x2, x3, x4, ...) x4
289 
290 #define FATAL_ARG_5(x1, x2, x3, x4, x5, ...) x5
291 
292 #define FATAL_ARG_6(x1, x2, x3, x4, x5, x6, ...) x6
293 
294 #define FATAL_ARG_7(x1, x2, x3, x4, x5, x6, x7, ...) x7
295 
296 #define FATAL_ARG_8(x1, x2, x3, x4, x5, x6, x7, x8, ...) x8
297 
298 #define FATAL_ARG_9(x1, x2, x3, x4, x5, x6, x7, x8, x9, ...) x9
299 
300 #define FATAL_ARG_10(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, ...) x10
301 
302 #define FATAL_ARG_11(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, ...) x11
303 
304 #define FATAL_ARG_12( \
305   x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, ... \
306 ) x12
307 
308 #define FATAL_ARG_13( \
309   x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, ... \
310 ) x13
311 
312 #define FATAL_ARG_14( \
313   x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, ... \
314 ) x14
315 
316 #define FATAL_ARG_15( \
317   x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, ... \
318 ) x15
319 
320 #define FATAL_ARG_16( \
321   x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, ... \
322 ) x16
323 
324 ///////////////////////
325 // FATAL_SKIP_n_ARGS //
326 ///////////////////////
327 
328 /**
329  * TODO: DOCUMENT
330  *
331  * @author: Marcelo Juchem <marcelo@fb.com>
332  */
333 #define FATAL_SKIP_1_ARG(x1, ...) __VA_ARGS__
334 
335 #define FATAL_SKIP_2_ARGS(x1, x2, ...) __VA_ARGS__
336 
337 #define FATAL_SKIP_3_ARGS(x1, x2, x3, ...) __VA_ARGS__
338 
339 #define FATAL_SKIP_4_ARGS(x1, x2, x3, x4, ...) __VA_ARGS__
340 
341 #define FATAL_SKIP_5_ARGS(x1, x2, x3, x4, x5, ...) __VA_ARGS__
342 
343 #define FATAL_SKIP_6_ARGS(x1, x2, x3, x4, x5, x6, ...) __VA_ARGS__
344 
345 #define FATAL_SKIP_7_ARGS(x1, x2, x3, x4, x5, x6, x7, ...) __VA_ARGS__
346 
347 #define FATAL_SKIP_8_ARGS(x1, x2, x3, x4, x5, x6, x7, x8, ...) __VA_ARGS__
348 
349 #define FATAL_SKIP_9_ARGS(x1, x2, x3, x4, x5, x6, x7, x8, x9, ...) __VA_ARGS__
350 
351 #define FATAL_SKIP_10_ARGS( \
352   x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, ... \
353 ) __VA_ARGS__
354 
355 #define FATAL_SKIP_11_ARGS( \
356   x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, ... \
357 ) __VA_ARGS__
358 
359 #define FATAL_SKIP_12_ARGS( \
360   x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, ... \
361 ) __VA_ARGS__
362 
363 #define FATAL_SKIP_13_ARGS( \
364   x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, ... \
365 ) __VA_ARGS__
366 
367 #define FATAL_SKIP_14_ARGS( \
368   x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, ... \
369 ) __VA_ARGS__
370 
371 #define FATAL_SKIP_15_ARGS( \
372   x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, ... \
373 ) __VA_ARGS__
374 
375 #define FATAL_SKIP_16_ARGS( \
376   x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, ... \
377 ) __VA_ARGS__
378 
379 ////////////////////
380 // FATAL_HAS_ARGS //
381 ////////////////////
382 
383 /**
384  * TODO: DOCUMENT
385  *
386  * @author: Marcelo Juchem <marcelo@fb.com>
387  */
388 #define FATAL_HAS_ARGS(...) \
389   FATAL_BOOL( \
390     FATAL_ARG_1( \
391       FATAL_IMPL_HAS_ARGS_1( \
392         FATAL_UNPARENTHESIZE( \
393           FATAL_UNPARENTHESIZE( \
394             FATAL_UNPARENTHESIZE( \
395               FATAL_UNPARENTHESIZE( \
396                 FATAL_UNPARENTHESIZE( \
397                   FATAL_UNPARENTHESIZE( \
398                     FATAL_UNPARENTHESIZE( \
399                       FATAL_UNPARENTHESIZE( \
400                         FATAL_UNPARENTHESIZE( \
401                           FATAL_UNPARENTHESIZE( \
402                             FATAL_UNPARENTHESIZE( \
403                               FATAL_UNPARENTHESIZE( \
404                                 FATAL_UNPARENTHESIZE( \
405                                   FATAL_UNPARENTHESIZE( \
406                                     FATAL_UNPARENTHESIZE( \
407                                       FATAL_UNPARENTHESIZE( \
408                                         FATAL_UNPARENTHESIZE( \
409                                           FATAL_UNPARENTHESIZE( \
410                                             FATAL_UNPARENTHESIZE(__VA_ARGS__) \
411                                           ) \
412                                         ) \
413                                       ) \
414                                     ) \
415                                   ) \
416                                 ) \
417                               ) \
418                             ) \
419                           ) \
420                         ) \
421                       ) \
422                     ) \
423                   ) \
424                 ) \
425               ) \
426             ) \
427           ) \
428         ) \
429       ) \
430     )() \
431   )
432 
433 #define FATAL_IMPL_HAS_ARGS_1(...) \
434   FATAL_ARG_1(FATAL_IMPL_HAS_ARGS_2 __VA_ARGS__)()
435 
436 #define FATAL_IMPL_HAS_ARGS_2(...) \
437   FATAL_IMPL_HAS_ARGS_3 __VA_ARGS__
438 
439 #define FATAL_IMPL_HAS_ARGS_3(...) \
440   0
441 
442 ///////////////////////
443 // FATAL_CONDITIONAL //
444 ///////////////////////
445 
446 /**
447  * TODO: DOCUMENT
448  *
449  * @author: Marcelo Juchem <marcelo@fb.com>
450  */
451 #define FATAL_CONDITIONAL(condition) \
452   FATAL_IMPL_CONDITIONAL(FATAL_BOOL(condition))
453 
454 #define FATAL_IMPL_CONDITIONAL(condition) \
455   FATAL_CAT(FATAL_CONDITIONAL_IMPL_, condition)
456 
457 #define FATAL_CONDITIONAL_IMPL_1(...) \
458   __VA_ARGS__ FATAL_IGNORE
459 
460 #define FATAL_CONDITIONAL_IMPL_0(...) \
461   FATAL_IDENTITY
462 
463 #define FATAL_CONDITIONAL_2(condition) \
464   FATAL_IMPL_CONDITIONAL_2(FATAL_BOOL(condition))
465 
466 #define FATAL_IMPL_CONDITIONAL_2(condition) \
467   FATAL_CAT(FATAL_CONDITIONAL_2_IMPL_, condition)
468 
469 #define FATAL_CONDITIONAL_2_IMPL_1(...) \
470   __VA_ARGS__ FATAL_IGNORE
471 
472 #define FATAL_CONDITIONAL_2_IMPL_0(...) \
473   FATAL_IDENTITY
474 
475 #define FATAL_CONDITIONAL_INTERNAL_UNPARENTHESIZE(condition) \
476   FATAL_IMPL_CONDITIONAL_INTERNAL_UNPARENTHESIZE(FATAL_BOOL(condition))
477 
478 #define FATAL_IMPL_CONDITIONAL_INTERNAL_UNPARENTHESIZE(condition) \
479   FATAL_CAT(FATAL_CONDITIONAL_INTERNAL_UNPARENTHESIZE_IMPL_, condition)
480 
481 #define FATAL_CONDITIONAL_INTERNAL_UNPARENTHESIZE_IMPL_1(...) \
482   __VA_ARGS__ FATAL_IGNORE
483 
484 #define FATAL_CONDITIONAL_INTERNAL_UNPARENTHESIZE_IMPL_0(...) \
485   FATAL_IDENTITY
486 
487 #define FATAL_CONDITIONAL_INTERNAL_MAP(condition) \
488   FATAL_IMPL_CONDITIONAL_INTERNAL_MAP(FATAL_BOOL(condition))
489 
490 #define FATAL_IMPL_CONDITIONAL_INTERNAL_MAP(condition) \
491   FATAL_CAT(FATAL_CONDITIONAL_INTERNAL_MAP_IMPL_, condition)
492 
493 #define FATAL_CONDITIONAL_INTERNAL_MAP_IMPL_1(...) \
494   __VA_ARGS__ FATAL_IGNORE
495 
496 #define FATAL_CONDITIONAL_INTERNAL_MAP_IMPL_0(...) \
497   FATAL_IDENTITY
498 
499 #define FATAL_CONDITIONAL_INTERNAL_MAP_2(condition) \
500   FATAL_IMPL_CONDITIONAL_INTERNAL_MAP_2(FATAL_BOOL(condition))
501 
502 #define FATAL_IMPL_CONDITIONAL_INTERNAL_MAP_2(condition) \
503   FATAL_CAT(FATAL_CONDITIONAL_INTERNAL_MAP_2_IMPL_, condition)
504 
505 #define FATAL_CONDITIONAL_INTERNAL_MAP_2_IMPL_1(...) \
506   __VA_ARGS__ FATAL_IGNORE
507 
508 #define FATAL_CONDITIONAL_INTERNAL_MAP_2_IMPL_0(...) \
509   FATAL_IDENTITY
510 
511 #define FATAL_CONDITIONAL_INTERNAL_MAP_3(condition) \
512   FATAL_IMPL_CONDITIONAL_INTERNAL_MAP_3(FATAL_BOOL(condition))
513 
514 #define FATAL_IMPL_CONDITIONAL_INTERNAL_MAP_3(condition) \
515   FATAL_CAT(FATAL_CONDITIONAL_INTERNAL_MAP_3_IMPL_, condition)
516 
517 #define FATAL_CONDITIONAL_INTERNAL_MAP_3_IMPL_1(...) \
518   __VA_ARGS__ FATAL_IGNORE
519 
520 #define FATAL_CONDITIONAL_INTERNAL_MAP_3_IMPL_0(...) \
521   FATAL_IDENTITY
522 
523 #define FATAL_CONDITIONAL_INTERNAL_MAP_4(condition) \
524   FATAL_IMPL_CONDITIONAL_INTERNAL_MAP_4(FATAL_BOOL(condition))
525 
526 #define FATAL_IMPL_CONDITIONAL_INTERNAL_MAP_4(condition) \
527   FATAL_CAT(FATAL_CONDITIONAL_INTERNAL_MAP_4_IMPL_, condition)
528 
529 #define FATAL_CONDITIONAL_INTERNAL_MAP_4_IMPL_1(...) \
530   __VA_ARGS__ FATAL_IGNORE
531 
532 #define FATAL_CONDITIONAL_INTERNAL_MAP_4_IMPL_0(...) \
533   FATAL_IDENTITY
534 
535 #define FATAL_CONDITIONAL_INTERNAL_MAP_5(condition) \
536   FATAL_IMPL_CONDITIONAL_INTERNAL_MAP_5(FATAL_BOOL(condition))
537 
538 #define FATAL_IMPL_CONDITIONAL_INTERNAL_MAP_5(condition) \
539   FATAL_CAT(FATAL_CONDITIONAL_INTERNAL_MAP_5_IMPL_, condition)
540 
541 #define FATAL_CONDITIONAL_INTERNAL_MAP_5_IMPL_1(...) \
542   __VA_ARGS__ FATAL_IGNORE
543 
544 #define FATAL_CONDITIONAL_INTERNAL_MAP_5_IMPL_0(...) \
545   FATAL_IDENTITY
546 
547 ///////////////////
548 // FATAL_DEFER_n //
549 ///////////////////
550 
551 /**
552  * TODO: DOCUMENT
553  *
554  * @author: Marcelo Juchem <marcelo@fb.com>
555  */
556 #define FATAL_DEFER_1(x) \
557   x FATAL_EMPTY()
558 
559 #define FATAL_DEFER_2(x) \
560   x FATAL_EMPTY FATAL_EMPTY()()
561 
562 #define FATAL_DEFER_3(x) \
563   x FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY()()()
564 
565 #define FATAL_DEFER_4(x) \
566   x FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY()()()()
567 
568 #define FATAL_DEFER_5(x) \
569   x FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY()()()()()
570 
571 #define FATAL_DEFER_6(x) \
572   x FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY \
573   FATAL_EMPTY()()()()()()
574 
575 #define FATAL_DEFER_7(x) \
576   x FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY \
577   FATAL_EMPTY FATAL_EMPTY()()()()()()()
578 
579 #define FATAL_DEFER_8(x) \
580   x FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY \
581   FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY()()()()()()()()
582 
583 #define FATAL_DEFER_9(x) \
584   x FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY \
585   FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY FATAL_EMPTY()()()()()()()()()
586 
587 ////////////////
588 // FATAL_EVAL //
589 ////////////////
590 
591 /**
592  * TODO: DOCUMENT
593  *
594  * @author: Marcelo Juchem <marcelo@fb.com>
595  */
596 #define FATAL_EVAL(...) \
597   FATAL_EVAL_512(FATAL_EVAL_512(__VA_ARGS__))
598 
599 #define FATAL_EVAL_512(...) \
600   FATAL_EVAL_256(FATAL_EVAL_256(__VA_ARGS__))
601 
602 #define FATAL_EVAL_256(...) \
603   FATAL_EVAL_128(FATAL_EVAL_128(__VA_ARGS__))
604 
605 #define FATAL_EVAL_128(...) \
606   FATAL_EVAL_64(FATAL_EVAL_64(__VA_ARGS__))
607 
608 #define FATAL_EVAL_64(...) \
609   FATAL_EVAL_32(FATAL_EVAL_32(__VA_ARGS__))
610 
611 #define FATAL_EVAL_32(...) \
612   FATAL_EVAL_16(FATAL_EVAL_16(__VA_ARGS__))
613 
614 #define FATAL_EVAL_16(...) \
615   FATAL_EVAL_8(FATAL_EVAL_8(__VA_ARGS__))
616 
617 #define FATAL_EVAL_8(...) \
618   FATAL_EVAL_4(FATAL_EVAL_4(__VA_ARGS__))
619 
620 #define FATAL_EVAL_4(...) \
621   FATAL_EVAL_2(FATAL_EVAL_2(__VA_ARGS__))
622 
623 #define FATAL_EVAL_2(...) \
624   FATAL_EVAL_1(FATAL_EVAL_1(__VA_ARGS__))
625 
626 #define FATAL_EVAL_1(...) \
627   __VA_ARGS__
628 
629 //////////////////////
630 // FATAL_SIMPLE_MAP //
631 //////////////////////
632 
633 /**
634  * TODO: DOCUMENT
635  *
636  * @author: Marcelo Juchem <marcelo@fb.com>
637  */
638 #define FATAL_SIMPLE_MAP(Fn, ...) \
639   FATAL_MAP(FATAL_IMPL_SIMPLE_MAP, Fn, __VA_ARGS__)
640 
641 #define FATAL_IMPL_SIMPLE_MAP(Fn, is_first, index, ...) \
642   Fn(__VA_ARGS__)
643 
644 ///////////////
645 // FATAL_MAP //
646 ///////////////
647 
648 /**
649  * TODO: DOCUMENT
650  *
651  * @author: Marcelo Juchem <marcelo@fb.com>
652  */
653 #define FATAL_MAP(Fn, arg, ...) \
654   FATAL_EVAL(FATAL_IMPL_MAP(Fn, arg, 1, 0, __VA_ARGS__))
655 
656 #define FATAL_IMPL_MAP(Fn, arg, is_first, index, x, ...) \
657   Fn(arg, is_first, index, x) \
658   FATAL_CONDITIONAL_INTERNAL_MAP(FATAL_HAS_ARGS(__VA_ARGS__))( \
659     FATAL_DEFER_2(FATAL_IMPL_MAP_RECURSE)()\
660       (Fn, arg, 0, (index + 1), __VA_ARGS__) \
661   )()
662 
663 #define FATAL_IMPL_MAP_RECURSE() \
664   FATAL_IMPL_MAP
665 
666 /////////////////
667 // FATAL_MAP_n //
668 /////////////////
669 
670 /**
671  * TODO: DOCUMENT AND TEST
672  *
673  * @author: Marcelo Juchem <marcelo@fb.com>
674  */
675 #define FATAL_MAP_2(Fn, arg, ...) \
676   FATAL_IMPL_MAP_2(Fn, arg, 1, 0, __VA_ARGS__)
677 
678 #define FATAL_IMPL_MAP_2(Fn, arg, is_first, index, x, ...) \
679   Fn(arg, is_first, index, x) \
680   FATAL_CONDITIONAL_INTERNAL_MAP_2(FATAL_HAS_ARGS(__VA_ARGS__))( \
681     FATAL_DEFER_2(FATAL_IMPL_MAP_2_RECURSE)()\
682       (Fn, arg, 0, (index + 1), __VA_ARGS__) \
683   )()
684 
685 #define FATAL_IMPL_MAP_2_RECURSE() \
686   FATAL_IMPL_MAP_2
687 
688 #define FATAL_MAP_3(Fn, arg, ...) \
689   FATAL_IMPL_MAP_3(Fn, arg, 1, 0, __VA_ARGS__)
690 
691 #define FATAL_IMPL_MAP_3(Fn, arg, is_first, index, x, ...) \
692   Fn(arg, is_first, index, x) \
693   FATAL_CONDITIONAL_INTERNAL_MAP_3(FATAL_HAS_ARGS(__VA_ARGS__))( \
694     FATAL_DEFER_3(FATAL_IMPL_MAP_3_RECURSE)()\
695       (Fn, arg, 0, (index + 1), __VA_ARGS__) \
696   )()
697 
698 #define FATAL_IMPL_MAP_3_RECURSE() \
699   FATAL_IMPL_MAP_3
700 
701 #define FATAL_MAP_4(Fn, arg, ...) \
702   FATAL_IMPL_MAP_4(Fn, arg, 1, 0, __VA_ARGS__)
703 
704 #define FATAL_IMPL_MAP_4(Fn, arg, is_first, index, x, ...) \
705   Fn(arg, is_first, index, x) \
706   FATAL_CONDITIONAL_INTERNAL_MAP_4(FATAL_HAS_ARGS(__VA_ARGS__))( \
707     FATAL_DEFER_4(FATAL_IMPL_MAP_4_RECURSE)()\
708       (Fn, arg, 0, (index + 1), __VA_ARGS__) \
709   )()
710 
711 #define FATAL_IMPL_MAP_4_RECURSE() \
712   FATAL_IMPL_MAP_4
713 
714 #define FATAL_MAP_5(Fn, arg, ...) \
715   FATAL_IMPL_MAP_5(Fn, arg, 1, 0, __VA_ARGS__)
716 
717 #define FATAL_IMPL_MAP_5(Fn, arg, is_first, index, x, ...) \
718   Fn(arg, is_first, index, x) \
719   FATAL_CONDITIONAL_INTERNAL_MAP_5(FATAL_HAS_ARGS(__VA_ARGS__))( \
720     FATAL_DEFER_5(FATAL_IMPL_MAP_5_RECURSE)()\
721       (Fn, arg, 0, (index + 1), __VA_ARGS__) \
722   )()
723 
724 #define FATAL_IMPL_MAP_5_RECURSE() \
725   FATAL_IMPL_MAP_5
726 
727 //////////////////
728 // FATAL_TO_STR //
729 //////////////////
730 
731 /**
732  * TODO: DOCUMENT
733  *
734  * @author: Marcelo Juchem <marcelo@fb.com>
735  */
736 #define FATAL_TO_STR(...) \
737   FATAL_IMPL_TO_STR(__VA_ARGS__)
738 
739 #define FATAL_IMPL_TO_STR(...) \
740   # __VA_ARGS__
741 
742 ///////////////
743 // FATAL_UID //
744 ///////////////
745 
746 /**
747  * TODO: DOCUMENT
748  *
749  * @author: Marcelo Juchem <marcelo@fb.com>
750  */
751 #define FATAL_UID(Prefix) \
752   FATAL_CAT(Prefix, FATAL_CAT(_, __LINE__))
753 
754 } // namespace fatal {
755 
756 #endif // FATAL_INCLUDE_fatal_preprocessor_h
757