Ark Server API (ASA) - Wiki
Loading...
Searching...
No Matches
ValueOrError.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 "Misc/Optional.h"
7#include "Misc/TVariant.h"
8#include "Templates/Tuple.h"
9#include "Templates/UnrealTemplate.h"
10
11template <typename... ArgTypes>
13{
14 TValueOrError_ValueProxy(ArgTypes&&... InArgs) : Args(Forward<ArgTypes>(InArgs)...) {}
15 TTuple<ArgTypes&&...> Args;
16};
17
18template <typename... ArgTypes>
20{
21 TValueOrError_ErrorProxy(ArgTypes&&... InArgs) : Args(Forward<ArgTypes>(InArgs)...) {}
22 TTuple<ArgTypes&&...> Args;
23};
24
25template <typename... ArgTypes>
26FORCEINLINE TValueOrError_ValueProxy<ArgTypes...> MakeValue(ArgTypes&&... Args)
27{
28 return TValueOrError_ValueProxy<ArgTypes...>(Forward<ArgTypes>(Args)...);
29}
30
31template <typename... ArgTypes>
32FORCEINLINE TValueOrError_ErrorProxy<ArgTypes...> MakeError(ArgTypes&&... Args)
33{
34 return TValueOrError_ErrorProxy<ArgTypes...>(Forward<ArgTypes>(Args)...);
35}
36
37/**
38 * Type used to return either a value or an error.
39 *
40 * These must have a value or an error when newly constructed, but it is possible to have neither
41 * because of the functions to steal the value or error. This is critical for callers to consider
42 * since it means that HasValue() and HasError() must be checked independently; a return value of
43 * false from one does not imply that the other will return true.
44 *
45 * The MakeValue and MakeError functions may be used to construct these conveniently.
46 */
47template <typename ValueType, typename ErrorType>
48class TValueOrError
49{
50 /** Wrap the error type to allow ValueType and ErrorType to be the same type. */
52 {
53 template <typename... ArgTypes>
54 FWrapErrorType(ArgTypes&&... Args) : Error(Forward<ArgTypes>(Args)...) {}
55 ErrorType Error;
56 };
57
58 /** A unique empty type used in the unset state after stealing the value or error. */
60 {
61 };
62
63 template <typename... ArgTypes, uint32... ArgIndices>
65 : Variant(TInPlaceType<ValueType>(), MoveTemp(Proxy.Args).template Get<ArgIndices>()...)
66 {
67 }
68
69 template <typename... ArgTypes, uint32... ArgIndices>
71 : Variant(TInPlaceType<FWrapErrorType>(), MoveTemp(Proxy.Args).template Get<ArgIndices>()...)
72 {
73 }
74
75public:
76 /** Construct the value from a proxy from MakeValue. */
77 template <typename... ArgTypes>
78 inline TValueOrError(TValueOrError_ValueProxy<ArgTypes...>&& Proxy)
79 : TValueOrError(MoveTemp(Proxy), TMakeIntegerSequence<uint32, sizeof...(ArgTypes)>())
80 {
81 }
82
83 /** Construct the error from a proxy from MakeError. */
84 template <typename... ArgTypes>
85 inline TValueOrError(TValueOrError_ErrorProxy<ArgTypes...>&& Proxy)
86 : TValueOrError(MoveTemp(Proxy), TMakeIntegerSequence<uint32, sizeof...(ArgTypes)>())
87 {
88 }
89
90 /** Check whether a value is set. Prefer HasValue and HasError to this. !IsValid() does *not* imply HasError(). */
91 inline bool IsValid() const { return Variant.template IsType<ValueType>(); }
92
93 /** Whether the error is set. An error does imply no value. No error does *not* imply that a value is set. */
94 inline bool HasError() const { return Variant.template IsType<FWrapErrorType>(); }
95
96 /** Access the error. Asserts if this does not have an error. */
97 inline ErrorType& GetError() & { return Variant.template Get<FWrapErrorType>().Error; }
98 inline const ErrorType& GetError() const & { return Variant.template Get<FWrapErrorType>().Error; }
99 inline ErrorType GetError() && { return MoveTemp(Variant.template Get<FWrapErrorType>().Error); }
100
101 /** Access the error if it is set. */
102 inline ErrorType* TryGetError()
103 {
104 if (FWrapErrorType* Wrap = Variant.template TryGet<FWrapErrorType>())
105 {
106 return &Wrap->Error;
107 }
108 return nullptr;
109 }
110 inline const ErrorType* TryGetError() const
111 {
112 if (const FWrapErrorType* Wrap = Variant.template TryGet<FWrapErrorType>())
113 {
114 return &Wrap->Error;
115 }
116 return nullptr;
117 }
118
119 /** Steal the error. Asserts if this does not have an error. This causes the error to be unset. */
120 inline ErrorType StealError()
121 {
122 ErrorType Temp = MoveTemp(GetError());
123 Variant.template Emplace<FEmptyType>();
124 return Temp;
125 }
126
127 /** Whether the value is set. A value does imply no error. No value does *not* imply that an error is set. */
128 inline bool HasValue() const { return Variant.template IsType<ValueType>(); }
129
130 /** Access the value. Asserts if this does not have a value. */
131 inline ValueType& GetValue() & { return Variant.template Get<ValueType>(); }
132 inline const ValueType& GetValue() const & { return Variant.template Get<ValueType>(); }
133 inline ValueType GetValue() && { return MoveTemp(Variant.template Get<ValueType>()); }
134
135 /** Access the value if it is set. */
136 inline ValueType* TryGetValue() { return Variant.template TryGet<ValueType>(); }
137 inline const ValueType* TryGetValue() const { return Variant.template TryGet<ValueType>(); }
138
139 /** Steal the value. Asserts if this does not have a value. This causes the value to be unset. */
140 inline ValueType StealValue()
141 {
142 ValueType Temp = MoveTemp(GetValue());
143 Variant.template Emplace<FEmptyType>();
144 return Temp;
145 }
146
147private:
148 TVariant<ValueType, FWrapErrorType, FEmptyType> Variant;
149};
150
151template <typename ValueType>
152class TValueOrError<ValueType, void>
153{
154 template <typename... ArgTypes, uint32... ArgIndices>
156 : Value(InPlace, MoveTemp(Proxy.Args).template Get<ArgIndices>()...)
157 {
158 }
159
160public:
161 /** Construct the value from a proxy from MakeValue. */
162 template <typename... ArgTypes>
163 inline TValueOrError(TValueOrError_ValueProxy<ArgTypes...>&& Proxy)
164 : TValueOrError(MoveTemp(Proxy), TMakeIntegerSequence<uint32, sizeof...(ArgTypes)>())
165 {
166 }
167
168 /** Construct the error from a proxy from MakeError. */
170 {
171 }
172
173 /** Whether the error is set. An error does imply no value. */
174 inline bool HasError() const { return !Value.IsSet(); }
175
176 /** Whether the value is set. A value does imply no error. */
177 inline bool HasValue() const { return Value.IsSet(); }
178
179 /** Access the value. Asserts if this does not have a value. */
180 inline ValueType& GetValue() & { return Value.GetValue(); }
181 inline const ValueType& GetValue() const & { return Value.GetValue(); }
182 inline ValueType GetValue() && { return MoveTemp(Value.GetValue()); }
183
184 /** Access the value if it is set. */
185 inline ValueType* TryGetValue() { return Value.GetPtrOrNull(); }
186 inline const ValueType* TryGetValue() const { return Value.GetPtrOrNull(); }
187
188 /** Steal the value. Asserts if this does not have a value. This causes the value to be unset. */
189 inline ValueType StealValue()
190 {
191 ValueType Temp = MoveTemp(GetValue());
192 Value.Reset();
193 return Temp;
194 }
195
196private:
197 TOptional<ValueType> Value;
198};
199
200template <typename ErrorType>
201class TValueOrError<void, ErrorType>
202{
203 template <typename... ArgTypes, uint32... ArgIndices>
205 : Error(InPlace, MoveTemp(Proxy.Args).template Get<ArgIndices>()...)
206 {
207 }
208
209public:
210 /** Construct the value from a proxy from MakeValue. */
212 {
213 }
214
215 /** Construct the error from a proxy from MakeError. */
216 template <typename... ArgTypes>
217 inline TValueOrError(TValueOrError_ErrorProxy<ArgTypes...>&& Proxy)
218 : TValueOrError(MoveTemp(Proxy), TMakeIntegerSequence<uint32, sizeof...(ArgTypes)>())
219 {
220 }
221
222 /** Whether the value is set. A value does imply no error. */
223 inline bool HasValue() const { return !Error.IsSet(); }
224
225 /** Whether the error is set. An error does imply no value. */
226 inline bool HasError() const { return Error.IsSet(); }
227
228 /** Access the error. Asserts if this does not have an error. */
229 inline ErrorType& GetError() & { return Error.GetValue(); }
230 inline const ErrorType& GetError() const & { return Error.GetValue(); }
231 inline ErrorType GetError() && { return MoveTemp(Error.GetValue()); }
232
233 /** Access the error if it is set. */
234 inline ErrorType* TryGetError() { return Error.GetPtrOrNull(); }
235 inline const ErrorType* TryGetError() const { return Error.GetPtrOrNull(); }
236
237 /** Steal the error. Asserts if this does not have an error. This causes the error to be unset. */
238 inline ErrorType StealError()
239 {
240 ErrorType Temp = MoveTemp(GetError());
241 Error.Reset();
242 return Temp;
243 }
244
245private:
246 TOptional<ErrorType> Error;
247};
248
249template <>
250class TValueOrError<void, void>
251{
252public:
253 /** Construct the value from a proxy from MakeValue. */
255 : bValue(true)
256 {
257 }
258
259 /** Construct the error from a proxy from MakeError. */
261 : bValue(false)
262 {
263 }
264
265 /** Whether the error is set. An error does imply no value. */
266 inline bool HasError() const { return !bValue; }
267
268 /** Whether the value is set. A value does imply no error. */
269 inline bool HasValue() const { return bValue; }
270
271private:
272 bool bValue;
273};
#define FORCEINLINE
Definition Platform.h:644
FORCEINLINE TValueOrError_ValueProxy< ArgTypes... > MakeValue(ArgTypes &&... Args)
FORCEINLINE TValueOrError_ErrorProxy< ArgTypes... > MakeError(ArgTypes &&... Args)
TValueOrError(TValueOrError_ErrorProxy<> &&Proxy)
TValueOrError(TValueOrError_ValueProxy< ArgTypes... > &&Proxy, TIntegerSequence< uint32, ArgIndices... >)
const ValueType * TryGetValue() const
const ValueType & GetValue() const &
TValueOrError(TValueOrError_ValueProxy< ArgTypes... > &&Proxy)
TOptional< ValueType > Value
TValueOrError(TValueOrError_ErrorProxy< ArgTypes... > &&Proxy)
const ErrorType & GetError() const &
TValueOrError(TValueOrError_ValueProxy<> &&Proxy)
const ErrorType * TryGetError() const
TOptional< ErrorType > Error
TValueOrError(TValueOrError_ErrorProxy< ArgTypes... > &&Proxy, TIntegerSequence< uint32, ArgIndices... >)
TValueOrError(TValueOrError_ValueProxy<> &&Proxy)
TValueOrError(TValueOrError_ErrorProxy<> &&Proxy)
ErrorType StealError()
const ValueType & GetValue() const &
ValueType * TryGetValue()
TValueOrError(TValueOrError_ErrorProxy< ArgTypes... > &&Proxy, TIntegerSequence< uint32, ArgIndices... >)
TValueOrError(TValueOrError_ValueProxy< ArgTypes... > &&Proxy)
ValueType GetValue() &&
ValueType & GetValue() &
const ValueType * TryGetValue() const
TValueOrError(TValueOrError_ValueProxy< ArgTypes... > &&Proxy, TIntegerSequence< uint32, ArgIndices... >)
ErrorType * TryGetError()
bool HasError() const
const ErrorType * TryGetError() const
ErrorType GetError() &&
TValueOrError(TValueOrError_ErrorProxy< ArgTypes... > &&Proxy)
ValueType StealValue()
TVariant< ValueType, FWrapErrorType, FEmptyType > Variant
bool HasValue() const
bool IsValid() const
const ErrorType & GetError() const &
ErrorType & GetError() &
FWrapErrorType(ArgTypes &&... Args)
TValueOrError_ErrorProxy(ArgTypes &&... InArgs)
TTuple< ArgTypes &&... > Args
TTuple< ArgTypes &&... > Args
TValueOrError_ValueProxy(ArgTypes &&... InArgs)