Program Listing for File QosPolicies.hpp

Return to documentation for file (/tmp/ws/src/fastrtps/include/fastdds/dds/core/policy/QosPolicies.hpp)

// Copyright 2016 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.

#ifndef _FASTDDS_DDS_QOS_QOSPOLICIES_HPP_
#define _FASTDDS_DDS_QOS_QOSPOLICIES_HPP_

#include <vector>

#include <fastdds/dds/core/policy/ParameterTypes.hpp>

#include <fastdds/rtps/attributes/ExternalLocators.hpp>
#include <fastdds/rtps/attributes/PropertyPolicy.h>
#include <fastdds/rtps/attributes/RTPSParticipantAllocationAttributes.hpp>
#include <fastdds/rtps/attributes/RTPSParticipantAttributes.h>
#include <fastdds/rtps/common/LocatorList.hpp>
#include <fastdds/rtps/common/Types.h>
#include <fastdds/rtps/common/Time_t.h>
#include <fastdds/rtps/resources/ResourceManagement.h>
#include <fastdds/rtps/flowcontrol/FlowControllerConsts.hpp>

#include <fastrtps/types/TypeObject.h>
#include <fastrtps/utils/collections/ResourceLimitedVector.hpp>

namespace eprosima {
namespace fastdds {
namespace dds {

enum QosPolicyId_t : uint32_t
{
    INVALID_QOS_POLICY_ID                   = 0,    //< Does not refer to any valid QosPolicy

    // Standard QosPolicies
    USERDATA_QOS_POLICY_ID                  = 1,    //< UserDataQosPolicy
    DURABILITY_QOS_POLICY_ID                = 2,    //< DurabilityQosPolicy
    PRESENTATION_QOS_POLICY_ID              = 3,    //< PresentationQosPolicy
    DEADLINE_QOS_POLICY_ID                  = 4,    //< DeadlineQosPolicy
    LATENCYBUDGET_QOS_POLICY_ID             = 5,    //< LatencyBudgetQosPolicy
    OWNERSHIP_QOS_POLICY_ID                 = 6,    //< OwnershipQosPolicy
    OWNERSHIPSTRENGTH_QOS_POLICY_ID         = 7,    //< OwnershipStrengthQosPolicy
    LIVELINESS_QOS_POLICY_ID                = 8,    //< LivelinessQosPolicy
    TIMEBASEDFILTER_QOS_POLICY_ID           = 9,    //< TimeBasedFilterQosPolicy
    PARTITION_QOS_POLICY_ID                 = 10,   //< PartitionQosPolicy
    RELIABILITY_QOS_POLICY_ID               = 11,   //< ReliabilityQosPolicy
    DESTINATIONORDER_QOS_POLICY_ID          = 12,   //< DestinationOrderQosPolicy
    HISTORY_QOS_POLICY_ID                   = 13,   //< HistoryQosPolicy
    RESOURCELIMITS_QOS_POLICY_ID            = 14,   //< ResourceLimitsQosPolicy
    ENTITYFACTORY_QOS_POLICY_ID             = 15,   //< EntityFactoryQosPolicy
    WRITERDATALIFECYCLE_QOS_POLICY_ID       = 16,   //< WriterDataLifecycleQosPolicy
    READERDATALIFECYCLE_QOS_POLICY_ID       = 17,   //< ReaderDataLifecycleQosPolicy
    TOPICDATA_QOS_POLICY_ID                 = 18,   //< TopicDataQosPolicy
    GROUPDATA_QOS_POLICY_ID                 = 19,   //< GroupDataQosPolicy
    TRANSPORTPRIORITY_QOS_POLICY_ID         = 20,   //< TransportPriorityQosPolicy
    LIFESPAN_QOS_POLICY_ID                  = 21,   //< LifespanQosPolicy
    DURABILITYSERVICE_QOS_POLICY_ID         = 22,   //< DurabilityServiceQosPolicy

    //XTypes extensions
    DATAREPRESENTATION_QOS_POLICY_ID            = 23,   //< DataRepresentationQosPolicy
    TYPECONSISTENCYENFORCEMENT_QOS_POLICY_ID    = 24,   //< TypeConsistencyEnforcementQosPolicy

    //eProsima Extensions
    DISABLEPOSITIVEACKS_QOS_POLICY_ID       = 25,   //< DisablePositiveACKsQosPolicy
    PARTICIPANTRESOURCELIMITS_QOS_POLICY_ID = 26,   //< ParticipantResourceLimitsQos
    PROPERTYPOLICY_QOS_POLICY_ID            = 27,   //< PropertyPolicyQos
    PUBLISHMODE_QOS_POLICY_ID               = 28,   //< PublishModeQosPolicy
    READERRESOURCELIMITS_QOS_POLICY_ID      = 29,   //< Reader ResourceLimitsQos
    RTPSENDPOINT_QOS_POLICY_ID              = 30,   //< RTPSEndpointQos
    RTPSRELIABLEREADER_QOS_POLICY_ID        = 31,   //< RTPSReliableReaderQos
    RTPSRELIABLEWRITER_QOS_POLICY_ID        = 32,   //< RTPSReliableWriterQos
    TRANSPORTCONFIG_QOS_POLICY_ID           = 33,   //< TransportConfigQos
    TYPECONSISTENCY_QOS_POLICY_ID           = 34,   //< TipeConsistencyQos
    WIREPROTOCOLCONFIG_QOS_POLICY_ID        = 35,   //< WireProtocolConfigQos
    WRITERRESOURCELIMITS_QOS_POLICY_ID      = 36,   //< WriterResourceLimitsQos

    NEXT_QOS_POLICY_ID                              //< Keep always the last element. For internal use only
};

using PolicyMask = std::bitset<NEXT_QOS_POLICY_ID>;

class QosPolicy
{
public:

    bool hasChanged;

    QosPolicy()
        : hasChanged(false)
        , send_always_(false)
    {
    }

    explicit QosPolicy(
            bool send_always)
        : hasChanged(false)
        , send_always_(send_always)
    {
    }

    QosPolicy(
            const QosPolicy& b) = default;

    virtual ~QosPolicy() = default;

    bool operator ==(
            const QosPolicy& b) const
    {
        // hasChanged field isn't needed to be compared to being equal two QosPolicy objects.
        return (this->send_always_ == b.send_always_);
    }

    QosPolicy& operator =(
            const QosPolicy& b) = default;

    virtual bool send_always() const
    {
        return send_always_;
    }

    virtual inline void clear() = 0;

protected:

    bool send_always_;
};

class EntityFactoryQosPolicy
{
public:

    bool autoenable_created_entities;

    RTPS_DllAPI EntityFactoryQosPolicy()
        : autoenable_created_entities(true)
    {
    }

    RTPS_DllAPI EntityFactoryQosPolicy(
            bool autoenable)
        : autoenable_created_entities(autoenable)
    {
    }

    virtual RTPS_DllAPI ~EntityFactoryQosPolicy()
    {
    }

