P99
p99_args.h
Go to the documentation of this file.
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-2012 Jens Gustedt, INRIA, France */
6 /* (C) copyright 2012 William Morris */
7 /* */
8 /* This file is free software; it is part of the P99 project. */
9 /* You can redistribute it and/or modify it under the terms of the QPL as */
10 /* given in the file LICENSE. It is distributed without any warranty; */
11 /* without even the implied warranty of merchantability or fitness for a */
12 /* particular purpose. */
13 /* */
14 #ifndef P99_ARGS_H_
15 # define P99_ARGS_H_
16 
22 #include "p99_paste.h"
23 
42 #define P00_NARG(...) P00_NARG_1(__VA_ARGS__)
43 
44 #define P00_IS__EQ__(...) ,
45 
67 #define P99_IS_EMPTY(...) \
68 P00_ISEMPTY( \
69  /* test if there is just one argument, that might be empty */ \
70  P99_HAS_COMMA(__VA_ARGS__), \
71  /* test if P99_IS__EQ__ together with the argument \
72  adds a comma */ \
73  P99_HAS_COMMA(P00_IS__EQ__ __VA_ARGS__), \
74  /* test if the argument together with a parenthesis \
75  adds a comma */ \
76  P99_HAS_COMMA(__VA_ARGS__ (/*empty*/)), \
77  /* test if placing it between P99_IS__EQ__ and the \
78  parenthesis adds a comma */ \
79  P99_HAS_COMMA(P00_IS__EQ__ __VA_ARGS__ (/*empty*/)) \
80  )
81 
82 #define P00_ISEMPTY(_0, _1, _2, _3) P99_HAS_COMMA(P99_PASTE5(P00_IS_EMPTY_CASE_, _0, _1, _2, _3))
83 #define P00_IS_EMPTY_CASE_0000 P00_IS_EMPTY_CASE_0000
84 #define P00_IS_EMPTY_CASE_0001 ,
85 #define P00_IS_EMPTY_CASE_0010 P00_IS_EMPTY_CASE_0010
86 #define P00_IS_EMPTY_CASE_0011 P00_IS_EMPTY_CASE_0011
87 #define P00_IS_EMPTY_CASE_0100 P00_IS_EMPTY_CASE_0100
88 #define P00_IS_EMPTY_CASE_0101 P00_IS_EMPTY_CASE_0101
89 #define P00_IS_EMPTY_CASE_0110 P00_IS_EMPTY_CASE_0110
90 #define P00_IS_EMPTY_CASE_0111 P00_IS_EMPTY_CASE_0111
91 #define P00_IS_EMPTY_CASE_1000 P00_IS_EMPTY_CASE_1000
92 #define P00_IS_EMPTY_CASE_1001 P00_IS_EMPTY_CASE_1001
93 #define P00_IS_EMPTY_CASE_1010 P00_IS_EMPTY_CASE_1010
94 #define P00_IS_EMPTY_CASE_1011 P00_IS_EMPTY_CASE_1011
95 #define P00_IS_EMPTY_CASE_1100 P00_IS_EMPTY_CASE_1100
96 #define P00_IS_EMPTY_CASE_1101 P00_IS_EMPTY_CASE_1101
97 #define P00_IS_EMPTY_CASE_1110 P00_IS_EMPTY_CASE_1110
98 #define P00_IS_EMPTY_CASE_1111 P00_IS_EMPTY_CASE_1111
99 
100 
101 #define P00_NARG_EMPTY_1(VAL) 0
102 #define P00_NARG_EMPTY_0(VAL) VAL
103 
112 #define P99_NARG(...) P00_NARG__1(P99_IS_EMPTY(__VA_ARGS__), P00_NARG(__VA_ARGS__))
113 #define P00_NARG__1(B, VAL) P00_NARG__2(P99_PASTE2(P00_NARG_EMPTY_, B), VAL)
114 #define P00_NARG__2(B, VAL) B(VAL)
115 
116 
137 #define P99_TOK_EQ(TOK, ...) P00_TOK_EQ_(P99_PASTE3(P00_IS_, TOK, _EQ_), __VA_ARGS__)
138 #define P00_TOK_EQ_(MAC, ...) P00_TOK_EQ__(MAC, __VA_ARGS__)
139 #define P00_TOK_EQ__(MAC, ...) P99_HAS_COMMA(P99_PASTE2(P00_TOK_EQ_, P00_NARG(MAC ## __VA_ARGS__ (~) MAC ## __VA_ARGS__))(~))
140 
141 #define P00_TOK_EQ_0(...) ~
142 #define P00_TOK_EQ_1(...) ~
143 #define P00_TOK_EQ_2(...) ,
144 #define P00_TOK_EQ_3(...) ~
145 #define P00_TOK_EQ_4(...) ~
146 
147 
208 #define P99_VA_ARGS(X) size_t X , ...
209 
210 #define P00_FSYMB(NAME) P99_PASTE5(NAME, _f, sy, mb, _)
211 
218 #define P99_FSYMB(NAME) P00_FSYMB(NAME)
219 
229 #define P99_LENGTH_VA_ARG(...) ((size_t)P99_NARG(__VA_ARGS__)), __VA_ARGS__
230 
231 
277 #define P99_LENGTH_ARR_ARG(T, ...) ((size_t)P99_NARG(__VA_ARGS__)), (T[]){ __VA_ARGS__ }
278 
279 
286 #endif /* !P99_ARGS_H_ */
macros that paste tokens in a predictable way