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