    bool operator ==(
            const EntityFactoryQosPolicy& b) const
    {
        return
            (this->autoenable_created_entities == b.autoenable_created_entities);
    }

    inline void clear()
    {
        EntityFactoryQosPolicy reset = EntityFactoryQosPolicy();
        std::swap(*this, reset);
    }

};

typedef enum DurabilityQosPolicyKind : fastrtps::rtps::octet
{
    VOLATILE_DURABILITY_QOS,
    TRANSIENT_LOCAL_DURABILITY_QOS,
    TRANSIENT_DURABILITY_QOS,
    PERSISTENT_DURABILITY_QOS
} DurabilityQosPolicyKind_t;

#define PARAMETER_KIND_LENGTH 4
#define PARAMETER_BOOL_LENGTH 4

class DurabilityQosPolicy : public Parameter_t, public QosPolicy
{
public:

    RTPS_DllAPI DurabilityQosPolicy()
        : Parameter_t(PID_DURABILITY, PARAMETER_KIND_LENGTH)
        , QosPolicy(true)
        , kind(VOLATILE_DURABILITY_QOS)
    {
    }

    virtual RTPS_DllAPI ~DurabilityQosPolicy() = default;

    inline fastrtps::rtps::DurabilityKind_t durabilityKind() const
    {
        switch (kind)
        {
            default:
            case VOLATILE_DURABILITY_QOS: return fastrtps::rtps::VOLATILE;
            case TRANSIENT_LOCAL_DURABILITY_QOS: return fastrtps::rtps::TRANSIENT_LOCAL;
            case TRANSIENT_DURABILITY_QOS: return fastrtps::rtps::TRANSIENT;
            case PERSISTENT_DURABILITY_QOS: return fastrtps::rtps::PERSISTENT;
        }
    }

    bool operator ==(
            const DurabilityQosPolicy& b) const
    {
        return (this->kind == b.kind) &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void durabilityKind(
            const fastrtps::rtps::DurabilityKind_t new_kind)
    {
        switch (new_kind)
        {
            default:
            case fastrtps::rtps::VOLATILE: kind = VOLATILE_DURABILITY_QOS; break;
            case fastrtps::rtps::TRANSIENT_LOCAL: kind = TRANSIENT_LOCAL_DURABILITY_QOS; break;
            case fastrtps::rtps::TRANSIENT: kind = TRANSIENT_DURABILITY_QOS; break;
            case fastrtps::rtps::PERSISTENT: kind = PERSISTENT_DURABILITY_QOS; break;
        }

    }

    inline void clear() override
    {
        DurabilityQosPolicy reset = DurabilityQosPolicy();
        std::swap(*this, reset);
    }

public:

    DurabilityQosPolicyKind_t kind;
};

class DeadlineQosPolicy : public Parameter_t, public QosPolicy
{
public:

    RTPS_DllAPI DeadlineQosPolicy()
        : Parameter_t(PID_DEADLINE, PARAMETER_TIME_LENGTH)
        , QosPolicy(true)
        , period(TIME_T_INFINITE_SECONDS, TIME_T_INFINITE_NANOSECONDS)
    {
    }

    virtual RTPS_DllAPI ~DeadlineQosPolicy() = default;

    bool operator ==(
            const DeadlineQosPolicy& b) const
    {
        return (this->period == b.period) &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        DeadlineQosPolicy reset = DeadlineQosPolicy();
        std::swap(*this, reset);
    }

public:

    fastrtps::Duration_t period;
};

class LatencyBudgetQosPolicy : public Parameter_t, public QosPolicy
{
public:

    RTPS_DllAPI LatencyBudgetQosPolicy()
        : Parameter_t(PID_LATENCY_BUDGET, PARAMETER_TIME_LENGTH)
        , QosPolicy(true)
        , duration(0, 0)
    {
    }

    virtual RTPS_DllAPI ~LatencyBudgetQosPolicy() = default;

    bool operator ==(
            const LatencyBudgetQosPolicy& b) const
    {
        return (this->duration == b.duration) &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        LatencyBudgetQosPolicy reset = LatencyBudgetQosPolicy();
        std::swap(*this, reset);
    }

public:

    fastrtps::Duration_t duration;
};

typedef enum LivelinessQosPolicyKind : fastrtps::rtps::octet
{
    AUTOMATIC_LIVELINESS_QOS,
    MANUAL_BY_PARTICIPANT_LIVELINESS_QOS,
    MANUAL_BY_TOPIC_LIVELINESS_QOS

} LivelinessQosPolicyKind;

class LivelinessQosPolicy : public Parameter_t, public QosPolicy
{
public:

    RTPS_DllAPI LivelinessQosPolicy()
        : Parameter_t(PID_LIVELINESS, PARAMETER_KIND_LENGTH + PARAMETER_TIME_LENGTH)
        , QosPolicy(true)
        , kind(AUTOMATIC_LIVELINESS_QOS)
        , lease_duration(TIME_T_INFINITE_SECONDS, TIME_T_INFINITE_NANOSECONDS)
        , announcement_period(TIME_T_INFINITE_SECONDS, TIME_T_INFINITE_NANOSECONDS)
    {
    }

    virtual RTPS_DllAPI ~LivelinessQosPolicy() = default;

    bool operator ==(
            const LivelinessQosPolicy& b) const
    {
        return (this->kind == b.kind) &&
               (this->lease_duration == b.lease_duration) &&
               (this->announcement_period == b.announcement_period) &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        LivelinessQosPolicy reset = LivelinessQosPolicy();
        std::swap(*this, reset);
    }

public:

    LivelinessQosPolicyKind kind;
    fastrtps::Duration_t lease_duration;
    fastrtps::Duration_t announcement_period;
};

typedef enum ReliabilityQosPolicyKind : fastrtps::rtps::octet
{
    BEST_EFFORT_RELIABILITY_QOS = 0x01,
    RELIABLE_RELIABILITY_QOS = 0x02
} ReliabilityQosPolicyKind;

class ReliabilityQosPolicy : public Parameter_t, public QosPolicy
{
public:

    RTPS_DllAPI ReliabilityQosPolicy()
        : Parameter_t(PID_RELIABILITY, PARAMETER_KIND_LENGTH + PARAMETER_TIME_LENGTH)
        , QosPolicy(true) //indicate send always
        , kind(BEST_EFFORT_RELIABILITY_QOS)
        , max_blocking_time{0, 100000000} // max_blocking_time = 100ms
    {
    }

    virtual RTPS_DllAPI ~ReliabilityQosPolicy() = default;

    bool operator ==(
            const ReliabilityQosPolicy& b) const
    {
        return (this->kind == b.kind) &&
               (this->max_blocking_time == b.max_blocking_time) &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        ReliabilityQosPolicy reset = ReliabilityQosPolicy();
        std::swap(*this, reset);
    }

public:

    ReliabilityQosPolicyKind kind;

