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 "cpp-common/bt2c/c-string-view.hpp"
18 #include "borrowed-object-iterator.hpp"
19 #include "borrowed-object.hpp"
20 #include "component-port.hpp"
21 #include "message-iterator.hpp"
25 class SelfSourceComponent;
26 class SelfFilterComponent;
27 class SelfSinkComponent;
29 class SelfComponent final : public BorrowedObject<bt_self_component>
32 explicit SelfComponent(const LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr}
36 explicit SelfComponent(bt_self_component_source * const libObjPtr) noexcept :
37 _ThisBorrowedObject {bt_self_component_source_as_self_component(libObjPtr)}
41 explicit SelfComponent(bt_self_component_filter * const libObjPtr) noexcept :
42 _ThisBorrowedObject {bt_self_component_filter_as_self_component(libObjPtr)}
46 explicit SelfComponent(bt_self_component_sink * const libObjPtr) noexcept :
47 _ThisBorrowedObject {bt_self_component_sink_as_self_component(libObjPtr)}
51 /* Not `explicit` to make them behave like copy constructors */
52 SelfComponent(SelfSourceComponent other) noexcept;
53 SelfComponent(SelfFilterComponent other) noexcept;
54 SelfComponent(SelfSinkComponent other) noexcept;
56 SelfComponent operator=(SelfSourceComponent other) noexcept;
57 SelfComponent operator=(SelfFilterComponent other) noexcept;
58 SelfComponent operator=(SelfSinkComponent other) noexcept;
60 ConstComponent asConstComponent() const noexcept
62 return ConstComponent {bt_self_component_as_component(this->libObjPtr())};
65 bool isSource() const noexcept
67 return this->asConstComponent().isSource();
70 bool isFilter() const noexcept
72 return this->asConstComponent().isFilter();
75 bool isSink() const noexcept
77 return this->asConstComponent().isSink();
80 bt2c::CStringView name() const noexcept
82 return this->asConstComponent().name();
85 LoggingLevel loggingLevel() const noexcept
87 return this->asConstComponent().loggingLevel();
90 std::uint64_t graphMipVersion() const noexcept
92 return bt_self_component_get_graph_mip_version(this->libObjPtr());
96 T& data() const noexcept
98 return *static_cast<T *>(bt_self_component_get_data(this->libObjPtr()));
101 template <typename T>
102 SelfComponent data(T& obj) const noexcept
104 bt_self_component_set_data(this->libObjPtr(),
105 const_cast<void *>(static_cast<const void *>(&obj)));
109 bt2::TraceClass::Shared createTraceClass() const
111 const auto libObjPtr = bt_trace_class_create(this->libObjPtr());
114 throw MemoryError {};
117 return bt2::TraceClass::Shared::createWithoutRef(libObjPtr);
120 bt2::ClockClass::Shared createClockClass() const
122 const auto libObjPtr = bt_clock_class_create(this->libObjPtr());
125 throw MemoryError {};
128 return bt2::ClockClass::Shared::createWithoutRef(libObjPtr);
134 template <typename LibObjT>
135 class SelfSpecificComponent : public BorrowedObject<LibObjT>
138 using typename BorrowedObject<LibObjT>::_ThisBorrowedObject;
141 using typename BorrowedObject<LibObjT>::LibObjPtr;
144 explicit SelfSpecificComponent(const LibObjPtr libObjPtr) noexcept :
145 _ThisBorrowedObject {libObjPtr}
149 template <typename PortT, typename LibPortT, typename AddPortFuncT, typename DataT>
150 PortT _addPort(const char * const name, DataT * const data, AddPortFuncT&& func) const
152 LibPortT *libPortPtr;
154 const auto status = func(this->libObjPtr(), name,
155 const_cast<void *>(static_cast<const void *>(data)), &libPortPtr);
158 case BT_SELF_COMPONENT_ADD_PORT_STATUS_OK:
159 return PortT {libPortPtr};
160 case BT_SELF_COMPONENT_ADD_PORT_STATUS_MEMORY_ERROR:
161 throw MemoryError {};
162 case BT_SELF_COMPONENT_ADD_PORT_STATUS_ERROR:
170 bt2c::CStringView name() const noexcept
172 return this->_selfComponent().name();
175 LoggingLevel loggingLevel() const noexcept
177 return this->_selfComponent().loggingLevel();
180 std::uint64_t graphMipVersion() const noexcept
182 return this->_selfComponent().graphMipVersion();
185 template <typename T>
186 T& data() const noexcept
188 return this->_selfComponent().template data<T>();
192 SelfComponent _selfComponent() const noexcept
194 return SelfComponent {this->libObjPtr()};
198 template <typename LibSelfCompT, typename LibSelfCompPortPtrT>
199 struct SelfComponentPortsSpec;
202 struct SelfComponentPortsSpec<bt_self_component_source, bt_self_component_port_output> final
204 static std::uint64_t portCount(bt_self_component_source * const libCompPtr) noexcept
206 return bt_component_source_get_output_port_count(
207 bt_self_component_source_as_component_source(libCompPtr));
210 static bt_self_component_port_output *portByIndex(bt_self_component_source * const libCompPtr,
211 const std::uint64_t index) noexcept
213 return bt_self_component_source_borrow_output_port_by_index(libCompPtr, index);
216 static bt_self_component_port_output *portByName(bt_self_component_source * const libCompPtr,
217 const char * const name) noexcept
219 return bt_self_component_source_borrow_output_port_by_name(libCompPtr, name);
224 struct SelfComponentPortsSpec<bt_self_component_filter, bt_self_component_port_output> final
226 static std::uint64_t portCount(bt_self_component_filter * const libCompPtr) noexcept
228 return bt_component_filter_get_output_port_count(
229 bt_self_component_filter_as_component_filter(libCompPtr));
232 static bt_self_component_port_output *portByIndex(bt_self_component_filter * const libCompPtr,
233 const std::uint64_t index) noexcept
235 return bt_self_component_filter_borrow_output_port_by_index(libCompPtr, index);
238 static bt_self_component_port_output *portByName(bt_self_component_filter * const libCompPtr,
239 const char * const name) noexcept
241 return bt_self_component_filter_borrow_output_port_by_name(libCompPtr, name);
246 struct SelfComponentPortsSpec<bt_self_component_filter, bt_self_component_port_input> final
248 static std::uint64_t portCount(bt_self_component_filter * const libCompPtr) noexcept
250 return bt_component_filter_get_input_port_count(
251 bt_self_component_filter_as_component_filter(libCompPtr));
254 static bt_self_component_port_input *portByIndex(bt_self_component_filter * const libCompPtr,
255 const std::uint64_t index) noexcept
257 return bt_self_component_filter_borrow_input_port_by_index(libCompPtr, index);
260 static bt_self_component_port_input *portByName(bt_self_component_filter * const libCompPtr,
261 const char * const name) noexcept
263 return bt_self_component_filter_borrow_input_port_by_name(libCompPtr, name);
268 struct SelfComponentPortsSpec<bt_self_component_sink, bt_self_component_port_input> final
270 static std::uint64_t portCount(bt_self_component_sink * const libCompPtr) noexcept
272 return bt_component_sink_get_input_port_count(
273 bt_self_component_sink_as_component_sink(libCompPtr));
276 static bt_self_component_port_input *portByIndex(bt_self_component_sink * const libCompPtr,
277 const std::uint64_t index) noexcept
279 return bt_self_component_sink_borrow_input_port_by_index(libCompPtr, index);
282 static bt_self_component_port_input *portByName(bt_self_component_sink * const libCompPtr,
283 const char * const name) noexcept
285 return bt_self_component_sink_borrow_input_port_by_name(libCompPtr, name);
289 } /* namespace internal */
291 template <typename LibSelfCompPortT, typename LibPortT>
292 class SelfComponentPort;
294 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
295 class SelfComponentPorts final : public BorrowedObject<LibSelfCompT>
298 using typename BorrowedObject<LibSelfCompT>::_ThisBorrowedObject;
299 using _Spec = internal::SelfComponentPortsSpec<LibSelfCompT, LibSelfCompPortT>;
302 using typename BorrowedObject<LibSelfCompT>::LibObjPtr;
303 using Port = SelfComponentPort<LibSelfCompPortT, LibPortT>;
304 using Iterator = BorrowedObjectIterator<SelfComponentPorts>;
306 explicit SelfComponentPorts(const LibObjPtr libObjPtr) noexcept :
307 _ThisBorrowedObject {libObjPtr}
311 std::uint64_t length() const noexcept
313 return _Spec::portCount(this->libObjPtr());
316 Port operator[](std::uint64_t index) const noexcept;
317 Port operator[](bt2c::CStringView name) const noexcept;
318 Iterator begin() const noexcept;
319 Iterator end() const noexcept;
320 Port front() const noexcept;
321 Port back() const noexcept;
324 class SelfSourceComponent final : public internal::SelfSpecificComponent<bt_self_component_source>
326 using _ThisSelfSpecificComponent = internal::SelfSpecificComponent<bt_self_component_source>;
329 using OutputPorts = SelfComponentPorts<bt_self_component_source, bt_self_component_port_output,
330 const bt_port_output>;
332 explicit SelfSourceComponent(bt_self_component_source * const libObjPtr) noexcept :
333 SelfSpecificComponent {libObjPtr}
337 ConstSourceComponent asConstComponent() const noexcept
339 return ConstSourceComponent {
340 bt_self_component_source_as_component_source(this->libObjPtr())};
343 using _ThisSelfSpecificComponent::data;
345 template <typename T>
346 SelfSourceComponent data(T& obj) const noexcept
348 this->_selfComponent().data(obj);
352 template <typename DataT>
353 OutputPorts::Port addOutputPort(bt2c::CStringView name, DataT& data) const;
355 OutputPorts::Port addOutputPort(bt2c::CStringView name) const;
357 OutputPorts outputPorts() const noexcept;
360 template <typename DataT>
361 OutputPorts::Port _addOutputPort(const char *name, DataT *data) const;
364 class SelfFilterComponent final : public internal::SelfSpecificComponent<bt_self_component_filter>
366 using _ThisSelfSpecificComponent = internal::SelfSpecificComponent<bt_self_component_filter>;
369 using InputPorts = SelfComponentPorts<bt_self_component_filter, bt_self_component_port_input,
370 const bt_port_input>;
371 using OutputPorts = SelfComponentPorts<bt_self_component_filter, bt_self_component_port_output,
372 const bt_port_output>;
374 explicit SelfFilterComponent(bt_self_component_filter * const libObjPtr) noexcept :
375 SelfSpecificComponent {libObjPtr}
379 ConstFilterComponent asConstComponent() const noexcept
381 return ConstFilterComponent {
382 bt_self_component_filter_as_component_filter(this->libObjPtr())};
385 using _ThisSelfSpecificComponent::data;
387 template <typename T>
388 SelfFilterComponent data(T& obj) const noexcept
390 this->_selfComponent().data(obj);
394 template <typename DataT>
395 InputPorts::Port addInputPort(bt2c::CStringView name, DataT& data) const;
397 InputPorts::Port addInputPort(bt2c::CStringView name) const;
399 InputPorts inputPorts() const noexcept;
401 template <typename DataT>
402 OutputPorts::Port addOutputPort(bt2c::CStringView name, DataT& data) const;
404 OutputPorts::Port addOutputPort(bt2c::CStringView name) const;
406 OutputPorts outputPorts() const noexcept;
409 template <typename DataT>
410 InputPorts::Port _addInputPort(const char *name, DataT *data) const;
412 template <typename DataT>
413 OutputPorts::Port _addOutputPort(const char *name, DataT *data) const;
416 class SelfSinkComponent final : public internal::SelfSpecificComponent<bt_self_component_sink>
418 using _ThisSelfSpecificComponent = internal::SelfSpecificComponent<bt_self_component_sink>;
421 using InputPorts = SelfComponentPorts<bt_self_component_sink, bt_self_component_port_input,
422 const bt_port_input>;
424 explicit SelfSinkComponent(bt_self_component_sink * const libObjPtr) noexcept :
425 SelfSpecificComponent {libObjPtr}
429 ConstSinkComponent asConstComponent() const noexcept
431 return ConstSinkComponent {bt_self_component_sink_as_component_sink(this->libObjPtr())};
434 using _ThisSelfSpecificComponent::data;
436 template <typename T>
437 SelfSinkComponent data(T& obj) const noexcept
439 this->_selfComponent().data(obj);
443 MessageIterator::Shared createMessageIterator(InputPorts::Port port) const;
445 bool isInterrupted() const noexcept
447 return static_cast<bool>(bt_self_component_sink_is_interrupted(this->libObjPtr()));
450 template <typename DataT>
451 InputPorts::Port addInputPort(bt2c::CStringView name, DataT& data) const;
453 InputPorts::Port addInputPort(bt2c::CStringView name) const;
455 InputPorts inputPorts() const noexcept;
458 template <typename DataT>
459 InputPorts::Port _addInputPort(const char *name, DataT *data) const;
462 inline SelfComponent::SelfComponent(const SelfSourceComponent other) noexcept :
463 SelfComponent {other.libObjPtr()}
467 inline SelfComponent::SelfComponent(const SelfFilterComponent other) noexcept :
468 SelfComponent {other.libObjPtr()}
472 inline SelfComponent::SelfComponent(const SelfSinkComponent other) noexcept :
473 SelfComponent {other.libObjPtr()}
477 inline SelfComponent SelfComponent::operator=(const SelfSourceComponent other) noexcept
479 *this = SelfComponent {other.libObjPtr()};
483 inline SelfComponent SelfComponent::operator=(const SelfFilterComponent other) noexcept
485 *this = SelfComponent {other.libObjPtr()};
489 inline SelfComponent SelfComponent::operator=(const SelfSinkComponent other) noexcept
491 *this = SelfComponent {other.libObjPtr()};
497 template <typename LibObjT>
498 struct SelfComponentPortSpec;
500 /* Functions specific to self component input ports */
502 struct SelfComponentPortSpec<bt_self_component_port_input> final
504 static bt_self_component_port *
505 asSelfCompPort(bt_self_component_port_input * const libObjPtr) noexcept
507 return bt_self_component_port_input_as_self_component_port(libObjPtr);
510 static const bt_port_input *
511 asConstPort(const bt_self_component_port_input * const libObjPtr) noexcept
513 return bt_self_component_port_input_as_port_input(libObjPtr);
517 /* Functions specific to self component output ports */
519 struct SelfComponentPortSpec<bt_self_component_port_output> final
521 static bt_self_component_port *
522 asSelfCompPort(bt_self_component_port_output * const libObjPtr) noexcept
524 return bt_self_component_port_output_as_self_component_port(libObjPtr);
527 static const bt_port_output *
528 asConstPort(bt_self_component_port_output * const libObjPtr) noexcept
530 return bt_self_component_port_output_as_port_output(libObjPtr);
534 } /* namespace internal */
536 template <typename LibSelfCompPortT, typename LibPortT>
537 class SelfComponentPort final : public BorrowedObject<LibSelfCompPortT>
540 using typename BorrowedObject<LibSelfCompPortT>::LibObjPtr;
542 explicit SelfComponentPort(const LibObjPtr libObjPtr) noexcept :
543 BorrowedObject<LibSelfCompPortT> {libObjPtr}
547 ConstPort<LibPortT> asConstPort() const noexcept
549 return ConstPort<LibPortT> {
550 internal::SelfComponentPortSpec<LibSelfCompPortT>::asConstPort(this->libObjPtr())};
553 bt2c::CStringView name() const noexcept
555 return this->asConstPort().name();
558 bool isConnected() const noexcept
560 return this->asConstPort().isConnected();
563 SelfComponent component() const noexcept
565 return SelfComponent {bt_self_component_port_borrow_component(this->_libSelfCompPortPtr())};
568 template <typename T>
569 T& data() const noexcept
571 return *static_cast<T *>(bt_self_component_port_get_data(this->_libSelfCompPortPtr()));
575 bt_self_component_port *_libSelfCompPortPtr() const noexcept
577 return internal::SelfComponentPortSpec<LibSelfCompPortT>::asSelfCompPort(this->libObjPtr());
581 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
582 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
583 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::operator[](
584 const std::uint64_t index) const noexcept
586 return Port {_Spec::portByIndex(this->libObjPtr(), index)};
589 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
590 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
591 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::operator[](
592 const bt2c::CStringView name) const noexcept
594 return Port {_Spec::portByName(this->libObjPtr(), name)};
597 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
598 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Iterator
599 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::begin() const noexcept
601 return Iterator {*this, 0};
604 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
605 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Iterator
606 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::end() const noexcept
608 return Iterator {*this, this->length()};
611 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
612 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
613 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::front() const noexcept
618 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
619 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
620 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::back() const noexcept
622 return (*this)[this->length() - 1];
625 using SelfComponentInputPort = SelfComponentPort<bt_self_component_port_input, const bt_port_input>;
627 using SelfComponentOutputPort =
628 SelfComponentPort<bt_self_component_port_output, const bt_port_output>;
630 template <typename DataT>
631 SelfSourceComponent::OutputPorts::Port SelfSourceComponent::_addOutputPort(const char * const name,
632 DataT * const data) const
634 return this->_addPort<SelfSourceComponent::OutputPorts::Port, bt_self_component_port_output>(
635 name, data, bt_self_component_source_add_output_port);
638 template <typename DataT>
639 SelfSourceComponent::OutputPorts::Port
640 SelfSourceComponent::addOutputPort(const bt2c::CStringView name, DataT& data) const
642 return this->_addOutputPort(name, &data);
645 inline SelfSourceComponent::OutputPorts::Port
646 SelfSourceComponent::addOutputPort(const bt2c::CStringView name) const
648 return this->_addOutputPort<void>(name, nullptr);
651 inline SelfSourceComponent::OutputPorts SelfSourceComponent::outputPorts() const noexcept
653 return OutputPorts {this->libObjPtr()};
656 template <typename DataT>
657 SelfFilterComponent::OutputPorts::Port SelfFilterComponent::_addOutputPort(const char * const name,
658 DataT * const data) const
660 return this->_addPort<SelfFilterComponent::OutputPorts::Port, bt_self_component_port_output>(
661 name, data, bt_self_component_filter_add_output_port);
664 template <typename DataT>
665 SelfFilterComponent::OutputPorts::Port
666 SelfFilterComponent::addOutputPort(const bt2c::CStringView name, DataT& data) const
668 return this->_addOutputPort(name, &data);
671 inline SelfFilterComponent::OutputPorts::Port
672 SelfFilterComponent::addOutputPort(const bt2c::CStringView name) const
674 return this->_addOutputPort<void>(name, nullptr);
677 inline SelfFilterComponent::OutputPorts SelfFilterComponent::outputPorts() const noexcept
679 return OutputPorts {this->libObjPtr()};
682 template <typename DataT>
683 SelfFilterComponent::InputPorts::Port SelfFilterComponent::_addInputPort(const char * const name,
684 DataT * const data) const
686 return this->_addPort<SelfFilterComponent::InputPorts::Port, bt_self_component_port_input>(
687 name, data, bt_self_component_filter_add_input_port);
690 template <typename DataT>
691 SelfFilterComponent::InputPorts::Port
692 SelfFilterComponent::addInputPort(const bt2c::CStringView name, DataT& data) const
694 return this->_addInputPort(name, &data);
697 inline SelfFilterComponent::InputPorts::Port
698 SelfFilterComponent::addInputPort(const bt2c::CStringView name) const
700 return this->_addInputPort<void>(name, nullptr);
703 inline SelfFilterComponent::InputPorts SelfFilterComponent::inputPorts() const noexcept
705 return InputPorts {this->libObjPtr()};
708 inline MessageIterator::Shared
709 SelfSinkComponent::createMessageIterator(const InputPorts::Port port) const
711 bt_message_iterator *libMsgIterPtr = nullptr;
713 const auto status = bt_message_iterator_create_from_sink_component(
714 this->libObjPtr(), port.libObjPtr(), &libMsgIterPtr);
717 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK:
718 return MessageIterator::Shared::createWithoutRef(libMsgIterPtr);
719 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_MEMORY_ERROR:
720 throw MemoryError {};
721 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_ERROR:
728 template <typename DataT>
729 SelfSinkComponent::InputPorts::Port SelfSinkComponent::_addInputPort(const char * const name,
730 DataT * const data) const
732 return this->_addPort<SelfSinkComponent::InputPorts::Port, bt_self_component_port_input>(
733 name, data, bt_self_component_sink_add_input_port);
736 template <typename DataT>
737 SelfSinkComponent::InputPorts::Port SelfSinkComponent::addInputPort(const bt2c::CStringView name,
740 return this->_addInputPort(name, &data);
743 inline SelfSinkComponent::InputPorts::Port
744 SelfSinkComponent::addInputPort(const bt2c::CStringView name) const
746 return this->_addInputPort<void>(name, nullptr);
749 inline SelfSinkComponent::InputPorts SelfSinkComponent::inputPorts() const noexcept
751 return InputPorts {this->libObjPtr()};
754 } /* namespace bt2 */
756 #endif /* BABELTRACE_CPP_COMMON_BT2_SELF_COMPONENT_PORT_HPP */