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 #ifndef TRACE_INTERNAL_PAIRS_INTERNAL_H_ 11 #define TRACE_INTERNAL_PAIRS_INTERNAL_H_ 12 13 // Count the number of pairs of arguments passed to it without evaluating them. 14 // When the number of arguments is uneven, rounds down. 15 // Works with 0 to 15 pairs. 16 #define TRACE_INTERNAL_COUNT_PAIRS(...) \ 17 TRACE_INTERNAL_COUNT_PAIRS_(__VA_ARGS__, \ 18 15, 14, 14, 13, 13, 12, 12, \ 19 11, 11, 10, 10, 9, 9, 8, 8, \ 20 7, 7, 6, 6, 5, 5, 4, 4, \ 21 3, 3, 2, 2, 1, 1, 0, 0) 22 #define TRACE_INTERNAL_COUNT_PAIRS_( \ 23 _15, _15X, _14, _14X, _13, _13X, _12, _12X, \ 24 _11, _11X, _10, _10X, _9, _9X, _8, _8X, \ 25 _7, _7X, _6, _6X, _5, _5X, _4, _4X, \ 26 _3, _3X, _2, _2X, _1, _1X, N, ...) N 27 28 // Applies a function or macro to each pair of arguments. 29 // Works with 0 to 15 pairs. 30 // 31 // |fn| is the function or macro name to apply 32 // |vn| is the name of a local variable that the caller may be using. It is 33 // passed on to |fn| in case it needs it, e.g., to uniquify any further local 34 // variable names that |fn| as a macro may want to create. 35 // 36 // |fn| must accept four arguments: 37 // - |vn|, described above 38 // - |idx|, which is 0,1,2,...,15 and designates the index of the name/value 39 // pair in the provided list 40 // - |key|, which is the key part of the key/value pair 41 // - |value|, which is the value part of the key/value pair 42 // 43 // Example: 44 // #define MY_FN(vn, idx, a, b) 45 // TRACE_INTERNAL_APPLY_PAIRWISE(MY_FN, my_var, "x", 1, "y", 2) 46 47 #define TRACE_INTERNAL_APPLY_PAIRWISE(fn, vn, ...) \ 48 TRACE_INTERNAL_APPLY_PAIRWISE_(TRACE_INTERNAL_COUNT_PAIRS(__VA_ARGS__)) \ 49 (fn, vn, __VA_ARGS__) 50 #define TRACE_INTERNAL_APPLY_PAIRWISE_(n) TRACE_INTERNAL_APPLY_PAIRWISE__(n) 51 #define TRACE_INTERNAL_APPLY_PAIRWISE__(n) TRACE_INTERNAL_APPLY_PAIRWISE##n 52 // clang-format off 53 #define TRACE_INTERNAL_APPLY_PAIRWISE0(fn, vn, ...) 54 #define TRACE_INTERNAL_APPLY_PAIRWISE1(fn, vn, k1, v1) \ 55 fn(vn, 1, k1, v1) 56 #define TRACE_INTERNAL_APPLY_PAIRWISE2(fn, vn, k1, v1, k2, v2) \ 57 fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) 58 #define TRACE_INTERNAL_APPLY_PAIRWISE3(fn, vn, k1, v1, k2, v2, k3, v3) \ 59 fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) 60 #define TRACE_INTERNAL_APPLY_PAIRWISE4(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4) \ 61 fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) 62 #define TRACE_INTERNAL_APPLY_PAIRWISE5(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 63 k5, v5) \ 64 fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \ 65 fn(vn, 5, k5, v5) 66 #define TRACE_INTERNAL_APPLY_PAIRWISE6(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 67 k5, v5, k6, v6) \ 68 fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \ 69 fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) 70 #define TRACE_INTERNAL_APPLY_PAIRWISE7(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 71 k5, v5, k6, v6, k7, v7) \ 72 fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \ 73 fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7) 74 #define TRACE_INTERNAL_APPLY_PAIRWISE8(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 75 k5, v5, k6, v6, k7, v7, k8, v8) \ 76 fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \ 77 fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7) fn(vn, 8, k8, v8) 78 #define TRACE_INTERNAL_APPLY_PAIRWISE9(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 79 k5, v5, k6, v6, k7, v7, k8, v8, \ 80 k9, v9) \ 81 fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \ 82 fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7) fn(vn, 8, k8, v8) \ 83 fn(vn, 9, k9, v9) 84 #define TRACE_INTERNAL_APPLY_PAIRWISE10(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 85 k5, v5, k6, v6, k7, v7, k8, v8, \ 86 k9, v9, k10, v10) \ 87 fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \ 88 fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7) fn(vn, 8, k8, v8) \ 89 fn(vn, 9, k9, v9) fn(vn, 10, k10, v10) 90 #define TRACE_INTERNAL_APPLY_PAIRWISE11(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 91 k5, v5, k6, v6, k7, v7, k8, v8, \ 92 k9, v9, k10, v10, k11, v11) \ 93 fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \ 94 fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7) fn(vn, 8, k8, v8) \ 95 fn(vn, 9, k9, v9) fn(vn, 10, k10, v10) fn(vn, 11, k11, v11) 96 #define TRACE_INTERNAL_APPLY_PAIRWISE12(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 97 k5, v5, k6, v6, k7, v7, k8, v8, \ 98 k9, v9, k10, v10, k11, v11, k12, v12) \ 99 fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \ 100 fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7) fn(vn, 8, k8, v8) \ 101 fn(vn, 9, k9, v9) fn(vn, 10, k10, v10) fn(vn, 11, k11, v11) fn(vn, 12, k12, v12) 102 #define TRACE_INTERNAL_APPLY_PAIRWISE13(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 103 k5, v5, k6, v6, k7, v7, k8, v8, \ 104 k9, v9, k10, v10, k11, v11, k12, v12, \ 105 k13, v13) \ 106 fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \ 107 fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7) fn(vn, 8, k8, v8) \ 108 fn(vn, 9, k9, v9) fn(vn, 10, k10, v10) fn(vn, 11, k11, v11) fn(vn, 12, k12, v12) \ 109 fn(vn, 13, k13, v13) 110 #define TRACE_INTERNAL_APPLY_PAIRWISE14(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 111 k5, v5, k6, v6, k7, v7, k8, v8, \ 112 k9, v9, k10, v10, k11, v11, k12, v12, \ 113 k13, v13, k14, v14) \ 114 fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \ 115 fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7) fn(vn, 8, k8, v8) \ 116 fn(vn, 9, k9, v9) fn(vn, 10, k10, v10) fn(vn, 11, k11, v11) fn(vn, 12, k12, v12) \ 117 fn(vn, 13, k13, v13) fn(vn, 14, k14, v14) 118 #define TRACE_INTERNAL_APPLY_PAIRWISE15(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 119 k5, v5, k6, v6, k7, v7, k8, v8, \ 120 k9, v9, k10, v10, k11, v11, k12, v12, \ 121 k13, v13, k14, v14, k15, v15) \ 122 fn(vn, 1, k1, v1) fn(vn, 2, k2, v2) fn(vn, 3, k3, v3) fn(vn, 4, k4, v4) \ 123 fn(vn, 5, k5, v5) fn(vn, 6, k6, v6) fn(vn, 7, k7, v7) fn(vn, 8, k8, v8) \ 124 fn(vn, 9, k9, v9) fn(vn, 10, k10, v10) fn(vn, 11, k11, v11) fn(vn, 12, k12, v12) \ 125 fn(vn, 13, k13, v13) fn(vn, 14, k14, v14) fn(vn, 15, k15, v15) 126 // clang-format on 127 128 // Applies a function or macro to each pair of arguments to produce a 129 // comma-separated result. Works with 0 to 15 pairs. 130 // 131 // Example: 132 // #define MY_FN(vn, idx, a, b) 133 // TRACE_INTERNAL_APPLY_PAIRWISE_CSV(MY_FN, my_var, "x", 1, "y", 2) 134 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV(fn, vn, ...) \ 135 TRACE_INTERNAL_APPLY_PAIRWISE_CSV_(TRACE_INTERNAL_COUNT_PAIRS(__VA_ARGS__)) \ 136 (fn, vn, __VA_ARGS__) 137 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV_(n) TRACE_INTERNAL_APPLY_PAIRWISE_CSV__(n) 138 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV__(n) TRACE_INTERNAL_APPLY_PAIRWISE_CSV##n 139 // clang-format off 140 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV0(fn, vn, ...) 141 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV1(fn, vn, k1, v1) \ 142 fn(vn, 1, k1, v1) 143 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV2(fn, vn, k1, v1, k2, v2) \ 144 fn(vn, 1, k1, v1), fn(vn, 2, k2, v2) 145 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV3(fn, vn, k1, v1, k2, v2, k3, v3) \ 146 fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3) 147 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV4(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4) \ 148 fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4) 149 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV5(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 150 k5, v5) \ 151 fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \ 152 fn(vn, 5, k5, v5) 153 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV6(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 154 k5, v5, k6, v6) \ 155 fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \ 156 fn(vn, 5, k5, v5), fn(vn, 6, k6, v6) 157 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV7(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 158 k5, v5, k6, v6, k7, v7) \ 159 fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \ 160 fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7) 161 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV8(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 162 k5, v5, k6, v6, k7, v7, k8, v8) \ 163 fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \ 164 fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7), fn(vn, 8, k8, v8) 165 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV9(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 166 k5, v5, k6, v6, k7, v7, k8, v8, \ 167 k9, v9) \ 168 fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \ 169 fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7), fn(vn, 8, k8, v8), \ 170 fn(vn, 9, k9, v9) 171 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV10(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 172 k5, v5, k6, v6, k7, v7, k8, v8, \ 173 k9, v9, k10, v10) \ 174 fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \ 175 fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7), fn(vn, 8, k8, v8), \ 176 fn(vn, 9, k9, v9), fn(vn, 10, k10, v10) 177 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV11(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 178 k5, v5, k6, v6, k7, v7, k8, v8, \ 179 k9, v9, k10, v10, k11, v11) \ 180 fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \ 181 fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7), fn(vn, 8, k8, v8), \ 182 fn(vn, 9, k9, v9), fn(vn, 10, k10, v10), fn(vn, 11, k11, v11) 183 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV12(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 184 k5, v5, k6, v6, k7, v7, k8, v8, \ 185 k9, v9, k10, v10, k11, v11, k12, v12) \ 186 fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \ 187 fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7), fn(vn, 8, k8, v8), \ 188 fn(vn, 9, k9, v9), fn(vn, 10, k10, v10), fn(vn, 11, k11, v11), fn(vn, 12, k12, v12) 189 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV13(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 190 k5, v5, k6, v6, k7, v7, k8, v8, \ 191 k9, v9, k10, v10, k11, v11, k12, v12, \ 192 k13, v13) \ 193 fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \ 194 fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7), fn(vn, 8, k8, v8), \ 195 fn(vn, 9, k9, v9), fn(vn, 10, k10, v10), fn(vn, 11, k11, v11), fn(vn, 12, k12, v12), \ 196 fn(vn, 13, k13, v13) 197 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV14(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 198 k5, v5, k6, v6, k7, v7, k8, v8, \ 199 k9, v9, k10, v10, k11, v11, k12, v12, \ 200 k13, v13, k14, v14) \ 201 fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \ 202 fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7), fn(vn, 8, k8, v8), \ 203 fn(vn, 9, k9, v9), fn(vn, 10, k10, v10), fn(vn, 11, k11, v11), fn(vn, 12, k12, v12), \ 204 fn(vn, 13, k13, v13), fn(vn, 14, k14, v14) 205 #define TRACE_INTERNAL_APPLY_PAIRWISE_CSV15(fn, vn, k1, v1, k2, v2, k3, v3, k4, v4, \ 206 k5, v5, k6, v6, k7, v7, k8, v8, \ 207 k9, v9, k10, v10, k11, v11, k12, v12, \ 208 k13, v13, k14, v14, k15, v15) \ 209 fn(vn, 1, k1, v1), fn(vn, 2, k2, v2), fn(vn, 3, k3, v3), fn(vn, 4, k4, v4), \ 210 fn(vn, 5, k5, v5), fn(vn, 6, k6, v6), fn(vn, 7, k7, v7), fn(vn, 8, k8, v8), \ 211 fn(vn, 9, k9, v9), fn(vn, 10, k10, v10), fn(vn, 11, k11, v11), fn(vn, 12, k12, v12), \ 212 fn(vn, 13, k13, v13), fn(vn, 14, k14, v14), fn(vn, 15, k15, v15) 213 // clang-format on 214 215 #endif // TRACE_INTERNAL_PAIRS_INTERNAL_H_ 216