MCRO
C++23 utilities for Unreal Engine.
Loading...
Searching...
No Matches
Inheritance.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/Templates.h"
16#include "Mcro/FunctionTraits.h"
17
19{
20 using namespace Mcro::Templates;
21 using namespace Mcro::FunctionTraits;
22
23 /**
24 * @brief
25 * Some MCRO utilities allow for intrusive method of declaring inheritance which can be later used to reflect
26 * upon base classes of a derived type.
27 */
28 template <typename T>
29 concept CHasBases = CIsTypeList<typename T::Bases>;
30
31 namespace Detail
32 {
33 template <CIsTypeList Bases, typename Function>
34 constexpr void ForEachExplicitBase(Function&& function);
35
36 template <typename T, typename Function>
37 constexpr void ForEachExplicitBase_Body(Function&& function)
38 {
39 function.template operator()<T> ();
40 if constexpr (CHasBases<T>)
41 ForEachExplicitBase<typename T::Bases>(FWD(function));
42 }
43
44 template <CIsTypeList Bases, typename Function, size_t... Indices>
45 constexpr void ForEachExplicitBase_Impl(Function&& function, std::index_sequence<Indices...>&&)
46 {
47 (ForEachExplicitBase_Body<TTypes_Get<Bases, Indices>>(FWD(function)), ...);
48 }
49
50 template <CIsTypeList Bases, typename Function>
51 constexpr void ForEachExplicitBase(Function&& function)
52 {
53 ForEachExplicitBase_Impl<Bases>(
54 FWD(function),
55 std::make_index_sequence<Bases::Count>()
56 );
57 }
58 }
59
60 /**
61 * @brief
62 * Operate on each of the explicitly listed base classes of a given type with a lambda function template. If any
63 * given type also happens to match `CHasBases`, iterate on their base types too recursively. Works directly with
64 * `CHasBases` or type lists (`CIsTypeList`).
65 *
66 * Usage:
67 * @code
68 * class FMyClass : public TInherit<FFoo, FBar>
69 * {...}
70 *
71 * ForEachExplicitBase<FMyClass>([] <typename T> ()
72 * {
73 * UE_LOG(LogTemp, Display, TEXT_"%s", *TTypeString<T>())
74 * });
75 * @endcode
76 *
77 * @tparam T A type which uses TInherit or has a TTypes list member-aliased as Bases
78 * @tparam Function Type of per-base operation
79 * @param function Per-base operation
80 */
81 template <typename T, typename Function>
82 requires (CHasBases<T> || CIsTypeList<T>)
83 constexpr void ForEachExplicitBase(Function&& function)
84 {
85 if constexpr (CHasBases<T>)
87 if constexpr (CIsTypeList<T>)
89 }
90
91 template <typename T, typename Bases>
92 requires (CHasBases<Bases> || CIsTypeList<Bases>)
93 constexpr bool HasExplicitBase()
94 {
95 bool valid = false;
96 ForEachExplicitBase<T>([&] <typename Base> ()
97 {
98 if constexpr (CSameAsDecayed<T, Base>)
99 valid = true;
100 });
101 return valid;
102 }
103
104 template <typename T, typename Bases>
105 concept CHasExplicitBase = (CHasBases<Bases> || CIsTypeList<Bases>)
107 ;
108
109 /**
110 * @brief
111 * Inherit via this template to allow other API to reflect upon the base types of deriving class. Base types are
112 * inherited as public. If you want privately inherited base classes, just inherit them as normal.
113 *
114 * Usage:
115 * @code
116 * class FMyThing : public TInherit<IFoo, IBar, IEtc>
117 * {
118 * // ...
119 * }
120 * @endcode
121 */
122 template <typename... BaseTypes>
123 class TInherit : public BaseTypes...
124 {
125 public:
126 using Bases = TTypes<BaseTypes...>;
127
128 /**
129 * @brief
130 * Operate on each of the explicit base class of this type with a lambda function template. If any given type
131 * also happens to match CHasBases, iterate on their base types too recursively
132 *
133 * This is the same as `ForEachExplicitBase` but for object instances of this type.
134 *
135 * Usage:
136 * @code
137 * class FMyClass : public TInherit<FFoo, FBar>
138 * {...}
139 *
140 * FMyClass value;
141 *
142 * value.ForEachBase([] <typename T> ()
143 * {
144 * UE_LOG(LogTemp, Display, TEXT_"%s", *TTypeString<T>())
145 * });
146 * @endcode
147 *
148 * @tparam Self deducing this
149 * @tparam Function Type of per-base operation
150 * @param function Per-base operation
151 */
152 template <typename Self, typename Function>
153 constexpr void ForEachBase(this Self&&, Function&& function)
154 {
156 }
157 };
158}
#define FWD(...)
Shorten forwarding expression with this macro so one may not need to specify explicit type.
Definition Macros.h:100
Inherit via this template to allow other API to reflect upon the base types of deriving class....
constexpr void ForEachBase(this Self &&, Function &&function)
Operate on each of the explicit base class of this type with a lambda function template....
Some MCRO utilities allow for intrusive method of declaring inheritance which can be later used to re...
Definition Inheritance.h:29
constexpr void ForEachExplicitBase_Body(Function &&function)
Definition Inheritance.h:37
constexpr void ForEachExplicitBase_Impl(Function &&function, std::index_sequence< Indices... > &&)
Definition Inheritance.h:45
constexpr void ForEachExplicitBase(Function &&function)
Definition Inheritance.h:51
constexpr bool HasExplicitBase()
Definition Inheritance.h:93
constexpr void ForEachExplicitBase(Function &&function)
Operate on each of the explicitly listed base classes of a given type with a lambda function template...
Definition Inheritance.h:83
This namespace provides templating utilities and introspection into template instantiations.
Definition Templates.h:21
This template is used to store pack of types in other templates, or to allow parameter pack inference...
Definition Templates.h:106