1 | /*
|
2 | * Souffle - A Datalog Compiler
|
3 | * Copyright (c) 2013, 2014, 2015 Oracle and/or its affiliates. All rights reserved
|
4 | * Licensed under the Universal Permissive License v 1.0 as shown at:
|
5 | * - https://opensource.org/licenses/UPL
|
6 | * - <souffle root>/licenses/SOUFFLE-UPL.txt
|
7 | */
|
8 |
|
9 | /************************************************************************
|
10 | *
|
11 | * @file SymbolTable.h
|
12 | *
|
13 | * Encodes/decodes symbols to numbers (and vice versa).
|
14 | *
|
15 | ***********************************************************************/
|
16 |
|
17 | #pragma once
|
18 |
|
19 | #include "souffle/RamTypes.h"
|
20 |
|
21 | #include <memory>
|
22 | #include <string>
|
23 |
|
24 | namespace souffle {
|
25 |
|
26 | /** Interface of a generic SymbolTable iterator. */
|
27 | class SymbolTableIteratorInterface {
|
28 | public:
|
29 | virtual ~SymbolTableIteratorInterface() {}
|
30 |
|
31 | virtual const std::pair<const std::string, const std::size_t>& get() const = 0;
|
32 |
|
33 | virtual bool equals(const SymbolTableIteratorInterface& other) = 0;
|
34 |
|
35 | virtual SymbolTableIteratorInterface& incr() = 0;
|
36 |
|
37 | virtual std::unique_ptr<SymbolTableIteratorInterface> copy() const = 0;
|
38 | };
|
39 |
|
40 | /**
|
41 | * @class SymbolTable
|
42 | *
|
43 | * SymbolTable encodes symbols to numbers and decodes numbers to symbols.
|
44 | */
|
45 | class SymbolTable {
|
46 | public:
|
47 | virtual ~SymbolTable() {}
|
48 |
|
49 | /**
|
50 | * @brief Iterator on a symbol table.
|
51 | *
|
52 | * Iterator over pairs of a symbol and its encoding index.
|
53 | */
|
54 | class Iterator {
|
55 | public:
|
56 | using value_type = const std::pair<const std::string, const std::size_t>;
|
57 | using reference = value_type&;
|
58 | using pointer = value_type*;
|
59 |
|
60 | Iterator(std::unique_ptr<SymbolTableIteratorInterface> ptr) : impl(std::move(ptr)) {}
|
61 |
|
62 | Iterator(const Iterator& it) : impl(it.impl->copy()) {}
|
63 |
|
64 | Iterator(Iterator&& it) : impl(std::move(it.impl)) {}
|
65 |
|
66 | reference operator*() const {
|
67 | return impl->get();
|
68 | }
|
69 |
|
70 | pointer operator->() const {
|
71 | return &impl->get();
|
72 | }
|
73 |
|
74 | Iterator& operator++() {
|
75 | impl->incr();
|
76 | return *this;
|
77 | }
|
78 |
|
79 | Iterator operator++(int) {
|
80 | Iterator prev(impl->copy());
|
81 | impl->incr();
|
82 | return prev;
|
83 | }
|
84 |
|
85 | bool operator==(const Iterator& I) const {
|
86 | return impl->equals(*I.impl);
|
87 | }
|
88 |
|
89 | bool operator!=(const Iterator& I) const {
|
90 | return !impl->equals(*I.impl);
|
91 | }
|
92 |
|
93 | private:
|
94 | std::unique_ptr<SymbolTableIteratorInterface> impl;
|
95 | };
|
96 |
|
97 | using iterator = Iterator;
|
98 |
|
99 | /** @brief Return an iterator on the first symbol. */
|
100 | virtual iterator begin() const = 0;
|
101 |
|
102 | /** @brief Return an iterator past the last symbol. */
|
103 | virtual iterator end() const = 0;
|
104 |
|
105 | /** @brief Check if the given symbol exist. */
|
106 | virtual bool weakContains(const std::string& symbol) const = 0;
|
107 |
|
108 | /** @brief Encode a symbol to a symbol index. */
|
109 | virtual RamDomain encode(const std::string& symbol) = 0;
|
110 |
|
111 | /** @brief Decode a symbol index to a symbol. */
|
112 | virtual const std::string& decode(const RamDomain index) const = 0;
|
113 |
|
114 | /** @brief Encode a symbol to a symbol index; aliases encode. */
|
115 | virtual RamDomain unsafeEncode(const std::string& symbol) = 0;
|
116 |
|
117 | /** @brief Decode a symbol index to a symbol; aliases decode. */
|
118 | virtual const std::string& unsafeDecode(const RamDomain index) const = 0;
|
119 |
|
120 | /**
|
121 | * @brief Encode the symbol, it is inserted if it does not exist.
|
122 | *
|
123 | * @return the symbol index and a boolean indicating if an insertion
|
124 | * happened.
|
125 | */
|
126 | virtual std::pair<RamDomain, bool> findOrInsert(const std::string& symbol) = 0;
|
127 | };
|
128 |
|
129 | } // namespace souffle
|