diff --git a/iceoryx_hoofs/include/iceoryx_hoofs/error_handling/error_handling.hpp b/iceoryx_hoofs/include/iceoryx_hoofs/error_handling/error_handling.hpp index c705f5369e..c9c8c5edc5 100644 --- a/iceoryx_hoofs/include/iceoryx_hoofs/error_handling/error_handling.hpp +++ b/iceoryx_hoofs/include/iceoryx_hoofs/error_handling/error_handling.hpp @@ -65,6 +65,8 @@ namespace iox error(POSH__SENDERPORT_ALLOCATE_FAILED) \ error(POSH__SENDERPORT_SUBSCRIBER_LIST_OVERFLOW) \ error(POSH__PUBLISHING_EMPTY_SAMPLE) \ + error(POSH__SENDING_EMPTY_REQUEST) \ + error(POSH__SENDING_EMPTY_RESPONSE) \ error(POSH__SHM_APP_BASEADDRESS_VIOLATES_SPECIFICATION) \ error(POSH__SHM_APP_SEGMENT_BASEADDRESS_VIOLATES_SPECIFICATION) \ error(POSH__SHM_APP_MAPP_ERR) \ diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/request.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/request.inl new file mode 100644 index 0000000000..955e4a11d2 --- /dev/null +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/request.inl @@ -0,0 +1,70 @@ +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by AVIN Systems Private Limited All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IOX_POSH_POPO_REQUEST_INL +#define IOX_POSH_POPO_REQUEST_INL + +namespace iox +{ +namespace popo +{ +template +template +inline Request::Request(cxx::unique_ptr&& requestUniquePtr, RpcInterface>& producer) noexcept + : Base_t(std::move(requestUniquePtr), producer) +{ +} + +template +template +inline Request::Request(cxx::unique_ptr&& requestUniquePtr) noexcept + : Base_t(std::move(requestUniquePtr)) +{ +} + +template +inline RequestHeader& Request::getRequestHeader() noexcept +{ + return *static_cast(mepoo::ChunkHeader::fromUserPayload(Base_t::m_members.smartchunkUniquePtr.get())->userHeader()); +} + +template +inline const RequestHeader& Request::getRequestHeader() const noexcept +{ + return const_cast*>(this)->getRequestHeader(); +} + +template +template +inline void Request::send() noexcept +{ + if (Base_t::m_members.smartchunkUniquePtr) + { + Base_t::m_members.transmitterRef.get().send(std::move(*this)); + } + else + { + LogError() << "Tried to send empty Request! Might be an already sent or moved Request!"; + errorHandler(Error::kPOSH__SENDING_EMPTY_REQUEST, nullptr, ErrorLevel::MODERATE); + } +} + +} // namespace popo +} // namespace iox + +#endif // IOX_POSH_POPO_REQUEST_INL diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/response.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/response.inl new file mode 100644 index 0000000000..56f2a4dcf5 --- /dev/null +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/response.inl @@ -0,0 +1,70 @@ +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by AVIN Systems Private Limited All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IOX_POSH_POPO_RESPONSE_INL +#define IOX_POSH_POPO_RESPONSE_INL + +namespace iox +{ +namespace popo +{ +template +template +inline Response::Response(cxx::unique_ptr&& responseUniquePtr, RpcInterface>& producer) noexcept + : Base_t(std::move(responseUniquePtr), producer) +{ +} + +template +template +inline Response::Response(cxx::unique_ptr&& responseUniquePtr) noexcept + : Base_t(std::move(responseUniquePtr)) +{ +} + +template +inline ResponseHeader& Response::getResponseHeader() noexcept +{ + return *static_cast(mepoo::ChunkHeader::fromUserPayload(Base_t::m_members.smartchunkUniquePtr.get())->userHeader()); +} + +template +inline const ResponseHeader& Response::getResponseHeader() const noexcept +{ + return const_cast*>(this)->getResponseHeader(); +} + +template +template +inline void Response::send() noexcept +{ + if (Base_t::m_members.smartchunkUniquePtr) + { + Base_t::m_members.transmitterRef.get().send(std::move(*this)); + } + else + { + LogError() << "Tried to send empty Response! Might be an already sent or moved Response!"; + errorHandler(Error::kPOSH__SENDING_EMPTY_RESPONSE, nullptr, ErrorLevel::MODERATE); + } +} + +} // namespace popo +} // namespace iox + +#endif // IOX_POSH_POPO_RESPONSE_INL diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/sample.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/sample.inl index f42a0276ae..a358ddf4fd 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/popo/sample.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/sample.inl @@ -1,5 +1,6 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. // Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by AVIN Systems Private Limited All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -22,96 +23,25 @@ namespace iox { namespace popo { -namespace internal -{ -template -inline SamplePrivateData::SamplePrivateData(cxx::unique_ptr&& sampleUniquePtr, - PublisherInterface& publisher) noexcept - : sampleUniquePtr(std::move(sampleUniquePtr)) - , publisherRef(publisher) -{ -} - -template -inline SamplePrivateData::SamplePrivateData(cxx::unique_ptr&& sampleUniquePtr) noexcept - : sampleUniquePtr(std::move(sampleUniquePtr)) -{ -} -} // namespace internal - template template inline Sample::Sample(cxx::unique_ptr&& sampleUniquePtr, PublisherInterface& publisher) noexcept - : m_members({std::move(sampleUniquePtr), publisher}) + : Base_t(std::move(sampleUniquePtr), publisher) { } template template inline Sample::Sample(cxx::unique_ptr&& sampleUniquePtr) noexcept - : m_members(std::move(sampleUniquePtr)) -{ -} - -template -inline T* Sample::operator->() noexcept -{ - return get(); -} - -template -inline const T* Sample::operator->() const noexcept -{ - return get(); -} - -template -inline T& Sample::operator*() noexcept -{ - return *get(); -} - -template -inline const T& Sample::operator*() const noexcept + : Base_t(std::move(sampleUniquePtr)) { - return *get(); -} - -template -inline Sample::operator bool() const noexcept -{ - return get() != nullptr; -} - -template -inline T* Sample::get() noexcept -{ - return m_members.sampleUniquePtr.get(); -} - -template -inline const T* Sample::get() const noexcept -{ - return m_members.sampleUniquePtr.get(); -} - -template -inline typename Sample::ConditionalConstChunkHeader_t* Sample::getChunkHeader() noexcept -{ - return mepoo::ChunkHeader::fromUserPayload(m_members.sampleUniquePtr.get()); -} - -template -inline const mepoo::ChunkHeader* Sample::getChunkHeader() const noexcept -{ - return mepoo::ChunkHeader::fromUserPayload(m_members.sampleUniquePtr.get()); } template template inline R& Sample::getUserHeader() noexcept { - return *static_cast(mepoo::ChunkHeader::fromUserPayload(m_members.sampleUniquePtr.get())->userHeader()); + return *static_cast(mepoo::ChunkHeader::fromUserPayload(Base_t::m_members.smartchunkUniquePtr.get())->userHeader()); } template @@ -125,9 +55,9 @@ template template inline void Sample::publish() noexcept { - if (m_members.sampleUniquePtr) + if (Base_t::m_members.smartchunkUniquePtr) { - m_members.publisherRef.get().publish(std::move(*this)); + Base_t::m_members.transmitterRef.get().publish(std::move(*this)); } else { @@ -136,12 +66,6 @@ inline void Sample::publish() noexcept } } -template -inline T* Sample::release() noexcept -{ - return m_members.sampleUniquePtr.release(); -} - } // namespace popo } // namespace iox diff --git a/iceoryx_posh/include/iceoryx_posh/internal/popo/smart_chunk.inl b/iceoryx_posh/include/iceoryx_posh/internal/popo/smart_chunk.inl new file mode 100644 index 0000000000..a108c025a4 --- /dev/null +++ b/iceoryx_posh/include/iceoryx_posh/internal/popo/smart_chunk.inl @@ -0,0 +1,124 @@ +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by AVIN Systems Private Limited All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IOX_POSH_POPO_SMARTCHUNK_INL +#define IOX_POSH_POPO_SMARTCHUNK_INL + +namespace iox +{ +namespace popo +{ +namespace internal +{ +template +inline SmartChunkPrivateData::SmartChunkPrivateData( + cxx::unique_ptr&& smartchunkUniquePtr, TransmissionInterface& transmitter) noexcept + : smartchunkUniquePtr(std::move(smartchunkUniquePtr)) + , transmitterRef(transmitter) +{ +} + +template +inline SmartChunkPrivateData::SmartChunkPrivateData( + cxx::unique_ptr&& smartchunkUniquePtr) noexcept + : smartchunkUniquePtr(std::move(smartchunkUniquePtr)) +{ +} + +} // namespace internal + +template +template +inline SmartChunk::SmartChunk(cxx::unique_ptr&& smartchunkUniquePtr, + TransmissionInterface& transmitter) noexcept + : m_members({std::move(smartchunkUniquePtr), transmitter}) +{ +} + +template +template +inline SmartChunk::SmartChunk(cxx::unique_ptr&& smartchunkUniquePtr) noexcept + : m_members(std::move(smartchunkUniquePtr)) +{ +} + +template +inline T* SmartChunk::operator->() noexcept +{ + return get(); +} + +template +inline const T* SmartChunk::operator->() const noexcept +{ + return get(); +} + +template +inline T& SmartChunk::operator*() noexcept +{ + return *get(); +} + +template +inline const T& SmartChunk::operator*() const noexcept +{ + return *get(); +} + +template +inline SmartChunk::operator bool() const noexcept +{ + return get() != nullptr; +} + +template +inline T* SmartChunk::get() noexcept +{ + return m_members.smartchunkUniquePtr.get(); +} + +template +inline const T* SmartChunk::get() const noexcept +{ + return m_members.smartchunkUniquePtr.get(); +} + +template +inline typename SmartChunk::ConditionalConstChunkHeader_t* +SmartChunk::getChunkHeader() noexcept +{ + return mepoo::ChunkHeader::fromUserPayload(m_members.smartchunkUniquePtr.get()); +} + +template +inline const mepoo::ChunkHeader* SmartChunk::getChunkHeader() const noexcept +{ + return mepoo::ChunkHeader::fromUserPayload(m_members.smartchunkUniquePtr.get()); +} + +template +inline T* SmartChunk::release() noexcept +{ + return m_members.smartchunkUniquePtr.release(); +} + +} // namespace popo +} // namespace iox + +#endif // IOX_POSH_POPO_SMARTCHUNK_INL diff --git a/iceoryx_posh/include/iceoryx_posh/popo/request.hpp b/iceoryx_posh/include/iceoryx_posh/popo/request.hpp new file mode 100644 index 0000000000..7a14595e25 --- /dev/null +++ b/iceoryx_posh/include/iceoryx_posh/popo/request.hpp @@ -0,0 +1,95 @@ +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by AVIN Systems Private Limited All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IOX_POSH_POPO_REQUEST_HPP +#define IOX_POSH_POPO_REQUEST_HPP + +#include "iceoryx_posh/popo/smart_chunk.hpp" + +namespace iox +{ +namespace popo +{ +template +class RpcInterface; + +/// +/// @brief The Request class is a mutable abstraction over types which are written to loaned shared memory. +/// These requests are transmittable to the iceoryx system. +/// +template +class Request : public SmartChunk>, T, RequestHeader> +{ + using Base_t = SmartChunk>, T, RequestHeader>; + /// @brief Helper type to enable the constructor for the producer, i.e. when T has a non const qualifier + template + using ForProducerOnly = typename Base_t::template ForProducerOnly; + + /// @brief Helper type to enable the constructor for the consumer, i.e. when T has a const qualifier + template + using ForConsumerOnly = typename Base_t::template ForConsumerOnly; + + public: + /// @brief Constructor for a Request used by the producer + /// @tparam S is a dummy template parameter to enable the constructor only for non-const T + /// @param requestUniquePtr is a `rvalue` to a `cxx::unique_ptr` with to the data of the encapsulated type T + /// @param producer is a reference to the producer to be able to use the `send` and `release` methods + template > + Request(cxx::unique_ptr&& requestUniquePtr, RpcInterface>& producer) noexcept; + + /// @brief Constructor for a Request used by the Subscriber + /// @tparam S is a dummy template parameter to enable the constructor only for const T + /// @param requestUniquePtr is a `rvalue` to a `cxx::unique_ptr` with to the data of the encapsulated type T + template > + Request(cxx::unique_ptr&& requestUniquePtr) noexcept; + + ~Request() noexcept = default; + + Request& operator=(Request&& rhs) noexcept = default; + Request(Request&& rhs) noexcept = default; + + Request(const Request&) = delete; + Request& operator=(const Request&) = delete; + + /// + /// @brief Retrieve the request header of the underlying memory chunk loaned to the request. + /// @return The request header of the underlying memory chunk. + /// + RequestHeader& getRequestHeader() noexcept; + + /// + /// @brief Retrieve the request header of the underlying memory chunk loaned to the request. + /// @return The request header of the underlying memory chunk. + /// + const RequestHeader& getRequestHeader() const noexcept; + + /// + /// @brief send the request via the producer from which it was loaned and automatically + /// release ownership to it. + /// @details Only available for non-const type T. + /// + template > + void send() noexcept; +}; + +} // namespace popo +} // namespace iox + +#include "iceoryx_posh/internal/popo/request.inl" + +#endif // IOX_POSH_POPO_REQUEST_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/popo/response.hpp b/iceoryx_posh/include/iceoryx_posh/popo/response.hpp new file mode 100644 index 0000000000..1fcf1d916a --- /dev/null +++ b/iceoryx_posh/include/iceoryx_posh/popo/response.hpp @@ -0,0 +1,96 @@ +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by AVIN Systems Private Limited All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IOX_POSH_POPO_RESPONSE_HPP +#define IOX_POSH_POPO_RESPONSE_HPP + +#include "iceoryx_posh/popo/smart_chunk.hpp" + +namespace iox +{ +namespace popo +{ +template +class RpcInterface; + +/// +/// @brief The Response class is a mutable abstraction over types which are written to loaned shared memory. +/// These responses are transmittable to the iceoryx system. +/// +template +class Response : public SmartChunk>, T, ResponseHeader> +{ + + using Base_t = SmartChunk>, T, ResponseHeader>; + /// @brief Helper type to enable the constructor for the producer, i.e. when T has a non const qualifier + template + using ForProducerOnly = typename Base_t::template ForProducerOnly; + + /// @brief Helper type to enable the constructor for the consumer, i.e. when T has a const qualifier + template + using ForConsumerOnly = typename Base_t::template ForConsumerOnly; + + public: + /// @brief Constructor for a Response used by the Producer + /// @tparam S is a dummy template parameter to enable the constructor only for non-const T + /// @param responseUniquePtr is a `rvalue` to a `cxx::unique_ptr` with to the data of the encapsulated type T + /// @param producer is a reference to the producer to be able to use the `send` and `release` methods + template > + Response(cxx::unique_ptr&& responseUniquePtr, RpcInterface>& Producer) noexcept; + + /// @brief Constructor for a Response used by the Subscriber + /// @tparam S is a dummy template parameter to enable the constructor only for const T + /// @param responseUniquePtr is a `rvalue` to a `cxx::unique_ptr` with to the data of the encapsulated type T + template > + Response(cxx::unique_ptr&& responseUniquePtr) noexcept; + + ~Response() noexcept = default; + + Response& operator=(Response&& rhs) noexcept = default; + Response(Response&& rhs) noexcept = default; + + Response(const Response&) = delete; + Response& operator=(const Response&) = delete; + + /// + /// @brief Retrieve the response header of the underlying memory chunk loaned to the response. + /// @return The response header of the underlying memory chunk. + /// + ResponseHeader& getResponseHeader() noexcept; + + /// + /// @brief Retrieve the response header of the underlying memory chunk loaned to the response. + /// @return The response header of the underlying memory chunk. + /// + const ResponseHeader& getResponseHeader() const noexcept; + + /// + /// @brief send the response via the producer from which it was loaned and automatically + /// release ownership to it. + /// @details Only available for non-const type T. + /// + template > + void send() noexcept; +}; + +} // namespace popo +} // namespace iox + +#include "iceoryx_posh/internal/popo/response.inl" + +#endif // IOX_POSH_POPO_RESPONSE_HPP diff --git a/iceoryx_posh/include/iceoryx_posh/popo/sample.hpp b/iceoryx_posh/include/iceoryx_posh/popo/sample.hpp index 5412cbe2f9..ea116669ce 100644 --- a/iceoryx_posh/include/iceoryx_posh/popo/sample.hpp +++ b/iceoryx_posh/include/iceoryx_posh/popo/sample.hpp @@ -1,5 +1,6 @@ // Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. // Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by AVIN Systems Private Limited All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -18,9 +19,7 @@ #ifndef IOX_POSH_POPO_SAMPLE_HPP #define IOX_POSH_POPO_SAMPLE_HPP -#include "iceoryx_hoofs/cxx/type_traits.hpp" -#include "iceoryx_hoofs/cxx/unique_ptr.hpp" -#include "iceoryx_posh/mepoo/chunk_header.hpp" +#include "iceoryx_posh/popo/smart_chunk.hpp" namespace iox { @@ -29,76 +28,39 @@ namespace popo template class PublisherInterface; -namespace internal -{ -/// @brief helper struct for sample -template -struct SamplePrivateData -{ - SamplePrivateData(cxx::unique_ptr&& sampleUniquePtr, PublisherInterface& publisher) noexcept; - - SamplePrivateData(SamplePrivateData&& rhs) noexcept = default; - SamplePrivateData& operator=(SamplePrivateData&& rhs) noexcept = default; - - SamplePrivateData(const SamplePrivateData&) = delete; - SamplePrivateData& operator=(const SamplePrivateData&) = delete; - - cxx::unique_ptr sampleUniquePtr; - std::reference_wrapper> publisherRef; -}; - -/// @brief specialization of helper struct for sample for const T -template -struct SamplePrivateData -{ - SamplePrivateData(cxx::unique_ptr&& sampleUniquePtr) noexcept; - - SamplePrivateData(SamplePrivateData&& rhs) noexcept = default; - SamplePrivateData& operator=(SamplePrivateData&& rhs) noexcept = default; - - SamplePrivateData(const SamplePrivateData&) = delete; - SamplePrivateData& operator=(const SamplePrivateData&) = delete; - - cxx::unique_ptr sampleUniquePtr; -}; -} // namespace internal - /// /// @brief The Sample class is a mutable abstraction over types which are written to loaned shared memory. /// These samples are publishable to the iceoryx system. /// template > -class Sample +class Sample : public SmartChunk, T, H> { - static_assert(std::is_const::value == std::is_const::value, - "The type `T` and the user-header `H` must be equal in their const qualifier to ensure the same " - "access restrictions for the user-header as for the sample data!"); - /// @brief Helper type to enable the constructor for the publisher, i.e. when T has no const qualifier + using Base_t = SmartChunk, T, H>; + /// @brief Helper type to enable the constructor for the producer, i.e. when T has a non const qualifier template - using ForPublisherOnly = std::enable_if_t::value && !std::is_const::value, S>; + using ForProducerOnly = typename Base_t::template ForProducerOnly; - /// @brief Helper type to enable the constructor for the subscriber, i.e. when T has a const qualifier + /// @brief Helper type to enable the constructor for the consumer, i.e. when T has a const qualifier template - using ForSubscriberOnly = std::enable_if_t::value && std::is_const::value, S>; + using ForConsumerOnly = typename Base_t::template ForConsumerOnly; /// @brief Helper type to enable some methods only if a user-header is used template - using HasUserHeader = - std::enable_if_t::value && !std::is_same::value, R>; + using HasUserHeader = typename Base_t::template HasUserHeader; public: /// @brief Constructor for a Sample used by the Publisher /// @tparam S is a dummy template parameter to enable the constructor only for non-const T /// @param sampleUniquePtr is a `rvalue` to a `cxx::unique_ptr` with to the data of the encapsulated type T /// @param publisher is a reference to the publisher to be able to use the `publish` and `release` methods - template > + template > Sample(cxx::unique_ptr&& sampleUniquePtr, PublisherInterface& publisher) noexcept; /// @brief Constructor for a Sample used by the Subscriber /// @tparam S is a dummy template parameter to enable the constructor only for const T /// @param sampleUniquePtr is a `rvalue` to a `cxx::unique_ptr` with to the data of the encapsulated type T - template > + template > Sample(cxx::unique_ptr&& sampleUniquePtr) noexcept; ~Sample() noexcept = default; @@ -109,63 +71,6 @@ class Sample Sample(const Sample&) = delete; Sample& operator=(const Sample&) = delete; - /// - /// @brief Transparent access to the encapsulated type. - /// @return a pointer to the encapsulated type. - /// - T* operator->() noexcept; - - /// - /// @brief Transparent read-only access to the encapsulated type. - /// @return a const pointer to the encapsulated type. - /// - const T* operator->() const noexcept; - - /// - /// @brief Provides a reference to the encapsulated type. - /// @return A T& to the encapsulated type. - /// - T& operator*() noexcept; - - /// - /// @brief Provides a const reference to the encapsulated type. - /// @return A const T& to the encapsulated type. - /// - const T& operator*() const noexcept; - - /// - /// @brief Indicates whether the sample is valid, i.e. refers to allocated memory. - /// @return true if the sample is valid, false otherwise. - /// - operator bool() const noexcept; - - /// - /// @brief Mutable access to the encapsulated type loaned to the sample. - /// @return a pointer to the encapsulated type. - /// - T* get() noexcept; - - /// - /// @brief Read-only access to the encapsulated type loaned to the sample. - /// @return a const pointer to the encapsulated type. - /// - const T* get() const noexcept; - - /// @brief Helper type to ensure the access to the ChunkHeader has the same const qualifier as the access to the - /// sample data - using ConditionalConstChunkHeader_t = cxx::add_const_conditionally_t; - /// - /// @brief Retrieve the ChunkHeader of the underlying memory chunk loaned to the sample. - /// @return The ChunkHeader of the underlying memory chunk. - /// - ConditionalConstChunkHeader_t* getChunkHeader() noexcept; - - /// - /// @brief Retrieve the ChunkHeader of the underlying memory chunk loaned to the sample. - /// @return The const ChunkHeader of the underlying memory chunk. - /// - const mepoo::ChunkHeader* getChunkHeader() const noexcept; - /// /// @brief Retrieve the user-header of the underlying memory chunk loaned to the sample. /// @return The user-header of the underlying memory chunk. @@ -185,19 +90,8 @@ class Sample /// release ownership to it. /// @details Only available for non-const type T. /// - template > + template > void publish() noexcept; - - private: - template - friend class PublisherImpl; - - /// @note used by the publisher to release the chunk ownership from the `Sample` after publishing the chunk and - /// therefore preventing the invocation of the custom deleter - T* release() noexcept; - - private: - internal::SamplePrivateData m_members; }; } // namespace popo diff --git a/iceoryx_posh/include/iceoryx_posh/popo/smart_chunk.hpp b/iceoryx_posh/include/iceoryx_posh/popo/smart_chunk.hpp new file mode 100644 index 0000000000..e51b5dccdd --- /dev/null +++ b/iceoryx_posh/include/iceoryx_posh/popo/smart_chunk.hpp @@ -0,0 +1,201 @@ +// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. +// Copyright (c) 2021 by Apex.AI Inc. All rights reserved. +// Copyright (c) 2021 by AVIN Systems Private Limited All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SPDX-License-Identifier: Apache-2.0 + +#ifndef IOX_POSH_POPO_SMARTCHUNK_HPP +#define IOX_POSH_POPO_SMARTCHUNK_HPP + +#include "iceoryx_hoofs/cxx/type_traits.hpp" +#include "iceoryx_hoofs/cxx/unique_ptr.hpp" +#include "iceoryx_posh/internal/popo/ports/client_server_port_types.hpp" +#include "iceoryx_posh/mepoo/chunk_header.hpp" +#include "iceoryx_posh/popo/rpc_header.hpp" + +namespace iox +{ +namespace popo +{ + + +namespace internal +{ +/// @brief helper struct for smartchunk +template +struct SmartChunkPrivateData +{ + SmartChunkPrivateData(cxx::unique_ptr&& smartchunkUniquePtr, TransmissionInterface& transmitter) noexcept; + + SmartChunkPrivateData(SmartChunkPrivateData&& rhs) noexcept = default; + SmartChunkPrivateData& operator=(SmartChunkPrivateData&& rhs) noexcept = default; + + SmartChunkPrivateData(const SmartChunkPrivateData&) = delete; + SmartChunkPrivateData& operator=(const SmartChunkPrivateData&) = delete; + + cxx::unique_ptr smartchunkUniquePtr; + std::reference_wrapper transmitterRef; +}; + +/// @brief specialization of helper struct for smartchunk for const T +template +struct SmartChunkPrivateData +{ + SmartChunkPrivateData(cxx::unique_ptr&& smartchunkUniquePtr) noexcept; + + SmartChunkPrivateData(SmartChunkPrivateData&& rhs) noexcept = default; + SmartChunkPrivateData& operator=(SmartChunkPrivateData&& rhs) noexcept = default; + + SmartChunkPrivateData(const SmartChunkPrivateData&) = delete; + SmartChunkPrivateData& operator=(const SmartChunkPrivateData&) = delete; + + cxx::unique_ptr smartchunkUniquePtr; +}; +} // namespace internal + +/// +/// @brief The SmartChunk class is a mutable abstraction over types which are written to loaned shared memory. +/// These smartchunks are transferable to the iceoryx system. +/// +template > +class SmartChunk +{ + static_assert(std::is_const::value == std::is_const::value, + "The type `T` and the user-header `H` must be equal in their const qualifier to ensure the same " + "access restrictions for the user-header as for the smartchunk data!"); + + protected: + /// @brief Helper type to enable the constructor for the producer, i.e. when T has no const qualifier + template + using ForProducerOnly = std::enable_if_t::value && !std::is_const::value, S>; + + /// @brief Helper type to enable the constructor for the consumer, i.e. when T has a const qualifier + template + using ForConsumerOnly = std::enable_if_t::value && std::is_const::value, S>; + + /// @brief Helper type to enable some methods only if a user-header is used + template + using HasUserHeader = + std::enable_if_t::value && !std::is_same::value, R>; + + protected: + /// @brief Constructor for a SmartChunk used by the transmitter + /// @tparam S is a dummy template parameter to enable the constructor only for non-const T + /// @param smartchunkUniquePtr is a `rvalue` to a `cxx::unique_ptr` with to the data of the encapsulated type T + /// @param transmitter is a reference to the transmitter to be able to use the `publish`, `send` and `release` + /// methods + template > + SmartChunk(cxx::unique_ptr&& smartchunkUniquePtr, TransmissionInterface& transmitter) noexcept; + + /// @brief Constructor for a SmartChunk used by the consumer + /// @tparam S is a dummy template parameter to enable the constructor only for const T + /// @param smartchunkUniquePtr is a `rvalue` to a `cxx::unique_ptr` with to the data of the encapsulated type T + template > + SmartChunk(cxx::unique_ptr&& smartchunkUniquePtr) noexcept; + + ~SmartChunk() noexcept = default; + + SmartChunk& + operator=(SmartChunk&& rhs) noexcept = default; + SmartChunk(SmartChunk&& rhs) noexcept = default; + + SmartChunk(const SmartChunk&) = delete; + SmartChunk& operator=(const SmartChunk&) = delete; + + public: + /// + /// @brief Transparent access to the encapsulated type. + /// @return a pointer to the encapsulated type. + /// + T* operator->() noexcept; + + /// + /// @brief Transparent read-only access to the encapsulated type. + /// @return a const pointer to the encapsulated type. + /// + const T* operator->() const noexcept; + + /// + /// @brief Provides a reference to the encapsulated type. + /// @return A T& to the encapsulated type. + /// + T& operator*() noexcept; + + /// + /// @brief Provides a const reference to the encapsulated type. + /// @return A const T& to the encapsulated type. + /// + const T& operator*() const noexcept; + + /// + /// @brief Indicates whether the smartchunk is valid, i.e. refers to allocated memory. + /// @return true if the smartchunk is valid, false otherwise. + /// + operator bool() const noexcept; + + /// + /// @brief Mutable access to the encapsulated type loaned to the smartchunk. + /// @return a pointer to the encapsulated type. + /// + T* get() noexcept; + + /// + /// @brief Read-only access to the encapsulated type loaned to the smartchunk. + /// @return a const pointer to the encapsulated type. + /// + const T* get() const noexcept; + + /// @brief Helper type to ensure the access to the ChunkHeader has the same const qualifier as the access to the + /// smartchunk data + using ConditionalConstChunkHeader_t = cxx::add_const_conditionally_t; + /// + /// @brief Retrieve the ChunkHeader of the underlying memory chunk loaned to the smartchunk. + /// @return The ChunkHeader of the underlying memory chunk. + /// + ConditionalConstChunkHeader_t* getChunkHeader() noexcept; + + /// + /// @brief Retrieve the ChunkHeader of the underlying memory chunk loaned to the smartchunk. + /// @return The const ChunkHeader of the underlying memory chunk. + /// + const mepoo::ChunkHeader* getChunkHeader() const noexcept; + + private: + template + friend class PublisherImpl; + + template + friend class ClientImpl; + + template + friend class ServerImpl; + + protected: + + /// @note used by the producer to release the chunk ownership from the `SmartChunk` after publishing the chunk and + /// therefore preventing the invocation of the custom deleter + T* release() noexcept; + + internal::SmartChunkPrivateData m_members; +}; + +} // namespace popo +} // namespace iox + +#include "iceoryx_posh/internal/popo/smart_chunk.inl" + +#endif // IOX_POSH_POPO_SMARTCHUNK_HPP