1
0
Fork 0

Codechange: do not use MallocT for the pool

Needed to make the placement new operator use Tindex over size_t because of
ambiguity for the delete operator variant that also has the size.
pull/13632/head
Rubidium 2025-02-20 18:59:28 +01:00 committed by rubidium42
parent 426b03b31a
commit 09716dba75
24 changed files with 80 additions and 96 deletions

View File

@ -583,7 +583,7 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = CompanyID::Invalid(
c = new Company(STR_SV_UNNAMED, is_ai); c = new Company(STR_SV_UNNAMED, is_ai);
} else { } else {
if (Company::IsValidID(company)) return nullptr; if (Company::IsValidID(company)) return nullptr;
c = new (company.base()) Company(STR_SV_UNNAMED, is_ai); c = new (company) Company(STR_SV_UNNAMED, is_ai);
} }
c->colour = colour; c->colour = colour;

View File

@ -10,9 +10,8 @@
#ifndef POOL_FUNC_HPP #ifndef POOL_FUNC_HPP
#define POOL_FUNC_HPP #define POOL_FUNC_HPP
#include "alloc_func.hpp"
#include "bitmath_func.hpp" #include "bitmath_func.hpp"
#include "mem_func.hpp" #include "math_func.hpp"
#include "pool_type.hpp" #include "pool_type.hpp"
#include "../error_func.h" #include "../error_func.h"
@ -27,23 +26,6 @@
requires std::is_base_of_v<PoolIDBase, Tindex> \ requires std::is_base_of_v<PoolIDBase, Tindex> \
type Pool<Titem, Tindex, Tgrowth_step, Tpool_type, Tcache> type Pool<Titem, Tindex, Tgrowth_step, Tpool_type, Tcache>
/**
* Create a clean pool.
* @param name The name for the pool.
*/
DEFINE_POOL_METHOD(inline)::Pool(const char *name) :
PoolBase(Tpool_type),
name(name),
first_free(0),
first_unused(0),
items(0),
#ifdef WITH_ASSERT
checked(0),
#endif /* WITH_ASSERT */
cleaning(false),
alloc_cache(nullptr)
{ }
/** /**
* Resizes the pool so 'index' can be addressed * Resizes the pool so 'index' can be addressed
* @param index index we will allocate later * @param index index we will allocate later
@ -114,7 +96,7 @@ DEFINE_POOL_METHOD(inline void *)::AllocateItem(size_t size, size_t index)
item = reinterpret_cast<Titem *>(this->alloc_cache); item = reinterpret_cast<Titem *>(this->alloc_cache);
this->alloc_cache = this->alloc_cache->next; this->alloc_cache = this->alloc_cache->next;
} else { } else {
item = reinterpret_cast<Titem *>(MallocT<uint8_t>(size)); item = reinterpret_cast<Titem *>(this->allocator.allocate(size));
} }
this->data[index] = item; this->data[index] = item;
SetBit(this->used_bitmap[index / BITMAP_SIZE], index % BITMAP_SIZE); SetBit(this->used_bitmap[index / BITMAP_SIZE], index % BITMAP_SIZE);
@ -169,11 +151,12 @@ DEFINE_POOL_METHOD(void *)::GetNew(size_t size, size_t index)
/** /**
* Deallocates memory used by this index and marks item as free * Deallocates memory used by this index and marks item as free
* @param size the size of the freed object
* @param index item to deallocate * @param index item to deallocate
* @pre unit is allocated (non-nullptr) * @pre unit is allocated (non-nullptr)
* @note 'delete nullptr' doesn't cause call of this function, so it is safe * @note 'delete nullptr' doesn't cause call of this function, so it is safe
*/ */
DEFINE_POOL_METHOD(void)::FreeItem(size_t index) DEFINE_POOL_METHOD(void)::FreeItem(size_t size, size_t index)
{ {
assert(index < this->data.size()); assert(index < this->data.size());
assert(this->data[index] != nullptr); assert(this->data[index] != nullptr);
@ -182,7 +165,7 @@ DEFINE_POOL_METHOD(void)::FreeItem(size_t index)
ac->next = this->alloc_cache; ac->next = this->alloc_cache;
this->alloc_cache = ac; this->alloc_cache = ac;
} else { } else {
free(this->data[index]); this->allocator.deallocate(reinterpret_cast<uint8_t*>(this->data[index]), size);
} }
this->data[index] = nullptr; this->data[index] = nullptr;
this->first_free = std::min(this->first_free, index); this->first_free = std::min(this->first_free, index);
@ -212,7 +195,7 @@ DEFINE_POOL_METHOD(void)::CleanPool()
while (this->alloc_cache != nullptr) { while (this->alloc_cache != nullptr) {
AllocCache *ac = this->alloc_cache; AllocCache *ac = this->alloc_cache;
this->alloc_cache = ac->next; this->alloc_cache = ac->next;
free(ac); this->allocator.deallocate(reinterpret_cast<uint8_t*>(ac), sizeof(Titem));
} }
} }
} }
@ -227,7 +210,7 @@ DEFINE_POOL_METHOD(void)::CleanPool()
#define INSTANTIATE_POOL_METHODS(name) \ #define INSTANTIATE_POOL_METHODS(name) \
template void * name ## Pool::GetNew(size_t size); \ template void * name ## Pool::GetNew(size_t size); \
template void * name ## Pool::GetNew(size_t size, size_t index); \ template void * name ## Pool::GetNew(size_t size, size_t index); \
template void name ## Pool::FreeItem(size_t index); \ template void name ## Pool::FreeItem(size_t size, size_t index); \
template void name ## Pool::CleanPool(); template void name ## Pool::CleanPool();
#endif /* POOL_FUNC_HPP */ #endif /* POOL_FUNC_HPP */

