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"
18 #include "cpp-common/bt2c/c-string-view.hpp"
20 #include "borrowed-object-iterator.hpp"
21 #include "borrowed-object.hpp"
22 #include "component-port.hpp"
23 #include "message-iterator.hpp"
27 class SelfSourceComponent;
28 class SelfFilterComponent;
29 class SelfSinkComponent;
31 class SelfComponent final : public BorrowedObject<bt_self_component>
34 explicit SelfComponent(const LibObjPtr libObjPtr) noexcept : _ThisBorrowedObject {libObjPtr}
38 explicit SelfComponent(bt_self_component_source * const libObjPtr) noexcept :
39 _ThisBorrowedObject {bt_self_component_source_as_self_component(libObjPtr)}
43 explicit SelfComponent(bt_self_component_filter * const libObjPtr) noexcept :
44 _ThisBorrowedObject {bt_self_component_filter_as_self_component(libObjPtr)}
48 explicit SelfComponent(bt_self_component_sink * const libObjPtr) noexcept :
49 _ThisBorrowedObject {bt_self_component_sink_as_self_component(libObjPtr)}
53 /* Not `explicit` to make them behave like copy constructors */
54 SelfComponent(SelfSourceComponent other) noexcept;
55 SelfComponent(SelfFilterComponent other) noexcept;
56 SelfComponent(SelfSinkComponent other) noexcept;
58 SelfComponent operator=(SelfSourceComponent other) noexcept;
59 SelfComponent operator=(SelfFilterComponent other) noexcept;
60 SelfComponent operator=(SelfSinkComponent other) noexcept;
62 ConstComponent asConstComponent() const noexcept
64 return ConstComponent {bt_self_component_as_component(this->libObjPtr())};
67 bool isSource() const noexcept
69 return this->asConstComponent().isSource();
72 bool isFilter() const noexcept
74 return this->asConstComponent().isFilter();
77 bool isSink() const noexcept
79 return this->asConstComponent().isSink();
82 bt2c::CStringView name() const noexcept
84 return this->asConstComponent().name();
87 LoggingLevel loggingLevel() const noexcept
89 return this->asConstComponent().loggingLevel();
92 std::uint64_t graphMipVersion() const noexcept
94 return bt_self_component_get_graph_mip_version(this->libObjPtr());
98 T& data() const noexcept
100 return *static_cast<T *>(bt_self_component_get_data(this->libObjPtr()));
103 template <typename T>
104 void data(T& obj) const noexcept
106 bt_self_component_set_data(this->libObjPtr(), static_cast<void *>(&obj));
110 template <typename LibObjT>
111 class SelfSpecificComponent : public BorrowedObject<LibObjT>
114 using typename BorrowedObject<LibObjT>::_ThisBorrowedObject;
117 using typename BorrowedObject<LibObjT>::LibObjPtr;
120 explicit SelfSpecificComponent(const LibObjPtr libObjPtr) noexcept :
121 _ThisBorrowedObject {libObjPtr}
125 template <typename PortT, typename LibPortT, typename AddPortFuncT, typename DataT>
126 PortT _addPort(const char * const name, DataT * const data, AddPortFuncT&& func) const
128 LibPortT *libPortPtr;
130 const auto status = func(this->libObjPtr(), name, static_cast<void *>(data), &libPortPtr);
133 case BT_SELF_COMPONENT_ADD_PORT_STATUS_OK:
134 return PortT {libPortPtr};
135 case BT_SELF_COMPONENT_ADD_PORT_STATUS_MEMORY_ERROR:
136 throw MemoryError {};
137 case BT_SELF_COMPONENT_ADD_PORT_STATUS_ERROR:
145 bt2c::CStringView name() const noexcept
147 return this->_selfComponent().name();
150 LoggingLevel loggingLevel() const noexcept
152 return this->_selfComponent().loggingLevel();
155 std::uint64_t graphMipVersion() const noexcept
157 return this->_selfComponent().graphMipVersion();
160 template <typename T>
161 T& data() const noexcept
163 return this->_selfComponent().template data<T>();
166 template <typename T>
167 void data(T& obj) const noexcept
169 this->_selfComponent().data(obj);
173 SelfComponent _selfComponent() const noexcept
175 return SelfComponent {this->libObjPtr()};
181 template <typename LibSelfCompT, typename LibSelfCompPortPtrT>
182 struct SelfComponentPortsSpec;
185 struct SelfComponentPortsSpec<bt_self_component_source, bt_self_component_port_output> final
187 static std::uint64_t portCount(bt_self_component_source * const libCompPtr) noexcept
189 return bt_component_source_get_output_port_count(
190 bt_self_component_source_as_component_source(libCompPtr));
193 static bt_self_component_port_output *portByIndex(bt_self_component_source * const libCompPtr,
194 const std::uint64_t index) noexcept
196 return bt_self_component_source_borrow_output_port_by_index(libCompPtr, index);
199 static bt_self_component_port_output *portByName(bt_self_component_source * const libCompPtr,
200 const char * const name) noexcept
202 return bt_self_component_source_borrow_output_port_by_name(libCompPtr, name);
207 struct SelfComponentPortsSpec<bt_self_component_filter, bt_self_component_port_output> final
209 static std::uint64_t portCount(bt_self_component_filter * const libCompPtr) noexcept
211 return bt_component_filter_get_output_port_count(
212 bt_self_component_filter_as_component_filter(libCompPtr));
215 static bt_self_component_port_output *portByIndex(bt_self_component_filter * const libCompPtr,
216 const std::uint64_t index) noexcept
218 return bt_self_component_filter_borrow_output_port_by_index(libCompPtr, index);
221 static bt_self_component_port_output *portByName(bt_self_component_filter * const libCompPtr,
222 const char * const name) noexcept
224 return bt_self_component_filter_borrow_output_port_by_name(libCompPtr, name);
229 struct SelfComponentPortsSpec<bt_self_component_filter, bt_self_component_port_input> final
231 static std::uint64_t portCount(bt_self_component_filter * const libCompPtr) noexcept
233 return bt_component_filter_get_input_port_count(
234 bt_self_component_filter_as_component_filter(libCompPtr));
237 static bt_self_component_port_input *portByIndex(bt_self_component_filter * const libCompPtr,
238 const std::uint64_t index) noexcept
240 return bt_self_component_filter_borrow_input_port_by_index(libCompPtr, index);
243 static bt_self_component_port_input *portByName(bt_self_component_filter * const libCompPtr,
244 const char * const name) noexcept
246 return bt_self_component_filter_borrow_input_port_by_name(libCompPtr, name);
251 struct SelfComponentPortsSpec<bt_self_component_sink, bt_self_component_port_input> final
253 static std::uint64_t portCount(bt_self_component_sink * const libCompPtr) noexcept
255 return bt_component_sink_get_input_port_count(
256 bt_self_component_sink_as_component_sink(libCompPtr));
259 static bt_self_component_port_input *portByIndex(bt_self_component_sink * const libCompPtr,
260 const std::uint64_t index) noexcept
262 return bt_self_component_sink_borrow_input_port_by_index(libCompPtr, index);
265 static bt_self_component_port_input *portByName(bt_self_component_sink * const libCompPtr,
266 const char * const name) noexcept
268 return bt_self_component_sink_borrow_input_port_by_name(libCompPtr, name);
272 } /* namespace internal */
274 template <typename LibSelfCompPortT, typename LibPortT>
275 class SelfComponentPort;
277 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
278 class SelfComponentPorts final : public BorrowedObject<LibSelfCompT>
281 using typename BorrowedObject<LibSelfCompT>::_ThisBorrowedObject;
282 using _Spec = internal::SelfComponentPortsSpec<LibSelfCompT, LibSelfCompPortT>;
285 using typename BorrowedObject<LibSelfCompT>::LibObjPtr;
286 using Port = SelfComponentPort<LibSelfCompPortT, LibPortT>;
287 using Iterator = BorrowedObjectIterator<SelfComponentPorts>;
289 explicit SelfComponentPorts(const LibObjPtr libObjPtr) noexcept :
290 _ThisBorrowedObject {libObjPtr}
294 std::uint64_t length() const noexcept
296 return _Spec::portCount(this->libObjPtr());
299 Port operator[](std::uint64_t index) const noexcept;
300 Port operator[](const char *name) const noexcept;
301 Port operator[](const std::string& name) const noexcept;
302 Iterator begin() const noexcept;
303 Iterator end() const noexcept;
304 Port front() const noexcept;
305 Port back() const noexcept;
308 class SelfSourceComponent final : public SelfSpecificComponent<bt_self_component_source>
311 using OutputPorts = SelfComponentPorts<bt_self_component_source, bt_self_component_port_output,
312 const bt_port_output>;
314 explicit SelfSourceComponent(bt_self_component_source * const libObjPtr) noexcept :
315 SelfSpecificComponent {libObjPtr}
319 ConstSourceComponent asConstComponent() const noexcept
321 return ConstSourceComponent {
322 bt_self_component_source_as_component_source(this->libObjPtr())};
325 template <typename DataT>
326 OutputPorts::Port addOutputPort(const char *name, DataT& data) const;
328 OutputPorts::Port addOutputPort(const char *name) const;
330 template <typename DataT>
331 OutputPorts::Port addOutputPort(const std::string& name, DataT& data) const;
333 OutputPorts::Port addOutputPort(const std::string& name) const;
334 OutputPorts outputPorts() const noexcept;
337 template <typename DataT>
338 OutputPorts::Port _addOutputPort(const char *name, DataT *data) const;
341 class SelfFilterComponent final : public SelfSpecificComponent<bt_self_component_filter>
344 using InputPorts = SelfComponentPorts<bt_self_component_filter, bt_self_component_port_input,
345 const bt_port_input>;
346 using OutputPorts = SelfComponentPorts<bt_self_component_filter, bt_self_component_port_output,
347 const bt_port_output>;
349 explicit SelfFilterComponent(bt_self_component_filter * const libObjPtr) noexcept :
350 SelfSpecificComponent {libObjPtr}
354 ConstFilterComponent asConstComponent() const noexcept
356 return ConstFilterComponent {
357 bt_self_component_filter_as_component_filter(this->libObjPtr())};
360 template <typename DataT>
361 InputPorts::Port addInputPort(const char *name, DataT& data) const;
363 InputPorts::Port addInputPort(const char *name) const;
365 template <typename DataT>
366 InputPorts::Port addInputPort(const std::string& name, DataT& data) const;
368 InputPorts::Port addInputPort(const std::string& name) const;
369 InputPorts inputPorts() const noexcept;
371 template <typename DataT>
372 OutputPorts::Port addOutputPort(const char *name, DataT& data) const;
374 OutputPorts::Port addOutputPort(const char *name) const;
376 template <typename DataT>
377 OutputPorts::Port addOutputPort(const std::string& name, DataT& data) const;
379 OutputPorts::Port addOutputPort(const std::string& name) const;
380 OutputPorts outputPorts() const noexcept;
383 template <typename DataT>
384 InputPorts::Port _addInputPort(const char *name, DataT *data) const;
386 template <typename DataT>
387 OutputPorts::Port _addOutputPort(const char *name, DataT *data) const;
390 class SelfSinkComponent final : public SelfSpecificComponent<bt_self_component_sink>
393 using InputPorts = SelfComponentPorts<bt_self_component_sink, bt_self_component_port_input,
394 const bt_port_input>;
396 explicit SelfSinkComponent(bt_self_component_sink * const libObjPtr) noexcept :
397 SelfSpecificComponent {libObjPtr}
401 ConstSinkComponent asConstComponent() const noexcept
403 return ConstSinkComponent {bt_self_component_sink_as_component_sink(this->libObjPtr())};
406 MessageIterator::Shared createMessageIterator(InputPorts::Port port) const;
408 bool isInterrupted() const noexcept
410 return static_cast<bool>(bt_self_component_sink_is_interrupted(this->libObjPtr()));
413 template <typename DataT>
414 InputPorts::Port addInputPort(const char *name, DataT& data) const;
416 InputPorts::Port addInputPort(const char *name) const;
418 template <typename DataT>
419 InputPorts::Port addInputPort(const std::string& name, DataT& data) const;
421 InputPorts::Port addInputPort(const std::string& name) const;
422 InputPorts inputPorts() const noexcept;
425 template <typename DataT>
426 InputPorts::Port _addInputPort(const char *name, DataT *data) const;
429 inline SelfComponent::SelfComponent(const SelfSourceComponent other) noexcept :
430 SelfComponent {other.libObjPtr()}
434 inline SelfComponent::SelfComponent(const SelfFilterComponent other) noexcept :
435 SelfComponent {other.libObjPtr()}
439 inline SelfComponent::SelfComponent(const SelfSinkComponent other) noexcept :
440 SelfComponent {other.libObjPtr()}
444 inline SelfComponent SelfComponent::operator=(const SelfSourceComponent other) noexcept
446 *this = SelfComponent {other.libObjPtr()};
450 inline SelfComponent SelfComponent::operator=(const SelfFilterComponent other) noexcept
452 *this = SelfComponent {other.libObjPtr()};
456 inline SelfComponent SelfComponent::operator=(const SelfSinkComponent other) noexcept
458 *this = SelfComponent {other.libObjPtr()};
464 template <typename LibObjT>
465 struct SelfComponentPortSpec;
467 /* Functions specific to self component input ports */
469 struct SelfComponentPortSpec<bt_self_component_port_input> final
471 static bt_self_component_port *
472 asSelfCompPort(bt_self_component_port_input * const libObjPtr) noexcept
474 return bt_self_component_port_input_as_self_component_port(libObjPtr);
477 static const bt_port_input *
478 asConstPort(const bt_self_component_port_input * const libObjPtr) noexcept
480 return bt_self_component_port_input_as_port_input(libObjPtr);
484 /* Functions specific to self component output ports */
486 struct SelfComponentPortSpec<bt_self_component_port_output> final
488 static bt_self_component_port *
489 asSelfCompPort(bt_self_component_port_output * const libObjPtr) noexcept
491 return bt_self_component_port_output_as_self_component_port(libObjPtr);
494 static const bt_port_output *
495 asConstPort(bt_self_component_port_output * const libObjPtr) noexcept
497 return bt_self_component_port_output_as_port_output(libObjPtr);
501 } /* namespace internal */
503 template <typename LibSelfCompPortT, typename LibPortT>
504 class SelfComponentPort final : public BorrowedObject<LibSelfCompPortT>
507 using typename BorrowedObject<LibSelfCompPortT>::LibObjPtr;
509 explicit SelfComponentPort(const LibObjPtr libObjPtr) noexcept :
510 BorrowedObject<LibSelfCompPortT> {libObjPtr}
514 ConstPort<LibPortT> asConstPort() const noexcept
516 return ConstPort<LibPortT> {
517 internal::SelfComponentPortSpec<LibSelfCompPortT>::asConstPort(this->libObjPtr())};
520 bt2c::CStringView name() const noexcept
522 return this->asConstPort().name();
525 bool isConnected() const noexcept
527 return this->asConstPort().isConnected();
530 SelfComponent component() const noexcept
532 return SelfComponent {bt_self_component_port_borrow_component(this->_libSelfCompPortPtr())};
535 template <typename T>
536 T& data() const noexcept
538 *static_cast<T *>(bt_self_component_port_get_data(this->_libSelfCompPortPtr()));
542 bt_self_component_port *_libSelfCompPortPtr() const noexcept
544 return internal::SelfComponentPortSpec<LibSelfCompPortT>::asSelfCompPort(this->libObjPtr());
548 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
549 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
550 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::operator[](
551 const std::uint64_t index) const noexcept
553 return Port {_Spec::portByIndex(this->libObjPtr(), index)};
556 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
557 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
558 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::operator[](
559 const char * const name) const noexcept
561 return Port {_Spec::portByName(this->libObjPtr(), name)};
564 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
565 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
566 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::operator[](
567 const std::string& name) const noexcept
569 return (*this)[name.data()];
572 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
573 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Iterator
574 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::begin() const noexcept
576 return Iterator {*this, 0};
579 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
580 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Iterator
581 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::end() const noexcept
583 return Iterator {*this, this->length()};
586 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
587 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
588 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::front() const noexcept
593 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
594 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
595 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::back() const noexcept
597 return (*this)[this->length() - 1];
600 using SelfComponentInputPort = SelfComponentPort<bt_self_component_port_input, const bt_port_input>;
602 using SelfComponentOutputPort =
603 SelfComponentPort<bt_self_component_port_output, const bt_port_output>;
605 template <typename DataT>
606 SelfSourceComponent::OutputPorts::Port SelfSourceComponent::_addOutputPort(const char * const name,
607 DataT * const data) const
609 return this->_addPort<SelfSourceComponent::OutputPorts::Port, bt_self_component_port_output>(
610 name, data, bt_self_component_source_add_output_port);
613 template <typename DataT>
614 SelfSourceComponent::OutputPorts::Port SelfSourceComponent::addOutputPort(const char * const name,
617 return this->_addOutputPort(name, &data);
620 inline SelfSourceComponent::OutputPorts::Port
621 SelfSourceComponent::addOutputPort(const char * const name) const
623 return this->_addOutputPort<void>(name, nullptr);
626 template <typename DataT>
627 SelfSourceComponent::OutputPorts::Port SelfSourceComponent::addOutputPort(const std::string& name,
630 return this->_addOutputPort(name.data(), &data);
633 inline SelfSourceComponent::OutputPorts::Port
634 SelfSourceComponent::addOutputPort(const std::string& name) const
636 return this->_addOutputPort<void>(name.data(), nullptr);
639 inline SelfSourceComponent::OutputPorts SelfSourceComponent::outputPorts() const noexcept
641 return OutputPorts {this->libObjPtr()};
644 template <typename DataT>
645 SelfFilterComponent::OutputPorts::Port SelfFilterComponent::_addOutputPort(const char * const name,
646 DataT * const data) const
648 return this->_addPort<SelfFilterComponent::OutputPorts::Port, bt_self_component_port_output>(
649 name, data, bt_self_component_filter_add_output_port);
652 template <typename DataT>
653 SelfFilterComponent::OutputPorts::Port SelfFilterComponent::addOutputPort(const char * const name,
656 return this->_addOutputPort(name, &data);
659 inline SelfFilterComponent::OutputPorts::Port
660 SelfFilterComponent::addOutputPort(const char * const name) const
662 return this->_addOutputPort<void>(name, nullptr);
665 template <typename DataT>
666 SelfFilterComponent::OutputPorts::Port SelfFilterComponent::addOutputPort(const std::string& name,
669 return this->_addOutputPort(name.data(), &data);
672 inline SelfFilterComponent::OutputPorts::Port
673 SelfFilterComponent::addOutputPort(const std::string& name) const
675 return this->_addOutputPort<void>(name.data(), nullptr);
678 inline SelfFilterComponent::OutputPorts SelfFilterComponent::outputPorts() const noexcept
680 return OutputPorts {this->libObjPtr()};
683 template <typename DataT>
684 SelfFilterComponent::InputPorts::Port SelfFilterComponent::_addInputPort(const char * const name,
685 DataT * const data) const
687 return this->_addPort<SelfFilterComponent::InputPorts::Port, bt_self_component_port_input>(
688 name, data, bt_self_component_filter_add_input_port);
691 template <typename DataT>
692 SelfFilterComponent::InputPorts::Port SelfFilterComponent::addInputPort(const char * const name,
695 return this->_addInputPort(name, &data);
698 inline SelfFilterComponent::InputPorts::Port
699 SelfFilterComponent::addInputPort(const char * const name) const
701 return this->_addInputPort<void>(name, nullptr);
704 template <typename DataT>
705 SelfFilterComponent::InputPorts::Port SelfFilterComponent::addInputPort(const std::string& name,
708 return this->_addInputPort(name.data(), &data);
711 inline SelfFilterComponent::InputPorts::Port
712 SelfFilterComponent::addInputPort(const std::string& name) const
714 return this->_addInputPort<void>(name.data(), nullptr);
717 inline SelfFilterComponent::InputPorts SelfFilterComponent::inputPorts() const noexcept
719 return InputPorts {this->libObjPtr()};
722 inline MessageIterator::Shared
723 SelfSinkComponent::createMessageIterator(const InputPorts::Port port) const
725 bt_message_iterator *libMsgIterPtr = nullptr;
727 const auto status = bt_message_iterator_create_from_sink_component(
728 this->libObjPtr(), port.libObjPtr(), &libMsgIterPtr);
731 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK:
732 BT_ASSERT(libMsgIterPtr);
733 return MessageIterator::Shared::createWithoutRef(libMsgIterPtr);
734 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_MEMORY_ERROR:
735 throw MemoryError {};
736 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_ERROR:
743 template <typename DataT>
744 SelfSinkComponent::InputPorts::Port SelfSinkComponent::_addInputPort(const char * const name,
745 DataT * const data) const
747 return this->_addPort<SelfSinkComponent::InputPorts::Port, bt_self_component_port_input>(
748 name, data, bt_self_component_sink_add_input_port);
751 template <typename DataT>
752 SelfSinkComponent::InputPorts::Port SelfSinkComponent::addInputPort(const char * const name,
755 return this->_addInputPort(name, &data);
758 inline SelfSinkComponent::InputPorts::Port
759 SelfSinkComponent::addInputPort(const char * const name) const
761 return this->_addInputPort<void>(name, nullptr);
764 template <typename DataT>
765 SelfSinkComponent::InputPorts::Port SelfSinkComponent::addInputPort(const std::string& name,
768 return this->_addInputPort(name.data(), &data);
771 inline SelfSinkComponent::InputPorts::Port
772 SelfSinkComponent::addInputPort(const std::string& name) const
774 return this->_addInputPort<void>(name.data(), nullptr);
777 inline SelfSinkComponent::InputPorts SelfSinkComponent::inputPorts() const noexcept
779 return InputPorts {this->libObjPtr()};
782 } /* namespace bt2 */
784 #endif /* BABELTRACE_CPP_COMMON_BT2_SELF_COMPONENT_PORT_HPP */