2 * Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
10 #include <common/exception.hpp>
11 #include <common/format.hpp>
13 namespace lst
= lttng::sessiond::trace
;
16 template <class FieldTypeSet
>
17 bool fields_are_equal(const FieldTypeSet
& a
, const FieldTypeSet
& b
)
19 if (a
.size() != b
.size()) {
23 return std::equal(a
.cbegin(), a
.cend(), b
.cbegin(),
24 [](typename
FieldTypeSet::const_reference field_a
,
25 typename
FieldTypeSet::const_reference field_b
) {
26 return *field_a
== *field_b
;
31 lst::type::type(unsigned int in_alignment
) : alignment
{in_alignment
}
39 bool lst::type::operator==(const lst::type
& other
) const noexcept
41 return typeid(*this) == typeid(other
) &&
42 alignment
== other
.alignment
&&
43 /* defer to concrete type comparison */
44 this->_is_equal(other
);
47 bool lst::type::operator!=(const lst::type
& other
) const noexcept
49 return !(*this == other
);
52 lst::field::field(std::string in_name
, lst::type::cuptr in_type
) :
53 name
{std::move(in_name
)}, _type
{std::move(in_type
)}
57 void lst::field::accept(lst::field_visitor
& visitor
) const
62 bool lst::field::operator==(const lst::field
& other
) const noexcept
64 return name
== other
.name
&& *_type
== *other
._type
;
67 lst::integer_type::integer_type(unsigned int in_alignment
,
68 enum lst::byte_order in_byte_order
,
70 enum lst::integer_type::signedness in_signedness
,
71 enum lst::integer_type::base in_base
) :
73 byte_order
{in_byte_order
},
75 signedness
{in_signedness
},
80 bool lst::integer_type::_is_equal(const type
&base_other
) const noexcept
82 const auto& other
= static_cast<decltype(*this)&>(base_other
);
84 return this->byte_order
== other
.byte_order
&&
85 this->size
== other
.size
&&
86 this->signedness
== other
.signedness
&&
87 this->base
== other
.base
;
90 void lst::integer_type::accept(type_visitor
& visitor
) const
95 lst::byte_order
lst::type::reverse_byte_order(lst::byte_order byte_order
) noexcept
97 if (byte_order
== lst::byte_order::BIG_ENDIAN_
) {
98 return lst::byte_order::LITTLE_ENDIAN_
;
100 return lst::byte_order::BIG_ENDIAN_
;
104 lst::floating_point_type::floating_point_type(unsigned int in_alignment
,
105 lst::byte_order in_byte_order
,
106 unsigned int in_exponent_digits
,
107 unsigned int in_mantissa_digits
) :
109 byte_order(in_byte_order
),
110 exponent_digits
{in_exponent_digits
},
111 mantissa_digits(in_mantissa_digits
)
113 /* Allowed (exponent, mantissa) pairs. */
114 static const std::vector
<std::pair
<unsigned int, unsigned int>> allowed_pairs
{
115 {5, 11}, /* binary16 */
116 {8, 24}, /* binary32 */
117 {11, 53}, /* binary64 */
118 {15, 113}, /* binary128 */
121 const auto input_pair
= decltype(allowed_pairs
)::value_type(exponent_digits
, mantissa_digits
);
122 for (const auto& pair
: allowed_pairs
) {
123 if (input_pair
== pair
) {
124 /* mantissa and exponent digits is a valid pair. */
129 LTTNG_THROW_INVALID_ARGUMENT_ERROR(
130 fmt::format("Invalid exponent/mantissa values provided while creating {}",
134 void lst::floating_point_type::accept(type_visitor
& visitor
) const
136 visitor
.visit(*this);
139 bool lst::floating_point_type::_is_equal(const type
& base_other
) const noexcept
141 const auto& other
= static_cast<decltype(*this)&>(base_other
);
143 return this->byte_order
== other
.byte_order
&&
144 this->exponent_digits
== other
.exponent_digits
&&
145 this->mantissa_digits
== other
.mantissa_digits
;
148 lst::enumeration_type::enumeration_type(unsigned int in_alignment
,
149 enum lst::byte_order in_byte_order
,
150 unsigned int in_size
,
151 enum signedness in_signedness
,
153 integer_type(in_alignment
, in_byte_order
, in_size
, in_signedness
, in_base
)
158 void lst::signed_enumeration_type::accept(type_visitor
& visitor
) const
160 visitor
.visit(*this);
164 void lst::unsigned_enumeration_type::accept(type_visitor
& visitor
) const
166 visitor
.visit(*this);
169 lst::array_type::array_type(unsigned int in_alignment
, type::cuptr in_element_type
) :
170 type(in_alignment
), element_type
{std::move(in_element_type
)}
174 bool lst::array_type::_is_equal(const type
& base_other
) const noexcept
176 const auto& other
= static_cast<decltype(*this)&>(base_other
);
178 return *this->element_type
== *other
.element_type
;
181 lst::static_length_array_type::static_length_array_type(unsigned int in_alignment
,
182 type::cuptr in_element_type
,
183 uint64_t in_length
) :
184 array_type(in_alignment
, std::move(in_element_type
)),
189 bool lst::static_length_array_type::_is_equal(const type
& base_other
) const noexcept
191 const auto& other
= static_cast<decltype(*this)&>(base_other
);
193 return array_type::_is_equal(base_other
) && this->length
== other
.length
;
196 void lst::static_length_array_type::accept(type_visitor
& visitor
) const
198 visitor
.visit(*this);
201 lst::dynamic_length_array_type::dynamic_length_array_type(unsigned int in_alignment
,
202 type::cuptr in_element_type
,
203 std::string in_length_field_name
) :
204 array_type(in_alignment
, std::move(in_element_type
)),
205 length_field_name
{std::move(in_length_field_name
)}
209 bool lst::dynamic_length_array_type::_is_equal(const type
& base_other
) const noexcept
211 const auto& other
= static_cast<decltype(*this)&>(base_other
);
213 return array_type::_is_equal(base_other
) &&
214 this->length_field_name
== other
.length_field_name
;
217 void lst::dynamic_length_array_type::accept(type_visitor
& visitor
) const
219 visitor
.visit(*this);
222 lst::string_type::string_type(unsigned int in_alignment
, enum encoding in_encoding
) :
223 type(in_alignment
), encoding
{in_encoding
}
227 bool lst::string_type::_is_equal(const type
& base_other
) const noexcept
229 const auto& other
= static_cast<decltype(*this)&>(base_other
);
231 return this->encoding
== other
.encoding
;
234 lst::static_length_string_type::static_length_string_type(
235 unsigned int in_alignment
, enum encoding in_encoding
, uint64_t in_length
) :
236 string_type(in_alignment
, in_encoding
), length
{in_length
}
240 bool lst::static_length_string_type::_is_equal(const type
& base_other
) const noexcept
242 const auto& other
= static_cast<decltype(*this)&>(base_other
);
244 return string_type::_is_equal(base_other
) && this->length
== other
.length
;
247 void lst::static_length_string_type::accept(type_visitor
& visitor
) const
249 visitor
.visit(*this);
252 lst::dynamic_length_string_type::dynamic_length_string_type(unsigned int in_alignment
,
253 enum encoding in_encoding
,
254 std::string in_length_field_name
) :
255 string_type(in_alignment
, in_encoding
), length_field_name
{std::move(in_length_field_name
)}
259 bool lst::dynamic_length_string_type::_is_equal(const type
& base_other
) const noexcept
261 const auto& other
= static_cast<decltype(*this)&>(base_other
);
263 return string_type::_is_equal(base_other
) &&
264 this->length_field_name
== other
.length_field_name
;
267 void lst::dynamic_length_string_type::accept(type_visitor
& visitor
) const
269 visitor
.visit(*this);
272 lst::null_terminated_string_type::null_terminated_string_type(unsigned int in_alignment
,
273 enum encoding in_encoding
) :
274 string_type(in_alignment
, in_encoding
)
278 void lst::null_terminated_string_type::accept(type_visitor
& visitor
) const
280 visitor
.visit(*this);
283 lst::structure_type::structure_type(unsigned int in_alignment
, fields in_fields
) :
284 type(in_alignment
), _fields
{std::move(in_fields
)}
288 bool lst::structure_type::_is_equal(const type
& base_other
) const noexcept
290 const auto &other
= static_cast<decltype(*this)&>(base_other
);
292 return fields_are_equal(this->_fields
, other
._fields
);
295 void lst::structure_type::accept(type_visitor
& visitor
) const
297 visitor
.visit(*this);
300 lst::variant_type::variant_type(unsigned int in_alignment
,
301 std::string in_tag_name
,
302 choices in_choices
) :
304 tag_name
{std::move(in_tag_name
)},
305 _choices
{std::move(in_choices
)}
309 bool lst::variant_type::_is_equal(const type
& base_other
) const noexcept
311 const auto &other
= static_cast<decltype(*this)&>(base_other
);
313 return this->tag_name
== other
.tag_name
&&
314 fields_are_equal(this->_choices
, other
._choices
);
317 void lst::variant_type::accept(type_visitor
& visitor
) const
319 visitor
.visit(*this);