This commit is contained in:
jeanlemotan
2024-07-02 18:06:33 +02:00
commit 8297b0b45f
157 changed files with 24865 additions and 0 deletions
+102
View File
@@ -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