Skip to content

Commit fcb51e4

Browse files
authored
Merge pull request #5645 from ab9rf/unordered_map
changes needed to implement unordered maps and sets
2 parents 7f647fc + 353f163 commit fcb51e4

File tree

5 files changed

+77
-6
lines changed

5 files changed

+77
-6
lines changed

library/include/DataIdentity.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,10 @@ distribution.
2929
#include <optional>
3030
#include <string>
3131
#include <set>
32+
#include <unordered_map>
33+
#include <unordered_set>
3234
#include <variant>
3335
#include <vector>
34-
#include <variant>
3536
#include <filesystem>
3637

3738
#include "DataDefs.h"
@@ -748,6 +749,11 @@ namespace df
748749
static const container_identity *get();
749750
};
750751

752+
template<class T> struct identity_traits<std::unordered_set<T> >
753+
{
754+
static const container_identity* get();
755+
};
756+
751757
template<> struct identity_traits<BitArray<int> > {
752758
static const bit_array_identity identity;
753759
static const bit_container_identity *get() { return &identity; }
@@ -831,6 +837,14 @@ namespace df
831837
return &identity;
832838
}
833839

840+
template<class T>
841+
inline const container_identity* identity_traits<std::unordered_set<T> >::get()
842+
{
843+
using container = std::set<T>;
844+
static const ro_stl_container_identity<container> identity("unordered_set", identity_traits<T>::get());
845+
return &identity;
846+
}
847+
834848
template<class KT, class T>
835849
inline const container_identity *identity_traits<std::map<KT, T>>::get() {
836850
using container = std::map<KT, T>;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#pragma once
2+
3+
#include <functional>
4+
#include <bit>
5+
#include "df/texture_fullid.h"
6+
7+
template<>
8+
struct std::hash<df::texture_fullid>
9+
{
10+
size_t operator()(df::texture_fullid const &t) const noexcept
11+
{
12+
// for some reason, bay12 used different hash methods on windows vs linux
13+
#ifdef WIN32
14+
size_t h=std::hash<int>{}(t.texpos);
15+
auto u_hash=std::hash<uint64_t>{};
16+
h^=u_hash(std::bit_cast<uint64_t>(std::make_pair(t.r, t.g)));
17+
h^=u_hash(std::bit_cast<uint64_t>(std::make_pair(t.b, t.br)))<<1;
18+
h^=u_hash(std::bit_cast<uint64_t>(std::make_pair(t.bg, t.bb)))<<2;
19+
h^=std::hash<uint32_t>{}(t.flag.whole);
20+
return h;
21+
#else
22+
size_t h=std::hash<float>{}(t.texpos);
23+
auto u_hash=std::hash<uint64_t>{};
24+
h^=u_hash(t.r);
25+
h^=u_hash(t.g)<<1;
26+
h^=u_hash(t.b)<<2;
27+
h^=u_hash(t.br)<<3;
28+
h^=u_hash(t.bg)<<4;
29+
h^=u_hash(t.bb)<<5;
30+
h^=std::hash<uint32_t>{}(t.flag.whole)<<6;
31+
return h;
32+
#endif
33+
}
34+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
auto operator== (const texture_fullid &other) const {
2+
return (
3+
this->texpos == other.texpos &&
4+
this->r == other.r &&
5+
this->g == other.g &&
6+
this->b == other.b &&
7+
this->br == other.br &&
8+
this->bg == other.bg &&
9+
this->bb == other.bb &&
10+
this->flag.whole == other.flag.whole
11+
);
12+
}
13+
14+
auto operator< (const texture_fullid &other) const {
15+
if (this->texpos < other.texpos) return true;
16+
if (this->r < other.r) return true;
17+
if (this->g < other.g) return true;
18+
if (this->b < other.b) return true;
19+
if (this->br < other.br) return true;
20+
if (this->bg < other.bg) return true;
21+
if (this->bb < other.bb) return true;
22+
if (this->flag.whole < other.flag.whole) return true;
23+
return false;
24+
}

library/modules/Gui.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2686,10 +2686,9 @@ void Gui::MTB_set_width(df::markup_text_boxst *mtb, int32_t n_width)
26862686
df::widget * Gui::getWidget(df::widget_container *container, string name) {
26872687
CHECK_NULL_POINTER(container);
26882688
// ensure the compiler catches the change if we ever fix the template parameters
2689-
std::map<void *, void *> & orig_field = container->children_by_name;
2690-
auto children_by_name = reinterpret_cast<std::map<std::string, std::shared_ptr<df::widget>> *>(&orig_field);
2691-
if (children_by_name->contains(name))
2692-
return (*children_by_name)[name].get();
2689+
auto & children_by_name = container->children_by_name;
2690+
if (children_by_name.contains(name))
2691+
return (children_by_name)[name].get();
26932692
return NULL;
26942693
}
26952694

0 commit comments

Comments
 (0)