Implement "set" function for arrays

This commit is contained in:
Konstantin Nazarov 2024-09-18 20:02:56 +01:00
parent b967aa6768
commit a81b54a37a
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
3 changed files with 35 additions and 0 deletions

View file

@ -692,6 +692,31 @@ Result<Value> Array::get(const Value& key) const {
return get(key.to<Int64>()->value()); return get(key.to<Int64>()->value());
} }
Result<Array> Array::set(uint64_t idx, const Value& value) const {
uint64_t res_size = TRY(size());
if (idx >= res_size) return ERROR(IndexOutOfRange);
auto pod = TRY(arena_alloc<PodArray>(res_size * sizeof(OffPtr<PodObject>)));
pod->header.tag = Tag::Array;
pod->size = res_size;
for (uint64_t i = 0; i < res_size; i++) {
pod->data[i] = _value->data[i].get();
}
pod->data[idx] = value.pod();
return Array(TRY(MkGcRoot(pod)));
}
Result<Array> Array::set(const Value& key, const Value& value) const {
if (!key.is<Int64>()) return ERROR(TypeMismatch);
return set(key.to<Int64>()->value(), value);
}
Result<Value> Array::set_value(const Value& key, const Value& value) const {
return Value(TRY(set(key, value)));
}
Result<Array> Array::append(const Value& rhs) const { Result<Array> Array::append(const Value& rhs) const {
uint64_t res_size = TRY(size()) + 1; uint64_t res_size = TRY(size()) + 1;
auto size = TRY(this->size()); auto size = TRY(this->size());

View file

@ -210,6 +210,10 @@ class Array : public Object {
Result<Value> get(uint64_t idx) const; Result<Value> get(uint64_t idx) const;
virtual Result<Value> get(const Value& key) const final; virtual Result<Value> get(const Value& key) const final;
Result<Array> set(uint64_t idx, const Value& value) const;
Result<Array> set(const Value& key, const Value& value) const;
virtual Result<Value> set_value(const Value& key,
const Value& value) const final;
Result<Array> append(const Value& rhs) const; Result<Array> append(const Value& rhs) const;
template <class V> template <class V>

View file

@ -10,6 +10,12 @@
(assert (= (get {1 2 3 4} 3) (assert (= (get {1 2 3 4} 3)
4)) 4))
(assert (= (set {:foo 1} :bar 2)
{:foo 1 :bar 2}))
(assert (= (set [1 2] 1 42)
[1 42]))
;; Accessing collections by symbol ;; Accessing collections by symbol
(assert (= (get {:foo 1 :bar 2} :bar) (assert (= (get {:foo 1 :bar 2} :bar)
2)) 2))