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
13 #include <babeltrace2/babeltrace.h>
15 #include "logging.hpp"
17 #include "common/assert.h"
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 const char *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));
109 template <typename LibObjT>
110 class SelfSpecificComponent : public BorrowedObject<LibObjT>
113 using typename BorrowedObject<LibObjT>::_ThisBorrowedObject;
116 using typename BorrowedObject<LibObjT>::_LibObjPtr;
119 explicit SelfSpecificComponent(const _LibObjPtr libObjPtr) noexcept :
120 _ThisBorrowedObject {libObjPtr}
124 template <typename PortT, typename LibPortT, typename AddPortFuncT, typename DataT>
125 PortT _addPort(const char * const name, DataT * const data, AddPortFuncT&& func) const
127 LibPortT *libPortPtr;
129 const auto status = func(this->libObjPtr(), name, static_cast<void *>(data), &libPortPtr);
132 case BT_SELF_COMPONENT_ADD_PORT_STATUS_OK:
133 return PortT {libPortPtr};
134 case BT_SELF_COMPONENT_ADD_PORT_STATUS_MEMORY_ERROR:
135 throw MemoryError {};
136 case BT_SELF_COMPONENT_ADD_PORT_STATUS_ERROR:
144 const char *name() const noexcept
146 return this->_selfComponent().name();
149 LoggingLevel loggingLevel() const noexcept
151 return this->_selfComponent().loggingLevel();
154 std::uint64_t graphMipVersion() const noexcept
156 return this->_selfComponent().graphMipVersion();
159 template <typename T>
160 T& data() const noexcept
162 return this->_selfComponent().template data<T>();
165 template <typename T>
166 void data(T& obj) const noexcept
168 this->_selfComponent().data(obj);
172 SelfComponent _selfComponent() const noexcept
174 return SelfComponent {this->libObjPtr()};
180 template <typename LibSelfCompT, typename LibSelfCompPortPtrT>
181 struct SelfComponentPortsSpec;
184 struct SelfComponentPortsSpec<bt_self_component_source, bt_self_component_port_output> final
186 static std::uint64_t portCount(bt_self_component_source * const libCompPtr) noexcept
188 return bt_component_source_get_output_port_count(
189 bt_self_component_source_as_component_source(libCompPtr));
192 static bt_self_component_port_output *portByIndex(bt_self_component_source * const libCompPtr,
193 const std::uint64_t index) noexcept
195 return bt_self_component_source_borrow_output_port_by_index(libCompPtr, index);
198 static bt_self_component_port_output *portByName(bt_self_component_source * const libCompPtr,
199 const char * const name) noexcept
201 return bt_self_component_source_borrow_output_port_by_name(libCompPtr, name);
206 struct SelfComponentPortsSpec<bt_self_component_filter, bt_self_component_port_output> final
208 static std::uint64_t portCount(bt_self_component_filter * const libCompPtr) noexcept
210 return bt_component_filter_get_output_port_count(
211 bt_self_component_filter_as_component_filter(libCompPtr));
214 static bt_self_component_port_output *portByIndex(bt_self_component_filter * const libCompPtr,
215 const std::uint64_t index) noexcept
217 return bt_self_component_filter_borrow_output_port_by_index(libCompPtr, index);
220 static bt_self_component_port_output *portByName(bt_self_component_filter * const libCompPtr,
221 const char * const name) noexcept
223 return bt_self_component_filter_borrow_output_port_by_name(libCompPtr, name);
228 struct SelfComponentPortsSpec<bt_self_component_filter, bt_self_component_port_input> final
230 static std::uint64_t portCount(bt_self_component_filter * const libCompPtr) noexcept
232 return bt_component_filter_get_input_port_count(
233 bt_self_component_filter_as_component_filter(libCompPtr));
236 static bt_self_component_port_input *portByIndex(bt_self_component_filter * const libCompPtr,
237 const std::uint64_t index) noexcept
239 return bt_self_component_filter_borrow_input_port_by_index(libCompPtr, index);
242 static bt_self_component_port_input *portByName(bt_self_component_filter * const libCompPtr,
243 const char * const name) noexcept
245 return bt_self_component_filter_borrow_input_port_by_name(libCompPtr, name);
250 struct SelfComponentPortsSpec<bt_self_component_sink, bt_self_component_port_input> final
252 static std::uint64_t portCount(bt_self_component_sink * const libCompPtr) noexcept
254 return bt_component_sink_get_input_port_count(
255 bt_self_component_sink_as_component_sink(libCompPtr));
258 static bt_self_component_port_input *portByIndex(bt_self_component_sink * const libCompPtr,
259 const std::uint64_t index) noexcept
261 return bt_self_component_sink_borrow_input_port_by_index(libCompPtr, index);
264 static bt_self_component_port_input *portByName(bt_self_component_sink * const libCompPtr,
265 const char * const name) noexcept
267 return bt_self_component_sink_borrow_input_port_by_name(libCompPtr, name);
271 } /* namespace internal */
273 template <typename LibSelfCompPortT, typename LibPortT>
274 class SelfComponentPort;
276 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
277 class SelfComponentPorts final : public BorrowedObject<LibSelfCompT>
280 using typename BorrowedObject<LibSelfCompT>::_ThisBorrowedObject;
281 using _Spec = internal::SelfComponentPortsSpec<LibSelfCompT, LibSelfCompPortT>;
284 using typename BorrowedObject<LibSelfCompT>::_LibObjPtr;
285 using Port = SelfComponentPort<LibSelfCompPortT, LibPortT>;
286 using Iterator = BorrowedObjectIterator<SelfComponentPorts>;
288 explicit SelfComponentPorts(const _LibObjPtr libObjPtr) noexcept :
289 _ThisBorrowedObject {libObjPtr}
293 std::uint64_t length() const noexcept
295 return _Spec::portCount(this->libObjPtr());
298 Port operator[](std::uint64_t index) const noexcept;
299 Port operator[](const char *name) const noexcept;
300 Port operator[](const std::string& name) const noexcept;
301 Iterator begin() const noexcept;
302 Iterator end() const noexcept;
303 Port front() const noexcept;
304 Port back() const noexcept;
307 class SelfSourceComponent final : public SelfSpecificComponent<bt_self_component_source>
310 using OutputPorts = SelfComponentPorts<bt_self_component_source, bt_self_component_port_output,
311 const bt_port_output>;
313 explicit SelfSourceComponent(bt_self_component_source * const libObjPtr) noexcept :
314 SelfSpecificComponent {libObjPtr}
318 ConstSourceComponent asConstComponent() const noexcept
320 return ConstSourceComponent {
321 bt_self_component_source_as_component_source(this->libObjPtr())};
324 template <typename DataT>
325 OutputPorts::Port addOutputPort(const char *name, DataT& data) const;
327 OutputPorts::Port addOutputPort(const char *name) const;
329 template <typename DataT>
330 OutputPorts::Port addOutputPort(const std::string& name, DataT& data) const;
332 OutputPorts::Port addOutputPort(const std::string& name) const;
333 OutputPorts outputPorts() const noexcept;
336 template <typename DataT>
337 OutputPorts::Port _addOutputPort(const char *name, DataT *data) const;
340 class SelfFilterComponent final : public SelfSpecificComponent<bt_self_component_filter>
343 using InputPorts = SelfComponentPorts<bt_self_component_filter, bt_self_component_port_input,
344 const bt_port_input>;
345 using OutputPorts = SelfComponentPorts<bt_self_component_filter, bt_self_component_port_output,
346 const bt_port_output>;
348 explicit SelfFilterComponent(bt_self_component_filter * const libObjPtr) noexcept :
349 SelfSpecificComponent {libObjPtr}
353 ConstFilterComponent asConstComponent() const noexcept
355 return ConstFilterComponent {
356 bt_self_component_filter_as_component_filter(this->libObjPtr())};
359 template <typename DataT>
360 InputPorts::Port addInputPort(const char *name, DataT& data) const;
362 InputPorts::Port addInputPort(const char *name) const;
364 template <typename DataT>
365 InputPorts::Port addInputPort(const std::string& name, DataT& data) const;
367 InputPorts::Port addInputPort(const std::string& name) const;
368 InputPorts inputPorts() const noexcept;
370 template <typename DataT>
371 OutputPorts::Port addOutputPort(const char *name, DataT& data) const;
373 OutputPorts::Port addOutputPort(const char *name) const;
375 template <typename DataT>
376 OutputPorts::Port addOutputPort(const std::string& name, DataT& data) const;
378 OutputPorts::Port addOutputPort(const std::string& name) const;
379 OutputPorts outputPorts() const noexcept;
382 template <typename DataT>
383 InputPorts::Port _addInputPort(const char *name, DataT *data) const;
385 template <typename DataT>
386 OutputPorts::Port _addOutputPort(const char *name, DataT *data) const;
389 class SelfSinkComponent final : public SelfSpecificComponent<bt_self_component_sink>
392 using InputPorts = SelfComponentPorts<bt_self_component_sink, bt_self_component_port_input,
393 const bt_port_input>;
395 explicit SelfSinkComponent(bt_self_component_sink * const libObjPtr) noexcept :
396 SelfSpecificComponent {libObjPtr}
400 ConstSinkComponent asConstComponent() const noexcept
402 return ConstSinkComponent {bt_self_component_sink_as_component_sink(this->libObjPtr())};
405 MessageIterator::Shared createMessageIterator(InputPorts::Port port) const;
407 bool isInterrupted() const noexcept
409 return static_cast<bool>(bt_self_component_sink_is_interrupted(this->libObjPtr()));
412 template <typename DataT>
413 InputPorts::Port addInputPort(const char *name, DataT& data) const;
415 InputPorts::Port addInputPort(const char *name) const;
417 template <typename DataT>
418 InputPorts::Port addInputPort(const std::string& name, DataT& data) const;
420 InputPorts::Port addInputPort(const std::string& name) const;
421 InputPorts inputPorts() const noexcept;
424 template <typename DataT>
425 InputPorts::Port _addInputPort(const char *name, DataT *data) const;
428 inline SelfComponent::SelfComponent(const SelfSourceComponent other) noexcept :
429 SelfComponent {other.libObjPtr()}
433 inline SelfComponent::SelfComponent(const SelfFilterComponent other) noexcept :
434 SelfComponent {other.libObjPtr()}
438 inline SelfComponent::SelfComponent(const SelfSinkComponent other) noexcept :
439 SelfComponent {other.libObjPtr()}
443 inline SelfComponent SelfComponent::operator=(const SelfSourceComponent other) noexcept
445 *this = SelfComponent {other.libObjPtr()};
449 inline SelfComponent SelfComponent::operator=(const SelfFilterComponent other) noexcept
451 *this = SelfComponent {other.libObjPtr()};
455 inline SelfComponent SelfComponent::operator=(const SelfSinkComponent other) noexcept
457 *this = SelfComponent {other.libObjPtr()};
463 template <typename LibObjT>
464 struct SelfComponentPortSpec;
466 /* Functions specific to self component input ports */
468 struct SelfComponentPortSpec<bt_self_component_port_input> final
470 static bt_self_component_port *
471 asSelfCompPort(bt_self_component_port_input * const libObjPtr) noexcept
473 return bt_self_component_port_input_as_self_component_port(libObjPtr);
476 static const bt_port_input *
477 asConstPort(const bt_self_component_port_input * const libObjPtr) noexcept
479 return bt_self_component_port_input_as_port_input(libObjPtr);
483 /* Functions specific to self component output ports */
485 struct SelfComponentPortSpec<bt_self_component_port_output> final
487 static bt_self_component_port *
488 asSelfCompPort(bt_self_component_port_output * const libObjPtr) noexcept
490 return bt_self_component_port_output_as_self_component_port(libObjPtr);
493 static const bt_port_output *
494 asConstPort(bt_self_component_port_output * const libObjPtr) noexcept
496 return bt_self_component_port_output_as_port_output(libObjPtr);
500 } /* namespace internal */
502 template <typename LibSelfCompPortT, typename LibPortT>
503 class SelfComponentPort final : public BorrowedObject<LibSelfCompPortT>
506 using typename BorrowedObject<LibSelfCompPortT>::_LibObjPtr;
508 explicit SelfComponentPort(const _LibObjPtr libObjPtr) noexcept :
509 BorrowedObject<LibSelfCompPortT> {libObjPtr}
513 ConstPort<LibPortT> asConstPort() const noexcept
515 return ConstPort<LibPortT> {
516 internal::SelfComponentPortSpec<LibSelfCompPortT>::asConstPort(this->libObjPtr())};
519 const char *name() const noexcept
521 return this->asConstPort().name();
524 bool isConnected() const noexcept
526 return this->asConstPort().isConnected();
529 SelfComponent component() const noexcept
531 return SelfComponent {bt_self_component_port_borrow_component(this->_libSelfCompPortPtr())};
534 template <typename T>
535 T& data() const noexcept
537 *static_cast<T *>(bt_self_component_port_get_data(this->_libSelfCompPortPtr()));
541 bt_self_component_port *_libSelfCompPortPtr() const noexcept
543 return internal::SelfComponentPortSpec<LibSelfCompPortT>::asSelfCompPort(this->libObjPtr());
547 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
548 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
549 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::operator[](
550 const std::uint64_t index) const noexcept
552 return Port {_Spec::portByIndex(this->libObjPtr(), index)};
555 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
556 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
557 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::operator[](
558 const char * const name) const noexcept
560 return Port {_Spec::portByName(this->libObjPtr(), name)};
563 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
564 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
565 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::operator[](
566 const std::string& name) const noexcept
568 return (*this)[name.data()];
571 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
572 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Iterator
573 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::begin() const noexcept
575 return Iterator {*this, 0};
578 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
579 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Iterator
580 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::end() const noexcept
582 return Iterator {*this, this->length()};
585 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
586 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
587 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::front() const noexcept
592 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
593 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
594 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::back() const noexcept
596 return (*this)[this->length() - 1];
599 using SelfComponentInputPort = SelfComponentPort<bt_self_component_port_input, const bt_port_input>;
601 using SelfComponentOutputPort =
602 SelfComponentPort<bt_self_component_port_output, const bt_port_output>;
604 template <typename DataT>
605 SelfSourceComponent::OutputPorts::Port SelfSourceComponent::_addOutputPort(const char * const name,
606 DataT * const data) const
608 return this->_addPort<SelfSourceComponent::OutputPorts::Port, bt_self_component_port_output>(
609 name, data, bt_self_component_source_add_output_port);
612 template <typename DataT>
613 SelfSourceComponent::OutputPorts::Port SelfSourceComponent::addOutputPort(const char * const name,
616 return this->_addOutputPort(name, &data);
619 inline SelfSourceComponent::OutputPorts::Port
620 SelfSourceComponent::addOutputPort(const char * const name) const
622 return this->_addOutputPort<void>(name, nullptr);
625 template <typename DataT>
626 SelfSourceComponent::OutputPorts::Port SelfSourceComponent::addOutputPort(const std::string& name,
629 return this->_addOutputPort(name.data(), &data);
632 inline SelfSourceComponent::OutputPorts::Port
633 SelfSourceComponent::addOutputPort(const std::string& name) const
635 return this->_addOutputPort<void>(name.data(), nullptr);
638 inline SelfSourceComponent::OutputPorts SelfSourceComponent::outputPorts() const noexcept
640 return OutputPorts {this->libObjPtr()};
643 template <typename DataT>
644 SelfFilterComponent::OutputPorts::Port SelfFilterComponent::_addOutputPort(const char * const name,
645 DataT * const data) const
647 return this->_addPort<SelfFilterComponent::OutputPorts::Port, bt_self_component_port_output>(
648 name, data, bt_self_component_filter_add_output_port);
651 template <typename DataT>
652 SelfFilterComponent::OutputPorts::Port SelfFilterComponent::addOutputPort(const char * const name,
655 return this->_addOutputPort(name, &data);
658 inline SelfFilterComponent::OutputPorts::Port
659 SelfFilterComponent::addOutputPort(const char * const name) const
661 return this->_addOutputPort<void>(name, nullptr);
664 template <typename DataT>
665 SelfFilterComponent::OutputPorts::Port SelfFilterComponent::addOutputPort(const std::string& name,
668 return this->_addOutputPort(name.data(), &data);
671 inline SelfFilterComponent::OutputPorts::Port
672 SelfFilterComponent::addOutputPort(const std::string& name) const
674 return this->_addOutputPort<void>(name.data(), 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 SelfFilterComponent::addInputPort(const char * const name,
694 return this->_addInputPort(name, &data);
697 inline SelfFilterComponent::InputPorts::Port
698 SelfFilterComponent::addInputPort(const char * const name) const
700 return this->_addInputPort<void>(name, nullptr);
703 template <typename DataT>
704 SelfFilterComponent::InputPorts::Port SelfFilterComponent::addInputPort(const std::string& name,
707 return this->_addInputPort(name.data(), &data);
710 inline SelfFilterComponent::InputPorts::Port
711 SelfFilterComponent::addInputPort(const std::string& name) const
713 return this->_addInputPort<void>(name.data(), nullptr);
716 inline SelfFilterComponent::InputPorts SelfFilterComponent::inputPorts() const noexcept
718 return InputPorts {this->libObjPtr()};
721 inline MessageIterator::Shared
722 SelfSinkComponent::createMessageIterator(const InputPorts::Port port) const
724 bt_message_iterator *libMsgIterPtr = nullptr;
726 const auto status = bt_message_iterator_create_from_sink_component(
727 this->libObjPtr(), port.libObjPtr(), &libMsgIterPtr);
730 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK:
731 BT_ASSERT(libMsgIterPtr);
732 return MessageIterator::Shared::createWithoutRef(libMsgIterPtr);
733 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_MEMORY_ERROR:
734 throw MemoryError {};
735 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_ERROR:
742 template <typename DataT>
743 SelfSinkComponent::InputPorts::Port SelfSinkComponent::_addInputPort(const char * const name,
744 DataT * const data) const
746 return this->_addPort<SelfSinkComponent::InputPorts::Port, bt_self_component_port_input>(
747 name, data, bt_self_component_sink_add_input_port);
750 template <typename DataT>
751 SelfSinkComponent::InputPorts::Port SelfSinkComponent::addInputPort(const char * const name,
754 return this->_addInputPort(name, &data);
757 inline SelfSinkComponent::InputPorts::Port
758 SelfSinkComponent::addInputPort(const char * const name) const
760 return this->_addInputPort<void>(name, nullptr);
763 template <typename DataT>
764 SelfSinkComponent::InputPorts::Port SelfSinkComponent::addInputPort(const std::string& name,
767 return this->_addInputPort(name.data(), &data);
770 inline SelfSinkComponent::InputPorts::Port
771 SelfSinkComponent::addInputPort(const std::string& name) const
773 return this->_addInputPort<void>(name.data(), nullptr);
776 inline SelfSinkComponent::InputPorts SelfSinkComponent::inputPorts() const noexcept
778 return InputPorts {this->libObjPtr()};
781 } /* namespace bt2 */
783 #endif /* BABELTRACE_CPP_COMMON_BT2_SELF_COMPONENT_PORT_HPP */