libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
hashset.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
13#include <unordered_set>
14#include <initializer_list>
15#include <promeki/namespace.h>
16#include <promeki/sharedptr.h>
17#include <promeki/list.h>
18
19PROMEKI_NAMESPACE_BEGIN
20
35template <typename T> class HashSet {
36 PROMEKI_SHARED_FINAL(HashSet)
37 public:
39 using Ptr = SharedPtr<HashSet>;
40
42 using Data = std::unordered_set<T>;
43
45 using Value = T;
46
48 using Iterator = typename Data::iterator;
49
51 using ConstIterator = typename Data::const_iterator;
52
54 HashSet() = default;
55
57 HashSet(const HashSet &other) : d(other.d) {}
58
60 HashSet(HashSet &&other) noexcept : d(std::move(other.d)) {}
61
66 HashSet(std::initializer_list<T> initList) : d(initList) {}
67
69 ~HashSet() = default;
70
72 HashSet &operator=(const HashSet &other) {
73 d = other.d;
74 return *this;
75 }
76
78 HashSet &operator=(HashSet &&other) noexcept {
79 d = std::move(other.d);
80 return *this;
81 }
82
83 // -- Iterators --
84
86 Iterator begin() noexcept { return d.begin(); }
87
89 ConstIterator begin() const noexcept { return d.cbegin(); }
90
92 ConstIterator cbegin() const noexcept { return d.cbegin(); }
93
95 ConstIterator constBegin() const noexcept { return d.cbegin(); }
96
98 Iterator end() noexcept { return d.end(); }
99
101 ConstIterator end() const noexcept { return d.cend(); }
102
104 ConstIterator cend() const noexcept { return d.cend(); }
105
107 ConstIterator constEnd() const noexcept { return d.cend(); }
108
109 // -- Capacity --
110
112 bool isEmpty() const noexcept { return d.empty(); }
113
115 size_t size() const noexcept { return d.size(); }
116
117 // -- Lookup --
118
120 bool contains(const T &value) const { return d.find(value) != d.end(); }
121
122 // -- Modifiers --
123
129 bool insert(const T &value) { return d.insert(value).second; }
130
136 bool insert(T &&value) { return d.insert(std::move(value)).second; }
137
143 bool remove(const T &value) { return d.erase(value) > 0; }
144
150 Iterator remove(Iterator pos) { return d.erase(pos); }
151
153 void clear() noexcept {
154 d.clear();
155 return;
156 }
157
162 void swap(HashSet &other) noexcept {
163 d.swap(other.d);
164 return;
165 }
166
167 // -- Set Operations --
168
174 HashSet unite(const HashSet &other) const {
175 HashSet ret = *this;
176 for (const auto &v : other.d) ret.d.insert(v);
177 return ret;
178 }
179
185 HashSet intersect(const HashSet &other) const {
186 HashSet ret;
187 for (const auto &v : d) {
188 if (other.contains(v)) ret.d.insert(v);
189 }
190 return ret;
191 }
192
198 HashSet subtract(const HashSet &other) const {
199 HashSet ret;
200 for (const auto &v : d) {
201 if (!other.contains(v)) ret.d.insert(v);
202 }
203 return ret;
204 }
205
206 // -- Convenience --
207
212 List<T> toList() const {
213 List<T> ret;
214 ret.reserve(d.size());
215 for (const auto &v : d) ret.pushToBack(v);
216 return ret;
217 }
218
224 template <typename Func> void forEach(Func &&func) const {
225 for (const auto &v : d) func(v);
226 return;
227 }
228
229 // -- Comparison --
230
232 friend bool operator==(const HashSet &lhs, const HashSet &rhs) { return lhs.d == rhs.d; }
233
235 friend bool operator!=(const HashSet &lhs, const HashSet &rhs) { return lhs.d != rhs.d; }
236
237 private:
238 Data d;
239};
240
241PROMEKI_NAMESPACE_END
242
243#endif // PROMEKI_ENABLE_CORE