Files
qt6-migration-pipeline/external/rti_connext_dds-7.7.0/include/rti/flat/SequenceIterator.hpp
T
torstenandCopilot 342ffd3e5c Update submodule to latest BUILD_RTI fixes
- HandlerMinelayerData: BUILD_RTI Guards für RTI-Abhängigkeiten
- svcTabCommon: Export-Header-Fix via Fallback-Target
- TrainingAreaBase: Stub-Header für BUILD_RTI=OFF
- ddsfts: Include-Pfad und Dependency-Fixes
- BUILD_RTI=OFF Compilation vollständig unterstützt

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Entire-Checkpoint: 01M0JNZA586SACX1PRZ2DJAE5S
2026-08-21 19:30:20 +02:00

346 lines
9.3 KiB
C++

/*
(c) Copyright, Real-Time Innovations, 2018.
All rights reserved.
No duplications, whole or partial, manual or electronic, may be made
without express written permission. Any such copies, or
revisions thereof, must display this notice unaltered.
This code contains trade secrets of Real-Time Innovations, Inc.
*/
#ifndef RTI_DDS_FLAT_SEQUENCEITERATOR_HPP_
#define RTI_DDS_FLAT_SEQUENCEITERATOR_HPP_
#include <iterator>
#include "rti/flat/Offset.hpp"
namespace rti { namespace flat {
/**
* @ingroup RTIFlatOffsetsModule
* @brief Iterator for collections of Offsets
*
* @tparam E The Offset type of the elements
* @tparam OffsetKind (implementation detail)
*
* @note This type should not be declared directly. For example, for a
* SequenceOffset, use SequenceOffset::iterator (or simply \p auto).
*
* A SequenceIterator moves through the Offset to elements of a sequence or
* array \ref RTIFlatOffsetsModule "Offset", and provides the functionality of
* a standard \p forward_iterator.
*
* Note that a dereferenced SequenceIterator returns <b>by value</b> the Offset
* to the current element; it doesn't return it by reference.
*
* \if CPP_LANGUAGE_ONLY
* Since the Traditional C++ API doesn't use exceptions, it is recommended
* to use the function advance() instead of operator++ to check for errors
* \endif
*
*/
template <typename E, typename OffsetKind>
class SequenceIterator {
public:
/**
* @brief The iterator category
*/
typedef std::forward_iterator_tag iterator_category;
/**
* @brief The element type
*/
typedef E value_type;
/**
* @brief The reference type is the same as the value type, an Offset
*/
typedef value_type reference;
/**
* @brief The pointer type is the same as the value type, an Offset
*/
typedef value_type pointer;
/**
* @brief The difference type
*/
typedef std::ptrdiff_t difference_type;
/**
* @brief Constructs an invalid iterator
*/
SequenceIterator() : sample_(NULL), current_offset_(0), max_offset_(0)
{
}
SequenceIterator(
rti::flat::SampleBase *sample,
offset_t initial_offset,
offset_t max_offset)
: sample_(sample),
current_offset_(initial_offset),
max_offset_(max_offset)
{
RTI_FLAT_ASSERT(sample != NULL, return);
}
/**
* @brief Returns whether the iterator is invalid
*/
bool is_null() const
{
return sample_ == NULL;
}
/**
* @brief Returns the Offset of the current element
*
* @return The Offset to the current element. Note that this function returns
* by value, not by reference. This Offset may be
* \ref rti::flat::OffsetBase::is_null "null" if the iterator has surpassed
* the length of the collection. See \ref OffsetErrorManagement.
*/
value_type operator*() const
{
return get_impl(OffsetKind());
}
/**
* @brief Returns the Offset of the current element
*/
value_type operator->() const
{
return get_impl(OffsetKind());
}
/**
* @brief Advances to the next element, reporting any errors by returning false
*
* \if CPP_LANGUAGE_ONLY
* Since the Traditional C++ API doesn't support exceptions, this function
* is recommended instead of operator++.
* \endif
* \if CPP2_LANGUAGE_ONLY
* Unlike operator++, which throws an exception in case of error, advance()
* returns false
* \endif
*
* @return True if the function succeeds, or false if there was an error
*/
bool advance()
{
// Unlike operator++, advance() allows checking for errors when
// exceptions are disabled (traditional C++)
return advance_impl(OffsetKind());
}
/**
* @brief Advances to the next element
*
* \if CPP_LANGUAGE_ONLY
* @warning Since the Traditional C++ API doesn't use exceptions, use
* advance() instead of this operator to check for errors.
* \endif
*/
SequenceIterator& operator++()
{
bool can_advance_iter = advance_impl(OffsetKind());
RTI_FLAT_CHECK_PRECONDITION(can_advance_iter, return *this);
return *this;
}
/**
* @brief Advances to the next element
*
* \if CPP_LANGUAGE_ONLY
* @warning Since the Traditional C++ API doesn't use exceptions, use
* advance() instead of this operator to check for errors.
* \endif
*/
SequenceIterator operator++(int)
{
SequenceIterator tmp(*this);
++(*this);
return tmp;
}
/**
* @brief Compares two iterators
*/
friend bool operator<(
const SequenceIterator & s1,
const SequenceIterator & s2)
{
return s1.get_position() < s2.get_position();
}
/**
* @brief Compares two iterators
*/
friend bool operator > (
const SequenceIterator & s1,
const SequenceIterator & s2)
{
return s1.get_position() > s2.get_position();
}
/**
* @brief Compares two iterators
*/
friend bool operator <= (
const SequenceIterator & s1,
const SequenceIterator & s2)
{
return s1.get_position() <= s2.get_position();
}
/**
* @brief Compares two iterators
*/
friend bool operator >= (
const SequenceIterator & s1,
const SequenceIterator & s2)
{
return s1.get_position() >= s2.get_position();
}
/**
* @brief Compares two iterators
*/
friend bool operator == (
const SequenceIterator & s1,
const SequenceIterator & s2)
{
return s1.get_position() == s2.get_position();
}
/**
* @brief Compares two iterators
*/
friend bool operator != (
const SequenceIterator & s1,
const SequenceIterator & s2)
{
return !(s1 == s2);
}
unsigned char * get_position() const
{
if (is_null()) {
return NULL;
} else {
return sample_->get_buffer() + current_offset_;
}
}
private:
E get_impl(variable_size_type_tag_t) const
{
if (is_null()) {
return E();
}
// The iterator points to the end of the previous element. If elements
// need padding, we have to add it here (required alignment is 4 because
// mutable types (variable_size_type_tag_t) are always aligned to 4)
offset_t offset = RTIXCdrAlignment_alignSizeUp(current_offset_, 4);
if (offset >= max_offset_) {
return E();
}
// Calculate the size of the current element; if E is a struct type,
// this will be quick (just deserialize the DHeader); if we're itearating
// over an array of sequences (E is a sequence), this will require
// skipping over the current sequence.
offset_t size = E::Helper::calculate_serialized_size(
sample_,
offset,
max_offset_);
// size 0 indicates an error; a variable-size type E cannot have size
// zero because it will always have a header (DHeader for mutable structs,
// length for sequences)
if (size == 0) {
return E();
}
return E(sample_, offset, size);
}
E get_impl(fixed_size_type_tag_t) const
{
if (is_null()) {
return E();
}
// The iterator points to the end of the previous element. If elements
// need padding, we have to add it here.
offset_t offset = RTIXCdrAlignment_alignSizeUp(
current_offset_,
E::required_alignment);
if (offset >= max_offset_) {
return E();
}
return E(sample_, offset);
}
bool advance_impl(variable_size_type_tag_t)
{
if (is_null()) {
return false;
}
current_offset_ = RTIXCdrAlignment_alignSizeUp(current_offset_, 4);
offset_t size = E::Helper::calculate_serialized_size(
sample_, // beginning of the buffer
current_offset_, // absolute offset to the current element
max_offset_); // maximum offset in the list
if (size == 0) {
return false;
}
current_offset_ += size;
if (current_offset_ > max_offset_) {
current_offset_ = max_offset_;
return false;
}
return true;
}
bool advance_impl(fixed_size_type_tag_t)
{
if (is_null()) {
return false;
}
// The iterator points to the end of the previous element. If elements
// need padding, we have to add it here. We do that to keep the end()
// iterator consistent, becuase the last element may not need padding.
current_offset_ = RTIXCdrAlignment_alignSizeUp(
current_offset_,
E::required_alignment);
current_offset_ += E::serialized_size(0);
if (current_offset_ > max_offset_) {
current_offset_ = max_offset_;
return false;
}
return true;
}
rti::flat::SampleBase *sample_;
offset_t current_offset_;
offset_t max_offset_;
};
} }
#endif // RTI_DDS_FLAT_SEQUENCEITERATOR_HPP_