Add some tests for the unordered associative containers.

[SVN r2954]
This commit is contained in:
Daniel James
2006-05-17 17:19:16 +00:00
parent 1301d774e0
commit 1be8ab0d30
21 changed files with 2020 additions and 0 deletions

23
test/unordered/Jamfile.v2 Normal file
View File

@@ -0,0 +1,23 @@
# Copyright Daniel James 2006. Use, modification, and distribution are
# subject to 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)
import testing ;
project unordered-test/unordered
: requirements
<toolset>intel-linux:"<cxxflags>-strict_ansi -cxxlib-icc"
;
test-suite unordered-tests
:
[ run equivalent_keys_tests.cpp ]
[ run compile_tests.cpp ]
[ run constructor_tests.cpp ]
[ run copy_tests.cpp ]
[ run assign_tests.cpp ]
[ run insert_tests.cpp ]
[ run erase_tests.cpp ]
[ run find_tests.cpp ]
;

View File

@@ -0,0 +1,91 @@
// Copyright Daniel James 2006. Use, modification, and distribution are
// subject to 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)
#include <boost/unordered_set.hpp>
#include <boost/unordered_map.hpp>
#include <boost/detail/lightweight_test.hpp>
#include "../objects/test.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/tracker.hpp"
#include "../helpers/equivalent.hpp"
#include <iostream>
template <class T>
void assign_tests1(T* = 0)
{
typename T::hasher hf;
typename T::key_equal eq;
std::cerr<<"assign_tests1.1\n";
{
T x;
x = x;
BOOST_TEST(x.empty());
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
}
std::cerr<<"assign_tests1.2\n";
{
test::random_values<T> v(1000);
T x(v.begin(), v.end());
test::ordered<T> tracker = test::create_ordered(x);
tracker.insert(v.begin(), v.end());
x = x;
tracker.compare(x);
T y;
y.max_load_factor(x.max_load_factor() / 20);
y = x;
tracker.compare(y);
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
}
}
template <class T>
void assign_tests2(T* = 0)
{
typename T::hasher hf;
typename T::key_equal eq;
typename T::hasher hf1(1);
typename T::key_equal eq1(1);
typename T::hasher hf2(2);
typename T::key_equal eq2(2);
std::cerr<<"assign_tests2.1\n";
{
// TODO: Need to generate duplicates...
test::random_values<T> v(1000);
T x1(v.begin(), v.end(), 0, hf1, eq1);
T x2(0, hf2, eq2);
x2 = x1;
BOOST_TEST(test::equivalent(x2.hash_function(), hf1));
BOOST_TEST(test::equivalent(x2.key_eq(), eq1));
check_container(x2, v);
}
}
int main()
{
assign_tests1((boost::unordered_set<int>*) 0);
assign_tests1((boost::unordered_multiset<int>*) 0);
assign_tests1((boost::unordered_map<int, int>*) 0);
assign_tests1((boost::unordered_multimap<int, int>*) 0);
assign_tests1((boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
assign_tests1((boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
assign_tests1((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
assign_tests1((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
assign_tests2((boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
assign_tests2((boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
assign_tests2((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
assign_tests2((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
return boost::report_errors();
}

View File

@@ -0,0 +1,297 @@
// Copyright Daniel James 2006. Use, modification, and distribution are
// subject to 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)
#include <boost/unordered_set.hpp>
#include <boost/unordered_map.hpp>
#include <boost/concept_check.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include "../helpers/check_return_type.hpp"
#include <iostream>
#include <boost/detail/lightweight_test.hpp>
#include "../objects/minimal.hpp"
template <class T> void sink(T const&) {}
template <class X, class Key>
void unordered_set_test(X& r, Key const& k)
{
BOOST_MPL_ASSERT((boost::is_same<
typename X::value_type,
typename X::key_type>));
}
template <class X, class Key, class T>
void unordered_map_test(X& r, Key const& k, T const& t)
{
BOOST_MPL_ASSERT((boost::is_same<
typename X::value_type,
std::pair<const typename X::key_type, T> >));
}
template <class X, class T>
void unordered_unique_test(X& r, T const& t)
{
typedef typename X::iterator iterator;
test::check_return_type<std::pair<iterator, bool> >::equals(r.insert(t));
}
template <class X, class T>
void unordered_equivalent_test(X& r, T const& t)
{
typedef typename X::iterator iterator;
test::check_return_type<iterator>::equals(r.insert(t));
}
template <class X, class Key, class T, class Hash, class Pred>
void unordered_test(X& ref, Key& k, T& t, Hash& hf, Pred& eq)
{
typedef typename X::iterator iterator;
typedef typename X::const_iterator const_iterator;
typedef typename X::local_iterator local_iterator;
typedef typename X::const_local_iterator const_local_iterator;
typedef typename X::key_type key_type;
typedef typename X::hasher hasher;
typedef typename X::key_equal key_equal;
BOOST_MPL_ASSERT((boost::is_same<Key, key_type>));
boost::function_requires<boost::CopyConstructibleConcept<key_type> >();
boost::function_requires<boost::AssignableConcept<key_type> >();
BOOST_MPL_ASSERT((boost::is_same<Hash, hasher>));
test::check_return_type<std::size_t>::equals(hf(k));
BOOST_MPL_ASSERT((boost::is_same<Pred, key_equal>));
test::check_return_type<bool>::convertible(eq(k, k));
// TODO: Pred is an equivalence relation. Doesn't really matter for these
// tests.
boost::function_requires<boost::InputIteratorConcept<local_iterator> >();
BOOST_MPL_ASSERT((boost::is_same<
typename boost::BOOST_ITERATOR_CATEGORY<local_iterator>::type,
typename boost::BOOST_ITERATOR_CATEGORY<iterator>::type >));
BOOST_MPL_ASSERT((boost::is_same<
typename boost::iterator_difference<local_iterator>::type,
typename boost::iterator_difference<iterator>::type >));
BOOST_MPL_ASSERT((boost::is_same<
typename boost::iterator_pointer<local_iterator>::type,
typename boost::iterator_pointer<iterator>::type >));
BOOST_MPL_ASSERT((boost::is_same<
typename boost::iterator_reference<local_iterator>::type,
typename boost::iterator_reference<iterator>::type >));
boost::function_requires<boost::InputIteratorConcept<const_local_iterator> >();
BOOST_MPL_ASSERT((boost::is_same<
typename boost::BOOST_ITERATOR_CATEGORY<const_local_iterator>::type,
typename boost::BOOST_ITERATOR_CATEGORY<const_iterator>::type >));
BOOST_MPL_ASSERT((boost::is_same<
typename boost::iterator_difference<const_local_iterator>::type,
typename boost::iterator_difference<const_iterator>::type >));
BOOST_MPL_ASSERT((boost::is_same<
typename boost::iterator_pointer<const_local_iterator>::type,
typename boost::iterator_pointer<const_iterator>::type >));
BOOST_MPL_ASSERT((boost::is_same<
typename boost::iterator_reference<const_local_iterator>::type,
typename boost::iterator_reference<const_iterator>::type >));
X(10, hf, eq);
X a(10, hf, eq);
X(10, hf);
X a2(10, hf);
X(10);
X a3(10);
X();
X a4();
typename X::value_type* i = 0;
typename X::value_type* j = 0;
X(i, j, 10, hf, eq);
X a5(i, j, 10, hf, eq);
X(i, j, 10, hf);
X a6(i, j, 10, hf);
X(i, j, 10);
X a7(i, j, 10);
X(i, j);
X a8(i, j);
X const b;
sink(X(b));
X a9(b);
a = b;
test::check_return_type<hasher>::equals(b.hash_function());
test::check_return_type<key_equal>::equals(b.key_eq());
iterator q = a.begin();
const_iterator r = a.begin();
test::check_return_type<iterator>::equals(a.insert(q, t));
test::check_return_type<const_iterator>::equals(a.insert(r, t));
// TODO: void return?
a.insert(i, j);
test::check_return_type<typename X::size_type>::equals(a.erase(k));
BOOST_TEST(a.empty());
if(a.empty()) {
a.insert(t);
q = a.begin();
test::check_return_type<iterator>::equals(a.erase(q));
}
BOOST_TEST(a.empty());
if(a.empty()) {
a.insert(t);
r = a.begin();
test::check_return_type<const_iterator>::equals(a.erase(r));
}
iterator q1 = a.begin(), q2 = a.end();
test::check_return_type<iterator>::equals(a.erase(q1, q2));
const_iterator r1 = a.begin(), r2 = a.end();
test::check_return_type<const_iterator>::equals(a.erase(r1, r2));
// TODO: void return?
a.clear();
test::check_return_type<iterator>::equals(a.find(k));
test::check_return_type<const_iterator>::equals(b.find(k));
test::check_return_type<typename X::size_type>::equals(b.count(k));
test::check_return_type<std::pair<iterator, iterator> >::equals(
a.equal_range(k));
test::check_return_type<std::pair<const_iterator, const_iterator> >::equals(
b.equal_range(k));
test::check_return_type<typename X::size_type>::equals(b.bucket_count());
test::check_return_type<typename X::size_type>::equals(b.max_bucket_count());
test::check_return_type<typename X::size_type>::equals(b.bucket(k));
test::check_return_type<typename X::size_type>::equals(b.bucket_size(0));
test::check_return_type<local_iterator>::equals(a.begin(0));
test::check_return_type<const_local_iterator>::equals(b.begin(0));
test::check_return_type<local_iterator>::equals(a.end(0));
test::check_return_type<const_local_iterator>::equals(b.end(0));
test::check_return_type<float>::equals(b.load_factor());
test::check_return_type<float>::equals(b.max_load_factor());
a.max_load_factor((float) 2.0);
a.rehash(100);
}
void test1()
{
boost::hash<int> hash;
std::equal_to<int> equal_to;
int value = 0;
std::pair<int const, int> map_value(0, 0);
std::cout<<"Test unordered_set.\n";
boost::unordered_set<int> set;
unordered_unique_test(set, value);
unordered_set_test(set, value);
unordered_test(set, value, value, hash, equal_to);
std::cout<<"Test unordered_multiset.\n";
boost::unordered_multiset<int> multiset;
unordered_equivalent_test(multiset, value);
unordered_set_test(multiset, value);
unordered_test(multiset, value, value, hash, equal_to);
std::cout<<"Test unordered_map.\n";
boost::unordered_map<int, int> map;
unordered_unique_test(map, map_value);
unordered_map_test(map, value, value);
unordered_test(map, value, map_value, hash, equal_to);
std::cout<<"Test unordered_multimap.\n";
boost::unordered_multimap<int, int> multimap;
unordered_equivalent_test(multimap, map_value);
unordered_map_test(multimap, value, value);
unordered_test(multimap, value, map_value, hash, equal_to);
}
void test2()
{
test::minimal::assignable assignable
= test::minimal::assignable::create();
test::minimal::copy_constructible copy_constructible
= test::minimal::copy_constructible::create();
test::minimal::hash<test::minimal::assignable> hash
= test::minimal::hash<test::minimal::assignable>::create();
test::minimal::equal_to<test::minimal::assignable> equal_to
= test::minimal::equal_to<test::minimal::assignable>::create();
typedef std::pair<test::minimal::assignable const,
test::minimal::copy_constructible> map_value_type;
map_value_type map_value(assignable, copy_constructible);
std::cout<<"Test unordered_set.\n";
boost::unordered_set<
test::minimal::assignable,
test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<test::minimal::assignable> > set;
unordered_unique_test(set, assignable);
unordered_set_test(set, assignable);
unordered_test(set, assignable, assignable, hash, equal_to);
std::cout<<"Test unordered_multiset.\n";
boost::unordered_multiset<
test::minimal::assignable,
test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<test::minimal::assignable> > multiset;
unordered_equivalent_test(multiset, assignable);
unordered_set_test(multiset, assignable);
unordered_test(multiset, assignable, assignable, hash, equal_to);
std::cout<<"Test unordered_map.\n";
boost::unordered_map<
test::minimal::assignable,
test::minimal::copy_constructible,
test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<map_value_type> > map;
unordered_unique_test(map, map_value);
unordered_map_test(map, assignable, copy_constructible);
unordered_test(map, assignable, map_value, hash, equal_to);
std::cout<<"Test unordered_multimap.\n";
boost::unordered_multimap<
test::minimal::assignable,
test::minimal::copy_constructible,
test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<map_value_type> > multimap;
unordered_equivalent_test(multimap, map_value);
unordered_map_test(multimap, assignable, copy_constructible);
unordered_test(multimap, assignable, map_value, hash, equal_to);
}
int main() {
test1();
test2();
return boost::report_errors();
}

View File

@@ -0,0 +1,202 @@
// Copyright Daniel James 2006. Use, modification, and distribution are
// subject to 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)
#include <boost/unordered_set.hpp>
#include <boost/unordered_map.hpp>
#include <boost/detail/lightweight_test.hpp>
#include "../objects/test.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/tracker.hpp"
#include "../helpers/equivalent.hpp"
#include <iostream>
template <class T>
void constructor_tests1(T* = 0)
{
typename T::hasher hf;
typename T::key_equal eq;
std::cerr<<"Construct 1\n";
{
T x(0, hf, eq);
BOOST_TEST(x.empty());
BOOST_TEST(x.bucket_count() >= 0);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
}
std::cerr<<"Construct 2\n";
{
T x(100, hf);
BOOST_TEST(x.empty());
BOOST_TEST(x.bucket_count() >= 100);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
}
std::cerr<<"Construct 3\n";
{
T x(2000);
BOOST_TEST(x.empty());
BOOST_TEST(x.bucket_count() >= 2000);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
}
std::cerr<<"Construct 4\n";
{
T x;
BOOST_TEST(x.empty());
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
}
std::cerr<<"Construct 5\n";
{
test::random_values<T> v(1000);
T x(v.begin(), v.end(), 10000, hf, eq);
BOOST_TEST(x.bucket_count() >= 10000);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
check_container(x, v);
}
std::cerr<<"Construct 6\n";
{
test::random_values<T> v(10);
T x(v.begin(), v.end(), 10000, hf);
BOOST_TEST(x.bucket_count() >= 10000);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
check_container(x, v);
}
std::cerr<<"Construct 7\n";
{
test::random_values<T> v(100);
T x(v.begin(), v.end(), 100);
BOOST_TEST(x.bucket_count() >= 100);
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
check_container(x, v);
}
std::cerr<<"Construct 8\n";
{
test::random_values<T> v(1);
T x(v.begin(), v.end());
BOOST_TEST(test::equivalent(x.hash_function(), hf));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
check_container(x, v);
}
}
template <class T>
void constructor_tests2(T* = 0)
{
typename T::hasher hf;
typename T::hasher hf1(1);
typename T::hasher hf2(2);
typename T::key_equal eq;
typename T::key_equal eq1(1);
typename T::key_equal eq2(2);
std::cerr<<"Construct 1\n";
{
T x(10000, hf1, eq1);
BOOST_TEST(x.bucket_count() >= 10000);
BOOST_TEST(test::equivalent(x.hash_function(), hf1));
BOOST_TEST(test::equivalent(x.key_eq(), eq1));
}
std::cerr<<"Construct 2\n";
{
T x(100, hf1);
BOOST_TEST(x.empty());
BOOST_TEST(x.bucket_count() >= 100);
BOOST_TEST(test::equivalent(x.hash_function(), hf1));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
}
std::cerr<<"Construct 3\n";
{
test::random_values<T> v(100);
T x(v.begin(), v.end(), 0, hf1, eq1);
BOOST_TEST(test::equivalent(x.hash_function(), hf1));
BOOST_TEST(test::equivalent(x.key_eq(), eq1));
check_container(x, v);
}
std::cerr<<"Construct 4\n";
{
test::random_values<T> v(5);
T x(v.begin(), v.end(), 1000, hf1);
BOOST_TEST(x.bucket_count() >= 1000);
BOOST_TEST(test::equivalent(x.hash_function(), hf1));
BOOST_TEST(test::equivalent(x.key_eq(), eq));
check_container(x, v);
}
std::cerr<<"Construct 5\n";
{
test::random_values<T> v(100);
T x(v.begin(), v.end(), 0, hf, eq);
T y(x.begin(), x.end(), 0, hf1, eq1);
check_container(x, v);
check_container(y, x);
}
std::cerr<<"Construct 6\n";
{
test::random_values<T> v(100);
T x(v.begin(), v.end(), 0, hf1, eq1);
T y(x.begin(), x.end(), 0, hf, eq);
check_container(x, v);
check_container(y, x);
}
std::cerr<<"Construct 7\n";
{
test::random_values<T> v(100);
T x(v.begin(), v.end(), 0, hf1, eq1);
T y(x.begin(), x.end(), 0, hf2, eq2);
check_container(x, v);
check_container(y, x);
}
}
int main()
{
std::cerr<<"Test1 unordered_set<int>\n";
constructor_tests1((boost::unordered_set<int>*) 0);
std::cerr<<"Test1 unordered_multiset<int>\n";
constructor_tests1((boost::unordered_multiset<int>*) 0);
std::cerr<<"Test1 unordered_map<int, int>\n";
constructor_tests1((boost::unordered_map<int, int>*) 0);
std::cerr<<"Test1 unordered_multimap<int, int>\n";
constructor_tests1((boost::unordered_multimap<int, int>*) 0);
std::cerr<<"Test1 unordered_set<test::object>\n";
constructor_tests1((boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
std::cerr<<"Test1 unordered_multiset<test::object>\n";
constructor_tests1((boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
std::cerr<<"Test1 unordered_map<test::object, test::object>\n";
constructor_tests1((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
std::cerr<<"Test1 unordered_multimap<test::object, test::object>\n";
constructor_tests1((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
std::cerr<<"Test2 unordered_set<test::object>\n";
constructor_tests2((boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
std::cerr<<"Test2 unordered_multiset<test::object>\n";
constructor_tests2((boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
std::cerr<<"Test2 unordered_map<test::object, test::object>\n";
constructor_tests2((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
std::cerr<<"Test2 unordered_multimap<test::object, test::object>\n";
constructor_tests2((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
return boost::report_errors();
}

View File

@@ -0,0 +1,103 @@
// Copyright Daniel James 2006. Use, modification, and distribution are
// subject to 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)
#include <boost/unordered_set.hpp>
#include <boost/unordered_map.hpp>
#include <boost/detail/lightweight_test.hpp>
#include "../objects/test.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/tracker.hpp"
#include "../helpers/equivalent.hpp"
#include "../helpers/invariants.hpp"
template <class T>
void copy_construct_tests1(T* = 0)
{
typename T::hasher hf;
typename T::key_equal eq;
{
T x;
T y(x);
BOOST_TEST(y.empty());
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
test::check_equivalent_keys(y);
}
{
test::random_values<T> v(1000);
T x(v.begin(), v.end());
T y(x);
test::unordered_equivalence_tester<T> equivalent(x);
equivalent(y);
test::check_equivalent_keys(y);
}
{
// In this test I drop the original containers max load factor, so it
// is much lower than the load factor. The hash table is not allowed
// to rehash, but the destination container should probably allocate
// enough buckets to decrease the load factor appropriately. Although,
// I don't think it has to.
test::random_values<T> v(1000);
T x(v.begin(), v.end());
x.max_load_factor(x.load_factor() / 4);
T y(x);
test::unordered_equivalence_tester<T> equivalent(x);
equivalent(y);
// I don't think this is guaranteed:
BOOST_TEST(y.load_factor() < y.max_load_factor());
test::check_equivalent_keys(y);
}
}
template <class T>
void copy_construct_tests2(T* ptr = 0)
{
copy_construct_tests1(ptr);
typename T::hasher hf(1);
typename T::key_equal eq(1);
{
// TODO: I could check how many buckets y has, it should be lower (QOI issue).
T x(10000, hf, eq);
T y(x);
BOOST_TEST(y.empty());
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
test::check_equivalent_keys(y);
}
{
// TODO: Invariant checks are especially important here.
test::random_values<T> v(1000);
T x(v.begin(), v.end(), 0, hf, eq);
T y(x);
test::unordered_equivalence_tester<T> equivalent(x);
equivalent(y);
test::check_equivalent_keys(y);
}
}
int main()
{
copy_construct_tests1((boost::unordered_set<int>*) 0);
copy_construct_tests1((boost::unordered_multiset<int>*) 0);
copy_construct_tests1((boost::unordered_map<int, int>*) 0);
copy_construct_tests1((boost::unordered_multimap<int, int>*) 0);
copy_construct_tests2((boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
copy_construct_tests2((boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
copy_construct_tests2((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
copy_construct_tests2((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
return boost::report_errors();
}

View File

@@ -0,0 +1,85 @@
// Copyright Daniel James 2006. Use, modification, and distribution are
// subject to 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)
#include <boost/unordered_set.hpp>
#include <boost/unordered_map.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <algorithm>
#include <map>
#include <deque>
#include "../helpers/tracker.hpp"
#include "../helpers/invariants.hpp"
#include <iostream>
template <class Container, class Iterator>
void test_equal_insertion(Iterator begin, Iterator end)
{
typedef test::ordered<Container> tracker;
Container x1;
tracker x2 = test::create_ordered(x1);
for(Iterator it = begin; it != end; ++it) {
x1.insert(*it);
x2.insert(*it);
x2.compare_key(x1, *it);
}
x2.compare(x1);
test::check_equivalent_keys(x1);
}
void set_tests()
{
int values[][5] = {
{1},
{54, 23},
{-13, 65},
{77, 77},
{986, 25, 986}
};
test_equal_insertion<boost::unordered_set<int> >(values[0], values[0] + 1);
test_equal_insertion<boost::unordered_set<int> >(values[1], values[1] + 2);
test_equal_insertion<boost::unordered_set<int> >(values[2], values[2] + 2);
test_equal_insertion<boost::unordered_set<int> >(values[3], values[3] + 2);
test_equal_insertion<boost::unordered_set<int> >(values[4], values[4] + 3);
test_equal_insertion<boost::unordered_multiset<int> >(values[0], values[0] + 1);
test_equal_insertion<boost::unordered_multiset<int> >(values[1], values[1] + 2);
test_equal_insertion<boost::unordered_multiset<int> >(values[2], values[2] + 2);
test_equal_insertion<boost::unordered_multiset<int> >(values[3], values[3] + 2);
test_equal_insertion<boost::unordered_multiset<int> >(values[4], values[4] + 3);
}
void map_tests()
{
typedef std::deque<std::pair<int const, int> > values_type;
values_type v[5];
v[0].push_back(std::pair<int const, int>(1,1));
v[1].push_back(std::pair<int const, int>(28,34));
v[1].push_back(std::pair<int const, int>(16,58));
v[1].push_back(std::pair<int const, int>(-124, 62));
v[2].push_back(std::pair<int const, int>(432,12));
v[2].push_back(std::pair<int const, int>(9,13));
v[2].push_back(std::pair<int const, int>(432,24));
for(int i = 0; i < 5; ++i)
test_equal_insertion<boost::unordered_map<int, int> >(
v[i].begin(), v[i].end());
for(int i2 = 0; i2 < 5; ++i2)
test_equal_insertion<boost::unordered_multimap<int, int> >(
v[i2].begin(), v[i2].end());
}
int main()
{
set_tests();
map_tests();
return boost::report_errors();
}

View File

@@ -0,0 +1,140 @@
// Copyright Daniel James 2006. Use, modification, and distribution are
// subject to 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)
#include <boost/unordered_set.hpp>
#include <boost/unordered_map.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/next_prior.hpp>
#include "../objects/test.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/tracker.hpp"
#include "../helpers/equivalent.hpp"
#include "../helpers/helpers.hpp"
#include <iostream>
template <class Container>
void erase_tests1(Container* = 0)
{
std::cerr<<"Erase by key.\n";
{
test::random_values<Container> v(1000);
Container x(v.begin(), v.end());
for(typename test::random_values<Container>::iterator it = v.begin();
it != v.end(); ++it)
{
std::size_t count = x.count(test::get_key<Container>(*it));
std::size_t old_size = x.size();
BOOST_TEST(count == x.erase(test::get_key<Container>(*it)));
BOOST_TEST(x.size() == old_size - count);
BOOST_TEST(x.count(test::get_key<Container>(*it)) == 0);
BOOST_TEST(x.find(test::get_key<Container>(*it)) == x.end());
}
}
std::cerr<<"erase(begin()).\n";
{
test::random_values<Container> v(1000);
Container x(v.begin(), v.end());
std::size_t size = x.size();
while(size > 0 && !x.empty())
{
typename Container::key_type key = test::get_key<Container>(*x.begin());
std::size_t count = x.count(key);
typename Container::iterator pos = x.erase(x.begin());
--size;
BOOST_TEST(pos == x.begin());
BOOST_TEST(x.count(key) == count - 1);
BOOST_TEST(x.size() == size);
}
BOOST_TEST(x.empty());
}
std::cerr<<"erase(random position).\n";
{
test::random_values<Container> v(1000);
Container x(v.begin(), v.end());
std::size_t size = x.size();
while(size > 0 && !x.empty())
{
using namespace std;
int index = rand() % x.size();
typename Container::const_iterator prev, pos, next;
if(index == 0) {
prev = pos = x.begin();
}
else {
prev = boost::next(x.begin(), index - 1);
pos = boost::next(prev);
}
next = boost::next(pos);
typename Container::key_type key = test::get_key<Container>(*x.begin());
std::size_t count = x.count(key);
BOOST_TEST(next == x.erase(pos));
--size;
if(size > 0)
BOOST_TEST(next ==
(index == 0 ? x.begin() : boost::next(prev)));
BOOST_TEST(x.count(key) == count - 1);
std::cerr<<x.count(key)<<"/"<<(count - 1)<<"\n";
BOOST_TEST(x.size() == size);
}
BOOST_TEST(x.empty());
}
std::cerr<<"erase(ranges).\n";
{
test::random_values<Container> v(500);
Container x(v.begin(), v.end());
std::size_t size = x.size();
// I'm actually stretching it a little here, as the standard says it
// returns 'the iterator immediately following the erase elements'
// and if nothing is erased, then there's nothing to follow. But I
// think this is the only sensible option...
BOOST_TEST(x.erase(x.end(), x.end()) == x.end());
BOOST_TEST(x.erase(x.begin(), x.begin()) == x.begin());
BOOST_TEST(x.size() == size);
BOOST_TEST(x.erase(x.begin(), x.end()) == x.end());
BOOST_TEST(x.empty());
BOOST_TEST(x.begin() == x.end());
BOOST_TEST(x.erase(x.begin(), x.end()) == x.begin());
}
// TODO: More range erase tests.
std::cerr<<"clear().\n";
{
test::random_values<Container> v(500);
Container x(v.begin(), v.end());
x.clear();
BOOST_TEST(x.empty());
BOOST_TEST(x.begin() == x.end());
}
}
int main()
{
std::cerr<<"Erase unordered_set<int>.\n";
erase_tests1((boost::unordered_set<int>*) 0);
std::cerr<<"\nErase unordered_multiset<int>.\n";
erase_tests1((boost::unordered_multiset<int>*) 0);
std::cerr<<"\nErase unordered_map<int>.\n";
erase_tests1((boost::unordered_map<int, int>*) 0);
std::cerr<<"\nErase unordered_multimap<int>.\n";
erase_tests1((boost::unordered_multimap<int, int>*) 0);
std::cerr<<"\nErase unordered_set<test::object,..>.\n";
erase_tests1((boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
std::cerr<<"\nErase unordered_multiset<test::object,..>.\n";
erase_tests1((boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
std::cerr<<"\nErase unordered_map<test::object,..>.\n";
erase_tests1((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
std::cerr<<"\nErase unordered_multimap<test::object,..>.\n";
erase_tests1((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
}

View File

@@ -0,0 +1,90 @@
// Copyright Daniel James 2006. Use, modification, and distribution are
// subject to 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)
#include <boost/unordered_set.hpp>
#include <boost/unordered_map.hpp>
#include <boost/detail/lightweight_test.hpp>
#include "../objects/test.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/tracker.hpp"
#include "../helpers/helpers.hpp"
template <class X>
void find_tests1(X*)
{
{
test::random_values<X> v(500);
X x(v.begin(), v.end());
X const& x_const = x;
test::ordered<X> tracker = test::create_ordered(x);
tracker.insert(v.begin(), v.end());
for(typename test::ordered<X>::const_iterator it =
tracker.begin(); it != tracker.end(); ++it)
{
typename X::key_type key = test::get_key<X>(*it);
typename X::iterator pos = x.find(key);
typename X::const_iterator const_pos = x_const.find(key);
BOOST_TEST(pos != x.end() &&
x.key_eq()(key, test::get_key<X>(*pos)));
BOOST_TEST(const_pos != x_const.end() &&
x_const.key_eq()(key, test::get_key<X>(*const_pos)));
BOOST_TEST(x.count(key) == tracker.count(key));
test::compare_pairs(x.equal_range(key),
tracker.equal_range(key),
(typename test::non_const_value_type<X>::type*) 0);
test::compare_pairs(x_const.equal_range(key),
tracker.equal_range(key),
(typename test::non_const_value_type<X>::type*) 0);
}
test::random_values<X> v2(500);
for(typename test::random_values<X>::const_iterator it =
v2.begin(); it != v2.end(); ++it)
{
typename X::key_type key = test::get_key<X>(*it);
if(tracker.find(test::get_key<X>(key)) == tracker.end())
{
BOOST_TEST(x.find(key) == x.end());
BOOST_TEST(x_const.find(key) == x_const.end());
BOOST_TEST(x.count(key) == 0);
std::pair<typename X::iterator,
typename X::iterator> range = x.equal_range(key);
BOOST_TEST(range.first == range.second);
}
}
}
{
X x;
test::random_values<X> v2(5);
for(typename test::random_values<X>::const_iterator it =
v2.begin(); it != v2.end(); ++it)
{
typename X::key_type key = test::get_key<X>(*it);
BOOST_TEST(x.find(key) == x.end());
BOOST_TEST(x.count(key) == 0);
std::pair<typename X::iterator,
typename X::iterator> range = x.equal_range(key);
BOOST_TEST(range.first == range.second);
}
}
}
int main()
{
find_tests1((boost::unordered_set<int>*) 0);
find_tests1((boost::unordered_multiset<int>*) 0);
find_tests1((boost::unordered_map<int, int>*) 0);
find_tests1((boost::unordered_multimap<int, int>*) 0);
find_tests1((boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
find_tests1((boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
find_tests1((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
find_tests1((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
}

View File

@@ -0,0 +1,188 @@
// Copyright Daniel James 2006. Use, modification, and distribution are
// subject to 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)
#include <boost/unordered_set.hpp>
#include <boost/unordered_map.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/next_prior.hpp>
#include "../objects/test.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/tracker.hpp"
#include "../helpers/equivalent.hpp"
#include "../helpers/invariants.hpp"
#include <iostream>
template <class Container>
void unique_insert_tests1(Container* = 0)
{
std::cerr<<"insert(value) tests for containers with unique keys.\n";
Container x;
test::ordered<Container> tracker = test::create_ordered(x);
test::random_values<Container> v(1000);
for(typename test::random_values<Container>::iterator it = v.begin();
it != v.end(); ++it)
{
std::pair<typename Container::iterator, bool> r1 = x.insert(*it);
std::pair<typename test::ordered<Container>::iterator, bool> r2
= tracker.insert(*it);
BOOST_TEST(r1.second == r2.second);
BOOST_TEST(*r1.first == *r2.first);
tracker.compare_key(x, *it);
}
test::check_equivalent_keys(x);
}
template <class Container>
void equivalent_insert_tests1(Container* = 0)
{
std::cerr<<"insert(value) tests for containers with equivalent keys.\n";
Container x;
test::ordered<Container> tracker = test::create_ordered(x);
test::random_values<Container> v(1000);
for(typename test::random_values<Container>::iterator it = v.begin();
it != v.end(); ++it)
{
typename Container::iterator r1 = x.insert(*it);
typename test::ordered<Container>::iterator r2 = tracker.insert(*it);
BOOST_TEST(*r1 == *r2);
tracker.compare_key(x, *it);
}
test::check_equivalent_keys(x);
}
template <class Container>
void insert_tests2(Container* = 0)
{
typedef typename test::ordered<Container> tracker_type;
typedef typename Container::iterator iterator;
typedef typename Container::const_iterator const_iterator;
typedef typename tracker_type::iterator tracker_iterator;
std::cerr<<"insert(begin(), value) tests.\n";
{
Container x;
tracker_type tracker = test::create_ordered(x);
test::random_values<Container> v(1000);
for(typename test::random_values<Container>::iterator it = v.begin();
it != v.end(); ++it)
{
iterator r1 = x.insert(x.begin(), *it);
tracker_iterator r2 = tracker.insert(tracker.begin(), *it);
BOOST_TEST(*r1 == *r2);
tracker.compare_key(x, *it);
}
test::check_equivalent_keys(x);
}
std::cerr<<"insert(end(), value) tests.\n";
{
Container x;
Container const& x_const = x;
tracker_type tracker = test::create_ordered(x);
test::random_values<Container> v(100);
for(typename test::random_values<Container>::iterator it = v.begin();
it != v.end(); ++it)
{
const_iterator r1 = x.insert(x_const.end(), *it);
tracker_iterator r2 = tracker.insert(tracker.end(), *it);
BOOST_TEST(*r1 == *r2);
tracker.compare_key(x, *it);
}
test::check_equivalent_keys(x);
}
std::cerr<<"insert(pos, value) tests.\n";
{
Container x;
const_iterator pos = x.begin();
tracker_type tracker = test::create_ordered(x);
test::random_values<Container> v(1000);
for(typename test::random_values<Container>::iterator it = v.begin();
it != v.end(); ++it)
{
pos = x.insert(pos, *it);
tracker_iterator r2 = tracker.insert(tracker.begin(), *it);
BOOST_TEST(*pos == *r2);
tracker.compare_key(x, *it);
}
test::check_equivalent_keys(x);
}
std::cerr<<"insert single item range tests.\n";
{
Container x;
tracker_type tracker = test::create_ordered(x);
test::random_values<Container> v(1000);
for(typename test::random_values<Container>::iterator it = v.begin();
it != v.end(); ++it)
{
x.insert(it, boost::next(it));
tracker.insert(*it);
tracker.compare_key(x, *it);
}
test::check_equivalent_keys(x);
}
std::cerr<<"insert range tests.\n";
{
Container x;
const_iterator pos = x.begin();
test::random_values<Container> v(1000);
x.insert(v.begin(), v.end());
check_container(x, v);
test::check_equivalent_keys(x);
}
}
int main()
{
unique_insert_tests1((boost::unordered_set<int>*) 0);
equivalent_insert_tests1((boost::unordered_multiset<int>*) 0);
unique_insert_tests1((boost::unordered_map<int, int>*) 0);
equivalent_insert_tests1((boost::unordered_multimap<int, int>*) 0);
unique_insert_tests1((boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
equivalent_insert_tests1((boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
unique_insert_tests1((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
equivalent_insert_tests1((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
insert_tests2((boost::unordered_set<int>*) 0);
insert_tests2((boost::unordered_multiset<int>*) 0);
insert_tests2((boost::unordered_map<int, int>*) 0);
insert_tests2((boost::unordered_multimap<int, int>*) 0);
insert_tests2((boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
insert_tests2((boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
insert_tests2((boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
insert_tests2((boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >*) 0);
return boost::report_errors();
}