Hi all, I reached this point in an older thread, and I hope it’s alright that I start a new thread now that the title no longer really reflects what the questions I have are about.
Here’s the short and long of it:
I need to convert from a pair of integers to another pair of integers, depending on a mapping read in from a file. The JUCE HashMap class seemed perfect for this:
https://docs.juce.com/master/classHashMap.html
I created a simple bag class “TwoInts” to hold the pairs of ints that will be used for both the keys and values, and understandably I need to supply my own hash function for that class:
The types of the key and value objects are set as template parameters. You can also specify a class to supply a hash function that converts a key value into an hashed integer. This class must have the form:
struct MyHashGenerator
{
int generateHash (MyKeyType key, int upperLimit) const
{
// The function must return a value 0 <= x < upperLimit
return someFunctionOfMyKeyType (key) % upperLimit;
}
};
I’ve created that class like this:
struct MyHashGenerator
{
int generateHash (TwoInts key, int upperLimit) const
{
String toHash;
toHash+=String(key.getFirst());
toHash+=String(key.getSecond());
return juce::DefaultHashFunctions::generateHash (toHash,upperLimit);
}
};
I’m now having trouble figuring out the syntax for declaring and initializing the HashMaps, though.
The documentation shows the template as
template<typename KeyType, typename ValueType, class HashFunctionType = DefaultHashFunctions, class TypeOfCriticalSectionToUse = DummyCriticalSection>
and it shows the constructor as
HashMap (int numberOfSlots=defaultHashTableSize, HashFunctionType hashFunction=HashFunctionType())
My best guess was to declare like this:
HashMap<TwoInts,TwoInts,MyHashGenerator> translator;
and then initialize like this:
:translator(1152, MyHashGenerator::generateHash())
But this semi-educated guess results in an error. (no matching function for call to ‘RelayerMApper:MyHashGenerator::generateHash()’)
Can someone show/explain the syntax I should be using here? Or does anyone know where I can find some example code of the JUCE HashMap class being used with a custom key class and corresponding hash function?
(I did get some suggestions in the previous thread to use nested std::unordered_maps which should work with the default hash functions, but I’d really like to use this as a learning opportunity, since I’m learning C++ as I go here, and it would be nice to be familiar with this syntax. If that doesn’t work out, I’ll certainly give the unordered_maps a shot.)
Thanks very much for any help!
Here’s the whole header file I have going, for reference:
#pragma once
#include "JuceHeader.h"
class RelayerMapper
{
public:
class TwoInts
{
public:
TwoInts(){}
TwoInts(int a, int b)
{
first=a;
second=b;
}
int getFirst()
{
return first;
}
int getSecond()
{
return second;
}
void setFirst(int in)
{
first=in;
}
void setSecond(int in)
{
second=in;
}
private:
int first, second;
};
struct MyHashGenerator
{
int generateHash (TwoInts key, int upperLimit) const
{
String toHash;
toHash+=String(key.getFirst());
toHash+=String(key.getSecond());
return juce::DefaultHashFunctions::generateHash (toHash,upperLimit);
}
};
RelayerMapper()
: dtMidiToCoords(1152, MyHashGenerator::generateHash()),
coordsToDtMidi(1872, MyHashGenerator::generateHash()),
axisToCoords(98)
{}
TwoInts MapDtMidiToCoords(TwoInts twoIntsIn, HashMap<TwoInts,TwoInts> hashmap)
{
return hashmap.getReference(twoIntsIn);
}
private:
HashMap<TwoInts,TwoInts,MyHashGenerator> dtMidiToCoords;
HashMap<TwoInts,TwoInts,MyHashGenerator> coordsToDtMidi;
HashMap<int,TwoInts> axisToCoords;
};