I am looking for tips on efficiency of the code and whether forwarding of the arguments are working as intended (perfect forwarding). Also in the get method, would it be better to return value type pointer instead of std::optional?
#include "BasicHash.h"
#include <string>
#include <iostream>
//djb2
size_t hashFunction(const std::string& key)
{
unsigned long hash = 5381;
int c;
const char* str = key.c_str();
while (c = *str++)
hash = ((hash << 5) + hash) + c;
return hash;
}
class TwoNumberStore
{
public:
TwoNumberStore(int a, int b) :
n1{ a }, n2{ b }
{
}
int n1 = 0;
int n2 = 0;
};
int main()
{
BasicHash<std::string, TwoNumberStore, 50, hashFunction> table;
table.EmplaceBack("First Two", 1, 2);
auto firstTwo = table.Get("First Two");
if (firstTwo.has_value())
{
std::cout << firstTwo.value().n1 << '\n';
std::cout << firstTwo.value().n2;
}
}
I just realised I was copying value in std::optional. Changed get to return a optional reference_wrapper instead.
decltype(auto) Get(KeyType&& key)
{
size_t hash = Hash(std::forward<KeyType>(key));
for (auto& pair : hashGroups[hash])
if (pair.key == key)
return std::optional<std::reference_wrapper<ValueType>>{ pair.value };
return std::optional<std::reference_wrapper<ValueType>>{};
}
This makes retrieving data even messier.
if (firstTwo.has_value())
{
std::cout << firstTwo.value().get().n1 << '\n';
std::cout << firstTwo.value().get().n2;
}