From e4fc8ef595bdd1566c16e31204667e1eb4d18c76 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sun, 24 Mar 2024 15:37:01 +0000 Subject: [PATCH] Codechange: Use std::span for industry cargo window instead of pointer + length. --- src/industry_gui.cpp | 106 +++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 60 deletions(-) diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index e08e391ef1..66f5ad12b7 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -2089,23 +2089,17 @@ struct CargoesField { /** * Make a piece of cargo column. - * @param cargoes Array of #CargoID (may contain #INVALID_CARGO). - * @param length Number of cargoes in \a cargoes. + * @param cargoes Span of #CargoID (may contain #INVALID_CARGO). * @param count Number of cargoes to display (should be at least the number of valid cargoes, or \c -1 to let the method compute it). * @param top_end This is the first cargo field of this column. * @param bottom_end This is the last cargo field of this column. * @note #supp_cargoes and #cust_cargoes should be filled in later. */ - void MakeCargo(const CargoID *cargoes, uint length, int count = -1, bool top_end = false, bool bottom_end = false) + void MakeCargo(const std::span cargoes, int count = -1, bool top_end = false, bool bottom_end = false) { this->type = CFT_CARGO; - auto insert = std::begin(this->u.cargo.vertical_cargoes); - for (uint i = 0; insert != std::end(this->u.cargo.vertical_cargoes) && i < length; i++) { - if (IsValidCargoID(cargoes[i])) { - *insert = cargoes[i]; - ++insert; - } - } + assert(std::size(cargoes) <= std::size(this->u.cargo.vertical_cargoes)); + auto insert = std::copy_if(std::begin(cargoes), std::end(cargoes), std::begin(this->u.cargo.vertical_cargoes), IsValidCargoID); this->u.cargo.num_cargoes = (count < 0) ? static_cast(insert - std::begin(this->u.cargo.vertical_cargoes)) : count; CargoIDComparator comparator; std::sort(std::begin(this->u.cargo.vertical_cargoes), insert, comparator); @@ -2118,16 +2112,15 @@ struct CargoesField { /** * Make a field displaying cargo type names. - * @param cargoes Array of #CargoID (may contain #INVALID_CARGO). - * @param length Number of cargoes in \a cargoes. + * @param cargoes Span of #CargoID (may contain #INVALID_CARGO). * @param left_align ALign texts to the left (else to the right). */ - void MakeCargoLabel(const CargoID *cargoes, uint length, bool left_align) + void MakeCargoLabel(const std::span cargoes, bool left_align) { this->type = CFT_CARGO_LABEL; - uint i; - for (i = 0; i < MAX_CARGOES && i < length; i++) this->u.cargo_label.cargoes[i] = cargoes[i]; - for (; i < MAX_CARGOES; i++) this->u.cargo_label.cargoes[i] = INVALID_CARGO; + assert(std::size(cargoes) <= std::size(this->u.cargo_label.cargoes)); + auto insert = std::copy(std::begin(cargoes), std::end(cargoes), std::begin(this->u.cargo_label.cargoes)); + std::fill(insert, std::end(this->u.cargo_label.cargoes), INVALID_CARGO); this->u.cargo_label.left_align = left_align; } @@ -2197,7 +2190,7 @@ struct CargoesField { } /* Draw the other_produced/other_accepted cargoes. */ - const CargoID *other_right, *other_left; + std::span other_right, other_left; if (_current_text_dir == TD_RTL) { other_right = this->u.industry.other_accepted; other_left = this->u.industry.other_produced; @@ -2471,7 +2464,7 @@ struct CargoesRow { int col = cargo_fld->ConnectCargo(cargo_fld->u.cargo.vertical_cargoes[i], !accepting); if (col >= 0) cargoes[col] = cargo_fld->u.cargo.vertical_cargoes[i]; } - label_fld->MakeCargoLabel(cargoes, lengthof(cargoes), accepting); + label_fld->MakeCargoLabel(cargoes, accepting); } @@ -2670,34 +2663,29 @@ struct IndustryCargoesWindow : public Window { /** * Do the two sets of cargoes have a valid cargo in common? - * @param cargoes1 Base address of the first cargo array. - * @param length1 Number of cargoes in the first cargo array. - * @param cargoes2 Base address of the second cargo array. - * @param length2 Number of cargoes in the second cargo array. + * @param cargoes1 Span of the first cargo list. + * @param cargoes2 Span of the second cargo list. * @return Arrays have at least one valid cargo in common. */ - static bool HasCommonValidCargo(const CargoID *cargoes1, uint length1, const CargoID *cargoes2, uint length2) + static bool HasCommonValidCargo(const std::span cargoes1, const std::span cargoes2) { - while (length1 > 0) { - if (IsValidCargoID(*cargoes1)) { - for (uint i = 0; i < length2; i++) if (*cargoes1 == cargoes2[i]) return true; + for (const CargoID cid1 : cargoes1) { + if (!IsValidCargoID(cid1)) continue; + for (const CargoID cid2 : cargoes2) { + if (cid1 == cid2) return true; } - cargoes1++; - length1--; } return false; } /** * Can houses be used to supply one of the cargoes? - * @param cargoes Base address of the cargo array. - * @param length Number of cargoes in the array. + * @param cargoes Span of cargo list. * @return Houses can supply at least one of the cargoes. */ - static bool HousesCanSupply(const CargoID *cargoes, uint length) + static bool HousesCanSupply(const std::span cargoes) { - for (uint i = 0; i < length; i++) { - CargoID cid = cargoes[i]; + for (const CargoID cid : cargoes) { if (!IsValidCargoID(cid)) continue; TownProductionEffect tpe = CargoSpec::Get(cid)->town_production_effect; if (tpe == TPE_PASSENGERS || tpe == TPE_MAIL) return true; @@ -2707,11 +2695,10 @@ struct IndustryCargoesWindow : public Window { /** * Can houses be used as customers of the produced cargoes? - * @param cargoes Base address of the cargo array. - * @param length Number of cargoes in the array. + * @param cargoes Span of cargo list. * @return Houses can accept at least one of the cargoes. */ - static bool HousesCanAccept(const CargoID *cargoes, uint length) + static bool HousesCanAccept(const std::span cargoes) { HouseZones climate_mask; switch (_settings_game.game_creation.landscape) { @@ -2721,14 +2708,14 @@ struct IndustryCargoesWindow : public Window { case LT_TOYLAND: climate_mask = HZ_TOYLND; break; default: NOT_REACHED(); } - for (uint i = 0; i < length; i++) { - if (!IsValidCargoID(cargoes[i])) continue; + for (const CargoID cid : cargoes) { + if (!IsValidCargoID(cid)) continue; for (const auto &hs : HouseSpec::Specs()) { if (!hs.enabled || !(hs.building_availability & climate_mask)) continue; for (uint j = 0; j < lengthof(hs.accepts_cargo); j++) { - if (hs.cargo_acceptance[j] > 0 && cargoes[i] == hs.accepts_cargo[j]) return true; + if (hs.cargo_acceptance[j] > 0 && cid == hs.accepts_cargo[j]) return true; } } } @@ -2738,17 +2725,16 @@ struct IndustryCargoesWindow : public Window { /** * Count how many industries have accepted cargoes in common with one of the supplied set. * @param cargoes Cargoes to search. - * @param length Number of cargoes in \a cargoes. * @return Number of industries that have an accepted cargo in common with the supplied set. */ - static int CountMatchingAcceptingIndustries(const CargoID *cargoes, uint length) + static int CountMatchingAcceptingIndustries(const std::span cargoes) { int count = 0; for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) { const IndustrySpec *indsp = GetIndustrySpec(it); if (!indsp->enabled) continue; - if (HasCommonValidCargo(cargoes, length, indsp->accepts_cargo, lengthof(indsp->accepts_cargo))) count++; + if (HasCommonValidCargo(cargoes, indsp->accepts_cargo)) count++; } return count; } @@ -2756,17 +2742,16 @@ struct IndustryCargoesWindow : public Window { /** * Count how many industries have produced cargoes in common with one of the supplied set. * @param cargoes Cargoes to search. - * @param length Number of cargoes in \a cargoes. * @return Number of industries that have a produced cargo in common with the supplied set. */ - static int CountMatchingProducingIndustries(const CargoID *cargoes, uint length) + static int CountMatchingProducingIndustries(const std::span cargoes) { int count = 0; for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) { const IndustrySpec *indsp = GetIndustrySpec(it); if (!indsp->enabled) continue; - if (HasCommonValidCargo(cargoes, length, indsp->produced_cargo, lengthof(indsp->produced_cargo))) count++; + if (HasCommonValidCargo(cargoes, indsp->produced_cargo)) count++; } return count; } @@ -2841,18 +2826,18 @@ struct IndustryCargoesWindow : public Window { first_row.columns[4].MakeHeader(STR_INDUSTRY_CARGOES_CUSTOMERS); const IndustrySpec *central_sp = GetIndustrySpec(displayed_it); - bool houses_supply = HousesCanSupply(central_sp->accepts_cargo, lengthof(central_sp->accepts_cargo)); - bool houses_accept = HousesCanAccept(central_sp->produced_cargo, lengthof(central_sp->produced_cargo)); + bool houses_supply = HousesCanSupply(central_sp->accepts_cargo); + bool houses_accept = HousesCanAccept(central_sp->produced_cargo); /* Make a field consisting of two cargo columns. */ - int num_supp = CountMatchingProducingIndustries(central_sp->accepts_cargo, lengthof(central_sp->accepts_cargo)) + houses_supply; - int num_cust = CountMatchingAcceptingIndustries(central_sp->produced_cargo, lengthof(central_sp->produced_cargo)) + houses_accept; + int num_supp = CountMatchingProducingIndustries(central_sp->accepts_cargo) + houses_supply; + int num_cust = CountMatchingAcceptingIndustries(central_sp->produced_cargo) + houses_accept; int num_indrows = std::max(3, std::max(num_supp, num_cust)); // One is needed for the 'it' industry, and 2 for the cargo labels. for (int i = 0; i < num_indrows; i++) { CargoesRow &row = this->fields.emplace_back(); row.columns[0].MakeEmpty(CFT_EMPTY); - row.columns[1].MakeCargo(central_sp->accepts_cargo, lengthof(central_sp->accepts_cargo)); + row.columns[1].MakeCargo(central_sp->accepts_cargo); row.columns[2].MakeEmpty(CFT_EMPTY); - row.columns[3].MakeCargo(central_sp->produced_cargo, lengthof(central_sp->produced_cargo)); + row.columns[3].MakeCargo(central_sp->produced_cargo); row.columns[4].MakeEmpty(CFT_EMPTY); } /* Add central industry. */ @@ -2872,12 +2857,12 @@ struct IndustryCargoesWindow : public Window { const IndustrySpec *indsp = GetIndustrySpec(it); if (!indsp->enabled) continue; - if (HasCommonValidCargo(central_sp->accepts_cargo, lengthof(central_sp->accepts_cargo), indsp->produced_cargo, lengthof(indsp->produced_cargo))) { + if (HasCommonValidCargo(central_sp->accepts_cargo, indsp->produced_cargo)) { this->PlaceIndustry(1 + supp_count * num_indrows / num_supp, 0, it); _displayed_industries.set(it); supp_count++; } - if (HasCommonValidCargo(central_sp->produced_cargo, lengthof(central_sp->produced_cargo), indsp->accepts_cargo, lengthof(indsp->accepts_cargo))) { + if (HasCommonValidCargo(central_sp->produced_cargo, indsp->accepts_cargo)) { this->PlaceIndustry(1 + cust_count * num_indrows / num_cust, 4, it); _displayed_industries.set(it); cust_count++; @@ -2917,15 +2902,16 @@ struct IndustryCargoesWindow : public Window { first_row.columns[3].MakeEmpty(CFT_SMALL_EMPTY); first_row.columns[4].MakeEmpty(CFT_SMALL_EMPTY); - bool houses_supply = HousesCanSupply(&cid, 1); - bool houses_accept = HousesCanAccept(&cid, 1); - int num_supp = CountMatchingProducingIndustries(&cid, 1) + houses_supply + 1; // Ensure room for the cargo label. - int num_cust = CountMatchingAcceptingIndustries(&cid, 1) + houses_accept; + auto cargoes = std::span(&cid, 1); + bool houses_supply = HousesCanSupply(cargoes); + bool houses_accept = HousesCanAccept(cargoes); + int num_supp = CountMatchingProducingIndustries(cargoes) + houses_supply + 1; // Ensure room for the cargo label. + int num_cust = CountMatchingAcceptingIndustries(cargoes) + houses_accept; int num_indrows = std::max(num_supp, num_cust); for (int i = 0; i < num_indrows; i++) { CargoesRow &row = this->fields.emplace_back(); row.columns[0].MakeEmpty(CFT_EMPTY); - row.columns[1].MakeCargo(&cid, 1); + row.columns[1].MakeCargo(cargoes); row.columns[2].MakeEmpty(CFT_EMPTY); row.columns[3].MakeEmpty(CFT_EMPTY); row.columns[4].MakeEmpty(CFT_EMPTY); @@ -2940,12 +2926,12 @@ struct IndustryCargoesWindow : public Window { const IndustrySpec *indsp = GetIndustrySpec(it); if (!indsp->enabled) continue; - if (HasCommonValidCargo(&cid, 1, indsp->produced_cargo, lengthof(indsp->produced_cargo))) { + if (HasCommonValidCargo(cargoes, indsp->produced_cargo)) { this->PlaceIndustry(1 + supp_count * num_indrows / num_supp, 0, it); _displayed_industries.set(it); supp_count++; } - if (HasCommonValidCargo(&cid, 1, indsp->accepts_cargo, lengthof(indsp->accepts_cargo))) { + if (HasCommonValidCargo(cargoes, indsp->accepts_cargo)) { this->PlaceIndustry(1 + cust_count * num_indrows / num_cust, 2, it); _displayed_industries.set(it); cust_count++;