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);
120 template <typename LibObjT>
121 class SelfSpecificComponent : public BorrowedObject<LibObjT>
124 using typename BorrowedObject<LibObjT>::_ThisBorrowedObject;
127 using typename BorrowedObject<LibObjT>::LibObjPtr;
130 explicit SelfSpecificComponent(const LibObjPtr libObjPtr) noexcept :
131 _ThisBorrowedObject {libObjPtr}
135 template <typename PortT, typename LibPortT, typename AddPortFuncT, typename DataT>
136 PortT _addPort(const char * const name, DataT * const data, AddPortFuncT&& func) const
138 LibPortT *libPortPtr;
140 const auto status = func(this->libObjPtr(), name, static_cast<void *>(data), &libPortPtr);
143 case BT_SELF_COMPONENT_ADD_PORT_STATUS_OK:
144 return PortT {libPortPtr};
145 case BT_SELF_COMPONENT_ADD_PORT_STATUS_MEMORY_ERROR:
146 throw MemoryError {};
147 case BT_SELF_COMPONENT_ADD_PORT_STATUS_ERROR:
155 bt2c::CStringView name() const noexcept
157 return this->_selfComponent().name();
160 LoggingLevel loggingLevel() const noexcept
162 return this->_selfComponent().loggingLevel();
165 std::uint64_t graphMipVersion() const noexcept
167 return this->_selfComponent().graphMipVersion();
170 template <typename T>
171 T& data() const noexcept
173 return this->_selfComponent().template data<T>();
176 template <typename T>
177 void data(T& obj) const noexcept
179 this->_selfComponent().data(obj);
183 SelfComponent _selfComponent() const noexcept
185 return SelfComponent {this->libObjPtr()};
191 template <typename LibSelfCompT, typename LibSelfCompPortPtrT>
192 struct SelfComponentPortsSpec;
195 struct SelfComponentPortsSpec<bt_self_component_source, bt_self_component_port_output> final
197 static std::uint64_t portCount(bt_self_component_source * const libCompPtr) noexcept
199 return bt_component_source_get_output_port_count(
200 bt_self_component_source_as_component_source(libCompPtr));
203 static bt_self_component_port_output *portByIndex(bt_self_component_source * const libCompPtr,
204 const std::uint64_t index) noexcept
206 return bt_self_component_source_borrow_output_port_by_index(libCompPtr, index);
209 static bt_self_component_port_output *portByName(bt_self_component_source * const libCompPtr,
210 const char * const name) noexcept
212 return bt_self_component_source_borrow_output_port_by_name(libCompPtr, name);
217 struct SelfComponentPortsSpec<bt_self_component_filter, bt_self_component_port_output> final
219 static std::uint64_t portCount(bt_self_component_filter * const libCompPtr) noexcept
221 return bt_component_filter_get_output_port_count(
222 bt_self_component_filter_as_component_filter(libCompPtr));
225 static bt_self_component_port_output *portByIndex(bt_self_component_filter * const libCompPtr,
226 const std::uint64_t index) noexcept
228 return bt_self_component_filter_borrow_output_port_by_index(libCompPtr, index);
231 static bt_self_component_port_output *portByName(bt_self_component_filter * const libCompPtr,
232 const char * const name) noexcept
234 return bt_self_component_filter_borrow_output_port_by_name(libCompPtr, name);
239 struct SelfComponentPortsSpec<bt_self_component_filter, bt_self_component_port_input> final
241 static std::uint64_t portCount(bt_self_component_filter * const libCompPtr) noexcept
243 return bt_component_filter_get_input_port_count(
244 bt_self_component_filter_as_component_filter(libCompPtr));
247 static bt_self_component_port_input *portByIndex(bt_self_component_filter * const libCompPtr,
248 const std::uint64_t index) noexcept
250 return bt_self_component_filter_borrow_input_port_by_index(libCompPtr, index);
253 static bt_self_component_port_input *portByName(bt_self_component_filter * const libCompPtr,
254 const char * const name) noexcept
256 return bt_self_component_filter_borrow_input_port_by_name(libCompPtr, name);
261 struct SelfComponentPortsSpec<bt_self_component_sink, bt_self_component_port_input> final
263 static std::uint64_t portCount(bt_self_component_sink * const libCompPtr) noexcept
265 return bt_component_sink_get_input_port_count(
266 bt_self_component_sink_as_component_sink(libCompPtr));
269 static bt_self_component_port_input *portByIndex(bt_self_component_sink * const libCompPtr,
270 const std::uint64_t index) noexcept
272 return bt_self_component_sink_borrow_input_port_by_index(libCompPtr, index);
275 static bt_self_component_port_input *portByName(bt_self_component_sink * const libCompPtr,
276 const char * const name) noexcept
278 return bt_self_component_sink_borrow_input_port_by_name(libCompPtr, name);
282 } /* namespace internal */
284 template <typename LibSelfCompPortT, typename LibPortT>
285 class SelfComponentPort;
287 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
288 class SelfComponentPorts final : public BorrowedObject<LibSelfCompT>
291 using typename BorrowedObject<LibSelfCompT>::_ThisBorrowedObject;
292 using _Spec = internal::SelfComponentPortsSpec<LibSelfCompT, LibSelfCompPortT>;
295 using typename BorrowedObject<LibSelfCompT>::LibObjPtr;
296 using Port = SelfComponentPort<LibSelfCompPortT, LibPortT>;
297 using Iterator = BorrowedObjectIterator<SelfComponentPorts>;
299 explicit SelfComponentPorts(const LibObjPtr libObjPtr) noexcept :
300 _ThisBorrowedObject {libObjPtr}
304 std::uint64_t length() const noexcept
306 return _Spec::portCount(this->libObjPtr());
309 Port operator[](std::uint64_t index) const noexcept;
310 Port operator[](bt2c::CStringView name) const noexcept;
311 Iterator begin() const noexcept;
312 Iterator end() const noexcept;
313 Port front() const noexcept;
314 Port back() const noexcept;
317 class SelfSourceComponent final : public SelfSpecificComponent<bt_self_component_source>
320 using OutputPorts = SelfComponentPorts<bt_self_component_source, bt_self_component_port_output,
321 const bt_port_output>;
323 explicit SelfSourceComponent(bt_self_component_source * const libObjPtr) noexcept :
324 SelfSpecificComponent {libObjPtr}
328 ConstSourceComponent asConstComponent() const noexcept
330 return ConstSourceComponent {
331 bt_self_component_source_as_component_source(this->libObjPtr())};
334 template <typename DataT>
335 OutputPorts::Port addOutputPort(bt2c::CStringView name, DataT& data) const;
337 OutputPorts::Port addOutputPort(bt2c::CStringView name) const;
339 OutputPorts outputPorts() const noexcept;
342 template <typename DataT>
343 OutputPorts::Port _addOutputPort(const char *name, DataT *data) const;
346 class SelfFilterComponent final : public SelfSpecificComponent<bt_self_component_filter>
349 using InputPorts = SelfComponentPorts<bt_self_component_filter, bt_self_component_port_input,
350 const bt_port_input>;
351 using OutputPorts = SelfComponentPorts<bt_self_component_filter, bt_self_component_port_output,
352 const bt_port_output>;
354 explicit SelfFilterComponent(bt_self_component_filter * const libObjPtr) noexcept :
355 SelfSpecificComponent {libObjPtr}
359 ConstFilterComponent asConstComponent() const noexcept
361 return ConstFilterComponent {
362 bt_self_component_filter_as_component_filter(this->libObjPtr())};
365 template <typename DataT>
366 InputPorts::Port addInputPort(bt2c::CStringView name, DataT& data) const;
368 InputPorts::Port addInputPort(bt2c::CStringView name) const;
370 InputPorts inputPorts() const noexcept;
372 template <typename DataT>
373 OutputPorts::Port addOutputPort(bt2c::CStringView name, DataT& data) const;
375 OutputPorts::Port addOutputPort(bt2c::CStringView name) const;
377 OutputPorts outputPorts() const noexcept;
380 template <typename DataT>
381 InputPorts::Port _addInputPort(const char *name, DataT *data) const;
383 template <typename DataT>
384 OutputPorts::Port _addOutputPort(const char *name, DataT *data) const;
387 class SelfSinkComponent final : public SelfSpecificComponent<bt_self_component_sink>
390 using InputPorts = SelfComponentPorts<bt_self_component_sink, bt_self_component_port_input,
391 const bt_port_input>;
393 explicit SelfSinkComponent(bt_self_component_sink * const libObjPtr) noexcept :
394 SelfSpecificComponent {libObjPtr}
398 ConstSinkComponent asConstComponent() const noexcept
400 return ConstSinkComponent {bt_self_component_sink_as_component_sink(this->libObjPtr())};
403 MessageIterator::Shared createMessageIterator(InputPorts::Port port) const;
405 bool isInterrupted() const noexcept
407 return static_cast<bool>(bt_self_component_sink_is_interrupted(this->libObjPtr()));
410 template <typename DataT>
411 InputPorts::Port addInputPort(bt2c::CStringView name, DataT& data) const;
413 InputPorts::Port addInputPort(bt2c::CStringView name) const;
415 InputPorts inputPorts() const noexcept;
418 template <typename DataT>
419 InputPorts::Port _addInputPort(const char *name, DataT *data) const;
422 inline SelfComponent::SelfComponent(const SelfSourceComponent other) noexcept :
423 SelfComponent {other.libObjPtr()}
427 inline SelfComponent::SelfComponent(const SelfFilterComponent other) noexcept :
428 SelfComponent {other.libObjPtr()}
432 inline SelfComponent::SelfComponent(const SelfSinkComponent other) noexcept :
433 SelfComponent {other.libObjPtr()}
437 inline SelfComponent SelfComponent::operator=(const SelfSourceComponent other) noexcept
439 *this = SelfComponent {other.libObjPtr()};
443 inline SelfComponent SelfComponent::operator=(const SelfFilterComponent other) noexcept
445 *this = SelfComponent {other.libObjPtr()};
449 inline SelfComponent SelfComponent::operator=(const SelfSinkComponent other) noexcept
451 *this = SelfComponent {other.libObjPtr()};
457 template <typename LibObjT>
458 struct SelfComponentPortSpec;
460 /* Functions specific to self component input ports */
462 struct SelfComponentPortSpec<bt_self_component_port_input> final
464 static bt_self_component_port *
465 asSelfCompPort(bt_self_component_port_input * const libObjPtr) noexcept
467 return bt_self_component_port_input_as_self_component_port(libObjPtr);
470 static const bt_port_input *
471 asConstPort(const bt_self_component_port_input * const libObjPtr) noexcept
473 return bt_self_component_port_input_as_port_input(libObjPtr);
477 /* Functions specific to self component output ports */
479 struct SelfComponentPortSpec<bt_self_component_port_output> final
481 static bt_self_component_port *
482 asSelfCompPort(bt_self_component_port_output * const libObjPtr) noexcept
484 return bt_self_component_port_output_as_self_component_port(libObjPtr);
487 static const bt_port_output *
488 asConstPort(bt_self_component_port_output * const libObjPtr) noexcept
490 return bt_self_component_port_output_as_port_output(libObjPtr);
494 } /* namespace internal */
496 template <typename LibSelfCompPortT, typename LibPortT>
497 class SelfComponentPort final : public BorrowedObject<LibSelfCompPortT>
500 using typename BorrowedObject<LibSelfCompPortT>::LibObjPtr;
502 explicit SelfComponentPort(const LibObjPtr libObjPtr) noexcept :
503 BorrowedObject<LibSelfCompPortT> {libObjPtr}
507 ConstPort<LibPortT> asConstPort() const noexcept
509 return ConstPort<LibPortT> {
510 internal::SelfComponentPortSpec<LibSelfCompPortT>::asConstPort(this->libObjPtr())};
513 bt2c::CStringView name() const noexcept
515 return this->asConstPort().name();
518 bool isConnected() const noexcept
520 return this->asConstPort().isConnected();
523 SelfComponent component() const noexcept
525 return SelfComponent {bt_self_component_port_borrow_component(this->_libSelfCompPortPtr())};
528 template <typename T>
529 T& data() const noexcept
531 *static_cast<T *>(bt_self_component_port_get_data(this->_libSelfCompPortPtr()));
535 bt_self_component_port *_libSelfCompPortPtr() const noexcept
537 return internal::SelfComponentPortSpec<LibSelfCompPortT>::asSelfCompPort(this->libObjPtr());
541 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
542 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
543 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::operator[](
544 const std::uint64_t index) const noexcept
546 return Port {_Spec::portByIndex(this->libObjPtr(), index)};
549 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
550 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
551 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::operator[](
552 const bt2c::CStringView name) const noexcept
554 return Port {_Spec::portByName(this->libObjPtr(), name)};
557 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
558 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Iterator
559 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::begin() const noexcept
561 return Iterator {*this, 0};
564 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
565 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Iterator
566 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::end() const noexcept
568 return Iterator {*this, this->length()};
571 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
572 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
573 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::front() const noexcept
578 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
579 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
580 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::back() const noexcept
582 return (*this)[this->length() - 1];
585 using SelfComponentInputPort = SelfComponentPort<bt_self_component_port_input, const bt_port_input>;
587 using SelfComponentOutputPort =
588 SelfComponentPort<bt_self_component_port_output, const bt_port_output>;
590 template <typename DataT>
591 SelfSourceComponent::OutputPorts::Port SelfSourceComponent::_addOutputPort(const char * const name,
592 DataT * const data) const
594 return this->_addPort<SelfSourceComponent::OutputPorts::Port, bt_self_component_port_output>(
595 name, data, bt_self_component_source_add_output_port);
598 template <typename DataT>
599 SelfSourceComponent::OutputPorts::Port
600 SelfSourceComponent::addOutputPort(const bt2c::CStringView name, DataT& data) const
602 return this->_addOutputPort(name, &data);
605 inline SelfSourceComponent::OutputPorts::Port
606 SelfSourceComponent::addOutputPort(const bt2c::CStringView name) const
608 return this->_addOutputPort<void>(name, nullptr);
611 inline SelfSourceComponent::OutputPorts SelfSourceComponent::outputPorts() const noexcept
613 return OutputPorts {this->libObjPtr()};
616 template <typename DataT>
617 SelfFilterComponent::OutputPorts::Port SelfFilterComponent::_addOutputPort(const char * const name,
618 DataT * const data) const
620 return this->_addPort<SelfFilterComponent::OutputPorts::Port, bt_self_component_port_output>(
621 name, data, bt_self_component_filter_add_output_port);
624 template <typename DataT>
625 SelfFilterComponent::OutputPorts::Port
626 SelfFilterComponent::addOutputPort(const bt2c::CStringView name, DataT& data) const
628 return this->_addOutputPort(name, &data);
631 inline SelfFilterComponent::OutputPorts::Port
632 SelfFilterComponent::addOutputPort(const bt2c::CStringView name) const
634 return this->_addOutputPort<void>(name, nullptr);
637 inline SelfFilterComponent::OutputPorts SelfFilterComponent::outputPorts() const noexcept
639 return OutputPorts {this->libObjPtr()};
642 template <typename DataT>
643 SelfFilterComponent::InputPorts::Port SelfFilterComponent::_addInputPort(const char * const name,
644 DataT * const data) const
646 return this->_addPort<SelfFilterComponent::InputPorts::Port, bt_self_component_port_input>(
647 name, data, bt_self_component_filter_add_input_port);
650 template <typename DataT>
651 SelfFilterComponent::InputPorts::Port
652 SelfFilterComponent::addInputPort(const bt2c::CStringView name, DataT& data) const
654 return this->_addInputPort(name, &data);
657 inline SelfFilterComponent::InputPorts::Port
658 SelfFilterComponent::addInputPort(const bt2c::CStringView name) const
660 return this->_addInputPort<void>(name, nullptr);
663 inline SelfFilterComponent::InputPorts SelfFilterComponent::inputPorts() const noexcept
665 return InputPorts {this->libObjPtr()};
668 inline MessageIterator::Shared
669 SelfSinkComponent::createMessageIterator(const InputPorts::Port port) const
671 bt_message_iterator *libMsgIterPtr = nullptr;
673 const auto status = bt_message_iterator_create_from_sink_component(
674 this->libObjPtr(), port.libObjPtr(), &libMsgIterPtr);
677 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK:
678 BT_ASSERT(libMsgIterPtr);
679 return MessageIterator::Shared::createWithoutRef(libMsgIterPtr);
680 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_MEMORY_ERROR:
681 throw MemoryError {};
682 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_ERROR:
689 template <typename DataT>
690 SelfSinkComponent::InputPorts::Port SelfSinkComponent::_addInputPort(const char * const name,
691 DataT * const data) const
693 return this->_addPort<SelfSinkComponent::InputPorts::Port, bt_self_component_port_input>(
694 name, data, bt_self_component_sink_add_input_port);
697 template <typename DataT>
698 SelfSinkComponent::InputPorts::Port SelfSinkComponent::addInputPort(const bt2c::CStringView name,
701 return this->_addInputPort(name, &data);
704 inline SelfSinkComponent::InputPorts::Port
705 SelfSinkComponent::addInputPort(const bt2c::CStringView name) const
707 return this->_addInputPort<void>(name, nullptr);
710 inline SelfSinkComponent::InputPorts SelfSinkComponent::inputPorts() const noexcept
712 return InputPorts {this->libObjPtr()};
715 } /* namespace bt2 */
717 #endif /* BABELTRACE_CPP_COMMON_BT2_SELF_COMPONENT_PORT_HPP */