View File

@ -125,7 +125,7 @@ private:
* @tparam Tindex Type of the index for this pool * @tparam Tindex Type of the index for this pool
* @tparam Tgrowth_step Size of growths; if the pool is full increase the size by this amount * @tparam Tgrowth_step Size of growths; if the pool is full increase the size by this amount
* @tparam Tpool_type Type of this pool * @tparam Tpool_type Type of this pool
* @tparam Tcache Whether to perform 'alloc' caching, i.e. don't actually free/malloc just reuse the memory * @tparam Tcache Whether to perform 'alloc' caching, i.e. don't actually deallocated/allocate just reuse the memory
* @warning when Tcache is enabled *all* instances of this pool's item must be of the same size. * @warning when Tcache is enabled *all* instances of this pool's item must be of the same size.
*/ */
template <class Titem, typename Tindex, size_t Tgrowth_step, PoolType Tpool_type = PoolType::Normal, bool Tcache = false> template <class Titem, typename Tindex, size_t Tgrowth_step, PoolType Tpool_type = PoolType::Normal, bool Tcache = false>
@ -137,20 +137,20 @@ public:
using BitmapStorage = size_t; using BitmapStorage = size_t;
static constexpr size_t BITMAP_SIZE = std::numeric_limits<BitmapStorage>::digits; static constexpr size_t BITMAP_SIZE = std::numeric_limits<BitmapStorage>::digits;
const char * const name; ///< Name of this pool const char * const name = nullptr; ///< Name of this pool
size_t first_free; ///< No item with index lower than this is free (doesn't say anything about this one!) size_t first_free = 0; ///< No item with index lower than this is free (doesn't say anything about this one!)
size_t first_unused; ///< This and all higher indexes are free (doesn't say anything about first_unused-1 !) size_t first_unused = 0; ///< This and all higher indexes are free (doesn't say anything about first_unused-1 !)
size_t items; ///< Number of used indexes (non-nullptr) size_t items = 0; ///< Number of used indexes (non-nullptr)
#ifdef WITH_ASSERT #ifdef WITH_ASSERT
size_t checked; ///< Number of items we checked for size_t checked = 0; ///< Number of items we checked for
#endif /* WITH_ASSERT */ #endif /* WITH_ASSERT */
bool cleaning; ///< True if cleaning pool (deleting all items) bool cleaning = false; ///< True if cleaning pool (deleting all items)
std::vector<Titem *> data; ///< Pointers to Titem std::vector<Titem *> data{}; ///< Pointers to Titem
std::vector<BitmapStorage> used_bitmap; ///< Bitmap of used indices. std::vector<BitmapStorage> used_bitmap{}; ///< Bitmap of used indices.
Pool(const char *name); Pool(const char *name) : PoolBase(Tpool_type), name(name) {}
void CleanPool() override; void CleanPool() override;
/** /**
@ -304,12 +304,12 @@ public:
* @param p memory to free * @param p memory to free
* @note the item has to be allocated in the pool! * @note the item has to be allocated in the pool!
*/ */
inline void operator delete(void *p) inline void operator delete(void *p, size_t size)
{ {
if (p == nullptr) return; if (p == nullptr) return;
Titem *pn = static_cast<Titem *>(p); Titem *pn = static_cast<Titem *>(p);
assert(pn == Tpool->Get(Pool::GetRawIndex(pn->index))); assert(pn == Tpool->Get(Pool::GetRawIndex(pn->index)));
Tpool->FreeItem(Pool::GetRawIndex(pn->index)); Tpool->FreeItem(size, Pool::GetRawIndex(pn->index));
} }
/** /**
@ -320,9 +320,9 @@ public:
* @note can never fail (return nullptr), use CanAllocate() to check first! * @note can never fail (return nullptr), use CanAllocate() to check first!
* @pre index has to be unused! Else it will crash * @pre index has to be unused! Else it will crash
*/ */
inline void *operator new(size_t size, size_t index) inline void *operator new(size_t size, Tindex index)
{ {
return Tpool->GetNew(size, index); return Tpool->GetNew(size, index.base());
} }
/** /**
@ -449,7 +449,8 @@ private:
}; };
/** Cache of freed pointers */ /** Cache of freed pointers */
AllocCache *alloc_cache; AllocCache *alloc_cache = nullptr;
std::allocator<uint8_t> allocator{};
void *AllocateItem(size_t size, size_t index); void *AllocateItem(size_t size, size_t index);
void ResizeFor(size_t index); void ResizeFor(size_t index);
@ -458,7 +459,7 @@ private:
void *GetNew(size_t size); void *GetNew(size_t size);
void *GetNew(size_t size, size_t index); void *GetNew(size_t size, size_t index);
void FreeItem(size_t index); void FreeItem(size_t size, size_t index);
static constexpr size_t GetRawIndex(size_t index) { return index; } static constexpr size_t GetRawIndex(size_t index) { return index; }
template <typename T> requires std::is_base_of_v<PoolIDBase, T> template <typename T> requires std::is_base_of_v<PoolIDBase, T>

