From e87165e4d9dd5728446c2d36f74b1757cd43ddcb Mon Sep 17 00:00:00 2001 From: Relintai Date: Thu, 6 Jan 2022 16:01:13 +0100 Subject: [PATCH] Started working on a Variant class. --- core/variant.cpp | 335 +++++++++++++++++++++++++++++++++++++++++++++++ core/variant.h | 114 ++++++++++++++++ 2 files changed, 449 insertions(+) create mode 100644 core/variant.cpp create mode 100644 core/variant.h diff --git a/core/variant.cpp b/core/variant.cpp new file mode 100644 index 0000000..66a5c74 --- /dev/null +++ b/core/variant.cpp @@ -0,0 +1,335 @@ +#include "variant.h" + +#include "core/math/math.h" +#include "core/reference.h" + +Variant::Type Variant::get_type() { + return _type; +} + +void Variant::clear() { +} +void Variant::zero() { +} + +void Variant::parse(const String &str) { +} +Variant Variant::parse_string(const String &str) { + return Variant(); +} + +bool Variant::is_null() const { + return _type == TYPE_NULL; +} +bool Variant::is_bool() const { + return _type == TYPE_BOOL; +} +bool Variant::is_int() const { + return _type == TYPE_INT; +} +bool Variant::is_uint() const { + return _type == TYPE_UINT; +} +bool Variant::is_float() const { + return _type == TYPE_FLOAT; +} +bool Variant::is_numeric() const { + return _type == TYPE_INT || _type == TYPE_UINT || _type == TYPE_FLOAT; +} +bool Variant::is_string() const { + return _type == TYPE_STRING; +} +bool Variant::is_object() const { + return _type == TYPE_OBJECT; +} +bool Variant::is_pointer() const { + return _type == TYPE_POINTER; +} +bool Variant::is_reference() const { + if (_type == TYPE_OBJECT) { + return _object->reference.is_valid(); + } + + return false; +} + +bool Variant::to_bool() const { + return _bool; +} +int Variant::to_int() const { + switch (_type) { + case TYPE_NULL: + return 0; + case TYPE_BOOL: + if (_bool) { + return 1; + } else { + return 0; + } + case TYPE_INT: + case TYPE_UINT: + return _int; + case TYPE_FLOAT: + return static_cast(_int); + case TYPE_STRING: + return _string->string->to_int(); + case TYPE_OBJECT: + case TYPE_POINTER: + // just read the value of the pointer as int + // Could return 1 or 0, but this is almost the same, but hopefully be more useful + return _int; + default: + return 0; + } +} +uint64_t Variant::to_uint() const { + switch (_type) { + case TYPE_NULL: + return 0; + case TYPE_BOOL: + if (_bool) { + return 1; + } else { + return 0; + } + case TYPE_INT: + case TYPE_UINT: + return _uint; + case TYPE_FLOAT: + return static_cast(_float); + case TYPE_STRING: + return _string->string->to_uint(); + case TYPE_OBJECT: + case TYPE_POINTER: + // just read the value of the pointer as uint + // Could return 1 or 0, but this is almost the same, but hopefully be more useful + return _uint; + default: + return 0; + } +} +float Variant::to_float() const { + switch (_type) { + case TYPE_NULL: + return 0; + case TYPE_BOOL: + if (_bool) { + return 0; + } else { + return 1; + } + case TYPE_INT: + return static_cast(_int); + case TYPE_UINT: + return static_cast(_uint); + case TYPE_FLOAT: + return _float; + case TYPE_STRING: + return _string->string->to_float(); + case TYPE_OBJECT: + case TYPE_POINTER: + if (_uint) { + return 1; + } else { + return 0; + } + default: + return 0; + } +} +String Variant::to_string() const { + switch (_type) { + case TYPE_NULL: + return "NULL"; + case TYPE_BOOL: + if (Math::is_zero_approx(_float)) { + return "false"; + } else { + return "true"; + } + case TYPE_INT: + return String::num(_int); + case TYPE_UINT: + return String::num(_uint); + case TYPE_FLOAT: + return String::num(_float); + case TYPE_STRING: + return *(_string->string); + case TYPE_OBJECT: + case TYPE_POINTER: + if (_uint) { + return "[ Object ]"; + } else { + return "[ Object (NULL) ]"; + } + default: + return ""; + } +} +Object *Variant::to_object() const { + return nullptr; +} +Reference *Variant::to_reference() const { + return nullptr; +} +void *Variant::to_pointer() const { + return nullptr; +} +String *Variant::get_string_ptr() const { + return nullptr; +} +bool Variant::is_string_owned() const { + return false; +} + +void Variant::set_null() { + clear(); + + _type = TYPE_NULL; +} +void Variant::set_bool(const bool value) { + clear(); + + _bool = value; +} +void Variant::set_int(const int value) { + clear(); + + _int = value; +} +void Variant::set_uint(const uint64_t value) { + clear(); + + _uint = value; +} +void Variant::set_float(const float value) { + clear(); + + _float = value; +} +void Variant::set_string(String *value, const bool copy) { + clear(); +} +void Variant::set_string(const String &value, const bool copy) { + clear(); +} +void Variant::set_object(Object *value) { + clear(); + + if (!value) { + return; + } + + _object = new ObjectData(); + _object->object = value; + + if (value->is_class_ptr(Reference::get_class_ptr_static())) { + _object->reference = Ref(Object::cast_to(value)); + } +} +void Variant::set_pointer(void *value) { + clear(); +} +void Variant::set_variant(const Variant &value) { + clear(); +} + +Variant::operator bool() const { + return to_bool(); +} +Variant::operator int() const { + return to_int(); +} +Variant::operator uint64_t() const { + return to_uint(); +} +Variant::operator float() const { + return to_float(); +} +Variant::operator String() const { + return to_string(); +} +Variant::operator Object *() const { + return to_object(); +} +Variant::operator Reference *() const { + return to_reference(); +} +Variant::operator void *() const { + return to_pointer(); +} + +void Variant::operator=(const Variant &other) { + set_variant(other); +} +bool Variant::operator==(const Variant &other) const { + if (_type != other._type) { + return false; + } + + return false; +} +bool Variant::operator!=(const Variant &other) const { + return !(operator==(other)); +} +bool Variant::operator<(const Variant &other) const { + if (_type != other._type) { + return _type < other._type; + } + + return false; +} + +Variant::Variant(const bool value) { + _type = TYPE_BOOL; + + _bool = value; +} +Variant::Variant(const int value) { + _type = TYPE_INT; + + _int = value; +} +Variant::Variant(const uint64_t value) { + _type = TYPE_UINT; + + _uint = value; +} +Variant::Variant(const float value) { + _type = TYPE_FLOAT; + + _float = value; +} +Variant::Variant(String *value, bool copy) { + _type = TYPE_NULL; + + set_string(value, copy); +} +Variant::Variant(const String &value, bool copy) { + _type = TYPE_NULL; + + set_string(value, copy); +} +Variant::Variant(Object *value) { + _type = TYPE_NULL; + + set_object(value); +} +Variant::Variant(void *value) { + _type = TYPE_NULL; + + set_pointer(value); +} +Variant::Variant(const Variant &value) { + _type = TYPE_NULL; + + set_variant(value); +} + +Variant::Variant() { + _type = TYPE_NULL; +} + +Variant::~Variant() { + clear(); +} \ No newline at end of file diff --git a/core/variant.h b/core/variant.h new file mode 100644 index 0000000..5cf6fd9 --- /dev/null +++ b/core/variant.h @@ -0,0 +1,114 @@ +#ifndef VARIANT_H +#define VARIANT_H + +#include "core/object.h" +#include "core/reference.h" +#include "core/string.h" + +class Variant { + +public: + enum Type { + TYPE_NULL = 0, + TYPE_BOOL, + TYPE_INT, + TYPE_UINT, + TYPE_FLOAT, + TYPE_STRING, + TYPE_OBJECT, + TYPE_POINTER, + }; + + Type get_type(); + + void clear(); + void zero(); + + void parse(const String &str); + static Variant parse_string(const String &str); + + bool is_null() const; + bool is_bool() const; + bool is_int() const; + bool is_uint() const; + bool is_float() const; + bool is_numeric() const; + bool is_string() const; + bool is_object() const; + bool is_pointer() const; + bool is_reference() const; + + bool to_bool() const; + int to_int() const; + uint64_t to_uint() const; + float to_float() const; + String to_string() const; + Object *to_object() const; + Reference *to_reference() const; + void *to_pointer() const; + String *get_string_ptr() const; + bool is_string_owned() const; + + void set_null(); + void set_bool(const bool value); + void set_int(const int value); + void set_uint(const uint64_t value); + void set_float(const float value); + void set_string(String *value, bool copy = false); + void set_string(const String &value, bool copy = true); + void set_object(Object *value); + void set_pointer(void *value); + void set_variant(const Variant &value); + + operator bool() const; + operator int() const; + operator uint64_t() const; + operator float() const; + operator String() const; + operator Object *() const; + operator Reference *() const; + operator void *() const; + + void operator=(const Variant &other); + bool operator==(const Variant &other) const; + bool operator!=(const Variant &other) const; + bool operator<(const Variant &other) const; + + Variant(const bool value); + Variant(const int value); + Variant(const uint64_t value); + Variant(const float value); + Variant(String *value, const bool copy = false); + Variant(const String &value, const bool copy = true); + Variant(Object *value); + Variant(void *value); + Variant(const Variant &value); + + Variant(); + ~Variant(); + +private: + struct StringData { + bool owner; + String *string; + }; + + struct ObjectData { + Object *object; + Ref reference; + }; + + union { + bool _bool; + int _int; + uint64_t _uint; + float _float; + StringData *_string; + ObjectData *_object; + void *_pointer; + }; + + Type _type; +}; + +#endif \ No newline at end of file