diff --git a/DualLookup.h b/DualLookup.h index 73cf91f..68ed877 100644 --- a/DualLookup.h +++ b/DualLookup.h @@ -2,6 +2,7 @@ #define DVEREB_DUALLOOKUP_H #include +#include struct DualLookupBase { // NOTE(dev): Used to determine which version of the string you want: @@ -25,22 +26,22 @@ public: /* Add a mapped pair to the container * returns false if it already exists, regardless of direction - * (i.e. value->equivilent is a duplicate of equivilent->value) + * (i.e. value->equivalent is a duplicate of equivalent->value) */ - bool add(T value, T equivilent); + bool add(T value, T equivalent, std::string context = ""); /* If found, Set result to the mapped value and true is returned. * If not found, result remains unchanged and false is returned. */ - bool get(T key, T &result, const Type &type = Type::OPPOSITE); + bool get(T key, T &result, std::string context = "", const Type &type = Type::OPPOSITE); /* If found, return true * else return false */ - bool contains(const T &key); + bool contains(const T &key, std::string context = ""); private: - std::unordered_map owner; - std::unordered_map mirror; + std::unordered_map > owner; + std::unordered_map > mirror; // NOTE(dev): These functions actually do the work: bool get_single(const T &key, T &result, const std::unordered_map &umap); @@ -53,31 +54,33 @@ DualLookup::DualLookup() } template -bool DualLookup::add(T value, T equivilent) +bool DualLookup::add(T value, T equivalent, std::string context) { // already exists - if(owner.find(value) != owner.end() || mirror.find(value) != mirror.end()) + if(owner[context].find(value) != owner[context].end() + || mirror[context].find(value) != mirror[context].end()) return false; - if(owner.find(equivilent) != owner.end() || mirror.find(equivilent) != mirror.end()) + if(owner[context].find(equivalent) != owner[context].end() + || mirror[context].find(equivalent) != mirror[context].end()) return false; - owner.insert({value, equivilent}); - mirror.insert({equivilent, value}); + owner[context].insert({value, equivalent}); + mirror[context].insert({equivalent, value}); return true; } template -bool DualLookup::get(T key, T &result, const Type &type) +bool DualLookup::get(T key, T &result, std::string context, const Type &type) { - if(get_single(key, result, owner)) + if(get_single(key, result, owner[context])) { //if(type == Type::OPPOSITE || type == Type::EQUIVALENT) if(type == Type::VALUE) result = key; return true; } - if(get_single(key, result, mirror)) + if(get_single(key, result, mirror[context])) { //if(type == Type::OPPOSITE || type == Type::VALUE) if(type == Type::EQUIVALENT) @@ -89,11 +92,11 @@ bool DualLookup::get(T key, T &result, const Type &type) } template -bool DualLookup::contains(const T &key) +bool DualLookup::contains(const T &key, std::string context) { - if(contains_single(key, owner)) + if(contains_single(key, owner[context])) return true; - if(contains_single(key, mirror)) + if(contains_single(key, mirror[context])) return true; return false; // didn't find it diff --git a/main.cpp b/main.cpp index a4de7a2..580bd47 100644 --- a/main.cpp +++ b/main.cpp @@ -12,6 +12,14 @@ TEST_CASE("all tests", "all") { REQUIRE(container.add(1, 2)); REQUIRE(string_container.add("1", "2")); + // context with same VALUE + REQUIRE(container.add(1, 3, "a")); + REQUIRE(string_container.add("1", "3", "a")); + + // context with save EQUIVALENT + REQUIRE(container.add(3, 2, "b")); + REQUIRE(string_container.add("3", "2", "b")); + SECTION ("no duplicates") { REQUIRE_FALSE(container.add(1, 2)); REQUIRE_FALSE(container.add(2, 1)); @@ -25,6 +33,34 @@ TEST_CASE("all tests", "all") { REQUIRE_FALSE(string_container.add("2", "3")); REQUIRE_FALSE(string_container.add("3", "1")); REQUIRE_FALSE(string_container.add("3", "2")); + + // context with same VALUE + REQUIRE_FALSE(container.add(1, 3, "a")); + REQUIRE_FALSE(container.add(3, 1, "a")); + REQUIRE_FALSE(container.add(1, 4, "a")); + REQUIRE_FALSE(container.add(3, 4, "a")); + REQUIRE_FALSE(container.add(4, 1, "a")); + REQUIRE_FALSE(container.add(4, 3, "a")); + REQUIRE_FALSE(string_container.add("1", "3", "a")); + REQUIRE_FALSE(string_container.add("3", "1", "a")); + REQUIRE_FALSE(string_container.add("1", "4", "a")); + REQUIRE_FALSE(string_container.add("3", "4", "a")); + REQUIRE_FALSE(string_container.add("4", "1", "a")); + REQUIRE_FALSE(string_container.add("4", "3", "a")); + + // context with save EQUIVALENT + REQUIRE_FALSE(container.add(3, 2, "b")); + REQUIRE_FALSE(container.add(2, 3, "b")); + REQUIRE_FALSE(container.add(3, 4, "b")); + REQUIRE_FALSE(container.add(2, 4, "b")); + REQUIRE_FALSE(container.add(4, 3, "b")); + REQUIRE_FALSE(container.add(4, 2, "b")); + REQUIRE_FALSE(string_container.add("3", "2", "b")); + REQUIRE_FALSE(string_container.add("2", "3", "b")); + REQUIRE_FALSE(string_container.add("3", "4", "b")); + REQUIRE_FALSE(string_container.add("2", "4", "b")); + REQUIRE_FALSE(string_container.add("4", "3", "b")); + REQUIRE_FALSE(string_container.add("4", "2", "b")); } SECTION ("searches") { @@ -37,6 +73,18 @@ TEST_CASE("all tests", "all") { REQUIRE(string_container.contains("1")); REQUIRE_FALSE(container.contains(10)); REQUIRE_FALSE(string_container.contains("10")); + + // context with same VALUE + REQUIRE(container.contains(1, "a")); + REQUIRE(string_container.contains("1", "a")); + REQUIRE_FALSE(container.contains(10, "a")); + REQUIRE_FALSE(string_container.contains("10", "a")); + + // context with save EQUIVALENT + REQUIRE(container.contains(2, "b")); + REQUIRE(string_container.contains("2", "b")); + REQUIRE_FALSE(container.contains(10, "b")); + REQUIRE_FALSE(string_container.contains("10", "b")); } SECTION ("not found in container and unedited") { @@ -46,14 +94,65 @@ TEST_CASE("all tests", "all") { REQUIRE(container_result == 10); REQUIRE_FALSE(string_container.get("20", string_container_result)); REQUIRE(string_container_result == "10"); + + // context with same VALUE + container_result = 10; + string_container_result = "10"; + REQUIRE_FALSE(container.get(2, container_result, "a")); + REQUIRE(container_result == 10); + REQUIRE_FALSE(string_container.get("2", string_container_result, "a")); + REQUIRE(string_container_result == "10"); + + // context with save EQUIVALENT + container_result = 10; + string_container_result = "10"; + REQUIRE_FALSE(container.get(1, container_result, "b")); + REQUIRE(container_result == 10); + REQUIRE_FALSE(string_container.get("1", string_container_result, "b")); + REQUIRE(string_container_result == "10"); } SECTION ("in container and set") { container_result = 0; REQUIRE(container.get(1, container_result)); REQUIRE(container_result == 2); + container_result = 0; + REQUIRE(container.get(2, container_result)); + REQUIRE(container_result == 1); + string_container_result = "0"; REQUIRE(string_container.get("1", string_container_result)); REQUIRE(string_container_result == "2"); + string_container_result = "0"; + REQUIRE(string_container.get("2", string_container_result)); + REQUIRE(string_container_result == "1"); + + // context with same VALUE + container_result = 0; + REQUIRE(container.get(1, container_result, "a")); + REQUIRE(container_result == 3); + container_result = 0; + REQUIRE(container.get(3, container_result, "a")); + REQUIRE(container_result == 1); + string_container_result = "0"; + REQUIRE(string_container.get("1", string_container_result, "a")); + REQUIRE(string_container_result == "3"); + string_container_result = "0"; + REQUIRE(string_container.get("3", string_container_result, "a")); + REQUIRE(string_container_result == "1"); + + // context with save EQUIVALENT + container_result = 0; + REQUIRE(container.get(3, container_result, "b")); + REQUIRE(container_result == 2); + container_result = 0; + REQUIRE(container.get(2, container_result, "b")); + REQUIRE(container_result == 3); + string_container_result = "0"; + REQUIRE(string_container.get("3", string_container_result, "b")); + REQUIRE(string_container_result == "2"); + string_container_result = "0"; + REQUIRE(string_container.get("2", string_container_result, "b")); + REQUIRE(string_container_result == "3"); } } @@ -65,27 +164,29 @@ TEST_CASE("all tests", "all") { REQUIRE(container.get(1, container_result)); CHECK(container_result == 2); container_result = 0; - REQUIRE(container.get(1, container_result, DualLookupBase::Type::OPPOSITE)); + REQUIRE(container.get(1, container_result, "", DualLookupBase::Type::OPPOSITE)); CHECK(container_result == 2); container_result = 0; - REQUIRE(container.get(1, container_result, DualLookupBase::Type::EQUIVALENT)); + REQUIRE(container.get(1, container_result, "", DualLookupBase::Type::EQUIVALENT)); CHECK(container_result == 2); container_result = 0; - REQUIRE(container.get(1, container_result, DualLookupBase::Type::VALUE)); + REQUIRE(container.get(1, container_result, "", DualLookupBase::Type::VALUE)); CHECK(container_result == 1); container_result = 0; REQUIRE(container.get(2, container_result)); CHECK(container_result == 1); container_result = 0; - REQUIRE(container.get(2, container_result, DualLookup::Type::OPPOSITE)); + REQUIRE(container.get(2, container_result, "", DualLookup::Type::OPPOSITE)); CHECK(container_result == 1); container_result = 0; - REQUIRE(container.get(2, container_result, DualLookup::Type::EQUIVALENT)); + REQUIRE(container.get(2, container_result, "", DualLookup::Type::EQUIVALENT)); CHECK(container_result == 2); container_result = 0; - REQUIRE(container.get(2, container_result, DualLookup::Type::VALUE)); + REQUIRE(container.get(2, container_result, "", DualLookup::Type::VALUE)); CHECK(container_result == 1); + // context with same VALUE + // context with save EQUIVALENT } } }