View File

@ -610,7 +610,7 @@ void SetupEngines()
assert(std::size(mapping) >= _engine_counts[type]); assert(std::size(mapping) >= _engine_counts[type]);
for (const EngineIDMapping &eid : mapping) { for (const EngineIDMapping &eid : mapping) {
new (eid.engine.base()) Engine(type, eid.internal_id); new (eid.engine) Engine(type, eid.internal_id);
} }
} }
} }

View File

@ -45,7 +45,7 @@ struct ERNWChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
EngineRenew *er = new (index) EngineRenew(); EngineRenew *er = new (EngineRenewID(index)) EngineRenew();
SlObject(er, slt); SlObject(er, slt);
/* Advanced vehicle lists, ungrouped vehicles got added */ /* Advanced vehicle lists, ungrouped vehicles got added */

View File

@ -162,7 +162,7 @@ struct CAPAChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
CargoPacket *cp = new (index) CargoPacket(); CargoPacket *cp = new (CargoPacketID(index)) CargoPacket();
SlObject(cp, slt); SlObject(cp, slt);
} }
} }

View File

@ -536,7 +536,7 @@ struct PLYRChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
Company *c = new (index) Company(); Company *c = new (CompanyID(index)) Company();
SlObject(c, slt); SlObject(c, slt);
_company_colours[index] = c->colour; _company_colours[index] = c->colour;
} }

