mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 05:09:34 -06:00
Common: Use C++20 <bit> header in BitSet.h
This commit is contained in:
@ -2,89 +2,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <bit>
|
||||
#include <cstddef>
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <intrin.h>
|
||||
|
||||
namespace Common
|
||||
{
|
||||
template <typename T>
|
||||
constexpr int CountSetBits(T v)
|
||||
{
|
||||
// from https://graphics.stanford.edu/~seander/bithacks.html
|
||||
// GCC has this built in, but MSVC's intrinsic will only emit the actual
|
||||
// POPCNT instruction, which we're not depending on
|
||||
v = v - ((v >> 1) & (T) ~(T)0 / 3);
|
||||
v = (v & (T) ~(T)0 / 15 * 3) + ((v >> 2) & (T) ~(T)0 / 15 * 3);
|
||||
v = (v + (v >> 4)) & (T) ~(T)0 / 255 * 15;
|
||||
return (T)(v * ((T) ~(T)0 / 255)) >> (sizeof(T) - 1) * 8;
|
||||
}
|
||||
inline int LeastSignificantSetBit(u8 val)
|
||||
{
|
||||
unsigned long index;
|
||||
_BitScanForward(&index, val);
|
||||
return (int)index;
|
||||
}
|
||||
inline int LeastSignificantSetBit(u16 val)
|
||||
{
|
||||
unsigned long index;
|
||||
_BitScanForward(&index, val);
|
||||
return (int)index;
|
||||
}
|
||||
inline int LeastSignificantSetBit(u32 val)
|
||||
{
|
||||
unsigned long index;
|
||||
_BitScanForward(&index, val);
|
||||
return (int)index;
|
||||
}
|
||||
inline int LeastSignificantSetBit(u64 val)
|
||||
{
|
||||
unsigned long index;
|
||||
_BitScanForward64(&index, val);
|
||||
return (int)index;
|
||||
}
|
||||
#else
|
||||
namespace Common
|
||||
{
|
||||
constexpr int CountSetBits(u8 val)
|
||||
{
|
||||
return __builtin_popcount(val);
|
||||
}
|
||||
constexpr int CountSetBits(u16 val)
|
||||
{
|
||||
return __builtin_popcount(val);
|
||||
}
|
||||
constexpr int CountSetBits(u32 val)
|
||||
{
|
||||
return __builtin_popcount(val);
|
||||
}
|
||||
constexpr int CountSetBits(u64 val)
|
||||
{
|
||||
return __builtin_popcountll(val);
|
||||
}
|
||||
inline int LeastSignificantSetBit(u8 val)
|
||||
{
|
||||
return __builtin_ctz(val);
|
||||
}
|
||||
inline int LeastSignificantSetBit(u16 val)
|
||||
{
|
||||
return __builtin_ctz(val);
|
||||
}
|
||||
inline int LeastSignificantSetBit(u32 val)
|
||||
{
|
||||
return __builtin_ctz(val);
|
||||
}
|
||||
inline int LeastSignificantSetBit(u64 val)
|
||||
{
|
||||
return __builtin_ctzll(val);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Similar to std::bitset, this is a class which encapsulates a bitset, i.e.
|
||||
// using the set bits of an integer to represent a set of integers. Like that
|
||||
// class, it acts like an array of bools:
|
||||
@ -146,7 +72,7 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
int bit = LeastSignificantSetBit(m_val);
|
||||
int bit = std::countr_zero(m_val);
|
||||
m_val &= ~(1 << bit);
|
||||
m_bit = bit;
|
||||
}
|
||||
@ -203,7 +129,7 @@ public:
|
||||
// Dolphin's official builds do not currently assume POPCNT support on x86,
|
||||
// so slower explicit bit twiddling is generated. Still should generally
|
||||
// be faster than a loop.
|
||||
constexpr unsigned int Count() const { return CountSetBits(m_val); }
|
||||
constexpr unsigned int Count() const { return std::popcount(m_val); }
|
||||
constexpr Iterator begin() const { return ++Iterator(m_val, 0); }
|
||||
constexpr Iterator end() const { return Iterator(m_val, -1); }
|
||||
IntTy m_val;
|
||||
|
Reference in New Issue
Block a user