File type_object.hpp

File List > astutedds > xtypes > type_object.hpp

Go to the documentation of this file

//
// Copyright (c) 2026, Astute Systems PTY LTD
//
// This file is part of the Astute DDS developed by Astute Systems.
//
// See the commercial LICENSE file in the project root for full license details.
//
// @file type_object.hpp
// @brief DDS X-Types TypeObject and TypeIdentifier
//
// Implements the type system from DDS-XTypes 1.3 specification.
// Reference: https://www.omg.org/spec/DDS-XTypes/1.3/PDF
//

#ifndef ASTUTEDDS_XTYPES_TYPE_OBJECT_HPP
#define ASTUTEDDS_XTYPES_TYPE_OBJECT_HPP

#include <astutedds/cdr/cdr_types.hpp>

#include <array>
#include <cstdint>
#include <optional>
#include <string>
#include <variant>
#include <vector>

namespace astutedds::xtypes
{

// Type Kind (7.2.2.1)
enum class TypeKind : uint8_t
{
    TK_NONE = 0x00,
    TK_BOOLEAN = 0x01,
    TK_BYTE = 0x02,
    TK_INT16 = 0x03,
    TK_INT32 = 0x04,
    TK_INT64 = 0x05,
    TK_UINT16 = 0x06,
    TK_UINT32 = 0x07,
    TK_UINT64 = 0x08,
    TK_FLOAT32 = 0x09,
    TK_FLOAT64 = 0x0a,
    TK_FLOAT128 = 0x0b,
    TK_INT8 = 0x0c,
    TK_UINT8 = 0x0d,
    TK_CHAR8 = 0x10,
    TK_CHAR16 = 0x11,
    TK_STRING8 = 0x20,
    TK_STRING16 = 0x21,
    TK_ALIAS = 0x30,
    TK_ENUM = 0x31,
    TK_BITMASK = 0x32,
    TK_ANNOTATION = 0x33,
    TK_STRUCTURE = 0x34,
    TK_UNION = 0x35,
    TK_BITSET = 0x36,
    TK_SEQUENCE = 0x40,
    TK_ARRAY = 0x41,
    TK_MAP = 0x42
};

// Equivalence Hash (7.3.4.9)
using EquivalenceHash = std::array<uint8_t, 14>;

// Type Identifier discriminator (7.3.4.5.1)
enum class TypeIdKind : uint8_t
{
    TI_STRING8_SMALL = 0x70,
    TI_STRING8_LARGE = 0x71,
    TI_STRING16_SMALL = 0x72,
    TI_STRING16_LARGE = 0x73,
    TI_PLAIN_SEQUENCE_SMALL = 0x74,
    TI_PLAIN_SEQUENCE_LARGE = 0x75,
    TI_PLAIN_ARRAY_SMALL = 0x76,
    TI_PLAIN_ARRAY_LARGE = 0x77,
    TI_PLAIN_MAP_SMALL = 0x78,
    TI_PLAIN_MAP_LARGE = 0x79,
    TI_STRONGLY_CONNECTED_COMPONENT = 0x7a,
    EK_COMPLETE = 0x7b,
    EK_MINIMAL = 0x7c
};

// Forward declarations
struct TypeIdentifier;

// String Type Identifier (7.3.4.5.2)
struct StringSTypeDefn
{
    uint8_t bound{0};  // 0 = unbounded
};

struct StringLTypeDefn
{
    uint32_t bound{0};  // 0 = unbounded
};

// Sequence Type Identifier (7.3.4.5.3)
struct PlainSequenceSElemDefn
{
    uint8_t bound{0};
    TypeIdentifier* element_identifier{nullptr};
};

struct PlainSequenceLElemDefn
{
    uint32_t bound{0};
    TypeIdentifier* element_identifier{nullptr};
};

// Array Type Identifier (7.3.4.5.4)
struct PlainArraySElemDefn
{
    std::vector<uint8_t> array_bound_seq;
    TypeIdentifier* element_identifier{nullptr};
};

struct PlainArrayLElemDefn
{
    std::vector<uint32_t> array_bound_seq;
    TypeIdentifier* element_identifier{nullptr};
};

// Map Type Identifier (7.3.4.5.5)
struct PlainMapSTypeDefn
{
    uint8_t bound{0};
    TypeIdentifier* key_identifier{nullptr};
    TypeIdentifier* element_identifier{nullptr};
};

struct PlainMapLTypeDefn
{
    uint32_t bound{0};
    TypeIdentifier* key_identifier{nullptr};
    TypeIdentifier* element_identifier{nullptr};
};

// Type Identifier (7.3.4.5)
struct TypeIdentifier
{
    using VariantType =
        std::variant<std::monostate,  // TK_NONE or primitive types
                     StringSTypeDefn, StringLTypeDefn, PlainSequenceSElemDefn, PlainSequenceLElemDefn,
                     PlainArraySElemDefn, PlainArrayLElemDefn, PlainMapSTypeDefn, PlainMapLTypeDefn, EquivalenceHash>;

