MCRO
C++23 utilities for Unreal Engine.
Loading...
Searching...
No Matches
Templates.h
Go to the documentation of this file.
1/** @noop License Comment
2 * @file
3 * @copyright
4 * This Source Code is subject to the terms of the Mozilla Public License, v2.0.
5 * If a copy of the MPL was not distributed with this file You can obtain one at
6 * https://mozilla.org/MPL/2.0/
7 *
8 * @author David Mórász
9 * @date 2025
10 */
11
12#pragma once
13
14#include "CoreMinimal.h"
15#include "Mcro/Concepts.h"
16
17/**
18 * @brief This namespace provides templating utilities and introspection into template instantiations.
19 */
21{
22 using namespace Mcro::Concepts;
23
24 namespace Detail
25 {
26 template <size_t I, typename First = void, typename... Rest>
28 {
29 using Type = typename TTypeAtPack_Impl<I - 1, Rest...>::Type;
30 };
31
32 template <typename First, typename... Rest>
33 struct TTypeAtPack_Impl<0, First, Rest...>
34 {
35 using Type = First;
36 };
37 }
38
39 template <size_t I, typename... T>
41 {
42 static_assert(I <= sizeof...(T), "Indexing parameter pack out of its bounds.");
43 using Type = typename Detail::TTypeAtPack_Impl<I, T...>::Type;
44 };
45
46 template <size_t I>
48 {
49 using Type = void;
50 };
51
52 /**
53 * @brief
54 * Get a specific item from a parameter pack at given index. It is an unspecified compile error to index an empty
55 * parameter pack.
56 */
57 template<size_t I, typename... Rest>
58 using TTypeAtPack = typename TTypeAtPack_Struct<I, Rest...>::Type;
59
60 /**
61 * @brief
62 * Get a specific item from the end of a parameter pack at given index (0 == last). It is an unspecified compile
63 * error to index an empty parameter pack.
64 */
65 template<size_t I, typename... Rest>
66 using TLastTypeAtPack = typename TTypeAtPack_Struct<sizeof...(Rest) - I, Rest...>::Type;
67
68 /**
69 * @brief
70 * Get a specific item from a parameter pack at given index disregarding CV-ref qualifiers. It is an unspecified
71 * compile error to index an empty parameter pack.
72 */
73 template<size_t I, typename... Rest>
74 using TTypeAtPackDecay = std::decay_t<typename TTypeAtPack_Struct<I, Rest...>::Type>;
75
76 /**
77 * @brief
78 * Get a specific item from the end of a parameter pack at given index (0 == last) disregarding CV-ref qualifiers.
79 * It is an unspecified compile error to index an empty parameter pack.
80 */
81 template<size_t I, typename... Rest>
82 using TLastTypeAtPackDecay = std::decay_t<typename TTypeAtPack_Struct<sizeof...(Rest) - I, Rest...>::Type>;
83
84 template <size_t I, typename T>
86 {
87 static_assert(sizeof(T) == 0, "TTupleSafeElement_Struct is instantiated with non TTuple.");
88 };
89
90 template <size_t I, typename... T>
91 struct TTupleSafeElement_Struct<I, TTuple<T...>>
92 {
93 using Type = TTypeAtPack<I, T...>;
94 };
95
96 /**
97 * @brief
98 * This template is used to store pack of types in other templates, or to allow parameter pack inference for
99 * functions. This template may be referred to as 'type-list' in other parts of the documentation.
100 *
101 * This may be much safer to use than tuples as they may try to use deleted features of listed types (especially
102 * Unreal tuples). `TTypes` will never attempt to use its arguments (not even in `decltype` or `declval` contexts)
103 */
104 template <typename... T>
105 struct TTypes
106 {
107 static constexpr size_t Count = sizeof...(T);
108
109 template <size_t I>
110 using Get = TTypeAtPack<I, T...>;
111
112 template <size_t I>
113 using GetDecay = TTypeAtPackDecay<I, T...>;
114 };
115
116 template <typename T>
117 struct TIsTypeList_Struct { static constexpr bool Value = false; };
118
119 template <typename... T>
120 struct TIsTypeList_Struct<TTypes<T...>> { static constexpr bool Value = true; };
121
122 /** @brief Concept constraining a given type to `TTypes` */
123 template <typename T>
125
126 template <CIsTypeList T, size_t I>
127 using TTypes_Get = T::template Get<I>;
128
129 template <CIsTypeList T, size_t I>
130 using TTypes_GetDecay = T::template GetDecay<I>;
131
132 /**
133 * @brief Base struct containing traits of specified template (which only accepts type parameters)
134 *
135 * @warning
136 * Until this proposal https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1985r0.pdf or equivalent is
137 * considered seriously, template traits only work with templates which only have type-parameters. Non-type
138 * parameters even when a default is specified for them will result in compile error.
139 */
140 template <template <typename...> typename Template>
142 {
143 template <typename T>
144 static constexpr bool Match = false;
145
146 template <typename... Params>
147 static constexpr bool Match<Template<Params...>> = true;
148
149 template <typename T>
150 static constexpr size_t ParameterCount = 0;
151
152 template <typename... Params>
153 static constexpr size_t ParameterCount<Template<Params...>> = sizeof...(Params);
154
155 template <typename T>
157 {
158 using Type = TTuple<>;
159 };
160
161 template <typename... Params>
162 struct Parameters<Template<Params...>>
163 {
164 using Type = TTuple<Params...>;
165 };
166
167 template <typename T>
169 {
170 using Type = TTuple<>;
171 };
172
173 template <typename... Params>
174 struct ParametersDecay<Template<Params...>>
175 {
176 using Type = TTuple<std::decay_t<Params>...>;
177 };
178
179 template <typename Instance, int I>
181
182 template <typename Instance, int I>
184 };
185
186 /**
187 * @brief Get template type parameters as a tuple
188 *
189 * @warning
190 * Until this proposal https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1985r0.pdf or equivalent is
191 * considered seriously, template traits only work with templates which only have type-parameters. Non-type
192 * parameters even when a default is specified for them will result in compile error.
193 */
194 template <template <typename...> typename Template, typename Instance>
195 using TTemplate_Params = typename TTemplate<Template>::template Parameters<Instance>::Type;
196
197 /**
198 * @brief Get decayed template type parameters as a tuple
199 *
200 * @warning
201 * Until this proposal https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1985r0.pdf or equivalent is
202 * considered seriously, template traits only work with templates which only have type-parameters. Non-type
203 * parameters even when a default is specified for them will result in compile error.
204 */
205 template <template <typename...> typename Template, typename Instance>
206 using TTemplate_ParamsDecay = typename TTemplate<Template>::template ParametersDecay<Instance>::Type;
207
208 /**
209 * @brief Get a type parameter at a specified position of a templated instance.
210 *
211 * @warning
212 * Until this proposal https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1985r0.pdf or equivalent is
213 * considered seriously, template traits only work with templates which only have type-parameters. Non-type
214 * parameters even when a default is specified for them will result in compile error.
215 */
216 template <template <typename...> typename Template, typename Instance, int I>
217 using TTemplate_Param = typename TTemplate<Template>::template Param<Instance, I>;
218
219 /**
220 * @brief Get a decayed type parameter at a specified position of a templated instance.
221 *
222 * @warning
223 * Until this proposal https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1985r0.pdf or equivalent is
224 * considered seriously, template traits only work with templates which only have type-parameters. Non-type
225 * parameters even when a default is specified for them will result in compile error.
226 */
227 template <template <typename...> typename Template, typename Instance, int I>
228 using TTemplate_ParamDecay = typename TTemplate<Template>::template ParamDecay<Instance, I>;
229
230 /**
231 * @brief Check if given type is an instantiation of a given template (which only accepts type parameters)
232 *
233 * @warning
234 * Until this proposal https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1985r0.pdf or equivalent is
235 * considered seriously, template traits only work with templates which only have type-parameters. Non-type
236 * parameters even when a default is specified for them will result in compile error.
237 */
238 template <typename Instance, template <typename...> typename Template>
239 concept CIsTemplate = TTemplate<Template>::template Match<std::decay_t<Instance>>;
240
241 /**
242 * @brief
243 * Get the number of template type parameters from a specified templated instance (which only has type parameters)
244 *
245 * @warning
246 * Until this proposal https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1985r0.pdf or equivalent is
247 * considered seriously, template traits only work with templates which only have type-parameters. Non-type
248 * parameters even when a default is specified for them will result in compile error.
249 */
250 template <template <typename...> typename Template, typename Instance>
251 inline constexpr size_t TTemplate_ParamCount = TTemplate<Template>::template ParameterCount<Instance>;
252
253 /** @brief Tired of typing `const_cast<FMyLongUnwieldyTypeName>(...)`? use this instead */
254 template <CConstType T>
255 constexpr auto&& AsConst(T&& input) { return FWD(input); }
256
257 /** @brief Tired of typing `const_cast<FMyLongUnwieldyTypeName>(...)`? use this instead */
258 template <CMutableType T>
259 constexpr auto&& AsConst(T&& input) { return FWD(const_cast<const T>(input)); }
260
261 /** @brief Tired of typing `const_cast<FMyLongUnwieldyTypeName>(...)`? use this instead */
262 template <CMutableType T>
263 constexpr auto&& AsMutable(T&& input) { return FWD(input); }
264
265 /** @brief Tired of typing `const_cast<FMyLongUnwieldyTypeName>(...)`? use this instead */
266 template <CConstType T>
267 constexpr auto&& AsMutable(T&& input) { return FWD(const_cast<T>(input)); }
268
269 /** @brief Tired of typing `const_cast<FMyLongUnwieldyTypeName*>(...)`? use this instead */
270 template <typename T>
271 constexpr auto AsConstPtr(const T* input) { return input; }
272
273 /** @brief Tired of typing `const_cast<FMyLongUnwieldyTypeName*>(...)`? use this instead */
274 template <typename T>
275 constexpr auto AsConstPtr(T* input) { return const_cast<const T*>(input); }
276
277 /** @brief Tired of typing `const_cast<FMyLongUnwieldyTypeName*>(...)`? use this instead */
278 template <typename T>
279 constexpr auto AsMutablePtr(T* input) { return input; }
280
281 /** @brief Tired of typing `const_cast<FMyLongUnwieldyTypeName*>(...)`? use this instead */
282 template <typename T>
283 constexpr auto AsMutablePtr(const T* input) { return const_cast<T*>(input); }
284}
This header exists because STL headers in Android doesn't define STL concepts (other than same_as whi...
#define FWD(...)
Shorten forwarding expression with this macro so one may not need to specify explicit type.
Definition Macros.h:100
Check if given type is an instantiation of a given template (which only accepts type parameters)
Definition Templates.h:239
Concept constraining a given type to TTypes
Definition Templates.h:124
This namespace provides templating utilities and introspection into template instantiations.
Definition Templates.h:21
typename TTypeAtPack_Struct< I, Rest... >::Type TTypeAtPack
Get a specific item from a parameter pack at given index. It is an unspecified compile error to index...
Definition Templates.h:58
typename TTemplate< Template >::template Parameters< Instance >::Type TTemplate_Params
Get template type parameters as a tuple.
Definition Templates.h:195
std::decay_t< typename TTypeAtPack_Struct< I, Rest... >::Type > TTypeAtPackDecay
Get a specific item from a parameter pack at given index disregarding CV-ref qualifiers....
Definition Templates.h:74
T::template Get< I > TTypes_Get
Definition Templates.h:127
std::decay_t< typename TTypeAtPack_Struct< sizeof...(Rest) - I, Rest... >::Type > TLastTypeAtPackDecay
Get a specific item from the end of a parameter pack at given index (0 == last) disregarding CV-ref q...
Definition Templates.h:82
typename TTypeAtPack_Struct< sizeof...(Rest) - I, Rest... >::Type TLastTypeAtPack
Get a specific item from the end of a parameter pack at given index (0 == last). It is an unspecified...
Definition Templates.h:66
constexpr auto AsMutablePtr(T *input)
Tired of typing const_cast<FMyLongUnwieldyTypeName*>(...)? use this instead.
Definition Templates.h:279
constexpr size_t TTemplate_ParamCount
Get the number of template type parameters from a specified templated instance (which only has type p...
Definition Templates.h:251
constexpr auto && AsMutable(T &&input)
Tired of typing const_cast<FMyLongUnwieldyTypeName>(...)? use this instead.
Definition Templates.h:263
T::template GetDecay< I > TTypes_GetDecay
Definition Templates.h:130
typename TTemplate< Template >::template Param< Instance, I > TTemplate_Param
Get a type parameter at a specified position of a templated instance.
Definition Templates.h:217
typename TTemplate< Template >::template ParametersDecay< Instance >::Type TTemplate_ParamsDecay
Get decayed template type parameters as a tuple.
Definition Templates.h:206
constexpr auto AsConstPtr(const T *input)
Tired of typing const_cast<FMyLongUnwieldyTypeName*>(...)? use this instead.
Definition Templates.h:271
constexpr auto && AsConst(T &&input)
Tired of typing const_cast<FMyLongUnwieldyTypeName>(...)? use this instead.
Definition Templates.h:255
typename TTemplate< Template >::template ParamDecay< Instance, I > TTemplate_ParamDecay
Get a decayed type parameter at a specified position of a templated instance.
Definition Templates.h:228
typename TTypeAtPack_Impl< I - 1, Rest... >::Type Type
Definition Templates.h:29
static constexpr bool Value
Definition Templates.h:117
Base struct containing traits of specified template (which only accepts type parameters)
Definition Templates.h:142
static constexpr size_t ParameterCount
Definition Templates.h:150
typename TTupleSafeElement_Struct< I, typename ParametersDecay< Instance >::Type >::Type ParamDecay
Definition Templates.h:183
typename TTupleSafeElement_Struct< I, typename Parameters< Instance >::Type >::Type Param
Definition Templates.h:180
static constexpr bool Match
Definition Templates.h:144
typename Detail::TTypeAtPack_Impl< I, T... >::Type Type
Definition Templates.h:43
This template is used to store pack of types in other templates, or to allow parameter pack inference...
Definition Templates.h:106
TTypeAtPack< I, T... > Get
Definition Templates.h:110
TTypeAtPackDecay< I, T... > GetDecay
Definition Templates.h:113
static constexpr size_t Count
Definition Templates.h:107