unordered/test/unordered/move_tests.cpp
Daniel James cf529e496a Movable unordered containers, full support only for compilers with rvalue references.
Merged revisions 44076-44414 via svnmerge from 
https://svn.boost.org/svn/boost/branches/unordered/trunk

........
  r44076 | danieljames | 2008-04-06 20:41:19 +0100 (Sun, 06 Apr 2008) | 1 line
  
  Move semantics for compilers with rvalue references.
........
  r44077 | danieljames | 2008-04-06 20:48:59 +0100 (Sun, 06 Apr 2008) | 1 line
  
  Do move assignment 'properly'.
........
  r44085 | danieljames | 2008-04-06 22:46:04 +0100 (Sun, 06 Apr 2008) | 1 line
  
  Use normal references for the move members, reset the source buckets_ pointer to stop the buckets getting deleted, and remove a superflous pointer check.
........
  r44109 | danieljames | 2008-04-07 23:49:36 +0100 (Mon, 07 Apr 2008) | 1 line
  
  Add missing tests.
........
  r44366 | danieljames | 2008-04-13 12:59:46 +0100 (Sun, 13 Apr 2008) | 1 line
  
  Avoid using rvalue references in the implementation files.
........
  r44368 | danieljames | 2008-04-13 15:13:33 +0100 (Sun, 13 Apr 2008) | 6 lines
  
  Use a cut down version of the work in progress move library to implement move
  semantics on more compilers. Unfortunately the move constructor with allocator
  isn't really practical at the moment, since in the case where the container
  can't be moved, and the allocators aren't equal it will copy the container
  twice.
........


[SVN r44486]
2008-04-17 07:34:15 +00:00

159 lines
5.6 KiB
C++

// 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)
#include <boost/unordered_set.hpp>
#include <boost/unordered_map.hpp>
#include "../helpers/test.hpp"
#include "../objects/test.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/tracker.hpp"
#include "../helpers/equivalent.hpp"
#include "../helpers/invariants.hpp"
namespace move_tests
{
test::seed_t seed(98624);
template<class T>
T empty(T* ptr) {
return T();
}
template<class T>
T create(test::random_values<T> const& v,
BOOST_DEDUCED_TYPENAME T::value_type const*& first) {
T x(v.begin(), v.end());
first = &*x.begin();
return x;
}
template<class T>
T create(test::random_values<T> const& v,
BOOST_DEDUCED_TYPENAME T::value_type const*& first,
BOOST_DEDUCED_TYPENAME T::hasher hf,
BOOST_DEDUCED_TYPENAME T::key_equal eq,
BOOST_DEDUCED_TYPENAME T::allocator_type al,
float mlf) {
T x(0, hf, eq, al);
x.max_load_factor(mlf);
x.insert(v.begin(), v.end());
first = &*x.begin();
return x;
}
template <class T>
void move_construct_tests1(T* ptr, test::random_generator const& generator = test::default_generator)
{
BOOST_DEDUCED_TYPENAME T::hasher hf;
BOOST_DEDUCED_TYPENAME T::key_equal eq;
BOOST_DEDUCED_TYPENAME T::allocator_type al;
{
T y(empty(ptr));
BOOST_TEST(y.empty());
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
BOOST_TEST(y.max_load_factor() == 1.0);
test::check_equivalent_keys(y);
}
{
test::random_values<T> v(1000);
BOOST_DEDUCED_TYPENAME T::value_type const* first = 0;
T y(create(v, first));
BOOST_TEST(first == &*y.begin());
test::check_container(y, v);
test::check_equivalent_keys(y);
}
}
template <class T>
void move_assign_tests1(T* ptr, test::random_generator const& generator = test::default_generator)
{
{
test::random_values<T> v(500);
BOOST_DEDUCED_TYPENAME T::value_type const* first = 0;
T y;
y = create(v, first);
BOOST_TEST(first == &*y.begin());
test::check_container(y, v);
test::check_equivalent_keys(y);
}
}
template <class T>
void move_construct_tests2(T* ptr,
test::random_generator const& generator = test::default_generator)
{
move_construct_tests1(ptr);
BOOST_DEDUCED_TYPENAME T::hasher hf(1);
BOOST_DEDUCED_TYPENAME T::key_equal eq(1);
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::random_values<T> v(500);
T y(create(v, first, hf, eq, al, 0.5));
BOOST_TEST(first == &*y.begin());
test::check_container(y, v);
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
BOOST_TEST(y.max_load_factor() == 0.5); // Not necessarily required.
test::check_equivalent_keys(y);
}
{
// 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_TEST(first != &*y.begin());
test::check_container(y, v);
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
BOOST_TEST(y.max_load_factor() == 2.0); // Not necessarily required.
test::check_equivalent_keys(y);
}
{
test::random_values<T> v(25);
T y(create(v, first, hf, eq, al, 1.0), al);
BOOST_TEST(first == &*y.begin());
test::check_container(y, v);
BOOST_TEST(test::equivalent(y.hash_function(), hf));
BOOST_TEST(test::equivalent(y.key_eq(), eq));
BOOST_TEST(test::equivalent(y.get_allocator(), al));
BOOST_TEST(y.max_load_factor() == 1.0); // Not necessarily required.
test::check_equivalent_keys(y);
}
}
boost::unordered_set<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_set;
boost::unordered_multiset<test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multiset;
boost::unordered_map<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_map;
boost::unordered_multimap<test::object, test::object, test::hash, test::equal_to, test::allocator<test::object> >* test_multimap;
using test::default_generator;
using test::generate_collisions;
UNORDERED_TEST(move_construct_tests1,
((test_set)(test_multiset)(test_map)(test_multimap))
)
UNORDERED_TEST(move_assign_tests1,
((test_set)(test_multiset)(test_map)(test_multimap))
)
UNORDERED_TEST(move_construct_tests2,
((test_set)(test_multiset)(test_map)(test_multimap))
((default_generator)(generate_collisions))
)
}
RUN_TESTS()