Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#264] cxx bindings for attributes #549

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/actions/install-iceoryx-deps-and-clang/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ runs:
shell: bash
run: |
sudo wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo add-apt-repository "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main"
sudo add-apt-repository "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-19 main"
sudo apt-get update
sudo apt-get install -y libacl1-dev
sudo apt-get install -y clang-format-18 clang-tidy-18 clang-tools-18 clang-18 lld
sudo apt-get install -y clang-format-19 clang-tidy-19 clang-tools-19 clang-19 lld
sudo rm /usr/bin/clang
sudo rm /usr/bin/clang++
sudo rm /usr/bin/clang-tidy
sudo rm /usr/bin/clang-format
sudo ln -s /usr/bin/clang-18 /usr/bin/clang
sudo ln -s /usr/bin/clang++-18 /usr/bin/clang++
sudo ln -s /usr/bin/clang-tidy-18 /usr/bin/clang-tidy
sudo ln -s /usr/bin/clang-format-18 /usr/bin/clang-format
sudo ln -s /usr/bin/clang-19 /usr/bin/clang
sudo ln -s /usr/bin/clang++-19 /usr/bin/clang++
sudo ln -s /usr/bin/clang-tidy-19 /usr/bin/clang-tidy
sudo ln -s /usr/bin/clang-format-19 /usr/bin/clang-format
1 change: 1 addition & 0 deletions doc/release-notes/iceoryx2-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
conflicts when merging.
-->

