#ifndef PORYGONLANG_USERDATACOLLECTIONVALUE_HPP #define PORYGONLANG_USERDATACOLLECTIONVALUE_HPP #include #include "UserDataCollectionType.hpp" #include "../../Evaluator/EvalValues/EvalValue.hpp" #include "../../Utilities/Random.hpp" using namespace Porygon::Evaluation; namespace Porygon::UserData { class UserDataCollectionHelper{ void* _parentObject; const EvalValue* (*_get)(void*, const EvalValue*); void (*_set)(void*, const EvalValue* , const EvalValue*); Iterator* (*_getIterator)(void*); public: UserDataCollectionHelper(void* parentObject, const EvalValue* (*get)(void*, const EvalValue*), void (*set)(void*, const EvalValue*, const EvalValue*), Iterator* (*getIterator)(void*)) : _parentObject(parentObject), _get(get), _set(set), _getIterator(getIterator){} const EvalValue* Get(const EvalValue* key) const{ return _get(_parentObject, key); } void Set(const EvalValue* key, const EvalValue* value) const{ _set(_parentObject, key, value); } [[nodiscard]] Iterator* GetIterator() const{ return _getIterator(_parentObject); } }; class UserDataCollectionValue : public Evaluation::EvalValue{ shared_ptr _type; shared_ptr _helper; const size_t _hash; UserDataCollectionValue(shared_ptr type, shared_ptr helper, size_t hash) : _type(std::move(type)), _helper(std::move(helper)), _hash(hash) { } public: UserDataCollectionValue(ScriptType* type, const UserDataCollectionHelper* helper) : _type(dynamic_cast(type)), _helper(helper), _hash(Utilities::Random::Get()) { } [[nodiscard]] TypeClass GetTypeClass() const final{ return TypeClass ::Table; } bool operator==(const EvalValue *b) const final{ return b->GetHashCode() == _hash; } [[nodiscard]] EvalValue* Clone() const final{ return new UserDataCollectionValue(_type, _helper, _hash); } [[nodiscard]] std::size_t GetHashCode() const final{ return _hash; } const EvalValue* IndexValue(const EvalValue *val) const final{ return _helper->Get(val); } [[nodiscard]] Iterator * GetKeyIterator() const final{ return _helper->GetIterator(); } void SetIndexValue(const EvalValue *key, const EvalValue* value) const final{ _helper->Set(key, value); delete value; } }; } #endif //PORYGONLANG_USERDATACOLLECTIONVALUE_HPP