View File

@ -49,7 +49,7 @@ struct DEPTChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
Depot *depot = new (index) Depot(); Depot *depot = new (DepotID(index)) Depot();
SlObject(depot, slt); SlObject(depot, slt);
/* Set the town 'pointer' so we can restore it later. */ /* Set the town 'pointer' so we can restore it later. */

View File

@ -108,7 +108,7 @@ struct CAPYChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
CargoPayment *cp = new (index) CargoPayment(); CargoPayment *cp = new (CargoPaymentID(index)) CargoPayment();
SlObject(cp, slt); SlObject(cp, slt);
} }
} }

View File

@ -44,7 +44,7 @@ struct GOALChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
Goal *s = new (index) Goal(); Goal *s = new (GoalID(index)) Goal();
SlObject(s, slt); SlObject(s, slt);
} }
} }

View File

@ -50,7 +50,7 @@ struct GRPSChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
Group *g = new (index) Group(); Group *g = new (GroupID(index)) Group();
SlObject(g, slt); SlObject(g, slt);
if (IsSavegameVersionBefore(SLV_189)) g->parent = GroupID::Invalid(); if (IsSavegameVersionBefore(SLV_189)) g->parent = GroupID::Invalid();

View File

@ -213,7 +213,7 @@ struct INDYChunkHandler : ChunkHandler {
SlIndustryProduced::ResetOldStructure(); SlIndustryProduced::ResetOldStructure();
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
Industry *i = new (index) Industry(); Industry *i = new (IndustryID(index)) Industry();
SlObject(i, slt); SlObject(i, slt);
/* Before savegame version 161, persistent storages were not stored in a pool. */ /* Before savegame version 161, persistent storages were not stored in a pool. */

View File

@ -45,7 +45,7 @@ struct LEAEChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
LeagueTableElement *lte = new (index) LeagueTableElement(); LeagueTableElement *lte = new (LeagueTableElementID(index)) LeagueTableElement();
SlObject(lte, slt); SlObject(lte, slt);
} }
} }
@ -76,7 +76,7 @@ struct LEATChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
LeagueTable *lt = new (index) LeagueTable(); LeagueTable *lt = new (LeagueTableID(index)) LeagueTable();
SlObject(lt, slt); SlObject(lt, slt);
} }
} }

View File

@ -277,7 +277,7 @@ struct LGRPChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
LinkGraph *lg = new (index) LinkGraph(); LinkGraph *lg = new (LinkGraphID(index)) LinkGraph();
SlObject(lg, slt); SlObject(lg, slt);
} }
} }
@ -305,7 +305,7 @@ struct LGRJChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
LinkGraphJob *lgj = new (index) LinkGraphJob(); LinkGraphJob *lgj = new (LinkGraphJobID(index)) LinkGraphJob();
SlObject(lgj, slt); SlObject(lgj, slt);
} }
} }

View File

@ -49,7 +49,7 @@ struct OBJSChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
Object *o = new (index) Object(); Object *o = new (ObjectID(index)) Object();
SlObject(o, slt); SlObject(o, slt);
} }
} }

View File