    fastrtps::Duration_t max_blocking_time;
};



enum OwnershipQosPolicyKind : fastrtps::rtps::octet
{
    SHARED_OWNERSHIP_QOS,
    EXCLUSIVE_OWNERSHIP_QOS
};

class OwnershipQosPolicy : public Parameter_t, public QosPolicy
{
public:

    RTPS_DllAPI OwnershipQosPolicy()
        : Parameter_t(PID_OWNERSHIP, PARAMETER_KIND_LENGTH)
        , QosPolicy(true)
        , kind(SHARED_OWNERSHIP_QOS)
    {
    }

    virtual RTPS_DllAPI ~OwnershipQosPolicy() = default;

    bool operator ==(
            const OwnershipQosPolicy& b) const
    {
        return (this->kind == b.kind) &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        OwnershipQosPolicy reset = OwnershipQosPolicy();
        std::swap(*this, reset);
    }

public:

    OwnershipQosPolicyKind kind;
};

enum DestinationOrderQosPolicyKind : fastrtps::rtps::octet
{
    BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS,
    BY_SOURCE_TIMESTAMP_DESTINATIONORDER_QOS
};



class DestinationOrderQosPolicy : public Parameter_t, public QosPolicy
{
public:

    RTPS_DllAPI DestinationOrderQosPolicy()
        : Parameter_t(PID_DESTINATION_ORDER, PARAMETER_KIND_LENGTH)
        , QosPolicy(true)
        , kind(BY_RECEPTION_TIMESTAMP_DESTINATIONORDER_QOS)
    {
    }

    virtual RTPS_DllAPI ~DestinationOrderQosPolicy() = default;

    bool operator ==(
            const DestinationOrderQosPolicy& b) const
    {
        return (this->kind == b.kind) &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        DestinationOrderQosPolicy reset = DestinationOrderQosPolicy();
        std::swap(*this, reset);
    }

public:

