Add common `ctf::ir` CTF IR classes
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Fri, 3 Nov 2023 18:32:50 +0000 (18:32 +0000)
committerSimon Marchi <simon.marchi@efficios.com>
Wed, 4 Sep 2024 19:05:14 +0000 (15:05 -0400)
commita0197f124aa95c055299c31d44be2a0566113fad
tree168648edaf03caa5820a1381dd966b2475a9fe48
parent5b5b29dadb9aa657158fc8a2e2e790b95ae195e2
Add common `ctf::ir` CTF IR classes

This patch adds common CTF IR class templates to the new
`src/plugins/ctf/common/metadata/ctf-ir.hpp` header.

The purpose of those new class templates is to have a common CTF IR
class hierarchy for all the `ctf` plugin component classes. This CTF IR
model is based on the CTF 2 model.

Although the file looks intimidating, it's pretty straightforward:

• The class hierarchy, under the `ctf::ir` namespace, (omitting template
  parameters) is as such:

      TraceCls
      DataStreamCls
      EventRecordCls
      ClkCls
      FieldLoc
      StructFieldMemberCls
      VariantFcOpt
      Fc
        FixedLenBitArrayFc
          FixedLenBitMapFc
          FixedLenBoolFc
          FixedLenFloatFc
          FixedLenIntFc
            FixedLenUIntFc
            FixedLenSIntFc
        VarLengthIntFc
          VarLengthUIntFc
          VarLengthSIntFc
        StrFc
          NullTerminatedStrFc
          NonNullTerminatedStrFc
            StaticLenStrFc
            DynLenStrFc
        BlobFc
          StaticLenBlobFc
          DynLenBlobFc
        ArrayFc
          StaticLenArrayFc
          DynLenArrayFc
        StructFc
        OptionalFc
          OptionalWithBoolSelFc
          OptionalWithIntSelFc
            OptionalWithUIntSelFc
            OptionalWithSIntSelFc
        VariantFc
          VariantWithUIntSelFc
          VariantWithSIntSelFc

• Each class template has the `UserMixinsT` template parameter.

  `UserMixinsT` is expected to be a user mixin container, a type
  defining the following nested types (user mixins):

  ‣ `ClkCls`
  ‣ `DataStreamCls`
  ‣ `DynLenArrayFc`
  ‣ `DynLenBlobFc`
  ‣ `DynLenStrFc`
  ‣ `EventRecordCls`
  ‣ `Fc`
  ‣ `FieldLoc`
  ‣ `FixedLenBitArrayFc`
  ‣ `FixedLenBitMapFc`
  ‣ `FixedLenBoolFc`
  ‣ `FixedLenIntFc`
  ‣ `FixedLenUIntFc`
  ‣ `OptionalFc`
  ‣ `OptionalWithBoolSelFc`
  ‣ `OptionalWithSIntSelFc`
  ‣ `OptionalWithUIntSelFc`
  ‣ `StaticLenArrayFc`
  ‣ `StaticLenBlobFc`
  ‣ `StaticLenStrFc`
  ‣ `StructFc`
  ‣ `StructFieldMemberCls`
  ‣ `TraceCls`
  ‣ `VariantFcOpt`
  ‣ `VariantWithSIntSelFc`
  ‣ `VariantWithUIntSelFc`
  ‣ `VarLenIntFc`
  ‣ `VarLenUIntFc`

• Most class templates inherit a given user mixin. For example,
  `FixedLenBoolFc` inherits `UserMixinsT::FixedLenBoolFc`. This makes it
  possible for the user to inject data and methods into the class while
  keeping the hierarchy and common features.

• A class template which inherits a user mixin M has a constructor which
  accepts an instance of M by value to initialize this part of
  the object.

  If a class template C which inherits a user mixin also inherits
  another class template inheriting another user mixin, then the
  constructor of C accepts both mixins. For example,
  FixedLenUIntFc::FixedLenUIntFc() accepts three mixins: field class,
  fixed-length bit array field class, and fixed-length integer
  field class.

• `Fc` has the typical asXyz() and isXyz() methods.

  To make isXyz() methods more efficient, `FcType` enumerators are
  bitwise compositions of `FcTypeTraits` values (traits/features).

• The `FcVisitor` and `ConstFcVisitor` base classes are available to
  visit field classes through the virtual Fc::accept() methods.

• There are a few internal mixins to share common members:

  `WithAttrsMixin`:
      Optional attributes.

  `WithPrefDispBaseMixin`:
      Preferred display base.

  `WithMappingsMixin`:
      Integer mappings.

  `WithLibCls`:
      libbabeltrace2 class.

  `UIntFcMixin`:
      Unsigned integer field roles.

  `StaticLenFcMixin`:
      Integral length.

  `DynLenFcMixin`:
      Length field location.

• The API offers `DefUserMixins` which defines empty user mixins to act
  as a base user mixin container structure.

Now, this is how you would use this API:

• Define your own user mixin container structure which inherits
  `ctf::ir::DefUserMixins`, defining the user mixins you need to add
  data and methods to specific common classes.

• Define aliases for each `ctf::ir` class template you need, using your
  user mixin container structure as the `UserMixinsT`
  template parameter.

• Create convenient object creation functions to construct specific CTF
  IR objects from parameters, hiding the internal user mixin details.

As an example, this builds and works as expected:

    #include <string>
    #include <iostream>

    #include "plugins/ctf/common/metadata/ctf-ir.hpp"

    // user mixin container
    struct MyMixins : ctf::ir::DefUserMixins
    {
        // structure field class mixin
        class StructFc
        {
        public:
            explicit StructFc(std::string favoriteKebSinger) :
                _mFavoriteKebSinger {std::move(favoriteKebSinger)}
            {
            }

            const std::string& favoriteKebSinger() const noexcept
            {
                return _mFavoriteKebSinger;
            }

        private:
            std::string _mFavoriteKebSinger;
        };
    };

    // custom object aliases
    using MyNullTerminatedStrFc = ctf::ir::NullTerminatedStrFc<MyMixins>;
    using MyStructFc = ctf::ir::StructFc<MyMixins>;
    using MyTraceCls = ctf::ir::TraceCls<MyMixins>;

    int main()
    {
        // create structure field class, constructing a `MyMixins::StructFc`
        MyStructFc::MemberClasses memberClasses;

        memberClasses.emplace_back(
            MyMixins::StructFieldMemberCls {}, "meow",
            bt2c::makeUnique<MyNullTerminatedStrFc>(MyMixins::Fc {}));

        auto pktHeaderFc = bt2c::makeUnique<MyStructFc>(
            MyMixins::Fc {},
            MyMixins::StructFc {"Claude Dubois"},
            std::move(memberClasses)
        );

        // create trace class
        MyTraceCls tc {
            MyMixins::TraceCls {},
            bt2s::nullopt, bt2s::nullopt, bt2s::nullopt,
            {}, std::move(pktHeaderFc)
        };

        // read custom user property
        std::cout << tc.pktHeaderFc()->favoriteKebSinger() << '\n';
    }

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: Ib4785c9a2f675bdc1415b149e9b57de1339f475e
Reviewed-on: https://review.lttng.org/c/babeltrace/+/7708
Reviewed-on: https://review.lttng.org/c/babeltrace/+/12253
CI-Build: Simon Marchi <simon.marchi@efficios.com>
Tested-by: jenkins <jenkins@lttng.org>
src/Makefile.am
src/plugins/ctf/common/metadata/ctf-ir.cpp [new file with mode: 0644]
src/plugins/ctf/common/metadata/ctf-ir.hpp [new file with mode: 0644]
This page took 0.026045 seconds and 4 git commands to generate.