Core/Algorithm: Add BitCount function

This commit is contained in:
Lynix 2016-11-18 01:13:30 +01:00
parent 2ed65e60e1
commit 359b5e6c3a
4 changed files with 24 additions and 11 deletions

View File

@ -22,6 +22,7 @@ namespace Nz
template<typename F, typename Tuple> decltype(auto) Apply(F&& fn, Tuple&& t); template<typename F, typename Tuple> decltype(auto) Apply(F&& fn, Tuple&& t);
template<typename O, typename F, typename Tuple> decltype(auto) Apply(O& object, F&& fn, Tuple&& t); template<typename O, typename F, typename Tuple> decltype(auto) Apply(O& object, F&& fn, Tuple&& t);
template<typename T> constexpr std::size_t BitCount();
template<typename T> ByteArray ComputeHash(HashType hash, const T& v); template<typename T> ByteArray ComputeHash(HashType hash, const T& v);
template<typename T> ByteArray ComputeHash(AbstractHash* hash, const T& v); template<typename T> ByteArray ComputeHash(AbstractHash* hash, const T& v);
template<typename T, std::size_t N> constexpr std::size_t CountOf(T(&name)[N]) noexcept; template<typename T, std::size_t N> constexpr std::size_t CountOf(T(&name)[N]) noexcept;

View File