    TypeIdKind discriminator{TypeIdKind::EK_MINIMAL};
    VariantType value;
};

// Member Flags (7.3.1.2.1.4)
struct MemberFlag
{
    static constexpr uint16_t TRY_CONSTRUCT_DISCARD = 0x0001;
    static constexpr uint16_t TRY_CONSTRUCT_USE_DEFAULT = 0x0002;
    static constexpr uint16_t IS_EXTERNAL = 0x0004;
    static constexpr uint16_t IS_OPTIONAL = 0x0008;
    static constexpr uint16_t IS_MUST_UNDERSTAND = 0x0010;
    static constexpr uint16_t IS_KEY = 0x0020;
    static constexpr uint16_t IS_DEFAULT = 0x0040;
};

// Common Structure Member (7.3.1.2.1)
struct CommonStructMember
{
    uint32_t member_id{0};
    uint16_t member_flags{0};
    TypeIdentifier member_type_id;
};

// Complete Structure Member (7.3.1.2.2)
struct CompleteStructMember
{
    CommonStructMember common;
    std::string name;
    std::vector<std::string> annotations;  // Simplified
};

// Minimal Structure Member (7.3.1.2.3)
struct MinimalStructMember
{
    CommonStructMember common;
    uint32_t name_hash{0};  // Hash of the member name
};

// Structure Type (7.3.1.2.4)
struct CompleteStructType
{
    cdr::ExtensibilityKind extensibility{cdr::ExtensibilityKind::FINAL};
    std::vector<CompleteStructMember> members;
    std::string name;
};

struct MinimalStructType
{
    cdr::ExtensibilityKind extensibility{cdr::ExtensibilityKind::FINAL};
    std::vector<MinimalStructMember> members;
};

// Enum Literal (7.3.1.3.1)
struct CommonEnumeratedLiteral
{
    int32_t value{0};
    uint16_t flags{0};
};

struct CompleteEnumeratedLiteral
{
    CommonEnumeratedLiteral common;
    std::string name;
};

struct MinimalEnumeratedLiteral
{
    CommonEnumeratedLiteral common;
    uint32_t name_hash{0};
};

// Enum Type (7.3.1.3.2)
struct CompleteEnumeratedType
{
    uint16_t bit_bound{32};  // Number of bits used
    std::vector<CompleteEnumeratedLiteral> literals;
    std::string name;
};

struct MinimalEnumeratedType
{
    uint16_t bit_bound{32};
    std::vector<MinimalEnumeratedLiteral> literals;
};

// Type Object (7.3.4.2)
struct CompleteTypeObject
{
    using VariantType = std::variant<std::monostate, CompleteStructType, CompleteEnumeratedType
                                     // Add other types as needed
                                     >;

    VariantType value;
};

struct MinimalTypeObject
{
    using VariantType = std::variant<std::monostate, MinimalStructType, MinimalEnumeratedType
                                     // Add other types as needed
                                     >;

    VariantType value;
};

struct TypeObject
{
    using VariantType = std::variant<CompleteTypeObject, MinimalTypeObject>;

    VariantType value;
};

// Factory functions for creating TypeObjects

CompleteTypeObject create_complete_struct_type_object(
    const std::string& name, const std::vector<CompleteStructMember>& members,
    cdr::ExtensibilityKind extensibility = cdr::ExtensibilityKind::FINAL);

MinimalTypeObject create_minimal_struct_type_object(
    const std::vector<MinimalStructMember>& members,
    cdr::ExtensibilityKind extensibility = cdr::ExtensibilityKind::FINAL);

CompleteTypeObject create_complete_enum_type_object(const std::string& name,
                                                    const std::vector<CompleteEnumeratedLiteral>& literals,
                                                    uint16_t bit_bound = 32);

MinimalTypeObject create_minimal_enum_type_object(const std::vector<MinimalEnumeratedLiteral>& literals,
                                                  uint16_t bit_bound = 32);

// TypeIdentifier creation functions

TypeIdentifier create_primitive_type_identifier(TypeKind kind);

TypeIdentifier create_string_type_identifier(uint32_t bound = 0);

TypeIdentifier create_sequence_type_identifier(const TypeIdentifier& element_type, uint32_t bound = 0);

TypeIdentifier create_array_type_identifier(const TypeIdentifier& element_type, const std::vector<uint32_t>& bounds);

std::vector<uint8_t> serialize_type_object(const TypeObject& type_obj);

EquivalenceHash generate_equivalence_hash(const TypeObject& type_obj);

TypeIdentifier create_type_identifier_from_hash(const EquivalenceHash& hash, bool use_minimal = true);

MinimalStructMember to_minimal_struct_member(const CompleteStructMember& complete);

MinimalEnumeratedLiteral to_minimal_enum_literal(const CompleteEnumeratedLiteral& complete);

// Assignability functions (DDS-XTypes 1.3 Section 7.6.3)

bool is_primitive_assignable(TypeKind source, TypeKind target);

bool is_string_assignable(const TypeIdentifier& source, const TypeIdentifier& target);

bool are_struct_members_assignable(const CommonStructMember& source, const CommonStructMember& target);

bool is_struct_assignable(const CompleteStructType& source, const CompleteStructType& target);

bool is_enum_assignable(const CompleteEnumeratedType& source, const CompleteEnumeratedType& target);

bool is_assignable(const TypeObject& source, const TypeObject& target);

// TypeIdentifier helper functions

bool operator==(const TypeIdentifier& lhs, const TypeIdentifier& rhs);
bool operator!=(const TypeIdentifier& lhs, const TypeIdentifier& rhs);

std::string to_string(const TypeIdentifier& ti);

TypeIdentifier clone_type_identifier(const TypeIdentifier& source);

bool is_primitive_type_identifier(const TypeIdentifier& ti);

bool is_string_type_identifier(const TypeIdentifier& ti);

bool is_collection_type_identifier(const TypeIdentifier& ti);

}  // namespace astutedds::xtypes

#endif  // ASTUTEDDS_XTYPES_TYPE_OBJECT_HPP