forked from intel/compile-time-init-build
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ConstexprSet.hpp
170 lines (152 loc) · 4.31 KB
/
ConstexprSet.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#pragma once
#include <container/ConstexprMap.hpp>
#include <cstddef>
#include <initializer_list>
/**
* A fully constexpr set implementation.
*
* ConstexprSet is perfect for compile-time initialization and configuration,
* but its performance may not be suitable for run-time operations. in_t
* particular, the current implementation has linear run-time O(n) for any key
* lookup operation.
*
* ConstexprSet owns the storage for the keys it stores. Carefully consider
* whether the KeyType is an object value or pointer.
*
* Consider an appropriate Capacity for the ConstexprSet. It will be able to
* contain up to "Capacity" number of keys.
*
* @tparam KeyType
* @tparam Capacity
*/
template <typename KeyType, std::size_t Capacity> class ConstexprSet {
private:
using StorageType = ConstexprMap<KeyType, bool, Capacity>;
StorageType storage{};
public:
constexpr ConstexprSet() = default;
constexpr ConstexprSet(std::initializer_list<KeyType> src) {
if (src.size() > Capacity) {
CIB_FATAL("Initializer list size {} is bigger than allocated set "
"capacity {}",
src.size(), Capacity);
} else {
for (auto k : src) {
storage.put(k, true);
}
}
}
/**
* <b>Runtime complexity:</b> O(1)
*
* @return
* Current number of keys stored in this set.
*/
[[nodiscard]] constexpr auto getSize() const -> std::size_t {
return storage.getSize();
}
/**
* <b>Runtime complexity:</b> O(1)
*/
[[nodiscard]] constexpr auto begin() -> typename StorageType::Entry * {
return storage.begin();
}
/**
* <b>Runtime complexity:</b> O(1)
*/
[[nodiscard]] constexpr auto end() -> typename StorageType::Entry * {
return storage.end();
}
/**
* <b>Runtime complexity:</b> O(1)
*/
[[nodiscard]] constexpr auto begin() const ->
typename StorageType::Entry const * {
return storage.begin();
}
/**
* <b>Runtime complexity:</b> O(1)
*/
[[nodiscard]] constexpr auto end() const ->
typename StorageType::Entry const * {
return storage.end();
}
/**
* Check if the set contains targetKey.
*
* <b>Runtime complexity:</b> O(n)
*
* @param targetKey
* The key to search for.
*
* @return
* True if targetKey is found in the set.
*/
[[nodiscard]] constexpr auto contains(KeyType targetKey) const -> bool {
return storage.contains(targetKey);
}
/**
* Put a key into the map. If the key 'k' already exists in the map, then
* no action is performed.
*
* <b>Runtime complexity:</b> O(n)
*
* @param k
* New key 'k' to add to the set.
*/
constexpr void add(KeyType k) { storage.put(k, true); }
/**
* Remove targetKey from the map. If targetKey is not found, do nothing.
*
* <b>Runtime complexity:</b> O(n * m)
*
* @param targetKey
* The key to search for and remove.
*/
constexpr void remove(KeyType targetKey) { storage.remove(targetKey); }
/**
* Add all keys from 'addSet' into this set.
*
* <b>Runtime complexity:</b> O(n * m)
*
* @param addSet
*/
template <typename RhsSetType> constexpr void addAll(RhsSetType addSet) {
for (auto entry : addSet) {
add(entry.key);
}
}
/**
* Remove all keys in 'removeSet' from this set.
*
* <b>Runtime complexity:</b> O(n * m)
*
* @param removeSet
*/
template <typename RhsSetType>
constexpr void removeAll(RhsSetType removeSet) {
for (auto entry : removeSet) {
remove(entry.key);
}
}
/**
* <b>Runtime complexity:</b> O(1)
*
* @return
* True if the set is empty.
*/
[[nodiscard]] constexpr auto isEmpty() const -> bool {
return storage.isEmpty();
}
/**
* Remove an unspecified key from the set.
*
* <b>Runtime complexity:</b> O(1)
*
* @return
* A key from the set.
*/
[[nodiscard]] constexpr auto pop() -> KeyType { return storage.pop().key; }
};
template <typename T, typename... Ts>
ConstexprSet(T, Ts...) -> ConstexprSet<T, 1 + sizeof...(Ts)>;