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.")
6#define Z_GENERIC_EXISTS
8#include "../core/array.hpp"
9#include "../core/string.hpp"
13#if __has_include(<cereal/cereal.hpp>)
14#include <cereal/types/complex.hpp>
20typedef std::complex<double> cplx;
36 std::variant<bool, long, double, std::complex<double>,
zstring, list> value;
40 enum { VOID, INT, FLOAT, COMPLEX, STRING, ARRAY };
49 template <typename INT, typename = typename std::enable_if<std::is_integral<INT>::value, INT>::type>
50 generic(INT initVal)
noexcept : value(long(initVal)) {}
56 generic(
double initVal)
noexcept : value(initVal) {}
62 generic(
const std::complex<double> &initVal)
noexcept : value(initVal) {}
68 generic(
const char *initVal)
noexcept : value(
zstring(initVal)) {}
74 generic(
const wchar_t *initVal)
noexcept : value(
zstring(initVal)) {}
80 generic(
const zstring &initVal)
noexcept : value(initVal) {}
86 generic(
const list &initVal)
noexcept : value(initVal) {}
95 generic(
const std::initializer_list<generic> &initVal)
noexcept : value(list(initVal)) {}
101 template <typename INT, typename = typename std::enable_if<std::is_integral<INT>::value, INT>::type>
102 explicit inline operator INT()
const {
110 explicit inline operator float() const noexcept {
118 explicit inline operator double() const noexcept {
126 long integer() const noexcept;
132 double floating() const noexcept;
138 std::complex<
double> complex() const noexcept;
151 zstring toString(
bool printArrays = false) const noexcept;
199 const list &array() const;
206 const list &arrayOr(const list &def) const noexcept;
212 bool numeric() const noexcept;
219 bool is(std::
size_t type) const noexcept;
225 int type() const noexcept;
231 zstring typeString() const noexcept;
238 int reducesTo(
bool castStrings = false) const noexcept;
245 bool reduce(
bool castStrings = false) noexcept;
252 bool promote(generic *other) noexcept;
260 generic &operator+=(const generic &other);
268 generic operator+(const generic &other)
const {
279 generic &operator-=(
const generic &other);
287 generic operator-(
const generic &other)
const {
298 generic &operator*=(
const generic &other);
306 generic operator*(
const generic &other)
const {
317 generic &operator/=(
const generic &other);
325 generic operator/(
const generic &other)
const {
337 generic &operator%=(
const generic &other);
346 generic operator%(
const generic &other)
const {
356 generic operator-()
const;
366 bool operator==(
const generic &other)
const;
376 bool equals(
const generic &other)
const {
377 return operator==(other);
385 inline bool operator!=(
const generic &other)
const {
386 return !operator==(other);
399 bool equivalent(
const generic &other)
const;
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();
410 ar(CEREAL_NVP(type));
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()));
430 template <
class archive>
431 void load(archive &ar) {
432 short int type = VOID;
433 ar(CEREAL_NVP(type));
437 ar(cereal::make_nvp(
"value", val));
439 }
else if (type == STRING) {
441 ar(cereal::make_nvp(
"value", val));
443 }
else if (type == COMPLEX) {
444 std::complex<double> val;
445 ar(cereal::make_nvp(
"value", val));
447 }
else if (type == FLOAT) {
449 ar(cereal::make_nvp(
"value", val));
451 }
else if (type == INT) {
453 ar(cereal::make_nvp(
"value", val));
A wrapper for std::vector.
Definition array.hpp:75
A template class for character strings.
Definition string.hpp:62