UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
UnrealTypeTraits.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3/*=============================================================================
4 UnrealTypeTraits.h: Unreal type traits definitions.
5 Note: Boost does a much better job of limiting instantiations.
6 We require VC8 so a lot of potential version checks are omitted.
7=============================================================================*/
8
9#pragma once
10
11#include "CoreTypes.h"
12#include "Templates/IsPointer.h"
14#include "Templates/AndOrNot.h"
15#include "Templates/EnableIf.h"
17#include "Templates/IsEnum.h"
18#include "Templates/Models.h"
19
20#include "Templates/IsPODType.h"
23
24/*-----------------------------------------------------------------------------
25 * Macros to abstract the presence of certain compiler intrinsic type traits
26 -----------------------------------------------------------------------------*/
27#define HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T)
28#define IS_POD(T) __is_pod(T)
29#define IS_EMPTY(T) __is_empty(T)
30
31
32/*-----------------------------------------------------------------------------
33 Type traits similar to TR1 (uses intrinsics supported by VC8)
34 Should be updated/revisited/discarded when compiler support for tr1 catches up.
35 -----------------------------------------------------------------------------*/
36
38template<typename DerivedType, typename BaseType>
40{
41 // Different size types so we can compare their sizes later.
42 typedef char No[1];
43 typedef char Yes[2];
44
45 // Overloading Test() s.t. only calling it with something that is
46 // a BaseType (or inherited from the BaseType) will return a Yes.
47 static Yes& Test( BaseType* );
48 static Yes& Test( const BaseType* );
49 static No& Test( ... );
50
51 // Makes a DerivedType ptr.
52 static DerivedType* DerivedTypePtr(){ return nullptr ;}
53
54 public:
55 // Test the derived type pointer. If it inherits from BaseType, the Test( BaseType* )
56 // will be chosen. If it does not, Test( ... ) will be chosen.
57 static constexpr bool Value = sizeof(Test( DerivedTypePtr() )) == sizeof(Yes);
58
59 static constexpr bool IsDerived = Value;
60};
61
63template <int32 N, typename... Types>
65
66template <int32 N, typename T, typename... OtherTypes>
68{
69 using Type = typename TNthTypeFromParameterPack<N - 1, OtherTypes...>::Type;
70};
71
72template <typename T, typename... OtherTypes>
74{
75 using Type = T;
76};
77
81template<typename T>
83{
84 template <typename CharType = TCHAR>
85 inline static constexpr decltype(auto) GetFormatSpecifier()
86 {
87 // Force the template instantiation to be dependent upon T so the compiler cannot automatically decide that this template can never be instantiated.
88 // If the static_assert below were a constant 0 or something not dependent on T, compilers are free to detect this and fail to compile the template.
89 // As specified in the C++ standard s14.6p8. A compiler is free to give a diagnostic here or not. MSVC ignores it, and clang/gcc instantiates the
90 // template and triggers the static_assert.
91 static_assert(sizeof(T) < 0, "Format specifier not supported for this type."); // request for a format specifier for a type we do not know about
92 return CHARTEXT(CharType, "Unknown"); \
93 }
94};
95#define Expose_TFormatSpecifier(type, format) \
96template<> \
97struct TFormatSpecifier<type> \
98{ \
99 template <typename CharType = TCHAR> \
100 UE_FORCEINLINE_HINT static constexpr decltype(auto) GetFormatSpecifier() \
101 { \
102 return CHARTEXT(CharType, format); \
103 } \
104};
105
115Expose_TFormatSpecifier(float, "%f")
117Expose_TFormatSpecifier(long double, "%f")
119Expose_TFormatSpecifier(unsigned long, "%lu")
120
121
126template<typename T> struct TIsReferenceType<T&> { enum { Value = true }; };
127template<typename T> struct TIsReferenceType<T&&> { enum { Value = true }; };
128
132template<typename T> struct TIsLValueReferenceType { enum { Value = false }; };
133template<typename T> struct TIsLValueReferenceType<T&> { enum { Value = true }; };
134
138template<typename T> struct TIsRValueReferenceType { enum { Value = false }; };
139template<typename T> struct TIsRValueReferenceType<T&&> { enum { Value = true }; };
140
144template<typename T>
146{
147 enum { Value = TIsArithmetic<T>::Value || std::is_void_v<T> };
148};
149
155template <typename T>
157{
158 enum { Value = false };
159};
160
161template <typename RetType, typename... Params>
162struct TIsFunction<RetType(Params...)>
163{
164 enum { Value = true };
165};
166
170template<typename T>
175
179template<typename T>
181{
182 enum { Value = false };
183};
184
185
189template<typename T>
191{
192 inline static TCHAR const* GetName()
193 {
194 check(0); // request for the name of a type we do not know about
195 return TEXT("Unknown");
196 }
197};
198
199#define Expose_TNameOf(type) \
200template<> \
201struct TNameOf<type> \
202{ \
203 UE_FORCEINLINE_HINT static TCHAR const* GetName() \
204 { \
205 return TEXT(#type); \
206 } \
207};
208
217Expose_TNameOf(float)
218Expose_TNameOf(double)
219
220/*-----------------------------------------------------------------------------
221 Call traits - Modeled somewhat after boost's interfaces.
222-----------------------------------------------------------------------------*/
223
224
227template <typename T, bool TypeIsSmall>
229{
230 typedef const T& ParamType;
231 typedef const T& ConstParamType;
232};
233template <typename T>
235{
236 typedef const T ParamType;
237 typedef const T ConstParamType;
238};
239template <typename T>
241{
242 typedef T* ParamType;
243 typedef const T* ConstParamType;
244};
245
246
247/*-----------------------------------------------------------------------------
248 Helper templates for dealing with 'const' in template code
249-----------------------------------------------------------------------------*/
250
251/*-----------------------------------------------------------------------------
252 * TCallTraits
253 *
254 * Same call traits as boost, though not with as complete a solution.
255 *
256 * The main member to note is ParamType, which specifies the optimal
257 * form to pass the type as a parameter to a function.
258 *
259 * Has a small-value optimization when a type is a POD type and as small as a pointer.
260-----------------------------------------------------------------------------*/
261
265template <typename T>
267{
268private:
269 enum { PassByValue = TOr<TAndValue<(sizeof(T) <= sizeof(void*)), TIsPODType<T>>, TIsArithmetic<T>>::Value };
270
271public:
272 typedef T ValueType;
273 typedef T& Reference;
274 typedef const T& ConstReference;
277};
278
282template <typename T>
283struct TCallTraits : public TCallTraitsBase<T> {};
284
285// Fix reference-to-reference problems.
286template <typename T>
287struct TCallTraits<T&>
288{
289 typedef T& ValueType;
290 typedef T& Reference;
291 typedef const T& ConstReference;
292 typedef T& ParamType;
294};
295
296// Array types
297template <typename T, size_t N>
298struct TCallTraits<T [N]>
299{
300private:
301 typedef T ArrayType[N];
302public:
303 typedef const T* ValueType;
304 typedef ArrayType& Reference;
305 typedef const ArrayType& ConstReference;
306 typedef const T* const ParamType;
307 typedef const T* const ConstPointerType;
308};
309
310// const array types
311template <typename T, size_t N>
312struct TCallTraits<const T [N]>
313{
314private:
315 typedef const T ArrayType[N];
316public:
317 typedef const T* ValueType;
318 typedef ArrayType& Reference;
319 typedef const ArrayType& ConstReference;
320 typedef const T* const ParamType;
321 typedef const T* const ConstPointerType;
322};
323
324
325/*-----------------------------------------------------------------------------
326 Traits for our particular container classes
327-----------------------------------------------------------------------------*/
328
333template<typename T>
335{
338
339 // There's no good way of detecting this so we'll just assume it to be true for certain known types and expect
340 // users to customize it for their custom types.
341 enum { IsBytewiseComparable = TOr<TIsEnum<T>, TIsArithmetic<T>, TIsPointer<T>>::Value };
342};
343
347template<typename T> struct TTypeTraits : public TTypeTraitsBase<T> {};
348
349
351{
353};
354
355template <typename T, typename U>
357{
358 // Param type is not an const lvalue reference, which means it's pass-by-value, so we should just provide a single type for copying.
359 // Move overloads will be ignored due to SFINAE.
360 typedef U Copy;
361};
362
363template <typename T>
364struct TMoveSupportTraitsBase<T, const T&>
365{
366 // Param type is a const lvalue reference, so we can provide an overload for moving.
367 typedef const T& Copy;
368 typedef T&& Move;
369};
370
390template <typename T>
391struct TMoveSupportTraits : TMoveSupportTraitsBase<T, typename TCallTraits<T>::ParamType>
392{
393};
394
408template <typename T, typename Arg>
410{
411 static_assert(
414 "TIsBitwiseConstructible is not designed to accept reference types");
415
416 static_assert(
417 std::is_same_v<T, std::remove_cv_t<T >> &&
418 std::is_same_v<Arg, std::remove_cv_t<Arg>>,
419 "TIsBitwiseConstructible is not designed to accept qualified types");
420
421 // Assume no bitwise construction in general
422 enum { Value = false };
423};
424
425template <typename T>
427{
428 // Ts can always be bitwise constructed from itself if it is trivially copyable.
430};
431
432template <typename T, typename U>
434{
435 // Constructing a const T is the same as constructing a T
436};
437
438// Const pointers can be bitwise constructed from non-const pointers.
439// This is not true for pointer conversions in general, e.g. where an offset may need to be applied in the case
440// of multiple inheritance, but there is no way of detecting that at compile-time.
441template <typename T>
442struct TIsBitwiseConstructible<const T*, T*>
443{
444 // Constructing a const T is the same as constructing a T
445 enum { Value = true };
446};
447
448// Unsigned types can be bitwise converted to their signed equivalents, and vice versa.
449// (assuming two's-complement, which we are)
450template <> struct TIsBitwiseConstructible<uint8, int8> { enum { Value = true }; };
451template <> struct TIsBitwiseConstructible< int8, uint8> { enum { Value = true }; };
452template <> struct TIsBitwiseConstructible<uint16, int16> { enum { Value = true }; };
453template <> struct TIsBitwiseConstructible< int16, uint16> { enum { Value = true }; };
454template <> struct TIsBitwiseConstructible<uint32, int32> { enum { Value = true }; };
455template <> struct TIsBitwiseConstructible< int32, uint32> { enum { Value = true }; };
456template <> struct TIsBitwiseConstructible<uint64, int64> { enum { Value = true }; };
457template <> struct TIsBitwiseConstructible< int64, uint64> { enum { Value = true }; };
458
459// ANSICHAR can be bitwise converted to a byte or UTF8CHAR
460// conversions in the other direction (to ANSICHAR) are not generally safe
461template <> struct TIsBitwiseConstructible< int8, ANSICHAR> { enum { Value = true }; };
462template <> struct TIsBitwiseConstructible<uint8, ANSICHAR> { enum { Value = true }; };
463template <> struct TIsBitwiseConstructible<UTF8CHAR, ANSICHAR> { enum { Value = true }; };
464
465// UTF8CHAR can be bitwise converted to a byte
466// conversions in the other direction (to UTF8CHAR) are not generally safe
467template <> struct TIsBitwiseConstructible< int8, UTF8CHAR> { enum { Value = true }; };
468template <> struct TIsBitwiseConstructible<uint8, UTF8CHAR> { enum { Value = true }; };
469
470#define GENERATE_MEMBER_FUNCTION_CHECK(MemberName, Result, ConstModifier, ...) \
471template <typename T> \
472class THasMemberFunction_##MemberName \
473{ \
474 template <typename U, Result(U::*)(__VA_ARGS__) ConstModifier> struct Check; \
475 template <typename U> static char MemberTest(Check<U, &U::MemberName> *); \
476 template <typename U> static int MemberTest(...); \
477public: \
478 enum { Value = sizeof(MemberTest<T>(nullptr)) == sizeof(char) }; \
479};
480
481/*-----------------------------------------------------------------------------
482 * Undef Macros abstracting the presence of certain compiler intrinsic type traits
483 -----------------------------------------------------------------------------*/
484#undef IS_EMPTY
485#undef IS_POD
486#undef HAS_TRIVIAL_CONSTRUCTOR
487
488#if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_5
489#include "Templates/Requires.h"
490#endif
#define check(expr)
Definition AssertionMacros.h:314
FPlatformTypes::int16 int16
A 16-bit signed integer.
Definition Platform.h:1123
FPlatformTypes::int8 int8
An 8-bit signed integer.
Definition Platform.h:1121
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
#define CHARTEXT(CharType, x)
Definition Platform.h:1291
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
FPlatformTypes::UTF8CHAR UTF8CHAR
An 8-bit character containing a UTF8 (Unicode, 8-bit, variable-width) code unit.
Definition Platform.h:1137
FPlatformTypes::ANSICHAR ANSICHAR
An ANSI character. Normally a signed type.
Definition Platform.h:1131
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
return true
Definition ExternalRpcRegistry.cpp:601
#define Expose_TNameOf(type)
Definition UnrealTypeTraits.h:199
#define Expose_TFormatSpecifier(type, format)
Definition UnrealTypeTraits.h:95
uint8_t uint8
Definition binka_ue_file_header.h:8
uint16_t uint16
Definition binka_ue_file_header.h:7
uint32_t uint32
Definition binka_ue_file_header.h:6
FUniformParams Params
Definition MeshPaintVirtualTexture.cpp:162
Definition TestUtils.cpp:8
Definition UnrealTypeTraits.h:351
virtual ~FVirtualDestructor()
Definition UnrealTypeTraits.h:352
Definition AndOrNot.h:15
Definition UnrealTypeTraits.h:267
TCallTraitsParamTypeHelper< T, PassByValue >::ConstParamType ConstPointerType
Definition UnrealTypeTraits.h:276
TCallTraitsParamTypeHelper< T, PassByValue >::ParamType ParamType
Definition UnrealTypeTraits.h:275
T ValueType
Definition UnrealTypeTraits.h:272
const T & ConstReference
Definition UnrealTypeTraits.h:274
T & Reference
Definition UnrealTypeTraits.h:273
const T ParamType
Definition UnrealTypeTraits.h:236
const T ConstParamType
Definition UnrealTypeTraits.h:237
const T * ConstParamType
Definition UnrealTypeTraits.h:243
T * ParamType
Definition UnrealTypeTraits.h:242
Definition UnrealTypeTraits.h:229
const T & ParamType
Definition UnrealTypeTraits.h:230
const T & ConstParamType
Definition UnrealTypeTraits.h:231
T & Reference
Definition UnrealTypeTraits.h:290
T & ConstPointerType
Definition UnrealTypeTraits.h:293
T & ValueType
Definition UnrealTypeTraits.h:289
const T & ConstReference
Definition UnrealTypeTraits.h:291
T & ParamType
Definition UnrealTypeTraits.h:292
const T *const ParamType
Definition UnrealTypeTraits.h:306
const ArrayType & ConstReference
Definition UnrealTypeTraits.h:305
ArrayType & Reference
Definition UnrealTypeTraits.h:304
const T *const ConstPointerType
Definition UnrealTypeTraits.h:307
const T * ValueType
Definition UnrealTypeTraits.h:303
const T *const ConstPointerType
Definition UnrealTypeTraits.h:321
ArrayType & Reference
Definition UnrealTypeTraits.h:318
const T *const ParamType
Definition UnrealTypeTraits.h:320
const T * ValueType
Definition UnrealTypeTraits.h:317
const ArrayType & ConstReference
Definition UnrealTypeTraits.h:319
Definition UnrealTypeTraits.h:283
Definition UnrealTypeTraits.h:83
static constexpr decltype(auto) GetFormatSpecifier()
Definition UnrealTypeTraits.h:85
Definition IsArithmetic.h:12
Definition UnrealTypeTraits.h:410
@ Value
Definition UnrealTypeTraits.h:422
Definition UnrealTypeTraits.h:40
char Yes[2]
Definition UnrealTypeTraits.h:43
static Yes & Test(BaseType *)
char No[1]
Definition UnrealTypeTraits.h:42
static constexpr bool Value
Definition UnrealTypeTraits.h:57
static No & Test(...)
static Yes & Test(const BaseType *)
static DerivedType * DerivedTypePtr()
Definition UnrealTypeTraits.h:52
static constexpr bool IsDerived
Definition UnrealTypeTraits.h:59
Definition UnrealTypeTraits.h:157
@ Value
Definition UnrealTypeTraits.h:158
Definition UnrealTypeTraits.h:146
@ Value
Definition UnrealTypeTraits.h:147
Definition UnrealTypeTraits.h:132
@ Value
Definition UnrealTypeTraits.h:132
Definition IsPODType.h:12
Definition IsPointer.h:12
Definition UnrealTypeTraits.h:138
@ Value
Definition UnrealTypeTraits.h:138
Definition UnrealTypeTraits.h:125
Definition IsTriviallyCopyConstructible.h:13
Definition UnrealTypeTraits.h:181
@ Value
Definition UnrealTypeTraits.h:182
Definition UnrealTypeTraits.h:172
T && Move
Definition UnrealTypeTraits.h:368
const T & Copy
Definition UnrealTypeTraits.h:367
Definition UnrealTypeTraits.h:357
U Copy
Definition UnrealTypeTraits.h:360
Definition UnrealTypeTraits.h:392
Definition UnrealTypeTraits.h:191
static TCHAR const * GetName()
Definition UnrealTypeTraits.h:192
T Type
Definition UnrealTypeTraits.h:75
typename TNthTypeFromParameterPack< N - 1, OtherTypes... >::Type Type
Definition UnrealTypeTraits.h:69
Definition UnrealTypeTraits.h:64
Definition AndOrNot.h:43
Definition UnrealTypeTraits.h:335
TCallTraits< T >::ParamType ConstInitType
Definition UnrealTypeTraits.h:336
TCallTraits< T >::ConstPointerType ConstPointerType
Definition UnrealTypeTraits.h:337
Definition UnrealTypeTraits.h:347