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>
15 namespace lst
= lttng::sessiond::trace
;
18 template <class FieldTypeSet
>
19 bool fields_are_equal(const FieldTypeSet
& a
, const FieldTypeSet
& b
)
21 if (a
.size() != b
.size()) {
25 return std::equal(a
.cbegin(), a
.cend(), b
.cbegin(),
26 [](typename
FieldTypeSet::const_reference field_a
,
27 typename
FieldTypeSet::const_reference field_b
) {
28 return *field_a
== *field_b
;
33 lst::field_location::field_location(lst::field_location::root in_lookup_root
,
34 lst::field_location::elements in_elements
) :
35 root_
{in_lookup_root
}, elements_
{std::move(in_elements
)}
39 bool lst::field_location::operator==(const lst::field_location
& other
) const noexcept
41 return root_
== other
.root_
&&
42 elements_
== other
.elements_
;
45 lst::type::type(unsigned int in_alignment
) : alignment
{in_alignment
}
53 bool lst::type::operator==(const lst::type
& other
) const noexcept
55 return typeid(*this) == typeid(other
) &&
56 alignment
== other
.alignment
&&
57 /* defer to concrete type comparison */
58 this->_is_equal(other
);
61 bool lst::type::operator!=(const lst::type
& other
) const noexcept
63 return !(*this == other
);
66 lst::field::field(std::string in_name
, lst::type::cuptr in_type
) :
67 name
{std::move(in_name
)}, _type
{std::move(in_type
)}
70 LTTNG_THROW_ERROR(fmt::format("Invalid type used to create field: field name = `{}`", name
));
74 void lst::field::accept(lst::field_visitor
& visitor
) const
79 bool lst::field::operator==(const lst::field
& other
) const noexcept
81 return name
== other
.name
&& *_type
== *other
._type
;
84 lst::type::cuptr
lst::field::move_type() noexcept
86 return std::move(_type
);
89 const lst::type
&lst::field::get_type() const
94 LTTNG_THROW_ERROR(fmt::format("Invalid attempt to access field type after transfer: field name = `{}`", name
));
98 lst::integer_type::integer_type(unsigned int in_alignment
,
99 enum lst::byte_order in_byte_order
,
100 unsigned int in_size
,
101 enum lst::integer_type::signedness in_signedness
,
102 enum lst::integer_type::base in_base
,
105 byte_order
{in_byte_order
},
107 signedness_
{in_signedness
},
109 roles_
{std::move(in_roles
)}
113 lst::type::cuptr
lst::integer_type::copy() const
115 return lttng::make_unique
<integer_type
>(
116 alignment
, byte_order
, size
, signedness_
, base_
, roles_
);
119 bool lst::integer_type::_is_equal(const type
&base_other
) const noexcept
121 const auto& other
= static_cast<decltype(*this)&>(base_other
);
123 return this->byte_order
== other
.byte_order
&&
124 this->size
== other
.size
&&
125 this->signedness_
== other
.signedness_
&&
126 this->base_
== other
.base_
&&
127 this->roles_
== other
.roles_
;
130 void lst::integer_type::accept(type_visitor
& visitor
) const
132 visitor
.visit(*this);
135 lst::byte_order
lst::type::reverse_byte_order(lst::byte_order byte_order
) noexcept
137 if (byte_order
== lst::byte_order::BIG_ENDIAN_
) {
138 return lst::byte_order::LITTLE_ENDIAN_
;
140 return lst::byte_order::BIG_ENDIAN_
;
144 lst::floating_point_type::floating_point_type(unsigned int in_alignment
,
145 lst::byte_order in_byte_order
,
146 unsigned int in_exponent_digits
,
147 unsigned int in_mantissa_digits
) :
149 byte_order(in_byte_order
),
150 exponent_digits
{in_exponent_digits
},
151 mantissa_digits(in_mantissa_digits
)
153 /* Allowed (exponent, mantissa) pairs. */
154 static const std::set
<std::pair
<unsigned int, unsigned int>> allowed_pairs
{
155 {5, 11}, /* binary16 */
156 {8, 24}, /* binary32 */
157 {11, 53}, /* binary64 */
158 {15, 113}, /* binary128 */
161 if (allowed_pairs
.find({exponent_digits
, mantissa_digits
}) != allowed_pairs
.end()) {
162 /* mantissa and exponent digits is a valid pair. */
166 LTTNG_THROW_INVALID_ARGUMENT_ERROR(
167 fmt::format("Invalid exponent/mantissa values provided while creating {}",
171 lst::type::cuptr
lst::floating_point_type::copy() const
173 return lttng::make_unique
<floating_point_type
>(
174 alignment
, byte_order
, exponent_digits
, mantissa_digits
);
177 void lst::floating_point_type::accept(type_visitor
& visitor
) const
179 visitor
.visit(*this);
182 bool lst::floating_point_type::_is_equal(const type
& base_other
) const noexcept
184 const auto& other
= static_cast<decltype(*this)&>(base_other
);
186 return this->byte_order
== other
.byte_order
&&
187 this->exponent_digits
== other
.exponent_digits
&&
188 this->mantissa_digits
== other
.mantissa_digits
;
191 lst::enumeration_type::enumeration_type(unsigned int in_alignment
,
192 enum lst::byte_order in_byte_order
,
193 unsigned int in_size
,
194 enum signedness in_signedness
,
196 lst::integer_type::roles in_roles
) :
197 integer_type(in_alignment
,
207 * Due to a bug in g++ < 7.1, these specializations must be enclosed in the namespaces
208 * rather than using the usual `namespace::namespace::function` notation:
209 * see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480.
215 void signed_enumeration_type::accept(type_visitor
& visitor
) const
217 visitor
.visit(*this);
221 void unsigned_enumeration_type::accept(type_visitor
& visitor
) const
223 visitor
.visit(*this);
227 void variant_type
<lst::signed_enumeration_type::mapping::range_t::range_integer_t
>::accept(
228 lst::type_visitor
& visitor
) const
230 visitor
.visit(*this);
234 void variant_type
<lst::unsigned_enumeration_type::mapping::range_t::range_integer_t
>::accept(
235 lst::type_visitor
& visitor
) const
237 visitor
.visit(*this);
239 } /* namespace trace */
240 } /* namespace sessiond */
241 } /* namespace lttng */
243 lst::array_type::array_type(unsigned int in_alignment
, type::cuptr in_element_type
) :
244 type(in_alignment
), element_type
{std::move(in_element_type
)}
248 bool lst::array_type::_is_equal(const type
& base_other
) const noexcept
250 const auto& other
= static_cast<decltype(*this)&>(base_other
);
252 return *this->element_type
== *other
.element_type
;
255 lst::static_length_array_type::static_length_array_type(unsigned int in_alignment
,
256 type::cuptr in_element_type
,
257 uint64_t in_length
) :
258 array_type(in_alignment
, std::move(in_element_type
)),
263 bool lst::static_length_array_type::_is_equal(const type
& base_other
) const noexcept
265 const auto& other
= static_cast<decltype(*this)&>(base_other
);
267 return array_type::_is_equal(base_other
) && this->length
== other
.length
;
270 lst::type::cuptr
lst::static_length_array_type::copy() const
272 return lttng::make_unique
<static_length_array_type
>(
273 alignment
, element_type
->copy(), length
);
276 void lst::static_length_array_type::accept(type_visitor
& visitor
) const
278 visitor
.visit(*this);
281 lst::dynamic_length_array_type::dynamic_length_array_type(unsigned int in_alignment
,
282 type::cuptr in_element_type
,
283 lst::field_location in_length_field_location
) :
284 array_type(in_alignment
, std::move(in_element_type
)),
285 length_field_location
{std::move(in_length_field_location
)}
289 bool lst::dynamic_length_array_type::_is_equal(const type
& base_other
) const noexcept
291 const auto& other
= static_cast<decltype(*this)&>(base_other
);
293 return array_type::_is_equal(base_other
) &&
294 this->length_field_location
== other
.length_field_location
;
297 lst::type::cuptr
lst::dynamic_length_array_type::copy() const
299 return lttng::make_unique
<dynamic_length_array_type
>(
300 alignment
, element_type
->copy(), length_field_location
);
303 void lst::dynamic_length_array_type::accept(type_visitor
& visitor
) const
305 visitor
.visit(*this);
308 lst::static_length_blob_type::static_length_blob_type(
309 unsigned int in_alignment
, uint64_t in_length_bytes
, roles in_roles
) :
310 type(in_alignment
), length_bytes
{in_length_bytes
}, roles_
{std::move(in_roles
)}
314 bool lst::static_length_blob_type::_is_equal(const type
& base_other
) const noexcept
316 const auto& other
= static_cast<decltype(*this)&>(base_other
);
318 return length_bytes
== other
.length_bytes
&& roles_
== other
.roles_
;
321 lst::type::cuptr
lst::static_length_blob_type::copy() const
323 return lttng::make_unique
<static_length_blob_type
>(alignment
, length_bytes
, roles_
);
326 void lst::static_length_blob_type::accept(type_visitor
& visitor
) const
328 visitor
.visit(*this);
331 lst::dynamic_length_blob_type::dynamic_length_blob_type(
332 unsigned int in_alignment
, lst::field_location in_length_field_location
) :
333 type(in_alignment
), length_field_location
{std::move(in_length_field_location
)}
337 bool lst::dynamic_length_blob_type::_is_equal(const type
& base_other
) const noexcept
339 const auto& other
= dynamic_cast<decltype(*this)&>(base_other
);
341 return length_field_location
== other
.length_field_location
;
344 lst::type::cuptr
lst::dynamic_length_blob_type::copy() const
346 return lttng::make_unique
<dynamic_length_blob_type
>(alignment
, length_field_location
);
349 void lst::dynamic_length_blob_type::accept(type_visitor
& visitor
) const
351 visitor
.visit(*this);
354 lst::string_type::string_type(unsigned int in_alignment
, enum encoding in_encoding
) :
355 type(in_alignment
), encoding_
{in_encoding
}
359 bool lst::string_type::_is_equal(const type
& base_other
) const noexcept
361 const auto& other
= static_cast<decltype(*this)&>(base_other
);
363 return this->encoding_
== other
.encoding_
;
366 lst::static_length_string_type::static_length_string_type(
367 unsigned int in_alignment
, enum encoding in_encoding
, uint64_t in_length
) :
368 string_type(in_alignment
, in_encoding
), length
{in_length
}
372 bool lst::static_length_string_type::_is_equal(const type
& base_other
) const noexcept
374 const auto& other
= static_cast<decltype(*this)&>(base_other
);
376 return string_type::_is_equal(base_other
) && this->length
== other
.length
;
379 lst::type::cuptr
lst::static_length_string_type::copy() const
381 return lttng::make_unique
<static_length_string_type
>(alignment
, encoding_
, length
);
384 void lst::static_length_string_type::accept(type_visitor
& visitor
) const
386 visitor
.visit(*this);
389 lst::dynamic_length_string_type::dynamic_length_string_type(unsigned int in_alignment
,
390 enum encoding in_encoding
,
391 field_location in_length_field_location
) :
392 string_type(in_alignment
, in_encoding
),
393 length_field_location
{std::move(in_length_field_location
)}
397 bool lst::dynamic_length_string_type::_is_equal(const type
& base_other
) const noexcept
399 const auto& other
= static_cast<decltype(*this)&>(base_other
);
401 return string_type::_is_equal(base_other
) &&
402 this->length_field_location
== other
.length_field_location
;
405 lst::type::cuptr
lst::dynamic_length_string_type::copy() const
407 return lttng::make_unique
<dynamic_length_string_type
>(
408 alignment
, encoding_
, length_field_location
);
411 void lst::dynamic_length_string_type::accept(type_visitor
& visitor
) const
413 visitor
.visit(*this);
416 lst::null_terminated_string_type::null_terminated_string_type(unsigned int in_alignment
,
417 enum encoding in_encoding
) :
418 string_type(in_alignment
, in_encoding
)
422 lst::type::cuptr
lst::null_terminated_string_type::copy() const
424 return lttng::make_unique
<null_terminated_string_type
>(alignment
, encoding_
);
427 void lst::null_terminated_string_type::accept(type_visitor
& visitor
) const
429 visitor
.visit(*this);
432 lst::structure_type::structure_type(unsigned int in_alignment
, fields in_fields
) :
433 type(in_alignment
), fields_
{std::move(in_fields
)}
437 bool lst::structure_type::_is_equal(const type
& base_other
) const noexcept
439 const auto &other
= static_cast<decltype(*this)&>(base_other
);
441 return fields_are_equal(this->fields_
, other
.fields_
);
444 lst::type::cuptr
lst::structure_type::copy() const
446 structure_type::fields copy_of_fields
;
448 copy_of_fields
.reserve(fields_
.size());
449 for (const auto& field
: fields_
) {
450 copy_of_fields
.emplace_back(lttng::make_unique
<lst::field
>(
451 field
->name
, field
->get_type().copy()));
454 return lttng::make_unique
<structure_type
>(alignment
, std::move(copy_of_fields
));
457 void lst::structure_type::accept(type_visitor
& visitor
) const
459 visitor
.visit(*this);