diff --git a/examples/C++/DDS/ZeroCopyExample/LoanableHelloWorldSubscriber.cxx b/examples/C++/DDS/ZeroCopyExample/LoanableHelloWorldSubscriber.cxx index 7035bccde31..e4c1bdee17e 100644 --- a/examples/C++/DDS/ZeroCopyExample/LoanableHelloWorldSubscriber.cxx +++ b/examples/C++/DDS/ZeroCopyExample/LoanableHelloWorldSubscriber.cxx @@ -19,6 +19,7 @@ * This file was generated by the tool fastcdrgen. */ +#include #include #include #include @@ -138,7 +139,7 @@ void LoanableHelloWorldSubscriber::SubListener::on_data_available( { // Print your structure data here. const LoanableHelloWorld& sample = data[i]; - + ++samples; std::cout << "Sample received (count=" << samples << ") at address " << &sample << std::endl << " index=" << sample.index() << std::endl diff --git a/include/fastdds/dds/core/LoanableConstSequence.hpp b/include/fastdds/dds/core/LoanableConstSequence.hpp new file mode 100644 index 00000000000..dcbd4b16046 --- /dev/null +++ b/include/fastdds/dds/core/LoanableConstSequence.hpp @@ -0,0 +1,133 @@ +// Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// 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. + +/** + * @file LoanableConstSequence.hpp + */ + +#ifndef _FASTDDS_DDS_CORE_LOANABLECONSTSEQUENCE_HPP_ +#define _FASTDDS_DDS_CORE_LOANABLECONSTSEQUENCE_HPP_ + +#include +#include +#include + +#include +#include + +namespace eprosima { +namespace fastdds { +namespace dds { + +/** + * A type-safe, ordered collection of elements that can receive the buffer from outside (loan). + * + * For users who define data types in OMG IDL, this type corresponds to the IDL express sequence. + * + * For any user-data type Foo that an application defines for the purpose of data-distribution with + * Fast DDS, a 'using FooConstSeq = LoanableConstSequence' is generated. The sequence offers a subset of the + * methods defined by the standard OMG IDL to C++ mapping for sequences. + * We refer to an IDL 'sequence' as \c FooSeq. + * + * The state of a sequence is described by the properties 'maximum', 'length' and 'has_ownership'. + * @li The 'maximum' represents the size of the underlying buffer; this is the maximum number of elements + * it can possibly hold. It is returned by the maximum() operation. + * @li The 'length' represents the actual number of elements it currently holds. It is returned by the + * length() operation. + * @li The 'has_ownership' flag represents whether the sequence owns the underlying buffer. It is returned + * by the has_ownership() operation. If the sequence does not own the underlying buffer, the underlying + * buffer is loaned from somewhere else. This flag influences the lifecycle of the sequence and what + * operations are allowed on it. The general guidelines are provided below and more details are described + * in detail as pre-conditions and post-conditions of each of the sequence's operations: + * + * @li If has_ownership == true, the sequence has ownership on the buffer. It is then responsible for + * destroying the buffer when the sequence is destroyed. + * @li If has_ownership == false, the sequence does not have ownership on the buffer. This implies that + * the sequence is loaning the buffer. The sequence should not be destroyed until the loan is returned. + * @li A sequence with a zero maximum always has has_ownership == true + */ +template +class LoanableConstSequence : public LoanableTypedConstCollection +{ +public: + + using size_type = LoanableCollection::size_type; + using element_type = LoanableCollection::element_type; + + /** + * Default constructor. + * + * Creates the sequence with no data. + * + * @post buffer() == nullptr + * @post has_ownership() == true + * @post length() == 0 + * @post maximum() == 0 + */ + LoanableConstSequence() = default; + + /** + * Deallocate this sequence's buffer. + * + * @pre has_ownership() == true. If this precondition is not met, no memory will be released and + * a warning will be logged. + * @post maximum() == 0 and the underlying buffer is released. + */ + ~LoanableConstSequence() + { + if (elements_ && !has_ownership_) + { + logWarning(SUBSCRIBER, "Sequence destroyed with active loan"); + return; + } + } + + // Non-copyable + LoanableConstSequence( + const LoanableConstSequence& other) = delete; + LoanableConstSequence& operator =( + const LoanableConstSequence& other) = delete; + + // Non-moveable + LoanableConstSequence( + LoanableConstSequence&& other) = delete; + LoanableConstSequence& operator =( + LoanableConstSequence&& other) = delete; + +protected: + + using LoanableCollection::maximum_; + using LoanableCollection::length_; + using LoanableCollection::elements_; + using LoanableCollection::has_ownership_; + +private: + + void resize( + size_type maximum) override + { + static_cast(maximum); + throw std::bad_alloc(); + } + +}; + +} // namespace dds +} // namespace fastdds +} // namespace eprosima + +// Macro to easily declare a LoanableConstSequence for a data type +#define FASTDDS_CONST_SEQUENCE(FooSeq, Foo) using FooSeq = eprosima::fastdds::dds::LoanableConstSequence + +#endif // _FASTDDS_DDS_CORE_LOANABLESEQUENCE_HPP_ diff --git a/include/fastdds/dds/core/LoanableSequence.hpp b/include/fastdds/dds/core/LoanableSequence.hpp index 1cdab9b845f..7cf8f480253 100644 --- a/include/fastdds/dds/core/LoanableSequence.hpp +++ b/include/fastdds/dds/core/LoanableSequence.hpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -58,8 +57,8 @@ namespace dds { * the sequence is loaning the buffer. The sequence should not be destroyed until the loan is returned. * @li A sequence with a zero maximum always has has_ownership == true */ -template -class LoanableSequence : public LoanableTypedCollection +template +class LoanableSequence : public LoanableTypedCollection { public: @@ -227,7 +226,5 @@ class LoanableSequence : public LoanableTypedCollection // Macro to easily declare a LoanableSequence for a data type #define FASTDDS_SEQUENCE(FooSeq, Foo) using FooSeq = eprosima::fastdds::dds::LoanableSequence -#define FASTDDS_CONST_SEQUENCE(FooSeq, Foo) using FooSeq = eprosima::fastdds::dds::LoanableSequence #endif // _FASTDDS_DDS_CORE_LOANABLESEQUENCE_HPP_ diff --git a/include/fastdds/dds/core/LoanableTypedCollection.hpp b/include/fastdds/dds/core/LoanableTypedCollection.hpp index a35159f6673..842b5230900 100644 --- a/include/fastdds/dds/core/LoanableTypedCollection.hpp +++ b/include/fastdds/dds/core/LoanableTypedCollection.hpp @@ -22,7 +22,6 @@ #include #include #include -#include #include @@ -35,7 +34,7 @@ namespace dds { * * This is an abstract class. See @ref LoanableSequence for details. */ -template +template class LoanableTypedCollection : public LoanableCollection { public: @@ -55,8 +54,7 @@ class LoanableTypedCollection : public LoanableCollection * * @return a reference to the element at position @c n */ - template - typename std::enable_if::type& operator []( + T& operator []( size_type n) { if (n >= length_) diff --git a/include/fastdds/dds/core/LoanableTypedConstCollection.hpp b/include/fastdds/dds/core/LoanableTypedConstCollection.hpp new file mode 100644 index 00000000000..0b4d061cd8c --- /dev/null +++ b/include/fastdds/dds/core/LoanableTypedConstCollection.hpp @@ -0,0 +1,73 @@ +// Copyright 2022 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// 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. + +/** + * @file LoanableTypedConstCollection.hpp + */ + +#ifndef _FASTDDS_DDS_CORE_LOANABLETYPEDCONSTCOLLECTION_HPP_ +#define _FASTDDS_DDS_CORE_LOANABLETYPEDCONSTCOLLECTION_HPP_ + +#include +#include +#include + +#include + +namespace eprosima { +namespace fastdds { +namespace dds { + +/** + * A type-safe accessible collection of generic opaque pointers that can receive the buffer from outside (loan). + * + * This is an abstract class. See @ref LoanableConstSequence for details. + */ +template +class LoanableTypedConstCollection : public LoanableCollection +{ +public: + + /** + * Get an element of the sequence. + * + * This is the operator that is invoked when the application indexes into a @em const sequence: + * @code{.cpp} + * element = sequence[n]; + * @endcode + * + * Note that a @em reference to the element is returned (and not a copy) + * + * @param [in] n index of element to access, must be >= 0 and less than length(). + * + * @return a const reference to the element at position @n + */ + const T& operator []( + size_type n) const + { + if (n >= length_) + { + throw std::out_of_range(""); + } + + return *static_cast(elements_[n]); + } + +}; + +} // namespace dds +} // namespace fastdds +} // namespace eprosima + +#endif // _FASTDDS_DDS_CORE_LOANABLETYPEDCONSTCOLLECTION_HPP_