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 Yahoo. 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;
};
}
|