* C++ bindings for attributes [#264](https://github.com/eclipse-iceoryx/iceoryx2/issues/264)
* Add Event-Multiplexer `WaitSet` [#390](https://github.com/eclipse-iceoryx/iceoryx2/issues/390)
* Add `PeriodicTimer` into POSIX building blocks [#425](https://github.com/eclipse-iceoryx/iceoryx2/issues/425)
* Developer permissions for resources [#460](https://github.com/eclipse-iceoryx/iceoryx2/issues/460)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ class CustomPublisher : public iox2::FileDescriptorBased {
.expect("");
}

static auto create(iox2::Node<iox2::ServiceType::Ipc>& node,
const iox2::ServiceName& service_name) -> CustomPublisher {
static auto create(iox2::Node<iox2::ServiceType::Ipc>& node, const iox2::ServiceName& service_name)
-> CustomPublisher {
auto pubsub_service = node.service_builder(service_name)
.publish_subscribe<TransmissionData>()
.history_size(HISTORY_SIZE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#ifndef IOX2_EXAMPLES_CUSTOM_SUBSCRIBER_HPP
#define IOX2_EXAMPLES_CUSTOM_SUBSCRIBER_HPP

#include "iox/into.hpp"
#include "iox2/file_descriptor.hpp"
#include "iox2/listener.hpp"
#include "iox2/node.hpp"
Expand Down Expand Up @@ -44,8 +43,8 @@ class CustomSubscriber : public iox2::FileDescriptorBased {
auto operator=(const CustomSubscriber&) -> CustomSubscriber& = delete;
auto operator=(CustomSubscriber&&) -> CustomSubscriber& = default;

static auto create(iox2::Node<iox2::ServiceType::Ipc>& node,
const iox2::ServiceName& service_name) -> CustomSubscriber {
static auto create(iox2::Node<iox2::ServiceType::Ipc>& node, const iox2::ServiceName& service_name)
-> CustomSubscriber {
auto pubsub_service =
node.service_builder(service_name).publish_subscribe<TransmissionData>().open_or_create().expect("");
auto event_service = node.service_builder(service_name).event().open_or_create().expect("");
Expand Down
4 changes: 4 additions & 0 deletions iceoryx2-ffi/cxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ target_include_directories(includes-only-cxx
# object lib

add_library(iceoryx2-cxx-object-lib OBJECT
src/attribute.cpp
src/attribute_set.cpp
src/attribute_specifier.cpp
src/attribute_verifier.cpp
src/config.cpp
src/event_id.cpp
src/file_descriptor.cpp
Expand Down
32 changes: 23 additions & 9 deletions iceoryx2-ffi/cxx/include/iox2/attribute.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,39 @@
#ifndef IOX2_ATTRIBUTE_HPP
#define IOX2_ATTRIBUTE_HPP

#include "iox/assertions_addendum.hpp"
#include "iox/string.hpp"
#include "iox2/internal/iceoryx2.hpp"

#include <string>

namespace iox2 {
/// Represents a single service attribute (key-value) pair that can be defined when the service
/// is being created.
class Attribute {
public:
using Key = iox::string<IOX2_ATTRIBUTE_KEY_LENGTH>;
using Value = iox::string<IOX2_ATTRIBUTE_VALUE_LENGTH>;
};

/// Represents a single view service attribute (key-value) pair that can be defined when the service
/// is being created.
///
/// @attention The parent from which the view was extracted MUST live longer than the
/// [`AttributeView`].
class AttributeView {
public:
/// Acquires the service attribute key
auto key() const -> Attribute::Key;

/// Acquires the service attribute value
auto value() const -> Attribute::Value;

private:
friend class AttributeSetView;
explicit AttributeView(iox2_attribute_h_ref handle);

auto key() const -> Key {
IOX_TODO();
}
auto value() const -> Value {
IOX_TODO();
}
iox2_attribute_h_ref m_handle = nullptr;
};
} // namespace iox2
//
auto operator<<(std::ostream& stream, const iox2::AttributeView& value) -> std::ostream&;

#endif
40 changes: 29 additions & 11 deletions iceoryx2-ffi/cxx/include/iox2/attribute_set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,44 @@
#ifndef IOX2_ATTRIBUTE_SET_HPP
#define IOX2_ATTRIBUTE_SET_HPP

#include "iox/assertions_addendum.hpp"
#include "iox/vector.hpp"
#include "iox/function.hpp"
#include "iox2/attribute.hpp"
#include "iox2/internal/iceoryx2.hpp"

#include <iostream>

namespace iox2 {
class AttributeSet {
/// Represents all service attributes. They can be set when the service is created.
///
/// @attention The parent from which the view was extracted MUST live longer than the
/// [`AttributeSetView`].
class AttributeSetView {
public:
auto get(const Attribute::Key& key) const -> iox::vector<Attribute::Value, IOX2_MAX_VALUES_PER_ATTRIBUTE_KEY> {
IOX_TODO();
}
};
/// Returns the number of [`Attribute`]s stored inside the [`AttributeSet`].
auto len() const -> uint64_t;

/// Returns a [`AttributeView`] at a specific index. The number of indices is returned via
/// [`AttributeSetView::len()`].
auto at(uint64_t index) const -> AttributeView;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Food for thought. For certification we might need to return an Optional<AttributeView> to not have to terminate for out of bounds access.

But we need to review the whole API for this scenarios, so I think it's fine to stay as is for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or we work with begin() and end() and iterators or for_each and for.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, that's a different use case. If someone really wants to access element at index N, then it only works by checking the size before using at ... but that's a different philosophical question


/// Returns all values to a specific key
void get_key_values(const Attribute::Key& key,
const iox::function<CallbackProgression(const Attribute::Value&)>& callback) const;

inline auto operator<<(std::ostream& stream, const AttributeSet& value) -> std::ostream& {
stream << "AttributeSet { }";
return stream;
}
private:
template <ServiceType, typename, typename>
friend class PortFactoryPublishSubscribe;
template <ServiceType>
friend class PortFactoryEvent;
friend class AttributeVerifier;
friend class AttributeSpecifier;

explicit AttributeSetView(iox2_attribute_set_h_ref handle);

iox2_attribute_set_h_ref m_handle = nullptr;
};
} // namespace iox2

auto operator<<(std::ostream& stream, const iox2::AttributeSetView& value) -> std::ostream&;

#endif
34 changes: 27 additions & 7 deletions iceoryx2-ffi/cxx/include/iox2/attribute_specifier.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,37 @@
#define IOX2_ATTRIBUTE_SPECIFIER_HPP

#include "attribute_set.hpp"
#include "iox/assertions_addendum.hpp"

namespace iox2 {

/// Represents the set of [`Attribute`]s that are defined when the [`Service`]
/// is created.
class AttributeSpecifier {
public:
auto define(const Attribute::Key& key, const Attribute::Value& value) -> AttributeSpecifier& {
IOX_TODO();
}
auto attributes() const -> AttributeSet& {
IOX_TODO();
}
/// Creates a new empty set of [`Attribute`]s
AttributeSpecifier();
AttributeSpecifier(const AttributeSpecifier&) = delete;
AttributeSpecifier(AttributeSpecifier&&) noexcept;
~AttributeSpecifier();

auto operator=(const AttributeSpecifier&) -> AttributeSpecifier& = delete;
auto operator=(AttributeSpecifier&&) noexcept -> AttributeSpecifier&;

/// Defines a value for a specific key. A key is allowed to have multiple values.
auto define(const Attribute::Key& key, const Attribute::Value& value) -> AttributeSpecifier&&;

/// Returns the underlying [`AttributeSetView`]
auto attributes() const -> AttributeSetView;

private:
template <ServiceType>
friend class ServiceBuilderEvent;
template <typename, typename, ServiceType>
friend class ServiceBuilderPublishSubscribe;

void drop();

iox2_attribute_specifier_h m_handle = nullptr;
};
} // namespace iox2

Expand Down
53 changes: 35 additions & 18 deletions iceoryx2-ffi/cxx/include/iox2/attribute_verifier.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,50 @@
#ifndef IOX2_ATTRIBUTE_VERIFIER_HPP
#define IOX2_ATTRIBUTE_VERIFIER_HPP

#include "iox/assertions_addendum.hpp"
#include "iox/expected.hpp"
#include "iox/vector.hpp"
#include "iox2/attribute.hpp"
#include "iox2/attribute_set.hpp"
#include "iox2/internal/iceoryx2.hpp"

namespace iox2 {
/// Represents the set of [`Attribute`]s that are required when the [`Service`]
/// is opened.
class AttributeVerifier {
public:
AttributeVerifier() = default;
auto require(const Attribute::Key& key, const Attribute::Value& value) -> AttributeVerifier& {
IOX_TODO();
}
auto require_key(const Attribute::Key& key) -> AttributeVerifier& {
IOX_TODO();
}
auto attributes() const -> const AttributeSet& {
IOX_TODO();
}
auto keys() const -> iox::vector<Attribute::Key, IOX2_MAX_ATTRIBUTES_PER_SERVICE> {
IOX_TODO();
}

auto verify_requirements(const AttributeSet& rhs) const -> iox::expected<void, Attribute::Key> {
IOX_TODO();
}
/// Creates a new empty set of [`Attribute`]s
AttributeVerifier();
AttributeVerifier(const AttributeVerifier&) = delete;
AttributeVerifier(AttributeVerifier&&) noexcept;
~AttributeVerifier();

auto operator=(const AttributeVerifier&) -> AttributeVerifier& = delete;
auto operator=(AttributeVerifier&&) noexcept -> AttributeVerifier&;

/// Requires a value for a specific key. A key is allowed to have multiple values.
auto require(const Attribute::Key& key, const Attribute::Value& value) -> AttributeVerifier&&;

/// Requires that a specific key is defined.
auto require_key(const Attribute::Key& key) -> AttributeVerifier&&;

/// Returns the underlying required [`AttributeSet`]
auto attributes() const -> AttributeSetView;

/// Returns the underlying required keys
auto keys() const -> iox::vector<Attribute::Key, IOX2_MAX_ATTRIBUTES_PER_SERVICE>;

/// Verifies if the [`AttributeSet`] contains all required keys and key-value pairs.
auto verify_requirements(const AttributeSetView& rhs) const -> iox::expected<void, Attribute::Key>;

private:
template <ServiceType>
friend class ServiceBuilderEvent;
template <typename, typename, ServiceType>
friend class ServiceBuilderPublishSubscribe;

void drop();

iox2_attribute_verifier_h m_handle = nullptr;
};
} // namespace iox2

Expand Down
14 changes: 7 additions & 7 deletions iceoryx2-ffi/cxx/include/iox2/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class Node {
friend class Global;
explicit Node(iox2_config_h* config);

iox2_config_h* m_config;
iox2_config_h* m_config = nullptr;
};

/// All configurable settings of a [`Service`].
Expand Down Expand Up @@ -103,7 +103,7 @@ class Service {
friend class Global;
explicit Service(iox2_config_h* config);

iox2_config_h* m_config;
iox2_config_h* m_config = nullptr;
};

/// The global settings
Expand All @@ -128,7 +128,7 @@ class Global {
friend class ::iox2::Config;
explicit Global(iox2_config_h* config);

iox2_config_h* m_config;
iox2_config_h* m_config = nullptr;
};

/// Default settings for the publish-subscribe messaging pattern. These settings are used unless
Expand Down Expand Up @@ -188,7 +188,7 @@ class PublishSubscribe {
friend class Defaults;
explicit PublishSubscribe(iox2_config_h* config);

iox2_config_h* m_config;
iox2_config_h* m_config = nullptr;
};

/// Default settings for the event messaging pattern. These settings are used unless
Expand Down Expand Up @@ -217,7 +217,7 @@ class Event {
friend class Defaults;
explicit Event(iox2_config_h* config);

iox2_config_h* m_config;
iox2_config_h* m_config = nullptr;
};

/// Default settings. These values are used when the user in the code does not specify anything
Expand All @@ -233,7 +233,7 @@ class Defaults {
friend class ::iox2::Config;
explicit Defaults(iox2_config_h* config);

iox2_config_h* m_config;
iox2_config_h* m_config = nullptr;
};
} // namespace config

Expand All @@ -258,7 +258,7 @@ class ConfigView {
friend class Service;

explicit ConfigView(iox2_config_ptr ptr);
iox2_config_ptr m_ptr;
iox2_config_ptr m_ptr = nullptr;
};

/// Represents the configuration that iceoryx2 will utilize. It is divided into two sections:
Expand Down
Loading
Loading