libzed 1.9.9
A general-purpose library for quick and simple data manipulation.
 
Loading...
Searching...
No Matches
generic.hpp
1#pragma once
2
3#if __cplusplus < 201703L
4#pragma message("\nNote: std::variant is not available so z::util::generic is disabled.\nCompile with STD=c++17 or greater to enable this feature.")
5#else // Otherwise std::variant is available
6#define Z_GENERIC_EXISTS
7
8#include "../core/array.hpp"
9#include "../core/string.hpp"
10#include <variant>
11
12#ifdef __has_include
13#if __has_include(<cereal/cereal.hpp>)
14#include <cereal/types/complex.hpp>
15#endif
16#endif
17
18namespace z {
19// Default complex type is double.
20typedef std::complex<double> cplx;
21
22namespace util {
30class generic {
31public:
34
35private:
36 std::variant<bool, long, double, std::complex<double>, zstring, list> value;
37
38public:
40 enum { VOID, INT, FLOAT, COMPLEX, STRING, ARRAY };
41
43 generic() noexcept {}
44
50 generic(INT initVal) noexcept : value(long(initVal)) {}
51
56 generic(double initVal) noexcept : value(initVal) {}
57
62 generic(const std::complex<double> &initVal) noexcept : value(initVal) {}
63
68 generic(const char *initVal) noexcept : value(zstring(initVal)) {}
69
74 generic(const wchar_t *initVal) noexcept : value(zstring(initVal)) {}
75
80 generic(const zstring &initVal) noexcept : value(initVal) {}
81
86 generic(const list &initVal) noexcept : value(initVal) {}
87
95 generic(const std::initializer_list<generic> &initVal) noexcept : value(list(initVal)) {}
96
102 explicit inline operator INT() const {
103 return integer();
104 }
105
110 explicit inline operator float() const noexcept {
111 return floating();
112 }
113
118 explicit inline operator double() const noexcept {
119 return floating();
120 }
121
127
133
139
151 zstring toString(bool printArrays = false) const noexcept; // safely cast to string; slow, copies to new string
152
163 zstring &string();
164
175 const zstring &string() const;
176
188
200
207
213
219 bool is(std::size_t type) const noexcept;
220
226
232
238 int reducesTo(bool castStrings = false) const noexcept; // the lowest we can downcast without losing precision
239
246
252 bool promote(generic *other) noexcept; // promote two numeric values to the same type
253
261
269 auto tmp = *this;
270 return tmp += other;
271 }
272
279 generic &operator-=(const generic &other);
280
287 generic operator-(const generic &other) const {
288 auto tmp = *this;
289 return tmp -= other;
290 }
291
298 generic &operator*=(const generic &other);
299
306 generic operator*(const generic &other) const {
307 auto tmp = *this;
308 return tmp *= other;
309 }
310
317 generic &operator/=(const generic &other);
318
325 generic operator/(const generic &other) const {
326 auto tmp = *this;
327 return tmp /= other;
328 }
329
337 generic &operator%=(const generic &other);
338
346 generic operator%(const generic &other) const {
347 auto tmp = *this;
348 return tmp %= other;
349 }
350
356 generic operator-() const;
357
366 bool operator==(const generic &other) const;
367
376 bool equals(const generic &other) const {
377 return operator==(other);
378 }
379
385 inline bool operator!=(const generic &other) const {
386 return !operator==(other);
387 }
388
399 bool equivalent(const generic &other) const;
400
401#ifdef __has_include
402#if __has_include(<cereal/cereal.hpp>)
407 template <typename archive>
408 void save(archive &ar) const {
409 const short int type = this->value.index();
411
412 if (type == ARRAY) {
413 ar(cereal::make_nvp("value", array()));
414 } else if (type == STRING) {
415 ar(cereal::make_nvp("value", string()));
416 } else if (type == COMPLEX) {
417 auto val = complex();
418 ar(cereal::make_nvp("value", val));
419 } else if (type == FLOAT) {
420 ar(cereal::make_nvp("value", floating()));
421 } else if (type == INT) {
422 ar(cereal::make_nvp("value", integer()));
423 }
424 }
425
430 template <class archive>
431 void load(archive &ar) {
432 short int type = VOID;
434
435 if (type == ARRAY) {
436 list val;
437 ar(cereal::make_nvp("value", val));
438 value = val;
439 } else if (type == STRING) {
440 zstring val;
441 ar(cereal::make_nvp("value", val));
442 value = val;
443 } else if (type == COMPLEX) {
444 std::complex<double> val;
445 ar(cereal::make_nvp("value", val));
446 value = val;
447 } else if (type == FLOAT) {
448 double val;
449 ar(cereal::make_nvp("value", val));
450 value = val;
451 } else if (type == INT) {
452 long val;
453 ar(cereal::make_nvp("value", val));
454 value = val;
455 }
456 }
457#endif
458#endif
459};
460
461} // namespace util
462} // namespace z
463
464#endif // End if std::variant is available
A wrapper for std::vector.
Definition array.hpp:72
A template class for character strings.
Definition string.hpp:62
A class for simple storage and manipulation of data regardless of type.
Definition generic.hpp:30
bool operator==(const generic &other) const
Check strict equality.
z::core::array< generic > list
typedef for an array of generic objects
Definition generic.hpp:33
generic & operator*=(const generic &other)
Multiply a value with this numeric value.
bool equals(const generic &other) const
Check strict equality.
Definition generic.hpp:376
bool reduce(bool castStrings=false) noexcept
Downcast a value as low as possible without losing precision.
generic & operator-=(const generic &other)
Subtract a value from this numeric value.
generic operator-(const generic &other) const
Subtract a value from this numeric value.
Definition generic.hpp:287
generic & operator%=(const generic &other)
Get the remainder of division by another value.
void save(archive &ar) const
Serialization output.
Definition generic.hpp:408
zstring toString(bool printArrays=false) const noexcept
Safely convert to a string.
void load(archive &ar)
Serialization input.
Definition generic.hpp:431
bool promote(generic *other) noexcept
Upcast two values as much as is needed for them to be the same type.
const list & arrayOr(const list &def) const noexcept
Get a reference to this array, or a default value if this is not an array.
generic & operator/=(const generic &other)
Divide this value by another numeric value.
bool is(std::size_t type) const noexcept
Check if this value is a specific type.
std::complex< double > complex() const noexcept
Conversion to a complex value.
double floating() const noexcept
Conversion to floating point.
bool equivalent(const generic &other) const
Check loose equality.
bool operator!=(const generic &other) const
Check strict inequality.
Definition generic.hpp:385
int type() const noexcept
Get the current type of this object.
int reducesTo(bool castStrings=false) const noexcept
Get the lowest type this value can be cast to without losing precision.
list & array()
Get a reference to this array.
generic operator/(const generic &other) const
Divide this value by another numeric value.
Definition generic.hpp:325
long integer() const noexcept
Conversion to integer.
generic operator*(const generic &other) const
Multiply a value with this numeric value.
Definition generic.hpp:306
generic operator-() const
Get the negation of this value.
generic operator%(const generic &other) const
Get the remainder of division by another value.
Definition generic.hpp:346
zstring typeString() const noexcept
Get a character string representing the current type.
bool numeric() const noexcept
Whether this value is a numeric type.