1
0
Fork 0

Codechange: Add HasFlag() to test if a value is present in a bitset enum type. (#12959)

This simplifies tests for `(x & y) != y` with enum classes by reducing repetition, similar to HasBit(), and also makes the intent of the expression clearer.
pull/12961/head
Peter Nelson 2024-09-22 14:51:37 +01:00 committed by GitHub
parent d450d4743e
commit 376e882a14
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 37 additions and 25 deletions

View File

@ -594,7 +594,7 @@ public:
if (it != this->engines[click_side].end()) {
const auto &item = *it;
const Rect r = this->GetWidget<NWidgetBase>(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.matrix).WithWidth(WidgetDimensions::scaled.hsep_indent * (item.indent + 1), _current_text_dir == TD_RTL);
if ((item.flags & EngineDisplayFlags::HasVariants) != EngineDisplayFlags::None && IsInsideMM(r.left, r.right, pt.x)) {
if (HasFlag(item.flags, EngineDisplayFlags::HasVariants) && IsInsideMM(r.left, r.right, pt.x)) {
/* toggle folded flag on engine */
assert(item.variant_id != INVALID_ENGINE);
Engine *engine = Engine::Get(item.variant_id);
@ -604,7 +604,7 @@ public:
InvalidateWindowClassesData(WC_BUILD_VEHICLE); // The build windows needs updating as well
return;
}
if ((item.flags & EngineDisplayFlags::Shaded) == EngineDisplayFlags::None) e = item.engine_id;
if (!HasFlag(item.flags, EngineDisplayFlags::Shaded)) e = item.engine_id;
}
/* If Ctrl is pressed on the left side and we don't have any engines of the selected type, stop autoreplacing.

View File

@ -1048,9 +1048,9 @@ void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_li
for (auto it = first; it != last; ++it) {
const auto &item = *it;
uint indent = item.indent * WidgetDimensions::scaled.hsep_indent;
bool has_variants = (item.flags & EngineDisplayFlags::HasVariants) != EngineDisplayFlags::None;
bool is_folded = (item.flags & EngineDisplayFlags::IsFolded) != EngineDisplayFlags::None;
bool shaded = (item.flags & EngineDisplayFlags::Shaded) != EngineDisplayFlags::None;
bool has_variants = HasFlag(item.flags, EngineDisplayFlags::HasVariants);
bool is_folded = HasFlag(item.flags, EngineDisplayFlags::IsFolded);
bool shaded = HasFlag(item.flags, EngineDisplayFlags::Shaded);
if (item.indent > 0) {
/* Draw tree continuation lines. */
@ -1138,9 +1138,9 @@ void GUIEngineListAddChildren(GUIEngineList &dst, const GUIEngineList &src, Engi
dst.emplace_back(e->display_last_variant == INVALID_ENGINE ? item.engine_id : e->display_last_variant, item.engine_id, flags, indent);
/* Add variants if not folded */
if ((item.flags & (EngineDisplayFlags::HasVariants | EngineDisplayFlags::IsFolded)) == EngineDisplayFlags::HasVariants) {
if (HasFlag(item.flags, EngineDisplayFlags::HasVariants) && !HasFlag(item.flags, EngineDisplayFlags::IsFolded)) {
/* Add this engine again as a child */
if ((item.flags & EngineDisplayFlags::Shaded) == EngineDisplayFlags::None) {
if (!HasFlag(item.flags, EngineDisplayFlags::Shaded)) {
dst.emplace_back(item.engine_id, item.engine_id, EngineDisplayFlags::None, indent + 1);
}
GUIEngineListAddChildren(dst, src, item.engine_id, indent + 1);
@ -1256,7 +1256,7 @@ struct BuildVehicleWindow : Window {
/* Select the first unshaded engine in the list as default when opening the window */
EngineID engine = INVALID_ENGINE;
auto it = std::find_if(this->eng_list.begin(), this->eng_list.end(), [&](GUIEngineListItem &item) { return (item.flags & EngineDisplayFlags::Shaded) == EngineDisplayFlags::None; });
auto it = std::find_if(this->eng_list.begin(), this->eng_list.end(), [&](GUIEngineListItem &item) { return !HasFlag(item.flags, EngineDisplayFlags::Shaded); });
if (it != this->eng_list.end()) engine = it->engine_id;
this->SelectEngine(engine);
}
@ -1659,7 +1659,7 @@ struct BuildVehicleWindow : Window {
if (it != this->eng_list.end()) {
const auto &item = *it;
const Rect r = this->GetWidget<NWidgetBase>(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.matrix).WithWidth(WidgetDimensions::scaled.hsep_indent * (item.indent + 1), _current_text_dir == TD_RTL);
if ((item.flags & EngineDisplayFlags::HasVariants) != EngineDisplayFlags::None && IsInsideMM(r.left, r.right, pt.x)) {
if (HasFlag(item.flags, EngineDisplayFlags::HasVariants) && IsInsideMM(r.left, r.right, pt.x)) {
/* toggle folded flag on engine */
assert(item.variant_id != INVALID_ENGINE);
Engine *engine = Engine::Get(item.variant_id);
@ -1669,7 +1669,7 @@ struct BuildVehicleWindow : Window {
InvalidateWindowClassesData(WC_BUILD_VEHICLE); // The build windows needs updating as well
return;
}
if ((item.flags & EngineDisplayFlags::Shaded) == EngineDisplayFlags::None) e = item.engine_id;
if (!HasFlag(item.flags, EngineDisplayFlags::Shaded)) e = item.engine_id;
}
this->SelectEngine(e);
this->SetDirty();

View File

@ -44,4 +44,16 @@
return static_cast<OtherEnumType>(static_cast<typename std::underlying_type<OtherEnumType>::type>(m1) + static_cast<typename std::underlying_type<EnumType>::type>(m2)); \
}
/**
* Checks if a value in a bitset enum is set.
* @param x The value to check.
* @param y The flag to check.
* @return True iff the flag is set.
*/
template <typename T, class = typename std::enable_if_t<std::is_enum_v<T>>>
debug_inline constexpr bool HasFlag(const T x, const T y)
{
return (x & y) == y;
}
#endif /* ENUM_TYPE_HPP */

View File

@ -612,7 +612,7 @@ void CalcEngineReliability(Engine *e, bool new_month)
{
/* Get source engine for reliability age. This is normally our engine unless variant reliability syncing is requested. */
Engine *re = e;
while (re->info.variant_id != INVALID_ENGINE && (re->info.extra_flags & ExtraEngineFlags::SyncReliability) != ExtraEngineFlags::None) {
while (re->info.variant_id != INVALID_ENGINE && HasFlag(re->info.extra_flags, ExtraEngineFlags::SyncReliability)) {
re = Engine::Get(re->info.variant_id);
}
@ -714,7 +714,7 @@ void StartupOneEngine(Engine *e, const TimerGameCalendar::YearMonthDay &aging_ym
/* Get parent variant index for syncing reliability via random seed. */
const Engine *re = e;
while (re->info.variant_id != INVALID_ENGINE && (re->info.extra_flags & ExtraEngineFlags::SyncReliability) != ExtraEngineFlags::None) {
while (re->info.variant_id != INVALID_ENGINE && HasFlag(re->info.extra_flags, ExtraEngineFlags::SyncReliability)) {
re = Engine::Get(re->info.variant_id);
}
@ -865,7 +865,7 @@ static void AcceptEnginePreview(EngineID eid, CompanyID company, int recursion_d
/* Find variants to be included in preview. */
for (Engine *ve : Engine::IterateType(e->type)) {
if (ve->index != eid && ve->info.variant_id == eid && (ve->info.extra_flags & ExtraEngineFlags::JoinPreview) != ExtraEngineFlags::None) {
if (ve->index != eid && ve->info.variant_id == eid && HasFlag(ve->info.extra_flags, ExtraEngineFlags::JoinPreview)) {
AcceptEnginePreview(ve->index, company, recursion_depth + 1);
}
}
@ -1092,7 +1092,7 @@ static void NewVehicleAvailable(Engine *e)
if (!IsVehicleTypeDisabled(e->type, true)) AI::BroadcastNewEvent(new ScriptEventEngineAvailable(index));
/* Only provide the "New Vehicle available" news paper entry, if engine can be built. */
if (!IsVehicleTypeDisabled(e->type, false) && (e->info.extra_flags & ExtraEngineFlags::NoNews) == ExtraEngineFlags::None) {
if (!IsVehicleTypeDisabled(e->type, false) && !HasFlag(e->info.extra_flags, ExtraEngineFlags::NoNews)) {
SetDParam(0, GetEngineCategoryName(index));
SetDParam(1, PackEngineNameDParam(index, EngineNameContext::PreviewNews));
AddNewsItem(STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE, NT_NEW_VEHICLES, NF_VEHICLE, NR_ENGINE, index);
@ -1137,7 +1137,7 @@ void CalendarEnginesMonthlyLoop()
if (IsWagon(e->index)) continue;
/* Engine has no preview */
if ((e->info.extra_flags & ExtraEngineFlags::NoPreview) != ExtraEngineFlags::None) continue;
if (HasFlag(e->info.extra_flags, ExtraEngineFlags::NoPreview)) continue;
/* Show preview dialog to one of the companies. */
e->flags |= ENGINE_EXCLUSIVE_PREVIEW;

View File

@ -1326,9 +1326,9 @@ static StationSpec::TileFlags GetStationTileFlags(StationGfx gfx, const StationS
void SetRailStationTileFlags(TileIndex tile, const StationSpec *statspec)
{
const auto flags = GetStationTileFlags(GetStationGfx(tile), statspec);
SetStationTileBlocked(tile, (flags & StationSpec::TileFlags::Blocked) == StationSpec::TileFlags::Blocked);
SetStationTileHavePylons(tile, (flags & StationSpec::TileFlags::Pylons) == StationSpec::TileFlags::Pylons);
SetStationTileHaveWires(tile, (flags & StationSpec::TileFlags::NoWires) != StationSpec::TileFlags::NoWires);
SetStationTileBlocked(tile, HasFlag(flags, StationSpec::TileFlags::Blocked));
SetStationTileHavePylons(tile, HasFlag(flags, StationSpec::TileFlags::Pylons));
SetStationTileHaveWires(tile, !HasFlag(flags, StationSpec::TileFlags::NoWires));
}
/**

View File

@ -2593,7 +2593,7 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command)
if (this->current_order.IsType(OT_GOTO_DEPOT)) {
bool halt_in_depot = (this->current_order.GetDepotActionType() & ODATFB_HALT) != 0;
if (((command & DepotCommand::Service) != DepotCommand::None) == halt_in_depot) {
if (HasFlag(command, DepotCommand::Service) == halt_in_depot) {
/* We called with a different DEPOT_SERVICE setting.
* Now we change the setting to apply the new one and let the vehicle head for the same depot.
* Note: the if is (true for requesting service == true for ordered to stop in depot) */
@ -2605,7 +2605,7 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command)
return CommandCost();
}
if ((command & DepotCommand::DontCancel) != DepotCommand::None) return CMD_ERROR; // Requested no cancellation of depot orders
if (HasFlag(command, DepotCommand::DontCancel)) return CMD_ERROR; // Requested no cancellation of depot orders
if (flags & DC_EXEC) {
/* If the orders to 'goto depot' are in the orders list (forced servicing),
* then skip to the next order; effectively cancelling this forced service */
@ -2636,7 +2636,7 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command)
this->SetDestTile(closestDepot.location);
this->current_order.MakeGoToDepot(closestDepot.destination, ODTF_MANUAL);
if ((command & DepotCommand::Service) == DepotCommand::None) this->current_order.SetDepotActionType(ODATFB_HALT);
if (!HasFlag(command, DepotCommand::Service)) this->current_order.SetDepotActionType(ODATFB_HALT);
SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
/* If there is no depot in front and the train is not already reversing, reverse automatically (trains only) */

View File

@ -1046,10 +1046,10 @@ static CommandCost SendAllVehiclesToDepot(DoCommandFlag flags, bool service, con
*/
CommandCost CmdSendVehicleToDepot(DoCommandFlag flags, VehicleID veh_id, DepotCommand depot_cmd, const VehicleListIdentifier &vli)
{
if ((depot_cmd & DepotCommand::MassSend) != DepotCommand::None) {
if (HasFlag(depot_cmd, DepotCommand::MassSend)) {
/* Mass goto depot requested */
if (!vli.Valid()) return CMD_ERROR;
return SendAllVehiclesToDepot(flags, (depot_cmd & DepotCommand::Service) != DepotCommand::None, vli);
return SendAllVehiclesToDepot(flags, HasFlag(depot_cmd, DepotCommand::Service), vli);
}
Vehicle *v = Vehicle::GetIfValid(veh_id);

View File

@ -932,8 +932,8 @@ void NWidgetBase::ApplyAspectRatio()
uint x = this->smallest_x;
uint y = this->smallest_y;
if ((this->aspect_flags & AspectFlags::ResizeX) == AspectFlags::ResizeX) x = std::max(this->smallest_x, static_cast<uint>(this->smallest_y * std::abs(this->aspect_ratio)));
if ((this->aspect_flags & AspectFlags::ResizeY) == AspectFlags::ResizeY) y = std::max(this->smallest_y, static_cast<uint>(this->smallest_x / std::abs(this->aspect_ratio)));
if (HasFlag(this->aspect_flags, AspectFlags::ResizeX)) x = std::max(this->smallest_x, static_cast<uint>(this->smallest_y * std::abs(this->aspect_ratio)));
if (HasFlag(this->aspect_flags, AspectFlags::ResizeY)) y = std::max(this->smallest_y, static_cast<uint>(this->smallest_x / std::abs(this->aspect_ratio)));
this->smallest_x = x;
this->smallest_y = y;