work around gcc-4-8's missing full std::hash impl

and improve our hash function while I'm there
develop
Myk Taylor 2020-10-06 09:39:21 -07:00
parent 0edebd7e1f
commit f270217be5
2 changed files with 17 additions and 6 deletions

@ -1,4 +1,5 @@
#include <functional> #include <functional>
#include <climits> // for CHAR_BIT
#include "df/building_design.h" #include "df/building_design.h"
#include "df/building_doorst.h" #include "df/building_doorst.h"
@ -386,11 +387,24 @@ BuildingTypeKey toBuildingTypeKey(df::ui_build_selector *uibs)
uibs->building_type, uibs->building_subtype, uibs->custom_type); uibs->building_type, uibs->building_subtype, uibs->custom_type);
} }
// rotates a size_t value left by count bits
// assumes count is not 0 or >= size_t_bits
// replace this with std::rotl when we move to C++20
static std::size_t rotl_size_t(size_t val, uint32_t count)
{
static const int size_t_bits = CHAR_BIT * sizeof(std::size_t);
return val << count | val >> (size_t_bits - count);
}
std::size_t BuildingTypeKeyHash::operator() (const BuildingTypeKey & key) const std::size_t BuildingTypeKeyHash::operator() (const BuildingTypeKey & key) const
{ {
return std::hash<df::building_type>()(std::get<0>(key)) // cast first param to appease gcc-4.8, which is missing the enum
^ std::hash<int16_t>()(std::get<1>(key)) // specializations for std::hash
^ std::hash<int32_t>()(std::get<2>(key)); std::size_t h1 = std::hash<int32_t>()(static_cast<int32_t>(std::get<0>(key)));
std::size_t h2 = std::hash<int16_t>()(std::get<1>(key));
std::size_t h3 = std::hash<int32_t>()(std::get<2>(key));
return h1 ^ rotl_size_t(h2, 8) ^ rotl_size_t(h3, 16);
} }

@ -25,9 +25,6 @@ REQUIRE_GLOBAL(world);
#define MAX_MASK 10 #define MAX_MASK 10
#define MAX_MATERIAL 21 #define MAX_MATERIAL 21
using namespace DFHack;
using namespace df::enums;
bool show_help = false; bool show_help = false;
bool quickfort_mode = false; bool quickfort_mode = false;
bool in_dummy_screen = false; bool in_dummy_screen = false;