aboutsummaryrefslogtreecommitdiffstats
path: root/vespalib/src/vespa/vespalib/data/slime/object_value.h
blob: 086f87521331b70ca3132528be017e10a47824b0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#pragma once

#include "value.h"
#include "nix_value.h"
#include "symbol.h"
#include "symbol_lookup.h"
#include "value_factory.h"
#include "symbol_inserter.h"
#include <vespa/vespalib/stllike/vector_map.h>

namespace vespalib { class Stash; }
namespace vespalib::slime {

/**
 * Class representing a collection of unordered values that can be
 * looked up by symbol.
 **/
class ObjectValue final : public Value
{
private:
    struct hasher {
        size_t operator () (const Symbol & s) const { return s.getValue(); }
    };
    using SymbolValueMap = vector_map<Symbol, Value*>;
    SymbolTable    &_symbolTable;
    Stash          &_stash;
    SymbolValueMap  _fields;

    Cursor &setIfUnset(SymbolInserter &symbol, const ValueFactory &input) {
        Value *&pos = _fields[symbol.insert()];
        if (pos != nullptr) {
            return *NixValue::invalid();
        }
        pos = input.create(_stash);
        return *pos;
    }

    Value *lookup(const SymbolLookup &symbol) const {
        auto pos = _fields.find(symbol.lookup());
        if (pos == _fields.end()) {
            return NixValue::invalid();
        }
        return pos->second;
    }
protected:
    Cursor &setLeaf(Symbol sym, const ValueFactory &input) override;
    Cursor &setLeaf(Memory name, const ValueFactory &input) override;

public:
    ObjectValue(SymbolTable &table, Stash & stash) : _symbolTable(table), _stash(stash), _fields() {
        _fields.reserve(4);
    }

    ObjectValue(SymbolTable &table, Stash & stash, SymbolInserter &symbol, Value *value)
        : _symbolTable(table), _stash(stash), _fields()
    {
        _fields.reserve(4);
        _fields[symbol.insert()] = value;
    }
    ObjectValue(const ObjectValue &) = delete;
    ObjectValue &operator=(const ObjectValue &) = delete;


    Type type() const override { return OBJECT::instance; }
    size_t children() const override { return _fields.size(); }
    size_t fields() const override { return _fields.size(); }
    void traverse(ObjectSymbolTraverser &ot) const override;
    void traverse(ObjectTraverser &ot) const override;

    Cursor &operator[](Symbol sym) const override;
    Cursor &operator[](Memory name) const override;

    Cursor &setArray(Symbol sym, size_t reserve) override;
    Cursor &setObject(Symbol sym) override;

    Cursor &setArray(Memory name, size_t reserve) override;
    Cursor &setObject(Memory name) override;
    Symbol resolve(Memory symbol_name) override;

    ~ObjectValue() override = default;
};

}