diff --git a/include/boost/intrusive/bstree_algorithms.hpp b/include/boost/intrusive/bstree_algorithms.hpp index 0a7cef0..d155d6d 100644 --- a/include/boost/intrusive/bstree_algorithms.hpp +++ b/include/boost/intrusive/bstree_algorithms.hpp @@ -1831,7 +1831,8 @@ class bstree_algorithms 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 std::size_t vine_nodes = count - leaf_nodes; while(vine_nodes > 1){ diff --git a/include/boost/intrusive/detail/utilities.hpp b/include/boost/intrusive/detail/utilities.hpp index 6b4ef26..31bb6e2 100644 --- a/include/boost/intrusive/detail/utilities.hpp +++ b/include/boost/intrusive/detail/utilities.hpp @@ -416,21 +416,38 @@ void destructor_impl(Hook &, detail::link_dispatch) #elif defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) //GCC >=3.4 - #if SIZE_MAX > UINT_MAX - #define BOOST_INTRUSIVE_CLZ_INTRINSIC __builtin_clzll - #elif SIZE_MAX > UINT_MAX - #define BOOST_INTRUSIVE_CLZ_INTRINSIC __builtin_clzl - #else - #define BOOST_INTRUSIVE_CLZ_INTRINSIC __builtin_clz + //Compile-time error in case of missing specialization + template + struct builtin_clz_dispatch; + + #if defined(BOOST_HAS_LONG_LONG) + template<> + struct builtin_clz_dispatch + { + static const unsigned long long call(unsigned long long n) + { return __builtin_clzll(n); } + }; #endif + template<> + struct builtin_clz_dispatch + { + static const unsigned long call(unsigned long n) + { return __builtin_clzl(n); } + }; + + template<> + struct builtin_clz_dispatch + { + static const unsigned int call(unsigned int n) + { return __builtin_clz(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::call(n); } - #undef BOOST_INTRUSIVE_CLZ_INTRINSIC - #else //Portable methods ////////////////////////////