variable.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. #ifndef VARIABLE_H
  2. #define VARIABLE_H
  3. #include "../utils/types.h"
  4. #include "primitive.h"
  5. #include "buffer_array.h"
  6. #include "array.h"
  7. #include "object.h"
  8. namespace binom {
  9. class Variable {
  10. union types {
  11. void* ptr;
  12. VarType* type;
  13. byte* bytes;
  14. Primitive primitive;
  15. BufferArray buffer_array;
  16. Array array;
  17. Object object;
  18. types(void* ptr) : ptr(ptr) {}
  19. ~types() {}
  20. } data;
  21. void* clone() const;
  22. void destroy();
  23. inline void throwIfNot(VarTypeClass type_class) const {
  24. if(type_class != typeClass()) throw Exception(ErrCode::binom_invalid_type, "Bad Variable-cast!");
  25. }
  26. friend class Primitive;
  27. friend class BufferArray;
  28. friend class Array;
  29. friend class Object;
  30. friend struct NamedVariable;
  31. friend class NodeVisitor;
  32. public:
  33. Variable() : data(nullptr) {}
  34. Variable(decltype(nullptr)) : data(nullptr) {}
  35. Variable(VarType type);
  36. // Bool init
  37. Variable(bool value);
  38. // Primitive init
  39. Variable(ui8 value);
  40. Variable(ui16 value);
  41. Variable(ui32 value);
  42. Variable(ui64 value);
  43. Variable(i8 value);
  44. Variable(i16 value);
  45. Variable(i32 value);
  46. Variable(i64 value);
  47. Variable(f32 value);
  48. Variable(f64 value);
  49. // Buffer_array init
  50. Variable(const std::string_view str);
  51. Variable(const std::u16string_view str);
  52. Variable(const std::u32string_view str);
  53. Variable(const std::wstring_view wstr);
  54. Variable(const std::string str);
  55. Variable(const std::u16string str);
  56. Variable(const std::u32string str);
  57. Variable(const std::wstring wstr);
  58. Variable(const char* str);
  59. Variable(const char16_t* str);
  60. Variable(const char32_t* str);
  61. Variable(const wchar_t* str);
  62. Variable(size_t size, ui8 value);
  63. Variable(size_t size, ui16 value);
  64. Variable(size_t size, ui32 value);
  65. Variable(size_t size, ui64 value);
  66. Variable(size_t size, i8 value);
  67. Variable(size_t size, i16 value);
  68. Variable(size_t size, i32 value);
  69. Variable(size_t size, i64 value);
  70. Variable(ui8* values, size_t size);
  71. Variable(ui16* values, size_t size);
  72. Variable(ui32* values, size_t size);
  73. Variable(ui64* values, size_t size);
  74. Variable(i8* values, size_t size);
  75. Variable(i16* values, size_t size);
  76. Variable(i32* values, size_t size);
  77. Variable(i64* values, size_t size);
  78. Variable(ui8arr array);
  79. Variable(ui16arr array);
  80. Variable(ui32arr array);
  81. Variable(ui64arr array);
  82. Variable(i8arr array);
  83. Variable(i16arr array);
  84. Variable(i32arr array);
  85. Variable(i64arr array);
  86. // Array
  87. Variable(varr array);
  88. // Object
  89. Variable(vobj object);
  90. Variable(Primitive primitive);
  91. Variable(BufferArray buffer_array);
  92. Variable(Array array);
  93. Variable(Object object);
  94. // By value reference
  95. Variable(ValueRef ref);
  96. Variable(Variable&& other);
  97. Variable(const Variable& other);
  98. ~Variable() {destroy();}
  99. static Variable create(VarType type);
  100. ByteArray serialize() const;
  101. static Variable deserialize(ByteArray::iterator& it);
  102. static inline Variable deserialize(ByteArray serialized) {ByteArray::iterator it = serialized.begin(); return deserialize(it);}
  103. static inline Variable deserialize(ByteArrayView serialized) {ByteArray::iterator it = serialized.begin(); return deserialize(it);}
  104. inline void* getDataPointer() const {return data.ptr;}
  105. inline VarType type() const noexcept {return (data.type == nullptr)? VarType::invalid_type :*data.type;}
  106. inline VarTypeClass typeClass() const noexcept {return (data.type == nullptr)? VarTypeClass::invalid_type :toTypeClass(*data.type);}
  107. inline bool isNull() const noexcept {return data.type == nullptr;}
  108. // Type class checks
  109. inline bool isPrimitive() const noexcept {return typeClass() == VarTypeClass::primitive;}
  110. inline bool isBufferArray() const noexcept {return typeClass() == VarTypeClass::buffer_array;}
  111. inline bool isArray() const noexcept {return typeClass() == VarTypeClass::array;}
  112. inline bool isObject() const noexcept {return typeClass() == VarTypeClass::object;}
  113. inline bool isByte() const noexcept {return (isPrimitive() || isBufferArray())? toValueType(type()) == ValType::byte : false;}
  114. inline bool isWord() const noexcept {return (isPrimitive() || isBufferArray())? toValueType(type()) == ValType::word : false;}
  115. inline bool isDword() const noexcept {return (isPrimitive() || isBufferArray())? toValueType(type()) == ValType::dword : false;}
  116. inline bool isQword() const noexcept {return (isPrimitive() || isBufferArray())? toValueType(type()) == ValType::qword : false;}
  117. // Type casts
  118. inline Primitive& toPrimitive() const {throwIfNot(VarTypeClass::primitive); return const_cast<Primitive&>(data.primitive);}
  119. inline BufferArray& toBufferArray() const {throwIfNot(VarTypeClass::buffer_array); return const_cast<BufferArray&>(data.buffer_array);}
  120. inline Array& toArray() const {throwIfNot(VarTypeClass::array); return const_cast<Array&>(data.array);}
  121. inline Object& toObject() const {throwIfNot(VarTypeClass::object); return const_cast<Object&>(data.object);}
  122. inline operator Primitive&() const {return toPrimitive();}
  123. inline operator BufferArray&() const {return toBufferArray();}
  124. inline operator Array&() const {return toArray();}
  125. inline operator Object&() const {return toObject();}
  126. // Member access
  127. inline Variable& getVariable(ui64 index) const {throwIfNot(VarTypeClass::array); return toArray().getVariable(index);}
  128. inline Variable& getVariable(BufferArray name) const {throwIfNot(VarTypeClass::object); return toObject().getVariable(name);}
  129. inline ValueRef getValue() const {throwIfNot(VarTypeClass::primitive); return toPrimitive().getValue();}
  130. inline ValueRef getValue(ui64 index) const {throwIfNot(VarTypeClass::buffer_array); return toBufferArray().getValue(index);}
  131. inline Variable& operator[](ui64 index) const {return getVariable(index);}
  132. inline Variable& operator[](BufferArray name) const {return getVariable(std::move(name));}
  133. Variable& operator=(Variable other);
  134. ui64 length() const;
  135. inline ui64 getMemberCount() const {return length();}
  136. bool operator==(Variable other) const;
  137. bool operator!=(Variable other) const;
  138. bool operator<(Variable other) const;
  139. bool operator<=(Variable other) const;
  140. bool operator>(Variable other) const;
  141. bool operator>=(Variable other) const;
  142. i8 getCompare(Variable other) const;
  143. inline bool contains(BufferArray name) const { if(!isObject()) return false; else return toObject().contains(std::move(name)); }
  144. inline bool inRange(ui64 index) const {
  145. switch (typeClass()) {
  146. case VarTypeClass::array: return toArray().inRange(index);
  147. case VarTypeClass::buffer_array: return toBufferArray().inRange(index);
  148. default: return false;
  149. }
  150. }
  151. NodeVisitor getNode();
  152. operator NodeVisitor();
  153. };
  154. // Initers or other
  155. struct NamedVariable {
  156. BufferArray name;
  157. Variable variable;
  158. NamedVariable& operator=(NamedVariable& other) {
  159. name.data.ptr = other.name.clone();
  160. variable.data.ptr = other.variable.clone();
  161. return *this;
  162. }
  163. };
  164. struct OutputManip {
  165. static inline bool print_type = false;
  166. static thread_local inline enum class Primitive : ui8 {
  167. HEX,
  168. SIGNED,
  169. UNSIGNED
  170. } primitive = Primitive::HEX;
  171. static thread_local inline enum class BufferArray : ui8 {
  172. PRIMITIVE,
  173. STRING
  174. } buffer_array = BufferArray::STRING;
  175. OutputManip() = delete;
  176. OutputManip(const OutputManip&) = delete;
  177. OutputManip(OutputManip&&) = delete;
  178. };
  179. }
  180. std::ostream& operator<<(std::ostream& os, const binom::ValueRef val);
  181. std::ostream& operator<<(std::ostream& os, binom::Primitive& primitive);
  182. std::ostream& operator<<(std::ostream& os, const binom::BufferArray& buffer);
  183. std::ostream& operator<<(std::ostream& os, const binom::Array& array);
  184. std::ostream& operator<<(std::ostream& os, const binom::Object& object);
  185. std::ostream& operator<<(std::ostream& os, const binom::Variable& var);
  186. #endif