|
@@ -21,45 +21,37 @@ struct HashMap final {
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
- int next;
|
|
|
-
|
|
|
- Node(const K& key, const V& value) : key(key), value(value), next(-1) {
|
|
|
- }
|
|
|
-
|
|
|
- Node(const K& key, V&& value)
|
|
|
- : key(key), value(std::move(value)), next(-1) {
|
|
|
- }
|
|
|
-
|
|
|
template<typename... Args>
|
|
|
Node(const K& key, Args&&... args)
|
|
|
- : key(key), value(std::forward<Args>(args)...), next(-1) {
|
|
|
+ : key(key), value(std::forward<Args>(args)...) {
|
|
|
}
|
|
|
};
|
|
|
+ using Nodes = List<List<Node>>;
|
|
|
|
|
|
- template<typename N, typename R>
|
|
|
- class BaseEntryIterator final {
|
|
|
+ template<typename N, typename I, typename R, R& (*A)(I&)>
|
|
|
+ class Iterator final {
|
|
|
N& nodes;
|
|
|
int indexA;
|
|
|
int indexB;
|
|
|
|
|
|
public:
|
|
|
- BaseEntryIterator(N& nodes, int indexA, int indexB)
|
|
|
+ Iterator(N& nodes, int indexA, int indexB)
|
|
|
: nodes(nodes), indexA(indexA), indexB(indexB) {
|
|
|
skip();
|
|
|
}
|
|
|
|
|
|
- BaseEntryIterator& operator++() {
|
|
|
+ Iterator& operator++() {
|
|
|
indexB++;
|
|
|
skip();
|
|
|
return *this;
|
|
|
}
|
|
|
|
|
|
- bool operator!=(const BaseEntryIterator& other) const {
|
|
|
+ bool operator!=(const Iterator& other) const {
|
|
|
return indexA != other.indexA || indexB != other.indexB;
|
|
|
}
|
|
|
|
|
|
- R& operator*() {
|
|
|
- return nodes[indexA][indexB];
|
|
|
+ R& operator*() const {
|
|
|
+ return A(nodes[indexA][indexB]);
|
|
|
}
|
|
|
|
|
|
private:
|
|
@@ -72,147 +64,60 @@ struct HashMap final {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- typedef BaseEntryIterator<List<List<Node>>, Node> EntryIterator;
|
|
|
- typedef BaseEntryIterator<const List<List<Node>>, const Node>
|
|
|
- ConstEntryIterator;
|
|
|
-
|
|
|
- struct EntryIteratorAdapter final {
|
|
|
- HashMap& map;
|
|
|
-
|
|
|
- EntryIterator begin() {
|
|
|
- return EntryIterator(map.nodes, 0, 0);
|
|
|
- }
|
|
|
-
|
|
|
- EntryIterator end() {
|
|
|
- return EntryIterator(map.nodes, map.nodes.getLength(), 0);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- struct ConstEntryIteratorAdapter final {
|
|
|
- const HashMap& map;
|
|
|
+ template<typename R>
|
|
|
+ static R& access(R& node) {
|
|
|
+ return node;
|
|
|
+ }
|
|
|
|
|
|
- ConstEntryIterator begin() const {
|
|
|
- return ConstEntryIterator(map.nodes, 0, 0);
|
|
|
- }
|
|
|
+ template<typename I, typename R>
|
|
|
+ static R& accessValue(I& node) {
|
|
|
+ return node.value;
|
|
|
+ }
|
|
|
|
|
|
- ConstEntryIterator end() const {
|
|
|
- return ConstEntryIterator(map.nodes, map.nodes.getLength(), 0);
|
|
|
- }
|
|
|
- };
|
|
|
+ static const K& accessKey(const Node& node) {
|
|
|
+ return node.getKey();
|
|
|
+ }
|
|
|
|
|
|
template<typename N, typename R>
|
|
|
- class BaseValueIterator final {
|
|
|
- N& nodes;
|
|
|
- int indexA;
|
|
|
- int indexB;
|
|
|
+ using BaseEntryIterator = Iterator<N, R, R, access<R>>;
|
|
|
+ using EntryIterator = BaseEntryIterator<Nodes, Node>;
|
|
|
+ using ConstEntryIterator = BaseEntryIterator<const Nodes, const Node>;
|
|
|
|
|
|
- public:
|
|
|
- BaseValueIterator(N& nodes, int indexA, int indexB)
|
|
|
- : nodes(nodes), indexA(indexA), indexB(indexB) {
|
|
|
- skip();
|
|
|
- }
|
|
|
+ template<typename N, typename I, typename R>
|
|
|
+ using BaseValueIterator = Iterator<N, I, R, accessValue<I, R>>;
|
|
|
+ using ValueIterator = BaseValueIterator<Nodes, Node, V>;
|
|
|
+ using ConstValueIterator =
|
|
|
+ BaseValueIterator<const Nodes, const Node, const V>;
|
|
|
|
|
|
- BaseValueIterator& operator++() {
|
|
|
- indexB++;
|
|
|
- skip();
|
|
|
- return *this;
|
|
|
- }
|
|
|
+ using ConstKeyIterator =
|
|
|
+ Iterator<const Nodes, const Node, const K, accessKey>;
|
|
|
|
|
|
- bool operator!=(const BaseValueIterator& other) const {
|
|
|
- return indexA != other.indexA || indexB != other.indexB;
|
|
|
- }
|
|
|
+ template<typename M, typename I>
|
|
|
+ struct IteratorAdapter final {
|
|
|
+ M& map;
|
|
|
|
|
|
- R& operator*() {
|
|
|
- return nodes[indexA][indexB].value;
|
|
|
+ I begin() const {
|
|
|
+ return I(map.nodes, 0, 0);
|
|
|
}
|
|
|
|
|
|
- private:
|
|
|
- void skip() {
|
|
|
- while(indexA < nodes.getLength() &&
|
|
|
- indexB >= nodes[indexA].getLength()) {
|
|
|
- indexA++;
|
|
|
- indexB = 0;
|
|
|
- }
|
|
|
+ I end() const {
|
|
|
+ return I(map.nodes, map.nodes.getLength(), 0);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- typedef BaseValueIterator<List<List<Node>>, V> ValueIterator;
|
|
|
- typedef BaseValueIterator<const List<List<Node>>, const V>
|
|
|
- ConstValueIterator;
|
|
|
+ using EntryIteratorAdapter = IteratorAdapter<HashMap, EntryIterator>;
|
|
|
+ using ConstEntryIteratorAdapter =
|
|
|
+ IteratorAdapter<const HashMap, ConstEntryIterator>;
|
|
|
|
|
|
- struct ValueIteratorAdapter final {
|
|
|
- HashMap& map;
|
|
|
+ using ValueIteratorAdapter = IteratorAdapter<HashMap, ValueIterator>;
|
|
|
+ using ConstValueIteratorAdapter =
|
|
|
+ IteratorAdapter<const HashMap, ConstValueIterator>;
|
|
|
|
|
|
- ValueIterator begin() {
|
|
|
- return ValueIterator(map.nodes, 0, 0);
|
|
|
- }
|
|
|
-
|
|
|
- ValueIterator end() {
|
|
|
- return ValueIterator(map.nodes, map.nodes.getLength(), 0);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- struct ConstValueIteratorAdapter final {
|
|
|
- const HashMap& map;
|
|
|
-
|
|
|
- ConstValueIterator begin() const {
|
|
|
- return ConstValueIterator(map.nodes, 0, 0);
|
|
|
- }
|
|
|
-
|
|
|
- ConstValueIterator end() const {
|
|
|
- return ConstValueIterator(map.nodes, map.nodes.getLength(), 0);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- class ConstKeyIterator final {
|
|
|
- const List<List<Node>>& nodes;
|
|
|
- int indexA;
|
|
|
- int indexB;
|
|
|
-
|
|
|
- public:
|
|
|
- ConstKeyIterator(const List<List<Node>>& nodes, int indexA, int indexB)
|
|
|
- : nodes(nodes), indexA(indexA), indexB(indexB) {
|
|
|
- skip();
|
|
|
- }
|
|
|
-
|
|
|
- ConstKeyIterator& operator++() {
|
|
|
- indexB++;
|
|
|
- skip();
|
|
|
- return *this;
|
|
|
- }
|
|
|
-
|
|
|
- bool operator!=(const ConstKeyIterator& other) const {
|
|
|
- return indexA != other.indexA || indexB != other.indexB;
|
|
|
- }
|
|
|
-
|
|
|
- const K& operator*() {
|
|
|
- return nodes[indexA][indexB].getKey();
|
|
|
- }
|
|
|
-
|
|
|
- private:
|
|
|
- void skip() {
|
|
|
- while(indexA < nodes.getLength() &&
|
|
|
- indexB >= nodes[indexA].getLength()) {
|
|
|
- indexA++;
|
|
|
- indexB = 0;
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- struct ConstKeyIteratorAdapter final {
|
|
|
- const HashMap& map;
|
|
|
-
|
|
|
- ConstKeyIterator begin() const {
|
|
|
- return ConstKeyIterator(map.nodes, 0, 0);
|
|
|
- }
|
|
|
-
|
|
|
- ConstKeyIterator end() const {
|
|
|
- return ConstKeyIterator(map.nodes, map.nodes.getLength(), 0);
|
|
|
- }
|
|
|
- };
|
|
|
+ using ConstKeyIteratorAdapter =
|
|
|
+ IteratorAdapter<const HashMap, ConstKeyIterator>;
|
|
|
|
|
|
private:
|
|
|
- List<List<Node>> nodes;
|
|
|
+ Nodes nodes;
|
|
|
int elements;
|
|
|
|
|
|
public:
|
|
@@ -233,28 +138,16 @@ public:
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
- HashMap& add(const K& key, const V& value) {
|
|
|
- rehash();
|
|
|
- Hash h = hash(key);
|
|
|
- V* v = searchList(key, h);
|
|
|
- if(v == nullptr) {
|
|
|
- nodes[h].add(key, value);
|
|
|
- elements++;
|
|
|
- } else {
|
|
|
- *v = value;
|
|
|
- }
|
|
|
- return *this;
|
|
|
- }
|
|
|
-
|
|
|
- HashMap& add(const K& key, V&& value) {
|
|
|
+ template<typename VA>
|
|
|
+ HashMap& add(const K& key, VA&& value) {
|
|
|
rehash();
|
|
|
Hash h = hash(key);
|
|
|
V* v = searchList(key, h);
|
|
|
if(v == nullptr) {
|
|
|
- nodes[h].add(key, std::move(value));
|
|
|
+ nodes[h].add(key, std::forward<VA>(value));
|
|
|
elements++;
|
|
|
} else {
|
|
|
- *v = std::move(value);
|
|
|
+ *v = std::forward<VA>(value);
|
|
|
}
|
|
|
return *this;
|
|
|
}
|
|
@@ -294,11 +187,11 @@ public:
|
|
|
return {*this};
|
|
|
}
|
|
|
|
|
|
- const ConstEntryIteratorAdapter entries() const {
|
|
|
+ ConstEntryIteratorAdapter entries() const {
|
|
|
return {*this};
|
|
|
}
|
|
|
|
|
|
- const ConstKeyIteratorAdapter keys() const {
|
|
|
+ ConstKeyIteratorAdapter keys() const {
|
|
|
return {*this};
|
|
|
}
|
|
|
|
|
@@ -306,7 +199,7 @@ public:
|
|
|
return {*this};
|
|
|
}
|
|
|
|
|
|
- const ConstValueIteratorAdapter values() const {
|
|
|
+ ConstValueIteratorAdapter values() const {
|
|
|
return {*this};
|
|
|
}
|
|
|
|