@ -615,7 +615,7 @@ static const OldChunks town_chunk[] = {
static bool LoadOldTown(LoadgameState &ls, int num) static bool LoadOldTown(LoadgameState &ls, int num)
{ {
Town *t = new (num) Town(); Town *t = new (TownID(num)) Town();
if (!LoadChunk(ls, t, town_chunk)) return false; if (!LoadChunk(ls, t, town_chunk)) return false;
if (t->xy != 0) { if (t->xy != 0) {
@ -640,7 +640,7 @@ static bool LoadOldOrder(LoadgameState &ls, int num)
{ {
if (!LoadChunk(ls, nullptr, order_chunk)) return false; if (!LoadChunk(ls, nullptr, order_chunk)) return false;
Order *o = new (num) Order(); Order *o = new (OrderID(num)) Order();
o->AssignOrder(UnpackOldOrder(_old_order)); o->AssignOrder(UnpackOldOrder(_old_order));
if (o->IsType(OT_NOTHING)) { if (o->IsType(OT_NOTHING)) {
@ -682,7 +682,7 @@ static const OldChunks depot_chunk[] = {
static bool LoadOldDepot(LoadgameState &ls, int num) static bool LoadOldDepot(LoadgameState &ls, int num)
{ {
Depot *d = new (num) Depot(); Depot *d = new (DepotID(num)) Depot();
if (!LoadChunk(ls, d, depot_chunk)) return false; if (!LoadChunk(ls, d, depot_chunk)) return false;
if (d->xy != 0) { if (d->xy != 0) {
@ -770,7 +770,7 @@ static const OldChunks station_chunk[] = {
static bool LoadOldStation(LoadgameState &ls, int num) static bool LoadOldStation(LoadgameState &ls, int num)
{ {
Station *st = new (num) Station(); Station *st = new (StationID(num)) Station();
_current_station_id = st->index; _current_station_id = st->index;
if (!LoadChunk(ls, st, station_chunk)) return false; if (!LoadChunk(ls, st, station_chunk)) return false;
@ -852,7 +852,7 @@ static const OldChunks industry_chunk[] = {
static bool LoadOldIndustry(LoadgameState &ls, int num) static bool LoadOldIndustry(LoadgameState &ls, int num)
{ {
Industry *i = new (num) Industry(); Industry *i = new (IndustryID(num)) Industry();
if (!LoadChunk(ls, i, industry_chunk)) return false; if (!LoadChunk(ls, i, industry_chunk)) return false;
if (i->location.tile != 0) { if (i->location.tile != 0) {
@ -978,7 +978,7 @@ static const OldChunks _company_chunk[] = {
static bool LoadOldCompany(LoadgameState &ls, int num) static bool LoadOldCompany(LoadgameState &ls, int num)
{ {
Company *c = new (num) Company(); Company *c = new (CompanyID(num)) Company();
_current_company_id = (CompanyID)num; _current_company_id = (CompanyID)num;
@ -1260,12 +1260,12 @@ bool LoadOldVehicle(LoadgameState &ls, int num)
default: return false; default: return false;
case 0x00 /* VEH_INVALID */: v = nullptr; break; case 0x00 /* VEH_INVALID */: v = nullptr; break;
case 0x25 /* MONORAIL */: case 0x25 /* MONORAIL */:
case 0x20 /* VEH_TRAIN */: v = new (_current_vehicle_id) Train(); break; case 0x20 /* VEH_TRAIN */: v = new (VehicleID(_current_vehicle_id)) Train(); break;
case 0x21 /* VEH_ROAD */: v = new (_current_vehicle_id) RoadVehicle(); break; case 0x21 /* VEH_ROAD */: v = new (VehicleID(_current_vehicle_id)) RoadVehicle(); break;
case 0x22 /* VEH_SHIP */: v = new (_current_vehicle_id) Ship(); break; case 0x22 /* VEH_SHIP */: v = new (VehicleID(_current_vehicle_id)) Ship(); break;
case 0x23 /* VEH_AIRCRAFT */: v = new (_current_vehicle_id) Aircraft(); break; case 0x23 /* VEH_AIRCRAFT */: v = new (VehicleID(_current_vehicle_id)) Aircraft(); break;
case 0x24 /* VEH_EFFECT */: v = new (_current_vehicle_id) EffectVehicle(); break; case 0x24 /* VEH_EFFECT */: v = new (VehicleID(_current_vehicle_id)) EffectVehicle(); break;
case 0x26 /* VEH_DISASTER */: v = new (_current_vehicle_id) DisasterVehicle(); break; case 0x26 /* VEH_DISASTER */: v = new (VehicleID(_current_vehicle_id)) DisasterVehicle(); break;
} }
if (!LoadChunk(ls, v, vehicle_chunk)) return false; if (!LoadChunk(ls, v, vehicle_chunk)) return false;
@ -1338,12 +1338,12 @@ bool LoadOldVehicle(LoadgameState &ls, int num)
switch (ReadByte(ls)) { switch (ReadByte(ls)) {
default: SlErrorCorrupt("Invalid vehicle type"); default: SlErrorCorrupt("Invalid vehicle type");
case 0x00 /* VEH_INVALID */: v = nullptr; break; case 0x00 /* VEH_INVALID */: v = nullptr; break;
case 0x10 /* VEH_TRAIN */: v = new (_current_vehicle_id) Train(); break; case 0x10 /* VEH_TRAIN */: v = new (VehicleID(_current_vehicle_id)) Train(); break;
case 0x11 /* VEH_ROAD */: v = new (_current_vehicle_id) RoadVehicle(); break; case 0x11 /* VEH_ROAD */: v = new (VehicleID(_current_vehicle_id)) RoadVehicle(); break;
case 0x12 /* VEH_SHIP */: v = new (_current_vehicle_id) Ship(); break; case 0x12 /* VEH_SHIP */: v = new (VehicleID(_current_vehicle_id)) Ship(); break;
case 0x13 /* VEH_AIRCRAFT*/: v = new (_current_vehicle_id) Aircraft(); break; case 0x13 /* VEH_AIRCRAFT*/: v = new (VehicleID(_current_vehicle_id)) Aircraft(); break;
case 0x14 /* VEH_EFFECT */: v = new (_current_vehicle_id) EffectVehicle(); break; case 0x14 /* VEH_EFFECT */: v = new (VehicleID(_current_vehicle_id)) EffectVehicle(); break;
case 0x15 /* VEH_DISASTER*/: v = new (_current_vehicle_id) DisasterVehicle(); break; case 0x15 /* VEH_DISASTER*/: v = new (VehicleID(_current_vehicle_id)) DisasterVehicle(); break;
} }
if (!LoadChunk(ls, v, vehicle_chunk)) return false; if (!LoadChunk(ls, v, vehicle_chunk)) return false;
@ -1413,7 +1413,7 @@ static const OldChunks sign_chunk[] = {
static bool LoadOldSign(LoadgameState &ls, int num) static bool LoadOldSign(LoadgameState &ls, int num)
{ {
Sign *si = new (num) Sign(); Sign *si = new (SignID(num)) Sign();
if (!LoadChunk(ls, si, sign_chunk)) return false; if (!LoadChunk(ls, si, sign_chunk)) return false;
if (_old_string_id != 0) { if (_old_string_id != 0) {
@ -1477,7 +1477,7 @@ static const OldChunks subsidy_chunk[] = {
static bool LoadOldSubsidy(LoadgameState &ls, int num) static bool LoadOldSubsidy(LoadgameState &ls, int num)
{ {
Subsidy *s = new (num) Subsidy(); Subsidy *s = new (SubsidyID(num)) Subsidy();
bool ret = LoadChunk(ls, s, subsidy_chunk); bool ret = LoadChunk(ls, s, subsidy_chunk);
if (!IsValidCargoType(s->cargo_type)) delete s; if (!IsValidCargoType(s->cargo_type)) delete s;
return ret; return ret;

View File

@ -148,7 +148,7 @@ struct ORDRChunkHandler : ChunkHandler {
SlCopy(&orders[0], len, SLE_UINT16); SlCopy(&orders[0], len, SLE_UINT16);
for (size_t i = 0; i < len; ++i) { for (size_t i = 0; i < len; ++i) {
Order *o = new (i) Order(); Order *o = new (OrderID(static_cast<uint32_t>(i))) Order();
o->AssignOrder(UnpackVersion4Order(orders[i])); o->AssignOrder(UnpackVersion4Order(orders[i]));
} }
} else if (IsSavegameVersionBefore(SLV_5, 2)) { } else if (IsSavegameVersionBefore(SLV_5, 2)) {
@ -158,7 +158,7 @@ struct ORDRChunkHandler : ChunkHandler {
SlCopy(&orders[0], len, SLE_UINT32); SlCopy(&orders[0], len, SLE_UINT32);
for (size_t i = 0; i < len; ++i) { for (size_t i = 0; i < len; ++i) {
new (i) Order(GB(orders[i], 0, 8), GB(orders[i], 8, 8), GB(orders[i], 16, 16)); new (OrderID(static_cast<uint32_t>(i))) Order(GB(orders[i], 0, 8), GB(orders[i], 8, 8), GB(orders[i], 16, 16));
} }
} }
@ -181,7 +181,7 @@ struct ORDRChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
Order *order = new (index) Order(); Order *order = new (OrderID(index)) Order();
SlObject(order, slt); SlObject(order, slt);
} }
} }
@ -229,7 +229,7 @@ struct ORDLChunkHandler : ChunkHandler {
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
/* set num_orders to 0 so it's a valid OrderList */ /* set num_orders to 0 so it's a valid OrderList */
OrderList *list = new (index) OrderList(0); OrderList *list = new (OrderListID(index)) OrderList(0);
SlObject(list, slt); SlObject(list, slt);
} }
@ -294,7 +294,7 @@ struct BKORChunkHandler : ChunkHandler {
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
/* set num_orders to 0 so it's a valid OrderList */ /* set num_orders to 0 so it's a valid OrderList */
OrderBackup *ob = new (index) OrderBackup(); OrderBackup *ob = new (OrderBackupID(index)) OrderBackup();
SlObject(ob, slt); SlObject(ob, slt);
} }
} }

View File

@ -49,7 +49,7 @@ struct SIGNChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
Sign *si = new (index) Sign(); Sign *si = new (SignID(index)) Sign();
SlObject(si, slt); SlObject(si, slt);
/* Before version 6.1, signs didn't have owner. /* Before version 6.1, signs didn't have owner.
* Before version 83, invalid signs were determined by si->str == 0. * Before version 83, invalid signs were determined by si->str == 0.

View File

@ -79,7 +79,7 @@ void MoveBuoysToWaypoints()
/* Stations and waypoints are in the same pool, so if a station /* Stations and waypoints are in the same pool, so if a station
* is deleted there must be place for a Waypoint. */ * is deleted there must be place for a Waypoint. */
assert(Waypoint::CanAllocateItem()); assert(Waypoint::CanAllocateItem());
Waypoint *wp = new (index.base()) Waypoint(xy); Waypoint *wp = new (index) Waypoint(xy);
wp->town = town; wp->town = town;
wp->string_id = train ? STR_SV_STNAME_WAYPOINT : STR_SV_STNAME_BUOY; wp->string_id = train ? STR_SV_STNAME_WAYPOINT : STR_SV_STNAME_BUOY;
wp->name = name; wp->name = name;
@ -512,7 +512,7 @@ struct STNSChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
Station *st = new (index) Station(); Station *st = new (StationID(index)) Station();
_waiting_acceptance = 0; _waiting_acceptance = 0;
SlObject(st, slt); SlObject(st, slt);
@ -714,7 +714,7 @@ struct STNNChunkHandler : ChunkHandler {
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
bool waypoint = static_cast<StationFacilities>(SlReadByte()).Test(StationFacility::Waypoint); bool waypoint = static_cast<StationFacilities>(SlReadByte()).Test(StationFacility::Waypoint);
BaseStation *bst = waypoint ? (BaseStation *)new (index) Waypoint() : new (index) Station(); BaseStation *bst = waypoint ? (BaseStation *)new (StationID(index)) Waypoint() : new (StationID(index)) Station();
SlObject(bst, slt); SlObject(bst, slt);
} }
} }
@ -752,7 +752,7 @@ struct ROADChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
RoadStop *rs = new (index) RoadStop(INVALID_TILE); RoadStop *rs = new (RoadStopID(index)) RoadStop(INVALID_TILE);
SlObject(rs, slt); SlObject(rs, slt);
} }

View File

@ -35,7 +35,7 @@ struct PSACChunkHandler : ChunkHandler {
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
assert(PersistentStorage::CanAllocateItem()); assert(PersistentStorage::CanAllocateItem());
PersistentStorage *ps = new (index) PersistentStorage(0, 0, TileIndex{}); PersistentStorage *ps = new (PersistentStorageID(index)) PersistentStorage(0, 0, TileIndex{});
SlObject(ps, slt); SlObject(ps, slt);
} }
} }

View File

@ -58,7 +58,7 @@ struct STPEChunkHandler : ChunkHandler {
int index; int index;
uint32_t max_sort_value = 0; uint32_t max_sort_value = 0;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
StoryPageElement *s = new (index) StoryPageElement(); StoryPageElement *s = new (StoryPageElementID(index)) StoryPageElement();
SlObject(s, slt); SlObject(s, slt);
if (s->sort_value > max_sort_value) { if (s->sort_value > max_sort_value) {
max_sort_value = s->sort_value; max_sort_value = s->sort_value;
@ -100,7 +100,7 @@ struct STPAChunkHandler : ChunkHandler {
int index; int index;
uint32_t max_sort_value = 0; uint32_t max_sort_value = 0;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
StoryPage *s = new (index) StoryPage(); StoryPage *s = new (StoryPageID(index)) StoryPage();
SlObject(s, slt); SlObject(s, slt);
if (s->sort_value > max_sort_value) { if (s->sort_value > max_sort_value) {
max_sort_value = s->sort_value; max_sort_value = s->sort_value;

View File

@ -48,7 +48,7 @@ struct SUBSChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
Subsidy *s = new (index) Subsidy(); Subsidy *s = new (SubsidyID(index)) Subsidy();
SlObject(s, slt); SlObject(s, slt);
} }
} }

View File

@ -300,7 +300,7 @@ struct CITYChunkHandler : ChunkHandler {
int index; int index;
while ((index = SlIterateArray()) != -1) { while ((index = SlIterateArray()) != -1) {
Town *t = new (index) Town(); Town *t = new (TownID(index)) Town();
SlObject(t, slt); SlObject(t, slt);
if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_END) && GetStringTab(t->townnametype) != TEXT_TAB_OLD_CUSTOM) { if (t->townnamegrfid == 0 && !IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_END) && GetStringTab(t->townnametype) != TEXT_TAB_OLD_CUSTOM) {

View File

@ -1124,12 +1124,12 @@ struct VEHSChunkHandler : ChunkHandler {
VehicleType vtype = (VehicleType)SlReadByte(); VehicleType vtype = (VehicleType)SlReadByte();
switch (vtype) { switch (vtype) {
case VEH_TRAIN: v = new (index) Train(); break; case VEH_TRAIN: v = new (VehicleID(index)) Train(); break;
case VEH_ROAD: v = new (index) RoadVehicle(); break; case VEH_ROAD: v = new (VehicleID(index)) RoadVehicle(); break;
case VEH_SHIP: v = new (index) Ship(); break; case VEH_SHIP: v = new (VehicleID(index)) Ship(); break;
case VEH_AIRCRAFT: v = new (index) Aircraft(); break; case VEH_AIRCRAFT: v = new (VehicleID(index)) Aircraft(); break;
case VEH_EFFECT: v = new (index) EffectVehicle(); break; case VEH_EFFECT: v = new (VehicleID(index)) EffectVehicle(); break;
case VEH_DISASTER: v = new (index) DisasterVehicle(); break; case VEH_DISASTER: v = new (VehicleID(index)) DisasterVehicle(); break;
case VEH_INVALID: // Savegame shouldn't contain invalid vehicles case VEH_INVALID: // Savegame shouldn't contain invalid vehicles
default: SlErrorCorrupt("Invalid vehicle type"); default: SlErrorCorrupt("Invalid vehicle type");
} }