Initial Commit. Needs refactored to run tests in parallel. Needs to avoid copying objects into both unordered_maps and reference them instead.
This commit is contained in:
commit
50d7342551
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
run-tests
|
94
DualLookup.h
Normal file
94
DualLookup.h
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#ifndef DVEREB_DUALLOOKUP_H
|
||||||
|
#define DVEREB_DUALLOOKUP_H
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
template <class T>
|
||||||
|
class DualLookup {
|
||||||
|
public:
|
||||||
|
DualLookup();
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
*/
|
||||||
|
bool add(T value, T equivilent);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* If found, return true
|
||||||
|
* else return false */
|
||||||
|
bool contains(const T &key);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<T, T> owner;
|
||||||
|
std::unordered_map<T, T> mirror;
|
||||||
|
|
||||||
|
// NOTE(dev): These functions actually do the work:
|
||||||
|
bool get_single(T key, T &result, const std::unordered_map<T, T> &umap);
|
||||||
|
bool contains_single(const T &key, const std::unordered_map<T, T> &umap);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
DualLookup<T>::DualLookup()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
bool DualLookup<T>::add(T value, T equivilent)
|
||||||
|
{
|
||||||
|
// already exists
|
||||||
|
if(owner.find(value) != owner.end() || mirror.find(value) != mirror.end())
|
||||||
|
return false;
|
||||||
|
if(owner.find(equivilent) != owner.end() || mirror.find(equivilent) != mirror.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
owner.insert({value, equivilent});
|
||||||
|
mirror.insert({equivilent, value});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
bool DualLookup<T>::get(T key, T &result)
|
||||||
|
{
|
||||||
|
if(get_single(key, result, owner))
|
||||||
|
return true;
|
||||||
|
if(get_single(key, result, mirror))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false; // didn't find it
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
bool DualLookup<T>::contains(const T &key)
|
||||||
|
{
|
||||||
|
if(contains_single(key, owner))
|
||||||
|
return true;
|
||||||
|
if(contains_single(key, mirror))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false; // didn't find it
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
bool DualLookup<T>::get_single(T key, T &result, const std::unordered_map<T, T> &umap)
|
||||||
|
{
|
||||||
|
auto i = umap.find(key);
|
||||||
|
if(i == umap.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
result = i->second;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
bool DualLookup<T>::contains_single(const T &key, const std::unordered_map<T, T> &umap)
|
||||||
|
{
|
||||||
|
return umap.find(key) != umap.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
5
Makefile
Normal file
5
Makefile
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
test: run-tests
|
||||||
|
./run-tests
|
||||||
|
|
||||||
|
run-tests: tests-main.cpp main.cpp DualLookup.h
|
||||||
|
clang++ -std=c++11 tests-main.cpp main.cpp -o run-tests
|
60
main.cpp
Normal file
60
main.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#include "catch.hpp"
|
||||||
|
|
||||||
|
#include "DualLookup.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
TEST_CASE("all tests", "all") {
|
||||||
|
DualLookup<int> container;
|
||||||
|
DualLookup<std::string> string_container;
|
||||||
|
|
||||||
|
SECTION ("allow add") {
|
||||||
|
REQUIRE(container.add(1, 2));
|
||||||
|
REQUIRE(string_container.add("1", "2"));
|
||||||
|
|
||||||
|
SECTION ("no duplicates") {
|
||||||
|
REQUIRE_FALSE(container.add(1, 2));
|
||||||
|
REQUIRE_FALSE(container.add(2, 1));
|
||||||
|
REQUIRE_FALSE(container.add(1, 3));
|
||||||
|
REQUIRE_FALSE(container.add(2, 3));
|
||||||
|
REQUIRE_FALSE(container.add(3, 1));
|
||||||
|
REQUIRE_FALSE(container.add(3, 2));
|
||||||
|
REQUIRE_FALSE(string_container.add("1", "2"));
|
||||||
|
REQUIRE_FALSE(string_container.add("2", "1"));
|
||||||
|
REQUIRE_FALSE(string_container.add("1", "3"));
|
||||||
|
REQUIRE_FALSE(string_container.add("2", "3"));
|
||||||
|
REQUIRE_FALSE(string_container.add("3", "1"));
|
||||||
|
REQUIRE_FALSE(string_container.add("3", "2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION ("searches") {
|
||||||
|
bool rtn;
|
||||||
|
int container_result;
|
||||||
|
std::string string_container_result;
|
||||||
|
|
||||||
|
SECTION ("found and not found") {
|
||||||
|
REQUIRE(container.contains(1));
|
||||||
|
REQUIRE(string_container.contains("1"));
|
||||||
|
REQUIRE_FALSE(container.contains(10));
|
||||||
|
REQUIRE_FALSE(string_container.contains("10"));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION ("not found in container and unedited") {
|
||||||
|
container_result = 10;
|
||||||
|
string_container_result = "10";
|
||||||
|
REQUIRE_FALSE(container.get(20, container_result));
|
||||||
|
REQUIRE(container_result == 10);
|
||||||
|
REQUIRE_FALSE(string_container.get("20", string_container_result));
|
||||||
|
REQUIRE(string_container_result == "10");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION ("in container and set") {
|
||||||
|
container_result = 0;
|
||||||
|
REQUIRE(container.get(1, container_result));
|
||||||
|
REQUIRE(container_result == 2);
|
||||||
|
REQUIRE(string_container.get("1", string_container_result));
|
||||||
|
REQUIRE(string_container_result == "2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
tests-main.cpp
Normal file
2
tests-main.cpp
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#define CATCH_CONFIG_MAIN
|
||||||
|
#include "catch.hpp"
|
Loading…
Reference in New Issue
Block a user