xref: /aosp_15_r20/external/perfetto/src/trace_processor/types/variadic.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SRC_TRACE_PROCESSOR_TYPES_VARIADIC_H_
18 #define SRC_TRACE_PROCESSOR_TYPES_VARIADIC_H_
19 
20 #include <cstddef>
21 #include <cstdint>
22 #include <functional>
23 #include <type_traits>
24 
25 #include "src/trace_processor/containers/string_pool.h"
26 
27 namespace perfetto::trace_processor {
28 
29 // Variadic type representing value of different possible types.
30 struct Variadic {
31   enum Type : size_t {
32     kInt,
33     kUint,
34     kString,
35     kReal,
36     kPointer,
37     kBool,
38     kJson,
39     kNull,
40     kMaxType = kNull,
41   };
42   static constexpr const char* const kTypeNames[] = {
43       "int", "uint", "string", "real", "pointer", "bool", "json", "null",
44   };
45 
IntegerVariadic46   static constexpr Variadic Integer(int64_t int_value) {
47     Variadic variadic(Type::kInt);
48     variadic.int_value = int_value;
49     return variadic;
50   }
51 
52   // BEWARE: Unsigned 64-bit integers will be handled as signed integers by
53   // SQLite for built-in SQL operators. This variadic type is used to
54   // distinguish between int64 and uint64 for correct JSON export of TrackEvent
55   // arguments.
UnsignedIntegerVariadic56   static constexpr Variadic UnsignedInteger(uint64_t uint_value) {
57     Variadic variadic(Type::kUint);
58     variadic.uint_value = uint_value;
59     return variadic;
60   }
61 
StringVariadic62   static constexpr Variadic String(StringPool::Id string_id) {
63     Variadic variadic(Type::kString);
64     variadic.string_value = string_id;
65     return variadic;
66   }
67 
RealVariadic68   static constexpr Variadic Real(double real_value) {
69     Variadic variadic(Type::kReal);
70     variadic.real_value = real_value;
71     return variadic;
72   }
73 
74   // This variadic type is used to distinguish between integers and pointer
75   // values for correct JSON export of TrackEvent arguments.
PointerVariadic76   static constexpr Variadic Pointer(uint64_t pointer_value) {
77     Variadic variadic(Type::kPointer);
78     variadic.pointer_value = pointer_value;
79     return variadic;
80   }
81 
BooleanVariadic82   static constexpr Variadic Boolean(bool bool_value) {
83     Variadic variadic(Type::kBool);
84     variadic.bool_value = bool_value;
85     return variadic;
86   }
87 
88   // This variadic type is used to distinguish between regular string and JSON
89   // string values for correct JSON export of TrackEvent arguments.
JsonVariadic90   static constexpr Variadic Json(StringPool::Id json_value) {
91     Variadic variadic(Type::kJson);
92     variadic.json_value = json_value;
93     return variadic;
94   }
95 
NullVariadic96   static constexpr Variadic Null() { return Variadic(Type::kNull); }
97 
98   // Used in tests.
99   bool operator==(const Variadic& other) const {
100     if (type == other.type) {
101       switch (type) {
102         case kInt:
103           return int_value == other.int_value;
104         case kUint:
105           return uint_value == other.uint_value;
106         case kString:
107           return string_value == other.string_value;
108         case kReal:
109           return std::equal_to<double>()(real_value, other.real_value);
110         case kPointer:
111           return pointer_value == other.pointer_value;
112         case kBool:
113           return bool_value == other.bool_value;
114         case kJson:
115           return json_value == other.json_value;
116         case kNull:
117           return true;
118       }
119     }
120     return false;
121   }
122 
123   Type type;
124   union {
125     int64_t int_value;
126     uint64_t uint_value;
127     StringPool::Id string_value;
128     double real_value;
129     uint64_t pointer_value;
130     bool bool_value;
131     StringPool::Id json_value;
132   };
133 
134  private:
VariadicVariadic135   constexpr explicit Variadic(Type t) : type(t), int_value(0) {}
136 };
137 
138 }  // namespace perfetto::trace_processor
139 
140 #endif  // SRC_TRACE_PROCESSOR_TYPES_VARIADIC_H_
141