#define LTTNG_FIELD_H
#include <common/format.hpp>
+#include <common/make-unique.hpp>
#include <vendor/optional.hpp>
bool operator==(const type& other) const noexcept;
bool operator!=(const type& other) const noexcept;
virtual ~type();
+
+ /* Obtain an independent copy of `type`. */
+ virtual type::cuptr copy() const = 0;
+
virtual void accept(type_visitor& visitor) const = 0;
const unsigned int alignment;
base base,
roles roles = {});
+ virtual type::cuptr copy() const override;
+
virtual void accept(type_visitor& visitor) const override;
const enum byte_order byte_order;
unsigned int exponent_digits,
unsigned int mantissa_digits);
+ virtual type::cuptr copy() const override final;
+
virtual void accept(type_visitor& visitor) const override final;
const enum byte_order byte_order;
{
}
- /* Mapping with an implicit value. */
- enumeration_mapping(std::string in_name) : name{std::move(in_name)}
+ enumeration_mapping(std::string in_name, MappingIntegerType value) : name{std::move(in_name)}, range{value, value}
{
}
}
const std::string name;
- const nonstd::optional<range_t> range;
+ /*
+ * Only one range per mapping is supported for the moment as
+ * the tracers (and CTF 1.8) can't express multiple ranges per
+ * mapping, which is allowed by CTF 2.
+ */
+ const range_t range;
};
template <class MappingIntegerType>
}
} /* namespace details */
-template <class MappingIntegerType>
+template <typename MappingIntegerType>
class typed_enumeration_type : public enumeration_type {
public:
using mapping = details::enumeration_mapping<MappingIntegerType>;
integer_type::signedness::UNSIGNED,
in_base,
std::move(in_roles)),
- _mappings{std::move(in_mappings)}
+ mappings_{std::move(in_mappings)}
+ {
+ }
+
+ virtual type::cuptr copy() const override
{
+ return lttng::make_unique<typed_enumeration_type<MappingIntegerType>>(
+ alignment, byte_order, size, base_, mappings_, roles_);
}
virtual void accept(type_visitor& visitor) const override final;
- const std::shared_ptr<const mappings> _mappings;
+ const std::shared_ptr<const mappings> mappings_;
private:
virtual bool _is_equal(const type& base_other) const noexcept override final
const auto& other = static_cast<const typed_enumeration_type<MappingIntegerType>&>(
base_other);
- return integer_type::_is_equal(base_other) && *this->_mappings == *other._mappings;
+ return integer_type::_is_equal(base_other) && *this->mappings_ == *other.mappings_;
}
};
type::cuptr element_type,
uint64_t in_length);
+ virtual type::cuptr copy() const override final;
+
virtual void accept(type_visitor& visitor) const override final;
const uint64_t length;
type::cuptr element_type,
field_location length_field_location);
+ virtual type::cuptr copy() const override final;
+
virtual void accept(type_visitor& visitor) const override final;
const field_location length_field_location;
public:
enum class role {
/* Packet header field class specific role. */
- TRACE_CLASS_UUID,
+ METADATA_STREAM_UUID,
};
using roles = std::vector<role>;
static_length_blob_type(unsigned int alignment, uint64_t in_length_bytes, roles roles = {});
+ virtual type::cuptr copy() const override final;
+
virtual void accept(type_visitor& visitor) const override final;
const uint64_t length_bytes;
public:
dynamic_length_blob_type(unsigned int alignment, field_location length_field_location);
+ virtual type::cuptr copy() const override final;
+
virtual void accept(type_visitor& visitor) const override final;
const field_location length_field_location;
public:
static_length_string_type(
unsigned int alignment, enum encoding in_encoding, uint64_t length);
+
+ virtual type::cuptr copy() const override final;
+
virtual void accept(type_visitor& visitor) const override final;
const uint64_t length;
dynamic_length_string_type(unsigned int alignment,
enum encoding in_encoding,
field_location length_field_location);
+
+ virtual type::cuptr copy() const override final;
+
virtual void accept(type_visitor& visitor) const override final;
const field_location length_field_location;
class null_terminated_string_type : public string_type {
public:
null_terminated_string_type(unsigned int alignment, enum encoding in_encoding);
+
+ virtual type::cuptr copy() const override final;
+
virtual void accept(type_visitor& visitor) const override final;
};
structure_type(unsigned int alignment, fields in_fields);
+ virtual type::cuptr copy() const override final;
+
virtual void accept(type_visitor& visitor) const override final;
- const fields _fields;
+ const fields fields_;
private:
virtual bool _is_equal(const type& base_other) const noexcept override final;
};
-template <class MappingIntegerType>
+template <typename MappingIntegerType>
class variant_type : public type {
static_assert(std::is_same<MappingIntegerType,
unsigned_enumeration_type::mapping::range_t::
choices in_choices) :
type(in_alignment),
selector_field_location{std::move(in_selector_field_location)},
- _choices{std::move(in_choices)}
+ choices_{std::move(in_choices)}
+ {
+ }
+
+ virtual type::cuptr copy() const override final
{
+ choices copy_of_choices;
+
+ copy_of_choices.reserve(choices_.size());
+ for (const auto& current_choice : choices_) {
+ copy_of_choices.emplace_back(
+ current_choice.first, current_choice.second->copy());
+ }
+
+ return lttng::make_unique<variant_type<MappingIntegerType>>(
+ alignment, selector_field_location, std::move(copy_of_choices));
}
virtual void accept(type_visitor& visitor) const override final;
const field_location selector_field_location;
- const choices _choices;
+ const choices choices_;
private:
static bool _choices_are_equal(const choices& a, const choices& b)
const auto& other = static_cast<decltype(*this)&>(base_other);
return selector_field_location == other.selector_field_location &&
- _choices_are_equal(_choices, other._choices);
+ _choices_are_equal(choices_, other.choices_);
}
};
} /* namespace lttng */
/*
+ * Field formatters for libfmt.
+ *
* Due to a bug in g++ < 7.1, this specialization must be enclosed in the fmt namespace,
* see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480.
*/
return format_to(ctx.out(), location_str);
}
};
+
+namespace details {
+template <typename MappingIntegerType>
+::std::string format_mapping_range(typename lttng::sessiond::trace::typed_enumeration_type<
+ MappingIntegerType>::mapping::range_t range)
+{
+ if (range.begin == range.end) {
+ return ::fmt::format("[{}]", range.begin);
+ } else {
+ return ::fmt::format("[{}, {}]", range.begin, range.end);
+ }
+}
+} /* namespace details */
+
+template <>
+struct formatter<typename lttng::sessiond::trace::signed_enumeration_type::mapping::range_t>
+ : formatter<std::string> {
+ template <typename FormatCtx>
+ typename FormatCtx::iterator
+ format(typename lttng::sessiond::trace::signed_enumeration_type::mapping::range_t range,
+ FormatCtx& ctx)
+ {
+ return format_to(ctx.out(),
+ details::format_mapping_range<
+ lttng::sessiond::trace::signed_enumeration_type::
+ mapping::range_t::range_integer_t>(
+ range));
+ }
+};
+
+template <>
+struct formatter<typename lttng::sessiond::trace::unsigned_enumeration_type::mapping::range_t>
+ : formatter<std::string> {
+ template <typename FormatCtx>
+ typename FormatCtx::iterator
+ format(typename lttng::sessiond::trace::unsigned_enumeration_type::mapping::range_t range,
+ FormatCtx& ctx)
+ {
+ return format_to(ctx.out(),
+ details::format_mapping_range<
+ lttng::sessiond::trace::unsigned_enumeration_type::
+ mapping::range_t::range_integer_t>(
+ range));
+ }
+};
+
} /* namespace fmt */
#endif /* LTTNG_FIELD_H */