Startle
Useful and efficient algorithms and facilities
dispatch.h
Go to the documentation of this file.
1 /* Copyright 2012-2018 Dustin M. DeWeese
2 
3  This file is part of the Startle library.
4 
5  Licensed under the Apache License, Version 2.0 (the "License");
6  you may not use this file except in compliance with the License.
7  You may obtain a copy of the License at
8 
9  http://www.apache.org/licenses/LICENSE-2.0
10 
11  Unless required by applicable law or agreed to in writing, software
12  distributed under the License is distributed on an "AS IS" BASIS,
13  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  See the License for the specific language governing permissions and
15  limitations under the License.
16 */
17 
18 #ifndef __DISPATCH__
19 #define __DISPATCH__
20 
25 // GET ________________________________________________________________________________
26 
30 #define GET(n, t) CONCAT(GET, n) t
31 #define GET0(x0, ...) x0
32 #define GET1(x0, x1, ...) x1
33 #define GET2(x0, x1, x2, ...) x2
34 #define GET3(x0, x1, x2, x3, ...) x3
35 #define GET4(x0, x1, x2, x3, x4, ...) x4
36 #define GET5(x0, x1, x2, x3, x4, x5, ...) x5
37 #define GET6(x0, x1, x2, x3, x4, x5, x6, ...) x6
38 #define GET7(x0, x1, x2, x3, x4, x5, x6, x7, ...) x7
39 #define GET8(x0, x1, x2, x3, x4, x5, x6, x7, x8, ...) x8
40 #define GET20(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, ...) x20
41 
42 // DISPATCH ________________________________________________________________________________
43 
45 #define ARG_COUNT(...) GET20(_X, ##__VA_ARGS__, _19, _18, _17, _16, _15, _14, _13, _12, _11, _10, _9, _8, _7, _6, _5, _4, _3, _2, _1, _0)
46 
54 #define DISPATCH(m, ...) CONCAT(m, ARG_COUNT(__VA_ARGS__))(__VA_ARGS__)
55 
56 // FORARG ________________________________________________________________________________
57 
58 #define FORARG_2(name, x0) \
59  CONCAT(name, _pre) \
60  CONCAT(name, _only)(GET(0, CONCAT(name, _args)), x0) \
61  CONCAT(name, _post)
62 #define FORARG_3(name, x0, x1) \
63  CONCAT(name, _pre) \
64  CONCAT(name, _first)(GET(1, CONCAT(name, _args)), x0) \
65  CONCAT(name, _last)(x1) \
66  CONCAT(name, _post)
67 #define FORARG_4(name, x0, x1, x2) \
68  CONCAT(name, _pre) \
69  CONCAT(name, _first)(GET(2, CONCAT(name, _args)), x0) \
70  CONCAT(name, _middle)(x1) \
71  CONCAT(name, _last)(x2) \
72  CONCAT(name, _post)
73 #define FORARG_5(name, x0, x1, x2, x3) \
74  CONCAT(name, _pre) \
75  CONCAT(name, _first)(GET(3, CONCAT(name, _args)), x0) \
76  CONCAT(name, _middle)(x1) \
77  CONCAT(name, _middle)(x2) \
78  CONCAT(name, _last)(x3) \
79  CONCAT(name, _post)
80 #define FORARG_6(name, x0, x1, x2, x3, x4) \
81  CONCAT(name, _pre) \
82  CONCAT(name, _first)(GET(4, CONCAT(name, _args)), x0) \
83  CONCAT(name, _middle)(x1) \
84  CONCAT(name, _middle)(x2) \
85  CONCAT(name, _middle)(x3) \
86  CONCAT(name, _last)(x4) \
87  CONCAT(name, _post)
88 #define FORARG_7(name, x0, x1, x2, x3, x4, x5) \
89  CONCAT(name, _pre) \
90  CONCAT(name, _first)(GET(5, CONCAT(name, _args)), x0) \
91  CONCAT(name, _middle)(x1) \
92  CONCAT(name, _middle)(x2) \
93  CONCAT(name, _middle)(x3) \
94  CONCAT(name, _middle)(x4) \
95  CONCAT(name, _last)(x5) \
96  CONCAT(name, _post)
97 #define FORARG_8(name, x0, x1, x2, x3, x4, x5, x6) \
98  CONCAT(name, _pre) \
99  CONCAT(name, _first)(GET(6, CONCAT(name, _args)), x0) \
100  CONCAT(name, _middle)(x1) \
101  CONCAT(name, _middle)(x2) \
102  CONCAT(name, _middle)(x3) \
103  CONCAT(name, _middle)(x4) \
104  CONCAT(name, _middle)(x5) \
105  CONCAT(name, _last)(x6) \
106  CONCAT(name, _post)
107 #define FORARG_9(name, x0, x1, x2, x3, x4, x5, x6, x7) \
108  CONCAT(name, _pre) \
109  CONCAT(name, _first)(GET(7, CONCAT(name, _args)), x0) \
110  CONCAT(name, _middle)(x1) \
111  CONCAT(name, _middle)(x2) \
112  CONCAT(name, _middle)(x3) \
113  CONCAT(name, _middle)(x4) \
114  CONCAT(name, _middle)(x5) \
115  CONCAT(name, _middle)(x6) \
116  CONCAT(name, _last)(x7) \
117  CONCAT(name, _post)
118 #define FORARG_10(name, x0, x1, x2, x3, x4, x5, x6, x7, x8) \
119  CONCAT(name, _pre) \
120  CONCAT(name, _first)(GET(8, CONCAT(name, _args)), x0) \
121  CONCAT(name, _middle)(x1) \
122  CONCAT(name, _middle)(x2) \
123  CONCAT(name, _middle)(x3) \
124  CONCAT(name, _middle)(x4) \
125  CONCAT(name, _middle)(x5) \
126  CONCAT(name, _middle)(x6) \
127  CONCAT(name, _middle)(x7) \
128  CONCAT(name, _last)(x8) \
129  CONCAT(name, _post)
130 
152 #define FORARG(name, ...) DISPATCH(FORARG, name, __VA_ARGS__)
153 
154 #define DUMMY_args (x, x, x, x, x, x, x, x, x)
155 
156 // drops the first argument, useful with __VA_ARGS__
157 #define DROP_pre
158 #define DROP_first(s, x)
159 #define DROP_middle(x) ,x
160 #define DROP_last(x) ,x
161 #define DROP_only(s, x)
162 #define DROP_post
163 #define DROP_args DUMMY_args
164 #define DROP(...) FORARG(DROP, __VA_ARGS__)
165 
166 #endif