]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/p99.qh
Small optimization
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / p99.qh
1 /* This may look like nonsense, but it really is -*- mode: C -*-              */
2 /*                                                                            */
3 /* Except for parts copied from previous work and as explicitly stated below, */
4 /* the authors and copyright holders for this work are as follows:            */
5 /* (C) copyright  2010-2013 Jens Gustedt, INRIA, France                       */
6 /* (C) copyright  2013 Pierre-Nicolas Clauss                                  */
7 /* (C) copyright  2012 William Morris                                         */
8 /*                                                                            */
9 /* This file is free software; it is part of the P99 project.                 */
10 /* You can redistribute it and/or modify it under the terms of the QPL as     */
11 /* given in the file LICENSE. It is distributed without any warranty;         */
12 /* without even the implied warranty of merchantability or fitness for a      */
13 /* particular purpose.                                                        */
14 /*                                                                            */
15 #pragma once
16
17 #define P99_MAX_NUMBER 16
18 #define P00_ARG(                            \
19     _01, _02, _03, _04, _05, _06, _07, _08, \
20     _09, _10, _11, _12, _13, _14, _15, _16, \
21     _00, ...) _00
22 #define P00_NARG(...) P00_ARG(__VA_ARGS__,  \
23     16, 15, 14, 13, 12, 11, 10,  9,         \
24      8,  7,  6,  5,  4,  3,  2,  1,         \
25      0, )
26 #define P99_HAS_COMMA(...) P00_ARG(__VA_ARGS__, \
27     1, 1, 1, 1, 1, 1, 1, 1,                     \
28     1, 1, 1, 1, 1, 1, 1, 0,                     \
29     0)
30
31 #define P99_IF_EMPTY(...) P99_IF_EQ(1, P99_IS_EMPTY(__VA_ARGS__))
32     // P99_HAS_COMMA(__VA_ARGS__),                         : test if there is just one argument, that might be empty
33     // P99_HAS_COMMA(P00_IS__EQ__ __VA_ARGS__),            : test if P99_IS__EQ__ together with the argument adds a comma
34     // P99_HAS_COMMA(__VA_ARGS__ (/*empty*/)),             : test if the argument together with a parenthesis adds a comma
35     // P99_HAS_COMMA(P00_IS__EQ__ __VA_ARGS__ (/*empty*/)) : test if placing it between P99_IS__EQ__ and the parenthesis adds a comma
36     #define P99_IS_EMPTY(...)                                                               \
37         P00_ISEMPTY(                                                                        \
38             P99_HAS_COMMA(__VA_ARGS__),                                                     \
39             P99_HAS_COMMA(P00_IS__EQ__ __VA_ARGS__),                                        \
40             P99_HAS_COMMA(__VA_ARGS__ (/*empty*/)),                                         \
41             P99_HAS_COMMA(P00_IS__EQ__ __VA_ARGS__ (/*empty*/))                             \
42         )
43         #define P00_IS__EQ__(...) ,
44         #define P00_ISEMPTY(_1, _2, _3, _4) P99_HAS_COMMA(P99_PASTE5(P00_IS_EMPTY_CASE_, _1, _2, _3, _4))
45             #define P00_IS_EMPTY_CASE_0000 P00_IS_EMPTY_CASE_0000
46             #define P00_IS_EMPTY_CASE_0001 ,
47             #define P00_IS_EMPTY_CASE_0010 P00_IS_EMPTY_CASE_0010
48             #define P00_IS_EMPTY_CASE_0011 P00_IS_EMPTY_CASE_0011
49             #define P00_IS_EMPTY_CASE_0100 P00_IS_EMPTY_CASE_0100
50             #define P00_IS_EMPTY_CASE_0101 P00_IS_EMPTY_CASE_0101
51             #define P00_IS_EMPTY_CASE_0110 P00_IS_EMPTY_CASE_0110
52             #define P00_IS_EMPTY_CASE_0111 P00_IS_EMPTY_CASE_0111
53             #define P00_IS_EMPTY_CASE_1000 P00_IS_EMPTY_CASE_1000
54             #define P00_IS_EMPTY_CASE_1001 P00_IS_EMPTY_CASE_1001
55             #define P00_IS_EMPTY_CASE_1010 P00_IS_EMPTY_CASE_1010
56             #define P00_IS_EMPTY_CASE_1011 P00_IS_EMPTY_CASE_1011
57             #define P00_IS_EMPTY_CASE_1100 P00_IS_EMPTY_CASE_1100
58             #define P00_IS_EMPTY_CASE_1101 P00_IS_EMPTY_CASE_1101
59             #define P00_IS_EMPTY_CASE_1110 P00_IS_EMPTY_CASE_1110
60             #define P00_IS_EMPTY_CASE_1111 P00_IS_EMPTY_CASE_1111
61
62
63 #define P00_IF_CLAUSE(EXP) P00__IF_CLAUSE(EXP, P00_CLAUSE1, P00_CLAUSE2, ~)
64     #define P00__IF_CLAUSE(A, B, C, ...) C
65     #define P00_CLAUSE1(...) __VA_ARGS__ P00_IGNORE
66         #define P00_IGNORE(...)
67     #define P00_CLAUSE2(...) P00_IDENT
68         #define P00_IDENT(...) __VA_ARGS__
69
70
71 #define P99_IF_EQ(A, B) P00_IF_CLAUSE(P99_PASTE4(P00_IS_, A, _EQ_, B)())
72     #define P00_IS_0_EQ_0(...) ,
73     #define P00_IS_1_EQ_1(...) ,
74
75
76 #define P99_CAT2(_1, _2) _1 ## _2
77 #define P99_PASTE2(_1, _2) \
78     P99_CAT2(_1, _2)
79 #define P99_PASTE3(_1, _2, _3) \
80     P99_PASTE2(P99_PASTE2(_1, _2), _3)
81 #define P99_PASTE4(_1, _2, _3, _4) \
82     P99_PASTE2(P99_PASTE3(_1, _2, _3), _4)
83 #define P99_PASTE5(_1, _2, _3, _4, _5) \
84     P99_PASTE2(P99_PASTE4(_1, _2, _3, _4), _5)