Live Cells C++
Reactive Programming for C++
Loading...
Searching...
No Matches
keys.hpp
1/*
2 * live_cells_cpp
3 * Copyright (C) 2024 Alexander Gutev <alex.gutev@gmail.com>
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License"); you
6 * may not use this file except in compliance with the License. You
7 * may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 */
17
18#ifndef LIVE_CELLS_KEYS_HPP
19#define LIVE_CELLS_KEYS_HPP
20
21#include <typeinfo>
22#include <functional>
23#include <memory>
24
25#include "util.hpp"
26
27namespace live_cells {
28
33 class key {
34 public:
35 virtual ~key() noexcept = default;
36
44 virtual bool eq(const key &k) const noexcept = 0;
45
51 virtual std::size_t hash() const noexcept = 0;
52
62 return false;
63 }
64 };
65
76 class key_ref {
77 public:
86 template <typename T, typename... Args>
87 static key_ref create(Args... args) {
88 return key_ref(
89 std::static_pointer_cast<const key>(
90 std::make_shared<T>(args...)
91 )
92 );
93 }
94
100 const key &operator *() const {
101 return *key_;
102 }
103
109 const key *operator->() const {
110 return key_.get();
111 }
112
113 private:
117 std::shared_ptr<const key> key_;
118
119 key_ref(std::shared_ptr<const key> ref) : key_(ref) {}
120 };
121
128 class unique_key : public key {
129 public:
130 bool eq(const key &k) const noexcept override;
131
132 std::size_t hash() const noexcept override;
133
134 bool is_unique() const noexcept override {
135 return true;
136 }
137 };
138
146 template <typename T, typename... Ts>
147 class value_key : public key {
151 const T value;
152
157 const value_key<Ts...> rest;
158
159 public:
167 value_key(T value, Ts... rest)
168 : value(value),
169 rest(rest...) {
170 }
171
172 bool eq(const key &other) const noexcept override {
173 auto *key = dynamic_cast<const value_key<T,Ts...> *>(&other);
174
175 if (key == nullptr) {
176 return false;
177 }
178
179 const auto &t1 = typeid(*this);
180 const auto &t2 = typeid(other);
181
182 return t1 == t2 && values_equal(*key);
183 }
184
185 std::size_t hash() const noexcept override {
186 return internal::hash_combine(0, typeid(*this).hash_code(), hash_values());
187 }
188
189 private:
198 bool values_equal(const value_key<T,Ts...> key) const noexcept {
199 return value == key.value && rest.values_equal(key.rest);
200 }
201
207 std::size_t hash_values() const noexcept {
208 return internal::hash_combine(0, value, rest.hash_values());
209 }
210 };
211
219 template <typename T>
220 class value_key<T> : public key {
224 const T value;
225
226 public:
232 value_key(T value) :
233 value(value) {}
234
235 bool eq(const key &other) const noexcept override {
236 auto *key = dynamic_cast<const value_key<T> *>(&other);
237
238 if (key == nullptr) {
239 return false;
240 }
241
242 const auto &t1 = typeid(*this);
243 const auto &t2 = typeid(other);
244
245 return t1 == t2 && values_equal(*key);
246 }
247
248 std::size_t hash() const noexcept override {
249 return internal::hash_combine(0, typeid(*this).hash_code(), hash_values());
250 }
251
252 private:
253 bool values_equal(const value_key<T> key) const noexcept {
254 return value == key.value;
255 }
256
257 std::size_t hash_values() const noexcept {
258 return std::hash<T>{}(value);
259 }
260
261 template <typename T1, typename... Ts>
262 friend class value_key;
263 };
264
265 inline bool operator ==(const key &k1, const key &k2) {
266 return k1.eq(k2);
267 }
268
269 inline bool operator !=(const key &k1, const key &k2) {
270 return !k1.eq(k2);
271 }
272
273 inline bool operator ==(const key_ref &k1, const key_ref &k2) {
274 return *k1 == *k2;
275 }
276
277 inline bool operator !=(const key_ref &k1, const key_ref &k2) {
278 return *k1 != *k2;
279 }
280
281} // live_cells
282
283template<>
284struct std::hash<live_cells::key> {
285 std::size_t operator()(const live_cells::key& k) const noexcept {
286 return k.hash();
287 }
288};
289
290template<>
291struct std::hash<live_cells::key_ref> {
292 std::size_t operator()(const live_cells::key_ref &k) const noexcept {
293 return k->hash();
294 }
295};
296
297#endif /* LIVE_CELLS_KEYS_HPP */
A computed cell which determines its argument cells at runtime.
Definition dynamic_compute_cell.hpp:153
Dynamically type key container.
Definition keys.hpp:76
static key_ref create(Args... args)
Create a key_ref holding a key of type T.
Definition keys.hpp:87
const key * operator->() const
Definition keys.hpp:109
const key & operator*() const
Definition keys.hpp:100
Defines the interface for a key which uniquely identifies a cell.
Definition keys.hpp:33
virtual bool is_unique() const noexcept
Is this a unique key?
Definition keys.hpp:61
virtual bool eq(const key &k) const noexcept=0
Compare this key to another key for equality.
virtual std::size_t hash() const noexcept=0
Compute the hash code for this key.
A key of uniquely identified by a single instance.
Definition keys.hpp:128
std::size_t hash() const noexcept override
Compute the hash code for this key.
Definition live_cells.cpp:33
bool eq(const key &k) const noexcept override
Compare this key to another key for equality.
Definition live_cells.cpp:29
bool is_unique() const noexcept override
Is this a unique key?
Definition keys.hpp:134
bool eq(const key &other) const noexcept override
Compare this key to another key for equality.
Definition keys.hpp:235
std::size_t hash() const noexcept override
Compute the hash code for this key.
Definition keys.hpp:248
value_key(T value)
Create a key distinguished from other keys by one value.
Definition keys.hpp:232
Base class for a key distinguished from other keys by one or more values.
Definition keys.hpp:147
value_key(T value, Ts... rest)
Create a key distinguished from other keys by one or more values.
Definition keys.hpp:167
std::size_t hash() const noexcept override
Compute the hash code for this key.
Definition keys.hpp:185
bool eq(const key &other) const noexcept override
Compare this key to another key for equality.
Definition keys.hpp:172
Definition boolean.hpp:26
constant_cell< T > value(const T &value)
Definition constant_cell.hpp:132
auto operator==(const T &a, const U &b)
Create a Cell that compares two cells for equality by ==.
Definition equality.hpp:57
auto operator!=(const T &a, const U &b)
Create a Cell that compares two cells for inequality by !=.
Definition equality.hpp:81