forked from boostorg/unordered
Merge in a few small changes to unordered.
Merged revisions 45277-45280 via svnmerge from https://svn.boost.org/svn/boost/branches/unordered/trunk ........ r45277 | danieljames | 2008-05-11 14:09:05 +0100 (Sun, 11 May 2008) | 2 lines Put the prime number list into a template so that they (hopefully) only get included once. ........ r45278 | danieljames | 2008-05-11 14:12:27 +0100 (Sun, 11 May 2008) | 2 lines Add a quick explanation for an odd looking constructor. ........ r45279 | danieljames | 2008-05-11 14:12:37 +0100 (Sun, 11 May 2008) | 2 lines No need to include the exception objects in helpers/strong.hpp. Now helpers on depend on the forwarding header from the objects. ........ r45280 | danieljames | 2008-05-11 14:14:31 +0100 (Sun, 11 May 2008) | 1 line Instead of comparing potentially dangling pointers in move_tests check if any objects have been constructed. ........ [SVN r45574]
This commit is contained in:
@@ -78,7 +78,13 @@ namespace boost {
|
||||
|
||||
// prime number list, accessor
|
||||
|
||||
static const std::size_t prime_list[] = {
|
||||
template<typename T> struct prime_list_template
|
||||
{
|
||||
static std::size_t const value[];
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
std::size_t const prime_list_template<T>::value[] = {
|
||||
53ul, 97ul, 193ul, 389ul, 769ul,
|
||||
1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
|
||||
49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
|
||||
@@ -86,12 +92,15 @@ namespace boost {
|
||||
50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
|
||||
1610612741ul, 3221225473ul, 4294967291ul };
|
||||
|
||||
typedef prime_list_template<std::size_t> prime_list;
|
||||
|
||||
// no throw
|
||||
inline std::size_t next_prime(std::size_t n) {
|
||||
std::size_t const* const prime_list_end = prime_list +
|
||||
sizeof(prime_list) / sizeof(*prime_list);
|
||||
std::size_t const* const prime_list_begin = prime_list::value;
|
||||
std::size_t const* const prime_list_end = prime_list_begin +
|
||||
sizeof(prime_list::value) / sizeof(*prime_list::value);
|
||||
std::size_t const* bound =
|
||||
std::lower_bound(prime_list,prime_list_end, n);
|
||||
std::lower_bound(prime_list_begin, prime_list_end, n);
|
||||
if(bound == prime_list_end)
|
||||
bound--;
|
||||
return *bound;
|
||||
@@ -99,11 +108,12 @@ namespace boost {
|
||||
|
||||
// no throw
|
||||
inline std::size_t prev_prime(std::size_t n) {
|
||||
std::size_t const* const prime_list_end = prime_list +
|
||||
sizeof(prime_list) / sizeof(*prime_list);
|
||||
std::size_t const* const prime_list_begin = prime_list::value;
|
||||
std::size_t const* const prime_list_end = prime_list_begin +
|
||||
sizeof(prime_list::value) / sizeof(*prime_list::value);
|
||||
std::size_t const* bound =
|
||||
std::upper_bound(prime_list,prime_list_end, n);
|
||||
if(bound != prime_list)
|
||||
std::upper_bound(prime_list_begin,prime_list_end, n);
|
||||
if(bound != prime_list_begin)
|
||||
bound--;
|
||||
return *bound;
|
||||
}
|
||||
|
61
test/helpers/count.hpp
Normal file
61
test/helpers/count.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
|
||||
// Copyright 2008 Daniel James.
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or move at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#if !defined(BOOST_UNORDERED_TEST_HELPERS_COUNT_HEAD)
|
||||
#define BOOST_UNORDERED_TEST_HELPERS_COUNT_HEAD
|
||||
|
||||
namespace test {
|
||||
struct object_count {
|
||||
int instances;
|
||||
int constructions;
|
||||
|
||||
object_count() : instances(0), constructions(0) {}
|
||||
void reset() { *this = object_count(); }
|
||||
|
||||
void construct() {
|
||||
++instances;
|
||||
++constructions;
|
||||
}
|
||||
|
||||
void destruct() {
|
||||
if(instances == 0) {
|
||||
BOOST_ERROR("Unbalanced constructions.");
|
||||
}
|
||||
else {
|
||||
--instances;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(object_count const& x) const {
|
||||
return instances == x.instances &&
|
||||
constructions == x.constructions;
|
||||
}
|
||||
|
||||
bool operator!=(object_count const& x) const {
|
||||
return !(*this == x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct counted_object
|
||||
{
|
||||
static object_count count_;
|
||||
|
||||
counted_object() { count_.construct(); }
|
||||
counted_object(counted_object const&) { count_.construct(); }
|
||||
~counted_object() { count_.destruct(); }
|
||||
};
|
||||
|
||||
template <class T> object_count counted_object<T>::count_;
|
||||
|
||||
struct globally_counted_object
|
||||
: counted_object<globally_counted_object> {};
|
||||
|
||||
namespace {
|
||||
object_count& global_object_count = globally_counted_object::count_;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -11,7 +11,7 @@
|
||||
#include "./metafunctions.hpp"
|
||||
#include "./equivalent.hpp"
|
||||
#include "./list.hpp"
|
||||
#include "../objects/exception.hpp"
|
||||
#include "./exception_test.hpp"
|
||||
|
||||
namespace test
|
||||
{
|
||||
|
@@ -11,7 +11,8 @@
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
#include "../helpers/fwd.hpp"
|
||||
#include "memory.hpp"
|
||||
#include "../helpers/count.hpp"
|
||||
#include "./memory.hpp"
|
||||
#include <map>
|
||||
|
||||
namespace test
|
||||
@@ -25,7 +26,7 @@ namespace test
|
||||
template <class T> class allocator;
|
||||
object generate(object const*);
|
||||
|
||||
class object
|
||||
class object : globally_counted_object
|
||||
{
|
||||
friend class hash;
|
||||
friend class equal_to;
|
||||
|
@@ -23,15 +23,15 @@ namespace move_tests
|
||||
|
||||
template<class T>
|
||||
T create(test::random_values<T> const& v,
|
||||
BOOST_DEDUCED_TYPENAME T::value_type const*& first) {
|
||||
test::object_count& count) {
|
||||
T x(v.begin(), v.end());
|
||||
first = &*x.begin();
|
||||
count = test::global_object_count;
|
||||
return x;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T create(test::random_values<T> const& v,
|
||||
BOOST_DEDUCED_TYPENAME T::value_type const*& first,
|
||||
test::object_count& count,
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf,
|
||||
BOOST_DEDUCED_TYPENAME T::key_equal eq,
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al,
|
||||
@@ -39,7 +39,7 @@ namespace move_tests
|
||||
T x(0, hf, eq, al);
|
||||
x.max_load_factor(mlf);
|
||||
x.insert(v.begin(), v.end());
|
||||
first = &*x.begin();
|
||||
count = test::global_object_count;
|
||||
return x;
|
||||
}
|
||||
|
||||
@@ -62,9 +62,9 @@ namespace move_tests
|
||||
|
||||
{
|
||||
test::random_values<T> v(1000);
|
||||
BOOST_DEDUCED_TYPENAME T::value_type const* first = 0;
|
||||
T y(create(v, first));
|
||||
BOOST_CHECK(first == &*y.begin());
|
||||
test::object_count count;
|
||||
T y(create(v, count));
|
||||
BOOST_CHECK(count == test::global_object_count);
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
@@ -75,10 +75,10 @@ namespace move_tests
|
||||
{
|
||||
{
|
||||
test::random_values<T> v(500);
|
||||
BOOST_DEDUCED_TYPENAME T::value_type const* first = 0;
|
||||
test::object_count count;
|
||||
T y;
|
||||
y = create(v, first);
|
||||
BOOST_CHECK(first == &*y.begin());
|
||||
y = create(v, count);
|
||||
BOOST_CHECK(count == test::global_object_count);
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
@@ -95,12 +95,12 @@ namespace move_tests
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al(1);
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al2(2);
|
||||
|
||||
BOOST_DEDUCED_TYPENAME T::value_type const* first;
|
||||
test::object_count count;
|
||||
|
||||
{
|
||||
test::random_values<T> v(500);
|
||||
T y(create(v, first, hf, eq, al, 0.5));
|
||||
BOOST_CHECK(first == &*y.begin());
|
||||
T y(create(v, count, hf, eq, al, 0.5));
|
||||
BOOST_CHECK(count == test::global_object_count);
|
||||
test::check_container(y, v);
|
||||
BOOST_CHECK(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_CHECK(test::equivalent(y.key_eq(), eq));
|
||||
@@ -112,8 +112,8 @@ namespace move_tests
|
||||
{
|
||||
// TODO: To do this correctly requires the fancy new allocator stuff.
|
||||
test::random_values<T> v(500);
|
||||
T y(create(v, first, hf, eq, al, 2.0), al2);
|
||||
BOOST_CHECK(first != &*y.begin());
|
||||
T y(create(v, count, hf, eq, al, 2.0), al2);
|
||||
BOOST_CHECK(count != test::global_object_count);
|
||||
test::check_container(y, v);
|
||||
BOOST_CHECK(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_CHECK(test::equivalent(y.key_eq(), eq));
|
||||
@@ -124,8 +124,8 @@ namespace move_tests
|
||||
|
||||
{
|
||||
test::random_values<T> v(25);
|
||||
T y(create(v, first, hf, eq, al, 1.0), al);
|
||||
BOOST_CHECK(first == &*y.begin());
|
||||
T y(create(v, count, hf, eq, al, 1.0), al);
|
||||
BOOST_CHECK(count == test::global_object_count);
|
||||
test::check_container(y, v);
|
||||
BOOST_CHECK(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_CHECK(test::equivalent(y.key_eq(), eq));
|
||||
|
@@ -15,7 +15,19 @@ namespace unnecessary_copy_tests
|
||||
static int moves;
|
||||
count_copies() : tag_(0) { ++copies; }
|
||||
explicit count_copies(int tag) : tag_(tag) { ++copies; }
|
||||
count_copies(count_copies const&, count_copies const& x) : tag_(x.tag_) { ++copies; }
|
||||
|
||||
// This bizarre constructor is an attempt to confuse emplace.
|
||||
//
|
||||
// unordered_map<count_copies, count_copies> x:
|
||||
// x.emplace(count_copies(1), count_copies(2));
|
||||
// x.emplace(count_copies(1), count_copies(2), count_copies(3));
|
||||
//
|
||||
// The first emplace should use the single argument constructor twice.
|
||||
// The second emplace should use the single argument contructor for
|
||||
// the key, and this constructor for the value.
|
||||
count_copies(count_copies const&, count_copies const& x)
|
||||
: tag_(x.tag_) { ++copies; }
|
||||
|
||||
count_copies(count_copies const& x) : tag_(x.tag_) { ++copies; }
|
||||
#if defined(BOOST_HAS_RVALUE_REFS)
|
||||
count_copies(count_copies&& x) : tag_(x.tag_) {
|
||||
|
Reference in New Issue
Block a user