From 36a5b82a339293066bc0eb4042bb55f239496dbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Sun, 9 Feb 2014 23:19:09 +0100 Subject: [PATCH] Fixed bug in 64 bit GCC implementations in floor_log2 and __builtin_clz dispatching --- include/boost/intrusive/bstree_algorithms.hpp | 3 +- include/boost/intrusive/detail/utilities.hpp | 35 ++++++++++++++----- 2 files changed, 28 insertions(+), 10 deletions(-) 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 ////////////////////////////