UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
Tuple.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreTypes.h"
9#include "Templates/Invoke.h"
12#include "Templates/Requires.h"
13#include "Templates/TypeHash.h"
14#include <tuple>
15#include <type_traits>
16
17// This workaround exists because Visual Studio causes false positives for code like this during static analysis:
18//
19// void TestFoo(TMap<int*, int>& Map)
20// {
21// for (const TPair<int*, int>& Pair : Map)
22// {
23// if (*Pair.Key == 15 && Pair.Value != 15) // warning C6011: Dereferencing NULL pointer 'Pair.Key'
24// {
25// }
26// }
27// }
28//
29// This seems to be a combination of the following:
30// - Dereferencing an iterator in a loop
31// - Iterator type is not a pointer.
32// - Key is a pointer type.
33// - Key and Value are members of a base class.
34// - Dereferencing is done as part of a compound boolean expression (removing '&& Pair.Value != 15' removes the warning)
35#if (defined(_MSC_VER) && !defined(__clang__)) && USING_CODE_ANALYSIS
36 #define UE_TUPLE_STATIC_ANALYSIS_WORKAROUND 0 // disable this to see if it's still needed
37#else
38 #define UE_TUPLE_STATIC_ANALYSIS_WORKAROUND 0
39#endif
40
41// MSVC generates bad codegen when getting a reference element from an rvalue tuple. So, if the element type is
42// an rvalue reference, get it via an lvalue - it will be the same reference value in either case.
43#if defined(_MSC_VER) && !defined(__clang__)
44 #define UE_TUPLE_REFERENCE_WORKAROUND 1
45#else
46 #define UE_TUPLE_REFERENCE_WORKAROUND 0
47#endif
48
49class FArchive;
50
51template <typename... Types>
52struct TTuple;
53
54template <typename KeyType, typename ValueType>
56
57template <typename... Types>
58constexpr TTuple<std::decay_t<Types>...> MakeTuple(Types&&... Args);
59
61{
64
65 template <typename T, typename... Types>
67
68 template <typename T, typename U, typename... Types>
69 constexpr uint32 TTypeCountInParameterPack_V<T, U, Types...> = TTypeCountInParameterPack_V<T, Types...> + (std::is_same_v<T, U> ? 1 : 0);
70
71 template <typename T, uint32 Index, uint32 TupleSize>
73 {
74 template <typename ArgType>
76 : Value(Forward<ArgType>(Arg))
77 {
78 }
79
81 : Value()
82 {
83 }
84
89
91 };
92
93 template <typename T>
94 struct TTupleBaseElement<T, 0, 2>
95 {
96 template <typename ArgType>
98 : Key(Forward<ArgType>(Arg))
99 {
100 }
101
103 : Key()
104 {
105 }
106
111
113 };
114
115 template <uint32 Index, uint32 TupleSize>
117 {
118 template <typename DeducedType, typename TupleType>
119 static inline decltype(auto) GetImpl(const volatile TTupleBaseElement<DeducedType, Index, TupleSize>& Element, TupleType&& Tuple)
120 {
121#if UE_TUPLE_REFERENCE_WORKAROUND
122 if constexpr (!std::is_reference_v<TupleType> && std::is_reference_v<DeducedType>)
123 {
124 return (DeducedType)GetImpl(Element, Tuple);
125 }
126 else
127#endif
128 {
129 // Brackets are important here - we want a reference type to be returned, not object type
131
132 // Keep tuple rvalue references to rvalue reference elements as rvalues, because that's how std::get() works, not how C++ struct member access works.
133 return static_cast<std::conditional_t<!std::is_reference_v<TupleType> && std::is_rvalue_reference_v<DeducedType>, DeducedType, decltype(Result)>>(Result);
134 }
135 }
136
137 template <typename TupleType>
138 static UE_FORCEINLINE_HINT decltype(auto) Get(TupleType&& Tuple)
139 {
140 return GetImpl(Tuple, Forward<TupleType>(Tuple));
141 }
142 };
143
144#if UE_TUPLE_STATIC_ANALYSIS_WORKAROUND
145 template <>
146 struct TTupleElementGetterByIndex<0, 2>
147 {
148 template <typename TupleType>
149 static inline decltype(auto) Get(TupleType&& Tuple)
150 {
151 // Brackets are important here - we want a reference type to be returned, not object type
152 decltype(auto) Result = (Forward<TupleType>(Tuple).Key);
153
154 // Keep tuple rvalue references to rvalue reference elements as rvalues, because that's how std::get() works, not how C++ struct member access works.
155 return static_cast<std::conditional_t<!std::is_reference_v<TupleType> && std::is_rvalue_reference_v<decltype(Tuple.Key)>, decltype(Tuple.Key), decltype(Result)>>(Result);
156 }
157 };
158 template <>
159 struct TTupleElementGetterByIndex<1, 2>
160 {
161 template <typename TupleType>
162 static inline decltype(auto) Get(TupleType&& Tuple)
163 {
164 // Brackets are important here - we want a reference type to be returned, not object type
165 decltype(auto) Result = (Forward<TupleType>(Tuple).Value);
166
167 // Keep tuple rvalue references to rvalue reference elements as rvalues, because that's how std::get() works, not how C++ struct member access works.
168 return static_cast<std::conditional_t<!std::is_reference_v<TupleType> && std::is_rvalue_reference_v<decltype(Tuple.Value)>, decltype(Tuple.Value), decltype(Result)>>(Result);
169 }
170 };
171#else
172 template <>
174 {
175 template <typename TupleType>
176 static inline decltype(auto) Get(TupleType&& Tuple)
177 {
178#if UE_TUPLE_REFERENCE_WORKAROUND
179 using KeyType = decltype(std::decay_t<TupleType>::Key);
180 if constexpr (!std::is_reference_v<TupleType> && std::is_reference_v<KeyType>)
181 {
182 return (KeyType)Get(Tuple);
183 }
184 else
185#endif
186 {
187 // Brackets are important here - we want a reference type to be returned, not object type
188 decltype(auto) Result = (ForwardAsBase<TupleType, TTupleBaseElement<decltype(Tuple.Key), 0, 2>>(Tuple).Key);
189
190 // Keep tuple rvalue references to rvalue reference elements as rvalues, because that's how std::get() works, not how C++ struct member access works.
191 return static_cast<std::conditional_t<!std::is_reference_v<TupleType> && std::is_rvalue_reference_v<decltype(Tuple.Key)>, decltype(Tuple.Key), decltype(Result)>>(Result);
192 }
193 }
194 };
195#endif
196
197 template <typename Type, uint32 TupleSize>
199 {
200 template <uint32 DeducedIndex, typename TupleType>
205
206 template <typename TupleType>
207 static UE_FORCEINLINE_HINT decltype(auto) Get(TupleType&& Tuple)
208 {
209 return GetImpl(Tuple, Forward<TupleType>(Tuple));
210 }
211 };
212
213#if UE_TUPLE_STATIC_ANALYSIS_WORKAROUND
214 template <typename Type>
215 struct TTupleElementGetterByType<Type, 2>
216 {
217 template <typename TupleType>
218 static inline decltype(auto) Get(TupleType&& Tuple)
219 {
220 if constexpr (std::is_same_v<Type, decltype(Tuple.Key)>)
221 {
223 }
224 else
225 {
226 static_assert(std::is_same_v<Type, decltype(Tuple.Value)>, "This has to be true - check the call site");
228 }
229 }
230 };
231#endif
232
233 template <uint32 ArgCount, uint32 ArgToCompare>
235 {
236 template <typename TupleType>
237 UE_FORCEINLINE_HINT static bool Compare(const TupleType& Lhs, const TupleType& Rhs)
238 {
239 return Lhs.template Get<ArgToCompare>() == Rhs.template Get<ArgToCompare>() && FEqualityHelper<ArgCount, ArgToCompare + 1>::Compare(Lhs, Rhs);
240 }
241 };
242
243 template <uint32 ArgCount>
245 {
246 template <typename TupleType>
247 UE_FORCEINLINE_HINT static bool Compare(const TupleType& Lhs, const TupleType& Rhs)
248 {
249 return true;
250 }
251 };
252
253 template <uint32 NumArgs, uint32 ArgToCompare = 0, bool Last = ArgToCompare + 1 == NumArgs>
255 {
256 template <typename TupleType>
257 UE_FORCEINLINE_HINT static bool Do(const TupleType& Lhs, const TupleType& Rhs)
258 {
259 return Lhs.template Get<ArgToCompare>() < Rhs.template Get<ArgToCompare>() || (!(Rhs.template Get<ArgToCompare>() < Lhs.template Get<ArgToCompare>()) && TLessThanHelper<NumArgs, ArgToCompare + 1>::Do(Lhs, Rhs));
260 }
261 };
262
263 template <uint32 NumArgs, uint32 ArgToCompare>
265 {
266 template <typename TupleType>
267 UE_FORCEINLINE_HINT static bool Do(const TupleType& Lhs, const TupleType& Rhs)
268 {
269 return Lhs.template Get<ArgToCompare>() < Rhs.template Get<ArgToCompare>();
270 }
271 };
272
273 template <uint32 NumArgs>
274 struct TLessThanHelper<NumArgs, NumArgs, false>
275 {
276 template <typename TupleType>
277 UE_FORCEINLINE_HINT static bool Do(const TupleType& Lhs, const TupleType& Rhs)
278 {
279 return false;
280 }
281 };
282
283 template <typename Indices, typename... Types>
285
286 template <uint32... Indices, typename... Types>
287 struct TTupleBase<TIntegerSequence<uint32, Indices...>, Types...> : TTupleBaseElement<Types, Indices, sizeof...(Types)>...
288 {
289 template <typename... ArgTypes>
290 constexpr explicit TTupleBase(EForwardingConstructor, ArgTypes&&... Args)
291 : TTupleBaseElement<Types, Indices, sizeof...(Types)>(ForwardingConstructor, Forward<ArgTypes>(Args))...
292 {
293 }
294
295 template <typename TupleType>
297 : TTupleBaseElement<Types, Indices, sizeof...(Types)>(ForwardingConstructor, Forward<TupleType>(Other).template Get<Indices>())...
298 {
299 }
300
301 constexpr TTupleBase() = default;
303 TTupleBase(const TTupleBase& Other) = default;
306
307 template <uint32 Index> UE_FORCEINLINE_HINT decltype(auto) Get() & { static_assert(Index < sizeof...(Types), "Invalid index passed to TTuple::Get"); return TTupleElementGetterByIndex<Index, sizeof...(Types)>::Get(static_cast< TTupleBase& >(*this)); }
308 template <uint32 Index> UE_FORCEINLINE_HINT decltype(auto) Get() const & { static_assert(Index < sizeof...(Types), "Invalid index passed to TTuple::Get"); return TTupleElementGetterByIndex<Index, sizeof...(Types)>::Get(static_cast<const TTupleBase& >(*this)); }
309 template <uint32 Index> UE_FORCEINLINE_HINT decltype(auto) Get() volatile& { static_assert(Index < sizeof...(Types), "Invalid index passed to TTuple::Get"); return TTupleElementGetterByIndex<Index, sizeof...(Types)>::Get(static_cast< volatile TTupleBase& >(*this)); }
310 template <uint32 Index> UE_FORCEINLINE_HINT decltype(auto) Get() const volatile& { static_assert(Index < sizeof...(Types), "Invalid index passed to TTuple::Get"); return TTupleElementGetterByIndex<Index, sizeof...(Types)>::Get(static_cast<const volatile TTupleBase& >(*this)); }
311 template <uint32 Index> UE_FORCEINLINE_HINT decltype(auto) Get() && { static_assert(Index < sizeof...(Types), "Invalid index passed to TTuple::Get"); return TTupleElementGetterByIndex<Index, sizeof...(Types)>::Get(static_cast< TTupleBase&&>(*this)); }
312 template <uint32 Index> UE_FORCEINLINE_HINT decltype(auto) Get() const && { static_assert(Index < sizeof...(Types), "Invalid index passed to TTuple::Get"); return TTupleElementGetterByIndex<Index, sizeof...(Types)>::Get(static_cast<const TTupleBase&&>(*this)); }
313 template <uint32 Index> UE_FORCEINLINE_HINT decltype(auto) Get() volatile&& { static_assert(Index < sizeof...(Types), "Invalid index passed to TTuple::Get"); return TTupleElementGetterByIndex<Index, sizeof...(Types)>::Get(static_cast< volatile TTupleBase&&>(*this)); }
314 template <uint32 Index> UE_FORCEINLINE_HINT decltype(auto) Get() const volatile&& { static_assert(Index < sizeof...(Types), "Invalid index passed to TTuple::Get"); return TTupleElementGetterByIndex<Index, sizeof...(Types)>::Get(static_cast<const volatile TTupleBase&&>(*this)); }
315
316 template <typename T> UE_FORCEINLINE_HINT decltype(auto) Get() & { static_assert(TTypeCountInParameterPack_V<T, Types...> == 1, "Invalid type passed to TTuple::Get"); return TTupleElementGetterByType<T, sizeof...(Types)>::Get(static_cast< TTupleBase& >(*this)); }
317 template <typename T> UE_FORCEINLINE_HINT decltype(auto) Get() const & { static_assert(TTypeCountInParameterPack_V<T, Types...> == 1, "Invalid type passed to TTuple::Get"); return TTupleElementGetterByType<T, sizeof...(Types)>::Get(static_cast<const TTupleBase& >(*this)); }
318 template <typename T> UE_FORCEINLINE_HINT decltype(auto) Get() volatile& { static_assert(TTypeCountInParameterPack_V<T, Types...> == 1, "Invalid type passed to TTuple::Get"); return TTupleElementGetterByType<T, sizeof...(Types)>::Get(static_cast< volatile TTupleBase& >(*this)); }
319 template <typename T> UE_FORCEINLINE_HINT decltype(auto) Get() const volatile& { static_assert(TTypeCountInParameterPack_V<T, Types...> == 1, "Invalid type passed to TTuple::Get"); return TTupleElementGetterByType<T, sizeof...(Types)>::Get(static_cast<const volatile TTupleBase& >(*this)); }
320 template <typename T> UE_FORCEINLINE_HINT decltype(auto) Get() && { static_assert(TTypeCountInParameterPack_V<T, Types...> == 1, "Invalid type passed to TTuple::Get"); return TTupleElementGetterByType<T, sizeof...(Types)>::Get(static_cast< TTupleBase&&>(*this)); }
321 template <typename T> UE_FORCEINLINE_HINT decltype(auto) Get() const && { static_assert(TTypeCountInParameterPack_V<T, Types...> == 1, "Invalid type passed to TTuple::Get"); return TTupleElementGetterByType<T, sizeof...(Types)>::Get(static_cast<const TTupleBase&&>(*this)); }
322 template <typename T> UE_FORCEINLINE_HINT decltype(auto) Get() volatile&& { static_assert(TTypeCountInParameterPack_V<T, Types...> == 1, "Invalid type passed to TTuple::Get"); return TTupleElementGetterByType<T, sizeof...(Types)>::Get(static_cast< volatile TTupleBase&&>(*this)); }
323 template <typename T> UE_FORCEINLINE_HINT decltype(auto) Get() const volatile&& { static_assert(TTypeCountInParameterPack_V<T, Types...> == 1, "Invalid type passed to TTuple::Get"); return TTupleElementGetterByType<T, sizeof...(Types)>::Get(static_cast<const volatile TTupleBase&&>(*this)); }
324
325 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyAfter(FuncType&& Func, ArgTypes&&... Args) & { return ::Invoke(Func, Forward<ArgTypes>(Args)..., static_cast< TTupleBase& >(*this).template Get<Indices>()...); }
326 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyAfter(FuncType&& Func, ArgTypes&&... Args) const & { return ::Invoke(Func, Forward<ArgTypes>(Args)..., static_cast<const TTupleBase& >(*this).template Get<Indices>()...); }
327 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyAfter(FuncType&& Func, ArgTypes&&... Args) volatile& { return ::Invoke(Func, Forward<ArgTypes>(Args)..., static_cast< volatile TTupleBase& >(*this).template Get<Indices>()...); }
328 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyAfter(FuncType&& Func, ArgTypes&&... Args) const volatile& { return ::Invoke(Func, Forward<ArgTypes>(Args)..., static_cast<const volatile TTupleBase& >(*this).template Get<Indices>()...); }
329 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyAfter(FuncType&& Func, ArgTypes&&... Args) && { return ::Invoke(Func, Forward<ArgTypes>(Args)..., static_cast< TTupleBase&&>(*this).template Get<Indices>()...); }
330 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyAfter(FuncType&& Func, ArgTypes&&... Args) const && { return ::Invoke(Func, Forward<ArgTypes>(Args)..., static_cast<const TTupleBase&&>(*this).template Get<Indices>()...); }
331 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyAfter(FuncType&& Func, ArgTypes&&... Args) volatile&& { return ::Invoke(Func, Forward<ArgTypes>(Args)..., static_cast< volatile TTupleBase&&>(*this).template Get<Indices>()...); }
332 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyAfter(FuncType&& Func, ArgTypes&&... Args) const volatile&& { return ::Invoke(Func, Forward<ArgTypes>(Args)..., static_cast<const volatile TTupleBase&&>(*this).template Get<Indices>()...); }
333
334 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyBefore(FuncType&& Func, ArgTypes&&... Args) & { return ::Invoke(Func, static_cast< TTupleBase& >(*this).template Get<Indices>()..., Forward<ArgTypes>(Args)...); }
335 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyBefore(FuncType&& Func, ArgTypes&&... Args) const & { return ::Invoke(Func, static_cast<const TTupleBase& >(*this).template Get<Indices>()..., Forward<ArgTypes>(Args)...); }
336 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyBefore(FuncType&& Func, ArgTypes&&... Args) volatile& { return ::Invoke(Func, static_cast< volatile TTupleBase& >(*this).template Get<Indices>()..., Forward<ArgTypes>(Args)...); }
337 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyBefore(FuncType&& Func, ArgTypes&&... Args) const volatile& { return ::Invoke(Func, static_cast<const volatile TTupleBase& >(*this).template Get<Indices>()..., Forward<ArgTypes>(Args)...); }
338 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyBefore(FuncType&& Func, ArgTypes&&... Args) && { return ::Invoke(Func, static_cast< TTupleBase&&>(*this).template Get<Indices>()..., Forward<ArgTypes>(Args)...); }
339 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyBefore(FuncType&& Func, ArgTypes&&... Args) const && { return ::Invoke(Func, static_cast<const TTupleBase&&>(*this).template Get<Indices>()..., Forward<ArgTypes>(Args)...); }
340 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyBefore(FuncType&& Func, ArgTypes&&... Args) volatile&& { return ::Invoke(Func, static_cast< volatile TTupleBase&&>(*this).template Get<Indices>()..., Forward<ArgTypes>(Args)...); }
341 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyBefore(FuncType&& Func, ArgTypes&&... Args) const volatile&& { return ::Invoke(Func, static_cast<const volatile TTupleBase&&>(*this).template Get<Indices>()..., Forward<ArgTypes>(Args)...); }
342
343 inline static void Serialize(FArchive& Ar, TTupleBase& Tuple)
344 {
345 // This should be implemented with a fold expression when our compilers support it
346 int Temp[] = { 0, (Ar << Tuple.template Get<Indices>(), 0)... };
347 (void)Temp;
348 }
349
351 {
352 // This should be implemented with a fold expression when our compilers support it
354 int Temp[] = { 0, (Stream.EnterElement() << Tuple.template Get<Indices>(), 0)... };
355 (void)Temp;
356 }
357
359 {
360 // This could be implemented with a fold expression when our compilers support it
361 return FEqualityHelper<sizeof...(Types), 0>::Compare(*this, Rhs);
362 }
363
365 {
366 return !(*this == Rhs);
367 }
368
370 {
371 return TLessThanHelper<sizeof...(Types)>::Do(*this, Rhs);
372 }
373
375 {
376 return !(Rhs < *this);
377 }
378
380 {
381 return Rhs < *this;
382 }
383
385 {
386 return !(*this < Rhs);
387 }
388 };
389
390#if UE_TUPLE_STATIC_ANALYSIS_WORKAROUND
391 template <typename KeyType, typename ValueType>
392 struct TTupleBase<TIntegerSequence<uint32, 0, 1>, KeyType, ValueType>
393 {
394 KeyType Key;
395 ValueType Value;
396
398
399 template <typename KeyArgType, typename ValueArgType>
401 : Key (Forward<KeyArgType >(KeyArg ))
403 {
404 }
405
406 template <typename TupleType>
407 explicit TTupleBase(EOtherTupleConstructor, TupleType&& Other)
408 : Key (Forward<TupleType>(Other).Get<0>())
409 , Value(Forward<TupleType>(Other).Get<1>())
410 {
411 }
412
413 TTupleBase() = default;
414 TTupleBase(TTupleBase&& Other) = default;
415 TTupleBase(const TTupleBase& Other) = default;
416 TTupleBase& operator=(TTupleBase&& Other) = default;
417 TTupleBase& operator=(const TTupleBase& Other) = default;
418
419 template <uint32 Index> UE_FORCEINLINE_HINT decltype(auto) Get() & { static_assert(Index < 2, "Invalid index passed to TTuple::Get"); return TTupleElementGetterByIndex<Index, 2>::Get(static_cast< TTupleBase& >(*this)); }
420 template <uint32 Index> UE_FORCEINLINE_HINT decltype(auto) Get() const & { static_assert(Index < 2, "Invalid index passed to TTuple::Get"); return TTupleElementGetterByIndex<Index, 2>::Get(static_cast<const TTupleBase& >(*this)); }
421 template <uint32 Index> UE_FORCEINLINE_HINT decltype(auto) Get() volatile& { static_assert(Index < 2, "Invalid index passed to TTuple::Get"); return TTupleElementGetterByIndex<Index, 2>::Get(static_cast< volatile TTupleBase& >(*this)); }
422 template <uint32 Index> UE_FORCEINLINE_HINT decltype(auto) Get() const volatile& { static_assert(Index < 2, "Invalid index passed to TTuple::Get"); return TTupleElementGetterByIndex<Index, 2>::Get(static_cast<const volatile TTupleBase& >(*this)); }
423 template <uint32 Index> UE_FORCEINLINE_HINT decltype(auto) Get() && { static_assert(Index < 2, "Invalid index passed to TTuple::Get"); return TTupleElementGetterByIndex<Index, 2>::Get(static_cast< TTupleBase&&>(*this)); }
424 template <uint32 Index> UE_FORCEINLINE_HINT decltype(auto) Get() const && { static_assert(Index < 2, "Invalid index passed to TTuple::Get"); return TTupleElementGetterByIndex<Index, 2>::Get(static_cast<const TTupleBase&&>(*this)); }
425 template <uint32 Index> UE_FORCEINLINE_HINT decltype(auto) Get() volatile&& { static_assert(Index < 2, "Invalid index passed to TTuple::Get"); return TTupleElementGetterByIndex<Index, 2>::Get(static_cast< volatile TTupleBase&&>(*this)); }
426 template <uint32 Index> UE_FORCEINLINE_HINT decltype(auto) Get() const volatile&& { static_assert(Index < 2, "Invalid index passed to TTuple::Get"); return TTupleElementGetterByIndex<Index, 2>::Get(static_cast<const volatile TTupleBase&&>(*this)); }
427
428 template <typename T> UE_FORCEINLINE_HINT decltype(auto) Get() & { static_assert(TTypeCountInParameterPack_V<T, KeyType, ValueType> == 1, "Invalid type passed to TTuple::Get"); return TTupleElementGetterByType<T, 2>::Get(static_cast< TTupleBase& >(*this)); }
429 template <typename T> UE_FORCEINLINE_HINT decltype(auto) Get() const & { static_assert(TTypeCountInParameterPack_V<T, KeyType, ValueType> == 1, "Invalid type passed to TTuple::Get"); return TTupleElementGetterByType<T, 2>::Get(static_cast<const TTupleBase& >(*this)); }
430 template <typename T> UE_FORCEINLINE_HINT decltype(auto) Get() volatile& { static_assert(TTypeCountInParameterPack_V<T, KeyType, ValueType> == 1, "Invalid type passed to TTuple::Get"); return TTupleElementGetterByType<T, 2>::Get(static_cast< volatile TTupleBase& >(*this)); }
431 template <typename T> UE_FORCEINLINE_HINT decltype(auto) Get() const volatile& { static_assert(TTypeCountInParameterPack_V<T, KeyType, ValueType> == 1, "Invalid type passed to TTuple::Get"); return TTupleElementGetterByType<T, 2>::Get(static_cast<const volatile TTupleBase& >(*this)); }
432 template <typename T> UE_FORCEINLINE_HINT decltype(auto) Get() && { static_assert(TTypeCountInParameterPack_V<T, KeyType, ValueType> == 1, "Invalid type passed to TTuple::Get"); return TTupleElementGetterByType<T, 2>::Get(static_cast< TTupleBase&&>(*this)); }
433 template <typename T> UE_FORCEINLINE_HINT decltype(auto) Get() const && { static_assert(TTypeCountInParameterPack_V<T, KeyType, ValueType> == 1, "Invalid type passed to TTuple::Get"); return TTupleElementGetterByType<T, 2>::Get(static_cast<const TTupleBase&&>(*this)); }
434 template <typename T> UE_FORCEINLINE_HINT decltype(auto) Get() volatile&& { static_assert(TTypeCountInParameterPack_V<T, KeyType, ValueType> == 1, "Invalid type passed to TTuple::Get"); return TTupleElementGetterByType<T, 2>::Get(static_cast< volatile TTupleBase&&>(*this)); }
435 template <typename T> UE_FORCEINLINE_HINT decltype(auto) Get() const volatile&& { static_assert(TTypeCountInParameterPack_V<T, KeyType, ValueType> == 1, "Invalid type passed to TTuple::Get"); return TTupleElementGetterByType<T, 2>::Get(static_cast<const volatile TTupleBase&&>(*this)); }
436
437 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyAfter(FuncType&& Func, ArgTypes&&... Args) & { return ::Invoke(Func, Forward<ArgTypes>(Args)..., static_cast< TTupleBase& >(*this).template Get<0>(), static_cast< TTupleBase& >(*this).template Get<1>()); }
438 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyAfter(FuncType&& Func, ArgTypes&&... Args) const & { return ::Invoke(Func, Forward<ArgTypes>(Args)..., static_cast<const TTupleBase& >(*this).template Get<0>(), static_cast<const TTupleBase& >(*this).template Get<1>()); }
439 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyAfter(FuncType&& Func, ArgTypes&&... Args) volatile& { return ::Invoke(Func, Forward<ArgTypes>(Args)..., static_cast< volatile TTupleBase& >(*this).template Get<0>(), static_cast< volatile TTupleBase& >(*this).template Get<1>()); }
440 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyAfter(FuncType&& Func, ArgTypes&&... Args) const volatile& { return ::Invoke(Func, Forward<ArgTypes>(Args)..., static_cast<const volatile TTupleBase& >(*this).template Get<0>(), static_cast<const volatile TTupleBase& >(*this).template Get<1>()); }
441 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyAfter(FuncType&& Func, ArgTypes&&... Args) && { return ::Invoke(Func, Forward<ArgTypes>(Args)..., static_cast< TTupleBase&&>(*this).template Get<0>(), static_cast< TTupleBase&&>(*this).template Get<1>()); }
442 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyAfter(FuncType&& Func, ArgTypes&&... Args) const && { return ::Invoke(Func, Forward<ArgTypes>(Args)..., static_cast<const TTupleBase&&>(*this).template Get<0>(), static_cast<const TTupleBase&&>(*this).template Get<1>()); }
443 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyAfter(FuncType&& Func, ArgTypes&&... Args) volatile&& { return ::Invoke(Func, Forward<ArgTypes>(Args)..., static_cast< volatile TTupleBase&&>(*this).template Get<0>(), static_cast< volatile TTupleBase&&>(*this).template Get<1>()); }
444 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyAfter(FuncType&& Func, ArgTypes&&... Args) const volatile&& { return ::Invoke(Func, Forward<ArgTypes>(Args)..., static_cast<const volatile TTupleBase&&>(*this).template Get<0>(), static_cast<const volatile TTupleBase&&>(*this).template Get<1>()); }
445
446 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyBefore(FuncType&& Func, ArgTypes&&... Args) & { return ::Invoke(Func, static_cast< TTupleBase& >(*this).template Get<0>(), static_cast< TTupleBase& >(*this).template Get<1>(), Forward<ArgTypes>(Args)...); }
447 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyBefore(FuncType&& Func, ArgTypes&&... Args) const & { return ::Invoke(Func, static_cast<const TTupleBase& >(*this).template Get<0>(), static_cast<const TTupleBase& >(*this).template Get<1>(), Forward<ArgTypes>(Args)...); }
448 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyBefore(FuncType&& Func, ArgTypes&&... Args) volatile& { return ::Invoke(Func, static_cast< volatile TTupleBase& >(*this).template Get<0>(), static_cast< volatile TTupleBase& >(*this).template Get<1>(), Forward<ArgTypes>(Args)...); }
449 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyBefore(FuncType&& Func, ArgTypes&&... Args) const volatile& { return ::Invoke(Func, static_cast<const volatile TTupleBase& >(*this).template Get<0>(), static_cast<const volatile TTupleBase& >(*this).template Get<1>(), Forward<ArgTypes>(Args)...); }
450 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyBefore(FuncType&& Func, ArgTypes&&... Args) && { return ::Invoke(Func, static_cast< TTupleBase&&>(*this).template Get<0>(), static_cast< TTupleBase&&>(*this).template Get<1>(), Forward<ArgTypes>(Args)...); }
451 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyBefore(FuncType&& Func, ArgTypes&&... Args) const && { return ::Invoke(Func, static_cast<const TTupleBase&&>(*this).template Get<0>(), static_cast<const TTupleBase&&>(*this).template Get<1>(), Forward<ArgTypes>(Args)...); }
452 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyBefore(FuncType&& Func, ArgTypes&&... Args) volatile&& { return ::Invoke(Func, static_cast< volatile TTupleBase&&>(*this).template Get<0>(), static_cast< volatile TTupleBase&&>(*this).template Get<1>(), Forward<ArgTypes>(Args)...); }
453 template <typename FuncType, typename... ArgTypes> decltype(auto) ApplyBefore(FuncType&& Func, ArgTypes&&... Args) const volatile&& { return ::Invoke(Func, static_cast<const volatile TTupleBase&&>(*this).template Get<0>(), static_cast<const volatile TTupleBase&&>(*this).template Get<1>(), Forward<ArgTypes>(Args)...); }
454
455 inline static void Serialize(FArchive& Ar, TTupleBase& Tuple)
456 {
457 Ar << Tuple.Key;
458 Ar << Tuple.Value;
459 }
460
461 inline static void SerializeStructured(FStructuredArchive::FSlot Slot, TTupleBase& Tuple)
462 {
464 Stream.EnterElement() << Tuple.Key;
465 Stream.EnterElement() << Tuple.Value;
466 }
467
468 UE_FORCEINLINE_HINT friend bool operator==(const TTupleBase& Lhs, const TTupleBase& Rhs)
469 {
470 // This could be implemented with a fold expression when our compilers support it
471 return FEqualityHelper<2, 0>::Compare(Lhs, Rhs);
472 }
473
474 UE_FORCEINLINE_HINT friend bool operator!=(const TTupleBase& Lhs, const TTupleBase& Rhs)
475 {
476 return !(Lhs == Rhs);
477 }
478
479 UE_FORCEINLINE_HINT friend bool operator<(const TTupleBase& Lhs, const TTupleBase& Rhs)
480 {
481 return TLessThanHelper<2>::Do(Lhs, Rhs);
482 }
483
484 UE_FORCEINLINE_HINT friend bool operator<=(const TTupleBase& Lhs, const TTupleBase& Rhs)
485 {
486 return !(Rhs < Lhs);
487 }
488
489 UE_FORCEINLINE_HINT friend bool operator>(const TTupleBase& Lhs, const TTupleBase& Rhs)
490 {
491 return Rhs < Lhs;
492 }
493
494 UE_FORCEINLINE_HINT friend bool operator>=(const TTupleBase& Lhs, const TTupleBase& Rhs)
495 {
496 return !(Lhs < Rhs);
497 }
498 };
499#endif
500
501 template <typename LhsType, typename RhsType, uint32... Indices>
502 static void Assign(LhsType& Lhs, RhsType&& Rhs, TIntegerSequence<uint32, Indices...>)
503 {
504 // This should be implemented with a fold expression when our compilers support it
505 int Temp[] = { 0, (Lhs.template Get<Indices>() = Forward<RhsType>(Rhs).template Get<Indices>(), 0)... };
506 (void)Temp;
507 }
508
509 template <typename... ElementTypes, typename... Types>
511 {
512 return TTuple<ElementTypes...>(Forward<Types>(Args)...);
513 }
514
515 template <typename IntegerSequence>
517
518 template <uint32... Indices>
520 {
521 template <typename TupleType, typename FuncType>
522 static decltype(auto) Do(TupleType&& Tuple, FuncType Func)
523 {
524 return MakeTuple(Func(Forward<TupleType>(Tuple).template Get<Indices>())...);
525 }
526 };
527
528 template <typename IntegerSequence>
530
531 template <uint32... Indices>
533 {
534 // We need a second function to do the invocation for a particular index, to avoid the pack expansion being
535 // attempted on the indices and tuples simultaneously.
536 template <uint32 Index, typename FuncType, typename... TupleTypes>
537 UE_FORCEINLINE_HINT static void InvokeFunc(FuncType&& Func, TupleTypes&&... Tuples)
538 {
540 }
541
542 template <typename FuncType, typename... TupleTypes>
543 static void Do(FuncType&& Func, TupleTypes&&... Tuples)
544 {
545 // This should be implemented with a fold expression when our compilers support it
546 int Temp[] = { 0, (InvokeFunc<Indices>(Forward<FuncType>(Func), Forward<TupleTypes>(Tuples)...), 0)... };
547 (void)Temp;
548 }
549 };
550
551
552 template <typename TupleType>
554
555 template <typename... Types>
556 struct TCVTupleArity<const volatile TTuple<Types...>>
557 {
558 enum { Value = sizeof...(Types) };
559 };
560
561 template <typename Type, typename TupleType>
563 {
564 static_assert(sizeof(TupleType) == 0, "TTupleIndex instantiated with a non-tuple type");
565 static constexpr uint32 Value = 0;
566 };
567
568 template <typename Type, typename... TupleTypes>
569 struct TCVTupleIndex<Type, const volatile TTuple<TupleTypes...>>
570 {
571 static_assert(TTypeCountInParameterPack_V<Type, TupleTypes...> >= 1, "TTupleIndex instantiated with a tuple which does not contain the type");
572 static_assert(TTypeCountInParameterPack_V<Type, TupleTypes...> <= 1, "TTupleIndex instantiated with a tuple which contains multiple instances of the type");
573
574 private:
575 template <uint32 DeducedIndex>
576 static auto Resolve(TTupleBaseElement<Type, DeducedIndex, sizeof...(TupleTypes)>*) -> char(&)[DeducedIndex + 1];
577 static auto Resolve(...) -> char;
578
579 public:
580 static constexpr uint32 Value = sizeof(Resolve(DeclVal<TTuple<TupleTypes...>*>())) - 1;
581 };
582
583#if UE_TUPLE_STATIC_ANALYSIS_WORKAROUND
584 template <typename Type, typename KeyType, typename ValueType>
585 struct TCVTupleIndex<Type, const volatile TTuple<KeyType, ValueType>>
586 {
587 static_assert(TTypeCountInParameterPack_V<Type, KeyType, ValueType> >= 1, "TTupleIndex instantiated with a tuple which does not contain the type");
588 static_assert(TTypeCountInParameterPack_V<Type, KeyType, ValueType> <= 1, "TTupleIndex instantiated with a tuple which contains multiple instances of the type");
589
590 static constexpr uint32 Value = std::is_same_v<Type, ValueType> ? 1 : 0;
591 };
592#endif
593
594 template <uint32 Index, typename TupleType>
596 {
597 static_assert(sizeof(TupleType) == 0, "TTupleElement instantiated with a non-tuple type");
598 using Type = void;
599 };
600
601 template <uint32 Index, typename... TupleTypes>
603 {
604 static_assert(Index < sizeof...(TupleTypes), "TTupleElement instantiated with an invalid index");
605
606#ifdef __clang__
608#else
609 private:
610 template <typename DeducedType>
612 static void Resolve(...);
613
614 public:
616#endif
617 };
618
619#if UE_TUPLE_STATIC_ANALYSIS_WORKAROUND
620 template <uint32 Index, typename KeyType, typename ValueType>
621 struct TCVTupleElement<Index, const volatile TTuple<KeyType, ValueType>>
622 {
623 static_assert(Index < 2, "TTupleElement instantiated with an invalid index");
624
625 using Type = std::conditional_t<Index == 0, KeyType, ValueType>;
626 };
627#endif
628
629 template <uint32 ArgToCombine, uint32 ArgCount>
631 {
632 template <typename TupleType>
637 };
638
639 template <uint32 ArgIndex>
641 {
642 template <typename TupleType>
644 {
645 return Hash;
646 }
647 };
648}
649
650template <typename... Types>
651struct TTuple : UE::Core::Private::Tuple::TTupleBase<TMakeIntegerSequence<uint32, sizeof...(Types)>, Types...>
652{
653private:
654 typedef UE::Core::Private::Tuple::TTupleBase<TMakeIntegerSequence<uint32, sizeof...(Types)>, Types...> Super;
655
656public:
657 template <UE::CNotCVRefTo<TTuple>... ArgTypes>
658 requires (std::is_constructible_v<Types, ArgTypes&&> && ...)
659 constexpr explicit(!std::conjunction_v<std::is_convertible<ArgTypes&&, Types>...>) TTuple(ArgTypes&&... Args)
661 {
662 }
663
664 template <typename... OtherTypes>
665 requires (std::is_constructible_v<Types, OtherTypes&&> && ...)
667 : Super(UE::Core::Private::Tuple::OtherTupleConstructor, MoveTemp(Other))
668 {
669 }
670
671 template <typename... OtherTypes>
672 requires (std::is_constructible_v<Types, const OtherTypes&> && ...)
674 : Super(UE::Core::Private::Tuple::OtherTupleConstructor, Other)
675 {
676 }
677
678 constexpr TTuple() requires (std::is_default_constructible_v<Types> && ...) = default;
679 TTuple(TTuple&&) = default;
680 TTuple(const TTuple&) = default;
681 TTuple& operator=(TTuple&&) = default;
682 TTuple& operator=(const TTuple&) = default;
683
684 template <typename... OtherTypes>
685 requires (std::is_assignable_v<Types, const OtherTypes&> && ...)
687 {
688 UE::Core::Private::Tuple::Assign(*this, Other, TMakeIntegerSequence<uint32, sizeof...(Types)>{});
689 return *this;
690 }
691
692 template <typename... OtherTypes>
693 requires (std::is_assignable_v<Types, OtherTypes&&> && ...)
695 {
696 UE::Core::Private::Tuple::Assign(*this, MoveTemp(Other), TMakeIntegerSequence<uint32, sizeof...(OtherTypes)>{});
697 return *this;
698 }
699};
700
701template <typename... Types>
703{
704 return UE::Core::Private::Tuple::TGetTupleHashHelper<1u, sizeof...(Types)>::Do(GetTypeHash(Tuple.template Get<0>()), Tuple);
705}
706
708{
709 return 0;
710}
711
712namespace Freeze
713{
714 template<typename KeyType, typename ValueType>
716 {
717 Writer.WriteObject(Object.Key);
718 Writer.WriteObject(Object.Value);
719 }
720
721 template<typename KeyType, typename ValueType>
723 {
725 Context.UnfreezeObject(Object.Key, &DstObject->Key);
726 Context.UnfreezeObject(Object.Value, &DstObject->Value);
727 return sizeof(Object);
728 }
729
730 template<typename KeyType, typename ValueType>
735
736 template<typename KeyType, typename ValueType>
738 {
741 return FMath::Min(FMath::Max(KeyAlignment, ValueAlignment), LayoutParams.MaxFieldAlignment);
742 }
743}
744
746
750template <typename TupleType>
751struct TTupleArity : UE::Core::Private::Tuple::TCVTupleArity<const volatile TupleType>
752{
753};
754
755
763template <typename Type, typename TupleType>
765
766
774template <uint32 Index, typename TupleType>
776
777
793template <typename... Types>
795{
796 return UE::Core::Private::Tuple::MakeTupleImpl<std::decay_t<Types>...>(Forward<Types>(Args)...);
797}
798
799
818template <typename... Types>
819UE_FORCEINLINE_HINT TTuple<Types&&...> ForwardAsTuple(Types&&... Args)
820{
821 return UE::Core::Private::Tuple::MakeTupleImpl<Types&&...>(Forward<Types>(Args)...);
822}
823
824
846template <typename FuncType, typename... Types>
847UE_FORCEINLINE_HINT decltype(auto) TransformTuple(TTuple<Types...>&& Tuple, FuncType Func)
848{
850}
851
852template <typename FuncType, typename... Types>
853UE_FORCEINLINE_HINT decltype(auto) TransformTuple(const TTuple<Types...>& Tuple, FuncType Func)
854{
855 return UE::Core::Private::Tuple::TTransformTuple_Impl<TMakeIntegerSequence<uint32, sizeof...(Types)>>::Do(Tuple, MoveTemp(Func));
856}
857
858
877template <typename FuncType, typename FirstTupleType, typename... TupleTypes>
882
898template <typename... Types>
899UE_FORCEINLINE_HINT TTuple<Types&...> Tie(Types&... Args)
900{
901 return TTuple<Types&...>(Args...);
902}
903
904template <typename T> constexpr bool TIsTuple_V = false;
905
906template <typename... Types> constexpr bool TIsTuple_V< TTuple<Types...>> = true;
907template <typename... Types> constexpr bool TIsTuple_V<const TTuple<Types...>> = true;
908template <typename... Types> constexpr bool TIsTuple_V< volatile TTuple<Types...>> = true;
909template <typename... Types> constexpr bool TIsTuple_V<const volatile TTuple<Types...>> = true;
910
911template <typename T>
913{
915};
916
918// TTuple support for structured bindings - not intended to be used directly //
920template <typename... ArgTypes>
921struct std::tuple_size<TTuple<ArgTypes...>>
922 : std::integral_constant<std::size_t, sizeof...(ArgTypes)>
923{
924};
925template <std::size_t N, typename... ArgTypes>
926#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 9000
927// libc++ 8.0 and older incorrectly defined std::tuple_element as class, whereas the standard
928// says it should be a struct.
929class std::tuple_element<N, TTuple<ArgTypes...>>
930#else
931struct std::tuple_element<N, TTuple<ArgTypes...>>
932#endif
933{
934public:
935 using type = typename TTupleElement<N, TTuple<ArgTypes...>>::Type;
936};
937
938template <int N, typename TupleType>
940decltype(auto) get(TupleType&& val)
941{
942 return ((TupleType&&)val).template Get<N>();
943}
945// End of structured binding support //
947
948template <typename... Types>
950{
952 return Ar;
953}
954
955template <typename... Types>
960
961#if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_4
962#include "Templates/Decay.h"
964#endif
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
AUTORTFM_INFER UE_FORCEINLINE_HINT constexpr auto Invoke(FuncType &&Func, ArgTypes &&... Args) -> decltype(((FuncType &&) Func)((ArgTypes &&) Args...))
Definition Invoke.h:44
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
return true
Definition ExternalRpcRegistry.cpp:601
typename UE4IntegerSequence_Private::TMakeIntegerSequenceImpl< T, N >::Type TMakeIntegerSequence
Definition IntegerSequence.h:31
#define DECLARE_TEMPLATE_INTRINSIC_TYPE_LAYOUT(TemplatePrefix, T)
Definition MemoryLayout.h:661
constexpr TTuple< std::decay_t< Types >... > MakeTuple(Types &&... Args)
Definition Tuple.h:794
constexpr bool TIsTuple_V
Definition Tuple.h:904
FArchive & operator<<(FArchive &Ar, TTuple< Types... > &Tuple)
Definition Tuple.h:949
UE_FORCEINLINE_HINT decltype(auto) TransformTuple(TTuple< Types... > &&Tuple, FuncType Func)
Definition Tuple.h:847
decltype(auto) get(TupleType &&val)
Definition Tuple.h:940
UE_FORCEINLINE_HINT void VisitTupleElements(FuncType &&Func, FirstTupleType &&FirstTuple, TupleTypes &&... Tuples)
Definition Tuple.h:878
UE_FORCEINLINE_HINT TTuple< Types &&... > ForwardAsTuple(Types &&... Args)
Definition Tuple.h:819
UE_FORCEINLINE_HINT uint32 GetTypeHash(const TTuple< Types... > &Tuple)
Definition Tuple.h:702
UE_FORCEINLINE_HINT TTuple< Types &... > Tie(Types &... Args)
Definition Tuple.h:899
constexpr uint32 HashCombineFast(uint32 A, uint32 B)
Definition TypeHash.h:74
UE_FORCEINLINE_HINT uint32 GetTypeHashHelper(const T &V)
Definition TypeHash.h:215
UE_REWRITE constexpr bool operator>(const LhsType &Lhs, const RhsType &Rhs)
Definition UEOps.h:90
UE_REWRITE constexpr bool operator<=(const LhsType &Lhs, const RhsType &Rhs)
Definition UEOps.h:118
UE_REWRITE constexpr bool operator>=(const LhsType &Lhs, const RhsType &Rhs)
Definition UEOps.h:104
UE_INTRINSIC_CAST UE_REWRITE decltype(auto) ForwardAsBase(std::remove_reference_t< T > &Obj)
Definition UnrealTemplate.h:757
T && DeclVal()
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Core.Build.cs:8
Definition Archive.h:1208
Definition MemoryImageWriter.h:14
CORE_API void WriteObject(const void *Object, const FTypeLayoutDesc &TypeDesc)
Definition MemoryImage.cpp:2099
Definition MemoryImageWriter.h:78
Definition SecureHash.h:314
Definition StructuredArchiveSlots.h:52
UE_API FStructuredArchiveStream EnterStream()
Definition StructuredArchiveSlots.h:263
Definition StructuredArchiveSlots.h:193
UE_API FStructuredArchiveSlot EnterElement()
Definition StructuredArchiveSlots.h:462
Definition Array.h:3955
UE_NODEBUG void IntrinsicWriteMemoryImage(FMemoryImageWriter &Writer, const TArray< T, AllocatorType > &Object, const FTypeLayoutDesc &)
Definition Array.h:3957
CORE_API uint32 AppendHashPair(const FTypeLayoutDesc &KeyTypeDesc, const FTypeLayoutDesc &ValueTypeDesc, const FPlatformTypeLayoutParameters &LayoutParams, FSHA1 &Hasher)
Definition MemoryImage.cpp:869
UE_NODEBUG uint32 IntrinsicUnfrozenCopy(const FMemoryUnfreezeContent &Context, const TArray< T, AllocatorType > &Object, void *OutDst)
Definition Array.h:3963
UE_NODEBUG uint32 IntrinsicGetTargetAlignment(const TArray< T, AllocatorType > *DummyObject, const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams)
Definition Array.h:3976
CORE_API uint32 GetTargetAlignment(const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams)
Definition MemoryImage.cpp:408
UE_NODEBUG uint32 IntrinsicAppendHash(const TArray< T, AllocatorType > *DummyObject, const FTypeLayoutDesc &TypeDesc, const FPlatformTypeLayoutParameters &LayoutParams, FSHA1 &Hasher)
Definition Array.h:3970
FORCEINLINE T * Get(const FObjectPtr &ObjectPtr)
Definition ObjectPtr.h:426
Definition OverriddenPropertySet.cpp:45
void SerializeStructured(FStructuredArchive::FSlot Slot, TPagedArray< ElementType, PageSizeInBytes, AllocatorType > &InOutPagedArray)
Definition PagedArray.h:122
Definition Tuple.h:61
EForwardingConstructor
Definition Tuple.h:62
@ ForwardingConstructor
Definition Tuple.h:62
UE_FORCEINLINE_HINT constexpr TTuple< ElementTypes... > MakeTupleImpl(Types &&... Args)
Definition Tuple.h:510
EOtherTupleConstructor
Definition Tuple.h:63
@ OtherTupleConstructor
Definition Tuple.h:63
constexpr uint32 TTypeCountInParameterPack_V
Definition Tuple.h:66
bool operator==(const TPtrVariantBase< LhsType, bLhsStrength > &Lhs, const TPtrVariantBase< RhsType, bRhsStrength > &Rhs)
Definition PointerVariants.h:186
bool operator!=(const TPtrVariantBase< LhsType, bLhsStrength > &Lhs, const TPtrVariantBase< RhsType, bRhsStrength > &Rhs)
Definition PointerVariants.h:192
FORCEINLINE UE_STRING_CLASS RhsType && Rhs
Definition String.cpp.inl:718
Definition AdvancedWidgetsModule.cpp:13
bool operator<(const FPropertyTypeName &Lhs, const FPropertyTypeName &Rhs)
Definition PropertyTypeName.cpp:341
@ false
Definition radaudio_common.h:23
U16 Index
Definition radfft.cpp:71
Definition MemoryLayout.h:799
Definition MemoryLayout.h:108
Definition IntegerSequence.h:9
Definition Tuple.h:913
@ Value
Definition Tuple.h:914
Definition Tuple.h:752
Definition Tuple.h:652
TTuple(const TTuple< OtherTypes... > &Other)
Definition Tuple.h:673
TTuple(const TTuple &)=default
TTuple & operator=(TTuple &&)=default
TTuple(TTuple &&)=default
TTuple & operator=(const TTuple< OtherTypes... > &Other)
Definition Tuple.h:686
TTuple & operator=(const TTuple &)=default
constexpr TTuple()=default
TTuple & operator=(TTuple< OtherTypes... > &&Other)
Definition Tuple.h:694
TTuple(TTuple< OtherTypes... > &&Other)
Definition Tuple.h:666
static UE_FORCEINLINE_HINT bool Compare(const TupleType &Lhs, const TupleType &Rhs)
Definition Tuple.h:247
static UE_FORCEINLINE_HINT bool Compare(const TupleType &Lhs, const TupleType &Rhs)
Definition Tuple.h:237
decltype(Resolve(DeclVal< TTuple< TupleTypes... > * >())) Type
Definition Tuple.h:615
static constexpr uint32 Value
Definition Tuple.h:565
static UE_FORCEINLINE_HINT uint32 Do(uint32 Hash, const TupleType &Tuple)
Definition Tuple.h:643
static UE_FORCEINLINE_HINT uint32 Do(uint32 Hash, const TupleType &Tuple)
Definition Tuple.h:633
static UE_FORCEINLINE_HINT bool Do(const TupleType &Lhs, const TupleType &Rhs)
Definition Tuple.h:267
static UE_FORCEINLINE_HINT bool Do(const TupleType &Lhs, const TupleType &Rhs)
Definition Tuple.h:277
static UE_FORCEINLINE_HINT bool Do(const TupleType &Lhs, const TupleType &Rhs)
Definition Tuple.h:257
static decltype(auto) Do(TupleType &&Tuple, FuncType Func)
Definition Tuple.h:522
TTupleBaseElement(const TTupleBaseElement &)=default
TTupleBaseElement & operator=(const TTupleBaseElement &)=default
constexpr TTupleBaseElement()
Definition Tuple.h:102
TTupleBaseElement & operator=(TTupleBaseElement &&)=default
constexpr TTupleBaseElement(EForwardingConstructor, ArgType &&Arg)
Definition Tuple.h:97
TTupleBaseElement & operator=(TTupleBaseElement &&)=default
TTupleBaseElement(const TTupleBaseElement &)=default
constexpr TTupleBaseElement(EForwardingConstructor, ArgType &&Arg)
Definition Tuple.h:75
TTupleBaseElement & operator=(const TTupleBaseElement &)=default
TTupleBaseElement(TTupleBaseElement &&)=default
constexpr TTupleBaseElement()
Definition Tuple.h:80
UE_FORCEINLINE_HINT decltype(auto) Get() const &
Definition Tuple.h:308
UE_FORCEINLINE_HINT bool operator>=(const TTupleBase &Rhs) const
Definition Tuple.h:384
decltype(auto) ApplyBefore(FuncType &&Func, ArgTypes &&... Args) const &&
Definition Tuple.h:339
decltype(auto) ApplyAfter(FuncType &&Func, ArgTypes &&... Args) &&
Definition Tuple.h:329
UE_FORCEINLINE_HINT decltype(auto) Get() const volatile &&
Definition Tuple.h:314
constexpr TTupleBase(EForwardingConstructor, ArgTypes &&... Args)
Definition Tuple.h:290
static void SerializeStructured(FStructuredArchive::FSlot Slot, TTupleBase &Tuple)
Definition Tuple.h:350
UE_FORCEINLINE_HINT decltype(auto) Get() volatile &
Definition Tuple.h:309
decltype(auto) ApplyAfter(FuncType &&Func, ArgTypes &&... Args) const volatile &
Definition Tuple.h:328
UE_FORCEINLINE_HINT decltype(auto) Get() &
Definition Tuple.h:307
decltype(auto) ApplyAfter(FuncType &&Func, ArgTypes &&... Args) const &&
Definition Tuple.h:330
decltype(auto) ApplyBefore(FuncType &&Func, ArgTypes &&... Args) volatile &&
Definition Tuple.h:340
decltype(auto) ApplyBefore(FuncType &&Func, ArgTypes &&... Args) volatile &
Definition Tuple.h:336
static void Serialize(FArchive &Ar, TTupleBase &Tuple)
Definition Tuple.h:343
TTupleBase(EOtherTupleConstructor, TupleType &&Other)
Definition Tuple.h:296
UE_FORCEINLINE_HINT bool operator<(const TTupleBase &Rhs) const
Definition Tuple.h:369
UE_FORCEINLINE_HINT decltype(auto) Get() &&
Definition Tuple.h:311
UE_FORCEINLINE_HINT decltype(auto) Get() const &&
Definition Tuple.h:312
UE_FORCEINLINE_HINT decltype(auto) Get() const volatile &
Definition Tuple.h:310
UE_FORCEINLINE_HINT bool operator==(const TTupleBase &Rhs) const
Definition Tuple.h:358
UE_FORCEINLINE_HINT decltype(auto) Get() volatile &&
Definition Tuple.h:313
decltype(auto) ApplyAfter(FuncType &&Func, ArgTypes &&... Args) const &
Definition Tuple.h:326
decltype(auto) ApplyBefore(FuncType &&Func, ArgTypes &&... Args) const &
Definition Tuple.h:335
decltype(auto) ApplyAfter(FuncType &&Func, ArgTypes &&... Args) volatile &
Definition Tuple.h:327
decltype(auto) ApplyAfter(FuncType &&Func, ArgTypes &&... Args) volatile &&
Definition Tuple.h:331
decltype(auto) ApplyBefore(FuncType &&Func, ArgTypes &&... Args) const volatile &
Definition Tuple.h:337
decltype(auto) ApplyBefore(FuncType &&Func, ArgTypes &&... Args) &&
Definition Tuple.h:338
decltype(auto) ApplyAfter(FuncType &&Func, ArgTypes &&... Args) const volatile &&
Definition Tuple.h:332
decltype(auto) ApplyAfter(FuncType &&Func, ArgTypes &&... Args) &
Definition Tuple.h:325
UE_FORCEINLINE_HINT bool operator!=(const TTupleBase &Rhs) const
Definition Tuple.h:364
UE_FORCEINLINE_HINT bool operator>(const TTupleBase &Rhs) const
Definition Tuple.h:379
decltype(auto) ApplyBefore(FuncType &&Func, ArgTypes &&... Args) const volatile &&
Definition Tuple.h:341
decltype(auto) ApplyBefore(FuncType &&Func, ArgTypes &&... Args) &
Definition Tuple.h:334
UE_FORCEINLINE_HINT bool operator<=(const TTupleBase &Rhs) const
Definition Tuple.h:374
static decltype(auto) Get(TupleType &&Tuple)
Definition Tuple.h:176
static decltype(auto) GetImpl(const volatile TTupleBaseElement< DeducedType, Index, TupleSize > &Element, TupleType &&Tuple)
Definition Tuple.h:119
static UE_FORCEINLINE_HINT decltype(auto) Get(TupleType &&Tuple)
Definition Tuple.h:138
static UE_FORCEINLINE_HINT decltype(auto) Get(TupleType &&Tuple)
Definition Tuple.h:207
static UE_FORCEINLINE_HINT decltype(auto) GetImpl(const volatile TTupleBaseElement< Type, DeducedIndex, TupleSize > &, TupleType &&Tuple)
Definition Tuple.h:201
static void Do(FuncType &&Func, TupleTypes &&... Tuples)
Definition Tuple.h:543
static UE_FORCEINLINE_HINT void InvokeFunc(FuncType &&Func, TupleTypes &&... Tuples)
Definition Tuple.h:537
typename TTupleElement< N, TTuple< ArgTypes... > >::Type type
Definition Tuple.h:935