forked from boostorg/unordered
Reformat with clang-format
This commit is contained in:
@@ -15,21 +15,21 @@
|
||||
// Already defined.
|
||||
#elif defined(BOOST_LIBSTDCXX11)
|
||||
// https://github.com/gcc-mirror/gcc/blob/gcc-4_6-branch/libstdc++-v3/include/bits/stl_pair.h#L70
|
||||
# if BOOST_LIBSTDCXX_VERSION > 40600
|
||||
# define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
|
||||
# endif
|
||||
#if BOOST_LIBSTDCXX_VERSION > 40600
|
||||
#define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
|
||||
#endif
|
||||
#elif defined(_LIBCPP_VERSION)
|
||||
// https://github.com/llvm-mirror/libcxx/blob/release_30/include/utility#L206
|
||||
# if LIBCPP_VERSION >= 3000
|
||||
# define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
|
||||
# endif
|
||||
#if LIBCPP_VERSION >= 3000
|
||||
#define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
|
||||
#endif
|
||||
#elif defined(BOOST_MSVC)
|
||||
// Apparently C++11 standard supported in Visual Studio 2012
|
||||
// https://msdn.microsoft.com/en-us/library/hh567368.aspx#stl
|
||||
// 2012 = VC+11 = BOOST_MSVC 1700 Hopefully!
|
||||
# if BOOST_MSVC >= 1700
|
||||
# define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
|
||||
# endif
|
||||
#if BOOST_MSVC >= 1700
|
||||
#define BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT)
|
||||
@@ -40,16 +40,16 @@
|
||||
#include <utility>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace unordered
|
||||
{
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
#if BOOST_UNORDERED_HAVE_PIECEWISE_CONSTRUCT
|
||||
using std::piecewise_construct_t;
|
||||
using std::piecewise_construct;
|
||||
using std::piecewise_construct_t;
|
||||
using std::piecewise_construct;
|
||||
#else
|
||||
struct piecewise_construct_t {};
|
||||
const piecewise_construct_t piecewise_construct = piecewise_construct_t();
|
||||
struct piecewise_construct_t
|
||||
{
|
||||
};
|
||||
const piecewise_construct_t piecewise_construct = piecewise_construct_t();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,76 +3,73 @@
|
||||
// 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)
|
||||
|
||||
#include <boost/unordered/unordered_map_fwd.hpp>
|
||||
#include <boost/unordered/detail/implementation.hpp>
|
||||
#include <boost/unordered/unordered_map_fwd.hpp>
|
||||
|
||||
namespace boost { namespace unordered { 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;
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
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 A allocator;
|
||||
typedef std::pair<K const, M> value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef K key_type;
|
||||
typedef A allocator;
|
||||
typedef std::pair<K const, M> value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef K key_type;
|
||||
|
||||
typedef boost::unordered::detail::allocator_traits<allocator>
|
||||
traits;
|
||||
typedef boost::unordered::detail::pick_node<allocator, value_type> pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
typedef boost::unordered::detail::allocator_traits<allocator> traits;
|
||||
typedef boost::unordered::detail::pick_node<allocator, value_type> pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
|
||||
typedef boost::unordered::detail::table_impl<types> table;
|
||||
typedef boost::unordered::detail::map_extractor<key_type, value_type>
|
||||
extractor;
|
||||
typedef boost::unordered::detail::table_impl<types> table;
|
||||
typedef boost::unordered::detail::map_extractor<key_type, value_type>
|
||||
extractor;
|
||||
|
||||
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::
|
||||
iterator<node> iterator;
|
||||
typedef boost::unordered::iterator_detail::
|
||||
c_iterator<node> c_iterator;
|
||||
typedef boost::unordered::iterator_detail::
|
||||
l_iterator<node, policy> l_iterator;
|
||||
typedef boost::unordered::iterator_detail::
|
||||
cl_iterator<node, policy> cl_iterator;
|
||||
};
|
||||
typedef boost::unordered::iterator_detail::iterator<node> iterator;
|
||||
typedef boost::unordered::iterator_detail::c_iterator<node> c_iterator;
|
||||
typedef boost::unordered::iterator_detail::l_iterator<node, policy>
|
||||
l_iterator;
|
||||
typedef boost::unordered::iterator_detail::cl_iterator<node, policy>
|
||||
cl_iterator;
|
||||
};
|
||||
|
||||
template <typename A, typename K, typename M, typename H, typename P>
|
||||
struct multimap
|
||||
{
|
||||
typedef boost::unordered::detail::multimap<A, K, M, H, P> types;
|
||||
template <typename A, typename K, typename M, typename H, typename P>
|
||||
struct multimap
|
||||
{
|
||||
typedef boost::unordered::detail::multimap<A, K, M, H, P> types;
|
||||
|
||||
typedef A allocator;
|
||||
typedef std::pair<K const, M> value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef K key_type;
|
||||
typedef A allocator;
|
||||
typedef std::pair<K const, M> value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef K key_type;
|
||||
|
||||
typedef boost::unordered::detail::allocator_traits<allocator> traits;
|
||||
typedef boost::unordered::detail::pick_grouped_node<allocator,
|
||||
value_type> pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
typedef boost::unordered::detail::allocator_traits<allocator> traits;
|
||||
typedef boost::unordered::detail::pick_grouped_node<allocator, value_type>
|
||||
pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
|
||||
typedef boost::unordered::detail::grouped_table_impl<types> table;
|
||||
typedef boost::unordered::detail::map_extractor<key_type, value_type>
|
||||
extractor;
|
||||
typedef boost::unordered::detail::grouped_table_impl<types> table;
|
||||
typedef boost::unordered::detail::map_extractor<key_type, value_type>
|
||||
extractor;
|
||||
|
||||
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::
|
||||
iterator<node> iterator;
|
||||
typedef boost::unordered::iterator_detail::
|
||||
c_iterator<node> c_iterator;
|
||||
typedef boost::unordered::iterator_detail::
|
||||
l_iterator<node, policy> l_iterator;
|
||||
typedef boost::unordered::iterator_detail::
|
||||
cl_iterator<node, policy> cl_iterator;
|
||||
};
|
||||
|
||||
}}}
|
||||
typedef boost::unordered::iterator_detail::iterator<node> iterator;
|
||||
typedef boost::unordered::iterator_detail::c_iterator<node> c_iterator;
|
||||
typedef boost::unordered::iterator_detail::l_iterator<node, policy>
|
||||
l_iterator;
|
||||
typedef boost::unordered::iterator_detail::cl_iterator<node, policy>
|
||||
cl_iterator;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,72 +3,70 @@
|
||||
// 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)
|
||||
|
||||
#include <boost/unordered/unordered_set_fwd.hpp>
|
||||
#include <boost/unordered/detail/implementation.hpp>
|
||||
#include <boost/unordered/unordered_set_fwd.hpp>
|
||||
|
||||
namespace boost { namespace unordered { namespace detail {
|
||||
template <typename A, typename T, typename H, typename P>
|
||||
struct set
|
||||
{
|
||||
typedef boost::unordered::detail::set<A, T, H, P> types;
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
namespace detail {
|
||||
template <typename A, typename T, typename H, typename P> struct set
|
||||
{
|
||||
typedef boost::unordered::detail::set<A, T, H, P> types;
|
||||
|
||||
typedef A allocator;
|
||||
typedef T value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef T key_type;
|
||||
typedef A allocator;
|
||||
typedef T value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef T key_type;
|
||||
|
||||
typedef boost::unordered::detail::allocator_traits<allocator> traits;
|
||||
typedef boost::unordered::detail::pick_node<allocator, value_type> pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
typedef boost::unordered::detail::allocator_traits<allocator> traits;
|
||||
typedef boost::unordered::detail::pick_node<allocator, value_type> pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
|
||||
typedef boost::unordered::detail::table_impl<types> table;
|
||||
typedef boost::unordered::detail::set_extractor<value_type> extractor;
|
||||
typedef boost::unordered::detail::table_impl<types> table;
|
||||
typedef boost::unordered::detail::set_extractor<value_type> extractor;
|
||||
|
||||
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::
|
||||
c_iterator<node> iterator;
|
||||
typedef boost::unordered::iterator_detail::
|
||||
c_iterator<node> c_iterator;
|
||||
typedef boost::unordered::iterator_detail::
|
||||
cl_iterator<node, policy> l_iterator;
|
||||
typedef boost::unordered::iterator_detail::
|
||||
cl_iterator<node, policy> cl_iterator;
|
||||
};
|
||||
typedef boost::unordered::iterator_detail::c_iterator<node> iterator;
|
||||
typedef boost::unordered::iterator_detail::c_iterator<node> c_iterator;
|
||||
typedef boost::unordered::iterator_detail::cl_iterator<node, policy>
|
||||
l_iterator;
|
||||
typedef boost::unordered::iterator_detail::cl_iterator<node, policy>
|
||||
cl_iterator;
|
||||
};
|
||||
|
||||
template <typename A, typename T, typename H, typename P>
|
||||
struct multiset
|
||||
{
|
||||
typedef boost::unordered::detail::multiset<A, T, H, P> types;
|
||||
template <typename A, typename T, typename H, typename P> struct multiset
|
||||
{
|
||||
typedef boost::unordered::detail::multiset<A, T, H, P> types;
|
||||
|
||||
typedef A allocator;
|
||||
typedef T value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef T key_type;
|
||||
typedef A allocator;
|
||||
typedef T value_type;
|
||||
typedef H hasher;
|
||||
typedef P key_equal;
|
||||
typedef T key_type;
|
||||
|
||||
typedef boost::unordered::detail::allocator_traits<allocator> traits;
|
||||
typedef boost::unordered::detail::pick_grouped_node<allocator,
|
||||
value_type> pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
typedef boost::unordered::detail::allocator_traits<allocator> traits;
|
||||
typedef boost::unordered::detail::pick_grouped_node<allocator, value_type>
|
||||
pick;
|
||||
typedef typename pick::node node;
|
||||
typedef typename pick::bucket bucket;
|
||||
typedef typename pick::link_pointer link_pointer;
|
||||
|
||||
typedef boost::unordered::detail::grouped_table_impl<types> table;
|
||||
typedef boost::unordered::detail::set_extractor<value_type> extractor;
|
||||
typedef boost::unordered::detail::grouped_table_impl<types> table;
|
||||
typedef boost::unordered::detail::set_extractor<value_type> extractor;
|
||||
|
||||
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::
|
||||
c_iterator<node> iterator;
|
||||
typedef boost::unordered::iterator_detail::
|
||||
c_iterator<node> c_iterator;
|
||||
typedef boost::unordered::iterator_detail::
|
||||
cl_iterator<node, policy> l_iterator;
|
||||
typedef boost::unordered::iterator_detail::
|
||||
cl_iterator<node, policy> cl_iterator;
|
||||
};
|
||||
}}}
|
||||
typedef boost::unordered::iterator_detail::c_iterator<node> iterator;
|
||||
typedef boost::unordered::iterator_detail::c_iterator<node> c_iterator;
|
||||
typedef boost::unordered::iterator_detail::cl_iterator<node, policy>
|
||||
l_iterator;
|
||||
typedef boost::unordered::iterator_detail::cl_iterator<node, policy>
|
||||
cl_iterator;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1260
-1505
File diff suppressed because it is too large
Load Diff
@@ -11,55 +11,48 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
#include <boost/unordered/detail/fwd.hpp>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace unordered
|
||||
{
|
||||
template <class K,
|
||||
class T,
|
||||
class H = boost::hash<K>,
|
||||
class P = std::equal_to<K>,
|
||||
class A = std::allocator<std::pair<const K, T> > >
|
||||
class unordered_map;
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
template <class K, class T, class H = boost::hash<K>,
|
||||
class P = std::equal_to<K>,
|
||||
class A = std::allocator<std::pair<const K, T> > >
|
||||
class unordered_map;
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline bool operator==(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>
|
||||
inline bool operator!=(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>
|
||||
inline void swap(unordered_map<K, T, H, P, A>&,
|
||||
unordered_map<K, T, H, P, A>&);
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline bool operator==(
|
||||
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>
|
||||
inline bool operator!=(
|
||||
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>
|
||||
inline void swap(unordered_map<K, T, H, P, A>&, unordered_map<K, T, H, P, A>&);
|
||||
|
||||
template <class K,
|
||||
class T,
|
||||
class H = boost::hash<K>,
|
||||
class P = std::equal_to<K>,
|
||||
class A = std::allocator<std::pair<const K, T> > >
|
||||
class unordered_multimap;
|
||||
template <class K, class T, class H = boost::hash<K>,
|
||||
class P = std::equal_to<K>,
|
||||
class A = std::allocator<std::pair<const K, T> > >
|
||||
class unordered_multimap;
|
||||
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline bool operator==(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>
|
||||
inline bool operator!=(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>
|
||||
inline void swap(unordered_multimap<K, T, H, P, A>&,
|
||||
unordered_multimap<K, T, H, P, A>&);
|
||||
}
|
||||
template <class K, class T, class H, class P, class A>
|
||||
inline bool operator==(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>
|
||||
inline bool operator!=(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>
|
||||
inline void swap(
|
||||
unordered_multimap<K, T, H, P, A>&, unordered_multimap<K, T, H, P, A>&);
|
||||
}
|
||||
|
||||
using boost::unordered::unordered_map;
|
||||
using boost::unordered::unordered_multimap;
|
||||
using boost::unordered::swap;
|
||||
using boost::unordered::operator==;
|
||||
using boost::unordered::operator!=;
|
||||
using boost::unordered::unordered_map;
|
||||
using boost::unordered::unordered_multimap;
|
||||
using boost::unordered::swap;
|
||||
using boost::unordered::operator==;
|
||||
using boost::unordered::operator!=;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+1175
-1414
File diff suppressed because it is too large
Load Diff
@@ -11,53 +11,46 @@
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
#include <boost/unordered/detail/fwd.hpp>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace unordered
|
||||
{
|
||||
template <class T,
|
||||
class H = boost::hash<T>,
|
||||
class P = std::equal_to<T>,
|
||||
class A = std::allocator<T> >
|
||||
class unordered_set;
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
template <class T, class H = boost::hash<T>, class P = std::equal_to<T>,
|
||||
class A = std::allocator<T> >
|
||||
class unordered_set;
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
inline bool operator==(unordered_set<T, H, P, A> const&,
|
||||
unordered_set<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
inline bool operator!=(unordered_set<T, H, P, A> const&,
|
||||
unordered_set<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
inline void swap(unordered_set<T, H, P, A> &m1,
|
||||
unordered_set<T, H, P, A> &m2);
|
||||
template <class T, class H, class P, class A>
|
||||
inline bool operator==(
|
||||
unordered_set<T, H, P, A> const&, unordered_set<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
inline bool operator!=(
|
||||
unordered_set<T, H, P, A> const&, unordered_set<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
inline void swap(unordered_set<T, H, P, A>& m1, unordered_set<T, H, P, A>& m2);
|
||||
|
||||
template <class T,
|
||||
class H = boost::hash<T>,
|
||||
class P = std::equal_to<T>,
|
||||
class A = std::allocator<T> >
|
||||
class unordered_multiset;
|
||||
template <class T, class H = boost::hash<T>, class P = std::equal_to<T>,
|
||||
class A = std::allocator<T> >
|
||||
class unordered_multiset;
|
||||
|
||||
template <class T, class H, class P, class A>
|
||||
inline bool operator==(unordered_multiset<T, H, P, A> const&,
|
||||
unordered_multiset<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
inline bool operator!=(unordered_multiset<T, H, P, A> const&,
|
||||
unordered_multiset<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
inline void swap(unordered_multiset<T, H, P, A> &m1,
|
||||
unordered_multiset<T, H, P, A> &m2);
|
||||
}
|
||||
template <class T, class H, class P, class A>
|
||||
inline bool operator==(unordered_multiset<T, H, P, A> const&,
|
||||
unordered_multiset<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
inline bool operator!=(unordered_multiset<T, H, P, A> const&,
|
||||
unordered_multiset<T, H, P, A> const&);
|
||||
template <class T, class H, class P, class A>
|
||||
inline void swap(
|
||||
unordered_multiset<T, H, P, A>& m1, unordered_multiset<T, H, P, A>& m2);
|
||||
}
|
||||
|
||||
using boost::unordered::unordered_set;
|
||||
using boost::unordered::unordered_multiset;
|
||||
using boost::unordered::swap;
|
||||
using boost::unordered::operator==;
|
||||
using boost::unordered::operator!=;
|
||||
using boost::unordered::unordered_set;
|
||||
using boost::unordered::unordered_multiset;
|
||||
using boost::unordered::swap;
|
||||
using boost::unordered::operator==;
|
||||
using boost::unordered::operator!=;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,17 +5,16 @@
|
||||
|
||||
#include "./containers.hpp"
|
||||
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
|
||||
#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
|
||||
|
||||
test::seed_t initialize_seed(12847);
|
||||
|
||||
template <class T>
|
||||
struct self_assign_base : public test::exception_base
|
||||
template <class T> struct self_assign_base : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
self_assign_base(std::size_t count = 0) : values(count) {}
|
||||
@@ -24,33 +23,33 @@ struct self_assign_base : public test::exception_base
|
||||
T init() const { return T(values.begin(), values.end()); }
|
||||
void run(T& x) const { x = x; }
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const
|
||||
{ test::check_equivalent_keys(x); }
|
||||
{
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct self_assign_test1 : self_assign_base<T> {};
|
||||
template <class T> struct self_assign_test1 : self_assign_base<T>
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct self_assign_test2 : self_assign_base<T>
|
||||
template <class T> struct self_assign_test2 : self_assign_base<T>
|
||||
{
|
||||
self_assign_test2() : self_assign_base<T>(100) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_base : public test::exception_base
|
||||
template <class T> struct assign_base : public test::exception_base
|
||||
{
|
||||
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::key_equal key_equal;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type;
|
||||
|
||||
assign_base(int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0) :
|
||||
x_values(),
|
||||
y_values(),
|
||||
x(0, hasher(tag1), key_equal(tag1), allocator_type(tag1)),
|
||||
y(0, hasher(tag2), key_equal(tag2), allocator_type(tag2))
|
||||
assign_base(int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0)
|
||||
: x_values(), y_values(),
|
||||
x(0, hasher(tag1), key_equal(tag1), allocator_type(tag1)),
|
||||
y(0, hasher(tag2), key_equal(tag2), allocator_type(tag2))
|
||||
{
|
||||
x.max_load_factor(mlf1);
|
||||
y.max_load_factor(mlf2);
|
||||
@@ -74,12 +73,11 @@ struct assign_base : public test::exception_base
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_values : assign_base<T>
|
||||
template <class T> struct assign_values : assign_base<T>
|
||||
{
|
||||
assign_values(unsigned int count1, unsigned int count2,
|
||||
int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0) :
|
||||
assign_base<T>(tag1, tag2, mlf1, mlf2)
|
||||
assign_values(unsigned int count1, unsigned int count2, int tag1, int tag2,
|
||||
float mlf1 = 1.0, float mlf2 = 1.0)
|
||||
: assign_base<T>(tag1, tag2, mlf1, mlf2)
|
||||
{
|
||||
this->x_values.fill(count1);
|
||||
this->y_values.fill(count2);
|
||||
@@ -88,47 +86,39 @@ struct assign_values : assign_base<T>
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test1 : assign_values<T>
|
||||
template <class T> struct assign_test1 : assign_values<T>
|
||||
{
|
||||
assign_test1() : assign_values<T>(0, 0, 0, 0) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test2 : assign_values<T>
|
||||
template <class T> struct assign_test2 : assign_values<T>
|
||||
{
|
||||
assign_test2() : assign_values<T>(60, 0, 0, 0) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test3 : assign_values<T>
|
||||
template <class T> struct assign_test3 : assign_values<T>
|
||||
{
|
||||
assign_test3() : assign_values<T>(0, 60, 0, 0) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test4 : assign_values<T>
|
||||
template <class T> struct assign_test4 : assign_values<T>
|
||||
{
|
||||
assign_test4() : assign_values<T>(10, 10, 1, 2) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test4a : assign_values<T>
|
||||
template <class T> struct assign_test4a : assign_values<T>
|
||||
{
|
||||
assign_test4a() : assign_values<T>(10, 100, 1, 2) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct assign_test5 : assign_values<T>
|
||||
template <class T> struct assign_test5 : assign_values<T>
|
||||
{
|
||||
assign_test5() : assign_values<T>(5, 60, 0, 0, 1.0f, 0.1f) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct equivalent_test1 : assign_base<T>
|
||||
template <class T> struct equivalent_test1 : assign_base<T>
|
||||
{
|
||||
equivalent_test1() :
|
||||
assign_base<T>(0, 0)
|
||||
equivalent_test1() : assign_base<T>(0, 0)
|
||||
{
|
||||
test::random_values<T> x_values2(10);
|
||||
this->x_values.insert(x_values2.begin(), x_values2.end());
|
||||
@@ -141,9 +131,8 @@ struct equivalent_test1 : assign_base<T>
|
||||
}
|
||||
};
|
||||
|
||||
EXCEPTION_TESTS(
|
||||
(self_assign_test1)(self_assign_test2)
|
||||
(assign_test1)(assign_test2)(assign_test3)(assign_test4)(assign_test4a)(assign_test5)
|
||||
(equivalent_test1),
|
||||
EXCEPTION_TESTS((self_assign_test1)(self_assign_test2)(assign_test1)(
|
||||
assign_test2)(assign_test3)(assign_test4)(assign_test4a)(
|
||||
assign_test5)(equivalent_test1),
|
||||
CONTAINER_SEQ)
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
#include "./containers.hpp"
|
||||
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/input_iterator.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
|
||||
template <typename T> inline void avoid_unused_warning(T const&) {}
|
||||
|
||||
@@ -20,62 +20,61 @@ struct objects
|
||||
test::exception::allocator<test::exception::object> allocator;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct construct_test1 : public objects, test::exception_base
|
||||
template <class T> struct construct_test1 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
void run() const
|
||||
{
|
||||
T x;
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct construct_test2 : public objects, test::exception_base
|
||||
template <class T> struct construct_test2 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
void run() const
|
||||
{
|
||||
T x(300);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct construct_test3 : public objects, test::exception_base
|
||||
template <class T> struct construct_test3 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
void run() const
|
||||
{
|
||||
T x(0, hash);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct construct_test4 : public objects, test::exception_base
|
||||
template <class T> struct construct_test4 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
void run() const
|
||||
{
|
||||
T x(0, hash, equal_to);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct construct_test5 : public objects, test::exception_base
|
||||
template <class T> struct construct_test5 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
void run() const
|
||||
{
|
||||
T x(50, hash, equal_to, allocator);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct construct_test6 : public objects, test::exception_base
|
||||
template <class T> struct construct_test6 : public objects, test::exception_base
|
||||
{
|
||||
void run() const {
|
||||
void run() const
|
||||
{
|
||||
T x(allocator);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct range : public test::exception_base
|
||||
template <class T> struct range : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
|
||||
@@ -83,37 +82,37 @@ struct range : public test::exception_base
|
||||
range(unsigned int count) : values(count) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct range_construct_test1 : public range<T>, objects
|
||||
template <class T> struct range_construct_test1 : public range<T>, objects
|
||||
{
|
||||
void run() const {
|
||||
void run() const
|
||||
{
|
||||
T x(this->values.begin(), this->values.end());
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct range_construct_test2 : public range<T>, objects
|
||||
template <class T> struct range_construct_test2 : public range<T>, objects
|
||||
{
|
||||
void run() const {
|
||||
void run() const
|
||||
{
|
||||
T x(this->values.begin(), this->values.end(), 0);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct range_construct_test3 : public range<T>, objects
|
||||
template <class T> struct range_construct_test3 : public range<T>, objects
|
||||
{
|
||||
void run() const {
|
||||
void run() const
|
||||
{
|
||||
T x(this->values.begin(), this->values.end(), 0, hash);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct range_construct_test4 : public range<T>, objects
|
||||
template <class T> 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);
|
||||
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
|
||||
// of objects in case it triggers a rehash.
|
||||
template <class T>
|
||||
struct range_construct_test5 : public range<T>, objects
|
||||
template <class T> struct range_construct_test5 : public range<T>, objects
|
||||
{
|
||||
range_construct_test5() : range<T>(60) {}
|
||||
|
||||
void run() const {
|
||||
T x(this->values.begin(), this->values.end(), 0,
|
||||
hash, equal_to, allocator);
|
||||
void run() const
|
||||
{
|
||||
T x(this->values.begin(), this->values.end(), 0, hash, equal_to,
|
||||
allocator);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct input_range_construct_test : public range<T>, objects
|
||||
template <class T> struct input_range_construct_test : public range<T>, objects
|
||||
{
|
||||
input_range_construct_test() : range<T>(60) {}
|
||||
|
||||
void run() const {
|
||||
void run() const
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
begin = this->values.begin(), end = this->values.end();
|
||||
T x(test::input_iterator(begin), test::input_iterator(end),
|
||||
0, hash, equal_to, allocator);
|
||||
begin = this->values.begin(),
|
||||
end = this->values.end();
|
||||
T x(test::input_iterator(begin), test::input_iterator(end), 0, hash,
|
||||
equal_to, allocator);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct copy_range_construct_test : public range<T>, objects
|
||||
template <class T> struct copy_range_construct_test : public range<T>, objects
|
||||
{
|
||||
copy_range_construct_test() : range<T>(60) {}
|
||||
|
||||
void run() const {
|
||||
void run() const
|
||||
{
|
||||
T x(test::copy_iterator(this->values.begin()),
|
||||
test::copy_iterator(this->values.end()),
|
||||
0, hash, equal_to, allocator);
|
||||
test::copy_iterator(this->values.end()), 0, hash, equal_to,
|
||||
allocator);
|
||||
avoid_unused_warning(x);
|
||||
}
|
||||
};
|
||||
|
||||
EXCEPTION_TESTS(
|
||||
(construct_test1)
|
||||
(construct_test2)
|
||||
(construct_test3)
|
||||
(construct_test4)
|
||||
(construct_test5)
|
||||
(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),
|
||||
(construct_test1)(construct_test2)(construct_test3)(construct_test4)(
|
||||
construct_test5)(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)
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -12,39 +12,33 @@
|
||||
|
||||
#include "../objects/exception.hpp"
|
||||
|
||||
typedef boost::unordered_set<
|
||||
test::exception::object,
|
||||
test::exception::hash,
|
||||
typedef boost::unordered_set<test::exception::object, test::exception::hash,
|
||||
test::exception::equal_to,
|
||||
test::exception::allocator<test::exception::object> > test_set;
|
||||
typedef boost::unordered_multiset<
|
||||
test::exception::object,
|
||||
test::exception::hash,
|
||||
test::exception::equal_to,
|
||||
test::exception::allocator2<test::exception::object> > test_multiset;
|
||||
typedef boost::unordered_map<
|
||||
test::exception::object,
|
||||
test::exception::object,
|
||||
test::exception::hash,
|
||||
test::exception::equal_to,
|
||||
test::exception::allocator2<test::exception::object> > test_map;
|
||||
typedef boost::unordered_multimap<
|
||||
test::exception::object,
|
||||
test::exception::object,
|
||||
test::exception::hash,
|
||||
test::exception::equal_to,
|
||||
test::exception::allocator<test::exception::object> > test_multimap;
|
||||
test::exception::allocator<test::exception::object> >
|
||||
test_set;
|
||||
typedef boost::unordered_multiset<test::exception::object,
|
||||
test::exception::hash, test::exception::equal_to,
|
||||
test::exception::allocator2<test::exception::object> >
|
||||
test_multiset;
|
||||
typedef boost::unordered_map<test::exception::object, test::exception::object,
|
||||
test::exception::hash, test::exception::equal_to,
|
||||
test::exception::allocator2<test::exception::object> >
|
||||
test_map;
|
||||
typedef boost::unordered_multimap<test::exception::object,
|
||||
test::exception::object, test::exception::hash, test::exception::equal_to,
|
||||
test::exception::allocator<test::exception::object> >
|
||||
test_multimap;
|
||||
typedef boost::unordered_set<
|
||||
std::pair<test::exception::object, test::exception::object>,
|
||||
test::exception::hash,
|
||||
test::exception::equal_to,
|
||||
test::exception::allocator<test::exception::object> > test_pair_set;
|
||||
test::exception::hash, test::exception::equal_to,
|
||||
test::exception::allocator<test::exception::object> >
|
||||
test_pair_set;
|
||||
typedef boost::unordered_multiset<
|
||||
std::pair<test::exception::object, test::exception::object>,
|
||||
test::exception::hash,
|
||||
test::exception::equal_to,
|
||||
test::exception::allocator2<test::exception::object> > test_pair_multiset;
|
||||
|
||||
test::exception::hash, test::exception::equal_to,
|
||||
test::exception::allocator2<test::exception::object> >
|
||||
test_pair_multiset;
|
||||
|
||||
#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)
|
||||
|
||||
@@ -11,47 +11,46 @@ template <typename T> inline void avoid_unused_warning(T const&) {}
|
||||
|
||||
test::seed_t initialize_seed(73041);
|
||||
|
||||
template <class T>
|
||||
struct copy_test1 : public test::exception_base
|
||||
template <class T> struct copy_test1 : public test::exception_base
|
||||
{
|
||||
T x;
|
||||
|
||||
void run() const {
|
||||
void run() const
|
||||
{
|
||||
T y(x);
|
||||
avoid_unused_warning(y);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct copy_test2 : public test::exception_base
|
||||
template <class T> struct copy_test2 : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
T x;
|
||||
|
||||
copy_test2() : values(5), x(values.begin(), values.end()) {}
|
||||
|
||||
void run() const {
|
||||
void run() const
|
||||
{
|
||||
T y(x);
|
||||
avoid_unused_warning(y);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct copy_test3 : public test::exception_base
|
||||
template <class T> struct copy_test3 : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
T x;
|
||||
|
||||
copy_test3() : values(100), x(values.begin(), values.end()) {}
|
||||
|
||||
void run() const {
|
||||
void run() const
|
||||
{
|
||||
T y(x);
|
||||
avoid_unused_warning(y);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct copy_with_allocator_test : public test::exception_base
|
||||
template <class T> struct copy_with_allocator_test : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
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()) {}
|
||||
|
||||
void run() const {
|
||||
void run() const
|
||||
{
|
||||
T y(x, allocator);
|
||||
avoid_unused_warning(y);
|
||||
}
|
||||
};
|
||||
|
||||
EXCEPTION_TESTS(
|
||||
(copy_test1)(copy_test2)(copy_test3)(copy_with_allocator_test),
|
||||
EXCEPTION_TESTS((copy_test1)(copy_test2)(copy_test3)(copy_with_allocator_test),
|
||||
CONTAINER_SEQ)
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -5,52 +5,46 @@
|
||||
|
||||
#include "./containers.hpp"
|
||||
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/helpers.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
|
||||
test::seed_t initialize_seed(835193);
|
||||
|
||||
template <class T>
|
||||
struct erase_test_base : public test::exception_base
|
||||
template <class T> struct erase_test_base : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
erase_test_base(unsigned int count = 5) : values(count) {}
|
||||
|
||||
typedef T data_type;
|
||||
|
||||
data_type init() const {
|
||||
return T(values.begin(), values.end());
|
||||
}
|
||||
data_type init() const { 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);
|
||||
|
||||
BOOST_TEST(scope.find("hash::") != std::string::npos ||
|
||||
scope.find("equal_to::") != std::string::npos ||
|
||||
scope == "operator==(object, object)");
|
||||
scope.find("equal_to::") != std::string::npos ||
|
||||
scope == "operator==(object, object)");
|
||||
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct erase_by_key_test1 : public erase_test_base<T>
|
||||
template <class T> struct erase_by_key_test1 : public erase_test_base<T>
|
||||
{
|
||||
void run(T& x) const
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
test::random_values<T>::const_iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
iterator;
|
||||
|
||||
for(iterator it = this->values.begin(), end = this->values.end();
|
||||
it != end; ++it)
|
||||
{
|
||||
for (iterator it = this->values.begin(), end = this->values.end();
|
||||
it != end; ++it) {
|
||||
x.erase(test::get_key<T>(*it));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
EXCEPTION_TESTS(
|
||||
(erase_by_key_test1),
|
||||
CONTAINER_SEQ)
|
||||
EXCEPTION_TESTS((erase_by_key_test1), CONTAINER_SEQ)
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -5,51 +5,52 @@
|
||||
|
||||
#include "./containers.hpp"
|
||||
|
||||
#include <string>
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/strong.hpp"
|
||||
#include "../helpers/helpers.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/strong.hpp"
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
test::seed_t initialize_seed(747373);
|
||||
|
||||
template <class T>
|
||||
struct insert_test_base : public test::exception_base
|
||||
template <class T> struct insert_test_base : public test::exception_base
|
||||
{
|
||||
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 test::strong<T> strong_type;
|
||||
|
||||
data_type init() const {
|
||||
return T();
|
||||
}
|
||||
data_type init() const { return T(); }
|
||||
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(
|
||||
T const& x, strong_type const& strong) const
|
||||
{
|
||||
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);
|
||||
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>
|
||||
struct emplace_test1 : public insert_test_base<T>
|
||||
template <class T> struct emplace_test1 : public insert_test_base<T>
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
|
||||
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
strong.store(x, test::detail::tracker.count_allocations);
|
||||
x.emplace(*it);
|
||||
}
|
||||
@@ -58,74 +59,72 @@ struct emplace_test1 : public insert_test_base<T>
|
||||
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
struct insert_test1 : public insert_test_base<T>
|
||||
template <class T> struct insert_test1 : public insert_test_base<T>
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
|
||||
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
strong.store(x, test::detail::tracker.count_allocations);
|
||||
x.insert(*it);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct insert_test2 : public insert_test_base<T>
|
||||
template <class T> struct insert_test2 : public insert_test_base<T>
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
|
||||
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
strong.store(x, test::detail::tracker.count_allocations);
|
||||
x.insert(x.begin(), *it);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct insert_test3 : public insert_test_base<T>
|
||||
template <class T> struct insert_test3 : public insert_test_base<T>
|
||||
{
|
||||
void run(T& x) const {
|
||||
x.insert(this->values.begin(), this->values.end());
|
||||
}
|
||||
void run(T& x) const { 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);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct insert_test4 : public insert_test_base<T>
|
||||
template <class T> struct insert_test4 : public insert_test_base<T>
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
|
||||
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
strong.store(x, test::detail::tracker.count_allocations);
|
||||
x.insert(it, test::next(it));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct insert_test_rehash1 : public insert_test_base<T>
|
||||
template <class T> struct insert_test_rehash1 : public insert_test_base<T>
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
|
||||
|
||||
insert_test_rehash1() : insert_test_base<T>(1000) {}
|
||||
|
||||
T init() const {
|
||||
T init() const
|
||||
{
|
||||
using namespace std;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::size_type size_type;
|
||||
|
||||
@@ -134,24 +133,24 @@ struct insert_test_rehash1 : public insert_test_base<T>
|
||||
// TODO: This doesn't really work is bucket_count is 0
|
||||
size_type bucket_count = x.bucket_count();
|
||||
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());
|
||||
x.insert(this->values.begin(),
|
||||
test::next(this->values.begin(), initial_elements));
|
||||
test::next(this->values.begin(), initial_elements));
|
||||
BOOST_TEST(bucket_count == x.bucket_count());
|
||||
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();
|
||||
int count = 0;
|
||||
BOOST_DEDUCED_TYPENAME T::const_iterator pos = x.cbegin();
|
||||
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
it = test::next(this->values.begin(), x.size()),
|
||||
end = this->values.end();
|
||||
it != end && count < 10; ++it, ++count)
|
||||
{
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
it = test::next(this->values.begin(), x.size()),
|
||||
end = this->values.end();
|
||||
it != end && count < 10; ++it, ++count) {
|
||||
strong.store(x, test::detail::tracker.count_allocations);
|
||||
pos = x.insert(pos, *it);
|
||||
}
|
||||
@@ -162,20 +161,19 @@ struct insert_test_rehash1 : public insert_test_base<T>
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct insert_test_rehash2 : public insert_test_rehash1<T>
|
||||
template <class T> struct insert_test_rehash2 : public insert_test_rehash1<T>
|
||||
{
|
||||
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();
|
||||
int count = 0;
|
||||
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
it = test::next(this->values.begin(), x.size()),
|
||||
end = this->values.end();
|
||||
it != end && count < 10; ++it, ++count)
|
||||
{
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
it = test::next(this->values.begin(), x.size()),
|
||||
end = this->values.end();
|
||||
it != end && count < 10; ++it, ++count) {
|
||||
strong.store(x, test::detail::tracker.count_allocations);
|
||||
x.insert(*it);
|
||||
}
|
||||
@@ -186,15 +184,15 @@ struct insert_test_rehash2 : public insert_test_rehash1<T>
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct insert_test_rehash3 : public insert_test_base<T>
|
||||
template <class T> struct insert_test_rehash3 : public insert_test_base<T>
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::size_type mutable
|
||||
rehash_bucket_count, original_bucket_count;
|
||||
BOOST_DEDUCED_TYPENAME T::size_type mutable rehash_bucket_count,
|
||||
original_bucket_count;
|
||||
|
||||
insert_test_rehash3() : insert_test_base<T>(1000) {}
|
||||
|
||||
T init() const {
|
||||
T init() const
|
||||
{
|
||||
using namespace std;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::size_type size_type;
|
||||
|
||||
@@ -202,78 +200,82 @@ struct insert_test_rehash3 : public insert_test_base<T>
|
||||
x.max_load_factor(0.25);
|
||||
|
||||
original_bucket_count = x.bucket_count();
|
||||
rehash_bucket_count = static_cast<size_type>(
|
||||
ceil((double) original_bucket_count * (double) x.max_load_factor())) - 1;
|
||||
rehash_bucket_count =
|
||||
static_cast<size_type>(ceil(
|
||||
(double)original_bucket_count * (double)x.max_load_factor())) -
|
||||
1;
|
||||
|
||||
size_type initial_elements =
|
||||
rehash_bucket_count > 5 ? rehash_bucket_count - 5 : 1;
|
||||
|
||||
BOOST_TEST(initial_elements < this->values.size());
|
||||
x.insert(this->values.begin(),
|
||||
test::next(this->values.begin(), initial_elements));
|
||||
test::next(this->values.begin(), initial_elements));
|
||||
BOOST_TEST(original_bucket_count == x.bucket_count());
|
||||
return x;
|
||||
}
|
||||
|
||||
void run(T& x) const {
|
||||
void run(T& x) const
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::size_type bucket_count = x.bucket_count();
|
||||
|
||||
x.insert(test::next(this->values.begin(), x.size()),
|
||||
test::next(this->values.begin(), x.size() + 20));
|
||||
test::next(this->values.begin(), x.size() + 20));
|
||||
|
||||
// This isn't actually a failure, but it means the test isn't doing its
|
||||
// job.
|
||||
BOOST_TEST(x.bucket_count() != bucket_count);
|
||||
}
|
||||
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const {
|
||||
if(x.size() < rehash_bucket_count) {
|
||||
//BOOST_TEST(x.bucket_count() == original_bucket_count);
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x) const
|
||||
{
|
||||
if (x.size() < rehash_bucket_count) {
|
||||
// BOOST_TEST(x.bucket_count() == original_bucket_count);
|
||||
}
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
#define BASIC_TESTS \
|
||||
(insert_test1)(insert_test2)(insert_test3)(insert_test4) \
|
||||
(insert_test_rehash1)(insert_test_rehash2)(insert_test_rehash3)
|
||||
#define BASIC_TESTS \
|
||||
(insert_test1)(insert_test2)(insert_test3)(insert_test4)( \
|
||||
insert_test_rehash1)(insert_test_rehash2)(insert_test_rehash3)
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#define ALL_TESTS (emplace_test1)BASIC_TESTS
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
|
||||
!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#define ALL_TESTS (emplace_test1) BASIC_TESTS
|
||||
#else
|
||||
#define ALL_TESTS BASIC_TESTS
|
||||
#endif
|
||||
|
||||
EXCEPTION_TESTS(ALL_TESTS, CONTAINER_SEQ)
|
||||
|
||||
template <class T>
|
||||
struct pair_emplace_test1 : public insert_test_base<T>
|
||||
template <class T> struct pair_emplace_test1 : public insert_test_base<T>
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
|
||||
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
strong.store(x, test::detail::tracker.count_allocations);
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(it->first),
|
||||
boost::make_tuple(it->second));
|
||||
boost::make_tuple(it->first), boost::make_tuple(it->second));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct pair_emplace_test2 : public insert_test_base<T>
|
||||
template <class T> struct pair_emplace_test2 : public insert_test_base<T>
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
|
||||
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
strong.store(x, test::detail::tracker.count_allocations);
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
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)
|
||||
|
||||
template <class T>
|
||||
struct index_insert_test1 : public insert_test_base<T>
|
||||
template <class T> struct index_insert_test1 : public insert_test_base<T>
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
|
||||
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
strong.store(x, test::detail::tracker.count_allocations);
|
||||
x[it->first];
|
||||
}
|
||||
|
||||
@@ -5,31 +5,30 @@
|
||||
|
||||
#include "./containers.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include <iostream>
|
||||
|
||||
#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
|
||||
|
||||
test::seed_t initialize_seed(12847);
|
||||
|
||||
template <class T>
|
||||
struct move_assign_base : public test::exception_base
|
||||
template <class T> struct move_assign_base : public test::exception_base
|
||||
{
|
||||
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::key_equal key_equal;
|
||||
typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type;
|
||||
|
||||
move_assign_base(int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0) :
|
||||
x_values(),
|
||||
y_values(),
|
||||
x(0, hasher(tag1), key_equal(tag1), allocator_type(tag1)),
|
||||
y(0, hasher(tag2), key_equal(tag2), allocator_type(tag2))
|
||||
move_assign_base(int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0)
|
||||
: x_values(), y_values(),
|
||||
x(0, hasher(tag1), key_equal(tag1), allocator_type(tag1)),
|
||||
y(0, hasher(tag2), key_equal(tag2), allocator_type(tag2))
|
||||
{
|
||||
x.max_load_factor(mlf1);
|
||||
y.max_load_factor(mlf2);
|
||||
@@ -37,7 +36,8 @@ struct move_assign_base : public test::exception_base
|
||||
|
||||
typedef T data_type;
|
||||
T init() const { return T(x); }
|
||||
void run(T& x1) const {
|
||||
void run(T& x1) const
|
||||
{
|
||||
test::exceptions_enable disable_exceptions(false);
|
||||
T y1 = y;
|
||||
disable_exceptions.release();
|
||||
@@ -58,12 +58,11 @@ struct move_assign_base : public test::exception_base
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct move_assign_values : move_assign_base<T>
|
||||
template <class T> struct move_assign_values : move_assign_base<T>
|
||||
{
|
||||
move_assign_values(unsigned int count1, unsigned int count2,
|
||||
int tag1, int tag2, float mlf1 = 1.0, float mlf2 = 1.0) :
|
||||
move_assign_base<T>(tag1, tag2, mlf1, mlf2)
|
||||
move_assign_values(unsigned int count1, unsigned int count2, int tag1,
|
||||
int tag2, float mlf1 = 1.0, float mlf2 = 1.0)
|
||||
: move_assign_base<T>(tag1, tag2, mlf1, mlf2)
|
||||
{
|
||||
this->x_values.fill(count1);
|
||||
this->y_values.fill(count2);
|
||||
@@ -72,47 +71,39 @@ struct move_assign_values : move_assign_base<T>
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct move_assign_test1 : move_assign_values<T>
|
||||
template <class T> struct move_assign_test1 : move_assign_values<T>
|
||||
{
|
||||
move_assign_test1() : move_assign_values<T>(0, 0, 0, 0) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct move_assign_test2 : move_assign_values<T>
|
||||
template <class T> struct move_assign_test2 : move_assign_values<T>
|
||||
{
|
||||
move_assign_test2() : move_assign_values<T>(60, 0, 0, 0) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct move_assign_test3 : move_assign_values<T>
|
||||
template <class T> struct move_assign_test3 : move_assign_values<T>
|
||||
{
|
||||
move_assign_test3() : move_assign_values<T>(0, 60, 0, 0) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct move_assign_test4 : move_assign_values<T>
|
||||
template <class T> struct move_assign_test4 : move_assign_values<T>
|
||||
{
|
||||
move_assign_test4() : move_assign_values<T>(10, 10, 1, 2) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct move_assign_test4a : move_assign_values<T>
|
||||
template <class T> struct move_assign_test4a : move_assign_values<T>
|
||||
{
|
||||
move_assign_test4a() : move_assign_values<T>(10, 100, 1, 2) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct move_assign_test5 : move_assign_values<T>
|
||||
template <class T> struct move_assign_test5 : move_assign_values<T>
|
||||
{
|
||||
move_assign_test5() : move_assign_values<T>(5, 60, 0, 0, 1.0f, 0.1f) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct equivalent_test1 : move_assign_base<T>
|
||||
template <class T> struct equivalent_test1 : move_assign_base<T>
|
||||
{
|
||||
equivalent_test1() :
|
||||
move_assign_base<T>(0, 0)
|
||||
equivalent_test1() : move_assign_base<T>(0, 0)
|
||||
{
|
||||
test::random_values<T> x_values2(10);
|
||||
this->x_values.insert(x_values2.begin(), x_values2.end());
|
||||
@@ -125,8 +116,8 @@ struct equivalent_test1 : move_assign_base<T>
|
||||
}
|
||||
};
|
||||
|
||||
EXCEPTION_TESTS(
|
||||
(move_assign_test1)(move_assign_test2)(move_assign_test3)(move_assign_test4)(move_assign_test4a)(move_assign_test5)
|
||||
(equivalent_test1),
|
||||
EXCEPTION_TESTS((move_assign_test1)(move_assign_test2)(move_assign_test3)(
|
||||
move_assign_test4)(move_assign_test4a)(move_assign_test5)(
|
||||
equivalent_test1),
|
||||
CONTAINER_SEQ)
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -5,76 +5,72 @@
|
||||
|
||||
#include "./containers.hpp"
|
||||
|
||||
#include <string>
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/strong.hpp"
|
||||
#include <string>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
test::seed_t initialize_seed(3298597);
|
||||
|
||||
template <class T>
|
||||
struct rehash_test_base : public test::exception_base
|
||||
template <class T> struct rehash_test_base : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
unsigned int n;
|
||||
rehash_test_base(unsigned int count = 100, unsigned int n_ = 0)
|
||||
: values(count), n(n_)
|
||||
{}
|
||||
{
|
||||
}
|
||||
|
||||
typedef T data_type;
|
||||
typedef test::strong<T> strong_type;
|
||||
|
||||
data_type init() const {
|
||||
data_type init() const
|
||||
{
|
||||
T x(values.begin(), values.end(), n);
|
||||
return x;
|
||||
}
|
||||
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(T const& x,
|
||||
strong_type const& strong) const
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION(
|
||||
T const& x, strong_type const& strong) const
|
||||
{
|
||||
std::string scope(test::scope);
|
||||
|
||||
if(scope.find("hash::operator()") == std::string::npos &&
|
||||
scope.find("equal_to::operator()") == std::string::npos &&
|
||||
scope != "operator==(object, object)")
|
||||
if (scope.find("hash::operator()") == std::string::npos &&
|
||||
scope.find("equal_to::operator()") == std::string::npos &&
|
||||
scope != "operator==(object, object)")
|
||||
strong.test(x);
|
||||
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct rehash_test0 : rehash_test_base<T>
|
||||
template <class T> struct rehash_test0 : rehash_test_base<T>
|
||||
{
|
||||
rehash_test0() : rehash_test_base<T>(0) {}
|
||||
void run(T& x) const { x.rehash(0); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct rehash_test1 : rehash_test_base<T>
|
||||
template <class T> struct rehash_test1 : rehash_test_base<T>
|
||||
{
|
||||
rehash_test1() : rehash_test_base<T>(0) {}
|
||||
void run(T& x) const { x.rehash(200); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct rehash_test2 : rehash_test_base<T>
|
||||
template <class T> struct rehash_test2 : rehash_test_base<T>
|
||||
{
|
||||
rehash_test2() : rehash_test_base<T>(0, 200) {}
|
||||
void run(T& x) const { x.rehash(0); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct rehash_test3 : rehash_test_base<T>
|
||||
template <class T> struct rehash_test3 : rehash_test_base<T>
|
||||
{
|
||||
rehash_test3() : rehash_test_base<T>(10, 0) {}
|
||||
void run(T& x) const { x.rehash(200); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct rehash_test4 : rehash_test_base<T>
|
||||
template <class T> struct rehash_test4 : rehash_test_base<T>
|
||||
{
|
||||
rehash_test4() : rehash_test_base<T>(10, 200) {}
|
||||
void run(T& x) const { x.rehash(0); }
|
||||
|
||||
@@ -5,17 +5,16 @@
|
||||
|
||||
#include "./containers.hpp"
|
||||
|
||||
#include "../helpers/random_values.hpp"
|
||||
#include "../helpers/invariants.hpp"
|
||||
#include "../helpers/random_values.hpp"
|
||||
|
||||
#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
|
||||
|
||||
test::seed_t initialize_seed(9387);
|
||||
|
||||
template <class T>
|
||||
struct self_swap_base : public test::exception_base
|
||||
template <class T> struct self_swap_base : public test::exception_base
|
||||
{
|
||||
test::random_values<T> values;
|
||||
self_swap_base(std::size_t count = 0) : values(count) {}
|
||||
@@ -23,31 +22,30 @@ struct self_swap_base : public test::exception_base
|
||||
typedef T data_type;
|
||||
T init() const { return T(values.begin(), values.end()); }
|
||||
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);
|
||||
|
||||
// TODO: In C++11 exceptions are only allowed in the swap function.
|
||||
BOOST_TEST(
|
||||
scope == "hash::hash(hash)" ||
|
||||
scope == "hash::operator=(hash)" ||
|
||||
scope == "equal_to::equal_to(equal_to)" ||
|
||||
scope == "equal_to::operator=(equal_to)");
|
||||
BOOST_TEST(scope == "hash::hash(hash)" ||
|
||||
scope == "hash::operator=(hash)" ||
|
||||
scope == "equal_to::equal_to(equal_to)" ||
|
||||
scope == "equal_to::operator=(equal_to)");
|
||||
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct self_swap_test1 : self_swap_base<T> {};
|
||||
template <class T> struct self_swap_test1 : self_swap_base<T>
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct self_swap_test2 : self_swap_base<T>
|
||||
template <class T> struct self_swap_test2 : self_swap_base<T>
|
||||
{
|
||||
self_swap_test2() : self_swap_base<T>(100) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct swap_base : public test::exception_base
|
||||
template <class T> struct swap_base : public test::exception_base
|
||||
{
|
||||
const test::random_values<T> x_values, y_values;
|
||||
const T initial_x, initial_y;
|
||||
@@ -58,69 +56,69 @@ struct swap_base : public test::exception_base
|
||||
|
||||
swap_base(unsigned int count1, unsigned int count2, int tag1, int tag2)
|
||||
: x_values(count1), y_values(count2),
|
||||
initial_x(x_values.begin(), x_values.end(), 0, hasher(tag1),
|
||||
key_equal(tag1), allocator_type(tag1)),
|
||||
initial_y(y_values.begin(), y_values.end(), 0, hasher(tag2),
|
||||
key_equal(tag2), allocator_type(
|
||||
T::allocator_type::propagate_on_container_swap::value ?
|
||||
tag2 : tag1))
|
||||
{}
|
||||
initial_x(x_values.begin(), x_values.end(), 0, hasher(tag1),
|
||||
key_equal(tag1), allocator_type(tag1)),
|
||||
initial_y(
|
||||
y_values.begin(), y_values.end(), 0, hasher(tag2),
|
||||
key_equal(tag2),
|
||||
allocator_type(
|
||||
T::allocator_type::propagate_on_container_swap::value ? tag2
|
||||
: tag1))
|
||||
{
|
||||
}
|
||||
|
||||
struct data_type {
|
||||
data_type(T const& x_, T const& y_)
|
||||
: x(x_), y(y_) {}
|
||||
struct data_type
|
||||
{
|
||||
data_type(T const& x_, T const& y_) : x(x_), y(y_) {}
|
||||
|
||||
T x, 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 {
|
||||
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);
|
||||
|
||||
// TODO: In C++11 exceptions are only allowed in the swap function.
|
||||
BOOST_TEST(
|
||||
scope == "hash::hash(hash)" ||
|
||||
scope == "hash::operator=(hash)" ||
|
||||
scope == "equal_to::equal_to(equal_to)" ||
|
||||
scope == "equal_to::operator=(equal_to)");
|
||||
|
||||
BOOST_TEST(scope == "hash::hash(hash)" ||
|
||||
scope == "hash::operator=(hash)" ||
|
||||
scope == "equal_to::equal_to(equal_to)" ||
|
||||
scope == "equal_to::operator=(equal_to)");
|
||||
|
||||
test::check_equivalent_keys(d.x);
|
||||
test::check_equivalent_keys(d.y);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct swap_test1 : swap_base<T>
|
||||
template <class T> struct swap_test1 : swap_base<T>
|
||||
{
|
||||
swap_test1() : swap_base<T>(0, 0, 0, 0) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct swap_test2 : swap_base<T>
|
||||
template <class 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>
|
||||
struct swap_test3 : swap_base<T>
|
||||
template <class 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>
|
||||
struct swap_test4 : swap_base<T>
|
||||
template <class T> struct swap_test4 : swap_base<T>
|
||||
{
|
||||
swap_test4() : swap_base<T>(10, 10, 1, 2) {}
|
||||
};
|
||||
|
||||
EXCEPTION_TESTS(
|
||||
(self_swap_test1)(self_swap_test2)
|
||||
(swap_test1)(swap_test2)(swap_test3)(swap_test4),
|
||||
EXCEPTION_TESTS((self_swap_test1)(self_swap_test2)(swap_test1)(swap_test2)(
|
||||
swap_test3)(swap_test4),
|
||||
CONTAINER_SEQ)
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -7,32 +7,27 @@
|
||||
#define BOOST_UNORDERED_TEST_HELPERS_CHECK_RETURN_TYPE_HEADER
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_same.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>
|
||||
struct check_return_type
|
||||
template <class T2> static void equals(T2)
|
||||
{
|
||||
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>
|
||||
static void equals_ref(T2&)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value));
|
||||
}
|
||||
template <class T2> static void equals_ref(T2&)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_same<T1, T2>::value));
|
||||
}
|
||||
|
||||
template <class T2>
|
||||
static void convertible(T2)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_convertible<T2, T1>::value));
|
||||
}
|
||||
};
|
||||
template <class T2> static void convertible(T2)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((boost::is_convertible<T2, T1>::value));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+70
-66
@@ -10,77 +10,81 @@
|
||||
#include <iostream>
|
||||
|
||||
namespace test {
|
||||
struct object_count {
|
||||
int instances;
|
||||
int constructions;
|
||||
struct object_count
|
||||
{
|
||||
int instances;
|
||||
int constructions;
|
||||
|
||||
object_count() : instances(0), constructions(0) {}
|
||||
void reset() { *this = object_count(); }
|
||||
object_count() : instances(0), constructions(0) {}
|
||||
void reset() { *this = object_count(); }
|
||||
|
||||
void construct() {
|
||||
++instances;
|
||||
++constructions;
|
||||
}
|
||||
|
||||
void destruct() {
|
||||
if(instances == 0) {
|
||||
BOOST_ERROR("Unbalanced constructions.");
|
||||
}
|
||||
else {
|
||||
--instances;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(object_count const& x) const {
|
||||
return instances == x.instances &&
|
||||
constructions == x.constructions;
|
||||
}
|
||||
|
||||
bool operator!=(object_count const& x) const {
|
||||
return !(*this == x);
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& out,
|
||||
object_count const& c)
|
||||
{
|
||||
out
|
||||
<< "[instances: "
|
||||
<< c.instances
|
||||
<< ", constructions: "
|
||||
<< c.constructions
|
||||
<< "]";
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
// 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
|
||||
// framework).
|
||||
//
|
||||
// boostinspect:nounnamed
|
||||
namespace {
|
||||
object_count global_object_count;
|
||||
}
|
||||
|
||||
struct counted_object
|
||||
void construct()
|
||||
{
|
||||
counted_object() { global_object_count.construct(); }
|
||||
counted_object(counted_object const&) { global_object_count.construct(); }
|
||||
~counted_object() { global_object_count.destruct(); }
|
||||
};
|
||||
++instances;
|
||||
++constructions;
|
||||
}
|
||||
|
||||
struct check_instances {
|
||||
int instances_;
|
||||
int constructions_;
|
||||
|
||||
check_instances() :
|
||||
instances_(global_object_count.instances),
|
||||
constructions_(global_object_count.constructions) {}
|
||||
~check_instances() { BOOST_TEST(global_object_count.instances == instances_); }
|
||||
void destruct()
|
||||
{
|
||||
if (instances == 0) {
|
||||
BOOST_ERROR("Unbalanced constructions.");
|
||||
} else {
|
||||
--instances;
|
||||
}
|
||||
}
|
||||
|
||||
int instances() const { return global_object_count.instances - instances_; }
|
||||
int constructions() const { return global_object_count.constructions - constructions_; }
|
||||
};
|
||||
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 << "[instances: " << c.instances
|
||||
<< ", constructions: " << c.constructions << "]";
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
// 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
|
||||
// framework).
|
||||
//
|
||||
// boostinspect:nounnamed
|
||||
namespace {
|
||||
object_count global_object_count;
|
||||
}
|
||||
|
||||
struct counted_object
|
||||
{
|
||||
counted_object() { global_object_count.construct(); }
|
||||
counted_object(counted_object const&) { global_object_count.construct(); }
|
||||
~counted_object() { global_object_count.destruct(); }
|
||||
};
|
||||
|
||||
struct check_instances
|
||||
{
|
||||
int instances_;
|
||||
int constructions_;
|
||||
|
||||
check_instances()
|
||||
: instances_(global_object_count.instances),
|
||||
constructions_(global_object_count.constructions)
|
||||
{
|
||||
}
|
||||
~check_instances()
|
||||
{
|
||||
BOOST_TEST(global_object_count.instances == instances_);
|
||||
}
|
||||
|
||||
int instances() const { return global_object_count.instances - instances_; }
|
||||
int constructions() const
|
||||
{
|
||||
return global_object_count.constructions - constructions_;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+67
-66
@@ -6,88 +6,89 @@
|
||||
#if !defined(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 "./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)
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool equivalent_impl(boost::hash<T> const&, boost::hash<T> const&, derived_type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool equivalent_impl(
|
||||
std::equal_to<T> const&, std::equal_to<T> const&, derived_type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T1, class T2, class T3, class T4>
|
||||
bool equivalent_impl(
|
||||
std::pair<T1, T2> const& x1, std::pair<T3, T4> const& x2, derived_type)
|
||||
{
|
||||
return equivalent_impl(x1.first, x2.first, derived) &&
|
||||
equivalent_impl(x1.second, x2.second, derived);
|
||||
}
|
||||
|
||||
struct equivalent_type
|
||||
{
|
||||
equivalent_type() {}
|
||||
|
||||
template <class T1, class T2>
|
||||
bool equivalent_impl(T1 const& x, T2 const& y, base_type) {
|
||||
return x == y;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool equivalent_impl(boost::hash<T> const&, boost::hash<T> const&,
|
||||
derived_type)
|
||||
bool operator()(T1 const& x, T2 const& y) const
|
||||
{
|
||||
return true;
|
||||
return equivalent_impl(x, y, derived);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
bool equivalent_impl(std::equal_to<T> const&, std::equal_to<T> const&,
|
||||
derived_type)
|
||||
const equivalent_type equivalent;
|
||||
|
||||
template <class Container> class unordered_equivalence_tester
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME Container::size_type size_;
|
||||
BOOST_DEDUCED_TYPENAME Container::hasher hasher_;
|
||||
BOOST_DEDUCED_TYPENAME Container::key_equal key_equal_;
|
||||
float max_load_factor_;
|
||||
|
||||
typedef test::list<BOOST_DEDUCED_TYPENAME Container::value_type> value_list;
|
||||
value_list values_;
|
||||
|
||||
public:
|
||||
unordered_equivalence_tester(Container const& x)
|
||||
: size_(x.size()), hasher_(x.hash_function()), key_equal_(x.key_eq()),
|
||||
max_load_factor_(x.max_load_factor()), values_(x.begin(), x.end())
|
||||
{
|
||||
return true;
|
||||
values_.sort();
|
||||
}
|
||||
|
||||
template <class T1, class T2, class T3, class T4>
|
||||
bool equivalent_impl(std::pair<T1, T2> const& x1,
|
||||
std::pair<T3, T4> const& x2, derived_type) {
|
||||
return equivalent_impl(x1.first, x2.first, derived) &&
|
||||
equivalent_impl(x1.second, x2.second, derived);
|
||||
}
|
||||
|
||||
struct equivalent_type {
|
||||
equivalent_type() {}
|
||||
|
||||
template <class T1, class T2>
|
||||
bool operator()(T1 const& x, T2 const& y) const {
|
||||
return equivalent_impl(x, y, derived);
|
||||
}
|
||||
};
|
||||
|
||||
const equivalent_type equivalent;
|
||||
|
||||
template <class Container>
|
||||
class unordered_equivalence_tester
|
||||
bool operator()(Container const& x) const
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME Container::size_type size_;
|
||||
BOOST_DEDUCED_TYPENAME Container::hasher hasher_;
|
||||
BOOST_DEDUCED_TYPENAME Container::key_equal key_equal_;
|
||||
float max_load_factor_;
|
||||
|
||||
typedef test::list<BOOST_DEDUCED_TYPENAME Container::value_type>
|
||||
value_list;
|
||||
value_list values_;
|
||||
public:
|
||||
unordered_equivalence_tester(Container const &x)
|
||||
: size_(x.size()),
|
||||
hasher_(x.hash_function()), key_equal_(x.key_eq()),
|
||||
max_load_factor_(x.max_load_factor()),
|
||||
values_(x.begin(), x.end())
|
||||
{
|
||||
values_.sort();
|
||||
}
|
||||
|
||||
bool operator()(Container const& x) const
|
||||
{
|
||||
if(!((size_ == x.size()) &&
|
||||
if (!((size_ == x.size()) &&
|
||||
(test::equivalent(hasher_, x.hash_function())) &&
|
||||
(test::equivalent(key_equal_, x.key_eq())) &&
|
||||
(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());
|
||||
copy.sort();
|
||||
return values_ == copy;
|
||||
}
|
||||
private:
|
||||
unordered_equivalence_tester();
|
||||
};
|
||||
value_list copy(x.begin(), x.end());
|
||||
copy.sort();
|
||||
return values_ == copy;
|
||||
}
|
||||
|
||||
private:
|
||||
unordered_equivalence_tester();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+221
-230
@@ -6,275 +6,266 @@
|
||||
#if !defined(BOOST_UNORDERED_EXCEPTION_TEST_HEADER)
|
||||
#define BOOST_UNORDERED_EXCEPTION_TEST_HEADER
|
||||
|
||||
#include "./test.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/seq/elem.hpp>
|
||||
#include <boost/preprocessor/seq/for_each_product.hpp>
|
||||
|
||||
# define UNORDERED_EXCEPTION_TEST_CASE(name, test_func, type) \
|
||||
UNORDERED_AUTO_TEST(name) \
|
||||
{ \
|
||||
test_func< type > fixture; \
|
||||
::test::lightweight::exception_safety( \
|
||||
fixture, BOOST_STRINGIZE(test_func<type>)); \
|
||||
} \
|
||||
#define UNORDERED_EXCEPTION_TEST_CASE(name, test_func, type) \
|
||||
UNORDERED_AUTO_TEST(name) \
|
||||
{ \
|
||||
test_func<type> fixture; \
|
||||
::test::lightweight::exception_safety( \
|
||||
fixture, BOOST_STRINGIZE(test_func<type>)); \
|
||||
}
|
||||
|
||||
# define UNORDERED_EXCEPTION_TEST_CASE_REPEAT(name, test_func, n, type) \
|
||||
UNORDERED_AUTO_TEST(name) \
|
||||
{ \
|
||||
for (unsigned i = 0; i < n; ++i) { \
|
||||
test_func< type > fixture; \
|
||||
::test::lightweight::exception_safety( \
|
||||
fixture, BOOST_STRINGIZE(test_func<type>)); \
|
||||
} \
|
||||
} \
|
||||
#define UNORDERED_EXCEPTION_TEST_CASE_REPEAT(name, test_func, n, type) \
|
||||
UNORDERED_AUTO_TEST(name) \
|
||||
{ \
|
||||
for (unsigned i = 0; i < n; ++i) { \
|
||||
test_func<type> fixture; \
|
||||
::test::lightweight::exception_safety( \
|
||||
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 EXCEPTION_TESTS(test_seq, param_seq) \
|
||||
BOOST_PP_SEQ_FOR_EACH_PRODUCT(EXCEPTION_TESTS_OP, \
|
||||
(test_seq)((1))(param_seq))
|
||||
#define EXCEPTION_TESTS(test_seq, param_seq) \
|
||||
BOOST_PP_SEQ_FOR_EACH_PRODUCT( \
|
||||
EXCEPTION_TESTS_OP, (test_seq)((1))(param_seq))
|
||||
|
||||
#define EXCEPTION_TESTS_REPEAT(n, test_seq, param_seq) \
|
||||
BOOST_PP_SEQ_FOR_EACH_PRODUCT(EXCEPTION_TESTS_OP, \
|
||||
(test_seq)((n))(param_seq))
|
||||
#define EXCEPTION_TESTS_REPEAT(n, test_seq, param_seq) \
|
||||
BOOST_PP_SEQ_FOR_EACH_PRODUCT( \
|
||||
EXCEPTION_TESTS_OP, (test_seq)((n))(param_seq))
|
||||
|
||||
#define EXCEPTION_TESTS_OP(r, product) \
|
||||
UNORDERED_EXCEPTION_TEST_CASE_REPEAT( \
|
||||
BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0, 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(2, product) \
|
||||
) \
|
||||
#define EXCEPTION_TESTS_OP(r, product) \
|
||||
UNORDERED_EXCEPTION_TEST_CASE_REPEAT( \
|
||||
BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0, 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(2, product))
|
||||
|
||||
#define UNORDERED_SCOPE(scope_name) \
|
||||
for(::test::scope_guard unordered_test_guard( \
|
||||
BOOST_STRINGIZE(scope_name)); \
|
||||
!unordered_test_guard.dismissed(); \
|
||||
unordered_test_guard.dismiss()) \
|
||||
#define UNORDERED_SCOPE(scope_name) \
|
||||
for (::test::scope_guard unordered_test_guard( \
|
||||
BOOST_STRINGIZE(scope_name)); \
|
||||
!unordered_test_guard.dismissed(); unordered_test_guard.dismiss())
|
||||
|
||||
#define UNORDERED_EPOINT(name) \
|
||||
if(::test::exceptions_enabled) { \
|
||||
UNORDERED_EPOINT_IMPL(name); \
|
||||
} \
|
||||
#define UNORDERED_EPOINT(name) \
|
||||
if (::test::exceptions_enabled) { \
|
||||
UNORDERED_EPOINT_IMPL(name); \
|
||||
}
|
||||
|
||||
#define ENABLE_EXCEPTIONS \
|
||||
::test::exceptions_enable BOOST_PP_CAT( \
|
||||
ENABLE_EXCEPTIONS_, __LINE__)(true) \
|
||||
#define ENABLE_EXCEPTIONS \
|
||||
::test::exceptions_enable BOOST_PP_CAT(ENABLE_EXCEPTIONS_, __LINE__)(true)
|
||||
|
||||
#define DISABLE_EXCEPTIONS \
|
||||
::test::exceptions_enable BOOST_PP_CAT( \
|
||||
ENABLE_EXCEPTIONS_, __LINE__)(false) \
|
||||
#define DISABLE_EXCEPTIONS \
|
||||
::test::exceptions_enable BOOST_PP_CAT(ENABLE_EXCEPTIONS_, __LINE__)(false)
|
||||
|
||||
namespace test {
|
||||
static char const* scope = "";
|
||||
bool exceptions_enabled = false;
|
||||
static char const* scope = "";
|
||||
bool exceptions_enabled = false;
|
||||
|
||||
class scope_guard {
|
||||
scope_guard& operator=(scope_guard const&);
|
||||
scope_guard(scope_guard const&);
|
||||
class scope_guard
|
||||
{
|
||||
scope_guard& operator=(scope_guard const&);
|
||||
scope_guard(scope_guard const&);
|
||||
|
||||
char const* old_scope_;
|
||||
char const* scope_;
|
||||
bool dismissed_;
|
||||
public:
|
||||
scope_guard(char const* name)
|
||||
: old_scope_(scope),
|
||||
scope_(name),
|
||||
dismissed_(false)
|
||||
{
|
||||
scope = scope_;
|
||||
char const* old_scope_;
|
||||
char const* scope_;
|
||||
bool dismissed_;
|
||||
|
||||
public:
|
||||
scope_guard(char const* name)
|
||||
: old_scope_(scope), scope_(name), dismissed_(false)
|
||||
{
|
||||
scope = scope_;
|
||||
}
|
||||
|
||||
~scope_guard()
|
||||
{
|
||||
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(exceptions_enable const&);
|
||||
|
||||
bool old_value_;
|
||||
bool released_;
|
||||
|
||||
public:
|
||||
exceptions_enable(bool enable)
|
||||
: old_value_(exceptions_enabled), released_(false)
|
||||
{
|
||||
exceptions_enabled = enable;
|
||||
}
|
||||
|
||||
~exceptions_enable()
|
||||
{
|
||||
if (!released_) {
|
||||
exceptions_enabled = old_value_;
|
||||
released_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
~scope_guard() {
|
||||
if(dismissed_) scope = old_scope_;
|
||||
void release()
|
||||
{
|
||||
if (!released_) {
|
||||
exceptions_enabled = old_value_;
|
||||
released_ = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void dismiss() {
|
||||
dismissed_ = true;
|
||||
}
|
||||
|
||||
bool dismissed() const {
|
||||
return dismissed_;
|
||||
}
|
||||
struct exception_base
|
||||
{
|
||||
struct data_type
|
||||
{
|
||||
};
|
||||
|
||||
class exceptions_enable
|
||||
struct strong_type
|
||||
{
|
||||
exceptions_enable& operator=(exceptions_enable const&);
|
||||
exceptions_enable(exceptions_enable const&);
|
||||
|
||||
bool old_value_;
|
||||
bool released_;
|
||||
public:
|
||||
exceptions_enable(bool enable)
|
||||
: old_value_(exceptions_enabled), released_(false)
|
||||
{
|
||||
exceptions_enabled = enable;
|
||||
}
|
||||
|
||||
~exceptions_enable()
|
||||
{
|
||||
if (!released_) {
|
||||
exceptions_enabled = old_value_;
|
||||
released_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
if (!released_) {
|
||||
exceptions_enabled = old_value_;
|
||||
released_ = true;
|
||||
}
|
||||
}
|
||||
template <class T> void store(T const&) {}
|
||||
template <class T> void test(T const&) const {}
|
||||
};
|
||||
data_type init() const { return data_type(); }
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION() const {}
|
||||
};
|
||||
|
||||
struct exception_base {
|
||||
struct data_type {};
|
||||
struct strong_type {
|
||||
template <class T> void store(T const&) {}
|
||||
template <class T> void test(T const&) const {}
|
||||
};
|
||||
data_type init() const { return data_type(); }
|
||||
void check BOOST_PREVENT_MACRO_SUBSTITUTION() const {}
|
||||
};
|
||||
template <class T, class P1, class P2, class T2>
|
||||
inline void call_ignore_extra_parameters(
|
||||
void (T::*fn)() const, T2 const& obj, P1&, P2&)
|
||||
{
|
||||
(obj.*fn)();
|
||||
}
|
||||
|
||||
template <class T, class P1, class P2, class T2>
|
||||
inline void call_ignore_extra_parameters(
|
||||
void (T::*fn)() const, T2 const& obj,
|
||||
P1&, P2&)
|
||||
template <class T, class P1, class P2, class T2>
|
||||
inline void call_ignore_extra_parameters(
|
||||
void (T::*fn)(P1&) const, T2 const& obj, P1& p1, P2&)
|
||||
{
|
||||
(obj.*fn)(p1);
|
||||
}
|
||||
|
||||
template <class T, class P1, class P2, class T2>
|
||||
inline void call_ignore_extra_parameters(
|
||||
void (T::*fn)(P1&, P2&) const, T2 const& obj, P1& p1, P2& p2)
|
||||
{
|
||||
(obj.*fn)(p1, p2);
|
||||
}
|
||||
|
||||
template <class T> T const& constant(T const& x) { return x; }
|
||||
|
||||
template <class Test> class test_runner
|
||||
{
|
||||
Test const& test_;
|
||||
bool exception_in_check_;
|
||||
|
||||
test_runner(test_runner const&);
|
||||
test_runner& operator=(test_runner const&);
|
||||
|
||||
public:
|
||||
test_runner(Test const& t) : test_(t), exception_in_check_(false) {}
|
||||
void run()
|
||||
{
|
||||
(obj.*fn)();
|
||||
}
|
||||
|
||||
template <class T, class P1, class P2, class T2>
|
||||
inline void call_ignore_extra_parameters(
|
||||
void (T::*fn)(P1&) const, T2 const& obj,
|
||||
P1& p1, P2&)
|
||||
{
|
||||
(obj.*fn)(p1);
|
||||
}
|
||||
|
||||
template <class T, class P1, class P2, class T2>
|
||||
inline void call_ignore_extra_parameters(
|
||||
void (T::*fn)(P1&, P2&) const, T2 const& obj,
|
||||
P1& p1, P2& p2)
|
||||
{
|
||||
(obj.*fn)(p1, p2);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T const& constant(T const& x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class Test>
|
||||
class test_runner
|
||||
{
|
||||
Test const& test_;
|
||||
bool exception_in_check_;
|
||||
|
||||
test_runner(test_runner const&);
|
||||
test_runner& operator=(test_runner const&);
|
||||
public:
|
||||
test_runner(Test const& t) : test_(t), exception_in_check_(false) {}
|
||||
void run() {
|
||||
DISABLE_EXCEPTIONS;
|
||||
test::check_instances check;
|
||||
test::scope = "";
|
||||
BOOST_DEDUCED_TYPENAME Test::data_type x(test_.init());
|
||||
BOOST_DEDUCED_TYPENAME Test::strong_type strong;
|
||||
strong.store(x);
|
||||
DISABLE_EXCEPTIONS;
|
||||
test::check_instances check;
|
||||
test::scope = "";
|
||||
BOOST_DEDUCED_TYPENAME Test::data_type x(test_.init());
|
||||
BOOST_DEDUCED_TYPENAME Test::strong_type strong;
|
||||
strong.store(x);
|
||||
try {
|
||||
ENABLE_EXCEPTIONS;
|
||||
call_ignore_extra_parameters<Test,
|
||||
BOOST_DEDUCED_TYPENAME Test::data_type,
|
||||
BOOST_DEDUCED_TYPENAME Test::strong_type>(
|
||||
&Test::run, test_, x, strong);
|
||||
} catch (...) {
|
||||
try {
|
||||
ENABLE_EXCEPTIONS;
|
||||
call_ignore_extra_parameters<
|
||||
Test,
|
||||
BOOST_DEDUCED_TYPENAME Test::data_type,
|
||||
BOOST_DEDUCED_TYPENAME Test::strong_type
|
||||
>(&Test::run, test_, x, strong);
|
||||
}
|
||||
catch(...) {
|
||||
try {
|
||||
DISABLE_EXCEPTIONS;
|
||||
call_ignore_extra_parameters<
|
||||
Test,
|
||||
BOOST_DEDUCED_TYPENAME Test::data_type const,
|
||||
BOOST_DEDUCED_TYPENAME Test::strong_type const
|
||||
>(&Test::check, test_, constant(x), constant(strong));
|
||||
} catch(...) {
|
||||
exception_in_check_ = true;
|
||||
}
|
||||
throw;
|
||||
DISABLE_EXCEPTIONS;
|
||||
call_ignore_extra_parameters<Test,
|
||||
BOOST_DEDUCED_TYPENAME Test::data_type const,
|
||||
BOOST_DEDUCED_TYPENAME Test::strong_type const>(
|
||||
&Test::check, test_, constant(x), constant(strong));
|
||||
} catch (...) {
|
||||
exception_in_check_ = true;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
void end() {
|
||||
if (exception_in_check_) {
|
||||
BOOST_ERROR("Unexcpected exception in test_runner check call.");
|
||||
}
|
||||
}
|
||||
void end()
|
||||
{
|
||||
if (exception_in_check_) {
|
||||
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 {
|
||||
static int iteration;
|
||||
static int count;
|
||||
namespace lightweight {
|
||||
static int iteration;
|
||||
static int count;
|
||||
|
||||
struct test_exception {
|
||||
char const* name;
|
||||
test_exception(char const* n) : name(n) {}
|
||||
};
|
||||
struct test_exception
|
||||
{
|
||||
char const* name;
|
||||
test_exception(char const* n) : name(n) {}
|
||||
};
|
||||
|
||||
struct test_failure {
|
||||
};
|
||||
struct test_failure
|
||||
{
|
||||
};
|
||||
|
||||
void epoint(char const* name) {
|
||||
++count;
|
||||
if(count == iteration) {
|
||||
throw test_exception(name);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Test>
|
||||
void exception_safety(Test const& f, char const* /*name*/) {
|
||||
test_runner<Test> runner(f);
|
||||
|
||||
iteration = 0;
|
||||
bool success = false;
|
||||
char const* error_msg = 0;
|
||||
do {
|
||||
++iteration;
|
||||
count = 0;
|
||||
|
||||
try {
|
||||
runner.run();
|
||||
success = true;
|
||||
}
|
||||
catch(test_failure) {
|
||||
error_msg = "test_failure caught.";
|
||||
break;
|
||||
}
|
||||
catch(test_exception) {
|
||||
continue;
|
||||
}
|
||||
catch(...) {
|
||||
error_msg = "Unexpected exception.";
|
||||
break;
|
||||
}
|
||||
} while(!success);
|
||||
|
||||
if (error_msg) { BOOST_ERROR(error_msg); }
|
||||
runner.end();
|
||||
}
|
||||
void epoint(char const* name)
|
||||
{
|
||||
++count;
|
||||
if (count == iteration) {
|
||||
throw test_exception(name);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Test> void exception_safety(Test const& f, char const* /*name*/)
|
||||
{
|
||||
test_runner<Test> runner(f);
|
||||
|
||||
iteration = 0;
|
||||
bool success = false;
|
||||
char const* error_msg = 0;
|
||||
do {
|
||||
++iteration;
|
||||
count = 0;
|
||||
|
||||
try {
|
||||
runner.run();
|
||||
success = true;
|
||||
} catch (test_failure) {
|
||||
error_msg = "test_failure caught.";
|
||||
break;
|
||||
} catch (test_exception) {
|
||||
continue;
|
||||
} catch (...) {
|
||||
error_msg = "Unexpected exception.";
|
||||
break;
|
||||
}
|
||||
} while (!success);
|
||||
|
||||
if (error_msg) {
|
||||
BOOST_ERROR(error_msg);
|
||||
}
|
||||
runner.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+18
-16
@@ -8,23 +8,25 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace test
|
||||
namespace test {
|
||||
typedef enum {
|
||||
default_generator,
|
||||
generate_collisions,
|
||||
limited_range
|
||||
} random_generator;
|
||||
|
||||
int generate(int const*, random_generator);
|
||||
char generate(char const*, random_generator);
|
||||
signed char generate(signed char const*, random_generator);
|
||||
std::string generate(std::string const*, random_generator);
|
||||
float generate(float const*, random_generator);
|
||||
|
||||
struct base_type
|
||||
{
|
||||
typedef enum {
|
||||
default_generator,
|
||||
generate_collisions,
|
||||
limited_range
|
||||
} random_generator;
|
||||
|
||||
int generate(int const*, random_generator);
|
||||
char generate(char const*, random_generator);
|
||||
signed char generate(signed char const*, random_generator);
|
||||
std::string generate(std::string const*, random_generator);
|
||||
float generate(float const*, random_generator);
|
||||
|
||||
struct base_type {} base;
|
||||
struct derived_type : base_type {} derived;
|
||||
} base;
|
||||
struct derived_type : base_type
|
||||
{
|
||||
} derived;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+70
-66
@@ -11,80 +11,84 @@
|
||||
#if !defined(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 <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) {
|
||||
using namespace std;
|
||||
srand(x);
|
||||
seed_t(unsigned int x)
|
||||
{
|
||||
using namespace std;
|
||||
srand(x);
|
||||
}
|
||||
};
|
||||
|
||||
std::size_t random_value(std::size_t max)
|
||||
{
|
||||
using namespace std;
|
||||
return static_cast<std::size_t>(rand()) % max;
|
||||
}
|
||||
|
||||
inline int generate(int const*, random_generator g)
|
||||
{
|
||||
using namespace std;
|
||||
int value = rand();
|
||||
if (g == limited_range) {
|
||||
value = value % 100;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
inline char generate(char const*, random_generator)
|
||||
{
|
||||
using namespace std;
|
||||
return static_cast<char>((rand() >> 1) % (128 - 32) + 32);
|
||||
}
|
||||
|
||||
inline signed char generate(signed char const*, random_generator)
|
||||
{
|
||||
using namespace std;
|
||||
return static_cast<signed char>(rand());
|
||||
}
|
||||
|
||||
inline std::string generate(std::string const*, random_generator g)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
char* char_ptr = 0;
|
||||
|
||||
std::string result;
|
||||
|
||||
if (g == limited_range) {
|
||||
std::size_t length = test::random_value(2) + 2;
|
||||
|
||||
char const* strings[] = {"'vZh(3~ms", "%m", "_Y%U", "N'Y", "4,J_J"};
|
||||
for (std::size_t i = 0; i < length; ++i) {
|
||||
result +=
|
||||
strings[random_value(sizeof(strings) / sizeof(strings[0]))];
|
||||
}
|
||||
};
|
||||
|
||||
std::size_t random_value(std::size_t max) {
|
||||
using namespace std;
|
||||
return static_cast<std::size_t>(rand()) % max;
|
||||
}
|
||||
|
||||
inline int generate(int const*, random_generator g)
|
||||
{
|
||||
using namespace std;
|
||||
int value = rand();
|
||||
if (g == limited_range) { value = value % 100; }
|
||||
return value;
|
||||
}
|
||||
|
||||
inline char generate(char const*, random_generator)
|
||||
{
|
||||
using namespace std;
|
||||
return static_cast<char>((rand() >> 1) % (128-32) + 32);
|
||||
}
|
||||
|
||||
inline signed char generate(signed char const*, random_generator)
|
||||
{
|
||||
using namespace std;
|
||||
return static_cast<signed char>(rand());
|
||||
}
|
||||
|
||||
inline std::string generate(std::string const*, random_generator g)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
char* char_ptr = 0;
|
||||
|
||||
std::string result;
|
||||
|
||||
if (g == limited_range) {
|
||||
std::size_t length = test::random_value(2) + 2;
|
||||
|
||||
char const* strings[] = { "'vZh(3~ms", "%m", "_Y%U", "N'Y", "4,J_J" };
|
||||
for (std::size_t i = 0; i < length; ++i) {
|
||||
result += strings[random_value(sizeof(strings) / sizeof(strings[0]))];
|
||||
}
|
||||
} else {
|
||||
std::size_t length = test::random_value(10) + 1;
|
||||
for (std::size_t i = 0; i < length; ++i) {
|
||||
result += generate(char_ptr, g);
|
||||
}
|
||||
else {
|
||||
std::size_t length = test::random_value(10) + 1;
|
||||
for (std::size_t i = 0; i < length; ++i) {
|
||||
result += generate(char_ptr, g);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float generate(float const*, random_generator g)
|
||||
{
|
||||
using namespace std;
|
||||
int x = 0;
|
||||
int value = generate(&x, g);
|
||||
return (float) value / (float) RAND_MAX;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
float generate(float const*, random_generator g)
|
||||
{
|
||||
using namespace std;
|
||||
int x = 0;
|
||||
int value = generate(&x, g);
|
||||
return (float)value / (float)RAND_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+34
-44
@@ -6,58 +6,48 @@
|
||||
#if !defined(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;
|
||||
|
||||
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)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME Container::key_type key_type;
|
||||
|
||||
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.first;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static key_type const& get_key(std::pair<key_type const, 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 x.first;
|
||||
}
|
||||
|
||||
// test::next
|
||||
//
|
||||
// Increments an iterator by 1 or a given value.
|
||||
// Like boost::next, but simpler and slower.
|
||||
|
||||
template <typename Iterator>
|
||||
Iterator next(Iterator it)
|
||||
template <class T>
|
||||
static key_type const& get_key(
|
||||
std::pair<key_type const, T> const& x, unsigned char = 0)
|
||||
{
|
||||
return ++it;
|
||||
return x.first;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Iterator, typename IntType>
|
||||
Iterator next(Iterator it, IntType x)
|
||||
{
|
||||
for(; x > 0; --x) {
|
||||
++it;
|
||||
}
|
||||
return it;
|
||||
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);
|
||||
}
|
||||
|
||||
// test::next
|
||||
//
|
||||
// Increments an iterator by 1 or a given value.
|
||||
// Like boost::next, but simpler and slower.
|
||||
|
||||
template <typename Iterator> Iterator next(Iterator it) { return ++it; }
|
||||
|
||||
template <typename Iterator, typename IntType>
|
||||
Iterator next(Iterator it, IntType x)
|
||||
{
|
||||
for (; x > 0; --x) {
|
||||
++it;
|
||||
}
|
||||
return it;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+147
-139
@@ -10,156 +10,164 @@
|
||||
#include <boost/iterator/iterator_traits.hpp>
|
||||
#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) {}
|
||||
proxy(proxy const& x) : v_(x.v_) {}
|
||||
operator value_type const&() const { return v_; }
|
||||
|
||||
value_type v_;
|
||||
private:
|
||||
proxy& operator=(proxy const&);
|
||||
};
|
||||
explicit proxy(value_type const& v) : v_(v) {}
|
||||
proxy(proxy const& x) : v_(x.v_) {}
|
||||
operator value_type const&() const { return v_; }
|
||||
|
||||
template <class Iterator>
|
||||
struct input_iterator_adaptor
|
||||
: public std::iterator<
|
||||
std::input_iterator_tag,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type,
|
||||
std::ptrdiff_t,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_pointer<Iterator>::type,
|
||||
proxy<Iterator>
|
||||
>
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type
|
||||
value_type;
|
||||
|
||||
input_iterator_adaptor()
|
||||
: base_() {}
|
||||
explicit input_iterator_adaptor(Iterator& it)
|
||||
: base_(&it) {}
|
||||
proxy<Iterator> operator*() const {
|
||||
return proxy<Iterator>(**base_);
|
||||
}
|
||||
value_type* operator->() const {
|
||||
return &**base_;
|
||||
}
|
||||
input_iterator_adaptor& operator++() {
|
||||
++*base_; return *this;
|
||||
}
|
||||
//input_iterator_adaptor operator++(int) {
|
||||
//}
|
||||
bool operator==(input_iterator_adaptor const& x) const {
|
||||
return *base_ == *x.base_;
|
||||
}
|
||||
bool operator!=(input_iterator_adaptor const& x) const {
|
||||
return *base_ != *x.base_;
|
||||
}
|
||||
private:
|
||||
Iterator* base_;
|
||||
};
|
||||
value_type v_;
|
||||
|
||||
template <class Iterator>
|
||||
input_iterator_adaptor<Iterator> input_iterator(Iterator& it)
|
||||
private:
|
||||
proxy& operator=(proxy const&);
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
struct input_iterator_adaptor
|
||||
: public std::iterator<std::input_iterator_tag,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type,
|
||||
std::ptrdiff_t,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_pointer<Iterator>::type,
|
||||
proxy<Iterator> >
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type
|
||||
value_type;
|
||||
|
||||
input_iterator_adaptor() : base_() {}
|
||||
explicit input_iterator_adaptor(Iterator& it) : base_(&it) {}
|
||||
proxy<Iterator> operator*() const { return proxy<Iterator>(**base_); }
|
||||
value_type* operator->() const { return &**base_; }
|
||||
input_iterator_adaptor& operator++()
|
||||
{
|
||||
return input_iterator_adaptor<Iterator>(it);
|
||||
++*base_;
|
||||
return *this;
|
||||
}
|
||||
// input_iterator_adaptor operator++(int) {
|
||||
//}
|
||||
bool operator==(input_iterator_adaptor const& x) const
|
||||
{
|
||||
return *base_ == *x.base_;
|
||||
}
|
||||
bool operator!=(input_iterator_adaptor const& x) const
|
||||
{
|
||||
return *base_ != *x.base_;
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
struct copy_iterator_adaptor
|
||||
: public std::iterator<
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_category<Iterator>::type,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_difference<Iterator>::type,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_pointer<Iterator>::type,
|
||||
proxy<Iterator>
|
||||
>
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type
|
||||
value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<Iterator>::type
|
||||
difference_type;
|
||||
|
||||
copy_iterator_adaptor()
|
||||
: base_() {}
|
||||
explicit copy_iterator_adaptor(Iterator const& it)
|
||||
: base_(it) {}
|
||||
value_type operator*() const {
|
||||
return *base_;
|
||||
}
|
||||
value_type* operator->() const {
|
||||
return &*base_;
|
||||
}
|
||||
value_type operator[](difference_type d) {
|
||||
return base_[d];
|
||||
}
|
||||
copy_iterator_adaptor& operator++() {
|
||||
++base_; return *this;
|
||||
}
|
||||
copy_iterator_adaptor operator++(int) {
|
||||
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;
|
||||
return *this;
|
||||
}
|
||||
copy_iterator_adaptor operator-=(difference_type x) {
|
||||
base_ -= x;
|
||||
return *this;
|
||||
}
|
||||
copy_iterator_adaptor operator+(difference_type n) {
|
||||
return copy_iterator_adaptor(base_+n);
|
||||
}
|
||||
copy_iterator_adaptor operator-(difference_type n) {
|
||||
return copy_iterator_adaptor(base_-n);
|
||||
}
|
||||
friend copy_iterator_adaptor operator+(
|
||||
difference_type n, copy_iterator_adaptor x) {
|
||||
return x+n;
|
||||
}
|
||||
difference_type operator-(copy_iterator_adaptor const& other) {
|
||||
return base_-other.base_;
|
||||
}
|
||||
bool operator==(copy_iterator_adaptor const& x) const {
|
||||
return base_ == x.base_;
|
||||
}
|
||||
bool operator!=(copy_iterator_adaptor const& x) const {
|
||||
return base_ != x.base_;
|
||||
}
|
||||
bool operator<(copy_iterator_adaptor const& x) const {
|
||||
return base_ < x.base_;
|
||||
}
|
||||
bool operator>(copy_iterator_adaptor const& x) const {
|
||||
return base_ > x.base_;
|
||||
}
|
||||
bool operator<=(copy_iterator_adaptor const& x) const {
|
||||
return base_ <= x.base_;
|
||||
}
|
||||
bool operator>=(copy_iterator_adaptor const& x) const {
|
||||
return base_ >= x.base_;
|
||||
}
|
||||
private:
|
||||
Iterator base_;
|
||||
};
|
||||
private:
|
||||
Iterator* base_;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
copy_iterator_adaptor<Iterator> copy_iterator(Iterator const& it)
|
||||
template <class Iterator>
|
||||
input_iterator_adaptor<Iterator> input_iterator(Iterator& it)
|
||||
{
|
||||
return input_iterator_adaptor<Iterator>(it);
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
struct copy_iterator_adaptor
|
||||
: public std::iterator<
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_category<Iterator>::type,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_difference<Iterator>::type,
|
||||
BOOST_DEDUCED_TYPENAME boost::iterator_pointer<Iterator>::type,
|
||||
proxy<Iterator> >
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<Iterator>::type
|
||||
value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<Iterator>::type
|
||||
difference_type;
|
||||
|
||||
copy_iterator_adaptor() : base_() {}
|
||||
explicit copy_iterator_adaptor(Iterator const& it) : base_(it) {}
|
||||
value_type operator*() const { return *base_; }
|
||||
value_type* operator->() const { return &*base_; }
|
||||
value_type operator[](difference_type d) { return base_[d]; }
|
||||
copy_iterator_adaptor& operator++()
|
||||
{
|
||||
return copy_iterator_adaptor<Iterator>(it);
|
||||
++base_;
|
||||
return *this;
|
||||
}
|
||||
copy_iterator_adaptor operator++(int)
|
||||
{
|
||||
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;
|
||||
return *this;
|
||||
}
|
||||
copy_iterator_adaptor operator-=(difference_type x)
|
||||
{
|
||||
base_ -= x;
|
||||
return *this;
|
||||
}
|
||||
copy_iterator_adaptor operator+(difference_type n)
|
||||
{
|
||||
return copy_iterator_adaptor(base_ + n);
|
||||
}
|
||||
copy_iterator_adaptor operator-(difference_type n)
|
||||
{
|
||||
return copy_iterator_adaptor(base_ - n);
|
||||
}
|
||||
friend copy_iterator_adaptor operator+(
|
||||
difference_type n, copy_iterator_adaptor x)
|
||||
{
|
||||
return x + n;
|
||||
}
|
||||
difference_type operator-(copy_iterator_adaptor const& other)
|
||||
{
|
||||
return base_ - other.base_;
|
||||
}
|
||||
bool operator==(copy_iterator_adaptor const& x) const
|
||||
{
|
||||
return base_ == x.base_;
|
||||
}
|
||||
bool operator!=(copy_iterator_adaptor const& x) const
|
||||
{
|
||||
return base_ != x.base_;
|
||||
}
|
||||
bool operator<(copy_iterator_adaptor const& x) const
|
||||
{
|
||||
return base_ < x.base_;
|
||||
}
|
||||
bool operator>(copy_iterator_adaptor const& x) const
|
||||
{
|
||||
return base_ > x.base_;
|
||||
}
|
||||
bool operator<=(copy_iterator_adaptor const& x) const
|
||||
{
|
||||
return base_ <= x.base_;
|
||||
}
|
||||
bool operator>=(copy_iterator_adaptor const& x) const
|
||||
{
|
||||
return base_ >= x.base_;
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator base_;
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
copy_iterator_adaptor<Iterator> copy_iterator(Iterator const& it)
|
||||
{
|
||||
return copy_iterator_adaptor<Iterator>(it);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+88
-90
@@ -9,114 +9,113 @@
|
||||
#if !defined(BOOST_UNORDERED_TEST_HELPERS_INVARIANT_HEADER)
|
||||
#define BOOST_UNORDERED_TEST_HELPERS_INVARIANT_HEADER
|
||||
|
||||
#include <set>
|
||||
#include <cmath>
|
||||
#include "./metafunctions.hpp"
|
||||
#include "./helpers.hpp"
|
||||
#include "./metafunctions.hpp"
|
||||
#include <cmath>
|
||||
#include <set>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127) // conditional expression is constant
|
||||
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
|
||||
#pragma warning(disable : 4127) // conditional expression is constant
|
||||
#pragma warning(disable : 4267) // conversion from 'size_t' to 'unsigned int',
|
||||
// possible loss of data
|
||||
#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();
|
||||
typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
|
||||
std::set<key_type, std::less<key_type> > found_;
|
||||
BOOST_DEDUCED_TYPENAME X::key_equal eq = x1.key_eq();
|
||||
typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
|
||||
std::set<key_type, std::less<key_type> > found_;
|
||||
|
||||
BOOST_DEDUCED_TYPENAME X::const_iterator
|
||||
it = x1.begin(), end = x1.end();
|
||||
BOOST_DEDUCED_TYPENAME X::size_type size = 0;
|
||||
while(it != end) {
|
||||
// First test that the current key has not occurred before, required
|
||||
// to test either that keys are unique or that equivalent keys are
|
||||
// adjacent. (6.3.1/6)
|
||||
key_type key = get_key<X>(*it);
|
||||
if(!found_.insert(key).second)
|
||||
BOOST_ERROR("Elements with equivalent keys aren't adjacent.");
|
||||
BOOST_DEDUCED_TYPENAME X::const_iterator it = x1.begin(), end = x1.end();
|
||||
BOOST_DEDUCED_TYPENAME X::size_type size = 0;
|
||||
while (it != end) {
|
||||
// First test that the current key has not occurred before, required
|
||||
// to test either that keys are unique or that equivalent keys are
|
||||
// adjacent. (6.3.1/6)
|
||||
key_type key = get_key<X>(*it);
|
||||
if (!found_.insert(key).second)
|
||||
BOOST_ERROR("Elements with equivalent keys aren't adjacent.");
|
||||
|
||||
// Iterate over equivalent keys, counting them.
|
||||
unsigned int count = 0;
|
||||
do {
|
||||
++it;
|
||||
++count;
|
||||
++size;
|
||||
} while(it != end && eq(get_key<X>(*it), key));
|
||||
// Iterate over equivalent keys, counting them.
|
||||
unsigned int count = 0;
|
||||
do {
|
||||
++it;
|
||||
++count;
|
||||
++size;
|
||||
} while (it != end && eq(get_key<X>(*it), key));
|
||||
|
||||
// If the container has unique keys, test that there's only one.
|
||||
// Since the previous test makes sure that all equivalent keys are
|
||||
// adjacent, this is all the equivalent keys - so the test is
|
||||
// sufficient. (6.3.1/6 again).
|
||||
if(test::has_unique_keys<X>::value && count != 1)
|
||||
BOOST_ERROR("Non-unique key.");
|
||||
// If the container has unique keys, test that there's only one.
|
||||
// Since the previous test makes sure that all equivalent keys are
|
||||
// adjacent, this is all the equivalent keys - so the test is
|
||||
// sufficient. (6.3.1/6 again).
|
||||
if (test::has_unique_keys<X>::value && count != 1)
|
||||
BOOST_ERROR("Non-unique key.");
|
||||
|
||||
if(x1.count(key) != count) {
|
||||
BOOST_ERROR("Incorrect output of count.");
|
||||
std::cerr<<x1.count(key)<<","<<count<<"\n";
|
||||
}
|
||||
|
||||
// Check that the keys are in the correct bucket and are
|
||||
// adjacent in the bucket.
|
||||
BOOST_DEDUCED_TYPENAME X::size_type bucket = x1.bucket(key);
|
||||
BOOST_DEDUCED_TYPENAME X::const_local_iterator
|
||||
lit = x1.begin(bucket), lend = x1.end(bucket);
|
||||
for(; lit != lend && !eq(get_key<X>(*lit), key); ++lit) continue;
|
||||
if(lit == lend)
|
||||
BOOST_ERROR("Unable to find element with a local_iterator");
|
||||
unsigned int count2 = 0;
|
||||
for(; lit != lend && eq(get_key<X>(*lit), key); ++lit) ++count2;
|
||||
if(count != count2)
|
||||
BOOST_ERROR("Element count doesn't match local_iterator.");
|
||||
for(; lit != lend; ++lit) {
|
||||
if(eq(get_key<X>(*lit), key)) {
|
||||
BOOST_ERROR("Non-adjacent element with equivalent key "
|
||||
"in bucket.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Check that size matches up.
|
||||
|
||||
if(x1.size() != size) {
|
||||
BOOST_ERROR("x1.size() doesn't match actual size.");
|
||||
std::cout<<x1.size()<<"/"<<size<<std::endl;
|
||||
if (x1.count(key) != count) {
|
||||
BOOST_ERROR("Incorrect output of count.");
|
||||
std::cerr << x1.count(key) << "," << count << "\n";
|
||||
}
|
||||
|
||||
// Check the load factor.
|
||||
|
||||
float load_factor = size == 0 ? 0 :
|
||||
static_cast<float>(size) / static_cast<float>(x1.bucket_count());
|
||||
using namespace std;
|
||||
if(fabs(x1.load_factor() - load_factor) > x1.load_factor() / 64)
|
||||
BOOST_ERROR("x1.load_factor() doesn't match actual load_factor.");
|
||||
|
||||
// Check that size in the buckets matches up.
|
||||
|
||||
BOOST_DEDUCED_TYPENAME X::size_type bucket_size = 0;
|
||||
|
||||
for (BOOST_DEDUCED_TYPENAME X::size_type
|
||||
i = 0; i < x1.bucket_count(); ++i)
|
||||
{
|
||||
for (BOOST_DEDUCED_TYPENAME X::const_local_iterator
|
||||
begin2 = x1.begin(i), end2 = x1.end(i);
|
||||
begin2 != end2; ++begin2)
|
||||
{
|
||||
++bucket_size;
|
||||
// Check that the keys are in the correct bucket and are
|
||||
// adjacent in the bucket.
|
||||
BOOST_DEDUCED_TYPENAME X::size_type bucket = x1.bucket(key);
|
||||
BOOST_DEDUCED_TYPENAME X::const_local_iterator lit = x1.begin(bucket),
|
||||
lend = x1.end(bucket);
|
||||
for (; lit != lend && !eq(get_key<X>(*lit), key); ++lit)
|
||||
continue;
|
||||
if (lit == lend)
|
||||
BOOST_ERROR("Unable to find element with a local_iterator");
|
||||
unsigned int count2 = 0;
|
||||
for (; lit != lend && eq(get_key<X>(*lit), key); ++lit)
|
||||
++count2;
|
||||
if (count != count2)
|
||||
BOOST_ERROR("Element count doesn't match local_iterator.");
|
||||
for (; lit != lend; ++lit) {
|
||||
if (eq(get_key<X>(*lit), key)) {
|
||||
BOOST_ERROR("Non-adjacent element with equivalent key "
|
||||
"in bucket.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if(x1.size() != bucket_size) {
|
||||
BOOST_ERROR("x1.size() doesn't match bucket size.");
|
||||
std::cout<<x1.size()<<"/"<<bucket_size<<std::endl;
|
||||
// Check that size matches up.
|
||||
|
||||
if (x1.size() != size) {
|
||||
BOOST_ERROR("x1.size() doesn't match actual size.");
|
||||
std::cout << x1.size() << "/" << size << std::endl;
|
||||
}
|
||||
|
||||
// Check the load factor.
|
||||
|
||||
float load_factor =
|
||||
size == 0 ? 0 : static_cast<float>(size) /
|
||||
static_cast<float>(x1.bucket_count());
|
||||
using namespace std;
|
||||
if (fabs(x1.load_factor() - load_factor) > x1.load_factor() / 64)
|
||||
BOOST_ERROR("x1.load_factor() doesn't match actual load_factor.");
|
||||
|
||||
// Check that size in the buckets matches up.
|
||||
|
||||
BOOST_DEDUCED_TYPENAME X::size_type bucket_size = 0;
|
||||
|
||||
for (BOOST_DEDUCED_TYPENAME X::size_type i = 0; i < x1.bucket_count();
|
||||
++i) {
|
||||
for (BOOST_DEDUCED_TYPENAME X::const_local_iterator
|
||||
begin2 = x1.begin(i),
|
||||
end2 = x1.end(i);
|
||||
begin2 != end2; ++begin2) {
|
||||
++bucket_size;
|
||||
}
|
||||
}
|
||||
|
||||
if (x1.size() != bucket_size) {
|
||||
BOOST_ERROR("x1.size() doesn't match bucket size.");
|
||||
std::cout << x1.size() << "/" << bucket_size << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
@@ -124,4 +123,3 @@ namespace test
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+275
-273
@@ -12,307 +12,309 @@
|
||||
#define UNORDERED_TEST_LIST_HEADER
|
||||
|
||||
#include <boost/limits.hpp>
|
||||
#include <iterator>
|
||||
#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>
|
||||
bool equal(It1 begin, It1 end, It2 compare)
|
||||
for (; begin != end; ++begin, ++compare)
|
||||
if (*begin != *compare)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename It1, typename It2, typename Pred>
|
||||
bool equal(It1 begin, It1 end, It2 compare, Pred predicate)
|
||||
{
|
||||
for (; begin != end; ++begin, ++compare)
|
||||
if (!predicate(*begin, *compare))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
template <typename T> class list_node
|
||||
{
|
||||
list_node(list_node const&);
|
||||
list_node& operator=(list_node const&);
|
||||
|
||||
public:
|
||||
T value_;
|
||||
list_node* next_;
|
||||
|
||||
list_node(T const& v) : value_(v), next_(0) {}
|
||||
list_node(T const& v, list_node* n) : value_(v), next_(n) {}
|
||||
};
|
||||
|
||||
template <typename T> class list_data
|
||||
{
|
||||
public:
|
||||
typedef list_node<T> node;
|
||||
typedef unsigned int size_type;
|
||||
|
||||
node* first_;
|
||||
node** last_ptr_;
|
||||
size_type size_;
|
||||
|
||||
list_data() : first_(0), last_ptr_(&first_), size_(0) {}
|
||||
|
||||
~list_data()
|
||||
{
|
||||
for(;begin != end; ++begin, ++compare)
|
||||
if(*begin != *compare) return false;
|
||||
return true;
|
||||
while (first_) {
|
||||
node* tmp = first_;
|
||||
first_ = first_->next_;
|
||||
delete tmp;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename It1, typename It2, typename Pred>
|
||||
bool equal(It1 begin, It1 end, It2 compare, Pred predicate)
|
||||
private:
|
||||
list_data(list_data const&);
|
||||
list_data& operator=(list_data const&);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class list_iterator
|
||||
: public std::iterator<std::forward_iterator_tag, T, int, T*, T&>
|
||||
{
|
||||
friend class list_const_iterator<T>;
|
||||
friend class test::list<T>;
|
||||
typedef list_node<T> node;
|
||||
typedef list_const_iterator<T> const_iterator;
|
||||
|
||||
node* ptr_;
|
||||
|
||||
public:
|
||||
list_iterator() : ptr_(0) {}
|
||||
explicit list_iterator(node* x) : ptr_(x) {}
|
||||
|
||||
T& operator*() const { return ptr_->value_; }
|
||||
T* operator->() const { return &ptr_->value_; }
|
||||
list_iterator& operator++()
|
||||
{
|
||||
for(;begin != end; ++begin, ++compare)
|
||||
if(!predicate(*begin, *compare)) return false;
|
||||
return true;
|
||||
ptr_ = ptr_->next_;
|
||||
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_; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class list_const_iterator : public std::iterator<std::forward_iterator_tag, T,
|
||||
int, T const*, T const&>
|
||||
{
|
||||
friend class list_iterator<T>;
|
||||
friend class test::list<T>;
|
||||
typedef list_node<T> node;
|
||||
typedef list_iterator<T> iterator;
|
||||
typedef list_const_iterator<T> const_iterator;
|
||||
|
||||
node* ptr_;
|
||||
|
||||
public:
|
||||
list_const_iterator() : ptr_(0) {}
|
||||
list_const_iterator(list_iterator<T> const& x) : ptr_(x.ptr_) {}
|
||||
|
||||
T const& operator*() const { return ptr_->value_; }
|
||||
T const* operator->() const { return &ptr_->value_; }
|
||||
|
||||
list_const_iterator& operator++()
|
||||
{
|
||||
ptr_ = ptr_->next_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template <typename T> class list;
|
||||
|
||||
namespace test_detail
|
||||
list_const_iterator operator++(int)
|
||||
{
|
||||
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& operator=(list_node const&);
|
||||
public:
|
||||
T value_;
|
||||
list_node* next_;
|
||||
|
||||
list_node(T const& v) : value_(v), next_(0) {}
|
||||
list_node(T const& v, list_node* n) : value_(v), next_(n) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class list_data
|
||||
{
|
||||
public:
|
||||
typedef list_node<T> node;
|
||||
typedef unsigned int size_type;
|
||||
|
||||
node* first_;
|
||||
node** last_ptr_;
|
||||
size_type size_;
|
||||
|
||||
list_data() : first_(0), last_ptr_(&first_), size_(0) {}
|
||||
|
||||
~list_data() {
|
||||
while(first_) {
|
||||
node* tmp = first_;
|
||||
first_ = first_->next_;
|
||||
delete tmp;
|
||||
}
|
||||
}
|
||||
private:
|
||||
list_data(list_data const&);
|
||||
list_data& operator=(list_data const&);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class list_iterator
|
||||
: public std::iterator<
|
||||
std::forward_iterator_tag, T,
|
||||
int, T*, T&>
|
||||
{
|
||||
friend class list_const_iterator<T>;
|
||||
friend class test::list<T>;
|
||||
typedef list_node<T> node;
|
||||
typedef list_const_iterator<T> const_iterator;
|
||||
|
||||
node* ptr_;
|
||||
public:
|
||||
list_iterator() : ptr_(0) {}
|
||||
explicit list_iterator(node* x) : ptr_(x) {}
|
||||
|
||||
T& operator*() const { return ptr_->value_; }
|
||||
T* operator->() const { return &ptr_->value_; }
|
||||
list_iterator& operator++() {
|
||||
ptr_ = ptr_->next_; 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_; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class list_const_iterator
|
||||
: public std::iterator<
|
||||
std::forward_iterator_tag, T,
|
||||
int, T const*, T const&>
|
||||
{
|
||||
friend class list_iterator<T>;
|
||||
friend class test::list<T>;
|
||||
typedef list_node<T> node;
|
||||
typedef list_iterator<T> iterator;
|
||||
typedef list_const_iterator<T> const_iterator;
|
||||
|
||||
node* ptr_;
|
||||
public:
|
||||
list_const_iterator() : ptr_(0) {}
|
||||
list_const_iterator(list_iterator<T> const& x) : ptr_(x.ptr_) {}
|
||||
|
||||
T const& operator*() const { return ptr_->value_; }
|
||||
T const* operator->() const { return &ptr_->value_; }
|
||||
|
||||
list_const_iterator& operator++()
|
||||
{
|
||||
ptr_ = ptr_->next_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
list_const_iterator operator++(int)
|
||||
{
|
||||
list_const_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_;
|
||||
}
|
||||
};
|
||||
list_const_iterator tmp = *this;
|
||||
ptr_ = ptr_->next_;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class list
|
||||
bool operator==(const_iterator y) const { return ptr_ == y.ptr_; }
|
||||
|
||||
bool operator!=(const_iterator y) const { return ptr_ != y.ptr_; }
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T> class list
|
||||
{
|
||||
typedef test::test_detail::list_data<T> data;
|
||||
typedef test::test_detail::list_node<T> node;
|
||||
data data_;
|
||||
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef value_type& reference;
|
||||
typedef value_type const& const_reference;
|
||||
typedef unsigned int size_type;
|
||||
|
||||
typedef test::test_detail::list_iterator<T> iterator;
|
||||
typedef test::test_detail::list_const_iterator<T> const_iterator;
|
||||
|
||||
list() : data_() {}
|
||||
|
||||
list(list const& other) : data_() { insert(other.begin(), other.end()); }
|
||||
|
||||
template <class InputIterator>
|
||||
list(InputIterator i, InputIterator j) : data_()
|
||||
{
|
||||
typedef test::test_detail::list_data<T> data;
|
||||
typedef test::test_detail::list_node<T> node;
|
||||
data data_;
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef value_type& reference;
|
||||
typedef value_type const& const_reference;
|
||||
typedef unsigned int size_type;
|
||||
insert(i, j);
|
||||
}
|
||||
|
||||
typedef test::test_detail::list_iterator<T> iterator;
|
||||
typedef test::test_detail::list_const_iterator<T> const_iterator;
|
||||
list& operator=(list const& other)
|
||||
{
|
||||
clear();
|
||||
insert(other.begin(), other.end());
|
||||
return *this;
|
||||
}
|
||||
|
||||
list() : data_() {}
|
||||
iterator begin() { return iterator(data_.first_); }
|
||||
iterator end() { return iterator(); }
|
||||
const_iterator begin() const { return iterator(data_.first_); }
|
||||
const_iterator end() const { return iterator(); }
|
||||
const_iterator cbegin() const { return iterator(data_.first_); }
|
||||
const_iterator cend() const { return iterator(); }
|
||||
|
||||
list(list const& other) : data_() {
|
||||
insert(other.begin(), other.end());
|
||||
}
|
||||
template <class InputIterator> void insert(InputIterator i, InputIterator j)
|
||||
{
|
||||
for (; i != j; ++i)
|
||||
push_back(*i);
|
||||
}
|
||||
|
||||
template <class InputIterator>
|
||||
list(InputIterator i, InputIterator j) : data_() {
|
||||
insert(i, j);
|
||||
}
|
||||
|
||||
list& operator=(list const& other) {
|
||||
clear();
|
||||
insert(other.begin(), other.end());
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator begin() { return iterator(data_.first_); }
|
||||
iterator end() { return iterator(); }
|
||||
const_iterator begin() const { return iterator(data_.first_); }
|
||||
const_iterator end() const { return iterator(); }
|
||||
const_iterator cbegin() const { return iterator(data_.first_); }
|
||||
const_iterator cend() const { return iterator(); }
|
||||
|
||||
template <class InputIterator>
|
||||
void insert(InputIterator i, InputIterator j) {
|
||||
for(; i != j; ++i)
|
||||
push_back(*i);
|
||||
}
|
||||
|
||||
void push_front(value_type const& v) {
|
||||
data_.first_ = new node(v, data_.first_);
|
||||
if(!data_.size_) data_.last_ptr_ = &(*data_.last_ptr_)->next_;
|
||||
++data_.size_;
|
||||
}
|
||||
|
||||
void push_back(value_type const& v) {
|
||||
*data_.last_ptr_ = new node(v);
|
||||
void push_front(value_type const& v)
|
||||
{
|
||||
data_.first_ = new node(v, data_.first_);
|
||||
if (!data_.size_)
|
||||
data_.last_ptr_ = &(*data_.last_ptr_)->next_;
|
||||
++data_.size_;
|
||||
++data_.size_;
|
||||
}
|
||||
|
||||
void push_back(value_type const& v)
|
||||
{
|
||||
*data_.last_ptr_ = new node(v);
|
||||
data_.last_ptr_ = &(*data_.last_ptr_)->next_;
|
||||
++data_.size_;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
while (data_.first_) {
|
||||
node* tmp = data_.first_;
|
||||
data_.first_ = data_.first_->next_;
|
||||
--data_.size_;
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
while(data_.first_) {
|
||||
node* tmp = data_.first_;
|
||||
data_.first_ = data_.first_->next_;
|
||||
--data_.size_;
|
||||
delete tmp;
|
||||
}
|
||||
data_.last_ptr_ = &data_.first_;
|
||||
data_.last_ptr_ = &data_.first_;
|
||||
}
|
||||
|
||||
void erase(const_iterator i, const_iterator j)
|
||||
{
|
||||
node** ptr = &data_.first_;
|
||||
|
||||
while (*ptr != i.ptr_) {
|
||||
ptr = &(*ptr)->next_;
|
||||
}
|
||||
|
||||
void erase(const_iterator i, const_iterator j) {
|
||||
node** ptr = &data_.first_;
|
||||
|
||||
while(*ptr != i.ptr_) {
|
||||
ptr = &(*ptr)->next_;
|
||||
}
|
||||
|
||||
while(*ptr != j.ptr_) {
|
||||
node* to_delete = *ptr;
|
||||
*ptr = (*ptr)->next_;
|
||||
--data_.size_;
|
||||
delete to_delete;
|
||||
}
|
||||
|
||||
if(!*ptr) data_.last_ptr_ = ptr;
|
||||
while (*ptr != j.ptr_) {
|
||||
node* to_delete = *ptr;
|
||||
*ptr = (*ptr)->next_;
|
||||
--data_.size_;
|
||||
delete to_delete;
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return !data_.size_;
|
||||
if (!*ptr)
|
||||
data_.last_ptr_ = ptr;
|
||||
}
|
||||
|
||||
bool empty() const { 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);
|
||||
}
|
||||
|
||||
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:
|
||||
template <typename Less>
|
||||
node** merge_sort(node** l, size_type recurse_limit, Less less)
|
||||
{
|
||||
node** ptr = &(*l)->next_;
|
||||
for (size_type count = 0; count < recurse_limit && *ptr; ++count) {
|
||||
ptr = merge_adjacent_ranges(
|
||||
l, ptr, merge_sort(ptr, count, less), less);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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:
|
||||
template <typename Less>
|
||||
node** merge_sort(node** l, size_type recurse_limit, Less less)
|
||||
{
|
||||
node** ptr = &(*l)->next_;
|
||||
for(size_type count = 0; count < recurse_limit && *ptr; ++count)
|
||||
{
|
||||
ptr = merge_adjacent_ranges(l, ptr,
|
||||
merge_sort(ptr, count, less), less);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template <typename Less>
|
||||
node** merge_adjacent_ranges(node** first, node** second,
|
||||
node** third, Less less)
|
||||
{
|
||||
for(;;) {
|
||||
for(;;) {
|
||||
if(first == second) return third;
|
||||
if(less((*second)->value_, (*first)->value_)) break;
|
||||
first = &(*first)->next_;
|
||||
}
|
||||
|
||||
swap_adjacent_ranges(first, second, third);
|
||||
first = &(*first)->next_;
|
||||
|
||||
// Since the two ranges we just swapped, the order is now:
|
||||
// first...third...second
|
||||
|
||||
for(;;) {
|
||||
if(first == third) return second;
|
||||
if(!less((*first)->value_, (*third)->value_)) break;
|
||||
first = &(*first)->next_;
|
||||
}
|
||||
|
||||
swap_adjacent_ranges(first, third, second);
|
||||
template <typename Less>
|
||||
node** merge_adjacent_ranges(
|
||||
node** first, node** second, node** third, Less less)
|
||||
{
|
||||
for (;;) {
|
||||
for (;;) {
|
||||
if (first == second)
|
||||
return third;
|
||||
if (less((*second)->value_, (*first)->value_))
|
||||
break;
|
||||
first = &(*first)->next_;
|
||||
}
|
||||
|
||||
swap_adjacent_ranges(first, second, third);
|
||||
first = &(*first)->next_;
|
||||
|
||||
// Since the two ranges we just swapped, the order is now:
|
||||
// first...third...second
|
||||
|
||||
for (;;) {
|
||||
if (first == third)
|
||||
return second;
|
||||
if (!less((*first)->value_, (*third)->value_))
|
||||
break;
|
||||
first = &(*first)->next_;
|
||||
}
|
||||
|
||||
swap_adjacent_ranges(first, third, second);
|
||||
first = &(*first)->next_;
|
||||
}
|
||||
|
||||
void swap_adjacent_ranges(node** first, node** second, node** third)
|
||||
{
|
||||
node* tmp = *first;
|
||||
*first = *second;
|
||||
*second = *third;
|
||||
*third = tmp;
|
||||
if(!*second) data_.last_ptr_ = second;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void swap_adjacent_ranges(node** first, node** second, node** third)
|
||||
{
|
||||
node* tmp = *first;
|
||||
*first = *second;
|
||||
*second = *third;
|
||||
*third = tmp;
|
||||
if (!*second)
|
||||
data_.last_ptr_ = second;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+130
-135
@@ -6,158 +6,153 @@
|
||||
#if !defined(BOOST_UNORDERED_TEST_MEMORY_HEADER)
|
||||
#define BOOST_UNORDERED_TEST_MEMORY_HEADER
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include "../helpers/test.hpp"
|
||||
#include <boost/assert.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
|
||||
void const* start;
|
||||
void const* end;
|
||||
|
||||
memory_area(void const* s, void const* e) : start(s), end(e)
|
||||
{
|
||||
struct memory_area {
|
||||
void const* start;
|
||||
void const* end;
|
||||
BOOST_ASSERT(start != end);
|
||||
}
|
||||
};
|
||||
|
||||
memory_area(void const* s, void const* e)
|
||||
: start(s), end(e)
|
||||
{
|
||||
BOOST_ASSERT(start != end);
|
||||
}
|
||||
};
|
||||
struct memory_track
|
||||
{
|
||||
explicit memory_track(int tag = -1) : constructed_(0), tag_(tag) {}
|
||||
|
||||
struct memory_track {
|
||||
explicit memory_track(int tag = -1) :
|
||||
constructed_(0),
|
||||
tag_(tag) {}
|
||||
int constructed_;
|
||||
int tag_;
|
||||
};
|
||||
|
||||
int constructed_;
|
||||
int tag_;
|
||||
};
|
||||
// This is a bit dodgy as it defines overlapping
|
||||
// areas as 'equal', so this isn't a total ordering.
|
||||
// But it is for non-overlapping memory regions - which
|
||||
// is what'll be stored.
|
||||
//
|
||||
// All searches will be for areas entirely contained by
|
||||
// a member of the set - so it should find the area that contains
|
||||
// the region that is searched for.
|
||||
|
||||
// This is a bit dodgy as it defines overlapping
|
||||
// areas as 'equal', so this isn't a total ordering.
|
||||
// But it is for non-overlapping memory regions - which
|
||||
// is what'll be stored.
|
||||
//
|
||||
// All searches will be for areas entirely contained by
|
||||
// a member of the set - so it should find the area that contains
|
||||
// the region that is searched for.
|
||||
struct memory_area_compare
|
||||
{
|
||||
bool operator()(memory_area const& x, memory_area const& y) const
|
||||
{
|
||||
return x.end <= y.start;
|
||||
}
|
||||
};
|
||||
|
||||
struct memory_area_compare {
|
||||
bool operator()(memory_area const& x, memory_area const& y) const {
|
||||
return x.end <= y.start;
|
||||
}
|
||||
};
|
||||
struct memory_tracker
|
||||
{
|
||||
typedef std::map<memory_area, memory_track, memory_area_compare,
|
||||
std::allocator<std::pair<memory_area const, memory_track> > >
|
||||
allocated_memory_type;
|
||||
|
||||
struct memory_tracker {
|
||||
typedef std::map<memory_area, memory_track, memory_area_compare,
|
||||
std::allocator<std::pair<memory_area const, memory_track> >
|
||||
> allocated_memory_type;
|
||||
allocated_memory_type allocated_memory;
|
||||
unsigned int count_allocators;
|
||||
unsigned int count_allocations;
|
||||
unsigned int count_constructions;
|
||||
|
||||
allocated_memory_type allocated_memory;
|
||||
unsigned int count_allocators;
|
||||
unsigned int count_allocations;
|
||||
unsigned int count_constructions;
|
||||
|
||||
memory_tracker() :
|
||||
count_allocators(0), count_allocations(0),
|
||||
count_constructions(0)
|
||||
{}
|
||||
|
||||
void allocator_ref()
|
||||
{
|
||||
if(count_allocators == 0) {
|
||||
count_allocations = 0;
|
||||
count_constructions = 0;
|
||||
allocated_memory.clear();
|
||||
}
|
||||
++count_allocators;
|
||||
}
|
||||
|
||||
void allocator_unref()
|
||||
{
|
||||
BOOST_TEST(count_allocators > 0);
|
||||
if(count_allocators > 0) {
|
||||
--count_allocators;
|
||||
if(count_allocators == 0) {
|
||||
bool no_allocations_left = (count_allocations == 0);
|
||||
bool no_constructions_left = (count_constructions == 0);
|
||||
bool allocated_memory_empty = allocated_memory.empty();
|
||||
|
||||
// Clearing the data before the checks terminate the
|
||||
// tests.
|
||||
count_allocations = 0;
|
||||
count_constructions = 0;
|
||||
allocated_memory.clear();
|
||||
|
||||
BOOST_TEST(no_allocations_left);
|
||||
BOOST_TEST(no_constructions_left);
|
||||
BOOST_TEST(allocated_memory_empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void track_allocate(void *ptr, std::size_t n, std::size_t size,
|
||||
int tag)
|
||||
{
|
||||
if(n == 0) {
|
||||
BOOST_ERROR("Allocating 0 length array.");
|
||||
}
|
||||
else {
|
||||
++count_allocations;
|
||||
allocated_memory.insert(
|
||||
std::pair<memory_area const, memory_track>(
|
||||
memory_area(ptr, (char*) ptr + n * size),
|
||||
memory_track(tag)));
|
||||
}
|
||||
}
|
||||
|
||||
void track_deallocate(void* ptr, std::size_t n, std::size_t size,
|
||||
int tag, bool check_tag_ = true)
|
||||
{
|
||||
allocated_memory_type::iterator pos =
|
||||
allocated_memory.find(
|
||||
memory_area(ptr, (char*) ptr + n * size));
|
||||
if(pos == allocated_memory.end()) {
|
||||
BOOST_ERROR("Deallocating unknown pointer.");
|
||||
} else {
|
||||
BOOST_TEST(pos->first.start == ptr);
|
||||
BOOST_TEST(pos->first.end == (char*) ptr + n * size);
|
||||
if (check_tag_) BOOST_TEST(pos->second.tag_ == tag);
|
||||
allocated_memory.erase(pos);
|
||||
}
|
||||
BOOST_TEST(count_allocations > 0);
|
||||
if(count_allocations > 0) --count_allocations;
|
||||
}
|
||||
|
||||
void track_construct(void* /*ptr*/, std::size_t /*size*/,
|
||||
int /*tag*/)
|
||||
{
|
||||
++count_constructions;
|
||||
}
|
||||
|
||||
void track_destroy(void* /*ptr*/, std::size_t /*size*/,
|
||||
int /*tag*/)
|
||||
{
|
||||
BOOST_TEST(count_constructions > 0);
|
||||
if(count_constructions > 0) --count_constructions;
|
||||
}
|
||||
};
|
||||
memory_tracker()
|
||||
: count_allocators(0), count_allocations(0), count_constructions(0)
|
||||
{
|
||||
}
|
||||
|
||||
namespace detail
|
||||
void allocator_ref()
|
||||
{
|
||||
// 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
|
||||
// framework).
|
||||
//
|
||||
// boostinspect:nounnamed
|
||||
namespace {
|
||||
test::detail::memory_tracker tracker;
|
||||
if (count_allocators == 0) {
|
||||
count_allocations = 0;
|
||||
count_constructions = 0;
|
||||
allocated_memory.clear();
|
||||
}
|
||||
++count_allocators;
|
||||
}
|
||||
|
||||
void allocator_unref()
|
||||
{
|
||||
BOOST_TEST(count_allocators > 0);
|
||||
if (count_allocators > 0) {
|
||||
--count_allocators;
|
||||
if (count_allocators == 0) {
|
||||
bool no_allocations_left = (count_allocations == 0);
|
||||
bool no_constructions_left = (count_constructions == 0);
|
||||
bool allocated_memory_empty = allocated_memory.empty();
|
||||
|
||||
// Clearing the data before the checks terminate the
|
||||
// tests.
|
||||
count_allocations = 0;
|
||||
count_constructions = 0;
|
||||
allocated_memory.clear();
|
||||
|
||||
BOOST_TEST(no_allocations_left);
|
||||
BOOST_TEST(no_constructions_left);
|
||||
BOOST_TEST(allocated_memory_empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void track_allocate(void* ptr, std::size_t n, std::size_t size, int tag)
|
||||
{
|
||||
if (n == 0) {
|
||||
BOOST_ERROR("Allocating 0 length array.");
|
||||
} else {
|
||||
++count_allocations;
|
||||
allocated_memory.insert(std::pair<memory_area const, memory_track>(
|
||||
memory_area(ptr, (char*)ptr + n * size), memory_track(tag)));
|
||||
}
|
||||
}
|
||||
|
||||
void track_deallocate(void* ptr, std::size_t n, std::size_t size, int tag,
|
||||
bool check_tag_ = true)
|
||||
{
|
||||
allocated_memory_type::iterator pos =
|
||||
allocated_memory.find(memory_area(ptr, (char*)ptr + n * size));
|
||||
if (pos == allocated_memory.end()) {
|
||||
BOOST_ERROR("Deallocating unknown pointer.");
|
||||
} else {
|
||||
BOOST_TEST(pos->first.start == ptr);
|
||||
BOOST_TEST(pos->first.end == (char*)ptr + n * size);
|
||||
if (check_tag_)
|
||||
BOOST_TEST(pos->second.tag_ == tag);
|
||||
allocated_memory.erase(pos);
|
||||
}
|
||||
BOOST_TEST(count_allocations > 0);
|
||||
if (count_allocations > 0)
|
||||
--count_allocations;
|
||||
}
|
||||
|
||||
void track_construct(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
|
||||
{
|
||||
++count_constructions;
|
||||
}
|
||||
|
||||
void track_destroy(void* /*ptr*/, std::size_t /*size*/, int /*tag*/)
|
||||
{
|
||||
BOOST_TEST(count_constructions > 0);
|
||||
if (count_constructions > 0)
|
||||
--count_constructions;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
// 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
|
||||
// framework).
|
||||
//
|
||||
// boostinspect:nounnamed
|
||||
namespace {
|
||||
test::detail::memory_tracker tracker;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,24 +9,26 @@
|
||||
#include <boost/config.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>
|
||||
struct has_unique_keys
|
||||
{
|
||||
static char flip(BOOST_DEDUCED_TYPENAME Container::iterator const&);
|
||||
static long flip(std::pair<BOOST_DEDUCED_TYPENAME Container::iterator, bool> const&);
|
||||
BOOST_STATIC_CONSTANT(bool, value = sizeof(long) == sizeof(
|
||||
flip(((Container*) 0)->insert(*(BOOST_DEDUCED_TYPENAME Container::value_type*) 0))
|
||||
));
|
||||
};
|
||||
template <class Container> struct has_unique_keys
|
||||
{
|
||||
static char flip(BOOST_DEDUCED_TYPENAME Container::iterator const&);
|
||||
static long flip(
|
||||
std::pair<BOOST_DEDUCED_TYPENAME Container::iterator, bool> const&);
|
||||
BOOST_STATIC_CONSTANT(bool,
|
||||
value = sizeof(long) ==
|
||||
sizeof(flip(
|
||||
((Container*)0)
|
||||
->insert(*(
|
||||
BOOST_DEDUCED_TYPENAME Container::value_type*)0))));
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
#if defined(_WIN32_WCE)
|
||||
// The standard windows mobile headers trigger this warning so I disable it
|
||||
// before doing anything else.
|
||||
#pragma warning(disable:4201) // nonstandard extension used :
|
||||
#pragma warning(disable : 4201) // nonstandard extension used :
|
||||
// nameless struct/union
|
||||
#endif
|
||||
|
||||
@@ -6,111 +6,104 @@
|
||||
#if !defined(BOOST_UNORDERED_TEST_HELPERS_RANDOM_VALUES_HEADER)
|
||||
#define BOOST_UNORDERED_TEST_HELPERS_RANDOM_VALUES_HEADER
|
||||
|
||||
#include "./generators.hpp"
|
||||
#include "./list.hpp"
|
||||
#include "./metafunctions.hpp"
|
||||
#include <algorithm>
|
||||
#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;
|
||||
|
||||
random_generator type_;
|
||||
|
||||
unordered_generator_set(random_generator type) : type_(type) {}
|
||||
|
||||
template <class T> void fill(T& x, std::size_t len)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME X::value_type value_type;
|
||||
value_type* value_ptr = 0;
|
||||
len += x.size();
|
||||
|
||||
random_generator type_;
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
value_type value = generate(value_ptr, type_);
|
||||
|
||||
unordered_generator_set(random_generator type)
|
||||
: type_(type) {}
|
||||
std::size_t count =
|
||||
type_ == generate_collisions ? random_value(5) + 1 : 1;
|
||||
|
||||
template <class T>
|
||||
void fill(T& x, std::size_t len) {
|
||||
value_type* value_ptr = 0;
|
||||
len += x.size();
|
||||
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
value_type value = generate(value_ptr, type_);
|
||||
|
||||
std::size_t count = type_ == generate_collisions ?
|
||||
random_value(5) + 1 : 1;
|
||||
|
||||
for(std::size_t j = 0; j < count; ++j) {
|
||||
x.push_back(value);
|
||||
}
|
||||
for (std::size_t j = 0; j < count; ++j) {
|
||||
x.push_back(value);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template <class X>
|
||||
struct unordered_generator_map
|
||||
template <class X> struct unordered_generator_map
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::mapped_type mapped_type;
|
||||
|
||||
random_generator type_;
|
||||
|
||||
unordered_generator_map(random_generator type) : type_(type) {}
|
||||
|
||||
template <class T> void fill(T& x, std::size_t len)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::mapped_type mapped_type;
|
||||
key_type* key_ptr = 0;
|
||||
mapped_type* mapped_ptr = 0;
|
||||
|
||||
random_generator type_;
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
key_type key = generate(key_ptr, type_);
|
||||
|
||||
unordered_generator_map(random_generator type)
|
||||
: type_(type) {}
|
||||
std::size_t count =
|
||||
type_ == generate_collisions ? random_value(5) + 1 : 1;
|
||||
|
||||
template <class T>
|
||||
void fill(T& x, std::size_t len) {
|
||||
key_type* key_ptr = 0;
|
||||
mapped_type* mapped_ptr = 0;
|
||||
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
key_type key = generate(key_ptr, type_);
|
||||
|
||||
std::size_t count = type_ == generate_collisions ?
|
||||
random_value(5) + 1 : 1;
|
||||
|
||||
for(std::size_t j = 0; j < count; ++j) {
|
||||
x.push_back(std::pair<key_type const, mapped_type>(
|
||||
key, generate(mapped_ptr, type_)));
|
||||
}
|
||||
for (std::size_t j = 0; j < count; ++j) {
|
||||
x.push_back(std::pair<key_type const, mapped_type>(
|
||||
key, generate(mapped_ptr, type_)));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template <class X>
|
||||
struct unordered_generator_base
|
||||
: public boost::detail::if_true<
|
||||
test::is_set<X>::value
|
||||
>::BOOST_NESTED_TEMPLATE then<
|
||||
test::unordered_generator_set<X>,
|
||||
test::unordered_generator_map<X>
|
||||
>
|
||||
template <class X>
|
||||
struct unordered_generator_base
|
||||
: public boost::detail::if_true<test::is_set<X>::value>::
|
||||
BOOST_NESTED_TEMPLATE then<test::unordered_generator_set<X>,
|
||||
test::unordered_generator_map<X> >
|
||||
{
|
||||
};
|
||||
|
||||
template <class X>
|
||||
struct unordered_generator : public unordered_generator_base<X>::type
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME unordered_generator_base<X>::type base;
|
||||
|
||||
unordered_generator(random_generator const& type = default_generator)
|
||||
: base(type)
|
||||
{
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template <class X>
|
||||
struct unordered_generator : public unordered_generator_base<X>::type
|
||||
template <class X>
|
||||
struct random_values : public test::list<BOOST_DEDUCED_TYPENAME X::value_type>
|
||||
{
|
||||
random_values() {}
|
||||
|
||||
explicit random_values(std::size_t count,
|
||||
test::random_generator const& generator = test::default_generator)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME unordered_generator_base<X>::type base;
|
||||
fill(count, generator);
|
||||
}
|
||||
|
||||
unordered_generator(random_generator const& type = default_generator)
|
||||
: base(type) {}
|
||||
};
|
||||
|
||||
template <class X>
|
||||
struct random_values
|
||||
: public test::list<BOOST_DEDUCED_TYPENAME X::value_type>
|
||||
void fill(std::size_t count,
|
||||
test::random_generator const& generator = test::default_generator)
|
||||
{
|
||||
random_values() {}
|
||||
|
||||
explicit random_values(std::size_t count, test::random_generator const& generator =
|
||||
test::default_generator)
|
||||
{
|
||||
fill(count, generator);
|
||||
}
|
||||
|
||||
void fill(std::size_t count, test::random_generator const& generator =
|
||||
test::default_generator)
|
||||
{
|
||||
test::unordered_generator<X> gen(generator);
|
||||
gen.fill(*this, count);
|
||||
}
|
||||
};
|
||||
test::unordered_generator<X> gen(generator);
|
||||
gen.fill(*this, count);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+27
-26
@@ -6,37 +6,38 @@
|
||||
#if !defined(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 <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;
|
||||
values_type values_;
|
||||
unsigned int allocations_;
|
||||
public:
|
||||
void store(X const& x, unsigned int allocations = 0) {
|
||||
DISABLE_EXCEPTIONS;
|
||||
values_.clear();
|
||||
values_.insert(x.cbegin(), x.cend());
|
||||
allocations_ = allocations;
|
||||
}
|
||||
typedef test::list<BOOST_DEDUCED_TYPENAME X::value_type> values_type;
|
||||
values_type values_;
|
||||
unsigned int allocations_;
|
||||
|
||||
void test(X const& x, unsigned int allocations = 0) const {
|
||||
if(!(x.size() == values_.size() &&
|
||||
test::equal(x.cbegin(), x.cend(), values_.begin(),
|
||||
test::equivalent)))
|
||||
BOOST_ERROR("Strong exception safety failure.");
|
||||
if(allocations != allocations_)
|
||||
BOOST_ERROR("Strong exception failure: extra allocations.");
|
||||
}
|
||||
};
|
||||
public:
|
||||
void store(X const& x, unsigned int allocations = 0)
|
||||
{
|
||||
DISABLE_EXCEPTIONS;
|
||||
values_.clear();
|
||||
values_.insert(x.cbegin(), x.cend());
|
||||
allocations_ = allocations;
|
||||
}
|
||||
|
||||
void test(X const& x, unsigned int allocations = 0) const
|
||||
{
|
||||
if (!(x.size() == values_.size() &&
|
||||
test::equal(
|
||||
x.cbegin(), x.cend(), values_.begin(), test::equivalent)))
|
||||
BOOST_ERROR("Strong exception safety failure.");
|
||||
if (allocations != allocations_)
|
||||
BOOST_ERROR("Strong exception failure: extra allocations.");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+86
-84
@@ -11,113 +11,115 @@
|
||||
#include <boost/preprocessor/stringize.hpp>
|
||||
#include <iostream>
|
||||
|
||||
#define UNORDERED_AUTO_TEST(x) \
|
||||
struct BOOST_PP_CAT(x, _type) : public ::test::registered_test_base { \
|
||||
BOOST_PP_CAT(x, _type)() \
|
||||
: ::test::registered_test_base(BOOST_PP_STRINGIZE(x)) \
|
||||
{ \
|
||||
::test::test_list::add_test(this); \
|
||||
} \
|
||||
void run(); \
|
||||
}; \
|
||||
BOOST_PP_CAT(x, _type) x; \
|
||||
void BOOST_PP_CAT(x, _type)::run() \
|
||||
#define UNORDERED_AUTO_TEST(x) \
|
||||
struct BOOST_PP_CAT(x, _type) : public ::test::registered_test_base \
|
||||
{ \
|
||||
BOOST_PP_CAT(x, _type) \
|
||||
() : ::test::registered_test_base(BOOST_PP_STRINGIZE(x)) \
|
||||
{ \
|
||||
::test::test_list::add_test(this); \
|
||||
} \
|
||||
void run(); \
|
||||
}; \
|
||||
BOOST_PP_CAT(x, _type) x; \
|
||||
void BOOST_PP_CAT(x, _type)::run()
|
||||
|
||||
#define RUN_TESTS() int main(int, char**) \
|
||||
{ \
|
||||
::test::write_compiler_info(); \
|
||||
::test::test_list::run_tests(); \
|
||||
return boost::report_errors(); \
|
||||
#define RUN_TESTS() \
|
||||
int main(int, char**) \
|
||||
{ \
|
||||
::test::write_compiler_info(); \
|
||||
::test::test_list::run_tests(); \
|
||||
return boost::report_errors(); \
|
||||
}
|
||||
|
||||
namespace test {
|
||||
struct registered_test_base {
|
||||
registered_test_base* next;
|
||||
char const* name;
|
||||
explicit registered_test_base(char const* n) : name(n) {}
|
||||
virtual void run() = 0;
|
||||
virtual ~registered_test_base() {}
|
||||
};
|
||||
struct registered_test_base
|
||||
{
|
||||
registered_test_base* next;
|
||||
char const* name;
|
||||
explicit registered_test_base(char const* n) : name(n) {}
|
||||
virtual void run() = 0;
|
||||
virtual ~registered_test_base() {}
|
||||
};
|
||||
|
||||
namespace test_list {
|
||||
static inline registered_test_base*& first() {
|
||||
static registered_test_base* ptr = 0;
|
||||
return ptr;
|
||||
}
|
||||
namespace test_list {
|
||||
static inline registered_test_base*& first()
|
||||
{
|
||||
static registered_test_base* ptr = 0;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static inline registered_test_base*& last() {
|
||||
static registered_test_base* ptr = 0;
|
||||
return ptr;
|
||||
}
|
||||
static inline registered_test_base*& last()
|
||||
{
|
||||
static registered_test_base* ptr = 0;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static inline void add_test(registered_test_base* test) {
|
||||
if(last()) {
|
||||
last()->next = test;
|
||||
}
|
||||
else {
|
||||
first() = test;
|
||||
}
|
||||
static inline void add_test(registered_test_base* test)
|
||||
{
|
||||
if (last()) {
|
||||
last()->next = test;
|
||||
} else {
|
||||
first() = test;
|
||||
}
|
||||
|
||||
last() = test;
|
||||
}
|
||||
last() = test;
|
||||
}
|
||||
|
||||
static inline void run_tests() {
|
||||
for(registered_test_base* i = first(); i; i = i->next) {
|
||||
std::cout<<"Running "<<i->name<<"\n"<<std::flush;
|
||||
i->run();
|
||||
std::cerr<<std::flush;
|
||||
std::cout<<std::flush;
|
||||
}
|
||||
}
|
||||
static inline void run_tests()
|
||||
{
|
||||
for (registered_test_base* i = first(); i; i = i->next) {
|
||||
std::cout << "Running " << i->name << "\n" << std::flush;
|
||||
i->run();
|
||||
std::cerr << std::flush;
|
||||
std::cout << std::flush;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void write_compiler_info() {
|
||||
inline void write_compiler_info()
|
||||
{
|
||||
#if defined(BOOST_GCC_CXX11)
|
||||
char const* cpp11 = "true";
|
||||
char const* cpp11 = "true";
|
||||
#else
|
||||
char const* cpp11 = "false";
|
||||
char const* cpp11 = "false";
|
||||
#endif
|
||||
|
||||
std::cout
|
||||
<< "Compiler: " << BOOST_COMPILER << "\n"
|
||||
<< "Library: " << BOOST_STDLIB << "\n"
|
||||
<< "C++11: " << cpp11 << "\n"
|
||||
<< "\n"
|
||||
<< std::flush;
|
||||
}
|
||||
std::cout << "Compiler: " << BOOST_COMPILER << "\n"
|
||||
<< "Library: " << BOOST_STDLIB << "\n"
|
||||
<< "C++11: " << cpp11 << "\n"
|
||||
<< "\n"
|
||||
<< 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/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)
|
||||
#define UNORDERED_TEST(name, parameters) \
|
||||
BOOST_PP_SEQ_FOR_EACH_PRODUCT(UNORDERED_TEST_OP, \
|
||||
((name))((1)) parameters) \
|
||||
#define UNORDERED_TEST(name, parameters) \
|
||||
BOOST_PP_SEQ_FOR_EACH_PRODUCT(UNORDERED_TEST_OP, ((name))((1))parameters)
|
||||
|
||||
#define UNORDERED_TEST_REPEAT(name, n, parameters) \
|
||||
BOOST_PP_SEQ_FOR_EACH_PRODUCT(UNORDERED_TEST_OP, \
|
||||
((name))((n)) parameters) \
|
||||
#define UNORDERED_TEST_REPEAT(name, n, parameters) \
|
||||
BOOST_PP_SEQ_FOR_EACH_PRODUCT(UNORDERED_TEST_OP, ((name))((n))parameters)
|
||||
|
||||
#define UNORDERED_TEST_OP(r, product) \
|
||||
UNORDERED_TEST_OP2( \
|
||||
BOOST_PP_SEQ_ELEM(0, product), \
|
||||
BOOST_PP_SEQ_ELEM(1, product), \
|
||||
BOOST_PP_SEQ_TAIL(BOOST_PP_SEQ_TAIL(product))) \
|
||||
#define UNORDERED_TEST_OP(r, product) \
|
||||
UNORDERED_TEST_OP2(BOOST_PP_SEQ_ELEM(0, product), \
|
||||
BOOST_PP_SEQ_ELEM(1, product), \
|
||||
BOOST_PP_SEQ_TAIL(BOOST_PP_SEQ_TAIL(product)))
|
||||
|
||||
#define UNORDERED_TEST_OP2(name, n, params) \
|
||||
UNORDERED_AUTO_TEST( \
|
||||
BOOST_PP_SEQ_FOLD_LEFT(UNORDERED_TEST_OP_JOIN, name, params)) \
|
||||
{ \
|
||||
for (int i = 0; i < n; ++i) \
|
||||
name BOOST_PP_SEQ_TO_TUPLE(params); \
|
||||
} \
|
||||
|
||||
#define UNORDERED_TEST_OP_JOIN(s, state, elem) \
|
||||
BOOST_PP_CAT(state, BOOST_PP_CAT(_, elem)) \
|
||||
#define UNORDERED_TEST_OP2(name, n, params) \
|
||||
UNORDERED_AUTO_TEST( \
|
||||
BOOST_PP_SEQ_FOLD_LEFT(UNORDERED_TEST_OP_JOIN, name, params)) \
|
||||
{ \
|
||||
for (int i = 0; i < n; ++i) \
|
||||
name BOOST_PP_SEQ_TO_TUPLE(params); \
|
||||
}
|
||||
|
||||
#define UNORDERED_TEST_OP_JOIN(s, state, elem) \
|
||||
BOOST_PP_CAT(state, BOOST_PP_CAT(_, elem))
|
||||
|
||||
#endif
|
||||
|
||||
+118
-138
@@ -9,159 +9,139 @@
|
||||
#if !defined(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 "./metafunctions.hpp"
|
||||
#include "./helpers.hpp"
|
||||
#include "./equivalent.hpp"
|
||||
#include "./helpers.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>
|
||||
struct equals_to_compare
|
||||
{
|
||||
typedef std::less<BOOST_DEDUCED_TYPENAME X::first_argument_type>
|
||||
type;
|
||||
};
|
||||
typedef std::less<BOOST_DEDUCED_TYPENAME X::first_argument_type> type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct equals_to_compare<test::equal_to>
|
||||
{
|
||||
typedef test::less type;
|
||||
};
|
||||
template <> struct equals_to_compare<test::equal_to>
|
||||
{
|
||||
typedef test::less type;
|
||||
};
|
||||
|
||||
template <class X1, class X2>
|
||||
void compare_range(X1 const& x1, X2 const& x2)
|
||||
template <class X1, class X2> void compare_range(X1 const& x1, X2 const& x2)
|
||||
{
|
||||
typedef test::list<BOOST_DEDUCED_TYPENAME X1::value_type> value_list;
|
||||
value_list values1(x1.begin(), x1.end());
|
||||
value_list values2(x2.begin(), x2.end());
|
||||
values1.sort();
|
||||
values2.sort();
|
||||
BOOST_TEST(values1.size() == values2.size() &&
|
||||
test::equal(values1.begin(), values1.end(), values2.begin(),
|
||||
test::equivalent));
|
||||
}
|
||||
|
||||
template <class X1, class X2, class T>
|
||||
void compare_pairs(X1 const& x1, X2 const& x2, T*)
|
||||
{
|
||||
test::list<T> values1(x1.first, x1.second);
|
||||
test::list<T> values2(x2.first, x2.second);
|
||||
values1.sort();
|
||||
values2.sort();
|
||||
BOOST_TEST(values1.size() == values2.size() &&
|
||||
test::equal(values1.begin(), values1.end(), values2.begin(),
|
||||
test::equivalent));
|
||||
}
|
||||
|
||||
template <typename X, bool is_set = test::is_set<X>::value,
|
||||
bool has_unique_keys = test::has_unique_keys<X>::value>
|
||||
struct ordered_base;
|
||||
|
||||
template <typename X> struct ordered_base<X, true, true>
|
||||
{
|
||||
typedef std::set<BOOST_DEDUCED_TYPENAME X::value_type,
|
||||
BOOST_DEDUCED_TYPENAME
|
||||
equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename X> struct ordered_base<X, true, false>
|
||||
{
|
||||
typedef std::multiset<BOOST_DEDUCED_TYPENAME X::value_type,
|
||||
BOOST_DEDUCED_TYPENAME
|
||||
equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename X> struct ordered_base<X, false, true>
|
||||
{
|
||||
typedef std::map<BOOST_DEDUCED_TYPENAME X::key_type,
|
||||
BOOST_DEDUCED_TYPENAME X::mapped_type,
|
||||
BOOST_DEDUCED_TYPENAME
|
||||
equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename X> struct ordered_base<X, false, false>
|
||||
{
|
||||
typedef std::multimap<BOOST_DEDUCED_TYPENAME X::key_type,
|
||||
BOOST_DEDUCED_TYPENAME X::mapped_type,
|
||||
BOOST_DEDUCED_TYPENAME
|
||||
equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
|
||||
type;
|
||||
};
|
||||
|
||||
template <class X> class ordered : public ordered_base<X>::type
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME ordered_base<X>::type base;
|
||||
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME base::key_compare key_compare;
|
||||
|
||||
ordered() : base() {}
|
||||
|
||||
explicit ordered(key_compare const& kc) : base(kc) {}
|
||||
|
||||
void compare(X const& x) { compare_range(x, *this); }
|
||||
|
||||
void compare_key(
|
||||
X const& x, BOOST_DEDUCED_TYPENAME X::value_type const& val)
|
||||
{
|
||||
typedef test::list<BOOST_DEDUCED_TYPENAME X1::value_type> value_list;
|
||||
value_list values1(x1.begin(), x1.end());
|
||||
value_list values2(x2.begin(), x2.end());
|
||||
values1.sort();
|
||||
values2.sort();
|
||||
BOOST_TEST(values1.size() == values2.size() &&
|
||||
test::equal(values1.begin(), values1.end(), values2.begin(),
|
||||
test::equivalent));
|
||||
compare_pairs(x.equal_range(get_key<X>(val)),
|
||||
this->equal_range(get_key<X>(val)),
|
||||
(BOOST_DEDUCED_TYPENAME X::value_type*)0);
|
||||
}
|
||||
|
||||
template <class X1, class X2, class T>
|
||||
void compare_pairs(X1 const& x1, X2 const& x2, T*)
|
||||
template <class It> void insert_range(It b, It e)
|
||||
{
|
||||
test::list<T> values1(x1.first, x1.second);
|
||||
test::list<T> values2(x2.first, x2.second);
|
||||
values1.sort();
|
||||
values2.sort();
|
||||
BOOST_TEST(values1.size() == values2.size() &&
|
||||
test::equal(values1.begin(), values1.end(),
|
||||
values2.begin(), test::equivalent));
|
||||
}
|
||||
|
||||
template <typename X,
|
||||
bool is_set = test::is_set<X>::value,
|
||||
bool has_unique_keys = test::has_unique_keys<X>::value>
|
||||
struct ordered_base;
|
||||
|
||||
template <typename X>
|
||||
struct ordered_base<X, true, true>
|
||||
{
|
||||
typedef std::set<
|
||||
BOOST_DEDUCED_TYPENAME X::value_type,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename X>
|
||||
struct ordered_base<X, true, false>
|
||||
{
|
||||
typedef std::multiset<
|
||||
BOOST_DEDUCED_TYPENAME X::value_type,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename X>
|
||||
struct ordered_base<X, false, true>
|
||||
{
|
||||
typedef std::map<
|
||||
BOOST_DEDUCED_TYPENAME X::key_type,
|
||||
BOOST_DEDUCED_TYPENAME X::mapped_type,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
|
||||
type;
|
||||
};
|
||||
|
||||
template <typename X>
|
||||
struct ordered_base<X, false, false>
|
||||
{
|
||||
typedef std::multimap<
|
||||
BOOST_DEDUCED_TYPENAME X::key_type,
|
||||
BOOST_DEDUCED_TYPENAME X::mapped_type,
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<BOOST_DEDUCED_TYPENAME X::key_equal>::type>
|
||||
type;
|
||||
};
|
||||
|
||||
template <class X>
|
||||
class ordered : public ordered_base<X>::type
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME ordered_base<X>::type base;
|
||||
public:
|
||||
typedef BOOST_DEDUCED_TYPENAME base::key_compare key_compare;
|
||||
|
||||
ordered()
|
||||
: base()
|
||||
{}
|
||||
|
||||
explicit ordered(key_compare const& kc)
|
||||
: base(kc)
|
||||
{}
|
||||
|
||||
void compare(X const& x)
|
||||
{
|
||||
compare_range(x, *this);
|
||||
while (b != e) {
|
||||
this->insert(*b);
|
||||
++b;
|
||||
}
|
||||
|
||||
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)),
|
||||
(BOOST_DEDUCED_TYPENAME X::value_type*) 0);
|
||||
}
|
||||
|
||||
template <class It>
|
||||
void insert_range(It b, It e) {
|
||||
while(b != e) {
|
||||
this->insert(*b);
|
||||
++b;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class Equals>
|
||||
BOOST_DEDUCED_TYPENAME
|
||||
equals_to_compare<Equals>::type create_compare(Equals const&)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<Equals>::type x;
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
template <class X>
|
||||
ordered<X> create_ordered(X const& container)
|
||||
{
|
||||
return ordered<X>(create_compare(container.key_eq()));
|
||||
}
|
||||
template <class Equals>
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<Equals>::type create_compare(
|
||||
Equals const&)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME equals_to_compare<Equals>::type x;
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class X1, class X2>
|
||||
void check_container(X1 const& container, X2 const& values)
|
||||
{
|
||||
ordered<X1> tracker = create_ordered(container);
|
||||
tracker.insert_range(values.begin(), values.end());
|
||||
tracker.compare(container);
|
||||
}
|
||||
template <class X> ordered<X> create_ordered(X const& container)
|
||||
{
|
||||
return ordered<X>(create_compare(container.key_eq()));
|
||||
}
|
||||
|
||||
template <class X1, class X2>
|
||||
void check_container(X1 const& container, X2 const& values)
|
||||
{
|
||||
ordered<X1> tracker = create_ordered(container);
|
||||
tracker.insert_range(values.begin(), values.end());
|
||||
tracker.compare(container);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+276
-253
@@ -13,309 +13,332 @@
|
||||
#include "../helpers/fwd.hpp"
|
||||
#include "../helpers/memory.hpp"
|
||||
|
||||
namespace test
|
||||
namespace test {
|
||||
struct allocator_false
|
||||
{
|
||||
struct allocator_false
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
is_select_on_copy = 0,
|
||||
is_propagate_on_swap = 0,
|
||||
is_propagate_on_assign = 0,
|
||||
is_propagate_on_move = 0,
|
||||
cxx11_construct = 0
|
||||
is_select_on_copy = 0,
|
||||
is_propagate_on_swap = 0,
|
||||
is_propagate_on_assign = 0,
|
||||
is_propagate_on_move = 0,
|
||||
cxx11_construct = 0
|
||||
};
|
||||
};
|
||||
|
||||
struct allocator_flags_all
|
||||
{
|
||||
enum
|
||||
{
|
||||
is_select_on_copy = 1,
|
||||
is_propagate_on_swap = 1,
|
||||
is_propagate_on_assign = 1,
|
||||
is_propagate_on_move = 1,
|
||||
cxx11_construct = 1
|
||||
};
|
||||
};
|
||||
|
||||
struct select_copy : allocator_false
|
||||
{
|
||||
enum
|
||||
{
|
||||
is_select_on_copy = 1
|
||||
};
|
||||
};
|
||||
struct propagate_swap : allocator_false
|
||||
{
|
||||
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
|
||||
{
|
||||
enum
|
||||
{
|
||||
value = Flag::is_propagate_on_swap
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
struct allocator_flags_all
|
||||
template <typename Flag> struct assign_allocator_base
|
||||
{
|
||||
struct propagate_on_container_copy_assignment
|
||||
{
|
||||
enum {
|
||||
is_select_on_copy = 1,
|
||||
is_propagate_on_swap = 1,
|
||||
is_propagate_on_assign = 1,
|
||||
is_propagate_on_move = 1,
|
||||
cxx11_construct = 1
|
||||
enum
|
||||
{
|
||||
value = Flag::is_propagate_on_assign
|
||||
};
|
||||
};
|
||||
|
||||
struct select_copy : allocator_false
|
||||
{ enum { is_select_on_copy = 1 }; };
|
||||
struct propagate_swap : allocator_false
|
||||
{ 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
|
||||
template <typename Flag> struct move_allocator_base
|
||||
{
|
||||
struct propagate_on_container_move_assignment
|
||||
{
|
||||
struct propagate_on_container_swap {
|
||||
enum { value = Flag::is_propagate_on_swap }; };
|
||||
enum
|
||||
{
|
||||
value = Flag::is_propagate_on_move
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
template <typename Flag>
|
||||
struct assign_allocator_base
|
||||
{
|
||||
struct propagate_on_container_copy_assignment {
|
||||
enum { value = Flag::is_propagate_on_assign }; };
|
||||
};
|
||||
namespace {
|
||||
// boostinspect:nounnamed
|
||||
bool force_equal_allocator_value = false;
|
||||
}
|
||||
|
||||
template <typename Flag>
|
||||
struct move_allocator_base
|
||||
{
|
||||
struct propagate_on_container_move_assignment {
|
||||
enum { value = Flag::is_propagate_on_move }; };
|
||||
};
|
||||
struct force_equal_allocator
|
||||
{
|
||||
bool old_value_;
|
||||
|
||||
namespace
|
||||
explicit force_equal_allocator(bool value)
|
||||
: old_value_(force_equal_allocator_value)
|
||||
{
|
||||
// boostinspect:nounnamed
|
||||
bool force_equal_allocator_value = false;
|
||||
force_equal_allocator_value = value;
|
||||
}
|
||||
|
||||
struct force_equal_allocator
|
||||
~force_equal_allocator() { force_equal_allocator_value = old_value_; }
|
||||
};
|
||||
|
||||
template <typename T> struct cxx11_allocator_base
|
||||
{
|
||||
int tag_;
|
||||
int selected_;
|
||||
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T value_type;
|
||||
|
||||
explicit cxx11_allocator_base(int t) : tag_(t), selected_(0)
|
||||
{
|
||||
bool old_value_;
|
||||
|
||||
explicit force_equal_allocator(bool value)
|
||||
: old_value_(force_equal_allocator_value)
|
||||
{ force_equal_allocator_value = value; }
|
||||
|
||||
~force_equal_allocator()
|
||||
{ force_equal_allocator_value = old_value_; }
|
||||
};
|
||||
detail::tracker.allocator_ref();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct cxx11_allocator_base
|
||||
template <typename Y>
|
||||
cxx11_allocator_base(cxx11_allocator_base<Y> const& x)
|
||||
: tag_(x.tag_), selected_(x.selected_)
|
||||
{
|
||||
int tag_;
|
||||
int selected_;
|
||||
detail::tracker.allocator_ref();
|
||||
}
|
||||
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef T* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T value_type;
|
||||
cxx11_allocator_base(cxx11_allocator_base const& x)
|
||||
: tag_(x.tag_), selected_(x.selected_)
|
||||
{
|
||||
detail::tracker.allocator_ref();
|
||||
}
|
||||
|
||||
explicit cxx11_allocator_base(int t)
|
||||
: tag_(t), selected_(0)
|
||||
{
|
||||
detail::tracker.allocator_ref();
|
||||
}
|
||||
|
||||
template <typename Y> cxx11_allocator_base(
|
||||
cxx11_allocator_base<Y> const& x)
|
||||
: tag_(x.tag_), selected_(x.selected_)
|
||||
{
|
||||
detail::tracker.allocator_ref();
|
||||
}
|
||||
~cxx11_allocator_base() { detail::tracker.allocator_unref(); }
|
||||
|
||||
cxx11_allocator_base(cxx11_allocator_base const& x)
|
||||
: tag_(x.tag_), selected_(x.selected_)
|
||||
{
|
||||
detail::tracker.allocator_ref();
|
||||
}
|
||||
pointer address(reference r) { return pointer(&r); }
|
||||
|
||||
~cxx11_allocator_base()
|
||||
{
|
||||
detail::tracker.allocator_unref();
|
||||
}
|
||||
const_pointer address(const_reference r) { return const_pointer(&r); }
|
||||
|
||||
pointer address(reference r)
|
||||
{
|
||||
return pointer(&r);
|
||||
}
|
||||
pointer allocate(size_type n)
|
||||
{
|
||||
pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
|
||||
detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
const_pointer address(const_reference r)
|
||||
{
|
||||
return const_pointer(&r);
|
||||
}
|
||||
pointer allocate(size_type n, void const*)
|
||||
{
|
||||
pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
|
||||
detail::tracker.track_allocate((void*)ptr, n, sizeof(T), tag_);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
pointer allocate(size_type n) {
|
||||
pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
|
||||
detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
|
||||
return ptr;
|
||||
}
|
||||
void deallocate(pointer p, size_type n)
|
||||
{
|
||||
// Only checking tags when propagating swap.
|
||||
// Note that tags will be tested
|
||||
// properly in the normal allocator.
|
||||
detail::tracker.track_deallocate(
|
||||
(void*)p, n, sizeof(T), tag_, !force_equal_allocator_value);
|
||||
::operator delete((void*)p);
|
||||
}
|
||||
|
||||
pointer allocate(size_type n, void const*)
|
||||
{
|
||||
pointer ptr(static_cast<T*>(::operator new(n * sizeof(T))));
|
||||
detail::tracker.track_allocate((void*) ptr, n, sizeof(T), tag_);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void deallocate(pointer p, size_type n)
|
||||
{
|
||||
// Only checking tags when propagating swap.
|
||||
// Note that tags will be tested
|
||||
// properly in the normal allocator.
|
||||
detail::tracker.track_deallocate((void*) p, n, sizeof(T), tag_,
|
||||
!force_equal_allocator_value);
|
||||
::operator delete((void*) p);
|
||||
}
|
||||
|
||||
void construct(T* p, T const& t) {
|
||||
detail::tracker.track_construct((void*) p, sizeof(T), tag_);
|
||||
new(p) T(t);
|
||||
}
|
||||
void construct(T* p, T const& t)
|
||||
{
|
||||
detail::tracker.track_construct((void*)p, sizeof(T), tag_);
|
||||
new (p) T(t);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
template<typename... 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)...);
|
||||
}
|
||||
template <typename... 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)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
void destroy(T* p) {
|
||||
detail::tracker.track_destroy((void*) p, sizeof(T), tag_);
|
||||
p->~T();
|
||||
}
|
||||
|
||||
size_type max_size() const {
|
||||
return (std::numeric_limits<size_type>::max)();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Flags = propagate_swap,
|
||||
typename Enable = void>
|
||||
struct cxx11_allocator;
|
||||
|
||||
template <typename T, typename Flags>
|
||||
struct cxx11_allocator<
|
||||
T, Flags,
|
||||
typename boost::disable_if_c<Flags::is_select_on_copy>::type
|
||||
> : public cxx11_allocator_base<T>,
|
||||
public swap_allocator_base<Flags>,
|
||||
public assign_allocator_base<Flags>,
|
||||
public move_allocator_base<Flags>,
|
||||
Flags
|
||||
void destroy(T* p)
|
||||
{
|
||||
detail::tracker.track_destroy((void*)p, sizeof(T), tag_);
|
||||
p->~T();
|
||||
}
|
||||
|
||||
size_type max_size() const
|
||||
{
|
||||
return (std::numeric_limits<size_type>::max)();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Flags = propagate_swap, typename Enable = void>
|
||||
struct cxx11_allocator;
|
||||
|
||||
template <typename T, typename Flags>
|
||||
struct cxx11_allocator<T, Flags,
|
||||
typename boost::disable_if_c<Flags::is_select_on_copy>::type>
|
||||
: public cxx11_allocator_base<T>,
|
||||
public swap_allocator_base<Flags>,
|
||||
public assign_allocator_base<Flags>,
|
||||
public move_allocator_base<Flags>,
|
||||
Flags
|
||||
{
|
||||
#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 402000)
|
||||
template <typename U> struct rebind {
|
||||
typedef cxx11_allocator<U, Flags> other;
|
||||
};
|
||||
template <typename U> struct rebind
|
||||
{
|
||||
typedef cxx11_allocator<U, Flags> other;
|
||||
};
|
||||
#endif
|
||||
|
||||
explicit cxx11_allocator(int t = 0)
|
||||
: cxx11_allocator_base<T>(t)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Y> cxx11_allocator(
|
||||
cxx11_allocator<Y, Flags> const& x)
|
||||
: cxx11_allocator_base<T>(x)
|
||||
{
|
||||
}
|
||||
explicit cxx11_allocator(int t = 0) : cxx11_allocator_base<T>(t) {}
|
||||
|
||||
cxx11_allocator(cxx11_allocator const& x)
|
||||
: cxx11_allocator_base<T>(x)
|
||||
{
|
||||
}
|
||||
|
||||
// When not propagating swap, allocators are always equal
|
||||
// to avoid undefined behaviour.
|
||||
bool operator==(cxx11_allocator const& x) const
|
||||
{
|
||||
return force_equal_allocator_value || (this->tag_ == x.tag_);
|
||||
}
|
||||
|
||||
bool operator!=(cxx11_allocator const& x) const
|
||||
{
|
||||
return !(*this == x);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Flags>
|
||||
struct cxx11_allocator<
|
||||
T, Flags,
|
||||
typename boost::enable_if_c<Flags::is_select_on_copy>::type
|
||||
> : public cxx11_allocator_base<T>,
|
||||
public swap_allocator_base<Flags>,
|
||||
public assign_allocator_base<Flags>,
|
||||
public move_allocator_base<Flags>,
|
||||
Flags
|
||||
template <typename Y>
|
||||
cxx11_allocator(cxx11_allocator<Y, Flags> const& x)
|
||||
: cxx11_allocator_base<T>(x)
|
||||
{
|
||||
cxx11_allocator select_on_container_copy_construction() const
|
||||
{
|
||||
cxx11_allocator tmp(*this);
|
||||
++tmp.selected_;
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
|
||||
cxx11_allocator(cxx11_allocator const& x) : cxx11_allocator_base<T>(x) {}
|
||||
|
||||
// When not propagating swap, allocators are always equal
|
||||
// to avoid undefined behaviour.
|
||||
bool operator==(cxx11_allocator const& x) const
|
||||
{
|
||||
return force_equal_allocator_value || (this->tag_ == x.tag_);
|
||||
}
|
||||
|
||||
bool operator!=(cxx11_allocator const& x) const { return !(*this == x); }
|
||||
};
|
||||
|
||||
template <typename T, typename Flags>
|
||||
struct cxx11_allocator<T, Flags,
|
||||
typename boost::enable_if_c<Flags::is_select_on_copy>::type>
|
||||
: public cxx11_allocator_base<T>,
|
||||
public swap_allocator_base<Flags>,
|
||||
public assign_allocator_base<Flags>,
|
||||
public move_allocator_base<Flags>,
|
||||
Flags
|
||||
{
|
||||
cxx11_allocator select_on_container_copy_construction() const
|
||||
{
|
||||
cxx11_allocator tmp(*this);
|
||||
++tmp.selected_;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_GCC_VERSION, < 402000)
|
||||
template <typename U> struct rebind {
|
||||
typedef cxx11_allocator<U, Flags> other;
|
||||
};
|
||||
template <typename U> struct rebind
|
||||
{
|
||||
typedef cxx11_allocator<U, Flags> other;
|
||||
};
|
||||
#endif
|
||||
|
||||
explicit cxx11_allocator(int t = 0)
|
||||
: cxx11_allocator_base<T>(t)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Y> cxx11_allocator(
|
||||
cxx11_allocator<Y, Flags> const& x)
|
||||
: cxx11_allocator_base<T>(x)
|
||||
{
|
||||
}
|
||||
explicit cxx11_allocator(int t = 0) : cxx11_allocator_base<T>(t) {}
|
||||
|
||||
cxx11_allocator(cxx11_allocator const& x)
|
||||
: cxx11_allocator_base<T>(x)
|
||||
{
|
||||
}
|
||||
|
||||
// When not propagating swap, allocators are always equal
|
||||
// to avoid undefined behaviour.
|
||||
bool operator==(cxx11_allocator const& x) const
|
||||
{
|
||||
return force_equal_allocator_value || (this->tag_ == x.tag_);
|
||||
}
|
||||
|
||||
bool operator!=(cxx11_allocator const& x) const
|
||||
{
|
||||
return !(*this == x);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Flags>
|
||||
bool equivalent_impl(
|
||||
cxx11_allocator<T, Flags> const& x,
|
||||
cxx11_allocator<T, Flags> const& y,
|
||||
test::derived_type)
|
||||
template <typename Y>
|
||||
cxx11_allocator(cxx11_allocator<Y, Flags> const& x)
|
||||
: cxx11_allocator_base<T>(x)
|
||||
{
|
||||
return x.tag_ == y.tag_;
|
||||
}
|
||||
|
||||
// Function to check how many times an allocator has been selected,
|
||||
// return 0 for other allocators.
|
||||
cxx11_allocator(cxx11_allocator const& x) : cxx11_allocator_base<T>(x) {}
|
||||
|
||||
struct convert_from_anything
|
||||
// When not propagating swap, allocators are always equal
|
||||
// to avoid undefined behaviour.
|
||||
bool operator==(cxx11_allocator const& x) const
|
||||
{
|
||||
template <typename T>
|
||||
convert_from_anything(T const&) {}
|
||||
};
|
||||
|
||||
inline int selected_count(convert_from_anything)
|
||||
{
|
||||
return 0;
|
||||
return force_equal_allocator_value || (this->tag_ == x.tag_);
|
||||
}
|
||||
|
||||
template <typename T, typename Flags>
|
||||
int selected_count(cxx11_allocator<T, Flags> const& x)
|
||||
{
|
||||
return x.selected_;
|
||||
}
|
||||
bool operator!=(cxx11_allocator const& x) const { return !(*this == x); }
|
||||
};
|
||||
|
||||
template <typename T, typename Flags>
|
||||
bool equivalent_impl(cxx11_allocator<T, Flags> const& x,
|
||||
cxx11_allocator<T, Flags> const& y, test::derived_type)
|
||||
{
|
||||
return x.tag_ == y.tag_;
|
||||
}
|
||||
|
||||
// Function to check how many times an allocator has been selected,
|
||||
// return 0 for other allocators.
|
||||
|
||||
struct convert_from_anything
|
||||
{
|
||||
template <typename T> convert_from_anything(T const&) {}
|
||||
};
|
||||
|
||||
inline int selected_count(convert_from_anything) { return 0; }
|
||||
|
||||
template <typename T, typename Flags>
|
||||
int selected_count(cxx11_allocator<T, Flags> const& x)
|
||||
{
|
||||
return x.selected_;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+632
-548
File diff suppressed because it is too large
Load Diff
@@ -6,13 +6,12 @@
|
||||
#if !defined(BOOST_UNORDERED_TEST_OBJECTS_FWD_HEADER)
|
||||
#define BOOST_UNORDERED_TEST_OBJECTS_FWD_HEADER
|
||||
|
||||
namespace test
|
||||
{
|
||||
class object;
|
||||
class hash;
|
||||
class less;
|
||||
class equal_to;
|
||||
template <class T> class allocator;
|
||||
namespace test {
|
||||
class object;
|
||||
class hash;
|
||||
class less;
|
||||
class equal_to;
|
||||
template <class T> class allocator;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+405
-392
@@ -10,13 +10,13 @@
|
||||
#if !defined(BOOST_UNORDERED_OBJECTS_MINIMAL_HEADER)
|
||||
#define BOOST_UNORDERED_OBJECTS_MINIMAL_HEADER
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/move/move.hpp>
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4100) // unreferenced formal parameter
|
||||
#pragma warning(disable : 4100) // unreferenced formal parameter
|
||||
#endif
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1500)
|
||||
@@ -25,480 +25,494 @@
|
||||
#define BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED 0
|
||||
#endif
|
||||
|
||||
namespace test
|
||||
namespace test {
|
||||
namespace minimal {
|
||||
class destructible;
|
||||
class copy_constructible;
|
||||
class copy_constructible_equality_comparable;
|
||||
class default_assignable;
|
||||
class assignable;
|
||||
|
||||
struct ampersand_operator_used
|
||||
{
|
||||
namespace minimal
|
||||
ampersand_operator_used() { BOOST_TEST(false); }
|
||||
};
|
||||
|
||||
template <class T> class hash;
|
||||
template <class T> class equal_to;
|
||||
template <class T> class ptr;
|
||||
template <class T> class const_ptr;
|
||||
template <class T> class allocator;
|
||||
template <class T> class cxx11_allocator;
|
||||
|
||||
struct constructor_param
|
||||
{
|
||||
class destructible;
|
||||
class copy_constructible;
|
||||
class copy_constructible_equality_comparable;
|
||||
class default_assignable;
|
||||
class assignable;
|
||||
operator int() const { return 0; }
|
||||
};
|
||||
|
||||
struct ampersand_operator_used {
|
||||
ampersand_operator_used() { BOOST_TEST(false); }
|
||||
};
|
||||
class destructible
|
||||
{
|
||||
public:
|
||||
destructible(constructor_param const&) {}
|
||||
~destructible() {}
|
||||
void dummy_member() const {}
|
||||
private:
|
||||
destructible(destructible const&);
|
||||
destructible& operator=(destructible const&);
|
||||
};
|
||||
|
||||
template <class T> class hash;
|
||||
template <class T> class equal_to;
|
||||
template <class T> class ptr;
|
||||
template <class T> class const_ptr;
|
||||
template <class T> class allocator;
|
||||
template <class T> class cxx11_allocator;
|
||||
class copy_constructible
|
||||
{
|
||||
public:
|
||||
copy_constructible(constructor_param const&) {}
|
||||
copy_constructible(copy_constructible const&) {}
|
||||
~copy_constructible() {}
|
||||
void dummy_member() const {}
|
||||
private:
|
||||
copy_constructible& operator=(copy_constructible const&);
|
||||
copy_constructible() {}
|
||||
};
|
||||
|
||||
struct constructor_param
|
||||
class copy_constructible_equality_comparable
|
||||
{
|
||||
public:
|
||||
copy_constructible_equality_comparable(constructor_param const&) {}
|
||||
|
||||
copy_constructible_equality_comparable(
|
||||
copy_constructible_equality_comparable const&)
|
||||
{
|
||||
operator int() const { return 0; }
|
||||
};
|
||||
|
||||
class destructible
|
||||
{
|
||||
public:
|
||||
destructible(constructor_param const&) {}
|
||||
~destructible() {}
|
||||
void dummy_member() const {}
|
||||
private:
|
||||
destructible(destructible const&);
|
||||
destructible& operator=(destructible const&);
|
||||
};
|
||||
|
||||
class copy_constructible
|
||||
{
|
||||
public:
|
||||
copy_constructible(constructor_param const&) {}
|
||||
copy_constructible(copy_constructible const&) {}
|
||||
~copy_constructible() {}
|
||||
void dummy_member() const {}
|
||||
private:
|
||||
copy_constructible& operator=(copy_constructible const&);
|
||||
copy_constructible() {}
|
||||
};
|
||||
|
||||
class copy_constructible_equality_comparable
|
||||
{
|
||||
public:
|
||||
copy_constructible_equality_comparable(constructor_param const&) {}
|
||||
|
||||
copy_constructible_equality_comparable(
|
||||
copy_constructible_equality_comparable const&)
|
||||
{
|
||||
}
|
||||
|
||||
~copy_constructible_equality_comparable()
|
||||
{
|
||||
}
|
||||
|
||||
void dummy_member() const {}
|
||||
private:
|
||||
copy_constructible_equality_comparable& operator=(
|
||||
copy_constructible_equality_comparable const&);
|
||||
copy_constructible_equality_comparable() {}
|
||||
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
|
||||
ampersand_operator_used operator&() const {
|
||||
return ampersand_operator_used(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
bool operator==(
|
||||
copy_constructible_equality_comparable,
|
||||
copy_constructible_equality_comparable)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(
|
||||
copy_constructible_equality_comparable,
|
||||
copy_constructible_equality_comparable)
|
||||
~copy_constructible_equality_comparable() {}
|
||||
|
||||
void dummy_member() const {}
|
||||
private:
|
||||
copy_constructible_equality_comparable& operator=(
|
||||
copy_constructible_equality_comparable const&);
|
||||
copy_constructible_equality_comparable() {}
|
||||
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
|
||||
ampersand_operator_used operator&() const
|
||||
{
|
||||
return false;
|
||||
return ampersand_operator_used();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class default_assignable
|
||||
{
|
||||
public:
|
||||
default_assignable(constructor_param const&) {}
|
||||
bool operator==(copy_constructible_equality_comparable,
|
||||
copy_constructible_equality_comparable)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
default_assignable()
|
||||
{
|
||||
}
|
||||
bool operator!=(copy_constructible_equality_comparable,
|
||||
copy_constructible_equality_comparable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
default_assignable(default_assignable const&)
|
||||
{
|
||||
}
|
||||
class default_assignable
|
||||
{
|
||||
public:
|
||||
default_assignable(constructor_param const&) {}
|
||||
|
||||
default_assignable& operator=(default_assignable const&)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
default_assignable() {}
|
||||
|
||||
~default_assignable()
|
||||
{
|
||||
}
|
||||
default_assignable(default_assignable const&) {}
|
||||
|
||||
void dummy_member() const {}
|
||||
default_assignable& operator=(default_assignable const&) { return *this; }
|
||||
|
||||
~default_assignable() {}
|
||||
|
||||
void dummy_member() const {}
|
||||
|
||||
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
|
||||
ampersand_operator_used operator&() const {
|
||||
return ampersand_operator_used(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
class assignable
|
||||
ampersand_operator_used operator&() const
|
||||
{
|
||||
public:
|
||||
assignable(constructor_param const&) {}
|
||||
assignable(assignable const&) {}
|
||||
assignable& operator=(assignable const&) { return *this; }
|
||||
~assignable() {}
|
||||
void dummy_member() const {}
|
||||
private:
|
||||
assignable() {}
|
||||
return ampersand_operator_used();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class assignable
|
||||
{
|
||||
public:
|
||||
assignable(constructor_param const&) {}
|
||||
assignable(assignable const&) {}
|
||||
assignable& operator=(assignable const&) { return *this; }
|
||||
~assignable() {}
|
||||
void dummy_member() const {}
|
||||
private:
|
||||
assignable() {}
|
||||
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
|
||||
ampersand_operator_used operator&() const {
|
||||
return ampersand_operator_used(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
struct movable_init {};
|
||||
|
||||
class movable1
|
||||
ampersand_operator_used operator&() const
|
||||
{
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(movable1)
|
||||
return ampersand_operator_used();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
public:
|
||||
movable1(constructor_param const&) {}
|
||||
movable1() {}
|
||||
explicit movable1(movable_init) {}
|
||||
movable1(BOOST_RV_REF(movable1)) {}
|
||||
movable1& operator=(BOOST_RV_REF(movable1)) { return *this; }
|
||||
~movable1() {}
|
||||
void dummy_member() const {}
|
||||
};
|
||||
struct movable_init
|
||||
{
|
||||
};
|
||||
|
||||
class movable1
|
||||
{
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(movable1)
|
||||
|
||||
public:
|
||||
movable1(constructor_param const&) {}
|
||||
movable1() {}
|
||||
explicit movable1(movable_init) {}
|
||||
movable1(BOOST_RV_REF(movable1)) {}
|
||||
movable1& operator=(BOOST_RV_REF(movable1)) { return *this; }
|
||||
~movable1() {}
|
||||
void dummy_member() const {}
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
class movable2
|
||||
{
|
||||
public:
|
||||
movable2(constructor_param const&) {}
|
||||
explicit movable2(movable_init) {}
|
||||
movable2(movable2&&) {}
|
||||
~movable2() {}
|
||||
movable2& operator=(movable2&&) { return *this; }
|
||||
void dummy_member() const {}
|
||||
private:
|
||||
movable2() {}
|
||||
movable2(movable2 const&);
|
||||
movable2& operator=(movable2 const&);
|
||||
};
|
||||
class movable2
|
||||
{
|
||||
public:
|
||||
movable2(constructor_param const&) {}
|
||||
explicit movable2(movable_init) {}
|
||||
movable2(movable2&&) {}
|
||||
~movable2() {}
|
||||
movable2& operator=(movable2&&) { return *this; }
|
||||
void dummy_member() const {}
|
||||
private:
|
||||
movable2() {}
|
||||
movable2(movable2 const&);
|
||||
movable2& operator=(movable2 const&);
|
||||
};
|
||||
#else
|
||||
typedef movable1 movable2;
|
||||
typedef movable1 movable2;
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
class hash
|
||||
{
|
||||
public:
|
||||
hash(constructor_param const&) {}
|
||||
hash() {}
|
||||
hash(hash const&) {}
|
||||
hash& operator=(hash const&) { return *this; }
|
||||
~hash() {}
|
||||
template <class T> class hash
|
||||
{
|
||||
public:
|
||||
hash(constructor_param const&) {}
|
||||
hash() {}
|
||||
hash(hash const&) {}
|
||||
hash& operator=(hash const&) { return *this; }
|
||||
~hash() {}
|
||||
|
||||
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
|
||||
ampersand_operator_used operator&() const {
|
||||
return ampersand_operator_used(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class equal_to
|
||||
ampersand_operator_used operator&() const
|
||||
{
|
||||
public:
|
||||
equal_to(constructor_param const&) {}
|
||||
equal_to() {}
|
||||
equal_to(equal_to const&) {}
|
||||
equal_to& operator=(equal_to const&) { return *this; }
|
||||
~equal_to() {}
|
||||
return ampersand_operator_used();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
bool operator()(T const&, T const&) const { return true; }
|
||||
template <class T> class equal_to
|
||||
{
|
||||
public:
|
||||
equal_to(constructor_param const&) {}
|
||||
equal_to() {}
|
||||
equal_to(equal_to const&) {}
|
||||
equal_to& operator=(equal_to const&) { return *this; }
|
||||
~equal_to() {}
|
||||
|
||||
bool operator()(T const&, T const&) const { return true; }
|
||||
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
|
||||
ampersand_operator_used operator&() const {
|
||||
return ampersand_operator_used(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class T> class ptr;
|
||||
template <class T> class const_ptr;
|
||||
|
||||
struct void_ptr
|
||||
ampersand_operator_used operator&() const
|
||||
{
|
||||
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)
|
||||
template <typename T>
|
||||
friend class ptr;
|
||||
private:
|
||||
template <typename T> friend class ptr;
|
||||
|
||||
private:
|
||||
#endif
|
||||
|
||||
void* ptr_;
|
||||
void* ptr_;
|
||||
|
||||
public:
|
||||
void_ptr() : ptr_(0) {}
|
||||
public:
|
||||
void_ptr() : ptr_(0) {}
|
||||
|
||||
template <typename T>
|
||||
explicit void_ptr(ptr<T> const& x) : ptr_(x.ptr_) {}
|
||||
template <typename T> explicit void_ptr(ptr<T> const& x) : ptr_(x.ptr_) {}
|
||||
|
||||
// I'm not using the safe bool idiom because the containers should be
|
||||
// able to cope with bool conversions.
|
||||
operator bool() const { return !!ptr_; }
|
||||
// I'm not using the safe bool idiom because the containers should be
|
||||
// able to cope with bool conversions.
|
||||
operator bool() const { return !!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_; }
|
||||
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)
|
||||
template <typename T>
|
||||
friend class const_ptr;
|
||||
private:
|
||||
template <typename T> friend class const_ptr;
|
||||
|
||||
private:
|
||||
#endif
|
||||
|
||||
void* ptr_;
|
||||
void* ptr_;
|
||||
|
||||
public:
|
||||
void_const_ptr() : ptr_(0) {}
|
||||
public:
|
||||
void_const_ptr() : ptr_(0) {}
|
||||
|
||||
template <typename T>
|
||||
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
|
||||
// able to cope with bool conversions.
|
||||
operator bool() const { return !!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>
|
||||
class ptr
|
||||
template <typename T>
|
||||
explicit void_const_ptr(const_ptr<T> const& x) : ptr_(x.ptr_)
|
||||
{
|
||||
friend class allocator<T>;
|
||||
friend class const_ptr<T>;
|
||||
friend struct void_ptr;
|
||||
}
|
||||
|
||||
T* ptr_;
|
||||
// I'm not using the safe bool idiom because the containers should be
|
||||
// able to cope with bool conversions.
|
||||
operator bool() const { return !!ptr_; }
|
||||
|
||||
ptr(T* x) : ptr_(x) {}
|
||||
public:
|
||||
ptr() : ptr_(0) {}
|
||||
explicit ptr(void_ptr const& x) : ptr_((T*) 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_; }
|
||||
};
|
||||
|
||||
T& operator*() const { return *ptr_; }
|
||||
T* operator->() const { return ptr_; }
|
||||
ptr& operator++() { ++ptr_; return *this; }
|
||||
ptr operator++(int) { ptr tmp(*this); ++ptr_; return tmp; }
|
||||
ptr operator+(std::ptrdiff_t s) const { return ptr<T>(ptr_ + s); }
|
||||
friend ptr operator+(std::ptrdiff_t s, ptr p)
|
||||
{ return ptr<T>(s + p.ptr_); }
|
||||
T& operator[](std::ptrdiff_t s) const { return ptr_[s]; }
|
||||
bool operator!() const { return !ptr_; }
|
||||
|
||||
// I'm not using the safe bool idiom because the containers should be
|
||||
// able to cope with bool conversions.
|
||||
operator bool() const { return !!ptr_; }
|
||||
template <class T> class ptr
|
||||
{
|
||||
friend class allocator<T>;
|
||||
friend class const_ptr<T>;
|
||||
friend struct void_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_; }
|
||||
bool operator>=(ptr const& x) const { return ptr_ >= x.ptr_; }
|
||||
T* ptr_;
|
||||
|
||||
ptr(T* x) : ptr_(x) {}
|
||||
public:
|
||||
ptr() : ptr_(0) {}
|
||||
explicit ptr(void_ptr const& x) : ptr_((T*)x.ptr_) {}
|
||||
|
||||
T& operator*() const { return *ptr_; }
|
||||
T* operator->() const { return ptr_; }
|
||||
ptr& operator++()
|
||||
{
|
||||
++ptr_;
|
||||
return *this;
|
||||
}
|
||||
ptr operator++(int)
|
||||
{
|
||||
ptr tmp(*this);
|
||||
++ptr_;
|
||||
return tmp;
|
||||
}
|
||||
ptr operator+(std::ptrdiff_t s) const { return ptr<T>(ptr_ + s); }
|
||||
friend ptr operator+(std::ptrdiff_t s, ptr p) { return ptr<T>(s + p.ptr_); }
|
||||
T& operator[](std::ptrdiff_t s) const { return ptr_[s]; }
|
||||
bool operator!() const { return !ptr_; }
|
||||
|
||||
// I'm not using the safe bool idiom because the containers should be
|
||||
// able to cope with bool conversions.
|
||||
operator bool() const { return !!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_; }
|
||||
bool operator>=(ptr const& x) const { return ptr_ >= x.ptr_; }
|
||||
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
|
||||
ampersand_operator_used operator&() const {
|
||||
return ampersand_operator_used(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class const_ptr
|
||||
ampersand_operator_used operator&() const
|
||||
{
|
||||
friend class allocator<T>;
|
||||
friend struct const_void_ptr;
|
||||
return ampersand_operator_used();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
T const* ptr_;
|
||||
template <class T> class const_ptr
|
||||
{
|
||||
friend class allocator<T>;
|
||||
friend struct const_void_ptr;
|
||||
|
||||
const_ptr(T const* ptr) : ptr_(ptr) {}
|
||||
public:
|
||||
const_ptr() : ptr_(0) {}
|
||||
const_ptr(ptr<T> const& x) : ptr_(x.ptr_) {}
|
||||
explicit const_ptr(void_const_ptr const& x) : ptr_((T const*) x.ptr_) {}
|
||||
T const* ptr_;
|
||||
|
||||
T const& operator*() const { return *ptr_; }
|
||||
T const* operator->() const { return ptr_; }
|
||||
const_ptr& operator++() { ++ptr_; 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)
|
||||
{ return ptr<T>(s + p.ptr_); }
|
||||
T const& operator[](int s) const { return ptr_[s]; }
|
||||
bool operator!() const { return !ptr_; }
|
||||
operator bool() const { return !!ptr_; }
|
||||
const_ptr(T const* ptr) : ptr_(ptr) {}
|
||||
public:
|
||||
const_ptr() : ptr_(0) {}
|
||||
const_ptr(ptr<T> const& x) : ptr_(x.ptr_) {}
|
||||
explicit const_ptr(void_const_ptr const& x) : ptr_((T const*)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_; }
|
||||
bool operator>=(const_ptr const& x) const { return ptr_ >= x.ptr_; }
|
||||
T const& operator*() const { return *ptr_; }
|
||||
T const* operator->() const { return ptr_; }
|
||||
const_ptr& operator++()
|
||||
{
|
||||
++ptr_;
|
||||
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)
|
||||
{
|
||||
return ptr<T>(s + p.ptr_);
|
||||
}
|
||||
T const& operator[](int s) const { return ptr_[s]; }
|
||||
bool operator!() const { return !ptr_; }
|
||||
operator bool() const { return !!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_; }
|
||||
bool operator>=(const_ptr const& x) const { return ptr_ >= x.ptr_; }
|
||||
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
|
||||
ampersand_operator_used operator&() const {
|
||||
return ampersand_operator_used(); }
|
||||
ampersand_operator_used operator&() const
|
||||
{
|
||||
return ampersand_operator_used();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class T> class allocator
|
||||
{
|
||||
public:
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef void_ptr void_pointer;
|
||||
typedef void_const_ptr const_void_pointer;
|
||||
typedef ptr<T> pointer;
|
||||
typedef const_ptr<T> const_pointer;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T value_type;
|
||||
|
||||
template <class U> struct rebind
|
||||
{
|
||||
typedef allocator<U> other;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class allocator
|
||||
allocator() {}
|
||||
template <class Y> allocator(allocator<Y> const&) {}
|
||||
allocator(allocator const&) {}
|
||||
~allocator() {}
|
||||
|
||||
pointer address(reference r) { return pointer(&r); }
|
||||
const_pointer address(const_reference r) { return const_pointer(&r); }
|
||||
|
||||
pointer allocate(size_type n)
|
||||
{
|
||||
public:
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef void_ptr void_pointer;
|
||||
typedef void_const_ptr const_void_pointer;
|
||||
typedef ptr<T> pointer;
|
||||
typedef const_ptr<T> const_pointer;
|
||||
typedef T& reference;
|
||||
typedef T const& const_reference;
|
||||
typedef T value_type;
|
||||
return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
|
||||
}
|
||||
|
||||
template <class U> struct rebind { typedef allocator<U> other; };
|
||||
template <class Y> pointer allocate(size_type n, const_ptr<Y>)
|
||||
{
|
||||
return pointer(static_cast<T*>(::operator new(n * sizeof(T))));
|
||||
}
|
||||
|
||||
allocator() {}
|
||||
template <class Y> allocator(allocator<Y> const&) {}
|
||||
allocator(allocator const&) {}
|
||||
~allocator() {}
|
||||
void deallocate(pointer p, size_type) { ::operator delete((void*)p.ptr_); }
|
||||
|
||||
pointer address(reference r) { return pointer(&r); }
|
||||
const_pointer address(const_reference r) { return const_pointer(&r); }
|
||||
|
||||
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))));
|
||||
}
|
||||
|
||||
void deallocate(pointer p, size_type)
|
||||
{
|
||||
::operator delete((void*) p.ptr_);
|
||||
}
|
||||
|
||||
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)
|
||||
template<class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args) {
|
||||
new((void*)p) T(boost::forward<Args>(args)...);
|
||||
}
|
||||
template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
new ((void*)p) T(boost::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
|
||||
void destroy(T* p) { p->~T(); }
|
||||
void destroy(T* p) { p->~T(); }
|
||||
|
||||
size_type max_size() const { return 1000; }
|
||||
size_type max_size() const { return 1000; }
|
||||
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) || \
|
||||
BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
public: allocator& operator=(allocator const&) { return *this;}
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) || \
|
||||
BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
|
||||
public:
|
||||
allocator& operator=(allocator const&) { return *this; }
|
||||
#else
|
||||
private: allocator& operator=(allocator const&);
|
||||
private:
|
||||
allocator& operator=(allocator const&);
|
||||
#endif
|
||||
#if BOOST_UNORDERED_CHECK_ADDR_OPERATOR_NOT_USED
|
||||
ampersand_operator_used operator&() const {
|
||||
return ampersand_operator_used(); }
|
||||
ampersand_operator_used operator&() const
|
||||
{
|
||||
return ampersand_operator_used();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline bool operator==(allocator<T> const&, allocator<T> const&)
|
||||
template <class T>
|
||||
inline bool operator==(allocator<T> const&, allocator<T> const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool operator!=(allocator<T> const&, allocator<T> const&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T> void swap(allocator<T>&, allocator<T>&) {}
|
||||
|
||||
// C++11 allocator
|
||||
//
|
||||
// Not a fully minimal C++11 allocator, just what I support. Hopefully will
|
||||
// cut down further in the future.
|
||||
|
||||
template <class T> class cxx11_allocator
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
// template <class U> struct rebind { typedef cxx11_allocator<U> other; };
|
||||
|
||||
cxx11_allocator() {}
|
||||
template <class Y> cxx11_allocator(cxx11_allocator<Y> const&) {}
|
||||
cxx11_allocator(cxx11_allocator const&) {}
|
||||
~cxx11_allocator() {}
|
||||
|
||||
T* address(T& r) { return &r; }
|
||||
T const* address(T const& r) { return &r; }
|
||||
|
||||
T* allocate(std::size_t n)
|
||||
{
|
||||
return true;
|
||||
return static_cast<T*>(::operator new(n * sizeof(T)));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool operator!=(allocator<T> const&, allocator<T> const&)
|
||||
template <class Y> T* allocate(std::size_t n, const_ptr<Y>)
|
||||
{
|
||||
return false;
|
||||
return static_cast<T*>(::operator new(n * sizeof(T)));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void swap(allocator<T>&, allocator<T>&)
|
||||
{
|
||||
}
|
||||
void deallocate(T* p, std::size_t) { ::operator delete((void*)p); }
|
||||
|
||||
// C++11 allocator
|
||||
//
|
||||
// Not a fully minimal C++11 allocator, just what I support. Hopefully will
|
||||
// cut down further in the future.
|
||||
|
||||
template <class T>
|
||||
class cxx11_allocator
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
//template <class U> struct rebind { typedef cxx11_allocator<U> other; };
|
||||
|
||||
cxx11_allocator() {}
|
||||
template <class Y> cxx11_allocator(cxx11_allocator<Y> const&) {}
|
||||
cxx11_allocator(cxx11_allocator const&) {}
|
||||
~cxx11_allocator() {}
|
||||
|
||||
T* address(T& r) { return &r; }
|
||||
T const* address(T const& r) { return &r; }
|
||||
|
||||
T* allocate(std::size_t n) {
|
||||
return static_cast<T*>(::operator new(n * sizeof(T)));
|
||||
}
|
||||
|
||||
template <class Y>
|
||||
T* allocate(std::size_t n, const_ptr<Y>) {
|
||||
return static_cast<T*>(::operator new(n * sizeof(T)));
|
||||
}
|
||||
|
||||
void deallocate(T* p, std::size_t) {
|
||||
::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)
|
||||
template<class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args) {
|
||||
new((void*)p) T(boost::forward<Args>(args)...);
|
||||
}
|
||||
template <class... Args> void construct(T* p, BOOST_FWD_REF(Args)... args)
|
||||
{
|
||||
new ((void*)p) T(boost::forward<Args>(args)...);
|
||||
}
|
||||
#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>
|
||||
inline bool operator==(cxx11_allocator<T> const&, cxx11_allocator<T> const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
template <class T>
|
||||
inline bool operator==(cxx11_allocator<T> const&, cxx11_allocator<T> const&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool operator!=(cxx11_allocator<T> const&, cxx11_allocator<T> const&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
template <class T>
|
||||
inline bool operator!=(cxx11_allocator<T> const&, cxx11_allocator<T> const&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void swap(cxx11_allocator<T>&, cxx11_allocator<T>&)
|
||||
{
|
||||
}
|
||||
template <class T> void swap(cxx11_allocator<T>&, cxx11_allocator<T>&) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,18 +522,17 @@ namespace boost {
|
||||
namespace test {
|
||||
namespace minimal {
|
||||
#endif
|
||||
std::size_t hash_value(
|
||||
test::minimal::copy_constructible_equality_comparable)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
std::size_t hash_value(test::minimal::copy_constructible_equality_comparable)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
}}
|
||||
}
|
||||
}
|
||||
#else
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
+580
-562
File diff suppressed because it is too large
Load Diff
@@ -3,71 +3,93 @@
|
||||
// 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)
|
||||
|
||||
#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 <boost/limits.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/unordered/detail/implementation.hpp>
|
||||
|
||||
// Boilerplate
|
||||
|
||||
#define ALLOCATOR_METHODS(name) \
|
||||
template <typename U> struct rebind { \
|
||||
typedef name<U> other; \
|
||||
}; \
|
||||
\
|
||||
name() {} \
|
||||
template <typename Y> name(name<Y> const&) {} \
|
||||
T* address(T& r) { return &r;} \
|
||||
T const* address(T const& r) { return &r; } \
|
||||
T* allocate(std::size_t n) \
|
||||
{ return static_cast<T*>(::operator new(n * sizeof(T))); } \
|
||||
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); } \
|
||||
void construct(T* p, T const& t) { new(p) T(t); } \
|
||||
void destroy(T* p) { p->~T(); } \
|
||||
std::size_t max_size() const \
|
||||
{ return (std::numeric_limits<std::size_t>::max)(); } \
|
||||
bool operator==(name<T> const&) { return true; } \
|
||||
bool operator!=(name<T> const&) { return false; } \
|
||||
#define ALLOCATOR_METHODS(name) \
|
||||
template <typename U> struct rebind \
|
||||
{ \
|
||||
typedef name<U> other; \
|
||||
}; \
|
||||
\
|
||||
name() {} \
|
||||
template <typename Y> name(name<Y> const&) {} \
|
||||
T* address(T& r) { return &r; } \
|
||||
T const* address(T const& r) { return &r; } \
|
||||
T* allocate(std::size_t n) \
|
||||
{ \
|
||||
return static_cast<T*>(::operator new(n * sizeof(T))); \
|
||||
} \
|
||||
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); } \
|
||||
void construct(T* p, T const& t) { new (p) T(t); } \
|
||||
void destroy(T* p) { p->~T(); } \
|
||||
std::size_t max_size() const \
|
||||
{ \
|
||||
return (std::numeric_limits<std::size_t>::max)(); \
|
||||
} \
|
||||
bool operator==(name<T> const&) { return true; } \
|
||||
bool operator!=(name<T> const&) { return false; } \
|
||||
/**/
|
||||
|
||||
#define ALLOCATOR_METHODS_TYPEDEFS(name) \
|
||||
template <typename U> struct rebind { \
|
||||
typedef name<U> other; \
|
||||
}; \
|
||||
\
|
||||
name() {} \
|
||||
template <typename Y> name(name<Y> const&) {} \
|
||||
pointer address(T& r) { return &r;} \
|
||||
const_pointer address(T const& r) { return &r; } \
|
||||
pointer allocate(std::size_t n) \
|
||||
{ return pointer(::operator new(n * sizeof(T))); } \
|
||||
pointer allocate(std::size_t n, void const*) \
|
||||
{ return pointer(::operator new(n * sizeof(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(); } \
|
||||
size_type max_size() const \
|
||||
{ return (std::numeric_limits<size_type>::max)(); } \
|
||||
bool operator==(name<T> const&) { return true; } \
|
||||
bool operator!=(name<T> const&) { return false; } \
|
||||
#define ALLOCATOR_METHODS_TYPEDEFS(name) \
|
||||
template <typename U> struct rebind \
|
||||
{ \
|
||||
typedef name<U> other; \
|
||||
}; \
|
||||
\
|
||||
name() {} \
|
||||
template <typename Y> name(name<Y> const&) {} \
|
||||
pointer address(T& r) { return &r; } \
|
||||
const_pointer address(T const& r) { return &r; } \
|
||||
pointer allocate(std::size_t n) \
|
||||
{ \
|
||||
return pointer(::operator new(n * sizeof(T))); \
|
||||
} \
|
||||
pointer allocate(std::size_t n, void const*) \
|
||||
{ \
|
||||
return pointer(::operator new(n * sizeof(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(); } \
|
||||
size_type max_size() const \
|
||||
{ \
|
||||
return (std::numeric_limits<size_type>::max)(); \
|
||||
} \
|
||||
bool operator==(name<T> const&) { return true; } \
|
||||
bool operator!=(name<T> const&) { return false; } \
|
||||
/**/
|
||||
|
||||
struct yes_type { enum { value = true }; };
|
||||
struct no_type { enum { value = false }; };
|
||||
struct yes_type
|
||||
{
|
||||
enum
|
||||
{
|
||||
value = true
|
||||
};
|
||||
};
|
||||
struct no_type
|
||||
{
|
||||
enum
|
||||
{
|
||||
value = false
|
||||
};
|
||||
};
|
||||
|
||||
// For tracking calls...
|
||||
|
||||
static int selected;
|
||||
void reset() {
|
||||
selected = 0;
|
||||
}
|
||||
void reset() { selected = 0; }
|
||||
|
||||
template <typename Allocator>
|
||||
int call_select()
|
||||
template <typename Allocator> int call_select()
|
||||
{
|
||||
typedef boost::unordered::detail::allocator_traits<Allocator> traits;
|
||||
Allocator a;
|
||||
@@ -79,8 +101,7 @@ int call_select()
|
||||
|
||||
// Empty allocator test
|
||||
|
||||
template <typename T>
|
||||
struct empty_allocator
|
||||
template <typename T> struct empty_allocator
|
||||
{
|
||||
typedef T value_type;
|
||||
ALLOCATOR_METHODS(empty_allocator)
|
||||
@@ -94,11 +115,14 @@ void test_empty_allocator()
|
||||
BOOST_STATIC_ASSERT((boost::is_same<traits::size_type,
|
||||
std::make_unsigned<std::ptrdiff_t>::type>::value));
|
||||
#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
|
||||
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::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_TEST(!traits::propagate_on_container_copy_assignment::value);
|
||||
BOOST_TEST(!traits::propagate_on_container_move_assignment::value);
|
||||
@@ -108,17 +132,17 @@ void test_empty_allocator()
|
||||
|
||||
// allocator 1
|
||||
|
||||
template <typename T>
|
||||
struct allocator1
|
||||
template <typename T> struct allocator1
|
||||
{
|
||||
typedef T value_type;
|
||||
ALLOCATOR_METHODS(allocator1)
|
||||
|
||||
|
||||
typedef yes_type propagate_on_container_copy_assignment;
|
||||
typedef yes_type propagate_on_container_move_assignment;
|
||||
typedef yes_type propagate_on_container_swap;
|
||||
|
||||
allocator1<T> select_on_container_copy_construction() const {
|
||||
|
||||
allocator1<T> select_on_container_copy_construction() const
|
||||
{
|
||||
++selected;
|
||||
return allocator1<T>();
|
||||
}
|
||||
@@ -132,11 +156,14 @@ void test_allocator1()
|
||||
BOOST_STATIC_ASSERT((boost::is_same<traits::size_type,
|
||||
std::make_unsigned<std::ptrdiff_t>::type>::value));
|
||||
#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
|
||||
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::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_TEST(traits::propagate_on_container_copy_assignment::value);
|
||||
BOOST_TEST(traits::propagate_on_container_move_assignment::value);
|
||||
@@ -146,25 +173,24 @@ void test_allocator1()
|
||||
|
||||
// allocator 2
|
||||
|
||||
template <typename Alloc>
|
||||
struct allocator2_base
|
||||
template <typename Alloc> struct allocator2_base
|
||||
{
|
||||
Alloc select_on_container_copy_construction() const {
|
||||
Alloc select_on_container_copy_construction() const
|
||||
{
|
||||
++selected;
|
||||
return Alloc();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct allocator2 : allocator2_base<allocator2<T> >
|
||||
template <typename T> struct allocator2 : allocator2_base<allocator2<T> >
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef T const* const_pointer;
|
||||
typedef std::size_t size_type;
|
||||
|
||||
|
||||
ALLOCATOR_METHODS(allocator2)
|
||||
|
||||
|
||||
typedef no_type propagate_on_container_copy_assignment;
|
||||
typedef no_type propagate_on_container_move_assignment;
|
||||
typedef no_type propagate_on_container_swap;
|
||||
@@ -174,10 +200,13 @@ void test_allocator2()
|
||||
{
|
||||
typedef allocator2<int> allocator;
|
||||
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::is_same<traits::difference_type, std::ptrdiff_t>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(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::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_TEST(!traits::propagate_on_container_copy_assignment::value);
|
||||
BOOST_TEST(!traits::propagate_on_container_move_assignment::value);
|
||||
@@ -187,31 +216,27 @@ void test_allocator2()
|
||||
|
||||
// allocator 3
|
||||
|
||||
template <typename T>
|
||||
struct ptr
|
||||
template <typename T> struct ptr
|
||||
{
|
||||
T* value_;
|
||||
|
||||
ptr(void* v) : value_((T*) v) {}
|
||||
|
||||
ptr(void* v) : value_((T*)v) {}
|
||||
T& operator*() const { return *value_; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ptr<void>
|
||||
template <> struct ptr<void>
|
||||
{
|
||||
void* value_;
|
||||
ptr(void* v) : value_(v) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ptr<const void>
|
||||
template <> struct ptr<const void>
|
||||
{
|
||||
void const* value_;
|
||||
ptr(void const* v) : value_(v) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct allocator3
|
||||
template <typename T> struct allocator3
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef ptr<T> pointer;
|
||||
@@ -219,11 +244,12 @@ struct allocator3
|
||||
typedef unsigned short size_type;
|
||||
|
||||
ALLOCATOR_METHODS_TYPEDEFS(allocator3)
|
||||
|
||||
|
||||
typedef yes_type propagate_on_container_copy_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;
|
||||
return allocator3<T>();
|
||||
}
|
||||
@@ -233,10 +259,13 @@ void test_allocator3()
|
||||
{
|
||||
typedef allocator3<int> allocator;
|
||||
typedef boost::unordered::detail::allocator_traits<allocator> traits;
|
||||
BOOST_STATIC_ASSERT((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::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::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_TEST(traits::propagate_on_container_copy_assignment::value);
|
||||
BOOST_TEST(!traits::propagate_on_container_move_assignment::value);
|
||||
|
||||
@@ -20,20 +20,19 @@
|
||||
#include <iostream>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable:4127) // conditional expression is constant
|
||||
#pragma warning(disable : 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
namespace assign_tests {
|
||||
|
||||
test::seed_t initialize_seed(96785);
|
||||
|
||||
template <class T>
|
||||
void assign_tests1(T*, test::random_generator generator)
|
||||
template <class T> void assign_tests1(T*, test::random_generator generator)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf;
|
||||
BOOST_DEDUCED_TYPENAME T::key_equal eq;
|
||||
|
||||
std::cerr<<"assign_tests1.1\n";
|
||||
std::cerr << "assign_tests1.1\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -44,7 +43,7 @@ void assign_tests1(T*, test::random_generator generator)
|
||||
BOOST_TEST(test::equivalent(x.key_eq(), eq));
|
||||
}
|
||||
|
||||
std::cerr<<"assign_tests1.2\n";
|
||||
std::cerr << "assign_tests1.2\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -69,8 +68,7 @@ void assign_tests1(T*, test::random_generator generator)
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void assign_tests2(T*, test::random_generator generator)
|
||||
template <class T> void assign_tests2(T*, test::random_generator generator)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf1(1);
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf2(2);
|
||||
@@ -78,10 +76,10 @@ void assign_tests2(T*, test::random_generator generator)
|
||||
BOOST_DEDUCED_TYPENAME T::key_equal eq2(2);
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al1(1);
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al2(2);
|
||||
|
||||
|
||||
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_;
|
||||
|
||||
@@ -95,7 +93,7 @@ void assign_tests2(T*, test::random_generator generator)
|
||||
test::check_container(x1, x2);
|
||||
}
|
||||
|
||||
std::cerr<<"assign_tests2.1\n";
|
||||
std::cerr << "assign_tests2.1\n";
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
std::cerr<<"assign_tests2.1a\n";
|
||||
std::cerr << "assign_tests2.1a\n";
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
std::cerr<<"assign_tests2.2\n";
|
||||
std::cerr << "assign_tests2.2\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -143,8 +141,7 @@ void assign_tests2(T*, test::random_generator generator)
|
||||
if (allocator_type::is_propagate_on_assign) {
|
||||
BOOST_TEST(test::equivalent(x2.get_allocator(), al1));
|
||||
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(), al1));
|
||||
}
|
||||
@@ -153,7 +150,7 @@ void assign_tests2(T*, test::random_generator generator)
|
||||
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_;
|
||||
|
||||
@@ -166,8 +163,7 @@ void assign_tests2(T*, test::random_generator generator)
|
||||
if (allocator_type::is_propagate_on_assign) {
|
||||
BOOST_TEST(test::equivalent(x2.get_allocator(), al1));
|
||||
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(), al1));
|
||||
}
|
||||
@@ -176,7 +172,7 @@ void assign_tests2(T*, test::random_generator generator)
|
||||
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_;
|
||||
|
||||
@@ -189,8 +185,7 @@ void assign_tests2(T*, test::random_generator generator)
|
||||
if (allocator_type::is_propagate_on_assign) {
|
||||
BOOST_TEST(test::equivalent(x2.get_allocator(), al1));
|
||||
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(), al1));
|
||||
}
|
||||
@@ -200,63 +195,51 @@ void assign_tests2(T*, test::random_generator generator)
|
||||
}
|
||||
}
|
||||
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
std::allocator<test::object> >* test_map_std_alloc;
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_multimap;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator1<test::object> >* test_multimap;
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_assign> >*
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_assign> >*
|
||||
test_set_prop_assign;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_assign> >*
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_assign> >*
|
||||
test_multiset_prop_assign;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_assign> >*
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_assign> >*
|
||||
test_map_prop_assign;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_assign> >*
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_assign> >*
|
||||
test_multimap_prop_assign;
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_assign> >*
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_assign> >*
|
||||
test_set_no_prop_assign;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_assign> >*
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_assign> >*
|
||||
test_multiset_no_prop_assign;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_assign> >*
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_assign> >*
|
||||
test_map_no_prop_assign;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_assign> >*
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_assign> >*
|
||||
test_multimap_no_prop_assign;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
template <typename T>
|
||||
bool is_propagate(T*)
|
||||
template <typename T> bool is_propagate(T*)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
UNORDERED_TEST(assign_tests1, (
|
||||
(test_map_std_alloc)
|
||||
(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_no_prop_assign)(test_multiset_no_prop_assign)(test_map_no_prop_assign)(test_multimap_no_prop_assign)
|
||||
)
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
UNORDERED_TEST(assign_tests1,
|
||||
((test_map_std_alloc)(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_no_prop_assign)(
|
||||
test_multiset_no_prop_assign)(test_map_no_prop_assign)(
|
||||
test_multimap_no_prop_assign))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(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_no_prop_assign)(test_multiset_no_prop_assign)(test_map_no_prop_assign)(test_multimap_no_prop_assign)
|
||||
)
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
UNORDERED_TEST(
|
||||
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_no_prop_assign)(test_multiset_no_prop_assign)(
|
||||
test_map_no_prop_assign)(test_multimap_no_prop_assign))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
||||
UNORDERED_AUTO_TEST(assign_default_initializer_list) {
|
||||
std::cerr<<"Initializer List Tests\n";
|
||||
UNORDERED_AUTO_TEST(assign_default_initializer_list)
|
||||
{
|
||||
std::cerr << "Initializer List Tests\n";
|
||||
std::initializer_list<std::pair<int const, int> > init;
|
||||
boost::unordered_map<int, int> x1;
|
||||
x1[25] = 3;
|
||||
@@ -303,18 +286,17 @@ UNORDERED_AUTO_TEST(assign_default_initializer_list) {
|
||||
#if !defined(BOOST_NO_CXX11_HDR_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;
|
||||
x.insert(10);
|
||||
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());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
|
||||
namespace at_tests {
|
||||
|
||||
UNORDERED_AUTO_TEST(at_tests) {
|
||||
UNORDERED_AUTO_TEST(at_tests)
|
||||
{
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Create Map" << std::endl;
|
||||
|
||||
boost::unordered_map<std::string, int> x;
|
||||
@@ -34,13 +35,11 @@ UNORDERED_AUTO_TEST(at_tests) {
|
||||
try {
|
||||
x.at("three");
|
||||
BOOST_ERROR("Should have thrown.");
|
||||
}
|
||||
catch(std::out_of_range) {
|
||||
} catch (std::out_of_range) {
|
||||
}
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Finished" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -17,16 +17,15 @@
|
||||
#include "../helpers/helpers.hpp"
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1400)
|
||||
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
|
||||
// possible loss of data.
|
||||
#pragma warning(disable : 4267) // conversion from 'size_t' to 'unsigned int',
|
||||
// possible loss of data.
|
||||
#endif
|
||||
|
||||
namespace bucket_tests {
|
||||
|
||||
test::seed_t initialize_seed(54635);
|
||||
|
||||
template <class X>
|
||||
void tests(X*, test::random_generator generator)
|
||||
template <class X> void tests(X*, test::random_generator generator)
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -38,66 +37,59 @@ void tests(X*, test::random_generator generator)
|
||||
|
||||
BOOST_TEST(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
|
||||
it = v.begin(), end = v.end(); it != end; ++it)
|
||||
{
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator
|
||||
it = v.begin(),
|
||||
end = v.end();
|
||||
it != end; ++it) {
|
||||
size_type bucket = x.bucket(test::get_key<X>(*it));
|
||||
|
||||
BOOST_TEST(bucket < x.bucket_count());
|
||||
if(bucket < x.bucket_count()) {
|
||||
if (bucket < x.bucket_count()) {
|
||||
// lit? lend?? I need a new naming scheme.
|
||||
const_local_iterator lit = x.begin(bucket), lend = x.end(bucket);
|
||||
while(lit != lend
|
||||
&& test::get_key<X>(*it) != test::get_key<X>(*lit))
|
||||
{
|
||||
while (lit != lend &&
|
||||
test::get_key<X>(*it) != test::get_key<X>(*lit)) {
|
||||
++lit;
|
||||
}
|
||||
BOOST_TEST(lit != lend);
|
||||
}
|
||||
}
|
||||
|
||||
for(size_type i = 0; i < x.bucket_count(); ++i) {
|
||||
BOOST_TEST(x.bucket_size(i) == static_cast<size_type>(
|
||||
std::distance(x.begin(i), x.end(i))));
|
||||
BOOST_TEST(x.bucket_size(i) == static_cast<size_type>(
|
||||
std::distance(x.cbegin(i), x.cend(i))));
|
||||
for (size_type i = 0; i < x.bucket_count(); ++i) {
|
||||
BOOST_TEST(x.bucket_size(i) ==
|
||||
static_cast<size_type>(std::distance(x.begin(i), x.end(i))));
|
||||
BOOST_TEST(x.bucket_size(i) == static_cast<size_type>(std::distance(
|
||||
x.cbegin(i), x.cend(i))));
|
||||
X const& x_ref = x;
|
||||
BOOST_TEST(x.bucket_size(i) == static_cast<size_type>(
|
||||
std::distance(x_ref.begin(i), x_ref.end(i))));
|
||||
BOOST_TEST(x.bucket_size(i) == static_cast<size_type>(
|
||||
std::distance(x_ref.cbegin(i), x_ref.cend(i))));
|
||||
BOOST_TEST(x.bucket_size(i) == static_cast<size_type>(std::distance(
|
||||
x_ref.begin(i), x_ref.end(i))));
|
||||
BOOST_TEST(x.bucket_size(i) == static_cast<size_type>(std::distance(
|
||||
x_ref.cbegin(i), x_ref.cend(i))));
|
||||
}
|
||||
}
|
||||
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
std::allocator<test::object> >* test_multimap_std_alloc;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, std::allocator<test::object> >* test_multimap_std_alloc;
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_multimap;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator2<test::object> >* test_multimap;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(tests,
|
||||
((test_multimap_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(tests, ((test_multimap_std_alloc)(test_set)(test_multiset)(
|
||||
test_map)(test_multimap))((default_generator)(
|
||||
generate_collisions)(limited_range)))
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -19,29 +19,18 @@
|
||||
|
||||
// Explicit instantiation to catch compile-time errors
|
||||
|
||||
template class boost::unordered_map<
|
||||
int,
|
||||
int,
|
||||
boost::hash<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<int, int, boost::hash<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<
|
||||
test::minimal::assignable const,
|
||||
template class boost::unordered_map<test::minimal::assignable const,
|
||||
test::minimal::default_assignable const,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<test::minimal::assignable> >;
|
||||
template class boost::unordered_multimap<
|
||||
test::minimal::assignable,
|
||||
test::minimal::assignable,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
template class boost::unordered_multimap<test::minimal::assignable,
|
||||
test::minimal::assignable, test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<test::minimal::assignable> >;
|
||||
|
||||
@@ -50,68 +39,70 @@ UNORDERED_AUTO_TEST(test0)
|
||||
test::minimal::constructor_param x;
|
||||
|
||||
typedef std::pair<test::minimal::assignable const,
|
||||
test::minimal::assignable> value_type;
|
||||
test::minimal::assignable>
|
||||
value_type;
|
||||
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,
|
||||
boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<std::pair<int const, int> >
|
||||
> int_map2;
|
||||
boost::unordered_map<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<std::pair<int const, int> > >
|
||||
int_map2;
|
||||
|
||||
boost::unordered_map<
|
||||
test::minimal::assignable,
|
||||
test::minimal::assignable,
|
||||
boost::unordered_map<test::minimal::assignable, test::minimal::assignable,
|
||||
test::minimal::hash<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_map2, std::pair<int const, int>(0, 0));
|
||||
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,
|
||||
boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<std::pair<int const, int> >
|
||||
> int_multimap2;
|
||||
boost::unordered_multimap<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<std::pair<int const, int> > >
|
||||
int_multimap2;
|
||||
|
||||
boost::unordered_multimap<
|
||||
test::minimal::assignable,
|
||||
boost::unordered_multimap<test::minimal::assignable,
|
||||
test::minimal::assignable,
|
||||
test::minimal::hash<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_multimap2, std::pair<int const, int>(0, 0));
|
||||
container_test(multimap, value);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_tests) {
|
||||
UNORDERED_AUTO_TEST(equality_tests)
|
||||
{
|
||||
typedef std::pair<
|
||||
test::minimal::copy_constructible_equality_comparable const,
|
||||
test::minimal::copy_constructible_equality_comparable> value_type;
|
||||
test::minimal::copy_constructible_equality_comparable const,
|
||||
test::minimal::copy_constructible_equality_comparable>
|
||||
value_type;
|
||||
|
||||
boost::unordered_map<int, int> int_map;
|
||||
|
||||
boost::unordered_map<int, int,
|
||||
boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<std::pair<int const, int> >
|
||||
> int_map2;
|
||||
boost::unordered_map<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<std::pair<int const, int> > >
|
||||
int_map2;
|
||||
|
||||
boost::unordered_map<
|
||||
test::minimal::copy_constructible_equality_comparable,
|
||||
test::minimal::copy_constructible_equality_comparable,
|
||||
test::minimal::hash<test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::equal_to<test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::allocator<value_type> > map;
|
||||
test::minimal::hash<
|
||||
test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::equal_to<
|
||||
test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::allocator<value_type> >
|
||||
map;
|
||||
|
||||
equality_test(int_map);
|
||||
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,
|
||||
boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<std::pair<int const, int> >
|
||||
> int_multimap2;
|
||||
boost::unordered_multimap<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<std::pair<int const, int> > >
|
||||
int_multimap2;
|
||||
|
||||
boost::unordered_multimap<
|
||||
test::minimal::copy_constructible_equality_comparable,
|
||||
test::minimal::copy_constructible_equality_comparable,
|
||||
test::minimal::hash<test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::equal_to<test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::allocator<value_type> > multimap;
|
||||
test::minimal::hash<
|
||||
test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::equal_to<
|
||||
test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::allocator<value_type> >
|
||||
multimap;
|
||||
|
||||
equality_test(int_multimap);
|
||||
equality_test(int_multimap2);
|
||||
equality_test(multimap);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(test1) {
|
||||
UNORDERED_AUTO_TEST(test1)
|
||||
{
|
||||
boost::hash<int> hash;
|
||||
std::equal_to<int> equal_to;
|
||||
int value = 0;
|
||||
std::pair<int const, int> map_value(0, 0);
|
||||
|
||||
std::cout<<"Test unordered_map.\n";
|
||||
std::cout << "Test unordered_map.\n";
|
||||
|
||||
boost::unordered_map<int, int> map;
|
||||
|
||||
boost::unordered_map<int, int,
|
||||
boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<std::pair<int const, int> >
|
||||
> map2;
|
||||
boost::unordered_map<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<std::pair<int const, int> > >
|
||||
map2;
|
||||
|
||||
unordered_unique_test(map, map_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_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,
|
||||
boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<std::pair<int const, int> >
|
||||
> multimap2;
|
||||
boost::unordered_multimap<int, int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<std::pair<int const, int> > >
|
||||
multimap2;
|
||||
|
||||
unordered_equivalent_test(multimap, map_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);
|
||||
|
||||
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);
|
||||
|
||||
std::cout<<"Test unordered_map.\n";
|
||||
std::cout << "Test unordered_map.\n";
|
||||
|
||||
boost::unordered_map<
|
||||
test::minimal::assignable,
|
||||
test::minimal::assignable,
|
||||
boost::unordered_map<test::minimal::assignable, test::minimal::assignable,
|
||||
test::minimal::hash<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_map_test(map, assignable, assignable);
|
||||
unordered_copyable_test(map, assignable, map_value, hash, equal_to);
|
||||
unordered_map_member_test(map, map_value);
|
||||
|
||||
boost::unordered_map<
|
||||
test::minimal::assignable,
|
||||
boost::unordered_map<test::minimal::assignable,
|
||||
test::minimal::default_assignable,
|
||||
test::minimal::hash<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;
|
||||
|
||||
unordered_map_functions(map2, assignable, default_assignable);
|
||||
|
||||
std::cout<<"Test unordered_multimap.\n";
|
||||
std::cout << "Test unordered_multimap.\n";
|
||||
|
||||
boost::unordered_multimap<
|
||||
test::minimal::assignable,
|
||||
boost::unordered_multimap<test::minimal::assignable,
|
||||
test::minimal::assignable,
|
||||
test::minimal::hash<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_map_test(multimap, assignable, assignable);
|
||||
|
||||
@@ -19,24 +19,16 @@
|
||||
|
||||
// Explicit instantiation to catch compile-time errors
|
||||
|
||||
template class boost::unordered_set<
|
||||
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>,
|
||||
template class boost::unordered_set<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> >;
|
||||
|
||||
template class boost::unordered_set<
|
||||
test::minimal::assignable const,
|
||||
template class boost::unordered_set<test::minimal::assignable const,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<test::minimal::assignable> >;
|
||||
template class boost::unordered_multiset<
|
||||
test::minimal::assignable,
|
||||
template class boost::unordered_multiset<test::minimal::assignable,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<test::minimal::assignable> >;
|
||||
@@ -47,60 +39,61 @@ UNORDERED_AUTO_TEST(test0)
|
||||
|
||||
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,
|
||||
boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<int>
|
||||
> int_set2;
|
||||
boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<int> >
|
||||
int_set2;
|
||||
|
||||
boost::unordered_set<
|
||||
test::minimal::assignable,
|
||||
boost::unordered_set<test::minimal::assignable,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<test::minimal::assignable> > set;
|
||||
test::minimal::allocator<test::minimal::assignable> >
|
||||
set;
|
||||
|
||||
container_test(int_set, 0);
|
||||
container_test(int_set2, 0);
|
||||
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,
|
||||
boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<int>
|
||||
> int_multiset2;
|
||||
boost::unordered_multiset<int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<int> >
|
||||
int_multiset2;
|
||||
|
||||
boost::unordered_multiset<
|
||||
test::minimal::assignable,
|
||||
boost::unordered_multiset<test::minimal::assignable,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<test::minimal::assignable> > multiset;
|
||||
test::minimal::allocator<test::minimal::assignable> >
|
||||
multiset;
|
||||
|
||||
container_test(int_multiset, 0);
|
||||
container_test(int_multiset2, 0);
|
||||
container_test(multiset, assignable);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_tests) {
|
||||
UNORDERED_AUTO_TEST(equality_tests)
|
||||
{
|
||||
typedef test::minimal::copy_constructible_equality_comparable value_type;
|
||||
|
||||
boost::unordered_set<int> int_set;
|
||||
|
||||
boost::unordered_set<int,
|
||||
boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<int>
|
||||
> int_set2;
|
||||
boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<int> >
|
||||
int_set2;
|
||||
|
||||
boost::unordered_set<
|
||||
test::minimal::copy_constructible_equality_comparable,
|
||||
test::minimal::hash<test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::equal_to<test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::allocator<value_type> > set;
|
||||
test::minimal::hash<
|
||||
test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::equal_to<
|
||||
test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::allocator<value_type> >
|
||||
set;
|
||||
|
||||
equality_test(int_set);
|
||||
equality_test(int_set2);
|
||||
@@ -108,16 +101,18 @@ UNORDERED_AUTO_TEST(equality_tests) {
|
||||
|
||||
boost::unordered_multiset<int> int_multiset;
|
||||
|
||||
boost::unordered_multiset<int,
|
||||
boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<int>
|
||||
> int_multiset2;
|
||||
boost::unordered_multiset<int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<int> >
|
||||
int_multiset2;
|
||||
|
||||
boost::unordered_multiset<
|
||||
test::minimal::copy_constructible_equality_comparable,
|
||||
test::minimal::hash<test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::equal_to<test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::allocator<value_type> > multiset;
|
||||
test::minimal::hash<
|
||||
test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::equal_to<
|
||||
test::minimal::copy_constructible_equality_comparable>,
|
||||
test::minimal::allocator<value_type> >
|
||||
multiset;
|
||||
|
||||
equality_test(int_multiset);
|
||||
equality_test(int_multiset2);
|
||||
@@ -130,14 +125,13 @@ UNORDERED_AUTO_TEST(test1)
|
||||
std::equal_to<int> equal_to;
|
||||
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,
|
||||
boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<int>
|
||||
> set2;
|
||||
|
||||
boost::unordered_set<int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<int> >
|
||||
set2;
|
||||
|
||||
unordered_unique_test(set, value);
|
||||
unordered_set_test(set, value);
|
||||
@@ -147,14 +141,13 @@ UNORDERED_AUTO_TEST(test1)
|
||||
unordered_set_test(set2, value);
|
||||
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,
|
||||
boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<int>
|
||||
> multiset2;
|
||||
|
||||
boost::unordered_multiset<int, boost::hash<int>, std::equal_to<int>,
|
||||
test::minimal::cxx11_allocator<int> >
|
||||
multiset2;
|
||||
|
||||
unordered_equivalent_test(multiset, value);
|
||||
unordered_set_test(multiset, value);
|
||||
@@ -168,32 +161,32 @@ UNORDERED_AUTO_TEST(test1)
|
||||
UNORDERED_AUTO_TEST(test2)
|
||||
{
|
||||
test::minimal::constructor_param x;
|
||||
|
||||
|
||||
test::minimal::assignable assignable(x);
|
||||
test::minimal::copy_constructible copy_constructible(x);
|
||||
test::minimal::hash<test::minimal::assignable> hash(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<
|
||||
test::minimal::assignable,
|
||||
boost::unordered_set<test::minimal::assignable,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<test::minimal::assignable> > set;
|
||||
test::minimal::allocator<test::minimal::assignable> >
|
||||
set;
|
||||
|
||||
unordered_unique_test(set, assignable);
|
||||
unordered_set_test(set, assignable);
|
||||
unordered_copyable_test(set, assignable, assignable, hash, equal_to);
|
||||
unordered_set_member_test(set, assignable);
|
||||
|
||||
std::cout<<"Test unordered_multiset.\n";
|
||||
std::cout << "Test unordered_multiset.\n";
|
||||
|
||||
boost::unordered_multiset<
|
||||
test::minimal::assignable,
|
||||
boost::unordered_multiset<test::minimal::assignable,
|
||||
test::minimal::hash<test::minimal::assignable>,
|
||||
test::minimal::equal_to<test::minimal::assignable>,
|
||||
test::minimal::allocator<test::minimal::assignable> > multiset;
|
||||
test::minimal::allocator<test::minimal::assignable> >
|
||||
multiset;
|
||||
|
||||
unordered_equivalent_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::equal_to<test::minimal::movable1> equal_to(x);
|
||||
|
||||
std::cout<<"Test unordered_set.\n";
|
||||
std::cout << "Test unordered_set.\n";
|
||||
|
||||
boost::unordered_set<
|
||||
test::minimal::movable1,
|
||||
boost::unordered_set<test::minimal::movable1,
|
||||
test::minimal::hash<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_movable_test(set, movable1, movable1, hash, equal_to);
|
||||
|
||||
std::cout<<"Test unordered_multiset.\n";
|
||||
std::cout << "Test unordered_multiset.\n";
|
||||
|
||||
boost::unordered_multiset<
|
||||
test::minimal::movable1,
|
||||
boost::unordered_multiset<test::minimal::movable1,
|
||||
test::minimal::hash<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_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::equal_to<test::minimal::movable2> equal_to(x);
|
||||
|
||||
std::cout<<"Test unordered_set.\n";
|
||||
std::cout << "Test unordered_set.\n";
|
||||
|
||||
boost::unordered_set<
|
||||
test::minimal::movable2,
|
||||
boost::unordered_set<test::minimal::movable2,
|
||||
test::minimal::hash<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_movable_test(set, movable2, movable2, hash, equal_to);
|
||||
|
||||
std::cout<<"Test unordered_multiset.\n";
|
||||
std::cout << "Test unordered_multiset.\n";
|
||||
|
||||
boost::unordered_multiset<
|
||||
test::minimal::movable2,
|
||||
boost::unordered_multiset<test::minimal::movable2,
|
||||
test::minimal::hash<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_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::equal_to<test::minimal::destructible> equal_to(x);
|
||||
|
||||
std::cout<<"Test unordered_set.\n";
|
||||
std::cout << "Test unordered_set.\n";
|
||||
|
||||
boost::unordered_set<
|
||||
test::minimal::destructible,
|
||||
boost::unordered_set<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);
|
||||
|
||||
std::cout<<"Test unordered_multiset.\n";
|
||||
std::cout << "Test unordered_multiset.\n";
|
||||
|
||||
boost::unordered_multiset<
|
||||
test::minimal::destructible,
|
||||
boost::unordered_multiset<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);
|
||||
}
|
||||
|
||||
+128
-152
@@ -5,9 +5,9 @@
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4100) // unreferenced formal parameter
|
||||
#pragma warning(disable:4610) // class can never be instantiated
|
||||
#pragma warning(disable:4510) // default constructor could not be generated
|
||||
#pragma warning(disable : 4100) // unreferenced formal parameter
|
||||
#pragma warning(disable : 4610) // class can never be instantiated
|
||||
#pragma warning(disable : 4510) // default constructor could not be generated
|
||||
#endif
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
@@ -16,13 +16,13 @@
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include "../helpers/check_return_type.hpp"
|
||||
#include <boost/iterator/iterator_traits.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 "../helpers/check_return_type.hpp"
|
||||
|
||||
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_default() { return T(); }
|
||||
|
||||
template <class X, class T>
|
||||
void container_test(X& r, T const&)
|
||||
template <class X, class T> void container_test(X& r, T const&)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::difference_type difference_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::size_type size_type;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_value<iterator>::type iterator_value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_value<const_iterator>::type const_iterator_value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_difference<iterator>::type iterator_difference_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_difference<const_iterator>::type
|
||||
const_iterator_difference_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<iterator>::type
|
||||
iterator_value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_value<const_iterator>::type
|
||||
const_iterator_value_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<iterator>::type
|
||||
iterator_difference_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<
|
||||
const_iterator>::type const_iterator_difference_type;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME X::value_type value_type;
|
||||
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_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
|
||||
|
||||
@@ -77,10 +76,10 @@ 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_integer);
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<difference_type, iterator_difference_type>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<difference_type,
|
||||
iterator_difference_type>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<difference_type,
|
||||
const_iterator_difference_type>::value));
|
||||
const_iterator_difference_type>::value));
|
||||
|
||||
// size_type
|
||||
|
||||
@@ -89,21 +88,19 @@ void container_test(X& r, T const&)
|
||||
|
||||
// size_type can represent any non-negative value type of difference_type
|
||||
// I'm not sure about either of these tests...
|
||||
size_type max_diff = static_cast<size_type>(
|
||||
(std::numeric_limits<difference_type>::max)());
|
||||
size_type max_diff =
|
||||
static_cast<size_type>((std::numeric_limits<difference_type>::max)());
|
||||
difference_type converted_diff(static_cast<difference_type>(max_diff));
|
||||
BOOST_TEST((std::numeric_limits<difference_type>::max)()
|
||||
== converted_diff);
|
||||
BOOST_TEST((std::numeric_limits<difference_type>::max)() == converted_diff);
|
||||
|
||||
BOOST_TEST(
|
||||
static_cast<comparison_type>(
|
||||
(std::numeric_limits<size_type>::max)()) >
|
||||
static_cast<comparison_type>((std::numeric_limits<size_type>::max)()) >
|
||||
static_cast<comparison_type>(
|
||||
(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)
|
||||
// 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(X().size() == 0);
|
||||
|
||||
X a,b;
|
||||
X a, b;
|
||||
X a_const;
|
||||
|
||||
sink(X(a));
|
||||
@@ -142,7 +139,7 @@ void container_test(X& r, T const&)
|
||||
X c2(a_const, m);
|
||||
sink(X(rvalue(a_const), m));
|
||||
X c3(rvalue(a_const), m);
|
||||
|
||||
|
||||
// Avoid unused variable warnings:
|
||||
|
||||
sink(u);
|
||||
@@ -155,8 +152,7 @@ void container_test(X& r, T const&)
|
||||
sink(c3);
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void unordered_destructible_test(X&)
|
||||
template <class X> void unordered_destructible_test(X&)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator 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)
|
||||
X x2(rvalue_default<X>());
|
||||
X x3 = rvalue_default<X>();
|
||||
// This can only be done if propagate_on_container_move_assignment::value
|
||||
// is true.
|
||||
// x2 = rvalue_default<X>();
|
||||
// This can only be done if propagate_on_container_move_assignment::value
|
||||
// is true.
|
||||
// x2 = rvalue_default<X>();
|
||||
#endif
|
||||
|
||||
X* ptr = new X();
|
||||
@@ -177,7 +173,7 @@ void unordered_destructible_test(X&)
|
||||
(&a1)->~X();
|
||||
::operator delete((void*)(&a1));
|
||||
|
||||
X a,b;
|
||||
X a, b;
|
||||
X const a_const;
|
||||
test::check_return_type<iterator>::equals(a.begin());
|
||||
test::check_return_type<const_iterator>::equals(a_const.begin());
|
||||
@@ -190,7 +186,7 @@ void unordered_destructible_test(X&)
|
||||
|
||||
a.swap(b);
|
||||
boost::swap(a, b);
|
||||
|
||||
|
||||
test::check_return_type<size_type>::equals(a.size());
|
||||
test::check_return_type<size_type>::equals(a.max_size());
|
||||
test::check_return_type<bool>::convertible(a.empty());
|
||||
@@ -201,8 +197,7 @@ void unordered_destructible_test(X&)
|
||||
test::check_return_type<allocator_type>::equals(a_const.get_allocator());
|
||||
}
|
||||
|
||||
template <class X, class Key>
|
||||
void unordered_set_test(X&, Key const&)
|
||||
template <class X, class Key> void unordered_set_test(X&, Key const&)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME X::value_type value_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::local_iterator local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::const_local_iterator const_local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<iterator>::type iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<const_iterator>::type
|
||||
const_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<local_iterator>::type local_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<const_local_iterator>::type
|
||||
const_local_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<iterator>::type
|
||||
iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<const_iterator>::type
|
||||
const_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<local_iterator>::type
|
||||
local_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<
|
||||
const_local_iterator>::type const_local_iterator_pointer;
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<value_type const*, iterator_pointer>::value));
|
||||
BOOST_STATIC_ASSERT((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));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<value_type const*, iterator_pointer>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(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>
|
||||
@@ -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::key_type key_type;
|
||||
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<value_type, std::pair<key_type const, T> >::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<value_type, std::pair<key_type const, T> >::value));
|
||||
|
||||
// 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::local_iterator local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::const_local_iterator const_local_iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<iterator>::type iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<const_iterator>::type
|
||||
const_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<local_iterator>::type local_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<const_local_iterator>::type
|
||||
const_local_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<iterator>::type
|
||||
iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<const_iterator>::type
|
||||
const_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<local_iterator>::type
|
||||
local_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<
|
||||
const_local_iterator>::type const_local_iterator_pointer;
|
||||
|
||||
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::is_same<value_type*, local_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 const*, const_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
|
||||
|
||||
@@ -274,12 +272,11 @@ void unordered_map_test(X& r, Key const& k, T const& v)
|
||||
r.emplace(k_lvalue, v_lvalue);
|
||||
r.emplace(rvalue(k), rvalue(v));
|
||||
|
||||
r.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(k), boost::make_tuple(v));
|
||||
r.emplace(boost::unordered::piecewise_construct, boost::make_tuple(k),
|
||||
boost::make_tuple(v));
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void equality_test(X& r)
|
||||
template <class X> void equality_test(X& 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));
|
||||
}
|
||||
|
||||
template <class X, class T>
|
||||
void unordered_unique_test(X& r, T const& t)
|
||||
template <class X, class T> void unordered_unique_test(X& r, T const& t)
|
||||
{
|
||||
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.emplace(t));
|
||||
}
|
||||
|
||||
template <class X, class T>
|
||||
void unordered_equivalent_test(X& r, T const& t)
|
||||
template <class X, class T> void unordered_equivalent_test(X& r, T const& t)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
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
|
||||
boost::BOOST_ITERATOR_CATEGORY<iterator>::type
|
||||
iterator_category;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_difference<iterator>::type
|
||||
boost::BOOST_ITERATOR_CATEGORY<iterator>::type iterator_category;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<iterator>::type
|
||||
iterator_difference;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<iterator>::type
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<iterator>::type
|
||||
iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_reference<iterator>::type
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<iterator>::type
|
||||
iterator_reference;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::BOOST_ITERATOR_CATEGORY<local_iterator>::type
|
||||
local_iterator_category;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_difference<local_iterator>::type
|
||||
local_iterator_difference;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<local_iterator>::type
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::BOOST_ITERATOR_CATEGORY<
|
||||
local_iterator>::type local_iterator_category;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<
|
||||
local_iterator>::type local_iterator_difference;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<local_iterator>::type
|
||||
local_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_reference<local_iterator>::type
|
||||
local_iterator_reference;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<
|
||||
local_iterator>::type local_iterator_reference;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::BOOST_ITERATOR_CATEGORY<const_iterator>::type
|
||||
const_iterator_category;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_difference<const_iterator>::type
|
||||
const_iterator_difference;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<const_iterator>::type
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::BOOST_ITERATOR_CATEGORY<
|
||||
const_iterator>::type const_iterator_category;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<
|
||||
const_iterator>::type const_iterator_difference;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<const_iterator>::type
|
||||
const_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_reference<const_iterator>::type
|
||||
const_iterator_reference;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_reference<
|
||||
const_iterator>::type const_iterator_reference;
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::BOOST_ITERATOR_CATEGORY<const_local_iterator>::type
|
||||
const_local_iterator_category;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_difference<const_local_iterator>::type
|
||||
const_local_iterator_difference;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_pointer<const_local_iterator>::type
|
||||
const_local_iterator_pointer;
|
||||
typedef BOOST_DEDUCED_TYPENAME
|
||||
boost::iterator_reference<const_local_iterator>::type
|
||||
const_local_iterator_reference;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::BOOST_ITERATOR_CATEGORY<
|
||||
const_local_iterator>::type const_local_iterator_category;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_difference<
|
||||
const_local_iterator>::type const_local_iterator_difference;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::iterator_pointer<
|
||||
const_local_iterator>::type 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;
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<Key, key_type>::value));
|
||||
//boost::function_requires<boost::CopyConstructibleConcept<key_type> >();
|
||||
//boost::function_requires<boost::AssignableConcept<key_type> >();
|
||||
// boost::function_requires<boost::CopyConstructibleConcept<key_type> >();
|
||||
// boost::function_requires<boost::AssignableConcept<key_type> >();
|
||||
|
||||
BOOST_STATIC_ASSERT((boost::is_same<Hash, hasher>::value));
|
||||
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));
|
||||
|
||||
boost::function_requires<boost::InputIteratorConcept<local_iterator> >();
|
||||
BOOST_STATIC_ASSERT((boost::is_same<local_iterator_category,
|
||||
iterator_category>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<local_iterator_difference,
|
||||
iterator_difference>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<local_iterator_pointer,
|
||||
iterator_pointer>::value));
|
||||
BOOST_STATIC_ASSERT((boost::is_same<local_iterator_reference,
|
||||
iterator_reference>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<local_iterator_category, iterator_category>::value));
|
||||
BOOST_STATIC_ASSERT((
|
||||
boost::is_same<local_iterator_difference, iterator_difference>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<local_iterator_pointer, iterator_pointer>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<local_iterator_reference, iterator_reference>::value));
|
||||
|
||||
boost::function_requires<
|
||||
boost::InputIteratorConcept<const_local_iterator> >();
|
||||
@@ -456,9 +435,9 @@ void unordered_test(X& x, Key& k, Hash& hf, Pred& eq)
|
||||
test::check_return_type<const_iterator>::equals(b.find(k));
|
||||
test::check_return_type<size_type>::equals(b.count(k));
|
||||
test::check_return_type<std::pair<iterator, iterator> >::equals(
|
||||
a.equal_range(k));
|
||||
a.equal_range(k));
|
||||
test::check_return_type<std::pair<const_iterator, const_iterator> >::equals(
|
||||
b.equal_range(k));
|
||||
b.equal_range(k));
|
||||
test::check_return_type<size_type>::equals(b.bucket_count());
|
||||
test::check_return_type<size_type>::equals(b.max_bucket_count());
|
||||
test::check_return_type<size_type>::equals(b.bucket(k));
|
||||
@@ -476,9 +455,9 @@ 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.max_load_factor());
|
||||
a.max_load_factor((float) 2.0);
|
||||
a.max_load_factor((float)2.0);
|
||||
a.rehash(100);
|
||||
|
||||
|
||||
// Avoid unused variable warnings:
|
||||
|
||||
sink(a);
|
||||
@@ -525,10 +504,10 @@ void unordered_copyable_test(X& x, Key& k, T& t, Hash& hf, Pred& eq)
|
||||
X(i, j, 10, m);
|
||||
X a7a(i, j, 10, m);
|
||||
|
||||
// Not specified for some reason (maybe ambiguity with another constructor?)
|
||||
//X(i, j, m);
|
||||
//X a8a(i, j, m);
|
||||
//sink(a8a);
|
||||
// Not specified for some reason (maybe ambiguity with another constructor?)
|
||||
// X(i, j, m);
|
||||
// X a8a(i, j, m);
|
||||
// sink(a8a);
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
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, hf);
|
||||
X({t}, min_buckets, hf, eq);
|
||||
//X({t}, m);
|
||||
// X({t}, m);
|
||||
X({t}, min_buckets, m);
|
||||
X({t}, min_buckets, hf, 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)
|
||||
std::initializer_list<T> list = {t};
|
||||
a.insert(list);
|
||||
a.insert({t,t,t});
|
||||
a.insert({t, t, t});
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1900)
|
||||
a.insert({});
|
||||
a.insert({t});
|
||||
a.insert({t,t});
|
||||
a.insert({t, t});
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -606,7 +585,7 @@ void unordered_movable_test(X& x, Key& k, T& /* t */, Hash& hf, Pred& eq)
|
||||
X a;
|
||||
allocator_type m = a.get_allocator();
|
||||
|
||||
test::minimal::constructor_param* i = 0;
|
||||
test::minimal::constructor_param* i = 0;
|
||||
test::minimal::constructor_param* j = 0;
|
||||
|
||||
// Constructors
|
||||
@@ -628,9 +607,9 @@ void unordered_movable_test(X& x, Key& k, T& /* t */, Hash& hf, Pred& eq)
|
||||
X a7a(i, j, 10, m);
|
||||
|
||||
// Not specified for some reason (maybe ambiguity with another constructor?)
|
||||
//X(i, j, m);
|
||||
//X a8a(i, j, m);
|
||||
//sink(a8a);
|
||||
// X(i, j, m);
|
||||
// X a8a(i, j, m);
|
||||
// sink(a8a);
|
||||
|
||||
const_iterator q = a.cbegin();
|
||||
|
||||
@@ -644,10 +623,9 @@ void unordered_movable_test(X& x, Key& k, T& /* t */, Hash& hf, Pred& eq)
|
||||
a.insert(boost::move(v2));
|
||||
T v3(v);
|
||||
test::check_return_type<iterator>::equals(
|
||||
a.emplace_hint(q, boost::move(v3)));
|
||||
a.emplace_hint(q, boost::move(v3)));
|
||||
T v4(v);
|
||||
test::check_return_type<iterator>::equals(
|
||||
a.insert(q, boost::move(v4)));
|
||||
test::check_return_type<iterator>::equals(a.insert(q, boost::move(v4)));
|
||||
|
||||
a.insert(i, j);
|
||||
|
||||
@@ -670,8 +648,7 @@ void unordered_movable_test(X& x, Key& k, T& /* t */, Hash& hf, Pred& eq)
|
||||
sink(a10);
|
||||
}
|
||||
|
||||
template <class X, class T>
|
||||
void unordered_set_member_test(X& x, T& t)
|
||||
template <class X, class T> void unordered_set_member_test(X& x, T& t)
|
||||
{
|
||||
X x1(x);
|
||||
x1.insert(t);
|
||||
@@ -679,8 +656,7 @@ void unordered_set_member_test(X& x, T& t)
|
||||
x1.cbegin()->dummy_member();
|
||||
}
|
||||
|
||||
template <class X, class T>
|
||||
void unordered_map_member_test(X& x, T& t)
|
||||
template <class X, class T> void unordered_map_member_test(X& x, T& t)
|
||||
{
|
||||
X x1(x);
|
||||
x1.insert(t);
|
||||
|
||||
@@ -22,14 +22,13 @@ namespace constructor_tests {
|
||||
|
||||
test::seed_t initialize_seed(356730);
|
||||
|
||||
template <class T>
|
||||
void constructor_tests1(T*, test::random_generator generator)
|
||||
template <class T> void constructor_tests1(T*, test::random_generator generator)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf;
|
||||
BOOST_DEDUCED_TYPENAME T::key_equal eq;
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al;
|
||||
|
||||
std::cerr<<"Construct 1\n";
|
||||
std::cerr << "Construct 1\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -41,7 +40,7 @@ void constructor_tests1(T*, test::random_generator generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 2\n";
|
||||
std::cerr << "Construct 2\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -54,7 +53,7 @@ void constructor_tests1(T*, test::random_generator generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 3\n";
|
||||
std::cerr << "Construct 3\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -67,7 +66,7 @@ void constructor_tests1(T*, test::random_generator generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 4\n";
|
||||
std::cerr << "Construct 4\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -79,7 +78,7 @@ void constructor_tests1(T*, test::random_generator generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 5\n";
|
||||
std::cerr << "Construct 5\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -93,7 +92,7 @@ void constructor_tests1(T*, test::random_generator generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 6\n";
|
||||
std::cerr << "Construct 6\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -107,7 +106,7 @@ void constructor_tests1(T*, test::random_generator generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 7\n";
|
||||
std::cerr << "Construct 7\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -121,7 +120,7 @@ void constructor_tests1(T*, test::random_generator generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 8\n";
|
||||
std::cerr << "Construct 8\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -134,7 +133,7 @@ void constructor_tests1(T*, test::random_generator generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 9\n";
|
||||
std::cerr << "Construct 9\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -146,7 +145,7 @@ void constructor_tests1(T*, test::random_generator generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 10\n";
|
||||
std::cerr << "Construct 10\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -160,7 +159,7 @@ void constructor_tests1(T*, test::random_generator generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 11\n";
|
||||
std::cerr << "Construct 11\n";
|
||||
{
|
||||
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 al2(2);
|
||||
|
||||
std::cerr<<"Construct 1\n";
|
||||
std::cerr << "Construct 1\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
T x(10000, hf1, eq1);
|
||||
@@ -197,7 +196,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 2\n";
|
||||
std::cerr << "Construct 2\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
T x(100, hf1);
|
||||
@@ -209,7 +208,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 3\n";
|
||||
std::cerr << "Construct 3\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
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);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 4\n";
|
||||
std::cerr << "Construct 4\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
std::cerr<<"Construct 5\n";
|
||||
std::cerr << "Construct 5\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
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);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 6\n";
|
||||
std::cerr << "Construct 6\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
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);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 7\n";
|
||||
std::cerr << "Construct 7\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
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);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 8 - from input iterator\n";
|
||||
std::cerr << "Construct 8 - from input iterator\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
test::random_values<T> v(100, generator);
|
||||
BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
|
||||
v_begin = v.begin(), v_end = v.end();
|
||||
T x(test::input_iterator(v_begin),
|
||||
test::input_iterator(v_end), 0, hf1, eq1);
|
||||
BOOST_DEDUCED_TYPENAME T::const_iterator
|
||||
x_begin = x.begin(), x_end = x.end();
|
||||
T y(test::input_iterator(x_begin),
|
||||
test::input_iterator(x_end), 0, hf2, eq2);
|
||||
v_begin = v.begin(),
|
||||
v_end = v.end();
|
||||
T x(test::input_iterator(v_begin), test::input_iterator(v_end), 0, hf1,
|
||||
eq1);
|
||||
BOOST_DEDUCED_TYPENAME T::const_iterator x_begin = x.begin(),
|
||||
x_end = x.end();
|
||||
T y(test::input_iterator(x_begin), test::input_iterator(x_end), 0, hf2,
|
||||
eq2);
|
||||
test::check_container(x, v);
|
||||
test::check_container(y, x);
|
||||
test::check_equivalent_keys(x);
|
||||
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::random_values<T> v(100, generator);
|
||||
T x(test::copy_iterator(v.begin()),
|
||||
test::copy_iterator(v.end()), 0, hf1, eq1);
|
||||
T y(test::copy_iterator(x.begin()),
|
||||
test::copy_iterator(x.end()), 0, hf2, eq2);
|
||||
T x(test::copy_iterator(v.begin()), test::copy_iterator(v.end()), 0,
|
||||
hf1, eq1);
|
||||
T y(test::copy_iterator(x.begin()), test::copy_iterator(x.end()), 0,
|
||||
hf2, eq2);
|
||||
test::check_container(x, v);
|
||||
test::check_container(y, x);
|
||||
test::check_equivalent_keys(x);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
std::cerr<<"Construct 9\n";
|
||||
|
||||
std::cerr << "Construct 9\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -320,8 +319,8 @@ void constructor_tests2(T*, test::random_generator const& generator)
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_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_;
|
||||
|
||||
@@ -332,7 +331,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
|
||||
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_;
|
||||
|
||||
@@ -344,7 +343,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
|
||||
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_;
|
||||
|
||||
@@ -356,7 +355,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
|
||||
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_;
|
||||
|
||||
@@ -368,7 +367,7 @@ void constructor_tests2(T*, test::random_generator const& generator)
|
||||
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_;
|
||||
|
||||
@@ -385,14 +384,11 @@ void constructor_tests2(T*, test::random_generator const& generator)
|
||||
template <class T>
|
||||
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<
|
||||
std::pair<
|
||||
BOOST_DEDUCED_TYPENAME T::key_type,
|
||||
BOOST_DEDUCED_TYPENAME T::mapped_type
|
||||
>
|
||||
> list;
|
||||
typedef test::list<std::pair<BOOST_DEDUCED_TYPENAME T::key_type,
|
||||
BOOST_DEDUCED_TYPENAME T::mapped_type> >
|
||||
list;
|
||||
test::random_values<T> v(1000, generator);
|
||||
list l(v.begin(), v.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);
|
||||
}
|
||||
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
std::allocator<test::object> >* test_map_std_alloc;
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_multimap;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator1<test::object> >* test_multimap;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(constructor_tests1,
|
||||
((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(constructor_tests2,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
((test_set)(test_multiset)(test_map)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(map_constructor_test,
|
||||
((test_map_std_alloc)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
((test_map_std_alloc)(test_map)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
||||
UNORDERED_AUTO_TEST(test_default_initializer_list) {
|
||||
std::cerr<<"Initializer List Tests\n";
|
||||
UNORDERED_AUTO_TEST(test_default_initializer_list)
|
||||
{
|
||||
std::cerr << "Initializer List Tests\n";
|
||||
std::initializer_list<int> init;
|
||||
boost::unordered_set<int> x1 = init;
|
||||
BOOST_TEST(x1.empty());
|
||||
@@ -450,15 +439,15 @@ UNORDERED_AUTO_TEST(test_default_initializer_list) {
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
||||
UNORDERED_AUTO_TEST(test_initializer_list) {
|
||||
std::cerr<<"Initializer List Tests\n";
|
||||
boost::unordered_set<int> x1 = { 2, 10, 45, -5 };
|
||||
UNORDERED_AUTO_TEST(test_initializer_list)
|
||||
{
|
||||
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(46) == x1.end());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
|
||||
test::seed_t initialize_seed(9063);
|
||||
|
||||
namespace copy_tests
|
||||
{
|
||||
namespace copy_tests {
|
||||
|
||||
template <class T>
|
||||
void copy_construct_tests1(T*, test::random_generator const& generator)
|
||||
@@ -30,7 +29,7 @@ void copy_construct_tests1(T*, test::random_generator const& generator)
|
||||
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf;
|
||||
BOOST_DEDUCED_TYPENAME T::key_equal eq;
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al;
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al;
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
@@ -43,7 +42,7 @@ void copy_construct_tests1(T*, test::random_generator const& generator)
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
|
||||
BOOST_TEST(test::selected_count(y.get_allocator()) ==
|
||||
(allocator_type::is_select_on_copy));
|
||||
(allocator_type::is_select_on_copy));
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
@@ -57,7 +56,7 @@ void copy_construct_tests1(T*, test::random_generator const& generator)
|
||||
test::unordered_equivalence_tester<T> equivalent(x);
|
||||
BOOST_TEST(equivalent(y));
|
||||
BOOST_TEST(test::selected_count(y.get_allocator()) ==
|
||||
(allocator_type::is_select_on_copy));
|
||||
(allocator_type::is_select_on_copy));
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
@@ -77,7 +76,7 @@ void copy_construct_tests1(T*, test::random_generator const& generator)
|
||||
// This isn't guaranteed:
|
||||
BOOST_TEST(y.load_factor() < y.max_load_factor());
|
||||
BOOST_TEST(test::selected_count(y.get_allocator()) ==
|
||||
(allocator_type::is_select_on_copy));
|
||||
(allocator_type::is_select_on_copy));
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
}
|
||||
@@ -89,7 +88,7 @@ void copy_construct_tests2(T*, test::random_generator const& generator)
|
||||
BOOST_DEDUCED_TYPENAME T::key_equal eq(1);
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al(1);
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al2(2);
|
||||
|
||||
|
||||
typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type;
|
||||
|
||||
{
|
||||
@@ -103,7 +102,7 @@ void copy_construct_tests2(T*, test::random_generator const& generator)
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||
BOOST_TEST(x.max_load_factor() == y.max_load_factor());
|
||||
BOOST_TEST(test::selected_count(y.get_allocator()) ==
|
||||
(allocator_type::is_select_on_copy));
|
||||
(allocator_type::is_select_on_copy));
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
@@ -132,7 +131,7 @@ void copy_construct_tests2(T*, test::random_generator const& generator)
|
||||
BOOST_TEST(equivalent(y));
|
||||
test::check_equivalent_keys(y);
|
||||
BOOST_TEST(test::selected_count(y.get_allocator()) ==
|
||||
(allocator_type::is_select_on_copy));
|
||||
(allocator_type::is_select_on_copy));
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||
}
|
||||
|
||||
@@ -151,73 +150,60 @@ void copy_construct_tests2(T*, test::random_generator const& generator)
|
||||
}
|
||||
}
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_multimap;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator2<test::object> >* test_multimap;
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::select_copy> >*
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::select_copy> >*
|
||||
test_set_select_copy;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::select_copy> >*
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::select_copy> >*
|
||||
test_multiset_select_copy;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::select_copy> >*
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::select_copy> >*
|
||||
test_map_select_copy;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::select_copy> >*
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::cxx11_allocator<test::object, test::select_copy> >*
|
||||
test_multimap_select_copy;
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_select_copy> >*
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_select_copy> >*
|
||||
test_set_no_select_copy;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_select_copy> >*
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_select_copy> >*
|
||||
test_multiset_no_select_copy;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_select_copy> >*
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_select_copy> >*
|
||||
test_map_no_select_copy;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_select_copy> >*
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::cxx11_allocator<test::object, test::no_select_copy> >*
|
||||
test_multimap_no_select_copy;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(copy_construct_tests1, (
|
||||
(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))
|
||||
)
|
||||
UNORDERED_TEST(copy_construct_tests1,
|
||||
((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()
|
||||
|
||||
+400
-368
@@ -15,424 +15,456 @@
|
||||
#include "../helpers/count.hpp"
|
||||
#include <string>
|
||||
|
||||
|
||||
// Test that various emplace methods work with different numbers of
|
||||
// arguments.
|
||||
|
||||
namespace emplace_tests {
|
||||
// Constructible with 2 to 10 arguments
|
||||
struct emplace_value : private test::counted_object {
|
||||
typedef int A0;
|
||||
typedef std::string A1;
|
||||
typedef char A2;
|
||||
typedef int A3;
|
||||
typedef int A4;
|
||||
typedef int A5;
|
||||
typedef int A6;
|
||||
typedef int A7;
|
||||
typedef int A8;
|
||||
typedef int A9;
|
||||
// Constructible with 2 to 10 arguments
|
||||
struct emplace_value : private test::counted_object
|
||||
{
|
||||
typedef int A0;
|
||||
typedef std::string A1;
|
||||
typedef char A2;
|
||||
typedef int A3;
|
||||
typedef int A4;
|
||||
typedef int A5;
|
||||
typedef int A6;
|
||||
typedef int A7;
|
||||
typedef int A8;
|
||||
typedef int A9;
|
||||
|
||||
int arg_count;
|
||||
int arg_count;
|
||||
|
||||
A0 a0;
|
||||
A1 a1;
|
||||
A2 a2;
|
||||
A3 a3;
|
||||
A4 a4;
|
||||
A5 a5;
|
||||
A6 a6;
|
||||
A7 a7;
|
||||
A8 a8;
|
||||
A9 a9;
|
||||
A0 a0;
|
||||
A1 a1;
|
||||
A2 a2;
|
||||
A3 a3;
|
||||
A4 a4;
|
||||
A5 a5;
|
||||
A6 a6;
|
||||
A7 a7;
|
||||
A8 a8;
|
||||
A9 a9;
|
||||
|
||||
emplace_value(
|
||||
A0 const& b0, A1 const& b1) :
|
||||
arg_count(2),
|
||||
a0(b0), a1(b1) {}
|
||||
emplace_value(A0 const& b0, A1 const& b1) : arg_count(2), a0(b0), a1(b1) {}
|
||||
|
||||
emplace_value(
|
||||
A0 const& b0, A1 const& b1, A2 const& b2) :
|
||||
arg_count(3),
|
||||
a0(b0), a1(b1), a2(b2) {}
|
||||
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2)
|
||||
: 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(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(
|
||||
A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
|
||||
A4 const& b4) :
|
||||
arg_count(5),
|
||||
a0(b0), a1(b1), a2(b2), a3(b3), a4(b4) {}
|
||||
emplace_value(
|
||||
A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3, A4 const& b4)
|
||||
: arg_count(5), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4)
|
||||
{
|
||||
}
|
||||
|
||||
emplace_value(
|
||||
A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
|
||||
A4 const& b4, A5 const& b5) :
|
||||
arg_count(6),
|
||||
a0(b0), a1(b1), a2(b2), a3(b3), a4(b4),
|
||||
a5(b5) {}
|
||||
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
|
||||
A4 const& b4, A5 const& b5)
|
||||
: arg_count(6), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5)
|
||||
{
|
||||
}
|
||||
|
||||
emplace_value(
|
||||
A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
|
||||
A4 const& b4, A5 const& b5, A6 const& b6) :
|
||||
arg_count(7),
|
||||
a0(b0), a1(b1), a2(b2), a3(b3), a4(b4),
|
||||
a5(b5), a6(b6) {}
|
||||
emplace_value(A0 const& b0, A1 const& b1, A2 const& b2, A3 const& b3,
|
||||
A4 const& b4, A5 const& b5, A6 const& b6)
|
||||
: arg_count(7), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6)
|
||||
{
|
||||
}
|
||||
|
||||
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) :
|
||||
arg_count(8),
|
||||
a0(b0), a1(b1), a2(b2), a3(b3), a4(b4),
|
||||
a5(b5), a6(b6), a7(b7) {}
|
||||
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)
|
||||
: arg_count(8), a0(b0), a1(b1), a2(b2), a3(b3), a4(b4), a5(b5), a6(b6),
|
||||
a7(b7)
|
||||
{
|
||||
}
|
||||
|
||||
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) :
|
||||
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)
|
||||
: 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) {}
|
||||
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;
|
||||
if (x.arg_count >= 1)
|
||||
boost::hash_combine(r1, x.a0);
|
||||
if (x.arg_count >= 2)
|
||||
boost::hash_combine(r1, x.a1);
|
||||
if (x.arg_count >= 3)
|
||||
boost::hash_combine(r1, x.a2);
|
||||
if (x.arg_count >= 4)
|
||||
boost::hash_combine(r1, x.a3);
|
||||
if (x.arg_count >= 5)
|
||||
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;
|
||||
}
|
||||
|
||||
friend std::size_t hash_value(emplace_value const& x) {
|
||||
std::size_t r1 = 23894278u;
|
||||
if (x.arg_count >= 1) boost::hash_combine(r1, x.a0);
|
||||
if (x.arg_count >= 2) boost::hash_combine(r1, x.a1);
|
||||
if (x.arg_count >= 3) boost::hash_combine(r1, x.a2);
|
||||
if (x.arg_count >= 4) boost::hash_combine(r1, x.a3);
|
||||
if (x.arg_count >= 5) 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;
|
||||
friend bool operator==(emplace_value const& x, emplace_value const& y)
|
||||
{
|
||||
if (x.arg_count != y.arg_count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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 >= 2 && x.a1 != y.a1) { 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;
|
||||
if (x.arg_count >= 1 && x.a0 != y.a0) {
|
||||
return false;
|
||||
}
|
||||
private:
|
||||
emplace_value();
|
||||
emplace_value(emplace_value const&);
|
||||
};
|
||||
|
||||
UNORDERED_AUTO_TEST(emplace_set) {
|
||||
test::check_instances check_;
|
||||
|
||||
typedef boost::unordered_set<emplace_value,
|
||||
boost::hash<emplace_value> > container;
|
||||
typedef container::iterator iterator;
|
||||
typedef std::pair<iterator, bool> return_type;
|
||||
container x(10);
|
||||
iterator i1;
|
||||
return_type r1,r2;
|
||||
|
||||
// 2 args
|
||||
|
||||
emplace_value v1(10, "x");
|
||||
r1 = x.emplace(10, std::string("x"));
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
BOOST_TEST(r1.second);
|
||||
BOOST_TEST(*r1.first == v1);
|
||||
BOOST_TEST(r1.first == x.find(v1));
|
||||
BOOST_TEST_EQ(check_.instances(), 2);
|
||||
BOOST_TEST_EQ(check_.constructions(), 2);
|
||||
|
||||
// 3 args
|
||||
|
||||
emplace_value v2(3, "foo", 'a');
|
||||
r1 = x.emplace(3, "foo", 'a');
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
BOOST_TEST(r1.second);
|
||||
BOOST_TEST(*r1.first == v2);
|
||||
BOOST_TEST(r1.first == x.find(v2));
|
||||
BOOST_TEST_EQ(check_.instances(), 4);
|
||||
BOOST_TEST_EQ(check_.constructions(), 4);
|
||||
|
||||
// 7 args with hint + duplicate
|
||||
|
||||
emplace_value v3(25, "something", 'z', 4, 5, 6, 7);
|
||||
i1 = x.emplace_hint(r1.first, 25, "something", 'z', 4, 5, 6, 7);
|
||||
BOOST_TEST_EQ(x.size(), 3u);
|
||||
BOOST_TEST(*i1 == v3);
|
||||
BOOST_TEST(i1 == x.find(v3));
|
||||
BOOST_TEST_EQ(check_.instances(), 6);
|
||||
BOOST_TEST_EQ(check_.constructions(), 6);
|
||||
|
||||
r2 = x.emplace(25, "something", 'z', 4, 5, 6, 7);
|
||||
BOOST_TEST_EQ(x.size(), 3u);
|
||||
BOOST_TEST(!r2.second);
|
||||
BOOST_TEST(i1 == r2.first);
|
||||
// The container has to construct an object in order to check
|
||||
// whether it can emplace, so there's an extra cosntruction
|
||||
// here.
|
||||
BOOST_TEST_EQ(check_.instances(), 6);
|
||||
BOOST_TEST_EQ(check_.constructions(), 7);
|
||||
|
||||
// 10 args + hint duplicate
|
||||
|
||||
std::string s1;
|
||||
emplace_value v4(10, s1, 'a', 4, 5, 6, 7, 8, 9, 10);
|
||||
r1 = x.emplace(10, s1, 'a', 4, 5, 6, 7, 8, 9, 10);
|
||||
BOOST_TEST_EQ(x.size(), 4u);
|
||||
BOOST_TEST(r1.second);
|
||||
BOOST_TEST(*r1.first == v4);
|
||||
BOOST_TEST(r1.first == x.find(v4));
|
||||
BOOST_TEST_EQ(check_.instances(), 8);
|
||||
BOOST_TEST_EQ(check_.constructions(), 9);
|
||||
|
||||
BOOST_TEST(r1.first ==
|
||||
x.emplace_hint(r1.first, 10, "", 'a', 4, 5, 6, 7, 8, 9, 10));
|
||||
BOOST_TEST(r1.first ==
|
||||
x.emplace_hint(r2.first, 10, "", 'a', 4, 5, 6, 7, 8, 9, 10));
|
||||
BOOST_TEST(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_.constructions(), 12);
|
||||
|
||||
BOOST_TEST_EQ(x.size(), 4u);
|
||||
BOOST_TEST(x.count(v1) == 1);
|
||||
BOOST_TEST(x.count(v2) == 1);
|
||||
BOOST_TEST(x.count(v3) == 1);
|
||||
BOOST_TEST(x.count(v4) == 1);
|
||||
if (x.arg_count >= 2 && x.a1 != y.a1) {
|
||||
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;
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(emplace_multiset) {
|
||||
test::check_instances check_;
|
||||
private:
|
||||
emplace_value();
|
||||
emplace_value(emplace_value const&);
|
||||
};
|
||||
|
||||
typedef boost::unordered_multiset<emplace_value,
|
||||
boost::hash<emplace_value> > container;
|
||||
typedef container::iterator iterator;
|
||||
container x(10);
|
||||
iterator i1, i2;
|
||||
UNORDERED_AUTO_TEST(emplace_set)
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
// 2 args.
|
||||
typedef boost::unordered_set<emplace_value, boost::hash<emplace_value> >
|
||||
container;
|
||||
typedef container::iterator iterator;
|
||||
typedef std::pair<iterator, bool> return_type;
|
||||
container x(10);
|
||||
iterator i1;
|
||||
return_type r1, r2;
|
||||
|
||||
emplace_value v1(10, "x");
|
||||
i1 = x.emplace(10, std::string("x"));
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
BOOST_TEST(i1 == x.find(v1));
|
||||
BOOST_TEST_EQ(check_.instances(), 2);
|
||||
BOOST_TEST_EQ(check_.constructions(), 2);
|
||||
// 2 args
|
||||
|
||||
// 4 args + duplicate
|
||||
emplace_value v1(10, "x");
|
||||
r1 = x.emplace(10, std::string("x"));
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
BOOST_TEST(r1.second);
|
||||
BOOST_TEST(*r1.first == v1);
|
||||
BOOST_TEST(r1.first == x.find(v1));
|
||||
BOOST_TEST_EQ(check_.instances(), 2);
|
||||
BOOST_TEST_EQ(check_.constructions(), 2);
|
||||
|
||||
emplace_value v2(4, "foo", 'a', 15);
|
||||
i1 = x.emplace(4, "foo", 'a', 15);
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
BOOST_TEST(i1 == x.find(v2));
|
||||
BOOST_TEST_EQ(check_.instances(), 4);
|
||||
BOOST_TEST_EQ(check_.constructions(), 4);
|
||||
// 3 args
|
||||
|
||||
i2 = x.emplace(4, "foo", 'a', 15);
|
||||
BOOST_TEST_EQ(x.size(), 3u);
|
||||
BOOST_TEST(i1 != i2);
|
||||
BOOST_TEST(*i1 == *i2);
|
||||
BOOST_TEST(x.count(*i1) == 2);
|
||||
BOOST_TEST_EQ(check_.instances(), 5);
|
||||
BOOST_TEST_EQ(check_.constructions(), 5);
|
||||
emplace_value v2(3, "foo", 'a');
|
||||
r1 = x.emplace(3, "foo", 'a');
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
BOOST_TEST(r1.second);
|
||||
BOOST_TEST(*r1.first == v2);
|
||||
BOOST_TEST(r1.first == x.find(v2));
|
||||
BOOST_TEST_EQ(check_.instances(), 4);
|
||||
BOOST_TEST_EQ(check_.constructions(), 4);
|
||||
|
||||
// 7 args + duplicate using hint.
|
||||
// 7 args with hint + duplicate
|
||||
|
||||
emplace_value v3(7, "", 'z', 4, 5, 6, 7);
|
||||
i1 = x.emplace(7, "", 'z', 4, 5, 6, 7);
|
||||
BOOST_TEST_EQ(x.size(), 4u);
|
||||
BOOST_TEST_EQ(i1->a2, 'z');
|
||||
BOOST_TEST(x.count(*i1) == 1);
|
||||
BOOST_TEST(i1 == x.find(v3));
|
||||
BOOST_TEST_EQ(check_.instances(), 7);
|
||||
BOOST_TEST_EQ(check_.constructions(), 7);
|
||||
emplace_value v3(25, "something", 'z', 4, 5, 6, 7);
|
||||
i1 = x.emplace_hint(r1.first, 25, "something", 'z', 4, 5, 6, 7);
|
||||
BOOST_TEST_EQ(x.size(), 3u);
|
||||
BOOST_TEST(*i1 == v3);
|
||||
BOOST_TEST(i1 == x.find(v3));
|
||||
BOOST_TEST_EQ(check_.instances(), 6);
|
||||
BOOST_TEST_EQ(check_.constructions(), 6);
|
||||
|
||||
i2 = x.emplace_hint(i1, 7, "", 'z', 4, 5, 6, 7);
|
||||
BOOST_TEST_EQ(x.size(), 5u);
|
||||
BOOST_TEST(*i1 == *i2);
|
||||
BOOST_TEST(i1 != i2);
|
||||
BOOST_TEST(x.count(*i1) == 2);
|
||||
BOOST_TEST_EQ(check_.instances(), 8);
|
||||
BOOST_TEST_EQ(check_.constructions(), 8);
|
||||
r2 = x.emplace(25, "something", 'z', 4, 5, 6, 7);
|
||||
BOOST_TEST_EQ(x.size(), 3u);
|
||||
BOOST_TEST(!r2.second);
|
||||
BOOST_TEST(i1 == r2.first);
|
||||
// The container has to construct an object in order to check
|
||||
// whether it can emplace, so there's an extra cosntruction
|
||||
// here.
|
||||
BOOST_TEST_EQ(check_.instances(), 6);
|
||||
BOOST_TEST_EQ(check_.constructions(), 7);
|
||||
|
||||
// 10 args with bad hint + duplicate
|
||||
// 10 args + hint duplicate
|
||||
|
||||
emplace_value v4(10, "", 'a', 4, 5, 6, 7, 8, 9, 10);
|
||||
i1 = x.emplace_hint(i2, 10, "", 'a', 4, 5, 6, 7, 8, 9, 10);
|
||||
BOOST_TEST_EQ(x.size(), 6u);
|
||||
BOOST_TEST_EQ(i1->arg_count, 10);
|
||||
BOOST_TEST(i1 == x.find(v4));
|
||||
BOOST_TEST_EQ(check_.instances(), 10);
|
||||
BOOST_TEST_EQ(check_.constructions(), 10);
|
||||
std::string s1;
|
||||
emplace_value v4(10, s1, 'a', 4, 5, 6, 7, 8, 9, 10);
|
||||
r1 = x.emplace(10, s1, 'a', 4, 5, 6, 7, 8, 9, 10);
|
||||
BOOST_TEST_EQ(x.size(), 4u);
|
||||
BOOST_TEST(r1.second);
|
||||
BOOST_TEST(*r1.first == v4);
|
||||
BOOST_TEST(r1.first == x.find(v4));
|
||||
BOOST_TEST_EQ(check_.instances(), 8);
|
||||
BOOST_TEST_EQ(check_.constructions(), 9);
|
||||
|
||||
i2 = x.emplace_hint(x.end(), 10, "", 'a', 4, 5, 6, 7, 8, 9, 10);
|
||||
BOOST_TEST_EQ(x.size(), 7u);
|
||||
BOOST_TEST(*i1 == *i2);
|
||||
BOOST_TEST(i1 != i2);
|
||||
BOOST_TEST(x.count(*i1) == 2);
|
||||
BOOST_TEST_EQ(check_.instances(), 11);
|
||||
BOOST_TEST_EQ(check_.constructions(), 11);
|
||||
BOOST_TEST(r1.first ==
|
||||
x.emplace_hint(r1.first, 10, "", 'a', 4, 5, 6, 7, 8, 9, 10));
|
||||
BOOST_TEST(r1.first ==
|
||||
x.emplace_hint(r2.first, 10, "", 'a', 4, 5, 6, 7, 8, 9, 10));
|
||||
BOOST_TEST(
|
||||
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_.constructions(), 12);
|
||||
|
||||
BOOST_TEST_EQ(x.count(v1), 1u);
|
||||
BOOST_TEST_EQ(x.count(v2), 2u);
|
||||
BOOST_TEST_EQ(x.count(v3), 2u);
|
||||
}
|
||||
BOOST_TEST_EQ(x.size(), 4u);
|
||||
BOOST_TEST(x.count(v1) == 1);
|
||||
BOOST_TEST(x.count(v2) == 1);
|
||||
BOOST_TEST(x.count(v3) == 1);
|
||||
BOOST_TEST(x.count(v4) == 1);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(emplace_map) {
|
||||
test::check_instances check_;
|
||||
UNORDERED_AUTO_TEST(emplace_multiset)
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
typedef boost::unordered_map<emplace_value, emplace_value,
|
||||
boost::hash<emplace_value> > container;
|
||||
typedef container::iterator iterator;
|
||||
typedef std::pair<iterator, bool> return_type;
|
||||
container x(10);
|
||||
return_type r1, r2;
|
||||
typedef boost::unordered_multiset<emplace_value,
|
||||
boost::hash<emplace_value> >
|
||||
container;
|
||||
typedef container::iterator iterator;
|
||||
container x(10);
|
||||
iterator i1, i2;
|
||||
|
||||
// 5/8 args + duplicate
|
||||
// 2 args.
|
||||
|
||||
emplace_value k1(5, "", 'b', 4, 5);
|
||||
emplace_value m1(8, "xxx", 'z', 4, 5, 6, 7, 8);
|
||||
r1 = x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(5, "", 'b', 4, 5),
|
||||
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
BOOST_TEST(r1.second);
|
||||
BOOST_TEST(x.find(k1) == r1.first);
|
||||
BOOST_TEST(x.find(k1)->second == m1);
|
||||
BOOST_TEST_EQ(check_.instances(), 4);
|
||||
BOOST_TEST_EQ(check_.constructions(), 4);
|
||||
emplace_value v1(10, "x");
|
||||
i1 = x.emplace(10, std::string("x"));
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
BOOST_TEST(i1 == x.find(v1));
|
||||
BOOST_TEST_EQ(check_.instances(), 2);
|
||||
BOOST_TEST_EQ(check_.constructions(), 2);
|
||||
|
||||
r2 = x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(5, "", 'b', 4, 5),
|
||||
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
BOOST_TEST(!r2.second);
|
||||
BOOST_TEST(r1.first == r2.first);
|
||||
BOOST_TEST(x.find(k1)->second == m1);
|
||||
BOOST_TEST_EQ(check_.instances(), 4);
|
||||
// constructions could possibly be 5 if the implementation only
|
||||
// constructed the key.
|
||||
BOOST_TEST_EQ(check_.constructions(), 6);
|
||||
// 4 args + duplicate
|
||||
|
||||
// 9/3 args + duplicates with hints, different mapped value.
|
||||
emplace_value v2(4, "foo", 'a', 15);
|
||||
i1 = x.emplace(4, "foo", 'a', 15);
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
BOOST_TEST(i1 == x.find(v2));
|
||||
BOOST_TEST_EQ(check_.instances(), 4);
|
||||
BOOST_TEST_EQ(check_.constructions(), 4);
|
||||
|
||||
emplace_value k2(9, "", 'b', 4, 5, 6, 7, 8, 9);
|
||||
emplace_value m2(3, "aaa", 'm');
|
||||
r1 = x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(3, "aaa", 'm'));
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
BOOST_TEST(r1.second);
|
||||
BOOST_TEST(r1.first->first.arg_count == 9);
|
||||
BOOST_TEST(r1.first->second.arg_count == 3);
|
||||
BOOST_TEST(x.find(k2) == r1.first);
|
||||
BOOST_TEST(x.find(k2)->second == m2);
|
||||
BOOST_TEST_EQ(check_.instances(), 8);
|
||||
BOOST_TEST_EQ(check_.constructions(), 10);
|
||||
i2 = x.emplace(4, "foo", 'a', 15);
|
||||
BOOST_TEST_EQ(x.size(), 3u);
|
||||
BOOST_TEST(i1 != i2);
|
||||
BOOST_TEST(*i1 == *i2);
|
||||
BOOST_TEST(x.count(*i1) == 2);
|
||||
BOOST_TEST_EQ(check_.instances(), 5);
|
||||
BOOST_TEST_EQ(check_.constructions(), 5);
|
||||
|
||||
BOOST_TEST(r1.first == x.emplace_hint(r1.first,
|
||||
boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(15, "jkjk")));
|
||||
BOOST_TEST(r1.first == x.emplace_hint(r2.first,
|
||||
boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(275, "xxx", 'm', 6)));
|
||||
BOOST_TEST(r1.first == x.emplace_hint(x.end(),
|
||||
boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(-10, "blah blah", '\0')));
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
BOOST_TEST(x.find(k2)->second == m2);
|
||||
BOOST_TEST_EQ(check_.instances(), 8);
|
||||
BOOST_TEST_EQ(check_.constructions(), 16);
|
||||
}
|
||||
// 7 args + duplicate using hint.
|
||||
|
||||
UNORDERED_AUTO_TEST(emplace_multimap) {
|
||||
test::check_instances check_;
|
||||
emplace_value v3(7, "", 'z', 4, 5, 6, 7);
|
||||
i1 = x.emplace(7, "", 'z', 4, 5, 6, 7);
|
||||
BOOST_TEST_EQ(x.size(), 4u);
|
||||
BOOST_TEST_EQ(i1->a2, 'z');
|
||||
BOOST_TEST(x.count(*i1) == 1);
|
||||
BOOST_TEST(i1 == x.find(v3));
|
||||
BOOST_TEST_EQ(check_.instances(), 7);
|
||||
BOOST_TEST_EQ(check_.constructions(), 7);
|
||||
|
||||
typedef boost::unordered_multimap<emplace_value, emplace_value,
|
||||
boost::hash<emplace_value> > container;
|
||||
typedef container::iterator iterator;
|
||||
container x(10);
|
||||
iterator i1, i2, i3, i4;
|
||||
i2 = x.emplace_hint(i1, 7, "", 'z', 4, 5, 6, 7);
|
||||
BOOST_TEST_EQ(x.size(), 5u);
|
||||
BOOST_TEST(*i1 == *i2);
|
||||
BOOST_TEST(i1 != i2);
|
||||
BOOST_TEST(x.count(*i1) == 2);
|
||||
BOOST_TEST_EQ(check_.instances(), 8);
|
||||
BOOST_TEST_EQ(check_.constructions(), 8);
|
||||
|
||||
// 5/8 args + duplicate
|
||||
// 10 args with bad hint + duplicate
|
||||
|
||||
emplace_value k1(5, "", 'b', 4, 5);
|
||||
emplace_value m1(8, "xxx", 'z', 4, 5, 6, 7, 8);
|
||||
i1 = x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(5, "", 'b', 4, 5),
|
||||
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
BOOST_TEST(x.find(k1) == i1);
|
||||
BOOST_TEST(x.find(k1)->second == m1);
|
||||
BOOST_TEST_EQ(check_.instances(), 4);
|
||||
BOOST_TEST_EQ(check_.constructions(), 4);
|
||||
emplace_value v4(10, "", 'a', 4, 5, 6, 7, 8, 9, 10);
|
||||
i1 = x.emplace_hint(i2, 10, "", 'a', 4, 5, 6, 7, 8, 9, 10);
|
||||
BOOST_TEST_EQ(x.size(), 6u);
|
||||
BOOST_TEST_EQ(i1->arg_count, 10);
|
||||
BOOST_TEST(i1 == x.find(v4));
|
||||
BOOST_TEST_EQ(check_.instances(), 10);
|
||||
BOOST_TEST_EQ(check_.constructions(), 10);
|
||||
|
||||
emplace_value m1a(8, "xxx", 'z', 4, 5, 6, 7, 8);
|
||||
i2 = x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(5, "", 'b', 4, 5),
|
||||
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
BOOST_TEST(i1 != i2);
|
||||
BOOST_TEST(i1->second == m1);
|
||||
BOOST_TEST(i2->second == m1a);
|
||||
BOOST_TEST_EQ(check_.instances(), 7);
|
||||
BOOST_TEST_EQ(check_.constructions(), 7);
|
||||
i2 = x.emplace_hint(x.end(), 10, "", 'a', 4, 5, 6, 7, 8, 9, 10);
|
||||
BOOST_TEST_EQ(x.size(), 7u);
|
||||
BOOST_TEST(*i1 == *i2);
|
||||
BOOST_TEST(i1 != i2);
|
||||
BOOST_TEST(x.count(*i1) == 2);
|
||||
BOOST_TEST_EQ(check_.instances(), 11);
|
||||
BOOST_TEST_EQ(check_.constructions(), 11);
|
||||
|
||||
// 9/3 args + duplicates with hints, different mapped value.
|
||||
BOOST_TEST_EQ(x.count(v1), 1u);
|
||||
BOOST_TEST_EQ(x.count(v2), 2u);
|
||||
BOOST_TEST_EQ(x.count(v3), 2u);
|
||||
}
|
||||
|
||||
emplace_value k2(9, "", 'b', 4, 5, 6, 7, 8, 9);
|
||||
emplace_value m2(3, "aaa", 'm');
|
||||
i1 = x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(3, "aaa", 'm'));
|
||||
BOOST_TEST_EQ(x.size(), 3u);
|
||||
BOOST_TEST(i1->first.arg_count == 9);
|
||||
BOOST_TEST(i1->second.arg_count == 3);
|
||||
BOOST_TEST_EQ(check_.instances(), 11);
|
||||
BOOST_TEST_EQ(check_.constructions(), 11);
|
||||
UNORDERED_AUTO_TEST(emplace_map)
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
emplace_value m2a(15, "jkjk");
|
||||
i2 = x.emplace_hint(i2,
|
||||
boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(15, "jkjk"));
|
||||
emplace_value m2b(275, "xxx", 'm', 6);
|
||||
i3 = x.emplace_hint(i1,
|
||||
boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(275, "xxx", 'm', 6));
|
||||
emplace_value m2c(-10, "blah blah", '\0');
|
||||
i4 = x.emplace_hint(x.end(),
|
||||
boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(-10, "blah blah", '\0'));
|
||||
BOOST_TEST_EQ(x.size(), 6u);
|
||||
BOOST_TEST(x.find(k2)->second == m2);
|
||||
BOOST_TEST_EQ(check_.instances(), 20);
|
||||
BOOST_TEST_EQ(check_.constructions(), 20);
|
||||
}
|
||||
typedef boost::unordered_map<emplace_value, emplace_value,
|
||||
boost::hash<emplace_value> >
|
||||
container;
|
||||
typedef container::iterator iterator;
|
||||
typedef std::pair<iterator, bool> return_type;
|
||||
container x(10);
|
||||
return_type r1, r2;
|
||||
|
||||
// 5/8 args + duplicate
|
||||
|
||||
emplace_value k1(5, "", 'b', 4, 5);
|
||||
emplace_value m1(8, "xxx", 'z', 4, 5, 6, 7, 8);
|
||||
r1 = x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(5, "", 'b', 4, 5),
|
||||
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
BOOST_TEST(r1.second);
|
||||
BOOST_TEST(x.find(k1) == r1.first);
|
||||
BOOST_TEST(x.find(k1)->second == m1);
|
||||
BOOST_TEST_EQ(check_.instances(), 4);
|
||||
BOOST_TEST_EQ(check_.constructions(), 4);
|
||||
|
||||
r2 = x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(5, "", 'b', 4, 5),
|
||||
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
BOOST_TEST(!r2.second);
|
||||
BOOST_TEST(r1.first == r2.first);
|
||||
BOOST_TEST(x.find(k1)->second == m1);
|
||||
BOOST_TEST_EQ(check_.instances(), 4);
|
||||
// constructions could possibly be 5 if the implementation only
|
||||
// constructed the key.
|
||||
BOOST_TEST_EQ(check_.constructions(), 6);
|
||||
|
||||
// 9/3 args + duplicates with hints, different mapped value.
|
||||
|
||||
emplace_value k2(9, "", 'b', 4, 5, 6, 7, 8, 9);
|
||||
emplace_value m2(3, "aaa", 'm');
|
||||
r1 = x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(3, "aaa", 'm'));
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
BOOST_TEST(r1.second);
|
||||
BOOST_TEST(r1.first->first.arg_count == 9);
|
||||
BOOST_TEST(r1.first->second.arg_count == 3);
|
||||
BOOST_TEST(x.find(k2) == r1.first);
|
||||
BOOST_TEST(x.find(k2)->second == m2);
|
||||
BOOST_TEST_EQ(check_.instances(), 8);
|
||||
BOOST_TEST_EQ(check_.constructions(), 10);
|
||||
|
||||
BOOST_TEST(r1.first ==
|
||||
x.emplace_hint(r1.first, boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(15, "jkjk")));
|
||||
BOOST_TEST(r1.first ==
|
||||
x.emplace_hint(r2.first, boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(275, "xxx", 'm', 6)));
|
||||
BOOST_TEST(r1.first ==
|
||||
x.emplace_hint(x.end(), boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(-10, "blah blah", '\0')));
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
BOOST_TEST(x.find(k2)->second == m2);
|
||||
BOOST_TEST_EQ(check_.instances(), 8);
|
||||
BOOST_TEST_EQ(check_.constructions(), 16);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(emplace_multimap)
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
typedef boost::unordered_multimap<emplace_value, emplace_value,
|
||||
boost::hash<emplace_value> >
|
||||
container;
|
||||
typedef container::iterator iterator;
|
||||
container x(10);
|
||||
iterator i1, i2, i3, i4;
|
||||
|
||||
// 5/8 args + duplicate
|
||||
|
||||
emplace_value k1(5, "", 'b', 4, 5);
|
||||
emplace_value m1(8, "xxx", 'z', 4, 5, 6, 7, 8);
|
||||
i1 = x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(5, "", 'b', 4, 5),
|
||||
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
|
||||
BOOST_TEST_EQ(x.size(), 1u);
|
||||
BOOST_TEST(x.find(k1) == i1);
|
||||
BOOST_TEST(x.find(k1)->second == m1);
|
||||
BOOST_TEST_EQ(check_.instances(), 4);
|
||||
BOOST_TEST_EQ(check_.constructions(), 4);
|
||||
|
||||
emplace_value m1a(8, "xxx", 'z', 4, 5, 6, 7, 8);
|
||||
i2 = x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(5, "", 'b', 4, 5),
|
||||
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
|
||||
BOOST_TEST_EQ(x.size(), 2u);
|
||||
BOOST_TEST(i1 != i2);
|
||||
BOOST_TEST(i1->second == m1);
|
||||
BOOST_TEST(i2->second == m1a);
|
||||
BOOST_TEST_EQ(check_.instances(), 7);
|
||||
BOOST_TEST_EQ(check_.constructions(), 7);
|
||||
|
||||
// 9/3 args + duplicates with hints, different mapped value.
|
||||
|
||||
emplace_value k2(9, "", 'b', 4, 5, 6, 7, 8, 9);
|
||||
emplace_value m2(3, "aaa", 'm');
|
||||
i1 = x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(3, "aaa", 'm'));
|
||||
BOOST_TEST_EQ(x.size(), 3u);
|
||||
BOOST_TEST(i1->first.arg_count == 9);
|
||||
BOOST_TEST(i1->second.arg_count == 3);
|
||||
BOOST_TEST_EQ(check_.instances(), 11);
|
||||
BOOST_TEST_EQ(check_.constructions(), 11);
|
||||
|
||||
emplace_value m2a(15, "jkjk");
|
||||
i2 = x.emplace_hint(i2, boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(15, "jkjk"));
|
||||
emplace_value m2b(275, "xxx", 'm', 6);
|
||||
i3 = x.emplace_hint(i1, boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(275, "xxx", 'm', 6));
|
||||
emplace_value m2c(-10, "blah blah", '\0');
|
||||
i4 = x.emplace_hint(x.end(), boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
|
||||
boost::make_tuple(-10, "blah blah", '\0'));
|
||||
BOOST_TEST_EQ(x.size(), 6u);
|
||||
BOOST_TEST(x.find(k2)->second == m2);
|
||||
BOOST_TEST_EQ(check_.instances(), 20);
|
||||
BOOST_TEST_EQ(check_.constructions(), 20);
|
||||
}
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
+126
-146
@@ -14,172 +14,152 @@
|
||||
#include <list>
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
namespace equality_tests
|
||||
namespace equality_tests {
|
||||
struct mod_compare
|
||||
{
|
||||
struct mod_compare
|
||||
bool alt_hash_;
|
||||
|
||||
explicit mod_compare(bool alt_hash = false) : alt_hash_(alt_hash) {}
|
||||
|
||||
bool operator()(int x, int y) const { return x % 1000 == y % 1000; }
|
||||
|
||||
std::size_t operator()(int x) const
|
||||
{
|
||||
bool alt_hash_;
|
||||
return alt_hash_ ? static_cast<std::size_t>(x % 250)
|
||||
: static_cast<std::size_t>((x + 5) % 250);
|
||||
}
|
||||
};
|
||||
|
||||
explicit mod_compare(bool alt_hash = false) : alt_hash_(alt_hash) {}
|
||||
|
||||
bool operator()(int x, int y) const
|
||||
{
|
||||
return x % 1000 == y % 1000;
|
||||
}
|
||||
|
||||
std::size_t operator()(int x) const
|
||||
{
|
||||
return alt_hash_ ?
|
||||
static_cast<std::size_t>(x % 250) :
|
||||
static_cast<std::size_t>((x + 5) % 250);
|
||||
}
|
||||
};
|
||||
|
||||
#define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_set<int, mod_compare, mod_compare> set1, set2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
|
||||
BOOST_TEST(set1 op set2); \
|
||||
#define UNORDERED_EQUALITY_SET_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_set<int, mod_compare, mod_compare> set1, set2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
|
||||
BOOST_TEST(set1 op set2); \
|
||||
}
|
||||
|
||||
#define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_multiset<int, mod_compare, mod_compare> \
|
||||
set1, set2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
|
||||
BOOST_TEST(set1 op set2); \
|
||||
#define UNORDERED_EQUALITY_MULTISET_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_multiset<int, mod_compare, mod_compare> set1, set2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_SET_INSERT, set2, seq2) \
|
||||
BOOST_TEST(set1 op set2); \
|
||||
}
|
||||
|
||||
#define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_map<int, int, mod_compare, mod_compare> \
|
||||
map1, map2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
|
||||
BOOST_TEST(map1 op map2); \
|
||||
#define UNORDERED_EQUALITY_MAP_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_map<int, int, mod_compare, mod_compare> map1, map2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
|
||||
BOOST_TEST(map1 op map2); \
|
||||
}
|
||||
|
||||
#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_multimap<int, int, mod_compare, mod_compare> \
|
||||
map1, map2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
|
||||
BOOST_TEST(map1 op map2); \
|
||||
#define UNORDERED_EQUALITY_MULTIMAP_TEST(seq1, op, seq2) \
|
||||
{ \
|
||||
boost::unordered_multimap<int, int, mod_compare, mod_compare> map1, \
|
||||
map2; \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map1, seq1) \
|
||||
BOOST_PP_SEQ_FOR_EACH(UNORDERED_MAP_INSERT, map2, seq2) \
|
||||
BOOST_TEST(map1 op map2); \
|
||||
}
|
||||
|
||||
#define UNORDERED_SET_INSERT(r, set, item) set.insert(item);
|
||||
#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));
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_size_tests)
|
||||
{
|
||||
boost::unordered_set<int> x1, x2;
|
||||
BOOST_TEST(x1 == x2);
|
||||
BOOST_TEST(!(x1 != x2));
|
||||
UNORDERED_AUTO_TEST(equality_size_tests)
|
||||
{
|
||||
boost::unordered_set<int> x1, x2;
|
||||
BOOST_TEST(x1 == x2);
|
||||
BOOST_TEST(!(x1 != x2));
|
||||
|
||||
x1.insert(1);
|
||||
BOOST_TEST(x1 != x2);
|
||||
BOOST_TEST(!(x1 == x2));
|
||||
BOOST_TEST(x2 != x1);
|
||||
BOOST_TEST(!(x2 == x1));
|
||||
|
||||
x2.insert(1);
|
||||
BOOST_TEST(x1 == x2);
|
||||
BOOST_TEST(!(x1 != x2));
|
||||
|
||||
x2.insert(2);
|
||||
BOOST_TEST(x1 != x2);
|
||||
BOOST_TEST(!(x1 == x2));
|
||||
BOOST_TEST(x2 != x1);
|
||||
BOOST_TEST(!(x2 == x1));
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_key_value_tests)
|
||||
{
|
||||
UNORDERED_EQUALITY_MULTISET_TEST((1), !=, (2))
|
||||
UNORDERED_EQUALITY_SET_TEST((2), ==, (2))
|
||||
UNORDERED_EQUALITY_MAP_TEST(((1)(1))((2)(1)), !=, ((1)(1))((3)(1)))
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_collision_test)
|
||||
{
|
||||
UNORDERED_EQUALITY_MULTISET_TEST(
|
||||
(1), !=, (501))
|
||||
UNORDERED_EQUALITY_MULTISET_TEST(
|
||||
(1)(251), !=, (1)(501))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((251)(1))((1)(1)), !=, ((501)(1))((1)(1)))
|
||||
UNORDERED_EQUALITY_MULTISET_TEST(
|
||||
(1)(501), ==, (1)(501))
|
||||
UNORDERED_EQUALITY_SET_TEST(
|
||||
(1)(501), ==, (501)(1))
|
||||
}
|
||||
x1.insert(1);
|
||||
BOOST_TEST(x1 != x2);
|
||||
BOOST_TEST(!(x1 == x2));
|
||||
BOOST_TEST(x2 != x1);
|
||||
BOOST_TEST(!(x2 == x1));
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_group_size_test)
|
||||
{
|
||||
UNORDERED_EQUALITY_MULTISET_TEST(
|
||||
(10)(20)(20), !=, (10)(10)(20))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((10)(1))((20)(1))((20)(1)), !=,
|
||||
((10)(1))((20)(1))((10)(1)))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((20)(1))((10)(1))((10)(1)), ==,
|
||||
((10)(1))((20)(1))((10)(1)))
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_map_value_test)
|
||||
{
|
||||
UNORDERED_EQUALITY_MAP_TEST(
|
||||
((1)(1)), !=, ((1)(2)))
|
||||
UNORDERED_EQUALITY_MAP_TEST(
|
||||
((1)(1)), ==, ((1)(1)))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((1)(1)), !=, ((1)(2)))
|
||||
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)))
|
||||
}
|
||||
x2.insert(1);
|
||||
BOOST_TEST(x1 == x2);
|
||||
BOOST_TEST(!(x1 != x2));
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_predicate_test)
|
||||
{
|
||||
UNORDERED_EQUALITY_SET_TEST(
|
||||
(1), !=, (1001))
|
||||
UNORDERED_EQUALITY_MAP_TEST(
|
||||
((1)(2))((1001)(1)), !=, ((1001)(2))((1)(1)))
|
||||
}
|
||||
x2.insert(2);
|
||||
BOOST_TEST(x1 != x2);
|
||||
BOOST_TEST(!(x1 == x2));
|
||||
BOOST_TEST(x2 != x1);
|
||||
BOOST_TEST(!(x2 == x1));
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_multiple_group_test)
|
||||
{
|
||||
UNORDERED_EQUALITY_MULTISET_TEST(
|
||||
(1)(1)(1)(1001)(2001)(2001)(2)(1002)(3)(1003)(2003), ==,
|
||||
(3)(1003)(2003)(1002)(2)(2001)(2001)(1)(1001)(1)(1)
|
||||
);
|
||||
}
|
||||
UNORDERED_AUTO_TEST(equality_key_value_tests)
|
||||
{
|
||||
UNORDERED_EQUALITY_MULTISET_TEST((1), !=, (2))
|
||||
UNORDERED_EQUALITY_SET_TEST((2), ==, (2))
|
||||
UNORDERED_EQUALITY_MAP_TEST(((1)(1))((2)(1)), !=, ((1)(1))((3)(1)))
|
||||
}
|
||||
|
||||
// Test that equality still works when the two containers have
|
||||
// different hash functions but the same equality predicate.
|
||||
UNORDERED_AUTO_TEST(equality_collision_test)
|
||||
{
|
||||
UNORDERED_EQUALITY_MULTISET_TEST((1), !=, (501))
|
||||
UNORDERED_EQUALITY_MULTISET_TEST((1)(251), !=, (1)(501))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(((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_different_hash_test)
|
||||
{
|
||||
typedef boost::unordered_set<int, mod_compare, mod_compare> set;
|
||||
set set1(0, mod_compare(false), mod_compare(false));
|
||||
set set2(0, mod_compare(true), mod_compare(true));
|
||||
BOOST_TEST(set1 == set2);
|
||||
set1.insert(1); set2.insert(2);
|
||||
BOOST_TEST(set1 != set2);
|
||||
set1.insert(2); set2.insert(1);
|
||||
BOOST_TEST(set1 == set2);
|
||||
set1.insert(10); set2.insert(20);
|
||||
BOOST_TEST(set1 != set2);
|
||||
set1.insert(20); set2.insert(10);
|
||||
BOOST_TEST(set1 == set2);
|
||||
}
|
||||
UNORDERED_AUTO_TEST(equality_group_size_test)
|
||||
{
|
||||
UNORDERED_EQUALITY_MULTISET_TEST((10)(20)(20), !=, (10)(10)(20))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((10)(1))((20)(1))((20)(1)), !=, ((10)(1))((20)(1))((10)(1)))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(
|
||||
((20)(1))((10)(1))((10)(1)), ==, ((10)(1))((20)(1))((10)(1)))
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_map_value_test)
|
||||
{
|
||||
UNORDERED_EQUALITY_MAP_TEST(((1)(1)), !=, ((1)(2)))
|
||||
UNORDERED_EQUALITY_MAP_TEST(((1)(1)), ==, ((1)(1)))
|
||||
UNORDERED_EQUALITY_MULTIMAP_TEST(((1)(1)), !=, ((1)(2)))
|
||||
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_EQUALITY_SET_TEST((1), !=, (1001))
|
||||
UNORDERED_EQUALITY_MAP_TEST(((1)(2))((1001)(1)), !=, ((1001)(2))((1)(1)))
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_multiple_group_test)
|
||||
{
|
||||
UNORDERED_EQUALITY_MULTISET_TEST(
|
||||
(1)(1)(1)(1001)(2001)(2001)(2)(1002)(3)(1003)(2003), ==,
|
||||
(3)(1003)(2003)(1002)(2)(2001)(2001)(1)(1001)(1)(1));
|
||||
}
|
||||
|
||||
// Test that equality still works when the two containers have
|
||||
// different hash functions but the same equality predicate.
|
||||
|
||||
UNORDERED_AUTO_TEST(equality_different_hash_test)
|
||||
{
|
||||
typedef boost::unordered_set<int, mod_compare, mod_compare> set;
|
||||
set set1(0, mod_compare(false), mod_compare(false));
|
||||
set set2(0, mod_compare(true), mod_compare(true));
|
||||
BOOST_TEST(set1 == set2);
|
||||
set1.insert(1);
|
||||
set2.insert(2);
|
||||
BOOST_TEST(set1 != set2);
|
||||
set1.insert(2);
|
||||
set2.insert(1);
|
||||
BOOST_TEST(set1 == set2);
|
||||
set1.insert(10);
|
||||
set2.insert(20);
|
||||
BOOST_TEST(set1 != set2);
|
||||
set1.insert(20);
|
||||
set2.insert(10);
|
||||
BOOST_TEST(set1 == set2);
|
||||
}
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -27,7 +27,7 @@ void test_equal_insertion(Iterator begin, Iterator end)
|
||||
Container x1;
|
||||
tracker x2 = test::create_ordered(x1);
|
||||
|
||||
for(Iterator it = begin; it != end; ++it) {
|
||||
for (Iterator it = begin; it != end; ++it) {
|
||||
x1.insert(*it);
|
||||
x2.insert(*it);
|
||||
x2.compare_key(x1, *it);
|
||||
@@ -39,13 +39,7 @@ void test_equal_insertion(Iterator begin, Iterator end)
|
||||
|
||||
UNORDERED_AUTO_TEST(set_tests)
|
||||
{
|
||||
int values[][5] = {
|
||||
{1},
|
||||
{54, 23},
|
||||
{-13, 65},
|
||||
{77, 77},
|
||||
{986, 25, 986}
|
||||
};
|
||||
int values[][5] = {{1}, {54, 23}, {-13, 65}, {77, 77}, {986, 25, 986}};
|
||||
|
||||
typedef boost::unordered_set<int> set;
|
||||
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;
|
||||
values_type v[5];
|
||||
v[0].push_back(std::pair<int const, int>(1,1));
|
||||
v[1].push_back(std::pair<int const, int>(28,34));
|
||||
v[1].push_back(std::pair<int const, int>(16,58));
|
||||
v[0].push_back(std::pair<int const, int>(1, 1));
|
||||
v[1].push_back(std::pair<int const, int>(28, 34));
|
||||
v[1].push_back(std::pair<int const, int>(16, 58));
|
||||
v[1].push_back(std::pair<int const, int>(-124, 62));
|
||||
v[2].push_back(std::pair<int const, int>(432,12));
|
||||
v[2].push_back(std::pair<int const, int>(9,13));
|
||||
v[2].push_back(std::pair<int const, int>(432,24));
|
||||
v[2].push_back(std::pair<int const, int>(432, 12));
|
||||
v[2].push_back(std::pair<int const, int>(9, 13));
|
||||
v[2].push_back(std::pair<int const, int>(432, 24));
|
||||
|
||||
for(int i = 0; i < 5; ++i)
|
||||
for (int i = 0; i < 5; ++i)
|
||||
test_equal_insertion<boost::unordered_map<int, int> >(
|
||||
v[i].begin(), v[i].end());
|
||||
|
||||
for(int i2 = 0; i2 < 5; ++i2)
|
||||
for (int i2 = 0; i2 < 5; ++i2)
|
||||
test_equal_insertion<boost::unordered_multimap<int, int> >(
|
||||
v[i2].begin(), v[i2].end());
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
#include "../objects/test.hpp"
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1400)
|
||||
#pragma warning(disable:4267) // conversion from 'size_t' to 'unsigned int',
|
||||
// possible loss of data.
|
||||
#pragma warning(disable : 4267) // conversion from 'size_t' to 'unsigned int',
|
||||
// possible loss of data.
|
||||
#endif
|
||||
|
||||
struct write_pair_type
|
||||
@@ -31,15 +31,14 @@ struct write_pair_type
|
||||
template <class X1, class X2>
|
||||
void operator()(std::pair<X1, X2> const& x) const
|
||||
{
|
||||
std::cout<<"("<<x.first<<","<<x.second<<")";
|
||||
std::cout << "(" << x.first << "," << x.second << ")";
|
||||
}
|
||||
} write_pair;
|
||||
|
||||
template <class Container>
|
||||
void write_container(Container const& x)
|
||||
template <class Container> void write_container(Container const& x)
|
||||
{
|
||||
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.
|
||||
@@ -51,7 +50,10 @@ struct collision_hash
|
||||
// For testing erase in 2 buckets.
|
||||
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.
|
||||
@@ -60,15 +62,15 @@ struct collision3_hash
|
||||
std::size_t operator()(int x) const { return static_cast<std::size_t>(x); }
|
||||
};
|
||||
|
||||
typedef boost::unordered_multimap<int, int,
|
||||
collision_hash, std::equal_to<int>,
|
||||
test::allocator1<std::pair<int const, int> > > collide_map;
|
||||
typedef boost::unordered_multimap<int, int,
|
||||
collision2_hash, std::equal_to<int>,
|
||||
test::allocator2<std::pair<int const, int> > > collide_map2;
|
||||
typedef boost::unordered_multimap<int, int,
|
||||
collision3_hash, std::equal_to<int>,
|
||||
test::allocator2<std::pair<int const, int> > > collide_map3;
|
||||
typedef boost::unordered_multimap<int, int, collision_hash, std::equal_to<int>,
|
||||
test::allocator1<std::pair<int const, int> > >
|
||||
collide_map;
|
||||
typedef boost::unordered_multimap<int, int, collision2_hash, std::equal_to<int>,
|
||||
test::allocator2<std::pair<int const, int> > >
|
||||
collide_map2;
|
||||
typedef boost::unordered_multimap<int, int, collision3_hash, std::equal_to<int>,
|
||||
test::allocator2<std::pair<int const, int> > >
|
||||
collide_map3;
|
||||
typedef collide_map::value_type collide_value;
|
||||
typedef test::list<collide_value> collide_list;
|
||||
|
||||
@@ -84,7 +86,7 @@ UNORDERED_AUTO_TEST(empty_range_tests)
|
||||
UNORDERED_AUTO_TEST(single_item_tests)
|
||||
{
|
||||
collide_list init;
|
||||
init.push_back(collide_value(1,1));
|
||||
init.push_back(collide_value(1, 1));
|
||||
|
||||
collide_map x(init.begin(), init.end());
|
||||
x.erase(x.begin(), x.begin());
|
||||
@@ -101,8 +103,8 @@ UNORDERED_AUTO_TEST(single_item_tests)
|
||||
UNORDERED_AUTO_TEST(two_equivalent_item_tests)
|
||||
{
|
||||
collide_list init;
|
||||
init.push_back(collide_value(1,1));
|
||||
init.push_back(collide_value(1,2));
|
||||
init.push_back(collide_value(1, 1));
|
||||
init.push_back(collide_value(1, 2));
|
||||
|
||||
{
|
||||
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());
|
||||
int value = test::next(x.begin())->second;
|
||||
x.erase(x.begin(), test::next(x.begin()));
|
||||
BOOST_TEST(x.count(1) == 1 && x.size() == 1 &&
|
||||
x.begin()->first == 1 && x.begin()->second == value);
|
||||
BOOST_TEST(x.count(1) == 1 && x.size() == 1 && x.begin()->first == 1 &&
|
||||
x.begin()->second == value);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
@@ -124,15 +126,15 @@ UNORDERED_AUTO_TEST(two_equivalent_item_tests)
|
||||
collide_map x(init.begin(), init.end());
|
||||
int value = x.begin()->second;
|
||||
x.erase(test::next(x.begin()), x.end());
|
||||
BOOST_TEST(x.count(1) == 1 && x.size() == 1 &&
|
||||
x.begin()->first == 1 && x.begin()->second == value);
|
||||
BOOST_TEST(x.count(1) == 1 && x.size() == 1 && x.begin()->first == 1 &&
|
||||
x.begin()->second == value);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
}
|
||||
|
||||
// More automated tests...
|
||||
|
||||
template<class Range1, class Range2>
|
||||
template <class Range1, class Range2>
|
||||
bool compare(Range1 const& x, Range2 const& y)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
template <class Container>
|
||||
void erase_subrange_tests(Container const& x)
|
||||
template <class Container> void erase_subrange_tests(Container const& x)
|
||||
{
|
||||
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 length = 0; length < x.size(); ++length) {
|
||||
for (std::size_t position = 0; position < x.size() - length;
|
||||
++position) {
|
||||
Container y(x);
|
||||
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.");
|
||||
std::cout<<"Erase: ["<<position<<","<<position + length<<")\n";
|
||||
std::cout << "Erase: [" << position << "," << position + length
|
||||
<< ")\n";
|
||||
write_container(init);
|
||||
write_container(y);
|
||||
}
|
||||
@@ -177,47 +179,46 @@ void x_by_y_erase_range_tests(Container*, int values, int duplicates)
|
||||
{
|
||||
Container y;
|
||||
|
||||
for(int i = 0; i < values; ++i) {
|
||||
for(int j = 0; j < duplicates; ++j) {
|
||||
for (int i = 0; i < values; ++i) {
|
||||
for (int j = 0; j < duplicates; ++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);
|
||||
}
|
||||
|
||||
template <class Container>
|
||||
void exhaustive_erase_tests(Container* x, int num_values,
|
||||
int num_duplicated)
|
||||
void exhaustive_erase_tests(Container* x, int num_values, int num_duplicated)
|
||||
{
|
||||
for(int i = 0; i < num_values; ++i) {
|
||||
for(int j = 0; j < num_duplicated; ++j) {
|
||||
for (int i = 0; i < num_values; ++i) {
|
||||
for (int j = 0; j < num_duplicated; ++j) {
|
||||
x_by_y_erase_range_tests(x, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
exhaustive_erase_tests((collide_map*) 0, 4, 4);
|
||||
std::cout<<"\n";
|
||||
exhaustive_erase_tests((collide_map*)0, 4, 4);
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(exhaustive_collide2_tests)
|
||||
{
|
||||
std::cout<<"exhaustive_collide2_tests:\n";
|
||||
exhaustive_erase_tests((collide_map2*) 0, 8, 4);
|
||||
std::cout<<"\n";
|
||||
std::cout << "exhaustive_collide2_tests:\n";
|
||||
exhaustive_erase_tests((collide_map2*)0, 8, 4);
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(exhaustive_collide3_tests)
|
||||
{
|
||||
std::cout<<"exhaustive_collide3_tests:\n";
|
||||
exhaustive_erase_tests((collide_map3*) 0, 8, 4);
|
||||
std::cout<<"\n";
|
||||
std::cout << "exhaustive_collide3_tests:\n";
|
||||
exhaustive_erase_tests((collide_map3*)0, 8, 4);
|
||||
std::cout << "\n";
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace erase_tests
|
||||
{
|
||||
namespace erase_tests {
|
||||
|
||||
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::const_iterator c_iterator;
|
||||
|
||||
std::cerr<<"Erase by key.\n";
|
||||
std::cerr << "Erase by key.\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<Container> v(1000, generator);
|
||||
Container x(v.begin(), v.end());
|
||||
int iterations = 0;
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<Container>::iterator
|
||||
it = v.begin(); it != v.end(); ++it)
|
||||
{
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<Container>::iterator
|
||||
it = v.begin();
|
||||
it != v.end(); ++it) {
|
||||
std::size_t count = x.count(test::get_key<Container>(*it));
|
||||
std::size_t old_size = x.size();
|
||||
BOOST_TEST(count == x.erase(test::get_key<Container>(*it)));
|
||||
BOOST_TEST(x.size() == old_size - count);
|
||||
BOOST_TEST(x.count(test::get_key<Container>(*it)) == 0);
|
||||
BOOST_TEST(x.find(test::get_key<Container>(*it)) == x.end());
|
||||
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_;
|
||||
|
||||
@@ -60,22 +60,22 @@ void erase_tests1(Container*, test::random_generator generator)
|
||||
Container x(v.begin(), v.end());
|
||||
std::size_t size = x.size();
|
||||
int iterations = 0;
|
||||
while(size > 0 && !x.empty())
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type
|
||||
key = test::get_key<Container>(*x.begin());
|
||||
while (size > 0 && !x.empty()) {
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type key =
|
||||
test::get_key<Container>(*x.begin());
|
||||
std::size_t count = x.count(key);
|
||||
iterator pos = x.erase(x.begin());
|
||||
--size;
|
||||
BOOST_TEST(pos == x.begin());
|
||||
BOOST_TEST(x.count(key) == count - 1);
|
||||
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());
|
||||
}
|
||||
|
||||
std::cerr<<"erase(random position).\n";
|
||||
std::cerr << "erase(random position).\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -83,38 +83,37 @@ void erase_tests1(Container*, test::random_generator generator)
|
||||
Container x(v.begin(), v.end());
|
||||
std::size_t size = x.size();
|
||||
int iterations = 0;
|
||||
while(size > 0 && !x.empty())
|
||||
{
|
||||
while (size > 0 && !x.empty()) {
|
||||
std::size_t index = test::random_value(x.size());
|
||||
c_iterator prev, pos, next;
|
||||
if(index == 0) {
|
||||
if (index == 0) {
|
||||
prev = pos = x.begin();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
prev = test::next(x.begin(), index - 1);
|
||||
pos = test::next(prev);
|
||||
}
|
||||
next = test::next(pos);
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type
|
||||
key = test::get_key<Container>(*pos);
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type key =
|
||||
test::get_key<Container>(*pos);
|
||||
std::size_t count = x.count(key);
|
||||
BOOST_TEST(count > 0);
|
||||
BOOST_TEST(next == x.erase(pos));
|
||||
--size;
|
||||
if(size > 0)
|
||||
BOOST_TEST(index == 0 ? next == x.begin() :
|
||||
next == test::next(prev));
|
||||
if (size > 0)
|
||||
BOOST_TEST(
|
||||
index == 0 ? next == x.begin() : next == test::next(prev));
|
||||
BOOST_TEST(x.count(key) == count - 1);
|
||||
if (x.count(key) != count - 1) {
|
||||
std::cerr << count << " => " << x.count(key) << std::endl;
|
||||
}
|
||||
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());
|
||||
}
|
||||
|
||||
std::cerr<<"erase(ranges).\n";
|
||||
std::cerr << "erase(ranges).\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -141,7 +140,7 @@ void erase_tests1(Container*, test::random_generator generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"erase(random ranges).\n";
|
||||
std::cerr << "erase(random ranges).\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
Container x;
|
||||
@@ -152,23 +151,23 @@ void erase_tests1(Container*, test::random_generator generator)
|
||||
|
||||
// Note that erase only invalidates the erased 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(x.cend());
|
||||
|
||||
while(iterators.size() > 1) {
|
||||
while (iterators.size() > 1) {
|
||||
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]);
|
||||
iterators.erase(
|
||||
test::next(iterators.begin(), start),
|
||||
test::next(iterators.begin(), start + length));
|
||||
iterators.erase(test::next(iterators.begin(), start),
|
||||
test::next(iterators.begin(), start + length));
|
||||
|
||||
BOOST_TEST(x.size() == iterators.size() - 1);
|
||||
BOOST_DEDUCED_TYPENAME std::vector<c_iterator>::const_iterator
|
||||
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);
|
||||
++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_;
|
||||
|
||||
@@ -188,21 +187,21 @@ void erase_tests1(Container*, test::random_generator generator)
|
||||
Container x(v.begin(), v.end());
|
||||
std::size_t size = x.size();
|
||||
int iterations = 0;
|
||||
while(size > 0 && !x.empty())
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type
|
||||
key = test::get_key<Container>(*x.begin());
|
||||
while (size > 0 && !x.empty()) {
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type key =
|
||||
test::get_key<Container>(*x.begin());
|
||||
std::size_t count = x.count(key);
|
||||
x.quick_erase(x.begin());
|
||||
--size;
|
||||
BOOST_TEST(x.count(key) == count - 1);
|
||||
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());
|
||||
}
|
||||
|
||||
std::cerr<<"quick_erase(random position).\n";
|
||||
std::cerr << "quick_erase(random position).\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -210,39 +209,37 @@ void erase_tests1(Container*, test::random_generator generator)
|
||||
Container x(v.begin(), v.end());
|
||||
std::size_t size = x.size();
|
||||
int iterations = 0;
|
||||
while(size > 0 && !x.empty())
|
||||
{
|
||||
while (size > 0 && !x.empty()) {
|
||||
std::size_t index = test::random_value(x.size());
|
||||
BOOST_DEDUCED_TYPENAME Container::const_iterator prev, pos, next;
|
||||
if(index == 0) {
|
||||
if (index == 0) {
|
||||
prev = pos = x.begin();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
prev = test::next(x.begin(), index - 1);
|
||||
pos = test::next(prev);
|
||||
}
|
||||
next = test::next(pos);
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type
|
||||
key = test::get_key<Container>(*pos);
|
||||
BOOST_DEDUCED_TYPENAME Container::key_type key =
|
||||
test::get_key<Container>(*pos);
|
||||
std::size_t count = x.count(key);
|
||||
BOOST_TEST(count > 0);
|
||||
x.quick_erase(pos);
|
||||
--size;
|
||||
if(size > 0)
|
||||
BOOST_TEST(index == 0 ? next == x.begin() :
|
||||
next == test::next(prev));
|
||||
if (size > 0)
|
||||
BOOST_TEST(
|
||||
index == 0 ? next == x.begin() : next == test::next(prev));
|
||||
BOOST_TEST(x.count(key) == count - 1);
|
||||
if (x.count(key) != count - 1) {
|
||||
std::cerr << count << " => " << x.count(key) << std::endl;
|
||||
}
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
std::cerr<<"clear().\n";
|
||||
std::cerr << "clear().\n";
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
@@ -253,31 +250,25 @@ void erase_tests1(Container*, test::random_generator generator)
|
||||
BOOST_TEST(x.begin() == x.end());
|
||||
}
|
||||
|
||||
std::cerr<<"\n";
|
||||
std::cerr << "\n";
|
||||
}
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_multimap;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator2<test::object> >* test_multimap;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(erase_tests1,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
UNORDERED_TEST(
|
||||
erase_tests1, ((test_set)(test_multiset)(test_map)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -16,13 +16,11 @@
|
||||
#include "../helpers/tracker.hpp"
|
||||
#include "../helpers/helpers.hpp"
|
||||
|
||||
namespace find_tests
|
||||
{
|
||||
namespace find_tests {
|
||||
|
||||
test::seed_t initialize_seed(78937);
|
||||
|
||||
template <class X>
|
||||
void find_tests1(X*, test::random_generator generator)
|
||||
template <class X> void find_tests1(X*, test::random_generator generator)
|
||||
{
|
||||
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);
|
||||
tracker.insert_range(v.begin(), v.end());
|
||||
|
||||
for(BOOST_DEDUCED_TYPENAME test::ordered<X>::const_iterator it1 =
|
||||
tracker.begin(); it1 != tracker.end(); ++it1)
|
||||
{
|
||||
for (BOOST_DEDUCED_TYPENAME test::ordered<X>::const_iterator it1 =
|
||||
tracker.begin();
|
||||
it1 != tracker.end(); ++it1) {
|
||||
BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it1);
|
||||
BOOST_DEDUCED_TYPENAME X::const_iterator
|
||||
const_pos = x_const.find(key);
|
||||
BOOST_DEDUCED_TYPENAME X::const_iterator const_pos =
|
||||
x_const.find(key);
|
||||
iterator pos = x.find(key);
|
||||
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() &&
|
||||
x.key_eq()(key, test::get_key<X>(*pos)));
|
||||
BOOST_TEST(
|
||||
pos != x.end() && x.key_eq()(key, test::get_key<X>(*pos)));
|
||||
|
||||
BOOST_TEST(x.count(key) == tracker.count(key));
|
||||
|
||||
test::compare_pairs(x.equal_range(key),
|
||||
tracker.equal_range(key),
|
||||
(BOOST_DEDUCED_TYPENAME X::value_type*) 0);
|
||||
test::compare_pairs(x.equal_range(key), tracker.equal_range(key),
|
||||
(BOOST_DEDUCED_TYPENAME X::value_type*)0);
|
||||
test::compare_pairs(x_const.equal_range(key),
|
||||
tracker.equal_range(key),
|
||||
(BOOST_DEDUCED_TYPENAME X::value_type*) 0);
|
||||
tracker.equal_range(key),
|
||||
(BOOST_DEDUCED_TYPENAME X::value_type*)0);
|
||||
}
|
||||
|
||||
test::random_values<X> v2(500, generator);
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator it2 =
|
||||
v2.begin(); it2 != v2.end(); ++it2)
|
||||
{
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator it2 =
|
||||
v2.begin();
|
||||
it2 != v2.end(); ++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_const.find(key) == x_const.end());
|
||||
BOOST_TEST(x.count(key) == 0);
|
||||
@@ -81,9 +77,9 @@ void find_tests1(X*, test::random_generator generator)
|
||||
X x;
|
||||
|
||||
test::random_values<X> v2(5, generator);
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator it3 =
|
||||
v2.begin(); it3 != v2.end(); ++it3)
|
||||
{
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator it3 =
|
||||
v2.begin();
|
||||
it3 != v2.end(); ++it3) {
|
||||
BOOST_DEDUCED_TYPENAME X::key_type key = test::get_key<X>(*it3);
|
||||
BOOST_TEST(x.find(key) == x.end());
|
||||
BOOST_TEST(x.count(key) == 0);
|
||||
@@ -96,7 +92,7 @@ void find_tests1(X*, test::random_generator generator)
|
||||
struct compatible_key
|
||||
{
|
||||
test::object o_;
|
||||
|
||||
|
||||
compatible_key(test::object const& o) : o_(o) {}
|
||||
};
|
||||
|
||||
@@ -104,7 +100,8 @@ struct compatible_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_);
|
||||
}
|
||||
};
|
||||
@@ -113,7 +110,8 @@ struct compatible_predicate
|
||||
{
|
||||
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_);
|
||||
}
|
||||
};
|
||||
@@ -125,49 +123,42 @@ void find_compatible_keys_test(X*, test::random_generator generator)
|
||||
value_iterator;
|
||||
test::random_values<X> v(500, generator);
|
||||
X x(v.begin(), v.end());
|
||||
|
||||
|
||||
compatible_hash h;
|
||||
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_TEST(x.find(key) == x.find(compatible_key(key), h, eq));
|
||||
}
|
||||
|
||||
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_TEST(x.find(key) == x.find(compatible_key(key), h, eq));
|
||||
}
|
||||
}
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_multimap;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator1<test::object> >* test_multimap;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(find_tests1,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
UNORDERED_TEST(
|
||||
find_tests1, ((test_set)(test_multiset)(test_map)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
UNORDERED_TEST(find_compatible_keys_test,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
((test_set)(test_multiset)(test_map)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -10,43 +10,41 @@
|
||||
// clang-format on
|
||||
|
||||
template <typename T>
|
||||
void call_swap(boost::unordered_map<T,T>& x,
|
||||
boost::unordered_map<T,T>& y)
|
||||
void call_swap(boost::unordered_map<T, T>& x, boost::unordered_map<T, T>& y)
|
||||
{
|
||||
swap(x,y);
|
||||
swap(x, y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool call_equals(boost::unordered_map<T,T>& x,
|
||||
boost::unordered_map<T,T>& y)
|
||||
bool call_equals(boost::unordered_map<T, T>& x, boost::unordered_map<T, T>& y)
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool call_not_equals(boost::unordered_map<T,T>& x,
|
||||
boost::unordered_map<T,T>& y)
|
||||
bool call_not_equals(
|
||||
boost::unordered_map<T, T>& x, boost::unordered_map<T, T>& y)
|
||||
{
|
||||
return x != y;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void call_swap(boost::unordered_multimap<T,T>& x,
|
||||
boost::unordered_multimap<T,T>& y)
|
||||
void call_swap(
|
||||
boost::unordered_multimap<T, T>& x, boost::unordered_multimap<T, T>& y)
|
||||
{
|
||||
swap(x,y);
|
||||
swap(x, y);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool call_equals(boost::unordered_multimap<T,T>& x,
|
||||
boost::unordered_multimap<T,T>& y)
|
||||
bool call_equals(
|
||||
boost::unordered_multimap<T, T>& x, boost::unordered_multimap<T, T>& y)
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool call_not_equals(boost::unordered_multimap<T,T>& x,
|
||||
boost::unordered_multimap<T,T>& y)
|
||||
bool call_not_equals(
|
||||
boost::unordered_multimap<T, T>& x, boost::unordered_multimap<T, T>& 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_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;
|
||||
x[1] = 2;
|
||||
y[2] = 1;
|
||||
@@ -73,7 +72,8 @@ UNORDERED_AUTO_TEST(use_map_fwd_declared_function) {
|
||||
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;
|
||||
call_swap(x, y);
|
||||
BOOST_TEST(call_equals(x, y));
|
||||
|
||||
@@ -9,53 +9,55 @@
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
|
||||
struct true_type { char x[100]; };
|
||||
struct false_type { char x; };
|
||||
struct true_type
|
||||
{
|
||||
char x[100];
|
||||
};
|
||||
struct false_type
|
||||
{
|
||||
char x;
|
||||
};
|
||||
|
||||
false_type is_unordered_set_impl(void*);
|
||||
|
||||
template <class Value, class Hash, class Pred, class Alloc>
|
||||
true_type is_unordered_set_impl(
|
||||
boost::unordered_set<Value, Hash, Pred, Alloc>*);
|
||||
boost::unordered_set<Value, Hash, Pred, Alloc>*);
|
||||
|
||||
template<typename T>
|
||||
void call_swap(boost::unordered_set<T>& x,
|
||||
boost::unordered_set<T>& y)
|
||||
template <typename T>
|
||||
void call_swap(boost::unordered_set<T>& x, boost::unordered_set<T>& y)
|
||||
{
|
||||
swap(x,y);
|
||||
swap(x, y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool call_equals(boost::unordered_set<T>& x,
|
||||
boost::unordered_set<T>& y)
|
||||
template <typename T>
|
||||
bool call_equals(boost::unordered_set<T>& x, boost::unordered_set<T>& y)
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool call_not_equals(boost::unordered_set<T>& x,
|
||||
boost::unordered_set<T>& y)
|
||||
template <typename T>
|
||||
bool call_not_equals(boost::unordered_set<T>& x, boost::unordered_set<T>& y)
|
||||
{
|
||||
return x != y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void call_swap(boost::unordered_multiset<T>& x,
|
||||
boost::unordered_multiset<T>& y)
|
||||
template <typename T>
|
||||
void call_swap(boost::unordered_multiset<T>& x, boost::unordered_multiset<T>& y)
|
||||
{
|
||||
swap(x,y);
|
||||
swap(x, y);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool call_equals(boost::unordered_multiset<T>& x,
|
||||
boost::unordered_multiset<T>& y)
|
||||
template <typename T>
|
||||
bool call_equals(
|
||||
boost::unordered_multiset<T>& x, boost::unordered_multiset<T>& y)
|
||||
{
|
||||
return x == y;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool call_not_equals(boost::unordered_multiset<T>& x,
|
||||
boost::unordered_multiset<T>& y)
|
||||
template <typename T>
|
||||
bool call_not_equals(
|
||||
boost::unordered_multiset<T>& x, boost::unordered_multiset<T>& 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_multiset<int> int_multiset;
|
||||
|
||||
UNORDERED_AUTO_TEST(use_fwd_declared_trait_without_definition) {
|
||||
BOOST_TEST(sizeof(is_unordered_set_impl((int_set*) 0))
|
||||
== sizeof(true_type));
|
||||
UNORDERED_AUTO_TEST(use_fwd_declared_trait_without_definition)
|
||||
{
|
||||
BOOST_TEST(sizeof(is_unordered_set_impl((int_set*)0)) == sizeof(true_type));
|
||||
}
|
||||
|
||||
#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_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;
|
||||
x.insert(1);
|
||||
y.insert(2);
|
||||
@@ -95,7 +99,8 @@ UNORDERED_AUTO_TEST(use_set_fwd_declared_function) {
|
||||
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;
|
||||
call_swap(x, y);
|
||||
BOOST_TEST(call_equals(x, y));
|
||||
|
||||
+137
-124
@@ -12,142 +12,155 @@
|
||||
|
||||
#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 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 {
|
||||
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() {}
|
||||
|
||||
template <typename T2>
|
||||
allocator(const allocator<T2>& 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()
|
||||
struct equals
|
||||
{
|
||||
template <typename T> bool operator()(T const&, T const&) const
|
||||
{
|
||||
incomplete_test::value x;
|
||||
m1[x] = x;
|
||||
m2.insert(std::make_pair(x, x));
|
||||
s1.insert(x);
|
||||
s2.insert(x);
|
||||
|
||||
c1.x.insert(std::make_pair(c1, c1));
|
||||
c2.x.insert(std::make_pair(c2, c2));
|
||||
c3.x.insert(c3);
|
||||
c4.x.insert(c4);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// And finally define the operators required for comparing elements.
|
||||
// This is a dubious way to implement an allocator, but good enough
|
||||
// for this test.
|
||||
template <typename T> struct allocator : std::allocator<T>
|
||||
{
|
||||
allocator() {}
|
||||
|
||||
std::size_t hash_value(value const&) { return 0; }
|
||||
bool operator==(value const&, value const&) { return true; }
|
||||
template <typename T2>
|
||||
allocator(const allocator<T2>& other) : std::allocator<T>(other)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
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; }
|
||||
// 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;
|
||||
m1[x] = x;
|
||||
m2.insert(std::make_pair(x, x));
|
||||
s1.insert(x);
|
||||
s2.insert(x);
|
||||
|
||||
c1.x.insert(std::make_pair(c1, c1));
|
||||
c2.x.insert(std::make_pair(c2, c2));
|
||||
c3.x.insert(c3);
|
||||
c4.x.insert(c4);
|
||||
}
|
||||
|
||||
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
|
||||
// things. It's probably irrational, but I find it reassuring.
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
#include <set>
|
||||
#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;
|
||||
container x;
|
||||
x.insert(x.cbegin(), 10);
|
||||
@@ -28,7 +28,8 @@ UNORDERED_AUTO_TEST(insert_hint_empty) {
|
||||
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;
|
||||
container x;
|
||||
x.emplace_hint(x.cbegin(), "hello", 50);
|
||||
@@ -38,7 +39,8 @@ UNORDERED_AUTO_TEST(insert_hint_empty2) {
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(insert_hint_single) {
|
||||
UNORDERED_AUTO_TEST(insert_hint_single)
|
||||
{
|
||||
typedef boost::unordered_multiset<std::string> container;
|
||||
container x;
|
||||
x.insert("equal");
|
||||
@@ -48,7 +50,8 @@ UNORDERED_AUTO_TEST(insert_hint_single) {
|
||||
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;
|
||||
container x;
|
||||
x.emplace(10, "one");
|
||||
@@ -67,18 +70,23 @@ UNORDERED_AUTO_TEST(insert_hint_single2) {
|
||||
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 offset = 0; offset <= size; ++offset) {
|
||||
for (unsigned int offset = 0; offset <= size; ++offset) {
|
||||
typedef boost::unordered_multiset<std::string> container;
|
||||
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);
|
||||
|
||||
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");
|
||||
|
||||
@@ -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;
|
||||
container x;
|
||||
x.insert(x.cbegin(), 10);
|
||||
@@ -98,7 +107,8 @@ UNORDERED_AUTO_TEST(insert_hint_unique) {
|
||||
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;
|
||||
container x;
|
||||
x.insert(10);
|
||||
@@ -114,7 +124,6 @@ UNORDERED_AUTO_TEST(insert_hint_unique_single) {
|
||||
BOOST_TEST_EQ(x.count(20), 1u);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -14,23 +14,25 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace insert_stable
|
||||
namespace insert_stable {
|
||||
struct member
|
||||
{
|
||||
struct member {
|
||||
int tag1_;
|
||||
int tag2_;
|
||||
|
||||
member() : tag1_(0), tag2_(0) {}
|
||||
member(int t1, int t2) : tag1_(t1), tag2_(t2) {}
|
||||
|
||||
friend bool operator==(member const& x, member const& y) {
|
||||
return x.tag1_ == y.tag1_;
|
||||
}
|
||||
|
||||
friend bool operator!=(member const& x, member const& y) {
|
||||
return x.tag1_ != y.tag1_;
|
||||
}
|
||||
};
|
||||
int tag1_;
|
||||
int tag2_;
|
||||
|
||||
member() : tag1_(0), tag2_(0) {}
|
||||
member(int t1, int t2) : tag1_(t1), tag2_(t2) {}
|
||||
|
||||
friend bool operator==(member const& x, member const& y)
|
||||
{
|
||||
return x.tag1_ == y.tag1_;
|
||||
}
|
||||
|
||||
friend bool operator!=(member const& x, member const& y)
|
||||
{
|
||||
return x.tag1_ != y.tag1_;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||
@@ -39,51 +41,72 @@ namespace boost
|
||||
namespace insert_stable
|
||||
#endif
|
||||
{
|
||||
std::size_t hash_value(insert_stable::member const& x) {
|
||||
return static_cast<std::size_t>(x.tag1_);
|
||||
}
|
||||
std::size_t hash_value(insert_stable::member const& x)
|
||||
{
|
||||
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;
|
||||
|
||||
x.insert(insert_stable::member(1,1));
|
||||
x.insert(insert_stable::member(1,2));
|
||||
x.insert(insert_stable::member(1,3));
|
||||
x.insert(insert_stable::member(1, 1));
|
||||
x.insert(insert_stable::member(1, 2));
|
||||
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
|
||||
it = x.begin(), end = x.end();
|
||||
it = x.begin(),
|
||||
end = x.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);
|
||||
if(it != end) { BOOST_TEST(it->tag2_ == 2); ++it; }
|
||||
if (it != end) {
|
||||
BOOST_TEST(it->tag2_ == 2);
|
||||
++it;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(stable_insert_test2) {
|
||||
UNORDERED_AUTO_TEST(stable_insert_test2)
|
||||
{
|
||||
boost::unordered_multimap<insert_stable::member, int> x;
|
||||
typedef
|
||||
boost::unordered_multimap<insert_stable::member, int>::const_iterator
|
||||
iterator;
|
||||
typedef boost::unordered_multimap<insert_stable::member,
|
||||
int>::const_iterator iterator;
|
||||
|
||||
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,3), 3);
|
||||
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, 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();
|
||||
iterator end = x.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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
+219
-210
@@ -22,7 +22,7 @@
|
||||
#include <iostream>
|
||||
|
||||
namespace insert_tests {
|
||||
|
||||
|
||||
test::seed_t initialize_seed(243432);
|
||||
|
||||
template <class X>
|
||||
@@ -33,30 +33,30 @@ void unique_insert_tests1(X*, test::random_generator generator)
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
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;
|
||||
test::ordered<X> tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
|
||||
it != v.end(); ++it)
|
||||
{
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
|
||||
it != v.end(); ++it) {
|
||||
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
std::pair<iterator, bool> r1 = x.insert(*it);
|
||||
std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool>
|
||||
r2 = tracker.insert(*it);
|
||||
std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool> r2 =
|
||||
tracker.insert(*it);
|
||||
|
||||
BOOST_TEST(r1.second == r2.second);
|
||||
BOOST_TEST(*r1.first == *r2.first);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -66,45 +66,43 @@ void unique_insert_tests1(X*, test::random_generator generator)
|
||||
template <class X>
|
||||
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_;
|
||||
|
||||
|
||||
X x;
|
||||
test::ordered<X> tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
|
||||
it != v.end(); ++it)
|
||||
{
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
|
||||
it != v.end(); ++it) {
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
BOOST_DEDUCED_TYPENAME X::iterator r1 = x.insert(*it);
|
||||
BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator r2
|
||||
= tracker.insert(*it);
|
||||
BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator r2 =
|
||||
tracker.insert(*it);
|
||||
|
||||
BOOST_TEST(*r1 == *r2);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void insert_tests2(X*, test::random_generator generator)
|
||||
template <class X> void insert_tests2(X*, test::random_generator generator)
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME test::ordered<X> tracker_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_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_;
|
||||
@@ -113,11 +111,11 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
tracker_type tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator
|
||||
it = v.begin(); it != v.end(); ++it)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME X::size_type
|
||||
old_bucket_count = x.bucket_count();
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it =
|
||||
v.begin();
|
||||
it != v.end(); ++it) {
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count =
|
||||
x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
iterator r1 = x.insert(x.begin(), *it);
|
||||
@@ -125,7 +123,8 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
BOOST_TEST(*r1 == *r2);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -133,7 +132,7 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"insert(end(), value) tests.\n";
|
||||
std::cerr << "insert(end(), value) tests.\n";
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
@@ -143,11 +142,11 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
tracker_type tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(100, generator);
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator
|
||||
it = v.begin(); it != v.end(); ++it)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME X::size_type
|
||||
old_bucket_count = x.bucket_count();
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it =
|
||||
v.begin();
|
||||
it != v.end(); ++it) {
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count =
|
||||
x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"insert(pos, value) tests.\n";
|
||||
std::cerr << "insert(pos, value) tests.\n";
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
@@ -173,11 +173,11 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
tracker_type tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator
|
||||
it = v.begin(); it != v.end(); ++it)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME X::size_type
|
||||
old_bucket_count = x.bucket_count();
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it =
|
||||
v.begin();
|
||||
it != v.end(); ++it) {
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count =
|
||||
x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
pos = x.insert(pos, *it);
|
||||
@@ -185,7 +185,8 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
BOOST_TEST(*pos == *r2);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -193,7 +194,7 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
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_;
|
||||
@@ -202,18 +203,19 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
tracker_type tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator
|
||||
it = v.begin(); it != v.end(); ++it)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME X::size_type
|
||||
old_bucket_count = x.bucket_count();
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it =
|
||||
v.begin();
|
||||
it != v.end(); ++it) {
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count =
|
||||
x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
x.insert(it, test::next(it));
|
||||
tracker.insert(*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);
|
||||
}
|
||||
|
||||
@@ -221,7 +223,7 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
std::cerr<<"insert range tests.\n";
|
||||
std::cerr << "insert range tests.\n";
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
@@ -235,7 +237,7 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
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_;
|
||||
@@ -253,7 +255,7 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
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_;
|
||||
@@ -262,14 +264,15 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
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));
|
||||
test::check_container(x, v);
|
||||
|
||||
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_;
|
||||
@@ -283,7 +286,7 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
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_;
|
||||
@@ -292,13 +295,15 @@ void insert_tests2(X*, test::random_generator generator)
|
||||
|
||||
test::random_values<X> v1(500, generator);
|
||||
test::random_values<X> v2(500, generator);
|
||||
x.insert(test::copy_iterator(v1.begin()), test::copy_iterator(v1.end()));
|
||||
x.insert(test::copy_iterator(v2.begin()), test::copy_iterator(v2.end()));
|
||||
x.insert(
|
||||
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);
|
||||
}
|
||||
|
||||
std::cerr<<"insert various ranges.\n";
|
||||
std::cerr << "insert various ranges.\n";
|
||||
|
||||
{
|
||||
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);
|
||||
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator
|
||||
it = v.begin(); it != v.end();)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it =
|
||||
v.begin();
|
||||
it != v.end();) {
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count =
|
||||
x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator
|
||||
next = it;
|
||||
BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator next =
|
||||
it;
|
||||
for (std::size_t j = test::random_value(20); j > 0; ++j) {
|
||||
++next;
|
||||
if (next == v.end()) { break; }
|
||||
if (next == v.end()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -341,30 +350,30 @@ void unique_emplace_tests1(X*, test::random_generator generator)
|
||||
typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
|
||||
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;
|
||||
test::ordered<X> tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
|
||||
it != v.end(); ++it)
|
||||
{
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
|
||||
it != v.end(); ++it) {
|
||||
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
std::pair<iterator, bool> r1 = x.emplace(*it);
|
||||
std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool>
|
||||
r2 = tracker.insert(*it);
|
||||
std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool> r2 =
|
||||
tracker.insert(*it);
|
||||
|
||||
BOOST_TEST(r1.second == r2.second);
|
||||
BOOST_TEST(*r1.first == *r2.first);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -375,27 +384,27 @@ void unique_emplace_tests1(X*, test::random_generator generator)
|
||||
template <class X>
|
||||
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;
|
||||
test::ordered<X> tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
|
||||
it != v.end(); ++it)
|
||||
{
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
|
||||
it != v.end(); ++it) {
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
BOOST_DEDUCED_TYPENAME X::iterator r1 = x.emplace(*it);
|
||||
BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator
|
||||
r2 = tracker.insert(*it);
|
||||
BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator r2 =
|
||||
tracker.insert(*it);
|
||||
|
||||
BOOST_TEST(*r1 == *r2);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -403,19 +412,18 @@ void equivalent_emplace_tests1(X*, test::random_generator generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void move_emplace_tests(X*, test::random_generator generator)
|
||||
template <class X> 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;
|
||||
test::ordered<X> tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
|
||||
it != v.end(); ++it)
|
||||
{
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
|
||||
it != v.end(); ++it) {
|
||||
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
@@ -425,7 +433,8 @@ void move_emplace_tests(X*, test::random_generator generator)
|
||||
tracker.insert(*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);
|
||||
}
|
||||
|
||||
@@ -433,11 +442,10 @@ void move_emplace_tests(X*, test::random_generator generator)
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void default_emplace_tests(X*, test::random_generator)
|
||||
template <class X> void default_emplace_tests(X*, test::random_generator)
|
||||
{
|
||||
#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;
|
||||
|
||||
X x;
|
||||
@@ -448,7 +456,7 @@ void default_emplace_tests(X*, test::random_generator)
|
||||
BOOST_TEST(x.size() == (is_unique ? 1u : 2u));
|
||||
x.emplace();
|
||||
BOOST_TEST(x.size() == (is_unique ? 1u : 3u));
|
||||
|
||||
|
||||
typename X::value_type y;
|
||||
BOOST_TEST(x.count(test::get_key<X>(y)) == (is_unique ? 1u : 3u));
|
||||
BOOST_TEST(*x.equal_range(test::get_key<X>(y)).first == y);
|
||||
@@ -457,31 +465,29 @@ void default_emplace_tests(X*, test::random_generator)
|
||||
BOOST_TEST(x.size() == (is_unique ? 1u : 4u));
|
||||
BOOST_TEST(x.count(test::get_key<X>(y)) == (is_unique ? 1u : 4u));
|
||||
BOOST_TEST(*x.equal_range(test::get_key<X>(y)).first == y);
|
||||
|
||||
|
||||
x.clear();
|
||||
BOOST_TEST(x.empty());
|
||||
x.emplace(y);
|
||||
BOOST_TEST(x.size() == 1);
|
||||
x.emplace(y);
|
||||
BOOST_TEST(x.size() == (is_unique ? 1u : 2u));
|
||||
|
||||
|
||||
BOOST_TEST(x.count(test::get_key<X>(y)) == (is_unique ? 1u : 2u));
|
||||
BOOST_TEST(*x.equal_range(test::get_key<X>(y)).first == y);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void map_tests(X*, test::random_generator generator)
|
||||
template <class X> void map_tests(X*, test::random_generator generator)
|
||||
{
|
||||
std::cerr<<"map tests.\n";
|
||||
std::cerr << "map tests.\n";
|
||||
|
||||
X x;
|
||||
test::ordered<X> tracker = test::create_ordered(x);
|
||||
|
||||
test::random_values<X> v(1000, generator);
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
|
||||
it != v.end(); ++it)
|
||||
{
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
|
||||
it != v.end(); ++it) {
|
||||
BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
|
||||
float b = x.max_load_factor();
|
||||
|
||||
@@ -490,12 +496,13 @@ void map_tests(X*, test::random_generator generator)
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
tracker.compare(x);
|
||||
test::check_equivalent_keys(x);
|
||||
test::check_equivalent_keys(x);
|
||||
}
|
||||
|
||||
// Some tests for when the range's value type doesn't match the container's
|
||||
@@ -504,20 +511,18 @@ void map_tests(X*, test::random_generator generator)
|
||||
template <class X>
|
||||
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_;
|
||||
|
||||
typedef test::list<
|
||||
std::pair<
|
||||
BOOST_DEDUCED_TYPENAME X::key_type,
|
||||
BOOST_DEDUCED_TYPENAME X::mapped_type
|
||||
>
|
||||
> list;
|
||||
typedef test::list<std::pair<BOOST_DEDUCED_TYPENAME X::key_type,
|
||||
BOOST_DEDUCED_TYPENAME X::mapped_type> >
|
||||
list;
|
||||
test::random_values<X> v(1000, generator);
|
||||
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);
|
||||
}
|
||||
@@ -525,98 +530,83 @@ void map_insert_range_test1(X*, test::random_generator generator)
|
||||
template <class X>
|
||||
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_;
|
||||
|
||||
typedef test::list<
|
||||
std::pair<BOOST_DEDUCED_TYPENAME X::key_type const, test::implicitly_convertible>
|
||||
> list;
|
||||
test::random_values<
|
||||
boost::unordered_map<BOOST_DEDUCED_TYPENAME X::key_type, test::implicitly_convertible>
|
||||
> v(1000, generator);
|
||||
typedef test::list<std::pair<BOOST_DEDUCED_TYPENAME X::key_type const,
|
||||
test::implicitly_convertible> >
|
||||
list;
|
||||
test::random_values<boost::unordered_map<BOOST_DEDUCED_TYPENAME X::key_type,
|
||||
test::implicitly_convertible> >
|
||||
v(1000, generator);
|
||||
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);
|
||||
}
|
||||
|
||||
boost::unordered_set<test::movable,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_set<test::movable, test::hash, test::equal_to,
|
||||
std::allocator<test::movable> >* test_set_std_alloc;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
std::allocator<test::object> >* test_multimap_std_alloc;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, std::allocator<test::object> >* test_multimap_std_alloc;
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::movable,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_multiset<test::movable, test::hash, test::equal_to,
|
||||
test::allocator2<test::movable> >* test_multiset;
|
||||
boost::unordered_map<test::movable, test::movable,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_map<test::movable, test::movable, test::hash, test::equal_to,
|
||||
test::allocator2<test::movable> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_multimap;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator1<test::object> >* test_multimap;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(unique_insert_tests1,
|
||||
((test_set_std_alloc)(test_set)(test_map))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
((test_set_std_alloc)(test_set)(test_map))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(equivalent_insert_tests1,
|
||||
((test_multimap_std_alloc)(test_multiset)(test_multimap))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
((test_multimap_std_alloc)(test_multiset)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(insert_tests2,
|
||||
((test_multimap_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
UNORDERED_TEST(
|
||||
insert_tests2, ((test_multimap_std_alloc)(test_set)(test_multiset)(
|
||||
test_map)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(unique_emplace_tests1,
|
||||
((test_set_std_alloc)(test_set)(test_map))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
((test_set_std_alloc)(test_set)(test_map))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(equivalent_emplace_tests1,
|
||||
((test_multimap_std_alloc)(test_multiset)(test_multimap))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
((test_multimap_std_alloc)(test_multiset)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(move_emplace_tests,
|
||||
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)
|
||||
(test_multiset)(test_multimap))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)(
|
||||
test_multiset)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(default_emplace_tests,
|
||||
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)
|
||||
(test_multiset)(test_multimap))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
((test_set_std_alloc)(test_multimap_std_alloc)(test_set)(test_map)(
|
||||
test_multiset)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(map_tests,
|
||||
((test_map))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
((test_map))((default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(map_insert_range_test1,
|
||||
((test_multimap_std_alloc)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
((test_multimap_std_alloc)(test_map)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
UNORDERED_TEST(map_insert_range_test2,
|
||||
((test_multimap_std_alloc)(test_map)(test_multimap))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
((test_multimap_std_alloc)(test_map)(test_multimap))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST)
|
||||
|
||||
@@ -638,7 +628,7 @@ struct initialize_from_two_ints
|
||||
UNORDERED_AUTO_TEST(insert_initializer_list_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(set.find(1) != set.end());
|
||||
BOOST_TEST(set.find(4) == set.end());
|
||||
@@ -651,25 +641,25 @@ UNORDERED_AUTO_TEST(insert_initializer_list_set)
|
||||
set2.insert({1, 2});
|
||||
#endif
|
||||
BOOST_TEST(set2.size() == 1);
|
||||
BOOST_TEST(set2.find({1,2}) != set2.end());
|
||||
BOOST_TEST(set2.find({2,1}) == set2.end());
|
||||
BOOST_TEST(set2.find({1, 2}) != 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.find({1,2}) != set2.end());
|
||||
BOOST_TEST(set2.find({3,4}) != set2.end());
|
||||
BOOST_TEST(set2.find({5,6}) != set2.end());
|
||||
BOOST_TEST(set2.find({7,8}) != set2.end());
|
||||
BOOST_TEST(set2.find({8,7}) == set2.end());
|
||||
BOOST_TEST(set2.find({1, 2}) != set2.end());
|
||||
BOOST_TEST(set2.find({3, 4}) != set2.end());
|
||||
BOOST_TEST(set2.find({5, 6}) != set2.end());
|
||||
BOOST_TEST(set2.find({7, 8}) != 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.find({1,2}) != set2.end());
|
||||
BOOST_TEST(set2.find({2,1}) != set2.end());
|
||||
BOOST_TEST(set2.find({3,4}) != set2.end());
|
||||
BOOST_TEST(set2.find({5,6}) != set2.end());
|
||||
BOOST_TEST(set2.find({7,8}) != set2.end());
|
||||
BOOST_TEST(set2.find({8,7}) == set2.end());
|
||||
BOOST_TEST(set2.find({1, 2}) != set2.end());
|
||||
BOOST_TEST(set2.find({2, 1}) != set2.end());
|
||||
BOOST_TEST(set2.find({3, 4}) != set2.end());
|
||||
BOOST_TEST(set2.find({5, 6}) != set2.end());
|
||||
BOOST_TEST(set2.find({7, 8}) != set2.end());
|
||||
BOOST_TEST(set2.find({8, 7}) == set2.end());
|
||||
}
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1800)
|
||||
@@ -677,13 +667,13 @@ UNORDERED_AUTO_TEST(insert_initializer_list_set)
|
||||
UNORDERED_AUTO_TEST(insert_initializer_list_multiset)
|
||||
{
|
||||
boost::unordered_multiset<std::string> multiset;
|
||||
//multiset.insert({});
|
||||
// multiset.insert({});
|
||||
BOOST_TEST(multiset.empty());
|
||||
multiset.insert({"a"});
|
||||
BOOST_TEST_EQ(multiset.size(), 1u);
|
||||
BOOST_TEST(multiset.find("a") != multiset.end());
|
||||
BOOST_TEST(multiset.find("b") == multiset.end());
|
||||
multiset.insert({"a","b"});
|
||||
multiset.insert({"a", "b"});
|
||||
BOOST_TEST(multiset.size() == 3);
|
||||
BOOST_TEST_EQ(multiset.count("a"), 2u);
|
||||
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)
|
||||
{
|
||||
boost::unordered_map<std::string, std::string> map;
|
||||
//map.insert({});
|
||||
// map.insert({});
|
||||
BOOST_TEST(map.empty());
|
||||
map.insert({{"a", "b"},{"a", "b"},{"d", ""}});
|
||||
map.insert({{"a", "b"}, {"a", "b"}, {"d", ""}});
|
||||
BOOST_TEST_EQ(map.size(), 2u);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(insert_initializer_list_multimap)
|
||||
{
|
||||
boost::unordered_multimap<std::string, std::string> multimap;
|
||||
//multimap.insert({});
|
||||
// multimap.insert({});
|
||||
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.count("a"), 2u);
|
||||
}
|
||||
@@ -716,15 +706,17 @@ UNORDERED_AUTO_TEST(insert_initializer_list_multimap)
|
||||
struct overloaded_constructor
|
||||
{
|
||||
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;
|
||||
|
||||
|
||||
bool operator==(overloaded_constructor const& rhs) const
|
||||
{
|
||||
return x1 == rhs.x1 && x2 == rhs.x2 && x3 == rhs.x3 && x4 == rhs.x4;
|
||||
}
|
||||
|
||||
|
||||
friend std::size_t hash_value(overloaded_constructor const& x)
|
||||
{
|
||||
std::size_t hash = 0;
|
||||
@@ -742,13 +734,13 @@ UNORDERED_AUTO_TEST(map_emplace_test)
|
||||
|
||||
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
|
||||
x.emplace();
|
||||
BOOST_TEST(x.find(0) != x.end() &&
|
||||
x.find(0)->second == overloaded_constructor());
|
||||
BOOST_TEST(
|
||||
x.find(0) != x.end() && x.find(0)->second == overloaded_constructor());
|
||||
#endif
|
||||
|
||||
x.emplace(2, 3);
|
||||
BOOST_TEST(x.find(2) != x.end() &&
|
||||
x.find(2)->second == overloaded_constructor(3));
|
||||
BOOST_TEST(
|
||||
x.find(2) != x.end() && x.find(2)->second == overloaded_constructor(3));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
struct derived_from_piecewise_construct_t :
|
||||
boost::unordered::piecewise_construct_t {};
|
||||
struct derived_from_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();
|
||||
}
|
||||
|
||||
struct convertible_to_piecewise {
|
||||
operator boost::unordered::piecewise_construct_t() const {
|
||||
struct convertible_to_piecewise
|
||||
{
|
||||
operator boost::unordered::piecewise_construct_t() const
|
||||
{
|
||||
return boost::unordered::piecewise_construct;
|
||||
}
|
||||
};
|
||||
@@ -799,38 +796,50 @@ UNORDERED_AUTO_TEST(map_emplace_test2)
|
||||
{
|
||||
boost::unordered_map<overloaded_constructor, overloaded_constructor> x;
|
||||
|
||||
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(), boost::make_tuple());
|
||||
BOOST_TEST(x.find(overloaded_constructor()) != x.end() &&
|
||||
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(),
|
||||
boost::make_tuple());
|
||||
BOOST_TEST(
|
||||
x.find(overloaded_constructor()) != x.end() &&
|
||||
x.find(overloaded_constructor())->second == overloaded_constructor());
|
||||
|
||||
x.emplace(convertible_to_piecewise(), boost::make_tuple(1), boost::make_tuple());
|
||||
BOOST_TEST(x.find(overloaded_constructor(1)) != x.end() &&
|
||||
x.emplace(
|
||||
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.emplace(piecewise_rvalue(), boost::make_tuple(2,3), boost::make_tuple(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));
|
||||
x.emplace(piecewise_rvalue(), boost::make_tuple(2, 3),
|
||||
boost::make_tuple(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;
|
||||
x.emplace(d, boost::make_tuple(9,3,1), boost::make_tuple(10));
|
||||
BOOST_TEST(x.find(overloaded_constructor(9,3,1)) != x.end() &&
|
||||
x.find(overloaded_constructor(9,3,1))->second == overloaded_constructor(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() &&
|
||||
x.find(overloaded_constructor(9, 3, 1))->second ==
|
||||
overloaded_constructor(10));
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
x.clear();
|
||||
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(1), boost::make_tuple(2,3));
|
||||
check = std::make_pair(overloaded_constructor(1), overloaded_constructor(2, 3));;
|
||||
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(1),
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -10,10 +10,8 @@
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
|
||||
void foo(boost::unordered_set<int>&,
|
||||
boost::unordered_map<int, int>&,
|
||||
boost::unordered_multiset<int>&,
|
||||
boost::unordered_multimap<int, int>&);
|
||||
void foo(boost::unordered_set<int>&, boost::unordered_map<int, int>&,
|
||||
boost::unordered_multiset<int>&, boost::unordered_multimap<int, int>&);
|
||||
|
||||
int main()
|
||||
{
|
||||
@@ -23,6 +21,6 @@ int main()
|
||||
boost::unordered_multimap<int, int> x4;
|
||||
|
||||
foo(x1, x2, x3, x4);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -10,18 +10,17 @@
|
||||
#include "../helpers/postfix.hpp"
|
||||
// clang-format on
|
||||
|
||||
void foo(boost::unordered_set<int>& x1,
|
||||
boost::unordered_map<int, int>& x2,
|
||||
boost::unordered_multiset<int>& x3,
|
||||
boost::unordered_multimap<int, int>& x4)
|
||||
void foo(boost::unordered_set<int>& x1, boost::unordered_map<int, int>& x2,
|
||||
boost::unordered_multiset<int>& x3, boost::unordered_multimap<int, int>& x4)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x0613))
|
||||
struct dummy {
|
||||
boost::unordered_set<int> x1;
|
||||
boost::unordered_map<int, int> x2;
|
||||
boost::unordered_multiset<int> x3;
|
||||
boost::unordered_multimap<int, int> x4;
|
||||
};
|
||||
struct dummy
|
||||
{
|
||||
boost::unordered_set<int> x1;
|
||||
boost::unordered_map<int, int> x2;
|
||||
boost::unordered_multiset<int> x3;
|
||||
boost::unordered_multimap<int, int> x4;
|
||||
};
|
||||
#endif
|
||||
|
||||
x1.insert(1);
|
||||
|
||||
@@ -16,16 +16,14 @@
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127) // conditional expression is constant
|
||||
#pragma warning(disable : 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
namespace load_factor_tests
|
||||
{
|
||||
namespace load_factor_tests {
|
||||
|
||||
test::seed_t initialize_seed(783656);
|
||||
|
||||
template <class X>
|
||||
void set_load_factor_tests(X*)
|
||||
template <class X> void set_load_factor_tests(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
|
||||
// reasonable.
|
||||
x.max_load_factor(2.0); BOOST_TEST(x.max_load_factor() == 2.0);
|
||||
x.max_load_factor(0.5); BOOST_TEST(x.max_load_factor() == 0.5);
|
||||
x.max_load_factor(2.0);
|
||||
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>
|
||||
@@ -47,13 +47,15 @@ void insert_test(X*, float mlf, test::random_generator generator)
|
||||
|
||||
test::random_values<X> values(1000, generator);
|
||||
|
||||
for(BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator
|
||||
it = values.begin(), end = values.end(); it != end; ++it)
|
||||
{
|
||||
for (BOOST_DEDUCED_TYPENAME test::random_values<X>::const_iterator
|
||||
it = values.begin(),
|
||||
end = values.end();
|
||||
it != end; ++it) {
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -65,12 +67,10 @@ void load_factor_insert_tests(X* ptr, test::random_generator generator)
|
||||
insert_test(ptr, 0.1f, generator);
|
||||
insert_test(ptr, 100.0f, generator);
|
||||
|
||||
insert_test(ptr, (std::numeric_limits<float>::min)(),
|
||||
generator);
|
||||
insert_test(ptr, (std::numeric_limits<float>::min)(), generator);
|
||||
|
||||
if(std::numeric_limits<float>::has_infinity)
|
||||
insert_test(ptr, std::numeric_limits<float>::infinity(),
|
||||
generator);
|
||||
if (std::numeric_limits<float>::has_infinity)
|
||||
insert_test(ptr, std::numeric_limits<float>::infinity(), generator);
|
||||
}
|
||||
|
||||
boost::unordered_set<int>* int_set_ptr;
|
||||
@@ -83,19 +83,16 @@ using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
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,
|
||||
((int_set_ptr)(int_multiset_ptr)(int_map_ptr)(int_multimap_ptr))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
((int_set_ptr)(int_multiset_ptr)(int_map_ptr)(int_multimap_ptr))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#pragma warning(disable:4127) // conditional expression is constant
|
||||
#pragma warning(disable : 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
@@ -3,60 +3,58 @@
|
||||
// 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)
|
||||
|
||||
#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 <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>
|
||||
struct SimpleAllocator
|
||||
{
|
||||
template <class Tp> struct SimpleAllocator
|
||||
{
|
||||
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)));
|
||||
}
|
||||
|
||||
void deallocate(Tp* p, std::size_t)
|
||||
{
|
||||
::operator delete((void*) p);
|
||||
}
|
||||
void deallocate(Tp* p, std::size_t) { ::operator delete((void*)p); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void test_simple_allocator()
|
||||
template <typename T> void test_simple_allocator()
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
typedef boost::unordered::detail::allocator_traits<
|
||||
SimpleAllocator<T> > traits;
|
||||
typedef boost::unordered::detail::allocator_traits<SimpleAllocator<T> >
|
||||
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::const_pointer, T 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::pointer, T*>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
(boost::is_same<typename traits::const_pointer, T 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
|
||||
BOOST_STATIC_ASSERT((boost::is_same<typename traits::size_type,
|
||||
std::make_unsigned<std::ptrdiff_t>::type>::value));
|
||||
#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
|
||||
|
||||
BOOST_TEST(!traits::propagate_on_container_copy_assignment::value);
|
||||
@@ -69,18 +67,18 @@ void test_simple_allocator()
|
||||
SimpleAllocator<T> a;
|
||||
|
||||
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, ptr2, T(30), ptr1);
|
||||
// traits::construct(a, ptr2, T(30), ptr1);
|
||||
|
||||
BOOST_TEST(*ptr1 == T(10));
|
||||
//BOOST_TEST(*ptr2 == T(30));
|
||||
// BOOST_TEST(*ptr2 == T(30));
|
||||
|
||||
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::max_size(a);
|
||||
|
||||
+303
-336
@@ -19,390 +19,357 @@
|
||||
#include "../helpers/invariants.hpp"
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable:4127) // conditional expression is constant
|
||||
#pragma warning(disable : 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
namespace move_tests
|
||||
{
|
||||
test::seed_t initialize_seed(98624);
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
namespace move_tests {
|
||||
test::seed_t initialize_seed(98624);
|
||||
#if defined(BOOST_UNORDERED_USE_MOVE) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#define BOOST_UNORDERED_TEST_MOVING 1
|
||||
#else
|
||||
#define BOOST_UNORDERED_TEST_MOVING 0
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
T empty(T*) {
|
||||
return T();
|
||||
}
|
||||
template <class T> T empty(T*) { return T(); }
|
||||
|
||||
template<class T>
|
||||
T create(test::random_values<T> const& v,
|
||||
test::object_count& count) {
|
||||
T x(v.begin(), v.end());
|
||||
count = test::global_object_count;
|
||||
return x;
|
||||
}
|
||||
template <class T>
|
||||
T create(test::random_values<T> const& v, test::object_count& count)
|
||||
{
|
||||
T x(v.begin(), v.end());
|
||||
count = test::global_object_count;
|
||||
return x;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T create(test::random_values<T> const& v,
|
||||
test::object_count& count,
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf,
|
||||
BOOST_DEDUCED_TYPENAME T::key_equal eq,
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al,
|
||||
float mlf) {
|
||||
T x(0, hf, eq, al);
|
||||
x.max_load_factor(mlf);
|
||||
x.insert(v.begin(), v.end());
|
||||
count = test::global_object_count;
|
||||
return x;
|
||||
}
|
||||
template <class T>
|
||||
T create(test::random_values<T> const& v, test::object_count& count,
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf, BOOST_DEDUCED_TYPENAME T::key_equal eq,
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al, float mlf)
|
||||
{
|
||||
T x(0, hf, eq, al);
|
||||
x.max_load_factor(mlf);
|
||||
x.insert(v.begin(), v.end());
|
||||
count = test::global_object_count;
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void move_construct_tests1(T* ptr, test::random_generator const& generator)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf;
|
||||
BOOST_DEDUCED_TYPENAME T::key_equal eq;
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al;
|
||||
|
||||
template <class T>
|
||||
void move_construct_tests1(T* ptr, test::random_generator const& generator)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf;
|
||||
BOOST_DEDUCED_TYPENAME T::key_equal eq;
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al;
|
||||
test::check_instances check_;
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
T y(empty(ptr));
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||
BOOST_TEST(y.max_load_factor() == 1.0);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(1000, generator);
|
||||
test::object_count count;
|
||||
T y(create(v, count));
|
||||
#if defined(BOOST_HAS_NRVO)
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
T y(empty(ptr));
|
||||
BOOST_TEST(y.empty());
|
||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||
BOOST_TEST(y.max_load_factor() == 1.0);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void move_assign_tests1(T*, test::random_generator const& generator)
|
||||
{
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(500, generator);
|
||||
test::object_count count;
|
||||
T y;
|
||||
y = create(v, count);
|
||||
#if BOOST_UNORDERED_TEST_MOVING && defined(BOOST_HAS_NRVO)
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void move_construct_tests2(T*, test::random_generator const& generator)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf(1);
|
||||
BOOST_DEDUCED_TYPENAME T::key_equal eq(1);
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al(1);
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al2(2);
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(1000, generator);
|
||||
test::object_count count;
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(500, generator);
|
||||
T y(create(v, count, hf, eq, al, 0.5));
|
||||
T y(create(v, count));
|
||||
#if defined(BOOST_HAS_NRVO)
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||
BOOST_TEST(y.max_load_factor() == 0.5); // Not necessarily required.
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
// TODO: To do this correctly requires the fancy new allocator
|
||||
// stuff.
|
||||
test::random_values<T> v(500, generator);
|
||||
T y(create(v, count, hf, eq, al, 2.0), al2);
|
||||
BOOST_TEST(count != test::global_object_count);
|
||||
test::check_container(y, v);
|
||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
|
||||
BOOST_TEST(y.max_load_factor() == 2.0); // Not necessarily required.
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(25, generator);
|
||||
T y(create(v, count, hf, eq, al, 1.0), al);
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
#elif defined(BOOST_HAS_NRVO)
|
||||
BOOST_TEST(
|
||||
static_cast<std::size_t>(test::global_object_count.constructions
|
||||
- count.constructions) <=
|
||||
(test::is_set<T>::value ? 1 : 2) *
|
||||
(test::has_unique_keys<T>::value ? 25 : v.size()));
|
||||
BOOST_TEST(count.instances == test::global_object_count.instances);
|
||||
#else
|
||||
BOOST_TEST(
|
||||
static_cast<std::size_t>(test::global_object_count.constructions
|
||||
- count.constructions) <=
|
||||
(test::is_set<T>::value ? 2 : 4) *
|
||||
(test::has_unique_keys<T>::value ? 25 : v.size()));
|
||||
BOOST_TEST(count.instances == test::global_object_count.instances);
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||
BOOST_TEST(y.max_load_factor() == 1.0); // Not necessarily required.
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void move_assign_tests2(T*, test::random_generator const& generator)
|
||||
template <class T>
|
||||
void move_assign_tests1(T*, test::random_generator const& generator)
|
||||
{
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf(1);
|
||||
BOOST_DEDUCED_TYPENAME T::key_equal eq(1);
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al1(1);
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al2(2);
|
||||
typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type;
|
||||
test::check_instances check_;
|
||||
|
||||
{
|
||||
test::random_values<T> v(500, generator);
|
||||
test::random_values<T> v2(0, generator);
|
||||
T y(v.begin(), v.end(), 0, hf, eq, al1);
|
||||
test::object_count count;
|
||||
y = create(v2, count, hf, eq, al2, 2.0);
|
||||
BOOST_TEST(y.empty());
|
||||
test::check_container(y, v2);
|
||||
test::check_equivalent_keys(y);
|
||||
BOOST_TEST(y.max_load_factor() == 2.0);
|
||||
test::random_values<T> v(500, generator);
|
||||
test::object_count count;
|
||||
T y;
|
||||
y = create(v, count);
|
||||
#if BOOST_UNORDERED_TEST_MOVING && defined(BOOST_HAS_NRVO)
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void move_construct_tests2(T*, test::random_generator const& generator)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf(1);
|
||||
BOOST_DEDUCED_TYPENAME T::key_equal eq(1);
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al(1);
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al2(2);
|
||||
|
||||
test::object_count count;
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(500, generator);
|
||||
T y(create(v, count, hf, eq, al, 0.5));
|
||||
#if defined(BOOST_HAS_NRVO)
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||
BOOST_TEST(y.max_load_factor() == 0.5); // Not necessarily required.
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
// TODO: To do this correctly requires the fancy new allocator
|
||||
// stuff.
|
||||
test::random_values<T> v(500, generator);
|
||||
T y(create(v, count, hf, eq, al, 2.0), al2);
|
||||
BOOST_TEST(count != test::global_object_count);
|
||||
test::check_container(y, v);
|
||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
|
||||
BOOST_TEST(y.max_load_factor() == 2.0); // Not necessarily required.
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(25, generator);
|
||||
T y(create(v, count, hf, eq, al, 1.0), al);
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
#elif defined(BOOST_HAS_NRVO)
|
||||
BOOST_TEST(
|
||||
static_cast<std::size_t>(test::global_object_count.constructions -
|
||||
count.constructions) <=
|
||||
(test::is_set<T>::value ? 1 : 2) *
|
||||
(test::has_unique_keys<T>::value ? 25 : v.size()));
|
||||
BOOST_TEST(count.instances == test::global_object_count.instances);
|
||||
#else
|
||||
BOOST_TEST(
|
||||
static_cast<std::size_t>(test::global_object_count.constructions -
|
||||
count.constructions) <=
|
||||
(test::is_set<T>::value ? 2 : 4) *
|
||||
(test::has_unique_keys<T>::value ? 25 : v.size()));
|
||||
BOOST_TEST(count.instances == test::global_object_count.instances);
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
BOOST_TEST(test::equivalent(y.hash_function(), hf));
|
||||
BOOST_TEST(test::equivalent(y.key_eq(), eq));
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al));
|
||||
BOOST_TEST(y.max_load_factor() == 1.0); // Not necessarily required.
|
||||
test::check_equivalent_keys(y);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void move_assign_tests2(T*, test::random_generator const& generator)
|
||||
{
|
||||
BOOST_DEDUCED_TYPENAME T::hasher hf(1);
|
||||
BOOST_DEDUCED_TYPENAME T::key_equal eq(1);
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al1(1);
|
||||
BOOST_DEDUCED_TYPENAME T::allocator_type al2(2);
|
||||
typedef BOOST_DEDUCED_TYPENAME T::allocator_type allocator_type;
|
||||
|
||||
{
|
||||
test::random_values<T> v(500, generator);
|
||||
test::random_values<T> v2(0, generator);
|
||||
T y(v.begin(), v.end(), 0, hf, eq, al1);
|
||||
test::object_count count;
|
||||
y = create(v2, count, hf, eq, al2, 2.0);
|
||||
BOOST_TEST(y.empty());
|
||||
test::check_container(y, v2);
|
||||
test::check_equivalent_keys(y);
|
||||
BOOST_TEST(y.max_load_factor() == 2.0);
|
||||
|
||||
#if defined(BOOST_HAS_NRVO)
|
||||
if (BOOST_UNORDERED_TEST_MOVING ?
|
||||
(bool) allocator_type::is_propagate_on_move :
|
||||
(bool) allocator_type::is_propagate_on_assign)
|
||||
{
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
|
||||
}
|
||||
else {
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al1));
|
||||
}
|
||||
#endif
|
||||
if (BOOST_UNORDERED_TEST_MOVING
|
||||
? (bool)allocator_type::is_propagate_on_move
|
||||
: (bool)allocator_type::is_propagate_on_assign) {
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
|
||||
} else {
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al1));
|
||||
}
|
||||
|
||||
{
|
||||
test::random_values<T> v(500, generator);
|
||||
test::object_count count;
|
||||
T y(0, hf, eq, al1);
|
||||
y = create(v, count, hf, eq, al2, 0.5);
|
||||
#if defined(BOOST_HAS_NRVO)
|
||||
if (BOOST_UNORDERED_TEST_MOVING &&
|
||||
allocator_type::is_propagate_on_move)
|
||||
{
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
}
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
BOOST_TEST(y.max_load_factor() == 0.5);
|
||||
}
|
||||
|
||||
{
|
||||
test::random_values<T> v(500, generator);
|
||||
test::object_count count;
|
||||
T y(0, hf, eq, al1);
|
||||
y = create(v, count, hf, eq, al2, 0.5);
|
||||
#if defined(BOOST_HAS_NRVO)
|
||||
if (BOOST_UNORDERED_TEST_MOVING &&
|
||||
allocator_type::is_propagate_on_move) {
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
}
|
||||
#endif
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
BOOST_TEST(y.max_load_factor() == 0.5);
|
||||
|
||||
#if defined(BOOST_HAS_NRVO)
|
||||
if (BOOST_UNORDERED_TEST_MOVING ?
|
||||
(bool) allocator_type::is_propagate_on_move :
|
||||
(bool) allocator_type::is_propagate_on_assign)
|
||||
{
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
|
||||
}
|
||||
else {
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al1));
|
||||
}
|
||||
if (BOOST_UNORDERED_TEST_MOVING
|
||||
? (bool)allocator_type::is_propagate_on_move
|
||||
: (bool)allocator_type::is_propagate_on_assign) {
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
|
||||
} else {
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al1));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(500, generator);
|
||||
T y(0, hf, eq, al1);
|
||||
|
||||
T x(0, hf, eq, al2);
|
||||
x.max_load_factor(0.25);
|
||||
x.insert(v.begin(), v.end());
|
||||
|
||||
test::object_count count = test::global_object_count;
|
||||
y = boost::move(x);
|
||||
if (BOOST_UNORDERED_TEST_MOVING &&
|
||||
allocator_type::is_propagate_on_move) {
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
}
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
BOOST_TEST(y.max_load_factor() == 0.25);
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v(500, generator);
|
||||
T y(0, hf, eq, al1);
|
||||
|
||||
T x(0, hf, eq, al2);
|
||||
x.max_load_factor(0.25);
|
||||
x.insert(v.begin(), v.end());
|
||||
|
||||
test::object_count count = test::global_object_count;
|
||||
y = boost::move(x);
|
||||
if (BOOST_UNORDERED_TEST_MOVING &&
|
||||
allocator_type::is_propagate_on_move)
|
||||
{
|
||||
BOOST_TEST(count == test::global_object_count);
|
||||
}
|
||||
test::check_container(y, v);
|
||||
test::check_equivalent_keys(y);
|
||||
BOOST_TEST(y.max_load_factor() == 0.25);
|
||||
|
||||
if (BOOST_UNORDERED_TEST_MOVING ?
|
||||
(bool) allocator_type::is_propagate_on_move :
|
||||
(bool) allocator_type::is_propagate_on_assign)
|
||||
{
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
|
||||
}
|
||||
else {
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al1));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
test::random_values<T> v1(1000, generator);
|
||||
test::random_values<T> v2(200, generator);
|
||||
|
||||
T x(0, hf, eq, al2);
|
||||
x.max_load_factor(0.5);
|
||||
x.insert(v2.begin(), v2.end());
|
||||
|
||||
test::object_count count1 = test::global_object_count;
|
||||
|
||||
T y(v1.begin(), v1.end(), 0, hf, eq, al1);
|
||||
y = boost::move(x);
|
||||
|
||||
test::object_count count2 = test::global_object_count;
|
||||
|
||||
if (BOOST_UNORDERED_TEST_MOVING &&
|
||||
allocator_type::is_propagate_on_move)
|
||||
{
|
||||
BOOST_TEST(count1.instances ==
|
||||
test::global_object_count.instances);
|
||||
BOOST_TEST(count2.constructions ==
|
||||
test::global_object_count.constructions);
|
||||
}
|
||||
|
||||
test::check_container(y, v2);
|
||||
test::check_equivalent_keys(y);
|
||||
BOOST_TEST(y.max_load_factor() == 0.5);
|
||||
|
||||
if (BOOST_UNORDERED_TEST_MOVING ?
|
||||
(bool) allocator_type::is_propagate_on_move :
|
||||
(bool) allocator_type::is_propagate_on_assign)
|
||||
{
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
|
||||
}
|
||||
else {
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al1));
|
||||
}
|
||||
if (BOOST_UNORDERED_TEST_MOVING
|
||||
? (bool)allocator_type::is_propagate_on_move
|
||||
: (bool)allocator_type::is_propagate_on_assign) {
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
|
||||
} else {
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al1));
|
||||
}
|
||||
}
|
||||
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
std::allocator<test::object> >* test_map_std_alloc;
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_multimap;
|
||||
test::random_values<T> v1(1000, generator);
|
||||
test::random_values<T> v2(200, generator);
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
T x(0, hf, eq, al2);
|
||||
x.max_load_factor(0.5);
|
||||
x.insert(v2.begin(), v2.end());
|
||||
|
||||
test::object_count count1 = test::global_object_count;
|
||||
|
||||
T y(v1.begin(), v1.end(), 0, hf, eq, al1);
|
||||
y = boost::move(x);
|
||||
|
||||
test::object_count count2 = test::global_object_count;
|
||||
|
||||
if (BOOST_UNORDERED_TEST_MOVING &&
|
||||
allocator_type::is_propagate_on_move) {
|
||||
BOOST_TEST(count1.instances == test::global_object_count.instances);
|
||||
BOOST_TEST(count2.constructions ==
|
||||
test::global_object_count.constructions);
|
||||
}
|
||||
|
||||
test::check_container(y, v2);
|
||||
test::check_equivalent_keys(y);
|
||||
BOOST_TEST(y.max_load_factor() == 0.5);
|
||||
|
||||
if (BOOST_UNORDERED_TEST_MOVING
|
||||
? (bool)allocator_type::is_propagate_on_move
|
||||
: (bool)allocator_type::is_propagate_on_assign) {
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al2));
|
||||
} else {
|
||||
BOOST_TEST(test::equivalent(y.get_allocator(), al1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
std::allocator<test::object> >* test_map_std_alloc;
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator2<test::object> >* test_multimap;
|
||||
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
test_set_prop_move;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
test_multiset_prop_move;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
test_map_prop_move;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::cxx11_allocator<test::object, test::propagate_move> >*
|
||||
test_multimap_prop_move;
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
test_set_no_prop_move;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
test_multiset_no_prop_move;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
test_map_no_prop_move;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_move> >*
|
||||
test_multimap_no_prop_move;
|
||||
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
using test::default_generator;
|
||||
using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
UNORDERED_TEST(move_construct_tests1, (
|
||||
(test_map_std_alloc)
|
||||
(test_set)(test_multiset)(test_map)(test_multimap)
|
||||
(test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(test_multimap_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_tests1, (
|
||||
(test_map_std_alloc)
|
||||
(test_set)(test_multiset)(test_map)(test_multimap)
|
||||
(test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(test_multimap_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_construct_tests2, (
|
||||
(test_set)(test_multiset)(test_map)(test_multimap)
|
||||
(test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(test_multimap_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, (
|
||||
(test_set)(test_multiset)(test_map)(test_multimap)
|
||||
(test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(test_multimap_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_construct_tests1,
|
||||
((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap)(
|
||||
test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(
|
||||
test_multimap_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_tests1,
|
||||
((test_map_std_alloc)(test_set)(test_multiset)(test_map)(test_multimap)(
|
||||
test_set_prop_move)(test_multiset_prop_move)(test_map_prop_move)(
|
||||
test_multimap_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_construct_tests2,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap)(test_set_prop_move)(
|
||||
test_multiset_prop_move)(test_map_prop_move)(test_multimap_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,
|
||||
((test_set)(test_multiset)(test_map)(test_multimap)(test_set_prop_move)(
|
||||
test_multiset_prop_move)(test_map_prop_move)(test_multimap_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)))
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
+147
-127
@@ -12,139 +12,159 @@
|
||||
|
||||
#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>
|
||||
{
|
||||
equal_to_possible_exception(equal_to_possible_exception const&) {}
|
||||
};
|
||||
struct equal_to_possible_exception : std::equal_to<int>
|
||||
{
|
||||
equal_to_possible_exception(equal_to_possible_exception const&) {}
|
||||
};
|
||||
|
||||
// Test that the move constructor does actually move without throwing
|
||||
// an exception when it claims to.
|
||||
// Test that the move constructor does actually move without throwing
|
||||
// an exception when it claims to.
|
||||
|
||||
struct test_exception {};
|
||||
struct test_exception
|
||||
{
|
||||
};
|
||||
|
||||
bool throwing_test_exception = false;
|
||||
void test_throw(char const* name) {
|
||||
if (throwing_test_exception) {
|
||||
std::cerr << "Throw exception in: " << name << std::endl;
|
||||
throw test_exception();
|
||||
}
|
||||
}
|
||||
|
||||
class hash_nothrow_move : boost::hash<int>
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(hash_nothrow_move)
|
||||
|
||||
typedef boost::hash<int> base;
|
||||
public:
|
||||
hash_nothrow_move(BOOST_RV_REF(hash_nothrow_move))
|
||||
BOOST_NOEXCEPT {}
|
||||
|
||||
hash_nothrow_move() { test_throw("Constructor"); }
|
||||
hash_nothrow_move(hash_nothrow_move const&) { test_throw("Copy"); }
|
||||
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>
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(equal_to_nothrow_move)
|
||||
|
||||
typedef std::equal_to<int> base;
|
||||
public:
|
||||
equal_to_nothrow_move(BOOST_RV_REF(equal_to_nothrow_move))
|
||||
BOOST_NOEXCEPT {}
|
||||
equal_to_nothrow_move() { test_throw("Constructor"); }
|
||||
equal_to_nothrow_move(equal_to_nothrow_move const&)
|
||||
{ test_throw("Copy"); }
|
||||
equal_to_nothrow_move& operator=(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);
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(test_noexcept)
|
||||
{
|
||||
if (have_is_nothrow_move) {
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_set<int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_multiset<int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_map<int, int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_multimap<int, int> >::value));
|
||||
}
|
||||
|
||||
BOOST_TEST((!boost::is_nothrow_move_constructible<
|
||||
boost::unordered_set<int, hash_possible_exception>
|
||||
>::value));
|
||||
BOOST_TEST((!boost::is_nothrow_move_constructible<
|
||||
boost::unordered_multiset<int, boost::hash<int>,
|
||||
equal_to_possible_exception>
|
||||
>::value));
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(test_no_throw_when_noexcept)
|
||||
{
|
||||
typedef boost::unordered_set<int,
|
||||
hash_nothrow_move, equal_to_nothrow_move> throwing_set;
|
||||
|
||||
if (have_is_nothrow_move)
|
||||
{
|
||||
BOOST_TEST(boost::is_nothrow_move_constructible<throwing_set>::value);
|
||||
|
||||
throwing_test_exception = false;
|
||||
|
||||
throwing_set x1;
|
||||
x1.insert(10);
|
||||
x1.insert(50);
|
||||
|
||||
try {
|
||||
throwing_test_exception = true;
|
||||
|
||||
throwing_set x2 = boost::move(x1);
|
||||
BOOST_TEST(x2.size() == 2);
|
||||
BOOST_TEST(*x2.begin() == 10 || *x2.begin() == 50);
|
||||
} catch(test_exception) {
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
|
||||
throwing_test_exception = false;
|
||||
}
|
||||
bool throwing_test_exception = false;
|
||||
void test_throw(char const* name)
|
||||
{
|
||||
if (throwing_test_exception) {
|
||||
std::cerr << "Throw exception in: " << name << std::endl;
|
||||
throw test_exception();
|
||||
}
|
||||
}
|
||||
|
||||
class hash_nothrow_move : boost::hash<int>
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(hash_nothrow_move)
|
||||
|
||||
typedef boost::hash<int> base;
|
||||
|
||||
public:
|
||||
hash_nothrow_move(BOOST_RV_REF(hash_nothrow_move)) BOOST_NOEXCEPT {}
|
||||
|
||||
hash_nothrow_move() { test_throw("Constructor"); }
|
||||
hash_nothrow_move(hash_nothrow_move const&) { test_throw("Copy"); }
|
||||
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>
|
||||
{
|
||||
BOOST_COPYABLE_AND_MOVABLE(equal_to_nothrow_move)
|
||||
|
||||
typedef std::equal_to<int> base;
|
||||
|
||||
public:
|
||||
equal_to_nothrow_move(BOOST_RV_REF(equal_to_nothrow_move)) BOOST_NOEXCEPT {}
|
||||
equal_to_nothrow_move() { test_throw("Constructor"); }
|
||||
equal_to_nothrow_move(equal_to_nothrow_move const&) { test_throw("Copy"); }
|
||||
equal_to_nothrow_move& operator=(
|
||||
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);
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(test_noexcept)
|
||||
{
|
||||
if (have_is_nothrow_move) {
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_set<int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_multiset<int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_map<int, int> >::value));
|
||||
BOOST_TEST((boost::is_nothrow_move_constructible<
|
||||
boost::unordered_multimap<int, int> >::value));
|
||||
}
|
||||
|
||||
BOOST_TEST((!boost::is_nothrow_move_constructible<
|
||||
boost::unordered_set<int, hash_possible_exception> >::value));
|
||||
BOOST_TEST(
|
||||
(!boost::is_nothrow_move_constructible<boost::unordered_multiset<int,
|
||||
boost::hash<int>, equal_to_possible_exception> >::value));
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(test_no_throw_when_noexcept)
|
||||
{
|
||||
typedef boost::unordered_set<int, hash_nothrow_move, equal_to_nothrow_move>
|
||||
throwing_set;
|
||||
|
||||
if (have_is_nothrow_move) {
|
||||
BOOST_TEST(boost::is_nothrow_move_constructible<throwing_set>::value);
|
||||
|
||||
throwing_test_exception = false;
|
||||
|
||||
throwing_set x1;
|
||||
x1.insert(10);
|
||||
x1.insert(50);
|
||||
|
||||
try {
|
||||
throwing_test_exception = true;
|
||||
|
||||
throwing_set x2 = boost::move(x1);
|
||||
BOOST_TEST(x2.size() == 2);
|
||||
BOOST_TEST(*x2.begin() == 10 || *x2.begin() == 50);
|
||||
} catch (test_exception) {
|
||||
BOOST_TEST(false);
|
||||
}
|
||||
|
||||
throwing_test_exception = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
#include "../helpers/metafunctions.hpp"
|
||||
#include "../objects/test.hpp"
|
||||
|
||||
namespace rehash_tests
|
||||
{
|
||||
namespace rehash_tests {
|
||||
|
||||
test::seed_t initialize_seed(2974);
|
||||
|
||||
@@ -25,12 +24,11 @@ template <class X>
|
||||
bool postcondition(X const& x, BOOST_DEDUCED_TYPENAME X::size_type n)
|
||||
{
|
||||
return static_cast<double>(x.bucket_count()) >=
|
||||
static_cast<double>(x.size()) / x.max_load_factor() &&
|
||||
x.bucket_count() >= n;
|
||||
static_cast<double>(x.size()) / x.max_load_factor() &&
|
||||
x.bucket_count() >= n;
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void rehash_empty_test1(X*)
|
||||
template <class X> void rehash_empty_test1(X*)
|
||||
{
|
||||
X x;
|
||||
|
||||
@@ -44,8 +42,7 @@ void rehash_empty_test1(X*)
|
||||
BOOST_TEST(postcondition(x, 10000000));
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void rehash_empty_test2(X*, test::random_generator generator)
|
||||
template <class X> void rehash_empty_test2(X*, test::random_generator generator)
|
||||
{
|
||||
test::random_values<X> v(1000, generator);
|
||||
test::ordered<X> tracker;
|
||||
@@ -60,14 +57,13 @@ void rehash_empty_test2(X*, test::random_generator generator)
|
||||
tracker.compare(x);
|
||||
|
||||
BOOST_TEST(postcondition(x, 10000));
|
||||
|
||||
|
||||
x.rehash(10000000);
|
||||
tracker.compare(x);
|
||||
BOOST_TEST(postcondition(x, 10000000));
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void rehash_empty_test3(X*, test::random_generator generator)
|
||||
template <class X> void rehash_empty_test3(X*, test::random_generator generator)
|
||||
{
|
||||
test::random_values<X> v(1000, generator);
|
||||
test::ordered<X> tracker;
|
||||
@@ -84,31 +80,33 @@ void rehash_empty_test3(X*, test::random_generator generator)
|
||||
BOOST_TEST(postcondition(x, 0));
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void rehash_test1(X*, test::random_generator generator)
|
||||
template <class X> void rehash_test1(X*, test::random_generator generator)
|
||||
{
|
||||
test::random_values<X> v(1000, generator);
|
||||
test::ordered<X> tracker;
|
||||
tracker.insert_range(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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
x.rehash(1000); BOOST_TEST(postcondition(x, 1000));
|
||||
x.rehash(1000);
|
||||
BOOST_TEST(postcondition(x, 1000));
|
||||
tracker.compare(x);
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void reserve_empty_test1(X*)
|
||||
template <class X> void reserve_empty_test1(X*)
|
||||
{
|
||||
X x;
|
||||
|
||||
@@ -121,8 +119,7 @@ void reserve_empty_test1(X*)
|
||||
BOOST_TEST(x.bucket_count() >= 10000000);
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void reserve_empty_test2(X*)
|
||||
template <class X> void reserve_empty_test2(X*)
|
||||
{
|
||||
X x;
|
||||
x.max_load_factor(0.25);
|
||||
@@ -136,21 +133,20 @@ void reserve_empty_test2(X*)
|
||||
BOOST_TEST(x.bucket_count() >= 40000000);
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void reserve_test1(X*, test::random_generator generator)
|
||||
template <class X> void reserve_test1(X*, test::random_generator generator)
|
||||
{
|
||||
for (int random_mlf = 0; random_mlf < 2; ++random_mlf)
|
||||
{
|
||||
for (std::size_t i = 1; i < 2000; i += i < 50 ? 1 : 13)
|
||||
{
|
||||
for (int random_mlf = 0; random_mlf < 2; ++random_mlf) {
|
||||
for (std::size_t i = 1; i < 2000; i += i < 50 ? 1 : 13) {
|
||||
test::random_values<X> v(i, generator);
|
||||
|
||||
test::ordered<X> tracker;
|
||||
tracker.insert_range(v.begin(), v.end());
|
||||
|
||||
X x;
|
||||
x.max_load_factor(random_mlf ?
|
||||
static_cast<float>(std::rand() % 1000) / 500.0f + 0.5f : 1.0f);
|
||||
x.max_load_factor(
|
||||
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());
|
||||
|
||||
// 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>
|
||||
void reserve_test2(X*, test::random_generator generator)
|
||||
template <class X> void reserve_test2(X*, test::random_generator generator)
|
||||
{
|
||||
for (int random_mlf = 0; random_mlf < 2; ++random_mlf)
|
||||
{
|
||||
for (std::size_t i = 0; i < 2000; i += i < 50 ? 1 : 13)
|
||||
{
|
||||
for (int random_mlf = 0; random_mlf < 2; ++random_mlf) {
|
||||
for (std::size_t i = 0; i < 2000; i += i < 50 ? 1 : 13) {
|
||||
test::random_values<X> v(i, generator);
|
||||
|
||||
test::ordered<X> tracker;
|
||||
tracker.insert_range(v.begin(), v.end());
|
||||
|
||||
X x;
|
||||
x.max_load_factor(random_mlf ?
|
||||
static_cast<float>(std::rand() % 1000) / 500.0f + 0.5f : 1.0f);
|
||||
x.max_load_factor(
|
||||
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());
|
||||
|
||||
std::size_t bucket_count = x.bucket_count();
|
||||
for (typename test::random_values<X>::iterator it = v.begin();
|
||||
it != v.end(); ++it)
|
||||
{
|
||||
it != v.end(); ++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_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_multiset_ptr;
|
||||
boost::unordered_map<test::movable, test::movable,
|
||||
test::hash, test::equal_to,
|
||||
boost::unordered_map<test::movable, test::movable, test::hash, test::equal_to,
|
||||
test::allocator2<test::movable> >* test_map_ptr;
|
||||
boost::unordered_multimap<int, int>* int_multimap_ptr;
|
||||
|
||||
@@ -213,35 +205,26 @@ using test::generate_collisions;
|
||||
using test::limited_range;
|
||||
|
||||
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,
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
UNORDERED_TEST(rehash_empty_test3,
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
UNORDERED_TEST(rehash_test1,
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
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,
|
||||
((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,
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
UNORDERED_TEST(reserve_test2,
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))
|
||||
((default_generator)(generate_collisions)(limited_range))
|
||||
)
|
||||
|
||||
((int_set_ptr)(test_multiset_ptr)(test_map_ptr)(int_multimap_ptr))(
|
||||
(default_generator)(generate_collisions)(limited_range)))
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
#include <algorithm>
|
||||
#include "../helpers/equivalent.hpp"
|
||||
|
||||
template <class X>
|
||||
void simple_test(X const& a)
|
||||
template <class X> void simple_test(X const& a)
|
||||
{
|
||||
test::unordered_equivalence_tester<X> equivalent(a);
|
||||
|
||||
@@ -74,9 +73,8 @@ void simple_test(X const& a)
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST(a.size() ==
|
||||
static_cast<BOOST_DEDUCED_TYPENAME X::size_type>(
|
||||
std::distance(a.begin(), a.end())));
|
||||
BOOST_TEST(a.size() == static_cast<BOOST_DEDUCED_TYPENAME X::size_type>(
|
||||
std::distance(a.begin(), a.end())));
|
||||
}
|
||||
|
||||
{
|
||||
@@ -95,38 +93,40 @@ UNORDERED_AUTO_TEST(simple_tests)
|
||||
using namespace std;
|
||||
srand(14878);
|
||||
|
||||
std::cout<<"Test unordered_set.\n";
|
||||
std::cout << "Test unordered_set.\n";
|
||||
boost::unordered_set<int> 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);
|
||||
|
||||
std::cout<<"Test unordered_multiset.\n";
|
||||
std::cout << "Test unordered_multiset.\n";
|
||||
boost::unordered_multiset<int> multiset;
|
||||
simple_test(multiset);
|
||||
|
||||
for(int i1 = 0; i1 < 1000; ++i1) {
|
||||
|
||||
for (int i1 = 0; i1 < 1000; ++i1) {
|
||||
int count = rand() % 10, index = rand();
|
||||
for(int j = 0; j < count; ++j)
|
||||
for (int j = 0; j < count; ++j)
|
||||
multiset.insert(index);
|
||||
}
|
||||
simple_test(multiset);
|
||||
|
||||
std::cout<<"Test unordered_map.\n";
|
||||
|
||||
std::cout << "Test unordered_map.\n";
|
||||
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()));
|
||||
}
|
||||
simple_test(map);
|
||||
|
||||
std::cout<<"Test unordered_multimap.\n";
|
||||
std::cout << "Test unordered_multimap.\n";
|
||||
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();
|
||||
for(int j = 0; j < count; ++j)
|
||||
for (int j = 0; j < count; ++j)
|
||||
multimap.insert(std::pair<const int, int>(index, rand()));
|
||||
}
|
||||
simple_test(multimap);
|
||||
|
||||
@@ -21,16 +21,14 @@
|
||||
#include "../helpers/invariants.hpp"
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(disable:4127) // conditional expression is constant
|
||||
#pragma warning(disable : 4127) // conditional expression is constant
|
||||
#endif
|
||||
|
||||
namespace swap_tests
|
||||
{
|
||||
namespace swap_tests {
|
||||
|
||||
test::seed_t initialize_seed(783472);
|
||||
|
||||
template <class X>
|
||||
void swap_test_impl(X& x1, X& x2)
|
||||
template <class X> void swap_test_impl(X& x1, X& x2)
|
||||
{
|
||||
test::ordered<X> tracker1 = test::create_ordered(x1);
|
||||
test::ordered<X> tracker2 = test::create_ordered(x2);
|
||||
@@ -41,8 +39,7 @@ void swap_test_impl(X& x1, X& x2)
|
||||
tracker2.compare(x1);
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void swap_tests1(X*, test::random_generator generator)
|
||||
template <class X> void swap_tests1(X*, test::random_generator generator)
|
||||
{
|
||||
{
|
||||
test::check_instances check_;
|
||||
@@ -54,7 +51,7 @@ void swap_tests1(X*, test::random_generator generator)
|
||||
{
|
||||
test::check_instances check_;
|
||||
|
||||
X x,y;
|
||||
X x, y;
|
||||
swap_test_impl(x, y);
|
||||
}
|
||||
|
||||
@@ -77,8 +74,7 @@ void swap_tests1(X*, test::random_generator generator)
|
||||
}
|
||||
}
|
||||
|
||||
template <class X>
|
||||
void swap_tests2(X* ptr, test::random_generator generator)
|
||||
template <class X> void swap_tests2(X* ptr, test::random_generator 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));
|
||||
|
||||
if (allocator_type::is_propagate_on_swap ||
|
||||
x.get_allocator() == y.get_allocator())
|
||||
{
|
||||
x.get_allocator() == y.get_allocator()) {
|
||||
swap_test_impl(x, y);
|
||||
}
|
||||
}
|
||||
@@ -141,67 +136,53 @@ void swap_tests2(X* ptr, test::random_generator generator)
|
||||
allocator_type(2));
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
std::allocator<test::object> >* test_map_std_alloc;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
std::allocator<test::object> >* test_map_std_alloc;
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_multimap;
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_set;
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::allocator2<test::object> >* test_multiset;
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::allocator1<test::object> >* test_map;
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::allocator2<test::object> >* test_multimap;
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_swap> >*
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_swap> >*
|
||||
test_set_prop_swap;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_swap> >*
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_swap> >*
|
||||
test_multiset_prop_swap;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_swap> >*
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_swap> >*
|
||||
test_map_prop_swap;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::propagate_swap> >*
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to, test::cxx11_allocator<test::object, test::propagate_swap> >*
|
||||
test_multimap_prop_swap;
|
||||
|
||||
boost::unordered_set<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_swap> >*
|
||||
boost::unordered_set<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_swap> >*
|
||||
test_set_no_prop_swap;
|
||||
boost::unordered_multiset<test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_swap> >*
|
||||
boost::unordered_multiset<test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_swap> >*
|
||||
test_multiset_no_prop_swap;
|
||||
boost::unordered_map<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_swap> >*
|
||||
boost::unordered_map<test::object, test::object, test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_swap> >*
|
||||
test_map_no_prop_swap;
|
||||
boost::unordered_multimap<test::object, test::object,
|
||||
test::hash, test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_swap> >*
|
||||
boost::unordered_multimap<test::object, test::object, test::hash,
|
||||
test::equal_to,
|
||||
test::cxx11_allocator<test::object, test::no_propagate_swap> >*
|
||||
test_multimap_no_prop_swap;
|
||||
|
||||
template <typename T>
|
||||
bool is_propagate(T*)
|
||||
template <typename T> bool is_propagate(T*)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
UNORDERED_TEST(swap_tests1, (
|
||||
(test_map_std_alloc)
|
||||
(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))
|
||||
)
|
||||
UNORDERED_TEST(swap_tests1,
|
||||
((test_map_std_alloc)(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()
|
||||
|
||||
@@ -13,101 +13,100 @@
|
||||
#include <iostream>
|
||||
#include "../helpers/test.hpp"
|
||||
|
||||
namespace unnecessary_copy_tests
|
||||
namespace unnecessary_copy_tests {
|
||||
struct count_copies
|
||||
{
|
||||
struct count_copies
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(count_copies)
|
||||
public:
|
||||
static int copies;
|
||||
static int moves;
|
||||
static int id_count;
|
||||
|
||||
count_copies() : tag_(0), id_(++id_count)
|
||||
{
|
||||
private:
|
||||
BOOST_COPYABLE_AND_MOVABLE(count_copies)
|
||||
public:
|
||||
static int copies;
|
||||
static int moves;
|
||||
static int id_count;
|
||||
|
||||
count_copies() : tag_(0), id_(++id_count) {
|
||||
++copies;
|
||||
trace_op("Default construct");
|
||||
}
|
||||
|
||||
explicit count_copies(int tag) : tag_(tag), id_(++id_count) {
|
||||
++copies;
|
||||
trace_op("Tag construct");
|
||||
}
|
||||
|
||||
// This bizarre constructor is an attempt to confuse emplace.
|
||||
//
|
||||
// unordered_map<count_copies, count_copies> x:
|
||||
// x.emplace(count_copies(1), count_copies(2));
|
||||
// x.emplace(count_copies(1), count_copies(2), count_copies(3));
|
||||
//
|
||||
// The first emplace should use the single argument constructor twice.
|
||||
// The second emplace should use the single argument contructor for
|
||||
// the key, and this constructor for the value.
|
||||
count_copies(count_copies const&, count_copies const& x)
|
||||
: tag_(x.tag_), id_(++id_count)
|
||||
{
|
||||
++copies;
|
||||
trace_op("Pair construct");
|
||||
}
|
||||
|
||||
count_copies(count_copies const& x) : tag_(x.tag_), id_(++id_count)
|
||||
{
|
||||
++copies;
|
||||
trace_op("Copy construct");
|
||||
}
|
||||
|
||||
count_copies(BOOST_RV_REF(count_copies) x) :
|
||||
tag_(x.tag_), id_(++id_count)
|
||||
{
|
||||
x.tag_ = -1; ++moves;
|
||||
trace_op("Move construct");
|
||||
}
|
||||
|
||||
count_copies& operator=(BOOST_COPY_ASSIGN_REF(count_copies) p) // Copy assignment
|
||||
{
|
||||
tag_ = p.tag_;
|
||||
++copies;
|
||||
trace_op("Copy assign");
|
||||
return *this;
|
||||
}
|
||||
|
||||
count_copies& operator=(BOOST_RV_REF(count_copies) p) //Move assignment
|
||||
{
|
||||
tag_ = p.tag_;
|
||||
++moves;
|
||||
trace_op("Move assign");
|
||||
return *this;
|
||||
}
|
||||
|
||||
~count_copies() {
|
||||
trace_op("Destruct");
|
||||
}
|
||||
|
||||
void trace_op(char const* str) {
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << str << ": " << tag_
|
||||
<< " (#" << id_ << ")" <<std::endl;
|
||||
}
|
||||
|
||||
int tag_;
|
||||
int id_;
|
||||
};
|
||||
|
||||
bool operator==(count_copies const& x, count_copies const& y) {
|
||||
return x.tag_ == y.tag_;
|
||||
++copies;
|
||||
trace_op("Default construct");
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T source() {
|
||||
return T();
|
||||
explicit count_copies(int tag) : tag_(tag), id_(++id_count)
|
||||
{
|
||||
++copies;
|
||||
trace_op("Tag construct");
|
||||
}
|
||||
|
||||
void reset() {
|
||||
count_copies::copies = 0;
|
||||
count_copies::moves = 0;
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM
|
||||
<< "\nReset\n" << std::endl;
|
||||
// This bizarre constructor is an attempt to confuse emplace.
|
||||
//
|
||||
// unordered_map<count_copies, count_copies> x:
|
||||
// x.emplace(count_copies(1), count_copies(2));
|
||||
// x.emplace(count_copies(1), count_copies(2), count_copies(3));
|
||||
//
|
||||
// The first emplace should use the single argument constructor twice.
|
||||
// The second emplace should use the single argument contructor for
|
||||
// the key, and this constructor for the value.
|
||||
count_copies(count_copies const&, count_copies const& x)
|
||||
: tag_(x.tag_), id_(++id_count)
|
||||
{
|
||||
++copies;
|
||||
trace_op("Pair construct");
|
||||
}
|
||||
|
||||
count_copies(count_copies const& x) : tag_(x.tag_), id_(++id_count)
|
||||
{
|
||||
++copies;
|
||||
trace_op("Copy construct");
|
||||
}
|
||||
|
||||
count_copies(BOOST_RV_REF(count_copies) x) : tag_(x.tag_), id_(++id_count)
|
||||
{
|
||||
x.tag_ = -1;
|
||||
++moves;
|
||||
trace_op("Move construct");
|
||||
}
|
||||
|
||||
count_copies& operator=(
|
||||
BOOST_COPY_ASSIGN_REF(count_copies) p) // Copy assignment
|
||||
{
|
||||
tag_ = p.tag_;
|
||||
++copies;
|
||||
trace_op("Copy assign");
|
||||
return *this;
|
||||
}
|
||||
|
||||
count_copies& operator=(BOOST_RV_REF(count_copies) p) // Move assignment
|
||||
{
|
||||
tag_ = p.tag_;
|
||||
++moves;
|
||||
trace_op("Move assign");
|
||||
return *this;
|
||||
}
|
||||
|
||||
~count_copies() { trace_op("Destruct"); }
|
||||
|
||||
void trace_op(char const* str)
|
||||
{
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << str << ": " << tag_ << " (#" << id_
|
||||
<< ")" << std::endl;
|
||||
}
|
||||
|
||||
int tag_;
|
||||
int id_;
|
||||
};
|
||||
|
||||
bool operator==(count_copies const& x, count_copies const& y)
|
||||
{
|
||||
return x.tag_ == y.tag_;
|
||||
}
|
||||
|
||||
template <class T> T source() { return T(); }
|
||||
|
||||
void reset()
|
||||
{
|
||||
count_copies::copies = 0;
|
||||
count_copies::moves = 0;
|
||||
|
||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM << "\nReset\n" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
|
||||
@@ -116,9 +115,10 @@ namespace boost
|
||||
namespace unnecessary_copy_tests
|
||||
#endif
|
||||
{
|
||||
std::size_t hash_value(unnecessary_copy_tests::count_copies const& x) {
|
||||
return static_cast<std::size_t>(x.tag_);
|
||||
}
|
||||
std::size_t hash_value(unnecessary_copy_tests::count_copies const& x)
|
||||
{
|
||||
return static_cast<std::size_t>(x.tag_);
|
||||
}
|
||||
}
|
||||
|
||||
// Boost.Move doesn't seem to work very well on this compiler.
|
||||
@@ -135,395 +135,408 @@ namespace unnecessary_copy_tests
|
||||
#define EXTRA_CONSTRUCT_COST 0
|
||||
#endif
|
||||
|
||||
#define COPY_COUNT(n) \
|
||||
if(::unnecessary_copy_tests::count_copies::copies != n) { \
|
||||
BOOST_ERROR("Wrong number of copies."); \
|
||||
std::cerr \
|
||||
<< "Number of copies: " \
|
||||
<< ::unnecessary_copy_tests::count_copies::copies \
|
||||
<< " expecting: " << n << std::endl; \
|
||||
#define COPY_COUNT(n) \
|
||||
if (::unnecessary_copy_tests::count_copies::copies != n) { \
|
||||
BOOST_ERROR("Wrong number of copies."); \
|
||||
std::cerr << "Number of copies: " \
|
||||
<< ::unnecessary_copy_tests::count_copies::copies \
|
||||
<< " expecting: " << n << std::endl; \
|
||||
}
|
||||
#define MOVE_COUNT(n) \
|
||||
if(::unnecessary_copy_tests::count_copies::moves != n) { \
|
||||
BOOST_ERROR("Wrong number of moves."); \
|
||||
std::cerr \
|
||||
<< "Number of moves: " \
|
||||
<< ::unnecessary_copy_tests::count_copies::moves \
|
||||
<< " expecting: " <<n << std::endl; \
|
||||
#define MOVE_COUNT(n) \
|
||||
if (::unnecessary_copy_tests::count_copies::moves != n) { \
|
||||
BOOST_ERROR("Wrong number of moves."); \
|
||||
std::cerr << "Number of moves: " \
|
||||
<< ::unnecessary_copy_tests::count_copies::moves \
|
||||
<< " expecting: " << n << std::endl; \
|
||||
}
|
||||
#define COPY_COUNT_RANGE(a, b) \
|
||||
if(::unnecessary_copy_tests::count_copies::copies < a || \
|
||||
::unnecessary_copy_tests::count_copies::copies > b) { \
|
||||
BOOST_ERROR("Wrong number of copies."); \
|
||||
std::cerr \
|
||||
<< "Number of copies: " \
|
||||
<< ::unnecessary_copy_tests::count_copies::copies \
|
||||
<< " expecting: [" << a << ", " << b << "]" << std::endl; \
|
||||
#define COPY_COUNT_RANGE(a, b) \
|
||||
if (::unnecessary_copy_tests::count_copies::copies < a || \
|
||||
::unnecessary_copy_tests::count_copies::copies > b) { \
|
||||
BOOST_ERROR("Wrong number of copies."); \
|
||||
std::cerr << "Number of copies: " \
|
||||
<< ::unnecessary_copy_tests::count_copies::copies \
|
||||
<< " expecting: [" << a << ", " << b << "]" << std::endl; \
|
||||
}
|
||||
#define MOVE_COUNT_RANGE(a, b) \
|
||||
if(::unnecessary_copy_tests::count_copies::moves < a || \
|
||||
::unnecessary_copy_tests::count_copies::moves > b) { \
|
||||
BOOST_ERROR("Wrong number of moves."); \
|
||||
std::cerr \
|
||||
<< "Number of moves: " \
|
||||
<< ::unnecessary_copy_tests::count_copies::moves \
|
||||
<< " expecting: [" << a << ", " << b << "]" << std::endl; \
|
||||
#define MOVE_COUNT_RANGE(a, b) \
|
||||
if (::unnecessary_copy_tests::count_copies::moves < a || \
|
||||
::unnecessary_copy_tests::count_copies::moves > b) { \
|
||||
BOOST_ERROR("Wrong number of moves."); \
|
||||
std::cerr << "Number of moves: " \
|
||||
<< ::unnecessary_copy_tests::count_copies::moves \
|
||||
<< " expecting: [" << a << ", " << b << "]" << std::endl; \
|
||||
}
|
||||
#define COPY_COUNT_EXTRA(a, b) \
|
||||
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 COPY_COUNT_EXTRA(a, b) COPY_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;
|
||||
T x;
|
||||
BOOST_DEDUCED_TYPENAME T::value_type a;
|
||||
reset();
|
||||
x.insert(a);
|
||||
COPY_COUNT(1);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void unnecessary_copy_insert_test(T*)
|
||||
{
|
||||
T x;
|
||||
BOOST_DEDUCED_TYPENAME T::value_type a;
|
||||
reset();
|
||||
x.insert(a);
|
||||
COPY_COUNT(1);
|
||||
}
|
||||
boost::unordered_set<count_copies>* set;
|
||||
boost::unordered_multiset<count_copies>* multiset;
|
||||
boost::unordered_map<int, count_copies>* map;
|
||||
boost::unordered_multimap<int, count_copies>* multimap;
|
||||
|
||||
boost::unordered_set<count_copies>* set;
|
||||
boost::unordered_multiset<count_copies>* multiset;
|
||||
boost::unordered_map<int, count_copies>* map;
|
||||
boost::unordered_multimap<int, count_copies>* multimap;
|
||||
UNORDERED_TEST(unnecessary_copy_insert_test, ((set)(multiset)(map)(multimap)))
|
||||
|
||||
UNORDERED_TEST(unnecessary_copy_insert_test,
|
||||
((set)(multiset)(map)(multimap)))
|
||||
template <class T> void unnecessary_copy_emplace_test(T*)
|
||||
{
|
||||
reset();
|
||||
T x;
|
||||
BOOST_DEDUCED_TYPENAME T::value_type a;
|
||||
COPY_COUNT(1);
|
||||
x.emplace(a);
|
||||
COPY_COUNT(2);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void unnecessary_copy_emplace_test(T*)
|
||||
{
|
||||
reset();
|
||||
T x;
|
||||
BOOST_DEDUCED_TYPENAME T::value_type a;
|
||||
COPY_COUNT(1);
|
||||
x.emplace(a);
|
||||
COPY_COUNT(2);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void unnecessary_copy_emplace_rvalue_test(T*)
|
||||
{
|
||||
reset();
|
||||
T x;
|
||||
x.emplace(source<BOOST_DEDUCED_TYPENAME T::value_type>());
|
||||
template <class T> void unnecessary_copy_emplace_rvalue_test(T*)
|
||||
{
|
||||
reset();
|
||||
T x;
|
||||
x.emplace(source<BOOST_DEDUCED_TYPENAME T::value_type>());
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
COPY_COUNT(1);
|
||||
COPY_COUNT(1);
|
||||
#else
|
||||
COPY_COUNT(2);
|
||||
COPY_COUNT(2);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
UNORDERED_TEST(unnecessary_copy_emplace_test,
|
||||
((set)(multiset)(map)(multimap)))
|
||||
UNORDERED_TEST(unnecessary_copy_emplace_rvalue_test,
|
||||
((set)(multiset)(map)(multimap)))
|
||||
UNORDERED_TEST(unnecessary_copy_emplace_test, ((set)(multiset)(map)(multimap)))
|
||||
UNORDERED_TEST(
|
||||
unnecessary_copy_emplace_rvalue_test, ((set)(multiset)(map)(multimap)))
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template <class T>
|
||||
void unnecessary_copy_emplace_std_move_test(T*)
|
||||
{
|
||||
reset();
|
||||
T x;
|
||||
BOOST_DEDUCED_TYPENAME T::value_type a;
|
||||
COPY_COUNT(1); MOVE_COUNT(0);
|
||||
x.emplace(std::move(a));
|
||||
COPY_COUNT(1); MOVE_COUNT(1);
|
||||
}
|
||||
template <class T> void unnecessary_copy_emplace_std_move_test(T*)
|
||||
{
|
||||
reset();
|
||||
T x;
|
||||
BOOST_DEDUCED_TYPENAME T::value_type a;
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT(0);
|
||||
x.emplace(std::move(a));
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT(1);
|
||||
}
|
||||
|
||||
UNORDERED_TEST(unnecessary_copy_emplace_std_move_test,
|
||||
((set)(multiset)(map)(multimap)))
|
||||
UNORDERED_TEST(
|
||||
unnecessary_copy_emplace_std_move_test, ((set)(multiset)(map)(multimap)))
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
void unnecessary_copy_emplace_boost_move_test(T*)
|
||||
{
|
||||
reset();
|
||||
T x;
|
||||
BOOST_DEDUCED_TYPENAME T::value_type a;
|
||||
COPY_COUNT(1); MOVE_COUNT_EXTRA(0, 1);
|
||||
x.emplace(boost::move(a));
|
||||
template <class T> void unnecessary_copy_emplace_boost_move_test(T*)
|
||||
{
|
||||
reset();
|
||||
T x;
|
||||
BOOST_DEDUCED_TYPENAME T::value_type a;
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT_EXTRA(0, 1);
|
||||
x.emplace(boost::move(a));
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
COPY_COUNT(1); MOVE_COUNT(1);
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT(1);
|
||||
#else
|
||||
// Since std::pair isn't movable, move only works for sets.
|
||||
COPY_COUNT_RANGE(1, 2); MOVE_COUNT_RANGE(0, 1);
|
||||
// Since std::pair isn't movable, move only works for sets.
|
||||
COPY_COUNT_RANGE(1, 2);
|
||||
MOVE_COUNT_RANGE(0, 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
UNORDERED_TEST(unnecessary_copy_emplace_boost_move_test,
|
||||
((set)(multiset)(map)(multimap)))
|
||||
UNORDERED_TEST(
|
||||
unnecessary_copy_emplace_boost_move_test, ((set)(multiset)(map)(multimap)))
|
||||
|
||||
template <class T>
|
||||
void unnecessary_copy_emplace_boost_move_set_test(T*)
|
||||
{
|
||||
reset();
|
||||
T x;
|
||||
BOOST_DEDUCED_TYPENAME T::value_type a;
|
||||
COPY_COUNT(1); MOVE_COUNT(0);
|
||||
x.emplace(boost::move(a));
|
||||
COPY_COUNT(1); MOVE_COUNT(1);
|
||||
}
|
||||
template <class T> void unnecessary_copy_emplace_boost_move_set_test(T*)
|
||||
{
|
||||
reset();
|
||||
T x;
|
||||
BOOST_DEDUCED_TYPENAME T::value_type a;
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT(0);
|
||||
x.emplace(boost::move(a));
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT(1);
|
||||
}
|
||||
|
||||
UNORDERED_TEST(unnecessary_copy_emplace_boost_move_set_test,
|
||||
((set)(multiset)))
|
||||
UNORDERED_TEST(unnecessary_copy_emplace_boost_move_set_test, ((set)(multiset)))
|
||||
|
||||
template <class T>
|
||||
void unnecessary_copy_emplace_boost_move_map_test(T*)
|
||||
{
|
||||
reset();
|
||||
T x;
|
||||
COPY_COUNT(0); MOVE_COUNT(0);
|
||||
BOOST_DEDUCED_TYPENAME T::value_type a;
|
||||
COPY_COUNT(1); MOVE_COUNT_EXTRA(0, 1);
|
||||
x.emplace(boost::move(a));
|
||||
template <class T> void unnecessary_copy_emplace_boost_move_map_test(T*)
|
||||
{
|
||||
reset();
|
||||
T x;
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT(0);
|
||||
BOOST_DEDUCED_TYPENAME T::value_type a;
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT_EXTRA(0, 1);
|
||||
x.emplace(boost::move(a));
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
COPY_COUNT(2); MOVE_COUNT_EXTRA(0, 1);
|
||||
COPY_COUNT(2);
|
||||
MOVE_COUNT_EXTRA(0, 1);
|
||||
#else
|
||||
COPY_COUNT(1); MOVE_COUNT(1);
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT(1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
UNORDERED_TEST(unnecessary_copy_emplace_boost_move_map_test,
|
||||
((map)(multimap)))
|
||||
UNORDERED_TEST(unnecessary_copy_emplace_boost_move_map_test, ((map)(multimap)))
|
||||
|
||||
UNORDERED_AUTO_TEST(unnecessary_copy_emplace_set_test)
|
||||
{
|
||||
// When calling 'source' the object is moved on some compilers, but not
|
||||
// others. So count that here to adjust later.
|
||||
UNORDERED_AUTO_TEST(unnecessary_copy_emplace_set_test)
|
||||
{
|
||||
// When calling 'source' the object is moved on some compilers, but not
|
||||
// others. So count that here to adjust later.
|
||||
|
||||
reset();
|
||||
source<count_copies>();
|
||||
int source_cost = ::unnecessary_copy_tests::count_copies::moves;
|
||||
reset();
|
||||
source<count_copies>();
|
||||
int source_cost = ::unnecessary_copy_tests::count_copies::moves;
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
reset();
|
||||
boost::unordered_set<count_copies> x;
|
||||
count_copies a;
|
||||
x.insert(a);
|
||||
COPY_COUNT(2); MOVE_COUNT(0);
|
||||
reset();
|
||||
boost::unordered_set<count_copies> x;
|
||||
count_copies a;
|
||||
x.insert(a);
|
||||
COPY_COUNT(2);
|
||||
MOVE_COUNT(0);
|
||||
|
||||
//
|
||||
// 0 arguments
|
||||
//
|
||||
//
|
||||
// 0 arguments
|
||||
//
|
||||
|
||||
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
|
||||
// The container will have to create a copy in order to compare with
|
||||
// the existing element.
|
||||
reset();
|
||||
x.emplace();
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || \
|
||||
// The container will have to create a copy in order to compare with
|
||||
// the existing element.
|
||||
reset();
|
||||
x.emplace();
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
// source_cost doesn't make much sense here, but it seems to fit.
|
||||
COPY_COUNT(1); MOVE_COUNT(source_cost);
|
||||
// source_cost doesn't make much sense here, but it seems to fit.
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT(source_cost);
|
||||
#else
|
||||
COPY_COUNT(1); MOVE_COUNT(1 + source_cost);
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT(1 + source_cost);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// 1 argument
|
||||
//
|
||||
//
|
||||
// 1 argument
|
||||
//
|
||||
|
||||
// Emplace should be able to tell that there already is an element
|
||||
// without creating a new one.
|
||||
reset();
|
||||
x.emplace(a);
|
||||
COPY_COUNT(0); MOVE_COUNT(0);
|
||||
// Emplace should be able to tell that there already is an element
|
||||
// without creating a new one.
|
||||
reset();
|
||||
x.emplace(a);
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT(0);
|
||||
|
||||
// A new object is created by source, but it shouldn't be moved or
|
||||
// copied.
|
||||
reset();
|
||||
x.emplace(source<count_copies>());
|
||||
COPY_COUNT(1); MOVE_COUNT(source_cost);
|
||||
// A new object is created by source, but it shouldn't be moved or
|
||||
// copied.
|
||||
reset();
|
||||
x.emplace(source<count_copies>());
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT(source_cost);
|
||||
|
||||
// No move should take place.
|
||||
reset();
|
||||
x.emplace(boost::move(a));
|
||||
// No move should take place.
|
||||
reset();
|
||||
x.emplace(boost::move(a));
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
COPY_COUNT(0); MOVE_COUNT(0);
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT(0);
|
||||
#else
|
||||
COPY_COUNT(0); MOVE_COUNT(1);
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT(1);
|
||||
#endif
|
||||
|
||||
// Use a new value for cases where a did get moved...
|
||||
count_copies b;
|
||||
// Use a new value for cases where a did get moved...
|
||||
count_copies b;
|
||||
|
||||
// The container will have to create a copy in order to compare with
|
||||
// the existing element.
|
||||
reset();
|
||||
x.emplace(b.tag_);
|
||||
COPY_COUNT(1); MOVE_COUNT(0);
|
||||
// The container will have to create a copy in order to compare with
|
||||
// the existing element.
|
||||
reset();
|
||||
x.emplace(b.tag_);
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT(0);
|
||||
|
||||
//
|
||||
// 2 arguments
|
||||
//
|
||||
//
|
||||
// 2 arguments
|
||||
//
|
||||
|
||||
// The container will have to create b copy in order to compare with
|
||||
// the existing element.
|
||||
//
|
||||
// Note to self: If copy_count == 0 it's an error not an optimization.
|
||||
// TODO: Devise a better test.
|
||||
// The container will have to create b copy in order to compare with
|
||||
// the existing element.
|
||||
//
|
||||
// Note to self: If copy_count == 0 it's an error not an optimization.
|
||||
// TODO: Devise a better test.
|
||||
|
||||
reset();
|
||||
reset();
|
||||
|
||||
x.emplace(b, b);
|
||||
COPY_COUNT(1); MOVE_COUNT(0);
|
||||
}
|
||||
x.emplace(b, b);
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT(0);
|
||||
}
|
||||
|
||||
UNORDERED_AUTO_TEST(unnecessary_copy_emplace_map_test)
|
||||
{
|
||||
// When calling 'source' the object is moved on some compilers, but not
|
||||
// others. So count that here to adjust later.
|
||||
UNORDERED_AUTO_TEST(unnecessary_copy_emplace_map_test)
|
||||
{
|
||||
// When calling 'source' the object is moved on some compilers, but not
|
||||
// others. So count that here to adjust later.
|
||||
|
||||
reset();
|
||||
source<count_copies>();
|
||||
int source_cost = ::unnecessary_copy_tests::count_copies::moves;
|
||||
reset();
|
||||
source<count_copies>();
|
||||
int source_cost = ::unnecessary_copy_tests::count_copies::moves;
|
||||
|
||||
reset();
|
||||
source<std::pair<count_copies, count_copies> >();
|
||||
int source_pair_cost = ::unnecessary_copy_tests::count_copies::moves;
|
||||
reset();
|
||||
source<std::pair<count_copies, count_copies> >();
|
||||
int source_pair_cost = ::unnecessary_copy_tests::count_copies::moves;
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
reset();
|
||||
boost::unordered_map<count_copies, count_copies> x;
|
||||
// TODO: Run tests for pairs without const etc.
|
||||
std::pair<count_copies const, count_copies> a;
|
||||
x.emplace(a);
|
||||
COPY_COUNT_EXTRA(4, 1); MOVE_COUNT_EXTRA(0, 1);
|
||||
reset();
|
||||
boost::unordered_map<count_copies, count_copies> x;
|
||||
// TODO: Run tests for pairs without const etc.
|
||||
std::pair<count_copies const, count_copies> a;
|
||||
x.emplace(a);
|
||||
COPY_COUNT_EXTRA(4, 1);
|
||||
MOVE_COUNT_EXTRA(0, 1);
|
||||
|
||||
//
|
||||
// 0 arguments
|
||||
//
|
||||
//
|
||||
// 0 arguments
|
||||
//
|
||||
|
||||
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100))
|
||||
// COPY_COUNT(1) would be okay here.
|
||||
reset();
|
||||
x.emplace();
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1700)
|
||||
// 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
|
||||
// non-const mapped value). Since 'emplace(boost::move(a))' (see below)
|
||||
// has the normal result, it must be some odd consequence of how
|
||||
// Visual C++ 11 handles calling move for default arguments.
|
||||
COPY_COUNT(3); MOVE_COUNT(1);
|
||||
# else
|
||||
COPY_COUNT_EXTRA(2, 1); MOVE_COUNT_EXTRA(0, 1);
|
||||
# endif
|
||||
// COPY_COUNT(1) would be okay here.
|
||||
reset();
|
||||
x.emplace();
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, == 1700)
|
||||
// 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
|
||||
// non-const mapped value). Since 'emplace(boost::move(a))' (see below)
|
||||
// has the normal result, it must be some odd consequence of how
|
||||
// Visual C++ 11 handles calling move for default arguments.
|
||||
COPY_COUNT(3);
|
||||
MOVE_COUNT(1);
|
||||
#else
|
||||
COPY_COUNT_EXTRA(2, 1);
|
||||
MOVE_COUNT_EXTRA(0, 1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(),
|
||||
boost::make_tuple());
|
||||
COPY_COUNT(2); MOVE_COUNT(0);
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct, boost::make_tuple(),
|
||||
boost::make_tuple());
|
||||
COPY_COUNT(2);
|
||||
MOVE_COUNT(0);
|
||||
|
||||
//
|
||||
// 1 argument
|
||||
//
|
||||
|
||||
//
|
||||
// 1 argument
|
||||
//
|
||||
reset();
|
||||
x.emplace(a);
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT(0);
|
||||
|
||||
reset();
|
||||
x.emplace(a);
|
||||
COPY_COUNT(0); MOVE_COUNT(0);
|
||||
// A new object is created by source, but it shouldn't be moved or
|
||||
// copied.
|
||||
reset();
|
||||
x.emplace(source<std::pair<count_copies, count_copies> >());
|
||||
COPY_COUNT(2);
|
||||
MOVE_COUNT(source_pair_cost);
|
||||
|
||||
// A new object is created by source, but it shouldn't be moved or
|
||||
// copied.
|
||||
reset();
|
||||
x.emplace(source<std::pair<count_copies, count_copies> >());
|
||||
COPY_COUNT(2); MOVE_COUNT(source_pair_cost);
|
||||
|
||||
#if !(defined(__GNUC__) && __cplusplus < 199900L) && \
|
||||
#if !(defined(__GNUC__) && __cplusplus < 199900L) && \
|
||||
!(defined(_MSC_VER) && _MSC_VER < 1600)
|
||||
count_copies part;
|
||||
reset();
|
||||
std::pair<count_copies const&, count_copies const&> a_ref(part, part);
|
||||
x.emplace(a_ref);
|
||||
COPY_COUNT(2); MOVE_COUNT(0);
|
||||
count_copies part;
|
||||
reset();
|
||||
std::pair<count_copies const&, count_copies const&> a_ref(part, part);
|
||||
x.emplace(a_ref);
|
||||
COPY_COUNT(2);
|
||||
MOVE_COUNT(0);
|
||||
|
||||
#endif
|
||||
|
||||
// No move should take place.
|
||||
// (since a is already in the container)
|
||||
reset();
|
||||
x.emplace(boost::move(a));
|
||||
COPY_COUNT(0); MOVE_COUNT(0);
|
||||
// No move should take place.
|
||||
// (since a is already in the container)
|
||||
reset();
|
||||
x.emplace(boost::move(a));
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT(0);
|
||||
|
||||
//
|
||||
// 2 arguments
|
||||
//
|
||||
//
|
||||
// 2 arguments
|
||||
//
|
||||
|
||||
std::pair<count_copies const, count_copies> b;
|
||||
std::pair<count_copies const, count_copies> b;
|
||||
|
||||
reset();
|
||||
x.emplace(b.first, b.second);
|
||||
COPY_COUNT(0); MOVE_COUNT(0);
|
||||
reset();
|
||||
x.emplace(b.first, b.second);
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT(0);
|
||||
|
||||
reset();
|
||||
x.emplace(source<count_copies>(), source<count_copies>());
|
||||
COPY_COUNT(2); MOVE_COUNT(source_cost * 2);
|
||||
reset();
|
||||
x.emplace(source<count_copies>(), source<count_copies>());
|
||||
COPY_COUNT(2);
|
||||
MOVE_COUNT(source_cost * 2);
|
||||
|
||||
// source<count_copies> creates a single copy.
|
||||
reset();
|
||||
x.emplace(b.first, source<count_copies>());
|
||||
COPY_COUNT(1); MOVE_COUNT(source_cost);
|
||||
// source<count_copies> creates a single copy.
|
||||
reset();
|
||||
x.emplace(b.first, source<count_copies>());
|
||||
COPY_COUNT(1);
|
||||
MOVE_COUNT(source_cost);
|
||||
|
||||
reset();
|
||||
x.emplace(count_copies(b.first.tag_), count_copies(b.second.tag_));
|
||||
COPY_COUNT(2); MOVE_COUNT(0);
|
||||
reset();
|
||||
x.emplace(count_copies(b.first.tag_), count_copies(b.second.tag_));
|
||||
COPY_COUNT(2);
|
||||
MOVE_COUNT(0);
|
||||
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(boost::ref(b.first)),
|
||||
boost::make_tuple(boost::ref(b.second)));
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT(0);
|
||||
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
boost::make_tuple(boost::ref(b.first)),
|
||||
boost::make_tuple(boost::ref(b.second)));
|
||||
COPY_COUNT(0); MOVE_COUNT(0);
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) || defined(BOOST_HAS_TR1_TUPLE)
|
||||
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
std::make_tuple(std::ref(b.first)),
|
||||
std::make_tuple(std::ref(b.second)));
|
||||
COPY_COUNT(0); MOVE_COUNT(0);
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
std::make_tuple(std::ref(b.first)),
|
||||
std::make_tuple(std::ref(b.second)));
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT(0);
|
||||
|
||||
std::pair<count_copies const, count_copies> move_source_trial;
|
||||
reset();
|
||||
std::make_tuple(std::move(move_source_trial.first));
|
||||
std::make_tuple(std::move(move_source_trial.second));
|
||||
int tuple_move_cost = ::unnecessary_copy_tests::count_copies::moves;
|
||||
int tuple_copy_cost = ::unnecessary_copy_tests::count_copies::copies;
|
||||
std::pair<count_copies const, count_copies> move_source_trial;
|
||||
reset();
|
||||
std::make_tuple(std::move(move_source_trial.first));
|
||||
std::make_tuple(std::move(move_source_trial.second));
|
||||
int tuple_move_cost = ::unnecessary_copy_tests::count_copies::moves;
|
||||
int tuple_copy_cost = ::unnecessary_copy_tests::count_copies::copies;
|
||||
|
||||
std::pair<count_copies const, count_copies> move_source;
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
std::make_tuple(std::move(move_source.first)),
|
||||
std::make_tuple(std::move(move_source.second)));
|
||||
COPY_COUNT(tuple_copy_cost);
|
||||
MOVE_COUNT(tuple_move_cost);
|
||||
std::pair<count_copies const, count_copies> move_source;
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
std::make_tuple(std::move(move_source.first)),
|
||||
std::make_tuple(std::move(move_source.second)));
|
||||
COPY_COUNT(tuple_copy_cost);
|
||||
MOVE_COUNT(tuple_move_cost);
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && \
|
||||
!(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 6) && \
|
||||
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && \
|
||||
!(defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 6) && \
|
||||
!(defined(BOOST_MSVC) && BOOST_MSVC < 1700)
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
std::forward_as_tuple(b.first),
|
||||
std::forward_as_tuple(b.second));
|
||||
COPY_COUNT(0); MOVE_COUNT(0);
|
||||
reset();
|
||||
x.emplace(boost::unordered::piecewise_construct,
|
||||
std::forward_as_tuple(b.first), std::forward_as_tuple(b.second));
|
||||
COPY_COUNT(0);
|
||||
MOVE_COUNT(0);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RUN_TESTS()
|
||||
|
||||
Reference in New Issue
Block a user