1// Copyright 2017 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//
6// Internal declarations used by the C tracing macros.
7// This is not part of the public API: use <trace/event.h> instead.
8//
9
10#pragma once
11
12// Count the number of pairs of arguments passed to it without evaluating them.
13// When the number of arguments is uneven, rounds down.
14// Works with 0 to 15 pairs.
15#define TRACE_INTERNAL_COUNT_PAIRS(...)                     \
16    TRACE_INTERNAL_COUNT_PAIRS_(__VA_ARGS__,                \
17                                15, 14, 14, 13, 13, 12, 12, \
18                                11, 11, 10, 10, 9, 9, 8, 8, \
19                                7, 7, 6, 6, 5, 5, 4, 4,     \
20                                3, 3, 2, 2, 1, 1, 0, 0)
21#define TRACE_INTERNAL_COUNT_PAIRS_(            \
22    _15, _15X, _14, _14X, _13, _13X, _12, _12X, \
23    _11, _11X, _10, _10X, _9, _9X, _8, _8X,     \
24    _7, _7X, _6, _6X, _5, _5X, _4, _4X,         \
25    _3, _3X, _2, _2X, _1, _1X, N, ...) N
26
27// Applies a function or macro to each pair of arguments.
28// Works with 0 to 15 pairs.
29//
30// Example:
31//     #define MY_FN(idx, a, b)
32//     TRACE_INTERNAL_APPLY_PAIRWISE(MY_FN, "x", 1, "y", 2)
33#define TRACE_INTERNAL_APPLY_PAIRWISE(fn, ...)                              \
34    TRACE_INTERNAL_APPLY_PAIRWISE_(TRACE_INTERNAL_COUNT_PAIRS(__VA_ARGS__)) \
35    (fn, __VA_ARGS__)
36#define TRACE_INTERNAL_APPLY_PAIRWISE_(n) TRACE_INTERNAL_APPLY_PAIRWISE__(n)
37#define TRACE_INTERNAL_APPLY_PAIRWISE__(n) TRACE_INTERNAL_APPLY_PAIRWISE##n
38#define TRACE_INTERNAL_APPLY_PAIRWISE0(fn, ...)
39#define TRACE_INTERNAL_APPLY_PAIRWISE1(fn, k1, v1) \
40    fn(1, k1, v1)
41#define TRACE_INTERNAL_APPLY_PAIRWISE2(fn, k1, v1, k2, v2) \
42    fn(1, k1, v1) fn(2, k2, v2)
43#define TRACE_INTERNAL_APPLY_PAIRWISE3(fn, k1, v1, k2, v2, k3, v3) \
44    fn(1, k1, v1) fn(2, k2, v2) fn(3, k3, v3)
45#define TRACE_INTERNAL_APPLY_PAIRWISE4(fn, k1, v1, k2, v2, k3, v3, k4, v4) \
46    fn(1, k1, v1) fn(2, k2, v2) fn(3, k3, v3) fn(4, k4, v4)
47#define TRACE_INTERNAL_APPLY_PAIRWISE5(fn, k1, v1, k2, v2, k3, v3, k4, v4, \
48                                       k5, v5)                             \
49    fn(1, k1, v1) fn(2, k2, v2) fn(3, k3, v3) fn(4, k4, v4)                \
50        fn(5, k5, v5)
51#define TRACE_INTERNAL_APPLY_PAIRWISE6(fn, k1, v1, k2, v2, k3, v3, k4, v4, \
52                                       k5, v5, k6, v6)                     \
53    fn(1, k1, v1) fn(2, k2, v2) fn(3, k3, v3) fn(4, k4, v4)                \
54        fn(5, k5, v5) fn(6, k6, v6)
55#define TRACE_INTERNAL_APPLY_PAIRWISE7(fn, k1, v1, k2, v2, k3, v3, k4, v4, \
56                                       k5, v5, k6, v6, k7, v7)             \
57    fn(1, k1, v1) fn(2, k2, v2) fn(3, k3, v3) fn(4, k4, v4)                \
58        fn(5, k5, v5) fn(6, k6, v6) fn(7, k7, v7)
59#define TRACE_INTERNAL_APPLY_PAIRWISE8(fn, k1, v1, k2, v2, k3, v3, k4, v4, \
60                                       k5, v5, k6, v6, k7, v7, k8, v8)     \
61    fn(1, k1, v1) fn(2, k2, v2) fn(3, k3, v3) fn(4, k4, v4)                \
62        fn(5, k5, v5) fn(6, k6, v6) fn(7, k7, v7) fn(8, k8, v8)
63#define TRACE_INTERNAL_APPLY_PAIRWISE9(fn, k1, v1, k2, v2, k3, v3, k4, v4, \
64                                       k5, v5, k6, v6, k7, v7, k8, v8,     \
65                                       k9, v9)                             \
66    fn(1, k1, v1) fn(2, k2, v2) fn(3, k3, v3) fn(4, k4, v4)                \
67        fn(5, k5, v5) fn(6, k6, v6) fn(7, k7, v7) fn(8, k8, v8)            \
68            fn(9, k9, v9)
69#define TRACE_INTERNAL_APPLY_PAIRWISE10(fn, k1, v1, k2, v2, k3, v3, k4, v4, \
70                                        k5, v5, k6, v6, k7, v7, k8, v8,     \
71                                        k9, v9, k10, v10)                   \
72    fn(1, k1, v1) fn(2, k2, v2) fn(3, k3, v3) fn(4, k4, v4)                 \
73        fn(5, k5, v5) fn(6, k6, v6) fn(7, k7, v7) fn(8, k8, v8)             \
74            fn(9, k9, v9) fn(10, k10, v10)
75#define TRACE_INTERNAL_APPLY_PAIRWISE11(fn, k1, v1, k2, v2, k3, v3, k4, v4, \
76                                        k5, v5, k6, v6, k7, v7, k8, v8,     \
77                                        k9, v9, k10, v10, k11, v11)         \
78    fn(1, k1, v1) fn(2, k2, v2) fn(3, k3, v3) fn(4, k4, v4)                 \
79        fn(5, k5, v5) fn(6, k6, v6) fn(7, k7, v7) fn(8, k8, v8)             \
80            fn(9, k9, v9) fn(10, k10, v10) fn(11, k11, v11)
81#define TRACE_INTERNAL_APPLY_PAIRWISE12(fn, k1, v1, k2, v2, k3, v3, k4, v4,   \
82                                        k5, v5, k6, v6, k7, v7, k8, v8,       \
83                                        k9, v9, k10, v10, k11, v11, k12, v12) \
84    fn(1, k1, v1) fn(2, k2, v2) fn(3, k3, v3) fn(4, k4, v4)                   \
85        fn(5, k5, v5) fn(6, k6, v6) fn(7, k7, v7) fn(8, k8, v8)               \
86            fn(9, k9, v9) fn(10, k10, v10) fn(11, k11, v11) fn(12, k12, v12)
87#define TRACE_INTERNAL_APPLY_PAIRWISE13(fn, k1, v1, k2, v2, k3, v3, k4, v4,   \
88                                        k5, v5, k6, v6, k7, v7, k8, v8,       \
89                                        k9, v9, k10, v10, k11, v11, k12, v12, \
90                                        k13, v13)                             \
91    fn(1, k1, v1) fn(2, k2, v2) fn(3, k3, v3) fn(4, k4, v4)                   \
92        fn(5, k5, v5) fn(6, k6, v6) fn(7, k7, v7) fn(8, k8, v8)               \
93            fn(9, k9, v9) fn(10, k10, v10) fn(11, k11, v11) fn(12, k12, v12)  \
94                fn(13, k13, v13)
95#define TRACE_INTERNAL_APPLY_PAIRWISE14(fn, k1, v1, k2, v2, k3, v3, k4, v4,   \
96                                        k5, v5, k6, v6, k7, v7, k8, v8,       \
97                                        k9, v9, k10, v10, k11, v11, k12, v12, \
98                                        k13, v13, k14, v14)                   \
99    fn(1, k1, v1) fn(2, k2, v2) fn(3, k3, v3) fn(4, k4, v4)                   \
100        fn(5, k5, v5) fn(6, k6, v6) fn(7, k7, v7) fn(8, k8, v8)               \
101            fn(9, k9, v9) fn(10, k10, v10) fn(11, k11, v11) fn(12, k12, v12)  \
102                fn(13, k13, v13) fn(14, k14, v14)
103#define TRACE_INTERNAL_APPLY_PAIRWISE15(fn, k1, v1, k2, v2, k3, v3, k4, v4,   \
104                                        k5, v5, k6, v6, k7, v7, k8, v8,       \
105                                        k9, v9, k10, v10, k11, v11, k12, v12, \
106                                        k13, v13, k14, v14, k15, v15)         \
107    fn(1, k1, v1) fn(2, k2, v2) fn(3, k3, v3) fn(4, k4, v4)                   \
108        fn(5, k5, v5) fn(6, k6, v6) fn(7, k7, v7) fn(8, k8, v8)               \
109            fn(9, k9, v9) fn(10, k10, v10) fn(11, k11, v11) fn(12, k12, v12)  \
110                fn(13, k13, v13) fn(14, k14, v14) fn(15, k15, v15)
111
112// Applies a function or macro to each pair of arguments to produce a
113// comma-separated result.  Works with 0 to 15 pairs.
114//
115// Example:
116//     #define MY_FN(idx, a, b)
117//     TRACE_INTERNAL_APPLY_PAIRWISE_CSV(MY_FN, "x", 1, "y", 2)
118#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV(fn, ...)                              \
119    TRACE_INTERNAL_APPLY_PAIRWISE_CSV_(TRACE_INTERNAL_COUNT_PAIRS(__VA_ARGS__)) \
120    (fn, __VA_ARGS__)
121#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV_(n) TRACE_INTERNAL_APPLY_PAIRWISE_CSV__(n)
122#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV__(n) TRACE_INTERNAL_APPLY_PAIRWISE_CSV##n
123#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV0(fn, ...)
124#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV1(fn, k1, v1) \
125    fn(1, k1, v1)
126#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV2(fn, k1, v1, k2, v2) \
127    fn(1, k1, v1), fn(2, k2, v2)
128#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV3(fn, k1, v1, k2, v2, k3, v3) \
129    fn(1, k1, v1), fn(2, k2, v2), fn(3, k3, v3)
130#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV4(fn, k1, v1, k2, v2, k3, v3, k4, v4) \
131    fn(1, k1, v1), fn(2, k2, v2), fn(3, k3, v3), fn(4, k4, v4)
132#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV5(fn, k1, v1, k2, v2, k3, v3, k4, v4, \
133                                           k5, v5)                             \
134    fn(1, k1, v1), fn(2, k2, v2), fn(3, k3, v3), fn(4, k4, v4),                \
135        fn(5, k5, v5)
136#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV6(fn, k1, v1, k2, v2, k3, v3, k4, v4, \
137                                           k5, v5, k6, v6)                     \
138    fn(1, k1, v1), fn(2, k2, v2), fn(3, k3, v3), fn(4, k4, v4),                \
139        fn(5, k5, v5), fn(6, k6, v6)
140#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV7(fn, k1, v1, k2, v2, k3, v3, k4, v4, \
141                                           k5, v5, k6, v6, k7, v7)             \
142    fn(1, k1, v1), fn(2, k2, v2), fn(3, k3, v3), fn(4, k4, v4),                \
143        fn(5, k5, v5), fn(6, k6, v6), fn(7, k7, v7)
144#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV8(fn, k1, v1, k2, v2, k3, v3, k4, v4, \
145                                           k5, v5, k6, v6, k7, v7, k8, v8)     \
146    fn(1, k1, v1), fn(2, k2, v2), fn(3, k3, v3), fn(4, k4, v4),                \
147        fn(5, k5, v5), fn(6, k6, v6), fn(7, k7, v7), fn(8, k8, v8)
148#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV9(fn, k1, v1, k2, v2, k3, v3, k4, v4, \
149                                           k5, v5, k6, v6, k7, v7, k8, v8,     \
150                                           k9, v9)                             \
151    fn(1, k1, v1), fn(2, k2, v2), fn(3, k3, v3), fn(4, k4, v4),                \
152        fn(5, k5, v5), fn(6, k6, v6), fn(7, k7, v7), fn(8, k8, v8),            \
153        fn(9, k9, v9)
154#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV10(fn, k1, v1, k2, v2, k3, v3, k4, v4, \
155                                            k5, v5, k6, v6, k7, v7, k8, v8,     \
156                                            k9, v9, k10, v10)                   \
157    fn(1, k1, v1), fn(2, k2, v2), fn(3, k3, v3), fn(4, k4, v4),                 \
158        fn(5, k5, v5), fn(6, k6, v6), fn(7, k7, v7), fn(8, k8, v8),             \
159        fn(9, k9, v9), fn(10, k10, v10)
160#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV11(fn, k1, v1, k2, v2, k3, v3, k4, v4, \
161                                            k5, v5, k6, v6, k7, v7, k8, v8,     \
162                                            k9, v9, k10, v10, k11, v11)         \
163    fn(1, k1, v1), fn(2, k2, v2), fn(3, k3, v3), fn(4, k4, v4),                 \
164        fn(5, k5, v5), fn(6, k6, v6), fn(7, k7, v7), fn(8, k8, v8),             \
165        fn(9, k9, v9), fn(10, k10, v10), fn(11, k11, v11)
166#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV12(fn, k1, v1, k2, v2, k3, v3, k4, v4,   \
167                                            k5, v5, k6, v6, k7, v7, k8, v8,       \
168                                            k9, v9, k10, v10, k11, v11, k12, v12) \
169    fn(1, k1, v1), fn(2, k2, v2), fn(3, k3, v3), fn(4, k4, v4),                   \
170        fn(5, k5, v5), fn(6, k6, v6), fn(7, k7, v7), fn(8, k8, v8),               \
171        fn(9, k9, v9), fn(10, k10, v10), fn(11, k11, v11), fn(12, k12, v12)
172#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV13(fn, k1, v1, k2, v2, k3, v3, k4, v4,   \
173                                            k5, v5, k6, v6, k7, v7, k8, v8,       \
174                                            k9, v9, k10, v10, k11, v11, k12, v12, \
175                                            k13, v13)                             \
176    fn(1, k1, v1), fn(2, k2, v2), fn(3, k3, v3), fn(4, k4, v4),                   \
177        fn(5, k5, v5), fn(6, k6, v6), fn(7, k7, v7), fn(8, k8, v8),               \
178        fn(9, k9, v9), fn(10, k10, v10), fn(11, k11, v11), fn(12, k12, v12),      \
179        fn(13, k13, v13)
180#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV14(fn, k1, v1, k2, v2, k3, v3, k4, v4,   \
181                                            k5, v5, k6, v6, k7, v7, k8, v8,       \
182                                            k9, v9, k10, v10, k11, v11, k12, v12, \
183                                            k13, v13, k14, v14)                   \
184    fn(1, k1, v1), fn(2, k2, v2), fn(3, k3, v3), fn(4, k4, v4),                   \
185        fn(5, k5, v5), fn(6, k6, v6), fn(7, k7, v7), fn(8, k8, v8),               \
186        fn(9, k9, v9), fn(10, k10, v10), fn(11, k11, v11), fn(12, k12, v12),      \
187        fn(13, k13, v13), fn(14, k14, v14)
188#define TRACE_INTERNAL_APPLY_PAIRWISE_CSV15(fn, k1, v1, k2, v2, k3, v3, k4, v4,   \
189                                            k5, v5, k6, v6, k7, v7, k8, v8,       \
190                                            k9, v9, k10, v10, k11, v11, k12, v12, \
191                                            k13, v13, k14, v14, k15, v15)         \
192    fn(1, k1, v1), fn(2, k2, v2), fn(3, k3, v3), fn(4, k4, v4),                   \
193        fn(5, k5, v5), fn(6, k6, v6), fn(7, k7, v7), fn(8, k8, v8),               \
194        fn(9, k9, v9), fn(10, k10, v10), fn(11, k11, v11), fn(12, k12, v12),      \
195        fn(13, k13, v13), fn(14, k14, v14), fn(15, k15, v15)
196