Fixed bug in 64 bit GCC implementations in floor_log2 and __builtin_clz dispatching

This commit is contained in:
Ion Gaztañaga
2014-02-09 23:19:09 +01:00
parent 5f368fe09f
commit 36a5b82a33
2 changed files with 28 additions and 10 deletions

View File

@@ -1831,7 +1831,8 @@ class bstree_algorithms
static void vine_to_subtree(const node_ptr & super_root, std::size_t count) static void vine_to_subtree(const node_ptr & super_root, std::size_t count)
{ {
std::size_t leaf_nodes = count + 1 - ((std::size_t) 1 << detail::floor_log2(count + 1)); const std::size_t one_szt = 1u;
std::size_t leaf_nodes = count + one_szt - std::size_t(one_szt << detail::floor_log2(count + one_szt));
compress_subtree(super_root, leaf_nodes); //create deepest leaves compress_subtree(super_root, leaf_nodes); //create deepest leaves
std::size_t vine_nodes = count - leaf_nodes; std::size_t vine_nodes = count - leaf_nodes;
while(vine_nodes > 1){ while(vine_nodes > 1){

View File

@@ -416,21 +416,38 @@ void destructor_impl(Hook &, detail::link_dispatch<normal_link>)
#elif defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) //GCC >=3.4 #elif defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) //GCC >=3.4
#if SIZE_MAX > UINT_MAX //Compile-time error in case of missing specialization
#define BOOST_INTRUSIVE_CLZ_INTRINSIC __builtin_clzll template<class Uint>
#elif SIZE_MAX > UINT_MAX struct builtin_clz_dispatch;
#define BOOST_INTRUSIVE_CLZ_INTRINSIC __builtin_clzl
#else #if defined(BOOST_HAS_LONG_LONG)
#define BOOST_INTRUSIVE_CLZ_INTRINSIC __builtin_clz template<>
struct builtin_clz_dispatch<unsigned long long>
{
static const unsigned long long call(unsigned long long n)
{ return __builtin_clzll(n); }
};
#endif #endif
template<>
struct builtin_clz_dispatch<unsigned long>
{
static const unsigned long call(unsigned long n)
{ return __builtin_clzl(n); }
};
template<>
struct builtin_clz_dispatch<unsigned int>
{
static const unsigned int call(unsigned int n)
{ return __builtin_clz(n); }
};
inline std::size_t floor_log2(std::size_t n) inline std::size_t floor_log2(std::size_t n)
{ {
return sizeof(std::size_t)*CHAR_BIT - 1 - BOOST_INTRUSIVE_CLZ_INTRINSIC(n); return sizeof(std::size_t)*CHAR_BIT - std::size_t(1) - builtin_clz_dispatch<std::size_t>::call(n);
} }
#undef BOOST_INTRUSIVE_CLZ_INTRINSIC
#else //Portable methods #else //Portable methods
//////////////////////////// ////////////////////////////