added narrow_cast

This commit is contained in:
joaquintides
2022-12-05 11:50:18 +01:00
committed by Christian Mazakas
parent 8b14b7cddc
commit f0037d336d
3 changed files with 52 additions and 32 deletions

View File

@ -23,6 +23,7 @@
#include <boost/predef.h>
#include <boost/type_traits/has_trivial_copy.hpp>
#include <boost/type_traits/is_nothrow_swappable.hpp>
#include <boost/unordered/detail/narrow_cast.hpp>
#include <boost/unordered/detail/xmx.hpp>
#include <boost/unordered/hash_traits.hpp>
#include <climits>
@ -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<unsigned char>(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<unsigned char>(match_word(hash));
}
inline unsigned char& at(std::size_t pos)
@ -533,11 +526,7 @@ struct group15
std::size_t pos=reinterpret_cast<uintptr_t>(pc)%sizeof(group15);
group15 *pg=reinterpret_cast<group15*>(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<boost::uint32_t>(x|(x>>15)|(x>>30));
#endif
boost::uint32_t y=narrow_cast<boost::uint32_t>(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<boost::uint32_t>(x|(x>>32));
#endif
boost::uint32_t y=narrow_cast<boost::uint32_t>(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<unsigned char>(hash)];
}
inline void set_impl(std::size_t pos,std::size_t n)

View File

@ -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 <boost/config.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/make_unsigned.hpp>
namespace boost{
namespace unordered{
namespace detail{
template<typename To,typename From>
BOOST_CONSTEXPR To narrow_cast(From x) BOOST_NOEXCEPT
{
BOOST_STATIC_ASSERT(boost::is_integral<From>::value);
BOOST_STATIC_ASSERT(boost::is_integral<To>::value);
BOOST_STATIC_ASSERT(sizeof(From)>=sizeof(To));
return static_cast<To>(
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<typename boost::make_unsigned<To>::type>(~static_cast<To>(0))
#endif
);
}
} /* namespace detail */
} /* namespace unordered */
} /* namespace boost */
#endif

View File

@ -11,6 +11,7 @@
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/unordered/detail/narrow_cast.hpp>
#include <boost/config.hpp>
@ -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<boost::uint32_t>(hash) + narrow_cast<boost::uint32_t>(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);
}