From d8605ad18da2a00fceb72b38325374b341ac6f16 Mon Sep 17 00:00:00 2001 From: glx22 Date: Sun, 27 Dec 2020 00:13:56 +0100 Subject: [PATCH] Codechange: Replace FOR_VEHICLE_ORDERS with range-based for loops --- src/autoreplace_cmd.cpp | 3 +- src/industry_cmd.cpp | 3 +- src/order_backup.cpp | 3 +- src/order_base.h | 2 -- src/order_cmd.cpp | 32 ++++++----------- src/order_gui.cpp | 3 +- src/saveload/afterload.cpp | 3 +- src/script/api/script_vehiclelist.cpp | 8 ++--- src/station_cmd.cpp | 3 +- src/vehicle_base.h | 49 +++++++++++++++++++++++++++ src/vehiclelist.cpp | 8 ++--- 11 files changed, 69 insertions(+), 48 deletions(-) diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 4b444ae196..e3639742ff 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -179,9 +179,8 @@ static bool VerifyAutoreplaceRefitForOrders(const Vehicle *v, EngineID engine_ty CargoTypes union_refit_mask_a = GetUnionOfArticulatedRefitMasks(v->engine_type, false); CargoTypes union_refit_mask_b = GetUnionOfArticulatedRefitMasks(engine_type, false); - const Order *o; const Vehicle *u = (v->type == VEH_TRAIN) ? v->First() : v; - FOR_VEHICLE_ORDERS(u, o) { + for (const Order *o : u->Orders()) { if (!o->IsRefit() || o->IsAutoRefit()) continue; CargoID cargo_type = o->GetRefitCargo(); diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 92741e3f69..816146212f 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -2609,8 +2609,7 @@ static int WhoCanServiceIndustry(Industry *ind) * We cannot check the first of shared orders only, since the first vehicle in such a chain * may have a different cargo type. */ - const Order *o; - FOR_VEHICLE_ORDERS(v, o) { + for (const Order *o : v->Orders()) { if (o->IsType(OT_GOTO_STATION) && !(o->GetUnloadType() & OUFB_TRANSFER)) { /* Vehicle visits a station to load or unload */ Station *st = Station::Get(o->GetDestination()); diff --git a/src/order_backup.cpp b/src/order_backup.cpp index d537d8ce5c..000df56540 100644 --- a/src/order_backup.cpp +++ b/src/order_backup.cpp @@ -56,8 +56,7 @@ OrderBackup::OrderBackup(const Vehicle *v, uint32 user) Order **tail = &this->orders; /* Count the number of orders */ - const Order *order; - FOR_VEHICLE_ORDERS(v, order) { + for (const Order *order : v->Orders()) { Order *copy = new Order(); copy->AssignOrder(*order); *tail = copy; diff --git a/src/order_base.h b/src/order_base.h index ba4959c0f3..923e67d423 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -392,6 +392,4 @@ public: void DebugCheckSanity() const; }; -#define FOR_VEHICLE_ORDERS(v, order) for (order = (v->orders.list == nullptr) ? nullptr : v->orders.list->GetFirstOrder(); order != nullptr; order = order->next) - #endif /* ORDER_BASE_H */ diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 1e9e8f2f3b..c9fa919890 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -969,8 +969,7 @@ void InsertOrder(Vehicle *v, Order *new_o, VehicleOrderID sel_ord) /* As we insert an order, the order to skip to will be 'wrong'. */ VehicleOrderID cur_order_id = 0; - Order *order; - FOR_VEHICLE_ORDERS(v, order) { + for (Order *order : v->Orders()) { if (order->IsType(OT_CONDITIONAL)) { VehicleOrderID order_id = order->GetConditionSkipToOrder(); if (order_id >= sel_ord) { @@ -1090,8 +1089,7 @@ void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord) /* As we delete an order, the order to skip to will be 'wrong'. */ VehicleOrderID cur_order_id = 0; - Order *order = nullptr; - FOR_VEHICLE_ORDERS(v, order) { + for (Order *order : v->Orders()) { if (order->IsType(OT_CONDITIONAL)) { VehicleOrderID order_id = order->GetConditionSkipToOrder(); if (order_id >= sel_ord) { @@ -1225,8 +1223,7 @@ CommandCost CmdMoveOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 } /* As we move an order, the order to skip to will be 'wrong'. */ - Order *order; - FOR_VEHICLE_ORDERS(v, order) { + for (Order *order : v->Orders()) { if (order->IsType(OT_CONDITIONAL)) { VehicleOrderID order_id = order->GetConditionSkipToOrder(); if (order_id == moving_order) { @@ -1560,9 +1557,7 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /* Is the vehicle already in the shared list? */ if (src->FirstShared() == dst->FirstShared()) return CMD_ERROR; - const Order *order; - - FOR_VEHICLE_ORDERS(src, order) { + for (const Order *order : src->Orders()) { if (!OrderGoesToStation(dst, order)) continue; /* Allow copying unreachable destinations if they were already unreachable for the source. @@ -1613,8 +1608,7 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /* Trucks can't copy all the orders from busses (and visa versa), * and neither can helicopters and aircraft. */ - const Order *order; - FOR_VEHICLE_ORDERS(src, order) { + for (const Order *order : src->Orders()) { if (OrderGoesToStation(dst, order) && !CanVehicleUseStation(dst, Station::Get(order->GetDestination()))) { return_cmd_error(STR_ERROR_CAN_T_COPY_SHARE_ORDER); @@ -1632,7 +1626,6 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 } if (flags & DC_EXEC) { - const Order *order; Order *first = nullptr; Order **order_dst; @@ -1642,7 +1635,7 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 DeleteVehicleOrders(dst, true, dst->GetNumOrders() != src->GetNumOrders()); order_dst = &first; - FOR_VEHICLE_ORDERS(src, order) { + for (const Order *order : src->Orders()) { *order_dst = new Order(); (*order_dst)->AssignOrder(*order); order_dst = &(*order_dst)->next; @@ -1749,13 +1742,12 @@ void CheckOrders(const Vehicle *v) /* Only check every 20 days, so that we don't flood the message log */ if (v->owner == _local_company && v->day_counter % 20 == 0) { - const Order *order; StringID message = INVALID_STRING_ID; /* Check the order list */ int n_st = 0; - FOR_VEHICLE_ORDERS(v, order) { + for (const Order *order : v->Orders()) { /* Dummy order? */ if (order->IsType(OT_DUMMY)) { message = STR_NEWS_VEHICLE_HAS_VOID_ORDER; @@ -1829,7 +1821,7 @@ void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, bool /* Clear the order from the order-list */ int id = -1; - FOR_VEHICLE_ORDERS(v, order) { + for (Order *order : v->Orders()) { id++; restart: @@ -1879,9 +1871,7 @@ restart: */ bool Vehicle::HasDepotOrder() const { - const Order *order; - - FOR_VEHICLE_ORDERS(this, order) { + for (const Order *order : this->Orders()) { if (order->IsType(OT_GOTO_DEPOT)) return true; } @@ -1940,9 +1930,7 @@ uint16 GetServiceIntervalClamped(uint interval, bool ispercent) */ static bool CheckForValidOrders(const Vehicle *v) { - const Order *order; - - FOR_VEHICLE_ORDERS(v, order) { + for (const Order *order : v->Orders()) { switch (order->GetType()) { case OT_GOTO_STATION: case OT_GOTO_DEPOT: diff --git a/src/order_gui.cpp b/src/order_gui.cpp index 4edf994f78..5529a8331e 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -793,8 +793,7 @@ public: if (_settings_client.gui.quick_goto && v->owner == _local_company) { /* If there are less than 2 station, make Go To active. */ int station_orders = 0; - const Order *order; - FOR_VEHICLE_ORDERS(v, order) { + for(const Order *order : v->Orders()) { if (order->IsType(OT_GOTO_STATION)) station_orders++; } diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index c617348d73..4eab99c883 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -1733,8 +1733,7 @@ bool AfterLoadGame() v->current_order.ConvertFromOldSavegame(); if (v->type == VEH_ROAD && v->IsPrimaryVehicle() && v->FirstShared() == v) { - Order* order; - FOR_VEHICLE_ORDERS(v, order) order->SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS); + for (Order *order : v->Orders()) order->SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS); } } } else if (IsSavegameVersionBefore(SLV_94)) { diff --git a/src/script/api/script_vehiclelist.cpp b/src/script/api/script_vehiclelist.cpp index 58c03ff9a9..3a4d2d135b 100644 --- a/src/script/api/script_vehiclelist.cpp +++ b/src/script/api/script_vehiclelist.cpp @@ -31,9 +31,7 @@ ScriptVehicleList_Station::ScriptVehicleList_Station(StationID station_id) for (const Vehicle *v : Vehicle::Iterate()) { if ((v->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && v->IsPrimaryVehicle()) { - const Order *order; - - FOR_VEHICLE_ORDERS(v, order) { + for (const Order *order : v->Orders()) { if ((order->IsType(OT_GOTO_STATION) || order->IsType(OT_GOTO_WAYPOINT)) && order->GetDestination() == station_id) { this->AddItem(v->index); break; @@ -81,9 +79,7 @@ ScriptVehicleList_Depot::ScriptVehicleList_Depot(TileIndex tile) for (const Vehicle *v : Vehicle::Iterate()) { if ((v->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && v->IsPrimaryVehicle() && v->type == type) { - const Order *order; - - FOR_VEHICLE_ORDERS(v, order) { + for (const Order *order : v->Orders()) { if (order->IsType(OT_GOTO_DEPOT) && order->GetDestination() == dest) { this->AddItem(v->index); break; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index cd56dcb698..64a7adca8e 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2486,8 +2486,7 @@ bool HasStationInUse(StationID station, bool include_company, CompanyID company) { for (const Vehicle *v : Vehicle::Iterate()) { if ((v->owner == company) == include_company) { - const Order *order; - FOR_VEHICLE_ORDERS(v, order) { + for (const Order *order : v->Orders()) { if ((order->IsType(OT_GOTO_STATION) || order->IsType(OT_GOTO_WAYPOINT)) && order->GetDestination() == station) { return true; } diff --git a/src/vehicle_base.h b/src/vehicle_base.h index bc72c6bbfd..019c94a29a 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -969,6 +969,55 @@ public: return v; } + + /** + * Iterator to iterate orders + * Supports deletion of current order + */ + struct OrderIterator { + typedef Order value_type; + typedef Order* pointer; + typedef Order& reference; + typedef size_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + explicit OrderIterator(OrderList *list) : list(list), prev(nullptr) + { + this->order = (this->list == nullptr) ? nullptr : this->list->GetFirstOrder(); + } + + bool operator==(const OrderIterator &other) const { return this->order == other.order; } + bool operator!=(const OrderIterator &other) const { return !(*this == other); } + Order * operator*() const { return this->order; } + OrderIterator & operator++() + { + this->prev = (this->prev == nullptr) ? this->list->GetFirstOrder() : this->prev->next; + this->order = (this->prev == nullptr) ? nullptr : this->prev->next; + return *this; + } + + private: + OrderList *list; + Order *order; + Order *prev; + }; + + /** + * Iterable ensemble of orders + */ + struct IterateWrapper { + OrderList *list; + IterateWrapper(OrderList *list = nullptr) : list(list) {} + OrderIterator begin() { return OrderIterator(this->list); } + OrderIterator end() { return OrderIterator(nullptr); } + bool empty() { return this->begin() == this->end(); } + }; + + /** + * Returns an iterable ensemble of orders of a vehicle + * @return an iterable ensemble of orders of a vehicle + */ + IterateWrapper Orders() const { return IterateWrapper(this->orders.list); } }; /** diff --git a/src/vehiclelist.cpp b/src/vehiclelist.cpp index de37e3abae..79df540cf4 100644 --- a/src/vehiclelist.cpp +++ b/src/vehiclelist.cpp @@ -118,9 +118,7 @@ bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &vli case VL_STATION_LIST: for (const Vehicle *v : Vehicle::Iterate()) { if (v->type == vli.vtype && v->IsPrimaryVehicle()) { - const Order *order; - - FOR_VEHICLE_ORDERS(v, order) { + for (const Order *order : v->Orders()) { if ((order->IsType(OT_GOTO_STATION) || order->IsType(OT_GOTO_WAYPOINT) || order->IsType(OT_IMPLICIT)) && order->GetDestination() == vli.index) { list->push_back(v); @@ -165,9 +163,7 @@ bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &vli case VL_DEPOT_LIST: for (const Vehicle *v : Vehicle::Iterate()) { if (v->type == vli.vtype && v->IsPrimaryVehicle()) { - const Order *order; - - FOR_VEHICLE_ORDERS(v, order) { + for (const Order *order : v->Orders()) { if (order->IsType(OT_GOTO_DEPOT) && !(order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) && order->GetDestination() == vli.index) { list->push_back(v); break;