mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-30 03:17:15 +02:00
added Peter Dimov's portable implementation of get_remainder
This commit is contained in:
@ -150,8 +150,7 @@ namespace boost {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_INT64_T) && \
|
#if !defined(BOOST_NO_INT64_T)
|
||||||
(defined(BOOST_HAS_INT128) || (defined(_MSC_VER) && defined(_M_X64)))
|
|
||||||
#define BOOST_UNORDERED_FCA_FASTMOD_SUPPORT
|
#define BOOST_UNORDERED_FCA_FASTMOD_SUPPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -203,20 +202,23 @@ namespace boost {
|
|||||||
// modulo) exploiting how compilers transform division
|
// modulo) exploiting how compilers transform division
|
||||||
//
|
//
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
static inline uint64_t get_remainder(uint64_t fractional, uint32_t d)
|
static inline uint64_t get_remainder(uint64_t fractional, uint32_t d)
|
||||||
{
|
{
|
||||||
// use fancy msvc instrinsic when available instead of using `>> 64`
|
#if defined(_MSC_VER) && defined(_WIN64)
|
||||||
//
|
// use MSVC instrinsic when available to avoid promotion to 128 bits
|
||||||
|
|
||||||
return __umulh(fractional, d);
|
return __umulh(fractional, d);
|
||||||
}
|
#elif defined(BOOST_HAS_INT128)
|
||||||
|
return static_cast<uint64_t>(((boost::uint128_type)fractional * d) >> 64);
|
||||||
#else
|
#else
|
||||||
static inline uint64_t get_remainder(uint64_t fractional, uint32_t d)
|
// portable implementation in the absence of boost::uint128_type
|
||||||
{
|
|
||||||
__extension__ typedef unsigned __int128 uint128;
|
uint64_t r1 = (fractional & UINT32_MAX) * d;
|
||||||
return static_cast<uint64_t>(((uint128)fractional * d) >> 64);
|
uint64_t r2 = (fractional >> 32 ) * d;
|
||||||
}
|
r2 += r1 >> 32;
|
||||||
|
return r2 >> 32;
|
||||||
#endif /* defined(_MSC_VER) */
|
#endif /* defined(_MSC_VER) */
|
||||||
|
}
|
||||||
|
|
||||||
static inline uint32_t fast_modulo(uint32_t a, uint64_t M, uint32_t d)
|
static inline uint32_t fast_modulo(uint32_t a, uint64_t M, uint32_t d)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user