31 #include <type_traits>
34 #include "../base/helpers.h"
35 #include "../base/logger.h"
36 #include "../base/name_detector.h"
37 #include "../base/traits.h"
38 #include "../serializer.h"
40 #ifndef VLINK_DDS_IDL_PREFIX
41 #define VLINK_DDS_IDL_PREFIX "dds::"
44 #if defined(VLINK_SUPPORT_CDR) || defined(VLINK_SUPPORT_ROS2)
45 #if __has_include(<fastcdr/Cdr.h>)
46 #include <fastcdr/Cdr.h>
47 #if FASTCDR_VERSION_MAJOR >= 2
48 #include <fastcdr/CdrSizeCalculator.hpp>
54 #warning "Fast CDR headers are required when CDR serialization support is enabled."
58 #ifdef VLINK_SUPPORT_ROS2
59 #if defined(VLINK_HAS_CDR) && __has_include(<rosidl_typesupport_fastrtps_cpp/message_type_support.h>)
60 #include <rosidl_typesupport_fastrtps_cpp/message_type_support.h>
62 #include <rosidl_runtime_cpp/traits.hpp>
63 #include <rosidl_typesupport_fastrtps_cpp/message_type_support_decl.hpp>
64 #ifndef VLINK_HAS_ROS2
65 #define VLINK_HAS_ROS2
67 #elif defined(VLINK_HAS_CDR)
68 #warning "ROS 2 message headers are required when ROS 2 message support is enabled."
72 #if __has_include(<google/protobuf/message_lite.h>)
73 #ifndef VLINK_HAS_PROTOBUF
74 #define VLINK_HAS_PROTOBUF
76 #include <google/protobuf/message_lite.h>
79 #if __has_include(<flatbuffers/flatbuffers.h>)
80 #ifndef VLINK_HAS_FLATBUFFERS
81 #define VLINK_HAS_FLATBUFFERS
83 #include <flatbuffers/flatbuffers.h>
94 inline constexpr
bool is_ros2_msg_type() noexcept {
96 return rosidl_generator_traits::is_message<RealType>::value;
100 inline const message_type_support_callbacks_t* get_ros2_msg_callbacks() noexcept {
101 const auto* type_support = rosidl_typesupport_fastrtps_cpp::get_message_type_support_handle<T>();
102 return type_support ?
static_cast<const message_type_support_callbacks_t*
>(type_support->data) :
nullptr;
106 template <
typename T>
108 if constexpr (is_bytes_type<T>()) {
110 }
else if constexpr (is_dynamic_type<T>()) {
113 }
else if constexpr (is_cdr_type<T>()) {
116 #ifdef VLINK_HAS_PROTOBUF
117 }
else if constexpr (is_proto_type<T>()) {
119 }
else if constexpr (is_proto_ptr_type<T>()) {
122 #ifdef VLINK_HAS_FLATBUFFERS
123 }
else if constexpr (is_flat_table_type<T>()) {
125 }
else if constexpr (is_flat_ptr_type<T>()) {
127 }
else if constexpr (is_flat_builder_type<T>()) {
130 }
else if constexpr (is_custom_type<T>()) {
132 }
else if constexpr (is_string_type<T>()) {
134 }
else if constexpr (is_chars_type<T>()) {
136 }
else if constexpr (is_standard_type<T>()) {
138 }
else if constexpr (is_standard_ptr_type<T>()) {
140 }
else if constexpr (is_stream_type<T>()) {
147 template <Type TypeT,
typename T>
148 inline static constexpr
SchemaType get_schema_type() noexcept {
155 if constexpr (RealType::kZerocopyTypes) {
161 return RealType::get_schema_type();
165 #ifdef VLINK_HAS_PROTOBUF
169 #ifdef VLINK_HAS_FLATBUFFERS
174 }
else if constexpr (TypeT ==
kCdrType) {
182 template <
typename T>
183 inline static constexpr
SchemaType get_schema_type() noexcept {
184 constexpr
auto kType = get_type_of<T>();
186 return get_schema_type<kType, T>();
189 template <Type TypeT,
typename T>
192 using NamedType = std::remove_pointer_t<RealType>;
197 return "vlink::DynamicData";
200 #ifdef VLINK_HAS_PROTOBUF
202 return std::string(NamedType{}.GetTypeName());
204 #ifdef VLINK_HAS_FLATBUFFERS
206 using TableType =
typename RealType::TableType;
208 return TableType::GetFullyQualifiedName();
210 std::string name = NameDetector::get<TableType>().data();
215 using TableType =
typename RealType::Table;
217 return TableType::GetFullyQualifiedName();
219 std::string name = NameDetector::get<TableType>().data();
224 using TableType = std::remove_pointer_t<T>;
226 return TableType::GetFullyQualifiedName();
228 std::string name = NameDetector::get<TableType>().data();
233 #ifdef VLINK_HAS_ROS2
234 }
else if constexpr (TypeT ==
kCdrType && is_ros2_msg_type<RealType>()) {
235 const auto* callbacks = get_ros2_msg_callbacks<RealType>();
237 if VUNLIKELY (!callbacks || !callbacks->message_namespace_ || !callbacks->message_name_) {
241 std::string name(callbacks->message_namespace_);
242 name.append(
"::dds_::").append(callbacks->message_name_).append(
"_");
248 }
else if constexpr (NameDetector::is_support<NamedType>()) {
249 return NameDetector::get<NamedType>().data();
255 template <
typename T>
257 constexpr
auto kType = get_type_of<T>();
259 return get_serialized_type<kType, T>();
262 template <Type TypeT,
typename T>
271 }
else if constexpr (TypeT ==
kCdrType) {
273 #ifdef VLINK_HAS_ROS2
274 if constexpr (is_ros2_msg_type<RealType>()) {
275 const auto* callbacks = get_ros2_msg_callbacks<RealType>();
277 if VUNLIKELY (!callbacks || !callbacks->get_serialized_size) {
281 const size_t payload_size = callbacks->get_serialized_size(&
deref(src));
282 return payload_size <= std::numeric_limits<uint32_t>::max() - 4U ? payload_size + 4U : 0U;
286 const size_t payload_size = RealType::getCdrSerializedSize(
deref(src));
287 return payload_size <= std::numeric_limits<uint32_t>::max() - 4U ? payload_size + 4U : 0U;
288 #if FASTCDR_VERSION_MAJOR >= 2
290 eprosima::fastcdr::CdrSizeCalculator calculator(eprosima::fastcdr::CdrVersion::XCDRv1);
291 size_t current_alignment = 0;
292 const size_t payload_size = calculator.calculate_serialized_size(
deref(src), current_alignment);
293 return payload_size <= std::numeric_limits<uint32_t>::max() - 4U ? payload_size + 4U : 0U;
299 #ifdef VLINK_HAS_ROS2
302 }
catch (
const std::exception&) {
306 #ifdef VLINK_HAS_PROTOBUF
309 return deref(src).ByteSizeLong();
311 return deref(src).ByteSize();
315 return src->ByteSizeLong();
317 return src->ByteSize();
322 return deref(src).get_serialized_size();
331 template <
typename T>
333 constexpr
auto kType = get_type_of<T>();
335 return get_serialized_size<kType>(src);
338 template <Type TypeT,
typename T>
340 [[maybe_unused]] uint8_t offset) {
346 using ReturnT = decltype(
deref(src) >> des);
348 if constexpr (std::is_convertible_v<ReturnT, bool>) {
350 VLOG_T(
"Serializer: Dynamic serialize failed.");
357 }
else if constexpr (TypeT ==
kCdrType) {
358 const size_t target_size = get_serialized_size<TypeT>(src);
360 if VUNLIKELY (target_size < 4U || target_size > std::numeric_limits<uint32_t>::max()) {
361 VLOG_W(
"Serializer: FastBuffer serialized size is invalid.");
376 eprosima::fastcdr::FastBuffer buffer(
reinterpret_cast<char*
>(des.
data()), des.
size());
377 #if FASTCDR_VERSION_MAJOR >= 2
379 ? eprosima::fastcdr::CdrVersion::DDS_CDR
380 : eprosima::fastcdr::CdrVersion::XCDRv1;
381 eprosima::fastcdr::Cdr cdr(buffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, kCdrVersion);
382 if constexpr (kCdrVersion == eprosima::fastcdr::CdrVersion::XCDRv1) {
383 cdr.set_encoding_flag(eprosima::fastcdr::EncodingAlgorithmFlag::PLAIN_CDR);
386 eprosima::fastcdr::Cdr cdr(buffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, eprosima::fastcdr::Cdr::DDS_CDR);
388 cdr.serialize_encapsulation();
390 #ifdef VLINK_HAS_ROS2
391 if constexpr (is_ros2_msg_type<RealType>()) {
392 const auto* callbacks = get_ros2_msg_callbacks<RealType>();
394 if VUNLIKELY (!callbacks || !callbacks->cdr_serialize || !callbacks->cdr_serialize(&
deref(src), cdr)) {
400 deref(src).serialize(cdr);
401 #if FASTCDR_VERSION_MAJOR >= 2
406 #ifdef VLINK_HAS_ROS2
409 }
catch (
const eprosima::fastcdr::exception::Exception& e) {
410 VLOG_T(
"Serializer: FastBuffer serialize failed: ", e.what(),
".");
412 }
catch (
const std::exception& e) {
413 VLOG_T(
"Serializer: CDR serialize failed: ", e.what(),
".");
417 #ifdef VLINK_HAS_PROTOBUF
421 size_t target_size =
deref(src).ByteSizeLong();
427 size_t target_size =
deref(src).ByteSize();
436 VLOG_T(
"Serializer: Protobuf serialize failed.");
442 size_t target_size = src->ByteSizeLong();
448 size_t target_size = src->ByteSize();
457 VLOG_T(
"Serializer: Protobuf ptr serialize failed.");
461 #ifdef VLINK_HAS_FLATBUFFERS
463 flatbuffers::FlatBufferBuilder fbb;
464 fbb.Finish(RealType::TableType::Pack(fbb, &
deref(src)));
466 if (des.
is_loaned() && des.
size() >= fbb.GetSize() + offset) {
467 std::memcpy(des.
data() + offset, fbb.GetBufferPointer(), fbb.GetSize());
476 auto& mutable_src =
const_cast<T&
>(src);
477 mutable_src.fbb_.Finish(mutable_src.Finish());
478 des =
Bytes::deep_copy(mutable_src.fbb_.GetBufferPointer(), mutable_src.fbb_.GetSize(), offset);
483 using ReturnT = decltype(
const_cast<RealType&
>(
deref(src)) >> des);
485 if constexpr (std::is_convertible_v<ReturnT, bool>) {
487 VLOG_T(
"Serializer: Custom serialize failed.");
491 const_cast<RealType&
>(
deref(src)) >> des;
502 if constexpr (std::is_array_v<T>) {
503 constexpr
size_t kExtent = std::extent_v<T>;
504 const auto* terminator =
static_cast<const char*
>(std::memchr(src,
'\0', kExtent));
507 VLOG_T(
"Serializer: Chars array is not null-terminated.");
511 size =
static_cast<size_t>(terminator - src);
514 VLOG_T(
"Serializer: Chars source is null.");
518 size = std::strlen(src);
521 des =
Bytes::deep_copy(
reinterpret_cast<const uint8_t*
>(src), size, offset);
523 std::stringstream ss;
525 const std::string str = ss.str();
526 des =
Bytes::deep_copy(
reinterpret_cast<const uint8_t*
>(str.data()), str.size(), offset);
528 const auto* src_ptr =
reinterpret_cast<const uint8_t*
>(&
deref(src));
532 VLOG_T(
"Serializer: Standard ptr does not support offset.");
536 const auto* src_ptr =
reinterpret_cast<const uint8_t*
>(src);
537 constexpr
size_t kSize =
sizeof(std::remove_pointer_t<T>);
540 std::memcpy(des.
data(), src_ptr, kSize);
552 template <
typename T>
554 constexpr
auto kType = get_type_of<T>();
559 template <Type TypeT,
typename T,
typename LoanCallbackT>
561 LoanCallbackT&& loan) {
562 #ifdef VLINK_HAS_FLATBUFFERS
564 auto& mutable_src =
const_cast<T&
>(src);
565 mutable_src.fbb_.Finish(mutable_src.Finish());
567 const size_t size = mutable_src.fbb_.GetSize();
570 des = std::forward<LoanCallbackT>(loan)(size);
576 std::memcpy(des.
data(), mutable_src.fbb_.GetBufferPointer(), size);
585 const size_t size = get_serialized_size<TypeT>(src);
590 des = std::forward<LoanCallbackT>(loan)(size);
599 auto* loan_data = des.
data();
600 const size_t loan_size = des.
size();
601 const bool ret = serialize<TypeT>(src, des, transport);
609 #ifdef VLINK_HAS_FLATBUFFERS
614 template <Type TypeT,
typename T>
623 using ReturnT = decltype(
deref(des) << src);
625 if constexpr (std::is_convertible_v<ReturnT, bool>) {
627 VLOG_T(
"Serializer: Dynamic deserialize failed.");
633 }
catch (
const std::exception& e) {
634 VLOG_T(
"Serializer: Dynamic deserialize threw: ", e.what(),
".");
638 }
else if constexpr (TypeT ==
kCdrType) {
640 VLOG_T(
"Serializer: FastBuffer payload has no CDR encapsulation.");
645 eprosima::fastcdr::FastBuffer buffer(
reinterpret_cast<char*
>(
const_cast<uint8_t*
>(src.
data())), src.
size());
646 #if FASTCDR_VERSION_MAJOR >= 2
647 eprosima::fastcdr::Cdr cdr(buffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN,
648 eprosima::fastcdr::CdrVersion::DDS_CDR);
650 eprosima::fastcdr::Cdr cdr(buffer, eprosima::fastcdr::Cdr::DEFAULT_ENDIAN, eprosima::fastcdr::Cdr::DDS_CDR);
652 cdr.read_encapsulation();
654 #ifdef VLINK_HAS_ROS2
655 if constexpr (is_ros2_msg_type<RealType>()) {
656 const auto* callbacks = get_ros2_msg_callbacks<RealType>();
658 if VUNLIKELY (!callbacks || !callbacks->cdr_deserialize || !callbacks->cdr_deserialize(cdr, &
deref(des))) {
664 deref(des).deserialize(cdr);
665 #if FASTCDR_VERSION_MAJOR >= 2
670 #ifdef VLINK_HAS_ROS2
673 }
catch (
const eprosima::fastcdr::exception::Exception& e) {
674 VLOG_T(
"Serializer: FastBuffer deserialize failed: ", e.what(),
".");
676 }
catch (
const std::exception& e) {
677 VLOG_T(
"Serializer: CDR deserialize failed: ", e.what(),
".");
681 #ifdef VLINK_HAS_PROTOBUF
685 VLOG_T(
"Serializer: Protobuf deserialize failed.");
694 VLOG_T(
"Serializer: Protobuf ptr deserialize failed.");
701 #ifdef VLINK_HAS_FLATBUFFERS
703 deref(des) = RealType{};
706 flatbuffers::Verifier verifier(src.
data(), src.
size());
708 if VUNLIKELY (!verifier.VerifyBuffer<
typename RealType::TableType>(
nullptr)) {
709 VLOG_T(
"Serializer: Flatbuffers table deserialize failed.");
713 auto target = flatbuffers::GetRoot<typename RealType::TableType>(src.
data());
714 target->UnPackTo(&
deref(des));
717 flatbuffers::Verifier verifier(src.
data(), src.
size());
719 if VUNLIKELY (!verifier.VerifyBuffer<std::remove_pointer_t<T>>(
nullptr)) {
720 VLOG_T(
"Serializer: Flatbuffers ptr verify failed.");
724 des =
const_cast<T
>(flatbuffers::GetRoot<std::remove_pointer_t<T>>(src.
data()));
727 VLOG_T(
"Serializer: Flatbuffers ptr deserialize failed.");
733 using ReturnT = decltype(
deref(des) << src);
735 if constexpr (std::is_convertible_v<ReturnT, bool>) {
737 VLOG_T(
"Serializer: Custom deserialize failed.");
743 }
catch (
const std::exception& e) {
744 VLOG_T(
"Serializer: Custom deserialize threw: ", e.what(),
".");
749 deref(des) = std::string(
reinterpret_cast<const char*
>(src.
data()), src.
size());
751 deref(des) = std::string();
756 VLOG_E(
"Serializer: Chars deserialization is not supported; use std::string.");
759 std::stringstream ss(std::string(
reinterpret_cast<const char*
>(src.
data()), src.
size()));
764 VLOG_T(
"Serializer: Stream deserialize failed.");
771 VLOG_T(
"Serializer: Standard layout deserialize failed.");
775 if VLIKELY (!src.
empty() && src.
size() ==
sizeof(std::remove_pointer_t<T>)) {
776 des =
reinterpret_cast<T
>(
const_cast<uint8_t*
>(src.
data()));
778 VLOG_T(
"Serializer: Standard ptr layout deserialize failed.");
789 template <
typename T>
791 constexpr
auto kType = get_type_of<T>();
795 template <
typename SrcT,
typename DesT>
796 inline bool convert(
const SrcT& src, DesT& des) {
797 static_assert(is_bytes_type<SrcT>() || is_bytes_type<DesT>(),
"SrcT or DesT must be Bytes.");
799 if constexpr (is_bytes_type<SrcT>() && is_bytes_type<DesT>()) {
800 des.shallow_copy(src);
802 }
else if constexpr (is_bytes_type<DesT>()) {
809 template <
typename T>
810 inline constexpr
auto&
deref(
const T& t) noexcept {
812 return *
const_cast<T&
>(t).
get();
814 return const_cast<T&
>(t);
818 template <
typename T>
820 return std::is_same_v<T, Bytes>;
823 template <
typename T>
829 template <
typename T>
834 #ifdef VLINK_HAS_ROS2
835 if constexpr (is_ros2_msg_type<RealType>()) {
848 template <
typename T>
850 #ifdef VLINK_HAS_PROTOBUF
858 template <
typename T>
860 #ifdef VLINK_HAS_PROTOBUF
861 return std::is_pointer_v<T> &&
VLINK_HAS_MEMBER(std::remove_pointer_t<T>, SerializeToArray(0, 0)) &&
868 template <
typename T>
870 #ifdef VLINK_HAS_FLATBUFFERS
872 return std::is_base_of_v<flatbuffers::NativeTable, RealType>;
878 template <
typename T>
880 #ifdef VLINK_HAS_FLATBUFFERS
887 template <
typename T>
889 #ifdef VLINK_HAS_FLATBUFFERS
890 return std::is_pointer_v<T> && std::is_base_of_v<flatbuffers::Table, std::remove_pointer_t<T>>;
896 template <
typename T>
902 template <
typename T>
905 return std::is_same_v<RealType, std::string>;
908 template <
typename T>
910 using DecayedType = std::decay_t<T>;
911 using CharType = std::remove_pointer_t<DecayedType>;
913 return std::is_pointer_v<DecayedType> && std::is_same_v<std::remove_cv_t<CharType>,
char> &&
914 !std::is_volatile_v<CharType>;
917 template <
typename T>
923 template <
typename T>
926 return !std::is_pointer_v<RealType> && std::is_trivial_v<RealType> && std::is_standard_layout_v<RealType>;
929 template <
typename T>
931 return std::is_pointer_v<T> && std::is_trivial_v<std::remove_pointer_t<T>> &&
932 std::is_standard_layout_v<std::remove_pointer_t<T>>;
Fixed-size 128-byte buffer holder with SBO, five ownership modes and integrated codecs.
Definition: bytes.h:120
bool empty() const noexcept
Reports whether the buffer is logically empty.
Definition: bytes.h:868
bool is_loaned() const noexcept
Reports whether the buffer is an iceoryx loan that VLink must not free.
Definition: bytes.h:866
static Bytes shallow_copy(uint8_t *data, size_t size) noexcept
Wraps an external mutable buffer as a non-owning alias.
size_t size() const noexcept
Returns the size of the payload region in bytes.
Definition: bytes.h:856
uint8_t * data() noexcept
Returns a mutable pointer to the start of the payload (post-offset).
Definition: bytes.h:848
static Bytes loan_internal(uint8_t *data, size_t size) noexcept
Wraps an iceoryx-loaned mutable payload as a non-owning, non-aliasing carrier.
static Bytes create(size_t size, uint8_t offset=0) noexcept
Allocates an owned buffer of the requested size with an optional header offset.
static Bytes deep_copy(uint8_t *data, size_t size, uint8_t offset=0) noexcept
Produces an owned copy of an external mutable buffer.
#define VLOG_E(...)
Definition: logger.h:841
#define VLOG_W(...)
Definition: logger.h:839
#define VLOG_T(...)
Definition: logger.h:833
#define VUNLIKELY(...)
Short alias for VLINK_UNLIKELY.
Definition: macros.h:289
#define VLIKELY(...)
Short alias for VLINK_LIKELY.
Definition: macros.h:284
Compile-time codec detection and dispatch for VLink message payloads.
constexpr bool contains_substring(std::string_view sv, std::string_view needle) noexcept
Constexpr substring search.
Definition: helpers.h:431
VLINK_EXPORT void replace_string(std::string &str, const std::string &from, const std::string &to) noexcept
Replaces all occurrences of from in str with to in place.
constexpr std::string_view get() noexcept
Returns the trimmed compile-time identifier for TypeT.
Definition: name_detector.h:603
constexpr bool is_proto_ptr_type() noexcept
Reports whether T is a raw pointer to a Protobuf-like message.
Definition: serializer-inl.h:859
std::string get_serialized_type() noexcept
Returns the serialised type-name string for T with explicit codec tag.
Definition: serializer-inl.h:256
constexpr bool is_dynamic_type() noexcept
Reports whether T is a VLink dynamic data type.
Definition: serializer-inl.h:824
constexpr bool is_chars_type() noexcept
Reports whether T is a pointer or array of non-volatile char.
Definition: serializer-inl.h:909
bool deserialize(const Bytes &src, T &des, [[maybe_unused]] TransportType transport)
Definition: serializer-inl.h:615
constexpr Type get_type_of() noexcept
Resolves the codec Type for T at compile time.
Definition: serializer-inl.h:107
Type
Identifies the codec to use for a given C++ message type.
Definition: serializer.h:154
@ kStandardPtrType
Pointer to trivial standard-layout struct (POD pointer).
Definition: serializer.h:169
@ kCustomType
User-defined codec via operator>>/<<.
Definition: serializer.h:158
@ kDynamicType
VLink dynamic typed data.
Definition: serializer.h:157
@ kFlatTableType
FlatBuffers NativeTable (object API).
Definition: serializer.h:162
@ kCharsType
C string serialisation; deserialise as std::string.
Definition: serializer.h:166
@ kUnknownType
Unsupported type; is_supported() returns false.
Definition: serializer.h:155
@ kBytesType
Bytes – raw byte pass-through.
Definition: serializer.h:156
@ kProtoPtrType
Protobuf-like raw pointer; caller-owned.
Definition: serializer.h:161
@ kStandardType
Trivial standard-layout struct (POD value).
Definition: serializer.h:168
@ kStringType
std::string payload bytes; no text-encoding validation.
Definition: serializer.h:165
@ kFlatBuilderType
FlatBuffers builder (fbb_ + Finish()).
Definition: serializer.h:164
@ kStreamType
Stream-serialisable via std::stringstream.
Definition: serializer.h:167
@ kProtoType
Protobuf-like value.
Definition: serializer.h:160
@ kCdrType
FastDDS CDR via serialize(Cdr&) / deserialize(Cdr&).
Definition: serializer.h:159
@ kFlatPtrType
Pointer to flatbuffers::Table (zero-copy view).
Definition: serializer.h:163
constexpr auto & deref(const T &t) noexcept
Dereferences a value, unwrapping std::shared_ptr when present.
Definition: serializer-inl.h:810
constexpr bool is_supported(Type type) noexcept
Reports whether type identifies a usable codec.
Definition: serializer-inl.h:90
constexpr bool is_custom_type() noexcept
Reports whether T provides a custom operator>>/<< codec.
Definition: serializer-inl.h:897
size_t get_serialized_size(const T &src) noexcept
Returns a serialised-size hint for src with explicit codec tag.
Definition: serializer-inl.h:263
bool serialize_to_transport(const T &src, Bytes &des, TransportType transport, bool use_loan, LoanCallbackT &&loan)
Serialises into transport-provided storage when available.
Definition: serializer-inl.h:560
bool convert(const SrcT &src, DesT &des)
Converts between two types where at least one side is Bytes.
Definition: serializer-inl.h:796
constexpr bool is_cdr_type() noexcept
Reports whether T is a FastDDS CDR-serialisable type.
Definition: serializer-inl.h:830
constexpr bool is_proto_type() noexcept
Reports whether T is a Protobuf-like message value type.
Definition: serializer-inl.h:849
std::string get_serialized_type() noexcept
Returns the serialised type-name string for T with explicit codec tag.
Definition: serializer-inl.h:190
bool serialize(const T &src, Bytes &des, [[maybe_unused]] TransportType transport, [[maybe_unused]] uint8_t offset)
Definition: serializer-inl.h:339
constexpr bool is_flat_ptr_type() noexcept
Reports whether T is a raw pointer to a flatbuffers::Table.
Definition: serializer-inl.h:888
constexpr bool is_flat_builder_type() noexcept
Reports whether T is a FlatBuffers builder type.
Definition: serializer-inl.h:879
constexpr bool is_standard_ptr_type() noexcept
Reports whether T is a pointer to a trivial standard-layout type.
Definition: serializer-inl.h:930
constexpr bool is_standard_type() noexcept
Reports whether T is a trivial standard-layout value (POD).
Definition: serializer-inl.h:924
constexpr bool is_flat_table_type() noexcept
Reports whether T is a FlatBuffers NativeTable type.
Definition: serializer-inl.h:869
constexpr bool is_string_type() noexcept
Reports whether T is std::string after unwrapping shared_ptr.
Definition: serializer-inl.h:903
constexpr bool is_bytes_type() noexcept
Reports whether T is exactly Bytes.
Definition: serializer-inl.h:819
constexpr bool is_stream_type() noexcept
Reports whether T supports bidirectional std::stringstream streaming.
Definition: serializer-inl.h:918
SchemaType
Coarse runtime schema family used by discovery, bag metadata and proxy routing.
Definition: types.h:203
@ kZeroCopy
Decode through the VLink zero-copy structs.
@ kProtobuf
Decode through the Protocol Buffers stack.
@ kFlatbuffers
Decode through the FlatBuffers stack.
@ kRaw
Treat the payload as opaque bytes.
@ kCdr
Native DDS CDR payload including its encapsulation header.
TransportType
Enumeration of every transport backend recognised by VLink.
Definition: types.h:126
@ kUnknown
Unknown or unsupported transport.
Type trait that always derives from std::false_type for any T.
Definition: traits.h:103
Detects whether T is (or derives from) a std::shared_ptr specialisation.
Definition: traits.h:193
Detects whether OT supports stream insertion (<<) and extraction (>>) with T.
Definition: traits.h:167
T Type
Resolved type after optional shared_ptr removal.
Definition: traits.h:211
#define VLINK_HAS_MEMBER(T, member)
Macro Definitions.
Definition: traits.h:316