diff --git a/include/boost/unordered/detail/foa.hpp b/include/boost/unordered/detail/foa.hpp index 41a1f153..ebeed0f7 100644 --- a/include/boost/unordered/detail/foa.hpp +++ b/include/boost/unordered/detail/foa.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -269,20 +270,12 @@ private: 0xF8F8F8F8u,0xF9F9F9F9u,0xFAFAFAFAu,0xFBFBFBFBu,0xFCFCFCFCu,0xFDFDFDFDu,0xFEFEFEFEu,0xFFFFFFFFu, }; -#if defined(__MSVC_RUNTIME_CHECKS) - return (int)word[hash&0xffu]; -#else - return (int)word[(unsigned char)hash]; -#endif + return (int)word[narrow_cast(hash)]; } inline static unsigned char reduced_hash(std::size_t hash) { -#if defined(__MSVC_RUNTIME_CHECKS) - return match_word(hash)&0xffu; -#else - return (unsigned char)match_word(hash); -#endif + return narrow_cast(match_word(hash)); } inline unsigned char& at(std::size_t pos) @@ -533,11 +526,7 @@ struct group15 std::size_t pos=reinterpret_cast(pc)%sizeof(group15); group15 *pg=reinterpret_cast(pc-pos); boost::uint64_t x=((pg->m[0])>>pos)&0x000100010001ull; -#if defined(__MSVC_RUNTIME_CHECKS) - boost::uint32_t y=(x|(x>>15)|(x>>30))&0xffffffffu; -#else - boost::uint32_t y=static_cast(x|(x>>15)|(x>>30)); -#endif + boost::uint32_t y=narrow_cast(x|(x>>15)|(x>>30)); return !pg->is_not_overflowed(y); }; @@ -552,11 +541,7 @@ struct group15 inline int match_occupied()const { boost::uint64_t x=m[0]|m[1]; -#if defined(__MSVC_RUNTIME_CHECKS) - boost::uint32_t y=(x|(x>>32))&0xffffffffu; -#else - boost::uint32_t y=static_cast(x|(x>>32)); -#endif + boost::uint32_t y=narrow_cast(x|(x>>32)); y|=y>>16; return y&0x7FFF; } @@ -591,11 +576,7 @@ private: 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, }; -#if defined(__MSVC_RUNTIME_CHECKS) - return table[hash&0xffu]; -#else - return table[(unsigned char)hash]; -#endif + return table[narrow_cast(hash)]; } inline void set_impl(std::size_t pos,std::size_t n) diff --git a/include/boost/unordered/detail/narrow_cast.hpp b/include/boost/unordered/detail/narrow_cast.hpp new file mode 100644 index 00000000..da89f67f --- /dev/null +++ b/include/boost/unordered/detail/narrow_cast.hpp @@ -0,0 +1,44 @@ +/* Copyright 2022 Joaquin M Lopez Munoz. + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * See https://www.boost.org/libs/unordered for library home page. + */ + +#ifndef BOOST_UNORDERED_DETAIL_NARROW_CAST_HPP +#define BOOST_UNORDERED_DETAIL_NARROW_CAST_HPP + +#include +#include +#include +#include + +namespace boost{ +namespace unordered{ +namespace detail{ + +template +BOOST_CONSTEXPR To narrow_cast(From x) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT(boost::is_integral::value); + BOOST_STATIC_ASSERT(boost::is_integral::value); + BOOST_STATIC_ASSERT(sizeof(From)>=sizeof(To)); + + return static_cast( + x + +#if defined(__MSVC_RUNTIME_CHECKS) + /* Avoids VS's "Run-Time Check Failure #1 - A cast to a smaller data type + * has caused a loss of data." + */ + &static_cast::type>(~static_cast(0)) +#endif + ); +} + +} /* namespace detail */ +} /* namespace unordered */ +} /* namespace boost */ + +#endif diff --git a/include/boost/unordered/detail/prime_fmod.hpp b/include/boost/unordered/detail/prime_fmod.hpp index 4c538487..fab8f94e 100644 --- a/include/boost/unordered/detail/prime_fmod.hpp +++ b/include/boost/unordered/detail/prime_fmod.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -117,15 +118,9 @@ namespace boost { #if defined(BOOST_UNORDERED_FCA_HAS_64B_SIZE_T) std::size_t sizes_under_32bit = inv_sizes32_len; if (BOOST_LIKELY(size_index < sizes_under_32bit)) { -#if defined(__MSVC_RUNTIME_CHECKS) return fast_modulo( - boost::uint32_t(hash & 0xffffffffu) + boost::uint32_t(hash >> 32), + narrow_cast(hash) + narrow_cast(hash >> 32), inv_sizes32[size_index], boost::uint32_t(sizes[size_index])); -#else - return fast_modulo( - boost::uint32_t(hash) + boost::uint32_t(hash >> 32), - inv_sizes32[size_index], boost::uint32_t(sizes[size_index])); -#endif } else { return positions[size_index - sizes_under_32bit](hash); }