VLink 2.0.0
A high-performance communication middleware
Loading...
Searching...
No Matches
serializer-inl.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2026 by Thun Lu. All rights reserved.
3 * Author: Thun Lu <thun.lu@zohomail.cn>
4 * Repo: https://github.com/thun-res/vlink
5 * _ __ __ _ __
6 * | | / / / / (_) ____ / /__
7 * | | / / / / / / / __ \ / //_/
8 * | |/ / / /___ / / / / / / / ,<
9 * |___/ /_____/ /_/ /_/ /_/ /_/|_|
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23
24#pragma once
25
26#include <cstring>
27#include <sstream>
28#include <string>
29#include <utility>
30
31#include "../base/helpers.h"
32#include "../base/logger.h"
34#include "../base/traits.h"
35#include "../serializer.h"
36
37#ifndef VLINK_FASTDDS_IDL_PREFIX
38#define VLINK_FASTDDS_IDL_PREFIX "dds::"
39#endif
40
41// NOLINTBEGIN
42
43// fastcdr
44#if __has_include(<fastcdr/Cdr.h>)
45[[maybe_unused]] static constexpr bool kRtHasFastcdr = true;
46
47#include <fastcdr/Cdr.h>
48#else
49#define FASTCDR_VERSION_MAJOR 1
50[[maybe_unused]] static constexpr bool kRtHasFastcdr = false;
51
53
55 public:
56 explicit FastBuffer(char*, size_t) {}
57};
58
60 public:
61 enum Type {
63 };
64};
65
66class Cdr {
67 public:
72
73 explicit Cdr(FastBuffer&, int, int) {}
74};
75} // namespace eprosima::fastcdr
76#endif
77
78// protobuf
79#if __has_include(<google/protobuf/message_lite.h>)
80[[maybe_unused]] static constexpr bool kRtHasProtobuf = true;
81
82#if __has_include(<google/protobuf/stubs/common.h>)
83#include <google/protobuf/stubs/common.h>
84#endif
85
86#include <google/protobuf/message_lite.h>
87#else
88
89#ifndef GOOGLE_PROTOBUF_VERSION
90#define GOOGLE_PROTOBUF_VERSION 0
91#endif
92
93[[maybe_unused]] static constexpr bool kRtHasProtobuf = false;
94
96
97struct Arena {
98 template <typename T>
99 [[maybe_unused]] static T* Create(Arena*) {
100 return nullptr;
101 }
102};
103
104} // namespace google::protobuf
105
106#endif
107
108// flatbuffers
109#if __has_include(<flatbuffers/flatbuffers.h>)
110[[maybe_unused]] static constexpr bool kRtHasFlatbuffers = true;
111
112#include <flatbuffers/flatbuffers.h>
113#else
114[[maybe_unused]] static constexpr bool kRtHasFlatbuffers = false;
115
116namespace flatbuffers {
117
118template <typename ReturnT, typename T>
119[[maybe_unused]] static const ReturnT* GetRoot(const T&) {
120 return nullptr;
121}
122
124 size_t GetSize() const { return 0; }
125
126 const uint8_t* GetBufferPointer() const { return nullptr; }
127
128 const uint8_t* GetCurrentBufferPointer() const { return nullptr; }
129
130 void PushBytes(const uint8_t*, size_t) {}
131
132 void Finish() const {}
133};
134
135struct Table {};
136
137struct NativeTable {};
138
139struct Verifier {
140 Verifier(const uint8_t*, size_t) {}
141
142 template <typename T>
143 bool VerifyBuffer(void*) {
144 return false;
145 }
146};
147
148} // namespace flatbuffers
149#endif
150
151// NOLINTEND
152
153namespace vlink {
154
155namespace Serializer { // NOLINT(readability-identifier-naming)
156
157[[maybe_unused]] inline constexpr bool is_supported(Type type) noexcept { return type != kUnknownType; }
158
159template <typename T>
160inline constexpr Type get_type_of() noexcept {
161 if constexpr (is_bytes_type<T>()) {
162 return kBytesType;
163 } else if constexpr (is_dynamic_type<T>()) {
164 return kDynamicType;
165 } else if constexpr (is_cdr_type<T>()) {
166 return kCdrType;
167 } else if constexpr (is_proto_type<T>()) {
168 return kProtoType;
169 } else if constexpr (is_proto_ptr_type<T>()) {
170 return kProtoPtrType;
171 } else if constexpr (is_flat_table_type<T>()) {
172 return kFlatTableType;
173 } else if constexpr (is_flat_ptr_type<T>()) {
174 return kFlatPtrType;
175 } else if constexpr (is_flat_builder_type<T>()) {
176 return kFlatBuilderType;
177 } else if constexpr (is_custom_type<T>()) {
178 return kCustomType;
179 } else if constexpr (is_string_type<T>()) {
180 return kStringType;
181 } else if constexpr (is_chars_type<T>()) {
182 return kCharsType;
183 } else if constexpr (is_standard_type<T>()) {
184 return kStandardType;
185 } else if constexpr (is_standard_ptr_type<T>()) {
186 return kStandardPtrType;
187 } else if constexpr (is_stream_type<T>()) {
188 return kStreamType;
189 } else {
190 return kUnknownType;
191 }
192}
193
194template <Type TypeT, typename T>
195inline static constexpr SchemaType get_schema_type() noexcept {
196 using RealType = typename Traits::RemoveSharedPtr<T>::Type;
197
198 if constexpr (TypeT == kBytesType) {
199 return SchemaType::kRaw;
200 } else if constexpr (TypeT == kCustomType) {
201 if constexpr (VLINK_HAS_MEMBER(RealType, kZerocopyTypes)) {
202 if constexpr (RealType::kZerocopyTypes) {
204 } else {
205 return SchemaType::kRaw;
206 }
207 } else if constexpr (VLINK_HAS_MEMBER(RealType, get_schema_type())) {
208 return RealType::get_schema_type();
209 } else {
210 return SchemaType::kRaw;
211 }
212 } else if constexpr (TypeT == kProtoType || TypeT == kProtoPtrType) {
214 } else if constexpr (TypeT == kFlatTableType || TypeT == kFlatPtrType || TypeT == kFlatBuilderType) {
216 } else {
217 return SchemaType::kRaw;
218 }
219}
220
221template <typename T>
222inline static constexpr SchemaType get_schema_type() noexcept {
223 constexpr auto kType = get_type_of<T>();
224
225 return get_schema_type<kType, T>();
226}
227
228template <Type TypeT, typename T>
229inline std::string get_serialized_type() noexcept {
230 using RealType = typename Traits::RemoveSharedPtr<T>::Type;
231 using NamedType = std::remove_pointer_t<RealType>;
232
233 if constexpr (TypeT == kBytesType) {
234 return "";
235 } else if constexpr (TypeT == kDynamicType) {
236 return "vlink::DynamicData";
237 } else if constexpr (TypeT == kCustomType && VLINK_HAS_MEMBER(RealType, get_serialized_type())) {
238 return RealType::get_serialized_type();
239 } else if constexpr (TypeT == kProtoType) {
240#if GOOGLE_PROTOBUF_VERSION >= 6030000
241 return std::string(RealType{}.GetTypeName());
242#else
243 return RealType{}.GetTypeName();
244#endif
245 } else if constexpr (TypeT == kProtoPtrType) {
246#if GOOGLE_PROTOBUF_VERSION >= 6030000
247 return std::string(std::remove_pointer_t<T>().GetTypeName());
248#else
249 return std::remove_pointer_t<T>().GetTypeName();
250#endif
251 } else if constexpr (TypeT == kFlatTableType) {
252 using TableType = typename RealType::TableType;
253 if constexpr (VLINK_HAS_MEMBER(TableType, GetFullyQualifiedName)) {
254 return TableType::GetFullyQualifiedName();
255 } else {
256 std::string name = NameDetector::get<TableType>().data();
257 Helpers::replace_string(name, "::", ".");
258 return name;
259 }
260 } else if constexpr (TypeT == kFlatBuilderType) {
261 using TableType = typename RealType::Table;
262 if constexpr (VLINK_HAS_MEMBER(TableType, GetFullyQualifiedName)) {
263 return TableType::GetFullyQualifiedName();
264 } else {
265 std::string name = NameDetector::get<TableType>().data();
266 Helpers::replace_string(name, "::", ".");
267 return name;
268 }
269 } else if constexpr (TypeT == kFlatPtrType) {
270 using TableType = std::remove_pointer_t<T>;
271 if constexpr (VLINK_HAS_MEMBER(TableType, GetFullyQualifiedName)) {
272 return TableType::GetFullyQualifiedName();
273 } else {
274 std::string name = NameDetector::get<TableType>().data();
275 Helpers::replace_string(name, "::", ".");
276 return name;
277 }
278 } else if constexpr (TypeT == kStringType || TypeT == kCharsType) {
279 return "string";
280 } else if constexpr (NameDetector::is_support<NamedType>()) {
281 return NameDetector::get<NamedType>().data();
282 } else {
283 return "";
284 }
285}
286
287template <typename T>
288inline std::string get_serialized_type() noexcept {
289 constexpr auto kType = get_type_of<T>();
290
292}
293
294template <Type TypeT, typename T>
295inline size_t get_serialized_size(const T& src) noexcept {
296 using RealType = typename Traits::RemoveSharedPtr<T>::Type;
297
298 if constexpr (TypeT == kBytesType) {
299 return 0;
300 } else if constexpr (TypeT == kDynamicType) {
301 return 0;
302 } else if constexpr (TypeT == kCdrType) {
303 if constexpr (VLINK_HAS_MEMBER(RealType, getCdrSerializedSize(deref(src)))) {
304 return RealType::getCdrSerializedSize(deref(src));
305 } else {
306 return 0;
307 }
308 } else if constexpr (TypeT == kProtoType) {
309 if constexpr (VLINK_HAS_MEMBER(RealType, ByteSizeLong())) {
310 return deref(src).ByteSizeLong();
311 } else {
312 return deref(src).ByteSize();
313 }
314 } else if constexpr (TypeT == kProtoPtrType) {
315 if constexpr (VLINK_HAS_MEMBER(std::remove_pointer_t<T>, ByteSizeLong())) {
316 return src->ByteSizeLong();
317 } else {
318 return src->ByteSize();
319 }
320 } else if constexpr (TypeT == kFlatTableType) {
321 return 0;
322 } else if constexpr (TypeT == kFlatBuilderType) {
323 return src.fbb_.GetSize();
324 } else if constexpr (TypeT == kFlatPtrType) {
325 return 0;
326 } else if constexpr (TypeT == kCustomType) {
327 if constexpr (VLINK_HAS_MEMBER(RealType, get_serialized_size())) {
328 return deref(src).get_serialized_size();
329 } else {
330 return 0;
331 }
332 } else if constexpr (TypeT == kStringType) {
333 return 0;
334 } else if constexpr (TypeT == kCharsType) {
335 return 0;
336 } else if constexpr (TypeT == kStreamType) {
337 return 0;
338 } else if constexpr (TypeT == kStandardType) {
339 return 0;
340 } else if constexpr (TypeT == kStandardPtrType) {
341 return 0;
342 } else {
343 return 0;
344 }
345}
346
347template <typename T>
348inline size_t get_serialized_size(const T& src) noexcept {
349 constexpr auto kType = get_type_of<T>();
350
351 return get_serialized_size<kType>(src);
352}
353
354template <Type TypeT, typename T>
355inline bool serialize(const T& src, Bytes& des, [[maybe_unused]] TransportType transport,
356 [[maybe_unused]] uint8_t offset) {
357 using RealType = typename Traits::RemoveSharedPtr<T>::Type;
358
359 if constexpr (TypeT == kBytesType) {
360 des = Bytes::deep_copy(src.data(), src.size(), offset);
361 } else if constexpr (TypeT == kDynamicType) {
362 deref(src) >> des;
363 } else if constexpr (TypeT == kCdrType) {
364 if (transport == TransportType::kDds) {
365 des = Bytes::shallow_copy_ptr(&const_cast<RealType&>(deref(src)));
366 } else {
367 if (!des.is_loaned()) {
368 if constexpr (VLINK_HAS_MEMBER(RealType, getCdrSerializedSize(deref(src)))) {
369 size_t target_size = RealType::getCdrSerializedSize(deref(src));
370
371 if (des.size() != target_size) {
372 des = Bytes::create(target_size, offset);
373 }
374 } else {
375 VLOG_W("Serializer: FastBuffer serialize is not supported without dds(v3).");
376 return false;
377 }
378 }
379
380 eprosima::fastcdr::FastBuffer buffer(reinterpret_cast<char*>(des.data()), des.size());
381#if FASTCDR_VERSION_MAJOR >= 2
384#else
386#endif
387 deref(src).serialize(cdr);
388 }
389 } else if constexpr (TypeT == kProtoType) {
390 if (!des.is_loaned()) {
391 if constexpr (VLINK_HAS_MEMBER(RealType, ByteSizeLong())) {
392 size_t target_size = deref(src).ByteSizeLong();
393
394 if (des.size() != target_size) {
395 des = Bytes::create(target_size, offset);
396 }
397 } else {
398 size_t target_size = deref(src).ByteSize();
399
400 if (des.size() != target_size) {
401 des = Bytes::create(target_size, offset);
402 }
403 }
404 }
405
406 if VUNLIKELY (!deref(src).SerializeToArray(des.data(), des.size())) {
407 VLOG_T("Serializer: Protobuf serialize failed.");
408 return false;
409 }
410 } else if constexpr (TypeT == kProtoPtrType) {
411 if (!des.is_loaned()) {
412 if constexpr (VLINK_HAS_MEMBER(std::remove_pointer_t<T>, ByteSizeLong())) {
413 size_t target_size = src->ByteSizeLong();
414
415 if (des.size() != target_size) {
416 des = Bytes::create(target_size, offset);
417 }
418 } else {
419 size_t target_size = src->ByteSize();
420
421 if (des.size() != target_size) {
422 des = Bytes::create(target_size, offset);
423 }
424 }
425 }
426
427 if VUNLIKELY (!src->SerializeToArray(des.data(), des.size())) {
428 VLOG_T("Serializer: Protobuf ptr serialize failed.");
429 return false;
430 }
431 } else if constexpr (TypeT == kFlatTableType) {
433 fbb.Finish(T::TableType::Pack(fbb, &deref(src)));
434 des = Bytes::deep_copy(fbb.GetBufferPointer(), fbb.GetSize(), offset);
435 } else if constexpr (TypeT == kFlatBuilderType) {
436 src.fbb_.Finish(const_cast<T&>(src).Finish());
437
438 if (des.is_loaned()) {
439 des = Bytes::shallow_copy(src.fbb_.GetBufferPointer(), src.fbb_.GetSize());
440 } else {
441 des = Bytes::deep_copy(src.fbb_.GetBufferPointer(), src.fbb_.GetSize(), offset);
442 }
443 } else if constexpr (TypeT == kFlatPtrType) {
444 static_assert(Traits::ExpectFalse<T>(), "Not support flat ptr type.");
445 } else if constexpr (TypeT == kCustomType) {
446 const_cast<RealType&>(deref(src)) >> des;
447 if (offset > 0) {
448 des = Bytes::deep_copy(des.data(), des.size(), offset);
449 }
450 } else if constexpr (TypeT == kStringType) {
451 des = Bytes::deep_copy(reinterpret_cast<const uint8_t*>(deref(src).data()), deref(src).size(), offset);
452 } else if constexpr (TypeT == kCharsType) {
453 des = Bytes::deep_copy(reinterpret_cast<const uint8_t*>(src), std::strlen(src), offset);
454 } else if constexpr (TypeT == kStreamType) {
455 thread_local std::stringstream ss;
456 ss.clear();
457 ss.str("");
458
459 ss << deref(src);
460 const std::string& str = ss.str();
461 des = Bytes::deep_copy(reinterpret_cast<const uint8_t*>(str.data()), str.size(), offset);
462 } else if constexpr (TypeT == kStandardType) {
463 const auto* src_ptr = reinterpret_cast<const uint8_t*>(&deref(src));
464 des = Bytes::deep_copy(src_ptr, sizeof(RealType), offset);
465 } else if constexpr (TypeT == kStandardPtrType) {
466 if VUNLIKELY (offset > 0) {
467 VLOG_T("Serializer: Standard ptr does not support offset.");
468 return false;
469 }
470 const auto* src_ptr = reinterpret_cast<const uint8_t*>(src);
471 des = Bytes::shallow_copy(src_ptr, sizeof(std::remove_pointer_t<T>));
472 } else {
473 static_assert(Traits::ExpectFalse<T>(), "Not support serialize.");
474 return false;
475 }
476
477 return true;
478}
479
480template <typename T>
481inline bool serialize(const T& src, Bytes& des) {
482 constexpr auto kType = get_type_of<T>();
483
485}
486
487template <Type TypeT, typename T>
488inline bool deserialize(const Bytes& src, T& des, [[maybe_unused]] TransportType transport) {
489 using RealType = typename Traits::RemoveSharedPtr<T>::Type;
490
491 if constexpr (TypeT == kBytesType) {
492 des = src;
493 return true;
494 } else if constexpr (TypeT == kDynamicType) {
495 deref(des) << src;
496 } else if constexpr (TypeT == kCdrType) {
497 if (transport == TransportType::kDds) {
498 if VUNLIKELY (!src.is_ptr()) {
499 VLOG_T("Serializer: Fastcdr src is not ptr.");
500 return false;
501 }
502
503 deref(des) = *src.to_ptr<RealType>();
504 } else {
505 if constexpr (VLINK_HAS_MEMBER(RealType, getCdrSerializedSize(deref(des)))) {
506 eprosima::fastcdr::FastBuffer buffer(reinterpret_cast<char*>(const_cast<uint8_t*>(src.data())), src.size());
507#if FASTCDR_VERSION_MAJOR >= 2
510#else
512#endif
513 deref(des).deserialize(cdr);
514 } else {
515 VLOG_W("Serializer: FastBuffer deserialize is not supported without dds(v3).");
516 return false;
517 }
518 }
519 } else if constexpr (TypeT == kProtoType) {
520 if (!src.empty()) {
521 if VUNLIKELY (!deref(des).ParseFromArray(src.data(), src.size())) {
522 VLOG_T("Serializer: Protobuf deserialize failed.");
523 return false;
524 }
525 } else {
526 deref(des).Clear();
527 }
528 } else if constexpr (TypeT == kProtoPtrType) {
529 if (!src.empty()) {
530 if VUNLIKELY (!des->ParseFromArray(src.data(), src.size())) {
531 VLOG_T("Serializer: Protobuf ptr deserialize failed.");
532 return false;
533 }
534 } else {
535 des->Clear();
536 }
537 } else if constexpr (TypeT == kFlatTableType) {
538 deref(des) = RealType{};
539
540 if VLIKELY (!src.empty()) {
541 flatbuffers::Verifier verifier(src.data(), src.size());
542
543 if VUNLIKELY (!verifier.VerifyBuffer<typename T::TableType>(nullptr)) {
544 VLOG_T("Serializer: Flatbuffers table deserialize failed.");
545 return false;
546 }
547
548 auto target = flatbuffers::GetRoot<typename RealType::TableType>(src.data());
549 target->UnPackTo(&deref(des));
550 }
551 } else if constexpr (TypeT == kFlatPtrType) {
552 flatbuffers::Verifier verifier(src.data(), src.size());
553
554 if VUNLIKELY (!verifier.VerifyBuffer<std::remove_pointer_t<T>>(nullptr)) {
555 VLOG_T("Serializer: Flatbuffers ptr verify failed.");
556 return false;
557 }
558
559 des = const_cast<T>(flatbuffers::GetRoot<std::remove_pointer_t<T>>(src.data()));
560
561 if VUNLIKELY (!des) {
562 VLOG_T("Serializer: Flatbuffers ptr deserialize failed.");
563 return false;
564 }
565 } else if constexpr (TypeT == kCustomType) {
566 deref(des) << src;
567 } else if constexpr (TypeT == kStringType) {
568 if VLIKELY (!src.empty()) {
569 deref(des) = std::string(reinterpret_cast<const char*>(src.data()), src.size());
570 } else {
571 deref(des) = std::string();
572 }
573 } else if constexpr (TypeT == kCharsType) {
574 if VLIKELY (!src.empty()) {
575 des = reinterpret_cast<const char*>(src.data());
576 } else {
577 des = "";
578 }
579 } else if constexpr (TypeT == kStreamType) {
580 thread_local std::stringstream ss;
581 ss.clear();
582 ss.str(std::string(reinterpret_cast<const char*>(src.data()), src.size()));
583
584 ss >> deref(des);
585 } else if constexpr (TypeT == kStandardType) {
586 if VLIKELY (!src.empty() && src.size() == sizeof(RealType)) {
587 std::memcpy(&deref(des), src.data(), src.size());
588 } else {
589 VLOG_T("Serializer: Standard layout deserialize failed.");
590 return false;
591 }
592 } else if constexpr (TypeT == kStandardPtrType) {
593 if VLIKELY (!src.empty() && src.size() == sizeof(std::remove_pointer_t<T>)) {
594 des = reinterpret_cast<T>(const_cast<uint8_t*>(src.data()));
595 } else {
596 VLOG_T("Serializer: Standard ptr layout deserialize failed.");
597 return false;
598 }
599 } else {
600 static_assert(Traits::ExpectFalse<T>(), "Not support deserialize.");
601 return false;
602 }
603
604 return true;
605}
606
607template <typename T>
608inline bool deserialize(const Bytes& src, T& des) {
609 constexpr auto kType = get_type_of<T>();
611}
612
613template <typename SrcT, typename DesT>
614inline bool convert(const SrcT& src, DesT& des) {
615 static_assert(is_bytes_type<SrcT>() || is_bytes_type<DesT>(), "SrcT or DesT must be Bytes.");
616
617 if constexpr (is_bytes_type<SrcT>() && is_bytes_type<DesT>()) {
618 des.shallow_copy(src);
619 return true;
620 } else if constexpr (is_bytes_type<DesT>()) {
621 return serialize(src, des);
622 } else {
623 return deserialize(src, des);
624 }
625}
626
627template <typename T>
628inline constexpr auto& deref(const T& t) noexcept {
629 if constexpr (Traits::IsSharedPtr<T>()) {
630 return *const_cast<T&>(t).get();
631 } else {
632 return const_cast<T&>(t);
633 }
634}
635
636template <typename T>
637inline constexpr bool is_bytes_type() noexcept {
638 return std::is_same_v<T, Bytes>;
639}
640
641template <typename T>
642inline constexpr bool is_dynamic_type() noexcept {
643 using RealType = typename Traits::RemoveSharedPtr<T>::Type;
644 return VLINK_HAS_MEMBER(RealType, is_vlink_dynamic_data());
645}
646
647template <typename T>
648inline constexpr bool is_cdr_type() noexcept {
649 using RealType = typename Traits::RemoveSharedPtr<T>::Type;
650
651 return kRtHasFastcdr && ((VLINK_HAS_MEMBER(RealType, serialize(std::declval<eprosima::fastcdr::Cdr&>())) &&
652 VLINK_HAS_MEMBER(RealType, deserialize(std::declval<eprosima::fastcdr::Cdr&>()))) ||
653 Helpers::contains_substring(NameDetector::get<RealType>(), VLINK_FASTDDS_IDL_PREFIX));
654}
655
656template <typename T>
657inline constexpr bool is_proto_type() noexcept {
658 using RealType = typename Traits::RemoveSharedPtr<T>::Type;
659 return kRtHasProtobuf && VLINK_HAS_MEMBER(RealType, SerializeToArray(0, 0)) &&
660 VLINK_HAS_MEMBER(RealType, ParseFromArray(0, 0));
661}
662
663template <typename T>
664inline constexpr bool is_proto_ptr_type() noexcept {
665 return kRtHasProtobuf && std::is_pointer_v<T> && VLINK_HAS_MEMBER(std::remove_pointer_t<T>, SerializeToArray(0, 0)) &&
666 VLINK_HAS_MEMBER(std::remove_pointer_t<T>, ParseFromArray(0, 0));
667}
668
669template <typename T>
670inline constexpr bool is_flat_table_type() noexcept {
671 using RealType = typename Traits::RemoveSharedPtr<T>::Type;
672 return kRtHasFlatbuffers && std::is_base_of_v<flatbuffers::NativeTable, RealType>;
673}
674
675template <typename T>
676inline constexpr bool is_flat_builder_type() noexcept {
677 return kRtHasFlatbuffers && VLINK_HAS_MEMBER(T, fbb_) && VLINK_HAS_MEMBER(T, Finish());
678}
679
680template <typename T>
681inline constexpr bool is_flat_ptr_type() noexcept {
682 return kRtHasFlatbuffers && std::is_pointer_v<T> && std::is_base_of_v<flatbuffers::Table, std::remove_pointer_t<T>>;
683}
684
685template <typename T>
686inline constexpr bool is_custom_type() noexcept {
687 using RealType = typename Traits::RemoveSharedPtr<T>::Type;
689}
690
691template <typename T>
692inline constexpr bool is_string_type() noexcept {
693 using RealType = typename Traits::RemoveSharedPtr<T>::Type;
694 return std::is_same_v<RealType, std::string>;
695}
696
697template <typename T>
698inline constexpr bool is_chars_type() noexcept {
699 return !std::is_same_v<T, std::string> && std::is_constructible_v<std::string, T>;
700}
701
702template <typename T>
703inline constexpr bool is_stream_type() noexcept {
704 using RealType = typename Traits::RemoveSharedPtr<T>::Type;
705 return !std::is_pointer_v<RealType> && Traits::Operatorable<std::stringstream, std::decay_t<RealType>>();
706}
707
708template <typename T>
709inline constexpr bool is_standard_type() noexcept {
710 using RealType = typename Traits::RemoveSharedPtr<T>::Type;
711 return !std::is_pointer_v<RealType> && std::is_trivial_v<RealType> && std::is_standard_layout_v<RealType>;
712}
713
714template <typename T>
715inline constexpr bool is_standard_ptr_type() noexcept {
716 return std::is_pointer_v<T> && std::is_trivial_v<std::remove_pointer_t<T>> &&
717 std::is_standard_layout_v<std::remove_pointer_t<T>>;
718}
719
720} // namespace Serializer
721
722} // namespace vlink
Definition serializer-inl.h:59
Type
Definition serializer-inl.h:61
@ DDS_CDR
Definition serializer-inl.h:62
Definition serializer-inl.h:66
Type
Definition serializer-inl.h:68
@ DEFAULT_ENDIAN
Definition serializer-inl.h:70
@ DDS_CDR
Definition serializer-inl.h:69
Cdr(FastBuffer &, int, int)
Definition serializer-inl.h:73
Definition serializer-inl.h:54
FastBuffer(char *, size_t)
Definition serializer-inl.h:56
String, number, hash and formatting utility functions.
Global singleton logger with three output styles and pluggable backends.
#define VLOG_W(...)
Definition logger.h:852
#define VLOG_T(...)
Definition logger.h:846
#define VUNLIKELY(...)
Shorthand alias for VLINK_UNLIKELY. Hints that the expression is unlikely true.
Definition macros.h:302
#define VLIKELY(...)
Shorthand alias for VLINK_LIKELY. Hints that the expression is likely true.
Definition macros.h:297
Compile-time type-name and enum-name detection utilities.
Compile-time type detection and codec dispatch for VLink messages.
Definition serializer-inl.h:52
Definition serializer-inl.h:116
Definition serializer-inl.h:95
Compile-time type-detection and serialisation utilities for VLink messages.
Definition serializer-inl.h:123
void Finish() const
Definition serializer-inl.h:132
const uint8_t * GetCurrentBufferPointer() const
Definition serializer-inl.h:128
void PushBytes(const uint8_t *, size_t)
Definition serializer-inl.h:130
const uint8_t * GetBufferPointer() const
Definition serializer-inl.h:126
size_t GetSize() const
Definition serializer-inl.h:124
Definition serializer-inl.h:137
Definition serializer-inl.h:135
Definition serializer-inl.h:139
bool VerifyBuffer(void *)
Definition serializer-inl.h:143
Verifier(const uint8_t *, size_t)
Definition serializer-inl.h:140
Definition serializer-inl.h:97
static T * Create(Arena *)
Definition serializer-inl.h:99
Compile-time type-trait utilities used internally by VLink.
#define VLINK_HAS_MEMBER(T, member)
Macro Definitions.
Definition traits.h:350