First
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
#pragma once
|
||||
|
||||
#include "tl/detail/prologue.h"
|
||||
#include "tl/functional.h"
|
||||
|
||||
namespace tl
|
||||
{
|
||||
namespace algorithm
|
||||
{
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Count the number of bit set for the given value.
|
||||
*/
|
||||
inline uint8_t bits_count(uint32_t i_value) noexcept
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
return uint8_t(__popcnt(i_value));
|
||||
#elif defined(__clang__) || defined(__GNUC__)
|
||||
return uint8_t(__builtin_popcount(i_value));
|
||||
#else
|
||||
static_assert(!std::is_same_v<T, T>, "no-builtin function found for this compiler");
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Count the number of bit set for the given value.
|
||||
*/
|
||||
inline uint64_t bits_count(uint64_t i_value) noexcept
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(TL_PLATFORM_64)
|
||||
return uint8_t(__popcnt64(i_value));
|
||||
#elif defined(TL_PLATFORM_32)
|
||||
return bits_count(uint32_t(i_value >> 32)) + bits_count(uint32_t(i_value & 0xffffffff));
|
||||
#else
|
||||
static_assert(!std::is_same_v<T, T>, "no-builtin function found for this compiler);");
|
||||
#endif // TL_PLATFORM_XX
|
||||
#elif defined(__clang__) || defined(__GNUC__)
|
||||
return uint8_t(__builtin_popcountl(i_value));
|
||||
#else
|
||||
static_assert(!std::is_same_v<T, T>, "no-builtin function found for this compiler");
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Position of the top bit set to 1.
|
||||
* @param the given value
|
||||
* @return -1 in case value is 0 otherwise the position.
|
||||
*/
|
||||
inline int8_t top_bit(uint32_t i_value) noexcept
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
unsigned long index = 0;
|
||||
return _BitScanReverse(&index, (unsigned long)i_value) ? uint8_t(index) : -1;
|
||||
#elif defined(__clang__) || defined(__GNUC__)
|
||||
return i_value ? 31u - __builtin_clzl(i_value) : -1;
|
||||
#else
|
||||
static_assert(!std::is_same_v<T, T>, "no-builtin function found for this compiler);");
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Position of the top bit set to 1.
|
||||
* @param the given value
|
||||
* @return -1 in case value is 0 otherwise the position.
|
||||
*/
|
||||
inline int8_t top_bit(uint64_t i_value) noexcept
|
||||
{
|
||||
#if defined(_MSC_VER)
|
||||
unsigned long index = 0;
|
||||
#if defined(TL_PLATFORM_64)
|
||||
return _BitScanReverse64(&index, (unsigned long long)i_value) ? uint8_t(index) : -1;
|
||||
#elif defined(TL_PLATFORM_32)
|
||||
const int8_t position = top_bit(uint32_t(i_value >> 32));
|
||||
if (position > -1)
|
||||
{
|
||||
return position + 32;
|
||||
}
|
||||
|
||||
return top_bit(uint32_t(i_value & 0xffffffff));
|
||||
#else
|
||||
static_assert(!std::is_same_v<T, T>, "no-builtin function found for this compiler);");
|
||||
#endif // TL_PLATFORM_XX
|
||||
#elif defined(__clang__) || defined(__GNUC__)
|
||||
return i_value ? 63u - __builtin_clzll(i_value) : -1;
|
||||
#else
|
||||
static_assert(!std::is_same_v<T, T>, "no-builtin function found for this compiler);");
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace algorithm
|
||||
} // namespace tl
|
||||
Reference in New Issue
Block a user