Compare commits

...

1 Commits

Author SHA1 Message Date
cat
772779e78f Tweaking DualKey Map to new Concept.hpp, and doing better templating 2026-02-26 01:33:14 +02:00

View File

@@ -8,8 +8,8 @@
*/ */
#ifndef GUARD_TOURMALINE_DUALKEYMAP_H #ifndef GUARD_TOURMALINE_DUALKEYMAP_H
#define GUARD_TOURMALINE_DUALKEYMAP_H #define GUARD_TOURMALINE_DUALKEYMAP_H
#include "../Concepts.hpp"
#include "../Systems/Logging.hpp" #include "../Systems/Logging.hpp"
#include "Concepts.hpp"
#include <array> #include <array>
#include <cmath> #include <cmath>
@@ -25,17 +25,16 @@
#include <vector> #include <vector>
namespace Tourmaline::Containers { namespace Tourmaline::Containers {
template <Hashable AKey, Hashable BKey, typename Value, template <Concepts::Hashable AKey, Concepts::Hashable BKey, typename Value,
uint64_t baseReservation = 2048> uint64_t baseReservation = 2048>
class DualkeyMap { class DualkeyMap {
public: public:
// Return Types // Return Types
template <typename OppositeKey, std::size_t resultKeyCount, template <typename OppositeKey, std::size_t Count>
std::size_t resultValueCount> requires Concepts::Either<OppositeKey, AKey, BKey>
requires Either<OppositeKey, AKey, BKey>
using MultiQueryResult = using MultiQueryResult =
std::pair<std::array<OppositeKey, resultKeyCount>, std::pair<const OppositeKey &,
std::array<std::reference_wrapper<Value>, resultValueCount>>; std::array<std::reference_wrapper<Value>, Count>>;
using QueryResult = using QueryResult =
std::pair<std::variant<std::monostate, std::reference_wrapper<const AKey>, std::pair<std::variant<std::monostate, std::reference_wrapper<const AKey>,
std::reference_wrapper<const BKey>>, std::reference_wrapper<const BKey>>,
@@ -197,17 +196,19 @@ public:
return finishedQuery; return finishedQuery;
} }
template <typename Key, std::size_t keyCount> template <typename Key,
requires Either<Key, AKey, BKey> typename OppositeKey = Concepts::OppositeOf<Key, AKey, BKey>,
std::size_t keyCount>
requires Concepts::Either<Key, AKey, BKey>
[[nodiscard("Discarding a very expensive query!")]] [[nodiscard("Discarding a very expensive query!")]]
int QueryWithAll(const Key (&keys)[keyCount]) { int QueryWithAll(const Key (&keys)[keyCount]) {
auto queryResults = queryWithMany<Key>(keys); std::vector<unprocessedMultiQueryResult<OppositeKey, keyCount>>
queryResults = queryWithMany<Key>(keys);
// You could very well use auto here but this helps // You could very well use auto here but this helps
// with LSP hints // with LSP hints
for (const unprocessedMultiQueryResult< for (const unprocessedMultiQueryResult<OppositeKey, keyCount> &queryRecord :
std::conditional_t<std::is_same_v<Key, AKey>, BKey, AKey>, queryResults) {
keyCount> &queryRecord : queryResults) {
if (queryRecord.howManyFound == keyCount) { if (queryRecord.howManyFound == keyCount) {
} }
} }
@@ -269,9 +270,10 @@ private:
std::stack<std::size_t> graveyard; std::stack<std::size_t> graveyard;
// Interal querying // Interal querying
template <typename Key, std::size_t keyCount> template <typename Key,
inline std::vector<unprocessedMultiQueryResult< typename OppositeKey = Concepts::OppositeOf<Key, AKey, BKey>,
std::conditional_t<std::is_same_v<Key, AKey>, BKey, AKey>, keyCount>> std::size_t keyCount>
inline std::vector<unprocessedMultiQueryResult<OppositeKey, keyCount>>
queryWithMany(const Key (&keys)[keyCount]) { queryWithMany(const Key (&keys)[keyCount]) {
constexpr bool searchingInFirstKey = std::is_same_v<Key, AKey>; constexpr bool searchingInFirstKey = std::is_same_v<Key, AKey>;
@@ -299,10 +301,10 @@ private:
uint64_t hashToCompare; uint64_t hashToCompare;
Key *keyToCompare; Key *keyToCompare;
std::conditional_t<searchingInFirstKey, BKey *, AKey *> resultKey; OppositeKey *resultKey;
std::vector<unprocessedMultiQueryResult< std::vector<unprocessedMultiQueryResult<OppositeKey, keyCount>>
std::conditional_t<searchingInFirstKey, BKey, AKey>, keyCount>>
queryResults; queryResults;
for (DualkeyHash *hash : hashList) { for (DualkeyHash *hash : hashList) {
// The hell of doing 2 conditions with similar logics in // The hell of doing 2 conditions with similar logics in
// the same logical block // the same logical block