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:
David Vereb 2017-11-08 14:50:35 -05:00
commit 50d7342551
6 changed files with 12174 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
run-tests

94
DualLookup.h Normal file
View 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
View 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

12012
catch.hpp Normal file

File diff suppressed because it is too large Load Diff

60
main.cpp Normal file
View 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
View File

@ -0,0 +1,2 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"