mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Use std::unordered_map and std::vector for sections
This allows us to control the order in which sections are iterated, instead of it depending on the internals of `std::map`. (This order is arbitrary, but should be deterministic regardless.)
This commit is contained in:
@@ -3,18 +3,20 @@
|
|||||||
#include "link/section.hpp"
|
#include "link/section.hpp"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <deque>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <map>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
|
|
||||||
std::map<std::string, std::unique_ptr<Section>> sections;
|
std::vector<std::unique_ptr<Section>> sectionList;
|
||||||
|
std::unordered_map<std::string, size_t> sectionMap; // Indexes into `sectionList`
|
||||||
|
|
||||||
void sect_ForEach(void (*callback)(Section &)) {
|
void sect_ForEach(void (*callback)(Section &)) {
|
||||||
for (auto &it : sections)
|
for (auto it = sectionList.rbegin(); it != sectionList.rend(); it++)
|
||||||
callback(*it.second);
|
callback(*it->get());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void checkSectUnionCompat(Section &target, Section &other) {
|
static void checkSectUnionCompat(Section &target, Section &other) {
|
||||||
@@ -215,13 +217,14 @@ void sect_AddSection(std::unique_ptr<Section> &§ion) {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// If not, add it
|
// If not, add it
|
||||||
sections.emplace(section->name, std::move(section));
|
sectionMap.emplace(section->name, sectionList.size());
|
||||||
|
sectionList.push_back(std::move(section));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Section *sect_GetSection(std::string const &name) {
|
Section *sect_GetSection(std::string const &name) {
|
||||||
auto search = sections.find(name);
|
auto search = sectionMap.find(name);
|
||||||
return search != sections.end() ? search->second.get() : nullptr;
|
return search != sectionMap.end() ? sectionList[search->second].get() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doSanityChecks(Section §ion) {
|
static void doSanityChecks(Section §ion) {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ SECTION "test", ROM0
|
|||||||
charmap "<FAR>", $08
|
charmap "<FAR>", $08
|
||||||
|
|
||||||
; At this point, enough nodes were allocated for 'foo' to be reallocated.
|
; At this point, enough nodes were allocated for 'foo' to be reallocated.
|
||||||
; Its value in the charmaps' std::map should have been updated too,
|
; Its value in the charmaps' `std::unordered_map` should have been updated too,
|
||||||
; so that usages of 'foo' will not segfault.
|
; so that usages of 'foo' will not segfault.
|
||||||
|
|
||||||
; This uses 'foo; by switching to it.
|
; This uses 'foo; by switching to it.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ SECTION "Collision course", OAM[$FE00]
|
|||||||
|
|
||||||
; All the following symbols used to collide with our custom hashmap,
|
; All the following symbols used to collide with our custom hashmap,
|
||||||
; which at some point caused `PURGE` to malfunction with them.
|
; which at some point caused `PURGE` to malfunction with them.
|
||||||
; We now use C++ `std::map` which reliably handles collisions.
|
; We now use C++ `std::unordered_map` which reliably handles collisions.
|
||||||
aqfj: ds 1 ; Give them different addresses
|
aqfj: ds 1 ; Give them different addresses
|
||||||
cxje: ds 1
|
cxje: ds 1
|
||||||
dgsd: ds 1
|
dgsd: ds 1
|
||||||
|
|||||||
Reference in New Issue
Block a user