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