Ark Server API (ASA) - Wiki
Loading...
Searching...
No Matches
EnumRange.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
7/**
8 * Defines a contiguous enum range containing Count values, starting from zero:
9 *
10 * Example:
11 *
12 * enum class ECountedThing
13 * {
14 * First,
15 * Second,
16 * Third,
17 *
18 * Count
19 * };
20 *
21 * // Defines iteration over ECountedThing to be: First, Second, Third
22 * ENUM_RANGE_BY_COUNT(ECountedThing, ECountedThing::Count)
23 */
24#define ENUM_RANGE_BY_COUNT(EnumType, Count) ENUM_RANGE_BY_FIRST_AND_LAST(EnumType, 0, (__underlying_type(EnumType))(Count) - 1)
25
26
27/**
28 * Defines a contiguous enum range with specific start and end values:
29 *
30 * Example:
31 *
32 * enum class EDoubleEndedThing
33 * {
34 * Invalid,
35 *
36 * First,
37 * Second,
38 * Third,
39 *
40 * Count
41 * };
42 *
43 * // Defines iteration over EDoubleEndedThing to be: First, Second, Third
44 * ENUM_RANGE_BY_FIRST_AND_LAST(EDoubleEndedThing, EDoubleEndedThing::First, EDoubleEndedThing::Third)
45 */
46#define ENUM_RANGE_BY_FIRST_AND_LAST(EnumType, First, Last)
47 template <>
48 struct NEnumRangePrivate::TEnumRangeTraits<EnumType>
49 {
50 enum { RangeType = 0 };
51 static constexpr __underlying_type(EnumType) Begin = (__underlying_type(EnumType))(First);
52 static constexpr __underlying_type(EnumType) End = (__underlying_type(EnumType))(Last) + 1;
53 };
54
55
56/**
57 * Defines a non-contiguous enum range with specific individual values:
58 *
59 * Example:
60 *
61 * enum class ERandomValuesThing
62 * {
63 * First = 2,
64 * Second = 3,
65 * Third = 5,
66 * Fourth = 7,
67 * Fifth = 11
68 * };
69 *
70 * // Defines iteration over ERandomValuesThing to be: First, Second, Third, Fourth, Fifth
71 * ENUM_RANGE_BY_VALUES(ERandomValuesThing, ERandomValuesThing::First, ERandomValuesThing::Second, ERandomValuesThing::Third, ERandomValuesThing::Fourth, ERandomValuesThing::Fifth)
72 */
73#define ENUM_RANGE_BY_VALUES(EnumType, ...)
74 template <>
75 struct NEnumRangePrivate::TEnumRangeTraits<EnumType>
76 {
77 enum { RangeType = 1 };
78 template <typename Dummy>
79 static const EnumType* GetPointer(bool bLast)
80 {
81 static constexpr EnumType Values[] = { __VA_ARGS__ };
82 return bLast ? Values + sizeof(Values) / sizeof(EnumType) : Values;
83 }
84 };
85
86
88{
89 template <typename EnumType>
91 {
92 enum { RangeType = -1 };
93 };
94
95 template <typename EnumType, int32 RangeType>
97 {
98 static_assert(sizeof(EnumType) == 0, "Unknown enum type - use one of the ENUM_RANGE macros to define iteration semantics for your enum type.");
99 };
100
101 template <typename EnumType>
103 {
104 typedef __underlying_type(EnumType) IntType;
105
107 : Value(InValue)
108 {
109 }
110
112 {
113 ++Value;
114 return *this;
115 }
116
117 FORCEINLINE EnumType operator*() const
118 {
119 return (EnumType)Value;
120 }
121
122 private:
124
126 {
127 return Lhs.Value != Rhs.Value;
128 }
129 };
130
131 template <typename EnumType>
133 {
134 FORCEINLINE explicit TEnumValueArrayIterator(const EnumType* InPtr)
135 : Ptr(InPtr)
136 {
137 }
138
140 {
141 ++Ptr;
142 return *this;
143 }
144
145 FORCEINLINE EnumType operator*() const
146 {
147 return *Ptr;
148 }
149
150 private:
151 const EnumType* Ptr;
152
154 {
155 return Lhs.Ptr != Rhs.Ptr;
156 }
157 };
158
159 template <typename EnumType>
160 struct TEnumRange_Impl<EnumType, 0>
161 {
164 };
165
166 template <typename EnumType>
167 struct TEnumRange_Impl<EnumType, 1>
168 {
170 TEnumValueArrayIterator<EnumType> end () const { return TEnumValueArrayIterator<EnumType>(TEnumRangeTraits<EnumType>::template GetPointer<void>(true )); }
171 };
172}
173
174namespace UE::EnumFlags::Private
175{
176 template <typename EnumType>
178 {
179 typedef __underlying_type(EnumType) IntType;
180
181 FORCEINLINE explicit TIterator(EnumType InFlags)
183 {
184 }
185
187 {
188 const IntType PoppedBit = Flags & (~Flags + 1);
189 Flags ^= PoppedBit;
190 return *this;
191 }
192
193 FORCEINLINE EnumType operator*() const
194 {
195 const IntType Result = Flags & (~Flags + 1);
196 return (EnumType)Result;
197 }
198
199 private:
201
202 FORCEINLINE friend bool operator!=(const TIterator& Lhs, const TIterator& Rhs)
203 {
204 return Lhs.Flags != Rhs.Flags;
205 }
206 };
207
208 template <typename EnumType>
209 struct TRange
210 {
211 explicit TRange(EnumType InFlags) : Flags(InFlags) {}
212
213 Private::TIterator<EnumType> begin() const { return Private::TIterator<EnumType>(Flags); }
214 Private::TIterator<EnumType> end() const { return Private::TIterator<EnumType>(EnumType(0)); }
215
216 private:
217 EnumType Flags;
218 };
219} // namespace UE::EnumFlags::Private
220
221/**
222 * Range type for iterating over enum values. Enums should define themselves as iterable by specifying
223 * one of the ENUM_RANGE_* macros.
224 *
225 * Example:
226 *
227 * for (ECountedThing Val : TEnumRange<ECountedThing>())
228 * {
229 * ...
230 * }
231 **/
232template <typename EnumType>
234{
235};
236
237/**
238 * Make a range for iterating over set flags in a flags enum.
239 *
240 * Example:
241 *
242 * EFlagThing Flags = EFlagThing::A | EFlagThing::B;
243 * for (EFlagThing Flag : MakeFlagsRange(Flags))
244 * {
245 * // Loop is run twice, once with Flag = EFlagThing::A, once with Flag = EFlagThing::B
246 * ...
247 * }
248 **/
249template <typename EnumType>
250UE::EnumFlags::Private::TRange<EnumType> MakeFlagsRange(EnumType Flags)
251{
252 return UE::EnumFlags::Private::TRange<EnumType>(Flags);
253}
#define ENUM_RANGE_BY_FIRST_AND_LAST(EnumType, First, Last)
Definition EnumRange.h:46
UE::EnumFlags::Private::TRange< EnumType > MakeFlagsRange(EnumType Flags)
Definition EnumRange.h:250
#define FORCEINLINE
Definition Platform.h:644
Definition Vector.h:40
FORCEINLINE friend bool operator!=(const TEnumContiguousIterator &Lhs, const TEnumContiguousIterator &Rhs)
Definition EnumRange.h:125
FORCEINLINE EnumType operator*() const
Definition EnumRange.h:117
typedef __underlying_type(EnumType) IntType
FORCEINLINE TEnumContiguousIterator & operator++()
Definition EnumRange.h:111
FORCEINLINE TEnumContiguousIterator(IntType InValue)
Definition EnumRange.h:106
TEnumContiguousIterator< EnumType > begin() const
Definition EnumRange.h:162
TEnumContiguousIterator< EnumType > end() const
Definition EnumRange.h:163
TEnumValueArrayIterator< EnumType > begin() const
Definition EnumRange.h:169
TEnumValueArrayIterator< EnumType > end() const
Definition EnumRange.h:170
FORCEINLINE friend bool operator!=(const TEnumValueArrayIterator &Lhs, const TEnumValueArrayIterator &Rhs)
Definition EnumRange.h:153
FORCEINLINE TEnumValueArrayIterator(const EnumType *InPtr)
Definition EnumRange.h:134
FORCEINLINE TEnumValueArrayIterator & operator++()
Definition EnumRange.h:139
FORCEINLINE EnumType operator*() const
Definition EnumRange.h:145
FORCEINLINE TIterator(EnumType InFlags)
Definition EnumRange.h:181
FORCEINLINE TIterator & operator++()
Definition EnumRange.h:186
typedef __underlying_type(EnumType) IntType
FORCEINLINE friend bool operator!=(const TIterator &Lhs, const TIterator &Rhs)
Definition EnumRange.h:202
FORCEINLINE EnumType operator*() const
Definition EnumRange.h:193
Private::TIterator< EnumType > begin() const
Definition EnumRange.h:213
Private::TIterator< EnumType > end() const
Definition EnumRange.h:214