Reformat with clang-format

This commit is contained in:
Daniel James
2017-02-19 13:05:17 +00:00
parent 01dcd36c41
commit bf5ef9824d
70 changed files with 13000 additions and 13625 deletions

View File

@@ -15,21 +15,21 @@
// Already defined. // Already defined.
#elif defined(BOOST_LIBSTDCXX11) #elif defined(BOOST_LIBSTDCXX11)
// https://github.com/gcc-mirror/gcc/blob/gcc-4_6-branch/libstdc++-v3/include/bits/stl_pair.h#L70 // https://github.com/gcc-mirror/gcc/blob/gcc-4_6-branch/libstdc++-v3/include/bits/stl_pair.h#L70
# if BOOST_LIBSTDCXX_VERSION > 40600 #if BOOST_LIBSTDCXX_VERSION > 40600
# define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1 #define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
# endif #endif
#elif defined(_LIBCPP_VERSION) #elif defined(_LIBCPP_VERSION)
// https://github.com/llvm-mirror/libcxx/blob/release_30/include/utility#L206 // https://github.com/llvm-mirror/libcxx/blob/release_30/include/utility#L206
# if LIBCPP_VERSION >= 3000 #if LIBCPP_VERSION >= 3000
# define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1 #define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
# endif #endif
#elif defined(BOOST_MSVC) #elif defined(BOOST_MSVC)
// Apparently C++11 standard supported in Visual Studio 2012 // Apparently C++11 standard supported in Visual Studio 2012
// https://msdn.microsoft.com/en-us/library/hh567368.aspx#stl // https://msdn.microsoft.com/en-us/library/hh567368.aspx#stl
// 2012 = VC+11 = BOOST_MSVC 1700 Hopefully! // 2012 = VC+11 = BOOST_MSVC 1700 Hopefully!
# if BOOST_MSVC >= 1700 #if BOOST_MSVC >= 1700
# define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1 #define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
# endif #endif
#endif #endif
#if !defined(BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT) #if !defined(BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT)
@@ -40,16 +40,16 @@
#include <utility> #include <utility>
#endif #endif
namespace boost namespace boost {
{ namespace unordered {
namespace unordered
{
#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT #if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
using std::piecewise_construct_t; using std::piecewise_construct_t;
using std::piecewise_construct; using std::piecewise_construct;
#else #else
struct piecewise_construct_t {}; struct piecewise_construct_t
const piecewise_construct_t piecewise_construct = piecewise_construct_t(); {
};
const piecewise_construct_t piecewise_construct = piecewise_construct_t();
#endif #endif
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -3,13 +3,14 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // 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) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/unordered/unordered_map_fwd.hpp>
#include <boost/unordered/detail/implementation.hpp> #include <boost/unordered/detail/implementation.hpp>
#include <boost/unordered/unordered_map_fwd.hpp>
namespace boost { namespace unordered { namespace detail { namespace boost {
template <typename A, typename K, typename M, typename H, typename P> namespace unordered {
struct map namespace detail {
{ template <typename A, typename K, typename M, typename H, typename P> struct map
{
typedef boost::unordered::detail::map<A, K, M, H, P> types; typedef boost::unordered::detail::map<A, K, M, H, P> types;
typedef A allocator; typedef A allocator;
@@ -18,8 +19,7 @@ namespace boost { namespace unordered { namespace detail {
typedef P key_equal; typedef P key_equal;
typedef K key_type; typedef K key_type;
typedef boost::unordered::detail::allocator_traits<allocator> typedef boost::unordered::detail::allocator_traits<allocator> traits;
traits;
typedef boost::unordered::detail::pick_node<allocator, value_type> pick; typedef boost::unordered::detail::pick_node<allocator, value_type> pick;
typedef typename pick::node node; typedef typename pick::node node;
typedef typename pick::bucket bucket; typedef typename pick::bucket bucket;
@@ -31,19 +31,17 @@ namespace boost { namespace unordered { namespace detail {
typedef typename boost::unordered::detail::pick_policy<K>::type policy; typedef typename boost::unordered::detail::pick_policy<K>::type policy;
typedef boost::unordered::iterator_detail:: typedef boost::unordered::iterator_detail::iterator<node> iterator;
iterator<node> iterator; typedef boost::unordered::iterator_detail::c_iterator<node> c_iterator;
typedef boost::unordered::iterator_detail:: typedef boost::unordered::iterator_detail::l_iterator<node, policy>
c_iterator<node> c_iterator; l_iterator;
typedef boost::unordered::iterator_detail:: typedef boost::unordered::iterator_detail::cl_iterator<node, policy>
l_iterator<node, policy> l_iterator; cl_iterator;
typedef boost::unordered::iterator_detail:: };
cl_iterator<node, policy> cl_iterator;
};
template <typename A, typename K, typename M, typename H, typename P> template <typename A, typename K, typename M, typename H, typename P>
struct multimap struct multimap
{ {
typedef boost::unordered::detail::multimap<A, K, M, H, P> types; typedef boost::unordered::detail::multimap<A, K, M, H, P> types;
typedef A allocator; typedef A allocator;
@@ -53,8 +51,8 @@ namespace boost { namespace unordered { namespace detail {
typedef K key_type; typedef K key_type;
typedef boost::unordered::detail::allocator_traits<allocator> traits; typedef boost::unordered::detail::allocator_traits<allocator> traits;
typedef boost::unordered::detail::pick_grouped_node<allocator, typedef boost::unordered::detail::pick_grouped_node<allocator, value_type>
value_type> pick; pick;
typedef typename pick::node node; typedef typename pick::node node;
typedef typename pick::bucket bucket; typedef typename pick::bucket bucket;
typedef typename pick::link_pointer link_pointer; typedef typename pick::link_pointer link_pointer;
@@ -65,14 +63,13 @@ namespace boost { namespace unordered { namespace detail {
typedef typename boost::unordered::detail::pick_policy<K>::type policy; typedef typename boost::unordered::detail::pick_policy<K>::type policy;
typedef boost::unordered::iterator_detail:: typedef boost::unordered::iterator_detail::iterator<node> iterator;
iterator<node> iterator; typedef boost::unordered::iterator_detail::c_iterator<node> c_iterator;
typedef boost::unordered::iterator_detail:: typedef boost::unordered::iterator_detail::l_iterator<node, policy>
c_iterator<node> c_iterator; l_iterator;
typedef boost::unordered::iterator_detail:: typedef boost::unordered::iterator_detail::cl_iterator<node, policy>
l_iterator<node, policy> l_iterator; cl_iterator;
typedef boost::unordered::iterator_detail:: };
cl_iterator<node, policy> cl_iterator; }
}; }
}
}}}

View File

@@ -3,13 +3,14 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // 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) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/unordered/unordered_set_fwd.hpp>
#include <boost/unordered/detail/implementation.hpp> #include <boost/unordered/detail/implementation.hpp>
#include <boost/unordered/unordered_set_fwd.hpp>
namespace boost { namespace unordered { namespace detail { namespace boost {
template <typename A, typename T, typename H, typename P> namespace unordered {
struct set namespace detail {
{ template <typename A, typename T, typename H, typename P> struct set
{
typedef boost::unordered::detail::set<A, T, H, P> types; typedef boost::unordered::detail::set<A, T, H, P> types;
typedef A allocator; typedef A allocator;
@@ -29,19 +30,16 @@ namespace boost { namespace unordered { namespace detail {
typedef typename boost::unordered::detail::pick_policy<T>::type policy; typedef typename boost::unordered::detail::pick_policy<T>::type policy;
typedef boost::unordered::iterator_detail:: typedef boost::unordered::iterator_detail::c_iterator<node> iterator;
c_iterator<node> iterator; typedef boost::unordered::iterator_detail::c_iterator<node> c_iterator;
typedef boost::unordered::iterator_detail:: typedef boost::unordered::iterator_detail::cl_iterator<node, policy>
c_iterator<node> c_iterator; l_iterator;
typedef boost::unordered::iterator_detail:: typedef boost::unordered::iterator_detail::cl_iterator<node, policy>
cl_iterator<node, policy> l_iterator; cl_iterator;
typedef boost::unordered::iterator_detail:: };
cl_iterator<node, policy> cl_iterator;
};
template <typename A, typename T, typename H, typename P> template <typename A, typename T, typename H, typename P> struct multiset
struct multiset {
{
typedef boost::unordered::detail::multiset<A, T, H, P> types; typedef boost::unordered::detail::multiset<A, T, H, P> types;
typedef A allocator; typedef A allocator;
@@ -51,8 +49,8 @@ namespace boost { namespace unordered { namespace detail {
typedef T key_type; typedef T key_type;
typedef boost::unordered::detail::allocator_traits<allocator> traits; typedef boost::unordered::detail::allocator_traits<allocator> traits;
typedef boost::unordered::detail::pick_grouped_node<allocator, typedef boost::unordered::detail::pick_grouped_node<allocator, value_type>
value_type> pick; pick;
typedef typename pick::node node; typedef typename pick::node node;
typedef typename pick::bucket bucket; typedef typename pick::bucket bucket;
typedef typename pick::link_pointer link_pointer; typedef typename pick::link_pointer link_pointer;
@@ -62,13 +60,13 @@ namespace boost { namespace unordered { namespace detail {
typedef typename boost::unordered::detail::pick_policy<T>::type policy; typedef typename boost::unordered::detail::pick_policy<T>::type policy;
typedef boost::unordered::iterator_detail:: typedef boost::unordered::iterator_detail::c_iterator<node> iterator;
c_iterator<node> iterator; typedef boost::unordered::iterator_detail::c_iterator<node> c_iterator;
typedef boost::unordered::iterator_detail:: typedef boost::unordered::iterator_detail::cl_iterator<node, policy>
c_iterator<node> c_iterator; l_iterator;
typedef boost::unordered::iterator_detail:: typedef boost::unordered::iterator_detail::cl_iterator<node, policy>
cl_iterator<node, policy> l_iterator; cl_iterator;
typedef boost::unordered::iterator_detail:: };
cl_iterator<node, policy> cl_iterator; }
}; }
}}} }

File diff suppressed because it is too large Load Diff

View File

@@ -11,55 +11,48 @@
#pragma once #pragma once
#endif #endif
#include <memory>
#include <functional>
#include <boost/functional/hash_fwd.hpp> #include <boost/functional/hash_fwd.hpp>
#include <boost/unordered/detail/fwd.hpp> #include <boost/unordered/detail/fwd.hpp>
#include <functional>
#include <memory>
namespace boost namespace boost {
{ namespace unordered {
namespace unordered template <class K, class T, class H = boost::hash<K>,
{
template <class K,
class T,
class H = boost::hash<K>,
class P = std::equal_to<K>, class P = std::equal_to<K>,
class A = std::allocator<std::pair<const K, T> > > class A = std::allocator<std::pair<const K, T> > >
class unordered_map; class unordered_map;
template <class K, class T, class H, class P, class A> template <class K, class T, class H, class P, class A>
inline bool operator==(unordered_map<K, T, H, P, A> const&, inline bool operator==(
unordered_map<K, T, H, P, A> const&); unordered_map<K, T, H, P, A> const&, unordered_map<K, T, H, P, A> const&);
template <class K, class T, class H, class P, class A> template <class K, class T, class H, class P, class A>
inline bool operator!=(unordered_map<K, T, H, P, A> const&, inline bool operator!=(
unordered_map<K, T, H, P, A> const&); unordered_map<K, T, H, P, A> const&, unordered_map<K, T, H, P, A> const&);
template <class K, class T, class H, class P, class A> template <class K, class T, class H, class P, class A>
inline void swap(unordered_map<K, T, H, P, A>&, inline void swap(unordered_map<K, T, H, P, A>&, unordered_map<K, T, H, P, A>&);
unordered_map<K, T, H, P, A>&);
template <class K, template <class K, class T, class H = boost::hash<K>,
class T,
class H = boost::hash<K>,
class P = std::equal_to<K>, class P = std::equal_to<K>,
class A = std::allocator<std::pair<const K, T> > > class A = std::allocator<std::pair<const K, T> > >
class unordered_multimap; class unordered_multimap;
template <class K, class T, class H, class P, class A> template <class K, class T, class H, class P, class A>
inline bool operator==(unordered_multimap<K, T, H, P, A> const&, inline bool operator==(unordered_multimap<K, T, H, P, A> const&,
unordered_multimap<K, T, H, P, A> const&); unordered_multimap<K, T, H, P, A> const&);
template <class K, class T, class H, class P, class A> template <class K, class T, class H, class P, class A>
inline bool operator!=(unordered_multimap<K, T, H, P, A> const&, inline bool operator!=(unordered_multimap<K, T, H, P, A> const&,
unordered_multimap<K, T, H, P, A> const&); unordered_multimap<K, T, H, P, A> const&);
template <class K, class T, class H, class P, class A> template <class K, class T, class H, class P, class A>
inline void swap(unordered_multimap<K, T, H, P, A>&, inline void swap(
unordered_multimap<K, T, H, P, A>&); unordered_multimap<K, T, H, P, A>&, unordered_multimap<K, T, H, P, A>&);
} }
using boost::unordered::unordered_map; using boost::unordered::unordered_map;
using boost::unordered::unordered_multimap; using boost::unordered::unordered_multimap;
using boost::unordered::swap; using boost::unordered::swap;
using boost::unordered::operator==; using boost::unordered::operator==;
using boost::unordered::operator!=; using boost::unordered::operator!=;
} }
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@@ -11,53 +11,46 @@
#pragma once #pragma once
#endif #endif
#include <memory>
#include <functional>
#include <boost/functional/hash_fwd.hpp> #include <boost/functional/hash_fwd.hpp>
#include <boost/unordered/detail/fwd.hpp> #include <boost/unordered/detail/fwd.hpp>
#include <functional>
#include <memory>
namespace boost namespace boost {
{ namespace unordered {
namespace unordered template <class T, class H = boost::hash<T>, class P = std::equal_to<T>,
{
template <class T,
class H = boost::hash<T>,
class P = std::equal_to<T>,
class A = std::allocator<T> > class A = std::allocator<T> >
class unordered_set; class unordered_set;
template <class T, class H, class P, class A> template <class T, class H, class P, class A>
inline bool operator==(unordered_set<T, H, P, A> const&, inline bool operator==(
unordered_set<T, H, P, A> const&); unordered_set<T, H, P, A> const&, unordered_set<T, H, P, A> const&);
template <class T, class H, class P, class A> template <class T, class H, class P, class A>
inline bool operator!=(unordered_set<T, H, P, A> const&, inline bool operator!=(
unordered_set<T, H, P, A> const&); unordered_set<T, H, P, A> const&, unordered_set<T, H, P, A> const&);
template <class T, class H, class P, class A> template <class T, class H, class P, class A>
inline void swap(unordered_set<T, H, P, A> &m1, inline void swap(unordered_set<T, H, P, A>& m1, unordered_set<T, H, P, A>& m2);
unordered_set<T, H, P, A> &m2);
template <class T, template <class T, class H = boost::hash<T>, class P = std::equal_to<T>,
class H = boost::hash<T>,
class P = std::equal_to<T>,
class A = std::allocator<T> > class A = std::allocator<T> >
class unordered_multiset; class unordered_multiset;
template <class T, class H, class P, class A> template <class T, class H, class P, class A>
inline bool operator==(unordered_multiset<T, H, P, A> const&, inline bool operator==(unordered_multiset<T, H, P, A> const&,
unordered_multiset<T, H, P, A> const&); unordered_multiset<T, H, P, A> const&);
template <class T, class H, class P, class A> template <class T, class H, class P, class A>
inline bool operator!=(unordered_multiset<T, H, P, A> const&, inline bool operator!=(unordered_multiset<T, H, P, A> const&,
unordered_multiset<T, H, P, A> const&); unordered_multiset<T, H, P, A> const&);
template <class T, class H, class P, class A> template <class T, class H, class P, class A>
inline void swap(unordered_multiset<T, H, P, A> &m1, inline void swap(
unordered_multiset<T, H, P, A> &m2); unordered_multiset<T, H, P, A>& m1, unordered_multiset<T, H, P, A>& m2);
} }
using boost::unordered::unordered_set; using boost::unordered::unordered_set;
using boost::unordered::unordered_multiset; using boost::unordered::unordered_multiset;
using boost::unordered::swap; using boost::unordered::swap;
using boost::unordered::operator==; using boost::unordered::operator==;
using boost::unordered::operator!=; using boost::unordered::operator!=;
} }
#endif #endif

View File

@@ -5,17 +5,16 @@
#include "./containers.hpp" #include "./containers.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/invariants.hpp" #include "../helpers/invariants.hpp"
#include "../helpers/random_values.hpp"
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
#pragma warning(disable:4512) // assignment operator could not be generated #pragma warning(disable : 4512) // assignment operator could not be generated
#endif #endif
test::seed_t initialize_seed(12847); test::seed_t initialize_seed(12847);
template <class T> template <class T> struct self_assign_base : public test::exception_base
struct self_assign_base : public test::exception_base
{ {
test::random_values<T> values; test::random_values<T> values;
self_assign_base(std::size_t count = 0) : values(count) {} self_assign_base(std::size_t count = 0) : values(count) {}
@@ -24,31 +23,31 @@ struct self_assign_base : public test::exception_base
T init() const { return T(values.begin(), values.end()); } T init() const { return T(values.begin(), values.end()); }
void run(T& x) const { x = x; } void run(T& x) const { x = x; }
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const
{ test::check_equivalent_keys(x); } {
test::check_equivalent_keys(x);
}
}; };
template <class T> template <class T> struct self_assign_test1 : self_assign_base<T>
struct self_assign_test1 : self_assign_base<T> {}; {
};
template <class T> template <class T> struct self_assign_test2 : self_assign_base<T>
struct self_assign_test2 : self_assign_base<T>
{ {
self_assign_test2() : self_assign_base<T>(100) {} self_assign_test2() : self_assign_base<T>(100) {}
}; };
template <class T> template <class T> struct assign_base : public test::exception_base
struct assign_base : public test::exception_base
{ {
test::random_values<T> x_values, y_values; test::random_values<T> x_values, y_values;
T x,y; T x, y;
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher; typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal; typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type; typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type;
assign_base(int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0) : assign_base(int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0)
x_values(), : x_values(), y_values(),
y_values(),
x(0, hasher(tag1), key_equal(tag1), allocator_type(tag1)), x(0, hasher(tag1), key_equal(tag1), allocator_type(tag1)),
y(0, hasher(tag2), key_equal(tag2), allocator_type(tag2)) y(0, hasher(tag2), key_equal(tag2), allocator_type(tag2))
{ {
@@ -74,12 +73,11 @@ struct assign_base : public test::exception_base
} }
}; };
template <class T> template <class T> struct assign_values : assign_base<T>
struct assign_values : assign_base<T>
{ {
assign_values(unsigned int count1, unsigned int count2, assign_values(unsigned int count1, unsigned int count2, int tag1, int tag2,
int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0) : float mlf1 = 1.0, float mlf2 = 1.0)
assign_base<T>(tag1, tag2, mlf1, mlf2) : assign_base<T>(tag1, tag2, mlf1, mlf2)
{ {
this->x_values.fill(count1); this->x_values.fill(count1);
this->y_values.fill(count2); this->y_values.fill(count2);
@@ -88,47 +86,39 @@ struct assign_values : assign_base<T>
} }
}; };
template <class T> template <class T> struct assign_test1 : assign_values<T>
struct assign_test1 : assign_values<T>
{ {
assign_test1() : assign_values<T>(0, 0, 0, 0) {} assign_test1() : assign_values<T>(0, 0, 0, 0) {}
}; };
template <class T> template <class T> struct assign_test2 : assign_values<T>
struct assign_test2 : assign_values<T>
{ {
assign_test2() : assign_values<T>(60, 0, 0, 0) {} assign_test2() : assign_values<T>(60, 0, 0, 0) {}
}; };
template <class T> template <class T> struct assign_test3 : assign_values<T>
struct assign_test3 : assign_values<T>
{ {
assign_test3() : assign_values<T>(0, 60, 0, 0) {} assign_test3() : assign_values<T>(0, 60, 0, 0) {}
}; };
template <class T> template <class T> struct assign_test4 : assign_values<T>
struct assign_test4 : assign_values<T>
{ {
assign_test4() : assign_values<T>(10, 10, 1, 2) {} assign_test4() : assign_values<T>(10, 10, 1, 2) {}
}; };
template <class T> template <class T> struct assign_test4a : assign_values<T>
struct assign_test4a : assign_values<T>
{ {
assign_test4a() : assign_values<T>(10, 100, 1, 2) {} assign_test4a() : assign_values<T>(10, 100, 1, 2) {}
}; };
template <class T> template <class T> struct assign_test5 : assign_values<T>
struct assign_test5 : assign_values<T>
{ {
assign_test5() : assign_values<T>(5, 60, 0, 0, 1.0f, 0.1f) {} assign_test5() : assign_values<T>(5, 60, 0, 0, 1.0f, 0.1f) {}
}; };
template <class T> template <class T> struct equivalent_test1 : assign_base<T>
struct equivalent_test1 : assign_base<T>
{ {
equivalent_test1() : equivalent_test1() : assign_base<T>(0, 0)
assign_base<T>(0, 0)
{ {
test::random_values<T> x_values2(10); test::random_values<T> x_values2(10);
this->x_values.insert(x_values2.begin(), x_values2.end()); this->x_values.insert(x_values2.begin(), x_values2.end());
@@ -141,9 +131,8 @@ struct equivalent_test1 : assign_base<T>
} }
}; };
EXCEPTION_TESTS( EXCEPTION_TESTS((self_assign_test1)(self_assign_test2)(assign_test1)(
(self_assign_test1)(self_assign_test2) assign_test2)(assign_test3)(assign_test4)(assign_test4a)(
(assign_test1)(assign_test2)(assign_test3)(assign_test4)(assign_test4a)(assign_test5) assign_test5)(equivalent_test1),
(equivalent_test1),
CONTAINER_SEQ) CONTAINER_SEQ)
RUN_TESTS() RUN_TESTS()

View File

@@ -5,8 +5,8 @@
#include "./containers.hpp" #include "./containers.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/input_iterator.hpp" #include "../helpers/input_iterator.hpp"
#include "../helpers/random_values.hpp"
template <typename T> inline void avoid_unused_warning(T const&) {} template <typename T> inline void avoid_unused_warning(T const&) {}
@@ -20,62 +20,61 @@ struct objects
test::exception::allocator<test::exception::object> allocator; test::exception::allocator<test::exception::object> allocator;
}; };
template <class T> template <class T> struct construct_test1 : public objects, test::exception_base
struct construct_test1 : public objects, test::exception_base
{ {
void run() const { void run() const
{
T x; T x;
avoid_unused_warning(x); avoid_unused_warning(x);
} }
}; };
template <class T> template <class T> struct construct_test2 : public objects, test::exception_base
struct construct_test2 : public objects, test::exception_base
{ {
void run() const { void run() const
{
T x(300); T x(300);
avoid_unused_warning(x); avoid_unused_warning(x);
} }
}; };
template <class T> template <class T> struct construct_test3 : public objects, test::exception_base
struct construct_test3 : public objects, test::exception_base
{ {
void run() const { void run() const
{
T x(0, hash); T x(0, hash);
avoid_unused_warning(x); avoid_unused_warning(x);
} }
}; };
template <class T> template <class T> struct construct_test4 : public objects, test::exception_base
struct construct_test4 : public objects, test::exception_base
{ {
void run() const { void run() const
{
T x(0, hash, equal_to); T x(0, hash, equal_to);
avoid_unused_warning(x); avoid_unused_warning(x);
} }
}; };
template <class T> template <class T> struct construct_test5 : public objects, test::exception_base
struct construct_test5 : public objects, test::exception_base
{ {
void run() const { void run() const
{
T x(50, hash, equal_to, allocator); T x(50, hash, equal_to, allocator);
avoid_unused_warning(x); avoid_unused_warning(x);
} }
}; };
template <class T> template <class T> struct construct_test6 : public objects, test::exception_base
struct construct_test6 : public objects, test::exception_base
{ {
void run() const { void run() const
{
T x(allocator); T x(allocator);
avoid_unused_warning(x); avoid_unused_warning(x);
} }
}; };
template <class T> template <class T> struct range : public test::exception_base
struct range : public test::exception_base
{ {
test::random_values<T> values; test::random_values<T> values;
@@ -83,37 +82,37 @@ struct range : public test::exception_base
range(unsigned int count) : values(count) {} range(unsigned int count) : values(count) {}
}; };
template <class T> template <class T> struct range_construct_test1 : public range<T>, objects
struct range_construct_test1 : public range<T>, objects
{ {
void run() const { void run() const
{
T x(this->values.begin(), this->values.end()); T x(this->values.begin(), this->values.end());
avoid_unused_warning(x); avoid_unused_warning(x);
} }
}; };
template <class T> template <class T> struct range_construct_test2 : public range<T>, objects
struct range_construct_test2 : public range<T>, objects
{ {
void run() const { void run() const
{
T x(this->values.begin(), this->values.end(), 0); T x(this->values.begin(), this->values.end(), 0);
avoid_unused_warning(x); avoid_unused_warning(x);
} }
}; };
template <class T> template <class T> struct range_construct_test3 : public range<T>, objects
struct range_construct_test3 : public range<T>, objects
{ {
void run() const { void run() const
{
T x(this->values.begin(), this->values.end(), 0, hash); T x(this->values.begin(), this->values.end(), 0, hash);
avoid_unused_warning(x); avoid_unused_warning(x);
} }
}; };
template <class T> template <class T> struct range_construct_test4 : public range<T>, objects
struct range_construct_test4 : public range<T>, objects
{ {
void run() const { void run() const
{
T x(this->values.begin(), this->values.end(), 100, hash, equal_to); T x(this->values.begin(), this->values.end(), 100, hash, equal_to);
avoid_unused_warning(x); avoid_unused_warning(x);
} }
@@ -121,58 +120,51 @@ struct range_construct_test4 : public range<T>, objects
// Need to run at least one test with a fairly large number // Need to run at least one test with a fairly large number
// of objects in case it triggers a rehash. // of objects in case it triggers a rehash.
template <class T> template <class T> struct range_construct_test5 : public range<T>, objects
struct range_construct_test5 : public range<T>, objects
{ {
range_construct_test5() : range<T>(60) {} range_construct_test5() : range<T>(60) {}
void run() const { void run() const
T x(this->values.begin(), this->values.end(), 0, {
hash, equal_to, allocator); T x(this->values.begin(), this->values.end(), 0, hash, equal_to,
allocator);
avoid_unused_warning(x); avoid_unused_warning(x);
} }
}; };
template <class T> template <class T> struct input_range_construct_test : public range<T>, objects
struct input_range_construct_test : public range<T>, objects
{ {
input_range_construct_test() : range<T>(60) {} input_range_construct_test() : range<T>(60) {}
void run() const { void run() const
{
BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
begin = this->values.begin(), end = this->values.end(); begin = this->values.begin(),
T x(test::input_iterator(begin), test::input_iterator(end), end = this->values.end();
0, hash, equal_to, allocator); T x(test::input_iterator(begin), test::input_iterator(end), 0, hash,
equal_to, allocator);
avoid_unused_warning(x); avoid_unused_warning(x);
} }
}; };
template <class T> template <class T> struct copy_range_construct_test : public range<T>, objects
struct copy_range_construct_test : public range<T>, objects
{ {
copy_range_construct_test() : range<T>(60) {} copy_range_construct_test() : range<T>(60) {}
void run() const { void run() const
{
T x(test::copy_iterator(this->values.begin()), T x(test::copy_iterator(this->values.begin()),
test::copy_iterator(this->values.end()), test::copy_iterator(this->values.end()), 0, hash, equal_to,
0, hash, equal_to, allocator); allocator);
avoid_unused_warning(x); avoid_unused_warning(x);
} }
}; };
EXCEPTION_TESTS( EXCEPTION_TESTS(
(construct_test1) (construct_test1)(construct_test2)(construct_test3)(construct_test4)(
(construct_test2) construct_test5)(construct_test6)(range_construct_test1)(
(construct_test3) range_construct_test2)(range_construct_test3)(range_construct_test4)(
(construct_test4) range_construct_test5)(input_range_construct_test)(
(construct_test5) copy_range_construct_test),
(construct_test6)
(range_construct_test1)
(range_construct_test2)
(range_construct_test3)
(range_construct_test4)
(range_construct_test5)
(input_range_construct_test)
(copy_range_construct_test),
CONTAINER_SEQ) CONTAINER_SEQ)
RUN_TESTS() RUN_TESTS()

View File

@@ -12,39 +12,33 @@
#include "../objects/exception.hpp" #include "../objects/exception.hpp"
typedef boost::unordered_set< typedef boost::unordered_set<test::exception::object, test::exception::hash,
test::exception::object,
test::exception::hash,
test::exception::equal_to, test::exception::equal_to,
test::exception::allocator<test::exception::object> > test_set; test::exception::allocator<test::exception::object> >
typedef boost::unordered_multiset< test_set;
test::exception::object, typedef boost::unordered_multiset<test::exception::object,
test::exception::hash, test::exception::hash, test::exception::equal_to,
test::exception::equal_to, test::exception::allocator2<test::exception::object> >
test::exception::allocator2<test::exception::object> > test_multiset; test_multiset;
typedef boost::unordered_map< typedef boost::unordered_map<test::exception::object, test::exception::object,
test::exception::object, test::exception::hash, test::exception::equal_to,
test::exception::object, test::exception::allocator2<test::exception::object> >
test::exception::hash, test_map;
test::exception::equal_to, typedef boost::unordered_multimap<test::exception::object,
test::exception::allocator2<test::exception::object> > test_map; test::exception::object, test::exception::hash, test::exception::equal_to,
typedef boost::unordered_multimap< test::exception::allocator<test::exception::object> >
test::exception::object, test_multimap;
test::exception::object,
test::exception::hash,
test::exception::equal_to,
test::exception::allocator<test::exception::object> > test_multimap;
typedef boost::unordered_set< typedef boost::unordered_set<
std::pair<test::exception::object, test::exception::object>, std::pair<test::exception::object, test::exception::object>,
test::exception::hash, test::exception::hash, test::exception::equal_to,
test::exception::equal_to, test::exception::allocator<test::exception::object> >
test::exception::allocator<test::exception::object> > test_pair_set; test_pair_set;
typedef boost::unordered_multiset< typedef boost::unordered_multiset<
std::pair<test::exception::object, test::exception::object>, std::pair<test::exception::object, test::exception::object>,
test::exception::hash, test::exception::hash, test::exception::equal_to,
test::exception::equal_to, test::exception::allocator2<test::exception::object> >
test::exception::allocator2<test::exception::object> > test_pair_multiset; test_pair_multiset;
#define CONTAINER_SEQ (test_set)(test_multiset)(test_map)(test_multimap) #define CONTAINER_SEQ (test_set)(test_multiset)(test_map)(test_multimap)
#define CONTAINER_PAIR_SEQ (test_pair_set)(test_pair_multiset)(test_map)(test_multimap) #define CONTAINER_PAIR_SEQ \
(test_pair_set)(test_pair_multiset)(test_map)(test_multimap)

View File

@@ -11,47 +11,46 @@ template <typename T> inline void avoid_unused_warning(T const&) {}
test::seed_t initialize_seed(73041); test::seed_t initialize_seed(73041);
template <class T> template <class T> struct copy_test1 : public test::exception_base
struct copy_test1 : public test::exception_base
{ {
T x; T x;
void run() const { void run() const
{
T y(x); T y(x);
avoid_unused_warning(y); avoid_unused_warning(y);
} }
}; };
template <class T> template <class T> struct copy_test2 : public test::exception_base
struct copy_test2 : public test::exception_base
{ {
test::random_values<T> values; test::random_values<T> values;
T x; T x;
copy_test2() : values(5), x(values.begin(), values.end()) {} copy_test2() : values(5), x(values.begin(), values.end()) {}
void run() const { void run() const
{
T y(x); T y(x);
avoid_unused_warning(y); avoid_unused_warning(y);
} }
}; };
template <class T> template <class T> struct copy_test3 : public test::exception_base
struct copy_test3 : public test::exception_base
{ {
test::random_values<T> values; test::random_values<T> values;
T x; T x;
copy_test3() : values(100), x(values.begin(), values.end()) {} copy_test3() : values(100), x(values.begin(), values.end()) {}
void run() const { void run() const
{
T y(x); T y(x);
avoid_unused_warning(y); avoid_unused_warning(y);
} }
}; };
template <class T> template <class T> struct copy_with_allocator_test : public test::exception_base
struct copy_with_allocator_test : public test::exception_base
{ {
test::random_values<T> values; test::random_values<T> values;
T x; T x;
@@ -59,13 +58,13 @@ struct copy_with_allocator_test : public test::exception_base
copy_with_allocator_test() : values(100), x(values.begin(), values.end()) {} copy_with_allocator_test() : values(100), x(values.begin(), values.end()) {}
void run() const { void run() const
{
T y(x, allocator); T y(x, allocator);
avoid_unused_warning(y); avoid_unused_warning(y);
} }
}; };
EXCEPTION_TESTS( EXCEPTION_TESTS((copy_test1)(copy_test2)(copy_test3)(copy_with_allocator_test),
(copy_test1)(copy_test2)(copy_test3)(copy_with_allocator_test),
CONTAINER_SEQ) CONTAINER_SEQ)
RUN_TESTS() RUN_TESTS()

View File

@@ -5,25 +5,23 @@
#include "./containers.hpp" #include "./containers.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/invariants.hpp"
#include "../helpers/helpers.hpp" #include "../helpers/helpers.hpp"
#include "../helpers/invariants.hpp"
#include "../helpers/random_values.hpp"
test::seed_t initialize_seed(835193); test::seed_t initialize_seed(835193);
template <class T> template <class T> struct erase_test_base : public test::exception_base
struct erase_test_base : public test::exception_base
{ {
test::random_values<T> values; test::random_values<T> values;
erase_test_base(unsigned int count = 5) : values(count) {} erase_test_base(unsigned int count = 5) : values(count) {}
typedef T data_type; typedef T data_type;
data_type init() const { data_type init() const { return T(values.begin(), values.end()); }
return T(values.begin(), values.end());
}
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const { void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const
{
std::string scope(test::scope); std::string scope(test::scope);
BOOST_TEST(scope.find("hash::") != std::string::npos || BOOST_TEST(scope.find("hash::") != std::string::npos ||
@@ -34,23 +32,19 @@ struct erase_test_base : public test::exception_base
} }
}; };
template <class T> template <class T> struct erase_by_key_test1 : public erase_test_base<T>
struct erase_by_key_test1 : public erase_test_base<T>
{ {
void run(T& x) const void run(T& x) const
{ {
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
test::random_values<T>::const_iterator iterator; iterator;
for(iterator it = this->values.begin(), end = this->values.end(); for (iterator it = this->values.begin(), end = this->values.end();
it != end; ++it) it != end; ++it) {
{
x.erase(test::get_key<T>(*it)); x.erase(test::get_key<T>(*it));
} }
} }
}; };
EXCEPTION_TESTS( EXCEPTION_TESTS((erase_by_key_test1), CONTAINER_SEQ)
(erase_by_key_test1),
CONTAINER_SEQ)
RUN_TESTS() RUN_TESTS()

View File

@@ -5,51 +5,52 @@
#include "./containers.hpp" #include "./containers.hpp"
#include <string>
#include "../helpers/random_values.hpp"
#include "../helpers/invariants.hpp"
#include "../helpers/strong.hpp"
#include "../helpers/helpers.hpp" #include "../helpers/helpers.hpp"
#include "../helpers/invariants.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/strong.hpp"
#include <cmath> #include <cmath>
#include <string>
test::seed_t initialize_seed(747373); test::seed_t initialize_seed(747373);
template <class T> template <class T> struct insert_test_base : public test::exception_base
struct insert_test_base : public test::exception_base
{ {
test::random_values<T> values; test::random_values<T> values;
insert_test_base(unsigned int count = 5) : values(count, test::limited_range) {} insert_test_base(unsigned int count = 5)
: values(count, test::limited_range)
{
}
typedef T data_type; typedef T data_type;
typedef test::strong<T> strong_type; typedef test::strong<T> strong_type;
data_type init() const { data_type init() const { return T(); }
return T();
}
void check BOOST_PREVENT_MACRO_SUBSTITUTION( void check BOOST_PREVENT_MACRO_SUBSTITUTION(
T const& x, strong_type const& strong) const T const& x, strong_type const& strong) const
{ {
std::string scope(test::scope); std::string scope(test::scope);
if(scope.find("hash::operator()") == std::string::npos) if (scope.find("hash::operator()") == std::string::npos)
strong.test(x, test::detail::tracker.count_allocations); strong.test(x, test::detail::tracker.count_allocations);
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
}; };
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template <class T> template <class T> struct emplace_test1 : public insert_test_base<T>
struct emplace_test1 : public insert_test_base<T>
{ {
typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type; typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
void run(T& x, strong_type& strong) const { void run(T& x, strong_type& strong) const
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
it = this->values.begin(), end = this->values.end();
it != end; ++it)
{ {
for (BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
it = this->values.begin(),
end = this->values.end();
it != end; ++it) {
strong.store(x, test::detail::tracker.count_allocations); strong.store(x, test::detail::tracker.count_allocations);
x.emplace(*it); x.emplace(*it);
} }
@@ -58,74 +59,72 @@ struct emplace_test1 : public insert_test_base<T>
#endif #endif
template <class T> template <class T> struct insert_test1 : public insert_test_base<T>
struct insert_test1 : public insert_test_base<T>
{ {
typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type; typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
void run(T& x, strong_type& strong) const { void run(T& x, strong_type& strong) const
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
it = this->values.begin(), end = this->values.end();
it != end; ++it)
{ {
for (BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
it = this->values.begin(),
end = this->values.end();
it != end; ++it) {
strong.store(x, test::detail::tracker.count_allocations); strong.store(x, test::detail::tracker.count_allocations);
x.insert(*it); x.insert(*it);
} }
} }
}; };
template <class T> template <class T> struct insert_test2 : public insert_test_base<T>
struct insert_test2 : public insert_test_base<T>
{ {
typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type; typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
void run(T& x, strong_type& strong) const { void run(T& x, strong_type& strong) const
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
it = this->values.begin(), end = this->values.end();
it != end; ++it)
{ {
for (BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
it = this->values.begin(),
end = this->values.end();
it != end; ++it) {
strong.store(x, test::detail::tracker.count_allocations); strong.store(x, test::detail::tracker.count_allocations);
x.insert(x.begin(), *it); x.insert(x.begin(), *it);
} }
} }
}; };
template <class T> template <class T> struct insert_test3 : public insert_test_base<T>
struct insert_test3 : public insert_test_base<T>
{ {
void run(T& x) const { void run(T& x) const { x.insert(this->values.begin(), this->values.end()); }
x.insert(this->values.begin(), this->values.end());
}
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const { void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const
{
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
}; };
template <class T> template <class T> struct insert_test4 : public insert_test_base<T>
struct insert_test4 : public insert_test_base<T>
{ {
typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type; typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
void run(T& x, strong_type& strong) const { void run(T& x, strong_type& strong) const
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
it = this->values.begin(), end = this->values.end();
it != end; ++it)
{ {
for (BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
it = this->values.begin(),
end = this->values.end();
it != end; ++it) {
strong.store(x, test::detail::tracker.count_allocations); strong.store(x, test::detail::tracker.count_allocations);
x.insert(it, test::next(it)); x.insert(it, test::next(it));
} }
} }
}; };
template <class T> template <class T> struct insert_test_rehash1 : public insert_test_base<T>
struct insert_test_rehash1 : public insert_test_base<T>
{ {
typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type; typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
insert_test_rehash1() : insert_test_base<T>(1000) {} insert_test_rehash1() : insert_test_base<T>(1000) {}
T init() const { T init() const
{
using namespace std; using namespace std;
typedef BOOST_DEDUCED_TYPENAME T::size_type size_type; typedef BOOST_DEDUCED_TYPENAME T::size_type size_type;
@@ -134,7 +133,7 @@ struct insert_test_rehash1 : public insert_test_base<T>
// TODO: This doesn't really work is bucket_count is 0 // TODO: This doesn't really work is bucket_count is 0
size_type bucket_count = x.bucket_count(); size_type bucket_count = x.bucket_count();
size_type initial_elements = static_cast<size_type>( size_type initial_elements = static_cast<size_type>(
ceil((double) bucket_count * (double) x.max_load_factor()) - 1); ceil((double)bucket_count * (double)x.max_load_factor()) - 1);
BOOST_TEST(initial_elements < this->values.size()); BOOST_TEST(initial_elements < this->values.size());
x.insert(this->values.begin(), x.insert(this->values.begin(),
test::next(this->values.begin(), initial_elements)); test::next(this->values.begin(), initial_elements));
@@ -142,16 +141,16 @@ struct insert_test_rehash1 : public insert_test_base<T>
return x; return x;
} }
void run(T& x, strong_type& strong) const { void run(T& x, strong_type& strong) const
{
BOOST_DEDUCED_TYPENAME T::size_type bucket_count = x.bucket_count(); BOOST_DEDUCED_TYPENAME T::size_type bucket_count = x.bucket_count();
int count = 0; int count = 0;
BOOST_DEDUCED_TYPENAME T::const_iterator pos = x.cbegin(); BOOST_DEDUCED_TYPENAME T::const_iterator pos = x.cbegin();
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator for (BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
it = test::next(this->values.begin(), x.size()), it = test::next(this->values.begin(), x.size()),
end = this->values.end(); end = this->values.end();
it != end && count < 10; ++it, ++count) it != end && count < 10; ++it, ++count) {
{
strong.store(x, test::detail::tracker.count_allocations); strong.store(x, test::detail::tracker.count_allocations);
pos = x.insert(pos, *it); pos = x.insert(pos, *it);
} }
@@ -162,20 +161,19 @@ struct insert_test_rehash1 : public insert_test_base<T>
} }
}; };
template <class T> template <class T> struct insert_test_rehash2 : public insert_test_rehash1<T>
struct insert_test_rehash2 : public insert_test_rehash1<T>
{ {
typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type; typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
void run(T& x, strong_type& strong) const { void run(T& x, strong_type& strong) const
{
BOOST_DEDUCED_TYPENAME T::size_type bucket_count = x.bucket_count(); BOOST_DEDUCED_TYPENAME T::size_type bucket_count = x.bucket_count();
int count = 0; int count = 0;
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator for (BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
it = test::next(this->values.begin(), x.size()), it = test::next(this->values.begin(), x.size()),
end = this->values.end(); end = this->values.end();
it != end && count < 10; ++it, ++count) it != end && count < 10; ++it, ++count) {
{
strong.store(x, test::detail::tracker.count_allocations); strong.store(x, test::detail::tracker.count_allocations);
x.insert(*it); x.insert(*it);
} }
@@ -186,15 +184,15 @@ struct insert_test_rehash2 : public insert_test_rehash1<T>
} }
}; };
template <class T> template <class T> struct insert_test_rehash3 : public insert_test_base<T>
struct insert_test_rehash3 : public insert_test_base<T>
{ {
BOOST_DEDUCED_TYPENAME T::size_type mutable BOOST_DEDUCED_TYPENAME T::size_type mutable rehash_bucket_count,
rehash_bucket_count, original_bucket_count; original_bucket_count;
insert_test_rehash3() : insert_test_base<T>(1000) {} insert_test_rehash3() : insert_test_base<T>(1000) {}
T init() const { T init() const
{
using namespace std; using namespace std;
typedef BOOST_DEDUCED_TYPENAME T::size_type size_type; typedef BOOST_DEDUCED_TYPENAME T::size_type size_type;
@@ -202,8 +200,10 @@ struct insert_test_rehash3 : public insert_test_base<T>
x.max_load_factor(0.25); x.max_load_factor(0.25);
original_bucket_count = x.bucket_count(); original_bucket_count = x.bucket_count();
rehash_bucket_count = static_cast<size_type>( rehash_bucket_count =
ceil((double) original_bucket_count * (double) x.max_load_factor())) - 1; static_cast<size_type>(ceil(
(double)original_bucket_count * (double)x.max_load_factor())) -
1;
size_type initial_elements = size_type initial_elements =
rehash_bucket_count > 5 ? rehash_bucket_count - 5 : 1; rehash_bucket_count > 5 ? rehash_bucket_count - 5 : 1;
@@ -215,7 +215,8 @@ struct insert_test_rehash3 : public insert_test_base<T>
return x; return x;
} }
void run(T& x) const { void run(T& x) const
{
BOOST_DEDUCED_TYPENAME T::size_type bucket_count = x.bucket_count(); BOOST_DEDUCED_TYPENAME T::size_type bucket_count = x.bucket_count();
x.insert(test::next(this->values.begin(), x.size()), x.insert(test::next(this->values.begin(), x.size()),
@@ -226,54 +227,55 @@ struct insert_test_rehash3 : public insert_test_base<T>
BOOST_TEST(x.bucket_count() != bucket_count); BOOST_TEST(x.bucket_count() != bucket_count);
} }
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const { void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const
if(x.size() < rehash_bucket_count) { {
//BOOST_TEST(x.bucket_count() == original_bucket_count); if (x.size() < rehash_bucket_count) {
// BOOST_TEST(x.bucket_count() == original_bucket_count);
} }
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
}; };
#define BASIC_TESTS \ #define BASIC_TESTS \
(insert_test1)(insert_test2)(insert_test3)(insert_test4) \ (insert_test1)(insert_test2)(insert_test3)(insert_test4)( \
(insert_test_rehash1)(insert_test_rehash2)(insert_test_rehash3) insert_test_rehash1)(insert_test_rehash2)(insert_test_rehash3)
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
#define ALL_TESTS (emplace_test1)BASIC_TESTS !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
#define ALL_TESTS (emplace_test1) BASIC_TESTS
#else #else
#define ALL_TESTS BASIC_TESTS #define ALL_TESTS BASIC_TESTS
#endif #endif
EXCEPTION_TESTS(ALL_TESTS, CONTAINER_SEQ) EXCEPTION_TESTS(ALL_TESTS, CONTAINER_SEQ)
template <class T> template <class T> struct pair_emplace_test1 : public insert_test_base<T>
struct pair_emplace_test1 : public insert_test_base<T>
{ {
typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type; typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
void run(T& x, strong_type& strong) const { void run(T& x, strong_type& strong) const
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
it = this->values.begin(), end = this->values.end();
it != end; ++it)
{ {
for (BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
it = this->values.begin(),
end = this->values.end();
it != end; ++it) {
strong.store(x, test::detail::tracker.count_allocations); strong.store(x, test::detail::tracker.count_allocations);
x.emplace(boost::unordered::piecewise_construct, x.emplace(boost::unordered::piecewise_construct,
boost::make_tuple(it->first), boost::make_tuple(it->first), boost::make_tuple(it->second));
boost::make_tuple(it->second));
} }
} }
}; };
template <class T> template <class T> struct pair_emplace_test2 : public insert_test_base<T>
struct pair_emplace_test2 : public insert_test_base<T>
{ {
typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type; typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
void run(T& x, strong_type& strong) const { void run(T& x, strong_type& strong) const
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
it = this->values.begin(), end = this->values.end();
it != end; ++it)
{ {
for (BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
it = this->values.begin(),
end = this->values.end();
it != end; ++it) {
strong.store(x, test::detail::tracker.count_allocations); strong.store(x, test::detail::tracker.count_allocations);
x.emplace(boost::unordered::piecewise_construct, x.emplace(boost::unordered::piecewise_construct,
boost::make_tuple(it->first), boost::make_tuple(it->first),
@@ -284,16 +286,16 @@ struct pair_emplace_test2 : public insert_test_base<T>
EXCEPTION_TESTS((pair_emplace_test1)(pair_emplace_test2), CONTAINER_PAIR_SEQ) EXCEPTION_TESTS((pair_emplace_test1)(pair_emplace_test2), CONTAINER_PAIR_SEQ)
template <class T> template <class T> struct index_insert_test1 : public insert_test_base<T>
struct index_insert_test1 : public insert_test_base<T>
{ {
typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type; typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
void run(T& x, strong_type& strong) const { void run(T& x, strong_type& strong) const
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
it = this->values.begin(), end = this->values.end();
it != end; ++it)
{ {
for (BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
it = this->values.begin(),
end = this->values.end();
it != end; ++it) {
strong.store(x, test::detail::tracker.count_allocations); strong.store(x, test::detail::tracker.count_allocations);
x[it->first]; x[it->first];
} }

View File

@@ -5,29 +5,28 @@
#include "./containers.hpp" #include "./containers.hpp"
#include <iostream>
#include "../helpers/random_values.hpp"
#include "../helpers/invariants.hpp" #include "../helpers/invariants.hpp"
#include "../helpers/random_values.hpp"
#include <iostream>
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
#pragma warning(disable:4512) // move_assignment operator could not be generated #pragma warning( \
disable : 4512) // move_assignment operator could not be generated
#endif #endif
test::seed_t initialize_seed(12847); test::seed_t initialize_seed(12847);
template <class T> template <class T> struct move_assign_base : public test::exception_base
struct move_assign_base : public test::exception_base
{ {
test::random_values<T> x_values, y_values; test::random_values<T> x_values, y_values;
T x,y; T x, y;
typedef BOOST_DEDUCED_TYPENAME T::hasher hasher; typedef BOOST_DEDUCED_TYPENAME T::hasher hasher;
typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal; typedef BOOST_DEDUCED_TYPENAME T::key_equal key_equal;
typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type; typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type;
move_assign_base(int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0) : move_assign_base(int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0)
x_values(), : x_values(), y_values(),
y_values(),
x(0, hasher(tag1), key_equal(tag1), allocator_type(tag1)), x(0, hasher(tag1), key_equal(tag1), allocator_type(tag1)),
y(0, hasher(tag2), key_equal(tag2), allocator_type(tag2)) y(0, hasher(tag2), key_equal(tag2), allocator_type(tag2))
{ {
@@ -37,7 +36,8 @@ struct move_assign_base : public test::exception_base
typedef T data_type; typedef T data_type;
T init() const { return T(x); } T init() const { return T(x); }
void run(T& x1) const { void run(T& x1) const
{
test::exceptions_enable disable_exceptions(false); test::exceptions_enable disable_exceptions(false);
T y1 = y; T y1 = y;
disable_exceptions.release(); disable_exceptions.release();
@@ -58,12 +58,11 @@ struct move_assign_base : public test::exception_base
} }
}; };
template <class T> template <class T> struct move_assign_values : move_assign_base<T>
struct move_assign_values : move_assign_base<T>
{ {
move_assign_values(unsigned int count1, unsigned int count2, move_assign_values(unsigned int count1, unsigned int count2, int tag1,
int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0) : int tag2, float mlf1 = 1.0, float mlf2 = 1.0)
move_assign_base<T>(tag1, tag2, mlf1, mlf2) : move_assign_base<T>(tag1, tag2, mlf1, mlf2)
{ {
this->x_values.fill(count1); this->x_values.fill(count1);
this->y_values.fill(count2); this->y_values.fill(count2);
@@ -72,47 +71,39 @@ struct move_assign_values : move_assign_base<T>
} }
}; };
template <class T> template <class T> struct move_assign_test1 : move_assign_values<T>
struct move_assign_test1 : move_assign_values<T>
{ {
move_assign_test1() : move_assign_values<T>(0, 0, 0, 0) {} move_assign_test1() : move_assign_values<T>(0, 0, 0, 0) {}
}; };
template <class T> template <class T> struct move_assign_test2 : move_assign_values<T>
struct move_assign_test2 : move_assign_values<T>
{ {
move_assign_test2() : move_assign_values<T>(60, 0, 0, 0) {} move_assign_test2() : move_assign_values<T>(60, 0, 0, 0) {}
}; };
template <class T> template <class T> struct move_assign_test3 : move_assign_values<T>
struct move_assign_test3 : move_assign_values<T>
{ {
move_assign_test3() : move_assign_values<T>(0, 60, 0, 0) {} move_assign_test3() : move_assign_values<T>(0, 60, 0, 0) {}
}; };
template <class T> template <class T> struct move_assign_test4 : move_assign_values<T>
struct move_assign_test4 : move_assign_values<T>
{ {
move_assign_test4() : move_assign_values<T>(10, 10, 1, 2) {} move_assign_test4() : move_assign_values<T>(10, 10, 1, 2) {}
}; };
template <class T> template <class T> struct move_assign_test4a : move_assign_values<T>
struct move_assign_test4a : move_assign_values<T>
{ {
move_assign_test4a() : move_assign_values<T>(10, 100, 1, 2) {} move_assign_test4a() : move_assign_values<T>(10, 100, 1, 2) {}
}; };
template <class T> template <class T> struct move_assign_test5 : move_assign_values<T>
struct move_assign_test5 : move_assign_values<T>
{ {
move_assign_test5() : move_assign_values<T>(5, 60, 0, 0, 1.0f, 0.1f) {} move_assign_test5() : move_assign_values<T>(5, 60, 0, 0, 1.0f, 0.1f) {}
}; };
template <class T> template <class T> struct equivalent_test1 : move_assign_base<T>
struct equivalent_test1 : move_assign_base<T>
{ {
equivalent_test1() : equivalent_test1() : move_assign_base<T>(0, 0)
move_assign_base<T>(0, 0)
{ {
test::random_values<T> x_values2(10); test::random_values<T> x_values2(10);
this->x_values.insert(x_values2.begin(), x_values2.end()); this->x_values.insert(x_values2.begin(), x_values2.end());
@@ -125,8 +116,8 @@ struct equivalent_test1 : move_assign_base<T>
} }
}; };
EXCEPTION_TESTS( EXCEPTION_TESTS((move_assign_test1)(move_assign_test2)(move_assign_test3)(
(move_assign_test1)(move_assign_test2)(move_assign_test3)(move_assign_test4)(move_assign_test4a)(move_assign_test5) move_assign_test4)(move_assign_test4a)(move_assign_test5)(
(equivalent_test1), equivalent_test1),
CONTAINER_SEQ) CONTAINER_SEQ)
RUN_TESTS() RUN_TESTS()

View File

@@ -5,38 +5,39 @@
#include "./containers.hpp" #include "./containers.hpp"
#include <string>
#include "../helpers/random_values.hpp"
#include "../helpers/invariants.hpp" #include "../helpers/invariants.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/strong.hpp" #include "../helpers/strong.hpp"
#include <string>
#include <iostream> #include <iostream>
test::seed_t initialize_seed(3298597); test::seed_t initialize_seed(3298597);
template <class T> template <class T> struct rehash_test_base : public test::exception_base
struct rehash_test_base : public test::exception_base
{ {
test::random_values<T> values; test::random_values<T> values;
unsigned int n; unsigned int n;
rehash_test_base(unsigned int count = 100, unsigned int n_ = 0) rehash_test_base(unsigned int count = 100, unsigned int n_ = 0)
: values(count), n(n_) : values(count), n(n_)
{} {
}
typedef T data_type; typedef T data_type;
typedef test::strong<T> strong_type; typedef test::strong<T> strong_type;
data_type init() const { data_type init() const
{
T x(values.begin(), values.end(), n); T x(values.begin(), values.end(), n);
return x; return x;
} }
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x, void check BOOST_PREVENT_MACRO_SUBSTITUTION(
strong_type const& strong) const T const& x, strong_type const& strong) const
{ {
std::string scope(test::scope); std::string scope(test::scope);
if(scope.find("hash::operator()") == std::string::npos && if (scope.find("hash::operator()") == std::string::npos &&
scope.find("equal_to::operator()") == std::string::npos && scope.find("equal_to::operator()") == std::string::npos &&
scope != "operator==(object, object)") scope != "operator==(object, object)")
strong.test(x); strong.test(x);
@@ -45,36 +46,31 @@ struct rehash_test_base : public test::exception_base
} }
}; };
template <class T> template <class T> struct rehash_test0 : rehash_test_base<T>
struct rehash_test0 : rehash_test_base<T>
{ {
rehash_test0() : rehash_test_base<T>(0) {} rehash_test0() : rehash_test_base<T>(0) {}
void run(T& x) const { x.rehash(0); } void run(T& x) const { x.rehash(0); }
}; };
template <class T> template <class T> struct rehash_test1 : rehash_test_base<T>
struct rehash_test1 : rehash_test_base<T>
{ {
rehash_test1() : rehash_test_base<T>(0) {} rehash_test1() : rehash_test_base<T>(0) {}
void run(T& x) const { x.rehash(200); } void run(T& x) const { x.rehash(200); }
}; };
template <class T> template <class T> struct rehash_test2 : rehash_test_base<T>
struct rehash_test2 : rehash_test_base<T>
{ {
rehash_test2() : rehash_test_base<T>(0, 200) {} rehash_test2() : rehash_test_base<T>(0, 200) {}
void run(T& x) const { x.rehash(0); } void run(T& x) const { x.rehash(0); }
}; };
template <class T> template <class T> struct rehash_test3 : rehash_test_base<T>
struct rehash_test3 : rehash_test_base<T>
{ {
rehash_test3() : rehash_test_base<T>(10, 0) {} rehash_test3() : rehash_test_base<T>(10, 0) {}
void run(T& x) const { x.rehash(200); } void run(T& x) const { x.rehash(200); }
}; };
template <class T> template <class T> struct rehash_test4 : rehash_test_base<T>
struct rehash_test4 : rehash_test_base<T>
{ {
rehash_test4() : rehash_test_base<T>(10, 200) {} rehash_test4() : rehash_test_base<T>(10, 200) {}
void run(T& x) const { x.rehash(0); } void run(T& x) const { x.rehash(0); }

View File

@@ -5,17 +5,16 @@
#include "./containers.hpp" #include "./containers.hpp"
#include "../helpers/random_values.hpp"
#include "../helpers/invariants.hpp" #include "../helpers/invariants.hpp"
#include "../helpers/random_values.hpp"
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
#pragma warning(disable:4512) // assignment operator could not be generated #pragma warning(disable : 4512) // assignment operator could not be generated
#endif #endif
test::seed_t initialize_seed(9387); test::seed_t initialize_seed(9387);
template <class T> template <class T> struct self_swap_base : public test::exception_base
struct self_swap_base : public test::exception_base
{ {
test::random_values<T> values; test::random_values<T> values;
self_swap_base(std::size_t count = 0) : values(count) {} self_swap_base(std::size_t count = 0) : values(count) {}
@@ -23,12 +22,12 @@ struct self_swap_base : public test::exception_base
typedef T data_type; typedef T data_type;
T init() const { return T(values.begin(), values.end()); } T init() const { return T(values.begin(), values.end()); }
void run(T& x) const { x.swap(x); } void run(T& x) const { x.swap(x); }
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const { void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const
{
std::string scope(test::scope); std::string scope(test::scope);
// TODO: In C++11 exceptions are only allowed in the swap function. // TODO: In C++11 exceptions are only allowed in the swap function.
BOOST_TEST( BOOST_TEST(scope == "hash::hash(hash)" ||
scope == "hash::hash(hash)" ||
scope == "hash::operator=(hash)" || scope == "hash::operator=(hash)" ||
scope == "equal_to::equal_to(equal_to)" || scope == "equal_to::equal_to(equal_to)" ||
scope == "equal_to::operator=(equal_to)"); scope == "equal_to::operator=(equal_to)");
@@ -37,17 +36,16 @@ struct self_swap_base : public test::exception_base
} }
}; };
template <class T> template <class T> struct self_swap_test1 : self_swap_base<T>
struct self_swap_test1 : self_swap_base<T> {}; {
};
template <class T> template <class T> struct self_swap_test2 : self_swap_base<T>
struct self_swap_test2 : self_swap_base<T>
{ {
self_swap_test2() : self_swap_base<T>(100) {} self_swap_test2() : self_swap_base<T>(100) {}
}; };
template <class T> template <class T> struct swap_base : public test::exception_base
struct swap_base : public test::exception_base
{ {
const test::random_values<T> x_values, y_values; const test::random_values<T> x_values, y_values;
const T initial_x, initial_y; const T initial_x, initial_y;
@@ -60,32 +58,37 @@ struct swap_base : public test::exception_base
: x_values(count1), y_values(count2), : x_values(count1), y_values(count2),
initial_x(x_values.begin(), x_values.end(), 0, hasher(tag1), initial_x(x_values.begin(), x_values.end(), 0, hasher(tag1),
key_equal(tag1), allocator_type(tag1)), key_equal(tag1), allocator_type(tag1)),
initial_y(y_values.begin(), y_values.end(), 0, hasher(tag2), initial_y(
key_equal(tag2), allocator_type( y_values.begin(), y_values.end(), 0, hasher(tag2),
T::allocator_type::propagate_on_container_swap::value ? key_equal(tag2),
tag2 : tag1)) allocator_type(
{} T::allocator_type::propagate_on_container_swap::value ? tag2
: tag1))
{
}
struct data_type { struct data_type
data_type(T const& x_, T const& y_) {
: x(x_), y(y_) {} data_type(T const& x_, T const& y_) : x(x_), y(y_) {}
T x, y; T x, y;
}; };
data_type init() const { return data_type(initial_x, initial_y); } data_type init() const { return data_type(initial_x, initial_y); }
void run(data_type& d) const { void run(data_type& d) const
{
try { try {
d.x.swap(d.y); d.x.swap(d.y);
} catch (std::runtime_error) {} } catch (std::runtime_error) {
} }
void check BOOST_PREVENT_MACRO_SUBSTITUTION(data_type const& d) const { }
void check BOOST_PREVENT_MACRO_SUBSTITUTION(data_type const& d) const
{
std::string scope(test::scope); std::string scope(test::scope);
// TODO: In C++11 exceptions are only allowed in the swap function. // TODO: In C++11 exceptions are only allowed in the swap function.
BOOST_TEST( BOOST_TEST(scope == "hash::hash(hash)" ||
scope == "hash::hash(hash)" ||
scope == "hash::operator=(hash)" || scope == "hash::operator=(hash)" ||
scope == "equal_to::equal_to(equal_to)" || scope == "equal_to::equal_to(equal_to)" ||
scope == "equal_to::operator=(equal_to)"); scope == "equal_to::operator=(equal_to)");
@@ -95,32 +98,27 @@ struct swap_base : public test::exception_base
} }
}; };
template <class T> template <class T> struct swap_test1 : swap_base<T>
struct swap_test1 : swap_base<T>
{ {
swap_test1() : swap_base<T>(0, 0, 0, 0) {} swap_test1() : swap_base<T>(0, 0, 0, 0) {}
}; };
template <class T> template <class T> struct swap_test2 : swap_base<T>
struct swap_test2 : swap_base<T>
{ {
swap_test2() : swap_base<T>(60, 0, 0, 0) {} swap_test2() : swap_base<T>(60, 0, 0, 0) {}
}; };
template <class T> template <class T> struct swap_test3 : swap_base<T>
struct swap_test3 : swap_base<T>
{ {
swap_test3() : swap_base<T>(0, 60, 0, 0) {} swap_test3() : swap_base<T>(0, 60, 0, 0) {}
}; };
template <class T> template <class T> struct swap_test4 : swap_base<T>
struct swap_test4 : swap_base<T>
{ {
swap_test4() : swap_base<T>(10, 10, 1, 2) {} swap_test4() : swap_base<T>(10, 10, 1, 2) {}
}; };
EXCEPTION_TESTS( EXCEPTION_TESTS((self_swap_test1)(self_swap_test2)(swap_test1)(swap_test2)(
(self_swap_test1)(self_swap_test2) swap_test3)(swap_test4),
(swap_test1)(swap_test2)(swap_test3)(swap_test4),
CONTAINER_SEQ) CONTAINER_SEQ)
RUN_TESTS() RUN_TESTS()

View File

@@ -7,32 +7,27 @@
#define BOOST_UNORDERED_TEST_HELPERS_CHECK_RETURN_TYPE_HEADER #define BOOST_UNORDERED_TEST_HELPERS_CHECK_RETURN_TYPE_HEADER
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_convertible.hpp> #include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_same.hpp>
namespace test namespace test {
template <class T1> struct check_return_type
{ {
template <class T1> template <class T2> static void equals(T2)
struct check_return_type
{
template <class T2>
static void equals(T2)
{ {
BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value)); BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value));
} }
template <class T2> template <class T2> static void equals_ref(T2&)
static void equals_ref(T2&)
{ {
BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value)); BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value));
} }
template <class T2> template <class T2> static void convertible(T2)
static void convertible(T2)
{ {
BOOST_STATIC_ASSERT((boost::is_convertible<T2, T1>::value)); BOOST_STATIC_ASSERT((boost::is_convertible<T2, T1>::value));
} }
}; };
} }
#endif #endif

View File

@@ -10,77 +10,81 @@
#include <iostream> #include <iostream>
namespace test { namespace test {
struct object_count { struct object_count
{
int instances; int instances;
int constructions; int constructions;
object_count() : instances(0), constructions(0) {} object_count() : instances(0), constructions(0) {}
void reset() { *this = object_count(); } void reset() { *this = object_count(); }
void construct() { void construct()
{
++instances; ++instances;
++constructions; ++constructions;
} }
void destruct() { void destruct()
if(instances == 0) { {
if (instances == 0) {
BOOST_ERROR("Unbalanced constructions."); BOOST_ERROR("Unbalanced constructions.");
} } else {
else {
--instances; --instances;
} }
} }
bool operator==(object_count const& x) const { bool operator==(object_count const& x) const
return instances == x.instances &&
constructions == x.constructions;
}
bool operator!=(object_count const& x) const {
return !(*this == x);
}
friend std::ostream& operator<<(std::ostream& out,
object_count const& c)
{ {
out return instances == x.instances && constructions == x.constructions;
<< "[instances: " }
<< c.instances
<< ", constructions: " bool operator!=(object_count const& x) const { return !(*this == x); }
<< c.constructions
<< "]"; friend std::ostream& operator<<(std::ostream& out, object_count const& c)
{
out << "[instances: " << c.instances
<< ", constructions: " << c.constructions << "]";
return out; return out;
} }
}; };
// This won't be a problem as I'm only using a single compile unit // This won't be a problem as I'm only using a single compile unit
// in each test (this is actually require by the minimal test // in each test (this is actually require by the minimal test
// framework). // framework).
// //
// boostinspect:nounnamed // boostinspect:nounnamed
namespace { namespace {
object_count global_object_count; object_count global_object_count;
} }
struct counted_object struct counted_object
{ {
counted_object() { global_object_count.construct(); } counted_object() { global_object_count.construct(); }
counted_object(counted_object const&) { global_object_count.construct(); } counted_object(counted_object const&) { global_object_count.construct(); }
~counted_object() { global_object_count.destruct(); } ~counted_object() { global_object_count.destruct(); }
}; };
struct check_instances { struct check_instances
{
int instances_; int instances_;
int constructions_; int constructions_;
check_instances() : check_instances()
instances_(global_object_count.instances), : instances_(global_object_count.instances),
constructions_(global_object_count.constructions) {} constructions_(global_object_count.constructions)
~check_instances() { BOOST_TEST(global_object_count.instances == instances_); } {
}
~check_instances()
{
BOOST_TEST(global_object_count.instances == instances_);
}
int instances() const { return global_object_count.instances - instances_; } int instances() const { return global_object_count.instances - instances_; }
int constructions() const { return global_object_count.constructions - constructions_; } int constructions() const
}; {
return global_object_count.constructions - constructions_;
}
};
} }
#endif #endif

View File

@@ -6,88 +6,89 @@
#if !defined(BOOST_UNORDERED_TESTS_EQUIVALENT_HEADER) #if !defined(BOOST_UNORDERED_TESTS_EQUIVALENT_HEADER)
#define BOOST_UNORDERED_TESTS_EQUIVALENT_HEADER #define BOOST_UNORDERED_TESTS_EQUIVALENT_HEADER
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#include <algorithm>
#include "./metafunctions.hpp"
#include "./fwd.hpp" #include "./fwd.hpp"
#include "./list.hpp" #include "./list.hpp"
#include "./metafunctions.hpp"
#include <algorithm>
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
namespace test namespace test {
template <class T1, class T2>
bool equivalent_impl(T1 const& x, T2 const& y, base_type)
{ {
template <class T1, class T2>
bool equivalent_impl(T1 const& x, T2 const& y, base_type) {
return x == y; return x == y;
} }
template <class T> template <class T>
bool equivalent_impl(boost::hash<T> const&, boost::hash<T> const&, bool equivalent_impl(boost::hash<T> const&, boost::hash<T> const&, derived_type)
derived_type) {
{
return true; return true;
} }
template <class T> template <class T>
bool equivalent_impl(std::equal_to<T> const&, std::equal_to<T> const&, bool equivalent_impl(
derived_type) std::equal_to<T> const&, std::equal_to<T> const&, derived_type)
{ {
return true; return true;
} }
template <class T1, class T2, class T3, class T4> template <class T1, class T2, class T3, class T4>
bool equivalent_impl(std::pair<T1, T2> const& x1, bool equivalent_impl(
std::pair<T3, T4> const& x2, derived_type) { std::pair<T1, T2> const& x1, std::pair<T3, T4> const& x2, derived_type)
{
return equivalent_impl(x1.first, x2.first, derived) && return equivalent_impl(x1.first, x2.first, derived) &&
equivalent_impl(x1.second, x2.second, derived); equivalent_impl(x1.second, x2.second, derived);
} }
struct equivalent_type { struct equivalent_type
{
equivalent_type() {} equivalent_type() {}
template <class T1, class T2> template <class T1, class T2>
bool operator()(T1 const& x, T2 const& y) const { bool operator()(T1 const& x, T2 const& y) const
{
return equivalent_impl(x, y, derived); return equivalent_impl(x, y, derived);
} }
}; };
const equivalent_type equivalent; const equivalent_type equivalent;
template <class Container> template <class Container> class unordered_equivalence_tester
class unordered_equivalence_tester {
{
BOOST_DEDUCED_TYPENAME Container::size_type size_; BOOST_DEDUCED_TYPENAME Container::size_type size_;
BOOST_DEDUCED_TYPENAME Container::hasher hasher_; BOOST_DEDUCED_TYPENAME Container::hasher hasher_;
BOOST_DEDUCED_TYPENAME Container::key_equal key_equal_; BOOST_DEDUCED_TYPENAME Container::key_equal key_equal_;
float max_load_factor_; float max_load_factor_;
typedef test::list<BOOST_DEDUCED_TYPENAME Container::value_type> typedef test::list<BOOST_DEDUCED_TYPENAME Container::value_type> value_list;
value_list;
value_list values_; value_list values_;
public: public:
unordered_equivalence_tester(Container const &x) unordered_equivalence_tester(Container const& x)
: size_(x.size()), : size_(x.size()), hasher_(x.hash_function()), key_equal_(x.key_eq()),
hasher_(x.hash_function()), key_equal_(x.key_eq()), max_load_factor_(x.max_load_factor()), values_(x.begin(), x.end())
max_load_factor_(x.max_load_factor()),
values_(x.begin(), x.end())
{ {
values_.sort(); values_.sort();
} }
bool operator()(Container const& x) const bool operator()(Container const& x) const
{ {
if(!((size_ == x.size()) && if (!((size_ == x.size()) &&
(test::equivalent(hasher_, x.hash_function())) && (test::equivalent(hasher_, x.hash_function())) &&
(test::equivalent(key_equal_, x.key_eq())) && (test::equivalent(key_equal_, x.key_eq())) &&
(max_load_factor_ == x.max_load_factor()) && (max_load_factor_ == x.max_load_factor()) &&
(values_.size() == x.size()))) return false; (values_.size() == x.size())))
return false;
value_list copy(x.begin(), x.end()); value_list copy(x.begin(), x.end());
copy.sort(); copy.sort();
return values_ == copy; return values_ == copy;
} }
private: private:
unordered_equivalence_tester(); unordered_equivalence_tester();
}; };
} }
#endif #endif

View File

@@ -6,113 +6,105 @@
#if !defined(BOOST_UNORDERED_EXCEPTION_TEST_HEADER) #if !defined(BOOST_UNORDERED_EXCEPTION_TEST_HEADER)
#define BOOST_UNORDERED_EXCEPTION_TEST_HEADER #define BOOST_UNORDERED_EXCEPTION_TEST_HEADER
#include "./test.hpp"
#include "./count.hpp" #include "./count.hpp"
#include "./test.hpp"
#include <boost/preprocessor/seq/for_each_product.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/seq/for_each_product.hpp>
# define UNORDERED_EXCEPTION_TEST_CASE(name, test_func, type) \ #define UNORDERED_EXCEPTION_TEST_CASE(name, test_func, type) \
UNORDERED_AUTO_TEST(name) \ UNORDERED_AUTO_TEST(name) \
{ \ { \
test_func< type > fixture; \ test_func<type> fixture; \
::test::lightweight::exception_safety( \ ::test::lightweight::exception_safety( \
fixture, BOOST_STRINGIZE(test_func<type>)); \ fixture, BOOST_STRINGIZE(test_func<type>)); \
} \ }
# define UNORDERED_EXCEPTION_TEST_CASE_REPEAT(name, test_func, n, type) \ #define UNORDERED_EXCEPTION_TEST_CASE_REPEAT(name, test_func, n, type) \
UNORDERED_AUTO_TEST(name) \ UNORDERED_AUTO_TEST(name) \
{ \ { \
for (unsigned i = 0; i < n; ++i) { \ for (unsigned i = 0; i < n; ++i) { \
test_func< type > fixture; \ test_func<type> fixture; \
::test::lightweight::exception_safety( \ ::test::lightweight::exception_safety( \
fixture, BOOST_STRINGIZE(test_func<type>)); \ fixture, BOOST_STRINGIZE(test_func<type>)); \
} \ } \
} \ }
#define UNORDERED_EPOINT_IMPL ::test::lightweight::epoint
# define UNORDERED_EPOINT_IMPL ::test::lightweight::epoint
#define UNORDERED_EXCEPTION_TEST_POSTFIX RUN_TESTS() #define UNORDERED_EXCEPTION_TEST_POSTFIX RUN_TESTS()
#define EXCEPTION_TESTS(test_seq, param_seq) \ #define EXCEPTION_TESTS(test_seq, param_seq) \
BOOST_PP_SEQ_FOR_EACH_PRODUCT(EXCEPTION_TESTS_OP, \ BOOST_PP_SEQ_FOR_EACH_PRODUCT( \
(test_seq)((1))(param_seq)) EXCEPTION_TESTS_OP, (test_seq)((1))(param_seq))
#define EXCEPTION_TESTS_REPEAT(n, test_seq, param_seq) \ #define EXCEPTION_TESTS_REPEAT(n, test_seq, param_seq) \
BOOST_PP_SEQ_FOR_EACH_PRODUCT(EXCEPTION_TESTS_OP, \ BOOST_PP_SEQ_FOR_EACH_PRODUCT( \
(test_seq)((n))(param_seq)) EXCEPTION_TESTS_OP, (test_seq)((n))(param_seq))
#define EXCEPTION_TESTS_OP(r, product) \ #define EXCEPTION_TESTS_OP(r, product) \
UNORDERED_EXCEPTION_TEST_CASE_REPEAT( \ UNORDERED_EXCEPTION_TEST_CASE_REPEAT( \
BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0, product), \ BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0, product), \
BOOST_PP_CAT(_, BOOST_PP_SEQ_ELEM(2, product)) \ BOOST_PP_CAT(_, BOOST_PP_SEQ_ELEM(2, product))), \
), \ BOOST_PP_SEQ_ELEM(0, product), BOOST_PP_SEQ_ELEM(1, product), \
BOOST_PP_SEQ_ELEM(0, product), \ BOOST_PP_SEQ_ELEM(2, product))
BOOST_PP_SEQ_ELEM(1, product), \
BOOST_PP_SEQ_ELEM(2, product) \
) \
#define UNORDERED_SCOPE(scope_name) \ #define UNORDERED_SCOPE(scope_name) \
for(::test::scope_guard unordered_test_guard( \ for (::test::scope_guard unordered_test_guard( \
BOOST_STRINGIZE(scope_name)); \ BOOST_STRINGIZE(scope_name)); \
!unordered_test_guard.dismissed(); \ !unordered_test_guard.dismissed(); unordered_test_guard.dismiss())
unordered_test_guard.dismiss()) \
#define UNORDERED_EPOINT(name) \ #define UNORDERED_EPOINT(name) \
if(::test::exceptions_enabled) { \ if (::test::exceptions_enabled) { \
UNORDERED_EPOINT_IMPL(name); \ UNORDERED_EPOINT_IMPL(name); \
} \ }
#define ENABLE_EXCEPTIONS \ #define ENABLE_EXCEPTIONS \
::test::exceptions_enable BOOST_PP_CAT( \ ::test::exceptions_enable BOOST_PP_CAT(ENABLE_EXCEPTIONS_, __LINE__)(true)
ENABLE_EXCEPTIONS_, __LINE__)(true) \
#define DISABLE_EXCEPTIONS \ #define DISABLE_EXCEPTIONS \
::test::exceptions_enable BOOST_PP_CAT( \ ::test::exceptions_enable BOOST_PP_CAT(ENABLE_EXCEPTIONS_, __LINE__)(false)
ENABLE_EXCEPTIONS_, __LINE__)(false) \
namespace test { namespace test {
static char const* scope = ""; static char const* scope = "";
bool exceptions_enabled = false; bool exceptions_enabled = false;
class scope_guard { class scope_guard
{
scope_guard& operator=(scope_guard const&); scope_guard& operator=(scope_guard const&);
scope_guard(scope_guard const&); scope_guard(scope_guard const&);
char const* old_scope_; char const* old_scope_;
char const* scope_; char const* scope_;
bool dismissed_; bool dismissed_;
public: public:
scope_guard(char const* name) scope_guard(char const* name)
: old_scope_(scope), : old_scope_(scope), scope_(name), dismissed_(false)
scope_(name),
dismissed_(false)
{ {
scope = scope_; scope = scope_;
} }
~scope_guard() { ~scope_guard()
if(dismissed_) scope = old_scope_;
}
void dismiss() {
dismissed_ = true;
}
bool dismissed() const {
return dismissed_;
}
};
class exceptions_enable
{ {
if (dismissed_)
scope = old_scope_;
}
void dismiss() { dismissed_ = true; }
bool dismissed() const { return dismissed_; }
};
class exceptions_enable
{
exceptions_enable& operator=(exceptions_enable const&); exceptions_enable& operator=(exceptions_enable const&);
exceptions_enable(exceptions_enable const&); exceptions_enable(exceptions_enable const&);
bool old_value_; bool old_value_;
bool released_; bool released_;
public: public:
exceptions_enable(bool enable) exceptions_enable(bool enable)
: old_value_(exceptions_enabled), released_(false) : old_value_(exceptions_enabled), released_(false)
@@ -135,58 +127,57 @@ namespace test {
released_ = true; released_ = true;
} }
} }
}; };
struct exception_base { struct exception_base
struct data_type {}; {
struct strong_type { struct data_type
{
};
struct strong_type
{
template <class T> void store(T const&) {} template <class T> void store(T const&) {}
template <class T> void test(T const&) const {} template <class T> void test(T const&) const {}
}; };
data_type init() const { return data_type(); } data_type init() const { return data_type(); }
void check BOOST_PREVENT_MACRO_SUBSTITUTION() const {} void check BOOST_PREVENT_MACRO_SUBSTITUTION() const {}
}; };
template <class T, class P1, class P2, class T2> template <class T, class P1, class P2, class T2>
inline void call_ignore_extra_parameters( inline void call_ignore_extra_parameters(
void (T::*fn)() const, T2 const& obj, void (T::*fn)() const, T2 const& obj, P1&, P2&)
P1&, P2&) {
{
(obj.*fn)(); (obj.*fn)();
} }
template <class T, class P1, class P2, class T2> template <class T, class P1, class P2, class T2>
inline void call_ignore_extra_parameters( inline void call_ignore_extra_parameters(
void (T::*fn)(P1&) const, T2 const& obj, void (T::*fn)(P1&) const, T2 const& obj, P1& p1, P2&)
P1& p1, P2&) {
{
(obj.*fn)(p1); (obj.*fn)(p1);
} }
template <class T, class P1, class P2, class T2> template <class T, class P1, class P2, class T2>
inline void call_ignore_extra_parameters( inline void call_ignore_extra_parameters(
void (T::*fn)(P1&, P2&) const, T2 const& obj, void (T::*fn)(P1&, P2&) const, T2 const& obj, P1& p1, P2& p2)
P1& p1, P2& p2) {
{
(obj.*fn)(p1, p2); (obj.*fn)(p1, p2);
} }
template <class T> template <class T> T const& constant(T const& x) { return x; }
T const& constant(T const& x) {
return x;
}
template <class Test> template <class Test> class test_runner
class test_runner {
{
Test const& test_; Test const& test_;
bool exception_in_check_; bool exception_in_check_;
test_runner(test_runner const&); test_runner(test_runner const&);
test_runner& operator=(test_runner const&); test_runner& operator=(test_runner const&);
public: public:
test_runner(Test const& t) : test_(t), exception_in_check_(false) {} test_runner(Test const& t) : test_(t), exception_in_check_(false) {}
void run() { void run()
{
DISABLE_EXCEPTIONS; DISABLE_EXCEPTIONS;
test::check_instances check; test::check_instances check;
test::scope = ""; test::scope = "";
@@ -195,56 +186,57 @@ namespace test {
strong.store(x); strong.store(x);
try { try {
ENABLE_EXCEPTIONS; ENABLE_EXCEPTIONS;
call_ignore_extra_parameters< call_ignore_extra_parameters<Test,
Test,
BOOST_DEDUCED_TYPENAME Test::data_type, BOOST_DEDUCED_TYPENAME Test::data_type,
BOOST_DEDUCED_TYPENAME Test::strong_type BOOST_DEDUCED_TYPENAME Test::strong_type>(
>(&Test::run, test_, x, strong); &Test::run, test_, x, strong);
} } catch (...) {
catch(...) {
try { try {
DISABLE_EXCEPTIONS; DISABLE_EXCEPTIONS;
call_ignore_extra_parameters< call_ignore_extra_parameters<Test,
Test,
BOOST_DEDUCED_TYPENAME Test::data_type const, BOOST_DEDUCED_TYPENAME Test::data_type const,
BOOST_DEDUCED_TYPENAME Test::strong_type const BOOST_DEDUCED_TYPENAME Test::strong_type const>(
>(&Test::check, test_, constant(x), constant(strong)); &Test::check, test_, constant(x), constant(strong));
} catch(...) { } catch (...) {
exception_in_check_ = true; exception_in_check_ = true;
} }
throw; throw;
} }
} }
void end() { void end()
{
if (exception_in_check_) { if (exception_in_check_) {
BOOST_ERROR("Unexcpected exception in test_runner check call."); BOOST_ERROR("Unexcpected exception in test_runner check call.");
} }
} }
}; };
// Quick exception testing based on lightweight test // Quick exception testing based on lightweight test
namespace lightweight { namespace lightweight {
static int iteration; static int iteration;
static int count; static int count;
struct test_exception { struct test_exception
{
char const* name; char const* name;
test_exception(char const* n) : name(n) {} test_exception(char const* n) : name(n) {}
}; };
struct test_failure { struct test_failure
}; {
};
void epoint(char const* name) { void epoint(char const* name)
{
++count; ++count;
if(count == iteration) { if (count == iteration) {
throw test_exception(name); throw test_exception(name);
} }
} }
template <class Test> template <class Test> void exception_safety(Test const& f, char const* /*name*/)
void exception_safety(Test const& f, char const* /*name*/) { {
test_runner<Test> runner(f); test_runner<Test> runner(f);
iteration = 0; iteration = 0;
@@ -257,24 +249,23 @@ namespace test {
try { try {
runner.run(); runner.run();
success = true; success = true;
} } catch (test_failure) {
catch(test_failure) {
error_msg = "test_failure caught."; error_msg = "test_failure caught.";
break; break;
} } catch (test_exception) {
catch(test_exception) {
continue; continue;
} } catch (...) {
catch(...) {
error_msg = "Unexpected exception."; error_msg = "Unexpected exception.";
break; break;
} }
} while(!success); } while (!success);
if (error_msg) { BOOST_ERROR(error_msg); } if (error_msg) {
BOOST_ERROR(error_msg);
}
runner.end(); runner.end();
} }
} }
} }
#endif #endif

View File

@@ -8,23 +8,25 @@
#include <string> #include <string>
namespace test namespace test {
{ typedef enum {
typedef enum {
default_generator, default_generator,
generate_collisions, generate_collisions,
limited_range limited_range
} random_generator; } random_generator;
int generate(int const*, random_generator); int generate(int const*, random_generator);
char generate(char const*, random_generator); char generate(char const*, random_generator);
signed char generate(signed char const*, random_generator); signed char generate(signed char const*, random_generator);
std::string generate(std::string const*, random_generator); std::string generate(std::string const*, random_generator);
float generate(float const*, random_generator); float generate(float const*, random_generator);
struct base_type {} base; struct base_type
struct derived_type : base_type {} derived; {
} base;
struct derived_type : base_type
{
} derived;
} }
#endif #endif

View File

@@ -11,49 +11,53 @@
#if !defined(BOOST_UNORDERED_TEST_HELPERS_GENERATORS_HEADER) #if !defined(BOOST_UNORDERED_TEST_HELPERS_GENERATORS_HEADER)
#define BOOST_UNORDERED_TEST_HELPERS_GENERATORS_HEADER #define BOOST_UNORDERED_TEST_HELPERS_GENERATORS_HEADER
#include "./fwd.hpp"
#include <boost/type_traits/add_const.hpp>
#include <cstdlib>
#include <stdexcept>
#include <string> #include <string>
#include <utility> #include <utility>
#include <stdexcept>
#include <cstdlib>
#include <boost/type_traits/add_const.hpp>
#include "./fwd.hpp"
namespace test namespace test {
struct seed_t
{ {
struct seed_t { seed_t(unsigned int x)
seed_t(unsigned int x) { {
using namespace std; using namespace std;
srand(x); srand(x);
} }
}; };
std::size_t random_value(std::size_t max) { std::size_t random_value(std::size_t max)
{
using namespace std; using namespace std;
return static_cast<std::size_t>(rand()) % max; return static_cast<std::size_t>(rand()) % max;
} }
inline int generate(int const*, random_generator g) inline int generate(int const*, random_generator g)
{ {
using namespace std; using namespace std;
int value = rand(); int value = rand();
if (g == limited_range) { value = value % 100; } if (g == limited_range) {
value = value % 100;
}
return value; return value;
} }
inline char generate(char const*, random_generator) inline char generate(char const*, random_generator)
{ {
using namespace std; using namespace std;
return static_cast<char>((rand() >> 1) % (128-32) + 32); return static_cast<char>((rand() >> 1) % (128 - 32) + 32);
} }
inline signed char generate(signed char const*, random_generator) inline signed char generate(signed char const*, random_generator)
{ {
using namespace std; using namespace std;
return static_cast<signed char>(rand()); return static_cast<signed char>(rand());
} }
inline std::string generate(std::string const*, random_generator g) inline std::string generate(std::string const*, random_generator g)
{ {
using namespace std; using namespace std;
char* char_ptr = 0; char* char_ptr = 0;
@@ -63,12 +67,12 @@ namespace test
if (g == limited_range) { if (g == limited_range) {
std::size_t length = test::random_value(2) + 2; std::size_t length = test::random_value(2) + 2;
char const* strings[] = { "'vZh(3~ms", "%m", "_Y%U", "N'Y", "4,J_J" }; char const* strings[] = {"'vZh(3~ms", "%m", "_Y%U", "N'Y", "4,J_J"};
for (std::size_t i = 0; i < length; ++i) { for (std::size_t i = 0; i < length; ++i) {
result += strings[random_value(sizeof(strings) / sizeof(strings[0]))]; result +=
strings[random_value(sizeof(strings) / sizeof(strings[0]))];
} }
} } else {
else {
std::size_t length = test::random_value(10) + 1; std::size_t length = test::random_value(10) + 1;
for (std::size_t i = 0; i < length; ++i) { for (std::size_t i = 0; i < length; ++i) {
result += generate(char_ptr, g); result += generate(char_ptr, g);
@@ -76,15 +80,15 @@ namespace test
} }
return result; return result;
} }
float generate(float const*, random_generator g) float generate(float const*, random_generator g)
{ {
using namespace std; using namespace std;
int x = 0; int x = 0;
int value = generate(&x, g); int value = generate(&x, g);
return (float) value / (float) RAND_MAX; return (float)value / (float)RAND_MAX;
} }
} }
#endif #endif

View File

@@ -6,58 +6,48 @@
#if !defined(BOOST_UNORDERED_TEST_HELPERS_HEADER) #if !defined(BOOST_UNORDERED_TEST_HELPERS_HEADER)
#define BOOST_UNORDERED_TEST_HELPERS_HEADER #define BOOST_UNORDERED_TEST_HELPERS_HEADER
namespace test namespace test {
template <class Container> struct get_key_impl
{ {
template <class Container>
struct get_key_impl
{
typedef BOOST_DEDUCED_TYPENAME Container::key_type key_type; typedef BOOST_DEDUCED_TYPENAME Container::key_type key_type;
static key_type const& get_key(key_type const& x) static key_type const& get_key(key_type const& x) { return x; }
template <class T>
static key_type const& get_key(std::pair<key_type, T> const& x, char = 0)
{ {
return x; return x.first;
} }
template <class T> template <class T>
static key_type const& get_key( static key_type const& get_key(
std::pair<key_type, T> const& x, char = 0) std::pair<key_type const, T> const& x, unsigned char = 0)
{ {
return x.first; return x.first;
} }
};
template <class T> template <class Container, class T>
static key_type const& get_key(std::pair<key_type const, T> const& x, inline BOOST_DEDUCED_TYPENAME Container::key_type const& get_key(T const& x)
unsigned char = 0) {
{
return x.first;
}
};
template <class Container, class T>
inline BOOST_DEDUCED_TYPENAME Container::key_type const& get_key(T const& x)
{
return get_key_impl<Container>::get_key(x); return get_key_impl<Container>::get_key(x);
} }
// test::next // test::next
// //
// Increments an iterator by 1 or a given value. // Increments an iterator by 1 or a given value.
// Like boost::next, but simpler and slower. // Like boost::next, but simpler and slower.
template <typename Iterator> template <typename Iterator> Iterator next(Iterator it) { return ++it; }
Iterator next(Iterator it)
{
return ++it;
}
template <typename Iterator, typename IntType> template <typename Iterator, typename IntType>
Iterator next(Iterator it, IntType x) Iterator next(Iterator it, IntType x)
{ {
for(; x > 0; --x) { for (; x > 0; --x) {
++it; ++it;
} }
return it; return it;
} }
} }
#endif #endif

View File

@@ -10,11 +10,9 @@
#include <boost/iterator/iterator_traits.hpp> #include <boost/iterator/iterator_traits.hpp>
#include <iterator> #include <iterator>
namespace test namespace test {
template <class Iterator> struct proxy
{ {
template <class Iterator>
struct proxy
{
typedef BOOST_DEDUCED_TYPENAME Iterator::value_type value_type; typedef BOOST_DEDUCED_TYPENAME Iterator::value_type value_type;
explicit proxy(value_type const& v) : v_(v) {} explicit proxy(value_type const& v) : v_(v) {}
@@ -22,144 +20,154 @@ namespace test
operator value_type const&() const { return v_; } operator value_type const&() const { return v_; }
value_type v_; value_type v_;
private: private:
proxy& operator=(proxy const&); proxy& operator=(proxy const&);
}; };
template <class Iterator> template <class Iterator>
struct input_iterator_adaptor struct input_iterator_adaptor
: public std::iterator< : public std::iterator<std::input_iterator_tag,
std::input_iterator_tag,
BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type, BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type,
std::ptrdiff_t, std::ptrdiff_t,
BOOST_DEDUCED_TYPENAME boost::iterator_pointer<Iterator>::type, BOOST_DEDUCED_TYPENAME boost::iterator_pointer<Iterator>::type,
proxy<Iterator> proxy<Iterator> >
> {
{
typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type
value_type; value_type;
input_iterator_adaptor() input_iterator_adaptor() : base_() {}
: base_() {} explicit input_iterator_adaptor(Iterator& it) : base_(&it) {}
explicit input_iterator_adaptor(Iterator& it) proxy<Iterator> operator*() const { return proxy<Iterator>(**base_); }
: base_(&it) {} value_type* operator->() const { return &**base_; }
proxy<Iterator> operator*() const { input_iterator_adaptor& operator++()
return proxy<Iterator>(**base_); {
++*base_;
return *this;
} }
value_type* operator->() const { // input_iterator_adaptor operator++(int) {
return &**base_;
}
input_iterator_adaptor& operator++() {
++*base_; return *this;
}
//input_iterator_adaptor operator++(int) {
//} //}
bool operator==(input_iterator_adaptor const& x) const { bool operator==(input_iterator_adaptor const& x) const
{
return *base_ == *x.base_; return *base_ == *x.base_;
} }
bool operator!=(input_iterator_adaptor const& x) const { bool operator!=(input_iterator_adaptor const& x) const
{
return *base_ != *x.base_; return *base_ != *x.base_;
} }
private: private:
Iterator* base_; Iterator* base_;
}; };
template <class Iterator> template <class Iterator>
input_iterator_adaptor<Iterator> input_iterator(Iterator& it) input_iterator_adaptor<Iterator> input_iterator(Iterator& it)
{ {
return input_iterator_adaptor<Iterator>(it); return input_iterator_adaptor<Iterator>(it);
} }
template <class Iterator> template <class Iterator>
struct copy_iterator_adaptor struct copy_iterator_adaptor
: public std::iterator< : public std::iterator<
BOOST_DEDUCED_TYPENAME boost::iterator_category<Iterator>::type, BOOST_DEDUCED_TYPENAME boost::iterator_category<Iterator>::type,
BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type, BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type,
BOOST_DEDUCED_TYPENAME boost::iterator_difference<Iterator>::type, BOOST_DEDUCED_TYPENAME boost::iterator_difference<Iterator>::type,
BOOST_DEDUCED_TYPENAME boost::iterator_pointer<Iterator>::type, BOOST_DEDUCED_TYPENAME boost::iterator_pointer<Iterator>::type,
proxy<Iterator> proxy<Iterator> >
> {
{
typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type
value_type; value_type;
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<Iterator>::type typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<Iterator>::type
difference_type; difference_type;
copy_iterator_adaptor() copy_iterator_adaptor() : base_() {}
: base_() {} explicit copy_iterator_adaptor(Iterator const& it) : base_(it) {}
explicit copy_iterator_adaptor(Iterator const& it) value_type operator*() const { return *base_; }
: base_(it) {} value_type* operator->() const { return &*base_; }
value_type operator*() const { value_type operator[](difference_type d) { return base_[d]; }
return *base_; copy_iterator_adaptor& operator++()
{
++base_;
return *this;
} }
value_type* operator->() const { copy_iterator_adaptor operator++(int)
return &*base_; {
copy_iterator_adaptor tmp(*this);
++base_;
return tmp;
} }
value_type operator[](difference_type d) { copy_iterator_adaptor& operator--()
return base_[d]; {
--base_;
return *this;
} }
copy_iterator_adaptor& operator++() { copy_iterator_adaptor operator--(int)
++base_; return *this; {
copy_iterator_adaptor tmp(*this);
--base_;
return tmp;
} }
copy_iterator_adaptor operator++(int) { copy_iterator_adaptor operator+=(difference_type x)
copy_iterator_adaptor tmp(*this); ++base_; return tmp; {
}
copy_iterator_adaptor& operator--() {
--base_; return *this;
}
copy_iterator_adaptor operator--(int) {
copy_iterator_adaptor tmp(*this); --base_; return tmp;
}
copy_iterator_adaptor operator+=(difference_type x) {
base_ += x; base_ += x;
return *this; return *this;
} }
copy_iterator_adaptor operator-=(difference_type x) { copy_iterator_adaptor operator-=(difference_type x)
{
base_ -= x; base_ -= x;
return *this; return *this;
} }
copy_iterator_adaptor operator+(difference_type n) { copy_iterator_adaptor operator+(difference_type n)
return copy_iterator_adaptor(base_+n); {
return copy_iterator_adaptor(base_ + n);
} }
copy_iterator_adaptor operator-(difference_type n) { copy_iterator_adaptor operator-(difference_type n)
return copy_iterator_adaptor(base_-n); {
return copy_iterator_adaptor(base_ - n);
} }
friend copy_iterator_adaptor operator+( friend copy_iterator_adaptor operator+(
difference_type n, copy_iterator_adaptor x) { difference_type n, copy_iterator_adaptor x)
return x+n; {
return x + n;
} }
difference_type operator-(copy_iterator_adaptor const& other) { difference_type operator-(copy_iterator_adaptor const& other)
return base_-other.base_; {
return base_ - other.base_;
} }
bool operator==(copy_iterator_adaptor const& x) const { bool operator==(copy_iterator_adaptor const& x) const
{
return base_ == x.base_; return base_ == x.base_;
} }
bool operator!=(copy_iterator_adaptor const& x) const { bool operator!=(copy_iterator_adaptor const& x) const
{
return base_ != x.base_; return base_ != x.base_;
} }
bool operator<(copy_iterator_adaptor const& x) const { bool operator<(copy_iterator_adaptor const& x) const
{
return base_ < x.base_; return base_ < x.base_;
} }
bool operator>(copy_iterator_adaptor const& x) const { bool operator>(copy_iterator_adaptor const& x) const
{
return base_ > x.base_; return base_ > x.base_;
} }
bool operator<=(copy_iterator_adaptor const& x) const { bool operator<=(copy_iterator_adaptor const& x) const
{
return base_ <= x.base_; return base_ <= x.base_;
} }
bool operator>=(copy_iterator_adaptor const& x) const { bool operator>=(copy_iterator_adaptor const& x) const
{
return base_ >= x.base_; return base_ >= x.base_;
} }
private: private:
Iterator base_; Iterator base_;
}; };
template <class Iterator> template <class Iterator>
copy_iterator_adaptor<Iterator> copy_iterator(Iterator const& it) copy_iterator_adaptor<Iterator> copy_iterator(Iterator const& it)
{ {
return copy_iterator_adaptor<Iterator>(it); return copy_iterator_adaptor<Iterator>(it);
} }
} }
#endif #endif

View File

@@ -9,36 +9,33 @@
#if !defined(BOOST_UNORDERED_TEST_HELPERS_INVARIANT_HEADER) #if !defined(BOOST_UNORDERED_TEST_HELPERS_INVARIANT_HEADER)
#define BOOST_UNORDERED_TEST_HELPERS_INVARIANT_HEADER #define BOOST_UNORDERED_TEST_HELPERS_INVARIANT_HEADER
#include <set>
#include <cmath>
#include "./metafunctions.hpp"
#include "./helpers.hpp" #include "./helpers.hpp"
#include "./metafunctions.hpp"
#include <cmath>
#include <set>
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4127) // conditional expression is constant #pragma warning(disable : 4127) // conditional expression is constant
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int', #pragma warning(disable : 4267) // conversion from 'size_t' to 'unsigned int',
// possible loss of data // possible loss of data
#endif #endif
namespace test namespace test {
template <class X> void check_equivalent_keys(X const& x1)
{ {
template <class X>
void check_equivalent_keys(X const& x1)
{
BOOST_DEDUCED_TYPENAME X::key_equal eq = x1.key_eq(); BOOST_DEDUCED_TYPENAME X::key_equal eq = x1.key_eq();
typedef BOOST_DEDUCED_TYPENAME X::key_type key_type; typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
std::set<key_type, std::less<key_type> > found_; std::set<key_type, std::less<key_type> > found_;
BOOST_DEDUCED_TYPENAME X::const_iterator BOOST_DEDUCED_TYPENAME X::const_iterator it = x1.begin(), end = x1.end();
it = x1.begin(), end = x1.end();
BOOST_DEDUCED_TYPENAME X::size_type size = 0; BOOST_DEDUCED_TYPENAME X::size_type size = 0;
while(it != end) { while (it != end) {
// First test that the current key has not occurred before, required // First test that the current key has not occurred before, required
// to test either that keys are unique or that equivalent keys are // to test either that keys are unique or that equivalent keys are
// adjacent. (6.3.1/6) // adjacent. (6.3.1/6)
key_type key = get_key<X>(*it); key_type key = get_key<X>(*it);
if(!found_.insert(key).second) if (!found_.insert(key).second)
BOOST_ERROR("Elements with equivalent keys aren't adjacent."); BOOST_ERROR("Elements with equivalent keys aren't adjacent.");
// Iterate over equivalent keys, counting them. // Iterate over equivalent keys, counting them.
@@ -47,34 +44,36 @@ namespace test
++it; ++it;
++count; ++count;
++size; ++size;
} while(it != end && eq(get_key<X>(*it), key)); } while (it != end && eq(get_key<X>(*it), key));
// If the container has unique keys, test that there's only one. // If the container has unique keys, test that there's only one.
// Since the previous test makes sure that all equivalent keys are // Since the previous test makes sure that all equivalent keys are
// adjacent, this is all the equivalent keys - so the test is // adjacent, this is all the equivalent keys - so the test is
// sufficient. (6.3.1/6 again). // sufficient. (6.3.1/6 again).
if(test::has_unique_keys<X>::value && count != 1) if (test::has_unique_keys<X>::value && count != 1)
BOOST_ERROR("Non-unique key."); BOOST_ERROR("Non-unique key.");
if(x1.count(key) != count) { if (x1.count(key) != count) {
BOOST_ERROR("Incorrect output of count."); BOOST_ERROR("Incorrect output of count.");
std::cerr<<x1.count(key)<<","<<count<<"\n"; std::cerr << x1.count(key) << "," << count << "\n";
} }
// Check that the keys are in the correct bucket and are // Check that the keys are in the correct bucket and are
// adjacent in the bucket. // adjacent in the bucket.
BOOST_DEDUCED_TYPENAME X::size_type bucket = x1.bucket(key); BOOST_DEDUCED_TYPENAME X::size_type bucket = x1.bucket(key);
BOOST_DEDUCED_TYPENAME X::const_local_iterator BOOST_DEDUCED_TYPENAME X::const_local_iterator lit = x1.begin(bucket),
lit = x1.begin(bucket), lend = x1.end(bucket); lend = x1.end(bucket);
for(; lit != lend && !eq(get_key<X>(*lit), key); ++lit) continue; for (; lit != lend && !eq(get_key<X>(*lit), key); ++lit)
if(lit == lend) continue;
if (lit == lend)
BOOST_ERROR("Unable to find element with a local_iterator"); BOOST_ERROR("Unable to find element with a local_iterator");
unsigned int count2 = 0; unsigned int count2 = 0;
for(; lit != lend && eq(get_key<X>(*lit), key); ++lit) ++count2; for (; lit != lend && eq(get_key<X>(*lit), key); ++lit)
if(count != count2) ++count2;
if (count != count2)
BOOST_ERROR("Element count doesn't match local_iterator."); BOOST_ERROR("Element count doesn't match local_iterator.");
for(; lit != lend; ++lit) { for (; lit != lend; ++lit) {
if(eq(get_key<X>(*lit), key)) { if (eq(get_key<X>(*lit), key)) {
BOOST_ERROR("Non-adjacent element with equivalent key " BOOST_ERROR("Non-adjacent element with equivalent key "
"in bucket."); "in bucket.");
break; break;
@@ -84,44 +83,43 @@ namespace test
// Check that size matches up. // Check that size matches up.
if(x1.size() != size) { if (x1.size() != size) {
BOOST_ERROR("x1.size() doesn't match actual size."); BOOST_ERROR("x1.size() doesn't match actual size.");
std::cout<<x1.size()<<"/"<<size<<std::endl; std::cout << x1.size() << "/" << size << std::endl;
} }
// Check the load factor. // Check the load factor.
float load_factor = size == 0 ? 0 : float load_factor =
static_cast<float>(size) / static_cast<float>(x1.bucket_count()); size == 0 ? 0 : static_cast<float>(size) /
static_cast<float>(x1.bucket_count());
using namespace std; using namespace std;
if(fabs(x1.load_factor() - load_factor) > x1.load_factor() / 64) if (fabs(x1.load_factor() - load_factor) > x1.load_factor() / 64)
BOOST_ERROR("x1.load_factor() doesn't match actual load_factor."); BOOST_ERROR("x1.load_factor() doesn't match actual load_factor.");
// Check that size in the buckets matches up. // Check that size in the buckets matches up.
BOOST_DEDUCED_TYPENAME X::size_type bucket_size = 0; BOOST_DEDUCED_TYPENAME X::size_type bucket_size = 0;
for (BOOST_DEDUCED_TYPENAME X::size_type for (BOOST_DEDUCED_TYPENAME X::size_type i = 0; i < x1.bucket_count();
i = 0; i < x1.bucket_count(); ++i) ++i) {
{
for (BOOST_DEDUCED_TYPENAME X::const_local_iterator for (BOOST_DEDUCED_TYPENAME X::const_local_iterator
begin2 = x1.begin(i), end2 = x1.end(i); begin2 = x1.begin(i),
begin2 != end2; ++begin2) end2 = x1.end(i);
{ begin2 != end2; ++begin2) {
++bucket_size; ++bucket_size;
} }
} }
if(x1.size() != bucket_size) { if (x1.size() != bucket_size) {
BOOST_ERROR("x1.size() doesn't match bucket size."); BOOST_ERROR("x1.size() doesn't match bucket size.");
std::cout<<x1.size()<<"/"<<bucket_size<<std::endl; std::cout << x1.size() << "/" << bucket_size << std::endl;
}
} }
} }
}
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
#pragma warning(pop) #pragma warning(pop)
#endif #endif
#endif #endif

View File

@@ -12,53 +12,51 @@
#define UNORDERED_TEST_LIST_HEADER #define UNORDERED_TEST_LIST_HEADER
#include <boost/limits.hpp> #include <boost/limits.hpp>
#include <iterator>
#include <functional> #include <functional>
#include <iterator>
namespace test namespace test {
template <typename It1, typename It2>
bool equal(It1 begin, It1 end, It2 compare)
{ {
template <typename It1, typename It2> for (; begin != end; ++begin, ++compare)
bool equal(It1 begin, It1 end, It2 compare) if (*begin != *compare)
{ return false;
for(;begin != end; ++begin, ++compare)
if(*begin != *compare) return false;
return true; return true;
} }
template <typename It1, typename It2, typename Pred> template <typename It1, typename It2, typename Pred>
bool equal(It1 begin, It1 end, It2 compare, Pred predicate) bool equal(It1 begin, It1 end, It2 compare, Pred predicate)
{ {
for(;begin != end; ++begin, ++compare) for (; begin != end; ++begin, ++compare)
if(!predicate(*begin, *compare)) return false; if (!predicate(*begin, *compare))
return false;
return true; return true;
} }
template <typename T> class list;
template <typename T> class list; namespace test_detail {
template <typename T> class list_node;
template <typename T> class list_data;
template <typename T> class list_iterator;
template <typename T> class list_const_iterator;
namespace test_detail template <typename T> class list_node
{ {
template <typename T> class list_node;
template <typename T> class list_data;
template <typename T> class list_iterator;
template <typename T> class list_const_iterator;
template <typename T>
class list_node
{
list_node(list_node const&); list_node(list_node const&);
list_node& operator=(list_node const&); list_node& operator=(list_node const&);
public: public:
T value_; T value_;
list_node* next_; list_node* next_;
list_node(T const& v) : value_(v), next_(0) {} list_node(T const& v) : value_(v), next_(0) {}
list_node(T const& v, list_node* n) : value_(v), next_(n) {} list_node(T const& v, list_node* n) : value_(v), next_(n) {}
}; };
template <typename T> template <typename T> class list_data
class list_data {
{
public: public:
typedef list_node<T> node; typedef list_node<T> node;
typedef unsigned int size_type; typedef unsigned int size_type;
@@ -69,50 +67,56 @@ namespace test
list_data() : first_(0), last_ptr_(&first_), size_(0) {} list_data() : first_(0), last_ptr_(&first_), size_(0) {}
~list_data() { ~list_data()
while(first_) { {
while (first_) {
node* tmp = first_; node* tmp = first_;
first_ = first_->next_; first_ = first_->next_;
delete tmp; delete tmp;
} }
} }
private: private:
list_data(list_data const&); list_data(list_data const&);
list_data& operator=(list_data const&); list_data& operator=(list_data const&);
}; };
template <typename T> template <typename T>
class list_iterator class list_iterator
: public std::iterator< : public std::iterator<std::forward_iterator_tag, T, int, T*, T&>
std::forward_iterator_tag, T, {
int, T*, T&>
{
friend class list_const_iterator<T>; friend class list_const_iterator<T>;
friend class test::list<T>; friend class test::list<T>;
typedef list_node<T> node; typedef list_node<T> node;
typedef list_const_iterator<T> const_iterator; typedef list_const_iterator<T> const_iterator;
node* ptr_; node* ptr_;
public: public:
list_iterator() : ptr_(0) {} list_iterator() : ptr_(0) {}
explicit list_iterator(node* x) : ptr_(x) {} explicit list_iterator(node* x) : ptr_(x) {}
T& operator*() const { return ptr_->value_; } T& operator*() const { return ptr_->value_; }
T* operator->() const { return &ptr_->value_; } T* operator->() const { return &ptr_->value_; }
list_iterator& operator++() { list_iterator& operator++()
ptr_ = ptr_->next_; return *this; } {
list_iterator operator++(int) { ptr_ = ptr_->next_;
list_iterator tmp = *this; ptr_ = ptr_->next_; return tmp; } return *this;
}
list_iterator operator++(int)
{
list_iterator tmp = *this;
ptr_ = ptr_->next_;
return tmp;
}
bool operator==(const_iterator y) const { return ptr_ == y.ptr_; } bool operator==(const_iterator y) const { return ptr_ == y.ptr_; }
bool operator!=(const_iterator y) const { return ptr_ != y.ptr_; } bool operator!=(const_iterator y) const { return ptr_ != y.ptr_; }
}; };
template <typename T> template <typename T>
class list_const_iterator class list_const_iterator : public std::iterator<std::forward_iterator_tag, T,
: public std::iterator<
std::forward_iterator_tag, T,
int, T const*, T const&> int, T const*, T const&>
{ {
friend class list_iterator<T>; friend class list_iterator<T>;
friend class test::list<T>; friend class test::list<T>;
typedef list_node<T> node; typedef list_node<T> node;
@@ -120,6 +124,7 @@ namespace test
typedef list_const_iterator<T> const_iterator; typedef list_const_iterator<T> const_iterator;
node* ptr_; node* ptr_;
public: public:
list_const_iterator() : ptr_(0) {} list_const_iterator() : ptr_(0) {}
list_const_iterator(list_iterator<T> const& x) : ptr_(x.ptr_) {} list_const_iterator(list_iterator<T> const& x) : ptr_(x.ptr_) {}
@@ -140,24 +145,18 @@ namespace test
return tmp; return tmp;
} }
bool operator==(const_iterator y) const bool operator==(const_iterator y) const { return ptr_ == y.ptr_; }
{
return ptr_ == y.ptr_;
}
bool operator!=(const_iterator y) const bool operator!=(const_iterator y) const { return ptr_ != y.ptr_; }
{ };
return ptr_ != y.ptr_; }
}
};
}
template <typename T> template <typename T> class list
class list {
{
typedef test::test_detail::list_data<T> data; typedef test::test_detail::list_data<T> data;
typedef test::test_detail::list_node<T> node; typedef test::test_detail::list_node<T> node;
data data_; data data_;
public: public:
typedef T value_type; typedef T value_type;
typedef value_type& reference; typedef value_type& reference;
@@ -169,16 +168,16 @@ namespace test
list() : data_() {} list() : data_() {}
list(list const& other) : data_() { list(list const& other) : data_() { insert(other.begin(), other.end()); }
insert(other.begin(), other.end());
}
template <class InputIterator> template <class InputIterator>
list(InputIterator i, InputIterator j) : data_() { list(InputIterator i, InputIterator j) : data_()
{
insert(i, j); insert(i, j);
} }
list& operator=(list const& other) { list& operator=(list const& other)
{
clear(); clear();
insert(other.begin(), other.end()); insert(other.begin(), other.end());
return *this; return *this;
@@ -191,26 +190,30 @@ namespace test
const_iterator cbegin() const { return iterator(data_.first_); } const_iterator cbegin() const { return iterator(data_.first_); }
const_iterator cend() const { return iterator(); } const_iterator cend() const { return iterator(); }
template <class InputIterator> template <class InputIterator> void insert(InputIterator i, InputIterator j)
void insert(InputIterator i, InputIterator j) { {
for(; i != j; ++i) for (; i != j; ++i)
push_back(*i); push_back(*i);
} }
void push_front(value_type const& v) { void push_front(value_type const& v)
{
data_.first_ = new node(v, data_.first_); data_.first_ = new node(v, data_.first_);
if(!data_.size_) data_.last_ptr_ = &(*data_.last_ptr_)->next_; if (!data_.size_)
data_.last_ptr_ = &(*data_.last_ptr_)->next_;
++data_.size_; ++data_.size_;
} }
void push_back(value_type const& v) { void push_back(value_type const& v)
{
*data_.last_ptr_ = new node(v); *data_.last_ptr_ = new node(v);
data_.last_ptr_ = &(*data_.last_ptr_)->next_; data_.last_ptr_ = &(*data_.last_ptr_)->next_;
++data_.size_; ++data_.size_;
} }
void clear() { void clear()
while(data_.first_) { {
while (data_.first_) {
node* tmp = data_.first_; node* tmp = data_.first_;
data_.first_ = data_.first_->next_; data_.first_ = data_.first_->next_;
--data_.size_; --data_.size_;
@@ -219,71 +222,67 @@ namespace test
data_.last_ptr_ = &data_.first_; data_.last_ptr_ = &data_.first_;
} }
void erase(const_iterator i, const_iterator j) { void erase(const_iterator i, const_iterator j)
{
node** ptr = &data_.first_; node** ptr = &data_.first_;
while(*ptr != i.ptr_) { while (*ptr != i.ptr_) {
ptr = &(*ptr)->next_; ptr = &(*ptr)->next_;
} }
while(*ptr != j.ptr_) { while (*ptr != j.ptr_) {
node* to_delete = *ptr; node* to_delete = *ptr;
*ptr = (*ptr)->next_; *ptr = (*ptr)->next_;
--data_.size_; --data_.size_;
delete to_delete; delete to_delete;
} }
if(!*ptr) data_.last_ptr_ = ptr; if (!*ptr)
data_.last_ptr_ = ptr;
} }
bool empty() const { bool empty() const { return !data_.size_; }
return !data_.size_;
size_type size() const { return data_.size_; }
void sort() { sort(std::less<T>()); }
template <typename Less> void sort(Less less = Less())
{
if (!empty())
merge_sort(
&data_.first_, (std::numeric_limits<size_type>::max)(), less);
} }
size_type size() const { bool operator==(list const& y) const
return data_.size_; {
return size() == y.size() && test::equal(begin(), end(), y.begin());
} }
void sort() { bool operator!=(list const& y) const { return !(*this == y); }
sort(std::less<T>());
}
template <typename Less>
void sort(Less less = Less()) {
if(!empty()) merge_sort(&data_.first_,
(std::numeric_limits<size_type>::max)(), less);
}
bool operator==(list const& y) const {
return size() == y.size() &&
test::equal(begin(), end(), y.begin());
}
bool operator!=(list const& y) const {
return !(*this == y);
}
private: private:
template <typename Less> template <typename Less>
node** merge_sort(node** l, size_type recurse_limit, Less less) node** merge_sort(node** l, size_type recurse_limit, Less less)
{ {
node** ptr = &(*l)->next_; node** ptr = &(*l)->next_;
for(size_type count = 0; count < recurse_limit && *ptr; ++count) for (size_type count = 0; count < recurse_limit && *ptr; ++count) {
{ ptr = merge_adjacent_ranges(
ptr = merge_adjacent_ranges(l, ptr, l, ptr, merge_sort(ptr, count, less), less);
merge_sort(ptr, count, less), less);
} }
return ptr; return ptr;
} }
template <typename Less> template <typename Less>
node** merge_adjacent_ranges(node** first, node** second, node** merge_adjacent_ranges(
node** third, Less less) node** first, node** second, node** third, Less less)
{ {
for(;;) { for (;;) {
for(;;) { for (;;) {
if(first == second) return third; if (first == second)
if(less((*second)->value_, (*first)->value_)) break; return third;
if (less((*second)->value_, (*first)->value_))
break;
first = &(*first)->next_; first = &(*first)->next_;
} }
@@ -293,9 +292,11 @@ namespace test
// Since the two ranges we just swapped, the order is now: // Since the two ranges we just swapped, the order is now:
// first...third...second // first...third...second
for(;;) { for (;;) {
if(first == third) return second; if (first == third)
if(!less((*first)->value_, (*third)->value_)) break; return second;
if (!less((*first)->value_, (*third)->value_))
break;
first = &(*first)->next_; first = &(*first)->next_;
} }
@@ -310,9 +311,10 @@ namespace test
*first = *second; *first = *second;
*second = *third; *second = *third;
*third = tmp; *third = tmp;
if(!*second) data_.last_ptr_ = second; if (!*second)
data_.last_ptr_ = second;
} }
}; };
} }
#endif #endif

View File

@@ -6,69 +6,69 @@
#if !defined(BOOST_UNORDERED_TEST_MEMORY_HEADER) #if !defined(BOOST_UNORDERED_TEST_MEMORY_HEADER)
#define BOOST_UNORDERED_TEST_MEMORY_HEADER #define BOOST_UNORDERED_TEST_MEMORY_HEADER
#include <memory> #include "../helpers/test.hpp"
#include <map>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/unordered/detail/implementation.hpp> #include <boost/unordered/detail/implementation.hpp>
#include "../helpers/test.hpp" #include <map>
#include <memory>
namespace test namespace test {
namespace detail {
struct memory_area
{ {
namespace detail
{
struct memory_area {
void const* start; void const* start;
void const* end; void const* end;
memory_area(void const* s, void const* e) memory_area(void const* s, void const* e) : start(s), end(e)
: start(s), end(e)
{ {
BOOST_ASSERT(start != end); BOOST_ASSERT(start != end);
} }
}; };
struct memory_track { struct memory_track
explicit memory_track(int tag = -1) : {
constructed_(0), explicit memory_track(int tag = -1) : constructed_(0), tag_(tag) {}
tag_(tag) {}
int constructed_; int constructed_;
int tag_; int tag_;
}; };
// This is a bit dodgy as it defines overlapping // This is a bit dodgy as it defines overlapping
// areas as 'equal', so this isn't a total ordering. // areas as 'equal', so this isn't a total ordering.
// But it is for non-overlapping memory regions - which // But it is for non-overlapping memory regions - which
// is what'll be stored. // is what'll be stored.
// //
// All searches will be for areas entirely contained by // All searches will be for areas entirely contained by
// a member of the set - so it should find the area that contains // a member of the set - so it should find the area that contains
// the region that is searched for. // the region that is searched for.
struct memory_area_compare { struct memory_area_compare
bool operator()(memory_area const& x, memory_area const& y) const { {
bool operator()(memory_area const& x, memory_area const& y) const
{
return x.end <= y.start; return x.end <= y.start;
} }
}; };
struct memory_tracker { struct memory_tracker
{
typedef std::map<memory_area, memory_track, memory_area_compare, typedef std::map<memory_area, memory_track, memory_area_compare,
std::allocator<std::pair<memory_area const, memory_track> > std::allocator<std::pair<memory_area const, memory_track> > >
> allocated_memory_type; allocated_memory_type;
allocated_memory_type allocated_memory; allocated_memory_type allocated_memory;
unsigned int count_allocators; unsigned int count_allocators;
unsigned int count_allocations; unsigned int count_allocations;
unsigned int count_constructions; unsigned int count_constructions;
memory_tracker() : memory_tracker()
count_allocators(0), count_allocations(0), : count_allocators(0), count_allocations(0), count_constructions(0)
count_constructions(0) {
{} }
void allocator_ref() void allocator_ref()
{ {
if(count_allocators == 0) { if (count_allocators == 0) {
count_allocations = 0; count_allocations = 0;
count_constructions = 0; count_constructions = 0;
allocated_memory.clear(); allocated_memory.clear();
@@ -79,9 +79,9 @@ namespace test
void allocator_unref() void allocator_unref()
{ {
BOOST_TEST(count_allocators > 0); BOOST_TEST(count_allocators > 0);
if(count_allocators > 0) { if (count_allocators > 0) {
--count_allocators; --count_allocators;
if(count_allocators == 0) { if (count_allocators == 0) {
bool no_allocations_left = (count_allocations == 0); bool no_allocations_left = (count_allocations == 0);
bool no_constructions_left = (count_constructions == 0); bool no_constructions_left = (count_constructions == 0);
bool allocated_memory_empty = allocated_memory.empty(); bool allocated_memory_empty = allocated_memory.empty();
@@ -99,65 +99,60 @@ namespace test
} }
} }
void track_allocate(void *ptr, std::size_t n, std::size_t size, void track_allocate(void* ptr, std::size_t n, std::size_t size, int tag)
int tag)
{ {
if(n == 0) { if (n == 0) {
BOOST_ERROR("Allocating 0 length array."); BOOST_ERROR("Allocating 0 length array.");
} } else {
else {
++count_allocations; ++count_allocations;
allocated_memory.insert( allocated_memory.insert(std::pair<memory_area const, memory_track>(
std::pair<memory_area const, memory_track>( memory_area(ptr, (char*)ptr + n * size), memory_track(tag)));
memory_area(ptr, (char*) ptr + n * size),
memory_track(tag)));
} }
} }
void track_deallocate(void* ptr, std::size_t n, std::size_t size, void track_deallocate(void* ptr, std::size_t n, std::size_t size, int tag,
int tag, bool check_tag_ = true) bool check_tag_ = true)
{ {
allocated_memory_type::iterator pos = allocated_memory_type::iterator pos =
allocated_memory.find( allocated_memory.find(memory_area(ptr, (char*)ptr + n * size));
memory_area(ptr, (char*) ptr + n * size)); if (pos == allocated_memory.end()) {
if(pos == allocated_memory.end()) {
BOOST_ERROR("Deallocating unknown pointer."); BOOST_ERROR("Deallocating unknown pointer.");
} else { } else {
BOOST_TEST(pos->first.start == ptr); BOOST_TEST(pos->first.start == ptr);
BOOST_TEST(pos->first.end == (char*) ptr + n * size); BOOST_TEST(pos->first.end == (char*)ptr + n * size);
if (check_tag_) BOOST_TEST(pos->second.tag_ == tag); if (check_tag_)
BOOST_TEST(pos->second.tag_ == tag);
allocated_memory.erase(pos); allocated_memory.erase(pos);
} }
BOOST_TEST(count_allocations > 0); BOOST_TEST(count_allocations > 0);
if(count_allocations > 0) --count_allocations; if (count_allocations > 0)
--count_allocations;
} }
void track_construct(void* /*ptr*/, std::size_t /*size*/, void track_construct(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
int /*tag*/)
{ {
++count_constructions; ++count_constructions;
} }
void track_destroy(void* /*ptr*/, std::size_t /*size*/, void track_destroy(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
int /*tag*/)
{ {
BOOST_TEST(count_constructions > 0); BOOST_TEST(count_constructions > 0);
if(count_constructions > 0) --count_constructions; if (count_constructions > 0)
} --count_constructions;
};
} }
};
}
namespace detail namespace detail {
{ // This won't be a problem as I'm only using a single compile unit
// This won't be a problem as I'm only using a single compile unit // in each test (this is actually required by the minimal test
// in each test (this is actually required by the minimal test // framework).
// framework). //
// // boostinspect:nounnamed
// boostinspect:nounnamed namespace {
namespace { test::detail::memory_tracker tracker;
test::detail::memory_tracker tracker; }
} }
}
} }
#endif #endif

View File

@@ -9,24 +9,26 @@
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/type_traits/is_same.hpp> #include <boost/type_traits/is_same.hpp>
namespace test namespace test {
template <class Container>
struct is_set
: public boost::is_same<BOOST_DEDUCED_TYPENAME Container::key_type,
BOOST_DEDUCED_TYPENAME Container::value_type>
{ {
template <class Container> };
struct is_set
: public boost::is_same<
BOOST_DEDUCED_TYPENAME Container::key_type,
BOOST_DEDUCED_TYPENAME Container::value_type> {};
template <class Container> template <class Container> struct has_unique_keys
struct has_unique_keys {
{
static char flip(BOOST_DEDUCED_TYPENAME Container::iterator const&); static char flip(BOOST_DEDUCED_TYPENAME Container::iterator const&);
static long flip(std::pair<BOOST_DEDUCED_TYPENAME Container::iterator, bool> const&); static long flip(
BOOST_STATIC_CONSTANT(bool, value = sizeof(long) == sizeof( std::pair<BOOST_DEDUCED_TYPENAME Container::iterator, bool> const&);
flip(((Container*) 0)->insert(*(BOOST_DEDUCED_TYPENAME Container::value_type*) 0)) BOOST_STATIC_CONSTANT(bool,
)); value = sizeof(long) ==
}; sizeof(flip(
((Container*)0)
->insert(*(
BOOST_DEDUCED_TYPENAME Container::value_type*)0))));
};
} }
#endif #endif

View File

@@ -6,6 +6,6 @@
#if defined(_WIN32_WCE) #if defined(_WIN32_WCE)
// The standard windows mobile headers trigger this warning so I disable it // The standard windows mobile headers trigger this warning so I disable it
// before doing anything else. // before doing anything else.
#pragma warning(disable:4201) // nonstandard extension used : #pragma warning(disable : 4201) // nonstandard extension used :
// nameless struct/union // nameless struct/union
#endif #endif

View File

@@ -6,111 +6,104 @@
#if !defined(BOOST_UNORDERED_TEST_HELPERS_RANDOM_VALUES_HEADER) #if !defined(BOOST_UNORDERED_TEST_HELPERS_RANDOM_VALUES_HEADER)
#define BOOST_UNORDERED_TEST_HELPERS_RANDOM_VALUES_HEADER #define BOOST_UNORDERED_TEST_HELPERS_RANDOM_VALUES_HEADER
#include "./generators.hpp"
#include "./list.hpp" #include "./list.hpp"
#include "./metafunctions.hpp"
#include <algorithm> #include <algorithm>
#include <boost/detail/select_type.hpp> #include <boost/detail/select_type.hpp>
#include "./generators.hpp"
#include "./metafunctions.hpp"
namespace test namespace test {
template <class X> struct unordered_generator_set
{ {
template <class X>
struct unordered_generator_set
{
typedef BOOST_DEDUCED_TYPENAME X::value_type value_type; typedef BOOST_DEDUCED_TYPENAME X::value_type value_type;
random_generator type_; random_generator type_;
unordered_generator_set(random_generator type) unordered_generator_set(random_generator type) : type_(type) {}
: type_(type) {}
template <class T> template <class T> void fill(T& x, std::size_t len)
void fill(T& x, std::size_t len) { {
value_type* value_ptr = 0; value_type* value_ptr = 0;
len += x.size(); len += x.size();
for (std::size_t i = 0; i < len; ++i) { for (std::size_t i = 0; i < len; ++i) {
value_type value = generate(value_ptr, type_); value_type value = generate(value_ptr, type_);
std::size_t count = type_ == generate_collisions ? std::size_t count =
random_value(5) + 1 : 1; type_ == generate_collisions ? random_value(5) + 1 : 1;
for(std::size_t j = 0; j < count; ++j) { for (std::size_t j = 0; j < count; ++j) {
x.push_back(value); x.push_back(value);
} }
} }
} }
}; };
template <class X> template <class X> struct unordered_generator_map
struct unordered_generator_map {
{
typedef BOOST_DEDUCED_TYPENAME X::key_type key_type; typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
typedef BOOST_DEDUCED_TYPENAME X::mapped_type mapped_type; typedef BOOST_DEDUCED_TYPENAME X::mapped_type mapped_type;
random_generator type_; random_generator type_;
unordered_generator_map(random_generator type) unordered_generator_map(random_generator type) : type_(type) {}
: type_(type) {}
template <class T> template <class T> void fill(T& x, std::size_t len)
void fill(T& x, std::size_t len) { {
key_type* key_ptr = 0; key_type* key_ptr = 0;
mapped_type* mapped_ptr = 0; mapped_type* mapped_ptr = 0;
for (std::size_t i = 0; i < len; ++i) { for (std::size_t i = 0; i < len; ++i) {
key_type key = generate(key_ptr, type_); key_type key = generate(key_ptr, type_);
std::size_t count = type_ == generate_collisions ? std::size_t count =
random_value(5) + 1 : 1; type_ == generate_collisions ? random_value(5) + 1 : 1;
for(std::size_t j = 0; j < count; ++j) { for (std::size_t j = 0; j < count; ++j) {
x.push_back(std::pair<key_type const, mapped_type>( x.push_back(std::pair<key_type const, mapped_type>(
key, generate(mapped_ptr, type_))); key, generate(mapped_ptr, type_)));
} }
} }
} }
}; };
template <class X> template <class X>
struct unordered_generator_base struct unordered_generator_base
: public boost::detail::if_true< : public boost::detail::if_true<test::is_set<X>::value>::
test::is_set<X>::value BOOST_NESTED_TEMPLATE then<test::unordered_generator_set<X>,
>::BOOST_NESTED_TEMPLATE then< test::unordered_generator_map<X> >
test::unordered_generator_set<X>, {
test::unordered_generator_map<X> };
>
{
};
template <class X> template <class X>
struct unordered_generator : public unordered_generator_base<X>::type struct unordered_generator : public unordered_generator_base<X>::type
{ {
typedef BOOST_DEDUCED_TYPENAME unordered_generator_base<X>::type base; typedef BOOST_DEDUCED_TYPENAME unordered_generator_base<X>::type base;
unordered_generator(random_generator const& type = default_generator) unordered_generator(random_generator const& type = default_generator)
: base(type) {} : base(type)
};
template <class X>
struct random_values
: public test::list<BOOST_DEDUCED_TYPENAME X::value_type>
{ {
}
};
template <class X>
struct random_values : public test::list<BOOST_DEDUCED_TYPENAME X::value_type>
{
random_values() {} random_values() {}
explicit random_values(std::size_t count, test::random_generator const& generator = explicit random_values(std::size_t count,
test::default_generator) test::random_generator const& generator = test::default_generator)
{ {
fill(count, generator); fill(count, generator);
} }
void fill(std::size_t count, test::random_generator const& generator = void fill(std::size_t count,
test::default_generator) test::random_generator const& generator = test::default_generator)
{ {
test::unordered_generator<X> gen(generator); test::unordered_generator<X> gen(generator);
gen.fill(*this, count); gen.fill(*this, count);
} }
}; };
} }
#endif #endif

View File

@@ -6,37 +6,38 @@
#if !defined(BOOST_UNORDERED_TEST_HELPERS_STRONG_HEADER) #if !defined(BOOST_UNORDERED_TEST_HELPERS_STRONG_HEADER)
#define BOOST_UNORDERED_TEST_HELPERS_STRONG_HEADER #define BOOST_UNORDERED_TEST_HELPERS_STRONG_HEADER
#include "./equivalent.hpp"
#include "./exception_test.hpp"
#include "./list.hpp"
#include <boost/config.hpp> #include <boost/config.hpp>
#include <iterator> #include <iterator>
#include "./equivalent.hpp"
#include "./list.hpp"
#include "./exception_test.hpp"
namespace test namespace test {
template <class X> class strong
{ {
template <class X>
class strong
{
typedef test::list<BOOST_DEDUCED_TYPENAME X::value_type> values_type; typedef test::list<BOOST_DEDUCED_TYPENAME X::value_type> values_type;
values_type values_; values_type values_;
unsigned int allocations_; unsigned int allocations_;
public: public:
void store(X const& x, unsigned int allocations = 0) { void store(X const& x, unsigned int allocations = 0)
{
DISABLE_EXCEPTIONS; DISABLE_EXCEPTIONS;
values_.clear(); values_.clear();
values_.insert(x.cbegin(), x.cend()); values_.insert(x.cbegin(), x.cend());
allocations_ = allocations; allocations_ = allocations;
} }
void test(X const& x, unsigned int allocations = 0) const { void test(X const& x, unsigned int allocations = 0) const
if(!(x.size() == values_.size() && {
test::equal(x.cbegin(), x.cend(), values_.begin(), if (!(x.size() == values_.size() &&
test::equivalent))) test::equal(
x.cbegin(), x.cend(), values_.begin(), test::equivalent)))
BOOST_ERROR("Strong exception safety failure."); BOOST_ERROR("Strong exception safety failure.");
if(allocations != allocations_) if (allocations != allocations_)
BOOST_ERROR("Strong exception failure: extra allocations."); BOOST_ERROR("Strong exception failure: extra allocations.");
} }
}; };
} }
#endif #endif

View File

@@ -12,18 +12,20 @@
#include <iostream> #include <iostream>
#define UNORDERED_AUTO_TEST(x) \ #define UNORDERED_AUTO_TEST(x) \
struct BOOST_PP_CAT(x, _type) : public ::test::registered_test_base { \ struct BOOST_PP_CAT(x, _type) : public ::test::registered_test_base \
BOOST_PP_CAT(x, _type)() \ { \
: ::test::registered_test_base(BOOST_PP_STRINGIZE(x)) \ BOOST_PP_CAT(x, _type) \
() : ::test::registered_test_base(BOOST_PP_STRINGIZE(x)) \
{ \ { \
::test::test_list::add_test(this); \ ::test::test_list::add_test(this); \
} \ } \
void run(); \ void run(); \
}; \ }; \
BOOST_PP_CAT(x, _type) x; \ BOOST_PP_CAT(x, _type) x; \
void BOOST_PP_CAT(x, _type)::run() \ void BOOST_PP_CAT(x, _type)::run()
#define RUN_TESTS() int main(int, char**) \ #define RUN_TESTS() \
int main(int, char**) \
{ \ { \
::test::write_compiler_info(); \ ::test::write_compiler_info(); \
::test::test_list::run_tests(); \ ::test::test_list::run_tests(); \
@@ -31,82 +33,83 @@
} }
namespace test { namespace test {
struct registered_test_base { struct registered_test_base
{
registered_test_base* next; registered_test_base* next;
char const* name; char const* name;
explicit registered_test_base(char const* n) : name(n) {} explicit registered_test_base(char const* n) : name(n) {}
virtual void run() = 0; virtual void run() = 0;
virtual ~registered_test_base() {} virtual ~registered_test_base() {}
}; };
namespace test_list { namespace test_list {
static inline registered_test_base*& first() { static inline registered_test_base*& first()
{
static registered_test_base* ptr = 0; static registered_test_base* ptr = 0;
return ptr; return ptr;
} }
static inline registered_test_base*& last() { static inline registered_test_base*& last()
{
static registered_test_base* ptr = 0; static registered_test_base* ptr = 0;
return ptr; return ptr;
} }
static inline void add_test(registered_test_base* test) { static inline void add_test(registered_test_base* test)
if(last()) { {
if (last()) {
last()->next = test; last()->next = test;
} } else {
else {
first() = test; first() = test;
} }
last() = test; last() = test;
} }
static inline void run_tests() { static inline void run_tests()
for(registered_test_base* i = first(); i; i = i->next) { {
std::cout<<"Running "<<i->name<<"\n"<<std::flush; for (registered_test_base* i = first(); i; i = i->next) {
std::cout << "Running " << i->name << "\n" << std::flush;
i->run(); i->run();
std::cerr<<std::flush; std::cerr << std::flush;
std::cout<<std::flush; std::cout << std::flush;
}
}
} }
}
}
inline void write_compiler_info() { inline void write_compiler_info()
{
#if defined(BOOST_GCC_CXX11) #if defined(BOOST_GCC_CXX11)
char const* cpp11 = "true"; char const* cpp11 = "true";
#else #else
char const* cpp11 = "false"; char const* cpp11 = "false";
#endif #endif
std::cout std::cout << "Compiler: " << BOOST_COMPILER << "\n"
<< "Compiler: " << BOOST_COMPILER << "\n"
<< "Library: " << BOOST_STDLIB << "\n" << "Library: " << BOOST_STDLIB << "\n"
<< "C++11: " << cpp11 << "\n" << "C++11: " << cpp11 << "\n"
<< "\n" << "\n"
<< std::flush; << std::flush;
} }
} }
#include <boost/preprocessor/seq/for_each_product.hpp>
#include <boost/preprocessor/seq/fold_left.hpp>
#include <boost/preprocessor/seq/to_tuple.hpp>
#include <boost/preprocessor/seq/seq.hpp>
#include <boost/preprocessor/cat.hpp> #include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/seq/fold_left.hpp>
#include <boost/preprocessor/seq/for_each_product.hpp>
#include <boost/preprocessor/seq/seq.hpp>
#include <boost/preprocessor/seq/to_tuple.hpp>
// Run test with every combination of the parameters (a sequence of sequences) // Run test with every combination of the parameters (a sequence of sequences)
#define UNORDERED_TEST(name, parameters) \ #define UNORDERED_TEST(name, parameters) \
BOOST_PP_SEQ_FOR_EACH_PRODUCT(UNORDERED_TEST_OP, \ BOOST_PP_SEQ_FOR_EACH_PRODUCT(UNORDERED_TEST_OP, ((name))((1))parameters)
((name))((1)) parameters) \
#define UNORDERED_TEST_REPEAT(name, n, parameters) \ #define UNORDERED_TEST_REPEAT(name, n, parameters) \
BOOST_PP_SEQ_FOR_EACH_PRODUCT(UNORDERED_TEST_OP, \ BOOST_PP_SEQ_FOR_EACH_PRODUCT(UNORDERED_TEST_OP, ((name))((n))parameters)
((name))((n)) parameters) \
#define UNORDERED_TEST_OP(r, product) \ #define UNORDERED_TEST_OP(r, product) \
UNORDERED_TEST_OP2( \ UNORDERED_TEST_OP2(BOOST_PP_SEQ_ELEM(0, product), \
BOOST_PP_SEQ_ELEM(0, product), \
BOOST_PP_SEQ_ELEM(1, product), \ BOOST_PP_SEQ_ELEM(1, product), \
BOOST_PP_SEQ_TAIL(BOOST_PP_SEQ_TAIL(product))) \ BOOST_PP_SEQ_TAIL(BOOST_PP_SEQ_TAIL(product)))
#define UNORDERED_TEST_OP2(name, n, params) \ #define UNORDERED_TEST_OP2(name, n, params) \
UNORDERED_AUTO_TEST( \ UNORDERED_AUTO_TEST( \
@@ -114,10 +117,9 @@ namespace test {
{ \ { \
for (int i = 0; i < n; ++i) \ for (int i = 0; i < n; ++i) \
name BOOST_PP_SEQ_TO_TUPLE(params); \ name BOOST_PP_SEQ_TO_TUPLE(params); \
} \ }
#define UNORDERED_TEST_OP_JOIN(s, state, elem) \ #define UNORDERED_TEST_OP_JOIN(s, state, elem) \
BOOST_PP_CAT(state, BOOST_PP_CAT(_, elem)) \ BOOST_PP_CAT(state, BOOST_PP_CAT(_, elem))
#endif #endif

View File

@@ -9,34 +9,29 @@
#if !defined(BOOST_UNORDERED_TEST_HELPERS_TRACKER_HEADER) #if !defined(BOOST_UNORDERED_TEST_HELPERS_TRACKER_HEADER)
#define BOOST_UNORDERED_TEST_HELPERS_TRACKER_HEADER #define BOOST_UNORDERED_TEST_HELPERS_TRACKER_HEADER
#include <set>
#include <map>
#include <iterator>
#include <algorithm>
#include "../objects/fwd.hpp" #include "../objects/fwd.hpp"
#include "./metafunctions.hpp"
#include "./helpers.hpp"
#include "./equivalent.hpp" #include "./equivalent.hpp"
#include "./helpers.hpp"
#include "./list.hpp" #include "./list.hpp"
#include "./metafunctions.hpp"
#include <algorithm>
#include <iterator>
#include <map>
#include <set>
namespace test namespace test {
template <typename X> struct equals_to_compare
{ {
template <typename X> typedef std::less<BOOST_DEDUCED_TYPENAME X::first_argument_type> type;
struct equals_to_compare };
{
typedef std::less<BOOST_DEDUCED_TYPENAME X::first_argument_type>
type;
};
template <> template <> struct equals_to_compare<test::equal_to>
struct equals_to_compare<test::equal_to> {
{
typedef test::less type; typedef test::less type;
}; };
template <class X1, class X2> template <class X1, class X2> void compare_range(X1 const& x1, X2 const& x2)
void compare_range(X1 const& x1, X2 const& x2) {
{
typedef test::list<BOOST_DEDUCED_TYPENAME X1::value_type> value_list; typedef test::list<BOOST_DEDUCED_TYPENAME X1::value_type> value_list;
value_list values1(x1.begin(), x1.end()); value_list values1(x1.begin(), x1.end());
value_list values2(x2.begin(), x2.end()); value_list values2(x2.begin(), x2.end());
@@ -45,123 +40,108 @@ namespace test
BOOST_TEST(values1.size() == values2.size() && BOOST_TEST(values1.size() == values2.size() &&
test::equal(values1.begin(), values1.end(), values2.begin(), test::equal(values1.begin(), values1.end(), values2.begin(),
test::equivalent)); test::equivalent));
} }
template <class X1, class X2, class T> template <class X1, class X2, class T>
void compare_pairs(X1 const& x1, X2 const& x2, T*) void compare_pairs(X1 const& x1, X2 const& x2, T*)
{ {
test::list<T> values1(x1.first, x1.second); test::list<T> values1(x1.first, x1.second);
test::list<T> values2(x2.first, x2.second); test::list<T> values2(x2.first, x2.second);
values1.sort(); values1.sort();
values2.sort(); values2.sort();
BOOST_TEST(values1.size() == values2.size() && BOOST_TEST(values1.size() == values2.size() &&
test::equal(values1.begin(), values1.end(), test::equal(values1.begin(), values1.end(), values2.begin(),
values2.begin(), test::equivalent)); test::equivalent));
} }
template <typename X, template <typename X, bool is_set = test::is_set<X>::value,
bool is_set = test::is_set<X>::value,
bool has_unique_keys = test::has_unique_keys<X>::value> bool has_unique_keys = test::has_unique_keys<X>::value>
struct ordered_base; struct ordered_base;
template <typename X> template <typename X> struct ordered_base<X, true, true>
struct ordered_base<X, true, true> {
{ typedef std::set<BOOST_DEDUCED_TYPENAME X::value_type,
typedef std::set< BOOST_DEDUCED_TYPENAME
BOOST_DEDUCED_TYPENAME X::value_type, equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
type; type;
}; };
template <typename X> template <typename X> struct ordered_base<X, true, false>
struct ordered_base<X, true, false> {
{ typedef std::multiset<BOOST_DEDUCED_TYPENAME X::value_type,
typedef std::multiset< BOOST_DEDUCED_TYPENAME
BOOST_DEDUCED_TYPENAME X::value_type, equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
type; type;
}; };
template <typename X> template <typename X> struct ordered_base<X, false, true>
struct ordered_base<X, false, true> {
{ typedef std::map<BOOST_DEDUCED_TYPENAME X::key_type,
typedef std::map<
BOOST_DEDUCED_TYPENAME X::key_type,
BOOST_DEDUCED_TYPENAME X::mapped_type, BOOST_DEDUCED_TYPENAME X::mapped_type,
BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type> BOOST_DEDUCED_TYPENAME
equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
type; type;
}; };
template <typename X> template <typename X> struct ordered_base<X, false, false>
struct ordered_base<X, false, false> {
{ typedef std::multimap<BOOST_DEDUCED_TYPENAME X::key_type,
typedef std::multimap<
BOOST_DEDUCED_TYPENAME X::key_type,
BOOST_DEDUCED_TYPENAME X::mapped_type, BOOST_DEDUCED_TYPENAME X::mapped_type,
BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type> BOOST_DEDUCED_TYPENAME
equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
type; type;
}; };
template <class X> template <class X> class ordered : public ordered_base<X>::type
class ordered : public ordered_base<X>::type {
{
typedef BOOST_DEDUCED_TYPENAME ordered_base<X>::type base; typedef BOOST_DEDUCED_TYPENAME ordered_base<X>::type base;
public: public:
typedef BOOST_DEDUCED_TYPENAME base::key_compare key_compare; typedef BOOST_DEDUCED_TYPENAME base::key_compare key_compare;
ordered() ordered() : base() {}
: base()
{}
explicit ordered(key_compare const& kc) explicit ordered(key_compare const& kc) : base(kc) {}
: base(kc)
{}
void compare(X const& x) void compare(X const& x) { compare_range(x, *this); }
void compare_key(
X const& x, BOOST_DEDUCED_TYPENAME X::value_type const& val)
{ {
compare_range(x, *this); compare_pairs(x.equal_range(get_key<X>(val)),
}
void compare_key(X const& x,
BOOST_DEDUCED_TYPENAME X::value_type const& val)
{
compare_pairs(
x.equal_range(get_key<X>(val)),
this->equal_range(get_key<X>(val)), this->equal_range(get_key<X>(val)),
(BOOST_DEDUCED_TYPENAME X::value_type*) 0); (BOOST_DEDUCED_TYPENAME X::value_type*)0);
} }
template <class It> template <class It> void insert_range(It b, It e)
void insert_range(It b, It e) { {
while(b != e) { while (b != e) {
this->insert(*b); this->insert(*b);
++b; ++b;
} }
} }
}; };
template <class Equals> template <class Equals>
BOOST_DEDUCED_TYPENAME BOOST_DEDUCED_TYPENAME equals_to_compare<Equals>::type create_compare(
equals_to_compare<Equals>::type create_compare(Equals const&) Equals const&)
{ {
BOOST_DEDUCED_TYPENAME equals_to_compare<Equals>::type x; BOOST_DEDUCED_TYPENAME equals_to_compare<Equals>::type x;
return x; return x;
} }
template <class X> template <class X> ordered<X> create_ordered(X const& container)
ordered<X> create_ordered(X const& container) {
{
return ordered<X>(create_compare(container.key_eq())); return ordered<X>(create_compare(container.key_eq()));
} }
template <class X1, class X2> template <class X1, class X2>
void check_container(X1 const& container, X2 const& values) void check_container(X1 const& container, X2 const& values)
{ {
ordered<X1> tracker = create_ordered(container); ordered<X1> tracker = create_ordered(container);
tracker.insert_range(values.begin(), values.end()); tracker.insert_range(values.begin(), values.end());
tracker.compare(container); tracker.compare(container);
} }
} }
#endif #endif

View File

@@ -13,90 +13,142 @@
#include "../helpers/fwd.hpp" #include "../helpers/fwd.hpp"
#include "../helpers/memory.hpp" #include "../helpers/memory.hpp"
namespace test namespace test {
struct allocator_false
{ {
struct allocator_false enum
{ {
enum {
is_select_on_copy = 0, is_select_on_copy = 0,
is_propagate_on_swap = 0, is_propagate_on_swap = 0,
is_propagate_on_assign = 0, is_propagate_on_assign = 0,
is_propagate_on_move = 0, is_propagate_on_move = 0,
cxx11_construct = 0 cxx11_construct = 0
}; };
}; };
struct allocator_flags_all struct allocator_flags_all
{
enum
{ {
enum {
is_select_on_copy = 1, is_select_on_copy = 1,
is_propagate_on_swap = 1, is_propagate_on_swap = 1,
is_propagate_on_assign = 1, is_propagate_on_assign = 1,
is_propagate_on_move = 1, is_propagate_on_move = 1,
cxx11_construct = 1 cxx11_construct = 1
}; };
};
struct select_copy : allocator_false
{
enum
{
is_select_on_copy = 1
}; };
};
struct select_copy : allocator_false struct propagate_swap : allocator_false
{ enum { is_select_on_copy = 1 }; }; {
struct propagate_swap : allocator_false enum
{ enum { is_propagate_on_swap = 1 }; };
struct propagate_assign : allocator_false
{ enum { is_propagate_on_assign = 1 }; };
struct propagate_move : allocator_false
{ enum { is_propagate_on_move = 1 }; };
struct no_select_copy : allocator_flags_all
{ enum { is_select_on_copy = 0 }; };
struct no_propagate_swap : allocator_flags_all
{ enum { is_propagate_on_swap = 0 }; };
struct no_propagate_assign : allocator_flags_all
{ enum { is_propagate_on_assign = 0 }; };
struct no_propagate_move : allocator_flags_all
{ enum { is_propagate_on_move = 0 }; };
template <typename Flag>
struct swap_allocator_base
{ {
struct propagate_on_container_swap { is_propagate_on_swap = 1
enum { value = Flag::is_propagate_on_swap }; };
}; };
};
template <typename Flag> struct propagate_assign : allocator_false
struct assign_allocator_base {
enum
{ {
struct propagate_on_container_copy_assignment { is_propagate_on_assign = 1
enum { value = Flag::is_propagate_on_assign }; };
}; };
};
template <typename Flag> struct propagate_move : allocator_false
struct move_allocator_base {
enum
{ {
struct propagate_on_container_move_assignment { is_propagate_on_move = 1
enum { value = Flag::is_propagate_on_move }; };
}; };
};
namespace struct no_select_copy : allocator_flags_all
{
enum
{ {
// boostinspect:nounnamed is_select_on_copy = 0
bool force_equal_allocator_value = false; };
} };
struct no_propagate_swap : allocator_flags_all
{
enum
{
is_propagate_on_swap = 0
};
};
struct no_propagate_assign : allocator_flags_all
{
enum
{
is_propagate_on_assign = 0
};
};
struct no_propagate_move : allocator_flags_all
{
enum
{
is_propagate_on_move = 0
};
};
struct force_equal_allocator template <typename Flag> struct swap_allocator_base
{
struct propagate_on_container_swap
{ {
enum
{
value = Flag::is_propagate_on_swap
};
};
};
template <typename Flag> struct assign_allocator_base
{
struct propagate_on_container_copy_assignment
{
enum
{
value = Flag::is_propagate_on_assign
};
};
};
template <typename Flag> struct move_allocator_base
{
struct propagate_on_container_move_assignment
{
enum
{
value = Flag::is_propagate_on_move
};
};
};
namespace {
// boostinspect:nounnamed
bool force_equal_allocator_value = false;
}
struct force_equal_allocator
{
bool old_value_; bool old_value_;
explicit force_equal_allocator(bool value) explicit force_equal_allocator(bool value)
: old_value_(force_equal_allocator_value) : old_value_(force_equal_allocator_value)
{ force_equal_allocator_value = value; }
~force_equal_allocator()
{ force_equal_allocator_value = old_value_; }
};
template <typename T>
struct cxx11_allocator_base
{ {
force_equal_allocator_value = value;
}
~force_equal_allocator() { force_equal_allocator_value = old_value_; }
};
template <typename T> struct cxx11_allocator_base
{
int tag_; int tag_;
int selected_; int selected_;
@@ -108,14 +160,13 @@ namespace test
typedef T const& const_reference; typedef T const& const_reference;
typedef T value_type; typedef T value_type;
explicit cxx11_allocator_base(int t) explicit cxx11_allocator_base(int t) : tag_(t), selected_(0)
: tag_(t), selected_(0)
{ {
detail::tracker.allocator_ref(); detail::tracker.allocator_ref();
} }
template <typename Y> cxx11_allocator_base( template <typename Y>
cxx11_allocator_base<Y> const& x) cxx11_allocator_base(cxx11_allocator_base<Y> const& x)
: tag_(x.tag_), selected_(x.selected_) : tag_(x.tag_), selected_(x.selected_)
{ {
detail::tracker.allocator_ref(); detail::tracker.allocator_ref();
@@ -127,31 +178,23 @@ namespace test
detail::tracker.allocator_ref(); detail::tracker.allocator_ref();
} }
~cxx11_allocator_base() ~cxx11_allocator_base() { detail::tracker.allocator_unref(); }
{
detail::tracker.allocator_unref();
}
pointer address(reference r) pointer address(reference r) { return pointer(&r); }
{
return pointer(&r);
}
const_pointer address(const_reference r) const_pointer address(const_reference r) { return const_pointer(&r); }
{
return const_pointer(&r);
}
pointer allocate(size_type n) { pointer allocate(size_type n)
{
pointer ptr(static_cast<T*>(::operator new(n * sizeof(T)))); pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_); detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
return ptr; return ptr;
} }
pointer allocate(size_type n, void const*) pointer allocate(size_type n, void const*)
{ {
pointer ptr(static_cast<T*>(::operator new(n * sizeof(T)))); pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_); detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
return ptr; return ptr;
} }
@@ -160,68 +203,66 @@ namespace test
// Only checking tags when propagating swap. // Only checking tags when propagating swap.
// Note that tags will be tested // Note that tags will be tested
// properly in the normal allocator. // properly in the normal allocator.
detail::tracker.track_deallocate((void*) p, n, sizeof(T), tag_, detail::tracker.track_deallocate(
!force_equal_allocator_value); (void*)p, n, sizeof(T), tag_, !force_equal_allocator_value);
::operator delete((void*) p); ::operator delete((void*)p);
} }
void construct(T* p, T const& t) { void construct(T* p, T const& t)
detail::tracker.track_construct((void*) p, sizeof(T), tag_); {
new(p) T(t); detail::tracker.track_construct((void*)p, sizeof(T), tag_);
new (p) T(t);
} }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<typename... Args> void construct(T* p, BOOST_FWD_REF(Args)... args) { template <typename... Args>
detail::tracker.track_construct((void*) p, sizeof(T), tag_); void construct(T* p, BOOST_FWD_REF(Args)... args)
new(p) T(boost::forward<Args>(args)...); {
detail::tracker.track_construct((void*)p, sizeof(T), tag_);
new (p) T(boost::forward<Args>(args)...);
} }
#endif #endif
void destroy(T* p) { void destroy(T* p)
detail::tracker.track_destroy((void*) p, sizeof(T), tag_); {
detail::tracker.track_destroy((void*)p, sizeof(T), tag_);
p->~T(); p->~T();
} }
size_type max_size() const { size_type max_size() const
{
return (std::numeric_limits<size_type>::max)(); return (std::numeric_limits<size_type>::max)();
} }
}; };
template <typename T, typename Flags = propagate_swap, template <typename T, typename Flags = propagate_swap, typename Enable = void>
typename Enable = void> struct cxx11_allocator;
struct cxx11_allocator;
template <typename T, typename Flags> template <typename T, typename Flags>
struct cxx11_allocator< struct cxx11_allocator<T, Flags,
T, Flags, typename boost::disable_if_c<Flags::is_select_on_copy>::type>
typename boost::disable_if_c<Flags::is_select_on_copy>::type : public cxx11_allocator_base<T>,
> : public cxx11_allocator_base<T>,
public swap_allocator_base<Flags>, public swap_allocator_base<Flags>,
public assign_allocator_base<Flags>, public assign_allocator_base<Flags>,
public move_allocator_base<Flags>, public move_allocator_base<Flags>,
Flags Flags
{ {
#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 402000) #if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 402000)
template <typename U> struct rebind { template <typename U> struct rebind
{
typedef cxx11_allocator<U, Flags> other; typedef cxx11_allocator<U, Flags> other;
}; };
#endif #endif
explicit cxx11_allocator(int t = 0) explicit cxx11_allocator(int t = 0) : cxx11_allocator_base<T>(t) {}
: cxx11_allocator_base<T>(t)
{
}
template <typename Y> cxx11_allocator( template <typename Y>
cxx11_allocator<Y, Flags> const& x) cxx11_allocator(cxx11_allocator<Y, Flags> const& x)
: cxx11_allocator_base<T>(x) : cxx11_allocator_base<T>(x)
{ {
} }
cxx11_allocator(cxx11_allocator const& x) cxx11_allocator(cxx11_allocator const& x) : cxx11_allocator_base<T>(x) {}
: cxx11_allocator_base<T>(x)
{
}
// When not propagating swap, allocators are always equal // When not propagating swap, allocators are always equal
// to avoid undefined behaviour. // to avoid undefined behaviour.
@@ -230,22 +271,18 @@ namespace test
return force_equal_allocator_value || (this->tag_ == x.tag_); return force_equal_allocator_value || (this->tag_ == x.tag_);
} }
bool operator!=(cxx11_allocator const& x) const bool operator!=(cxx11_allocator const& x) const { return !(*this == x); }
{ };
return !(*this == x);
}
};
template <typename T, typename Flags> template <typename T, typename Flags>
struct cxx11_allocator< struct cxx11_allocator<T, Flags,
T, Flags, typename boost::enable_if_c<Flags::is_select_on_copy>::type>
typename boost::enable_if_c<Flags::is_select_on_copy>::type : public cxx11_allocator_base<T>,
> : public cxx11_allocator_base<T>,
public swap_allocator_base<Flags>, public swap_allocator_base<Flags>,
public assign_allocator_base<Flags>, public assign_allocator_base<Flags>,
public move_allocator_base<Flags>, public move_allocator_base<Flags>,
Flags Flags
{ {
cxx11_allocator select_on_container_copy_construction() const cxx11_allocator select_on_container_copy_construction() const
{ {
cxx11_allocator tmp(*this); cxx11_allocator tmp(*this);
@@ -254,26 +291,21 @@ namespace test
} }
#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 402000) #if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 402000)
template <typename U> struct rebind { template <typename U> struct rebind
{
typedef cxx11_allocator<U, Flags> other; typedef cxx11_allocator<U, Flags> other;
}; };
#endif #endif
explicit cxx11_allocator(int t = 0) explicit cxx11_allocator(int t = 0) : cxx11_allocator_base<T>(t) {}
: cxx11_allocator_base<T>(t)
{
}
template <typename Y> cxx11_allocator( template <typename Y>
cxx11_allocator<Y, Flags> const& x) cxx11_allocator(cxx11_allocator<Y, Flags> const& x)
: cxx11_allocator_base<T>(x) : cxx11_allocator_base<T>(x)
{ {
} }
cxx11_allocator(cxx11_allocator const& x) cxx11_allocator(cxx11_allocator const& x) : cxx11_allocator_base<T>(x) {}
: cxx11_allocator_base<T>(x)
{
}
// When not propagating swap, allocators are always equal // When not propagating swap, allocators are always equal
// to avoid undefined behaviour. // to avoid undefined behaviour.
@@ -282,40 +314,31 @@ namespace test
return force_equal_allocator_value || (this->tag_ == x.tag_); return force_equal_allocator_value || (this->tag_ == x.tag_);
} }
bool operator!=(cxx11_allocator const& x) const bool operator!=(cxx11_allocator const& x) const { return !(*this == x); }
{ };
return !(*this == x);
}
};
template <typename T, typename Flags> template <typename T, typename Flags>
bool equivalent_impl( bool equivalent_impl(cxx11_allocator<T, Flags> const& x,
cxx11_allocator<T, Flags> const& x, cxx11_allocator<T, Flags> const& y, test::derived_type)
cxx11_allocator<T, Flags> const& y, {
test::derived_type)
{
return x.tag_ == y.tag_; return x.tag_ == y.tag_;
} }
// Function to check how many times an allocator has been selected, // Function to check how many times an allocator has been selected,
// return 0 for other allocators. // return 0 for other allocators.
struct convert_from_anything struct convert_from_anything
{ {
template <typename T> template <typename T> convert_from_anything(T const&) {}
convert_from_anything(T const&) {} };
};
inline int selected_count(convert_from_anything) inline int selected_count(convert_from_anything) { return 0; }
{
return 0;
}
template <typename T, typename Flags> template <typename T, typename Flags>
int selected_count(cxx11_allocator<T, Flags> const& x) int selected_count(cxx11_allocator<T, Flags> const& x)
{ {
return x.selected_; return x.selected_;
} }
} }
#endif #endif

View File

@@ -8,88 +8,101 @@
#include "../helpers/exception_test.hpp" #include "../helpers/exception_test.hpp"
#include "../helpers/count.hpp"
#include "../helpers/fwd.hpp"
#include "../helpers/memory.hpp"
#include <boost/limits.hpp>
#include <cstddef> #include <cstddef>
#include <iostream> #include <iostream>
#include <boost/limits.hpp>
#include <new> #include <new>
#include "../helpers/fwd.hpp"
#include "../helpers/count.hpp"
#include "../helpers/memory.hpp"
namespace test namespace test {
namespace exception {
class object;
class hash;
class equal_to;
template <class T> class allocator;
object generate(object const*, random_generator);
std::pair<object, object> generate(
std::pair<object, object> const*, random_generator);
struct true_type
{ {
namespace exception enum
{
value = true
};
};
struct false_type
{ {
class object; enum
class hash;
class equal_to;
template <class T> class allocator;
object generate(object const*, random_generator);
std::pair<object, object> generate(std::pair<object, object> const*, random_generator);
struct true_type
{ {
enum { value = true }; value = false
}; };
};
struct false_type class object : private counted_object
{ {
enum { value = false };
};
class object : private counted_object
{
public: public:
int tag1_, tag2_; int tag1_, tag2_;
explicit object() : tag1_(0), tag2_(0) explicit object() : tag1_(0), tag2_(0)
{ {
UNORDERED_SCOPE(object::object()) { UNORDERED_SCOPE(object::object())
{
UNORDERED_EPOINT("Mock object default constructor."); UNORDERED_EPOINT("Mock object default constructor.");
} }
} }
explicit object(int t1, int t2 = 0) : tag1_(t1), tag2_(t2) explicit object(int t1, int t2 = 0) : tag1_(t1), tag2_(t2)
{ {
UNORDERED_SCOPE(object::object(int)) { UNORDERED_SCOPE(object::object(int))
{
UNORDERED_EPOINT("Mock object constructor by value."); UNORDERED_EPOINT("Mock object constructor by value.");
} }
} }
object(object const& x) object(object const& x) : counted_object(x), tag1_(x.tag1_), tag2_(x.tag2_)
: counted_object(x), tag1_(x.tag1_), tag2_(x.tag2_) {
UNORDERED_SCOPE(object::object(object))
{ {
UNORDERED_SCOPE(object::object(object)) {
UNORDERED_EPOINT("Mock object copy constructor."); UNORDERED_EPOINT("Mock object copy constructor.");
} }
} }
~object() { ~object()
{
tag1_ = -1; tag1_ = -1;
tag2_ = -1; tag2_ = -1;
} }
object& operator=(object const& x) object& operator=(object const& x)
{ {
UNORDERED_SCOPE(object::operator=(object)) { UNORDERED_SCOPE(object::operator=(object))
{
tag1_ = x.tag1_; tag1_ = x.tag1_;
UNORDERED_EPOINT("Mock object assign operator 1."); UNORDERED_EPOINT("Mock object assign operator 1.");
tag2_ = x.tag2_; tag2_ = x.tag2_;
//UNORDERED_EPOINT("Mock object assign operator 2."); // UNORDERED_EPOINT("Mock object assign operator 2.");
} }
return *this; return *this;
} }
friend bool operator==(object const& x1, object const& x2) { friend bool operator==(object const& x1, object const& x2)
UNORDERED_SCOPE(operator==(object, object)) { {
UNORDERED_SCOPE(operator==(object, object))
{
UNORDERED_EPOINT("Mock object equality operator."); UNORDERED_EPOINT("Mock object equality operator.");
} }
return x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_; return x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_;
} }
friend bool operator!=(object const& x1, object const& x2) { friend bool operator!=(object const& x1, object const& x2)
UNORDERED_SCOPE(operator!=(object, object)) { {
UNORDERED_SCOPE(operator!=(object, object))
{
UNORDERED_EPOINT("Mock object inequality operator."); UNORDERED_EPOINT("Mock object inequality operator.");
} }
@@ -98,17 +111,21 @@ namespace exception
// None of the last few functions are used by the unordered associative // None of the last few functions are used by the unordered associative
// containers - so there aren't any exception points. // containers - so there aren't any exception points.
friend bool operator<(object const& x1, object const& x2) { friend bool operator<(object const& x1, object const& x2)
{
return x1.tag1_ < x2.tag1_ || return x1.tag1_ < x2.tag1_ ||
(x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_); (x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_);
} }
friend object generate(object const*, random_generator g) { friend object generate(object const*, random_generator g)
{
int* x = 0; int* x = 0;
return object(::test::generate(x, g), ::test::generate(x, g)); return object(::test::generate(x, g), ::test::generate(x, g));
} }
friend std::pair<object, object> generate(std::pair<object, object> const*, random_generator g) { friend std::pair<object, object> generate(
std::pair<object, object> const*, random_generator g)
{
int* x = 0; int* x = 0;
return std::make_pair( return std::make_pair(
object(::test::generate(x, g), ::test::generate(x, g)), object(::test::generate(x, g), ::test::generate(x, g)),
@@ -117,32 +134,35 @@ namespace exception
friend std::ostream& operator<<(std::ostream& out, object const& o) friend std::ostream& operator<<(std::ostream& out, object const& o)
{ {
return out<<"("<<o.tag1_<<","<<o.tag2_<<")"; return out << "(" << o.tag1_ << "," << o.tag2_ << ")";
} }
}; };
class hash class hash
{ {
int tag_; int tag_;
public: public:
hash(int t = 0) : tag_(t) hash(int t = 0) : tag_(t)
{ {
UNORDERED_SCOPE(hash::object()) { UNORDERED_SCOPE(hash::object())
{
UNORDERED_EPOINT("Mock hash default constructor."); UNORDERED_EPOINT("Mock hash default constructor.");
} }
} }
hash(hash const& x) hash(hash const& x) : tag_(x.tag_)
: tag_(x.tag_) {
UNORDERED_SCOPE(hash::hash(hash))
{ {
UNORDERED_SCOPE(hash::hash(hash)) {
UNORDERED_EPOINT("Mock hash copy constructor."); UNORDERED_EPOINT("Mock hash copy constructor.");
} }
} }
hash& operator=(hash const& x) hash& operator=(hash const& x)
{ {
UNORDERED_SCOPE(hash::operator=(hash)) { UNORDERED_SCOPE(hash::operator=(hash))
{
UNORDERED_EPOINT("Mock hash assign operator 1."); UNORDERED_EPOINT("Mock hash assign operator 1.");
tag_ = x.tag_; tag_ = x.tag_;
UNORDERED_EPOINT("Mock hash assign operator 2."); UNORDERED_EPOINT("Mock hash assign operator 2.");
@@ -150,25 +170,30 @@ namespace exception
return *this; return *this;
} }
std::size_t operator()(object const& x) const { std::size_t operator()(object const& x) const
UNORDERED_SCOPE(hash::operator()(object)) { {
UNORDERED_SCOPE(hash::operator()(object))
{
UNORDERED_EPOINT("Mock hash function."); UNORDERED_EPOINT("Mock hash function.");
} }
return hash_impl(x); return hash_impl(x);
} }
std::size_t operator()(std::pair<object, object> const& x) const { std::size_t operator()(std::pair<object, object> const& x) const
UNORDERED_SCOPE(hash::operator()(std::pair<object, object>)) { {
UNORDERED_SCOPE(hash::operator()(std::pair<object, object>))
{
UNORDERED_EPOINT("Mock hash pair function."); UNORDERED_EPOINT("Mock hash pair function.");
} }
return hash_impl(x.first) * 193ul + hash_impl(x.second) * 97ul + 29ul; return hash_impl(x.first) * 193ul + hash_impl(x.second) * 97ul + 29ul;
} }
std::size_t hash_impl(object const& x) const { std::size_t hash_impl(object const& x) const
{
int result; int result;
switch(tag_) { switch (tag_) {
case 1: case 1:
result = x.tag1_; result = x.tag1_;
break; break;
@@ -181,43 +206,50 @@ namespace exception
return static_cast<std::size_t>(result); return static_cast<std::size_t>(result);
} }
friend bool operator==(hash const& x1, hash const& x2) { friend bool operator==(hash const& x1, hash const& x2)
UNORDERED_SCOPE(operator==(hash, hash)) { {
UNORDERED_SCOPE(operator==(hash, hash))
{
UNORDERED_EPOINT("Mock hash equality function."); UNORDERED_EPOINT("Mock hash equality function.");
} }
return x1.tag_ == x2.tag_; return x1.tag_ == x2.tag_;
} }
friend bool operator!=(hash const& x1, hash const& x2) { friend bool operator!=(hash const& x1, hash const& x2)
UNORDERED_SCOPE(hash::operator!=(hash, hash)) { {
UNORDERED_SCOPE(hash::operator!=(hash, hash))
{
UNORDERED_EPOINT("Mock hash inequality function."); UNORDERED_EPOINT("Mock hash inequality function.");
} }
return x1.tag_ != x2.tag_; return x1.tag_ != x2.tag_;
} }
}; };
class equal_to class equal_to
{ {
int tag_; int tag_;
public: public:
equal_to(int t = 0) : tag_(t) equal_to(int t = 0) : tag_(t)
{ {
UNORDERED_SCOPE(equal_to::equal_to()) { UNORDERED_SCOPE(equal_to::equal_to())
{
UNORDERED_EPOINT("Mock equal_to default constructor."); UNORDERED_EPOINT("Mock equal_to default constructor.");
} }
} }
equal_to(equal_to const& x) equal_to(equal_to const& x) : tag_(x.tag_)
: tag_(x.tag_) {
UNORDERED_SCOPE(equal_to::equal_to(equal_to))
{ {
UNORDERED_SCOPE(equal_to::equal_to(equal_to)) {
UNORDERED_EPOINT("Mock equal_to copy constructor."); UNORDERED_EPOINT("Mock equal_to copy constructor.");
} }
} }
equal_to& operator=(equal_to const& x) equal_to& operator=(equal_to const& x)
{ {
UNORDERED_SCOPE(equal_to::operator=(equal_to)) { UNORDERED_SCOPE(equal_to::operator=(equal_to))
{
UNORDERED_EPOINT("Mock equal_to assign operator 1."); UNORDERED_EPOINT("Mock equal_to assign operator 1.");
tag_ = x.tag_; tag_ = x.tag_;
UNORDERED_EPOINT("Mock equal_to assign operator 2."); UNORDERED_EPOINT("Mock equal_to assign operator 2.");
@@ -225,24 +257,32 @@ namespace exception
return *this; return *this;
} }
bool operator()(object const& x1, object const& x2) const { bool operator()(object const& x1, object const& x2) const
UNORDERED_SCOPE(equal_to::operator()(object, object)) { {
UNORDERED_SCOPE(equal_to::operator()(object, object))
{
UNORDERED_EPOINT("Mock equal_to function."); UNORDERED_EPOINT("Mock equal_to function.");
} }
return equal_impl(x1, x2); return equal_impl(x1, x2);
} }
bool operator()(std::pair<object, object> const& x1, std::pair<object, object> const& x2) const { bool operator()(std::pair<object, object> const& x1,
UNORDERED_SCOPE(equal_to::operator()(std::pair<object, object>, std::pair<object, object>)) { std::pair<object, object> const& x2) const
{
UNORDERED_SCOPE(equal_to::operator()(
std::pair<object, object>, std::pair<object, object>))
{
UNORDERED_EPOINT("Mock equal_to function."); UNORDERED_EPOINT("Mock equal_to function.");
} }
return equal_impl(x1.first, x2.first) && equal_impl(x1.second, x2.second); return equal_impl(x1.first, x2.first) &&
equal_impl(x1.second, x2.second);
} }
bool equal_impl(object const& x1, object const& x2) const { bool equal_impl(object const& x1, object const& x2) const
switch(tag_) { {
switch (tag_) {
case 1: case 1:
return x1.tag1_ == x2.tag1_; return x1.tag1_ == x2.tag1_;
case 2: case 2:
@@ -252,24 +292,27 @@ namespace exception
} }
} }
friend bool operator==(equal_to const& x1, equal_to const& x2) { friend bool operator==(equal_to const& x1, equal_to const& x2)
UNORDERED_SCOPE(operator==(equal_to, equal_to)) { {
UNORDERED_SCOPE(operator==(equal_to, equal_to))
{
UNORDERED_EPOINT("Mock equal_to equality function."); UNORDERED_EPOINT("Mock equal_to equality function.");
} }
return x1.tag_ == x2.tag_; return x1.tag_ == x2.tag_;
} }
friend bool operator!=(equal_to const& x1, equal_to const& x2) { friend bool operator!=(equal_to const& x1, equal_to const& x2)
UNORDERED_SCOPE(operator!=(equal_to, equal_to)) { {
UNORDERED_SCOPE(operator!=(equal_to, equal_to))
{
UNORDERED_EPOINT("Mock equal_to inequality function."); UNORDERED_EPOINT("Mock equal_to inequality function.");
} }
return x1.tag_ != x2.tag_; return x1.tag_ != x2.tag_;
} }
}; };
template <class T> template <class T> class allocator
class allocator {
{
public: public:
int tag_; int tag_;
typedef std::size_t size_type; typedef std::size_t size_type;
@@ -280,11 +323,15 @@ namespace exception
typedef T const& const_reference; typedef T const& const_reference;
typedef T value_type; typedef T value_type;
template <class U> struct rebind { typedef allocator<U> other; }; template <class U> struct rebind
{
typedef allocator<U> other;
};
explicit allocator(int t = 0) : tag_(t) explicit allocator(int t = 0) : tag_(t)
{ {
UNORDERED_SCOPE(allocator::allocator()) { UNORDERED_SCOPE(allocator::allocator())
{
UNORDERED_EPOINT("Mock allocator default constructor."); UNORDERED_EPOINT("Mock allocator default constructor.");
} }
test::detail::tracker.allocator_ref(); test::detail::tracker.allocator_ref();
@@ -292,7 +339,8 @@ namespace exception
template <class Y> allocator(allocator<Y> const& x) : tag_(x.tag_) template <class Y> allocator(allocator<Y> const& x) : tag_(x.tag_)
{ {
UNORDERED_SCOPE(allocator::allocator()) { UNORDERED_SCOPE(allocator::allocator())
{
UNORDERED_EPOINT("Mock allocator template copy constructor."); UNORDERED_EPOINT("Mock allocator template copy constructor.");
} }
test::detail::tracker.allocator_ref(); test::detail::tracker.allocator_ref();
@@ -300,18 +348,19 @@ namespace exception
allocator(allocator const& x) : tag_(x.tag_) allocator(allocator const& x) : tag_(x.tag_)
{ {
UNORDERED_SCOPE(allocator::allocator()) { UNORDERED_SCOPE(allocator::allocator())
{
UNORDERED_EPOINT("Mock allocator copy constructor."); UNORDERED_EPOINT("Mock allocator copy constructor.");
} }
test::detail::tracker.allocator_ref(); test::detail::tracker.allocator_ref();
} }
~allocator() { ~allocator() { test::detail::tracker.allocator_unref(); }
test::detail::tracker.allocator_unref();
}
allocator& operator=(allocator const& x) { allocator& operator=(allocator const& x)
UNORDERED_SCOPE(allocator::allocator()) { {
UNORDERED_SCOPE(allocator::allocator())
{
UNORDERED_EPOINT("Mock allocator assignment operator."); UNORDERED_EPOINT("Mock allocator assignment operator.");
tag_ = x.tag_; tag_ = x.tag_;
} }
@@ -322,86 +371,101 @@ namespace exception
// destructor, which is very limiting. I need to check up on // destructor, which is very limiting. I need to check up on
// this. // this.
pointer address(reference r) { pointer address(reference r)
//UNORDERED_SCOPE(allocator::address(reference)) { {
// UNORDERED_SCOPE(allocator::address(reference)) {
// UNORDERED_EPOINT("Mock allocator address function."); // UNORDERED_EPOINT("Mock allocator address function.");
//} //}
return pointer(&r); return pointer(&r);
} }
const_pointer address(const_reference r) { const_pointer address(const_reference r)
//UNORDERED_SCOPE(allocator::address(const_reference)) { {
// UNORDERED_SCOPE(allocator::address(const_reference)) {
// UNORDERED_EPOINT("Mock allocator const address function."); // UNORDERED_EPOINT("Mock allocator const address function.");
//} //}
return const_pointer(&r); return const_pointer(&r);
} }
pointer allocate(size_type n) { pointer allocate(size_type n)
{
T* ptr = 0; T* ptr = 0;
UNORDERED_SCOPE(allocator::allocate(size_type)) { UNORDERED_SCOPE(allocator::allocate(size_type))
{
UNORDERED_EPOINT("Mock allocator allocate function."); UNORDERED_EPOINT("Mock allocator allocate function.");
using namespace std; using namespace std;
ptr = (T*) malloc(n * sizeof(T)); ptr = (T*)malloc(n * sizeof(T));
if(!ptr) throw std::bad_alloc(); if (!ptr)
throw std::bad_alloc();
} }
test::detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_); test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
return pointer(ptr); return pointer(ptr);
//return pointer(static_cast<T*>(::operator new(n * sizeof(T)))); // return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
} }
pointer allocate(size_type n, void const*) pointer allocate(size_type n, void const*)
{ {
T* ptr = 0; T* ptr = 0;
UNORDERED_SCOPE(allocator::allocate(size_type, const_pointer)) { UNORDERED_SCOPE(allocator::allocate(size_type, const_pointer))
{
UNORDERED_EPOINT("Mock allocator allocate function."); UNORDERED_EPOINT("Mock allocator allocate function.");
using namespace std; using namespace std;
ptr = (T*) malloc(n * sizeof(T)); ptr = (T*)malloc(n * sizeof(T));
if(!ptr) throw std::bad_alloc(); if (!ptr)
throw std::bad_alloc();
} }
test::detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_); test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
return pointer(ptr); return pointer(ptr);
//return pointer(static_cast<T*>(::operator new(n * sizeof(T)))); // return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
} }
void deallocate(pointer p, size_type n) void deallocate(pointer p, size_type n)
{ {
//::operator delete((void*) p); //::operator delete((void*) p);
if(p) { if (p) {
test::detail::tracker.track_deallocate((void*) p, n, sizeof(T), tag_); test::detail::tracker.track_deallocate(
(void*)p, n, sizeof(T), tag_);
using namespace std; using namespace std;
free(p); free(p);
} }
} }
void construct(pointer p, T const& t) { void construct(pointer p, T const& t)
UNORDERED_SCOPE(allocator::construct(T*, T)) { {
UNORDERED_SCOPE(allocator::construct(T*, T))
{
UNORDERED_EPOINT("Mock allocator construct function."); UNORDERED_EPOINT("Mock allocator construct function.");
new(p) T(t); new (p) T(t);
} }
test::detail::tracker.track_construct((void*) p, sizeof(T), tag_); test::detail::tracker.track_construct((void*)p, sizeof(T), tag_);
} }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args) { template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args)
UNORDERED_SCOPE(allocator::construct(pointer, BOOST_FWD_REF(Args)...)) { {
UNORDERED_SCOPE(allocator::construct(pointer, BOOST_FWD_REF(Args)...))
{
UNORDERED_EPOINT("Mock allocator construct function."); UNORDERED_EPOINT("Mock allocator construct function.");
new(p) T(boost::forward<Args>(args)...); new (p) T(boost::forward<Args>(args)...);
} }
test::detail::tracker.track_construct((void*) p, sizeof(T), tag_); test::detail::tracker.track_construct((void*)p, sizeof(T), tag_);
} }
#endif #endif
void destroy(T* p) { void destroy(T* p)
test::detail::tracker.track_destroy((void*) p, sizeof(T), tag_); {
test::detail::tracker.track_destroy((void*)p, sizeof(T), tag_);
p->~T(); p->~T();
} }
size_type max_size() const { size_type max_size() const
UNORDERED_SCOPE(allocator::construct(pointer, T)) { {
UNORDERED_SCOPE(allocator::construct(pointer, T))
{
UNORDERED_EPOINT("Mock allocator max_size function."); UNORDERED_EPOINT("Mock allocator max_size function.");
} }
return (std::numeric_limits<std::size_t>::max)(); return (std::numeric_limits<std::size_t>::max)();
@@ -410,38 +474,36 @@ namespace exception
typedef true_type propagate_on_container_copy_assignment; typedef true_type propagate_on_container_copy_assignment;
typedef true_type propagate_on_container_move_assignment; typedef true_type propagate_on_container_move_assignment;
typedef true_type propagate_on_container_swap; typedef true_type propagate_on_container_swap;
}; };
template <class T> template <class T> void swap(allocator<T>& x, allocator<T>& y)
void swap(allocator<T>& x, allocator<T>& y) {
{
std::swap(x.tag_, y.tag_); std::swap(x.tag_, y.tag_);
} }
// It's pretty much impossible to write a compliant swap when these // It's pretty much impossible to write a compliant swap when these
// two can throw. So they don't. // two can throw. So they don't.
template <class T> template <class T>
inline bool operator==(allocator<T> const& x, allocator<T> const& y) inline bool operator==(allocator<T> const& x, allocator<T> const& y)
{ {
//UNORDERED_SCOPE(operator==(allocator, allocator)) { // UNORDERED_SCOPE(operator==(allocator, allocator)) {
// UNORDERED_EPOINT("Mock allocator equality operator."); // UNORDERED_EPOINT("Mock allocator equality operator.");
//} //}
return x.tag_ == y.tag_; return x.tag_ == y.tag_;
} }
template <class T> template <class T>
inline bool operator!=(allocator<T> const& x, allocator<T> const& y) inline bool operator!=(allocator<T> const& x, allocator<T> const& y)
{ {
//UNORDERED_SCOPE(operator!=(allocator, allocator)) { // UNORDERED_SCOPE(operator!=(allocator, allocator)) {
// UNORDERED_EPOINT("Mock allocator inequality operator."); // UNORDERED_EPOINT("Mock allocator inequality operator.");
//} //}
return x.tag_ != y.tag_; return x.tag_ != y.tag_;
} }
template <class T> template <class T> class allocator2
class allocator2 {
{
public: public:
int tag_; int tag_;
typedef std::size_t size_type; typedef std::size_t size_type;
@@ -452,11 +514,15 @@ namespace exception
typedef T const& const_reference; typedef T const& const_reference;
typedef T value_type; typedef T value_type;
template <class U> struct rebind { typedef allocator2<U> other; }; template <class U> struct rebind
{
typedef allocator2<U> other;
};
explicit allocator2(int t = 0) : tag_(t) explicit allocator2(int t = 0) : tag_(t)
{ {
UNORDERED_SCOPE(allocator2::allocator2()) { UNORDERED_SCOPE(allocator2::allocator2())
{
UNORDERED_EPOINT("Mock allocator2 default constructor."); UNORDERED_EPOINT("Mock allocator2 default constructor.");
} }
test::detail::tracker.allocator_ref(); test::detail::tracker.allocator_ref();
@@ -464,7 +530,8 @@ namespace exception
allocator2(allocator<T> const& x) : tag_(x.tag_) allocator2(allocator<T> const& x) : tag_(x.tag_)
{ {
UNORDERED_SCOPE(allocator2::allocator2()) { UNORDERED_SCOPE(allocator2::allocator2())
{
UNORDERED_EPOINT("Mock allocator2 constructor from allocator."); UNORDERED_EPOINT("Mock allocator2 constructor from allocator.");
} }
test::detail::tracker.allocator_ref(); test::detail::tracker.allocator_ref();
@@ -472,7 +539,8 @@ namespace exception
template <class Y> allocator2(allocator2<Y> const& x) : tag_(x.tag_) template <class Y> allocator2(allocator2<Y> const& x) : tag_(x.tag_)
{ {
UNORDERED_SCOPE(allocator2::allocator2()) { UNORDERED_SCOPE(allocator2::allocator2())
{
UNORDERED_EPOINT("Mock allocator2 template copy constructor."); UNORDERED_EPOINT("Mock allocator2 template copy constructor.");
} }
test::detail::tracker.allocator_ref(); test::detail::tracker.allocator_ref();
@@ -480,18 +548,19 @@ namespace exception
allocator2(allocator2 const& x) : tag_(x.tag_) allocator2(allocator2 const& x) : tag_(x.tag_)
{ {
UNORDERED_SCOPE(allocator2::allocator2()) { UNORDERED_SCOPE(allocator2::allocator2())
{
UNORDERED_EPOINT("Mock allocator2 copy constructor."); UNORDERED_EPOINT("Mock allocator2 copy constructor.");
} }
test::detail::tracker.allocator_ref(); test::detail::tracker.allocator_ref();
} }
~allocator2() { ~allocator2() { test::detail::tracker.allocator_unref(); }
test::detail::tracker.allocator_unref();
}
allocator2& operator=(allocator2 const& x) { allocator2& operator=(allocator2 const& x)
UNORDERED_SCOPE(allocator2::allocator2()) { {
UNORDERED_SCOPE(allocator2::allocator2())
{
UNORDERED_EPOINT("Mock allocator2 assignment operator."); UNORDERED_EPOINT("Mock allocator2 assignment operator.");
tag_ = x.tag_; tag_ = x.tag_;
} }
@@ -502,86 +571,101 @@ namespace exception
// destructor, which is very limiting. I need to check up on // destructor, which is very limiting. I need to check up on
// this. // this.
pointer address(reference r) { pointer address(reference r)
//UNORDERED_SCOPE(allocator2::address(reference)) { {
// UNORDERED_SCOPE(allocator2::address(reference)) {
// UNORDERED_EPOINT("Mock allocator2 address function."); // UNORDERED_EPOINT("Mock allocator2 address function.");
//} //}
return pointer(&r); return pointer(&r);
} }
const_pointer address(const_reference r) { const_pointer address(const_reference r)
//UNORDERED_SCOPE(allocator2::address(const_reference)) { {
// UNORDERED_SCOPE(allocator2::address(const_reference)) {
// UNORDERED_EPOINT("Mock allocator2 const address function."); // UNORDERED_EPOINT("Mock allocator2 const address function.");
//} //}
return const_pointer(&r); return const_pointer(&r);
} }
pointer allocate(size_type n) { pointer allocate(size_type n)
{
T* ptr = 0; T* ptr = 0;
UNORDERED_SCOPE(allocator2::allocate(size_type)) { UNORDERED_SCOPE(allocator2::allocate(size_type))
{
UNORDERED_EPOINT("Mock allocator2 allocate function."); UNORDERED_EPOINT("Mock allocator2 allocate function.");
using namespace std; using namespace std;
ptr = (T*) malloc(n * sizeof(T)); ptr = (T*)malloc(n * sizeof(T));
if(!ptr) throw std::bad_alloc(); if (!ptr)
throw std::bad_alloc();
} }
test::detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_); test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
return pointer(ptr); return pointer(ptr);
//return pointer(static_cast<T*>(::operator new(n * sizeof(T)))); // return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
} }
pointer allocate(size_type n, void const*) pointer allocate(size_type n, void const*)
{ {
T* ptr = 0; T* ptr = 0;
UNORDERED_SCOPE(allocator2::allocate(size_type, const_pointer)) { UNORDERED_SCOPE(allocator2::allocate(size_type, const_pointer))
{
UNORDERED_EPOINT("Mock allocator2 allocate function."); UNORDERED_EPOINT("Mock allocator2 allocate function.");
using namespace std; using namespace std;
ptr = (T*) malloc(n * sizeof(T)); ptr = (T*)malloc(n * sizeof(T));
if(!ptr) throw std::bad_alloc(); if (!ptr)
throw std::bad_alloc();
} }
test::detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_); test::detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
return pointer(ptr); return pointer(ptr);
//return pointer(static_cast<T*>(::operator new(n * sizeof(T)))); // return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
} }
void deallocate(pointer p, size_type n) void deallocate(pointer p, size_type n)
{ {
//::operator delete((void*) p); //::operator delete((void*) p);
if(p) { if (p) {
test::detail::tracker.track_deallocate((void*) p, n, sizeof(T), tag_); test::detail::tracker.track_deallocate(
(void*)p, n, sizeof(T), tag_);
using namespace std; using namespace std;
free(p); free(p);
} }
} }
void construct(pointer p, T const& t) { void construct(pointer p, T const& t)
UNORDERED_SCOPE(allocator2::construct(T*, T)) { {
UNORDERED_SCOPE(allocator2::construct(T*, T))
{
UNORDERED_EPOINT("Mock allocator2 construct function."); UNORDERED_EPOINT("Mock allocator2 construct function.");
new(p) T(t); new (p) T(t);
} }
test::detail::tracker.track_construct((void*) p, sizeof(T), tag_); test::detail::tracker.track_construct((void*)p, sizeof(T), tag_);
} }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args) { template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args)
UNORDERED_SCOPE(allocator2::construct(pointer, BOOST_FWD_REF(Args)...)) { {
UNORDERED_SCOPE(allocator2::construct(pointer, BOOST_FWD_REF(Args)...))
{
UNORDERED_EPOINT("Mock allocator2 construct function."); UNORDERED_EPOINT("Mock allocator2 construct function.");
new(p) T(boost::forward<Args>(args)...); new (p) T(boost::forward<Args>(args)...);
} }
test::detail::tracker.track_construct((void*) p, sizeof(T), tag_); test::detail::tracker.track_construct((void*)p, sizeof(T), tag_);
} }
#endif #endif
void destroy(T* p) { void destroy(T* p)
test::detail::tracker.track_destroy((void*) p, sizeof(T), tag_); {
test::detail::tracker.track_destroy((void*)p, sizeof(T), tag_);
p->~T(); p->~T();
} }
size_type max_size() const { size_type max_size() const
UNORDERED_SCOPE(allocator2::construct(pointer, T)) { {
UNORDERED_SCOPE(allocator2::construct(pointer, T))
{
UNORDERED_EPOINT("Mock allocator2 max_size function."); UNORDERED_EPOINT("Mock allocator2 max_size function.");
} }
return (std::numeric_limits<std::size_t>::max)(); return (std::numeric_limits<std::size_t>::max)();
@@ -590,52 +674,52 @@ namespace exception
typedef false_type propagate_on_container_copy_assignment; typedef false_type propagate_on_container_copy_assignment;
typedef false_type propagate_on_container_move_assignment; typedef false_type propagate_on_container_move_assignment;
typedef false_type propagate_on_container_swap; typedef false_type propagate_on_container_swap;
}; };
template <class T> template <class T> void swap(allocator2<T>& x, allocator2<T>& y)
void swap(allocator2<T>& x, allocator2<T>& y) {
{
std::swap(x.tag_, y.tag_); std::swap(x.tag_, y.tag_);
} }
// It's pretty much impossible to write a compliant swap when these // It's pretty much impossible to write a compliant swap when these
// two can throw. So they don't. // two can throw. So they don't.
template <class T> template <class T>
inline bool operator==(allocator2<T> const& x, allocator2<T> const& y) inline bool operator==(allocator2<T> const& x, allocator2<T> const& y)
{ {
//UNORDERED_SCOPE(operator==(allocator2, allocator2)) { // UNORDERED_SCOPE(operator==(allocator2, allocator2)) {
// UNORDERED_EPOINT("Mock allocator2 equality operator."); // UNORDERED_EPOINT("Mock allocator2 equality operator.");
//} //}
return x.tag_ == y.tag_; return x.tag_ == y.tag_;
} }
template <class T> template <class T>
inline bool operator!=(allocator2<T> const& x, allocator2<T> const& y) inline bool operator!=(allocator2<T> const& x, allocator2<T> const& y)
{ {
//UNORDERED_SCOPE(operator!=(allocator2, allocator2)) { // UNORDERED_SCOPE(operator!=(allocator2, allocator2)) {
// UNORDERED_EPOINT("Mock allocator2 inequality operator."); // UNORDERED_EPOINT("Mock allocator2 inequality operator.");
//} //}
return x.tag_ != y.tag_; return x.tag_ != y.tag_;
} }
} }
} }
// Workaround for ADL deficient compilers // Workaround for ADL deficient compilers
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
namespace test namespace test {
test::exception::object generate(
test::exception::object const* x, random_generator g)
{ {
test::exception::object generate(test::exception::object const* x,
random_generator g) {
return test::exception::generate(x, g); return test::exception::generate(x, g);
} }
std::pair<test::exception::object, test::exception::object> generate(std::pair<test::exception::object, test::exception::object> const* x, std::pair<test::exception::object, test::exception::object> generate(
random_generator g) { std::pair<test::exception::object, test::exception::object> const* x,
random_generator g)
{
return test::exception::generate(x, g); return test::exception::generate(x, g);
} }
} }
#endif #endif
#endif #endif

View File

@@ -6,13 +6,12 @@
#if !defined(BOOST_UNORDERED_TEST_OBJECTS_FWD_HEADER) #if !defined(BOOST_UNORDERED_TEST_OBJECTS_FWD_HEADER)
#define BOOST_UNORDERED_TEST_OBJECTS_FWD_HEADER #define BOOST_UNORDERED_TEST_OBJECTS_FWD_HEADER
namespace test namespace test {
{ class object;
class object; class hash;
class hash; class less;
class less; class equal_to;
class equal_to; template <class T> class allocator;
template <class T> class allocator;
} }
#endif #endif

View File

@@ -10,13 +10,13 @@
#if !defined(BOOST_UNORDERED_OBJECTS_MINIMAL_HEADER) #if !defined(BOOST_UNORDERED_OBJECTS_MINIMAL_HEADER)
#define BOOST_UNORDERED_OBJECTS_MINIMAL_HEADER #define BOOST_UNORDERED_OBJECTS_MINIMAL_HEADER
#include <cstddef>
#include <boost/move/move.hpp> #include <boost/move/move.hpp>
#include <cstddef>
#include <utility> #include <utility>
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4100) // unreferenced formal parameter #pragma warning(disable : 4100) // unreferenced formal parameter
#endif #endif
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1500) #if !BOOST_WORKAROUND(BOOST_MSVC, == 1500)
@@ -25,34 +25,33 @@
#define BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED 0 #define BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED 0
#endif #endif
namespace test namespace test {
{ namespace minimal {
namespace minimal class destructible;
{ class copy_constructible;
class destructible; class copy_constructible_equality_comparable;
class copy_constructible; class default_assignable;
class copy_constructible_equality_comparable; class assignable;
class default_assignable;
class assignable;
struct ampersand_operator_used { struct ampersand_operator_used
{
ampersand_operator_used() { BOOST_TEST(false); } ampersand_operator_used() { BOOST_TEST(false); }
}; };
template <class T> class hash; template <class T> class hash;
template <class T> class equal_to; template <class T> class equal_to;
template <class T> class ptr; template <class T> class ptr;
template <class T> class const_ptr; template <class T> class const_ptr;
template <class T> class allocator; template <class T> class allocator;
template <class T> class cxx11_allocator; template <class T> class cxx11_allocator;
struct constructor_param struct constructor_param
{ {
operator int() const { return 0; } operator int() const { return 0; }
}; };
class destructible class destructible
{ {
public: public:
destructible(constructor_param const&) {} destructible(constructor_param const&) {}
~destructible() {} ~destructible() {}
@@ -60,10 +59,10 @@ namespace minimal
private: private:
destructible(destructible const&); destructible(destructible const&);
destructible& operator=(destructible const&); destructible& operator=(destructible const&);
}; };
class copy_constructible class copy_constructible
{ {
public: public:
copy_constructible(constructor_param const&) {} copy_constructible(constructor_param const&) {}
copy_constructible(copy_constructible const&) {} copy_constructible(copy_constructible const&) {}
@@ -72,10 +71,10 @@ namespace minimal
private: private:
copy_constructible& operator=(copy_constructible const&); copy_constructible& operator=(copy_constructible const&);
copy_constructible() {} copy_constructible() {}
}; };
class copy_constructible_equality_comparable class copy_constructible_equality_comparable
{ {
public: public:
copy_constructible_equality_comparable(constructor_param const&) {} copy_constructible_equality_comparable(constructor_param const&) {}
@@ -84,9 +83,7 @@ namespace minimal
{ {
} }
~copy_constructible_equality_comparable() ~copy_constructible_equality_comparable() {}
{
}
void dummy_member() const {} void dummy_member() const {}
private: private:
@@ -94,57 +91,50 @@ namespace minimal
copy_constructible_equality_comparable const&); copy_constructible_equality_comparable const&);
copy_constructible_equality_comparable() {} copy_constructible_equality_comparable() {}
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED #if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
ampersand_operator_used operator&() const { ampersand_operator_used operator&() const
return ampersand_operator_used(); } {
return ampersand_operator_used();
}
#endif #endif
}; };
bool operator==( bool operator==(copy_constructible_equality_comparable,
copy_constructible_equality_comparable,
copy_constructible_equality_comparable) copy_constructible_equality_comparable)
{ {
return true; return true;
} }
bool operator!=( bool operator!=(copy_constructible_equality_comparable,
copy_constructible_equality_comparable,
copy_constructible_equality_comparable) copy_constructible_equality_comparable)
{ {
return false; return false;
} }
class default_assignable class default_assignable
{ {
public: public:
default_assignable(constructor_param const&) {} default_assignable(constructor_param const&) {}
default_assignable() default_assignable() {}
{
}
default_assignable(default_assignable const&) default_assignable(default_assignable const&) {}
{
}
default_assignable& operator=(default_assignable const&) default_assignable& operator=(default_assignable const&) { return *this; }
{
return *this;
}
~default_assignable() ~default_assignable() {}
{
}
void dummy_member() const {} void dummy_member() const {}
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED #if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
ampersand_operator_used operator&() const { ampersand_operator_used operator&() const
return ampersand_operator_used(); }
#endif
};
class assignable
{ {
return ampersand_operator_used();
}
#endif
};
class assignable
{
public: public:
assignable(constructor_param const&) {} assignable(constructor_param const&) {}
assignable(assignable const&) {} assignable(assignable const&) {}
@@ -154,15 +144,19 @@ namespace minimal
private: private:
assignable() {} assignable() {}
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED #if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
ampersand_operator_used operator&() const { ampersand_operator_used operator&() const
return ampersand_operator_used(); }
#endif
};
struct movable_init {};
class movable1
{ {
return ampersand_operator_used();
}
#endif
};
struct movable_init
{
};
class movable1
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(movable1) BOOST_MOVABLE_BUT_NOT_COPYABLE(movable1)
public: public:
@@ -173,11 +167,11 @@ namespace minimal
movable1& operator=(BOOST_RV_REF(movable1)) { return *this; } movable1& operator=(BOOST_RV_REF(movable1)) { return *this; }
~movable1() {} ~movable1() {}
void dummy_member() const {} void dummy_member() const {}
}; };
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
class movable2 class movable2
{ {
public: public:
movable2(constructor_param const&) {} movable2(constructor_param const&) {}
explicit movable2(movable_init) {} explicit movable2(movable_init) {}
@@ -189,14 +183,13 @@ namespace minimal
movable2() {} movable2() {}
movable2(movable2 const&); movable2(movable2 const&);
movable2& operator=(movable2 const&); movable2& operator=(movable2 const&);
}; };
#else #else
typedef movable1 movable2; typedef movable1 movable2;
#endif #endif
template <class T> template <class T> class hash
class hash {
{
public: public:
hash(constructor_param const&) {} hash(constructor_param const&) {}
hash() {} hash() {}
@@ -206,14 +199,15 @@ namespace minimal
std::size_t operator()(T const&) const { return 0; } std::size_t operator()(T const&) const { return 0; }
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED #if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
ampersand_operator_used operator&() const { ampersand_operator_used operator&() const
return ampersand_operator_used(); }
#endif
};
template <class T>
class equal_to
{ {
return ampersand_operator_used();
}
#endif
};
template <class T> class equal_to
{
public: public:
equal_to(constructor_param const&) {} equal_to(constructor_param const&) {}
equal_to() {} equal_to() {}
@@ -223,19 +217,21 @@ namespace minimal
bool operator()(T const&, T const&) const { return true; } bool operator()(T const&, T const&) const { return true; }
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED #if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
ampersand_operator_used operator&() const { ampersand_operator_used operator&() const
return ampersand_operator_used(); }
#endif
};
template <class T> class ptr;
template <class T> class const_ptr;
struct void_ptr
{ {
return ampersand_operator_used();
}
#endif
};
template <class T> class ptr;
template <class T> class const_ptr;
struct void_ptr
{
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template <typename T> template <typename T> friend class ptr;
friend class ptr;
private: private:
#endif #endif
@@ -244,8 +240,7 @@ namespace minimal
public: public:
void_ptr() : ptr_(0) {} void_ptr() : ptr_(0) {}
template <typename T> template <typename T> explicit void_ptr(ptr<T> const& x) : ptr_(x.ptr_) {}
explicit void_ptr(ptr<T> const& x) : ptr_(x.ptr_) {}
// I'm not using the safe bool idiom because the containers should be // I'm not using the safe bool idiom because the containers should be
// able to cope with bool conversions. // able to cope with bool conversions.
@@ -253,13 +248,13 @@ namespace minimal
bool operator==(void_ptr const& x) const { return ptr_ == x.ptr_; } bool operator==(void_ptr const& x) const { return ptr_ == x.ptr_; }
bool operator!=(void_ptr const& x) const { return ptr_ != x.ptr_; } bool operator!=(void_ptr const& x) const { return ptr_ != x.ptr_; }
}; };
class void_const_ptr class void_const_ptr
{ {
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template <typename T> template <typename T> friend class const_ptr;
friend class const_ptr;
private: private:
#endif #endif
@@ -269,7 +264,9 @@ namespace minimal
void_const_ptr() : ptr_(0) {} void_const_ptr() : ptr_(0) {}
template <typename T> template <typename T>
explicit void_const_ptr(const_ptr<T> const& x) : ptr_(x.ptr_) {} explicit void_const_ptr(const_ptr<T> const& x) : ptr_(x.ptr_)
{
}
// I'm not using the safe bool idiom because the containers should be // I'm not using the safe bool idiom because the containers should be
// able to cope with bool conversions. // able to cope with bool conversions.
@@ -277,11 +274,10 @@ namespace minimal
bool operator==(void_const_ptr const& x) const { return ptr_ == x.ptr_; } bool operator==(void_const_ptr const& x) const { return ptr_ == x.ptr_; }
bool operator!=(void_const_ptr const& x) const { return ptr_ != x.ptr_; } bool operator!=(void_const_ptr const& x) const { return ptr_ != x.ptr_; }
}; };
template <class T> template <class T> class ptr
class ptr {
{
friend class allocator<T>; friend class allocator<T>;
friend class const_ptr<T>; friend class const_ptr<T>;
friend struct void_ptr; friend struct void_ptr;
@@ -291,15 +287,23 @@ namespace minimal
ptr(T* x) : ptr_(x) {} ptr(T* x) : ptr_(x) {}
public: public:
ptr() : ptr_(0) {} ptr() : ptr_(0) {}
explicit ptr(void_ptr const& x) : ptr_((T*) x.ptr_) {} explicit ptr(void_ptr const& x) : ptr_((T*)x.ptr_) {}
T& operator*() const { return *ptr_; } T& operator*() const { return *ptr_; }
T* operator->() const { return ptr_; } T* operator->() const { return ptr_; }
ptr& operator++() { ++ptr_; return *this; } ptr& operator++()
ptr operator++(int) { ptr tmp(*this); ++ptr_; return tmp; } {
++ptr_;
return *this;
}
ptr operator++(int)
{
ptr tmp(*this);
++ptr_;
return tmp;
}
ptr operator+(std::ptrdiff_t s) const { return ptr<T>(ptr_ + s); } ptr operator+(std::ptrdiff_t s) const { return ptr<T>(ptr_ + s); }
friend ptr operator+(std::ptrdiff_t s, ptr p) friend ptr operator+(std::ptrdiff_t s, ptr p) { return ptr<T>(s + p.ptr_); }
{ return ptr<T>(s + p.ptr_); }
T& operator[](std::ptrdiff_t s) const { return ptr_[s]; } T& operator[](std::ptrdiff_t s) const { return ptr_[s]; }
bool operator!() const { return !ptr_; } bool operator!() const { return !ptr_; }
@@ -314,14 +318,15 @@ namespace minimal
bool operator<=(ptr const& x) const { return ptr_ <= x.ptr_; } bool operator<=(ptr const& x) const { return ptr_ <= x.ptr_; }
bool operator>=(ptr const& x) const { return ptr_ >= x.ptr_; } bool operator>=(ptr const& x) const { return ptr_ >= x.ptr_; }
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED #if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
ampersand_operator_used operator&() const { ampersand_operator_used operator&() const
return ampersand_operator_used(); }
#endif
};
template <class T>
class const_ptr
{ {
return ampersand_operator_used();
}
#endif
};
template <class T> class const_ptr
{
friend class allocator<T>; friend class allocator<T>;
friend struct const_void_ptr; friend struct const_void_ptr;
@@ -331,16 +336,26 @@ namespace minimal
public: public:
const_ptr() : ptr_(0) {} const_ptr() : ptr_(0) {}
const_ptr(ptr<T> const& x) : ptr_(x.ptr_) {} const_ptr(ptr<T> const& x) : ptr_(x.ptr_) {}
explicit const_ptr(void_const_ptr const& x) : ptr_((T const*) x.ptr_) {} explicit const_ptr(void_const_ptr const& x) : ptr_((T const*)x.ptr_) {}
T const& operator*() const { return *ptr_; } T const& operator*() const { return *ptr_; }
T const* operator->() const { return ptr_; } T const* operator->() const { return ptr_; }
const_ptr& operator++() { ++ptr_; return *this; } const_ptr& operator++()
const_ptr operator++(int) { const_ptr tmp(*this); ++ptr_; return tmp; } {
const_ptr operator+(std::ptrdiff_t s) const ++ptr_;
{ return const_ptr(ptr_ + s); } return *this;
}
const_ptr operator++(int)
{
const_ptr tmp(*this);
++ptr_;
return tmp;
}
const_ptr operator+(std::ptrdiff_t s) const { return const_ptr(ptr_ + s); }
friend const_ptr operator+(std::ptrdiff_t s, const_ptr p) friend const_ptr operator+(std::ptrdiff_t s, const_ptr p)
{ return ptr<T>(s + p.ptr_); } {
return ptr<T>(s + p.ptr_);
}
T const& operator[](int s) const { return ptr_[s]; } T const& operator[](int s) const { return ptr_[s]; }
bool operator!() const { return !ptr_; } bool operator!() const { return !ptr_; }
operator bool() const { return !!ptr_; } operator bool() const { return !!ptr_; }
@@ -352,14 +367,15 @@ namespace minimal
bool operator<=(const_ptr const& x) const { return ptr_ <= x.ptr_; } bool operator<=(const_ptr const& x) const { return ptr_ <= x.ptr_; }
bool operator>=(const_ptr const& x) const { return ptr_ >= x.ptr_; } bool operator>=(const_ptr const& x) const { return ptr_ >= x.ptr_; }
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED #if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
ampersand_operator_used operator&() const { ampersand_operator_used operator&() const
return ampersand_operator_used(); }
#endif
};
template <class T>
class allocator
{ {
return ampersand_operator_used();
}
#endif
};
template <class T> class allocator
{
public: public:
typedef std::size_t size_type; typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
@@ -371,7 +387,10 @@ namespace minimal
typedef T const& const_reference; typedef T const& const_reference;
typedef T value_type; typedef T value_type;
template <class U> struct rebind { typedef allocator<U> other; }; template <class U> struct rebind
{
typedef allocator<U> other;
};
allocator() {} allocator() {}
template <class Y> allocator(allocator<Y> const&) {} template <class Y> allocator(allocator<Y> const&) {}
@@ -381,26 +400,24 @@ namespace minimal
pointer address(reference r) { return pointer(&r); } pointer address(reference r) { return pointer(&r); }
const_pointer address(const_reference r) { return const_pointer(&r); } const_pointer address(const_reference r) { return const_pointer(&r); }
pointer allocate(size_type n) { pointer allocate(size_type n)
return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
}
template <class Y>
pointer allocate(size_type n, const_ptr<Y>)
{ {
return pointer(static_cast<T*>(::operator new(n * sizeof(T)))); return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
} }
void deallocate(pointer p, size_type) template <class Y> pointer allocate(size_type n, const_ptr<Y>)
{ {
::operator delete((void*) p.ptr_); return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
} }
void construct(T* p, T const& t) { new((void*)p) T(t); } void deallocate(pointer p, size_type) { ::operator delete((void*)p.ptr_); }
void construct(T* p, T const& t) { new ((void*)p) T(t); }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args) { template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args)
new((void*)p) T(boost::forward<Args>(args)...); {
new ((void*)p) T(boost::forward<Args>(args)...);
} }
#endif #endif
@@ -410,44 +427,44 @@ namespace minimal
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) || \ #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) || \
BOOST_WORKAROUND(BOOST_MSVC, <= 1300) BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
public: allocator& operator=(allocator const&) { return *this;} public:
allocator& operator=(allocator const&) { return *this; }
#else #else
private: allocator& operator=(allocator const&); private:
allocator& operator=(allocator const&);
#endif #endif
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED #if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
ampersand_operator_used operator&() const { ampersand_operator_used operator&() const
return ampersand_operator_used(); } {
return ampersand_operator_used();
}
#endif #endif
}; };
template <class T> template <class T>
inline bool operator==(allocator<T> const&, allocator<T> const&) inline bool operator==(allocator<T> const&, allocator<T> const&)
{ {
return true; return true;
} }
template <class T> template <class T>
inline bool operator!=(allocator<T> const&, allocator<T> const&) inline bool operator!=(allocator<T> const&, allocator<T> const&)
{ {
return false; return false;
} }
template <class T> template <class T> void swap(allocator<T>&, allocator<T>&) {}
void swap(allocator<T>&, allocator<T>&)
{
}
// C++11 allocator // C++11 allocator
// //
// Not a fully minimal C++11 allocator, just what I support. Hopefully will // Not a fully minimal C++11 allocator, just what I support. Hopefully will
// cut down further in the future. // cut down further in the future.
template <class T> template <class T> class cxx11_allocator
class cxx11_allocator {
{
public: public:
typedef T value_type; typedef T value_type;
//template <class U> struct rebind { typedef cxx11_allocator<U> other; }; // template <class U> struct rebind { typedef cxx11_allocator<U> other; };
cxx11_allocator() {} cxx11_allocator() {}
template <class Y> cxx11_allocator(cxx11_allocator<Y> const&) {} template <class Y> cxx11_allocator(cxx11_allocator<Y> const&) {}
@@ -457,48 +474,45 @@ namespace minimal
T* address(T& r) { return &r; } T* address(T& r) { return &r; }
T const* address(T const& r) { return &r; } T const* address(T const& r) { return &r; }
T* allocate(std::size_t n) { T* allocate(std::size_t n)
{
return static_cast<T*>(::operator new(n * sizeof(T))); return static_cast<T*>(::operator new(n * sizeof(T)));
} }
template <class Y> template <class Y> T* allocate(std::size_t n, const_ptr<Y>)
T* allocate(std::size_t n, const_ptr<Y>) { {
return static_cast<T*>(::operator new(n * sizeof(T))); return static_cast<T*>(::operator new(n * sizeof(T)));
} }
void deallocate(T* p, std::size_t) { void deallocate(T* p, std::size_t) { ::operator delete((void*)p); }
::operator delete((void*) p);
}
void construct(T* p, T const& t) { new((void*)p) T(t); } void construct(T* p, T const& t) { new ((void*)p) T(t); }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args) { template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args)
new((void*)p) T(boost::forward<Args>(args)...); {
new ((void*)p) T(boost::forward<Args>(args)...);
} }
#endif #endif
void destroy(T* p) { p->~T(); } void destroy(T* p) { p->~T(); }
std::size_t max_size() const { return 1000u; } std::size_t max_size() const { return 1000u; }
}; };
template <class T> template <class T>
inline bool operator==(cxx11_allocator<T> const&, cxx11_allocator<T> const&) inline bool operator==(cxx11_allocator<T> const&, cxx11_allocator<T> const&)
{ {
return true; return true;
} }
template <class T> template <class T>
inline bool operator!=(cxx11_allocator<T> const&, cxx11_allocator<T> const&) inline bool operator!=(cxx11_allocator<T> const&, cxx11_allocator<T> const&)
{ {
return false; return false;
} }
template <class T> template <class T> void swap(cxx11_allocator<T>&, cxx11_allocator<T>&) {}
void swap(cxx11_allocator<T>&, cxx11_allocator<T>&)
{
}
} }
} }
@@ -508,18 +522,17 @@ namespace boost {
namespace test { namespace test {
namespace minimal { namespace minimal {
#endif #endif
std::size_t hash_value( std::size_t hash_value(test::minimal::copy_constructible_equality_comparable)
test::minimal::copy_constructible_equality_comparable) {
{
return 1; return 1;
} }
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) #if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
}} }
}
#else #else
} }
#endif #endif
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
#pragma warning(pop) #pragma warning(pop)
#endif #endif

View File

@@ -6,71 +6,77 @@
#if !defined(BOOST_UNORDERED_TEST_OBJECTS_HEADER) #if !defined(BOOST_UNORDERED_TEST_OBJECTS_HEADER)
#define BOOST_UNORDERED_TEST_OBJECTS_HEADER #define BOOST_UNORDERED_TEST_OBJECTS_HEADER
#include "../helpers/count.hpp"
#include "../helpers/fwd.hpp"
#include "../helpers/memory.hpp"
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/limits.hpp> #include <boost/limits.hpp>
#include <cstddef> #include <cstddef>
#include "../helpers/fwd.hpp"
#include "../helpers/count.hpp"
#include "../helpers/memory.hpp"
namespace test namespace test {
// Note that the default hash function will work for any equal_to (but not
// very well).
class object;
class movable;
class implicitly_convertible;
class hash;
class less;
class equal_to;
template <class T> class allocator1;
template <class T> class allocator2;
object generate(object const*, random_generator);
movable generate(movable const*, random_generator);
implicitly_convertible generate(
implicitly_convertible const*, random_generator);
inline void ignore_variable(void const*) {}
class object : private counted_object
{ {
// Note that the default hash function will work for any equal_to (but not
// very well).
class object;
class movable;
class implicitly_convertible;
class hash;
class less;
class equal_to;
template <class T> class allocator1;
template <class T> class allocator2;
object generate(object const*, random_generator);
movable generate(movable const*, random_generator);
implicitly_convertible generate(implicitly_convertible const*, random_generator);
inline void ignore_variable(void const*) {}
class object : private counted_object
{
friend class hash; friend class hash;
friend class equal_to; friend class equal_to;
friend class less; friend class less;
int tag1_, tag2_; int tag1_, tag2_;
public: public:
explicit object(int t1 = 0, int t2 = 0) : tag1_(t1), tag2_(t2) {} explicit object(int t1 = 0, int t2 = 0) : tag1_(t1), tag2_(t2) {}
~object() { ~object()
{
tag1_ = -1; tag1_ = -1;
tag2_ = -1; tag2_ = -1;
} }
friend bool operator==(object const& x1, object const& x2) { friend bool operator==(object const& x1, object const& x2)
{
return x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_; return x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_;
} }
friend bool operator!=(object const& x1, object const& x2) { friend bool operator!=(object const& x1, object const& x2)
{
return x1.tag1_ != x2.tag1_ || x1.tag2_ != x2.tag2_; return x1.tag1_ != x2.tag1_ || x1.tag2_ != x2.tag2_;
} }
friend bool operator<(object const& x1, object const& x2) { friend bool operator<(object const& x1, object const& x2)
{
return x1.tag1_ < x2.tag1_ || return x1.tag1_ < x2.tag1_ ||
(x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_); (x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_);
} }
friend object generate(object const*, random_generator g) { friend object generate(object const*, random_generator g)
{
int* x = 0; int* x = 0;
return object(generate(x, g), generate(x, g)); return object(generate(x, g), generate(x, g));
} }
friend std::ostream& operator<<(std::ostream& out, object const& o) friend std::ostream& operator<<(std::ostream& out, object const& o)
{ {
return out<<"("<<o.tag1_<<","<<o.tag2_<<")"; return out << "(" << o.tag1_ << "," << o.tag2_ << ")";
} }
}; };
class movable : private counted_object class movable : private counted_object
{ {
friend class hash; friend class hash;
friend class equal_to; friend class equal_to;
friend class less; friend class less;
@@ -80,14 +86,14 @@ namespace test
public: public:
explicit movable(int t1 = 0, int t2 = 0) : tag1_(t1), tag2_(t2) {} explicit movable(int t1 = 0, int t2 = 0) : tag1_(t1), tag2_(t2) {}
movable(movable const& x) : movable(movable const& x)
counted_object(x), tag1_(x.tag1_), tag2_(x.tag2_) : counted_object(x), tag1_(x.tag1_), tag2_(x.tag2_)
{ {
BOOST_TEST(x.tag1_ != -1); BOOST_TEST(x.tag1_ != -1);
} }
movable(BOOST_RV_REF(movable) x) : movable(BOOST_RV_REF(movable) x)
counted_object(x), tag1_(x.tag1_), tag2_(x.tag2_) : counted_object(x), tag1_(x.tag1_), tag2_(x.tag2_)
{ {
BOOST_TEST(x.tag1_ != -1); BOOST_TEST(x.tag1_ != -1);
x.tag1_ = -1; x.tag1_ = -1;
@@ -102,7 +108,7 @@ namespace test
return *this; return *this;
} }
movable& operator=(BOOST_RV_REF(movable) x) //Move assignment movable& operator=(BOOST_RV_REF(movable) x) // Move assignment
{ {
BOOST_TEST(x.tag1_ != -1); BOOST_TEST(x.tag1_ != -1);
tag1_ = x.tag1_; tag1_ = x.tag1_;
@@ -112,78 +118,83 @@ namespace test
return *this; return *this;
} }
~movable() { ~movable()
{
tag1_ = -1; tag1_ = -1;
tag2_ = -1; tag2_ = -1;
} }
friend bool operator==(movable const& x1, movable const& x2) { friend bool operator==(movable const& x1, movable const& x2)
{
BOOST_TEST(x1.tag1_ != -1 && x2.tag1_ != -1); BOOST_TEST(x1.tag1_ != -1 && x2.tag1_ != -1);
return x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_; return x1.tag1_ == x2.tag1_ && x1.tag2_ == x2.tag2_;
} }
friend bool operator!=(movable const& x1, movable const& x2) { friend bool operator!=(movable const& x1, movable const& x2)
{
BOOST_TEST(x1.tag1_ != -1 && x2.tag1_ != -1); BOOST_TEST(x1.tag1_ != -1 && x2.tag1_ != -1);
return x1.tag1_ != x2.tag1_ || x1.tag2_ != x2.tag2_; return x1.tag1_ != x2.tag1_ || x1.tag2_ != x2.tag2_;
} }
friend bool operator<(movable const& x1, movable const& x2) { friend bool operator<(movable const& x1, movable const& x2)
{
BOOST_TEST(x1.tag1_ != -1 && x2.tag1_ != -1); BOOST_TEST(x1.tag1_ != -1 && x2.tag1_ != -1);
return x1.tag1_ < x2.tag1_ || return x1.tag1_ < x2.tag1_ ||
(x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_); (x1.tag1_ == x2.tag1_ && x1.tag2_ < x2.tag2_);
} }
friend movable generate(movable const*, random_generator g) { friend movable generate(movable const*, random_generator g)
{
int* x = 0; int* x = 0;
return movable(generate(x, g), generate(x, g)); return movable(generate(x, g), generate(x, g));
} }
friend std::ostream& operator<<(std::ostream& out, movable const& o) friend std::ostream& operator<<(std::ostream& out, movable const& o)
{ {
return out<<"("<<o.tag1_<<","<<o.tag2_<<")"; return out << "(" << o.tag1_ << "," << o.tag2_ << ")";
} }
}; };
class implicitly_convertible : private counted_object class implicitly_convertible : private counted_object
{ {
int tag1_, tag2_; int tag1_, tag2_;
public:
public:
explicit implicitly_convertible(int t1 = 0, int t2 = 0) explicit implicitly_convertible(int t1 = 0, int t2 = 0)
: tag1_(t1), tag2_(t2) : tag1_(t1), tag2_(t2)
{}
operator object() const
{ {
return object(tag1_, tag2_);
} }
operator movable() const operator object() const { return object(tag1_, tag2_); }
{
return movable(tag1_, tag2_);
}
friend implicitly_convertible generate(implicitly_convertible const*, random_generator g) { operator movable() const { return movable(tag1_, tag2_); }
friend implicitly_convertible generate(
implicitly_convertible const*, random_generator g)
{
int* x = 0; int* x = 0;
return implicitly_convertible(generate(x, g), generate(x, g)); return implicitly_convertible(generate(x, g), generate(x, g));
} }
friend std::ostream& operator<<(std::ostream& out, implicitly_convertible const& o) friend std::ostream& operator<<(
std::ostream& out, implicitly_convertible const& o)
{ {
return out<<"("<<o.tag1_<<","<<o.tag2_<<")"; return out << "(" << o.tag1_ << "," << o.tag2_ << ")";
} }
}; };
// Note: This is a deliberately bad hash function. // Note: This is a deliberately bad hash function.
class hash class hash
{ {
int type_; int type_;
public: public:
explicit hash(int t = 0) : type_(t) {} explicit hash(int t = 0) : type_(t) {}
std::size_t operator()(object const& x) const { std::size_t operator()(object const& x) const
{
int result; int result;
switch(type_) { switch (type_) {
case 1: case 1:
result = x.tag1_; result = x.tag1_;
break; break;
@@ -196,9 +207,10 @@ namespace test
return static_cast<std::size_t>(result); return static_cast<std::size_t>(result);
} }
std::size_t operator()(movable const& x) const { std::size_t operator()(movable const& x) const
{
int result; int result;
switch(type_) { switch (type_) {
case 1: case 1:
result = x.tag1_; result = x.tag1_;
break; break;
@@ -211,9 +223,10 @@ namespace test
return static_cast<std::size_t>(result); return static_cast<std::size_t>(result);
} }
std::size_t operator()(int x) const { std::size_t operator()(int x) const
{
int result; int result;
switch(type_) { switch (type_) {
case 1: case 1:
result = x; result = x;
break; break;
@@ -226,31 +239,31 @@ namespace test
return static_cast<std::size_t>(result); return static_cast<std::size_t>(result);
} }
friend bool operator==(hash const& x1, hash const& x2) { friend bool operator==(hash const& x1, hash const& x2)
{
return x1.type_ == x2.type_; return x1.type_ == x2.type_;
} }
friend bool operator!=(hash const& x1, hash const& x2) { friend bool operator!=(hash const& x1, hash const& x2)
{
return x1.type_ != x2.type_; return x1.type_ != x2.type_;
} }
}; };
std::size_t hash_value(test::object const& x) { std::size_t hash_value(test::object const& x) { return hash()(x); }
return hash()(x);
}
std::size_t hash_value(test::movable const& x) { std::size_t hash_value(test::movable const& x) { return hash()(x); }
return hash()(x);
}
class less class less
{ {
int type_; int type_;
public: public:
explicit less(int t = 0) : type_(t) {} explicit less(int t = 0) : type_(t) {}
bool operator()(object const& x1, object const& x2) const { bool operator()(object const& x1, object const& x2) const
switch(type_) { {
switch (type_) {
case 1: case 1:
return x1.tag1_ < x2.tag1_; return x1.tag1_ < x2.tag1_;
case 2: case 2:
@@ -260,8 +273,9 @@ namespace test
} }
} }
bool operator()(movable const& x1, movable const& x2) const { bool operator()(movable const& x1, movable const& x2) const
switch(type_) { {
switch (type_) {
case 1: case 1:
return x1.tag1_ < x2.tag1_; return x1.tag1_ < x2.tag1_;
case 2: case 2:
@@ -271,23 +285,24 @@ namespace test
} }
} }
std::size_t operator()(int x1, int x2) const { std::size_t operator()(int x1, int x2) const { return x1 < x2; }
return x1 < x2;
}
friend bool operator==(less const& x1, less const& x2) { friend bool operator==(less const& x1, less const& x2)
{
return x1.type_ == x2.type_; return x1.type_ == x2.type_;
} }
}; };
class equal_to class equal_to
{ {
int type_; int type_;
public: public:
explicit equal_to(int t = 0) : type_(t) {} explicit equal_to(int t = 0) : type_(t) {}
bool operator()(object const& x1, object const& x2) const { bool operator()(object const& x1, object const& x2) const
switch(type_) { {
switch (type_) {
case 1: case 1:
return x1.tag1_ == x2.tag1_; return x1.tag1_ == x2.tag1_;
case 2: case 2:
@@ -297,8 +312,9 @@ namespace test
} }
} }
bool operator()(movable const& x1, movable const& x2) const { bool operator()(movable const& x1, movable const& x2) const
switch(type_) { {
switch (type_) {
case 1: case 1:
return x1.tag1_ == x2.tag1_; return x1.tag1_ == x2.tag1_;
case 2: case 2:
@@ -308,117 +324,110 @@ namespace test
} }
} }
std::size_t operator()(int x1, int x2) const { std::size_t operator()(int x1, int x2) const { return x1 == x2; }
return x1 == x2;
}
friend bool operator==(equal_to const& x1, equal_to const& x2) { friend bool operator==(equal_to const& x1, equal_to const& x2)
{
return x1.type_ == x2.type_; return x1.type_ == x2.type_;
} }
friend bool operator!=(equal_to const& x1, equal_to const& x2) { friend bool operator!=(equal_to const& x1, equal_to const& x2)
{
return x1.type_ != x2.type_; return x1.type_ != x2.type_;
} }
friend less create_compare(equal_to x) { friend less create_compare(equal_to x) { return less(x.type_); }
return less(x.type_); };
}
};
// allocator1 only has the old fashioned 'construct' method and has // allocator1 only has the old fashioned 'construct' method and has
// a few less typedefs. allocator2 uses a custom pointer class. // a few less typedefs. allocator2 uses a custom pointer class.
template <class T> template <class T> class allocator1
class allocator1 {
{
public: public:
int tag_; int tag_;
typedef T value_type; typedef T value_type;
template <class U> struct rebind { typedef allocator1<U> other; }; template <class U> struct rebind
{
typedef allocator1<U> other;
};
explicit allocator1(int t = 0) : tag_(t) explicit allocator1(int t = 0) : tag_(t)
{ {
detail::tracker.allocator_ref(); detail::tracker.allocator_ref();
} }
template <class Y> allocator1(allocator1<Y> const& x) template <class Y> allocator1(allocator1<Y> const& x) : tag_(x.tag_)
: tag_(x.tag_)
{ {
detail::tracker.allocator_ref(); detail::tracker.allocator_ref();
} }
allocator1(allocator1 const& x) allocator1(allocator1 const& x) : tag_(x.tag_)
: tag_(x.tag_)
{ {
detail::tracker.allocator_ref(); detail::tracker.allocator_ref();
} }
~allocator1() ~allocator1() { detail::tracker.allocator_unref(); }
{
detail::tracker.allocator_unref();
}
T* allocate(std::size_t n) { T* allocate(std::size_t n)
{
T* ptr(static_cast<T*>(::operator new(n * sizeof(T)))); T* ptr(static_cast<T*>(::operator new(n * sizeof(T))));
detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_); detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
return ptr; return ptr;
} }
T* allocate(std::size_t n, void const*) T* allocate(std::size_t n, void const*)
{ {
T* ptr(static_cast<T*>(::operator new(n * sizeof(T)))); T* ptr(static_cast<T*>(::operator new(n * sizeof(T))));
detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_); detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
return ptr; return ptr;
} }
void deallocate(T* p, std::size_t n) void deallocate(T* p, std::size_t n)
{ {
detail::tracker.track_deallocate((void*) p, n, sizeof(T), tag_); detail::tracker.track_deallocate((void*)p, n, sizeof(T), tag_);
::operator delete((void*) p); ::operator delete((void*)p);
} }
void construct(T* p, T const& t) { void construct(T* p, T const& t)
{
// Don't count constructions here as it isn't always called. // Don't count constructions here as it isn't always called.
//detail::tracker.track_construct((void*) p, sizeof(T), tag_); // detail::tracker.track_construct((void*) p, sizeof(T), tag_);
new(p) T(t); new (p) T(t);
} }
void destroy(T* p) { void destroy(T* p)
//detail::tracker.track_destroy((void*) p, sizeof(T), tag_); {
// detail::tracker.track_destroy((void*) p, sizeof(T), tag_);
p->~T(); p->~T();
// Work around MSVC buggy unused parameter warning. // Work around MSVC buggy unused parameter warning.
ignore_variable(&p); ignore_variable(&p);
} }
bool operator==(allocator1 const& x) const bool operator==(allocator1 const& x) const { return tag_ == x.tag_; }
{
return tag_ == x.tag_;
}
bool operator!=(allocator1 const& x) const bool operator!=(allocator1 const& x) const { return tag_ != x.tag_; }
{
return tag_ != x.tag_;
}
enum { enum
{
is_select_on_copy = false, is_select_on_copy = false,
is_propagate_on_swap = false, is_propagate_on_swap = false,
is_propagate_on_assign = false, is_propagate_on_assign = false,
is_propagate_on_move = false is_propagate_on_move = false
}; };
}; };
template <class T> class ptr; template <class T> class ptr;
template <class T> class const_ptr; template <class T> class const_ptr;
struct void_ptr struct void_ptr
{ {
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template <typename T> template <typename T> friend class ptr;
friend class ptr;
private: private:
#endif #endif
@@ -427,8 +436,7 @@ namespace test
public: public:
void_ptr() : ptr_(0) {} void_ptr() : ptr_(0) {}
template <typename T> template <typename T> explicit void_ptr(ptr<T> const& x) : ptr_(x.ptr_) {}
explicit void_ptr(ptr<T> const& x) : ptr_(x.ptr_) {}
// I'm not using the safe bool idiom because the containers should be // I'm not using the safe bool idiom because the containers should be
// able to cope with bool conversions. // able to cope with bool conversions.
@@ -436,13 +444,13 @@ namespace test
bool operator==(void_ptr const& x) const { return ptr_ == x.ptr_; } bool operator==(void_ptr const& x) const { return ptr_ == x.ptr_; }
bool operator!=(void_ptr const& x) const { return ptr_ != x.ptr_; } bool operator!=(void_ptr const& x) const { return ptr_ != x.ptr_; }
}; };
class void_const_ptr class void_const_ptr
{ {
#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
template <typename T> template <typename T> friend class const_ptr;
friend class const_ptr;
private: private:
#endif #endif
@@ -452,7 +460,9 @@ namespace test
void_const_ptr() : ptr_(0) {} void_const_ptr() : ptr_(0) {}
template <typename T> template <typename T>
explicit void_const_ptr(const_ptr<T> const& x) : ptr_(x.ptr_) {} explicit void_const_ptr(const_ptr<T> const& x) : ptr_(x.ptr_)
{
}
// I'm not using the safe bool idiom because the containers should be // I'm not using the safe bool idiom because the containers should be
// able to cope with bool conversions. // able to cope with bool conversions.
@@ -460,11 +470,10 @@ namespace test
bool operator==(void_const_ptr const& x) const { return ptr_ == x.ptr_; } bool operator==(void_const_ptr const& x) const { return ptr_ == x.ptr_; }
bool operator!=(void_const_ptr const& x) const { return ptr_ != x.ptr_; } bool operator!=(void_const_ptr const& x) const { return ptr_ != x.ptr_; }
}; };
template <class T> template <class T> class ptr
class ptr {
{
friend class allocator2<T>; friend class allocator2<T>;
friend class const_ptr<T>; friend class const_ptr<T>;
friend struct void_ptr; friend struct void_ptr;
@@ -474,15 +483,23 @@ namespace test
ptr(T* x) : ptr_(x) {} ptr(T* x) : ptr_(x) {}
public: public:
ptr() : ptr_(0) {} ptr() : ptr_(0) {}
explicit ptr(void_ptr const& x) : ptr_((T*) x.ptr_) {} explicit ptr(void_ptr const& x) : ptr_((T*)x.ptr_) {}
T& operator*() const { return *ptr_; } T& operator*() const { return *ptr_; }
T* operator->() const { return ptr_; } T* operator->() const { return ptr_; }
ptr& operator++() { ++ptr_; return *this; } ptr& operator++()
ptr operator++(int) { ptr tmp(*this); ++ptr_; return tmp; } {
++ptr_;
return *this;
}
ptr operator++(int)
{
ptr tmp(*this);
++ptr_;
return tmp;
}
ptr operator+(std::ptrdiff_t s) const { return ptr<T>(ptr_ + s); } ptr operator+(std::ptrdiff_t s) const { return ptr<T>(ptr_ + s); }
friend ptr operator+(std::ptrdiff_t s, ptr p) friend ptr operator+(std::ptrdiff_t s, ptr p) { return ptr<T>(s + p.ptr_); }
{ return ptr<T>(s + p.ptr_); }
T& operator[](std::ptrdiff_t s) const { return ptr_[s]; } T& operator[](std::ptrdiff_t s) const { return ptr_[s]; }
bool operator!() const { return !ptr_; } bool operator!() const { return !ptr_; }
@@ -496,11 +513,10 @@ namespace test
bool operator>(ptr const& x) const { return ptr_ > x.ptr_; } bool operator>(ptr const& x) const { return ptr_ > x.ptr_; }
bool operator<=(ptr const& x) const { return ptr_ <= x.ptr_; } bool operator<=(ptr const& x) const { return ptr_ <= x.ptr_; }
bool operator>=(ptr const& x) const { return ptr_ >= x.ptr_; } bool operator>=(ptr const& x) const { return ptr_ >= x.ptr_; }
}; };
template <class T> template <class T> class const_ptr
class const_ptr {
{
friend class allocator2<T>; friend class allocator2<T>;
friend struct const_void_ptr; friend struct const_void_ptr;
@@ -510,16 +526,26 @@ namespace test
public: public:
const_ptr() : ptr_(0) {} const_ptr() : ptr_(0) {}
const_ptr(ptr<T> const& x) : ptr_(x.ptr_) {} const_ptr(ptr<T> const& x) : ptr_(x.ptr_) {}
explicit const_ptr(void_const_ptr const& x) : ptr_((T const*) x.ptr_) {} explicit const_ptr(void_const_ptr const& x) : ptr_((T const*)x.ptr_) {}
T const& operator*() const { return *ptr_; } T const& operator*() const { return *ptr_; }
T const* operator->() const { return ptr_; } T const* operator->() const { return ptr_; }
const_ptr& operator++() { ++ptr_; return *this; } const_ptr& operator++()
const_ptr operator++(int) { const_ptr tmp(*this); ++ptr_; return tmp; } {
const_ptr operator+(std::ptrdiff_t s) const ++ptr_;
{ return const_ptr(ptr_ + s); } return *this;
}
const_ptr operator++(int)
{
const_ptr tmp(*this);
++ptr_;
return tmp;
}
const_ptr operator+(std::ptrdiff_t s) const { return const_ptr(ptr_ + s); }
friend const_ptr operator+(std::ptrdiff_t s, const_ptr p) friend const_ptr operator+(std::ptrdiff_t s, const_ptr p)
{ return ptr<T>(s + p.ptr_); } {
return ptr<T>(s + p.ptr_);
}
T const& operator[](int s) const { return ptr_[s]; } T const& operator[](int s) const { return ptr_[s]; }
bool operator!() const { return !ptr_; } bool operator!() const { return !ptr_; }
operator bool() const { return !!ptr_; } operator bool() const { return !!ptr_; }
@@ -530,17 +556,17 @@ namespace test
bool operator>(const_ptr const& x) const { return ptr_ > x.ptr_; } bool operator>(const_ptr const& x) const { return ptr_ > x.ptr_; }
bool operator<=(const_ptr const& x) const { return ptr_ <= x.ptr_; } bool operator<=(const_ptr const& x) const { return ptr_ <= x.ptr_; }
bool operator>=(const_ptr const& x) const { return ptr_ >= x.ptr_; } bool operator>=(const_ptr const& x) const { return ptr_ >= x.ptr_; }
}; };
template <class T> template <class T> class allocator2
class allocator2 {
{ #ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
# ifdef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
public: public:
# else #else
template <class> friend class allocator2; template <class> friend class allocator2;
# endif #endif
int tag_; int tag_;
public: public:
typedef std::size_t size_type; typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
@@ -552,111 +578,103 @@ namespace test
typedef T const& const_reference; typedef T const& const_reference;
typedef T value_type; typedef T value_type;
template <class U> struct rebind { typedef allocator2<U> other; }; template <class U> struct rebind
{
typedef allocator2<U> other;
};
explicit allocator2(int t = 0) : tag_(t) explicit allocator2(int t = 0) : tag_(t)
{ {
detail::tracker.allocator_ref(); detail::tracker.allocator_ref();
} }
template <class Y> allocator2(allocator2<Y> const& x) template <class Y> allocator2(allocator2<Y> const& x) : tag_(x.tag_)
: tag_(x.tag_)
{ {
detail::tracker.allocator_ref(); detail::tracker.allocator_ref();
} }
allocator2(allocator2 const& x) allocator2(allocator2 const& x) : tag_(x.tag_)
: tag_(x.tag_)
{ {
detail::tracker.allocator_ref(); detail::tracker.allocator_ref();
} }
~allocator2() ~allocator2() { detail::tracker.allocator_unref(); }
{
detail::tracker.allocator_unref();
}
pointer address(reference r) pointer address(reference r) { return pointer(&r); }
{
return pointer(&r);
}
const_pointer address(const_reference r) const_pointer address(const_reference r) { return const_pointer(&r); }
{
return const_pointer(&r);
}
pointer allocate(size_type n) { pointer allocate(size_type n)
{
pointer p(static_cast<T*>(::operator new(n * sizeof(T)))); pointer p(static_cast<T*>(::operator new(n * sizeof(T))));
detail::tracker.track_allocate((void*) p.ptr_, n, sizeof(T), tag_); detail::tracker.track_allocate((void*)p.ptr_, n, sizeof(T), tag_);
return p; return p;
} }
pointer allocate(size_type n, void const*) pointer allocate(size_type n, void const*)
{ {
pointer ptr(static_cast<T*>(::operator new(n * sizeof(T)))); pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_); detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
return ptr; return ptr;
} }
void deallocate(pointer p, size_type n) void deallocate(pointer p, size_type n)
{ {
detail::tracker.track_deallocate((void*) p.ptr_, n, sizeof(T), tag_); detail::tracker.track_deallocate((void*)p.ptr_, n, sizeof(T), tag_);
::operator delete((void*) p.ptr_); ::operator delete((void*)p.ptr_);
} }
void construct(T* p, T const& t) { void construct(T* p, T const& t)
detail::tracker.track_construct((void*) p, sizeof(T), tag_); {
new(p) T(t); detail::tracker.track_construct((void*)p, sizeof(T), tag_);
new (p) T(t);
} }
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args) { template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args)
detail::tracker.track_construct((void*) p, sizeof(T), tag_); {
new(p) T(boost::forward<Args>(args)...); detail::tracker.track_construct((void*)p, sizeof(T), tag_);
new (p) T(boost::forward<Args>(args)...);
} }
#endif #endif
void destroy(T* p) { void destroy(T* p)
detail::tracker.track_destroy((void*) p, sizeof(T), tag_); {
detail::tracker.track_destroy((void*)p, sizeof(T), tag_);
p->~T(); p->~T();
} }
size_type max_size() const { size_type max_size() const
{
return (std::numeric_limits<size_type>::max)(); return (std::numeric_limits<size_type>::max)();
} }
bool operator==(allocator2 const& x) const bool operator==(allocator2 const& x) const { return tag_ == x.tag_; }
{
return tag_ == x.tag_;
}
bool operator!=(allocator2 const& x) const bool operator!=(allocator2 const& x) const { return tag_ != x.tag_; }
{
return tag_ != x.tag_;
}
enum { enum
{
is_select_on_copy = false, is_select_on_copy = false,
is_propagate_on_swap = false, is_propagate_on_swap = false,
is_propagate_on_assign = false, is_propagate_on_assign = false,
is_propagate_on_move = false is_propagate_on_move = false
}; };
}; };
template <class T> template <class T>
bool equivalent_impl(allocator1<T> const& x, allocator1<T> const& y, bool equivalent_impl(
test::derived_type) allocator1<T> const& x, allocator1<T> const& y, test::derived_type)
{ {
return x == y; return x == y;
} }
template <class T> template <class T>
bool equivalent_impl(allocator2<T> const& x, allocator2<T> const& y, bool equivalent_impl(
test::derived_type) allocator2<T> const& x, allocator2<T> const& y, test::derived_type)
{ {
return x == y; return x == y;
} }
} }
#endif #endif

View File

@@ -3,71 +3,93 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // 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) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/unordered/detail/implementation.hpp>
#include <boost/detail/lightweight_test.hpp> #include <boost/detail/lightweight_test.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp>
#include <boost/limits.hpp> #include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/unordered/detail/implementation.hpp>
// Boilerplate // Boilerplate
#define ALLOCATOR_METHODS(name) \ #define ALLOCATOR_METHODS(name) \
template <typename U> struct rebind { \ template <typename U> struct rebind \
{ \
typedef name<U> other; \ typedef name<U> other; \
}; \ }; \
\ \
name() {} \ name() {} \
template <typename Y> name(name<Y> const&) {} \ template <typename Y> name(name<Y> const&) {} \
T* address(T& r) { return &r;} \ T* address(T& r) { return &r; } \
T const* address(T const& r) { return &r; } \ T const* address(T const& r) { return &r; } \
T* allocate(std::size_t n) \ T* allocate(std::size_t n) \
{ return static_cast<T*>(::operator new(n * sizeof(T))); } \ { \
return static_cast<T*>(::operator new(n * sizeof(T))); \
} \
T* allocate(std::size_t n, void const*) \ T* allocate(std::size_t n, void const*) \
{ return static_cast<T*>(::operator new(n * sizeof(T))); } \ { \
void deallocate(T* p, std::size_t) { ::operator delete((void*) p); } \ return static_cast<T*>(::operator new(n * sizeof(T))); \
void construct(T* p, T const& t) { new(p) T(t); } \ } \
void deallocate(T* p, std::size_t) { ::operator delete((void*)p); } \
void construct(T* p, T const& t) { new (p) T(t); } \
void destroy(T* p) { p->~T(); } \ void destroy(T* p) { p->~T(); } \
std::size_t max_size() const \ std::size_t max_size() const \
{ return (std::numeric_limits<std::size_t>::max)(); } \ { \
return (std::numeric_limits<std::size_t>::max)(); \
} \
bool operator==(name<T> const&) { return true; } \ bool operator==(name<T> const&) { return true; } \
bool operator!=(name<T> const&) { return false; } \ bool operator!=(name<T> const&) { return false; } \
/**/ /**/
#define ALLOCATOR_METHODS_TYPEDEFS(name) \ #define ALLOCATOR_METHODS_TYPEDEFS(name) \
template <typename U> struct rebind { \ template <typename U> struct rebind \
{ \
typedef name<U> other; \ typedef name<U> other; \
}; \ }; \
\ \
name() {} \ name() {} \
template <typename Y> name(name<Y> const&) {} \ template <typename Y> name(name<Y> const&) {} \
pointer address(T& r) { return &r;} \ pointer address(T& r) { return &r; } \
const_pointer address(T const& r) { return &r; } \ const_pointer address(T const& r) { return &r; } \
pointer allocate(std::size_t n) \ pointer allocate(std::size_t n) \
{ return pointer(::operator new(n * sizeof(T))); } \ { \
return pointer(::operator new(n * sizeof(T))); \
} \
pointer allocate(std::size_t n, void const*) \ pointer allocate(std::size_t n, void const*) \
{ return pointer(::operator new(n * sizeof(T))); } \ { \
void deallocate(pointer p, std::size_t) \ return pointer(::operator new(n * sizeof(T))); \
{ ::operator delete((void*) p); } \ } \
void construct(T* p, T const& t) { new(p) T(t); } \ void deallocate(pointer p, std::size_t) { ::operator delete((void*)p); } \
void construct(T* p, T const& t) { new (p) T(t); } \
void destroy(T* p) { p->~T(); } \ void destroy(T* p) { p->~T(); } \
size_type max_size() const \ size_type max_size() const \
{ return (std::numeric_limits<size_type>::max)(); } \ { \
return (std::numeric_limits<size_type>::max)(); \
} \
bool operator==(name<T> const&) { return true; } \ bool operator==(name<T> const&) { return true; } \
bool operator!=(name<T> const&) { return false; } \ bool operator!=(name<T> const&) { return false; } \
/**/ /**/
struct yes_type { enum { value = true }; }; struct yes_type
struct no_type { enum { value = false }; }; {
enum
{
value = true
};
};
struct no_type
{
enum
{
value = false
};
};
// For tracking calls... // For tracking calls...
static int selected; static int selected;
void reset() { void reset() { selected = 0; }
selected = 0;
}
template <typename Allocator> template <typename Allocator> int call_select()
int call_select()
{ {
typedef boost::unordered::detail::allocator_traits<Allocator> traits; typedef boost::unordered::detail::allocator_traits<Allocator> traits;
Allocator a; Allocator a;
@@ -79,8 +101,7 @@ int call_select()
// Empty allocator test // Empty allocator test
template <typename T> template <typename T> struct empty_allocator
struct empty_allocator
{ {
typedef T value_type; typedef T value_type;
ALLOCATOR_METHODS(empty_allocator) ALLOCATOR_METHODS(empty_allocator)
@@ -94,11 +115,14 @@ void test_empty_allocator()
BOOST_STATIC_ASSERT((boost::is_same<traits::size_type, BOOST_STATIC_ASSERT((boost::is_same<traits::size_type,
std::make_unsigned<std::ptrdiff_t>::type>::value)); std::make_unsigned<std::ptrdiff_t>::type>::value));
#else #else
BOOST_STATIC_ASSERT((boost::is_same<traits::size_type, std::size_t>::value)); BOOST_STATIC_ASSERT(
(boost::is_same<traits::size_type, std::size_t>::value));
#endif #endif
BOOST_STATIC_ASSERT((boost::is_same<traits::difference_type, std::ptrdiff_t>::value)); BOOST_STATIC_ASSERT(
(boost::is_same<traits::difference_type, std::ptrdiff_t>::value));
BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, int*>::value)); BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, int*>::value));
BOOST_STATIC_ASSERT((boost::is_same<traits::const_pointer, int const*>::value)); BOOST_STATIC_ASSERT(
(boost::is_same<traits::const_pointer, int const*>::value));
BOOST_STATIC_ASSERT((boost::is_same<traits::value_type, int>::value)); BOOST_STATIC_ASSERT((boost::is_same<traits::value_type, int>::value));
BOOST_TEST(!traits::propagate_on_container_copy_assignment::value); BOOST_TEST(!traits::propagate_on_container_copy_assignment::value);
BOOST_TEST(!traits::propagate_on_container_move_assignment::value); BOOST_TEST(!traits::propagate_on_container_move_assignment::value);
@@ -108,8 +132,7 @@ void test_empty_allocator()
// allocator 1 // allocator 1
template <typename T> template <typename T> struct allocator1
struct allocator1
{ {
typedef T value_type; typedef T value_type;
ALLOCATOR_METHODS(allocator1) ALLOCATOR_METHODS(allocator1)
@@ -118,7 +141,8 @@ struct allocator1
typedef yes_type propagate_on_container_move_assignment; typedef yes_type propagate_on_container_move_assignment;
typedef yes_type propagate_on_container_swap; typedef yes_type propagate_on_container_swap;
allocator1<T> select_on_container_copy_construction() const { allocator1<T> select_on_container_copy_construction() const
{
++selected; ++selected;
return allocator1<T>(); return allocator1<T>();
} }
@@ -132,11 +156,14 @@ void test_allocator1()
BOOST_STATIC_ASSERT((boost::is_same<traits::size_type, BOOST_STATIC_ASSERT((boost::is_same<traits::size_type,
std::make_unsigned<std::ptrdiff_t>::type>::value)); std::make_unsigned<std::ptrdiff_t>::type>::value));
#else #else
BOOST_STATIC_ASSERT((boost::is_same<traits::size_type, std::size_t>::value)); BOOST_STATIC_ASSERT(
(boost::is_same<traits::size_type, std::size_t>::value));
#endif #endif
BOOST_STATIC_ASSERT((boost::is_same<traits::difference_type, std::ptrdiff_t>::value)); BOOST_STATIC_ASSERT(
(boost::is_same<traits::difference_type, std::ptrdiff_t>::value));
BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, int*>::value)); BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, int*>::value));
BOOST_STATIC_ASSERT((boost::is_same<traits::const_pointer, int const*>::value)); BOOST_STATIC_ASSERT(
(boost::is_same<traits::const_pointer, int const*>::value));
BOOST_STATIC_ASSERT((boost::is_same<traits::value_type, int>::value)); BOOST_STATIC_ASSERT((boost::is_same<traits::value_type, int>::value));
BOOST_TEST(traits::propagate_on_container_copy_assignment::value); BOOST_TEST(traits::propagate_on_container_copy_assignment::value);
BOOST_TEST(traits::propagate_on_container_move_assignment::value); BOOST_TEST(traits::propagate_on_container_move_assignment::value);
@@ -146,17 +173,16 @@ void test_allocator1()
// allocator 2 // allocator 2
template <typename Alloc> template <typename Alloc> struct allocator2_base
struct allocator2_base
{ {
Alloc select_on_container_copy_construction() const { Alloc select_on_container_copy_construction() const
{
++selected; ++selected;
return Alloc(); return Alloc();
} }
}; };
template <typename T> template <typename T> struct allocator2 : allocator2_base<allocator2<T> >
struct allocator2 : allocator2_base<allocator2<T> >
{ {
typedef T value_type; typedef T value_type;
typedef T* pointer; typedef T* pointer;
@@ -174,10 +200,13 @@ void test_allocator2()
{ {
typedef allocator2<int> allocator; typedef allocator2<int> allocator;
typedef boost::unordered::detail::allocator_traits<allocator> traits; typedef boost::unordered::detail::allocator_traits<allocator> traits;
BOOST_STATIC_ASSERT((boost::is_same<traits::size_type, std::size_t>::value)); BOOST_STATIC_ASSERT(
BOOST_STATIC_ASSERT((boost::is_same<traits::difference_type, std::ptrdiff_t>::value)); (boost::is_same<traits::size_type, std::size_t>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<traits::difference_type, std::ptrdiff_t>::value));
BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, int*>::value)); BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, int*>::value));
BOOST_STATIC_ASSERT((boost::is_same<traits::const_pointer, int const*>::value)); BOOST_STATIC_ASSERT(
(boost::is_same<traits::const_pointer, int const*>::value));
BOOST_STATIC_ASSERT((boost::is_same<traits::value_type, int>::value)); BOOST_STATIC_ASSERT((boost::is_same<traits::value_type, int>::value));
BOOST_TEST(!traits::propagate_on_container_copy_assignment::value); BOOST_TEST(!traits::propagate_on_container_copy_assignment::value);
BOOST_TEST(!traits::propagate_on_container_move_assignment::value); BOOST_TEST(!traits::propagate_on_container_move_assignment::value);
@@ -187,31 +216,27 @@ void test_allocator2()
// allocator 3 // allocator 3
template <typename T> template <typename T> struct ptr
struct ptr
{ {
T* value_; T* value_;
ptr(void* v) : value_((T*) v) {} ptr(void* v) : value_((T*)v) {}
T& operator*() const { return *value_; } T& operator*() const { return *value_; }
}; };
template <> template <> struct ptr<void>
struct ptr<void>
{ {
void* value_; void* value_;
ptr(void* v) : value_(v) {} ptr(void* v) : value_(v) {}
}; };
template <> template <> struct ptr<const void>
struct ptr<const void>
{ {
void const* value_; void const* value_;
ptr(void const* v) : value_(v) {} ptr(void const* v) : value_(v) {}
}; };
template <typename T> template <typename T> struct allocator3
struct allocator3
{ {
typedef T value_type; typedef T value_type;
typedef ptr<T> pointer; typedef ptr<T> pointer;
@@ -223,7 +248,8 @@ struct allocator3
typedef yes_type propagate_on_container_copy_assignment; typedef yes_type propagate_on_container_copy_assignment;
typedef no_type propagate_on_container_move_assignment; typedef no_type propagate_on_container_move_assignment;
allocator3<T> select_on_container_copy_construction() const { allocator3<T> select_on_container_copy_construction() const
{
++selected; ++selected;
return allocator3<T>(); return allocator3<T>();
} }
@@ -233,10 +259,13 @@ void test_allocator3()
{ {
typedef allocator3<int> allocator; typedef allocator3<int> allocator;
typedef boost::unordered::detail::allocator_traits<allocator> traits; typedef boost::unordered::detail::allocator_traits<allocator> traits;
BOOST_STATIC_ASSERT((boost::is_same<traits::size_type, unsigned short>::value)); BOOST_STATIC_ASSERT(
BOOST_STATIC_ASSERT((boost::is_same<traits::difference_type, std::ptrdiff_t>::value)); (boost::is_same<traits::size_type, unsigned short>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<traits::difference_type, std::ptrdiff_t>::value));
BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, ptr<int> >::value)); BOOST_STATIC_ASSERT((boost::is_same<traits::pointer, ptr<int> >::value));
BOOST_STATIC_ASSERT((boost::is_same<traits::const_pointer, ptr<int const> >::value)); BOOST_STATIC_ASSERT(
(boost::is_same<traits::const_pointer, ptr<int const> >::value));
BOOST_STATIC_ASSERT((boost::is_same<traits::value_type, int>::value)); BOOST_STATIC_ASSERT((boost::is_same<traits::value_type, int>::value));
BOOST_TEST(traits::propagate_on_container_copy_assignment::value); BOOST_TEST(traits::propagate_on_container_copy_assignment::value);
BOOST_TEST(!traits::propagate_on_container_move_assignment::value); BOOST_TEST(!traits::propagate_on_container_move_assignment::value);

View File

@@ -20,20 +20,19 @@
#include <iostream> #include <iostream>
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
#pragma warning(disable:4127) // conditional expression is constant #pragma warning(disable : 4127) // conditional expression is constant
#endif #endif
namespace assign_tests { namespace assign_tests {
test::seed_t initialize_seed(96785); test::seed_t initialize_seed(96785);
template <class T> template <class T> void assign_tests1(T*, test::random_generator generator)
void assign_tests1(T*, test::random_generator generator)
{ {
BOOST_DEDUCED_TYPENAME T::hasher hf; BOOST_DEDUCED_TYPENAME T::hasher hf;
BOOST_DEDUCED_TYPENAME T::key_equal eq; BOOST_DEDUCED_TYPENAME T::key_equal eq;
std::cerr<<"assign_tests1.1\n"; std::cerr << "assign_tests1.1\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -44,7 +43,7 @@ void assign_tests1(T*, test::random_generator generator)
BOOST_TEST(test::equivalent(x.key_eq(), eq)); BOOST_TEST(test::equivalent(x.key_eq(), eq));
} }
std::cerr<<"assign_tests1.2\n"; std::cerr << "assign_tests1.2\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -69,8 +68,7 @@ void assign_tests1(T*, test::random_generator generator)
} }
} }
template <class T> template <class T> void assign_tests2(T*, test::random_generator generator)
void assign_tests2(T*, test::random_generator generator)
{ {
BOOST_DEDUCED_TYPENAME T::hasher hf1(1); BOOST_DEDUCED_TYPENAME T::hasher hf1(1);
BOOST_DEDUCED_TYPENAME T::hasher hf2(2); BOOST_DEDUCED_TYPENAME T::hasher hf2(2);
@@ -81,7 +79,7 @@ void assign_tests2(T*, test::random_generator generator)
typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type; typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type;
std::cerr<<"assign_tests2.0 - empty container\n"; std::cerr << "assign_tests2.0 - empty container\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -95,7 +93,7 @@ void assign_tests2(T*, test::random_generator generator)
test::check_container(x1, x2); test::check_container(x1, x2);
} }
std::cerr<<"assign_tests2.1\n"; std::cerr << "assign_tests2.1\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -112,7 +110,7 @@ void assign_tests2(T*, test::random_generator generator)
BOOST_TEST(x2.load_factor() <= x2.max_load_factor()); BOOST_TEST(x2.load_factor() <= x2.max_load_factor());
} }
std::cerr<<"assign_tests2.1a\n"; std::cerr << "assign_tests2.1a\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -130,7 +128,7 @@ void assign_tests2(T*, test::random_generator generator)
BOOST_TEST(x2.load_factor() <= x2.max_load_factor()); BOOST_TEST(x2.load_factor() <= x2.max_load_factor());
} }
std::cerr<<"assign_tests2.2\n"; std::cerr << "assign_tests2.2\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -143,8 +141,7 @@ void assign_tests2(T*, test::random_generator generator)
if (allocator_type::is_propagate_on_assign) { if (allocator_type::is_propagate_on_assign) {
BOOST_TEST(test::equivalent(x2.get_allocator(), al1)); BOOST_TEST(test::equivalent(x2.get_allocator(), al1));
BOOST_TEST(!test::equivalent(x2.get_allocator(), al2)); BOOST_TEST(!test::equivalent(x2.get_allocator(), al2));
} } else {
else {
BOOST_TEST(test::equivalent(x2.get_allocator(), al2)); BOOST_TEST(test::equivalent(x2.get_allocator(), al2));
BOOST_TEST(!test::equivalent(x2.get_allocator(), al1)); BOOST_TEST(!test::equivalent(x2.get_allocator(), al1));
} }
@@ -153,7 +150,7 @@ void assign_tests2(T*, test::random_generator generator)
BOOST_TEST(x2.load_factor() <= x2.max_load_factor()); BOOST_TEST(x2.load_factor() <= x2.max_load_factor());
} }
std::cerr<<"assign_tests2.3\n"; std::cerr << "assign_tests2.3\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -166,8 +163,7 @@ void assign_tests2(T*, test::random_generator generator)
if (allocator_type::is_propagate_on_assign) { if (allocator_type::is_propagate_on_assign) {
BOOST_TEST(test::equivalent(x2.get_allocator(), al1)); BOOST_TEST(test::equivalent(x2.get_allocator(), al1));
BOOST_TEST(!test::equivalent(x2.get_allocator(), al2)); BOOST_TEST(!test::equivalent(x2.get_allocator(), al2));
} } else {
else {
BOOST_TEST(test::equivalent(x2.get_allocator(), al2)); BOOST_TEST(test::equivalent(x2.get_allocator(), al2));
BOOST_TEST(!test::equivalent(x2.get_allocator(), al1)); BOOST_TEST(!test::equivalent(x2.get_allocator(), al1));
} }
@@ -176,7 +172,7 @@ void assign_tests2(T*, test::random_generator generator)
BOOST_TEST(x2.load_factor() <= x2.max_load_factor()); BOOST_TEST(x2.load_factor() <= x2.max_load_factor());
} }
std::cerr<<"assign_tests2.4\n"; std::cerr << "assign_tests2.4\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -189,8 +185,7 @@ void assign_tests2(T*, test::random_generator generator)
if (allocator_type::is_propagate_on_assign) { if (allocator_type::is_propagate_on_assign) {
BOOST_TEST(test::equivalent(x2.get_allocator(), al1)); BOOST_TEST(test::equivalent(x2.get_allocator(), al1));
BOOST_TEST(!test::equivalent(x2.get_allocator(), al2)); BOOST_TEST(!test::equivalent(x2.get_allocator(), al2));
} } else {
else {
BOOST_TEST(test::equivalent(x2.get_allocator(), al2)); BOOST_TEST(test::equivalent(x2.get_allocator(), al2));
BOOST_TEST(!test::equivalent(x2.get_allocator(), al1)); BOOST_TEST(!test::equivalent(x2.get_allocator(), al1));
} }
@@ -200,54 +195,43 @@ void assign_tests2(T*, test::random_generator generator)
} }
} }
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
std::allocator<test::object> >* test_map_std_alloc; std::allocator<test::object> >* test_map_std_alloc;
boost::unordered_set<test::object, boost::unordered_set<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator1<test::object> >* test_set; test::allocator1<test::object> >* test_set;
boost::unordered_multiset<test::object, boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator2<test::object> >* test_multiset; test::allocator2<test::object> >* test_multiset;
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator2<test::object> >* test_map; test::allocator2<test::object> >* test_map;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to, test::allocator1<test::object> >* test_multimap;
test::allocator1<test::object> >* test_multimap;
boost::unordered_set<test::object, boost::unordered_set<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::propagate_assign> >* test::cxx11_allocator<test::object, test::propagate_assign> >*
test_set_prop_assign; test_set_prop_assign;
boost::unordered_multiset<test::object, boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::propagate_assign> >* test::cxx11_allocator<test::object, test::propagate_assign> >*
test_multiset_prop_assign; test_multiset_prop_assign;
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::propagate_assign> >* test::cxx11_allocator<test::object, test::propagate_assign> >*
test_map_prop_assign; test_map_prop_assign;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to,
test::cxx11_allocator<test::object, test::propagate_assign> >* test::cxx11_allocator<test::object, test::propagate_assign> >*
test_multimap_prop_assign; test_multimap_prop_assign;
boost::unordered_set<test::object, boost::unordered_set<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::no_propagate_assign> >* test::cxx11_allocator<test::object, test::no_propagate_assign> >*
test_set_no_prop_assign; test_set_no_prop_assign;
boost::unordered_multiset<test::object, boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::no_propagate_assign> >* test::cxx11_allocator<test::object, test::no_propagate_assign> >*
test_multiset_no_prop_assign; test_multiset_no_prop_assign;
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::no_propagate_assign> >* test::cxx11_allocator<test::object, test::no_propagate_assign> >*
test_map_no_prop_assign; test_map_no_prop_assign;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to,
test::cxx11_allocator<test::object, test::no_propagate_assign> >* test::cxx11_allocator<test::object, test::no_propagate_assign> >*
test_multimap_no_prop_assign; test_multimap_no_prop_assign;
@@ -255,8 +239,7 @@ using test::default_generator;
using test::generate_collisions; using test::generate_collisions;
using test::limited_range; using test::limited_range;
template <typename T> template <typename T> bool is_propagate(T*)
bool is_propagate(T*)
{ {
return T::allocator_type::is_propagate_on_assign; return T::allocator_type::is_propagate_on_assign;
} }
@@ -268,27 +251,27 @@ UNORDERED_AUTO_TEST(check_traits)
BOOST_TEST(!is_propagate(test_set_no_prop_assign)); BOOST_TEST(!is_propagate(test_set_no_prop_assign));
} }
UNORDERED_TEST(assign_tests1, ( UNORDERED_TEST(assign_tests1,
(test_map_std_alloc) ((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap)(
(test_set)(test_multiset)(test_map)(test_multimap) test_set_prop_assign)(test_multiset_prop_assign)(test_map_prop_assign)(
(test_set_prop_assign)(test_multiset_prop_assign)(test_map_prop_assign)(test_multimap_prop_assign) test_multimap_prop_assign)(test_set_no_prop_assign)(
(test_set_no_prop_assign)(test_multiset_no_prop_assign)(test_map_no_prop_assign)(test_multimap_no_prop_assign) test_multiset_no_prop_assign)(test_map_no_prop_assign)(
) test_multimap_no_prop_assign))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
UNORDERED_TEST(assign_tests2, ( UNORDERED_TEST(
(test_set)(test_multiset)(test_map)(test_multimap) assign_tests2, ((test_set)(test_multiset)(test_map)(test_multimap)(
(test_set_prop_assign)(test_multiset_prop_assign)(test_map_prop_assign)(test_multimap_prop_assign) test_set_prop_assign)(test_multiset_prop_assign)(
(test_set_no_prop_assign)(test_multiset_no_prop_assign)(test_map_no_prop_assign)(test_multimap_no_prop_assign) test_map_prop_assign)(test_multimap_prop_assign)(
) test_set_no_prop_assign)(test_multiset_no_prop_assign)(
((default_generator)(generate_collisions)(limited_range)) test_map_no_prop_assign)(test_multimap_no_prop_assign))(
) (default_generator)(generate_collisions)(limited_range)))
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
UNORDERED_AUTO_TEST(assign_default_initializer_list) { UNORDERED_AUTO_TEST(assign_default_initializer_list)
std::cerr<<"Initializer List Tests\n"; {
std::cerr << "Initializer List Tests\n";
std::initializer_list<std::pair<int const, int> > init; std::initializer_list<std::pair<int const, int> > init;
boost::unordered_map<int, int> x1; boost::unordered_map<int, int> x1;
x1[25] = 3; x1[25] = 3;
@@ -303,18 +286,17 @@ UNORDERED_AUTO_TEST(assign_default_initializer_list) {
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
UNORDERED_AUTO_TEST(assign_initializer_list) UNORDERED_AUTO_TEST(assign_initializer_list)
{ {
std::cerr<<"Initializer List Tests\n"; std::cerr << "Initializer List Tests\n";
boost::unordered_set<int> x; boost::unordered_set<int> x;
x.insert(10); x.insert(10);
x.insert(20); x.insert(20);
x = { 1, 2, -10 }; x = {1, 2, -10};
BOOST_TEST(x.find(10) == x.end()); BOOST_TEST(x.find(10) == x.end());
BOOST_TEST(x.find(-10) != x.end()); BOOST_TEST(x.find(-10) != x.end());
} }
#endif #endif
} }
RUN_TESTS() RUN_TESTS()

View File

@@ -14,7 +14,8 @@
namespace at_tests { namespace at_tests {
UNORDERED_AUTO_TEST(at_tests) { UNORDERED_AUTO_TEST(at_tests)
{
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Create Map" << std::endl; BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Create Map" << std::endl;
boost::unordered_map<std::string, int> x; boost::unordered_map<std::string, int> x;
@@ -34,13 +35,11 @@ UNORDERED_AUTO_TEST(at_tests) {
try { try {
x.at("three"); x.at("three");
BOOST_ERROR("Should have thrown."); BOOST_ERROR("Should have thrown.");
} } catch (std::out_of_range) {
catch(std::out_of_range) {
} }
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Finished" << std::endl; BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Finished" << std::endl;
} }
} }
RUN_TESTS() RUN_TESTS()

View File

@@ -17,7 +17,7 @@
#include "../helpers/helpers.hpp" #include "../helpers/helpers.hpp"
#if BOOST_WORKAROUND(BOOST_MSVC, < 1400) #if BOOST_WORKAROUND(BOOST_MSVC, < 1400)
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int', #pragma warning(disable : 4267) // conversion from 'size_t' to 'unsigned int',
// possible loss of data. // possible loss of data.
#endif #endif
@@ -25,8 +25,7 @@ namespace bucket_tests {
test::seed_t initialize_seed(54635); test::seed_t initialize_seed(54635);
template <class X> template <class X> void tests(X*, test::random_generator generator)
void tests(X*, test::random_generator generator)
{ {
test::check_instances check_; test::check_instances check_;
@@ -38,66 +37,59 @@ void tests(X*, test::random_generator generator)
BOOST_TEST(x.bucket_count() <= x.max_bucket_count()); BOOST_TEST(x.bucket_count() <= x.max_bucket_count());
if (!(x.bucket_count() <= x.max_bucket_count())) { if (!(x.bucket_count() <= x.max_bucket_count())) {
std::cerr<<x.bucket_count()<<"<="<<x.max_bucket_count()<<"\n"; std::cerr << x.bucket_count() << "<=" << x.max_bucket_count() << "\n";
} }
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator for (BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator
it = v.begin(), end = v.end(); it != end; ++it) it = v.begin(),
{ end = v.end();
it != end; ++it) {
size_type bucket = x.bucket(test::get_key<X>(*it)); size_type bucket = x.bucket(test::get_key<X>(*it));
BOOST_TEST(bucket < x.bucket_count()); BOOST_TEST(bucket < x.bucket_count());
if(bucket < x.bucket_count()) { if (bucket < x.bucket_count()) {
// lit? lend?? I need a new naming scheme. // lit? lend?? I need a new naming scheme.
const_local_iterator lit = x.begin(bucket), lend = x.end(bucket); const_local_iterator lit = x.begin(bucket), lend = x.end(bucket);
while(lit != lend while (lit != lend &&
&& test::get_key<X>(*it) != test::get_key<X>(*lit)) test::get_key<X>(*it) != test::get_key<X>(*lit)) {
{
++lit; ++lit;
} }
BOOST_TEST(lit != lend); BOOST_TEST(lit != lend);
} }
} }
for(size_type i = 0; i < x.bucket_count(); ++i) { for (size_type i = 0; i < x.bucket_count(); ++i) {
BOOST_TEST(x.bucket_size(i) == static_cast<size_type>( BOOST_TEST(x.bucket_size(i) ==
std::distance(x.begin(i), x.end(i)))); static_cast<size_type>(std::distance(x.begin(i), x.end(i))));
BOOST_TEST(x.bucket_size(i) == static_cast<size_type>( BOOST_TEST(x.bucket_size(i) == static_cast<size_type>(std::distance(
std::distance(x.cbegin(i), x.cend(i)))); x.cbegin(i), x.cend(i))));
X const& x_ref = x; X const& x_ref = x;
BOOST_TEST(x.bucket_size(i) == static_cast<size_type>( BOOST_TEST(x.bucket_size(i) == static_cast<size_type>(std::distance(
std::distance(x_ref.begin(i), x_ref.end(i)))); x_ref.begin(i), x_ref.end(i))));
BOOST_TEST(x.bucket_size(i) == static_cast<size_type>( BOOST_TEST(x.bucket_size(i) == static_cast<size_type>(std::distance(
std::distance(x_ref.cbegin(i), x_ref.cend(i)))); x_ref.cbegin(i), x_ref.cend(i))));
} }
} }
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to, std::allocator<test::object> >* test_multimap_std_alloc;
std::allocator<test::object> >* test_multimap_std_alloc;
boost::unordered_set<test::object, boost::unordered_set<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator2<test::object> >* test_set; test::allocator2<test::object> >* test_set;
boost::unordered_multiset<test::object, boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator1<test::object> >* test_multiset; test::allocator1<test::object> >* test_multiset;
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator1<test::object> >* test_map; test::allocator1<test::object> >* test_map;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to, test::allocator2<test::object> >* test_multimap;
test::allocator2<test::object> >* test_multimap;
using test::default_generator; using test::default_generator;
using test::generate_collisions; using test::generate_collisions;
using test::limited_range; using test::limited_range;
UNORDERED_TEST(tests, UNORDERED_TEST(tests, ((test_multimap_std_alloc)(test_set)(test_multiset)(
((test_multimap_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap)) test_map)(test_multimap))((default_generator)(
((default_generator)(generate_collisions)(limited_range)) generate_collisions)(limited_range)))
)
} }
RUN_TESTS() RUN_TESTS()

View File

@@ -19,29 +19,18 @@
// Explicit instantiation to catch compile-time errors // Explicit instantiation to catch compile-time errors
template class boost::unordered_map< template class boost::unordered_map<int, int, boost::hash<int>,
int, std::equal_to<int>, test::minimal::allocator<std::pair<int const, int> > >;
int, template class boost::unordered_multimap<int const, int const, boost::hash<int>,
boost::hash<int>, std::equal_to<int>, test::minimal::allocator<std::pair<int const, int> > >;
std::equal_to<int>,
test::minimal::allocator<std::pair<int const, int> > >;
template class boost::unordered_multimap<
int const,
int const,
boost::hash<int>,
std::equal_to<int>,
test::minimal::allocator<std::pair<int const, int> > >;
template class boost::unordered_map< template class boost::unordered_map<test::minimal::assignable const,
test::minimal::assignable const,
test::minimal::default_assignable const, test::minimal::default_assignable const,
test::minimal::hash<test::minimal::assignable>, test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>, test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<test::minimal::assignable> >; test::minimal::allocator<test::minimal::assignable> >;
template class boost::unordered_multimap< template class boost::unordered_multimap<test::minimal::assignable,
test::minimal::assignable, test::minimal::assignable, test::minimal::hash<test::minimal::assignable>,
test::minimal::assignable,
test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>, test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<test::minimal::assignable> >; test::minimal::allocator<test::minimal::assignable> >;
@@ -50,68 +39,70 @@ UNORDERED_AUTO_TEST(test0)
test::minimal::constructor_param x; test::minimal::constructor_param x;
typedef std::pair<test::minimal::assignable const, typedef std::pair<test::minimal::assignable const,
test::minimal::assignable> value_type; test::minimal::assignable>
value_type;
value_type value(x, x); value_type value(x, x);
std::cout<<"Test unordered_map.\n"; std::cout << "Test unordered_map.\n";
boost::unordered_map<int, int> int_map; boost::unordered_map<int, int> int_map;
boost::unordered_map<int, int, boost::unordered_map<int, int, boost::hash<int>, std::equal_to<int>,
boost::hash<int>, std::equal_to<int>, test::minimal::cxx11_allocator<std::pair<int const, int> > >
test::minimal::cxx11_allocator<std::pair<int const, int> > int_map2;
> int_map2;
boost::unordered_map< boost::unordered_map<test::minimal::assignable, test::minimal::assignable,
test::minimal::assignable,
test::minimal::assignable,
test::minimal::hash<test::minimal::assignable>, test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>, test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<value_type> > map; test::minimal::allocator<value_type> >
map;
container_test(int_map, std::pair<int const, int>(0, 0)); container_test(int_map, std::pair<int const, int>(0, 0));
container_test(int_map2, std::pair<int const, int>(0, 0)); container_test(int_map2, std::pair<int const, int>(0, 0));
container_test(map, value); container_test(map, value);
std::cout<<"Test unordered_multimap.\n"; std::cout << "Test unordered_multimap.\n";
boost::unordered_multimap<int, int> int_multimap; boost::unordered_multimap<int, int> int_multimap;
boost::unordered_multimap<int, int, boost::unordered_multimap<int, int, boost::hash<int>, std::equal_to<int>,
boost::hash<int>, std::equal_to<int>, test::minimal::cxx11_allocator<std::pair<int const, int> > >
test::minimal::cxx11_allocator<std::pair<int const, int> > int_multimap2;
> int_multimap2;
boost::unordered_multimap< boost::unordered_multimap<test::minimal::assignable,
test::minimal::assignable,
test::minimal::assignable, test::minimal::assignable,
test::minimal::hash<test::minimal::assignable>, test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>, test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<value_type> > multimap; test::minimal::allocator<value_type> >
multimap;
container_test(int_multimap, std::pair<int const, int>(0, 0)); container_test(int_multimap, std::pair<int const, int>(0, 0));
container_test(int_multimap2, std::pair<int const, int>(0, 0)); container_test(int_multimap2, std::pair<int const, int>(0, 0));
container_test(multimap, value); container_test(multimap, value);
} }
UNORDERED_AUTO_TEST(equality_tests) { UNORDERED_AUTO_TEST(equality_tests)
{
typedef std::pair< typedef std::pair<
test::minimal::copy_constructible_equality_comparable const, test::minimal::copy_constructible_equality_comparable const,
test::minimal::copy_constructible_equality_comparable> value_type; test::minimal::copy_constructible_equality_comparable>
value_type;
boost::unordered_map<int, int> int_map; boost::unordered_map<int, int> int_map;
boost::unordered_map<int, int, boost::unordered_map<int, int, boost::hash<int>, std::equal_to<int>,
boost::hash<int>, std::equal_to<int>, test::minimal::cxx11_allocator<std::pair<int const, int> > >
test::minimal::cxx11_allocator<std::pair<int const, int> > int_map2;
> int_map2;
boost::unordered_map< boost::unordered_map<
test::minimal::copy_constructible_equality_comparable, test::minimal::copy_constructible_equality_comparable,
test::minimal::copy_constructible_equality_comparable, test::minimal::copy_constructible_equality_comparable,
test::minimal::hash<test::minimal::copy_constructible_equality_comparable>, test::minimal::hash<
test::minimal::equal_to<test::minimal::copy_constructible_equality_comparable>, test::minimal::copy_constructible_equality_comparable>,
test::minimal::allocator<value_type> > map; test::minimal::equal_to<
test::minimal::copy_constructible_equality_comparable>,
test::minimal::allocator<value_type> >
map;
equality_test(int_map); equality_test(int_map);
equality_test(int_map2); equality_test(int_map2);
@@ -119,37 +110,39 @@ UNORDERED_AUTO_TEST(equality_tests) {
boost::unordered_multimap<int, int> int_multimap; boost::unordered_multimap<int, int> int_multimap;
boost::unordered_multimap<int, int, boost::unordered_multimap<int, int, boost::hash<int>, std::equal_to<int>,
boost::hash<int>, std::equal_to<int>, test::minimal::cxx11_allocator<std::pair<int const, int> > >
test::minimal::cxx11_allocator<std::pair<int const, int> > int_multimap2;
> int_multimap2;
boost::unordered_multimap< boost::unordered_multimap<
test::minimal::copy_constructible_equality_comparable, test::minimal::copy_constructible_equality_comparable,
test::minimal::copy_constructible_equality_comparable, test::minimal::copy_constructible_equality_comparable,
test::minimal::hash<test::minimal::copy_constructible_equality_comparable>, test::minimal::hash<
test::minimal::equal_to<test::minimal::copy_constructible_equality_comparable>, test::minimal::copy_constructible_equality_comparable>,
test::minimal::allocator<value_type> > multimap; test::minimal::equal_to<
test::minimal::copy_constructible_equality_comparable>,
test::minimal::allocator<value_type> >
multimap;
equality_test(int_multimap); equality_test(int_multimap);
equality_test(int_multimap2); equality_test(int_multimap2);
equality_test(multimap); equality_test(multimap);
} }
UNORDERED_AUTO_TEST(test1) { UNORDERED_AUTO_TEST(test1)
{
boost::hash<int> hash; boost::hash<int> hash;
std::equal_to<int> equal_to; std::equal_to<int> equal_to;
int value = 0; int value = 0;
std::pair<int const, int> map_value(0, 0); std::pair<int const, int> map_value(0, 0);
std::cout<<"Test unordered_map.\n"; std::cout << "Test unordered_map.\n";
boost::unordered_map<int, int> map; boost::unordered_map<int, int> map;
boost::unordered_map<int, int, boost::unordered_map<int, int, boost::hash<int>, std::equal_to<int>,
boost::hash<int>, std::equal_to<int>, test::minimal::cxx11_allocator<std::pair<int const, int> > >
test::minimal::cxx11_allocator<std::pair<int const, int> > map2;
> map2;
unordered_unique_test(map, map_value); unordered_unique_test(map, map_value);
unordered_map_test(map, value, value); unordered_map_test(map, value, value);
@@ -161,14 +154,13 @@ UNORDERED_AUTO_TEST(test1) {
unordered_copyable_test(map2, value, map_value, hash, equal_to); unordered_copyable_test(map2, value, map_value, hash, equal_to);
unordered_map_functions(map2, value, value); unordered_map_functions(map2, value, value);
std::cout<<"Test unordered_multimap.\n"; std::cout << "Test unordered_multimap.\n";
boost::unordered_multimap<int, int> multimap; boost::unordered_multimap<int, int> multimap;
boost::unordered_multimap<int, int, boost::unordered_multimap<int, int, boost::hash<int>, std::equal_to<int>,
boost::hash<int>, std::equal_to<int>, test::minimal::cxx11_allocator<std::pair<int const, int> > >
test::minimal::cxx11_allocator<std::pair<int const, int> > multimap2;
> multimap2;
unordered_equivalent_test(multimap, map_value); unordered_equivalent_test(multimap, map_value);
unordered_map_test(multimap, value, value); unordered_map_test(multimap, value, value);
@@ -189,42 +181,42 @@ UNORDERED_AUTO_TEST(test2)
test::minimal::equal_to<test::minimal::assignable> equal_to(x); test::minimal::equal_to<test::minimal::assignable> equal_to(x);
typedef std::pair<test::minimal::assignable const, typedef std::pair<test::minimal::assignable const,
test::minimal::assignable> map_value_type; test::minimal::assignable>
map_value_type;
map_value_type map_value(assignable, assignable); map_value_type map_value(assignable, assignable);
std::cout<<"Test unordered_map.\n"; std::cout << "Test unordered_map.\n";
boost::unordered_map< boost::unordered_map<test::minimal::assignable, test::minimal::assignable,
test::minimal::assignable,
test::minimal::assignable,
test::minimal::hash<test::minimal::assignable>, test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>, test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<map_value_type> > map; test::minimal::allocator<map_value_type> >
map;
unordered_unique_test(map, map_value); unordered_unique_test(map, map_value);
unordered_map_test(map, assignable, assignable); unordered_map_test(map, assignable, assignable);
unordered_copyable_test(map, assignable, map_value, hash, equal_to); unordered_copyable_test(map, assignable, map_value, hash, equal_to);
unordered_map_member_test(map, map_value); unordered_map_member_test(map, map_value);
boost::unordered_map< boost::unordered_map<test::minimal::assignable,
test::minimal::assignable,
test::minimal::default_assignable, test::minimal::default_assignable,
test::minimal::hash<test::minimal::assignable>, test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>, test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<map_value_type> > map2; test::minimal::allocator<map_value_type> >
map2;
test::minimal::default_assignable default_assignable; test::minimal::default_assignable default_assignable;
unordered_map_functions(map2, assignable, default_assignable); unordered_map_functions(map2, assignable, default_assignable);
std::cout<<"Test unordered_multimap.\n"; std::cout << "Test unordered_multimap.\n";
boost::unordered_multimap< boost::unordered_multimap<test::minimal::assignable,
test::minimal::assignable,
test::minimal::assignable, test::minimal::assignable,
test::minimal::hash<test::minimal::assignable>, test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>, test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<map_value_type> > multimap; test::minimal::allocator<map_value_type> >
multimap;
unordered_equivalent_test(multimap, map_value); unordered_equivalent_test(multimap, map_value);
unordered_map_test(multimap, assignable, assignable); unordered_map_test(multimap, assignable, assignable);

View File

@@ -19,24 +19,16 @@
// Explicit instantiation to catch compile-time errors // Explicit instantiation to catch compile-time errors
template class boost::unordered_set< template class boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
int,
boost::hash<int>,
std::equal_to<int>,
test::minimal::allocator<int> >;
template class boost::unordered_multiset<
int const,
boost::hash<int>,
std::equal_to<int>,
test::minimal::allocator<int> >; test::minimal::allocator<int> >;
template class boost::unordered_multiset<int const, boost::hash<int>,
std::equal_to<int>, test::minimal::allocator<int> >;
template class boost::unordered_set< template class boost::unordered_set<test::minimal::assignable const,
test::minimal::assignable const,
test::minimal::hash<test::minimal::assignable>, test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>, test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<test::minimal::assignable> >; test::minimal::allocator<test::minimal::assignable> >;
template class boost::unordered_multiset< template class boost::unordered_multiset<test::minimal::assignable,
test::minimal::assignable,
test::minimal::hash<test::minimal::assignable>, test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>, test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<test::minimal::assignable> >; test::minimal::allocator<test::minimal::assignable> >;
@@ -47,60 +39,61 @@ UNORDERED_AUTO_TEST(test0)
test::minimal::assignable assignable(x); test::minimal::assignable assignable(x);
std::cout<<"Test unordered_set.\n"; std::cout << "Test unordered_set.\n";
boost::unordered_set<int> int_set; boost::unordered_set<int> int_set;
boost::unordered_set<int, boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
boost::hash<int>, std::equal_to<int>, test::minimal::cxx11_allocator<int> >
test::minimal::cxx11_allocator<int> int_set2;
> int_set2;
boost::unordered_set< boost::unordered_set<test::minimal::assignable,
test::minimal::assignable,
test::minimal::hash<test::minimal::assignable>, test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>, test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<test::minimal::assignable> > set; test::minimal::allocator<test::minimal::assignable> >
set;
container_test(int_set, 0); container_test(int_set, 0);
container_test(int_set2, 0); container_test(int_set2, 0);
container_test(set, assignable); container_test(set, assignable);
std::cout<<"Test unordered_multiset.\n"; std::cout << "Test unordered_multiset.\n";
boost::unordered_multiset<int> int_multiset; boost::unordered_multiset<int> int_multiset;
boost::unordered_multiset<int, boost::unordered_multiset<int, boost::hash<int>, std::equal_to<int>,
boost::hash<int>, std::equal_to<int>, test::minimal::cxx11_allocator<int> >
test::minimal::cxx11_allocator<int> int_multiset2;
> int_multiset2;
boost::unordered_multiset< boost::unordered_multiset<test::minimal::assignable,
test::minimal::assignable,
test::minimal::hash<test::minimal::assignable>, test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>, test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<test::minimal::assignable> > multiset; test::minimal::allocator<test::minimal::assignable> >
multiset;
container_test(int_multiset, 0); container_test(int_multiset, 0);
container_test(int_multiset2, 0); container_test(int_multiset2, 0);
container_test(multiset, assignable); container_test(multiset, assignable);
} }
UNORDERED_AUTO_TEST(equality_tests) { UNORDERED_AUTO_TEST(equality_tests)
{
typedef test::minimal::copy_constructible_equality_comparable value_type; typedef test::minimal::copy_constructible_equality_comparable value_type;
boost::unordered_set<int> int_set; boost::unordered_set<int> int_set;
boost::unordered_set<int, boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
boost::hash<int>, std::equal_to<int>, test::minimal::cxx11_allocator<int> >
test::minimal::cxx11_allocator<int> int_set2;
> int_set2;
boost::unordered_set< boost::unordered_set<
test::minimal::copy_constructible_equality_comparable, test::minimal::copy_constructible_equality_comparable,
test::minimal::hash<test::minimal::copy_constructible_equality_comparable>, test::minimal::hash<
test::minimal::equal_to<test::minimal::copy_constructible_equality_comparable>, test::minimal::copy_constructible_equality_comparable>,
test::minimal::allocator<value_type> > set; test::minimal::equal_to<
test::minimal::copy_constructible_equality_comparable>,
test::minimal::allocator<value_type> >
set;
equality_test(int_set); equality_test(int_set);
equality_test(int_set2); equality_test(int_set2);
@@ -108,16 +101,18 @@ UNORDERED_AUTO_TEST(equality_tests) {
boost::unordered_multiset<int> int_multiset; boost::unordered_multiset<int> int_multiset;
boost::unordered_multiset<int, boost::unordered_multiset<int, boost::hash<int>, std::equal_to<int>,
boost::hash<int>, std::equal_to<int>, test::minimal::cxx11_allocator<int> >
test::minimal::cxx11_allocator<int> int_multiset2;
> int_multiset2;
boost::unordered_multiset< boost::unordered_multiset<
test::minimal::copy_constructible_equality_comparable, test::minimal::copy_constructible_equality_comparable,
test::minimal::hash<test::minimal::copy_constructible_equality_comparable>, test::minimal::hash<
test::minimal::equal_to<test::minimal::copy_constructible_equality_comparable>, test::minimal::copy_constructible_equality_comparable>,
test::minimal::allocator<value_type> > multiset; test::minimal::equal_to<
test::minimal::copy_constructible_equality_comparable>,
test::minimal::allocator<value_type> >
multiset;
equality_test(int_multiset); equality_test(int_multiset);
equality_test(int_multiset2); equality_test(int_multiset2);
@@ -130,14 +125,13 @@ UNORDERED_AUTO_TEST(test1)
std::equal_to<int> equal_to; std::equal_to<int> equal_to;
int value = 0; int value = 0;
std::cout<<"Test unordered_set." << std::endl; std::cout << "Test unordered_set." << std::endl;
boost::unordered_set<int> set; boost::unordered_set<int> set;
boost::unordered_set<int, boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
boost::hash<int>, std::equal_to<int>, test::minimal::cxx11_allocator<int> >
test::minimal::cxx11_allocator<int> set2;
> set2;
unordered_unique_test(set, value); unordered_unique_test(set, value);
unordered_set_test(set, value); unordered_set_test(set, value);
@@ -147,14 +141,13 @@ UNORDERED_AUTO_TEST(test1)
unordered_set_test(set2, value); unordered_set_test(set2, value);
unordered_copyable_test(set2, value, value, hash, equal_to); unordered_copyable_test(set2, value, value, hash, equal_to);
std::cout<<"Test unordered_multiset." << std::endl; std::cout << "Test unordered_multiset." << std::endl;
boost::unordered_multiset<int> multiset; boost::unordered_multiset<int> multiset;
boost::unordered_multiset<int, boost::unordered_multiset<int, boost::hash<int>, std::equal_to<int>,
boost::hash<int>, std::equal_to<int>, test::minimal::cxx11_allocator<int> >
test::minimal::cxx11_allocator<int> multiset2;
> multiset2;
unordered_equivalent_test(multiset, value); unordered_equivalent_test(multiset, value);
unordered_set_test(multiset, value); unordered_set_test(multiset, value);
@@ -174,26 +167,26 @@ UNORDERED_AUTO_TEST(test2)
test::minimal::hash<test::minimal::assignable> hash(x); test::minimal::hash<test::minimal::assignable> hash(x);
test::minimal::equal_to<test::minimal::assignable> equal_to(x); test::minimal::equal_to<test::minimal::assignable> equal_to(x);
std::cout<<"Test unordered_set.\n"; std::cout << "Test unordered_set.\n";
boost::unordered_set< boost::unordered_set<test::minimal::assignable,
test::minimal::assignable,
test::minimal::hash<test::minimal::assignable>, test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>, test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<test::minimal::assignable> > set; test::minimal::allocator<test::minimal::assignable> >
set;
unordered_unique_test(set, assignable); unordered_unique_test(set, assignable);
unordered_set_test(set, assignable); unordered_set_test(set, assignable);
unordered_copyable_test(set, assignable, assignable, hash, equal_to); unordered_copyable_test(set, assignable, assignable, hash, equal_to);
unordered_set_member_test(set, assignable); unordered_set_member_test(set, assignable);
std::cout<<"Test unordered_multiset.\n"; std::cout << "Test unordered_multiset.\n";
boost::unordered_multiset< boost::unordered_multiset<test::minimal::assignable,
test::minimal::assignable,
test::minimal::hash<test::minimal::assignable>, test::minimal::hash<test::minimal::assignable>,
test::minimal::equal_to<test::minimal::assignable>, test::minimal::equal_to<test::minimal::assignable>,
test::minimal::allocator<test::minimal::assignable> > multiset; test::minimal::allocator<test::minimal::assignable> >
multiset;
unordered_equivalent_test(multiset, assignable); unordered_equivalent_test(multiset, assignable);
unordered_set_test(multiset, assignable); unordered_set_test(multiset, assignable);
@@ -209,27 +202,27 @@ UNORDERED_AUTO_TEST(movable1_tests)
test::minimal::hash<test::minimal::movable1> hash(x); test::minimal::hash<test::minimal::movable1> hash(x);
test::minimal::equal_to<test::minimal::movable1> equal_to(x); test::minimal::equal_to<test::minimal::movable1> equal_to(x);
std::cout<<"Test unordered_set.\n"; std::cout << "Test unordered_set.\n";
boost::unordered_set< boost::unordered_set<test::minimal::movable1,
test::minimal::movable1,
test::minimal::hash<test::minimal::movable1>, test::minimal::hash<test::minimal::movable1>,
test::minimal::equal_to<test::minimal::movable1>, test::minimal::equal_to<test::minimal::movable1>,
test::minimal::allocator<test::minimal::movable1> > set; test::minimal::allocator<test::minimal::movable1> >
set;
//unordered_unique_test(set, movable1); // unordered_unique_test(set, movable1);
unordered_set_test(set, movable1); unordered_set_test(set, movable1);
unordered_movable_test(set, movable1, movable1, hash, equal_to); unordered_movable_test(set, movable1, movable1, hash, equal_to);
std::cout<<"Test unordered_multiset.\n"; std::cout << "Test unordered_multiset.\n";
boost::unordered_multiset< boost::unordered_multiset<test::minimal::movable1,
test::minimal::movable1,
test::minimal::hash<test::minimal::movable1>, test::minimal::hash<test::minimal::movable1>,
test::minimal::equal_to<test::minimal::movable1>, test::minimal::equal_to<test::minimal::movable1>,
test::minimal::allocator<test::minimal::movable1> > multiset; test::minimal::allocator<test::minimal::movable1> >
multiset;
//unordered_equivalent_test(multiset, movable1); // unordered_equivalent_test(multiset, movable1);
unordered_set_test(multiset, movable1); unordered_set_test(multiset, movable1);
unordered_movable_test(multiset, movable1, movable1, hash, equal_to); unordered_movable_test(multiset, movable1, movable1, hash, equal_to);
} }
@@ -242,27 +235,27 @@ UNORDERED_AUTO_TEST(movable2_tests)
test::minimal::hash<test::minimal::movable2> hash(x); test::minimal::hash<test::minimal::movable2> hash(x);
test::minimal::equal_to<test::minimal::movable2> equal_to(x); test::minimal::equal_to<test::minimal::movable2> equal_to(x);
std::cout<<"Test unordered_set.\n"; std::cout << "Test unordered_set.\n";
boost::unordered_set< boost::unordered_set<test::minimal::movable2,
test::minimal::movable2,
test::minimal::hash<test::minimal::movable2>, test::minimal::hash<test::minimal::movable2>,
test::minimal::equal_to<test::minimal::movable2>, test::minimal::equal_to<test::minimal::movable2>,
test::minimal::allocator<test::minimal::movable2> > set; test::minimal::allocator<test::minimal::movable2> >
set;
//unordered_unique_test(set, movable2); // unordered_unique_test(set, movable2);
unordered_set_test(set, movable2); unordered_set_test(set, movable2);
unordered_movable_test(set, movable2, movable2, hash, equal_to); unordered_movable_test(set, movable2, movable2, hash, equal_to);
std::cout<<"Test unordered_multiset.\n"; std::cout << "Test unordered_multiset.\n";
boost::unordered_multiset< boost::unordered_multiset<test::minimal::movable2,
test::minimal::movable2,
test::minimal::hash<test::minimal::movable2>, test::minimal::hash<test::minimal::movable2>,
test::minimal::equal_to<test::minimal::movable2>, test::minimal::equal_to<test::minimal::movable2>,
test::minimal::allocator<test::minimal::movable2> > multiset; test::minimal::allocator<test::minimal::movable2> >
multiset;
//unordered_equivalent_test(multiset, movable2); // unordered_equivalent_test(multiset, movable2);
unordered_set_test(multiset, movable2); unordered_set_test(multiset, movable2);
unordered_movable_test(multiset, movable2, movable2, hash, equal_to); unordered_movable_test(multiset, movable2, movable2, hash, equal_to);
} }
@@ -275,21 +268,21 @@ UNORDERED_AUTO_TEST(destructible_tests)
test::minimal::hash<test::minimal::destructible> hash(x); test::minimal::hash<test::minimal::destructible> hash(x);
test::minimal::equal_to<test::minimal::destructible> equal_to(x); test::minimal::equal_to<test::minimal::destructible> equal_to(x);
std::cout<<"Test unordered_set.\n"; std::cout << "Test unordered_set.\n";
boost::unordered_set< boost::unordered_set<test::minimal::destructible,
test::minimal::destructible,
test::minimal::hash<test::minimal::destructible>, test::minimal::hash<test::minimal::destructible>,
test::minimal::equal_to<test::minimal::destructible> > set; test::minimal::equal_to<test::minimal::destructible> >
set;
unordered_destructible_test(set); unordered_destructible_test(set);
std::cout<<"Test unordered_multiset.\n"; std::cout << "Test unordered_multiset.\n";
boost::unordered_multiset< boost::unordered_multiset<test::minimal::destructible,
test::minimal::destructible,
test::minimal::hash<test::minimal::destructible>, test::minimal::hash<test::minimal::destructible>,
test::minimal::equal_to<test::minimal::destructible> > multiset; test::minimal::equal_to<test::minimal::destructible> >
multiset;
unordered_destructible_test(multiset); unordered_destructible_test(multiset);
} }

View File

@@ -5,9 +5,9 @@
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4100) // unreferenced formal parameter #pragma warning(disable : 4100) // unreferenced formal parameter
#pragma warning(disable:4610) // class can never be instantiated #pragma warning(disable : 4610) // class can never be instantiated
#pragma warning(disable:4510) // default constructor could not be generated #pragma warning(disable : 4510) // default constructor could not be generated
#endif #endif
#include <boost/concept_check.hpp> #include <boost/concept_check.hpp>
@@ -16,13 +16,13 @@
#pragma warning(pop) #pragma warning(pop)
#endif #endif
#include <boost/static_assert.hpp> #include "../helpers/check_return_type.hpp"
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/iterator/iterator_traits.hpp> #include <boost/iterator/iterator_traits.hpp>
#include <boost/limits.hpp> #include <boost/limits.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/swap.hpp> #include <boost/utility/swap.hpp>
#include "../helpers/check_return_type.hpp"
typedef long double comparison_type; typedef long double comparison_type;
@@ -30,23 +30,21 @@ template <class T> void sink(T const&) {}
template <class T> T rvalue(T const& v) { return v; } template <class T> T rvalue(T const& v) { return v; }
template <class T> T rvalue_default() { return T(); } template <class T> T rvalue_default() { return T(); }
template <class X, class T> template <class X, class T> void container_test(X& r, T const&)
void container_test(X& r, T const&)
{ {
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator; typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator; typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator;
typedef BOOST_DEDUCED_TYPENAME X::difference_type difference_type; typedef BOOST_DEDUCED_TYPENAME X::difference_type difference_type;
typedef BOOST_DEDUCED_TYPENAME X::size_type size_type; typedef BOOST_DEDUCED_TYPENAME X::size_type size_type;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<iterator>::type
boost::iterator_value<iterator>::type iterator_value_type; iterator_value_type;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<const_iterator>::type
boost::iterator_value<const_iterator>::type const_iterator_value_type; const_iterator_value_type;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<iterator>::type
boost::iterator_difference<iterator>::type iterator_difference_type; iterator_difference_type;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<
boost::iterator_difference<const_iterator>::type const_iterator>::type const_iterator_difference_type;
const_iterator_difference_type;
typedef BOOST_DEDUCED_TYPENAME X::value_type value_type; typedef BOOST_DEDUCED_TYPENAME X::value_type value_type;
typedef BOOST_DEDUCED_TYPENAME X::reference reference; typedef BOOST_DEDUCED_TYPENAME X::reference reference;
@@ -66,7 +64,8 @@ void container_test(X& r, T const&)
boost::function_requires<boost::InputIteratorConcept<iterator> >(); boost::function_requires<boost::InputIteratorConcept<iterator> >();
BOOST_STATIC_ASSERT((boost::is_same<T, iterator_value_type>::value)); BOOST_STATIC_ASSERT((boost::is_same<T, iterator_value_type>::value));
BOOST_STATIC_ASSERT((boost::is_convertible<iterator, const_iterator>::value)); BOOST_STATIC_ASSERT(
(boost::is_convertible<iterator, const_iterator>::value));
// const_iterator // const_iterator
@@ -77,8 +76,8 @@ void container_test(X& r, T const&)
BOOST_STATIC_ASSERT(std::numeric_limits<difference_type>::is_signed); BOOST_STATIC_ASSERT(std::numeric_limits<difference_type>::is_signed);
BOOST_STATIC_ASSERT(std::numeric_limits<difference_type>::is_integer); BOOST_STATIC_ASSERT(std::numeric_limits<difference_type>::is_integer);
BOOST_STATIC_ASSERT((boost::is_same<difference_type, BOOST_STATIC_ASSERT(
iterator_difference_type>::value)); (boost::is_same<difference_type, iterator_difference_type>::value));
BOOST_STATIC_ASSERT((boost::is_same<difference_type, BOOST_STATIC_ASSERT((boost::is_same<difference_type,
const_iterator_difference_type>::value)); const_iterator_difference_type>::value));
@@ -89,21 +88,19 @@ void container_test(X& r, T const&)
// size_type can represent any non-negative value type of difference_type // size_type can represent any non-negative value type of difference_type
// I'm not sure about either of these tests... // I'm not sure about either of these tests...
size_type max_diff = static_cast<size_type>( size_type max_diff =
(std::numeric_limits<difference_type>::max)()); static_cast<size_type>((std::numeric_limits<difference_type>::max)());
difference_type converted_diff(static_cast<difference_type>(max_diff)); difference_type converted_diff(static_cast<difference_type>(max_diff));
BOOST_TEST((std::numeric_limits<difference_type>::max)() BOOST_TEST((std::numeric_limits<difference_type>::max)() == converted_diff);
== converted_diff);
BOOST_TEST( BOOST_TEST(
static_cast<comparison_type>( static_cast<comparison_type>((std::numeric_limits<size_type>::max)()) >
(std::numeric_limits<size_type>::max)()) >
static_cast<comparison_type>( static_cast<comparison_type>(
(std::numeric_limits<difference_type>::max)())); (std::numeric_limits<difference_type>::max)()));
// Constructors // Constructors
// I don't test the runtime post-conditions here. // I don't test the runtime post-conditions here.
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
// It isn't specified in the container requirements that the no argument // It isn't specified in the container requirements that the no argument
@@ -117,7 +114,7 @@ void container_test(X& r, T const&)
BOOST_TEST(u.size() == 0); BOOST_TEST(u.size() == 0);
BOOST_TEST(X().size() == 0); BOOST_TEST(X().size() == 0);
X a,b; X a, b;
X a_const; X a_const;
sink(X(a)); sink(X(a));
@@ -155,8 +152,7 @@ void container_test(X& r, T const&)
sink(c3); sink(c3);
} }
template <class X> template <class X> void unordered_destructible_test(X&)
void unordered_destructible_test(X&)
{ {
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator; typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator; typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator;
@@ -167,9 +163,9 @@ void unordered_destructible_test(X&)
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
X x2(rvalue_default<X>()); X x2(rvalue_default<X>());
X x3 = rvalue_default<X>(); X x3 = rvalue_default<X>();
// This can only be done if propagate_on_container_move_assignment::value // This can only be done if propagate_on_container_move_assignment::value
// is true. // is true.
// x2 = rvalue_default<X>(); // x2 = rvalue_default<X>();
#endif #endif
X* ptr = new X(); X* ptr = new X();
@@ -177,7 +173,7 @@ void unordered_destructible_test(X&)
(&a1)->~X(); (&a1)->~X();
::operator delete((void*)(&a1)); ::operator delete((void*)(&a1));
X a,b; X a, b;
X const a_const; X const a_const;
test::check_return_type<iterator>::equals(a.begin()); test::check_return_type<iterator>::equals(a.begin());
test::check_return_type<const_iterator>::equals(a_const.begin()); test::check_return_type<const_iterator>::equals(a_const.begin());
@@ -201,8 +197,7 @@ void unordered_destructible_test(X&)
test::check_return_type<allocator_type>::equals(a_const.get_allocator()); test::check_return_type<allocator_type>::equals(a_const.get_allocator());
} }
template <class X, class Key> template <class X, class Key> void unordered_set_test(X&, Key const&)
void unordered_set_test(X&, Key const&)
{ {
typedef BOOST_DEDUCED_TYPENAME X::value_type value_type; typedef BOOST_DEDUCED_TYPENAME X::value_type value_type;
typedef BOOST_DEDUCED_TYPENAME X::key_type key_type; typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
@@ -215,21 +210,23 @@ void unordered_set_test(X&, Key const&)
typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator; typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator;
typedef BOOST_DEDUCED_TYPENAME X::local_iterator local_iterator; typedef BOOST_DEDUCED_TYPENAME X::local_iterator local_iterator;
typedef BOOST_DEDUCED_TYPENAME X::const_local_iterator const_local_iterator; typedef BOOST_DEDUCED_TYPENAME X::const_local_iterator const_local_iterator;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<iterator>::type
boost::iterator_pointer<iterator>::type iterator_pointer; iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<const_iterator>::type
boost::iterator_pointer<const_iterator>::type
const_iterator_pointer; const_iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<local_iterator>::type
boost::iterator_pointer<local_iterator>::type local_iterator_pointer; local_iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<
boost::iterator_pointer<const_local_iterator>::type const_local_iterator>::type const_local_iterator_pointer;
const_local_iterator_pointer;
BOOST_STATIC_ASSERT((boost::is_same<value_type const*, iterator_pointer>::value)); BOOST_STATIC_ASSERT(
BOOST_STATIC_ASSERT((boost::is_same<value_type const*, const_iterator_pointer>::value)); (boost::is_same<value_type const*, iterator_pointer>::value));
BOOST_STATIC_ASSERT((boost::is_same<value_type const*, local_iterator_pointer>::value)); BOOST_STATIC_ASSERT(
BOOST_STATIC_ASSERT((boost::is_same<value_type const*, const_local_iterator_pointer>::value)); (boost::is_same<value_type const*, const_iterator_pointer>::value));
BOOST_STATIC_ASSERT(
(boost::is_same<value_type const*, local_iterator_pointer>::value));
BOOST_STATIC_ASSERT((boost::is_same<value_type const*,
const_local_iterator_pointer>::value));
} }
template <class X, class Key, class T> template <class X, class Key, class T>
@@ -238,8 +235,8 @@ void unordered_map_test(X& r, Key const& k, T const& v)
typedef BOOST_DEDUCED_TYPENAME X::value_type value_type; typedef BOOST_DEDUCED_TYPENAME X::value_type value_type;
typedef BOOST_DEDUCED_TYPENAME X::key_type key_type; typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
BOOST_STATIC_ASSERT(( BOOST_STATIC_ASSERT(
boost::is_same<value_type, std::pair<key_type const, T> >::value)); (boost::is_same<value_type, std::pair<key_type const, T> >::value));
// iterator pointer / const_pointer_type // iterator pointer / const_pointer_type
@@ -247,21 +244,22 @@ void unordered_map_test(X& r, Key const& k, T const& v)
typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator; typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator;
typedef BOOST_DEDUCED_TYPENAME X::local_iterator local_iterator; typedef BOOST_DEDUCED_TYPENAME X::local_iterator local_iterator;
typedef BOOST_DEDUCED_TYPENAME X::const_local_iterator const_local_iterator; typedef BOOST_DEDUCED_TYPENAME X::const_local_iterator const_local_iterator;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<iterator>::type
boost::iterator_pointer<iterator>::type iterator_pointer; iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<const_iterator>::type
boost::iterator_pointer<const_iterator>::type
const_iterator_pointer; const_iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<local_iterator>::type
boost::iterator_pointer<local_iterator>::type local_iterator_pointer; local_iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<
boost::iterator_pointer<const_local_iterator>::type const_local_iterator>::type const_local_iterator_pointer;
const_local_iterator_pointer;
BOOST_STATIC_ASSERT((boost::is_same<value_type*, iterator_pointer>::value)); BOOST_STATIC_ASSERT((boost::is_same<value_type*, iterator_pointer>::value));
BOOST_STATIC_ASSERT((boost::is_same<value_type const*, const_iterator_pointer>::value)); BOOST_STATIC_ASSERT(
BOOST_STATIC_ASSERT((boost::is_same<value_type*, local_iterator_pointer>::value)); (boost::is_same<value_type const*, const_iterator_pointer>::value));
BOOST_STATIC_ASSERT((boost::is_same<value_type const*, const_local_iterator_pointer>::value)); BOOST_STATIC_ASSERT(
(boost::is_same<value_type*, local_iterator_pointer>::value));
BOOST_STATIC_ASSERT((boost::is_same<value_type const*,
const_local_iterator_pointer>::value));
// Calling functions // Calling functions
@@ -274,12 +272,11 @@ void unordered_map_test(X& r, Key const& k, T const& v)
r.emplace(k_lvalue, v_lvalue); r.emplace(k_lvalue, v_lvalue);
r.emplace(rvalue(k), rvalue(v)); r.emplace(rvalue(k), rvalue(v));
r.emplace(boost::unordered::piecewise_construct, r.emplace(boost::unordered::piecewise_construct, boost::make_tuple(k),
boost::make_tuple(k), boost::make_tuple(v)); boost::make_tuple(v));
} }
template <class X> template <class X> void equality_test(X& r)
void equality_test(X& r)
{ {
X const a = r, b = r; X const a = r, b = r;
@@ -289,16 +286,14 @@ void equality_test(X& r)
test::check_return_type<bool>::equals(boost::operator!=(a, b)); test::check_return_type<bool>::equals(boost::operator!=(a, b));
} }
template <class X, class T> template <class X, class T> void unordered_unique_test(X& r, T const& t)
void unordered_unique_test(X& r, T const& t)
{ {
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator; typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
test::check_return_type<std::pair<iterator, bool> >::equals(r.insert(t)); test::check_return_type<std::pair<iterator, bool> >::equals(r.insert(t));
test::check_return_type<std::pair<iterator, bool> >::equals(r.emplace(t)); test::check_return_type<std::pair<iterator, bool> >::equals(r.emplace(t));
} }
template <class X, class T> template <class X, class T> void unordered_equivalent_test(X& r, T const& t)
void unordered_equivalent_test(X& r, T const& t)
{ {
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator; typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
test::check_return_type<iterator>::equals(r.insert(t)); test::check_return_type<iterator>::equals(r.insert(t));
@@ -334,61 +329,45 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
typedef BOOST_DEDUCED_TYPENAME X::const_local_iterator const_local_iterator; typedef BOOST_DEDUCED_TYPENAME X::const_local_iterator const_local_iterator;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME
boost::BOOST_ITERATOR_CATEGORY<iterator>::type boost::BOOST_ITERATOR_CATEGORY<iterator>::type iterator_category;
iterator_category; typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<iterator>::type
typedef BOOST_DEDUCED_TYPENAME
boost::iterator_difference<iterator>::type
iterator_difference; iterator_difference;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<iterator>::type
boost::iterator_pointer<iterator>::type
iterator_pointer; iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<iterator>::type
boost::iterator_reference<iterator>::type
iterator_reference; iterator_reference;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::BOOST_ITERATOR_CATEGORY<
boost::BOOST_ITERATOR_CATEGORY<local_iterator>::type local_iterator>::type local_iterator_category;
local_iterator_category; typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<
typedef BOOST_DEDUCED_TYPENAME local_iterator>::type local_iterator_difference;
boost::iterator_difference<local_iterator>::type typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<local_iterator>::type
local_iterator_difference;
typedef BOOST_DEDUCED_TYPENAME
boost::iterator_pointer<local_iterator>::type
local_iterator_pointer; local_iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<
boost::iterator_reference<local_iterator>::type local_iterator>::type local_iterator_reference;
local_iterator_reference;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::BOOST_ITERATOR_CATEGORY<
boost::BOOST_ITERATOR_CATEGORY<const_iterator>::type const_iterator>::type const_iterator_category;
const_iterator_category; typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<
typedef BOOST_DEDUCED_TYPENAME const_iterator>::type const_iterator_difference;
boost::iterator_difference<const_iterator>::type typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<const_iterator>::type
const_iterator_difference;
typedef BOOST_DEDUCED_TYPENAME
boost::iterator_pointer<const_iterator>::type
const_iterator_pointer; const_iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<
boost::iterator_reference<const_iterator>::type const_iterator>::type const_iterator_reference;
const_iterator_reference;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::BOOST_ITERATOR_CATEGORY<
boost::BOOST_ITERATOR_CATEGORY<const_local_iterator>::type const_local_iterator>::type const_local_iterator_category;
const_local_iterator_category; typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<
typedef BOOST_DEDUCED_TYPENAME const_local_iterator>::type const_local_iterator_difference;
boost::iterator_difference<const_local_iterator>::type typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<
const_local_iterator_difference; const_local_iterator>::type const_local_iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<
boost::iterator_pointer<const_local_iterator>::type const_local_iterator>::type const_local_iterator_reference;
const_local_iterator_pointer;
typedef BOOST_DEDUCED_TYPENAME
boost::iterator_reference<const_local_iterator>::type
const_local_iterator_reference;
typedef BOOST_DEDUCED_TYPENAME X::allocator_type allocator_type; typedef BOOST_DEDUCED_TYPENAME X::allocator_type allocator_type;
BOOST_STATIC_ASSERT((boost::is_same<Key, key_type>::value)); BOOST_STATIC_ASSERT((boost::is_same<Key, key_type>::value));
//boost::function_requires<boost::CopyConstructibleConcept<key_type> >(); // boost::function_requires<boost::CopyConstructibleConcept<key_type> >();
//boost::function_requires<boost::AssignableConcept<key_type> >(); // boost::function_requires<boost::AssignableConcept<key_type> >();
BOOST_STATIC_ASSERT((boost::is_same<Hash, hasher>::value)); BOOST_STATIC_ASSERT((boost::is_same<Hash, hasher>::value));
test::check_return_type<std::size_t>::equals(hf(k)); test::check_return_type<std::size_t>::equals(hf(k));
@@ -397,14 +376,14 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
test::check_return_type<bool>::convertible(eq(k, k)); test::check_return_type<bool>::convertible(eq(k, k));
boost::function_requires<boost::InputIteratorConcept<local_iterator> >(); boost::function_requires<boost::InputIteratorConcept<local_iterator> >();
BOOST_STATIC_ASSERT((boost::is_same<local_iterator_category, BOOST_STATIC_ASSERT(
iterator_category>::value)); (boost::is_same<local_iterator_category, iterator_category>::value));
BOOST_STATIC_ASSERT((boost::is_same<local_iterator_difference, BOOST_STATIC_ASSERT((
iterator_difference>::value)); boost::is_same<local_iterator_difference, iterator_difference>::value));
BOOST_STATIC_ASSERT((boost::is_same<local_iterator_pointer, BOOST_STATIC_ASSERT(
iterator_pointer>::value)); (boost::is_same<local_iterator_pointer, iterator_pointer>::value));
BOOST_STATIC_ASSERT((boost::is_same<local_iterator_reference, BOOST_STATIC_ASSERT(
iterator_reference>::value)); (boost::is_same<local_iterator_reference, iterator_reference>::value));
boost::function_requires< boost::function_requires<
boost::InputIteratorConcept<const_local_iterator> >(); boost::InputIteratorConcept<const_local_iterator> >();
@@ -476,7 +455,7 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
test::check_return_type<float>::equals(b.load_factor()); test::check_return_type<float>::equals(b.load_factor());
test::check_return_type<float>::equals(b.max_load_factor()); test::check_return_type<float>::equals(b.max_load_factor());
a.max_load_factor((float) 2.0); a.max_load_factor((float)2.0);
a.rehash(100); a.rehash(100);
// Avoid unused variable warnings: // Avoid unused variable warnings:
@@ -525,10 +504,10 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
X(i, j, 10, m); X(i, j, 10, m);
X a7a(i, j, 10, m); X a7a(i, j, 10, m);
// Not specified for some reason (maybe ambiguity with another constructor?) // Not specified for some reason (maybe ambiguity with another constructor?)
//X(i, j, m); // X(i, j, m);
//X a8a(i, j, m); // X a8a(i, j, m);
//sink(a8a); // sink(a8a);
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
std::size_t min_buckets = 10; std::size_t min_buckets = 10;
@@ -536,7 +515,7 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
X({t}, min_buckets); X({t}, min_buckets);
X({t}, min_buckets, hf); X({t}, min_buckets, hf);
X({t}, min_buckets, hf, eq); X({t}, min_buckets, hf, eq);
//X({t}, m); // X({t}, m);
X({t}, min_buckets, m); X({t}, min_buckets, m);
X({t}, min_buckets, hf, m); X({t}, min_buckets, hf, m);
X({t}, min_buckets, hf, eq, m); X({t}, min_buckets, hf, eq, m);
@@ -559,12 +538,12 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
std::initializer_list<T> list = {t}; std::initializer_list<T> list = {t};
a.insert(list); a.insert(list);
a.insert({t,t,t}); a.insert({t, t, t});
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1900) #if !BOOST_WORKAROUND(BOOST_MSVC, < 1900)
a.insert({}); a.insert({});
a.insert({t}); a.insert({t});
a.insert({t,t}); a.insert({t, t});
#endif #endif
#endif #endif
@@ -628,9 +607,9 @@ void unordered_movable_test(X& x, Key& k, T& /* t */, Hash& hf, Pred& eq)
X a7a(i, j, 10, m); X a7a(i, j, 10, m);
// Not specified for some reason (maybe ambiguity with another constructor?) // Not specified for some reason (maybe ambiguity with another constructor?)
//X(i, j, m); // X(i, j, m);
//X a8a(i, j, m); // X a8a(i, j, m);
//sink(a8a); // sink(a8a);
const_iterator q = a.cbegin(); const_iterator q = a.cbegin();
@@ -646,8 +625,7 @@ void unordered_movable_test(X& x, Key& k, T& /* t */, Hash& hf, Pred& eq)
test::check_return_type<iterator>::equals( test::check_return_type<iterator>::equals(
a.emplace_hint(q, boost::move(v3))); a.emplace_hint(q, boost::move(v3)));
T v4(v); T v4(v);
test::check_return_type<iterator>::equals( test::check_return_type<iterator>::equals(a.insert(q, boost::move(v4)));
a.insert(q, boost::move(v4)));
a.insert(i, j); a.insert(i, j);
@@ -670,8 +648,7 @@ void unordered_movable_test(X& x, Key& k, T& /* t */, Hash& hf, Pred& eq)
sink(a10); sink(a10);
} }
template <class X, class T> template <class X, class T> void unordered_set_member_test(X& x, T& t)
void unordered_set_member_test(X& x, T& t)
{ {
X x1(x); X x1(x);
x1.insert(t); x1.insert(t);
@@ -679,8 +656,7 @@ void unordered_set_member_test(X& x, T& t)
x1.cbegin()->dummy_member(); x1.cbegin()->dummy_member();
} }
template <class X, class T> template <class X, class T> void unordered_map_member_test(X& x, T& t)
void unordered_map_member_test(X& x, T& t)
{ {
X x1(x); X x1(x);
x1.insert(t); x1.insert(t);

View File

@@ -22,14 +22,13 @@ namespace constructor_tests {
test::seed_t initialize_seed(356730); test::seed_t initialize_seed(356730);
template <class T> template <class T> void constructor_tests1(T*, test::random_generator generator)
void constructor_tests1(T*, test::random_generator generator)
{ {
BOOST_DEDUCED_TYPENAME T::hasher hf; BOOST_DEDUCED_TYPENAME T::hasher hf;
BOOST_DEDUCED_TYPENAME T::key_equal eq; BOOST_DEDUCED_TYPENAME T::key_equal eq;
BOOST_DEDUCED_TYPENAME T::allocator_type al; BOOST_DEDUCED_TYPENAME T::allocator_type al;
std::cerr<<"Construct 1\n"; std::cerr << "Construct 1\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -41,7 +40,7 @@ void constructor_tests1(T*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"Construct 2\n"; std::cerr << "Construct 2\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -54,7 +53,7 @@ void constructor_tests1(T*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"Construct 3\n"; std::cerr << "Construct 3\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -67,7 +66,7 @@ void constructor_tests1(T*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"Construct 4\n"; std::cerr << "Construct 4\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -79,7 +78,7 @@ void constructor_tests1(T*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"Construct 5\n"; std::cerr << "Construct 5\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -93,7 +92,7 @@ void constructor_tests1(T*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"Construct 6\n"; std::cerr << "Construct 6\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -107,7 +106,7 @@ void constructor_tests1(T*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"Construct 7\n"; std::cerr << "Construct 7\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -121,7 +120,7 @@ void constructor_tests1(T*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"Construct 8\n"; std::cerr << "Construct 8\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -134,7 +133,7 @@ void constructor_tests1(T*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"Construct 9\n"; std::cerr << "Construct 9\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -146,7 +145,7 @@ void constructor_tests1(T*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"Construct 10\n"; std::cerr << "Construct 10\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -160,7 +159,7 @@ void constructor_tests1(T*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"Construct 11\n"; std::cerr << "Construct 11\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -186,7 +185,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
BOOST_DEDUCED_TYPENAME T::allocator_type al1(1); BOOST_DEDUCED_TYPENAME T::allocator_type al1(1);
BOOST_DEDUCED_TYPENAME T::allocator_type al2(2); BOOST_DEDUCED_TYPENAME T::allocator_type al2(2);
std::cerr<<"Construct 1\n"; std::cerr << "Construct 1\n";
{ {
test::check_instances check_; test::check_instances check_;
T x(10000, hf1, eq1); T x(10000, hf1, eq1);
@@ -197,7 +196,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"Construct 2\n"; std::cerr << "Construct 2\n";
{ {
test::check_instances check_; test::check_instances check_;
T x(100, hf1); T x(100, hf1);
@@ -209,7 +208,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"Construct 3\n"; std::cerr << "Construct 3\n";
{ {
test::check_instances check_; test::check_instances check_;
test::random_values<T> v(100, generator); test::random_values<T> v(100, generator);
@@ -221,7 +220,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"Construct 4\n"; std::cerr << "Construct 4\n";
{ {
test::check_instances check_; test::check_instances check_;
test::random_values<T> v(5, generator); test::random_values<T> v(5, generator);
@@ -234,8 +233,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr << "Construct 5\n";
std::cerr<<"Construct 5\n";
{ {
test::check_instances check_; test::check_instances check_;
test::random_values<T> v(100, generator); test::random_values<T> v(100, generator);
@@ -247,7 +245,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
test::check_equivalent_keys(y); test::check_equivalent_keys(y);
} }
std::cerr<<"Construct 6\n"; std::cerr << "Construct 6\n";
{ {
test::check_instances check_; test::check_instances check_;
test::random_values<T> v(100, generator); test::random_values<T> v(100, generator);
@@ -259,7 +257,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
test::check_equivalent_keys(y); test::check_equivalent_keys(y);
} }
std::cerr<<"Construct 7\n"; std::cerr << "Construct 7\n";
{ {
test::check_instances check_; test::check_instances check_;
test::random_values<T> v(100, generator); test::random_values<T> v(100, generator);
@@ -271,39 +269,40 @@ void constructor_tests2(T*, test::random_generator const& generator)
test::check_equivalent_keys(y); test::check_equivalent_keys(y);
} }
std::cerr<<"Construct 8 - from input iterator\n"; std::cerr << "Construct 8 - from input iterator\n";
{ {
test::check_instances check_; test::check_instances check_;
test::random_values<T> v(100, generator); test::random_values<T> v(100, generator);
BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
v_begin = v.begin(), v_end = v.end(); v_begin = v.begin(),
T x(test::input_iterator(v_begin), v_end = v.end();
test::input_iterator(v_end), 0, hf1, eq1); T x(test::input_iterator(v_begin), test::input_iterator(v_end), 0, hf1,
BOOST_DEDUCED_TYPENAME T::const_iterator eq1);
x_begin = x.begin(), x_end = x.end(); BOOST_DEDUCED_TYPENAME T::const_iterator x_begin = x.begin(),
T y(test::input_iterator(x_begin), x_end = x.end();
test::input_iterator(x_end), 0, hf2, eq2); T y(test::input_iterator(x_begin), test::input_iterator(x_end), 0, hf2,
eq2);
test::check_container(x, v); test::check_container(x, v);
test::check_container(y, x); test::check_container(y, x);
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
test::check_equivalent_keys(y); test::check_equivalent_keys(y);
} }
std::cerr<<"Construct 8.5 - from copy iterator\n"; std::cerr << "Construct 8.5 - from copy iterator\n";
{ {
test::check_instances check_; test::check_instances check_;
test::random_values<T> v(100, generator); test::random_values<T> v(100, generator);
T x(test::copy_iterator(v.begin()), T x(test::copy_iterator(v.begin()), test::copy_iterator(v.end()), 0,
test::copy_iterator(v.end()), 0, hf1, eq1); hf1, eq1);
T y(test::copy_iterator(x.begin()), T y(test::copy_iterator(x.begin()), test::copy_iterator(x.end()), 0,
test::copy_iterator(x.end()), 0, hf2, eq2); hf2, eq2);
test::check_container(x, v); test::check_container(x, v);
test::check_container(y, x); test::check_container(y, x);
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
test::check_equivalent_keys(y); test::check_equivalent_keys(y);
} }
std::cerr<<"Construct 9\n"; std::cerr << "Construct 9\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -321,7 +320,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
std::initializer_list<BOOST_DEDUCED_TYPENAME T::value_type> list; std::initializer_list<BOOST_DEDUCED_TYPENAME T::value_type> list;
std::cerr<<"Initializer list construct 1\n"; std::cerr << "Initializer list construct 1\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -332,7 +331,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
BOOST_TEST(test::equivalent(x.get_allocator(), al)); BOOST_TEST(test::equivalent(x.get_allocator(), al));
} }
std::cerr<<"Initializer list construct 2\n"; std::cerr << "Initializer list construct 2\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -344,7 +343,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
BOOST_TEST(test::equivalent(x.get_allocator(), al)); BOOST_TEST(test::equivalent(x.get_allocator(), al));
} }
std::cerr<<"Initializer list construct 3\n"; std::cerr << "Initializer list construct 3\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -356,7 +355,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
BOOST_TEST(test::equivalent(x.get_allocator(), al)); BOOST_TEST(test::equivalent(x.get_allocator(), al));
} }
std::cerr<<"Initializer list construct 4\n"; std::cerr << "Initializer list construct 4\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -368,7 +367,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
BOOST_TEST(test::equivalent(x.get_allocator(), al)); BOOST_TEST(test::equivalent(x.get_allocator(), al));
} }
std::cerr<<"Initializer list construct 5\n"; std::cerr << "Initializer list construct 5\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -385,14 +384,11 @@ void constructor_tests2(T*, test::random_generator const& generator)
template <class T> template <class T>
void map_constructor_test(T*, test::random_generator const& generator) void map_constructor_test(T*, test::random_generator const& generator)
{ {
std::cerr<<"map_constructor_test\n"; std::cerr << "map_constructor_test\n";
typedef test::list< typedef test::list<std::pair<BOOST_DEDUCED_TYPENAME T::key_type,
std::pair< BOOST_DEDUCED_TYPENAME T::mapped_type> >
BOOST_DEDUCED_TYPENAME T::key_type, list;
BOOST_DEDUCED_TYPENAME T::mapped_type
>
> list;
test::random_values<T> v(1000, generator); test::random_values<T> v(1000, generator);
list l(v.begin(), v.end()); list l(v.begin(), v.end());
T x(l.begin(), l.end()); T x(l.begin(), l.end());
@@ -401,46 +397,39 @@ void map_constructor_test(T*, test::random_generator const& generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
std::allocator<test::object> >* test_map_std_alloc; std::allocator<test::object> >* test_map_std_alloc;
boost::unordered_set<test::object, boost::unordered_set<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator1<test::object> >* test_set; test::allocator1<test::object> >* test_set;
boost::unordered_multiset<test::object, boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator2<test::object> >* test_multiset; test::allocator2<test::object> >* test_multiset;
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator2<test::object> >* test_map; test::allocator2<test::object> >* test_map;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to, test::allocator1<test::object> >* test_multimap;
test::allocator1<test::object> >* test_multimap;
using test::default_generator; using test::default_generator;
using test::generate_collisions; using test::generate_collisions;
using test::limited_range; using test::limited_range;
UNORDERED_TEST(constructor_tests1, UNORDERED_TEST(constructor_tests1,
((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap)) ((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
UNORDERED_TEST(constructor_tests2, UNORDERED_TEST(constructor_tests2,
((test_set)(test_multiset)(test_map)(test_multimap)) ((test_set)(test_multiset)(test_map)(test_multimap))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
UNORDERED_TEST(map_constructor_test, UNORDERED_TEST(map_constructor_test,
((test_map_std_alloc)(test_map)(test_multimap)) ((test_map_std_alloc)(test_map)(test_multimap))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
UNORDERED_AUTO_TEST(test_default_initializer_list) { UNORDERED_AUTO_TEST(test_default_initializer_list)
std::cerr<<"Initializer List Tests\n"; {
std::cerr << "Initializer List Tests\n";
std::initializer_list<int> init; std::initializer_list<int> init;
boost::unordered_set<int> x1 = init; boost::unordered_set<int> x1 = init;
BOOST_TEST(x1.empty()); BOOST_TEST(x1.empty());
@@ -450,15 +439,15 @@ UNORDERED_AUTO_TEST(test_default_initializer_list) {
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
UNORDERED_AUTO_TEST(test_initializer_list) { UNORDERED_AUTO_TEST(test_initializer_list)
std::cerr<<"Initializer List Tests\n"; {
boost::unordered_set<int> x1 = { 2, 10, 45, -5 }; std::cerr << "Initializer List Tests\n";
boost::unordered_set<int> x1 = {2, 10, 45, -5};
BOOST_TEST(x1.find(10) != x1.end()); BOOST_TEST(x1.find(10) != x1.end());
BOOST_TEST(x1.find(46) == x1.end()); BOOST_TEST(x1.find(46) == x1.end());
} }
#endif #endif
} }
RUN_TESTS() RUN_TESTS()

View File

@@ -20,8 +20,7 @@
test::seed_t initialize_seed(9063); test::seed_t initialize_seed(9063);
namespace copy_tests namespace copy_tests {
{
template <class T> template <class T>
void copy_construct_tests1(T*, test::random_generator const& generator) void copy_construct_tests1(T*, test::random_generator const& generator)
@@ -151,73 +150,60 @@ void copy_construct_tests2(T*, test::random_generator const& generator)
} }
} }
boost::unordered_set<test::object, boost::unordered_set<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator1<test::object> >* test_set; test::allocator1<test::object> >* test_set;
boost::unordered_multiset<test::object, boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator2<test::object> >* test_multiset; test::allocator2<test::object> >* test_multiset;
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator1<test::object> >* test_map; test::allocator1<test::object> >* test_map;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to, test::allocator2<test::object> >* test_multimap;
test::allocator2<test::object> >* test_multimap;
boost::unordered_set<test::object, boost::unordered_set<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::select_copy> >* test::cxx11_allocator<test::object, test::select_copy> >*
test_set_select_copy; test_set_select_copy;
boost::unordered_multiset<test::object, boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::select_copy> >* test::cxx11_allocator<test::object, test::select_copy> >*
test_multiset_select_copy; test_multiset_select_copy;
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::select_copy> >* test::cxx11_allocator<test::object, test::select_copy> >*
test_map_select_copy; test_map_select_copy;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to, test::cxx11_allocator<test::object, test::select_copy> >*
test::cxx11_allocator<test::object, test::select_copy> >*
test_multimap_select_copy; test_multimap_select_copy;
boost::unordered_set<test::object, boost::unordered_set<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::no_select_copy> >* test::cxx11_allocator<test::object, test::no_select_copy> >*
test_set_no_select_copy; test_set_no_select_copy;
boost::unordered_multiset<test::object, boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::no_select_copy> >* test::cxx11_allocator<test::object, test::no_select_copy> >*
test_multiset_no_select_copy; test_multiset_no_select_copy;
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::no_select_copy> >* test::cxx11_allocator<test::object, test::no_select_copy> >*
test_map_no_select_copy; test_map_no_select_copy;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to, test::cxx11_allocator<test::object, test::no_select_copy> >*
test::cxx11_allocator<test::object, test::no_select_copy> >*
test_multimap_no_select_copy; test_multimap_no_select_copy;
using test::default_generator; using test::default_generator;
using test::generate_collisions; using test::generate_collisions;
using test::limited_range; using test::limited_range;
UNORDERED_TEST(copy_construct_tests1, ( UNORDERED_TEST(copy_construct_tests1,
(test_set)(test_multiset)(test_map)(test_multimap) ((test_set)(test_multiset)(test_map)(test_multimap)(test_set_select_copy)(
(test_set_select_copy)(test_multiset_select_copy)(test_map_select_copy)(test_multimap_select_copy) test_multiset_select_copy)(test_map_select_copy)(
(test_set_no_select_copy)(test_multiset_no_select_copy)(test_map_no_select_copy)(test_multimap_no_select_copy) test_multimap_select_copy)(test_set_no_select_copy)(
) test_multiset_no_select_copy)(test_map_no_select_copy)(
((default_generator)(generate_collisions)(limited_range)) test_multimap_no_select_copy))(
) (default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST(copy_construct_tests2, (
(test_set)(test_multiset)(test_map)(test_multimap)
(test_set_select_copy)(test_multiset_select_copy)(test_map_select_copy)(test_multimap_select_copy)
(test_set_no_select_copy)(test_multiset_no_select_copy)(test_map_no_select_copy)(test_multimap_no_select_copy)
)
((default_generator)(generate_collisions)(limited_range))
)
UNORDERED_TEST(copy_construct_tests2,
((test_set)(test_multiset)(test_map)(test_multimap)(test_set_select_copy)(
test_multiset_select_copy)(test_map_select_copy)(
test_multimap_select_copy)(test_set_no_select_copy)(
test_multiset_no_select_copy)(test_map_no_select_copy)(
test_multimap_no_select_copy))(
(default_generator)(generate_collisions)(limited_range)))
} }
RUN_TESTS() RUN_TESTS()

View File

@@ -15,13 +15,13 @@
#include "../helpers/count.hpp" #include "../helpers/count.hpp"
#include <string> #include <string>
// Test that various emplace methods work with different numbers of // Test that various emplace methods work with different numbers of
// arguments. // arguments.
namespace emplace_tests { namespace emplace_tests {
// Constructible with 2 to 10 arguments // Constructible with 2 to 10 arguments
struct emplace_value : private test::counted_object { struct emplace_value : private test::counted_object
{
typedef int A0; typedef int A0;
typedef std::string A1; typedef std::string A1;
typedef char A2; typedef char A2;
@@ -46,109 +46,138 @@ namespace emplace_tests {
A8 a8; A8 a8;
A9 a9; A9 a9;
emplace_value( emplace_value(A0 const& b0, A1 const& b1) : arg_count(2), a0(b0), a1(b1) {}
A0 const& b0, A1 const& b1) :
arg_count(2), emplace_value(A0 const& b0, A1 const& b1, A2 const& b2)
a0(b0), a1(b1) {} : arg_count(3), a0(b0), a1(b1), a2(b2)
{
}
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3)
: arg_count(4), a0(b0), a1(b1), a2(b2), a3(b3)
{
}
emplace_value( emplace_value(
A0 const& b0, A1 const& b1, A2 const& b2) : A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3, A4 const& b4)
arg_count(3), : arg_count(5), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4)
a0(b0), a1(b1), a2(b2) {} {
}
emplace_value( emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3) : A4 const& b4, A5 const& b5)
arg_count(4), : arg_count(6), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5)
a0(b0), a1(b1), a2(b2), a3(b3) {} {
}
emplace_value( emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3, A4 const& b4, A5 const& b5, A6 const& b6)
A4 const& b4) : : arg_count(7), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6)
arg_count(5), {
a0(b0), a1(b1), a2(b2), a3(b3), a4(b4) {} }
emplace_value( emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3, A4 const& b4, A5 const& b5, A6 const& b6, A7 const& b7)
A4 const& b4, A5 const& b5) : : arg_count(8), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6),
arg_count(6), a7(b7)
a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), {
a5(b5) {} }
emplace_value( emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3, A4 const& b4, A5 const& b5, A6 const& b6, A7 const& b7, A8 const& b8)
A4 const& b4, A5 const& b5, A6 const& b6) : : arg_count(9), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6),
arg_count(7), a7(b7), a8(b8)
a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), {
a5(b5), a6(b6) {} }
emplace_value( emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3, A4 const& b4, A5 const& b5, A6 const& b6, A7 const& b7, A8 const& b8,
A4 const& b4, A5 const& b5, A6 const& b6, A7 const& b7) : A9 const& b9)
arg_count(8), : arg_count(10), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6),
a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a7(b7), a8(b8), a9(b9)
a5(b5), a6(b6), a7(b7) {} {
}
emplace_value( friend std::size_t hash_value(emplace_value const& x)
A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3, {
A4 const& b4, A5 const& b5, A6 const& b6, A7 const& b7,
A8 const& b8) :
arg_count(9),
a0(b0), a1(b1), a2(b2), a3(b3), a4(b4),
a5(b5), a6(b6), a7(b7), a8(b8) {}
emplace_value(
A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
A4 const& b4, A5 const& b5, A6 const& b6, A7 const& b7,
A8 const& b8, A9 const& b9) :
arg_count(10),
a0(b0), a1(b1), a2(b2), a3(b3), a4(b4),
a5(b5), a6(b6), a7(b7), a8(b8), a9(b9) {}
friend std::size_t hash_value(emplace_value const& x) {
std::size_t r1 = 23894278u; std::size_t r1 = 23894278u;
if (x.arg_count >= 1) boost::hash_combine(r1, x.a0); if (x.arg_count >= 1)
if (x.arg_count >= 2) boost::hash_combine(r1, x.a1); boost::hash_combine(r1, x.a0);
if (x.arg_count >= 3) boost::hash_combine(r1, x.a2); if (x.arg_count >= 2)
if (x.arg_count >= 4) boost::hash_combine(r1, x.a3); boost::hash_combine(r1, x.a1);
if (x.arg_count >= 5) boost::hash_combine(r1, x.a4); if (x.arg_count >= 3)
if (x.arg_count >= 6) boost::hash_combine(r1, x.a5); boost::hash_combine(r1, x.a2);
if (x.arg_count >= 7) boost::hash_combine(r1, x.a6); if (x.arg_count >= 4)
if (x.arg_count >= 8) boost::hash_combine(r1, x.a7); boost::hash_combine(r1, x.a3);
if (x.arg_count >= 9) boost::hash_combine(r1, x.a8); if (x.arg_count >= 5)
if (x.arg_count >= 10) boost::hash_combine(r1, x.a9); boost::hash_combine(r1, x.a4);
if (x.arg_count >= 6)
boost::hash_combine(r1, x.a5);
if (x.arg_count >= 7)
boost::hash_combine(r1, x.a6);
if (x.arg_count >= 8)
boost::hash_combine(r1, x.a7);
if (x.arg_count >= 9)
boost::hash_combine(r1, x.a8);
if (x.arg_count >= 10)
boost::hash_combine(r1, x.a9);
return r1; return r1;
} }
friend bool operator==(emplace_value const& x, emplace_value const& y) { friend bool operator==(emplace_value const& x, emplace_value const& y)
if (x.arg_count != y.arg_count) { return false; } {
if (x.arg_count >= 1 && x.a0 != y.a0) { return false; } if (x.arg_count != y.arg_count) {
if (x.arg_count >= 2 && x.a1 != y.a1) { return false; } return false;
if (x.arg_count >= 3 && x.a2 != y.a2) { return false; } }
if (x.arg_count >= 4 && x.a3 != y.a3) { return false; } if (x.arg_count >= 1 && x.a0 != y.a0) {
if (x.arg_count >= 5 && x.a4 != y.a4) { return false; } return false;
if (x.arg_count >= 6 && x.a5 != y.a5) { return false; } }
if (x.arg_count >= 7 && x.a6 != y.a6) { return false; } if (x.arg_count >= 2 && x.a1 != y.a1) {
if (x.arg_count >= 8 && x.a7 != y.a7) { return false; } return false;
if (x.arg_count >= 9 && x.a8 != y.a8) { return false; } }
if (x.arg_count >= 10 && x.a9 != y.a9) { return false; } if (x.arg_count >= 3 && x.a2 != y.a2) {
return false;
}
if (x.arg_count >= 4 && x.a3 != y.a3) {
return false;
}
if (x.arg_count >= 5 && x.a4 != y.a4) {
return false;
}
if (x.arg_count >= 6 && x.a5 != y.a5) {
return false;
}
if (x.arg_count >= 7 && x.a6 != y.a6) {
return false;
}
if (x.arg_count >= 8 && x.a7 != y.a7) {
return false;
}
if (x.arg_count >= 9 && x.a8 != y.a8) {
return false;
}
if (x.arg_count >= 10 && x.a9 != y.a9) {
return false;
}
return true; return true;
} }
private: private:
emplace_value(); emplace_value();
emplace_value(emplace_value const&); emplace_value(emplace_value const&);
}; };
UNORDERED_AUTO_TEST(emplace_set) { UNORDERED_AUTO_TEST(emplace_set)
{
test::check_instances check_; test::check_instances check_;
typedef boost::unordered_set<emplace_value, typedef boost::unordered_set<emplace_value, boost::hash<emplace_value> >
boost::hash<emplace_value> > container; container;
typedef container::iterator iterator; typedef container::iterator iterator;
typedef std::pair<iterator, bool> return_type; typedef std::pair<iterator, bool> return_type;
container x(10); container x(10);
iterator i1; iterator i1;
return_type r1,r2; return_type r1, r2;
// 2 args // 2 args
@@ -208,8 +237,8 @@ namespace emplace_tests {
x.emplace_hint(r1.first, 10, "", 'a', 4, 5, 6, 7, 8, 9, 10)); x.emplace_hint(r1.first, 10, "", 'a', 4, 5, 6, 7, 8, 9, 10));
BOOST_TEST(r1.first == BOOST_TEST(r1.first ==
x.emplace_hint(r2.first, 10, "", 'a', 4, 5, 6, 7, 8, 9, 10)); x.emplace_hint(r2.first, 10, "", 'a', 4, 5, 6, 7, 8, 9, 10));
BOOST_TEST(r1.first == BOOST_TEST(
x.emplace_hint(x.end(), 10, "", 'a', 4, 5, 6, 7, 8, 9, 10)); r1.first == x.emplace_hint(x.end(), 10, "", 'a', 4, 5, 6, 7, 8, 9, 10));
BOOST_TEST_EQ(check_.instances(), 8); BOOST_TEST_EQ(check_.instances(), 8);
BOOST_TEST_EQ(check_.constructions(), 12); BOOST_TEST_EQ(check_.constructions(), 12);
@@ -218,13 +247,15 @@ namespace emplace_tests {
BOOST_TEST(x.count(v2) == 1); BOOST_TEST(x.count(v2) == 1);
BOOST_TEST(x.count(v3) == 1); BOOST_TEST(x.count(v3) == 1);
BOOST_TEST(x.count(v4) == 1); BOOST_TEST(x.count(v4) == 1);
} }
UNORDERED_AUTO_TEST(emplace_multiset) { UNORDERED_AUTO_TEST(emplace_multiset)
{
test::check_instances check_; test::check_instances check_;
typedef boost::unordered_multiset<emplace_value, typedef boost::unordered_multiset<emplace_value,
boost::hash<emplace_value> > container; boost::hash<emplace_value> >
container;
typedef container::iterator iterator; typedef container::iterator iterator;
container x(10); container x(10);
iterator i1, i2; iterator i1, i2;
@@ -295,13 +326,15 @@ namespace emplace_tests {
BOOST_TEST_EQ(x.count(v1), 1u); BOOST_TEST_EQ(x.count(v1), 1u);
BOOST_TEST_EQ(x.count(v2), 2u); BOOST_TEST_EQ(x.count(v2), 2u);
BOOST_TEST_EQ(x.count(v3), 2u); BOOST_TEST_EQ(x.count(v3), 2u);
} }
UNORDERED_AUTO_TEST(emplace_map) { UNORDERED_AUTO_TEST(emplace_map)
{
test::check_instances check_; test::check_instances check_;
typedef boost::unordered_map<emplace_value, emplace_value, typedef boost::unordered_map<emplace_value, emplace_value,
boost::hash<emplace_value> > container; boost::hash<emplace_value> >
container;
typedef container::iterator iterator; typedef container::iterator iterator;
typedef std::pair<iterator, bool> return_type; typedef std::pair<iterator, bool> return_type;
container x(10); container x(10);
@@ -349,29 +382,31 @@ namespace emplace_tests {
BOOST_TEST_EQ(check_.instances(), 8); BOOST_TEST_EQ(check_.instances(), 8);
BOOST_TEST_EQ(check_.constructions(), 10); BOOST_TEST_EQ(check_.constructions(), 10);
BOOST_TEST(r1.first == x.emplace_hint(r1.first, BOOST_TEST(r1.first ==
boost::unordered::piecewise_construct, x.emplace_hint(r1.first, boost::unordered::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9), boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(15, "jkjk"))); boost::make_tuple(15, "jkjk")));
BOOST_TEST(r1.first == x.emplace_hint(r2.first, BOOST_TEST(r1.first ==
boost::unordered::piecewise_construct, x.emplace_hint(r2.first, boost::unordered::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9), boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(275, "xxx", 'm', 6))); boost::make_tuple(275, "xxx", 'm', 6)));
BOOST_TEST(r1.first == x.emplace_hint(x.end(), BOOST_TEST(r1.first ==
boost::unordered::piecewise_construct, x.emplace_hint(x.end(), boost::unordered::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9), boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(-10, "blah blah", '\0'))); boost::make_tuple(-10, "blah blah", '\0')));
BOOST_TEST_EQ(x.size(), 2u); BOOST_TEST_EQ(x.size(), 2u);
BOOST_TEST(x.find(k2)->second == m2); BOOST_TEST(x.find(k2)->second == m2);
BOOST_TEST_EQ(check_.instances(), 8); BOOST_TEST_EQ(check_.instances(), 8);
BOOST_TEST_EQ(check_.constructions(), 16); BOOST_TEST_EQ(check_.constructions(), 16);
} }
UNORDERED_AUTO_TEST(emplace_multimap) { UNORDERED_AUTO_TEST(emplace_multimap)
{
test::check_instances check_; test::check_instances check_;
typedef boost::unordered_multimap<emplace_value, emplace_value, typedef boost::unordered_multimap<emplace_value, emplace_value,
boost::hash<emplace_value> > container; boost::hash<emplace_value> >
container;
typedef container::iterator iterator; typedef container::iterator iterator;
container x(10); container x(10);
iterator i1, i2, i3, i4; iterator i1, i2, i3, i4;
@@ -414,25 +449,22 @@ namespace emplace_tests {
BOOST_TEST_EQ(check_.constructions(), 11); BOOST_TEST_EQ(check_.constructions(), 11);
emplace_value m2a(15, "jkjk"); emplace_value m2a(15, "jkjk");
i2 = x.emplace_hint(i2, i2 = x.emplace_hint(i2, boost::unordered::piecewise_construct,
boost::unordered::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9), boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(15, "jkjk")); boost::make_tuple(15, "jkjk"));
emplace_value m2b(275, "xxx", 'm', 6); emplace_value m2b(275, "xxx", 'm', 6);
i3 = x.emplace_hint(i1, i3 = x.emplace_hint(i1, boost::unordered::piecewise_construct,
boost::unordered::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9), boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(275, "xxx", 'm', 6)); boost::make_tuple(275, "xxx", 'm', 6));
emplace_value m2c(-10, "blah blah", '\0'); emplace_value m2c(-10, "blah blah", '\0');
i4 = x.emplace_hint(x.end(), i4 = x.emplace_hint(x.end(), boost::unordered::piecewise_construct,
boost::unordered::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9), boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(-10, "blah blah", '\0')); boost::make_tuple(-10, "blah blah", '\0'));
BOOST_TEST_EQ(x.size(), 6u); BOOST_TEST_EQ(x.size(), 6u);
BOOST_TEST(x.find(k2)->second == m2); BOOST_TEST(x.find(k2)->second == m2);
BOOST_TEST_EQ(check_.instances(), 20); BOOST_TEST_EQ(check_.instances(), 20);
BOOST_TEST_EQ(check_.constructions(), 20); BOOST_TEST_EQ(check_.constructions(), 20);
} }
} }
RUN_TESTS() RUN_TESTS()

View File

@@ -14,26 +14,21 @@
#include <list> #include <list>
#include "../helpers/test.hpp" #include "../helpers/test.hpp"
namespace equality_tests namespace equality_tests {
struct mod_compare
{ {
struct mod_compare
{
bool alt_hash_; bool alt_hash_;
explicit mod_compare(bool alt_hash = false) : alt_hash_(alt_hash) {} explicit mod_compare(bool alt_hash = false) : alt_hash_(alt_hash) {}
bool operator()(int x, int y) const bool operator()(int x, int y) const { return x % 1000 == y % 1000; }
{
return x % 1000 == y % 1000;
}
std::size_t operator()(int x) const std::size_t operator()(int x) const
{ {
return alt_hash_ ? return alt_hash_ ? static_cast<std::size_t>(x % 250)
static_cast<std::size_t>(x % 250) : : static_cast<std::size_t>((x + 5) % 250);
static_cast<std::size_t>((x + 5) % 250);
} }
}; };
#define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \ #define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \
{ \ { \
@@ -45,8 +40,7 @@ namespace equality_tests
#define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \ #define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \
{ \ { \
boost::unordered_multiset<int, mod_compare, mod_compare> \ boost::unordered_multiset<int, mod_compare, mod_compare> set1, set2; \
set1, set2; \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \ BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \ BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
BOOST_TEST(set1 op set2); \ BOOST_TEST(set1 op set2); \
@@ -54,8 +48,7 @@ namespace equality_tests
#define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \ #define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \
{ \ { \
boost::unordered_map<int, int, mod_compare, mod_compare> \ boost::unordered_map<int, int, mod_compare, mod_compare> map1, map2; \
map1, map2; \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \ BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \ BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
BOOST_TEST(map1 op map2); \ BOOST_TEST(map1 op map2); \
@@ -63,8 +56,8 @@ namespace equality_tests
#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \ #define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
{ \ { \
boost::unordered_multimap<int, int, mod_compare, mod_compare> \ boost::unordered_multimap<int, int, mod_compare, mod_compare> map1, \
map1, map2; \ map2; \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \ BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \ BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
BOOST_TEST(map1 op map2); \ BOOST_TEST(map1 op map2); \
@@ -74,8 +67,8 @@ namespace equality_tests
#define UNORDERED_MAP_INSERT(r, map, item) \ #define UNORDERED_MAP_INSERT(r, map, item) \
map.insert(std::pair<int const, int> BOOST_PP_SEQ_TO_TUPLE(item)); map.insert(std::pair<int const, int> BOOST_PP_SEQ_TO_TUPLE(item));
UNORDERED_AUTO_TEST(equality_size_tests) UNORDERED_AUTO_TEST(equality_size_tests)
{ {
boost::unordered_set<int> x1, x2; boost::unordered_set<int> x1, x2;
BOOST_TEST(x1 == x2); BOOST_TEST(x1 == x2);
BOOST_TEST(!(x1 != x2)); BOOST_TEST(!(x1 != x2));
@@ -95,91 +88,78 @@ namespace equality_tests
BOOST_TEST(!(x1 == x2)); BOOST_TEST(!(x1 == x2));
BOOST_TEST(x2 != x1); BOOST_TEST(x2 != x1);
BOOST_TEST(!(x2 == x1)); BOOST_TEST(!(x2 == x1));
} }
UNORDERED_AUTO_TEST(equality_key_value_tests) UNORDERED_AUTO_TEST(equality_key_value_tests)
{ {
UNORDERED_EQUALITY_MULTISET_TEST((1), !=, (2)) UNORDERED_EQUALITY_MULTISET_TEST((1), !=, (2))
UNORDERED_EQUALITY_SET_TEST((2), ==, (2)) UNORDERED_EQUALITY_SET_TEST((2), ==, (2))
UNORDERED_EQUALITY_MAP_TEST(((1)(1))((2)(1)), !=, ((1)(1))((3)(1))) UNORDERED_EQUALITY_MAP_TEST(((1)(1))((2)(1)), !=, ((1)(1))((3)(1)))
} }
UNORDERED_AUTO_TEST(equality_collision_test) UNORDERED_AUTO_TEST(equality_collision_test)
{ {
UNORDERED_EQUALITY_MULTISET_TEST( UNORDERED_EQUALITY_MULTISET_TEST((1), !=, (501))
(1), !=, (501)) UNORDERED_EQUALITY_MULTISET_TEST((1)(251), !=, (1)(501))
UNORDERED_EQUALITY_MULTISET_TEST( UNORDERED_EQUALITY_MULTIMAP_TEST(((251)(1))((1)(1)), !=, ((501)(1))((1)(1)))
(1)(251), !=, (1)(501)) UNORDERED_EQUALITY_MULTISET_TEST((1)(501), ==, (1)(501))
UNORDERED_EQUALITY_MULTIMAP_TEST( UNORDERED_EQUALITY_SET_TEST((1)(501), ==, (501)(1))
((251)(1))((1)(1)), !=, ((501)(1))((1)(1))) }
UNORDERED_EQUALITY_MULTISET_TEST(
(1)(501), ==, (1)(501))
UNORDERED_EQUALITY_SET_TEST(
(1)(501), ==, (501)(1))
}
UNORDERED_AUTO_TEST(equality_group_size_test) UNORDERED_AUTO_TEST(equality_group_size_test)
{ {
UNORDERED_EQUALITY_MULTISET_TEST( UNORDERED_EQUALITY_MULTISET_TEST((10)(20)(20), !=, (10)(10)(20))
(10)(20)(20), !=, (10)(10)(20))
UNORDERED_EQUALITY_MULTIMAP_TEST( UNORDERED_EQUALITY_MULTIMAP_TEST(
((10)(1))((20)(1))((20)(1)), !=, ((10)(1))((20)(1))((20)(1)), !=, ((10)(1))((20)(1))((10)(1)))
((10)(1))((20)(1))((10)(1)))
UNORDERED_EQUALITY_MULTIMAP_TEST( UNORDERED_EQUALITY_MULTIMAP_TEST(
((20)(1))((10)(1))((10)(1)), ==, ((20)(1))((10)(1))((10)(1)), ==, ((10)(1))((20)(1))((10)(1)))
((10)(1))((20)(1))((10)(1))) }
}
UNORDERED_AUTO_TEST(equality_map_value_test) UNORDERED_AUTO_TEST(equality_map_value_test)
{ {
UNORDERED_EQUALITY_MAP_TEST( UNORDERED_EQUALITY_MAP_TEST(((1)(1)), !=, ((1)(2)))
((1)(1)), !=, ((1)(2))) UNORDERED_EQUALITY_MAP_TEST(((1)(1)), ==, ((1)(1)))
UNORDERED_EQUALITY_MAP_TEST( UNORDERED_EQUALITY_MULTIMAP_TEST(((1)(1)), !=, ((1)(2)))
((1)(1)), ==, ((1)(1))) UNORDERED_EQUALITY_MULTIMAP_TEST(((1)(1))((1)(1)), !=, ((1)(1))((1)(2)))
UNORDERED_EQUALITY_MULTIMAP_TEST( UNORDERED_EQUALITY_MULTIMAP_TEST(((1)(2))((1)(1)), ==, ((1)(1))((1)(2)))
((1)(1)), !=, ((1)(2))) UNORDERED_EQUALITY_MULTIMAP_TEST(((1)(2))((1)(1)), !=, ((1)(1))((1)(3)))
UNORDERED_EQUALITY_MULTIMAP_TEST( }
((1)(1))((1)(1)), !=, ((1)(1))((1)(2)))
UNORDERED_EQUALITY_MULTIMAP_TEST(
((1)(2))((1)(1)), ==, ((1)(1))((1)(2)))
UNORDERED_EQUALITY_MULTIMAP_TEST(
((1)(2))((1)(1)), !=, ((1)(1))((1)(3)))
}
UNORDERED_AUTO_TEST(equality_predicate_test) UNORDERED_AUTO_TEST(equality_predicate_test)
{ {
UNORDERED_EQUALITY_SET_TEST( UNORDERED_EQUALITY_SET_TEST((1), !=, (1001))
(1), !=, (1001)) UNORDERED_EQUALITY_MAP_TEST(((1)(2))((1001)(1)), !=, ((1001)(2))((1)(1)))
UNORDERED_EQUALITY_MAP_TEST( }
((1)(2))((1001)(1)), !=, ((1001)(2))((1)(1)))
}
UNORDERED_AUTO_TEST(equality_multiple_group_test) UNORDERED_AUTO_TEST(equality_multiple_group_test)
{ {
UNORDERED_EQUALITY_MULTISET_TEST( UNORDERED_EQUALITY_MULTISET_TEST(
(1)(1)(1)(1001)(2001)(2001)(2)(1002)(3)(1003)(2003), ==, (1)(1)(1)(1001)(2001)(2001)(2)(1002)(3)(1003)(2003), ==,
(3)(1003)(2003)(1002)(2)(2001)(2001)(1)(1001)(1)(1) (3)(1003)(2003)(1002)(2)(2001)(2001)(1)(1001)(1)(1));
); }
}
// Test that equality still works when the two containers have // Test that equality still works when the two containers have
// different hash functions but the same equality predicate. // different hash functions but the same equality predicate.
UNORDERED_AUTO_TEST(equality_different_hash_test) UNORDERED_AUTO_TEST(equality_different_hash_test)
{ {
typedef boost::unordered_set<int, mod_compare, mod_compare> set; typedef boost::unordered_set<int, mod_compare, mod_compare> set;
set set1(0, mod_compare(false), mod_compare(false)); set set1(0, mod_compare(false), mod_compare(false));
set set2(0, mod_compare(true), mod_compare(true)); set set2(0, mod_compare(true), mod_compare(true));
BOOST_TEST(set1 == set2); BOOST_TEST(set1 == set2);
set1.insert(1); set2.insert(2); set1.insert(1);
set2.insert(2);
BOOST_TEST(set1 != set2); BOOST_TEST(set1 != set2);
set1.insert(2); set2.insert(1); set1.insert(2);
set2.insert(1);
BOOST_TEST(set1 == set2); BOOST_TEST(set1 == set2);
set1.insert(10); set2.insert(20); set1.insert(10);
set2.insert(20);
BOOST_TEST(set1 != set2); BOOST_TEST(set1 != set2);
set1.insert(20); set2.insert(10); set1.insert(20);
set2.insert(10);
BOOST_TEST(set1 == set2); BOOST_TEST(set1 == set2);
} }
} }
RUN_TESTS() RUN_TESTS()

View File

@@ -27,7 +27,7 @@ void test_equal_insertion(Iterator begin, Iterator end)
Container x1; Container x1;
tracker x2 = test::create_ordered(x1); tracker x2 = test::create_ordered(x1);
for(Iterator it = begin; it != end; ++it) { for (Iterator it = begin; it != end; ++it) {
x1.insert(*it); x1.insert(*it);
x2.insert(*it); x2.insert(*it);
x2.compare_key(x1, *it); x2.compare_key(x1, *it);
@@ -39,13 +39,7 @@ void test_equal_insertion(Iterator begin, Iterator end)
UNORDERED_AUTO_TEST(set_tests) UNORDERED_AUTO_TEST(set_tests)
{ {
int values[][5] = { int values[][5] = {{1}, {54, 23}, {-13, 65}, {77, 77}, {986, 25, 986}};
{1},
{54, 23},
{-13, 65},
{77, 77},
{986, 25, 986}
};
typedef boost::unordered_set<int> set; typedef boost::unordered_set<int> set;
typedef boost::unordered_multiset<int> multiset; typedef boost::unordered_multiset<int> multiset;
@@ -67,19 +61,19 @@ UNORDERED_AUTO_TEST(map_tests)
{ {
typedef test::list<std::pair<int const, int> > values_type; typedef test::list<std::pair<int const, int> > values_type;
values_type v[5]; values_type v[5];
v[0].push_back(std::pair<int const, int>(1,1)); 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>(28, 34));
v[1].push_back(std::pair<int const, int>(16,58)); v[1].push_back(std::pair<int const, int>(16, 58));
v[1].push_back(std::pair<int const, int>(-124, 62)); 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>(432, 12));
v[2].push_back(std::pair<int const, int>(9,13)); v[2].push_back(std::pair<int const, int>(9, 13));
v[2].push_back(std::pair<int const, int>(432,24)); v[2].push_back(std::pair<int const, int>(432, 24));
for(int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
test_equal_insertion<boost::unordered_map<int, int> >( test_equal_insertion<boost::unordered_map<int, int> >(
v[i].begin(), v[i].end()); v[i].begin(), v[i].end());
for(int i2 = 0; i2 < 5; ++i2) for (int i2 = 0; i2 < 5; ++i2)
test_equal_insertion<boost::unordered_multimap<int, int> >( test_equal_insertion<boost::unordered_multimap<int, int> >(
v[i2].begin(), v[i2].end()); v[i2].begin(), v[i2].end());
} }

View File

@@ -22,7 +22,7 @@
#include "../objects/test.hpp" #include "../objects/test.hpp"
#if BOOST_WORKAROUND(BOOST_MSVC, < 1400) #if BOOST_WORKAROUND(BOOST_MSVC, < 1400)
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int', #pragma warning(disable : 4267) // conversion from 'size_t' to 'unsigned int',
// possible loss of data. // possible loss of data.
#endif #endif
@@ -31,15 +31,14 @@ struct write_pair_type
template <class X1, class X2> template <class X1, class X2>
void operator()(std::pair<X1, X2> const& x) const void operator()(std::pair<X1, X2> const& x) const
{ {
std::cout<<"("<<x.first<<","<<x.second<<")"; std::cout << "(" << x.first << "," << x.second << ")";
} }
} write_pair; } write_pair;
template <class Container> template <class Container> void write_container(Container const& x)
void write_container(Container const& x)
{ {
std::for_each(x.begin(), x.end(), write_pair); std::for_each(x.begin(), x.end(), write_pair);
std::cout<<"\n"; std::cout << "\n";
} }
// Make everything collide - for testing erase in a single bucket. // Make everything collide - for testing erase in a single bucket.
@@ -51,7 +50,10 @@ struct collision_hash
// For testing erase in 2 buckets. // For testing erase in 2 buckets.
struct collision2_hash struct collision2_hash
{ {
std::size_t operator()(int x) const { return static_cast<std::size_t>(x & 1); } std::size_t operator()(int x) const
{
return static_cast<std::size_t>(x & 1);
}
}; };
// For testing erase in lots of buckets. // For testing erase in lots of buckets.
@@ -60,15 +62,15 @@ struct collision3_hash
std::size_t operator()(int x) const { return static_cast<std::size_t>(x); } std::size_t operator()(int x) const { return static_cast<std::size_t>(x); }
}; };
typedef boost::unordered_multimap<int, int, typedef boost::unordered_multimap<int, int, collision_hash, std::equal_to<int>,
collision_hash, std::equal_to<int>, test::allocator1<std::pair<int const, int> > >
test::allocator1<std::pair<int const, int> > > collide_map; collide_map;
typedef boost::unordered_multimap<int, int, typedef boost::unordered_multimap<int, int, collision2_hash, std::equal_to<int>,
collision2_hash, std::equal_to<int>, test::allocator2<std::pair<int const, int> > >
test::allocator2<std::pair<int const, int> > > collide_map2; collide_map2;
typedef boost::unordered_multimap<int, int, typedef boost::unordered_multimap<int, int, collision3_hash, std::equal_to<int>,
collision3_hash, std::equal_to<int>, test::allocator2<std::pair<int const, int> > >
test::allocator2<std::pair<int const, int> > > collide_map3; collide_map3;
typedef collide_map::value_type collide_value; typedef collide_map::value_type collide_value;
typedef test::list<collide_value> collide_list; typedef test::list<collide_value> collide_list;
@@ -84,7 +86,7 @@ UNORDERED_AUTO_TEST(empty_range_tests)
UNORDERED_AUTO_TEST(single_item_tests) UNORDERED_AUTO_TEST(single_item_tests)
{ {
collide_list init; collide_list init;
init.push_back(collide_value(1,1)); init.push_back(collide_value(1, 1));
collide_map x(init.begin(), init.end()); collide_map x(init.begin(), init.end());
x.erase(x.begin(), x.begin()); x.erase(x.begin(), x.begin());
@@ -101,8 +103,8 @@ UNORDERED_AUTO_TEST(single_item_tests)
UNORDERED_AUTO_TEST(two_equivalent_item_tests) UNORDERED_AUTO_TEST(two_equivalent_item_tests)
{ {
collide_list init; collide_list init;
init.push_back(collide_value(1,1)); init.push_back(collide_value(1, 1));
init.push_back(collide_value(1,2)); init.push_back(collide_value(1, 2));
{ {
collide_map x(init.begin(), init.end()); collide_map x(init.begin(), init.end());
@@ -115,8 +117,8 @@ UNORDERED_AUTO_TEST(two_equivalent_item_tests)
collide_map x(init.begin(), init.end()); collide_map x(init.begin(), init.end());
int value = test::next(x.begin())->second; int value = test::next(x.begin())->second;
x.erase(x.begin(), test::next(x.begin())); x.erase(x.begin(), test::next(x.begin()));
BOOST_TEST(x.count(1) == 1 && x.size() == 1 && BOOST_TEST(x.count(1) == 1 && x.size() == 1 && x.begin()->first == 1 &&
x.begin()->first == 1 && x.begin()->second == value); x.begin()->second == value);
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
@@ -124,15 +126,15 @@ UNORDERED_AUTO_TEST(two_equivalent_item_tests)
collide_map x(init.begin(), init.end()); collide_map x(init.begin(), init.end());
int value = x.begin()->second; int value = x.begin()->second;
x.erase(test::next(x.begin()), x.end()); x.erase(test::next(x.begin()), x.end());
BOOST_TEST(x.count(1) == 1 && x.size() == 1 && BOOST_TEST(x.count(1) == 1 && x.size() == 1 && x.begin()->first == 1 &&
x.begin()->first == 1 && x.begin()->second == value); x.begin()->second == value);
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
} }
// More automated tests... // More automated tests...
template<class Range1, class Range2> template <class Range1, class Range2>
bool compare(Range1 const& x, Range2 const& y) bool compare(Range1 const& x, Range2 const& y)
{ {
collide_list a(x.begin(), x.end()); collide_list a(x.begin(), x.end());
@@ -154,17 +156,17 @@ bool general_erase_range_test(Container& x, std::size_t start, std::size_t end)
return compare(l, x); return compare(l, x);
} }
template <class Container> template <class Container> void erase_subrange_tests(Container const& x)
void erase_subrange_tests(Container const& x)
{ {
for(std::size_t length = 0; length < x.size(); ++length) { for (std::size_t length = 0; length < x.size(); ++length) {
for(std::size_t position = 0; position < x.size() - length; ++position) for (std::size_t position = 0; position < x.size() - length;
{ ++position) {
Container y(x); Container y(x);
collide_list init(y.begin(), y.end()); collide_list init(y.begin(), y.end());
if(!general_erase_range_test(y, position, position + length)) { if (!general_erase_range_test(y, position, position + length)) {
BOOST_ERROR("general_erase_range_test failed."); BOOST_ERROR("general_erase_range_test failed.");
std::cout<<"Erase: ["<<position<<","<<position + length<<")\n"; std::cout << "Erase: [" << position << "," << position + length
<< ")\n";
write_container(init); write_container(init);
write_container(y); write_container(y);
} }
@@ -177,22 +179,21 @@ void x_by_y_erase_range_tests(Container*, int values, int duplicates)
{ {
Container y; Container y;
for(int i = 0; i < values; ++i) { for (int i = 0; i < values; ++i) {
for(int j = 0; j < duplicates; ++j) { for (int j = 0; j < duplicates; ++j) {
y.insert(collide_value(i, j)); y.insert(collide_value(i, j));
} }
} }
std::cout<<"Values: "<<values<<", Duplicates: "<<duplicates<<"\n"; std::cout << "Values: " << values << ", Duplicates: " << duplicates << "\n";
erase_subrange_tests(y); erase_subrange_tests(y);
} }
template <class Container> template <class Container>
void exhaustive_erase_tests(Container* x, int num_values, void exhaustive_erase_tests(Container* x, int num_values, int num_duplicated)
int num_duplicated)
{ {
for(int i = 0; i < num_values; ++i) { for (int i = 0; i < num_values; ++i) {
for(int j = 0; j < num_duplicated; ++j) { for (int j = 0; j < num_duplicated; ++j) {
x_by_y_erase_range_tests(x, i, j); x_by_y_erase_range_tests(x, i, j);
} }
} }
@@ -200,24 +201,24 @@ void exhaustive_erase_tests(Container* x, int num_values,
UNORDERED_AUTO_TEST(exhaustive_collide_tests) UNORDERED_AUTO_TEST(exhaustive_collide_tests)
{ {
std::cout<<"exhaustive_collide_tests:\n"; std::cout << "exhaustive_collide_tests:\n";
collide_map m; collide_map m;
exhaustive_erase_tests((collide_map*) 0, 4, 4); exhaustive_erase_tests((collide_map*)0, 4, 4);
std::cout<<"\n"; std::cout << "\n";
} }
UNORDERED_AUTO_TEST(exhaustive_collide2_tests) UNORDERED_AUTO_TEST(exhaustive_collide2_tests)
{ {
std::cout<<"exhaustive_collide2_tests:\n"; std::cout << "exhaustive_collide2_tests:\n";
exhaustive_erase_tests((collide_map2*) 0, 8, 4); exhaustive_erase_tests((collide_map2*)0, 8, 4);
std::cout<<"\n"; std::cout << "\n";
} }
UNORDERED_AUTO_TEST(exhaustive_collide3_tests) UNORDERED_AUTO_TEST(exhaustive_collide3_tests)
{ {
std::cout<<"exhaustive_collide3_tests:\n"; std::cout << "exhaustive_collide3_tests:\n";
exhaustive_erase_tests((collide_map3*) 0, 8, 4); exhaustive_erase_tests((collide_map3*)0, 8, 4);
std::cout<<"\n"; std::cout << "\n";
} }
RUN_TESTS() RUN_TESTS()

View File

@@ -21,8 +21,7 @@
#include <iostream> #include <iostream>
#include <cstdlib> #include <cstdlib>
namespace erase_tests namespace erase_tests {
{
test::seed_t initialize_seed(85638); test::seed_t initialize_seed(85638);
@@ -32,27 +31,28 @@ void erase_tests1(Container*, test::random_generator generator)
typedef BOOST_DEDUCED_TYPENAME Container::iterator iterator; typedef BOOST_DEDUCED_TYPENAME Container::iterator iterator;
typedef BOOST_DEDUCED_TYPENAME Container::const_iterator c_iterator; typedef BOOST_DEDUCED_TYPENAME Container::const_iterator c_iterator;
std::cerr<<"Erase by key.\n"; std::cerr << "Erase by key.\n";
{ {
test::check_instances check_; test::check_instances check_;
test::random_values<Container> v(1000, generator); test::random_values<Container> v(1000, generator);
Container x(v.begin(), v.end()); Container x(v.begin(), v.end());
int iterations = 0; int iterations = 0;
for(BOOST_DEDUCED_TYPENAME test::random_values<Container>::iterator for (BOOST_DEDUCED_TYPENAME test::random_values<Container>::iterator
it = v.begin(); it != v.end(); ++it) it = v.begin();
{ it != v.end(); ++it) {
std::size_t count = x.count(test::get_key<Container>(*it)); std::size_t count = x.count(test::get_key<Container>(*it));
std::size_t old_size = x.size(); std::size_t old_size = x.size();
BOOST_TEST(count == x.erase(test::get_key<Container>(*it))); BOOST_TEST(count == x.erase(test::get_key<Container>(*it)));
BOOST_TEST(x.size() == old_size - count); BOOST_TEST(x.size() == old_size - count);
BOOST_TEST(x.count(test::get_key<Container>(*it)) == 0); BOOST_TEST(x.count(test::get_key<Container>(*it)) == 0);
BOOST_TEST(x.find(test::get_key<Container>(*it)) == x.end()); BOOST_TEST(x.find(test::get_key<Container>(*it)) == x.end());
if (++iterations % 20 == 0) test::check_equivalent_keys(x); if (++iterations % 20 == 0)
test::check_equivalent_keys(x);
} }
} }
std::cerr<<"erase(begin()).\n"; std::cerr << "erase(begin()).\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -60,22 +60,22 @@ void erase_tests1(Container*, test::random_generator generator)
Container x(v.begin(), v.end()); Container x(v.begin(), v.end());
std::size_t size = x.size(); std::size_t size = x.size();
int iterations = 0; int iterations = 0;
while(size > 0 && !x.empty()) while (size > 0 && !x.empty()) {
{ BOOST_DEDUCED_TYPENAME Container::key_type key =
BOOST_DEDUCED_TYPENAME Container::key_type test::get_key<Container>(*x.begin());
key = test::get_key<Container>(*x.begin());
std::size_t count = x.count(key); std::size_t count = x.count(key);
iterator pos = x.erase(x.begin()); iterator pos = x.erase(x.begin());
--size; --size;
BOOST_TEST(pos == x.begin()); BOOST_TEST(pos == x.begin());
BOOST_TEST(x.count(key) == count - 1); BOOST_TEST(x.count(key) == count - 1);
BOOST_TEST(x.size() == size); BOOST_TEST(x.size() == size);
if (++iterations % 20 == 0) test::check_equivalent_keys(x); if (++iterations % 20 == 0)
test::check_equivalent_keys(x);
} }
BOOST_TEST(x.empty()); BOOST_TEST(x.empty());
} }
std::cerr<<"erase(random position).\n"; std::cerr << "erase(random position).\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -83,38 +83,37 @@ void erase_tests1(Container*, test::random_generator generator)
Container x(v.begin(), v.end()); Container x(v.begin(), v.end());
std::size_t size = x.size(); std::size_t size = x.size();
int iterations = 0; int iterations = 0;
while(size > 0 && !x.empty()) while (size > 0 && !x.empty()) {
{
std::size_t index = test::random_value(x.size()); std::size_t index = test::random_value(x.size());
c_iterator prev, pos, next; c_iterator prev, pos, next;
if(index == 0) { if (index == 0) {
prev = pos = x.begin(); prev = pos = x.begin();
} } else {
else {
prev = test::next(x.begin(), index - 1); prev = test::next(x.begin(), index - 1);
pos = test::next(prev); pos = test::next(prev);
} }
next = test::next(pos); next = test::next(pos);
BOOST_DEDUCED_TYPENAME Container::key_type BOOST_DEDUCED_TYPENAME Container::key_type key =
key = test::get_key<Container>(*pos); test::get_key<Container>(*pos);
std::size_t count = x.count(key); std::size_t count = x.count(key);
BOOST_TEST(count > 0); BOOST_TEST(count > 0);
BOOST_TEST(next == x.erase(pos)); BOOST_TEST(next == x.erase(pos));
--size; --size;
if(size > 0) if (size > 0)
BOOST_TEST(index == 0 ? next == x.begin() : BOOST_TEST(
next == test::next(prev)); index == 0 ? next == x.begin() : next == test::next(prev));
BOOST_TEST(x.count(key) == count - 1); BOOST_TEST(x.count(key) == count - 1);
if (x.count(key) != count - 1) { if (x.count(key) != count - 1) {
std::cerr << count << " => " << x.count(key) << std::endl; std::cerr << count << " => " << x.count(key) << std::endl;
} }
BOOST_TEST(x.size() == size); BOOST_TEST(x.size() == size);
if (++iterations % 20 == 0) test::check_equivalent_keys(x); if (++iterations % 20 == 0)
test::check_equivalent_keys(x);
} }
BOOST_TEST(x.empty()); BOOST_TEST(x.empty());
} }
std::cerr<<"erase(ranges).\n"; std::cerr << "erase(ranges).\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -141,7 +140,7 @@ void erase_tests1(Container*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"erase(random ranges).\n"; std::cerr << "erase(random ranges).\n";
{ {
test::check_instances check_; test::check_instances check_;
Container x; Container x;
@@ -152,23 +151,23 @@ void erase_tests1(Container*, test::random_generator generator)
// Note that erase only invalidates the erased iterators. // Note that erase only invalidates the erased iterators.
std::vector<c_iterator> iterators; std::vector<c_iterator> iterators;
for(c_iterator it = x.cbegin(); it != x.cend(); ++it) { for (c_iterator it = x.cbegin(); it != x.cend(); ++it) {
iterators.push_back(it); iterators.push_back(it);
} }
iterators.push_back(x.cend()); iterators.push_back(x.cend());
while(iterators.size() > 1) { while (iterators.size() > 1) {
std::size_t start = test::random_value(iterators.size()); std::size_t start = test::random_value(iterators.size());
std::size_t length = test::random_value(iterators.size() - start); std::size_t length =
test::random_value(iterators.size() - start);
x.erase(iterators[start], iterators[start + length]); x.erase(iterators[start], iterators[start + length]);
iterators.erase( iterators.erase(test::next(iterators.begin(), start),
test::next(iterators.begin(), start),
test::next(iterators.begin(), start + length)); test::next(iterators.begin(), start + length));
BOOST_TEST(x.size() == iterators.size() - 1); BOOST_TEST(x.size() == iterators.size() - 1);
BOOST_DEDUCED_TYPENAME std::vector<c_iterator>::const_iterator BOOST_DEDUCED_TYPENAME std::vector<c_iterator>::const_iterator
i2 = iterators.begin(); i2 = iterators.begin();
for(c_iterator i1 = x.cbegin(); i1 != x.cend(); ++i1) { for (c_iterator i1 = x.cbegin(); i1 != x.cend(); ++i1) {
BOOST_TEST(i1 == *i2); BOOST_TEST(i1 == *i2);
++i2; ++i2;
} }
@@ -180,7 +179,7 @@ void erase_tests1(Container*, test::random_generator generator)
} }
} }
std::cerr<<"quick_erase(begin()).\n"; std::cerr << "quick_erase(begin()).\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -188,21 +187,21 @@ void erase_tests1(Container*, test::random_generator generator)
Container x(v.begin(), v.end()); Container x(v.begin(), v.end());
std::size_t size = x.size(); std::size_t size = x.size();
int iterations = 0; int iterations = 0;
while(size > 0 && !x.empty()) while (size > 0 && !x.empty()) {
{ BOOST_DEDUCED_TYPENAME Container::key_type key =
BOOST_DEDUCED_TYPENAME Container::key_type test::get_key<Container>(*x.begin());
key = test::get_key<Container>(*x.begin());
std::size_t count = x.count(key); std::size_t count = x.count(key);
x.quick_erase(x.begin()); x.quick_erase(x.begin());
--size; --size;
BOOST_TEST(x.count(key) == count - 1); BOOST_TEST(x.count(key) == count - 1);
BOOST_TEST(x.size() == size); BOOST_TEST(x.size() == size);
if (++iterations % 20 == 0) test::check_equivalent_keys(x); if (++iterations % 20 == 0)
test::check_equivalent_keys(x);
} }
BOOST_TEST(x.empty()); BOOST_TEST(x.empty());
} }
std::cerr<<"quick_erase(random position).\n"; std::cerr << "quick_erase(random position).\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -210,39 +209,37 @@ void erase_tests1(Container*, test::random_generator generator)
Container x(v.begin(), v.end()); Container x(v.begin(), v.end());
std::size_t size = x.size(); std::size_t size = x.size();
int iterations = 0; int iterations = 0;
while(size > 0 && !x.empty()) while (size > 0 && !x.empty()) {
{
std::size_t index = test::random_value(x.size()); std::size_t index = test::random_value(x.size());
BOOST_DEDUCED_TYPENAME Container::const_iterator prev, pos, next; BOOST_DEDUCED_TYPENAME Container::const_iterator prev, pos, next;
if(index == 0) { if (index == 0) {
prev = pos = x.begin(); prev = pos = x.begin();
} } else {
else {
prev = test::next(x.begin(), index - 1); prev = test::next(x.begin(), index - 1);
pos = test::next(prev); pos = test::next(prev);
} }
next = test::next(pos); next = test::next(pos);
BOOST_DEDUCED_TYPENAME Container::key_type BOOST_DEDUCED_TYPENAME Container::key_type key =
key = test::get_key<Container>(*pos); test::get_key<Container>(*pos);
std::size_t count = x.count(key); std::size_t count = x.count(key);
BOOST_TEST(count > 0); BOOST_TEST(count > 0);
x.quick_erase(pos); x.quick_erase(pos);
--size; --size;
if(size > 0) if (size > 0)
BOOST_TEST(index == 0 ? next == x.begin() : BOOST_TEST(
next == test::next(prev)); index == 0 ? next == x.begin() : next == test::next(prev));
BOOST_TEST(x.count(key) == count - 1); BOOST_TEST(x.count(key) == count - 1);
if (x.count(key) != count - 1) { if (x.count(key) != count - 1) {
std::cerr << count << " => " << x.count(key) << std::endl; std::cerr << count << " => " << x.count(key) << std::endl;
} }
BOOST_TEST(x.size() == size); BOOST_TEST(x.size() == size);
if (++iterations % 20 == 0) test::check_equivalent_keys(x); if (++iterations % 20 == 0)
test::check_equivalent_keys(x);
} }
BOOST_TEST(x.empty()); BOOST_TEST(x.empty());
} }
std::cerr << "clear().\n";
std::cerr<<"clear().\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -253,31 +250,25 @@ void erase_tests1(Container*, test::random_generator generator)
BOOST_TEST(x.begin() == x.end()); BOOST_TEST(x.begin() == x.end());
} }
std::cerr<<"\n"; std::cerr << "\n";
} }
boost::unordered_set<test::object, boost::unordered_set<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator1<test::object> >* test_set; test::allocator1<test::object> >* test_set;
boost::unordered_multiset<test::object, boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator2<test::object> >* test_multiset; test::allocator2<test::object> >* test_multiset;
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator1<test::object> >* test_map; test::allocator1<test::object> >* test_map;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to, test::allocator2<test::object> >* test_multimap;
test::allocator2<test::object> >* test_multimap;
using test::default_generator; using test::default_generator;
using test::generate_collisions; using test::generate_collisions;
using test::limited_range; using test::limited_range;
UNORDERED_TEST(erase_tests1, UNORDERED_TEST(
((test_set)(test_multiset)(test_map)(test_multimap)) erase_tests1, ((test_set)(test_multiset)(test_map)(test_multimap))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
} }
RUN_TESTS() RUN_TESTS()

View File

@@ -16,13 +16,11 @@
#include "../helpers/tracker.hpp" #include "../helpers/tracker.hpp"
#include "../helpers/helpers.hpp" #include "../helpers/helpers.hpp"
namespace find_tests namespace find_tests {
{
test::seed_t initialize_seed(78937); test::seed_t initialize_seed(78937);
template <class X> template <class X> void find_tests1(X*, test::random_generator generator)
void find_tests1(X*, test::random_generator generator)
{ {
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator; typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
@@ -35,37 +33,35 @@ void find_tests1(X*, test::random_generator generator)
test::ordered<X> tracker = test::create_ordered(x); test::ordered<X> tracker = test::create_ordered(x);
tracker.insert_range(v.begin(), v.end()); tracker.insert_range(v.begin(), v.end());
for(BOOST_DEDUCED_TYPENAME test::ordered<X>::const_iterator it1 = for (BOOST_DEDUCED_TYPENAME test::ordered<X>::const_iterator it1 =
tracker.begin(); it1 != tracker.end(); ++it1) tracker.begin();
{ it1 != tracker.end(); ++it1) {
BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it1); BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it1);
BOOST_DEDUCED_TYPENAME X::const_iterator BOOST_DEDUCED_TYPENAME X::const_iterator const_pos =
const_pos = x_const.find(key); x_const.find(key);
iterator pos = x.find(key); iterator pos = x.find(key);
BOOST_TEST(const_pos != x_const.end()); BOOST_TEST(const_pos != x_const.end());
BOOST_TEST(const_pos != x_const.end() && BOOST_TEST(const_pos != x_const.end() &&
x_const.key_eq()(key, test::get_key<X>(*const_pos))); x_const.key_eq()(key, test::get_key<X>(*const_pos)));
BOOST_TEST(pos != x.end()); BOOST_TEST(pos != x.end());
BOOST_TEST(pos != x.end() && BOOST_TEST(
x.key_eq()(key, test::get_key<X>(*pos))); pos != x.end() && x.key_eq()(key, test::get_key<X>(*pos)));
BOOST_TEST(x.count(key) == tracker.count(key)); BOOST_TEST(x.count(key) == tracker.count(key));
test::compare_pairs(x.equal_range(key), test::compare_pairs(x.equal_range(key), tracker.equal_range(key),
tracker.equal_range(key), (BOOST_DEDUCED_TYPENAME X::value_type*)0);
(BOOST_DEDUCED_TYPENAME X::value_type*) 0);
test::compare_pairs(x_const.equal_range(key), test::compare_pairs(x_const.equal_range(key),
tracker.equal_range(key), tracker.equal_range(key),
(BOOST_DEDUCED_TYPENAME X::value_type*) 0); (BOOST_DEDUCED_TYPENAME X::value_type*)0);
} }
test::random_values<X> v2(500, generator); test::random_values<X> v2(500, generator);
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator it2 = for (BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator it2 =
v2.begin(); it2 != v2.end(); ++it2) v2.begin();
{ it2 != v2.end(); ++it2) {
BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it2); BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it2);
if(tracker.find(test::get_key<X>(key)) == tracker.end()) if (tracker.find(test::get_key<X>(key)) == tracker.end()) {
{
BOOST_TEST(x.find(key) == x.end()); BOOST_TEST(x.find(key) == x.end());
BOOST_TEST(x_const.find(key) == x_const.end()); BOOST_TEST(x_const.find(key) == x_const.end());
BOOST_TEST(x.count(key) == 0); BOOST_TEST(x.count(key) == 0);
@@ -81,9 +77,9 @@ void find_tests1(X*, test::random_generator generator)
X x; X x;
test::random_values<X> v2(5, generator); test::random_values<X> v2(5, generator);
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator it3 = for (BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator it3 =
v2.begin(); it3 != v2.end(); ++it3) v2.begin();
{ it3 != v2.end(); ++it3) {
BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it3); BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it3);
BOOST_TEST(x.find(key) == x.end()); BOOST_TEST(x.find(key) == x.end());
BOOST_TEST(x.count(key) == 0); BOOST_TEST(x.count(key) == 0);
@@ -104,7 +100,8 @@ struct compatible_hash
{ {
test::hash hash_; test::hash hash_;
std::size_t operator()(compatible_key const& k) const { std::size_t operator()(compatible_key const& k) const
{
return hash_(k.o_); return hash_(k.o_);
} }
}; };
@@ -113,7 +110,8 @@ struct compatible_predicate
{ {
test::equal_to equal_; test::equal_to equal_;
bool operator()(compatible_key const& k1, compatible_key const& k2) const { bool operator()(compatible_key const& k1, compatible_key const& k2) const
{
return equal_(k1.o_, k2.o_); return equal_(k1.o_, k2.o_);
} }
}; };
@@ -129,45 +127,38 @@ void find_compatible_keys_test(X*, test::random_generator generator)
compatible_hash h; compatible_hash h;
compatible_predicate eq; compatible_predicate eq;
for(value_iterator it = v.begin(), end = v.end(); it != end; ++it) { for (value_iterator it = v.begin(), end = v.end(); it != end; ++it) {
BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it); BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it);
BOOST_TEST(x.find(key) == x.find(compatible_key(key), h, eq)); BOOST_TEST(x.find(key) == x.find(compatible_key(key), h, eq));
} }
test::random_values<X> v2(20, generator); test::random_values<X> v2(20, generator);
for(value_iterator it = v2.begin(), end = v2.end(); it != end; ++it) { for (value_iterator it = v2.begin(), end = v2.end(); it != end; ++it) {
BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it); BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it);
BOOST_TEST(x.find(key) == x.find(compatible_key(key), h, eq)); BOOST_TEST(x.find(key) == x.find(compatible_key(key), h, eq));
} }
} }
boost::unordered_set<test::object, boost::unordered_set<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator2<test::object> >* test_set; test::allocator2<test::object> >* test_set;
boost::unordered_multiset<test::object, boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator1<test::object> >* test_multiset; test::allocator1<test::object> >* test_multiset;
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator2<test::object> >* test_map; test::allocator2<test::object> >* test_map;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to, test::allocator1<test::object> >* test_multimap;
test::allocator1<test::object> >* test_multimap;
using test::default_generator; using test::default_generator;
using test::generate_collisions; using test::generate_collisions;
using test::limited_range; using test::limited_range;
UNORDERED_TEST(find_tests1, UNORDERED_TEST(
((test_set)(test_multiset)(test_map)(test_multimap)) find_tests1, ((test_set)(test_multiset)(test_map)(test_multimap))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
UNORDERED_TEST(find_compatible_keys_test, UNORDERED_TEST(find_compatible_keys_test,
((test_set)(test_multiset)(test_map)(test_multimap)) ((test_set)(test_multiset)(test_map)(test_multimap))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
} }
RUN_TESTS() RUN_TESTS()

View File

@@ -10,43 +10,41 @@
// clang-format on // clang-format on
template <typename T> template <typename T>
void call_swap(boost::unordered_map<T,T>& x, void call_swap(boost::unordered_map<T, T>& x, boost::unordered_map<T, T>& y)
boost::unordered_map<T,T>& y)
{ {
swap(x,y); swap(x, y);
} }
template <typename T> template <typename T>
bool call_equals(boost::unordered_map<T,T>& x, bool call_equals(boost::unordered_map<T, T>& x, boost::unordered_map<T, T>& y)
boost::unordered_map<T,T>& y)
{ {
return x == y; return x == y;
} }
template <typename T> template <typename T>
bool call_not_equals(boost::unordered_map<T,T>& x, bool call_not_equals(
boost::unordered_map<T,T>& y) boost::unordered_map<T, T>& x, boost::unordered_map<T, T>& y)
{ {
return x != y; return x != y;
} }
template <typename T> template <typename T>
void call_swap(boost::unordered_multimap<T,T>& x, void call_swap(
boost::unordered_multimap<T,T>& y) boost::unordered_multimap<T, T>& x, boost::unordered_multimap<T, T>& y)
{ {
swap(x,y); swap(x, y);
} }
template <typename T> template <typename T>
bool call_equals(boost::unordered_multimap<T,T>& x, bool call_equals(
boost::unordered_multimap<T,T>& y) boost::unordered_multimap<T, T>& x, boost::unordered_multimap<T, T>& y)
{ {
return x == y; return x == y;
} }
template <typename T> template <typename T>
bool call_not_equals(boost::unordered_multimap<T,T>& x, bool call_not_equals(
boost::unordered_multimap<T,T>& y) boost::unordered_multimap<T, T>& x, boost::unordered_multimap<T, T>& y)
{ {
return x != y; return x != y;
} }
@@ -57,7 +55,8 @@ bool call_not_equals(boost::unordered_multimap<T,T>& x,
typedef boost::unordered_map<int, int> int_map; typedef boost::unordered_map<int, int> int_map;
typedef boost::unordered_multimap<int, int> int_multimap; typedef boost::unordered_multimap<int, int> int_multimap;
UNORDERED_AUTO_TEST(use_map_fwd_declared_function) { UNORDERED_AUTO_TEST(use_map_fwd_declared_function)
{
int_map x, y; int_map x, y;
x[1] = 2; x[1] = 2;
y[2] = 1; y[2] = 1;
@@ -73,7 +72,8 @@ UNORDERED_AUTO_TEST(use_map_fwd_declared_function) {
BOOST_TEST(call_not_equals(x, y)); BOOST_TEST(call_not_equals(x, y));
} }
UNORDERED_AUTO_TEST(use_multimap_fwd_declared_function) { UNORDERED_AUTO_TEST(use_multimap_fwd_declared_function)
{
int_multimap x, y; int_multimap x, y;
call_swap(x, y); call_swap(x, y);
BOOST_TEST(call_equals(x, y)); BOOST_TEST(call_equals(x, y));

View File

@@ -9,8 +9,14 @@
#include "../helpers/postfix.hpp" #include "../helpers/postfix.hpp"
// clang-format on // clang-format on
struct true_type { char x[100]; }; struct true_type
struct false_type { char x; }; {
char x[100];
};
struct false_type
{
char x;
};
false_type is_unordered_set_impl(void*); false_type is_unordered_set_impl(void*);
@@ -18,44 +24,40 @@ template <class Value, class Hash, class Pred, class Alloc>
true_type is_unordered_set_impl( true_type is_unordered_set_impl(
boost::unordered_set<Value, Hash, Pred, Alloc>*); boost::unordered_set<Value, Hash, Pred, Alloc>*);
template<typename T> template <typename T>
void call_swap(boost::unordered_set<T>& x, void call_swap(boost::unordered_set<T>& x, boost::unordered_set<T>& y)
boost::unordered_set<T>& y)
{ {
swap(x,y); swap(x, y);
} }
template<typename T> template <typename T>
bool call_equals(boost::unordered_set<T>& x, bool call_equals(boost::unordered_set<T>& x, boost::unordered_set<T>& y)
boost::unordered_set<T>& y)
{ {
return x == y; return x == y;
} }
template<typename T> template <typename T>
bool call_not_equals(boost::unordered_set<T>& x, bool call_not_equals(boost::unordered_set<T>& x, boost::unordered_set<T>& y)
boost::unordered_set<T>& y)
{ {
return x != y; return x != y;
} }
template<typename T> template <typename T>
void call_swap(boost::unordered_multiset<T>& x, void call_swap(boost::unordered_multiset<T>& x, boost::unordered_multiset<T>& y)
boost::unordered_multiset<T>& y)
{ {
swap(x,y); swap(x, y);
} }
template<typename T> template <typename T>
bool call_equals(boost::unordered_multiset<T>& x, bool call_equals(
boost::unordered_multiset<T>& y) boost::unordered_multiset<T>& x, boost::unordered_multiset<T>& y)
{ {
return x == y; return x == y;
} }
template<typename T> template <typename T>
bool call_not_equals(boost::unordered_multiset<T>& x, bool call_not_equals(
boost::unordered_multiset<T>& y) boost::unordered_multiset<T>& x, boost::unordered_multiset<T>& y)
{ {
return x != y; return x != y;
} }
@@ -65,21 +67,23 @@ bool call_not_equals(boost::unordered_multiset<T>& x,
typedef boost::unordered_set<int> int_set; typedef boost::unordered_set<int> int_set;
typedef boost::unordered_multiset<int> int_multiset; typedef boost::unordered_multiset<int> int_multiset;
UNORDERED_AUTO_TEST(use_fwd_declared_trait_without_definition) { UNORDERED_AUTO_TEST(use_fwd_declared_trait_without_definition)
BOOST_TEST(sizeof(is_unordered_set_impl((int_set*) 0)) {
== sizeof(true_type)); BOOST_TEST(sizeof(is_unordered_set_impl((int_set*)0)) == sizeof(true_type));
} }
#include <boost/unordered_set.hpp> #include <boost/unordered_set.hpp>
UNORDERED_AUTO_TEST(use_fwd_declared_trait) { UNORDERED_AUTO_TEST(use_fwd_declared_trait)
{
boost::unordered_set<int> x; boost::unordered_set<int> x;
BOOST_TEST(sizeof(is_unordered_set_impl(&x)) == sizeof(true_type)); BOOST_TEST(sizeof(is_unordered_set_impl(&x)) == sizeof(true_type));
BOOST_TEST(sizeof(is_unordered_set_impl((int*) 0)) == sizeof(false_type)); BOOST_TEST(sizeof(is_unordered_set_impl((int*)0)) == sizeof(false_type));
} }
UNORDERED_AUTO_TEST(use_set_fwd_declared_function) { UNORDERED_AUTO_TEST(use_set_fwd_declared_function)
{
int_set x, y; int_set x, y;
x.insert(1); x.insert(1);
y.insert(2); y.insert(2);
@@ -95,7 +99,8 @@ UNORDERED_AUTO_TEST(use_set_fwd_declared_function) {
BOOST_TEST(call_not_equals(x, y)); BOOST_TEST(call_not_equals(x, y));
} }
UNORDERED_AUTO_TEST(use_multiset_fwd_declared_function) { UNORDERED_AUTO_TEST(use_multiset_fwd_declared_function)
{
int_multiset x, y; int_multiset x, y;
call_swap(x, y); call_swap(x, y);
BOOST_TEST(call_equals(x, y)); BOOST_TEST(call_equals(x, y));

View File

@@ -12,113 +12,125 @@
#include <utility> #include <utility>
namespace x namespace x {
struct D
{ {
struct D { boost::unordered_map<D, D> x; }; boost::unordered_map<D, D> x;
};
} }
namespace incomplete_test namespace incomplete_test {
// Declare, but don't define some types.
struct value;
struct hash;
struct equals;
template <class T> struct allocator;
// Declare some instances
typedef boost::unordered_map<value, value, hash, equals,
allocator<std::pair<value const, value> > >
map;
typedef boost::unordered_multimap<value, value, hash, equals,
allocator<std::pair<value const, value> > >
multimap;
typedef boost::unordered_set<value, hash, equals, allocator<value> > set;
typedef boost::unordered_multiset<value, hash, equals, allocator<value> >
multiset;
// Now define the types which are stored as members, as they are needed for
// declaring struct members.
struct hash
{ {
// Declare, but don't define some types. template <typename T> std::size_t operator()(T const&) const { return 0; }
};
struct value; struct equals
struct hash; {
struct equals; template <typename T> bool operator()(T const&, T const&) const
template <class T> struct allocator; {
return true;
}
};
// Declare some instances // This is a dubious way to implement an allocator, but good enough
// for this test.
typedef boost::unordered_map<value, value, hash, equals, template <typename T> struct allocator : std::allocator<T>
allocator<std::pair<value const, value> > > map; {
typedef boost::unordered_multimap<value, value, hash, equals,
allocator<std::pair<value const, value> > > multimap;
typedef boost::unordered_set<value, hash, equals,
allocator<value> > set;
typedef boost::unordered_multiset<value, hash, equals,
allocator<value> > multiset;
// Now define the types which are stored as members, as they are needed for
// declaring struct members.
struct hash {
template <typename T>
std::size_t operator()(T const&) const { return 0; }
};
struct equals {
template <typename T>
bool operator()(T const&, T const&) const { return true; }
};
// This is a dubious way to implement an allocator, but good enough
// for this test.
template <typename T>
struct allocator : std::allocator<T> {
allocator() {} allocator() {}
template <typename T2> template <typename T2>
allocator(const allocator<T2>& other) : allocator(const allocator<T2>& other) : std::allocator<T>(other)
std::allocator<T>(other) {}
};
// Declare some members of a structs.
//
// Incomplete hash, equals and allocator aren't here supported at the
// moment.
struct struct1 {
boost::unordered_map<struct1, struct1, hash, equals,
allocator<std::pair<struct1 const, struct1> > > x;
};
struct struct2 {
boost::unordered_multimap<struct2, struct2, hash, equals,
allocator<std::pair<struct2 const, struct2> > > x;
};
struct struct3 {
boost::unordered_set<struct3, hash, equals,
allocator<struct3> > x;
};
struct struct4 {
boost::unordered_multiset<struct4, hash, equals,
allocator<struct4> > x;
};
// Now define the value type.
struct value {};
// Create some instances.
incomplete_test::map m1;
incomplete_test::multimap m2;
incomplete_test::set s1;
incomplete_test::multiset s2;
incomplete_test::struct1 c1;
incomplete_test::struct2 c2;
incomplete_test::struct3 c3;
incomplete_test::struct4 c4;
// Now declare, but don't define, the operators required for comparing
// elements.
std::size_t hash_value(value const&);
bool operator==(value const&, value const&);
std::size_t hash_value(struct1 const&);
std::size_t hash_value(struct2 const&);
std::size_t hash_value(struct3 const&);
std::size_t hash_value(struct4 const&);
bool operator==(struct1 const&, struct1 const&);
bool operator==(struct2 const&, struct2 const&);
bool operator==(struct3 const&, struct3 const&);
bool operator==(struct4 const&, struct4 const&);
// And finally use these
void use_types()
{ {
}
};
// Declare some members of a structs.
//
// Incomplete hash, equals and allocator aren't here supported at the
// moment.
struct struct1
{
boost::unordered_map<struct1, struct1, hash, equals,
allocator<std::pair<struct1 const, struct1> > >
x;
};
struct struct2
{
boost::unordered_multimap<struct2, struct2, hash, equals,
allocator<std::pair<struct2 const, struct2> > >
x;
};
struct struct3
{
boost::unordered_set<struct3, hash, equals, allocator<struct3> > x;
};
struct struct4
{
boost::unordered_multiset<struct4, hash, equals, allocator<struct4> > x;
};
// Now define the value type.
struct value
{
};
// Create some instances.
incomplete_test::map m1;
incomplete_test::multimap m2;
incomplete_test::set s1;
incomplete_test::multiset s2;
incomplete_test::struct1 c1;
incomplete_test::struct2 c2;
incomplete_test::struct3 c3;
incomplete_test::struct4 c4;
// Now declare, but don't define, the operators required for comparing
// elements.
std::size_t hash_value(value const&);
bool operator==(value const&, value const&);
std::size_t hash_value(struct1 const&);
std::size_t hash_value(struct2 const&);
std::size_t hash_value(struct3 const&);
std::size_t hash_value(struct4 const&);
bool operator==(struct1 const&, struct1 const&);
bool operator==(struct2 const&, struct2 const&);
bool operator==(struct3 const&, struct3 const&);
bool operator==(struct4 const&, struct4 const&);
// And finally use these
void use_types()
{
incomplete_test::value x; incomplete_test::value x;
m1[x] = x; m1[x] = x;
m2.insert(std::make_pair(x, x)); m2.insert(std::make_pair(x, x));
@@ -129,25 +141,26 @@ namespace incomplete_test
c2.x.insert(std::make_pair(c2, c2)); c2.x.insert(std::make_pair(c2, c2));
c3.x.insert(c3); c3.x.insert(c3);
c4.x.insert(c4); c4.x.insert(c4);
}
// And finally define the operators required for comparing elements.
std::size_t hash_value(value const&) { return 0; }
bool operator==(value const&, value const&) { return true; }
std::size_t hash_value(struct1 const&) { return 0; }
std::size_t hash_value(struct2 const&) { return 0; }
std::size_t hash_value(struct3 const&) { return 0; }
std::size_t hash_value(struct4 const&) { return 0; }
bool operator==(struct1 const&, struct1 const&) { return true; }
bool operator==(struct2 const&, struct2 const&) { return true; }
bool operator==(struct3 const&, struct3 const&) { return true; }
bool operator==(struct4 const&, struct4 const&) { return true; }
} }
int main() { // And finally define the operators required for comparing elements.
std::size_t hash_value(value const&) { return 0; }
bool operator==(value const&, value const&) { return true; }
std::size_t hash_value(struct1 const&) { return 0; }
std::size_t hash_value(struct2 const&) { return 0; }
std::size_t hash_value(struct3 const&) { return 0; }
std::size_t hash_value(struct4 const&) { return 0; }
bool operator==(struct1 const&, struct1 const&) { return true; }
bool operator==(struct2 const&, struct2 const&) { return true; }
bool operator==(struct3 const&, struct3 const&) { return true; }
bool operator==(struct4 const&, struct4 const&) { return true; }
}
int main()
{
// This could just be a compile test, but I like to be able to run these // This could just be a compile test, but I like to be able to run these
// things. It's probably irrational, but I find it reassuring. // things. It's probably irrational, but I find it reassuring.

View File

@@ -17,9 +17,9 @@
#include <set> #include <set>
#include <iostream> #include <iostream>
namespace insert_hint namespace insert_hint {
UNORDERED_AUTO_TEST(insert_hint_empty)
{ {
UNORDERED_AUTO_TEST(insert_hint_empty) {
typedef boost::unordered_multiset<int> container; typedef boost::unordered_multiset<int> container;
container x; container x;
x.insert(x.cbegin(), 10); x.insert(x.cbegin(), 10);
@@ -28,7 +28,8 @@ UNORDERED_AUTO_TEST(insert_hint_empty) {
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
UNORDERED_AUTO_TEST(insert_hint_empty2) { UNORDERED_AUTO_TEST(insert_hint_empty2)
{
typedef boost::unordered_multimap<std::string, int> container; typedef boost::unordered_multimap<std::string, int> container;
container x; container x;
x.emplace_hint(x.cbegin(), "hello", 50); x.emplace_hint(x.cbegin(), "hello", 50);
@@ -38,7 +39,8 @@ UNORDERED_AUTO_TEST(insert_hint_empty2) {
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
UNORDERED_AUTO_TEST(insert_hint_single) { UNORDERED_AUTO_TEST(insert_hint_single)
{
typedef boost::unordered_multiset<std::string> container; typedef boost::unordered_multiset<std::string> container;
container x; container x;
x.insert("equal"); x.insert("equal");
@@ -48,7 +50,8 @@ UNORDERED_AUTO_TEST(insert_hint_single) {
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
UNORDERED_AUTO_TEST(insert_hint_single2) { UNORDERED_AUTO_TEST(insert_hint_single2)
{
typedef boost::unordered_multimap<int, std::string> container; typedef boost::unordered_multimap<int, std::string> container;
container x; container x;
x.emplace(10, "one"); x.emplace(10, "one");
@@ -67,18 +70,23 @@ UNORDERED_AUTO_TEST(insert_hint_single2) {
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
UNORDERED_AUTO_TEST(insert_hint_multiple) { UNORDERED_AUTO_TEST(insert_hint_multiple)
{
for (unsigned int size = 0; size < 10; ++size) { for (unsigned int size = 0; size < 10; ++size) {
for (unsigned int offset = 0; offset <= size; ++offset) { for (unsigned int offset = 0; offset <= size; ++offset) {
typedef boost::unordered_multiset<std::string> container; typedef boost::unordered_multiset<std::string> container;
container x; container x;
for (unsigned int i = 0; i < size; ++i) { x.insert("multiple"); } for (unsigned int i = 0; i < size; ++i) {
x.insert("multiple");
}
BOOST_TEST_EQ(x.size(), size); BOOST_TEST_EQ(x.size(), size);
container::const_iterator position = x.cbegin(); container::const_iterator position = x.cbegin();
for (unsigned int i = 0; i < offset; ++i) { ++position; } for (unsigned int i = 0; i < offset; ++i) {
++position;
}
x.insert(position, "multiple"); x.insert(position, "multiple");
@@ -89,7 +97,8 @@ UNORDERED_AUTO_TEST(insert_hint_multiple) {
} }
} }
UNORDERED_AUTO_TEST(insert_hint_unique) { UNORDERED_AUTO_TEST(insert_hint_unique)
{
typedef boost::unordered_set<int> container; typedef boost::unordered_set<int> container;
container x; container x;
x.insert(x.cbegin(), 10); x.insert(x.cbegin(), 10);
@@ -98,7 +107,8 @@ UNORDERED_AUTO_TEST(insert_hint_unique) {
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
UNORDERED_AUTO_TEST(insert_hint_unique_single) { UNORDERED_AUTO_TEST(insert_hint_unique_single)
{
typedef boost::unordered_set<int> container; typedef boost::unordered_set<int> container;
container x; container x;
x.insert(10); x.insert(10);
@@ -114,7 +124,6 @@ UNORDERED_AUTO_TEST(insert_hint_unique_single) {
BOOST_TEST_EQ(x.count(20), 1u); BOOST_TEST_EQ(x.count(20), 1u);
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
} }
RUN_TESTS() RUN_TESTS()

View File

@@ -14,23 +14,25 @@
#include <iostream> #include <iostream>
namespace insert_stable namespace insert_stable {
struct member
{ {
struct member {
int tag1_; int tag1_;
int tag2_; int tag2_;
member() : tag1_(0), tag2_(0) {} member() : tag1_(0), tag2_(0) {}
member(int t1, int t2) : tag1_(t1), tag2_(t2) {} member(int t1, int t2) : tag1_(t1), tag2_(t2) {}
friend bool operator==(member const& x, member const& y) { friend bool operator==(member const& x, member const& y)
{
return x.tag1_ == y.tag1_; return x.tag1_ == y.tag1_;
} }
friend bool operator!=(member const& x, member const& y) { friend bool operator!=(member const& x, member const& y)
{
return x.tag1_ != y.tag1_; return x.tag1_ != y.tag1_;
} }
}; };
} }
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
@@ -39,51 +41,72 @@ namespace boost
namespace insert_stable namespace insert_stable
#endif #endif
{ {
std::size_t hash_value(insert_stable::member const& x) { std::size_t hash_value(insert_stable::member const& x)
{
return static_cast<std::size_t>(x.tag1_); return static_cast<std::size_t>(x.tag1_);
} }
} }
UNORDERED_AUTO_TEST(stable_insert_test1) { UNORDERED_AUTO_TEST(stable_insert_test1)
{
boost::unordered_multiset<insert_stable::member> x; boost::unordered_multiset<insert_stable::member> x;
x.insert(insert_stable::member(1,1)); x.insert(insert_stable::member(1, 1));
x.insert(insert_stable::member(1,2)); x.insert(insert_stable::member(1, 2));
x.insert(insert_stable::member(1,3)); x.insert(insert_stable::member(1, 3));
BOOST_TEST(x.count(insert_stable::member(1,4)) == 3); BOOST_TEST(x.count(insert_stable::member(1, 4)) == 3);
boost::unordered_multiset<insert_stable::member>::const_iterator boost::unordered_multiset<insert_stable::member>::const_iterator
it = x.begin(), end = x.end(); it = x.begin(),
end = x.end();
BOOST_TEST(it != end); BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->tag2_ == 1); ++it; } if (it != end) {
BOOST_TEST(it->tag2_ == 1);
++it;
}
BOOST_TEST(it != end); BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->tag2_ == 2); ++it; } if (it != end) {
BOOST_TEST(it->tag2_ == 2);
++it;
}
BOOST_TEST(it != end); BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->tag2_ == 3); ++it; } if (it != end) {
BOOST_TEST(it->tag2_ == 3);
++it;
}
BOOST_TEST(it == end); BOOST_TEST(it == end);
} }
UNORDERED_AUTO_TEST(stable_insert_test2) { UNORDERED_AUTO_TEST(stable_insert_test2)
{
boost::unordered_multimap<insert_stable::member, int> x; boost::unordered_multimap<insert_stable::member, int> x;
typedef typedef boost::unordered_multimap<insert_stable::member,
boost::unordered_multimap<insert_stable::member, int>::const_iterator int>::const_iterator iterator;
iterator;
iterator it = x.emplace(insert_stable::member(1,1), 1); iterator it = x.emplace(insert_stable::member(1, 1), 1);
it = x.emplace(insert_stable::member(1,2), 2); it = x.emplace(insert_stable::member(1, 2), 2);
it = x.emplace(insert_stable::member(1,3), 3); it = x.emplace(insert_stable::member(1, 3), 3);
BOOST_TEST(x.count(insert_stable::member(1,4)) == 3); BOOST_TEST(x.count(insert_stable::member(1, 4)) == 3);
it = x.begin(); it = x.begin();
iterator end = x.end(); iterator end = x.end();
BOOST_TEST(it != end); BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->first.tag2_ == 1 && it->second == 1); ++it; } if (it != end) {
BOOST_TEST(it->first.tag2_ == 1 && it->second == 1);
++it;
}
BOOST_TEST(it != end); BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->first.tag2_ == 2 && it->second == 2); ++it; } if (it != end) {
BOOST_TEST(it->first.tag2_ == 2 && it->second == 2);
++it;
}
BOOST_TEST(it != end); BOOST_TEST(it != end);
if(it != end) { BOOST_TEST(it->first.tag2_ == 3 && it->second == 3); ++it; } if (it != end) {
BOOST_TEST(it->first.tag2_ == 3 && it->second == 3);
++it;
}
BOOST_TEST(it == end); BOOST_TEST(it == end);
} }

View File

@@ -33,30 +33,30 @@ void unique_insert_tests1(X*, test::random_generator generator)
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator; typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
typedef test::ordered<X> ordered; typedef test::ordered<X> ordered;
std::cerr<<"insert(value) tests for containers with unique keys.\n"; std::cerr << "insert(value) tests for containers with unique keys.\n";
X x; X x;
test::ordered<X> tracker = test::create_ordered(x); test::ordered<X> tracker = test::create_ordered(x);
test::random_values<X> v(1000, generator); test::random_values<X> v(1000, generator);
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin(); for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
it != v.end(); ++it) it != v.end(); ++it) {
{
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count(); BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
float b = x.max_load_factor(); float b = x.max_load_factor();
std::pair<iterator, bool> r1 = x.insert(*it); std::pair<iterator, bool> r1 = x.insert(*it);
std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool> std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool> r2 =
r2 = tracker.insert(*it); tracker.insert(*it);
BOOST_TEST(r1.second == r2.second); BOOST_TEST(r1.second == r2.second);
BOOST_TEST(*r1.first == *r2.first); BOOST_TEST(*r1.first == *r2.first);
tracker.compare_key(x, *it); tracker.compare_key(x, *it);
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count)) if (static_cast<double>(x.size()) <=
b * static_cast<double>(old_bucket_count))
BOOST_TEST(x.bucket_count() == old_bucket_count); BOOST_TEST(x.bucket_count() == old_bucket_count);
} }
@@ -66,45 +66,43 @@ void unique_insert_tests1(X*, test::random_generator generator)
template <class X> template <class X>
void equivalent_insert_tests1(X*, test::random_generator generator) void equivalent_insert_tests1(X*, test::random_generator generator)
{ {
std::cerr<<"insert(value) tests for containers with equivalent keys.\n"; std::cerr << "insert(value) tests for containers with equivalent keys.\n";
test::check_instances check_; test::check_instances check_;
X x; X x;
test::ordered<X> tracker = test::create_ordered(x); test::ordered<X> tracker = test::create_ordered(x);
test::random_values<X> v(1000, generator); test::random_values<X> v(1000, generator);
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin(); for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
it != v.end(); ++it) it != v.end(); ++it) {
{
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count(); BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
float b = x.max_load_factor(); float b = x.max_load_factor();
BOOST_DEDUCED_TYPENAME X::iterator r1 = x.insert(*it); BOOST_DEDUCED_TYPENAME X::iterator r1 = x.insert(*it);
BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator r2 BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator r2 =
= tracker.insert(*it); tracker.insert(*it);
BOOST_TEST(*r1 == *r2); BOOST_TEST(*r1 == *r2);
tracker.compare_key(x, *it); tracker.compare_key(x, *it);
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count)) if (static_cast<double>(x.size()) <=
b * static_cast<double>(old_bucket_count))
BOOST_TEST(x.bucket_count() == old_bucket_count); BOOST_TEST(x.bucket_count() == old_bucket_count);
} }
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
template <class X> template <class X> void insert_tests2(X*, test::random_generator generator)
void insert_tests2(X*, test::random_generator generator)
{ {
typedef BOOST_DEDUCED_TYPENAME test::ordered<X> tracker_type; typedef BOOST_DEDUCED_TYPENAME test::ordered<X> tracker_type;
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator; typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator; typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator;
typedef BOOST_DEDUCED_TYPENAME tracker_type::iterator tracker_iterator; typedef BOOST_DEDUCED_TYPENAME tracker_type::iterator tracker_iterator;
std::cerr<<"insert(begin(), value) tests.\n"; std::cerr << "insert(begin(), value) tests.\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -113,11 +111,11 @@ void insert_tests2(X*, test::random_generator generator)
tracker_type tracker = test::create_ordered(x); tracker_type tracker = test::create_ordered(x);
test::random_values<X> v(1000, generator); test::random_values<X> v(1000, generator);
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it =
it = v.begin(); it != v.end(); ++it) v.begin();
{ it != v.end(); ++it) {
BOOST_DEDUCED_TYPENAME X::size_type BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count =
old_bucket_count = x.bucket_count(); x.bucket_count();
float b = x.max_load_factor(); float b = x.max_load_factor();
iterator r1 = x.insert(x.begin(), *it); iterator r1 = x.insert(x.begin(), *it);
@@ -125,7 +123,8 @@ void insert_tests2(X*, test::random_generator generator)
BOOST_TEST(*r1 == *r2); BOOST_TEST(*r1 == *r2);
tracker.compare_key(x, *it); tracker.compare_key(x, *it);
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count)) if (static_cast<double>(x.size()) <=
b * static_cast<double>(old_bucket_count))
BOOST_TEST(x.bucket_count() == old_bucket_count); BOOST_TEST(x.bucket_count() == old_bucket_count);
} }
@@ -133,7 +132,7 @@ void insert_tests2(X*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"insert(end(), value) tests.\n"; std::cerr << "insert(end(), value) tests.\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -143,11 +142,11 @@ void insert_tests2(X*, test::random_generator generator)
tracker_type tracker = test::create_ordered(x); tracker_type tracker = test::create_ordered(x);
test::random_values<X> v(100, generator); test::random_values<X> v(100, generator);
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it =
it = v.begin(); it != v.end(); ++it) v.begin();
{ it != v.end(); ++it) {
BOOST_DEDUCED_TYPENAME X::size_type BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count =
old_bucket_count = x.bucket_count(); x.bucket_count();
float b = x.max_load_factor(); float b = x.max_load_factor();
const_iterator r1 = x.insert(x_const.end(), *it); const_iterator r1 = x.insert(x_const.end(), *it);
@@ -155,7 +154,8 @@ void insert_tests2(X*, test::random_generator generator)
BOOST_TEST(*r1 == *r2); BOOST_TEST(*r1 == *r2);
tracker.compare_key(x, *it); tracker.compare_key(x, *it);
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count)) if (static_cast<double>(x.size()) <=
b * static_cast<double>(old_bucket_count))
BOOST_TEST(x.bucket_count() == old_bucket_count); BOOST_TEST(x.bucket_count() == old_bucket_count);
} }
@@ -163,7 +163,7 @@ void insert_tests2(X*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"insert(pos, value) tests.\n"; std::cerr << "insert(pos, value) tests.\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -173,11 +173,11 @@ void insert_tests2(X*, test::random_generator generator)
tracker_type tracker = test::create_ordered(x); tracker_type tracker = test::create_ordered(x);
test::random_values<X> v(1000, generator); test::random_values<X> v(1000, generator);
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it =
it = v.begin(); it != v.end(); ++it) v.begin();
{ it != v.end(); ++it) {
BOOST_DEDUCED_TYPENAME X::size_type BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count =
old_bucket_count = x.bucket_count(); x.bucket_count();
float b = x.max_load_factor(); float b = x.max_load_factor();
pos = x.insert(pos, *it); pos = x.insert(pos, *it);
@@ -185,7 +185,8 @@ void insert_tests2(X*, test::random_generator generator)
BOOST_TEST(*pos == *r2); BOOST_TEST(*pos == *r2);
tracker.compare_key(x, *it); tracker.compare_key(x, *it);
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count)) if (static_cast<double>(x.size()) <=
b * static_cast<double>(old_bucket_count))
BOOST_TEST(x.bucket_count() == old_bucket_count); BOOST_TEST(x.bucket_count() == old_bucket_count);
} }
@@ -193,7 +194,7 @@ void insert_tests2(X*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"insert single item range tests.\n"; std::cerr << "insert single item range tests.\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -202,18 +203,19 @@ void insert_tests2(X*, test::random_generator generator)
tracker_type tracker = test::create_ordered(x); tracker_type tracker = test::create_ordered(x);
test::random_values<X> v(1000, generator); test::random_values<X> v(1000, generator);
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it =
it = v.begin(); it != v.end(); ++it) v.begin();
{ it != v.end(); ++it) {
BOOST_DEDUCED_TYPENAME X::size_type BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count =
old_bucket_count = x.bucket_count(); x.bucket_count();
float b = x.max_load_factor(); float b = x.max_load_factor();
x.insert(it, test::next(it)); x.insert(it, test::next(it));
tracker.insert(*it); tracker.insert(*it);
tracker.compare_key(x, *it); tracker.compare_key(x, *it);
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count)) if (static_cast<double>(x.size()) <=
b * static_cast<double>(old_bucket_count))
BOOST_TEST(x.bucket_count() == old_bucket_count); BOOST_TEST(x.bucket_count() == old_bucket_count);
} }
@@ -221,7 +223,7 @@ void insert_tests2(X*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"insert range tests.\n"; std::cerr << "insert range tests.\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -235,7 +237,7 @@ void insert_tests2(X*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"insert range with rehash tests.\n"; std::cerr << "insert range with rehash tests.\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -253,7 +255,7 @@ void insert_tests2(X*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"insert input iterator range tests.\n"; std::cerr << "insert input iterator range tests.\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -262,14 +264,15 @@ void insert_tests2(X*, test::random_generator generator)
test::random_values<X> v(1000, generator); test::random_values<X> v(1000, generator);
BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator
begin = v.begin(), end = v.end(); begin = v.begin(),
end = v.end();
x.insert(test::input_iterator(begin), test::input_iterator(end)); x.insert(test::input_iterator(begin), test::input_iterator(end));
test::check_container(x, v); test::check_container(x, v);
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"insert copy iterator range tests.\n"; std::cerr << "insert copy iterator range tests.\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -283,7 +286,7 @@ void insert_tests2(X*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"insert copy iterator range test 2.\n"; std::cerr << "insert copy iterator range test 2.\n";
{ {
test::check_instances check_; test::check_instances check_;
@@ -292,13 +295,15 @@ void insert_tests2(X*, test::random_generator generator)
test::random_values<X> v1(500, generator); test::random_values<X> v1(500, generator);
test::random_values<X> v2(500, generator); test::random_values<X> v2(500, generator);
x.insert(test::copy_iterator(v1.begin()), test::copy_iterator(v1.end())); x.insert(
x.insert(test::copy_iterator(v2.begin()), test::copy_iterator(v2.end())); test::copy_iterator(v1.begin()), test::copy_iterator(v1.end()));
x.insert(
test::copy_iterator(v2.begin()), test::copy_iterator(v2.end()));
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
std::cerr<<"insert various ranges.\n"; std::cerr << "insert various ranges.\n";
{ {
for (int i = 0; i < 100; ++i) { for (int i = 0; i < 100; ++i) {
@@ -307,17 +312,20 @@ void insert_tests2(X*, test::random_generator generator)
test::random_values<X> v(1000, generator); test::random_values<X> v(1000, generator);
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it =
it = v.begin(); it != v.end();) v.begin();
{ it != v.end();) {
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count(); BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count =
x.bucket_count();
float b = x.max_load_factor(); float b = x.max_load_factor();
BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator next =
next = it; it;
for (std::size_t j = test::random_value(20); j > 0; ++j) { for (std::size_t j = test::random_value(20); j > 0; ++j) {
++next; ++next;
if (next == v.end()) { break; } if (next == v.end()) {
break;
}
} }
x.insert(it, next); x.insert(it, next);
@@ -326,7 +334,8 @@ void insert_tests2(X*, test::random_generator generator)
tracker.compare(x); // Slow, but I can't see any other way. tracker.compare(x); // Slow, but I can't see any other way.
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count)) if (static_cast<double>(x.size()) <=
b * static_cast<double>(old_bucket_count))
BOOST_TEST(x.bucket_count() == old_bucket_count); BOOST_TEST(x.bucket_count() == old_bucket_count);
} }
@@ -341,30 +350,30 @@ void unique_emplace_tests1(X*, test::random_generator generator)
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator; typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
typedef test::ordered<X> ordered; typedef test::ordered<X> ordered;
std::cerr<<"emplace(value) tests for containers with unique keys.\n"; std::cerr << "emplace(value) tests for containers with unique keys.\n";
X x; X x;
test::ordered<X> tracker = test::create_ordered(x); test::ordered<X> tracker = test::create_ordered(x);
test::random_values<X> v(1000, generator); test::random_values<X> v(1000, generator);
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin(); for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
it != v.end(); ++it) it != v.end(); ++it) {
{
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count(); BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
float b = x.max_load_factor(); float b = x.max_load_factor();
std::pair<iterator, bool> r1 = x.emplace(*it); std::pair<iterator, bool> r1 = x.emplace(*it);
std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool> std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool> r2 =
r2 = tracker.insert(*it); tracker.insert(*it);
BOOST_TEST(r1.second == r2.second); BOOST_TEST(r1.second == r2.second);
BOOST_TEST(*r1.first == *r2.first); BOOST_TEST(*r1.first == *r2.first);
tracker.compare_key(x, *it); tracker.compare_key(x, *it);
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count)) if (static_cast<double>(x.size()) <=
b * static_cast<double>(old_bucket_count))
BOOST_TEST(x.bucket_count() == old_bucket_count); BOOST_TEST(x.bucket_count() == old_bucket_count);
} }
@@ -375,27 +384,27 @@ void unique_emplace_tests1(X*, test::random_generator generator)
template <class X> template <class X>
void equivalent_emplace_tests1(X*, test::random_generator generator) void equivalent_emplace_tests1(X*, test::random_generator generator)
{ {
std::cerr<<"emplace(value) tests for containers with equivalent keys.\n"; std::cerr << "emplace(value) tests for containers with equivalent keys.\n";
X x; X x;
test::ordered<X> tracker = test::create_ordered(x); test::ordered<X> tracker = test::create_ordered(x);
test::random_values<X> v(1000, generator); test::random_values<X> v(1000, generator);
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin(); for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
it != v.end(); ++it) it != v.end(); ++it) {
{
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count(); BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
float b = x.max_load_factor(); float b = x.max_load_factor();
BOOST_DEDUCED_TYPENAME X::iterator r1 = x.emplace(*it); BOOST_DEDUCED_TYPENAME X::iterator r1 = x.emplace(*it);
BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator r2 =
r2 = tracker.insert(*it); tracker.insert(*it);
BOOST_TEST(*r1 == *r2); BOOST_TEST(*r1 == *r2);
tracker.compare_key(x, *it); tracker.compare_key(x, *it);
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count)) if (static_cast<double>(x.size()) <=
b * static_cast<double>(old_bucket_count))
BOOST_TEST(x.bucket_count() == old_bucket_count); BOOST_TEST(x.bucket_count() == old_bucket_count);
} }
@@ -403,19 +412,18 @@ void equivalent_emplace_tests1(X*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
template <class X> template <class X> void move_emplace_tests(X*, test::random_generator generator)
void move_emplace_tests(X*, test::random_generator generator)
{ {
std::cerr<<"emplace(move(value)) tests for containers with unique keys.\n"; std::cerr
<< "emplace(move(value)) tests for containers with unique keys.\n";
X x; X x;
test::ordered<X> tracker = test::create_ordered(x); test::ordered<X> tracker = test::create_ordered(x);
test::random_values<X> v(1000, generator); test::random_values<X> v(1000, generator);
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin(); for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
it != v.end(); ++it) it != v.end(); ++it) {
{
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count(); BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
float b = x.max_load_factor(); float b = x.max_load_factor();
@@ -425,7 +433,8 @@ void move_emplace_tests(X*, test::random_generator generator)
tracker.insert(*it); tracker.insert(*it);
tracker.compare_key(x, *it); tracker.compare_key(x, *it);
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count)) if (static_cast<double>(x.size()) <=
b * static_cast<double>(old_bucket_count))
BOOST_TEST(x.bucket_count() == old_bucket_count); BOOST_TEST(x.bucket_count() == old_bucket_count);
} }
@@ -433,11 +442,10 @@ void move_emplace_tests(X*, test::random_generator generator)
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
template <class X> template <class X> void default_emplace_tests(X*, test::random_generator)
void default_emplace_tests(X*, test::random_generator)
{ {
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100)) #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
std::cerr<<"emplace() tests.\n"; std::cerr << "emplace() tests.\n";
bool is_unique = test::has_unique_keys<X>::value; bool is_unique = test::has_unique_keys<X>::value;
X x; X x;
@@ -470,18 +478,16 @@ void default_emplace_tests(X*, test::random_generator)
#endif #endif
} }
template <class X> template <class X> void map_tests(X*, test::random_generator generator)
void map_tests(X*, test::random_generator generator)
{ {
std::cerr<<"map tests.\n"; std::cerr << "map tests.\n";
X x; X x;
test::ordered<X> tracker = test::create_ordered(x); test::ordered<X> tracker = test::create_ordered(x);
test::random_values<X> v(1000, generator); test::random_values<X> v(1000, generator);
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin(); for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
it != v.end(); ++it) it != v.end(); ++it) {
{
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count(); BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
float b = x.max_load_factor(); float b = x.max_load_factor();
@@ -490,7 +496,8 @@ void map_tests(X*, test::random_generator generator)
tracker.compare_key(x, *it); tracker.compare_key(x, *it);
if(static_cast<double>(x.size()) <= b * static_cast<double>(old_bucket_count)) if (static_cast<double>(x.size()) <=
b * static_cast<double>(old_bucket_count))
BOOST_TEST(x.bucket_count() == old_bucket_count); BOOST_TEST(x.bucket_count() == old_bucket_count);
} }
@@ -504,20 +511,18 @@ void map_tests(X*, test::random_generator generator)
template <class X> template <class X>
void map_insert_range_test1(X*, test::random_generator generator) void map_insert_range_test1(X*, test::random_generator generator)
{ {
std::cerr<<"map_insert_range_test1\n"; std::cerr << "map_insert_range_test1\n";
test::check_instances check_; test::check_instances check_;
typedef test::list< typedef test::list<std::pair<BOOST_DEDUCED_TYPENAME X::key_type,
std::pair< BOOST_DEDUCED_TYPENAME X::mapped_type> >
BOOST_DEDUCED_TYPENAME X::key_type, list;
BOOST_DEDUCED_TYPENAME X::mapped_type
>
> list;
test::random_values<X> v(1000, generator); test::random_values<X> v(1000, generator);
list l(v.begin(), v.end()); list l(v.begin(), v.end());
X x; x.insert(l.begin(), l.end()); X x;
x.insert(l.begin(), l.end());
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
@@ -525,98 +530,83 @@ void map_insert_range_test1(X*, test::random_generator generator)
template <class X> template <class X>
void map_insert_range_test2(X*, test::random_generator generator) void map_insert_range_test2(X*, test::random_generator generator)
{ {
std::cerr<<"map_insert_range_test2\n"; std::cerr << "map_insert_range_test2\n";
test::check_instances check_; test::check_instances check_;
typedef test::list< typedef test::list<std::pair<BOOST_DEDUCED_TYPENAME X::key_type const,
std::pair<BOOST_DEDUCED_TYPENAME X::key_type const, test::implicitly_convertible> test::implicitly_convertible> >
> list; list;
test::random_values< test::random_values<boost::unordered_map<BOOST_DEDUCED_TYPENAME X::key_type,
boost::unordered_map<BOOST_DEDUCED_TYPENAME X::key_type, test::implicitly_convertible> test::implicitly_convertible> >
> v(1000, generator); v(1000, generator);
list l(v.begin(), v.end()); list l(v.begin(), v.end());
X x; x.insert(l.begin(), l.end()); X x;
x.insert(l.begin(), l.end());
test::check_equivalent_keys(x); test::check_equivalent_keys(x);
} }
boost::unordered_set<test::movable, boost::unordered_set<test::movable, test::hash, test::equal_to,
test::hash, test::equal_to,
std::allocator<test::movable> >* test_set_std_alloc; std::allocator<test::movable> >* test_set_std_alloc;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to, std::allocator<test::object> >* test_multimap_std_alloc;
std::allocator<test::object> >* test_multimap_std_alloc;
boost::unordered_set<test::object, boost::unordered_set<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator1<test::object> >* test_set; test::allocator1<test::object> >* test_set;
boost::unordered_multiset<test::movable, boost::unordered_multiset<test::movable, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator2<test::movable> >* test_multiset; test::allocator2<test::movable> >* test_multiset;
boost::unordered_map<test::movable, test::movable, boost::unordered_map<test::movable, test::movable, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator2<test::movable> >* test_map; test::allocator2<test::movable> >* test_map;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to, test::allocator1<test::object> >* test_multimap;
test::allocator1<test::object> >* test_multimap;
using test::default_generator; using test::default_generator;
using test::generate_collisions; using test::generate_collisions;
using test::limited_range; using test::limited_range;
UNORDERED_TEST(unique_insert_tests1, UNORDERED_TEST(unique_insert_tests1,
((test_set_std_alloc)(test_set)(test_map)) ((test_set_std_alloc)(test_set)(test_map))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
UNORDERED_TEST(equivalent_insert_tests1, UNORDERED_TEST(equivalent_insert_tests1,
((test_multimap_std_alloc)(test_multiset)(test_multimap)) ((test_multimap_std_alloc)(test_multiset)(test_multimap))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
UNORDERED_TEST(insert_tests2, UNORDERED_TEST(
((test_multimap_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap)) insert_tests2, ((test_multimap_std_alloc)(test_set)(test_multiset)(
((default_generator)(generate_collisions)(limited_range)) test_map)(test_multimap))(
) (default_generator)(generate_collisions)(limited_range)))
UNORDERED_TEST(unique_emplace_tests1, UNORDERED_TEST(unique_emplace_tests1,
((test_set_std_alloc)(test_set)(test_map)) ((test_set_std_alloc)(test_set)(test_map))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
UNORDERED_TEST(equivalent_emplace_tests1, UNORDERED_TEST(equivalent_emplace_tests1,
((test_multimap_std_alloc)(test_multiset)(test_multimap)) ((test_multimap_std_alloc)(test_multiset)(test_multimap))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
UNORDERED_TEST(move_emplace_tests, UNORDERED_TEST(move_emplace_tests,
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map) ((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)(
(test_multiset)(test_multimap)) test_multiset)(test_multimap))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
UNORDERED_TEST(default_emplace_tests, UNORDERED_TEST(default_emplace_tests,
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map) ((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)(
(test_multiset)(test_multimap)) test_multiset)(test_multimap))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
UNORDERED_TEST(map_tests, UNORDERED_TEST(map_tests,
((test_map)) ((test_map))((default_generator)(generate_collisions)(limited_range)))
((default_generator)(generate_collisions)(limited_range))
)
UNORDERED_TEST(map_insert_range_test1, UNORDERED_TEST(map_insert_range_test1,
((test_multimap_std_alloc)(test_map)(test_multimap)) ((test_multimap_std_alloc)(test_map)(test_multimap))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
UNORDERED_TEST(map_insert_range_test2, UNORDERED_TEST(map_insert_range_test2,
((test_multimap_std_alloc)(test_map)(test_multimap)) ((test_multimap_std_alloc)(test_map)(test_multimap))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
@@ -638,7 +628,7 @@ struct initialize_from_two_ints
UNORDERED_AUTO_TEST(insert_initializer_list_set) UNORDERED_AUTO_TEST(insert_initializer_list_set)
{ {
boost::unordered_set<int> set; boost::unordered_set<int> set;
set.insert({1,2,3,1}); set.insert({1, 2, 3, 1});
BOOST_TEST_EQ(set.size(), 3u); BOOST_TEST_EQ(set.size(), 3u);
BOOST_TEST(set.find(1) != set.end()); BOOST_TEST(set.find(1) != set.end());
BOOST_TEST(set.find(4) == set.end()); BOOST_TEST(set.find(4) == set.end());
@@ -651,25 +641,25 @@ UNORDERED_AUTO_TEST(insert_initializer_list_set)
set2.insert({1, 2}); set2.insert({1, 2});
#endif #endif
BOOST_TEST(set2.size() == 1); BOOST_TEST(set2.size() == 1);
BOOST_TEST(set2.find({1,2}) != set2.end()); BOOST_TEST(set2.find({1, 2}) != set2.end());
BOOST_TEST(set2.find({2,1}) == set2.end()); BOOST_TEST(set2.find({2, 1}) == set2.end());
set2.insert({{3,4},{5,6},{7,8}}); set2.insert({{3, 4}, {5, 6}, {7, 8}});
BOOST_TEST(set2.size() == 4); BOOST_TEST(set2.size() == 4);
BOOST_TEST(set2.find({1,2}) != set2.end()); BOOST_TEST(set2.find({1, 2}) != set2.end());
BOOST_TEST(set2.find({3,4}) != set2.end()); BOOST_TEST(set2.find({3, 4}) != set2.end());
BOOST_TEST(set2.find({5,6}) != set2.end()); BOOST_TEST(set2.find({5, 6}) != set2.end());
BOOST_TEST(set2.find({7,8}) != set2.end()); BOOST_TEST(set2.find({7, 8}) != set2.end());
BOOST_TEST(set2.find({8,7}) == set2.end()); BOOST_TEST(set2.find({8, 7}) == set2.end());
set2.insert({{2, 1}, {3,4}}); set2.insert({{2, 1}, {3, 4}});
BOOST_TEST(set2.size() == 5); BOOST_TEST(set2.size() == 5);
BOOST_TEST(set2.find({1,2}) != set2.end()); BOOST_TEST(set2.find({1, 2}) != set2.end());
BOOST_TEST(set2.find({2,1}) != set2.end()); BOOST_TEST(set2.find({2, 1}) != set2.end());
BOOST_TEST(set2.find({3,4}) != set2.end()); BOOST_TEST(set2.find({3, 4}) != set2.end());
BOOST_TEST(set2.find({5,6}) != set2.end()); BOOST_TEST(set2.find({5, 6}) != set2.end());
BOOST_TEST(set2.find({7,8}) != set2.end()); BOOST_TEST(set2.find({7, 8}) != set2.end());
BOOST_TEST(set2.find({8,7}) == set2.end()); BOOST_TEST(set2.find({8, 7}) == set2.end());
} }
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1800) #if !BOOST_WORKAROUND(BOOST_MSVC, == 1800)
@@ -677,13 +667,13 @@ UNORDERED_AUTO_TEST(insert_initializer_list_set)
UNORDERED_AUTO_TEST(insert_initializer_list_multiset) UNORDERED_AUTO_TEST(insert_initializer_list_multiset)
{ {
boost::unordered_multiset<std::string> multiset; boost::unordered_multiset<std::string> multiset;
//multiset.insert({}); // multiset.insert({});
BOOST_TEST(multiset.empty()); BOOST_TEST(multiset.empty());
multiset.insert({"a"}); multiset.insert({"a"});
BOOST_TEST_EQ(multiset.size(), 1u); BOOST_TEST_EQ(multiset.size(), 1u);
BOOST_TEST(multiset.find("a") != multiset.end()); BOOST_TEST(multiset.find("a") != multiset.end());
BOOST_TEST(multiset.find("b") == multiset.end()); BOOST_TEST(multiset.find("b") == multiset.end());
multiset.insert({"a","b"}); multiset.insert({"a", "b"});
BOOST_TEST(multiset.size() == 3); BOOST_TEST(multiset.size() == 3);
BOOST_TEST_EQ(multiset.count("a"), 2u); BOOST_TEST_EQ(multiset.count("a"), 2u);
BOOST_TEST_EQ(multiset.count("b"), 1u); BOOST_TEST_EQ(multiset.count("b"), 1u);
@@ -695,18 +685,18 @@ UNORDERED_AUTO_TEST(insert_initializer_list_multiset)
UNORDERED_AUTO_TEST(insert_initializer_list_map) UNORDERED_AUTO_TEST(insert_initializer_list_map)
{ {
boost::unordered_map<std::string, std::string> map; boost::unordered_map<std::string, std::string> map;
//map.insert({}); // map.insert({});
BOOST_TEST(map.empty()); BOOST_TEST(map.empty());
map.insert({{"a", "b"},{"a", "b"},{"d", ""}}); map.insert({{"a", "b"}, {"a", "b"}, {"d", ""}});
BOOST_TEST_EQ(map.size(), 2u); BOOST_TEST_EQ(map.size(), 2u);
} }
UNORDERED_AUTO_TEST(insert_initializer_list_multimap) UNORDERED_AUTO_TEST(insert_initializer_list_multimap)
{ {
boost::unordered_multimap<std::string, std::string> multimap; boost::unordered_multimap<std::string, std::string> multimap;
//multimap.insert({}); // multimap.insert({});
BOOST_TEST(multimap.empty()); BOOST_TEST(multimap.empty());
multimap.insert({{"a", "b"},{"a", "b"},{"d", ""}}); multimap.insert({{"a", "b"}, {"a", "b"}, {"d", ""}});
BOOST_TEST_EQ(multimap.size(), 3u); BOOST_TEST_EQ(multimap.size(), 3u);
BOOST_TEST_EQ(multimap.count("a"), 2u); BOOST_TEST_EQ(multimap.count("a"), 2u);
} }
@@ -716,7 +706,9 @@ UNORDERED_AUTO_TEST(insert_initializer_list_multimap)
struct overloaded_constructor struct overloaded_constructor
{ {
overloaded_constructor(int x1_ = 1, int x2_ = 2, int x3_ = 3, int x4_ = 4) overloaded_constructor(int x1_ = 1, int x2_ = 2, int x3_ = 3, int x4_ = 4)
: x1(x1_), x2(x2_), x3(x3_), x4(x4_) {} : x1(x1_), x2(x2_), x3(x3_), x4(x4_)
{
}
int x1, x2, x3, x4; int x1, x2, x3, x4;
@@ -742,13 +734,13 @@ UNORDERED_AUTO_TEST(map_emplace_test)
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100)) #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
x.emplace(); x.emplace();
BOOST_TEST(x.find(0) != x.end() && BOOST_TEST(
x.find(0)->second == overloaded_constructor()); x.find(0) != x.end() && x.find(0)->second == overloaded_constructor());
#endif #endif
x.emplace(2, 3); x.emplace(2, 3);
BOOST_TEST(x.find(2) != x.end() && BOOST_TEST(
x.find(2)->second == overloaded_constructor(3)); x.find(2) != x.end() && x.find(2)->second == overloaded_constructor(3));
} }
UNORDERED_AUTO_TEST(set_emplace_test) UNORDERED_AUTO_TEST(set_emplace_test)
@@ -782,15 +774,20 @@ UNORDERED_AUTO_TEST(set_emplace_test)
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
} }
struct derived_from_piecewise_construct_t : struct derived_from_piecewise_construct_t
boost::unordered::piecewise_construct_t {}; : boost::unordered::piecewise_construct_t
{
};
derived_from_piecewise_construct_t piecewise_rvalue() { derived_from_piecewise_construct_t piecewise_rvalue()
{
return derived_from_piecewise_construct_t(); return derived_from_piecewise_construct_t();
} }
struct convertible_to_piecewise { struct convertible_to_piecewise
operator boost::unordered::piecewise_construct_t() const { {
operator boost::unordered::piecewise_construct_t() const
{
return boost::unordered::piecewise_construct; return boost::unordered::piecewise_construct;
} }
}; };
@@ -799,38 +796,50 @@ UNORDERED_AUTO_TEST(map_emplace_test2)
{ {
boost::unordered_map<overloaded_constructor, overloaded_constructor> x; boost::unordered_map<overloaded_constructor, overloaded_constructor> x;
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(), boost::make_tuple()); x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(),
BOOST_TEST(x.find(overloaded_constructor()) != x.end() && boost::make_tuple());
BOOST_TEST(
x.find(overloaded_constructor()) != x.end() &&
x.find(overloaded_constructor())->second == overloaded_constructor()); x.find(overloaded_constructor())->second == overloaded_constructor());
x.emplace(convertible_to_piecewise(), boost::make_tuple(1), boost::make_tuple()); x.emplace(
BOOST_TEST(x.find(overloaded_constructor(1)) != x.end() && convertible_to_piecewise(), boost::make_tuple(1), boost::make_tuple());
BOOST_TEST(
x.find(overloaded_constructor(1)) != x.end() &&
x.find(overloaded_constructor(1))->second == overloaded_constructor()); x.find(overloaded_constructor(1))->second == overloaded_constructor());
x.emplace(piecewise_rvalue(), boost::make_tuple(2,3), boost::make_tuple(4,5,6)); x.emplace(piecewise_rvalue(), boost::make_tuple(2, 3),
BOOST_TEST(x.find(overloaded_constructor(2,3)) != x.end() && boost::make_tuple(4, 5, 6));
x.find(overloaded_constructor(2,3))->second == overloaded_constructor(4,5,6)); BOOST_TEST(x.find(overloaded_constructor(2, 3)) != x.end() &&
x.find(overloaded_constructor(2, 3))->second ==
overloaded_constructor(4, 5, 6));
derived_from_piecewise_construct_t d; derived_from_piecewise_construct_t d;
x.emplace(d, boost::make_tuple(9,3,1), boost::make_tuple(10)); x.emplace(d, boost::make_tuple(9, 3, 1), boost::make_tuple(10));
BOOST_TEST(x.find(overloaded_constructor(9,3,1)) != x.end() && BOOST_TEST(x.find(overloaded_constructor(9, 3, 1)) != x.end() &&
x.find(overloaded_constructor(9,3,1))->second == overloaded_constructor(10)); x.find(overloaded_constructor(9, 3, 1))->second ==
overloaded_constructor(10));
} }
UNORDERED_AUTO_TEST(set_emplace_test2) UNORDERED_AUTO_TEST(set_emplace_test2)
{ {
boost::unordered_set<std::pair<overloaded_constructor, overloaded_constructor> > x; boost::unordered_set<
std::pair<overloaded_constructor, overloaded_constructor> >
x;
std::pair<overloaded_constructor, overloaded_constructor> check; std::pair<overloaded_constructor, overloaded_constructor> check;
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(), boost::make_tuple()); x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(),
boost::make_tuple());
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
x.clear(); x.clear();
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(1), boost::make_tuple(2,3)); x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(1),
check = std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3));; boost::make_tuple(2, 3));
check =
std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3));
;
BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check); BOOST_TEST(x.find(check) != x.end() && *x.find(check) == check);
} }
} }
RUN_TESTS() RUN_TESTS()

View File

@@ -10,10 +10,8 @@
#include "../helpers/postfix.hpp" #include "../helpers/postfix.hpp"
// clang-format on // clang-format on
void foo(boost::unordered_set<int>&, void foo(boost::unordered_set<int>&, boost::unordered_map<int, int>&,
boost::unordered_map<int, int>&, boost::unordered_multiset<int>&, boost::unordered_multimap<int, int>&);
boost::unordered_multiset<int>&,
boost::unordered_multimap<int, int>&);
int main() int main()
{ {

View File

@@ -10,13 +10,12 @@
#include "../helpers/postfix.hpp" #include "../helpers/postfix.hpp"
// clang-format on // clang-format on
void foo(boost::unordered_set<int>& x1, void foo(boost::unordered_set<int>& x1, boost::unordered_map<int, int>& x2,
boost::unordered_map<int, int>& x2, boost::unordered_multiset<int>& x3, boost::unordered_multimap<int, int>& x4)
boost::unordered_multiset<int>& x3,
boost::unordered_multimap<int, int>& x4)
{ {
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613)) #if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
struct dummy { struct dummy
{
boost::unordered_set<int> x1; boost::unordered_set<int> x1;
boost::unordered_map<int, int> x2; boost::unordered_map<int, int> x2;
boost::unordered_multiset<int> x3; boost::unordered_multiset<int> x3;

View File

@@ -16,16 +16,14 @@
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
#pragma warning(push) #pragma warning(push)
#pragma warning(disable:4127) // conditional expression is constant #pragma warning(disable : 4127) // conditional expression is constant
#endif #endif
namespace load_factor_tests namespace load_factor_tests {
{
test::seed_t initialize_seed(783656); test::seed_t initialize_seed(783656);
template <class X> template <class X> void set_load_factor_tests(X*)
void set_load_factor_tests(X*)
{ {
X x; X x;
@@ -34,8 +32,10 @@ void set_load_factor_tests(X*)
// A valid implementation could fail these tests, but I think they're // A valid implementation could fail these tests, but I think they're
// reasonable. // reasonable.
x.max_load_factor(2.0); BOOST_TEST(x.max_load_factor() == 2.0); x.max_load_factor(2.0);
x.max_load_factor(0.5); BOOST_TEST(x.max_load_factor() == 0.5); BOOST_TEST(x.max_load_factor() == 2.0);
x.max_load_factor(0.5);
BOOST_TEST(x.max_load_factor() == 0.5);
} }
template <class X> template <class X>
@@ -47,13 +47,15 @@ void insert_test(X*, float mlf, test::random_generator generator)
test::random_values<X> values(1000, generator); test::random_values<X> values(1000, generator);
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator for (BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator
it = values.begin(), end = values.end(); it != end; ++it) it = values.begin(),
{ end = values.end();
it != end; ++it) {
BOOST_DEDUCED_TYPENAME X::size_type old_size = x.size(), BOOST_DEDUCED_TYPENAME X::size_type old_size = x.size(),
old_bucket_count = x.bucket_count(); old_bucket_count = x.bucket_count();
x.insert(*it); x.insert(*it);
if(static_cast<double>(old_size + 1) <= b * static_cast<double>(old_bucket_count)) if (static_cast<double>(old_size + 1) <=
b * static_cast<double>(old_bucket_count))
BOOST_TEST(x.bucket_count() == old_bucket_count); BOOST_TEST(x.bucket_count() == old_bucket_count);
} }
} }
@@ -65,12 +67,10 @@ void load_factor_insert_tests(X* ptr, test::random_generator generator)
insert_test(ptr, 0.1f, generator); insert_test(ptr, 0.1f, generator);
insert_test(ptr, 100.0f, generator); insert_test(ptr, 100.0f, generator);
insert_test(ptr, (std::numeric_limits<float>::min)(), insert_test(ptr, (std::numeric_limits<float>::min)(), generator);
generator);
if(std::numeric_limits<float>::has_infinity) if (std::numeric_limits<float>::has_infinity)
insert_test(ptr, std::numeric_limits<float>::infinity(), insert_test(ptr, std::numeric_limits<float>::infinity(), generator);
generator);
} }
boost::unordered_set<int>* int_set_ptr; boost::unordered_set<int>* int_set_ptr;
@@ -83,19 +83,16 @@ using test::generate_collisions;
using test::limited_range; using test::limited_range;
UNORDERED_TEST(set_load_factor_tests, UNORDERED_TEST(set_load_factor_tests,
((int_set_ptr)(int_multiset_ptr)(int_map_ptr)(int_multimap_ptr)) ((int_set_ptr)(int_multiset_ptr)(int_map_ptr)(int_multimap_ptr)))
)
UNORDERED_TEST(load_factor_insert_tests, UNORDERED_TEST(load_factor_insert_tests,
((int_set_ptr)(int_multiset_ptr)(int_map_ptr)(int_multimap_ptr)) ((int_set_ptr)(int_multiset_ptr)(int_map_ptr)(int_multimap_ptr))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
} }
RUN_TESTS() RUN_TESTS()
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
#pragma warning(pop) #pragma warning(pop)
#pragma warning(disable:4127) // conditional expression is constant #pragma warning(disable : 4127) // conditional expression is constant
#endif #endif

View File

@@ -3,60 +3,58 @@
// Distributed under the Boost Software License, Version 1.0. (See accompanying // 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) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/unordered/detail/implementation.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp>
#include "../objects/test.hpp" #include "../objects/test.hpp"
#include <boost/detail/lightweight_test.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/unordered/detail/implementation.hpp>
template <class Tp> template <class Tp> struct SimpleAllocator
struct SimpleAllocator
{ {
typedef Tp value_type; typedef Tp value_type;
SimpleAllocator() SimpleAllocator() {}
{
}
template <class T> SimpleAllocator(const SimpleAllocator<T>&) template <class T> SimpleAllocator(const SimpleAllocator<T>&) {}
{
}
Tp *allocate(std::size_t n) Tp* allocate(std::size_t n)
{ {
return static_cast<Tp*>(::operator new(n * sizeof(Tp))); return static_cast<Tp*>(::operator new(n * sizeof(Tp)));
} }
void deallocate(Tp* p, std::size_t) void deallocate(Tp* p, std::size_t) { ::operator delete((void*)p); }
{
::operator delete((void*) p);
}
}; };
template <typename T> template <typename T> void test_simple_allocator()
void test_simple_allocator()
{ {
test::check_instances check_; test::check_instances check_;
typedef boost::unordered::detail::allocator_traits< typedef boost::unordered::detail::allocator_traits<SimpleAllocator<T> >
SimpleAllocator<T> > traits; traits;
BOOST_STATIC_ASSERT((boost::is_same<typename traits::allocator_type, SimpleAllocator<T> >::value)); BOOST_STATIC_ASSERT((boost::is_same<typename traits::allocator_type,
SimpleAllocator<T> >::value));
BOOST_STATIC_ASSERT((boost::is_same<typename traits::value_type, T>::value)); BOOST_STATIC_ASSERT(
(boost::is_same<typename traits::value_type, T>::value));
BOOST_STATIC_ASSERT((boost::is_same<typename traits::pointer, T* >::value)); BOOST_STATIC_ASSERT((boost::is_same<typename traits::pointer, T*>::value));
BOOST_STATIC_ASSERT((boost::is_same<typename traits::const_pointer, T const*>::value)); BOOST_STATIC_ASSERT(
//BOOST_STATIC_ASSERT((boost::is_same<typename traits::void_pointer, void* >::value)); (boost::is_same<typename traits::const_pointer, T const*>::value));
//BOOST_STATIC_ASSERT((boost::is_same<typename traits::const_void_pointer, void const*>::value)); // BOOST_STATIC_ASSERT((boost::is_same<typename traits::void_pointer, void*
// >::value));
// BOOST_STATIC_ASSERT((boost::is_same<typename traits::const_void_pointer,
// void const*>::value));
BOOST_STATIC_ASSERT((boost::is_same<typename traits::difference_type, std::ptrdiff_t>::value)); BOOST_STATIC_ASSERT((boost::is_same<typename traits::difference_type,
std::ptrdiff_t>::value));
#if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 1 #if BOOST_UNORDERED_USE_ALLOCATOR_TRAITS == 1
BOOST_STATIC_ASSERT((boost::is_same<typename traits::size_type, BOOST_STATIC_ASSERT((boost::is_same<typename traits::size_type,
std::make_unsigned<std::ptrdiff_t>::type>::value)); std::make_unsigned<std::ptrdiff_t>::type>::value));
#else #else
BOOST_STATIC_ASSERT((boost::is_same<typename traits::size_type, std::size_t>::value)); BOOST_STATIC_ASSERT(
(boost::is_same<typename traits::size_type, std::size_t>::value));
#endif #endif
BOOST_TEST(!traits::propagate_on_container_copy_assignment::value); BOOST_TEST(!traits::propagate_on_container_copy_assignment::value);
@@ -69,18 +67,18 @@ void test_simple_allocator()
SimpleAllocator<T> a; SimpleAllocator<T> a;
T* ptr1 = traits::allocate(a, 1); T* ptr1 = traits::allocate(a, 1);
//T* ptr2 = traits::allocate(a, 1, static_cast<void const*>(ptr1)); // T* ptr2 = traits::allocate(a, 1, static_cast<void const*>(ptr1));
traits::construct(a, ptr1, T(10)); traits::construct(a, ptr1, T(10));
//traits::construct(a, ptr2, T(30), ptr1); // traits::construct(a, ptr2, T(30), ptr1);
BOOST_TEST(*ptr1 == T(10)); BOOST_TEST(*ptr1 == T(10));
//BOOST_TEST(*ptr2 == T(30)); // BOOST_TEST(*ptr2 == T(30));
traits::destroy(a, ptr1); traits::destroy(a, ptr1);
//traits::destroy(a, ptr2); // traits::destroy(a, ptr2);
//traits::deallocate(a, ptr2, 1); // traits::deallocate(a, ptr2, 1);
traits::deallocate(a, ptr1, 1); traits::deallocate(a, ptr1, 1);
traits::max_size(a); traits::max_size(a);

View File

@@ -19,48 +19,43 @@
#include "../helpers/invariants.hpp" #include "../helpers/invariants.hpp"
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
#pragma warning(disable:4127) // conditional expression is constant #pragma warning(disable : 4127) // conditional expression is constant
#endif #endif
namespace move_tests namespace move_tests {
{ test::seed_t initialize_seed(98624);
test::seed_t initialize_seed(98624); #if defined(BOOST_UNORDERED_USE_MOVE) || \
#if defined(BOOST_UNORDERED_USE_MOVE) || !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
#define BOOST_UNORDERED_TEST_MOVING 1 #define BOOST_UNORDERED_TEST_MOVING 1
#else #else
#define BOOST_UNORDERED_TEST_MOVING 0 #define BOOST_UNORDERED_TEST_MOVING 0
#endif #endif
template<class T> template <class T> T empty(T*) { return T(); }
T empty(T*) {
return T();
}
template<class T> template <class T>
T create(test::random_values<T> const& v, T create(test::random_values<T> const& v, test::object_count& count)
test::object_count& count) { {
T x(v.begin(), v.end()); T x(v.begin(), v.end());
count = test::global_object_count; count = test::global_object_count;
return x; return x;
} }
template<class T> template <class T>
T create(test::random_values<T> const& v, T create(test::random_values<T> const& v, test::object_count& count,
test::object_count& count, BOOST_DEDUCED_TYPENAME T::hasher hf, BOOST_DEDUCED_TYPENAME T::key_equal eq,
BOOST_DEDUCED_TYPENAME T::hasher hf, BOOST_DEDUCED_TYPENAME T::allocator_type al, float mlf)
BOOST_DEDUCED_TYPENAME T::key_equal eq, {
BOOST_DEDUCED_TYPENAME T::allocator_type al,
float mlf) {
T x(0, hf, eq, al); T x(0, hf, eq, al);
x.max_load_factor(mlf); x.max_load_factor(mlf);
x.insert(v.begin(), v.end()); x.insert(v.begin(), v.end());
count = test::global_object_count; count = test::global_object_count;
return x; return x;
} }
template <class T> template <class T>
void move_construct_tests1(T* ptr, test::random_generator const& generator) void move_construct_tests1(T* ptr, test::random_generator const& generator)
{ {
BOOST_DEDUCED_TYPENAME T::hasher hf; BOOST_DEDUCED_TYPENAME T::hasher hf;
BOOST_DEDUCED_TYPENAME T::key_equal eq; BOOST_DEDUCED_TYPENAME T::key_equal eq;
BOOST_DEDUCED_TYPENAME T::allocator_type al; BOOST_DEDUCED_TYPENAME T::allocator_type al;
@@ -89,11 +84,11 @@ namespace move_tests
test::check_container(y, v); test::check_container(y, v);
test::check_equivalent_keys(y); test::check_equivalent_keys(y);
} }
} }
template <class T> template <class T>
void move_assign_tests1(T*, test::random_generator const& generator) void move_assign_tests1(T*, test::random_generator const& generator)
{ {
{ {
test::check_instances check_; test::check_instances check_;
@@ -107,11 +102,11 @@ namespace move_tests
test::check_container(y, v); test::check_container(y, v);
test::check_equivalent_keys(y); test::check_equivalent_keys(y);
} }
} }
template <class T> template <class T>
void move_construct_tests2(T*, test::random_generator const& generator) void move_construct_tests2(T*, test::random_generator const& generator)
{ {
BOOST_DEDUCED_TYPENAME T::hasher hf(1); BOOST_DEDUCED_TYPENAME T::hasher hf(1);
BOOST_DEDUCED_TYPENAME T::key_equal eq(1); BOOST_DEDUCED_TYPENAME T::key_equal eq(1);
BOOST_DEDUCED_TYPENAME T::allocator_type al(1); BOOST_DEDUCED_TYPENAME T::allocator_type al(1);
@@ -160,15 +155,15 @@ namespace move_tests
BOOST_TEST(count == test::global_object_count); BOOST_TEST(count == test::global_object_count);
#elif defined(BOOST_HAS_NRVO) #elif defined(BOOST_HAS_NRVO)
BOOST_TEST( BOOST_TEST(
static_cast<std::size_t>(test::global_object_count.constructions static_cast<std::size_t>(test::global_object_count.constructions -
- count.constructions) <= count.constructions) <=
(test::is_set<T>::value ? 1 : 2) * (test::is_set<T>::value ? 1 : 2) *
(test::has_unique_keys<T>::value ? 25 : v.size())); (test::has_unique_keys<T>::value ? 25 : v.size()));
BOOST_TEST(count.instances == test::global_object_count.instances); BOOST_TEST(count.instances == test::global_object_count.instances);
#else #else
BOOST_TEST( BOOST_TEST(
static_cast<std::size_t>(test::global_object_count.constructions static_cast<std::size_t>(test::global_object_count.constructions -
- count.constructions) <= count.constructions) <=
(test::is_set<T>::value ? 2 : 4) * (test::is_set<T>::value ? 2 : 4) *
(test::has_unique_keys<T>::value ? 25 : v.size())); (test::has_unique_keys<T>::value ? 25 : v.size()));
BOOST_TEST(count.instances == test::global_object_count.instances); BOOST_TEST(count.instances == test::global_object_count.instances);
@@ -180,11 +175,11 @@ namespace move_tests
BOOST_TEST(y.max_load_factor() == 1.0); // Not necessarily required. BOOST_TEST(y.max_load_factor() == 1.0); // Not necessarily required.
test::check_equivalent_keys(y); test::check_equivalent_keys(y);
} }
} }
template <class T> template <class T>
void move_assign_tests2(T*, test::random_generator const& generator) void move_assign_tests2(T*, test::random_generator const& generator)
{ {
BOOST_DEDUCED_TYPENAME T::hasher hf(1); BOOST_DEDUCED_TYPENAME T::hasher hf(1);
BOOST_DEDUCED_TYPENAME T::key_equal eq(1); BOOST_DEDUCED_TYPENAME T::key_equal eq(1);
BOOST_DEDUCED_TYPENAME T::allocator_type al1(1); BOOST_DEDUCED_TYPENAME T::allocator_type al1(1);
@@ -203,13 +198,11 @@ namespace move_tests
BOOST_TEST(y.max_load_factor() == 2.0); BOOST_TEST(y.max_load_factor() == 2.0);
#if defined(BOOST_HAS_NRVO) #if defined(BOOST_HAS_NRVO)
if (BOOST_UNORDERED_TEST_MOVING ? if (BOOST_UNORDERED_TEST_MOVING
(bool) allocator_type::is_propagate_on_move : ? (bool)allocator_type::is_propagate_on_move
(bool) allocator_type::is_propagate_on_assign) : (bool)allocator_type::is_propagate_on_assign) {
{
BOOST_TEST(test::equivalent(y.get_allocator(), al2)); BOOST_TEST(test::equivalent(y.get_allocator(), al2));
} } else {
else {
BOOST_TEST(test::equivalent(y.get_allocator(), al1)); BOOST_TEST(test::equivalent(y.get_allocator(), al1));
} }
#endif #endif
@@ -222,8 +215,7 @@ namespace move_tests
y = create(v, count, hf, eq, al2, 0.5); y = create(v, count, hf, eq, al2, 0.5);
#if defined(BOOST_HAS_NRVO) #if defined(BOOST_HAS_NRVO)
if (BOOST_UNORDERED_TEST_MOVING && if (BOOST_UNORDERED_TEST_MOVING &&
allocator_type::is_propagate_on_move) allocator_type::is_propagate_on_move) {
{
BOOST_TEST(count == test::global_object_count); BOOST_TEST(count == test::global_object_count);
} }
#endif #endif
@@ -232,13 +224,11 @@ namespace move_tests
BOOST_TEST(y.max_load_factor() == 0.5); BOOST_TEST(y.max_load_factor() == 0.5);
#if defined(BOOST_HAS_NRVO) #if defined(BOOST_HAS_NRVO)
if (BOOST_UNORDERED_TEST_MOVING ? if (BOOST_UNORDERED_TEST_MOVING
(bool) allocator_type::is_propagate_on_move : ? (bool)allocator_type::is_propagate_on_move
(bool) allocator_type::is_propagate_on_assign) : (bool)allocator_type::is_propagate_on_assign) {
{
BOOST_TEST(test::equivalent(y.get_allocator(), al2)); BOOST_TEST(test::equivalent(y.get_allocator(), al2));
} } else {
else {
BOOST_TEST(test::equivalent(y.get_allocator(), al1)); BOOST_TEST(test::equivalent(y.get_allocator(), al1));
} }
#endif #endif
@@ -257,21 +247,18 @@ namespace move_tests
test::object_count count = test::global_object_count; test::object_count count = test::global_object_count;
y = boost::move(x); y = boost::move(x);
if (BOOST_UNORDERED_TEST_MOVING && if (BOOST_UNORDERED_TEST_MOVING &&
allocator_type::is_propagate_on_move) allocator_type::is_propagate_on_move) {
{
BOOST_TEST(count == test::global_object_count); BOOST_TEST(count == test::global_object_count);
} }
test::check_container(y, v); test::check_container(y, v);
test::check_equivalent_keys(y); test::check_equivalent_keys(y);
BOOST_TEST(y.max_load_factor() == 0.25); BOOST_TEST(y.max_load_factor() == 0.25);
if (BOOST_UNORDERED_TEST_MOVING ? if (BOOST_UNORDERED_TEST_MOVING
(bool) allocator_type::is_propagate_on_move : ? (bool)allocator_type::is_propagate_on_move
(bool) allocator_type::is_propagate_on_assign) : (bool)allocator_type::is_propagate_on_assign) {
{
BOOST_TEST(test::equivalent(y.get_allocator(), al2)); BOOST_TEST(test::equivalent(y.get_allocator(), al2));
} } else {
else {
BOOST_TEST(test::equivalent(y.get_allocator(), al1)); BOOST_TEST(test::equivalent(y.get_allocator(), al1));
} }
} }
@@ -294,10 +281,8 @@ namespace move_tests
test::object_count count2 = test::global_object_count; test::object_count count2 = test::global_object_count;
if (BOOST_UNORDERED_TEST_MOVING && if (BOOST_UNORDERED_TEST_MOVING &&
allocator_type::is_propagate_on_move) allocator_type::is_propagate_on_move) {
{ BOOST_TEST(count1.instances == test::global_object_count.instances);
BOOST_TEST(count1.instances ==
test::global_object_count.instances);
BOOST_TEST(count2.constructions == BOOST_TEST(count2.constructions ==
test::global_object_count.constructions); test::global_object_count.constructions);
} }
@@ -306,103 +291,85 @@ namespace move_tests
test::check_equivalent_keys(y); test::check_equivalent_keys(y);
BOOST_TEST(y.max_load_factor() == 0.5); BOOST_TEST(y.max_load_factor() == 0.5);
if (BOOST_UNORDERED_TEST_MOVING ? if (BOOST_UNORDERED_TEST_MOVING
(bool) allocator_type::is_propagate_on_move : ? (bool)allocator_type::is_propagate_on_move
(bool) allocator_type::is_propagate_on_assign) : (bool)allocator_type::is_propagate_on_assign) {
{
BOOST_TEST(test::equivalent(y.get_allocator(), al2)); BOOST_TEST(test::equivalent(y.get_allocator(), al2));
} } else {
else {
BOOST_TEST(test::equivalent(y.get_allocator(), al1)); BOOST_TEST(test::equivalent(y.get_allocator(), al1));
} }
} }
} }
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
std::allocator<test::object> >* test_map_std_alloc; std::allocator<test::object> >* test_map_std_alloc;
boost::unordered_set<test::object, boost::unordered_set<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator2<test::object> >* test_set; test::allocator2<test::object> >* test_set;
boost::unordered_multiset<test::object, boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator1<test::object> >* test_multiset; test::allocator1<test::object> >* test_multiset;
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator1<test::object> >* test_map; test::allocator1<test::object> >* test_map;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to, test::allocator2<test::object> >* test_multimap;
test::allocator2<test::object> >* test_multimap;
boost::unordered_set<test::object, boost::unordered_set<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::propagate_move> >* test::cxx11_allocator<test::object, test::propagate_move> >*
test_set_prop_move; test_set_prop_move;
boost::unordered_multiset<test::object, boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::propagate_move> >* test::cxx11_allocator<test::object, test::propagate_move> >*
test_multiset_prop_move; test_multiset_prop_move;
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::propagate_move> >* test::cxx11_allocator<test::object, test::propagate_move> >*
test_map_prop_move; test_map_prop_move;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to, test::cxx11_allocator<test::object, test::propagate_move> >*
test::cxx11_allocator<test::object, test::propagate_move> >*
test_multimap_prop_move; test_multimap_prop_move;
boost::unordered_set<test::object, boost::unordered_set<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::no_propagate_move> >* test::cxx11_allocator<test::object, test::no_propagate_move> >*
test_set_no_prop_move; test_set_no_prop_move;
boost::unordered_multiset<test::object, boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::no_propagate_move> >* test::cxx11_allocator<test::object, test::no_propagate_move> >*
test_multiset_no_prop_move; test_multiset_no_prop_move;
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::no_propagate_move> >* test::cxx11_allocator<test::object, test::no_propagate_move> >*
test_map_no_prop_move; test_map_no_prop_move;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to,
test::cxx11_allocator<test::object, test::no_propagate_move> >* test::cxx11_allocator<test::object, test::no_propagate_move> >*
test_multimap_no_prop_move; test_multimap_no_prop_move;
using test::default_generator; using test::default_generator;
using test::generate_collisions; using test::generate_collisions;
using test::limited_range; using test::limited_range;
UNORDERED_TEST(move_construct_tests1, ( UNORDERED_TEST(move_construct_tests1,
(test_map_std_alloc) ((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap)(
(test_set)(test_multiset)(test_map)(test_multimap) test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(
(test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(test_multimap_prop_move) test_multimap_prop_move)(test_set_no_prop_move)(
(test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(test_multimap_no_prop_move) test_multiset_no_prop_move)(test_map_no_prop_move)(
) test_multimap_no_prop_move))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
) UNORDERED_TEST(move_assign_tests1,
UNORDERED_TEST(move_assign_tests1, ( ((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap)(
(test_map_std_alloc) test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(
(test_set)(test_multiset)(test_map)(test_multimap) test_multimap_prop_move)(test_set_no_prop_move)(
(test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(test_multimap_prop_move) test_multiset_no_prop_move)(test_map_no_prop_move)(
(test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(test_multimap_no_prop_move) test_multimap_no_prop_move))(
) (default_generator)(generate_collisions)(limited_range)))
((default_generator)(generate_collisions)(limited_range)) UNORDERED_TEST(move_construct_tests2,
) ((test_set)(test_multiset)(test_map)(test_multimap)(test_set_prop_move)(
UNORDERED_TEST(move_construct_tests2, ( test_multiset_prop_move)(test_map_prop_move)(test_multimap_prop_move)(
(test_set)(test_multiset)(test_map)(test_multimap) test_set_no_prop_move)(test_multiset_no_prop_move)(
(test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(test_multimap_prop_move) test_map_no_prop_move)(test_multimap_no_prop_move))(
(test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(test_multimap_no_prop_move) (default_generator)(generate_collisions)(limited_range)))
) UNORDERED_TEST(move_assign_tests2,
((default_generator)(generate_collisions)(limited_range)) ((test_set)(test_multiset)(test_map)(test_multimap)(test_set_prop_move)(
) test_multiset_prop_move)(test_map_prop_move)(test_multimap_prop_move)(
UNORDERED_TEST(move_assign_tests2, ( test_set_no_prop_move)(test_multiset_no_prop_move)(
(test_set)(test_multiset)(test_map)(test_multimap) test_map_no_prop_move)(test_multimap_no_prop_move))(
(test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(test_multimap_prop_move) (default_generator)(generate_collisions)(limited_range)))
(test_set_no_prop_move)(test_multiset_no_prop_move)(test_map_no_prop_move)(test_multimap_no_prop_move)
)
((default_generator)(generate_collisions)(limited_range))
)
} }
RUN_TESTS() RUN_TESTS()

View File

@@ -12,91 +12,114 @@
#include "../helpers/test.hpp" #include "../helpers/test.hpp"
namespace noexcept_tests namespace noexcept_tests {
// Test the noexcept is set correctly for the move constructor.
struct hash_possible_exception : boost::hash<int>
{ {
// Test the noexcept is set correctly for the move constructor.
struct hash_possible_exception : boost::hash<int>
{
hash_possible_exception(hash_possible_exception const&) {} hash_possible_exception(hash_possible_exception const&) {}
}; };
struct equal_to_possible_exception : std::equal_to<int> struct equal_to_possible_exception : std::equal_to<int>
{ {
equal_to_possible_exception(equal_to_possible_exception const&) {} equal_to_possible_exception(equal_to_possible_exception const&) {}
}; };
// Test that the move constructor does actually move without throwing // Test that the move constructor does actually move without throwing
// an exception when it claims to. // an exception when it claims to.
struct test_exception {}; struct test_exception
{
};
bool throwing_test_exception = false; bool throwing_test_exception = false;
void test_throw(char const* name) { void test_throw(char const* name)
{
if (throwing_test_exception) { if (throwing_test_exception) {
std::cerr << "Throw exception in: " << name << std::endl; std::cerr << "Throw exception in: " << name << std::endl;
throw test_exception(); throw test_exception();
} }
} }
class hash_nothrow_move : boost::hash<int> class hash_nothrow_move : boost::hash<int>
{ {
BOOST_COPYABLE_AND_MOVABLE(hash_nothrow_move) BOOST_COPYABLE_AND_MOVABLE(hash_nothrow_move)
typedef boost::hash<int> base; typedef boost::hash<int> base;
public: public:
hash_nothrow_move(BOOST_RV_REF(hash_nothrow_move)) hash_nothrow_move(BOOST_RV_REF(hash_nothrow_move)) BOOST_NOEXCEPT {}
BOOST_NOEXCEPT {}
hash_nothrow_move() { test_throw("Constructor"); } hash_nothrow_move() { test_throw("Constructor"); }
hash_nothrow_move(hash_nothrow_move const&) { test_throw("Copy"); } hash_nothrow_move(hash_nothrow_move const&) { test_throw("Copy"); }
hash_nothrow_move& operator=(BOOST_COPY_ASSIGN_REF(hash_nothrow_move)) hash_nothrow_move& operator=(BOOST_COPY_ASSIGN_REF(hash_nothrow_move))
{ test_throw("Assign"); return *this; }
hash_nothrow_move& operator=(BOOST_RV_REF(hash_nothrow_move))
{ test_throw("Move Assign"); return *this; }
std::size_t operator()(int x) const
{ test_throw("Operator"); return static_cast<base const&>(*this)(x); }
};
class equal_to_nothrow_move : std::equal_to<int>
{ {
test_throw("Assign");
return *this;
}
hash_nothrow_move& operator=(BOOST_RV_REF(hash_nothrow_move))
{
test_throw("Move Assign");
return *this;
}
std::size_t operator()(int x) const
{
test_throw("Operator");
return static_cast<base const&>(*this)(x);
}
};
class equal_to_nothrow_move : std::equal_to<int>
{
BOOST_COPYABLE_AND_MOVABLE(equal_to_nothrow_move) BOOST_COPYABLE_AND_MOVABLE(equal_to_nothrow_move)
typedef std::equal_to<int> base; typedef std::equal_to<int> base;
public: public:
equal_to_nothrow_move(BOOST_RV_REF(equal_to_nothrow_move)) equal_to_nothrow_move(BOOST_RV_REF(equal_to_nothrow_move)) BOOST_NOEXCEPT {}
BOOST_NOEXCEPT {}
equal_to_nothrow_move() { test_throw("Constructor"); } equal_to_nothrow_move() { test_throw("Constructor"); }
equal_to_nothrow_move(equal_to_nothrow_move const&) equal_to_nothrow_move(equal_to_nothrow_move const&) { test_throw("Copy"); }
{ test_throw("Copy"); } equal_to_nothrow_move& operator=(
equal_to_nothrow_move& operator=(BOOST_COPY_ASSIGN_REF(equal_to_nothrow_move)) BOOST_COPY_ASSIGN_REF(equal_to_nothrow_move))
{ test_throw("Assign"); return *this; }
equal_to_nothrow_move& operator=(BOOST_RV_REF(equal_to_nothrow_move))
{ test_throw("Move Assign"); return *this; }
std::size_t operator()(int x, int y) const
{ test_throw("Operator"); return static_cast<base const&>(*this)(x, y); }
};
bool have_is_nothrow_move = false;
UNORDERED_AUTO_TEST(check_is_nothrow_move)
{ {
BOOST_TEST(!boost::is_nothrow_move_constructible<hash_possible_exception>::value); test_throw("Assign");
have_is_nothrow_move = boost::is_nothrow_move_constructible<hash_nothrow_move>::value; return *this;
}
equal_to_nothrow_move& operator=(BOOST_RV_REF(equal_to_nothrow_move))
{
test_throw("Move Assign");
return *this;
}
std::size_t operator()(int x, int y) const
{
test_throw("Operator");
return static_cast<base const&>(*this)(x, y);
}
};
// Copied from boost::is_nothrow_move_constructible implementation bool have_is_nothrow_move = false;
// to make sure this does actually detect it when expected.
// UNORDERED_AUTO_TEST(check_is_nothrow_move)
// The type trait is also available when BOOST_IS_NOTHROW_MOVE_CONSTRUCT {
// is defined (for some versions of Visual C++?) but detects 'throw()', BOOST_TEST(
// not noexcept. !boost::is_nothrow_move_constructible<hash_possible_exception>::value);
#if !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_SFINAE_EXPR) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40800) have_is_nothrow_move =
boost::is_nothrow_move_constructible<hash_nothrow_move>::value;
// Copied from boost::is_nothrow_move_constructible implementation
// to make sure this does actually detect it when expected.
//
// The type trait is also available when BOOST_IS_NOTHROW_MOVE_CONSTRUCT
// is defined (for some versions of Visual C++?) but detects 'throw()',
// not noexcept.
#if !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_SFINAE_EXPR) && \
!BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40800)
BOOST_TEST(have_is_nothrow_move); BOOST_TEST(have_is_nothrow_move);
#endif #endif
} }
UNORDERED_AUTO_TEST(test_noexcept) UNORDERED_AUTO_TEST(test_noexcept)
{ {
if (have_is_nothrow_move) { if (have_is_nothrow_move) {
BOOST_TEST((boost::is_nothrow_move_constructible< BOOST_TEST((boost::is_nothrow_move_constructible<
boost::unordered_set<int> >::value)); boost::unordered_set<int> >::value));
@@ -109,21 +132,18 @@ namespace noexcept_tests
} }
BOOST_TEST((!boost::is_nothrow_move_constructible< BOOST_TEST((!boost::is_nothrow_move_constructible<
boost::unordered_set<int, hash_possible_exception> boost::unordered_set<int, hash_possible_exception> >::value));
>::value)); BOOST_TEST(
BOOST_TEST((!boost::is_nothrow_move_constructible< (!boost::is_nothrow_move_constructible<boost::unordered_multiset<int,
boost::unordered_multiset<int, boost::hash<int>, boost::hash<int>, equal_to_possible_exception> >::value));
equal_to_possible_exception> }
>::value));
}
UNORDERED_AUTO_TEST(test_no_throw_when_noexcept) UNORDERED_AUTO_TEST(test_no_throw_when_noexcept)
{ {
typedef boost::unordered_set<int, typedef boost::unordered_set<int, hash_nothrow_move, equal_to_nothrow_move>
hash_nothrow_move, equal_to_nothrow_move> throwing_set; throwing_set;
if (have_is_nothrow_move) if (have_is_nothrow_move) {
{
BOOST_TEST(boost::is_nothrow_move_constructible<throwing_set>::value); BOOST_TEST(boost::is_nothrow_move_constructible<throwing_set>::value);
throwing_test_exception = false; throwing_test_exception = false;
@@ -138,13 +158,13 @@ namespace noexcept_tests
throwing_set x2 = boost::move(x1); throwing_set x2 = boost::move(x1);
BOOST_TEST(x2.size() == 2); BOOST_TEST(x2.size() == 2);
BOOST_TEST(*x2.begin() == 10 || *x2.begin() == 50); BOOST_TEST(*x2.begin() == 10 || *x2.begin() == 50);
} catch(test_exception) { } catch (test_exception) {
BOOST_TEST(false); BOOST_TEST(false);
} }
throwing_test_exception = false; throwing_test_exception = false;
} }
} }
} }
RUN_TESTS() RUN_TESTS()

View File

@@ -16,8 +16,7 @@
#include "../helpers/metafunctions.hpp" #include "../helpers/metafunctions.hpp"
#include "../objects/test.hpp" #include "../objects/test.hpp"
namespace rehash_tests namespace rehash_tests {
{
test::seed_t initialize_seed(2974); test::seed_t initialize_seed(2974);
@@ -29,8 +28,7 @@ bool postcondition(X const& x, BOOST_DEDUCED_TYPENAME X::size_type n)
x.bucket_count() >= n; x.bucket_count() >= n;
} }
template <class X> template <class X> void rehash_empty_test1(X*)
void rehash_empty_test1(X*)
{ {
X x; X x;
@@ -44,8 +42,7 @@ void rehash_empty_test1(X*)
BOOST_TEST(postcondition(x, 10000000)); BOOST_TEST(postcondition(x, 10000000));
} }
template <class X> template <class X> void rehash_empty_test2(X*, test::random_generator generator)
void rehash_empty_test2(X*, test::random_generator generator)
{ {
test::random_values<X> v(1000, generator); test::random_values<X> v(1000, generator);
test::ordered<X> tracker; test::ordered<X> tracker;
@@ -66,8 +63,7 @@ void rehash_empty_test2(X*, test::random_generator generator)
BOOST_TEST(postcondition(x, 10000000)); BOOST_TEST(postcondition(x, 10000000));
} }
template <class X> template <class X> void rehash_empty_test3(X*, test::random_generator generator)
void rehash_empty_test3(X*, test::random_generator generator)
{ {
test::random_values<X> v(1000, generator); test::random_values<X> v(1000, generator);
test::ordered<X> tracker; test::ordered<X> tracker;
@@ -84,31 +80,33 @@ void rehash_empty_test3(X*, test::random_generator generator)
BOOST_TEST(postcondition(x, 0)); BOOST_TEST(postcondition(x, 0));
} }
template <class X> template <class X> void rehash_test1(X*, test::random_generator generator)
void rehash_test1(X*, test::random_generator generator)
{ {
test::random_values<X> v(1000, generator); test::random_values<X> v(1000, generator);
test::ordered<X> tracker; test::ordered<X> tracker;
tracker.insert_range(v.begin(), v.end()); tracker.insert_range(v.begin(), v.end());
X x(v.begin(), v.end()); X x(v.begin(), v.end());
x.rehash(0); BOOST_TEST(postcondition(x, 0)); x.rehash(0);
BOOST_TEST(postcondition(x, 0));
tracker.compare(x); tracker.compare(x);
x.max_load_factor(0.25); x.max_load_factor(0.25);
x.rehash(0); BOOST_TEST(postcondition(x, 0)); x.rehash(0);
BOOST_TEST(postcondition(x, 0));
tracker.compare(x); tracker.compare(x);
x.max_load_factor(50.0); x.max_load_factor(50.0);
x.rehash(0); BOOST_TEST(postcondition(x, 0)); x.rehash(0);
BOOST_TEST(postcondition(x, 0));
tracker.compare(x); tracker.compare(x);
x.rehash(1000); BOOST_TEST(postcondition(x, 1000)); x.rehash(1000);
BOOST_TEST(postcondition(x, 1000));
tracker.compare(x); tracker.compare(x);
} }
template <class X> template <class X> void reserve_empty_test1(X*)
void reserve_empty_test1(X*)
{ {
X x; X x;
@@ -121,8 +119,7 @@ void reserve_empty_test1(X*)
BOOST_TEST(x.bucket_count() >= 10000000); BOOST_TEST(x.bucket_count() >= 10000000);
} }
template <class X> template <class X> void reserve_empty_test2(X*)
void reserve_empty_test2(X*)
{ {
X x; X x;
x.max_load_factor(0.25); x.max_load_factor(0.25);
@@ -136,21 +133,20 @@ void reserve_empty_test2(X*)
BOOST_TEST(x.bucket_count() >= 40000000); BOOST_TEST(x.bucket_count() >= 40000000);
} }
template <class X> template <class X> void reserve_test1(X*, test::random_generator generator)
void reserve_test1(X*, test::random_generator generator)
{ {
for (int random_mlf = 0; random_mlf < 2; ++random_mlf) for (int random_mlf = 0; random_mlf < 2; ++random_mlf) {
{ for (std::size_t i = 1; i < 2000; i += i < 50 ? 1 : 13) {
for (std::size_t i = 1; i < 2000; i += i < 50 ? 1 : 13)
{
test::random_values<X> v(i, generator); test::random_values<X> v(i, generator);
test::ordered<X> tracker; test::ordered<X> tracker;
tracker.insert_range(v.begin(), v.end()); tracker.insert_range(v.begin(), v.end());
X x; X x;
x.max_load_factor(random_mlf ? x.max_load_factor(
static_cast<float>(std::rand() % 1000) / 500.0f + 0.5f : 1.0f); random_mlf
? static_cast<float>(std::rand() % 1000) / 500.0f + 0.5f
: 1.0f);
x.reserve(test::has_unique_keys<X>::value ? i : v.size()); x.reserve(test::has_unique_keys<X>::value ? i : v.size());
// Insert an element before the range insert, otherwise there are // Insert an element before the range insert, otherwise there are
@@ -168,28 +164,26 @@ void reserve_test1(X*, test::random_generator generator)
} }
} }
template <class X> template <class X> void reserve_test2(X*, test::random_generator generator)
void reserve_test2(X*, test::random_generator generator)
{ {
for (int random_mlf = 0; random_mlf < 2; ++random_mlf) for (int random_mlf = 0; random_mlf < 2; ++random_mlf) {
{ for (std::size_t i = 0; i < 2000; i += i < 50 ? 1 : 13) {
for (std::size_t i = 0; i < 2000; i += i < 50 ? 1 : 13)
{
test::random_values<X> v(i, generator); test::random_values<X> v(i, generator);
test::ordered<X> tracker; test::ordered<X> tracker;
tracker.insert_range(v.begin(), v.end()); tracker.insert_range(v.begin(), v.end());
X x; X x;
x.max_load_factor(random_mlf ? x.max_load_factor(
static_cast<float>(std::rand() % 1000) / 500.0f + 0.5f : 1.0f); random_mlf
? static_cast<float>(std::rand() % 1000) / 500.0f + 0.5f
: 1.0f);
x.reserve(test::has_unique_keys<X>::value ? i : v.size()); x.reserve(test::has_unique_keys<X>::value ? i : v.size());
std::size_t bucket_count = x.bucket_count(); std::size_t bucket_count = x.bucket_count();
for (typename test::random_values<X>::iterator it = v.begin(); for (typename test::random_values<X>::iterator it = v.begin();
it != v.end(); ++it) it != v.end(); ++it) {
{
x.insert(*it); x.insert(*it);
} }
@@ -200,11 +194,9 @@ void reserve_test2(X*, test::random_generator generator)
} }
boost::unordered_set<int>* int_set_ptr; boost::unordered_set<int>* int_set_ptr;
boost::unordered_multiset<test::object, boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator2<test::object> >* test_multiset_ptr; test::allocator2<test::object> >* test_multiset_ptr;
boost::unordered_map<test::movable, test::movable, boost::unordered_map<test::movable, test::movable, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator2<test::movable> >* test_map_ptr; test::allocator2<test::movable> >* test_map_ptr;
boost::unordered_multimap<int, int>* int_multimap_ptr; boost::unordered_multimap<int, int>* int_multimap_ptr;
@@ -213,35 +205,26 @@ using test::generate_collisions;
using test::limited_range; using test::limited_range;
UNORDERED_TEST(rehash_empty_test1, UNORDERED_TEST(rehash_empty_test1,
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)) ((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)))
)
UNORDERED_TEST(rehash_empty_test2, UNORDERED_TEST(rehash_empty_test2,
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)) ((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
UNORDERED_TEST(rehash_empty_test3, UNORDERED_TEST(rehash_empty_test3,
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)) ((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
UNORDERED_TEST(rehash_test1, UNORDERED_TEST(rehash_test1,
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)) ((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
UNORDERED_TEST(reserve_empty_test1, UNORDERED_TEST(reserve_empty_test1,
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)) ((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)))
)
UNORDERED_TEST(reserve_empty_test2, UNORDERED_TEST(reserve_empty_test2,
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)) ((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)))
)
UNORDERED_TEST(reserve_test1, UNORDERED_TEST(reserve_test1,
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)) ((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
UNORDERED_TEST(reserve_test2, UNORDERED_TEST(reserve_test2,
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr)) ((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
} }
RUN_TESTS() RUN_TESTS()

View File

@@ -17,8 +17,7 @@
#include <algorithm> #include <algorithm>
#include "../helpers/equivalent.hpp" #include "../helpers/equivalent.hpp"
template <class X> template <class X> void simple_test(X const& a)
void simple_test(X const& a)
{ {
test::unordered_equivalence_tester<X> equivalent(a); test::unordered_equivalence_tester<X> equivalent(a);
@@ -74,8 +73,7 @@ void simple_test(X const& a)
} }
{ {
BOOST_TEST(a.size() == BOOST_TEST(a.size() == static_cast<BOOST_DEDUCED_TYPENAME X::size_type>(
static_cast<BOOST_DEDUCED_TYPENAME X::size_type>(
std::distance(a.begin(), a.end()))); std::distance(a.begin(), a.end())));
} }
@@ -95,38 +93,40 @@ UNORDERED_AUTO_TEST(simple_tests)
using namespace std; using namespace std;
srand(14878); srand(14878);
std::cout<<"Test unordered_set.\n"; std::cout << "Test unordered_set.\n";
boost::unordered_set<int> set; boost::unordered_set<int> set;
simple_test(set); simple_test(set);
set.insert(1); set.insert(2); set.insert(1456); set.insert(1);
set.insert(2);
set.insert(1456);
simple_test(set); simple_test(set);
std::cout<<"Test unordered_multiset.\n"; std::cout << "Test unordered_multiset.\n";
boost::unordered_multiset<int> multiset; boost::unordered_multiset<int> multiset;
simple_test(multiset); simple_test(multiset);
for(int i1 = 0; i1 < 1000; ++i1) { for (int i1 = 0; i1 < 1000; ++i1) {
int count = rand() % 10, index = rand(); int count = rand() % 10, index = rand();
for(int j = 0; j < count; ++j) for (int j = 0; j < count; ++j)
multiset.insert(index); multiset.insert(index);
} }
simple_test(multiset); simple_test(multiset);
std::cout<<"Test unordered_map.\n"; std::cout << "Test unordered_map.\n";
boost::unordered_map<int, int> map; boost::unordered_map<int, int> map;
for(int i2 = 0; i2 < 1000; ++i2) { for (int i2 = 0; i2 < 1000; ++i2) {
map.insert(std::pair<const int, int>(rand(), rand())); map.insert(std::pair<const int, int>(rand(), rand()));
} }
simple_test(map); simple_test(map);
std::cout<<"Test unordered_multimap.\n"; std::cout << "Test unordered_multimap.\n";
boost::unordered_multimap<int, int> multimap; boost::unordered_multimap<int, int> multimap;
for(int i3 = 0; i3 < 1000; ++i3) { for (int i3 = 0; i3 < 1000; ++i3) {
int count = rand() % 10, index = rand(); int count = rand() % 10, index = rand();
for(int j = 0; j < count; ++j) for (int j = 0; j < count; ++j)
multimap.insert(std::pair<const int, int>(index, rand())); multimap.insert(std::pair<const int, int>(index, rand()));
} }
simple_test(multimap); simple_test(multimap);

View File

@@ -21,16 +21,14 @@
#include "../helpers/invariants.hpp" #include "../helpers/invariants.hpp"
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
#pragma warning(disable:4127) // conditional expression is constant #pragma warning(disable : 4127) // conditional expression is constant
#endif #endif
namespace swap_tests namespace swap_tests {
{
test::seed_t initialize_seed(783472); test::seed_t initialize_seed(783472);
template <class X> template <class X> void swap_test_impl(X& x1, X& x2)
void swap_test_impl(X& x1, X& x2)
{ {
test::ordered<X> tracker1 = test::create_ordered(x1); test::ordered<X> tracker1 = test::create_ordered(x1);
test::ordered<X> tracker2 = test::create_ordered(x2); test::ordered<X> tracker2 = test::create_ordered(x2);
@@ -41,8 +39,7 @@ void swap_test_impl(X& x1, X& x2)
tracker2.compare(x1); tracker2.compare(x1);
} }
template <class X> template <class X> void swap_tests1(X*, test::random_generator generator)
void swap_tests1(X*, test::random_generator generator)
{ {
{ {
test::check_instances check_; test::check_instances check_;
@@ -54,7 +51,7 @@ void swap_tests1(X*, test::random_generator generator)
{ {
test::check_instances check_; test::check_instances check_;
X x,y; X x, y;
swap_test_impl(x, y); swap_test_impl(x, y);
} }
@@ -77,8 +74,7 @@ void swap_tests1(X*, test::random_generator generator)
} }
} }
template <class X> template <class X> void swap_tests2(X* ptr, test::random_generator generator)
void swap_tests2(X* ptr, test::random_generator generator)
{ {
swap_tests1(ptr, generator); swap_tests1(ptr, generator);
@@ -123,8 +119,7 @@ void swap_tests2(X* ptr, test::random_generator generator)
X y(vy.begin(), vy.end(), 0, hasher(), key_equal(), allocator_type(2)); X y(vy.begin(), vy.end(), 0, hasher(), key_equal(), allocator_type(2));
if (allocator_type::is_propagate_on_swap || if (allocator_type::is_propagate_on_swap ||
x.get_allocator() == y.get_allocator()) x.get_allocator() == y.get_allocator()) {
{
swap_test_impl(x, y); swap_test_impl(x, y);
} }
} }
@@ -141,67 +136,53 @@ void swap_tests2(X* ptr, test::random_generator generator)
allocator_type(2)); allocator_type(2));
if (allocator_type::is_propagate_on_swap || if (allocator_type::is_propagate_on_swap ||
x.get_allocator() == y.get_allocator()) x.get_allocator() == y.get_allocator()) {
{
swap_test_impl(x, y); swap_test_impl(x, y);
swap_test_impl(x, y); swap_test_impl(x, y);
} }
} }
} }
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
std::allocator<test::object> >* test_map_std_alloc; std::allocator<test::object> >* test_map_std_alloc;
boost::unordered_set<test::object, boost::unordered_set<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator1<test::object> >* test_set; test::allocator1<test::object> >* test_set;
boost::unordered_multiset<test::object, boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator2<test::object> >* test_multiset; test::allocator2<test::object> >* test_multiset;
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::allocator1<test::object> >* test_map; test::allocator1<test::object> >* test_map;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to, test::allocator2<test::object> >* test_multimap;
test::allocator2<test::object> >* test_multimap;
boost::unordered_set<test::object, boost::unordered_set<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::propagate_swap> >* test::cxx11_allocator<test::object, test::propagate_swap> >*
test_set_prop_swap; test_set_prop_swap;
boost::unordered_multiset<test::object, boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::propagate_swap> >* test::cxx11_allocator<test::object, test::propagate_swap> >*
test_multiset_prop_swap; test_multiset_prop_swap;
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::propagate_swap> >* test::cxx11_allocator<test::object, test::propagate_swap> >*
test_map_prop_swap; test_map_prop_swap;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to, test::cxx11_allocator<test::object, test::propagate_swap> >*
test::cxx11_allocator<test::object, test::propagate_swap> >*
test_multimap_prop_swap; test_multimap_prop_swap;
boost::unordered_set<test::object, boost::unordered_set<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::no_propagate_swap> >* test::cxx11_allocator<test::object, test::no_propagate_swap> >*
test_set_no_prop_swap; test_set_no_prop_swap;
boost::unordered_multiset<test::object, boost::unordered_multiset<test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::no_propagate_swap> >* test::cxx11_allocator<test::object, test::no_propagate_swap> >*
test_multiset_no_prop_swap; test_multiset_no_prop_swap;
boost::unordered_map<test::object, test::object, boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
test::hash, test::equal_to,
test::cxx11_allocator<test::object, test::no_propagate_swap> >* test::cxx11_allocator<test::object, test::no_propagate_swap> >*
test_map_no_prop_swap; test_map_no_prop_swap;
boost::unordered_multimap<test::object, test::object, boost::unordered_multimap<test::object, test::object, test::hash,
test::hash, test::equal_to, test::equal_to,
test::cxx11_allocator<test::object, test::no_propagate_swap> >* test::cxx11_allocator<test::object, test::no_propagate_swap> >*
test_multimap_no_prop_swap; test_multimap_no_prop_swap;
template <typename T> template <typename T> bool is_propagate(T*)
bool is_propagate(T*)
{ {
return T::allocator_type::is_propagate_on_swap; return T::allocator_type::is_propagate_on_swap;
} }
@@ -217,22 +198,19 @@ UNORDERED_AUTO_TEST(check_traits)
BOOST_TEST(!is_propagate(test_set_no_prop_swap)); BOOST_TEST(!is_propagate(test_set_no_prop_swap));
} }
UNORDERED_TEST(swap_tests1, ( UNORDERED_TEST(swap_tests1,
(test_map_std_alloc) ((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap)(
(test_set)(test_multiset)(test_map)(test_multimap) test_set_prop_swap)(test_multiset_prop_swap)(test_map_prop_swap)(
(test_set_prop_swap)(test_multiset_prop_swap)(test_map_prop_swap)(test_multimap_prop_swap) test_multimap_prop_swap)(test_set_no_prop_swap)(
(test_set_no_prop_swap)(test_multiset_no_prop_swap)(test_map_no_prop_swap)(test_multimap_no_prop_swap) test_multiset_no_prop_swap)(test_map_no_prop_swap)(
) test_multimap_no_prop_swap))(
((default_generator)(generate_collisions)(limited_range)) (default_generator)(generate_collisions)(limited_range)))
)
UNORDERED_TEST(swap_tests2, (
(test_set)(test_multiset)(test_map)(test_multimap)
(test_set_prop_swap)(test_multiset_prop_swap)(test_map_prop_swap)(test_multimap_prop_swap)
(test_set_no_prop_swap)(test_multiset_no_prop_swap)(test_map_no_prop_swap)(test_multimap_no_prop_swap)
)
((default_generator)(generate_collisions)(limited_range))
)
UNORDERED_TEST(swap_tests2,
((test_set)(test_multiset)(test_map)(test_multimap)(test_set_prop_swap)(
test_multiset_prop_swap)(test_map_prop_swap)(test_multimap_prop_swap)(
test_set_no_prop_swap)(test_multiset_no_prop_swap)(
test_map_no_prop_swap)(test_multimap_no_prop_swap))(
(default_generator)(generate_collisions)(limited_range)))
} }
RUN_TESTS() RUN_TESTS()

View File

@@ -13,10 +13,9 @@
#include <iostream> #include <iostream>
#include "../helpers/test.hpp" #include "../helpers/test.hpp"
namespace unnecessary_copy_tests namespace unnecessary_copy_tests {
struct count_copies
{ {
struct count_copies
{
private: private:
BOOST_COPYABLE_AND_MOVABLE(count_copies) BOOST_COPYABLE_AND_MOVABLE(count_copies)
public: public:
@@ -24,12 +23,14 @@ namespace unnecessary_copy_tests
static int moves; static int moves;
static int id_count; static int id_count;
count_copies() : tag_(0), id_(++id_count) { count_copies() : tag_(0), id_(++id_count)
{
++copies; ++copies;
trace_op("Default construct"); trace_op("Default construct");
} }
explicit count_copies(int tag) : tag_(tag), id_(++id_count) { explicit count_copies(int tag) : tag_(tag), id_(++id_count)
{
++copies; ++copies;
trace_op("Tag construct"); trace_op("Tag construct");
} }
@@ -56,14 +57,15 @@ namespace unnecessary_copy_tests
trace_op("Copy construct"); trace_op("Copy construct");
} }
count_copies(BOOST_RV_REF(count_copies) x) : count_copies(BOOST_RV_REF(count_copies) x) : tag_(x.tag_), id_(++id_count)
tag_(x.tag_), id_(++id_count)
{ {
x.tag_ = -1; ++moves; x.tag_ = -1;
++moves;
trace_op("Move construct"); trace_op("Move construct");
} }
count_copies& operator=(BOOST_COPY_ASSIGN_REF(count_copies) p) // Copy assignment count_copies& operator=(
BOOST_COPY_ASSIGN_REF(count_copies) p) // Copy assignment
{ {
tag_ = p.tag_; tag_ = p.tag_;
++copies; ++copies;
@@ -71,7 +73,7 @@ namespace unnecessary_copy_tests
return *this; return *this;
} }
count_copies& operator=(BOOST_RV_REF(count_copies) p) //Move assignment count_copies& operator=(BOOST_RV_REF(count_copies) p) // Move assignment
{ {
tag_ = p.tag_; tag_ = p.tag_;
++moves; ++moves;
@@ -79,35 +81,32 @@ namespace unnecessary_copy_tests
return *this; return *this;
} }
~count_copies() { ~count_copies() { trace_op("Destruct"); }
trace_op("Destruct");
}
void trace_op(char const* str) { void trace_op(char const* str)
BOOST_LIGHTWEIGHT_TEST_OSTREAM << str << ": " << tag_ {
<< " (#" << id_ << ")" <<std::endl; BOOST_LIGHTWEIGHT_TEST_OSTREAM << str << ": " << tag_ << " (#" << id_
<< ")" << std::endl;
} }
int tag_; int tag_;
int id_; int id_;
}; };
bool operator==(count_copies const& x, count_copies const& y) { bool operator==(count_copies const& x, count_copies const& y)
{
return x.tag_ == y.tag_; return x.tag_ == y.tag_;
} }
template <class T> template <class T> T source() { return T(); }
T source() {
return T();
}
void reset() { void reset()
{
count_copies::copies = 0; count_copies::copies = 0;
count_copies::moves = 0; count_copies::moves = 0;
BOOST_LIGHTWEIGHT_TEST_OSTREAM BOOST_LIGHTWEIGHT_TEST_OSTREAM << "\nReset\n" << std::endl;
<< "\nReset\n" << std::endl; }
}
} }
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) #if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
@@ -116,9 +115,10 @@ namespace boost
namespace unnecessary_copy_tests namespace unnecessary_copy_tests
#endif #endif
{ {
std::size_t hash_value(unnecessary_copy_tests::count_copies const& x) { std::size_t hash_value(unnecessary_copy_tests::count_copies const& x)
{
return static_cast<std::size_t>(x.tag_); return static_cast<std::size_t>(x.tag_);
} }
} }
// Boost.Move doesn't seem to work very well on this compiler. // Boost.Move doesn't seem to work very well on this compiler.
@@ -136,82 +136,71 @@ namespace unnecessary_copy_tests
#endif #endif
#define COPY_COUNT(n) \ #define COPY_COUNT(n) \
if(::unnecessary_copy_tests::count_copies::copies != n) { \ if (::unnecessary_copy_tests::count_copies::copies != n) { \
BOOST_ERROR("Wrong number of copies."); \ BOOST_ERROR("Wrong number of copies."); \
std::cerr \ std::cerr << "Number of copies: " \
<< "Number of copies: " \
<< ::unnecessary_copy_tests::count_copies::copies \ << ::unnecessary_copy_tests::count_copies::copies \
<< " expecting: " << n << std::endl; \ << " expecting: " << n << std::endl; \
} }
#define MOVE_COUNT(n) \ #define MOVE_COUNT(n) \
if(::unnecessary_copy_tests::count_copies::moves != n) { \ if (::unnecessary_copy_tests::count_copies::moves != n) { \
BOOST_ERROR("Wrong number of moves."); \ BOOST_ERROR("Wrong number of moves."); \
std::cerr \ std::cerr << "Number of moves: " \
<< "Number of moves: " \
<< ::unnecessary_copy_tests::count_copies::moves \ << ::unnecessary_copy_tests::count_copies::moves \
<< " expecting: " <<n << std::endl; \ << " expecting: " << n << std::endl; \
} }
#define COPY_COUNT_RANGE(a, b) \ #define COPY_COUNT_RANGE(a, b) \
if(::unnecessary_copy_tests::count_copies::copies < a || \ if (::unnecessary_copy_tests::count_copies::copies < a || \
::unnecessary_copy_tests::count_copies::copies > b) { \ ::unnecessary_copy_tests::count_copies::copies > b) { \
BOOST_ERROR("Wrong number of copies."); \ BOOST_ERROR("Wrong number of copies."); \
std::cerr \ std::cerr << "Number of copies: " \
<< "Number of copies: " \
<< ::unnecessary_copy_tests::count_copies::copies \ << ::unnecessary_copy_tests::count_copies::copies \
<< " expecting: [" << a << ", " << b << "]" << std::endl; \ << " expecting: [" << a << ", " << b << "]" << std::endl; \
} }
#define MOVE_COUNT_RANGE(a, b) \ #define MOVE_COUNT_RANGE(a, b) \
if(::unnecessary_copy_tests::count_copies::moves < a || \ if (::unnecessary_copy_tests::count_copies::moves < a || \
::unnecessary_copy_tests::count_copies::moves > b) { \ ::unnecessary_copy_tests::count_copies::moves > b) { \
BOOST_ERROR("Wrong number of moves."); \ BOOST_ERROR("Wrong number of moves."); \
std::cerr \ std::cerr << "Number of moves: " \
<< "Number of moves: " \
<< ::unnecessary_copy_tests::count_copies::moves \ << ::unnecessary_copy_tests::count_copies::moves \
<< " expecting: [" << a << ", " << b << "]" << std::endl; \ << " expecting: [" << a << ", " << b << "]" << std::endl; \
} }
#define COPY_COUNT_EXTRA(a, b) \ #define COPY_COUNT_EXTRA(a, b) COPY_COUNT_RANGE(a, a + b * EXTRA_CONSTRUCT_COST)
COPY_COUNT_RANGE(a, a + b * EXTRA_CONSTRUCT_COST) #define MOVE_COUNT_EXTRA(a, b) MOVE_COUNT_RANGE(a, a + b * EXTRA_CONSTRUCT_COST)
#define MOVE_COUNT_EXTRA(a, b) \
MOVE_COUNT_RANGE(a, a + b * EXTRA_CONSTRUCT_COST)
namespace unnecessary_copy_tests namespace unnecessary_copy_tests {
int count_copies::copies;
int count_copies::moves;
int count_copies::id_count;
template <class T> void unnecessary_copy_insert_test(T*)
{ {
int count_copies::copies;
int count_copies::moves;
int count_copies::id_count;
template <class T>
void unnecessary_copy_insert_test(T*)
{
T x; T x;
BOOST_DEDUCED_TYPENAME T::value_type a; BOOST_DEDUCED_TYPENAME T::value_type a;
reset(); reset();
x.insert(a); x.insert(a);
COPY_COUNT(1); COPY_COUNT(1);
} }
boost::unordered_set<count_copies>* set; boost::unordered_set<count_copies>* set;
boost::unordered_multiset<count_copies>* multiset; boost::unordered_multiset<count_copies>* multiset;
boost::unordered_map<int, count_copies>* map; boost::unordered_map<int, count_copies>* map;
boost::unordered_multimap<int, count_copies>* multimap; boost::unordered_multimap<int, count_copies>* multimap;
UNORDERED_TEST(unnecessary_copy_insert_test, UNORDERED_TEST(unnecessary_copy_insert_test, ((set)(multiset)(map)(multimap)))
((set)(multiset)(map)(multimap)))
template <class T> template <class T> void unnecessary_copy_emplace_test(T*)
void unnecessary_copy_emplace_test(T*) {
{
reset(); reset();
T x; T x;
BOOST_DEDUCED_TYPENAME T::value_type a; BOOST_DEDUCED_TYPENAME T::value_type a;
COPY_COUNT(1); COPY_COUNT(1);
x.emplace(a); x.emplace(a);
COPY_COUNT(2); COPY_COUNT(2);
} }
template <class T> template <class T> void unnecessary_copy_emplace_rvalue_test(T*)
void unnecessary_copy_emplace_rvalue_test(T*) {
{
reset(); reset();
T x; T x;
x.emplace(source<BOOST_DEDUCED_TYPENAME T::value_type>()); x.emplace(source<BOOST_DEDUCED_TYPENAME T::value_type>());
@@ -220,83 +209,87 @@ namespace unnecessary_copy_tests
#else #else
COPY_COUNT(2); COPY_COUNT(2);
#endif #endif
} }
UNORDERED_TEST(unnecessary_copy_emplace_test, UNORDERED_TEST(unnecessary_copy_emplace_test, ((set)(multiset)(map)(multimap)))
((set)(multiset)(map)(multimap))) UNORDERED_TEST(
UNORDERED_TEST(unnecessary_copy_emplace_rvalue_test, unnecessary_copy_emplace_rvalue_test, ((set)(multiset)(map)(multimap)))
((set)(multiset)(map)(multimap)))
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
template <class T> template <class T> void unnecessary_copy_emplace_std_move_test(T*)
void unnecessary_copy_emplace_std_move_test(T*) {
{
reset(); reset();
T x; T x;
BOOST_DEDUCED_TYPENAME T::value_type a; BOOST_DEDUCED_TYPENAME T::value_type a;
COPY_COUNT(1); MOVE_COUNT(0); COPY_COUNT(1);
MOVE_COUNT(0);
x.emplace(std::move(a)); x.emplace(std::move(a));
COPY_COUNT(1); MOVE_COUNT(1); COPY_COUNT(1);
} MOVE_COUNT(1);
}
UNORDERED_TEST(unnecessary_copy_emplace_std_move_test, UNORDERED_TEST(
((set)(multiset)(map)(multimap))) unnecessary_copy_emplace_std_move_test, ((set)(multiset)(map)(multimap)))
#endif #endif
template <class T> template <class T> void unnecessary_copy_emplace_boost_move_test(T*)
void unnecessary_copy_emplace_boost_move_test(T*) {
{
reset(); reset();
T x; T x;
BOOST_DEDUCED_TYPENAME T::value_type a; BOOST_DEDUCED_TYPENAME T::value_type a;
COPY_COUNT(1); MOVE_COUNT_EXTRA(0, 1); COPY_COUNT(1);
MOVE_COUNT_EXTRA(0, 1);
x.emplace(boost::move(a)); x.emplace(boost::move(a));
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
COPY_COUNT(1); MOVE_COUNT(1); COPY_COUNT(1);
MOVE_COUNT(1);
#else #else
// Since std::pair isn't movable, move only works for sets. // Since std::pair isn't movable, move only works for sets.
COPY_COUNT_RANGE(1, 2); MOVE_COUNT_RANGE(0, 1); COPY_COUNT_RANGE(1, 2);
MOVE_COUNT_RANGE(0, 1);
#endif #endif
} }
UNORDERED_TEST(unnecessary_copy_emplace_boost_move_test, UNORDERED_TEST(
((set)(multiset)(map)(multimap))) unnecessary_copy_emplace_boost_move_test, ((set)(multiset)(map)(multimap)))
template <class T> template <class T> void unnecessary_copy_emplace_boost_move_set_test(T*)
void unnecessary_copy_emplace_boost_move_set_test(T*) {
{
reset(); reset();
T x; T x;
BOOST_DEDUCED_TYPENAME T::value_type a; BOOST_DEDUCED_TYPENAME T::value_type a;
COPY_COUNT(1); MOVE_COUNT(0); COPY_COUNT(1);
MOVE_COUNT(0);
x.emplace(boost::move(a)); x.emplace(boost::move(a));
COPY_COUNT(1); MOVE_COUNT(1); COPY_COUNT(1);
} MOVE_COUNT(1);
}
UNORDERED_TEST(unnecessary_copy_emplace_boost_move_set_test, UNORDERED_TEST(unnecessary_copy_emplace_boost_move_set_test, ((set)(multiset)))
((set)(multiset)))
template <class T> template <class T> void unnecessary_copy_emplace_boost_move_map_test(T*)
void unnecessary_copy_emplace_boost_move_map_test(T*) {
{
reset(); reset();
T x; T x;
COPY_COUNT(0); MOVE_COUNT(0); COPY_COUNT(0);
MOVE_COUNT(0);
BOOST_DEDUCED_TYPENAME T::value_type a; BOOST_DEDUCED_TYPENAME T::value_type a;
COPY_COUNT(1); MOVE_COUNT_EXTRA(0, 1); COPY_COUNT(1);
MOVE_COUNT_EXTRA(0, 1);
x.emplace(boost::move(a)); x.emplace(boost::move(a));
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
COPY_COUNT(2); MOVE_COUNT_EXTRA(0, 1); COPY_COUNT(2);
MOVE_COUNT_EXTRA(0, 1);
#else #else
COPY_COUNT(1); MOVE_COUNT(1); COPY_COUNT(1);
MOVE_COUNT(1);
#endif #endif
} }
UNORDERED_TEST(unnecessary_copy_emplace_boost_move_map_test, UNORDERED_TEST(unnecessary_copy_emplace_boost_move_map_test, ((map)(multimap)))
((map)(multimap)))
UNORDERED_AUTO_TEST(unnecessary_copy_emplace_set_test) UNORDERED_AUTO_TEST(unnecessary_copy_emplace_set_test)
{ {
// When calling 'source' the object is moved on some compilers, but not // When calling 'source' the object is moved on some compilers, but not
// others. So count that here to adjust later. // others. So count that here to adjust later.
@@ -310,11 +303,12 @@ namespace unnecessary_copy_tests
boost::unordered_set<count_copies> x; boost::unordered_set<count_copies> x;
count_copies a; count_copies a;
x.insert(a); x.insert(a);
COPY_COUNT(2); MOVE_COUNT(0); COPY_COUNT(2);
MOVE_COUNT(0);
// //
// 0 arguments // 0 arguments
// //
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100)) #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
// The container will have to create a copy in order to compare with // The container will have to create a copy in order to compare with
@@ -324,9 +318,11 @@ namespace unnecessary_copy_tests
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || \ #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || \
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES) !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
// source_cost doesn't make much sense here, but it seems to fit. // source_cost doesn't make much sense here, but it seems to fit.
COPY_COUNT(1); MOVE_COUNT(source_cost); COPY_COUNT(1);
MOVE_COUNT(source_cost);
#else #else
COPY_COUNT(1); MOVE_COUNT(1 + source_cost); COPY_COUNT(1);
MOVE_COUNT(1 + source_cost);
#endif #endif
#endif #endif
@@ -338,21 +334,25 @@ namespace unnecessary_copy_tests
// without creating a new one. // without creating a new one.
reset(); reset();
x.emplace(a); x.emplace(a);
COPY_COUNT(0); MOVE_COUNT(0); COPY_COUNT(0);
MOVE_COUNT(0);
// A new object is created by source, but it shouldn't be moved or // A new object is created by source, but it shouldn't be moved or
// copied. // copied.
reset(); reset();
x.emplace(source<count_copies>()); x.emplace(source<count_copies>());
COPY_COUNT(1); MOVE_COUNT(source_cost); COPY_COUNT(1);
MOVE_COUNT(source_cost);
// No move should take place. // No move should take place.
reset(); reset();
x.emplace(boost::move(a)); x.emplace(boost::move(a));
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
COPY_COUNT(0); MOVE_COUNT(0); COPY_COUNT(0);
MOVE_COUNT(0);
#else #else
COPY_COUNT(0); MOVE_COUNT(1); COPY_COUNT(0);
MOVE_COUNT(1);
#endif #endif
// Use a new value for cases where a did get moved... // Use a new value for cases where a did get moved...
@@ -362,7 +362,8 @@ namespace unnecessary_copy_tests
// the existing element. // the existing element.
reset(); reset();
x.emplace(b.tag_); x.emplace(b.tag_);
COPY_COUNT(1); MOVE_COUNT(0); COPY_COUNT(1);
MOVE_COUNT(0);
// //
// 2 arguments // 2 arguments
@@ -377,11 +378,12 @@ namespace unnecessary_copy_tests
reset(); reset();
x.emplace(b, b); x.emplace(b, b);
COPY_COUNT(1); MOVE_COUNT(0); COPY_COUNT(1);
} MOVE_COUNT(0);
}
UNORDERED_AUTO_TEST(unnecessary_copy_emplace_map_test) UNORDERED_AUTO_TEST(unnecessary_copy_emplace_map_test)
{ {
// When calling 'source' the object is moved on some compilers, but not // When calling 'source' the object is moved on some compilers, but not
// others. So count that here to adjust later. // others. So count that here to adjust later.
@@ -400,34 +402,36 @@ namespace unnecessary_copy_tests
// TODO: Run tests for pairs without const etc. // TODO: Run tests for pairs without const etc.
std::pair<count_copies const, count_copies> a; std::pair<count_copies const, count_copies> a;
x.emplace(a); x.emplace(a);
COPY_COUNT_EXTRA(4, 1); MOVE_COUNT_EXTRA(0, 1); COPY_COUNT_EXTRA(4, 1);
MOVE_COUNT_EXTRA(0, 1);
// //
// 0 arguments // 0 arguments
// //
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100)) #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
// COPY_COUNT(1) would be okay here. // COPY_COUNT(1) would be okay here.
reset(); reset();
x.emplace(); x.emplace();
# if BOOST_WORKAROUND(BOOST_MSVC, == 1700) #if BOOST_WORKAROUND(BOOST_MSVC, == 1700)
// This is a little odd, Visual C++ 11 seems to move the pair, which // This is a little odd, Visual C++ 11 seems to move the pair, which
// results in one copy (for the const key) and one move (for the // results in one copy (for the const key) and one move (for the
// non-const mapped value). Since 'emplace(boost::move(a))' (see below) // non-const mapped value). Since 'emplace(boost::move(a))' (see below)
// has the normal result, it must be some odd consequence of how // has the normal result, it must be some odd consequence of how
// Visual C++ 11 handles calling move for default arguments. // Visual C++ 11 handles calling move for default arguments.
COPY_COUNT(3); MOVE_COUNT(1); COPY_COUNT(3);
# else MOVE_COUNT(1);
COPY_COUNT_EXTRA(2, 1); MOVE_COUNT_EXTRA(0, 1); #else
# endif COPY_COUNT_EXTRA(2, 1);
MOVE_COUNT_EXTRA(0, 1);
#endif
#endif #endif
reset(); reset();
x.emplace(boost::unordered::piecewise_construct, x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(),
boost::make_tuple(),
boost::make_tuple()); boost::make_tuple());
COPY_COUNT(2); MOVE_COUNT(0); COPY_COUNT(2);
MOVE_COUNT(0);
// //
// 1 argument // 1 argument
@@ -435,13 +439,15 @@ namespace unnecessary_copy_tests
reset(); reset();
x.emplace(a); x.emplace(a);
COPY_COUNT(0); MOVE_COUNT(0); COPY_COUNT(0);
MOVE_COUNT(0);
// A new object is created by source, but it shouldn't be moved or // A new object is created by source, but it shouldn't be moved or
// copied. // copied.
reset(); reset();
x.emplace(source<std::pair<count_copies, count_copies> >()); x.emplace(source<std::pair<count_copies, count_copies> >());
COPY_COUNT(2); MOVE_COUNT(source_pair_cost); COPY_COUNT(2);
MOVE_COUNT(source_pair_cost);
#if !(defined(__GNUC__) && __cplusplus < 199900L) && \ #if !(defined(__GNUC__) && __cplusplus < 199900L) && \
!(defined(_MSC_VER) && _MSC_VER < 1600) !(defined(_MSC_VER) && _MSC_VER < 1600)
@@ -449,7 +455,8 @@ namespace unnecessary_copy_tests
reset(); reset();
std::pair<count_copies const&, count_copies const&> a_ref(part, part); std::pair<count_copies const&, count_copies const&> a_ref(part, part);
x.emplace(a_ref); x.emplace(a_ref);
COPY_COUNT(2); MOVE_COUNT(0); COPY_COUNT(2);
MOVE_COUNT(0);
#endif #endif
@@ -457,7 +464,8 @@ namespace unnecessary_copy_tests
// (since a is already in the container) // (since a is already in the container)
reset(); reset();
x.emplace(boost::move(a)); x.emplace(boost::move(a));
COPY_COUNT(0); MOVE_COUNT(0); COPY_COUNT(0);
MOVE_COUNT(0);
// //
// 2 arguments // 2 arguments
@@ -467,26 +475,31 @@ namespace unnecessary_copy_tests
reset(); reset();
x.emplace(b.first, b.second); x.emplace(b.first, b.second);
COPY_COUNT(0); MOVE_COUNT(0); COPY_COUNT(0);
MOVE_COUNT(0);
reset(); reset();
x.emplace(source<count_copies>(), source<count_copies>()); x.emplace(source<count_copies>(), source<count_copies>());
COPY_COUNT(2); MOVE_COUNT(source_cost * 2); COPY_COUNT(2);
MOVE_COUNT(source_cost * 2);
// source<count_copies> creates a single copy. // source<count_copies> creates a single copy.
reset(); reset();
x.emplace(b.first, source<count_copies>()); x.emplace(b.first, source<count_copies>());
COPY_COUNT(1); MOVE_COUNT(source_cost); COPY_COUNT(1);
MOVE_COUNT(source_cost);
reset(); reset();
x.emplace(count_copies(b.first.tag_), count_copies(b.second.tag_)); x.emplace(count_copies(b.first.tag_), count_copies(b.second.tag_));
COPY_COUNT(2); MOVE_COUNT(0); COPY_COUNT(2);
MOVE_COUNT(0);
reset(); reset();
x.emplace(boost::unordered::piecewise_construct, x.emplace(boost::unordered::piecewise_construct,
boost::make_tuple(boost::ref(b.first)), boost::make_tuple(boost::ref(b.first)),
boost::make_tuple(boost::ref(b.second))); boost::make_tuple(boost::ref(b.second)));
COPY_COUNT(0); MOVE_COUNT(0); COPY_COUNT(0);
MOVE_COUNT(0);
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) || defined(BOOST_HAS_TR1_TUPLE) #if !defined(BOOST_NO_CXX11_HDR_TUPLE) || defined(BOOST_HAS_TR1_TUPLE)
@@ -494,7 +507,8 @@ namespace unnecessary_copy_tests
x.emplace(boost::unordered::piecewise_construct, x.emplace(boost::unordered::piecewise_construct,
std::make_tuple(std::ref(b.first)), std::make_tuple(std::ref(b.first)),
std::make_tuple(std::ref(b.second))); std::make_tuple(std::ref(b.second)));
COPY_COUNT(0); MOVE_COUNT(0); COPY_COUNT(0);
MOVE_COUNT(0);
std::pair<count_copies const, count_copies> move_source_trial; std::pair<count_copies const, count_copies> move_source_trial;
reset(); reset();
@@ -516,14 +530,13 @@ namespace unnecessary_copy_tests
!(defined(BOOST_MSVC) && BOOST_MSVC < 1700) !(defined(BOOST_MSVC) && BOOST_MSVC < 1700)
reset(); reset();
x.emplace(boost::unordered::piecewise_construct, x.emplace(boost::unordered::piecewise_construct,
std::forward_as_tuple(b.first), std::forward_as_tuple(b.first), std::forward_as_tuple(b.second));
std::forward_as_tuple(b.second)); COPY_COUNT(0);
COPY_COUNT(0); MOVE_COUNT(0); MOVE_COUNT(0);
#endif #endif
#endif #endif
}
}
} }
RUN_TESTS() RUN_TESTS()