Plasma Engine  2.0
Loading...
Searching...
No Matches
VariantHelper_inl.h
1
2
3// for some reason MSVC does not accept the template keyword here
4#if PL_ENABLED(PL_COMPILER_MSVC_PURE)
5# define CALL_FUNCTOR(functor, type) return functor.operator()<type>(std::forward<Args>(args)...)
6#else
7# define CALL_FUNCTOR(functor, type) return functor.template operator()<type>(std::forward<Args>(args)...)
8#endif
9
10template <typename Functor, class... Args>
11auto plVariant::DispatchTo(Functor& ref_functor, Type::Enum type, Args&&... args)
12{
13 switch (type)
14 {
15 case Type::Bool:
16 CALL_FUNCTOR(ref_functor, bool);
17 break;
18
19 case Type::Int8:
20 CALL_FUNCTOR(ref_functor, plInt8);
21 break;
22
23 case Type::UInt8:
24 CALL_FUNCTOR(ref_functor, plUInt8);
25 break;
26
27 case Type::Int16:
28 CALL_FUNCTOR(ref_functor, plInt16);
29 break;
30
31 case Type::UInt16:
32 CALL_FUNCTOR(ref_functor, plUInt16);
33 break;
34
35 case Type::Int32:
36 CALL_FUNCTOR(ref_functor, plInt32);
37 break;
38
39 case Type::UInt32:
40 CALL_FUNCTOR(ref_functor, plUInt32);
41 break;
42
43 case Type::Int64:
44 CALL_FUNCTOR(ref_functor, plInt64);
45 break;
46
47 case Type::UInt64:
48 CALL_FUNCTOR(ref_functor, plUInt64);
49 break;
50
51 case Type::Float:
52 CALL_FUNCTOR(ref_functor, float);
53 break;
54
55 case Type::Double:
56 CALL_FUNCTOR(ref_functor, double);
57 break;
58
59 case Type::Color:
60 CALL_FUNCTOR(ref_functor, plColor);
61 break;
62
64 CALL_FUNCTOR(ref_functor, plColorGammaUB);
65 break;
66
67 case Type::Vector2:
68 CALL_FUNCTOR(ref_functor, plVec2);
69 break;
70
71 case Type::Vector3:
72 CALL_FUNCTOR(ref_functor, plVec3);
73 break;
74
75 case Type::Vector4:
76 CALL_FUNCTOR(ref_functor, plVec4);
77 break;
78
79 case Type::Vector2I:
80 CALL_FUNCTOR(ref_functor, plVec2I32);
81 break;
82
83 case Type::Vector3I:
84 CALL_FUNCTOR(ref_functor, plVec3I32);
85 break;
86
87 case Type::Vector4I:
88 CALL_FUNCTOR(ref_functor, plVec4I32);
89 break;
90
91 case Type::Vector2U:
92 CALL_FUNCTOR(ref_functor, plVec2U32);
93 break;
94
95 case Type::Vector3U:
96 CALL_FUNCTOR(ref_functor, plVec3U32);
97 break;
98
99 case Type::Vector4U:
100 CALL_FUNCTOR(ref_functor, plVec4U32);
101 break;
102
103 case Type::Quaternion:
104 CALL_FUNCTOR(ref_functor, plQuat);
105 break;
106
107 case Type::Matrix3:
108 CALL_FUNCTOR(ref_functor, plMat3);
109 break;
110
111 case Type::Matrix4:
112 CALL_FUNCTOR(ref_functor, plMat4);
113 break;
114
115 case Type::Transform:
116 CALL_FUNCTOR(ref_functor, plTransform);
117 break;
118
119 case Type::String:
120 CALL_FUNCTOR(ref_functor, plString);
121 break;
122
123 case Type::StringView:
124 CALL_FUNCTOR(ref_functor, plStringView);
125 break;
126
127 case Type::DataBuffer:
128 CALL_FUNCTOR(ref_functor, plDataBuffer);
129 break;
130
131 case Type::Time:
132 CALL_FUNCTOR(ref_functor, plTime);
133 break;
134
135 case Type::Uuid:
136 CALL_FUNCTOR(ref_functor, plUuid);
137 break;
138
139 case Type::Angle:
140 CALL_FUNCTOR(ref_functor, plAngle);
141 break;
142
144 CALL_FUNCTOR(ref_functor, plHashedString);
145 break;
146
148 CALL_FUNCTOR(ref_functor, plTempHashedString);
149 break;
150
152 CALL_FUNCTOR(ref_functor, plVariantArray);
153 break;
154
156 CALL_FUNCTOR(ref_functor, plVariantDictionary);
157 break;
158
160 CALL_FUNCTOR(ref_functor, plTypedObject);
161 break;
162
163 default:
164 PL_REPORT_FAILURE("Could not dispatch type '{0}'", type);
165 // Intended fall through to disable warning.
167 CALL_FUNCTOR(ref_functor, plTypedPointer);
168 break;
169 }
170}
171
172#undef CALL_FUNCTOR
173
175{
176 friend class plVariant;
177 friend struct ConvertFunc;
178
179 static void To(const plVariant& value, bool& result, bool& bSuccessful)
180 {
181 bSuccessful = true;
182
183 if (value.GetType() <= plVariant::Type::Double)
184 result = value.ConvertNumber<plInt32>() != 0;
186 {
187 plStringView s = value.IsA<plString>() ? value.Cast<plString>().GetView() : value.Cast<plHashedString>().GetView();
188 if (plConversionUtils::StringToBool(s, result) == PL_FAILURE)
189 {
190 result = false;
191 bSuccessful = false;
192 }
193 }
194 else
195 PL_REPORT_FAILURE("Conversion to bool failed");
196 }
197
198 static void To(const plVariant& value, plInt8& result, bool& bSuccessful)
199 {
200 plInt32 tempResult = 0;
201 To(value, tempResult, bSuccessful);
202 result = (plInt8)tempResult;
203 }
204
205 static void To(const plVariant& value, plUInt8& result, bool& bSuccessful)
206 {
207 plUInt32 tempResult = 0;
208 To(value, tempResult, bSuccessful);
209 result = (plUInt8)tempResult;
210 }
211
212 static void To(const plVariant& value, plInt16& result, bool& bSuccessful)
213 {
214 plInt32 tempResult = 0;
215 To(value, tempResult, bSuccessful);
216 result = (plInt16)tempResult;
217 }
218
219 static void To(const plVariant& value, plUInt16& result, bool& bSuccessful)
220 {
221 plUInt32 tempResult = 0;
222 To(value, tempResult, bSuccessful);
223 result = (plUInt16)tempResult;
224 }
225
226 static void To(const plVariant& value, plInt32& result, bool& bSuccessful)
227 {
228 bSuccessful = true;
229
230 if (value.GetType() <= plVariant::Type::Double)
231 result = value.ConvertNumber<plInt32>();
233 {
234 plStringView s = value.IsA<plString>() ? value.Cast<plString>().GetView() : value.Cast<plHashedString>().GetView();
235 if (plConversionUtils::StringToInt(s, result) == PL_FAILURE)
236 {
237 result = 0;
238 bSuccessful = false;
239 }
240 }
241 else
242 PL_REPORT_FAILURE("Conversion to int failed");
243 }
244
245 static void To(const plVariant& value, plUInt32& result, bool& bSuccessful)
246 {
247 bSuccessful = true;
248
249 if (value.GetType() <= plVariant::Type::Double)
250 result = value.ConvertNumber<plUInt32>();
252 {
253 plStringView s = value.IsA<plString>() ? value.Cast<plString>().GetView() : value.Cast<plHashedString>().GetView();
254 plInt64 tmp = result;
255 if (plConversionUtils::StringToInt64(s, tmp) == PL_FAILURE)
256 {
257 result = 0;
258 bSuccessful = false;
259 }
260 else
261 result = (plUInt32)tmp;
262 }
263 else
264 PL_REPORT_FAILURE("Conversion to uint failed");
265 }
266
267 static void To(const plVariant& value, plInt64& result, bool& bSuccessful)
268 {
269 bSuccessful = true;
270
271 if (value.GetType() <= plVariant::Type::Double)
272 result = value.ConvertNumber<plInt64>();
274 {
275 plStringView s = value.IsA<plString>() ? value.Cast<plString>().GetView() : value.Cast<plHashedString>().GetView();
276 if (plConversionUtils::StringToInt64(s, result) == PL_FAILURE)
277 {
278 result = 0;
279 bSuccessful = false;
280 }
281 }
282 else
283 PL_REPORT_FAILURE("Conversion to int64 failed");
284 }
285
286 static void To(const plVariant& value, plUInt64& result, bool& bSuccessful)
287 {
288 bSuccessful = true;
289
290 if (value.GetType() <= plVariant::Type::Double)
291 result = value.ConvertNumber<plUInt64>();
293 {
294 plStringView s = value.IsA<plString>() ? value.Cast<plString>().GetView() : value.Cast<plHashedString>().GetView();
295 plInt64 tmp = result;
296 if (plConversionUtils::StringToInt64(s, tmp) == PL_FAILURE)
297 {
298 result = 0;
299 bSuccessful = false;
300 }
301 else
302 result = (plUInt64)tmp;
303 }
304 else
305 PL_REPORT_FAILURE("Conversion to uint64 failed");
306 }
307
308 static void To(const plVariant& value, float& result, bool& bSuccessful)
309 {
310 bSuccessful = true;
311
312 if (value.GetType() <= plVariant::Type::Double)
313 result = value.ConvertNumber<float>();
315 {
316 plStringView s = value.IsA<plString>() ? value.Cast<plString>().GetView() : value.Cast<plHashedString>().GetView();
317 double tmp = result;
318 if (plConversionUtils::StringToFloat(s, tmp) == PL_FAILURE)
319 {
320 result = 0.0f;
321 bSuccessful = false;
322 }
323 else
324 result = (float)tmp;
325 }
326 else
327 PL_REPORT_FAILURE("Conversion to float failed");
328 }
329
330 static void To(const plVariant& value, double& result, bool& bSuccessful)
331 {
332 bSuccessful = true;
333
334 if (value.GetType() <= plVariant::Type::Double)
335 result = value.ConvertNumber<double>();
337 {
338 plStringView s = value.IsA<plString>() ? value.Cast<plString>().GetView() : value.Cast<plHashedString>().GetView();
339 if (plConversionUtils::StringToFloat(s, result) == PL_FAILURE)
340 {
341 result = 0.0;
342 bSuccessful = false;
343 }
344 }
345 else
346 PL_REPORT_FAILURE("Conversion to double failed");
347 }
348
349 static void To(const plVariant& value, plString& result, bool& bSuccessful)
350 {
351 bSuccessful = true;
352
353 if (value.IsValid() == false)
354 {
355 result = "<Invalid>";
356 return;
357 }
358
359 ToStringFunc toStringFunc;
360 toStringFunc.m_pThis = &value;
361 toStringFunc.m_pResult = &result;
362
363 plVariant::DispatchTo(toStringFunc, value.GetType());
364 }
365
366 static void To(const plVariant& value, plStringView& result, bool& bSuccessful)
367 {
368 bSuccessful = true;
369
370 result = value.IsA<plString>() ? value.Get<plString>().GetView() : value.Get<plHashedString>().GetView();
371 }
372
373 static void To(const plVariant& value, plTypedPointer& result, bool& bSuccessful)
374 {
375 bSuccessful = true;
376 PL_ASSERT_DEBUG(value.GetType() == plVariant::Type::TypedPointer, "Only ptr can be converted to void*!");
377 result = value.Cast<plTypedPointer>();
378 }
379
380 static void To(const plVariant& value, plColor& result, bool& bSuccessful)
381 {
382 bSuccessful = true;
383
385 result = value.Cast<plColorGammaUB>();
386 else
387 PL_REPORT_FAILURE("Conversion to plColor failed");
388 }
389
390 static void To(const plVariant& value, plColorGammaUB& result, bool& bSuccessful)
391 {
392 bSuccessful = true;
393
394 if (value.GetType() == plVariant::Type::Color)
395 result = value.Cast<plColor>();
396 else
397 PL_REPORT_FAILURE("Conversion to plColorGammaUB failed");
398 }
399
400 template <typename T, typename V1, typename V2>
401 static void ToVec2X(const plVariant& value, T& result, bool& bSuccessful)
402 {
403 bSuccessful = true;
404
405 if (value.IsA<V1>())
406 {
407 const V1& v = value.Cast<V1>();
408 result = T(static_cast<typename T::ComponentType>(v.x), static_cast<typename T::ComponentType>(v.y));
409 }
410 else if (value.IsA<V2>())
411 {
412 const V2& v = value.Cast<V2>();
413 result = T(static_cast<typename T::ComponentType>(v.x), static_cast<typename T::ComponentType>(v.y));
414 }
415 else
416 {
417 PL_REPORT_FAILURE("Conversion to plVec2X failed");
418 bSuccessful = false;
419 }
420 }
421
422 static void To(const plVariant& value, plVec2& result, bool& bSuccessful) { ToVec2X<plVec2, plVec2I32, plVec2U32>(value, result, bSuccessful); }
423
424 static void To(const plVariant& value, plVec2I32& result, bool& bSuccessful) { ToVec2X<plVec2I32, plVec2, plVec2U32>(value, result, bSuccessful); }
425
426 static void To(const plVariant& value, plVec2U32& result, bool& bSuccessful) { ToVec2X<plVec2U32, plVec2I32, plVec2>(value, result, bSuccessful); }
427
428 template <typename T, typename V1, typename V2>
429 static void ToVec3X(const plVariant& value, T& result, bool& bSuccessful)
430 {
431 bSuccessful = true;
432
433 if (value.IsA<V1>())
434 {
435 const V1& v = value.Cast<V1>();
436 result = T(static_cast<typename T::ComponentType>(v.x), static_cast<typename T::ComponentType>(v.y), static_cast<typename T::ComponentType>(v.z));
437 }
438 else if (value.IsA<V2>())
439 {
440 const V2& v = value.Cast<V2>();
441 result = T(static_cast<typename T::ComponentType>(v.x), static_cast<typename T::ComponentType>(v.y), static_cast<typename T::ComponentType>(v.z));
442 }
443 else
444 {
445 PL_REPORT_FAILURE("Conversion to plVec3X failed");
446 bSuccessful = false;
447 }
448 }
449
450 static void To(const plVariant& value, plVec3& result, bool& bSuccessful) { ToVec3X<plVec3, plVec3I32, plVec3U32>(value, result, bSuccessful); }
451
452 static void To(const plVariant& value, plVec3I32& result, bool& bSuccessful) { ToVec3X<plVec3I32, plVec3, plVec3U32>(value, result, bSuccessful); }
453
454 static void To(const plVariant& value, plVec3U32& result, bool& bSuccessful) { ToVec3X<plVec3U32, plVec3I32, plVec3>(value, result, bSuccessful); }
455
456 template <typename T, typename V1, typename V2>
457 static void ToVec4X(const plVariant& value, T& result, bool& bSuccessful)
458 {
459 bSuccessful = true;
460
461 if (value.IsA<V1>())
462 {
463 const V1& v = value.Cast<V1>();
464 result = T(static_cast<typename T::ComponentType>(v.x), static_cast<typename T::ComponentType>(v.y), static_cast<typename T::ComponentType>(v.z), static_cast<typename T::ComponentType>(v.w));
465 }
466 else if (value.IsA<V2>())
467 {
468 const V2& v = value.Cast<V2>();
469 result = T(static_cast<typename T::ComponentType>(v.x), static_cast<typename T::ComponentType>(v.y), static_cast<typename T::ComponentType>(v.z), static_cast<typename T::ComponentType>(v.w));
470 }
471 else
472 {
473 PL_REPORT_FAILURE("Conversion to plVec4X failed");
474 bSuccessful = false;
475 }
476 }
477
478 static void To(const plVariant& value, plVec4& result, bool& bSuccessful) { ToVec4X<plVec4, plVec4I32, plVec4U32>(value, result, bSuccessful); }
479
480 static void To(const plVariant& value, plVec4I32& result, bool& bSuccessful) { ToVec4X<plVec4I32, plVec4, plVec4U32>(value, result, bSuccessful); }
481
482 static void To(const plVariant& value, plVec4U32& result, bool& bSuccessful) { ToVec4X<plVec4U32, plVec4I32, plVec4>(value, result, bSuccessful); }
483
484 static void To(const plVariant& value, plHashedString& result, bool& bSuccessful)
485 {
486 bSuccessful = true;
487
488 if (value.GetType() == plVariantType::String)
489 result.Assign(value.Cast<plString>());
490 else if (value.GetType() == plVariantType::StringView)
491 result.Assign(value.Cast<plStringView>());
492 else
493 {
494 plString s;
495 To(value, s, bSuccessful);
496 result.Assign(s.GetView());
497 }
498 }
499
500 static void To(const plVariant& value, plTempHashedString& result, bool& bSuccessful)
501 {
502 bSuccessful = true;
503
504 if (value.GetType() == plVariantType::String)
505 result = value.Cast<plString>();
506 else if (value.GetType() == plVariantType::StringView)
507 result = value.Cast<plStringView>();
508 else if (value.GetType() == plVariant::Type::HashedString)
509 result = value.Cast<plHashedString>();
510 else
511 {
512 plString s;
513 To(value, s, bSuccessful);
514 result = s.GetView();
515 }
516 }
517
518 template <typename T>
519 static void To(const plVariant& value, T& result, bool& bSuccessful)
520 {
521 PL_REPORT_FAILURE("Conversion function not implemented for target type '{0}'", plVariant::TypeDeduction<T>::value);
522 bSuccessful = false;
523 }
524
525 struct ToStringFunc
526 {
527 template <typename T>
528 PL_ALWAYS_INLINE void operator()()
529 {
530 plStringBuilder tmp;
531 *m_pResult = plConversionUtils::ToString(m_pThis->Cast<T>(), tmp);
532 }
533
534 const plVariant* m_pThis;
535 plString* m_pResult;
536 };
537};
Float wrapper struct for a safe usage and conversions of angles.
Definition Angle.h:10
A 8bit per channel unsigned normalized (values interpreted as 0-1) color storage format that represen...
Definition Color8UNorm.h:99
plColor represents an RGBA color in linear color space. Values are stored as float,...
Definition Color.h:44
This class is optimized to take nearly no memory (sizeof(void*)) and to allow very fast checks whethe...
Definition HashedString.h:25
plStringBuilder is a class that is meant for creating and modifying strings.
Definition StringBuilder.h:35
plStringView represent a read-only sub-string of a larger string, as it can store a dedicated string ...
Definition StringView.h:34
A class to use together with plHashedString for quick comparisons with temporary strings that need no...
Definition HashedString.h:151
This data type is the abstraction for 128-bit Uuid (also known as GUID) instances.
Definition Uuid.h:11
Definition VariantHelper_inl.h:175
plVariant is a class that can store different types of variables, which is useful in situations where...
Definition Variant.h:44
bool IsValid() const
Returns whether this variant stores any other type than 'Invalid'.
Definition Variant_inl.h:274
static auto DispatchTo(Functor &ref_functor, Type::Enum type, Args &&... args)
This will call the overloaded operator() (function call operator) of the provided functor.
Definition VariantHelper_inl.h:11
Type::Enum GetType() const
Returns the exact plVariant::Type value.
Definition Variant_inl.h:351
const T & Get() const
Returns the variants value as the provided type.
bool IsA() const
Returns whether the stored type is exactly the given type.
PL_FOUNDATION_DLL plResult StringToBool(plStringView sText, bool &out_bRes, const char **out_pLastParsePosition=nullptr)
Parses szString and checks that the first word it finds starts with a phrase that can be interpreted ...
Definition ConversionUtils.cpp:310
PL_FOUNDATION_DLL plResult StringToInt(plStringView sText, plInt32 &out_iRes, const char **out_pLastParsePosition=nullptr)
Parses szString and converts it to an integer value. Returns PL_FAILURE if the string contains no par...
Definition ConversionUtils.cpp:87
PL_FOUNDATION_DLL plResult StringToInt64(plStringView sText, plInt64 &out_iRes, const char **out_pLastParsePosition=nullptr)
Same as StringToInt but converts to a 64bit integer value instead.
Definition ConversionUtils.cpp:111
PL_ALWAYS_INLINE const plStringBuilder & ToString(bool value, plStringBuilder &out_sResult)
Converts a bool to a string.
Definition ConversionUtils.h:176
PL_FOUNDATION_DLL plResult StringToFloat(plStringView sText, double &out_fRes, const char **out_pLastParsePosition=nullptr)
Parses szString and converts it to a double value. Returns PL_FAILURE if the string contains no parse...
Definition ConversionUtils.cpp:162
plStringView GetView() const
Returns a string view to this string's data.
Definition StringBase_inl.h:329
The time class encapsulates a double value storing the time in seconds.
Definition Time.h:12
Defines a reference to an immutable object owned by an plVariant.
Definition Variant.h:24
A typed raw pointer.
Definition TypedPointer.h:13
A helper struct to convert the C++ type, which is passed as the template argument,...
Definition VariantType.h:97
Enum
This enum describes the type of data that is currently stored inside the variant. Note that changes t...
Definition VariantType.h:26
@ Matrix3
The variant stores an plMat3. A heap allocation is required to store this data type.
Definition VariantType.h:53
@ DataBuffer
The variant stores an plDataBuffer, a typedef to DynamicArray<plUInt8>. A heap allocation is required...
Definition VariantType.h:58
@ UInt8
The variant stores an plUInt8.
Definition VariantType.h:33
@ ColorGamma
The variant stores an plColorGammaUB value.
Definition VariantType.h:62
@ Vector3I
The variant stores an plVec3I32.
Definition VariantType.h:47
@ Int8
The variant stores an plInt8.
Definition VariantType.h:32
@ TempHashedString
The variant stores an plTempHashedString value.
Definition VariantType.h:64
@ Vector2U
The variant stores an plVec2U32.
Definition VariantType.h:49
@ Bool
The variant stores a bool.
Definition VariantType.h:31
@ Int32
The variant stores an plInt32.
Definition VariantType.h:36
@ Matrix4
The variant stores an plMat4. A heap allocation is required to store this data type.
Definition VariantType.h:54
@ Uuid
The variant stores an plUuid value.
Definition VariantType.h:60
@ Vector3
The variant stores an plVec3.
Definition VariantType.h:44
@ Vector4I
The variant stores an plVec4I32.
Definition VariantType.h:48
@ String
The variant stores a string. A heap allocation is required to store this data type.
Definition VariantType.h:56
@ Double
The variant stores a double.
Definition VariantType.h:41
@ TypedPointer
The variant stores an plTypedPointer value. Reflected type and data queries will match the pointed to...
Definition VariantType.h:71
@ Time
The variant stores an plTime value.
Definition VariantType.h:59
@ Color
The variant stores an plColor.
Definition VariantType.h:42
@ UInt16
The variant stores an plUInt16.
Definition VariantType.h:35
@ Angle
The variant stores an plAngle value.
Definition VariantType.h:61
@ Float
The variant stores a float.
Definition VariantType.h:40
@ VariantArray
The variant stores an array of plVariant's. A heap allocation is required to store this data type.
Definition VariantType.h:69
@ Vector2I
The variant stores an plVec2I32.
Definition VariantType.h:46
@ VariantDictionary
The variant stores a dictionary (hashmap) of plVariant's. A heap allocation is required to store this...
Definition VariantType.h:70
@ StringView
The variant stores an plStringView.
Definition VariantType.h:57
@ Vector3U
The variant stores an plVec3U32.
Definition VariantType.h:50
@ HashedString
The variant stores an plHashedString value.
Definition VariantType.h:63
@ Vector2
The variant stores an plVec2.
Definition VariantType.h:43
@ UInt32
The variant stores an plUInt32.
Definition VariantType.h:37
@ Transform
The variant stores an plTransform. A heap allocation is required to store this data type.
Definition VariantType.h:55
@ Quaternion
The variant stores an plQuat.
Definition VariantType.h:52
@ Vector4U
The variant stores an plVec4U32.
Definition VariantType.h:51
@ Int16
The variant stores an plInt16.
Definition VariantType.h:34
@ UInt64
The variant stores an plUInt64.
Definition VariantType.h:39
@ Vector4
The variant stores an plVec4.
Definition VariantType.h:45
@ TypedObject
The variant stores an plTypedObject value. Reflected type and data queries will match the object....
Definition VariantType.h:72
@ Int64
The variant stores an plInt64.
Definition VariantType.h:38