UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
StaticAssertCompleteType.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"
6#include <utility>
7
9{
10 class FIncompleteType;
11
12#if defined(__clang__) || defined(__GNUC__)
13 // Under Clang, a zero-sized array cannot be used in a template specialization, and also under GCC cannot be used as a function overload
14 // or used with traits like std::is_array or std::remove_extent.
15 // Testing for sizeof(T) == 0 works though, and should be the only type this is true for, then operator+ is used to coerce this into a
16 // pointer and dereferenced to give a reference which can be used to check the completeness of the element type of the array.
17 template <typename T, SIZE_T SizeOfT = sizeof(T)>
19 {
20 static T& Func();
21 };
22 template <typename T>
24 {
25 static decltype(*+std::declval<T>())& Func();
26 };
27#else
28 // The above trick doesn't work for zero-sized arrays under MSVC, where sizeof(T[0]) is illegal, but specialization does.
29 template <typename T>
31 {
32 static T& Func();
33 };
34 template <typename T>
36 {
37 static T& Func();
38 };
39#endif
40
41 template <typename T>
45
46 // Voids will give an unhelpful error message when trying to take a reference to them, so work around it
47 template <> struct TUEStaticAssertTypeChecker< void> { static FIncompleteType Func(); };
48 template <> struct TUEStaticAssertTypeChecker<const void> { static FIncompleteType Func(); };
49 template <> struct TUEStaticAssertTypeChecker<volatile void> { static FIncompleteType Func(); };
50 template <> struct TUEStaticAssertTypeChecker<const volatile void> { static FIncompleteType Func(); };
51
52 // References are always complete types, but as we're using sizeof to check and sizeof ignores
53 // references, let's just return a known complete type to make it work.
54 template <typename T> struct TUEStaticAssertTypeChecker<T&> { static int Func(); };
55 template <typename T> struct TUEStaticAssertTypeChecker<T&&> { static int Func(); };
56
57 // Function types are complete types, but we can't form a reference to one, so let's just make those work too
58 template <typename RetType, typename... ArgTypes> struct TUEStaticAssertTypeChecker<RetType(ArgTypes...)> { static int Func(); };
59}
60
61// Causes a compile error if a type is incomplete
62#define UE_STATIC_ASSERT_COMPLETE_TYPE(TypeToCheck, ...) static_assert(sizeof(UEStaticAssertCompleteType_Private::TUEStaticAssertTypeChecker<TypeToCheck>::Func()), ##__VA_ARGS__)
63
64// Tests
65
66// Each of these should fail to compile
67#if 0
68 UE_STATIC_ASSERT_COMPLETE_TYPE( void, "CV void is incomplete");
69 UE_STATIC_ASSERT_COMPLETE_TYPE( volatile void, "CV void is incomplete");
70 UE_STATIC_ASSERT_COMPLETE_TYPE(const void, "CV void is incomplete");
71 UE_STATIC_ASSERT_COMPLETE_TYPE(const volatile void, "CV void is incomplete");
72 UE_STATIC_ASSERT_COMPLETE_TYPE(UEStaticAssertCompleteType_Private::FIncompleteType, "A forward-declared-but-undefined class is incomplete");
73 UE_STATIC_ASSERT_COMPLETE_TYPE(UEStaticAssertCompleteType_Private::FIncompleteType[2], "An array of an incomplete class is incomplete");
74 UE_STATIC_ASSERT_COMPLETE_TYPE(int[], "An array of a complete type of unspecified bound is incomplete");
75 UE_STATIC_ASSERT_COMPLETE_TYPE(UEStaticAssertCompleteType_Private::FIncompleteType[0], "A zero-sized array of an incomplete type is incomplete");
76#endif
77
78// Each of these should pass
79#if 0
80 UE_STATIC_ASSERT_COMPLETE_TYPE(UEStaticAssertCompleteType_Private::FIncompleteType*, "A pointer to an incomplete type is complete");
81 UE_STATIC_ASSERT_COMPLETE_TYPE(UEStaticAssertCompleteType_Private::FIncompleteType&, "A reference to an incomplete type is complete");
82 UE_STATIC_ASSERT_COMPLETE_TYPE(UEStaticAssertCompleteType_Private::FIncompleteType (UEStaticAssertCompleteType_Private::FIncompleteType), "A function type is not incomplete, even if it returns or takes an incomplete type");
83 UE_STATIC_ASSERT_COMPLETE_TYPE(UEStaticAssertCompleteType_Private::FIncompleteType(&)(UEStaticAssertCompleteType_Private::FIncompleteType), "References to function types must give a good error");
84 UE_STATIC_ASSERT_COMPLETE_TYPE(int[0], "A zero-sized array of a complete type is complete");
85#endif
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define UE_STATIC_ASSERT_COMPLETE_TYPE(TypeToCheck,...)
Definition StaticAssertCompleteType.h:62
Definition StaticAssertCompleteType.h:9