| 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
|