UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
NestedVariant.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Containers/Array.h"
6#include "Containers/Map.h"
7#include "Misc/TVariant.h"
9#include <type_traits>
10
55template<typename... ValueTypes>
56class TVariantArray : public TArray<TVariant<ValueTypes...>>, public TSharedFromThis<TVariantArray<ValueTypes...>>
57{
58public:
59 using VariantType = TVariant<ValueTypes...>;
61
62 static TSharedRef<TVariantArray<ValueTypes...>> CreateVariant()
63 {
64 return MakeShared<TVariantArray<ValueTypes...>>();
65 }
66
67 template<typename ValueType, typename VariantValueType = std::remove_cv_t<std::remove_reference_t<ValueType>>>
72
73 template<typename ValueType>
75 {
76 for (const ValueType& Value : Array)
77 {
79 }
80 }
81
82 template<typename ValueType>
84 {
85 if (Index >= 0 && Index < ArrayType::Num())
86 {
87 if (ArrayType::operator[](Index).template IsType<TSharedRef<ValueType>>())
88 {
90 return true;
91 }
92 }
93
94 return false;
95 }
96
97 template<typename ValueType>
99 {
100 if (Index >= 0 && Index < ArrayType::Num())
101 {
102 if (ArrayType::operator[](Index).template IsType<ValueType>())
103 {
105 return true;
106 }
107 }
108
109 return false;
110 }
111
112 template<typename ValueType>
114 {
115 OutValue.Reserve(ArrayType::Num());
116 for (int32 Index = 0; Index < ArrayType::Num(); Index++)
117 {
118 if (ArrayType::operator[](Index).template IsType<ValueType>())
119 {
120 OutValue.Add(ArrayType::operator[](Index).template Get<ValueType>());
121 }
122 }
123
124 return ArrayType::Num() == OutValue.Num();
125 }
126};
127
129template<typename KeyType, typename... ValueTypes>
130class TVariantMap : public TMap<KeyType, TVariant<ValueTypes...>>, public TSharedFromThis<TVariantMap<KeyType, ValueTypes...>>
131{
132public:
133 using VariantType = TVariant<ValueTypes...>;
135
136 static TSharedRef<TVariantMap<KeyType, ValueTypes...>> CreateVariant()
137 {
138 return MakeShared<TVariantMap<KeyType, ValueTypes...>>();
139 }
140
141 template<typename ValueType, typename AddKeyType, typename VariantValueType = std::remove_cv_t<std::remove_reference_t<ValueType>>>
146
147 template<typename ValueType>
149 {
150 for (const TPair<KeyType, ValueType>& Pair : Map)
151 {
152 AddVariant(Pair.Key, Pair.Value);
153 }
154 }
155
156 template<typename ValueType, typename GetKeyType>
157 bool GetVariant(const GetKeyType& Key, TSharedPtr<ValueType>& OutValue) const
158 {
159 if (const VariantType* Attribute = MapType::Find(Key))
160 {
161 if (Attribute->template IsType<TSharedRef<ValueType>>())
162 {
164 return true;
165 }
166 }
167
168 return false;
169 }
170
171 template<typename ValueType, typename GetKeyType>
172 bool GetVariant(const GetKeyType& Key, ValueType& OutValue) const
173 {
174 if (const VariantType* Attribute = MapType::Find(Key))
175 {
176 if (Attribute->template IsType<ValueType>())
177 {
178 OutValue = Attribute->template Get<ValueType>();
179 return true;
180 }
181 }
182
183 return false;
184 }
185
186 template<typename ValueType>
188 {
189 OutValue.Reserve(MapType::Num());
190 for (const TPair<KeyType, VariantType>& Pair : MapType::Pairs)
191 {
192 if (Pair.Value.template IsType<ValueType>())
193 {
194 OutValue.Add(Pair.Key, Pair.Value.template Get<ValueType>());
195 }
196 }
197
198 return MapType::Num() == OutValue.Num();
199 }
200};
201
202// Classes for working with nested TVariants that also have TArray and TMap references holding TVariants of the same types.
203// This is just one possible nesting structure. Other custom structures can be built for various use cases (no arrays, arrays with fixed types, etc).
204// First declare types to allow for nesting.
205
206template<typename KeyType, typename... ValueTypes> class TNestedVariantArray;
207template<typename KeyType, typename... ValueTypes> using TNestedVariantArrayRef = TSharedRef<TNestedVariantArray<KeyType, ValueTypes...>>;
208template<typename KeyType, typename... ValueTypes> using TNestedVariantArrayPtr = TSharedPtr<TNestedVariantArray<KeyType, ValueTypes...>>;
209
210template<typename KeyType, typename... ValueTypes> class TNestedVariantMap;
211template<typename KeyType, typename... ValueTypes> using TNestedVariantMapRef = TSharedRef<TNestedVariantMap<KeyType, ValueTypes...>>;
212template<typename KeyType, typename... ValueTypes> using TNestedVariantMapPtr = TSharedPtr<TNestedVariantMap<KeyType, ValueTypes...>>;
213
214template<typename KeyType, typename... ValueTypes> using FNestedVariantValue = TVariant<ValueTypes..., TNestedVariantArrayRef<KeyType, ValueTypes...>, TNestedVariantMapRef<KeyType, ValueTypes...>>;
215
216
217// Common methods between TNestedVariantArray and TNestedVariantMap.
219{
220 template<typename VisitType>
222
223 // Single void* methods for use with AppendArray and AppendMap.
224 using FSingleType = const void*;
226
227 [[nodiscard]] inline FSingleType MakeID(const void* InID)
228 {
229 return InID;
230 }
231
232 [[nodiscard]] inline bool ContainsID(const FSingleVisit& VisitSet, FSingleType ID)
233 {
234 return VisitSet.Contains(ID);
235 }
236
237 [[nodiscard]] inline FString ToString(FSingleType InID)
238 {
239 return FString::Printf(TEXT("%p"), InID);
240 }
241 // ~Single void* methods.
242
243 // Dual void* methods for use with Array and Map operator==.
246
247 [[nodiscard]] inline FDualType MakeID(const void* Left, const void* Right)
248 {
249 return MakeTuple(Left, Right);
250 }
251
252 [[nodiscard]] inline bool ContainsID(const FDualVisit& VisitSet, FDualType& ID)
253 {
254 // Check Left/Right and Right/Left variants.
255 return VisitSet.Contains(ID) || VisitSet.Contains(FDualType{ ID.Value, ID.Key });
256 }
257
258 [[nodiscard]] inline FString ToString(FDualType InPair)
259 {
260 return FString::Printf(TEXT("%p, %p"), InPair.Key, InPair.Value);
261 }
262 // ~Dual void* methods.
263
264 // Recursion protection for nested composites.
265 template<typename VisitType, int32 MaxDepth>
267 {
270 bool bSuccess = false;
271
272 TRecursionScope() = delete;
273
275 {
276 Enter();
277 }
278
280 {
281 Enter();
282 }
283
285 {
286 // Pop the scope if we didn't fail our checks.
287 if (bSuccess)
288 {
289 Visited.Remove(ID);
290 }
291 }
292
293 [[nodiscard]] explicit operator bool() const { return bSuccess; }
294
295 [[nodiscard]] FString GetError() const
296 {
297 if (bSuccess)
298 {
299 return FString();
300 }
301 else
302 {
303 if (Visited.Num() >= MaxDepth)
304 {
305 return FString::Printf(TEXT("Max Depth Reached: %d!"), MaxDepth);
306 }
307 else
308 {
309 return FString::Printf(TEXT("Duplicate scope: %s!"), *ToString(ID));
310 }
311 }
312 }
313
314 private:
315 void Enter()
316 {
317 // Check max recursion depth.
318 if (Visited.Num() >= MaxDepth)
319 {
320 return;
321 }
322
323 // Check to see if we have already visited this node.
324 if (ContainsID(Visited, ID))
325 {
326 return;
327 }
328
329 // Push/track this scope.
330 bSuccess = Visited.Add(ID).IsValidId();
331 }
332 };
333
334 // Comparison functions for use with operator==.
335 template<int32 MaxDepth, typename KeyType, typename... ValueTypes, typename T>
336 [[nodiscard]] bool Compare(const T& Lhs, const T& Rhs, FDualVisit& /* Unused */)
337 {
338 return Lhs == Rhs;
339 }
340
341 // Forward declaration for use in various Compare functions.
342 template<int32 MaxDepth, typename KeyType, typename... ValueTypes>
344
345 // TNestedVariantArray comparison.
346 template<int32 MaxDepth, typename KeyType, typename... ValueTypes>
348 {
349 using ThisType = TVariantArray<ValueTypes..., TNestedVariantArrayRef<KeyType, ValueTypes...>, TNestedVariantMapRef<KeyType, ValueTypes...>>;
350 const ThisType& LeftTyped = static_cast<const ThisType&>(Lhs);
351 const ThisType& RightTyped = static_cast<const ThisType&>(Rhs);
352
353 // Compare addresses.
354 if (&Lhs == &Rhs)
355 {
356 return true;
357 }
358
359 // If the arrays have differing numbers of variants then they are not equal.
360 if (LeftTyped.Num() != RightTyped.Num())
361 {
362 return false;
363 }
364
365 // Check recursion scope/depth.
366 const TRecursionScope<FDualType, MaxDepth> Scope(Visited, &Lhs, &Rhs);
367 if (!Scope)
368 {
369 return false;
370 }
371
372 for (int32 Index = 0; Index < LeftTyped.Num(); ++Index)
373 {
374 // Order-dependent equals.
376 {
377 return false;
378 }
379 }
380
381 return true;
382 }
383
384 // Dereference TNestedVariantArrayRef to TNestedVariantArray.
385 template<int32 MaxDepth, typename KeyType, typename... ValueTypes>
387 {
388 return Compare<MaxDepth, KeyType, ValueTypes...>(*Lhs, *Rhs, Visited);
389 }
390
391 // TNestedVariantMap comparison.
392 template<int32 MaxDepth, typename KeyType, typename... ValueTypes>
394 {
395 using ThisType = TVariantMap<KeyType, ValueTypes..., TNestedVariantArrayRef<KeyType, ValueTypes...>, TNestedVariantMapRef<KeyType, ValueTypes...>>;
396 using MapType = typename ThisType::MapType;
397 using VariantType = typename ThisType::VariantType;
398
399 const MapType& LeftTyped = static_cast<const MapType&>(Lhs);
400 const MapType& RightTyped = static_cast<const MapType&>(Rhs);
401
402 // Compare addresses.
403 if (&Lhs == &Rhs)
404 {
405 return true;
406 }
407
408 // If the maps have differing numbers of variants then they are not equal.
409 if (LeftTyped.Num() != RightTyped.Num())
410 {
411 return false;
412 }
413
414 // Check recursion scope/depth.
415 const TRecursionScope<FDualType, MaxDepth> Scope(Visited, &Lhs, &Rhs);
416 if (!Scope)
417 {
418 return false;
419 }
420
421 // Order-independent comparison (constant-time TMap lookup).
422 for (const TPair<KeyType, VariantType>& Pair : LeftTyped)
423 {
424 // Find the left map's variants in the right map.
425 const VariantType* RightVal = RightTyped.Find(Pair.Key);
426 if (!RightVal)
427 {
428 return false;
429 }
430
431 // Found it, now compare.
433 {
434 return false;
435 }
436 }
437
438 return true;
439 }
440
441 // Dereference TNestedVariantMapRef to TNestedVariantMap.
442 template<int32 MaxDepth, typename KeyType, typename... ValueTypes>
444 {
445 return Compare<MaxDepth, KeyType, ValueTypes...>(*Lhs, *Rhs, Visited);
446 }
447
448 template<int32 MaxDepth, typename KeyType, typename... ValueTypes>
450 {
451 return ::Visit([&VisitedSet](auto const& LVisited, auto const& RVisited)
452 {
453 using LeftDecayed = std::decay_t<decltype(LVisited)>;
454 using RightDecayed = std::decay_t<decltype(RVisited)>;
455 if constexpr (!std::is_same_v<LeftDecayed, RightDecayed>)
456 {
457 return false;
458 }
459 else
460 {
461 return Compare<MaxDepth, KeyType, ValueTypes...>(LVisited, RVisited, VisitedSet);
462 }
463 }, Lhs, Rhs);
464 }
465
466 // String appending methods for use with ToDebugString().
467 inline void AppendIndent(FString& OutString, int32 TabDepth)
468 {
469 for (int32 i = 0; i < TabDepth; ++i)
470 {
471 OutString.AppendChar(TEXT('\t'));
472 }
473 }
474
475 // Forward declarations used in AppendVariant.
476 template<int32 MaxDepth, int32 TabOffset, typename KeyType, typename... ValueTypes>
477 void AppendArray(const TNestedVariantArray<KeyType, ValueTypes...>& Array, FString& OutString, FSingleVisit& Visited);
478
479 template<int32 MaxDepth, int32 TabOffset, typename KeyType, typename... ValueTypes>
480 void AppendMap(const TNestedVariantMap<KeyType, ValueTypes...>& Map, FString& OutString, FSingleVisit& Visited);
481
482 template<typename T>
483 inline void AppendValue(FString& OutString, const T& V)
484 {
485 OutString += ::LexToString(V);
486 }
487
488 inline void AppendValue(FString& OutString, const FString& S)
489 {
490 OutString += S;
491 }
492
493 inline void AppendValue(FString& OutString, double Double, int32 Precision)
494 {
495 OutString += FString::Printf(TEXT("%.*f"), Precision, Double);
496 }
497
498 template<int32 MaxDepth, int32 TabOffset, bool bAfterKey, typename KeyType, typename... ValueTypes>
500 {
501 ::Visit([&VisitedSet, &OutString](auto const& Visited)
502 {
503 using DecayedType = std::decay_t<decltype(Visited)>;
504 if constexpr (std::is_same_v<DecayedType, TNestedVariantArrayRef<KeyType, ValueTypes...>>)
505 {
506 // If we printed a map with a Key: in the log.
507 if constexpr (bAfterKey)
508 {
509 OutString.AppendChar(TEXT('\n'));
510 }
511
512 AppendArray<MaxDepth, TabOffset, KeyType, ValueTypes...>(*Visited, OutString, VisitedSet);
513 }
514 else if constexpr (std::is_same_v<DecayedType, TNestedVariantMapRef<KeyType, ValueTypes...>>)
515 {
516 // If we printed a map with a Key: in the log.
517 if constexpr (bAfterKey)
518 {
519 OutString.AppendChar(TEXT('\n'));
520 }
521
522 AppendMap<MaxDepth, TabOffset, KeyType, ValueTypes...>(*Visited, OutString, VisitedSet);
523 }
524 else if constexpr (std::is_floating_point_v<DecayedType>)
525 {
526 // If we're not after a key then we're on our own line and need indentation.
527 if constexpr (!bAfterKey)
528 {
529 AppendIndent(OutString, TabOffset + VisitedSet.Num());
530 }
531
532 AppendValue(OutString, static_cast<double>(Visited), 2);
533 OutString.AppendChar(TEXT('\n'));
534 }
535 else
536 {
537 // If we're not after a key then we're on our own line and need indentation.
538 if constexpr (!bAfterKey)
539 {
540 AppendIndent(OutString, TabOffset + VisitedSet.Num());
541 }
542
543 AppendValue(OutString, Visited);
544 OutString.AppendChar(TEXT('\n'));
545 }
546 }, Variant);
547 }
548
549 template<int32 MaxDepth, int32 TabOffset, typename KeyType, typename... ValueTypes>
551 {
552 const int32 TabDepth = Visited.Num() + TabOffset;
553
554 // Check recursion scope/depth.
555 const TRecursionScope<FSingleType, MaxDepth> Scope(Visited, &Array);
556 if (!Scope)
557 {
558 AppendIndent(OutString, TabDepth);
559 OutString += Scope.GetError();
560 OutString.AppendChar(TEXT('\n'));
561 return;
562 }
563
564 AppendIndent(OutString, TabDepth);
565 OutString += TEXT("[\n");
566
567 const int32 ArrayNum = Array.Num();
568 if (ArrayNum > 0)
569 {
570 // Arrays do not have Key/Value pairs.
571 constexpr bool bAfterKey = false;
572
573 for (int32 i = 0; i < ArrayNum; ++i)
574 {
575 AppendVariant<MaxDepth, TabOffset, bAfterKey, KeyType, ValueTypes...>(Array[i], OutString, Visited);
576 }
577 }
578
579 AppendIndent(OutString, TabDepth);
580 OutString += TEXT("]\n");
581 }
582
583 template<int32 MaxDepth, int32 TabOffset, typename KeyType, typename... ValueTypes>
584 void AppendMap(const TNestedVariantMap<KeyType, ValueTypes...>& Map, FString& OutString, FSingleVisit& Visited)
585 {
586 using ThisType = TVariantMap<KeyType, ValueTypes..., TNestedVariantArrayRef<KeyType, ValueTypes...>, TNestedVariantMapRef <KeyType, ValueTypes...>>;
587 using MapType = typename ThisType::MapType;
588 using VariantType = FNestedVariantValue<KeyType, ValueTypes...>;
589
590 const MapType& MapBase = static_cast<const MapType&>(Map);
591
592 const int32 TabDepth = Visited.Num() + TabOffset;
593
594 // Check recursion scope/depth.
595 const TRecursionScope<FSingleType, MaxDepth> Scope(Visited, &Map);
596 if (!Scope)
597 {
598 AppendIndent(OutString, TabDepth);
599 OutString += Scope.GetError();
600 OutString.AppendChar(TEXT('\n'));
601 return;
602 }
603
604 AppendIndent(OutString, TabDepth);
605 OutString += TEXT("{\n");
606
607 // All variants appended to the string will be after their associated Key.
608 constexpr bool bAfterKey = true;
609
610 for (const TPair<KeyType, VariantType>& Pair : MapBase)
611 {
612 AppendIndent(OutString, TabDepth + 1);
613 OutString += ::LexToString(Pair.Key);
614 OutString += TEXT(": ");
615
616 AppendVariant<MaxDepth, TabOffset, bAfterKey, KeyType, ValueTypes...>(Pair.Value, OutString, Visited);
617 }
618
619 AppendIndent(OutString, TabDepth);
620 OutString += TEXT("}\n");
621 }
622} // namespace UE::Online::NestedVariant
623
624
626template<typename KeyType, typename... ValueTypes>
627class TNestedVariantArray : public TVariantArray<ValueTypes..., TNestedVariantArrayRef<KeyType, ValueTypes...>, TNestedVariantMapRef<KeyType, ValueTypes...>>
628{
629public:
630 static TNestedVariantArrayRef<KeyType, ValueTypes...> CreateVariant() {
631 return MakeShared<TNestedVariantArray<KeyType, ValueTypes...>>();
632 }
633
635 {
636 constexpr int32 MaxDepth = 64;
638 return UE::Online::NestedVariant::Compare<MaxDepth>(*this, Other, Visited);
639 }
640
642 {
643 return !(*this == Other);
644 }
645
646 template<int32 MaxDepth = 32, int32 TabOffset = 0>
647 void ToDebugString(FString& OutString) const
648 {
649 OutString.Reset(256);
650
652 UE::Online::NestedVariant::AppendArray<MaxDepth, TabOffset>(*this, OutString, Visited);
653
654 // Strip the final newline.
655 OutString.RemoveFromEnd(TEXT("\n"));
656 }
657};
658
660template<typename KeyType, typename... ValueTypes>
661class TNestedVariantMap : public TVariantMap<KeyType, ValueTypes..., TNestedVariantArrayRef<KeyType, ValueTypes...>, TNestedVariantMapRef<KeyType, ValueTypes...>>
662{
663public:
664 static TNestedVariantMapRef<KeyType, ValueTypes...> CreateVariant() {
665 return MakeShared<TNestedVariantMap<KeyType, ValueTypes...>>();
666 }
667
669 {
670 constexpr int32 MaxDepth = 64;
672 return UE::Online::NestedVariant::Compare<MaxDepth>(*this, Other, Visited);
673 }
674
676 {
677 return !(*this == Other);
678 }
679
680 template<int32 MaxDepth = 32, int32 TabOffset = 0>
681 void ToDebugString(FString& OutString) const
682 {
683 OutString.Reset(256);
684
686 UE::Online::NestedVariant::AppendMap<MaxDepth, TabOffset>(*this, OutString, Visited);
687
688 // Strip the final newline.
689 OutString.RemoveFromEnd(TEXT("\n"));
690 }
691};
692
694template<typename KeyType, typename... ValueTypes>
696{
697public:
698 using FArray = TNestedVariantArray<KeyType, ValueTypes...>;
699 using FArrayRef = TNestedVariantArrayRef<KeyType, ValueTypes...>;
700 using FArrayPtr = TNestedVariantArrayPtr<KeyType, ValueTypes...>;
701
702 using FMap = TNestedVariantMap<KeyType, ValueTypes...>;
703 using FMapRef = TNestedVariantMapRef<KeyType, ValueTypes...>;
704 using FMapPtr = TNestedVariantMapPtr<KeyType, ValueTypes...>;
705
706 using FValue = FNestedVariantValue<KeyType, ValueTypes...>;
707};
708
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
TSharedRef< InObjectType, InMode > MakeShared(InArgTypes &&... Args)
Definition SharedPointer.h:2009
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
const bool
Definition NetworkReplayStreaming.h:178
decltype(auto) Visit(Func &&Callable, Variants &&... Args)
Definition TVariant.h:271
constexpr TTuple< std::decay_t< Types >... > MakeTuple(Types &&... Args)
Definition Tuple.h:794
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
typename InAllocatorType::SizeType SizeType
Definition Array.h:675
UE_FORCEINLINE_HINT ElementType & Emplace_GetRef(ArgsType &&... Args) UE_LIFETIMEBOUND
Definition Array.h:2613
UE_NODEBUG UE_FORCEINLINE_HINT ElementType & operator[](SizeType Index) UE_LIFETIMEBOUND
Definition Array.h:1171
Definition UnrealString.h.inl:34
Definition NestedVariant.h:628
bool operator==(const TNestedVariantArray &Other) const
Definition NestedVariant.h:634
void ToDebugString(FString &OutString) const
Definition NestedVariant.h:647
bool operator!=(const TNestedVariantArray &Other) const
Definition NestedVariant.h:641
static TNestedVariantArrayRef< KeyType, ValueTypes... > CreateVariant()
Definition NestedVariant.h:630
Definition NestedVariant.h:662
bool operator==(const TNestedVariantMap &Other) const
Definition NestedVariant.h:668
void ToDebugString(FString &OutString) const
Definition NestedVariant.h:681
bool operator!=(const TNestedVariantMap &Other) const
Definition NestedVariant.h:675
static TNestedVariantMapRef< KeyType, ValueTypes... > CreateVariant()
Definition NestedVariant.h:664
Definition NestedVariant.h:696
Definition SharedPointer.h:1640
Definition SharedPointer.h:692
Definition SharedPointer.h:153
Definition NestedVariant.h:57
bool GetVariant(ArrayType::SizeType Index, ValueType &OutValue) const
Definition NestedVariant.h:98
static TSharedRef< TVariantArray< ValueTypes... > > CreateVariant()
Definition NestedVariant.h:62
VariantValueType & AddVariant(ValueType &&Value)
Definition NestedVariant.h:68
TVariant< ValueTypes... > VariantType
Definition NestedVariant.h:59
void AddVariantArray(const TArray< ValueType > &Array)
Definition NestedVariant.h:74
bool GetVariant(ArrayType::SizeType Index, TSharedPtr< ValueType > &OutValue) const
Definition NestedVariant.h:83
bool GetVariantArray(TArray< ValueType > &OutValue) const
Definition NestedVariant.h:113
Definition NestedVariant.h:131
TVariant< ValueTypes... > VariantType
Definition NestedVariant.h:133
static TSharedRef< TVariantMap< KeyType, ValueTypes... > > CreateVariant()
Definition NestedVariant.h:136
bool GetVariant(const GetKeyType &Key, TSharedPtr< ValueType > &OutValue) const
Definition NestedVariant.h:157
bool GetVariantMap(TMap< KeyType, ValueType > &OutValue) const
Definition NestedVariant.h:187
void AddVariantMap(const TMap< KeyType, ValueType > &Map)
Definition NestedVariant.h:148
VariantValueType & AddVariant(AddKeyType &&Key, ValueType &&Value)
Definition NestedVariant.h:142
bool GetVariant(const GetKeyType &Key, ValueType &OutValue) const
Definition NestedVariant.h:172
Definition TVariant.h:48
uint32 MaxDepth
Definition AndroidPlatformStackWalk.cpp:159
Definition NestedVariant.h:219
bool Compare(const T &Lhs, const T &Rhs, FDualVisit &)
Definition NestedVariant.h:336
void AppendMap(const TNestedVariantMap< KeyType, ValueTypes... > &Map, FString &OutString, FSingleVisit &Visited)
Definition NestedVariant.h:584
const void * FSingleType
Definition NestedVariant.h:224
TSet< VisitType > TGuardType
Definition NestedVariant.h:221
TGuardType< FDualType > FDualVisit
Definition NestedVariant.h:245
bool ContainsID(const FSingleVisit &VisitSet, FSingleType ID)
Definition NestedVariant.h:232
bool CompareVariants(const FNestedVariantValue< KeyType, ValueTypes... > &Lhs, const FNestedVariantValue< KeyType, ValueTypes... > &Rhs, FDualVisit &VisitedSet)
Definition NestedVariant.h:449
FSingleType MakeID(const void *InID)
Definition NestedVariant.h:227
void AppendArray(const TNestedVariantArray< KeyType, ValueTypes... > &Array, FString &OutString, FSingleVisit &Visited)
Definition NestedVariant.h:550
void AppendVariant(const FNestedVariantValue< KeyType, ValueTypes... > &Variant, FString &OutString, FSingleVisit &VisitedSet)
Definition NestedVariant.h:499
void AppendIndent(FString &OutString, int32 TabDepth)
Definition NestedVariant.h:467
void AppendValue(FString &OutString, const T &V)
Definition NestedVariant.h:483
TGuardType< FSingleType > FSingleVisit
Definition NestedVariant.h:225
const TCHAR * LexToString(EOnlineServices Value)
Definition CoreOnline.cpp:28
U16 Index
Definition radfft.cpp:71
Definition TVariant.h:13
Definition Tuple.h:652
Definition NestedVariant.h:267
TGuardType< VisitType > & Visited
Definition NestedVariant.h:268
TRecursionScope(TGuardType< VisitType > &InVisited, const void *InID)
Definition NestedVariant.h:274
FString GetError() const
Definition NestedVariant.h:295
TRecursionScope(TGuardType< VisitType > &InVisited, const void *InLeft, const void *InRight)
Definition NestedVariant.h:279
~TRecursionScope()
Definition NestedVariant.h:284
bool bSuccess
Definition NestedVariant.h:270
VisitType ID
Definition NestedVariant.h:269