1/*
2 * LegacyClonk
3 *
4 * Copyright (c) 2019-2022, The LegacyClonk Team and contributors
5 *
6 * Distributed under the terms of the ISC license; see accompanying file
7 * "COPYING" for details.
8 *
9 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
10 * See accompanying file "TRADEMARK" for details.
11 *
12 * To redistribute this file separately, substitute the full license texts
13 * for the above references.
14 */
15
16#pragma once
17
18#include "C4Value.h"
19#include "C4ValueStandardRefCountedContainer.h"
20
21#include <unordered_map>
22#include <forward_list>
23#include <list>
24#include <memory>
25
26class C4ValueHash : public C4ValueStandardRefCountedContainer<C4ValueHash>
27{
28public:
29 using key_type = C4Value;
30 using mapped_type = C4Value;
31
32private:
33 struct MapEntry
34 {
35 C4Value *value;
36 std::list<const C4Value *>::iterator keyOrderIterator;
37 };
38
39 struct KeyEqual
40 {
41 bool operator()(const C4Value &lhs, const C4Value &rhs) const noexcept { return lhs.Equals(other: rhs, strict: C4AulScriptStrict::MAXSTRICT); }
42 };
43
44 std::unordered_map<key_type, MapEntry, std::hash<key_type>, KeyEqual> map;
45 std::forward_list<C4Value *> emptyValues;
46
47 // we need a defined order for network sync
48 std::list<const C4Value *> keyOrder;
49
50public:
51
52 class Iterator
53 {
54 using pair_type = std::pair<const C4Value &, C4Value &>;
55 using iterator_type = decltype(keyOrder.begin());
56 iterator_type it, end;
57 C4ValueHash *map;
58 std::optional<pair_type> current;
59
60 void update();
61
62 public:
63 Iterator(C4ValueHash *map, iterator_type it, iterator_type end);
64
65 Iterator &operator++();
66 pair_type &operator*();
67 bool operator==(const Iterator &other) const;
68 };
69
70 C4ValueHash();
71 C4ValueHash(const C4ValueHash &other);
72
73 ~C4ValueHash();
74
75 virtual void CompileFunc(StdCompiler *pComp) override;
76 virtual void DenumeratePointers() override;
77
78 C4ValueHash &operator=(const C4ValueHash &other);
79 bool operator==(const C4ValueHash &other) const;
80 virtual bool hasIndex(const C4Value &key) const override;
81 virtual C4Value &operator[](const C4Value &key) override;
82 virtual const C4Value &operator[](const C4Value &key) const;
83 Iterator begin();
84 Iterator end();
85
86 bool contains(const C4Value &key) const;
87 void removeValue(C4Value *value);
88 auto size() const { return map.size(); }
89 void clear();
90};
91