Fixed #8468. Added 64 bit prime values.

This commit is contained in:
Ion Gaztañaga
2014-03-18 17:06:38 +01:00
parent bd9f607af4
commit 6c623e8d16
5 changed files with 100 additions and 13 deletions

View File

@@ -3795,10 +3795,13 @@ to be inserted in intrusive containers are allocated using `std::vector` or `std
extra parameter is `splaytree_algorithms` functions.
* Fixed bugs:
* [@https://svn.boost.org/trac/boost/ticket/8468 #8468: Compile error on visual studio 2010/2012 using vector with custom allocator and aligned types]
* [@https://svn.boost.org/trac/boost/ticket/9332 #9332: ['"has_member_function_callable_with.hpp compile error on msvc-12.0"]].
* Optimized tree rebalancing code to avoid redundant assignments.
* Added 64 bit prime values for `suggested_upper_bucket_count`/`suggested_lower_bucket_count` in 64 bit platforms.
[endsect]
[section:release_notes_boost_1_55_00 Boost 1.55 Release]

View File

@@ -24,6 +24,7 @@
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/trivial_value_traits.hpp>
#include <cstddef>
#include <climits>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/pointer_cast.hpp>
#include <boost/move/core.hpp>
@@ -40,15 +41,59 @@ struct prime_list_holder
static const std::size_t prime_list_size;
};
//We only support LLP64(Win64) or LP64(most Unix) data models
#ifdef _WIN64 //In 64 bit windows sizeof(size_t) == sizeof(unsigned long long)
#define BOOST_INTRUSIVE_PRIME_C(NUMBER) NUMBER##ULL
#define BOOST_INTRUSIVE_64_BIT_SIZE_T 1
#else //In 32 bit windows and 32/64 bit unixes sizeof(size_t) == sizeof(unsigned long)
#define BOOST_INTRUSIVE_PRIME_C(NUMBER) NUMBER##UL
#define BOOST_INTRUSIVE_64_BIT_SIZE_T (((((ULONG_MAX>>16)>>16)>>16)>>15) != 0)
#endif
template<int Dummy>
const std::size_t prime_list_holder<Dummy>::prime_list[] = {
3ul, 7ul, 11ul, 17ul, 29ul,
53ul, 97ul, 193ul, 389ul, 769ul,
1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
1610612741ul, 3221225473ul, 4294967291ul };
BOOST_INTRUSIVE_PRIME_C(3), BOOST_INTRUSIVE_PRIME_C(7),
BOOST_INTRUSIVE_PRIME_C(11), BOOST_INTRUSIVE_PRIME_C(17),
BOOST_INTRUSIVE_PRIME_C(29), BOOST_INTRUSIVE_PRIME_C(53),
BOOST_INTRUSIVE_PRIME_C(97), BOOST_INTRUSIVE_PRIME_C(193),
BOOST_INTRUSIVE_PRIME_C(389), BOOST_INTRUSIVE_PRIME_C(769),
BOOST_INTRUSIVE_PRIME_C(1543), BOOST_INTRUSIVE_PRIME_C(3079),
BOOST_INTRUSIVE_PRIME_C(6151), BOOST_INTRUSIVE_PRIME_C(12289),
BOOST_INTRUSIVE_PRIME_C(24593), BOOST_INTRUSIVE_PRIME_C(49157),
BOOST_INTRUSIVE_PRIME_C(98317), BOOST_INTRUSIVE_PRIME_C(196613),
BOOST_INTRUSIVE_PRIME_C(393241), BOOST_INTRUSIVE_PRIME_C(786433),
BOOST_INTRUSIVE_PRIME_C(1572869), BOOST_INTRUSIVE_PRIME_C(3145739),
BOOST_INTRUSIVE_PRIME_C(6291469), BOOST_INTRUSIVE_PRIME_C(12582917),
BOOST_INTRUSIVE_PRIME_C(25165843), BOOST_INTRUSIVE_PRIME_C(50331653),
BOOST_INTRUSIVE_PRIME_C(100663319), BOOST_INTRUSIVE_PRIME_C(201326611),
BOOST_INTRUSIVE_PRIME_C(402653189), BOOST_INTRUSIVE_PRIME_C(805306457),
BOOST_INTRUSIVE_PRIME_C(1610612741), BOOST_INTRUSIVE_PRIME_C(3221225473),
#if BOOST_INTRUSIVE_64_BIT_SIZE_T
//Taken from Boost.MultiIndex code, thanks to Joaquin M Lopez Munoz.
BOOST_INTRUSIVE_PRIME_C(6442450939), BOOST_INTRUSIVE_PRIME_C(12884901893),
BOOST_INTRUSIVE_PRIME_C(25769803751), BOOST_INTRUSIVE_PRIME_C(51539607551),
BOOST_INTRUSIVE_PRIME_C(103079215111), BOOST_INTRUSIVE_PRIME_C(206158430209),
BOOST_INTRUSIVE_PRIME_C(412316860441), BOOST_INTRUSIVE_PRIME_C(824633720831),
BOOST_INTRUSIVE_PRIME_C(1649267441651), BOOST_INTRUSIVE_PRIME_C(3298534883309),
BOOST_INTRUSIVE_PRIME_C(6597069766657), BOOST_INTRUSIVE_PRIME_C(13194139533299),
BOOST_INTRUSIVE_PRIME_C(26388279066623), BOOST_INTRUSIVE_PRIME_C(52776558133303),
BOOST_INTRUSIVE_PRIME_C(105553116266489), BOOST_INTRUSIVE_PRIME_C(211106232532969),
BOOST_INTRUSIVE_PRIME_C(422212465066001), BOOST_INTRUSIVE_PRIME_C(844424930131963),
BOOST_INTRUSIVE_PRIME_C(1688849860263953), BOOST_INTRUSIVE_PRIME_C(3377699720527861),
BOOST_INTRUSIVE_PRIME_C(6755399441055731), BOOST_INTRUSIVE_PRIME_C(13510798882111483),
BOOST_INTRUSIVE_PRIME_C(27021597764222939), BOOST_INTRUSIVE_PRIME_C(54043195528445957),
BOOST_INTRUSIVE_PRIME_C(108086391056891903), BOOST_INTRUSIVE_PRIME_C(216172782113783843),
BOOST_INTRUSIVE_PRIME_C(432345564227567621), BOOST_INTRUSIVE_PRIME_C(864691128455135207),
BOOST_INTRUSIVE_PRIME_C(1729382256910270481), BOOST_INTRUSIVE_PRIME_C(3458764513820540933),
BOOST_INTRUSIVE_PRIME_C(6917529027641081903), BOOST_INTRUSIVE_PRIME_C(13835058055282163729),
BOOST_INTRUSIVE_PRIME_C(18446744073709551557)
#else
BOOST_INTRUSIVE_PRIME_C(4294967291)
#endif
};
#undef BOOST_INTRUSIVE_PRIME_C
#undef BOOST_INTRUSIVE_64_BIT_SIZE_T
template<int Dummy>
const std::size_t prime_list_holder<Dummy>::prime_list_size

View File

@@ -64,18 +64,32 @@ struct apply
typedef typename F::template apply<Param>::type type;
};
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
template <class T, class U>
struct is_convertible
{
static const bool value = __is_convertible_to(T, U);
};
#else
template <class T, class U>
class is_convertible
{
typedef char true_t;
class false_t { char dummy[2]; };
static true_t dispatch(U);
//use any_conversion as first parameter since in MSVC
//overaligned types can't go through ellipsis
static false_t dispatch(...);
static const T &trigger();
static true_t dispatch(U);
static T &trigger();
public:
static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
};
#endif
template<
bool C
, typename T1

View File

@@ -2585,8 +2585,7 @@ class hashtable_impl
const std::size_t *primes = &detail::prime_list_holder<0>::prime_list[0];
const std::size_t *primes_end = primes + detail::prime_list_holder<0>::prime_list_size;
std::size_t const* bound = std::lower_bound(primes, primes_end, n);
if(bound == primes_end)
--bound;
bound -= (bound == primes_end);
return size_type(*bound);
}
@@ -2604,8 +2603,7 @@ class hashtable_impl
const std::size_t *primes = &detail::prime_list_holder<0>::prime_list[0];
const std::size_t *primes_end = primes + detail::prime_list_holder<0>::prime_list_size;
size_type const* bound = std::upper_bound(primes, primes_end, n);
if(bound != primes)
--bound;
bound -= (bound != primes);
return size_type(*bound);
}

View File

@@ -193,6 +193,33 @@ void test_common_unordered_and_associative_container(Container & c, Data & d, bo
c.clear();
BOOST_TEST( c.equal_range(*da, c.hash_function(), c.key_eq()).first == c.end() );
//
//suggested_upper_bucket_count
//
//Maximum fallbacks to the highest possible value
typename Container::size_type sz = Container::suggested_upper_bucket_count(size_type(-1));
BOOST_TEST( sz > size_type(-1)/2 );
//In the rest of cases the upper bound is returned
sz = Container::suggested_upper_bucket_count(size_type(-1)/2);
BOOST_TEST( sz >= size_type(-1)/2 );
sz = Container::suggested_upper_bucket_count(size_type(-1)/4);
BOOST_TEST( sz >= size_type(-1)/4 );
sz = Container::suggested_upper_bucket_count(0);
BOOST_TEST( sz > 0 );
//
//suggested_lower_bucket_count
//
sz = Container::suggested_lower_bucket_count(size_type(-1));
BOOST_TEST( sz <= size_type(-1) );
//In the rest of cases the lower bound is returned
sz = Container::suggested_lower_bucket_count(size_type(-1)/2);
BOOST_TEST( sz <= size_type(-1)/2 );
sz = Container::suggested_lower_bucket_count(size_type(-1)/4);
BOOST_TEST( sz <= size_type(-1)/4 );
//Minimum fallbacks to the lowest possible value
sz = Container::suggested_upper_bucket_count(0);
BOOST_TEST( sz > 0 );
}
template< class Container, class Data >