@ -11,6 +11,7 @@
#include <Nazara/Core/ByteArray.hpp> #include <Nazara/Core/ByteArray.hpp>
#include <Nazara/Core/Error.hpp> #include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Stream.hpp> #include <Nazara/Core/Stream.hpp>
#include <climits>
#include <Nazara/Core/Debug.hpp> #include <Nazara/Core/Debug.hpp>
namespace Nz namespace Nz
@ -70,6 +71,17 @@ namespace Nz
return Detail::ApplyImplMethod(object, std::forward<F>(fn), std::forward<Tuple>(t), std::make_index_sequence<tSize>()); return Detail::ApplyImplMethod(object, std::forward<F>(fn), std::forward<Tuple>(t), std::make_index_sequence<tSize>());
} }
/*!
* \ingroup core
* \brief Returns the number of bits occupied by the type T
* \return Number of bits occupied by the type
*/
template<typename T>
constexpr std::size_t BitCount()
{
return CHAR_BIT * sizeof(T);
}
/*! /*!
* \ingroup core * \ingroup core
* \brief Computes the hash of a hashable object * \brief Computes the hash of a hashable object

View File

@ -110,7 +110,7 @@ namespace Nz
Bitset& operator^=(const Bitset& bitset); Bitset& operator^=(const Bitset& bitset);
static constexpr Block fullBitMask = std::numeric_limits<Block>::max(); static constexpr Block fullBitMask = std::numeric_limits<Block>::max();
static constexpr std::size_t bitsPerBlock = std::numeric_limits<Block>::digits; static constexpr std::size_t bitsPerBlock = BitCount<Block>();
static constexpr std::size_t npos = std::numeric_limits<std::size_t>::max(); static constexpr std::size_t npos = std::numeric_limits<std::size_t>::max();
static Bitset FromPointer(const void* ptr, std::size_t bitCount, PointerSequence* sequence = nullptr); static Bitset FromPointer(const void* ptr, std::size_t bitCount, PointerSequence* sequence = nullptr);

View File

@ -6,7 +6,7 @@
#include <Nazara/Core/Error.hpp> #include <Nazara/Core/Error.hpp>
#include <Nazara/Math/Algorithm.hpp> #include <Nazara/Math/Algorithm.hpp>
#include <cstdlib> #include <cstdlib>
#include <limits> #include <Nazara/Core/Algorithm.hpp>
#include <utility> #include <utility>
#include <Nazara/Core/Debug.hpp> #include <Nazara/Core/Debug.hpp>
@ -122,13 +122,13 @@ namespace Nz
{ {
if (sizeof(T) <= sizeof(Block)) if (sizeof(T) <= sizeof(Block))
{ {
m_bitCount = std::numeric_limits<T>::digits; m_bitCount = BitCount<T>();
m_blocks.push_back(static_cast<Block>(value)); m_blocks.push_back(static_cast<Block>(value));
} }
else else
{ {
// Note: I was kinda tired when I wrote this, there's probably a much easier method than checking bits to write bits // Note: I was kinda tired when I wrote this, there's probably a much easier method than checking bits to write bits
for (std::size_t bitPos = 0; bitPos < std::numeric_limits<T>::digits; bitPos++) for (std::size_t bitPos = 0; bitPos < BitCount<T>(); bitPos++)
{ {
if (value & (T(1U) << bitPos)) if (value & (T(1U) << bitPos))
UnboundedSet(bitPos, true); UnboundedSet(bitPos, true);
@ -139,9 +139,9 @@ namespace Nz
/*! /*!
* \brief Appends bits to the bitset * \brief Appends bits to the bitset
* *
* This function expand the bitset with bits extracted from a numerical value * This function extends the bitset with bits extracted from an integer value
* *
* \param bits A numerical value from where bits will be extracted * \param bits An integer value from where bits will be extracted
* \param bitCount Number of bits to extract from the value * \param bitCount Number of bits to extract from the value
* *
* \remark This function does not require bitCount to be lower or equal to the number of bits of T, thus * \remark This function does not require bitCount to be lower or equal to the number of bits of T, thus
@ -172,8 +172,8 @@ namespace Nz
for (std::size_t block = 0; block < blockCount - 1; ++block) for (std::size_t block = 0; block < blockCount - 1; ++block)
{ {
m_blocks.push_back(static_cast<Block>(bits)); m_blocks.push_back(static_cast<Block>(bits));
bits >>= std::numeric_limits<Block>::digits; bits >>= BitCount<Block>();
bitCount -= std::numeric_limits<Block>::digits; bitCount -= BitCount<Block>();
} }
// For the last iteration, mask out the bits we don't want // For the last iteration, mask out the bits we don't want
@ -331,7 +331,7 @@ namespace Nz
/*! /*!
* \brief Read a byte sequence into a bitset * \brief Read a byte sequence into a bitset
* *
* This function expand the bitset with bits read from a byte sequence * This function extends the bitset with bits read from a byte sequence
* *
* \param ptr A pointer to the start of the byte sequence * \param ptr A pointer to the start of the byte sequence
* \param bitCount Number of bits to read from the byte sequence * \param bitCount Number of bits to read from the byte sequence
@ -352,7 +352,7 @@ namespace Nz
/*! /*!
* \brief Read a byte sequence into a bitset * \brief Read a byte sequence into a bitset
* *
* This function expand the bitset with bits read from a pointer sequence (made of a pointer and a bit index) * This function extends the bitset with bits read from a pointer sequence (made of a pointer and a bit index)
* *
* \param sequence A pointer sequence to the start of the byte sequence * \param sequence A pointer sequence to the start of the byte sequence
* \param bitCount Number of bits to read from the byte sequence * \param bitCount Number of bits to read from the byte sequence
@ -865,7 +865,7 @@ namespace Nz
{ {
static_assert(std::is_integral<T>() && std::is_unsigned<T>(), "T must be a unsigned integral type"); static_assert(std::is_integral<T>() && std::is_unsigned<T>(), "T must be a unsigned integral type");
NazaraAssert(m_bitCount <= std::numeric_limits<T>::digits, "Bit count cannot be greater than T bit count"); NazaraAssert(m_bitCount <= BitCount<T>(), "Bit count cannot be greater than T bit count");
T value = 0; T value = 0;
for (std::size_t i = 0; i < m_blocks.size(); ++i) for (std::size_t i = 0; i < m_blocks.size(); ++i)