summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorglx22 <glx@openttd.org>2021-06-13 04:18:21 +0200
committerLoïc Guilloux <glx22@users.noreply.github.com>2021-07-09 21:36:09 +0200
commit89ab8b79a51b4963da55dce195ea1ab520c73b50 (patch)
treef0ba92ca28e0a322ea277568ee3a75a276e3ae52 /src/core
parent5844027eb8588197d82fe896f027182621c4f923 (diff)
downloadopenttd-89ab8b79a51b4963da55dce195ea1ab520c73b50.tar.xz
Codechange: Remove FOR_EACH_SET_BIT
Diffstat (limited to 'src/core')
-rw-r--r--src/core/bitmath_func.hpp63
1 files changed, 49 insertions, 14 deletions
diff --git a/src/core/bitmath_func.hpp b/src/core/bitmath_func.hpp
index 4af46d343..917a247da 100644
--- a/src/core/bitmath_func.hpp
+++ b/src/core/bitmath_func.hpp
@@ -345,20 +345,55 @@ static inline T ROR(const T x, const uint8 n)
) \
if ((___FESBE_bits & 1) != 0)
-/**
- * Do an operation for each set set bit in a value.
- *
- * This macros is used to do an operation for each set
- * bit in a variable. The first parameter is a variable
- * that is used as the bit position counter.
- * The second parameter is an expression of the bits
- * we need to iterate over. This expression will be
- * evaluated once.
- *
- * @param bitpos_var The position counter variable.
- * @param bitset_value The value which we check for set bits.
- */
-#define FOR_EACH_SET_BIT(bitpos_var, bitset_value) FOR_EACH_SET_BIT_EX(uint, bitpos_var, uint, bitset_value)
+ /**
+ * Iterable ensemble of each set bit in a value.
+ * @tparam Tbitpos Type of the position variable.
+ * @tparam Tbitset Type of the bitset value.
+*/
+template <typename Tbitpos = uint, typename Tbitset = uint>
+struct SetBitIterator {
+ struct Iterator {
+ typedef Tbitpos value_type;
+ typedef value_type *pointer;
+ typedef value_type &reference;
+ typedef size_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ explicit Iterator(Tbitset bitset) : bitset(bitset), bitpos(static_cast<Tbitpos>(0))
+ {
+ this->Validate();
+ }
+
+ bool operator==(const Iterator &other) const
+ {
+ return this->bitset == other.bitset && (this->bitset == 0 || this->bitpos == other.bitpos);
+ }
+ bool operator!=(const Iterator &other) const { return !(*this == other); }
+ Tbitpos operator*() const { return this->bitpos; }
+ Iterator & operator++() { this->Next(); this->Validate(); return *this; }
+
+ private:
+ Tbitset bitset;
+ Tbitpos bitpos;
+ void Validate()
+ {
+ while (this->bitset != 0 && (this->bitset & 1) == 0) this->Next();
+ }
+ void Next()
+ {
+ this->bitset = static_cast<Tbitset>(this->bitset >> 1);
+ this->bitpos++;
+ }
+ };
+
+ SetBitIterator(Tbitset bitset) : bitset(bitset) {}
+ Iterator begin() { return Iterator(this->bitset); }
+ Iterator end() { return Iterator(static_cast<Tbitset>(0)); }
+ bool empty() { return this->begin() == this->end(); }
+
+private:
+ Tbitset bitset;
+};
#if defined(__APPLE__)
/* Make endian swapping use Apple's macros to increase speed