    DestinationOrderQosPolicyKind kind;
};


class GenericDataQosPolicy : public Parameter_t, public QosPolicy,
    public fastrtps::ResourceLimitedVector<fastrtps::rtps::octet>
{
    using ResourceLimitedOctetVector = fastrtps::ResourceLimitedVector<fastrtps::rtps::octet>;

public:

    RTPS_DllAPI GenericDataQosPolicy(
            ParameterId_t pid)
        : Parameter_t(pid, 0)
        , QosPolicy(false)
        , ResourceLimitedOctetVector()
    {
    }

    RTPS_DllAPI GenericDataQosPolicy(
            ParameterId_t pid,
            uint16_t in_length)
        : Parameter_t(pid, in_length)
        , QosPolicy(false)
        , ResourceLimitedOctetVector()
    {
    }

    RTPS_DllAPI GenericDataQosPolicy(
            const GenericDataQosPolicy& data)
        : Parameter_t(data.Pid, data.length)
        , QosPolicy(false)
        , ResourceLimitedOctetVector(data)
    {
    }

    RTPS_DllAPI GenericDataQosPolicy(
            ParameterId_t pid,
            const collection_type& data)
        : Parameter_t(pid, 0)
        , QosPolicy(false)
        , ResourceLimitedOctetVector()
    {
        assign(data.begin(), data.end());
        length = static_cast<uint16_t>((size() + 7u) & ~3u);
    }

    virtual RTPS_DllAPI ~GenericDataQosPolicy() = default;

    GenericDataQosPolicy& operator =(
            const collection_type& b)
    {
        if (collection_ != b)
        {
            //If the object is size limited, already has max_size() allocated
            //assign() will always stop copying when reaching max_size()
            assign(b.begin(), b.end());
            length = static_cast<uint16_t>((size() + 7u) & ~3u);
            hasChanged = true;
        }
        return *this;
    }

    GenericDataQosPolicy& operator =(
            const GenericDataQosPolicy& b)
    {
        QosPolicy::operator =(b);
        Parameter_t::operator =(b);
        configuration_ = b.configuration_;
        collection_.reserve(b.collection_.capacity());
        collection_.assign(b.collection_.begin(), b.collection_.end());
        return *this;
    }

    bool operator ==(
            const GenericDataQosPolicy& b) const
    {
        return collection_ == b.collection_ &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    bool operator ==(
            const collection_type& b) const
    {
        return collection_ == b;
    }

    void set_max_size (
            size_t size)
    {
        if (size > 0)
        {
            configuration_ = fastrtps::ResourceLimitedContainerConfig::fixed_size_configuration(size);
            collection_.reserve(configuration_.maximum);
        }
        else
        {
            configuration_ = fastrtps::ResourceLimitedContainerConfig::dynamic_allocation_configuration();
        }
    }

    void resize(
            size_t new_size)
    {
        collection_.resize(new_size);
    }

    inline const collection_type& dataVec() const
    {
        return collection_;
    }

    inline void clear() override
    {
        ResourceLimitedOctetVector::clear();
        hasChanged = false;
    }

    RTPS_DllAPI inline const collection_type& data_vec() const
    {
        return collection_;
    }

    RTPS_DllAPI inline collection_type& data_vec()
    {
        return collection_;
    }

    RTPS_DllAPI inline void data_vec(
            const collection_type& vec)
    {
        if (collection_ != vec)
        {
            assign(vec.begin(), vec.end());
            length = static_cast<uint16_t>((size() + 7u) & ~3u);
            hasChanged = true;
        }
    }

    RTPS_DllAPI inline const collection_type& getValue() const
    {
        return collection_;
    }

    RTPS_DllAPI inline void setValue(
            const collection_type& vec)
    {
        data_vec(vec);
    }

};

// *INDENT-OFF*  (uncrustify seems to have problems with this macro)
#define TEMPLATE_DATA_QOS_POLICY(TClassName, TPid)                                         \
    class TClassName : public GenericDataQosPolicy                                         \
    {                                                                                      \
    public:                                                                                \
                                                                                           \
        RTPS_DllAPI TClassName()                                                           \
            : GenericDataQosPolicy(TPid)                                                   \
        {                                                                                  \
        }                                                                                  \
                                                                                           \
        RTPS_DllAPI TClassName(                                                            \
                uint16_t in_length)                                                        \
            : GenericDataQosPolicy(TPid, in_length)                                        \
        {                                                                                  \
        }                                                                                  \
                                                                                           \
                                                                                \
        RTPS_DllAPI TClassName(                                                            \
                const TClassName &data) = default;                                         \
                                                                                           \
                                                                                \
        RTPS_DllAPI TClassName(                                                            \
                const collection_type &data)                                               \
            : GenericDataQosPolicy(TPid, data)                                             \
        {                                                                                  \
        }                                                                                  \
                                                                                           \
        virtual RTPS_DllAPI ~TClassName() = default;                                       \
                                                                                           \
                                                                                \
        TClassName& operator =(                                                            \
                const TClassName& b) = default;                                            \
    };
// *INDENT-ON*

//Variable used to generate the doxygen documentation for this QoS Policies
#ifdef DOXYGEN_DOCUMENTATION
class UserDataQosPolicy : public GenericDataQosPolicy
{
};
class TopicDataQosPolicy : public GenericDataQosPolicy
{
};
class GroupDataQosPolicy : public GenericDataQosPolicy
{
};
#endif  // DOXYGEN_DOCUMENTATION

TEMPLATE_DATA_QOS_POLICY(UserDataQosPolicy, PID_USER_DATA)
TEMPLATE_DATA_QOS_POLICY(TopicDataQosPolicy, PID_TOPIC_DATA)
TEMPLATE_DATA_QOS_POLICY(GroupDataQosPolicy, PID_GROUP_DATA)


class TimeBasedFilterQosPolicy : public Parameter_t, public QosPolicy
{
public:

    RTPS_DllAPI TimeBasedFilterQosPolicy()
        : Parameter_t(PID_TIME_BASED_FILTER, PARAMETER_TIME_LENGTH)
        , QosPolicy(false)
        , minimum_separation(0, 0)
    {
    }

    virtual RTPS_DllAPI ~TimeBasedFilterQosPolicy() = default;

    bool operator ==(
            const TimeBasedFilterQosPolicy& b) const
    {
        return (this->minimum_separation == b.minimum_separation) &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        TimeBasedFilterQosPolicy reset = TimeBasedFilterQosPolicy();
        std::swap(*this, reset);
    }

public:

    fastrtps::Duration_t minimum_separation;
};

enum PresentationQosPolicyAccessScopeKind : fastrtps::rtps::octet
{
    INSTANCE_PRESENTATION_QOS,
    TOPIC_PRESENTATION_QOS,
    GROUP_PRESENTATION_QOS
};

#define PARAMETER_PRESENTATION_LENGTH 8

class PresentationQosPolicy : public Parameter_t, public QosPolicy
{
public:

    RTPS_DllAPI PresentationQosPolicy()
        : Parameter_t(PID_PRESENTATION, PARAMETER_PRESENTATION_LENGTH)
        , QosPolicy(false)
        , access_scope(INSTANCE_PRESENTATION_QOS)
        , coherent_access(false)
        , ordered_access(false)
    {
    }

    virtual RTPS_DllAPI ~PresentationQosPolicy() = default;

    bool operator ==(
            const PresentationQosPolicy& b) const
    {
        return (this->access_scope == b.access_scope) &&
               (this->coherent_access == b.coherent_access) &&
               (this->ordered_access == b.ordered_access) &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        PresentationQosPolicy reset = PresentationQosPolicy();
        std::swap(*this, reset);
    }

public:

    PresentationQosPolicyAccessScopeKind access_scope;
    bool coherent_access;
    bool ordered_access;
};


class Partition_t
{

    friend class PartitionQosPolicy;

private:

    const char* partition_;

private:

    Partition_t()
    {
        partition_ = nullptr;
    }

public:

    explicit Partition_t(
            const void* ptr)
    {
        partition_ = (char*)ptr;
    }

    bool operator ==(
            const Partition_t& rhs) const
    {
        return (size() == rhs.size() &&
               (size() == 0 || strcmp(partition_ + 4, rhs.partition_ + 4)));
    }

    bool operator !=(
            const Partition_t& rhs) const
    {
        return !(*this == rhs);
    }

    uint32_t size() const
    {
        return *(uint32_t*)partition_;
    }

    const char* name() const
    {
        return partition_ + 4;
    }

};

class PartitionQosPolicy : public Parameter_t, public QosPolicy
{
public:

    class const_iterator
    {
    public:

        typedef const_iterator self_type;
        typedef const Partition_t value_type;
        typedef const Partition_t reference;
        typedef const Partition_t* pointer;
        typedef size_t difference_type;
        typedef std::forward_iterator_tag iterator_category;

        const_iterator(
                const fastrtps::rtps::octet* ptr)
            : ptr_(ptr)
            , value_ (ptr_)
        {
        }

        self_type operator ++()
        {
            self_type tmp = *this;
            advance();
            return tmp;
        }

        self_type operator ++(
                int)
        {
            advance();
            return *this;
        }

        reference operator *()
        {
            return value_;
        }

        pointer operator ->()
        {
            return &value_;
        }

        bool operator ==(
                const self_type& rhs) const
        {
            return ptr_ == rhs.ptr_;
        }

        bool operator !=(
                const self_type& rhs) const
        {
            return ptr_ != rhs.ptr_;
        }

    protected:

        void advance()
        {
            //Size of the element (with alignment)
            uint32_t size = *(uint32_t*)ptr_;
            ptr_ += (4u + ((size + 3u) & ~3u));
            value_ = Partition_t(ptr_);
        }

    private:

        const fastrtps::rtps::octet* ptr_;
        Partition_t value_;

    };

public:

    RTPS_DllAPI PartitionQosPolicy()
        : Parameter_t(PID_PARTITION, 0)
        , QosPolicy(false)
        , max_size_ (0)
        , Npartitions_ (0)
    {
    }

    RTPS_DllAPI PartitionQosPolicy(
            uint16_t in_length)
        : Parameter_t(PID_PARTITION, in_length)
        , QosPolicy(false)
        , max_size_ (in_length)
        , partitions_(in_length)
        , Npartitions_ (0)
    {
    }

    RTPS_DllAPI PartitionQosPolicy(
            const PartitionQosPolicy& b)
        : Parameter_t(b)
        , QosPolicy(b)
        , max_size_ (b.max_size_)
        , partitions_(b.max_size_ != 0 ?
                b.partitions_.max_size :
                b.partitions_.length)
        , Npartitions_ (b.Npartitions_)
    {
        partitions_.copy(&b.partitions_, b.max_size_ != 0);
    }

    virtual RTPS_DllAPI ~PartitionQosPolicy() = default;

    bool operator ==(
            const PartitionQosPolicy& b) const
    {
        return (this->max_size_ == b.max_size_) &&
               (this->Npartitions_ == b.Npartitions_) &&
               (this->partitions_ == b.partitions_) &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    PartitionQosPolicy& operator =(
            const PartitionQosPolicy& b)
    {
        QosPolicy::operator =(b);
        Parameter_t::operator =(b);
        max_size_ = b.max_size_;
        partitions_.reserve(max_size_ != 0 ?
                b.partitions_.max_size :
                b.partitions_.length);
        partitions_.copy(&b.partitions_, b.max_size_ != 0);
        Npartitions_ = b.Npartitions_;

        return *this;
    }

    const_iterator begin() const
    {
        return const_iterator(partitions_.data);
    }

    const_iterator end() const
    {
        return const_iterator(partitions_.data + partitions_.length);
    }

    uint32_t size() const
    {
        return Npartitions_;
    }

    uint32_t empty() const
    {
        return Npartitions_ == 0;
    }

    void set_max_size (
            uint32_t size)
    {
        partitions_.reserve(size);
        max_size_ = size;
    }

    uint32_t max_size () const
    {
        return max_size_;
    }

    RTPS_DllAPI inline void push_back(
            const char* name)
    {
        //Realloc if needed;
        uint32_t size = (uint32_t)strlen(name) + 1;
        uint32_t alignment = ((size + 3u) & ~3u) - size;

        if (max_size_ != 0 && (partitions_.max_size < partitions_.length +
                size + alignment + 4))
        {
            return;
        }

        partitions_.reserve(partitions_.length + size + alignment + 4);

        fastrtps::rtps::octet* o = (fastrtps::rtps::octet*)&size;
        memcpy(partitions_.data + partitions_.length, o, 4);
        partitions_.length += 4;

        memcpy(partitions_.data + partitions_.length, name, size);
        partitions_.length += size;

        memset(partitions_.data + partitions_.length, 0, alignment);
        partitions_.length += alignment;

        ++Npartitions_;
        hasChanged = true;
    }

    RTPS_DllAPI inline void clear() override
    {
        partitions_.length = 0;
        Npartitions_ = 0;
        hasChanged = false;
    }

    RTPS_DllAPI inline const std::vector<std::string> getNames() const
    {
        return names();
    }

    RTPS_DllAPI inline void setNames(
            std::vector<std::string>& nam)
    {
        names(nam);
    }

    RTPS_DllAPI inline const std::vector<std::string> names() const
    {
        std::vector<std::string> names;
        if (Npartitions_ > 0)
        {
            for (auto it = begin(); it != end(); ++it)
            {
                names.push_back(it->name());
            }
        }
        return names;
    }

    RTPS_DllAPI inline void names(
            std::vector<std::string>& nam)
    {
        clear();
        for (auto it = nam.begin(); it != nam.end(); ++it)
        {
            push_back(it->c_str());
        }
        hasChanged = true;
    }

private:

    uint32_t max_size_;
    fastrtps::rtps::SerializedPayload_t partitions_;
    uint32_t Npartitions_;
};

enum HistoryQosPolicyKind : fastrtps::rtps::octet
{
    KEEP_LAST_HISTORY_QOS,
    KEEP_ALL_HISTORY_QOS
};

class HistoryQosPolicy : public Parameter_t, public QosPolicy
{
public:

    RTPS_DllAPI HistoryQosPolicy()
        : Parameter_t(PID_HISTORY, PARAMETER_KIND_LENGTH + 4)
        , QosPolicy(true)
        , kind(KEEP_LAST_HISTORY_QOS)
        , depth(1)
    {
    }

    virtual RTPS_DllAPI ~HistoryQosPolicy() = default;

    bool operator ==(
            const HistoryQosPolicy& b) const
    {
        return (this->kind == b.kind) &&
               (this->depth == b.depth) &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        HistoryQosPolicy reset = HistoryQosPolicy();
        std::swap(*this, reset);
    }

public:

    HistoryQosPolicyKind kind;
    int32_t depth;
};

constexpr int32_t LENGTH_UNLIMITED = -1;

class ResourceLimitsQosPolicy : public Parameter_t, public QosPolicy
{
public:

    int32_t max_samples;
    int32_t max_instances;
    int32_t max_samples_per_instance;
    int32_t allocated_samples;
    int32_t extra_samples;

    RTPS_DllAPI ResourceLimitsQosPolicy()
        : Parameter_t(PID_RESOURCE_LIMITS, 4 + 4 + 4)
        , QosPolicy(false)
        , max_samples(5000)
        , max_instances(10)
        , max_samples_per_instance(400)
        , allocated_samples(100)
        , extra_samples(1)
    {
    }

    virtual RTPS_DllAPI ~ResourceLimitsQosPolicy() = default;

    bool operator ==(
            const ResourceLimitsQosPolicy& b) const
    {
        return (this->max_samples == b.max_samples) &&
               (this->max_instances == b.max_instances) &&
               (this->max_samples_per_instance == b.max_samples_per_instance) &&
               (this->allocated_samples == b.allocated_samples) &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        ResourceLimitsQosPolicy reset = ResourceLimitsQosPolicy();
        std::swap(*this, reset);
    }

};



class DurabilityServiceQosPolicy : public Parameter_t, public QosPolicy
{
public:

    RTPS_DllAPI DurabilityServiceQosPolicy()
        : Parameter_t(PID_DURABILITY_SERVICE, PARAMETER_TIME_LENGTH + PARAMETER_KIND_LENGTH + 4 + 4 + 4 + 4)
        , QosPolicy(false)
        , history_kind(KEEP_LAST_HISTORY_QOS)
        , history_depth(1)
        , max_samples(LENGTH_UNLIMITED)
        , max_instances(LENGTH_UNLIMITED)
        , max_samples_per_instance(LENGTH_UNLIMITED)
    {
    }

    virtual RTPS_DllAPI ~DurabilityServiceQosPolicy() = default;

    bool operator ==(
            const DurabilityServiceQosPolicy& b) const
    {
        return (this->history_kind == b.history_kind) &&
               (this->history_depth == b.history_depth) &&
               (this->max_samples == b.max_samples) &&
               (this->max_instances == b.max_instances) &&
               (this->max_samples_per_instance == b.max_samples_per_instance) &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        DurabilityServiceQosPolicy reset = DurabilityServiceQosPolicy();
        std::swap(*this, reset);
    }

public:

    fastrtps::Duration_t service_cleanup_delay;
    HistoryQosPolicyKind history_kind;
    int32_t history_depth;
    int32_t max_samples;
    int32_t max_instances;
    int32_t max_samples_per_instance;
};

class LifespanQosPolicy : public Parameter_t, public QosPolicy
{
public:

    RTPS_DllAPI LifespanQosPolicy()
        : Parameter_t(PID_LIFESPAN, PARAMETER_TIME_LENGTH)
        , QosPolicy(true)
        , duration(TIME_T_INFINITE_SECONDS, TIME_T_INFINITE_NANOSECONDS)
    {
    }

    virtual RTPS_DllAPI ~LifespanQosPolicy() = default;

    bool operator ==(
            const LifespanQosPolicy& b) const
    {
        return (this->duration == b.duration) &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        LifespanQosPolicy reset = LifespanQosPolicy();
        std::swap(*this, reset);
    }

public:

    fastrtps::Duration_t duration;
};

class OwnershipStrengthQosPolicy : public Parameter_t, public QosPolicy
{
public:

    RTPS_DllAPI OwnershipStrengthQosPolicy()
        : Parameter_t(PID_OWNERSHIP_STRENGTH, 4)
        , QosPolicy(false)
        , value(0)
    {
    }

    virtual RTPS_DllAPI ~OwnershipStrengthQosPolicy() = default;

    bool operator ==(
            const OwnershipStrengthQosPolicy& b) const
    {
        return (this->value == b.value) &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        OwnershipStrengthQosPolicy reset = OwnershipStrengthQosPolicy();
        std::swap(*this, reset);
    }

public:

    uint32_t value;
};


class TransportPriorityQosPolicy : public Parameter_t, public QosPolicy
{
public:

    uint32_t value;

    RTPS_DllAPI TransportPriorityQosPolicy()
        : Parameter_t(PID_TRANSPORT_PRIORITY, 4)
        , QosPolicy(false)
        , value(0)
    {
    }

    virtual RTPS_DllAPI ~TransportPriorityQosPolicy() = default;

    bool operator ==(
            const TransportPriorityQosPolicy& b) const
    {
        return (this->value == b.value) &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        TransportPriorityQosPolicy reset = TransportPriorityQosPolicy();
        std::swap(*this, reset);
    }

};

typedef enum PublishModeQosPolicyKind : fastrtps::rtps::octet
{
    SYNCHRONOUS_PUBLISH_MODE,
    ASYNCHRONOUS_PUBLISH_MODE
} PublishModeQosPolicyKind_t;

class PublishModeQosPolicy : public QosPolicy
{
public:

    PublishModeQosPolicyKind kind = SYNCHRONOUS_PUBLISH_MODE;

    const char* flow_controller_name = fastdds::rtps::FASTDDS_FLOW_CONTROLLER_DEFAULT;

    inline void clear() override
    {
        PublishModeQosPolicy reset = PublishModeQosPolicy();
        std::swap(*this, reset);
    }

    bool operator ==(
            const PublishModeQosPolicy& b) const
    {
        return (this->kind == b.kind) &&
               0 == strcmp(flow_controller_name, b.flow_controller_name) &&
               QosPolicy::operator ==(b);
    }

};

typedef enum DataRepresentationId : int16_t
{
    XCDR_DATA_REPRESENTATION = 0,
    XML_DATA_REPRESENTATION = 1,
    XCDR2_DATA_REPRESENTATION = 2
} DataRepresentationId_t;

class DataRepresentationQosPolicy : public Parameter_t, public QosPolicy
{
public:

    std::vector<DataRepresentationId_t> m_value;

    RTPS_DllAPI DataRepresentationQosPolicy()
        : Parameter_t(PID_DATA_REPRESENTATION, 0)
        , QosPolicy(true)
    {
    }

    virtual RTPS_DllAPI ~DataRepresentationQosPolicy() override = default;

    bool operator ==(
            const DataRepresentationQosPolicy& b) const
    {
        return (this->m_value == b.m_value) &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        DataRepresentationQosPolicy reset = DataRepresentationQosPolicy();
        std::swap(*this, reset);
    }

};

enum TypeConsistencyKind : uint16_t
{
    DISALLOW_TYPE_COERCION,
    ALLOW_TYPE_COERCION
};

class TypeConsistencyEnforcementQosPolicy : public Parameter_t, public QosPolicy
{
public:

    TypeConsistencyKind m_kind;
    bool m_ignore_sequence_bounds;
    bool m_ignore_string_bounds;
    bool m_ignore_member_names;
    bool m_prevent_type_widening;
    bool m_force_type_validation;

    RTPS_DllAPI TypeConsistencyEnforcementQosPolicy()
        : Parameter_t(PID_TYPE_CONSISTENCY_ENFORCEMENT, 8) // 2 + 5 + 1 alignment byte
        , QosPolicy(true)
    {
        m_kind = ALLOW_TYPE_COERCION;
        m_ignore_sequence_bounds = true;
        m_ignore_string_bounds = true;
        m_ignore_member_names = false;
        m_prevent_type_widening = false;
        m_force_type_validation = false;
    }

    virtual RTPS_DllAPI ~TypeConsistencyEnforcementQosPolicy() override = default;

    bool operator ==(
            const TypeConsistencyEnforcementQosPolicy& b) const
    {
        return m_kind == b.m_kind &&
               m_ignore_sequence_bounds == b.m_ignore_sequence_bounds &&
               m_ignore_string_bounds == b.m_ignore_string_bounds &&
               m_ignore_member_names == b.m_ignore_member_names &&
               m_prevent_type_widening == b.m_prevent_type_widening &&
               m_force_type_validation == b.m_force_type_validation &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        TypeConsistencyEnforcementQosPolicy reset = TypeConsistencyEnforcementQosPolicy();
        std::swap(*this, reset);
    }

};

class DisablePositiveACKsQosPolicy : public Parameter_t, public QosPolicy
{
public:

    RTPS_DllAPI DisablePositiveACKsQosPolicy()
        : Parameter_t(PID_DISABLE_POSITIVE_ACKS, PARAMETER_BOOL_LENGTH)
        , QosPolicy(true)
        , enabled(false)
        , duration(TIME_T_INFINITE_SECONDS, TIME_T_INFINITE_NANOSECONDS)
    {
    }

    virtual RTPS_DllAPI ~DisablePositiveACKsQosPolicy() = default;

    bool operator ==(
            const DisablePositiveACKsQosPolicy& b) const
    {
        return enabled == b.enabled &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        DisablePositiveACKsQosPolicy reset = DisablePositiveACKsQosPolicy();
        std::swap(*this, reset);
    }

public:

    bool enabled;
    fastrtps::Duration_t duration;
};

class TypeIdV1 : public Parameter_t, public QosPolicy
{
public:

    fastrtps::types::TypeIdentifier m_type_identifier;


    RTPS_DllAPI TypeIdV1()
        : Parameter_t(PID_TYPE_IDV1, 0)
        , QosPolicy(false)
        , m_type_identifier()
    {
    }

    RTPS_DllAPI TypeIdV1(
            const TypeIdV1& type)
        : Parameter_t(type.Pid, type.length)
        , QosPolicy(type.send_always_)
        , m_type_identifier(type.m_type_identifier)
    {
    }

    RTPS_DllAPI TypeIdV1(
            const fastrtps::types::TypeIdentifier& identifier)
        : Parameter_t(PID_TYPE_IDV1, 0)
        , QosPolicy(false)
        , m_type_identifier(identifier)
    {
    }

    RTPS_DllAPI TypeIdV1(
            TypeIdV1&& type)
        : Parameter_t(type.Pid, type.length)
        , QosPolicy(type.send_always_)
        , m_type_identifier(std::move(type.m_type_identifier))
    {
    }

    RTPS_DllAPI TypeIdV1& operator =(
            const TypeIdV1& type)
    {
        Pid = type.Pid;
        length = type.length;
        send_always_ = type.send_always_;

        m_type_identifier = type.m_type_identifier;

        return *this;
    }

    RTPS_DllAPI TypeIdV1& operator =(
            TypeIdV1&& type)
    {
        Pid = type.Pid;
        length = type.length;
        send_always_ = type.send_always_;

        m_type_identifier = std::move(type.m_type_identifier);

        return *this;
    }

    virtual RTPS_DllAPI ~TypeIdV1() override = default;

    inline void clear() override
    {
        *this = TypeIdV1();
    }

    RTPS_DllAPI TypeIdV1& operator =(
            const fastrtps::types::TypeIdentifier& type_id)
    {
        m_type_identifier = type_id;
        return *this;
    }

    RTPS_DllAPI const fastrtps::types::TypeIdentifier& get() const
    {
        return m_type_identifier;
    }

};

class TypeObjectV1 : public Parameter_t, public QosPolicy
{
public:

    fastrtps::types::TypeObject m_type_object;

    RTPS_DllAPI TypeObjectV1()
        : Parameter_t(PID_TYPE_OBJECTV1, 0)
        , QosPolicy(false)
        , m_type_object()
    {
    }

    RTPS_DllAPI TypeObjectV1(
            const TypeObjectV1& type)
        : Parameter_t(type.Pid, type.length)
        , QosPolicy(type.send_always_)
        , m_type_object(type.m_type_object)
    {
    }

    RTPS_DllAPI TypeObjectV1(
            const fastrtps::types::TypeObject& type)
        : Parameter_t(PID_TYPE_OBJECTV1, 0)
        , QosPolicy(false)
        , m_type_object(type)
    {
    }

    RTPS_DllAPI TypeObjectV1(
            TypeObjectV1&& type)
        : Parameter_t(type.Pid, type.length)
        , QosPolicy(type.send_always_)
        , m_type_object(std::move(type.m_type_object))
    {
    }

    RTPS_DllAPI TypeObjectV1& operator =(
            const TypeObjectV1& type)
    {
        Pid = type.Pid;
        length = type.length;
        send_always_ = type.send_always_;

        m_type_object = type.m_type_object;

        return *this;
    }

    RTPS_DllAPI TypeObjectV1& operator =(
            TypeObjectV1&& type)
    {
        Pid = type.Pid;
        length = type.length;
        send_always_ = type.send_always_;

        m_type_object = std::move(type.m_type_object);

        return *this;
    }

    virtual RTPS_DllAPI ~TypeObjectV1() override = default;

    inline void clear() override
    {
        *this = TypeObjectV1();
    }

    RTPS_DllAPI TypeObjectV1& operator =(
            const fastrtps::types::TypeObject& type_object)
    {
        m_type_object = type_object;
        return *this;
    }

    RTPS_DllAPI const fastrtps::types::TypeObject& get() const
    {
        return m_type_object;
    }

};

namespace xtypes {

class TypeInformation : public Parameter_t, public QosPolicy
{
public:

    fastrtps::types::TypeInformation type_information;

    RTPS_DllAPI TypeInformation()
        : Parameter_t(PID_TYPE_INFORMATION, 0)
        , QosPolicy(false)
        , type_information()
        , assigned_(false)
    {
    }

    RTPS_DllAPI TypeInformation(
            const TypeInformation& type)
        : Parameter_t(type.Pid, type.length)
        , QosPolicy(type.send_always_)
        , type_information(type.type_information)
        , assigned_(type.assigned_)
    {
    }

    RTPS_DllAPI TypeInformation(
            const fastrtps::types::TypeInformation& info)
        : Parameter_t(PID_TYPE_INFORMATION, 0)
        , QosPolicy(false)
        , type_information(info)
        , assigned_(true)
    {
    }

    RTPS_DllAPI TypeInformation(
            TypeInformation&& type)
        : Parameter_t(type.Pid, type.length)
        , QosPolicy(type.send_always_)
        , type_information(std::move(type.type_information))
        , assigned_(type.assigned_)
    {
    }

    RTPS_DllAPI TypeInformation& operator =(
            const TypeInformation& type)
    {
        Pid = type.Pid;
        length = type.length;
        send_always_ = type.send_always_;

        type_information = type.type_information;
        assigned_ = type.assigned_;

        return *this;
    }

    RTPS_DllAPI TypeInformation& operator =(
            TypeInformation&& type)
    {
        Pid = type.Pid;
        length = type.length;
        send_always_ = type.send_always_;

        type_information = std::move(type.type_information);
        assigned_ = type.assigned_;

        return *this;
    }

    virtual RTPS_DllAPI ~TypeInformation() override = default;

    inline void clear() override
    {
        *this = TypeInformation();
    }

    RTPS_DllAPI bool assigned() const
    {
        return assigned_;
    }

    RTPS_DllAPI void assigned(
            bool value)
    {
        assigned_ = value;
    }

    RTPS_DllAPI TypeInformation& operator =(
            const fastrtps::types::TypeInformation& type_info)
    {
        type_information = type_info;
        assigned_ = true;
        return *this;
    }

private:

    bool assigned_;
};

} // namespace xtypes

using ParticipantResourceLimitsQos = fastrtps::rtps::RTPSParticipantAllocationAttributes;

using PropertyPolicyQos = fastrtps::rtps::PropertyPolicy;

class WireProtocolConfigQos : public QosPolicy
{

public:

    RTPS_DllAPI WireProtocolConfigQos()
        : QosPolicy(false)
        , participant_id(-1)
    {
    }

    virtual RTPS_DllAPI ~WireProtocolConfigQos() = default;

    bool operator ==(
            const WireProtocolConfigQos& b) const
    {
        return (this->prefix == b.prefix) &&
               (this->participant_id == b.participant_id) &&
               (this->builtin == b.builtin) &&
               (this->port == b.port) &&
               (this->throughput_controller == b.throughput_controller) &&
               (this->default_unicast_locator_list == b.default_unicast_locator_list) &&
               (this->default_multicast_locator_list == b.default_multicast_locator_list) &&
               (this->default_external_unicast_locators == b.default_external_unicast_locators) &&
               (this->ignore_non_matching_locators == b.ignore_non_matching_locators) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        WireProtocolConfigQos reset = WireProtocolConfigQos();
        std::swap(*this, reset);
    }

    fastrtps::rtps::GuidPrefix_t prefix;

    int32_t participant_id;

    fastrtps::rtps::BuiltinAttributes builtin;

    fastrtps::rtps::PortParameters port;

    fastrtps::rtps::ThroughputControllerDescriptor throughput_controller;

    rtps::LocatorList default_unicast_locator_list;

    rtps::LocatorList default_multicast_locator_list;

    rtps::ExternalLocators default_external_unicast_locators;

    bool ignore_non_matching_locators = false;
};

class TransportConfigQos : public QosPolicy
{
public:

    RTPS_DllAPI TransportConfigQos()
        : QosPolicy(false)
        , use_builtin_transports(true)
        , send_socket_buffer_size(0)
        , listen_socket_buffer_size(0)
    {
    }

    virtual RTPS_DllAPI ~TransportConfigQos() = default;

    bool operator ==(
            const TransportConfigQos& b) const
    {
        return (this->user_transports == b.user_transports) &&
               (this->use_builtin_transports == b.use_builtin_transports) &&
               (this->send_socket_buffer_size == b.send_socket_buffer_size) &&
               (this->listen_socket_buffer_size == b.listen_socket_buffer_size) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        TransportConfigQos reset = TransportConfigQos();
        std::swap(*this, reset);
    }

    std::vector<std::shared_ptr<fastdds::rtps::TransportDescriptorInterface>> user_transports;

    bool use_builtin_transports;

    uint32_t send_socket_buffer_size;

    uint32_t listen_socket_buffer_size;
};

class RTPSEndpointQos
{
public:

    RTPS_DllAPI RTPSEndpointQos() = default;

    virtual RTPS_DllAPI ~RTPSEndpointQos() = default;

    bool operator ==(
            const RTPSEndpointQos& b) const
    {
        return (this->unicast_locator_list == b.unicast_locator_list) &&
               (this->multicast_locator_list == b.multicast_locator_list) &&
               (this->remote_locator_list == b.remote_locator_list) &&
               (this->external_unicast_locators == b.external_unicast_locators) &&
               (this->ignore_non_matching_locators == b.ignore_non_matching_locators) &&
               (this->user_defined_id == b.user_defined_id) &&
               (this->entity_id == b.entity_id) &&
               (this->history_memory_policy == b.history_memory_policy);
    }

    rtps::LocatorList unicast_locator_list;

    rtps::LocatorList multicast_locator_list;

    rtps::LocatorList remote_locator_list;

    fastdds::rtps::ExternalLocators external_unicast_locators;

    bool ignore_non_matching_locators = false;

    int16_t user_defined_id = -1;

    int16_t entity_id = -1;

    fastrtps::rtps::MemoryManagementPolicy_t history_memory_policy =
            fastrtps::rtps::PREALLOCATED_WITH_REALLOC_MEMORY_MODE;
};

class WriterResourceLimitsQos
{
public:

    RTPS_DllAPI WriterResourceLimitsQos()
        : matched_subscriber_allocation()
        , reader_filters_allocation(0, 32u, 1u)
    {
    }

    virtual RTPS_DllAPI ~WriterResourceLimitsQos() = default;

    bool operator ==(
            const WriterResourceLimitsQos& b) const
    {
        return (matched_subscriber_allocation == b.matched_subscriber_allocation) &&
               (reader_filters_allocation == b.reader_filters_allocation);
    }

    fastrtps::ResourceLimitedContainerConfig matched_subscriber_allocation;
    fastrtps::ResourceLimitedContainerConfig reader_filters_allocation;
};

enum DataSharingKind : fastrtps::rtps::octet
{
    AUTO = 0x01,
    ON = 0x02,
    OFF = 0x03
};


class DataSharingQosPolicy : public Parameter_t, public QosPolicy
{
public:

    RTPS_DllAPI DataSharingQosPolicy()
        : Parameter_t(PID_DATASHARING, 0)
        , QosPolicy(true)
    {
        //Needed to generate the automatic domain ID
        automatic();
    }

    virtual RTPS_DllAPI ~DataSharingQosPolicy() = default;

    RTPS_DllAPI DataSharingQosPolicy(
            const DataSharingQosPolicy& b)
        : Parameter_t(b)
        , QosPolicy(b)
        , kind_(b.kind())
        , shm_directory_ (b.shm_directory())
        , max_domains_ (b.max_domains())
        , domain_ids_(b.max_domains() != 0 ?
                b.max_domains() :
                b.domain_ids().size())
    {
        domain_ids_ = b.domain_ids();
    }

    RTPS_DllAPI DataSharingQosPolicy& operator =(
            const DataSharingQosPolicy& b)
    {
        QosPolicy::operator =(b);
        Parameter_t::operator =(b);
        kind_ = b.kind();
        shm_directory_ = b.shm_directory();
        max_domains_ = b.max_domains();
        domain_ids_.reserve(max_domains_ != 0 ?
                max_domains_ :
                b.domain_ids().size());
        domain_ids_ = b.domain_ids();

        return *this;
    }

    bool operator ==(
            const DataSharingQosPolicy& b) const
    {
        return kind_ == b.kind_ &&
               shm_directory_ == b.shm_directory_ &&
               domain_ids_ == b.domain_ids_ &&
               Parameter_t::operator ==(b) &&
               QosPolicy::operator ==(b);
    }

    inline void clear() override
    {
        DataSharingQosPolicy reset = DataSharingQosPolicy();
        std::swap(*this, reset);
    }

    RTPS_DllAPI const DataSharingKind& kind() const
    {
        return kind_;
    }

    RTPS_DllAPI const std::string& shm_directory() const
    {
        return shm_directory_;
    }

    RTPS_DllAPI const std::vector<uint64_t>& domain_ids() const
    {
        return domain_ids_;
    }

    RTPS_DllAPI void set_max_domains(
            uint32_t size)
    {
        domain_ids_.reserve(size);
        max_domains_ = size;
    }

    RTPS_DllAPI const uint32_t& max_domains() const
    {
        return max_domains_;
    }

    RTPS_DllAPI void automatic()
    {
        setup (AUTO, "", std::vector<uint16_t>());
    }

    RTPS_DllAPI void automatic(
            const std::vector<uint16_t>& domain_ids)
    {
        setup (AUTO, "", domain_ids);
    }

    RTPS_DllAPI void automatic(
            const std::string& directory)
    {
        setup (AUTO, directory, std::vector<uint16_t>());
    }

    RTPS_DllAPI void automatic(
            const std::string& directory,
            const std::vector<uint16_t>& domain_ids)
    {
        setup (AUTO, directory, domain_ids);
    }

    RTPS_DllAPI void on(
            const std::string& directory)
    {
        // TODO [ILG]: This parameter is unused right now. Activate the assert once it is used
        //assert(!directory.empty());
        setup (ON, directory, std::vector<uint16_t>());
    }

    RTPS_DllAPI void on(
            const std::string& directory,
            const std::vector<uint16_t>& domain_ids)
    {
        // TODO [ILG]: This parameter is unused right now. Activate the assert once it is used
        //assert(!directory.empty());
        setup (ON, directory, domain_ids);
    }

    RTPS_DllAPI void off()
    {
        setup (OFF, "", std::vector<uint16_t>());
    }

    RTPS_DllAPI void add_domain_id(
            uint16_t id)
    {
        if (max_domains_ == 0 || domain_ids_.size() < max_domains_)
        {
            domain_ids_.push_back(id);
        }
    }

    // Not on the exported API, but must be public for other internal classes
    void add_domain_id(
            uint64_t id)
    {
        if (max_domains_ == 0 || domain_ids_.size() < max_domains_)
        {
            domain_ids_.push_back(id);
        }
    }

private:

    void setup(
            const DataSharingKind& kind,
            const std::string& directory,
            const std::vector<uint16_t>& domain_ids)
    {
        kind_ = kind;
        shm_directory_ = directory;
        domain_ids_.clear();

        for (uint16_t id : domain_ids)
        {
            add_domain_id(id);
        }
    }

    DataSharingKind kind_ = AUTO;

    std::string shm_directory_;

    uint32_t max_domains_ = 0;

    std::vector<uint64_t> domain_ids_;
};


} // namespace dds
} // namespace fastdds
} // namespace eprosima

#endif // _FASTDDS_DDS_QOS_QOSPOLICIES_HPP_