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(),
106 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);
132 template <typename LibObjT>
133 class SelfSpecificComponent : public BorrowedObject<LibObjT>
136 using typename BorrowedObject<LibObjT>::_ThisBorrowedObject;
139 using typename BorrowedObject<LibObjT>::LibObjPtr;
142 explicit SelfSpecificComponent(const LibObjPtr libObjPtr) noexcept :
143 _ThisBorrowedObject {libObjPtr}
147 template <typename PortT, typename LibPortT, typename AddPortFuncT, typename DataT>
148 PortT _addPort(const char * const name, DataT * const data, AddPortFuncT&& func) const
150 LibPortT *libPortPtr;
152 const auto status = func(this->libObjPtr(), name,
153 const_cast<void *>(static_cast<const void *>(data)), &libPortPtr);
156 case BT_SELF_COMPONENT_ADD_PORT_STATUS_OK:
157 return PortT {libPortPtr};
158 case BT_SELF_COMPONENT_ADD_PORT_STATUS_MEMORY_ERROR:
159 throw MemoryError {};
160 case BT_SELF_COMPONENT_ADD_PORT_STATUS_ERROR:
168 bt2c::CStringView name() const noexcept
170 return this->_selfComponent().name();
173 LoggingLevel loggingLevel() const noexcept
175 return this->_selfComponent().loggingLevel();
178 std::uint64_t graphMipVersion() const noexcept
180 return this->_selfComponent().graphMipVersion();
183 template <typename T>
184 T& data() const noexcept
186 return this->_selfComponent().template data<T>();
189 template <typename T>
190 void data(T& obj) const noexcept
192 this->_selfComponent().data(obj);
196 SelfComponent _selfComponent() const noexcept
198 return SelfComponent {this->libObjPtr()};
204 template <typename LibSelfCompT, typename LibSelfCompPortPtrT>
205 struct SelfComponentPortsSpec;
208 struct SelfComponentPortsSpec<bt_self_component_source, bt_self_component_port_output> final
210 static std::uint64_t portCount(bt_self_component_source * const libCompPtr) noexcept
212 return bt_component_source_get_output_port_count(
213 bt_self_component_source_as_component_source(libCompPtr));
216 static bt_self_component_port_output *portByIndex(bt_self_component_source * const libCompPtr,
217 const std::uint64_t index) noexcept
219 return bt_self_component_source_borrow_output_port_by_index(libCompPtr, index);
222 static bt_self_component_port_output *portByName(bt_self_component_source * const libCompPtr,
223 const char * const name) noexcept
225 return bt_self_component_source_borrow_output_port_by_name(libCompPtr, name);
230 struct SelfComponentPortsSpec<bt_self_component_filter, bt_self_component_port_output> final
232 static std::uint64_t portCount(bt_self_component_filter * const libCompPtr) noexcept
234 return bt_component_filter_get_output_port_count(
235 bt_self_component_filter_as_component_filter(libCompPtr));
238 static bt_self_component_port_output *portByIndex(bt_self_component_filter * const libCompPtr,
239 const std::uint64_t index) noexcept
241 return bt_self_component_filter_borrow_output_port_by_index(libCompPtr, index);
244 static bt_self_component_port_output *portByName(bt_self_component_filter * const libCompPtr,
245 const char * const name) noexcept
247 return bt_self_component_filter_borrow_output_port_by_name(libCompPtr, name);
252 struct SelfComponentPortsSpec<bt_self_component_filter, bt_self_component_port_input> final
254 static std::uint64_t portCount(bt_self_component_filter * const libCompPtr) noexcept
256 return bt_component_filter_get_input_port_count(
257 bt_self_component_filter_as_component_filter(libCompPtr));
260 static bt_self_component_port_input *portByIndex(bt_self_component_filter * const libCompPtr,
261 const std::uint64_t index) noexcept
263 return bt_self_component_filter_borrow_input_port_by_index(libCompPtr, index);
266 static bt_self_component_port_input *portByName(bt_self_component_filter * const libCompPtr,
267 const char * const name) noexcept
269 return bt_self_component_filter_borrow_input_port_by_name(libCompPtr, name);
274 struct SelfComponentPortsSpec<bt_self_component_sink, bt_self_component_port_input> final
276 static std::uint64_t portCount(bt_self_component_sink * const libCompPtr) noexcept
278 return bt_component_sink_get_input_port_count(
279 bt_self_component_sink_as_component_sink(libCompPtr));
282 static bt_self_component_port_input *portByIndex(bt_self_component_sink * const libCompPtr,
283 const std::uint64_t index) noexcept
285 return bt_self_component_sink_borrow_input_port_by_index(libCompPtr, index);
288 static bt_self_component_port_input *portByName(bt_self_component_sink * const libCompPtr,
289 const char * const name) noexcept
291 return bt_self_component_sink_borrow_input_port_by_name(libCompPtr, name);
295 } /* namespace internal */
297 template <typename LibSelfCompPortT, typename LibPortT>
298 class SelfComponentPort;
300 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
301 class SelfComponentPorts final : public BorrowedObject<LibSelfCompT>
304 using typename BorrowedObject<LibSelfCompT>::_ThisBorrowedObject;
305 using _Spec = internal::SelfComponentPortsSpec<LibSelfCompT, LibSelfCompPortT>;
308 using typename BorrowedObject<LibSelfCompT>::LibObjPtr;
309 using Port = SelfComponentPort<LibSelfCompPortT, LibPortT>;
310 using Iterator = BorrowedObjectIterator<SelfComponentPorts>;
312 explicit SelfComponentPorts(const LibObjPtr libObjPtr) noexcept :
313 _ThisBorrowedObject {libObjPtr}
317 std::uint64_t length() const noexcept
319 return _Spec::portCount(this->libObjPtr());
322 Port operator[](std::uint64_t index) const noexcept;
323 Port operator[](bt2c::CStringView name) const noexcept;
324 Iterator begin() const noexcept;
325 Iterator end() const noexcept;
326 Port front() const noexcept;
327 Port back() const noexcept;
330 class SelfSourceComponent final : public SelfSpecificComponent<bt_self_component_source>
333 using OutputPorts = SelfComponentPorts<bt_self_component_source, bt_self_component_port_output,
334 const bt_port_output>;
336 explicit SelfSourceComponent(bt_self_component_source * const libObjPtr) noexcept :
337 SelfSpecificComponent {libObjPtr}
341 ConstSourceComponent asConstComponent() const noexcept
343 return ConstSourceComponent {
344 bt_self_component_source_as_component_source(this->libObjPtr())};
347 template <typename DataT>
348 OutputPorts::Port addOutputPort(bt2c::CStringView name, DataT& data) const;
350 OutputPorts::Port addOutputPort(bt2c::CStringView name) const;
352 OutputPorts outputPorts() const noexcept;
355 template <typename DataT>
356 OutputPorts::Port _addOutputPort(const char *name, DataT *data) const;
359 class SelfFilterComponent final : public SelfSpecificComponent<bt_self_component_filter>
362 using InputPorts = SelfComponentPorts<bt_self_component_filter, bt_self_component_port_input,
363 const bt_port_input>;
364 using OutputPorts = SelfComponentPorts<bt_self_component_filter, bt_self_component_port_output,
365 const bt_port_output>;
367 explicit SelfFilterComponent(bt_self_component_filter * const libObjPtr) noexcept :
368 SelfSpecificComponent {libObjPtr}
372 ConstFilterComponent asConstComponent() const noexcept
374 return ConstFilterComponent {
375 bt_self_component_filter_as_component_filter(this->libObjPtr())};
378 template <typename DataT>
379 InputPorts::Port addInputPort(bt2c::CStringView name, DataT& data) const;
381 InputPorts::Port addInputPort(bt2c::CStringView name) const;
383 InputPorts inputPorts() const noexcept;
385 template <typename DataT>
386 OutputPorts::Port addOutputPort(bt2c::CStringView name, DataT& data) const;
388 OutputPorts::Port addOutputPort(bt2c::CStringView name) const;
390 OutputPorts outputPorts() const noexcept;
393 template <typename DataT>
394 InputPorts::Port _addInputPort(const char *name, DataT *data) const;
396 template <typename DataT>
397 OutputPorts::Port _addOutputPort(const char *name, DataT *data) const;
400 class SelfSinkComponent final : public SelfSpecificComponent<bt_self_component_sink>
403 using InputPorts = SelfComponentPorts<bt_self_component_sink, bt_self_component_port_input,
404 const bt_port_input>;
406 explicit SelfSinkComponent(bt_self_component_sink * const libObjPtr) noexcept :
407 SelfSpecificComponent {libObjPtr}
411 ConstSinkComponent asConstComponent() const noexcept
413 return ConstSinkComponent {bt_self_component_sink_as_component_sink(this->libObjPtr())};
416 MessageIterator::Shared createMessageIterator(InputPorts::Port port) const;
418 bool isInterrupted() const noexcept
420 return static_cast<bool>(bt_self_component_sink_is_interrupted(this->libObjPtr()));
423 template <typename DataT>
424 InputPorts::Port addInputPort(bt2c::CStringView name, DataT& data) const;
426 InputPorts::Port addInputPort(bt2c::CStringView name) const;
428 InputPorts inputPorts() const noexcept;
431 template <typename DataT>
432 InputPorts::Port _addInputPort(const char *name, DataT *data) const;
435 inline SelfComponent::SelfComponent(const SelfSourceComponent other) noexcept :
436 SelfComponent {other.libObjPtr()}
440 inline SelfComponent::SelfComponent(const SelfFilterComponent other) noexcept :
441 SelfComponent {other.libObjPtr()}
445 inline SelfComponent::SelfComponent(const SelfSinkComponent other) noexcept :
446 SelfComponent {other.libObjPtr()}
450 inline SelfComponent SelfComponent::operator=(const SelfSourceComponent other) noexcept
452 *this = SelfComponent {other.libObjPtr()};
456 inline SelfComponent SelfComponent::operator=(const SelfFilterComponent other) noexcept
458 *this = SelfComponent {other.libObjPtr()};
462 inline SelfComponent SelfComponent::operator=(const SelfSinkComponent other) noexcept
464 *this = SelfComponent {other.libObjPtr()};
470 template <typename LibObjT>
471 struct SelfComponentPortSpec;
473 /* Functions specific to self component input ports */
475 struct SelfComponentPortSpec<bt_self_component_port_input> final
477 static bt_self_component_port *
478 asSelfCompPort(bt_self_component_port_input * const libObjPtr) noexcept
480 return bt_self_component_port_input_as_self_component_port(libObjPtr);
483 static const bt_port_input *
484 asConstPort(const bt_self_component_port_input * const libObjPtr) noexcept
486 return bt_self_component_port_input_as_port_input(libObjPtr);
490 /* Functions specific to self component output ports */
492 struct SelfComponentPortSpec<bt_self_component_port_output> final
494 static bt_self_component_port *
495 asSelfCompPort(bt_self_component_port_output * const libObjPtr) noexcept
497 return bt_self_component_port_output_as_self_component_port(libObjPtr);
500 static const bt_port_output *
501 asConstPort(bt_self_component_port_output * const libObjPtr) noexcept
503 return bt_self_component_port_output_as_port_output(libObjPtr);
507 } /* namespace internal */
509 template <typename LibSelfCompPortT, typename LibPortT>
510 class SelfComponentPort final : public BorrowedObject<LibSelfCompPortT>
513 using typename BorrowedObject<LibSelfCompPortT>::LibObjPtr;
515 explicit SelfComponentPort(const LibObjPtr libObjPtr) noexcept :
516 BorrowedObject<LibSelfCompPortT> {libObjPtr}
520 ConstPort<LibPortT> asConstPort() const noexcept
522 return ConstPort<LibPortT> {
523 internal::SelfComponentPortSpec<LibSelfCompPortT>::asConstPort(this->libObjPtr())};
526 bt2c::CStringView name() const noexcept
528 return this->asConstPort().name();
531 bool isConnected() const noexcept
533 return this->asConstPort().isConnected();
536 SelfComponent component() const noexcept
538 return SelfComponent {bt_self_component_port_borrow_component(this->_libSelfCompPortPtr())};
541 template <typename T>
542 T& data() const noexcept
544 return *static_cast<T *>(bt_self_component_port_get_data(this->_libSelfCompPortPtr()));
548 bt_self_component_port *_libSelfCompPortPtr() const noexcept
550 return internal::SelfComponentPortSpec<LibSelfCompPortT>::asSelfCompPort(this->libObjPtr());
554 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
555 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
556 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::operator[](
557 const std::uint64_t index) const noexcept
559 return Port {_Spec::portByIndex(this->libObjPtr(), index)};
562 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
563 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
564 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::operator[](
565 const bt2c::CStringView name) const noexcept
567 return Port {_Spec::portByName(this->libObjPtr(), name)};
570 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
571 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Iterator
572 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::begin() const noexcept
574 return Iterator {*this, 0};
577 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
578 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Iterator
579 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::end() const noexcept
581 return Iterator {*this, this->length()};
584 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
585 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
586 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::front() const noexcept
591 template <typename LibSelfCompT, typename LibSelfCompPortT, typename LibPortT>
592 typename SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::Port
593 SelfComponentPorts<LibSelfCompT, LibSelfCompPortT, LibPortT>::back() const noexcept
595 return (*this)[this->length() - 1];
598 using SelfComponentInputPort = SelfComponentPort<bt_self_component_port_input, const bt_port_input>;
600 using SelfComponentOutputPort =
601 SelfComponentPort<bt_self_component_port_output, const bt_port_output>;
603 template <typename DataT>
604 SelfSourceComponent::OutputPorts::Port SelfSourceComponent::_addOutputPort(const char * const name,
605 DataT * const data) const
607 return this->_addPort<SelfSourceComponent::OutputPorts::Port, bt_self_component_port_output>(
608 name, data, bt_self_component_source_add_output_port);
611 template <typename DataT>
612 SelfSourceComponent::OutputPorts::Port
613 SelfSourceComponent::addOutputPort(const bt2c::CStringView name, DataT& data) const
615 return this->_addOutputPort(name, &data);
618 inline SelfSourceComponent::OutputPorts::Port
619 SelfSourceComponent::addOutputPort(const bt2c::CStringView name) const
621 return this->_addOutputPort<void>(name, nullptr);
624 inline SelfSourceComponent::OutputPorts SelfSourceComponent::outputPorts() const noexcept
626 return OutputPorts {this->libObjPtr()};
629 template <typename DataT>
630 SelfFilterComponent::OutputPorts::Port SelfFilterComponent::_addOutputPort(const char * const name,
631 DataT * const data) const
633 return this->_addPort<SelfFilterComponent::OutputPorts::Port, bt_self_component_port_output>(
634 name, data, bt_self_component_filter_add_output_port);
637 template <typename DataT>
638 SelfFilterComponent::OutputPorts::Port
639 SelfFilterComponent::addOutputPort(const bt2c::CStringView name, DataT& data) const
641 return this->_addOutputPort(name, &data);
644 inline SelfFilterComponent::OutputPorts::Port
645 SelfFilterComponent::addOutputPort(const bt2c::CStringView name) const
647 return this->_addOutputPort<void>(name, nullptr);
650 inline SelfFilterComponent::OutputPorts SelfFilterComponent::outputPorts() const noexcept
652 return OutputPorts {this->libObjPtr()};
655 template <typename DataT>
656 SelfFilterComponent::InputPorts::Port SelfFilterComponent::_addInputPort(const char * const name,
657 DataT * const data) const
659 return this->_addPort<SelfFilterComponent::InputPorts::Port, bt_self_component_port_input>(
660 name, data, bt_self_component_filter_add_input_port);
663 template <typename DataT>
664 SelfFilterComponent::InputPorts::Port
665 SelfFilterComponent::addInputPort(const bt2c::CStringView name, DataT& data) const
667 return this->_addInputPort(name, &data);
670 inline SelfFilterComponent::InputPorts::Port
671 SelfFilterComponent::addInputPort(const bt2c::CStringView name) const
673 return this->_addInputPort<void>(name, nullptr);
676 inline SelfFilterComponent::InputPorts SelfFilterComponent::inputPorts() const noexcept
678 return InputPorts {this->libObjPtr()};
681 inline MessageIterator::Shared
682 SelfSinkComponent::createMessageIterator(const InputPorts::Port port) const
684 bt_message_iterator *libMsgIterPtr = nullptr;
686 const auto status = bt_message_iterator_create_from_sink_component(
687 this->libObjPtr(), port.libObjPtr(), &libMsgIterPtr);
690 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK:
691 BT_ASSERT(libMsgIterPtr);
692 return MessageIterator::Shared::createWithoutRef(libMsgIterPtr);
693 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_MEMORY_ERROR:
694 throw MemoryError {};
695 case BT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_ERROR:
702 template <typename DataT>
703 SelfSinkComponent::InputPorts::Port SelfSinkComponent::_addInputPort(const char * const name,
704 DataT * const data) const
706 return this->_addPort<SelfSinkComponent::InputPorts::Port, bt_self_component_port_input>(
707 name, data, bt_self_component_sink_add_input_port);
710 template <typename DataT>
711 SelfSinkComponent::InputPorts::Port SelfSinkComponent::addInputPort(const bt2c::CStringView name,
714 return this->_addInputPort(name, &data);
717 inline SelfSinkComponent::InputPorts::Port
718 SelfSinkComponent::addInputPort(const bt2c::CStringView name) const
720 return this->_addInputPort<void>(name, nullptr);
723 inline SelfSinkComponent::InputPorts SelfSinkComponent::inputPorts() const noexcept
725 return InputPorts {this->libObjPtr()};
728 } /* namespace bt2 */
730 #endif /* BABELTRACE_CPP_COMMON_BT2_SELF_COMPONENT_PORT_HPP */