diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -3,7 +3,6 @@ add_files( alloc_func.hpp alloc_type.hpp backup_type.hpp - bitmath_func.cpp bitmath_func.hpp endian_func.hpp endian_type.hpp diff --git a/src/core/bitmath_func.cpp b/src/core/bitmath_func.cpp deleted file mode 100644 --- a/src/core/bitmath_func.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - * This file is part of OpenTTD. - * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. - * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . - */ - -/** @file bitmath_func.cpp Functions related to bit mathematics. */ - -#include "../stdafx.h" -#include "bitmath_func.hpp" - -#include "../safeguards.h" - -const uint8_t _ffb_64[64] = { - 0, 0, 1, 0, 2, 0, 1, 0, - 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, - 3, 0, 1, 0, 2, 0, 1, 0, - 5, 0, 1, 0, 2, 0, 1, 0, - 3, 0, 1, 0, 2, 0, 1, 0, - 4, 0, 1, 0, 2, 0, 1, 0, - 3, 0, 1, 0, 2, 0, 1, 0, -}; diff --git a/src/core/bitmath_func.hpp b/src/core/bitmath_func.hpp --- a/src/core/bitmath_func.hpp +++ b/src/core/bitmath_func.hpp @@ -183,45 +183,6 @@ inline T ToggleBit(T &x, const uint8_t y return x = (T)(x ^ ((T)1U << y)); } - -/** Lookup table to check which bit is set in a 6 bit variable */ -extern const uint8_t _ffb_64[64]; - -/** - * Returns the first non-zero bit in a 6-bit value (from right). - * - * Returns the position of the first bit that is not zero, counted from the - * LSB. Ie, 110100 returns 2, 000001 returns 0, etc. When x == 0 returns - * 0. - * - * @param x The 6-bit value to check the first zero-bit - * @return The first position of a bit started from the LSB or 0 if x is 0. - */ -#define FIND_FIRST_BIT(x) _ffb_64[(x)] - -/** - * Finds the position of the first non-zero bit in an integer. - * - * This function returns the position of the first bit set in the - * integer. It does only check the bits of the bitmask - * 0x3F3F (0011111100111111) and checks only the - * bits of the bitmask 0x3F00 if and only if the - * lower part 0x00FF is 0. This results the bits at 0x00C0 must - * be also zero to check the bits at 0x3F00. - * - * @param value The value to check the first bits - * @return The position of the first bit which is set - * @see FIND_FIRST_BIT - */ -inline uint8_t FindFirstBit2x64(const int value) -{ - if ((value & 0xFF) == 0) { - return FIND_FIRST_BIT((value >> 8) & 0x3F) + 8; - } else { - return FIND_FIRST_BIT(value & 0x3F); - } -} - /** * Search the first set bit in a value. * When no bit is set, it returns 0. @@ -234,7 +195,11 @@ constexpr uint8_t FindFirstBit(T x) { if (x == 0) return 0; - return std::countr_zero(x); + if constexpr (std::is_enum_v) { + return std::countr_zero>(x); + } else { + return std::countr_zero(x); + } } /** diff --git a/src/pathfinder/npf/npf.cpp b/src/pathfinder/npf/npf.cpp --- a/src/pathfinder/npf/npf.cpp +++ b/src/pathfinder/npf/npf.cpp @@ -1225,11 +1225,11 @@ bool NPFShipCheckReverse(const Ship *v, if (best_td != nullptr) { DiagDirection entry = ReverseDiagDir(VehicleExitDir(v->direction, v->state)); TrackdirBits rtds = DiagdirReachesTrackdirs(entry) & TrackStatusToTrackdirBits(GetTileTrackStatus(v->tile, TRANSPORT_WATER, 0, entry)); - Trackdir best = (Trackdir)FindFirstBit2x64(rtds); + Trackdir best = (Trackdir)FindFirstBit(rtds); rtds = KillFirstBit(rtds); if (rtds == TRACKDIR_BIT_NONE) return false; /* At most one choice. */ for (; rtds != TRACKDIR_BIT_NONE; rtds = KillFirstBit(rtds)) { - Trackdir td = (Trackdir)FindFirstBit2x64(rtds); + Trackdir td = (Trackdir)FindFirstBit(rtds); ftd = NPFRouteToStationOrTileTwoWay(v->tile, best, false, v->tile, td, false, &fstd, &user); if (ftd.best_bird_dist == 0 && NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) best = td; } diff --git a/src/pathfinder/yapf/yapf_base.hpp b/src/pathfinder/yapf/yapf_base.hpp --- a/src/pathfinder/yapf/yapf_base.hpp +++ b/src/pathfinder/yapf/yapf_base.hpp @@ -192,7 +192,7 @@ public: { bool is_choice = (KillFirstBit(tf.m_new_td_bits) != TRACKDIR_BIT_NONE); for (TrackdirBits rtds = tf.m_new_td_bits; rtds != TRACKDIR_BIT_NONE; rtds = KillFirstBit(rtds)) { - Trackdir td = (Trackdir)FindFirstBit2x64(rtds); + Trackdir td = (Trackdir)FindFirstBit(rtds); Node &n = Yapf().CreateNewNode(); n.Set(parent, tf.m_new_tile, td, is_choice); Yapf().AddNewNode(n, tf); diff --git a/src/pathfinder/yapf/yapf_common.hpp b/src/pathfinder/yapf/yapf_common.hpp --- a/src/pathfinder/yapf/yapf_common.hpp +++ b/src/pathfinder/yapf/yapf_common.hpp @@ -42,7 +42,7 @@ public: { bool is_choice = (KillFirstBit(m_orgTrackdirs) != TRACKDIR_BIT_NONE); for (TrackdirBits tdb = m_orgTrackdirs; tdb != TRACKDIR_BIT_NONE; tdb = KillFirstBit(tdb)) { - Trackdir td = (Trackdir)FindFirstBit2x64(tdb); + Trackdir td = (Trackdir)FindFirstBit(tdb); Node &n1 = Yapf().CreateNewNode(); n1.Set(nullptr, m_orgTile, td, is_choice); Yapf().AddStartupNode(n1); diff --git a/src/pathfinder/yapf/yapf_costrail.hpp b/src/pathfinder/yapf/yapf_costrail.hpp --- a/src/pathfinder/yapf/yapf_costrail.hpp +++ b/src/pathfinder/yapf/yapf_costrail.hpp @@ -504,7 +504,7 @@ no_entry_cost: // jump here at the begin } /* Gather the next tile/trackdir/tile_type/rail_type. */ - TILE next(tf_local.m_new_tile, (Trackdir)FindFirstBit2x64(tf_local.m_new_td_bits)); + TILE next(tf_local.m_new_tile, (Trackdir)FindFirstBit(tf_local.m_new_td_bits)); if (TrackFollower::DoTrackMasking() && IsTileType(next.tile, MP_RAILWAY)) { if (HasSignalOnTrackdir(next.tile, next.td) && IsPbsSignal(GetSignalType(next.tile, TrackdirToTrack(next.td)))) { diff --git a/src/pathfinder/yapf/yapf_road.cpp b/src/pathfinder/yapf/yapf_road.cpp --- a/src/pathfinder/yapf/yapf_road.cpp +++ b/src/pathfinder/yapf/yapf_road.cpp @@ -145,7 +145,7 @@ public: /* if there are more trackdirs available & reachable, we are at the end of segment */ if (KillFirstBit(F.m_new_td_bits) != TRACKDIR_BIT_NONE) break; - Trackdir new_td = (Trackdir)FindFirstBit2x64(F.m_new_td_bits); + Trackdir new_td = (Trackdir)FindFirstBit(F.m_new_td_bits); /* stop if RV is on simple loop with no junctions */ if (F.m_new_tile == n.m_key.m_tile && new_td == n.m_key.m_td) return false; @@ -535,7 +535,7 @@ Trackdir YapfRoadVehicleChooseTrack(cons } Trackdir td_ret = pfnChooseRoadTrack(v, tile, enterdir, path_found, path_cache); - return (td_ret != INVALID_TRACKDIR) ? td_ret : (Trackdir)FindFirstBit2x64(trackdirs); + return (td_ret != INVALID_TRACKDIR) ? td_ret : (Trackdir)FindFirstBit(trackdirs); } FindDepotData YapfRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_distance) diff --git a/src/pathfinder/yapf/yapf_ship.cpp b/src/pathfinder/yapf/yapf_ship.cpp --- a/src/pathfinder/yapf/yapf_ship.cpp +++ b/src/pathfinder/yapf/yapf_ship.cpp @@ -206,7 +206,7 @@ public: /* use vehicle's current direction if that's possible, otherwise use first usable one. */ Trackdir veh_dir = v->GetVehicleTrackdir(); - return (HasTrackdir(trackdirs, veh_dir)) ? veh_dir : (Trackdir)FindFirstBit2x64(trackdirs); + return (HasTrackdir(trackdirs, veh_dir)) ? veh_dir : (Trackdir)FindFirstBit(trackdirs); } /* Move back to the old tile/trackdir (where ship is coming from). */ diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -960,7 +960,7 @@ static Trackdir RoadFindPathToDest(RoadV /* Vehicle expected a choice here, invalidate its path. */ v->path.clear(); } - return_track(FindFirstBit2x64(trackdirs)); + return_track(FindFirstBit(trackdirs)); } /* Attempt to follow cached path. */ diff --git a/src/spritecache.cpp b/src/spritecache.cpp --- a/src/spritecache.cpp +++ b/src/spritecache.cpp @@ -374,7 +374,7 @@ static bool PadSprites(SpriteLoader::Spr static bool ResizeSprites(SpriteLoader::SpriteCollection &sprite, uint8_t sprite_avail, SpriteEncoder *encoder) { /* Create a fully zoomed image if it does not exist */ - ZoomLevel first_avail = static_cast(FIND_FIRST_BIT(sprite_avail)); + ZoomLevel first_avail = static_cast(FindFirstBit(sprite_avail)); if (first_avail != ZOOM_LVL_NORMAL) { if (!ResizeSpriteIn(sprite, first_avail, ZOOM_LVL_NORMAL)) return false; SetBit(sprite_avail, ZOOM_LVL_NORMAL); diff --git a/src/track_func.h b/src/track_func.h --- a/src/track_func.h +++ b/src/track_func.h @@ -132,7 +132,7 @@ inline Track RemoveFirstTrack(TrackBits { if (*tracks != TRACK_BIT_NONE && *tracks != INVALID_TRACK_BIT) { assert((*tracks & ~TRACK_BIT_MASK) == TRACK_BIT_NONE); - Track first = (Track)FIND_FIRST_BIT(*tracks); + Track first = (Track)FindFirstBit(*tracks); ClrBit(*tracks, first); return first; } @@ -157,7 +157,7 @@ inline Trackdir RemoveFirstTrackdir(Trac { if (*trackdirs != TRACKDIR_BIT_NONE && *trackdirs != INVALID_TRACKDIR_BIT) { assert((*trackdirs & ~TRACKDIR_BIT_MASK) == TRACKDIR_BIT_NONE); - Trackdir first = (Trackdir)FindFirstBit2x64(*trackdirs); + Trackdir first = (Trackdir)FindFirstBit(*trackdirs); ClrBit(*trackdirs, first); return first; } @@ -176,7 +176,7 @@ inline Trackdir RemoveFirstTrackdir(Trac */ inline Track FindFirstTrack(TrackBits tracks) { - return (tracks != TRACK_BIT_NONE && tracks != INVALID_TRACK_BIT) ? (Track)FIND_FIRST_BIT(tracks) : INVALID_TRACK; + return (tracks != TRACK_BIT_NONE && tracks != INVALID_TRACK_BIT) ? (Track)FindFirstBit(tracks) : INVALID_TRACK; } /** @@ -193,7 +193,7 @@ inline Track FindFirstTrack(TrackBits tr inline Track TrackBitsToTrack(TrackBits tracks) { assert(tracks == INVALID_TRACK_BIT || (tracks != TRACK_BIT_NONE && KillFirstBit(tracks & TRACK_BIT_MASK) == TRACK_BIT_NONE)); - return tracks != INVALID_TRACK_BIT ? (Track)FIND_FIRST_BIT(tracks & TRACK_BIT_MASK) : INVALID_TRACK; + return tracks != INVALID_TRACK_BIT ? (Track)FindFirstBit(tracks & TRACK_BIT_MASK) : INVALID_TRACK; } /** @@ -211,7 +211,7 @@ inline Track TrackBitsToTrack(TrackBits inline Trackdir FindFirstTrackdir(TrackdirBits trackdirs) { assert((trackdirs & ~TRACKDIR_BIT_MASK) == TRACKDIR_BIT_NONE); - return (trackdirs != TRACKDIR_BIT_NONE) ? (Trackdir)FindFirstBit2x64(trackdirs) : INVALID_TRACKDIR; + return (trackdirs != TRACKDIR_BIT_NONE) ? (Trackdir)FindFirstBit(trackdirs) : INVALID_TRACKDIR; } /* diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -3428,7 +3428,7 @@ bool TrainController(Train *v, Vehicle * chosen_track == TRACK_BIT_LEFT || chosen_track == TRACK_BIT_RIGHT); /* Update XY to reflect the entrance to the new tile, and select the direction to use */ - const byte *b = _initial_tile_subcoord[FIND_FIRST_BIT(chosen_track)][enterdir]; + const byte *b = _initial_tile_subcoord[FindFirstBit(chosen_track)][enterdir]; gp.x = (gp.x & ~0xF) | b[0]; gp.y = (gp.y & ~0xF) | b[1]; Direction chosen_dir = (Direction)b[2];