dlinear  0.0.1
Delta-complete SMT solver for linear programming
Loading...
Searching...
No Matches
ScopedUnorderedSet.hpp
1
11#pragma once
12
13#include <functional>
14#include <iostream>
15#include <memory>
16#include <tuple>
17#include <unordered_set>
18#include <utility>
19#include <vector>
20
21namespace dlinear {
22
23template <class Key, class Hash = std::hash<Key>, class KeyEqual = std::equal_to<Key>,
24 class Allocator = std::allocator<Key>>
26 public:
28 using UnorderedSetType = std::unordered_set<Key, Hash, KeyEqual, Allocator>;
29 using key_type = typename UnorderedSetType::key_type;
30 using value_type = typename UnorderedSetType::value_type;
31 using size_type = typename UnorderedSetType::size_type;
32 using const_iterator = typename UnorderedSetType::const_iterator;
33
36 enum class ActionKind {
37 INSERT,
38 };
39 using Action = std::tuple<ActionKind, Key>;
40
41 ScopedUnorderedSet() = default;
42 ScopedUnorderedSet(const ScopedUnorderedSet &) = default;
43 ScopedUnorderedSet(ScopedUnorderedSet &&) noexcept = default;
44 ScopedUnorderedSet &operator=(const ScopedUnorderedSet &) = default;
45 ScopedUnorderedSet &operator=(ScopedUnorderedSet &&) noexcept = default;
46 ~ScopedUnorderedSet() = default;
47
53 const_iterator begin() const { return set_.begin(); }
54 const_iterator cbegin() const { return set_.cbegin(); }
55 const_iterator end() const { return set_.end(); }
56 const_iterator cend() const { return set_.cend(); }
57
59 bool empty() const { return set_.empty(); }
60 size_type size() const { return set_.size(); }
61
63 void clear() {
64 set_.clear();
65 actions_.clear();
66 stack_.clear();
67 }
68 void insert(const Key &k) {
69 auto it = set_.find(k);
70 if (it == set_.end()) {
71 // Case 1) k does not exist.
72 actions_.emplace_back(ActionKind::INSERT, k);
73 set_.emplace(k);
74 }
75 }
76
77 size_type count(const Key &key) const { return set_.count(key); }
79 const_iterator find(const Key &key) const { return set_.find(key); }
80
82 void push() { stack_.push_back(actions_.size()); }
83 void pop() {
84 if (stack_.empty()) {
85 throw std::runtime_error("ScopedUnorderedSet cannot be popped because it's scope is empty.");
86 }
87 size_type idx = stack_.back();
88 while (idx < actions_.size()) {
89 const Action &item{actions_.back()};
90 const ActionKind kind{std::get<0>(item)};
91 const Key &k{std::get<1>(item)};
92 auto it = set_.find(k);
93 switch (kind) {
95 // Remove k.
96 set_.erase(it);
97 break;
98 }
99 actions_.pop_back();
100 }
101 stack_.pop_back();
102 }
103
104 private:
105 std::vector<Action> actions_;
106 std::vector<size_type> stack_;
107 UnorderedSetType set_;
108};
109
110} // namespace dlinear
ActionKind
To backtrack, we need to record the actions applied to this container.
@ INSERT
Insert(k) means that k is inserted.
std::unordered_set< Key, Hash, KeyEqual, Allocator > UnorderedSetType
Aliases.
const_iterator begin() const
Iterators.
const_iterator find(const Key &key) const
Global namespace for the dlinear library.