2 * Copyright (c) 2023 Philippe Proulx <pproulx@efficios.com>
4 * SPDX-License-Identifier: MIT
7 #ifndef BABELTRACE_CPP_COMMON_BT2_SELF_COMPONENT_PORT_HPP
8 #define BABELTRACE_CPP_COMMON_BT2_SELF_COMPONENT_PORT_HPP
12 #include <babeltrace2/babeltrace.h>
14 #include "logging.hpp"
16 #include "common/assert.h"
17 #include "cpp-common/bt2c/c-string-view.hpp"
19 #include "borrowed-object-iterator.hpp"
20 #include "borrowed-object.hpp"
21 #include "component-port.hpp"
22 #include "message-iterator.hpp"
26 class SelfSourceComponent;
27 class SelfFilterComponent;
28 class SelfSinkComponent;
30 class SelfComponent final : public BorrowedObject<bt_self_component>
33 explicit SelfComponent(const LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr}
37 explicit SelfComponent(bt_self_component_source * const libObjPtr) noexcept :
38 _ThisBorrowedObject {bt_self_component_source_as_self_component(libObjPtr)}
42 explicit SelfComponent(bt_self_component_filter * const libObjPtr) noexcept :
43 _ThisBorrowedObject {bt_self_component_filter_as_self_component(libObjPtr)}
47 explicit SelfComponent(bt_self_component_sink * const libObjPtr) noexcept :
48 _ThisBorrowedObject {bt_self_component_sink_as_self_component(libObjPtr)}
52 /* Not `explicit` to make them behave like copy constructors */
53 SelfComponent(SelfSourceComponent other) noexcept;
54 SelfComponent(SelfFilterComponent other) noexcept;
55 SelfComponent(SelfSinkComponent other) noexcept;
57 SelfComponent operator=(SelfSourceComponent other) noexcept;
58 SelfComponent operator=(SelfFilterComponent other) noexcept;
59 SelfComponent operator=(SelfSinkComponent other) noexcept;
61 ConstComponent asConstComponent() const noexcept
63 return ConstComponent {bt_self_component_as_component(this->libObjPtr())};
66 bool isSource() const noexcept
68 return this->asConstComponent().isSource();
71 bool isFilter() const noexcept
73 return this->asConstComponent().isFilter();
76 bool isSink() const noexcept
78 return this->asConstComponent().isSink();
81 bt2c::CStringView name() const noexcept
83 return this->asConstComponent().name();
86 LoggingLevel loggingLevel() const noexcept
88 return this->asConstComponent().loggingLevel();
91 std::uint64_t graphMipVersion() const noexcept
93 return bt_self_component_get_graph_mip_version(this->libObjPtr());
97 T& data() const noexcept
99 return *static_cast<T *>(bt_self_component_get_data(this->libObjPtr()));
102 template <typename T>
103 void data(T& obj) const noexcept
105 bt_self_component_set_data(this->libObjPtr(), static_cast<void *>(&obj));
108 bt2::TraceClass::Shared createTraceClass() const
110 const auto libObjPtr = bt_trace_class_create(this->libObjPtr());
113 throw MemoryError {};
116 return bt2::TraceClass::Shared::createWithoutRef(libObjPtr);
119 bt2::ClockClass::Shared createClockClass() const
121 const auto libObjPtr = bt_clock_class_create(this->libObjPtr());
124 throw MemoryError {};
127 return bt2::ClockClass::Shared::createWithoutRef(libObjPtr);
131 template <typename LibObjT>
132 class SelfSpecificComponent : public BorrowedObject<LibObjT>
135 using typename BorrowedObject<LibObjT>::_ThisBorrowedObject;
138 using typename BorrowedObject<LibObjT>::LibObjPtr;
141 explicit SelfSpecificComponent(const LibObjPtr libObjPtr) noexcept :
142 _ThisBorrowedObject {libObjPtr}
146 template <typename PortT, typename LibPortT, typename AddPortFuncT, typename DataT>
147 PortT _addPort(const char * const name, DataT * const data, AddPortFuncT&& func) const
149 LibPortT *libPortPtr;
151 const auto status = func(this->libObjPtr(), name, static_cast<void *>(data), &libPortPtr);
154 case BT_SELF_COMPONENT_ADD_PORT_STATUS_OK:
155 return PortT {libPortPtr};
156 case BT_SELF_COMPONENT_ADD_PORT_STATUS_MEMORY_ERROR:
157 throw MemoryError {};
158 case BT_SELF_COMPONENT_ADD_PORT_STATUS_ERROR:
166 bt2c::CStringView name() const noexcept
168 return this->_selfComponent().name();
171 LoggingLevel loggingLevel() const noexcept
173 return this->_selfComponent().loggingLevel();
176 std::uint64_t graphMipVersion() const noexcept
178 return this->_selfComponent().graphMipVersion();
181 template <typename T>
182 T& data() const noexcept
184 return this->_selfComponent().template data<T>();
187 template <typename T>
188 void data(T& obj) const noexcept
190 this->_selfComponent().data(obj);
194 SelfComponent _selfComponent() const noexcept
196 return SelfComponent {this->libObjPtr()};
202 template <typename LibSelfCompT, typename LibSelfCompPortPtrT>
203 struct SelfComponentPortsSpec;
206 struct SelfComponentPortsSpec<bt_self_component_source, bt_self_component_port_output> final
208 static std::uint64_t portCount(bt_self_component_source * const libCompPtr) noexcept
210 return bt_component_source_get_output_port_count(
211 bt_self_component_source_as_component_source(libCompPtr));
214 static bt_self_component_port_output *portByIndex(bt_self_component_source * const libCompPtr,
215 const std::uint64_t index) noexcept
217 return bt_self_component_source_borrow_output_port_by_index(libCompPtr, index);
220 static bt_self_component_port_output *portByName(bt_self_component_source * const libCompPtr,
221 const char * const name) noexcept
223 return bt_self_component_source_borrow_output_port_by_name(libCompPtr, name);
228 struct SelfComponentPortsSpec<bt_self_component_filter, bt_self_component_port_output> final
230 static std::uint64_t portCount(bt_self_component_filter * const libCompPtr) noexcept
232 return bt_component_filter_get_output_port_count(
233 bt_self_component_filter_as_component_filter(libCompPtr));
236 static bt_self_component_port_output *portByIndex(bt_self_component_filter * const libCompPtr,
237 const std::uint64_t index) noexcept
239 return bt_self_component_filter_borrow_output_port_by_index(libCompPtr, index);
242 static bt_self_component_port_output *portByName(bt_self_component_filter * const libCompPtr,
243 const char * const name) noexcept
245 return bt_self_component_filter_borrow_output_port_by_name(libCompPtr, name);
250 struct SelfComponentPortsSpec<bt_self_component_filter, bt_self_component_port_input> final
252 static std::uint64_t portCount(bt_self_component_filter * const libCompPtr) noexcept
254 return bt_component_filter_get_input_port_count(
255 bt_self_component_filter_as_component_filter(libCompPtr));
258 static bt_self_component_port_input *portByIndex(bt_self_component_filter * const libCompPtr,
259 const std::uint64_t index) noexcept
261 return bt_self_component_filter_borrow_input_port_by_index(libCompPtr, index);
264 static bt_self_component_port_input *portByName(bt_self_component_filter * const libCompPtr,
265 const char * const name) noexcept
267 return bt_self_component_filter_borrow_input_port_by_name(libCompPtr, name);
272 struct SelfComponentPortsSpec<bt_self_component_sink, bt_self_component_port_input> final
274 static std::uint64_t portCount(bt_self_component_sink * const libCompPtr) noexcept
276 return bt_component_sink_get_input_port_count(
277 bt_self_component_sink_as_component_sink(libCompPtr));
280 static bt_self_component_port_input *portByIndex(bt_self_component_sink * const libCompPtr,
281 const std::uint64_t index) noexcept
283 return bt_self_component_sink_borrow_input_port_by_index(libCompPtr, index);
286 static bt_self_component_port_input *portByName(bt_self_component_sink * const libCompPtr,
287 const char * const name) noexcept
289 return bt_self_component_sink_borrow_input_port_by_name(libCompPtr, name);
293 } /* namespace internal */
295 template <typename LibSelfCompPortT, typename LibPortT>
296 class SelfComponentPort;
298 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
299 class SelfComponentPorts final : public BorrowedObject<LibSelfCompT>
302 using typename BorrowedObject<LibSelfCompT>::_ThisBorrowedObject;
303 using _Spec = internal::SelfComponentPortsSpec<LibSelfCompT, LibSelfCompPortT>;
306 using typename BorrowedObject<LibSelfCompT>::LibObjPtr;
307 using Port = SelfComponentPort<LibSelfCompPortT, LibPortT>;
308 using Iterator = BorrowedObjectIterator<SelfComponentPorts>;
310 explicit SelfComponentPorts(const LibObjPtr libObjPtr) noexcept :
311 _ThisBorrowedObject {libObjPtr}
315 std::uint64_t length() const noexcept
317 return _Spec::portCount(this->libObjPtr());
320 Port operator[](std::uint64_t index) const noexcept;
321 Port operator[](bt2c::CStringView name) const noexcept;
322 Iterator begin() const noexcept;
323 Iterator end() const noexcept;
324 Port front() const noexcept;
325 Port back() const noexcept;
328 class SelfSourceComponent final : public SelfSpecificComponent<bt_self_component_source>
331 using OutputPorts = SelfComponentPorts<bt_self_component_source, bt_self_component_port_output,
332 const bt_port_output>;
334 explicit SelfSourceComponent(bt_self_component_source * const libObjPtr) noexcept :
335 SelfSpecificComponent {libObjPtr}
339 ConstSourceComponent asConstComponent() const noexcept
341 return ConstSourceComponent {
342 bt_self_component_source_as_component_source(this->libObjPtr())};
345 template <typename DataT>
346 OutputPorts::Port addOutputPort(bt2c::CStringView name, DataT& data) const;
348 OutputPorts::Port addOutputPort(bt2c::CStringView name) const;
350 OutputPorts outputPorts() const noexcept;
353 template <typename DataT>
354 OutputPorts::Port _addOutputPort(const char *name, DataT *data) const;
357 class SelfFilterComponent final : public SelfSpecificComponent<bt_self_component_filter>
360 using InputPorts = SelfComponentPorts<bt_self_component_filter, bt_self_component_port_input,
361 const bt_port_input>;
362 using OutputPorts = SelfComponentPorts<bt_self_component_filter, bt_self_component_port_output,
363 const bt_port_output>;
365 explicit SelfFilterComponent(bt_self_component_filter * const libObjPtr) noexcept :
366 SelfSpecificComponent {libObjPtr}
370 ConstFilterComponent asConstComponent() const noexcept
372 return ConstFilterComponent {
373 bt_self_component_filter_as_component_filter(this->libObjPtr())};
376 template <typename DataT>
377 InputPorts::Port addInputPort(bt2c::CStringView name, DataT& data) const;
379 InputPorts::Port addInputPort(bt2c::CStringView name) const;
381 InputPorts inputPorts() const noexcept;
383 template <typename DataT>
384 OutputPorts::Port addOutputPort(bt2c::CStringView name, DataT& data) const;
386 OutputPorts::Port addOutputPort(bt2c::CStringView name) const;
388 OutputPorts outputPorts() const noexcept;
391 template <typename DataT>
392 InputPorts::Port _addInputPort(const char *name, DataT *data) const;
394 template <typename DataT>
395 OutputPorts::Port _addOutputPort(const char *name, DataT *data) const;
398 class SelfSinkComponent final : public SelfSpecificComponent<bt_self_component_sink>
401 using InputPorts = SelfComponentPorts<bt_self_component_sink, bt_self_component_port_input,
402 const bt_port_input>;
404 explicit SelfSinkComponent(bt_self_component_sink * const libObjPtr) noexcept :
405 SelfSpecificComponent {libObjPtr}
409 ConstSinkComponent asConstComponent() const noexcept
411 return ConstSinkComponent {bt_self_component_sink_as_component_sink(this->libObjPtr())};
414 MessageIterator::Shared createMessageIterator(InputPorts::Port port) const;
416 bool isInterrupted() const noexcept
418 return static_cast<bool>(bt_self_component_sink_is_interrupted(this->libObjPtr()));
421 template <typename DataT>
422 InputPorts::Port addInputPort(bt2c::CStringView name, DataT& data) const;
424 InputPorts::Port addInputPort(bt2c::CStringView name) const;
426 InputPorts inputPorts() const noexcept;
429 template <typename DataT>
430 InputPorts::Port _addInputPort(const char *name, DataT *data) const;
433 inline SelfComponent::SelfComponent(const SelfSourceComponent other) noexcept :
434 SelfComponent {other.libObjPtr()}
438 inline SelfComponent::SelfComponent(const SelfFilterComponent other) noexcept :
439 SelfComponent {other.libObjPtr()}
443 inline SelfComponent::SelfComponent(const SelfSinkComponent other) noexcept :
444 SelfComponent {other.libObjPtr()}
448 inline SelfComponent SelfComponent::operator=(const SelfSourceComponent other) noexcept
450 *this = SelfComponent {other.libObjPtr()};
454 inline SelfComponent SelfComponent::operator=(const SelfFilterComponent other) noexcept
456 *this = SelfComponent {other.libObjPtr()};
460 inline SelfComponent SelfComponent::operator=(const SelfSinkComponent other) noexcept
462 *this = SelfComponent {other.libObjPtr()};
468 template <typename LibObjT>
469 struct SelfComponentPortSpec;
471 /* Functions specific to self component input ports */
473 struct SelfComponentPortSpec<bt_self_component_port_input> final
475 static bt_self_component_port *
476 asSelfCompPort(bt_self_component_port_input * const libObjPtr) noexcept
478 return bt_self_component_port_input_as_self_component_port(libObjPtr);
481 static const bt_port_input *
482 asConstPort(const bt_self_component_port_input * const libObjPtr) noexcept
484 return bt_self_component_port_input_as_port_input(libObjPtr);
488 /* Functions specific to self component output ports */
490 struct SelfComponentPortSpec<bt_self_component_port_output> final
492 static bt_self_component_port *
493 asSelfCompPort(bt_self_component_port_output * const libObjPtr) noexcept
495 return bt_self_component_port_output_as_self_component_port(libObjPtr);
498 static const bt_port_output *
499 asConstPort(bt_self_component_port_output * const libObjPtr) noexcept
501 return bt_self_component_port_output_as_port_output(libObjPtr);
505 } /* namespace internal */
507 template <typename LibSelfCompPortT, typename LibPortT>
508 class SelfComponentPort final : public BorrowedObject<LibSelfCompPortT>
511 using typename BorrowedObject<LibSelfCompPortT>::LibObjPtr;
513 explicit SelfComponentPort(const LibObjPtr libObjPtr) noexcept :
514 BorrowedObject<LibSelfCompPortT> {libObjPtr}
518 ConstPort<LibPortT> asConstPort() const noexcept
520 return ConstPort<LibPortT> {
521 internal::SelfComponentPortSpec<LibSelfCompPortT>::asConstPort(this->libObjPtr())};
524 bt2c::CStringView name() const noexcept
526 return this->asConstPort().name();
529 bool isConnected() const noexcept
531 return this->asConstPort().isConnected();
534 SelfComponent component() const noexcept
536 return SelfComponent {bt_self_component_port_borrow_component(this->_libSelfCompPortPtr())};
539 template <typename T>
540 T& data() const noexcept
542 *static_cast<T *>(bt_self_component_port_get_data(this->_libSelfCompPortPtr()));
546 bt_self_component_port *_libSelfCompPortPtr() const noexcept
548 return internal::SelfComponentPortSpec<LibSelfCompPortT>::asSelfCompPort(this->libObjPtr());
552 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
553 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
554 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::operator[](
555 const std::uint64_t index) const noexcept
557 return Port {_Spec::portByIndex(this->libObjPtr(), index)};
560 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
561 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
562 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::operator[](
563 const bt2c::CStringView name) const noexcept
565 return Port {_Spec::portByName(this->libObjPtr(), name)};
568 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
569 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Iterator
570 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::begin() const noexcept
572 return Iterator {*this, 0};
575 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
576 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Iterator
577 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::end() const noexcept
579 return Iterator {*this, this->length()};
582 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
583 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
584 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::front() const noexcept
589 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
590 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
591 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::back() const noexcept
593 return (*this)[this->length() - 1];
596 using SelfComponentInputPort = SelfComponentPort<bt_self_component_port_input, const bt_port_input>;
598 using SelfComponentOutputPort =
599 SelfComponentPort<bt_self_component_port_output, const bt_port_output>;
601 template <typename DataT>
602 SelfSourceComponent::OutputPorts::Port SelfSourceComponent::_addOutputPort(const char * const name,
603 DataT * const data) const
605 return this->_addPort<SelfSourceComponent::OutputPorts::Port, bt_self_component_port_output>(
606 name, data, bt_self_component_source_add_output_port);
609 template <typename DataT>
610 SelfSourceComponent::OutputPorts::Port
611 SelfSourceComponent::addOutputPort(const bt2c::CStringView name, DataT& data) const
613 return this->_addOutputPort(name, &data);
616 inline SelfSourceComponent::OutputPorts::Port
617 SelfSourceComponent::addOutputPort(const bt2c::CStringView name) const
619 return this->_addOutputPort<void>(name, nullptr);
622 inline SelfSourceComponent::OutputPorts SelfSourceComponent::outputPorts() const noexcept
624 return OutputPorts {this->libObjPtr()};
627 template <typename DataT>
628 SelfFilterComponent::OutputPorts::Port SelfFilterComponent::_addOutputPort(const char * const name,
629 DataT * const data) const
631 return this->_addPort<SelfFilterComponent::OutputPorts::Port, bt_self_component_port_output>(
632 name, data, bt_self_component_filter_add_output_port);
635 template <typename DataT>
636 SelfFilterComponent::OutputPorts::Port
637 SelfFilterComponent::addOutputPort(const bt2c::CStringView name, DataT& data) const
639 return this->_addOutputPort(name, &data);
642 inline SelfFilterComponent::OutputPorts::Port
643 SelfFilterComponent::addOutputPort(const bt2c::CStringView name) const
645 return this->_addOutputPort<void>(name, nullptr);
648 inline SelfFilterComponent::OutputPorts SelfFilterComponent::outputPorts() const noexcept
650 return OutputPorts {this->libObjPtr()};
653 template <typename DataT>
654 SelfFilterComponent::InputPorts::Port SelfFilterComponent::_addInputPort(const char * const name,
655 DataT * const data) const
657 return this->_addPort<SelfFilterComponent::InputPorts::Port, bt_self_component_port_input>(
658 name, data, bt_self_component_filter_add_input_port);
661 template <typename DataT>
662 SelfFilterComponent::InputPorts::Port
663 SelfFilterComponent::addInputPort(const bt2c::CStringView name, DataT& data) const
665 return this->_addInputPort(name, &data);
668 inline SelfFilterComponent::InputPorts::Port
669 SelfFilterComponent::addInputPort(const bt2c::CStringView name) const
671 return this->_addInputPort<void>(name, nullptr);
674 inline SelfFilterComponent::InputPorts SelfFilterComponent::inputPorts() const noexcept
676 return InputPorts {this->libObjPtr()};
679 inline MessageIterator::Shared
680 SelfSinkComponent::createMessageIterator(const InputPorts::Port port) const
682 bt_message_iterator *libMsgIterPtr = nullptr;
684 const auto status = bt_message_iterator_create_from_sink_component(
685 this->libObjPtr(), port.libObjPtr(), &libMsgIterPtr);
688 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK:
689 BT_ASSERT(libMsgIterPtr);
690 return MessageIterator::Shared::createWithoutRef(libMsgIterPtr);
691 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_MEMORY_ERROR:
692 throw MemoryError {};
693 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_ERROR:
700 template <typename DataT>
701 SelfSinkComponent::InputPorts::Port SelfSinkComponent::_addInputPort(const char * const name,
702 DataT * const data) const
704 return this->_addPort<SelfSinkComponent::InputPorts::Port, bt_self_component_port_input>(
705 name, data, bt_self_component_sink_add_input_port);
708 template <typename DataT>
709 SelfSinkComponent::InputPorts::Port SelfSinkComponent::addInputPort(const bt2c::CStringView name,
712 return this->_addInputPort(name, &data);
715 inline SelfSinkComponent::InputPorts::Port
716 SelfSinkComponent::addInputPort(const bt2c::CStringView name) const
718 return this->_addInputPort<void>(name, nullptr);
721 inline SelfSinkComponent::InputPorts SelfSinkComponent::inputPorts() const noexcept
723 return InputPorts {this->libObjPtr()};
726 } /* namespace bt2 */
728 #endif /* BABELTRACE_CPP_COMMON_BT2_SELF_COMPONENT_PORT_HPP */